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(r
"(\d+)\.\.(\d+)\s*(?:\#\s+(.*))?"
67 _
, plan_stop
, comment
= match
.groups()
68 plan_stop
= int(plan_stop
)
69 if plan_start
> plan_stop
and plan_stop
== 0:
72 subunit
.write("test: file skip\n")
73 subunit
.write("skip: file skip [\n")
74 subunit
.write("%s\n" % comment
)
77 # not a plan line, or have seen one before
78 match
= re
.match(r
"(ok|not ok)(?:\s+(\d+)?)?(?:\s+([^#]*[^#\s]+)\s*)?(?:\s+#\s+(TODO|SKIP|skip|todo)(?:\s+(.*))?)?"
81 # new test, emit current one.
83 status
, number
, description
, directive
, directive_comment
= match
.groups()
88 if description
is None:
91 description
= ' ' + description
92 if directive
is not None:
93 if directive
.upper() == 'TODO':
95 elif directive
.upper() == 'SKIP':
97 if directive_comment
is not None:
98 log
.append(directive_comment
)
99 if number
is not None:
101 while plan_start
< number
:
102 plan_start
= _skipped_test(subunit
, plan_start
)
103 test_name
= "test %d%s" % (plan_start
, description
)
106 match
= re
.match(r
"Bail out\!(?:\s*(.*))?"
109 reason
, = match
.groups()
113 extra
= ' %s' % reason
115 test_name
= "Bail out!%s" % extra
119 match
= re
.match(r
"\#.*"
122 log
.append(line
[:-1])
126 while plan_start
<= plan_stop
:
127 # record missed tests
128 plan_start
= _skipped_test(subunit
, plan_start
)
132 sys
.exit(TAP2SubUnit(sys
.stdin
, sys
.stdout
))