3 # tap2subunit: convert a tap stream to a subunit stream.
4 # Extract from the subunit source:
5 # Copyright (C) 2005 Robert Collins <robertc@robertcollins.net>
7 # Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
8 # license at the users choice. A copy of both licenses are available in the
9 # project source as Apache-2.0 and BSD. You may not use this file except in
10 # compliance with one of these two licences.
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT
14 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15 # license you chose for the specific language governing permissions and
16 # limitations under that license.
23 def TAP2SubUnit(tap
, subunit
):
24 """Filter a TAP pipe into a subunit pipe.
26 :param tap: A tap pipe/stream/file object.
27 :param subunit: A pipe/stream/file object to write subunit results to.
28 :return: The exit code to exit with.
36 def _skipped_test(subunit
, plan_start
):
37 # Some tests were skipped.
38 subunit
.write('test: test %d\n' % plan_start
)
39 subunit
.write('error: test %d [\n' % plan_start
)
40 subunit
.write('test missing from TAP output\n')
43 # Test data for the next test to emit
51 subunit
.write("test: %s\n" % test_name
)
53 subunit
.write("%s: %s\n" % (result
, test_name
))
55 subunit
.write("%s: %s [\n" % (result
, test_name
))
58 subunit
.write("%s\n" % line
)
62 if state
== BEFORE_PLAN
:
63 match
= re
.match("(\d+)\.\.(\d+)\s*(?:\#\s+(.*))?\n", line
)
66 _
, plan_stop
, comment
= match
.groups()
67 plan_stop
= int(plan_stop
)
68 if plan_start
> plan_stop
and plan_stop
== 0:
71 subunit
.write("test: file skip\n")
72 subunit
.write("skip: file skip [\n")
73 subunit
.write("%s\n" % comment
)
76 # not a plan line, or have seen one before
77 match
= re
.match("(ok|not ok)(?:\s+(\d+)?)?(?:\s+([^#]*[^#\s]+)\s*)?(?:\s+#\s+(TODO|SKIP|skip|todo)(?:\s+(.*))?)?\n", line
)
79 # new test, emit current one.
81 status
, number
, description
, directive
, directive_comment
= match
.groups()
86 if description
is None:
89 description
= ' ' + description
90 if directive
is not None:
91 if directive
.upper() == 'TODO':
93 elif directive
.upper() == 'SKIP':
95 if directive_comment
is not None:
96 log
.append(directive_comment
)
97 if number
is not None:
99 while plan_start
< number
:
100 plan_start
= _skipped_test(subunit
, plan_start
)
101 test_name
= "test %d%s" % (plan_start
, description
)
104 match
= re
.match("Bail out\!(?:\s*(.*))?\n", line
)
106 reason
, = match
.groups()
110 extra
= ' %s' % reason
112 test_name
= "Bail out!%s" % extra
116 match
= re
.match("\#.*\n", line
)
118 log
.append(line
[:-1])
122 while plan_start
<= plan_stop
:
123 # record missed tests
124 plan_start
= _skipped_test(subunit
, plan_start
)
128 sys
.exit(TAP2SubUnit(sys
.stdin
, sys
.stdout
))