1 # SPDX-License-Identifier: BSD-2-Clause
3 # Copyright (c) 2016, Matt Layman
5 from __future__
import print_function
10 from tap
.directive
import Directive
11 from tap
.i18n
import _
12 from tap
.line
import Result
15 class Tracker(object):
17 self
, outdir
=None, combined
=False, streaming
=False, stream
=None, header
=True
21 # Combine all the test results into one file.
22 self
.combined
= combined
23 self
.combined_line_number
= 0
24 # Test case ordering is important for the combined results
25 # because of how numbers are assigned. The test cases
26 # must be tracked in order so that reporting can sequence
27 # the line numbers properly.
28 self
.combined_test_cases_seen
= []
30 # Stream output directly to a stream instead of file output.
31 self
.streaming
= streaming
34 # Display the test case header unless told not to.
37 # Internal state for tracking each test case.
40 # Python versions 2 and 3 keep maketrans in different locations.
41 if sys
.version_info
[0] < 3:
42 self
._sanitized
_table
= string
.maketrans(' \\/\n', '----')
43 else: # pragma: no cover
44 self
._sanitized
_table
= str.maketrans(' \\/\n', '----')
46 def _get_outdir(self
):
49 def _set_outdir(self
, outdir
):
51 if outdir
and not os
.path
.exists(outdir
):
54 outdir
= property(_get_outdir
, _set_outdir
)
56 def _track(self
, class_name
):
57 """Keep track of which test cases have executed."""
58 if self
._test
_cases
.get(class_name
) is None:
59 if self
.streaming
and self
.header
:
60 self
._write
_test
_case
_header
(class_name
, self
.stream
)
62 self
._test
_cases
[class_name
] = []
64 self
.combined_test_cases_seen
.append(class_name
)
66 def add_ok(self
, class_name
, description
, directive
=''):
69 number
=self
._get
_next
_line
_number
(class_name
),
70 description
=description
,
71 directive
=Directive(directive
),
73 self
._add
_line
(class_name
, result
)
75 def add_not_ok(self
, class_name
, description
, directive
='', diagnostics
=None):
78 number
=self
._get
_next
_line
_number
(class_name
),
79 description
=description
,
80 diagnostics
=diagnostics
,
81 directive
=Directive(directive
),
83 self
._add
_line
(class_name
, result
)
85 def add_skip(self
, class_name
, description
, reason
):
86 directive
= 'SKIP {0}'.format(reason
)
89 number
=self
._get
_next
_line
_number
(class_name
),
90 description
=description
,
91 directive
=Directive(directive
),
93 self
._add
_line
(class_name
, result
)
95 def _add_line(self
, class_name
, result
):
96 self
._track
(class_name
)
98 print(result
, file=self
.stream
)
99 self
._test
_cases
[class_name
].append(result
)
101 def _get_next_line_number(self
, class_name
):
102 if self
.combined
or self
.streaming
:
103 # This has an obvious side effect. Oh well.
104 self
.combined_line_number
+= 1
105 return self
.combined_line_number
108 return len(self
._test
_cases
[class_name
]) + 1
110 # A result is created before the call to _track so the test
111 # case may not be tracked yet. In that case, the line is 1.
114 def generate_tap_reports(self
):
115 """Generate TAP reports.
117 The results are either combined into a single output file or
118 the output file name is generated from the test case.
121 # The results already went to the stream, record the plan.
122 print('1..{0}'.format(self
.combined_line_number
), file=self
.stream
)
126 combined_file
= 'testresults.tap'
128 combined_file
= os
.path
.join(self
.outdir
, combined_file
)
129 with
open(combined_file
, 'w') as out_file
:
130 for test_case
in self
.combined_test_cases_seen
:
131 self
.generate_tap_report(
132 test_case
, self
._test
_cases
[test_case
], out_file
134 print('1..{0}'.format(self
.combined_line_number
), file=out_file
)
136 for test_case
, tap_lines
in self
._test
_cases
.items():
137 with
open(self
._get
_tap
_file
_path
(test_case
), 'w') as out_file
:
138 self
.generate_tap_report(test_case
, tap_lines
, out_file
)
140 def generate_tap_report(self
, test_case
, tap_lines
, out_file
):
141 self
._write
_test
_case
_header
(test_case
, out_file
)
143 for tap_line
in tap_lines
:
144 print(tap_line
, file=out_file
)
146 # For combined results, the plan is only output once after
147 # all the test cases complete.
148 if not self
.combined
:
149 print('1..{0}'.format(len(tap_lines
)), file=out_file
)
151 def _write_test_case_header(self
, test_case
, stream
):
153 _('# TAP results for {test_case}').format(test_case
=test_case
), file=stream
156 def _get_tap_file_path(self
, test_case
):
157 """Get the TAP output file path for the test case."""
158 sanitized_test_case
= test_case
.translate(self
._sanitized
_table
)
159 tap_file
= sanitized_test_case
+ '.tap'
161 return os
.path
.join(self
.outdir
, tap_file
)
This page took 0.032766 seconds and 4 git commands to generate.