Skip to content

Commit 191fe7d

Browse files
authored
Merge pull request #116 from sbillinge/pkg_resources
pkg resources
2 parents bb4f92d + cb65f54 commit 191fe7d

19 files changed

+1860
-1852
lines changed

requirements/test.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ codecov
44
coverage
55
pytest-cov
66
pytest-env
7+
sympy

tests/__init__.py

Lines changed: 0 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +0,0 @@
1-
#!/usr/bin/env python
2-
##############################################################################
3-
#
4-
# diffpy.srfit by DANSE Diffraction group
5-
# Simon J. L. Billinge
6-
# (c) 2010 The Trustees of Columbia University
7-
# in the City of New York. All rights reserved.
8-
#
9-
# File coded by: Pavol Juhas
10-
#
11-
# See AUTHORS.txt for a list of people who contributed.
12-
# See LICENSE_DANSE.txt for license information.
13-
#
14-
##############################################################################
15-
"""Unit tests for diffpy.srfit."""
16-
17-
import logging
18-
import unittest
19-
20-
# create logger instance for the tests subpackage
21-
logging.basicConfig()
22-
logger = logging.getLogger(__name__)
23-
del logging
24-
25-
26-
def testsuite(pattern=""):
27-
"""Create a unit tests suite for diffpy.srfit package.
28-
29-
Parameters
30-
----------
31-
pattern : str, optional
32-
Regular expression pattern for selecting test cases.
33-
Select all tests when empty. Ignore the pattern when
34-
any of unit test modules fails to import.
35-
36-
Returns
37-
-------
38-
suite : `unittest.TestSuite`
39-
The TestSuite object containing the matching tests.
40-
"""
41-
import re
42-
from itertools import chain
43-
from os.path import dirname
44-
45-
from pkg_resources import resource_filename
46-
47-
loader = unittest.defaultTestLoader
48-
thisdir = resource_filename(__name__, "")
49-
depth = __name__.count(".") + 1
50-
topdir = thisdir
51-
for i in range(depth):
52-
topdir = dirname(topdir)
53-
suite_all = loader.discover(thisdir, top_level_dir=topdir)
54-
# always filter the suite by pattern to test-cover the selection code.
55-
suite = unittest.TestSuite()
56-
rx = re.compile(pattern)
57-
tsuites = list(chain.from_iterable(suite_all))
58-
tsok = all(isinstance(ts, unittest.TestSuite) for ts in tsuites)
59-
if not tsok: # pragma: no cover
60-
return suite_all
61-
tcases = chain.from_iterable(tsuites)
62-
for tc in tcases:
63-
tcwords = tc.id().split(".")
64-
shortname = ".".join(tcwords[-3:])
65-
if rx.search(shortname):
66-
suite.addTest(tc)
67-
# verify all tests are found for an empty pattern.
68-
assert pattern or suite_all.countTestCases() == suite.countTestCases()
69-
return suite
70-
71-
72-
def test():
73-
"""Execute all unit tests for the diffpy.srfit package.
74-
75-
Returns
76-
-------
77-
result : `unittest.TestResult`
78-
"""
79-
suite = testsuite()
80-
runner = unittest.TextTestRunner()
81-
result = runner.run(suite)
82-
return result
83-
84-
85-
# End of file

tests/conftest.py

Lines changed: 141 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,92 @@
1+
import importlib.resources
12
import json
3+
import logging
4+
import sys
5+
from functools import lru_cache
26
from pathlib import Path
37

48
import pytest
9+
import six
510

11+
import diffpy.srfit.equation.literals as literals
12+
from diffpy.srfit.sas.sasimport import sasimport
613

7-
@pytest.fixture
14+
logger = logging.getLogger(__name__)
15+
16+
17+
@lru_cache()
18+
def has_sas():
19+
try:
20+
sasimport("sas.pr.invertor")
21+
sasimport("sas.models")
22+
return True
23+
except ImportError:
24+
return False
25+
26+
27+
# diffpy.structure
28+
@lru_cache()
29+
def has_diffpy_structure():
30+
try:
31+
import diffpy.structure as m
32+
33+
del m
34+
return True
35+
except ImportError:
36+
return False
37+
logger.warning(
38+
"Cannot import diffpy.structure, Structure tests skipped."
39+
)
40+
41+
42+
@lru_cache()
43+
def has_pyobjcryst():
44+
try:
45+
import pyobjcryst as m
46+
47+
del m
48+
return True
49+
except ImportError:
50+
return False
51+
logger.warning("Cannot import pyobjcryst, pyobjcryst tests skipped.")
52+
53+
54+
# diffpy.srreal
55+
56+
57+
@lru_cache()
58+
def has_diffpy_srreal():
59+
try:
60+
import diffpy.srreal.pdfcalculator as m
61+
62+
del m
63+
return True
64+
except ImportError:
65+
return False
66+
logger.warning("Cannot import diffpy.srreal, PDF tests skipped.")
67+
68+
69+
@pytest.fixture(scope="session")
70+
def sas_available():
71+
return has_sas()
72+
73+
74+
@pytest.fixture(scope="session")
75+
def diffpy_structure_available():
76+
return has_diffpy_structure()
77+
78+
79+
@pytest.fixture(scope="session")
80+
def diffpy_srreal_available():
81+
return has_diffpy_srreal()
82+
83+
84+
@pytest.fixture(scope="session")
85+
def pyobjcryst_available():
86+
return has_pyobjcryst()
87+
88+
89+
@pytest.fixture(scope="session")
890
def user_filesystem(tmp_path):
991
base_dir = Path(tmp_path)
1092
home_dir = base_dir / "home_dir"
@@ -17,3 +99,61 @@ def user_filesystem(tmp_path):
1799
json.dump(home_config_data, f)
18100

19101
yield tmp_path
102+
103+
104+
@pytest.fixture(scope="session")
105+
def datafile():
106+
"""Fixture to load a test data file from the testdata package directory."""
107+
108+
def _datafile(filename):
109+
return importlib.resources.files("tests.testdata").joinpath(filename)
110+
111+
return _datafile
112+
113+
114+
@pytest.fixture(scope="session")
115+
def make_args():
116+
def _makeArgs(num):
117+
args = []
118+
for i in range(num):
119+
j = i + 1
120+
args.append(literals.Argument(name="v%i" % j, value=j))
121+
return args
122+
123+
return _makeArgs
124+
125+
126+
@pytest.fixture(scope="session")
127+
def noObserversInGlobalBuilders():
128+
def _noObserversInGlobalBuilders():
129+
"""True if no observer function leaks to global builder objects.
130+
131+
Ensure objects are not immortal due to a reference from static
132+
value.
133+
"""
134+
from diffpy.srfit.equation.builder import _builders
135+
136+
rv = True
137+
for n, b in _builders.items():
138+
if b.literal and b.literal._observers:
139+
rv = False
140+
break
141+
return rv
142+
143+
return _noObserversInGlobalBuilders()
144+
145+
146+
@pytest.fixture(scope="session")
147+
def capturestdout():
148+
def _capturestdout(f, *args, **kwargs):
149+
"""Capture the standard output from a call of function f."""
150+
savestdout = sys.stdout
151+
fp = six.StringIO()
152+
try:
153+
sys.stdout = fp
154+
f(*args, **kwargs)
155+
finally:
156+
sys.stdout = savestdout
157+
return fp.getvalue()
158+
159+
return _capturestdout

0 commit comments

Comments
 (0)