Skip to content

Commit

Permalink
Add support for TAP version 12.
Browse files Browse the repository at this point in the history
This is the consequences of two things taken from the TAP specification
document: https://testanything.org/tap-specification.html
  - version line must be the first line and is only required for TAP
version 13, every version explicitly set below 13 is an error.
  - YAML management is only specified for version 13

Add test scenarios for version line missing and test plan at the end
(this is specified that the plan could be at the beginning of output
or at the end)

Signed-off-by: Frederic Martinsons <frederic.martinsons@sigfox.com>
  • Loading branch information
fmartinsons committed Jun 3, 2021
1 parent adf657e commit cc80bfc
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 13 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
A utility that converts [TAP version 13](https://testanything.org/) to [JUnit](https://junit.org/junit5/). That's it.
A utility that converts [TAP version 12 and 13](https://testanything.org/) to [JUnit](https://junit.org/junit5/). That's it.

Upstream is currently unmaintained at https://bitbucket.org/fedoraqa/pytap13/src/develop/

Expand Down
53 changes: 41 additions & 12 deletions tap2junit/tap13.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

import yamlish

RE_VERSION = re.compile(r"^\s*TAP version 13\s*$")
RE_VERSION = re.compile(r"^\s*TAP version (?P<version>.*)$")
RE_PLAN = re.compile(
r"^\s*(?P<start>\d+)\.\.(?P<end>\d+)\s*(#\s*(?P<explanation>.*))?\s*$"
)
Expand Down Expand Up @@ -65,8 +65,30 @@ def _parse(self, source):

in_test = False
in_yaml = False

version12 = False
# see https://testanything.org/tap-version-13-specification.html
# To indicate that this is TAP13 the first line must be
# 'TAP version 13'
non_empty_lines = [
line for line in source.getvalue().splitlines() if line.strip()
]
match = RE_VERSION.match(non_empty_lines[0])
if match:
# It is an error if version is anything below 13 (so not an int is an error)
version = int(match.groupdict()["version"])
if version < 13:
raise ValueError("Version specified is less than 13")
else:
# No version, so it is 12: https://testanything.org/tap-specification.html
version12 = True
seek_version = False
seek_plan = True
seek_test = True
self.__tests_counter = 0

for line in source:
if not seek_version and RE_VERSION.match(line):
if not version12 and not seek_version and RE_VERSION.match(line):
# refack: breaking TAP13 spec, to allow multiple TAP headers
seek_version = True
seek_plan = False
Expand All @@ -92,13 +114,18 @@ def _parse(self, source):
self.tests[-1].diagnostics.append(line)
continue
if RE_YAMLISH_START.match(line):
if version12:
raise ValueError(
"Bad TAP format, yaml block detected but no "
"TAP version 13 line"
)
self.tests[-1]._yaml_buffer = [line.strip()]
in_yaml = True
continue

# this is "beginning" of the parsing, skip all lines until
# version is found
if seek_version:
# this is "beginning" of the parsing for TAP version 13
# skip all lines until version is found
if not version12 and seek_version:
if RE_VERSION.match(line):
seek_version = False
seek_plan = True
Expand All @@ -107,10 +134,10 @@ def _parse(self, source):
continue

if seek_plan:
m = RE_PLAN.match(line)
if m:
d = m.groupdict()
self.tests_planned = int(d.get("end", 0))
match = RE_PLAN.match(line)
if match:
fields = match.groupdict()
self.tests_planned = int(fields.get("end", 0))
seek_plan = False

# Stop processing if tests were found before the plan
Expand All @@ -119,10 +146,10 @@ def _parse(self, source):
break

if seek_test:
m = RE_TEST_LINE.match(line)
if m:
match = RE_TEST_LINE.match(line)
if match:
self.__tests_counter += 1
t_attrs = m.groupdict()
t_attrs = match.groupdict()
if t_attrs["id"] is None:
t_attrs["id"] = self.__tests_counter
t_attrs["id"] = int(t_attrs["id"])
Expand Down Expand Up @@ -163,6 +190,8 @@ def _parse(self, source):
description="Test %s missing" % (i + 1),
comment="DIAG: Test %s not present" % (i + 1),
)
# Even for version 12 file which doesn't specify YAML we use
# this field to ease thing for the caller
t.yaml = {"severity": "missing", "exitcode": -1}
self.tests.append(t)

Expand Down
8 changes: 8 additions & 0 deletions test/fixtures/test-plan-at-end.tap
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
TAP version 13
ok 1 /MyTest/1
ok 2 /MyTest/2
# My test 2 comments
ok 3 /MyTest/3
not ok 4 /MyTest/3
ok /MyTest/4
1..5
7 changes: 7 additions & 0 deletions test/fixtures/test-tap12.tap
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
1..5
ok 1 /MyTest/1
ok 2 /MyTest/2
# My test 2 comments
ok 3 /MyTest/3
not ok 4 /MyTest/3
ok /MyTest/4

0 comments on commit cc80bfc

Please sign in to comment.