Skip to content

Commit

Permalink
support nested TAP (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
MoLow authored Sep 4, 2022
1 parent e10856b commit a7124b6
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 13 deletions.
41 changes: 28 additions & 13 deletions tap2junit/tap13.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ def __init__(self, result, id, description=None, directive=None, comment=None):
class TAP13:
def __init__(self):
self.tests = []
self.__tests_counter = 0
self.__tests_counter = [0]
self._test_indentation = [0]
self.tests_planned = None

def _parse_yaml(self, line, in_yaml, in_yaml_block):
Expand All @@ -77,6 +78,14 @@ def _parse_yaml(self, line, in_yaml, in_yaml_block):

return in_yaml, in_yaml_block

def _handle_indentation(self, current_indentation):
if current_indentation > self._test_indentation[-1]:
self._test_indentation.append(current_indentation)
self.__tests_counter.append(0)
if current_indentation < self._test_indentation[-1]:
self._test_indentation.pop()
self.__tests_counter.pop()

def _parse(self, source):
seek_version = True
seek_plan = False
Expand Down Expand Up @@ -104,7 +113,8 @@ def _parse(self, source):
seek_version = False
seek_plan = True
seek_test = True
self.__tests_counter = 0
self.__tests_counter = [0]
self._test_indentation = [0]

for line in source:
if (
Expand All @@ -120,14 +130,16 @@ def _parse(self, source):
in_test = False
in_yaml = False
in_yaml_block = False
self.__tests_counter = 0
self.__tests_counter = [0]
self._test_indentation = [0]
# raise ValueError("Bad TAP format, multiple TAP headers")

if in_yaml:
in_yaml, in_yaml_block = self._parse_yaml(line, in_yaml, in_yaml_block)
continue

line = line.strip()
unstriped_line = line
line = unstriped_line.strip()

if in_test:
if RE_EXPLANATION.match(line):
Expand Down Expand Up @@ -163,38 +175,41 @@ def _parse(self, source):

# Stop processing if tests were found before the plan
# if plan is at the end, it must be last line -> stop processing
if self.__tests_counter > 0:
if len(self.__tests_counter) == 1 and self.__tests_counter[0] > 0:
break

if seek_test:
match = RE_TEST_LINE.match(line)
if match:
self.__tests_counter += 1
self._handle_indentation(len(unstriped_line) - len(line))
self.__tests_counter[-1] += 1
t_attrs = match.groupdict()
if t_attrs["id"] is None:
t_attrs["id"] = self.__tests_counter
t_attrs["id"] = self.__tests_counter[-1]
t_attrs["id"] = int(t_attrs["id"])
if t_attrs["id"] < self.__tests_counter:
if t_attrs["id"] < self.__tests_counter[-1]:
raise ValueError("Descending test id on line: %r" % line)
# according to TAP13 specs, missing tests must be handled as
# 'not ok' so here we add the missing tests in sequence
while t_attrs["id"] > self.__tests_counter:
while t_attrs["id"] > self.__tests_counter[-1]:
self.tests.append(
Test(
"not ok",
self.__tests_counter,
self.__tests_counter[-1],
comment="DIAG: Test %s not present"
% self.__tests_counter,
% self.__tests_counter[-1],
)
)
self.__tests_counter += 1
self.__tests_counter[-1] += 1
t = Test(**t_attrs)
if t.result == "Bail out!":
t.result = "not ok"
# according to TAP13 specs, everything after this is an
# explanation of why testing must be stopped
t.diagnostics = t.diagnostics or t.description
t.description = "Bail out for Test %s" % self.__tests_counter
t.description = (
"Bail out for Test %s" % self.__tests_counter[-1]
)
self.tests.append(t)
in_test = True
continue
Expand Down
50 changes: 50 additions & 0 deletions test/fixtures/test-nested.tap
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
TAP version 13
# Subtest: parent
# Subtest: top level 1
ok 1 - top level 1
---
duration_ms: 0.340575089
...
# Subtest: top level 2
ok 2 - top level 2
---
duration_ms: 0.30303944
...
# Subtest: nested
# Subtest: nested 1
ok 1 - nested 1
---
duration_ms: 2.367745206
...
# Subtest: nested 2
not ok 2 - nested 2
---
duration_ms: 2.332323873
failureType: 'cancelledByParent'
error: 'Promise resolution is still pending but the event loop has already resolved'
code: 'ERR_TEST_FAILURE'
stack: |-
process.emit (node:events:513:28)
...
1..2
not ok 3 - nested
---
duration_ms: 2.367870901
failureType: 'fail'
error: 'Promise resolution is still pending but the event loop has already resolved'
code: 'ERR_TEST_FAILURE'
stack: |-
process.emit (node:events:513:28)
...
# Subtest: top level 4
ok 4 - top level 4
---
duration_ms: 0.340575089
...
1..4
ok 1 - parent
---
duration_ms: 2.489501484
...
1..1
# tests 1
31 changes: 31 additions & 0 deletions test/output/test-nested.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<testsuites disabled="0" errors="0" failures="2" tests="7" time="10.541631082">
<testsuite disabled="0" errors="0" failures="2" name="test/fixtures/test-nested" skipped="0" tests="7" time="10.541631082" hostname="{HOSTNAME}">
<testcase name="- top level 1" time="0.340575"/>
<testcase name="- top level 2" time="0.303039"/>
<testcase name="- nested 1" time="2.367745"/>
<testcase name="- nested 2" time="2.332324">
<failure type="failure" message=" (0)">
---
code: ERR_TEST_FAILURE
duration_ms: 2.332323873
error: Promise resolution is still pending but the event loop has already resolved
failureType: cancelledByParent
...
</failure>
</testcase>
<testcase name="- nested" time="2.367871">
<failure type="failure" message=" (0)">
---
code: ERR_TEST_FAILURE
duration_ms: 2.367870901
error: Promise resolution is still pending but the event loop has already resolved
failureType: fail
...
</failure>
<system-err>['# Subtest: top level 4']</system-err>
</testcase>
<testcase name="- top level 4" time="0.340575"/>
<testcase name="- parent" time="2.489501"/>
</testsuite>
</testsuites>

0 comments on commit a7124b6

Please sign in to comment.