diff --git a/pysrc/pipfile.py b/pysrc/pipfile.py index b032d36f..75439b90 100644 --- a/pysrc/pipfile.py +++ b/pysrc/pipfile.py @@ -23,19 +23,35 @@ def __init__(self, name): def from_dict(cls, name, requirement_dict, pos_in_toml): req = cls(name) - req.version = requirement_dict.get('version') - req.editable = requirement_dict.get('editable', False) + req.version = parse_req(requirement_dict.get('version')) + req.editable = parse_req(requirement_dict.get('editable', False)) for vcs in ['git', 'hg', 'svn', 'bzr']: if vcs in requirement_dict: req.vcs = vcs req.vcs_uri = requirement_dict[vcs] break - req.markers = requirement_dict.get('markers') + req.markers = parse_req(requirement_dict.get('markers')) # proper file name to be injected into provenance by the calling code req.provenance = ('Pipfile', pos_in_toml[0], pos_in_toml[0]) - return req +''' +The toml parser returns each requirement as a tuple +of the value and ending position, for multiple requirements +e.g. +{ + 'version': ('*', (9, 23)), + 'markers': ("sys_platform == 'linux' ; python_version != '3.4'", (8, 36)) +} for entry +waitress = {version = "*", markers="sys_platform == 'linux' ; python_version != '3.4'"} +This functions returns the value without the position for one such instance +e.g. parse_req(("sys_platform == 'linux' ; python_version != '3.4'", (8, 36))) returns "sys_platform == 'linux' ; python_version != '3.4'" +''' +def parse_req(pipfile_req): + if type(pipfile_req) is tuple: + return pipfile_req[0] + return pipfile_req + def val_with_pos(kind, text, value, pos): return (value, pos) diff --git a/pysrc/test_pipfile.py b/pysrc/test_pipfile.py new file mode 100644 index 00000000..31d2aaa3 --- /dev/null +++ b/pysrc/test_pipfile.py @@ -0,0 +1,75 @@ +# run with: +# cd pysrc; python3 test_pipfile.py; cd .. + +from pipfile import PipfileRequirement, parse +from collections import namedtuple + +import unittest + +try: + from mock import patch +except: + from unittest.mock import patch + +class TestPipfileRequirement(unittest.TestCase): + def test_init(self): + req = PipfileRequirement("example") + self.assertEqual(req.name, "example") + self.assertFalse(req.editable) + self.assertIsNone(req.vcs) + self.assertIsNone(req.vcs_uri) + self.assertIsNone(req.version) + self.assertIsNone(req.markers) + self.assertIsNone(req.provenance) + + def test_from_dict(self): + requirement_dict = { + 'version': '*', + 'editable': True, + 'git': 'git_uri', + 'markers': 'sys_platform == "linux" ; python_version != "3.4"' + } + pos_in_toml = (1, 2) + req = PipfileRequirement.from_dict("example", requirement_dict, pos_in_toml) + self.assertEqual(req.name, "example") + self.assertTrue(req.editable) + self.assertEqual(req.vcs, "git") + self.assertEqual(req.vcs_uri, "git_uri") + self.assertEqual(req.version, "*") + self.assertEqual(req.markers, 'sys_platform == "linux" ; python_version != "3.4"') + self.assertEqual(req.provenance, ('Pipfile', 1, 1)) + + def test_parse(self): + pipfile_content = """ + [packages] + requests = "*" + flask = { version = "1.0", markers = "python_version < '3.7'" } + + [dev-packages] + pytest = "*" + """ + parsed_data = parse(pipfile_content) + + self.assertIn('packages', parsed_data) + self.assertIn('dev-packages', parsed_data) + + packages = parsed_data['packages'] + self.assertIsInstance(packages, list) + self.assertEqual(len(packages), 2) + + dev_packages = parsed_data['dev-packages'] + self.assertIsInstance(dev_packages, list) + self.assertEqual(len(dev_packages), 1) + + self.assertEqual(packages[0].name, 'flask') + self.assertEqual(packages[0].editable, False) + self.assertEqual(packages[0].vcs, None) + self.assertEqual(packages[0].vcs_uri, None) + self.assertEqual(packages[0].version, '1.0') + self.assertEqual(packages[0].markers, 'python_version < \'3.7\'') + self.assertEqual(packages[0].provenance, ('Pipfile', 4, 4)) + + + +if __name__ == '__main__': + unittest.main()