test_gather_sources_and_dependencies()   D
last analyzed

Complexity

Conditions 12

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
c 0
b 0
f 0
dl 0
loc 24
rs 4.8

How to fix   Complexity   

Complexity

Complex classes like test_gather_sources_and_dependencies() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
#!/usr/bin/env python
2
# coding=utf-8
3
from __future__ import division, print_function, unicode_literals
4
5
import os.path
6
7
import mock
8
import pytest
9
from sacred.dependencies import (PEP440_VERSION_PATTERN, PackageDependency,
10
                                 Source, gather_sources_and_dependencies,
11
                                 get_digest, get_py_file_if_possible,
12
                                 is_local_source)
13
import sacred.optional as opt
14
15
EXAMPLE_SOURCE = 'tests/__init__.py'
16
EXAMPLE_DIGEST = 'e3e5102d21897ad2bfa1140e359075e1'
17
18
19
@pytest.mark.parametrize('version', [
20
    '0.9.11', '2012.04', '1!1.1', '17.10a104', '43.0rc1', '0.9.post3',
21
    '12.4a22.post8', '13.3rc2.dev1515', '1.0.dev456', '1.0a1', '1.0a2.dev456',
22
    '1.0a12.dev456', '1.0a12', '1.0b1.dev456', '1.0b2', '1.0b2.post345.dev456',
23
    '1.0b2.post345', '1.0rc1.dev456', '1.0rc1', '1.0', '1.0.post456.dev34',
24
    '1.0.post456', '1.1.dev1'
25
])
26
def test_pep440_version_pattern(version):
27
    assert PEP440_VERSION_PATTERN.match(version)
28
29
30
def test_pep440_version_pattern_invalid():
31
    assert PEP440_VERSION_PATTERN.match('foo') is None
32
    assert PEP440_VERSION_PATTERN.match('_12_') is None
33
    assert PEP440_VERSION_PATTERN.match('version 4') is None
34
35
36
def test_source_get_digest():
37
    assert get_digest(EXAMPLE_SOURCE) == EXAMPLE_DIGEST
38
39
40
def test_source_create_empty():
41
    with pytest.raises(ValueError):
42
        Source.create('')
43
44
45
def test_source_create_non_existing():
46
    with pytest.raises(ValueError):
47
        Source.create('doesnotexist.py')
48
49
50
def test_source_create_py():
51
    s = Source.create(EXAMPLE_SOURCE)
52
    assert s.filename == os.path.abspath(EXAMPLE_SOURCE)
53
    assert s.digest == EXAMPLE_DIGEST
54
55
56
def test_source_to_json():
57
    s = Source.create(EXAMPLE_SOURCE)
58
    assert s.to_json() == (os.path.abspath(EXAMPLE_SOURCE), EXAMPLE_DIGEST)
59
60
61
def test_get_py_file_if_possible_with_py_file():
62
    assert get_py_file_if_possible(EXAMPLE_SOURCE) == EXAMPLE_SOURCE
63
64
65
def test_get_py_file_if_possible_with_pyc_file():
66
    assert get_py_file_if_possible(EXAMPLE_SOURCE + 'c') == EXAMPLE_SOURCE
67
68
69
def test_source_repr():
70
    s = Source.create(EXAMPLE_SOURCE)
71
    assert repr(s) == "<Source: {}>".format(os.path.abspath(EXAMPLE_SOURCE))
72
73
74
def test_get_py_file_if_possible_with_pyc_but_nonexistent_py_file():
75
    assert get_py_file_if_possible('doesnotexist.pyc') == 'doesnotexist.pyc'
76
77
78
versions = [
79
    ('0.7.2', '0.7.2'),
80
    ('1.0', '1.0'),
81
    ('foobar', None),
82
    (10, None),
83
    ((2, 6), '2.6'),
84
    ((1, 4, 8), '1.4.8')
85
]
86
87
88
@pytest.mark.parametrize('version,expected', versions)
89
def test_package_dependency_get_version_heuristic_version__(version, expected):
90
    mod = mock.Mock(spec=[], __version__=version)
91
    assert PackageDependency.get_version_heuristic(mod) == expected
92
93
94
@pytest.mark.parametrize('version,expected', versions)
95
def test_package_dependency_get_version_heuristic_version(version, expected):
96
    mod = mock.Mock(spec=[], version=version)
97
    assert PackageDependency.get_version_heuristic(mod) == expected
98
99
100
@pytest.mark.parametrize('version,expected', versions)
101
def test_package_dependency_get_version_heuristic_VERSION(version, expected):
102
    mod = mock.Mock(spec=[], VERSION=version)
103
    assert PackageDependency.get_version_heuristic(mod) == expected
104
105
106
def test_package_dependency_create_no_version():
107
    mod = mock.Mock(spec=[], __name__='testmod')
108
    pd = PackageDependency.create(mod)
109
    assert pd.name == 'testmod'
110
    assert pd.version is None
111
112
113
def test_package_dependency_fill_non_missing_version():
114
    pd = PackageDependency('mymod', '1.2.3rc4')
115
    pd.fill_missing_version()
116
    assert pd.version == '1.2.3rc4'
117
118
119
def test_package_dependency_fill_missing_version_unknown():
120
    pd = PackageDependency('mymod', None)
121
    pd.fill_missing_version()
122
    assert pd.version == None
123
124
125
def test_package_dependency_fill_missing_version():
126
    pd = PackageDependency('pytest', None)
127
    pd.fill_missing_version()
128
    assert pd.version == pytest.__version__
129
130
131
def test_package_dependency_repr():
132
    pd = PackageDependency('pytest', '12.4')
133
    assert repr(pd) == '<PackageDependency: pytest=12.4>'
134
135
136
def test_gather_sources_and_dependencies():
137
    from tests.dependency_example import some_func
138
    main, sources, deps = gather_sources_and_dependencies(some_func.__globals__)
139
    assert isinstance(main, Source)
140
    assert isinstance(sources, set)
141
    assert isinstance(deps, set)
142
    assert main == Source.create('tests/dependency_example.py')
143
    expected_sources = {
144
        Source.create('tests/__init__.py'),
145
        Source.create('tests/dependency_example.py'),
146
        Source.create('tests/foo/__init__.py'),
147
        Source.create('tests/foo/bar.py')
148
    }
149
    assert sources == expected_sources
150
151
    assert PackageDependency.create(pytest) in deps
152
    assert PackageDependency.create(mock) in deps
153
    # If numpy is installed on the test system it will automatically be added
154
    # as an additional dependency, so test for that:
155
    if opt.has_numpy:
156
        assert PackageDependency.create(opt.np) in deps
157
        assert len(deps) == 3
158
    else:
159
        assert len(deps) == 2
160
161
162
def test_custom_base_dir():
163
    from tests.basedir.my_experiment import some_func
164
    base_dir = os.path.abspath('tests')
165
    main, sources, deps = gather_sources_and_dependencies(some_func.__globals__, base_dir)
166
    assert isinstance(main, Source)
167
    assert isinstance(sources, set)
168
    assert isinstance(deps, set)
169
    assert main == Source.create('tests/basedir/my_experiment.py')
170
    expected_sources = {
171
        Source.create('tests/__init__.py'),
172
        Source.create('tests/basedir/__init__.py'),
173
        Source.create('tests/basedir/my_experiment.py'),
174
        Source.create('tests/foo/__init__.py'),
175
        Source.create('tests/foo/bar.py')
176
    }
177
    assert sources == expected_sources
178
179
180
@pytest.mark.parametrize('f_name, mod_name, ex_path, is_local', [
181
    ('./foo.py', 'bar', '.', False),
182
    ('./foo.pyc', 'bar', '.', False),
183
    ('./bar.py', 'bar', '.', True),
184
    ('./bar.pyc', 'bar', '.', True),
185
    ('./venv/py/bar.py', 'bar', '.', False),
186
    ('./venv/py/bar.py', 'venv.py.bar', '.', True),
187
    ('./venv/py/bar.pyc', 'venv.py.bar', '.', True),
188
    ('foo.py', 'bar', '.', False),
189
    ('bar.py', 'bar', '.', True),
190
    ('bar.pyc', 'bar', '.', True),
191
    ('bar.pyc', 'some.bar', '.', False),
192
    ('/home/user/bar.py', 'user.bar', '/home/user/', True),
193
    ('bar/__init__.py', 'bar', '.', True),
194
    ('bar/__init__.py', 'foo', '.', False),
195
    ('/home/user/bar/__init__.py', 'home.user.bar', '/home/user/', True),
196
    ('/home/user/bar/__init__.py', 'home.user.foo', '/home/user/', False),
197
])
198
def test_is_local_source(f_name, mod_name, ex_path, is_local):
199
    assert is_local_source(f_name, mod_name, ex_path) == is_local
200