2019-07-14 12:50:48 +00:00
|
|
|
|
|
|
|
try:
|
|
|
|
from unittest import mock
|
|
|
|
except ImportError:
|
|
|
|
import mock
|
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
import pipdeptree as p
|
|
|
|
|
|
|
|
|
2020-05-10 11:52:33 +00:00
|
|
|
# Tests for DAG classes
|
|
|
|
|
2019-07-14 12:50:48 +00:00
|
|
|
def mock_pkgs(simple_graph):
|
|
|
|
for node, children in simple_graph.items():
|
|
|
|
p = mock.Mock(key=node, project_name=node)
|
|
|
|
as_req = mock.Mock(key=node, project_name=node)
|
|
|
|
p.as_requirement = mock.Mock(return_value=as_req)
|
|
|
|
reqs = []
|
|
|
|
for c in children:
|
|
|
|
r = mock.Mock(key=c, project_name=c)
|
|
|
|
reqs.append(r)
|
|
|
|
p.requires = mock.Mock(return_value=reqs)
|
|
|
|
yield p
|
|
|
|
|
|
|
|
|
2020-04-12 12:10:42 +00:00
|
|
|
def mock_PackageDAG(simple_graph):
|
2019-07-14 12:50:48 +00:00
|
|
|
pkgs = list(mock_pkgs(simple_graph))
|
2020-04-12 12:10:42 +00:00
|
|
|
return p.PackageDAG.from_pkgs(pkgs)
|
2019-07-14 12:50:48 +00:00
|
|
|
|
|
|
|
|
|
|
|
# util for comparing tree contents with a simple graph
|
2020-04-12 12:10:42 +00:00
|
|
|
def dag_to_dict(g):
|
|
|
|
return {k.key: [v.key for v in vs] for k, vs in g._obj.items()}
|
2019-07-14 12:50:48 +00:00
|
|
|
|
|
|
|
|
2020-04-12 12:10:42 +00:00
|
|
|
def sort_map_values(m):
|
|
|
|
return {k: sorted(v) for k, v in m.items()}
|
2019-07-14 12:50:48 +00:00
|
|
|
|
|
|
|
|
2020-04-12 12:10:42 +00:00
|
|
|
t = mock_PackageDAG({'a': ['b', 'c'],
|
|
|
|
'b': ['d'],
|
|
|
|
'c': ['d', 'e'],
|
|
|
|
'd': ['e'],
|
|
|
|
'e': [],
|
|
|
|
'f': ['b'],
|
|
|
|
'g': ['e', 'f']})
|
2019-07-14 12:50:48 +00:00
|
|
|
|
|
|
|
|
2020-04-12 12:10:42 +00:00
|
|
|
def test_PackageDAG__get_node_as_parent():
|
|
|
|
assert 'b' == t.get_node_as_parent('b').key
|
|
|
|
assert 'c' == t.get_node_as_parent('c').key
|
2019-07-14 12:50:48 +00:00
|
|
|
|
|
|
|
|
2020-04-12 12:10:42 +00:00
|
|
|
def test_PackageDAG_filter():
|
2019-07-14 12:50:48 +00:00
|
|
|
# When both show_only and exclude are not specified, same tree
|
|
|
|
# object is returned
|
|
|
|
assert t.filter(None, None) is t
|
|
|
|
|
|
|
|
# when show_only is specified
|
2020-04-12 12:10:42 +00:00
|
|
|
g1 = dag_to_dict(t.filter(set(['a', 'd']), None))
|
2019-07-14 12:50:48 +00:00
|
|
|
expected = {'a': ['b', 'c'],
|
|
|
|
'b': ['d'],
|
|
|
|
'c': ['d', 'e'],
|
|
|
|
'd': ['e'],
|
|
|
|
'e': []}
|
|
|
|
assert expected == g1
|
|
|
|
|
|
|
|
# when exclude is specified
|
2020-04-12 12:10:42 +00:00
|
|
|
g2 = dag_to_dict(t.filter(None, ['d']))
|
2019-07-14 12:50:48 +00:00
|
|
|
expected = {'a': ['b', 'c'],
|
|
|
|
'b': [],
|
|
|
|
'c': ['e'],
|
|
|
|
'e': [],
|
|
|
|
'f': ['b'],
|
|
|
|
'g': ['e', 'f']}
|
|
|
|
assert expected == g2
|
|
|
|
|
|
|
|
# when both show_only and exclude are specified
|
2020-04-12 12:10:42 +00:00
|
|
|
g3 = dag_to_dict(t.filter(set(['a', 'g']), set(['d', 'e'])))
|
2019-07-14 12:50:48 +00:00
|
|
|
expected = {'a': ['b', 'c'],
|
|
|
|
'b': [],
|
|
|
|
'c': [],
|
|
|
|
'f': ['b'],
|
|
|
|
'g': ['f']}
|
|
|
|
assert expected == g3
|
|
|
|
|
|
|
|
# when conflicting values in show_only and exclude, AssertionError
|
|
|
|
# is raised
|
|
|
|
with pytest.raises(AssertionError):
|
2020-04-12 12:10:42 +00:00
|
|
|
dag_to_dict(t.filter(set(['d']), set(['D', 'e'])))
|
2019-07-14 12:50:48 +00:00
|
|
|
|
|
|
|
|
2020-04-12 12:10:42 +00:00
|
|
|
def test_PackageDAG_reverse():
|
2019-07-14 12:50:48 +00:00
|
|
|
t1 = t.reverse()
|
|
|
|
expected = {'a': [],
|
|
|
|
'b': ['a', 'f'],
|
|
|
|
'c': ['a'],
|
|
|
|
'd': ['b', 'c'],
|
|
|
|
'e': ['c', 'd', 'g'],
|
|
|
|
'f': ['g'],
|
|
|
|
'g': []}
|
2020-04-12 12:10:42 +00:00
|
|
|
assert isinstance(t1, p.ReversedPackageDAG)
|
|
|
|
assert sort_map_values(expected) == sort_map_values(dag_to_dict(t1))
|
2020-04-12 18:51:21 +00:00
|
|
|
assert all([isinstance(k, p.ReqPackage) for k in t1.keys()])
|
|
|
|
assert all([isinstance(v, p.DistPackage) for v in p.flatten(t1.values())])
|
|
|
|
|
|
|
|
# testing reversal of ReversedPackageDAG instance
|
|
|
|
expected = {'a': ['b', 'c'],
|
|
|
|
'b': ['d'],
|
|
|
|
'c': ['d', 'e'],
|
|
|
|
'd': ['e'],
|
|
|
|
'e': [],
|
|
|
|
'f': ['b'],
|
|
|
|
'g': ['e', 'f']}
|
|
|
|
t2 = t1.reverse()
|
|
|
|
assert isinstance(t2, p.PackageDAG)
|
|
|
|
assert sort_map_values(expected) == sort_map_values(dag_to_dict(t2))
|
|
|
|
assert all([isinstance(k, p.DistPackage) for k in t2.keys()])
|
|
|
|
assert all([isinstance(v, p.ReqPackage) for v in p.flatten(t2.values())])
|
2020-05-10 11:52:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
# Tests for Package classes
|
|
|
|
#
|
|
|
|
# Note: For all render methods, we are only testing for frozen=False
|
|
|
|
# as mocks with frozen=True are a lot more complicated
|
|
|
|
|
|
|
|
def test_DistPackage__render_as_root():
|
|
|
|
foo = mock.Mock(key='foo', project_name='foo', version='20.4.1')
|
|
|
|
dp = p.DistPackage(foo)
|
|
|
|
is_frozen = False
|
|
|
|
assert 'foo==20.4.1' == dp.render_as_root(is_frozen)
|
|
|
|
|
|
|
|
|
|
|
|
def test_DistPackage__render_as_branch():
|
|
|
|
foo = mock.Mock(key='foo', project_name='foo', version='20.4.1')
|
|
|
|
bar = mock.Mock(key='bar', project_name='bar', version='4.1.0')
|
|
|
|
bar_req = mock.Mock(key='bar',
|
|
|
|
project_name='bar',
|
|
|
|
version='4.1.0',
|
|
|
|
specs=[('>=', '4.0')])
|
|
|
|
rp = p.ReqPackage(bar_req, dist=bar)
|
|
|
|
dp = p.DistPackage(foo).as_parent_of(rp)
|
|
|
|
is_frozen = False
|
|
|
|
assert 'foo==20.4.1 [requires: bar>=4.0]' == dp.render_as_branch(is_frozen)
|
|
|
|
|
|
|
|
|
|
|
|
def test_DistPackage__as_parent_of():
|
|
|
|
foo = mock.Mock(key='foo', project_name='foo', version='20.4.1')
|
|
|
|
dp = p.DistPackage(foo)
|
|
|
|
assert dp.req is None
|
|
|
|
|
|
|
|
bar = mock.Mock(key='bar', project_name='bar', version='4.1.0')
|
|
|
|
bar_req = mock.Mock(key='bar',
|
|
|
|
project_name='bar',
|
|
|
|
version='4.1.0',
|
|
|
|
specs=[('>=', '4.0')])
|
|
|
|
rp = p.ReqPackage(bar_req, dist=bar)
|
|
|
|
dp1 = dp.as_parent_of(rp)
|
|
|
|
assert dp1._obj == dp._obj
|
|
|
|
assert dp1.req is rp
|
|
|
|
|
|
|
|
dp2 = dp.as_parent_of(None)
|
|
|
|
assert dp2 is dp
|
|
|
|
|
|
|
|
|
|
|
|
def test_DistPackage__as_dict():
|
|
|
|
foo = mock.Mock(key='foo', project_name='foo', version='1.3.2b1')
|
|
|
|
dp = p.DistPackage(foo)
|
|
|
|
result = dp.as_dict()
|
|
|
|
expected = {'key': 'foo',
|
|
|
|
'package_name': 'foo',
|
|
|
|
'installed_version': '1.3.2b1'}
|
|
|
|
assert expected == result
|
|
|
|
|
|
|
|
|
|
|
|
def test_ReqPackage__render_as_root():
|
|
|
|
bar = mock.Mock(key='bar', project_name='bar', version='4.1.0')
|
|
|
|
bar_req = mock.Mock(key='bar',
|
|
|
|
project_name='bar',
|
|
|
|
version='4.1.0',
|
|
|
|
specs=[('>=', '4.0')])
|
|
|
|
rp = p.ReqPackage(bar_req, dist=bar)
|
|
|
|
is_frozen = False
|
|
|
|
assert 'bar==4.1.0' == rp.render_as_root(is_frozen)
|
|
|
|
|
|
|
|
|
|
|
|
def test_ReqPackage__render_as_branch():
|
|
|
|
bar = mock.Mock(key='bar', project_name='bar', version='4.1.0')
|
|
|
|
bar_req = mock.Mock(key='bar',
|
|
|
|
project_name='bar',
|
|
|
|
version='4.1.0',
|
|
|
|
specs=[('>=', '4.0')])
|
|
|
|
rp = p.ReqPackage(bar_req, dist=bar)
|
|
|
|
is_frozen = False
|
|
|
|
assert 'bar [required: >=4.0, installed: 4.1.0]' == rp.render_as_branch(is_frozen)
|
|
|
|
|
|
|
|
|
|
|
|
def test_ReqPackage__as_dict():
|
|
|
|
bar = mock.Mock(key='bar', project_name='bar', version='4.1.0')
|
|
|
|
bar_req = mock.Mock(key='bar',
|
|
|
|
project_name='bar',
|
|
|
|
version='4.1.0',
|
|
|
|
specs=[('>=', '4.0')])
|
|
|
|
rp = p.ReqPackage(bar_req, dist=bar)
|
|
|
|
result = rp.as_dict()
|
|
|
|
expected = {'key': 'bar',
|
|
|
|
'package_name': 'bar',
|
|
|
|
'installed_version': '4.1.0',
|
|
|
|
'required_version': '>=4.0'}
|
|
|
|
assert expected == result
|