Skip to content

Commit 9754938

Browse files
committed
Add test built from JSON test data file
* test methods are create dynamically from the data * there is no dependencies on py.test Signed-off-by: Philippe Ombredanne <pombredanne@nexb.com>
1 parent c294af4 commit 9754938

File tree

1 file changed

+118
-0
lines changed

1 file changed

+118
-0
lines changed

test_purl.py

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# Copyright (c) the purl authors
2+
#
3+
# Permission is hereby granted, free of charge, to any person obtaining a copy
4+
# of this software and associated documentation files (the "Software"), to deal
5+
# in the Software without restriction, including without limitation the rights
6+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
# copies of the Software, and to permit persons to whom the Software is
8+
# furnished to do so, subject to the following conditions:
9+
#
10+
# The above copyright notice and this permission notice shall be included in all
11+
# copies or substantial portions of the Software.
12+
#
13+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
# SOFTWARE.
20+
21+
# Visit https://github.com/package-url/purl-python for support and download.
22+
23+
from __future__ import absolute_import
24+
from __future__ import print_function
25+
from __future__ import unicode_literals
26+
27+
import json
28+
import re
29+
import unittest
30+
31+
from purl import PackageURL
32+
33+
# Python 2 and 3 support
34+
try:
35+
# Python 2
36+
unicode
37+
str = unicode
38+
basestring = basestring
39+
except NameError:
40+
# Python 3
41+
unicode = str
42+
basestring = (bytes, str,)
43+
44+
45+
def create_test_function(description, purl, canonical_purl, is_invalid,
46+
type, name, namespace, version, qualifiers, subpath,
47+
test_func_prefix='test_purl_', **kwargs):
48+
"""
49+
Return a new (test function, test_name) where the test_function closed on
50+
test arguments. If is_error is True the tests are expected to raise an
51+
Exception.
52+
"""
53+
def test_purl(self):
54+
# TODO: add tests for is_invalid data
55+
56+
# parsing the test canonical `purl` then re-building a `purl` from these
57+
# parsed components should return the test canonical `purl`
58+
cano = PackageURL.from_string(purl)
59+
assert canonical_purl == cano.to_string()
60+
61+
# parsing the test `purl` should return the components parsed from the
62+
# test canonical `purl`
63+
parsed = PackageURL.from_string(canonical_purl)
64+
assert cano.to_dict() == parsed.to_dict()
65+
66+
# parsing the test `purl` then re-building a `purl` from these parsed
67+
# components should return the test canonical `purl`
68+
assert canonical_purl == parsed.to_string()
69+
70+
# building a `purl` from the test components should return the test
71+
# canonical `purl`
72+
built = PackageURL(type, namespace, name, version, qualifiers, subpath)
73+
assert canonical_purl == built.to_string()
74+
75+
# create a good function name for use in test discovery
76+
if not description:
77+
description = purl
78+
test_name = python_safe_name(test_func_prefix + description)
79+
test_purl.__name__ = test_name
80+
test_purl.funcname = test_name
81+
return test_purl, test_name
82+
83+
84+
def python_safe_name(s):
85+
"""
86+
Return a name derived from string `s` safe to use as a Python function name.
87+
88+
For example:
89+
>>> s = "not `\\a /`good` -safe name ??"
90+
>>> assert python_safe_name(s) == 'not_good_safe_name'
91+
"""
92+
no_punctuation = re.compile(r'[\W_]', re.MULTILINE).sub
93+
s = s.lower()
94+
s = no_punctuation(' ', s)
95+
s = '_'.join(s.split())
96+
if isinstance(s, unicode):
97+
s = s.encode('ascii', 'ignore')
98+
return s
99+
100+
101+
class PurlTest(unittest.TestCase):
102+
pass
103+
104+
105+
def build_tests(clazz=PurlTest, test_file='test-suite-data.json'):
106+
"""
107+
Dynamically build test methods for each purl test found in the `test_file`
108+
JSON file and attach a test method to the `clazz` class.
109+
"""
110+
with open(test_file) as tf:
111+
tests_data = json.load(tf)
112+
for items in tests_data:
113+
test_func, test_name = create_test_function(**items)
114+
# attach that method to the class
115+
setattr(clazz, test_name, test_func)
116+
117+
118+
build_tests()

0 commit comments

Comments
 (0)