Skip to content

Commit d9c94d4

Browse files
authored
Merge pull request #14 from cclauss/pre-release
Cleanup to prepare for a release
2 parents ee5c20b + 1f04dca commit d9c94d4

File tree

12 files changed

+111
-143
lines changed

12 files changed

+111
-143
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ env:
1212
install: pip install flake8 junit-xml yamlish
1313
before_script: flake8 . --count --select=E9,F --show-source --statistics
1414
script:
15+
- python tap2junit/tap13.py
1516
- python -m tap2junit -i test/fixtures/${FILENAME}.tap -o test/output/${FILENAME}.xml
1617
- cat test/output/${FILENAME}.xml

Pipfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ verify_ssl = true
44
name = "pypi"
55

66
[packages]
7-
yamlish = "*"
87
junit-xml = "*"
8+
yamlish = "*"
99

1010
[dev-packages]
1111

Pipfile.lock

Lines changed: 0 additions & 60 deletions
This file was deleted.

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
A utility that converts [TAP version 13](https://testanything.org/) to [JUnit](https://junit.org/junit5/). That's it.
2+
3+
The syntax expected is currently pretty custom-tailored for use at https://ci.nodejs.org.
4+
5+
Improvements welcome.
6+
7+
To install:
8+
9+
`pip install tap2junit`
10+
11+
To run:
12+
13+
`tap2junit -i file.tap -o file.xml`
14+
15+
Suggested code hygiene:
16+
```
17+
$ flake8 --max-line-length=88 .
18+
$ isort -rc .
19+
$ black .
20+
```

README.rst

Lines changed: 0 additions & 14 deletions
This file was deleted.

setup.cfg

Lines changed: 0 additions & 2 deletions
This file was deleted.

setup.py

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,35 @@
1-
# coding: utf-8
2-
3-
# Always prefer setuptools over distutils
4-
from setuptools import setup
5-
# To use a consistent encoding
6-
from codecs import open
71
from os import path
82

3+
import setuptools
4+
95
here = path.abspath(path.dirname(__file__))
106

117
# Get the long description from the README file
12-
with open(path.join(here, 'README.rst'), encoding='utf-8') as f:
13-
long_description = f.read()
8+
with open(path.join(here, "README.md")) as in_file:
9+
long_description = in_file.read()
1410

15-
setup(
16-
name='tap2junit',
17-
version='0.1.5',
18-
description='Tap13 to jUnit',
11+
setuptools.setup(
12+
name="tap2junit",
13+
version="0.1.5",
14+
description="Tap13 to jUnit",
1915
long_description=long_description,
20-
url='https://github.com/jbergstroem/tap2junit',
21-
author='Johan Bergström',
22-
author_email='bugs@bergtroem.nu',
16+
url="https://github.com/nodejs/tap2junit",
17+
author="Node.js contributors",
18+
author_email="cclauss@me.com",
2319
classifiers=[
24-
'Development Status :: 3 - Alpha',
25-
'Intended Audience :: Developers',
26-
'Topic :: Software Development :: Build Tools',
20+
"Development Status :: 4 - Beta",
21+
"Intended Audience :: Developers",
2722
"License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)",
28-
'Programming Language :: Python :: 2',
29-
'Programming Language :: Python :: 3',
23+
"Programming Language :: Python :: 2",
24+
"Programming Language :: Python :: 2.7",
25+
"Programming Language :: Python :: 3",
26+
"Programming Language :: Python :: 3.5",
27+
"Programming Language :: Python :: 3.6",
28+
"Programming Language :: Python :: 3.7",
29+
"Topic :: Software Development :: Build Tools",
3030
],
31-
keywords='tap13 junit',
32-
packages=['tap2junit'],
33-
install_requires=['yamlish', 'junit-xml'],
34-
entry_points={
35-
'console_scripts': [
36-
'tap2junit = tap2junit.__main__:main',
37-
],
38-
},
31+
keywords="tap13 junit",
32+
packages=["tap2junit"],
33+
install_requires=["junit-xml", "yamlish"],
34+
entry_points={"console_scripts": ["tap2junit = tap2junit.__main__:main"]},
3935
)

tap2junit/__main__.py

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,28 @@
11
import argparse
22
import os
33
import platform
4-
from junit_xml import TestSuite, TestCase
4+
5+
from junit_xml import TestCase, TestSuite
56
from tap2junit.tap13 import TAP13 as tap13
67

78

89
def map_yaml_to_junit(test):
910
yaml = test.yaml or {}
1011
# Even though the name is `duration_ms` the value is in seconds.
11-
elapsed_sec = yaml.get('duration_ms', None)
12+
elapsed_sec = yaml.get("duration_ms", None)
1213
t = TestCase(test.description, classname=None, elapsed_sec=elapsed_sec)
13-
if test.result == 'ok':
14-
if test.directive in ['SKIP', 'TODO']:
14+
if test.result == "ok":
15+
if test.directive in ("SKIP", "TODO"):
1516
t.add_skipped_info(test.comment)
1617
else:
1718
t.stdout = test.comment
1819

19-
elif test.result == 'not ok':
20-
err_code = yaml.get('exitcode', 0)
21-
err_severity = yaml.get('severity', '')
22-
err_output = yaml.get('stack', '')
20+
elif test.result == "not ok":
21+
err_code = yaml.get("exitcode", 0)
22+
err_severity = yaml.get("severity", "")
23+
err_output = yaml.get("stack", "")
2324
error_message = "{} ({})".format(err_severity, err_code)
24-
if err_severity == 'crashed' or err_code < 0:
25+
if err_code < 0 or err_severity == "crashed":
2526
t.add_error_info(error_message, err_output, err_code)
2627
else:
2728
t.add_failure_info(error_message, err_output, err_code)
@@ -40,16 +41,28 @@ def convert(in_file, out_file):
4041
input_file = os.path.splitext(in_file.name)[0]
4142
data = in_file.read()
4243
result = parse(input_file, data)
43-
TestSuite.to_file(out_file, [result], prettyprint=True, encoding='utf-8')
44+
TestSuite.to_file(out_file, [result], prettyprint=True, encoding="utf-8")
4445

4546

4647
def main():
47-
arg_parser = argparse.ArgumentParser('tap2junit')
48-
arg_parser.add_argument('--input', '-i', type=argparse.FileType('r'), help='path to tap13 file', required=True)
49-
arg_parser.add_argument('--output', '-o', type=argparse.FileType('w'), help='output file name', required=True)
50-
args = arg_parser.parse_args()
51-
convert(args.input, args.output)
48+
arg_parser = argparse.ArgumentParser("tap2junit")
49+
arg_parser.add_argument(
50+
"--input",
51+
"-i",
52+
type=argparse.FileType("r"),
53+
help="path to tap13 file",
54+
required=True,
55+
)
56+
arg_parser.add_argument(
57+
"--output",
58+
"-o",
59+
type=argparse.FileType("w"),
60+
help="output file name",
61+
required=True,
62+
)
63+
args = arg_parser.parse_args()
64+
convert(args.input, args.output)
5265

5366

5467
if __name__ == "__main__":
55-
main()
68+
main()

tap2junit/tap13.py

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from __future__ import print_function
21
# Copyright 2013, Red Hat, Inc.
32
#
43
# This program is free software; you can redistribute it and/or modify
@@ -20,12 +19,14 @@
2019
from __future__ import print_function
2120

2221
import re
22+
23+
import yamlish
24+
2325
try:
2426
from StringIO import StringIO
2527
except ImportError:
2628
from io import StringIO
27-
28-
import yamlish
29+
2930

3031
try:
3132
basestring
@@ -34,15 +35,23 @@
3435

3536

3637
RE_VERSION = re.compile(r"^\s*TAP version 13\s*$")
37-
RE_PLAN = re.compile(r"^\s*(?P<start>\d+)\.\.(?P<end>\d+)\s*(#\s*(?P<explanation>.*))?\s*$")
38-
RE_TEST_LINE = re.compile(r"^\s*(?P<result>(not\s+)?ok)\s*(?P<id>\d+)?\s*(?P<description>[^#]+)?\s*(#\s*(?P<directive>TODO|SKIP)?\s*(?P<comment>.+)?)?\s*$", re.IGNORECASE)
38+
RE_PLAN = re.compile(
39+
r"^\s*(?P<start>\d+)\.\.(?P<end>\d+)\s*(#\s*(?P<explanation>.*))?\s*$"
40+
)
41+
RE_TEST_LINE = re.compile(
42+
(
43+
r"^\s*(?P<result>(not\s+)?ok)\s*(?P<id>\d+)?\s*(?P<description>[^#]+)"
44+
r"?\s*(#\s*(?P<directive>TODO|SKIP)?\s*(?P<comment>.+)?)?\s*$"
45+
),
46+
re.IGNORECASE,
47+
)
3948
RE_EXPLANATION = re.compile(r"^\s*#\s*(?P<explanation>.+)?\s*$")
4049
RE_YAMLISH_START = re.compile(r"^\s*---.*$")
4150
RE_YAMLISH_END = re.compile(r"^\s*\.\.\.\s*$")
4251

4352

4453
class Test(object):
45-
def __init__(self, result, id, description = None, directive = None, comment = None):
54+
def __init__(self, result, id, description=None, directive=None, comment=None):
4655
self.result = result
4756
self.id = id
4857
self.description = description
@@ -62,7 +71,6 @@ def __init__(self):
6271
self.__tests_counter = 0
6372
self.tests_planned = None
6473

65-
6674
def _parse(self, source):
6775
seek_version = True
6876
seek_plan = False
@@ -116,11 +124,11 @@ def _parse(self, source):
116124
m = RE_PLAN.match(line)
117125
if m:
118126
d = m.groupdict()
119-
self.tests_planned = int(d.get('end', 0))
127+
self.tests_planned = int(d.get("end", 0))
120128
seek_plan = False
121129

122130
# Stop processing if tests were found before the plan
123-
# if plan is at the end, it must be the last line -> stop processing
131+
# if plan is at the end, it must be last line -> stop processing
124132
if self.__tests_counter > 0:
125133
break
126134

@@ -129,15 +137,22 @@ def _parse(self, source):
129137
if m:
130138
self.__tests_counter += 1
131139
t_attrs = m.groupdict()
132-
if t_attrs['id'] is None:
133-
t_attrs['id'] = self.__tests_counter
134-
t_attrs['id'] = int(t_attrs['id'])
135-
if t_attrs['id'] < self.__tests_counter:
140+
if t_attrs["id"] is None:
141+
t_attrs["id"] = self.__tests_counter
142+
t_attrs["id"] = int(t_attrs["id"])
143+
if t_attrs["id"] < self.__tests_counter:
136144
raise ValueError("Descending test id on line: %r" % line)
137-
# according to TAP13 specs, missing tests must be handled as 'not ok'
138-
# here we add the missing tests in sequence
139-
while t_attrs['id'] > self.__tests_counter:
140-
self.tests.append(Test('not ok', self.__tests_counter, comment = 'DIAG: Test %s not present' % self.__tests_counter))
145+
# according to TAP13 specs, missing tests must be handled as
146+
# 'not ok'. Here we add the missing tests in sequence
147+
while t_attrs["id"] > self.__tests_counter:
148+
self.tests.append(
149+
Test(
150+
"not ok",
151+
self.__tests_counter,
152+
comment="DIAG: Test %s not present"
153+
% self.__tests_counter,
154+
)
155+
)
141156
self.__tests_counter += 1
142157
t = Test(**t_attrs)
143158
self.tests.append(t)
@@ -150,8 +165,9 @@ def _parse(self, source):
150165

151166
if len(self.tests) != self.tests_planned:
152167
for i in range(len(self.tests), self.tests_planned):
153-
self.tests.append(Test('not ok', i+1, comment = 'DIAG: Test %s not present'))
154-
168+
self.tests.append(
169+
Test("not ok", i + 1, comment="DIAG: Test %s not present")
170+
)
155171

156172
def parse(self, source):
157173
if isinstance(source, basestring):
@@ -199,6 +215,7 @@ def parse(self, source):
199215
t.parse(input)
200216

201217
import pprint
218+
202219
for test in t.tests:
203220
print(test.result, test.id, test.description, "#", test.directive, test.comment)
204221
pprint.pprint(test.yaml_buffer)

test/fixtures/test2.xml

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)