Skip to content

Commit

Permalink
Update tap13.py to latest (Apache licensed)
Browse files Browse the repository at this point in the history
Pulled lastest from upstream:

        $ curl -o tap2junit/tap13.py \
            https://bitbucket.org/fedoraqa/pytap13/raw/master/pytap13.py

Note that the upstream version is now under the Apache License.

Fixes nodejs/admin#413
  • Loading branch information
sam-github committed Oct 4, 2019
1 parent db953be commit b2248c0
Showing 1 changed file with 38 additions and 77 deletions.
115 changes: 38 additions & 77 deletions tap2junit/tap13.py
Original file line number Diff line number Diff line change
@@ -1,57 +1,35 @@
# Copyright 2013, Red Hat, Inc.
# Copyright 2019, Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# http://www.apache.org/licenses/LICENSE-2.0
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Author: Josef Skladanka <jskladan@redhat.com>

from __future__ import print_function

import re

import yamlish

try:
from StringIO import StringIO
except ImportError:
from io import StringIO
import StringIO


try:
basestring
except NameError:
basestring = str


RE_VERSION = re.compile(r"^\s*TAP version 13\s*$")
RE_PLAN = re.compile(
r"^\s*(?P<start>\d+)\.\.(?P<end>\d+)\s*(#\s*(?P<explanation>.*))?\s*$"
)
RE_TEST_LINE = re.compile(
(
r"^\s*(?P<result>(not\s+)?ok)\s*(?P<id>\d+)?\s*(?P<description>[^#]+)"
r"?\s*(#\s*(?P<directive>TODO|SKIP)?\s*(?P<comment>.+)?)?\s*$"
),
re.IGNORECASE,
)
RE_PLAN = re.compile(r"^\s*(?P<start>\d+)\.\.(?P<end>\d+)\s*(#\s*(?P<explanation>.*))?\s*$")
RE_TEST_LINE = re.compile(r"^\s*(?P<result>(not\s+)?ok)\s*(?P<id>\d+)?\s*(?P<description>[^#]+)?\s*(#\s*(?P<directive>TODO|SKIP)?\s*(?P<comment>.+)?)?\s*$", re.IGNORECASE)
RE_EXPLANATION = re.compile(r"^\s*#\s*(?P<explanation>.+)?\s*$")
RE_YAMLISH_START = re.compile(r"^\s*---.*$")
RE_YAMLISH_END = re.compile(r"^\s*\.\.\.\s*$")


class Test(object):
def __init__(self, result, id, description=None, directive=None, comment=None):
def __init__(self, result, id, description = None, directive = None, comment = None):
self.result = result
self.id = id
self.description = description
Expand All @@ -60,8 +38,8 @@ def __init__(self, result, id, description=None, directive=None, comment=None):
except AttributeError:
self.directive = directive
self.comment = comment
self.yaml = {}
self.yaml_buffer = []
self.yaml = None
self._yaml_buffer = None
self.diagnostics = []


Expand All @@ -71,6 +49,7 @@ def __init__(self):
self.__tests_counter = 0
self.tests_planned = None


def _parse(self, source):
seek_version = True
seek_plan = False
Expand All @@ -79,24 +58,16 @@ def _parse(self, source):
in_test = False
in_yaml = False
for line in source:

if not seek_version and RE_VERSION.match(line):
# refack: breaking TAP13 spec, to allow multiple TAP headers
seek_version = True
seek_plan = False
seek_test = False
in_test = False
in_yaml = False
self.__tests_counter = 0
# raise ValueError("Bad TAP format, multiple TAP headers")
raise ValueError("Bad TAP format, multiple TAP headers")

if in_yaml:
if RE_YAMLISH_END.match(line):
self.tests[-1].yaml_buffer.append(line.strip())
self.tests[-1]._yaml_buffer.append(line.strip())
in_yaml = False
self.tests[-1].yaml = yamlish.load(self.tests[-1].yaml_buffer)
self.tests[-1].yaml = yamlish.load(self.tests[-1]._yaml_buffer)
else:
self.tests[-1].yaml_buffer.append(line.rstrip())
self.tests[-1]._yaml_buffer.append(line.rstrip())
continue

line = line.strip()
Expand All @@ -106,7 +77,7 @@ def _parse(self, source):
self.tests[-1].diagnostics.append(line)
continue
if RE_YAMLISH_START.match(line):
self.tests[-1].yaml_buffer = [line.strip()]
self.tests[-1]._yaml_buffer = [line.strip()]
in_yaml = True
continue

Expand All @@ -124,11 +95,11 @@ def _parse(self, source):
m = RE_PLAN.match(line)
if m:
d = m.groupdict()
self.tests_planned = int(d.get("end", 0))
self.tests_planned = int(d.get('end', 0))
seek_plan = False

# Stop processing if tests were found before the plan
# if plan is at the end, it must be last line -> stop processing
# if plan is at the end, it must be the last line -> stop processing
if self.__tests_counter > 0:
break

Expand All @@ -137,22 +108,15 @@ def _parse(self, source):
if m:
self.__tests_counter += 1
t_attrs = m.groupdict()
if t_attrs["id"] is None:
t_attrs["id"] = self.__tests_counter
t_attrs["id"] = int(t_attrs["id"])
if t_attrs["id"] < self.__tests_counter:
if t_attrs['id'] is None:
t_attrs['id'] = self.__tests_counter
t_attrs['id'] = int(t_attrs['id'])
if t_attrs['id'] < self.__tests_counter:
raise ValueError("Descending test id on line: %r" % line)
# according to TAP13 specs, missing tests must be handled as
# 'not ok'. Here we add the missing tests in sequence
while t_attrs["id"] > self.__tests_counter:
self.tests.append(
Test(
"not ok",
self.__tests_counter,
comment="DIAG: Test %s not present"
% self.__tests_counter,
)
)
# according to TAP13 specs, missing tests must be handled as 'not ok'
# here we add the missing tests in sequence
while t_attrs['id'] > self.__tests_counter:
self.tests.append(Test('not ok', self.__tests_counter, comment = 'DIAG: Test %s not present' % self.__tests_counter))
self.__tests_counter += 1
t = Test(**t_attrs)
self.tests.append(t)
Expand All @@ -165,17 +129,15 @@ def _parse(self, source):

if len(self.tests) != self.tests_planned:
for i in range(len(self.tests), self.tests_planned):
self.tests.append(
Test("not ok", i + 1, comment="DIAG: Test %s not present")
)
self.tests.append(Test('not ok', i+1, comment = 'DIAG: Test %s not present'))


def parse(self, source):
if isinstance(source, basestring):
self._parse(StringIO(source))
if isinstance(source, (str, unicode)):
self._parse(StringIO.StringIO(source))
elif hasattr(source, "__iter__"):
self._parse(source)


if __name__ == "__main__":
input = """
TAP version 13
Expand Down Expand Up @@ -215,8 +177,7 @@ def parse(self, source):
t.parse(input)

import pprint

for test in t.tests:
print(test.result, test.id, test.description, "#", test.directive, test.comment)
pprint.pprint(test.yaml_buffer)
print test.result, test.id, test.description, "#", test.directive, test.comment
pprint.pprint(test._yaml_buffer)
pprint.pprint(test.yaml)

0 comments on commit b2248c0

Please sign in to comment.