diff --git a/polymerist/data/__init__.py b/polymerist/data/__init__.py new file mode 100644 index 0000000..309d669 --- /dev/null +++ b/polymerist/data/__init__.py @@ -0,0 +1 @@ +'''Additional data shipped along with polymerist source code''' \ No newline at end of file diff --git a/polymerist/genutils/pkginspect.py b/polymerist/genutils/pkginspect.py new file mode 100644 index 0000000..a160ff0 --- /dev/null +++ b/polymerist/genutils/pkginspect.py @@ -0,0 +1,57 @@ +'''For checking whether object are valid Python modules and packages, and if so for gathering info from within them''' + +from typing import Union +from pathlib import Path + +from importlib.resources import ( + Package, + files as get_package_path +) +from importlib.resources._common import get_package, from_package, resolve + + +def is_module(module : Package) -> bool: + '''Determine whether a given Package-like (i.e. str or ModuleType) is a valid Python module + This will return True for packages, bottom-level modules (i.e. *.py) and Python scripts''' + try: + resolve(module) + return True + except ModuleNotFoundError: + return False + +def is_package(package : Package) -> bool: + '''Determine whether a given Package-like (i.e. str or ModuleType) is a valid Python package''' + try: + get_package(package) + return True + except (ModuleNotFoundError, TypeError): + return False + + +def get_resource_path_within_package(relative_path : Union[str, Path], package : Package) -> Path: + '''Get the Path to a resource (i.e. either a directory or a file) which lives within a Python package''' + package_path : Path = get_package_path(package) # will also implicitly check that the provided package exists as a module + resource_path = package_path / relative_path # concat to Path here means string inputs for relative_path are valid without explicit conversion + + if not resource_path.exists(): # if this block is reached, it means "package" is a real module and resource path is DEFINED relative to package's path, so the below message is valid + raise ValueError(f'{resolve(package).__name__} contains no resource "{relative_path}"') + + return resource_path + +def get_dir_path_within_package(relative_path : Union[str, Path], package : Package) -> Path: + '''Get the Path to a directory which lives within a Python package''' + dir_path : Path = get_resource_path_within_package(package=package, relative_path=relative_path) # performs all check associated with getting the resource + + if not dir_path.is_dir(): + raise NotADirectoryError(f'{resolve(package).__name__} contains "{dir_path}", but it is not a directory') + + return dir_path + +def get_file_path_within_package(relative_path : Union[str, Path], package : Package) -> Path: + '''Get the Path to a (non-directory) file which lives within a Python package''' + file_path : Path = get_resource_path_within_package(package=package, relative_path=relative_path) # performs all check associated with getting the resource + + if not file_path.is_file(): + raise FileNotFoundError(f'{resolve(package).__name__} contains no file "{file_path}"') + + return file_path \ No newline at end of file diff --git a/polymerist/genutils/sequences/discernment/_tests.py b/polymerist/genutils/sequences/discernment/_tests.py deleted file mode 100644 index ab11d36..0000000 --- a/polymerist/genutils/sequences/discernment/_tests.py +++ /dev/null @@ -1,59 +0,0 @@ -'''Unit tests for DISCERNMENT-related functionality''' - -# TODO: add logging - -import json -from pathlib import Path - -from .inventory import SymbolInventory -from .strategies import DISCERNMENTStrategy - - -class DISCERNMENTIncosistencyError(Exception): - '''Custom Exception for indicating inconsistencies between DISCERNMENT Strategy implementations''' - pass - -def check_discernment_algorithm_consistency(ignore_multiplicities : bool=False, unique_bins : bool=False) -> None: - '''Check to ensure that all implementations of DISCERNMENT solution strageties yield the same outputs and don't modify a provided symbol inventory - Raises failure-specific Exception if inconsistency is detected, terminates silently (no Exception, returns None) otherwise''' - # hard-code inputs and expected solution - WORD = 'accg' - CHOICE_BINS = ('bbc','aced','bad','daea','fccce','g','abcd','fggegc') - - LOCAL_DIR = Path(__file__).parent - SOLUTION_PATH = LOCAL_DIR / 'correct_discernment_solution.json' - - with SOLUTION_PATH.open('r') as file: - CORRECT_SOLUTION = set( - tuple(indices) - for indices in json.load(file) - ) - - sym_inv = SymbolInventory.from_bins(CHOICE_BINS) - orig_sym_inv = sym_inv.deepcopy() - - all_results : dict[str, set[int]] = {} - for DSClass in DISCERNMENTStrategy.__subclasses__(): - method_name = DSClass.__name__ - ds_strat = DSClass() - - solution = set( - idxs - for idxs in ds_strat.enumerate_choice_labels( - WORD, - sym_inv, - ignore_multiplicities=ignore_multiplicities, - unique_bins=unique_bins - ) - ) - if solution != CORRECT_SOLUTION: # check that answer produces is accurate - raise DISCERNMENTIncosistencyError(f'Algorithm {method_name} does not produce to correct enumeration of bin labels') - if sym_inv != orig_sym_inv: # check that the symbol inventory is unmodified - raise DISCERNMENTIncosistencyError(f'Algorithm {method_name} does not return symbol inventory to original state after completion') - for other_method_name, other_solution in all_results.items(): # check against all other methods PRIOR TO INSERTION (minimal number of checks guaranteed to verify all pairwise checks) - # print(method_name, other_method_name) - if (solution - other_solution != set()) or (other_solution - solution != set()): # check both symmetric differences to make sure none are - raise DISCERNMENTIncosistencyError(f'Algorithms {method_name} and {other_method_name} produce inconsistent solutions') - - # implicit else - all_results[method_name] = solution \ No newline at end of file diff --git a/polymerist/tests/analysis/__init__.py b/polymerist/tests/analysis/__init__.py new file mode 100644 index 0000000..ba40be5 --- /dev/null +++ b/polymerist/tests/analysis/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `analysis` package''' \ No newline at end of file diff --git a/polymerist/tests/data/__init__.py b/polymerist/tests/data/__init__.py new file mode 100644 index 0000000..b591267 --- /dev/null +++ b/polymerist/tests/data/__init__.py @@ -0,0 +1 @@ +'''Reference data used to load or verify unit tests''' \ No newline at end of file diff --git a/polymerist/genutils/sequences/discernment/correct_discernment_solution.json b/polymerist/tests/data/correct_discernment_solution.json similarity index 100% rename from polymerist/genutils/sequences/discernment/correct_discernment_solution.json rename to polymerist/tests/data/correct_discernment_solution.json diff --git a/polymerist/tests/data/sample.dat b/polymerist/tests/data/sample.dat new file mode 100644 index 0000000..3ed2e08 --- /dev/null +++ b/polymerist/tests/data/sample.dat @@ -0,0 +1 @@ +I contain pointless sample text for debugging purposes! \ No newline at end of file diff --git a/polymerist/tests/genutils/__init__.py b/polymerist/tests/genutils/__init__.py new file mode 100644 index 0000000..954d19f --- /dev/null +++ b/polymerist/tests/genutils/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `genutils` package''' \ No newline at end of file diff --git a/polymerist/tests/genutils/decorators/__init__.py b/polymerist/tests/genutils/decorators/__init__.py new file mode 100644 index 0000000..1573261 --- /dev/null +++ b/polymerist/tests/genutils/decorators/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `decorators` package''' \ No newline at end of file diff --git a/polymerist/tests/genutils/fileutils/__init__.py b/polymerist/tests/genutils/fileutils/__init__.py new file mode 100644 index 0000000..7f49e8c --- /dev/null +++ b/polymerist/tests/genutils/fileutils/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `fileutils` package''' \ No newline at end of file diff --git a/polymerist/tests/genutils/fileutils/jsonio/__init__.py b/polymerist/tests/genutils/fileutils/jsonio/__init__.py new file mode 100644 index 0000000..6bf0714 --- /dev/null +++ b/polymerist/tests/genutils/fileutils/jsonio/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `jsonio` package''' \ No newline at end of file diff --git a/polymerist/tests/genutils/logutils/__init__.py b/polymerist/tests/genutils/logutils/__init__.py new file mode 100644 index 0000000..88e053e --- /dev/null +++ b/polymerist/tests/genutils/logutils/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `logutils` package''' \ No newline at end of file diff --git a/polymerist/tests/genutils/sequences/__init__.py b/polymerist/tests/genutils/sequences/__init__.py new file mode 100644 index 0000000..c754f33 --- /dev/null +++ b/polymerist/tests/genutils/sequences/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `sequences` package''' \ No newline at end of file diff --git a/polymerist/tests/genutils/sequences/discernment/__init__.py b/polymerist/tests/genutils/sequences/discernment/__init__.py new file mode 100644 index 0000000..6cee0a6 --- /dev/null +++ b/polymerist/tests/genutils/sequences/discernment/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `discernment` package''' \ No newline at end of file diff --git a/polymerist/tests/genutils/sequences/discernment/test_discernment.py b/polymerist/tests/genutils/sequences/discernment/test_discernment.py new file mode 100644 index 0000000..3e9d347 --- /dev/null +++ b/polymerist/tests/genutils/sequences/discernment/test_discernment.py @@ -0,0 +1,97 @@ +'''Unit tests for DISCERNMENT-related functionality''' + +import pytest +from polymerist.genutils.pkginspect import get_file_path_within_package +from polymerist.tests import data as testdata + +import json +from pathlib import Path + +from polymerist.genutils.sequences.discernment.inventory import SymbolInventory +from polymerist.genutils.sequences.discernment.strategies import DISCERNMENTStrategy + + +# DEFINE/LOAD HARD-CODED INPUTS AND EXPECTED OUTPUTS TO A PARTICULAR DISCERNMENT PROBLEM +@pytest.fixture(scope='module') +def word() -> str: + return 'accg' + +@pytest.fixture(scope='module') +def choice_bins() -> str: + return ('bbc','aced','bad','daea','fccce','g','abcd','fggegc') + +@pytest.fixture(scope='module') +def symbol_inventory(choice_bins) -> SymbolInventory: + return SymbolInventory.from_bins(choice_bins) + +@pytest.fixture(scope='module') +def solution_path() -> Path: + return get_file_path_within_package('correct_discernment_solution.json', testdata) + +@pytest.fixture(scope='module') +def correct_solution(solution_path) -> set[tuple[int, ...]]: + with solution_path.open('r') as file: + solution = set( + tuple(indices) + for indices in json.load(file) + ) + return solution + + +@pytest.mark.parametrize("ignore_multiplicities,unique_bins,DSClass", [(False, False, DSClass) for DSClass in DISCERNMENTStrategy.__subclasses__()]) # TODO: produce solutions with unique bins AND ignored multiplicities to fully test +class TestDISCERNMENTStrategies: + all_results : dict[str, set[int]] = {} # cache solutions to avoid tedoius recalculations + def test_preserves_symbol_inventory( + self, + word : str, + symbol_inventory : SymbolInventory, + correct_solution : set[tuple[int, ...]], + ignore_multiplicities : bool, + unique_bins : bool, + DSClass : type[DISCERNMENTStrategy], + ) -> None: + '''Check to ensure that all implementations of DISCERNMENT solution strageties yield the same outputs and don't modify a provided symbol inventory + Raises failure-specific Exception if inconsistency is detected, terminates silently (no Exception, returns None) otherwise''' + mod_sym_inv = symbol_inventory.deepcopy() # create a copy of the symbol inventory to ensure any errant modifications do not affect other tests + + method_name = DSClass.__name__ + ds_strat = DSClass() + proposed_solution = set( + idxs + for idxs in ds_strat.enumerate_choice_labels( + word, + mod_sym_inv, + ignore_multiplicities=ignore_multiplicities, + unique_bins=unique_bins + ) + ) + self.all_results[method_name] = proposed_solution # cache for comparison in later tests + assert (mod_sym_inv == symbol_inventory), f'Algorithm {method_name} does not produce to correct enumeration of bin labels' + + def test_solution_is_correct( + self, + word : str, + symbol_inventory : SymbolInventory, + correct_solution : set[tuple[int, ...]], + ignore_multiplicities : bool, + unique_bins : bool, + DSClass : type[DISCERNMENTStrategy], + ) -> None: + method_name = DSClass.__name__ + assert (self.all_results[method_name] == correct_solution), f'Algorithm {method_name} does not return symbol inventory to original state after completion' + + def test_solution_strategies_are_consistent( + self, + word : str, + symbol_inventory : SymbolInventory, + correct_solution : set[tuple[int, ...]], + ignore_multiplicities : bool, + unique_bins : bool, + DSClass : type[DISCERNMENTStrategy], + ) -> None: + method_name = DSClass.__name__ + proposed_solution = self.all_results[method_name] + + for other_method_name, other_solution in self.all_results.items(): # check against all other methods PRIOR TO INSERTION (minimal number of checks guaranteed to verify all pairwise checks) + # check both symmetric differences to make sure no solution sequences are unique to either method + assert (proposed_solution - other_solution == set()) and (other_solution - proposed_solution == set()), f'Algorithms {method_name} and {other_method_name} produce inconsistent solutions' diff --git a/polymerist/tests/genutils/sequences/similarity/__init__.py b/polymerist/tests/genutils/sequences/similarity/__init__.py new file mode 100644 index 0000000..dea3ddf --- /dev/null +++ b/polymerist/tests/genutils/sequences/similarity/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `similarity` package''' \ No newline at end of file diff --git a/polymerist/tests/genutils/test_pkginspect.py b/polymerist/tests/genutils/test_pkginspect.py new file mode 100644 index 0000000..a8edbd9 --- /dev/null +++ b/polymerist/tests/genutils/test_pkginspect.py @@ -0,0 +1,119 @@ +'''Unit tests for package inspection utilities''' + +from types import ModuleType + +import pytest +from pathlib import Path +import math, json # use these as test cases, since they are pretty stable in stdlib + +from polymerist import polymerist # this is a dummy toplevel module, and NOt the entire polymerist package +from polymerist import genutils +from polymerist.genutils import pkginspect +from polymerist import tests + + + +# TABULATED EXPECTED TESTS OUTPUTS +non_module_types = [ # types that are obviously not modules OR packages, and which should fail + bool, int, float, complex, tuple, list, dict, set, # str, Path # str and Path need to be tested separately +] + +are_modules = [ + ('--not_a_module--', False), # deliberately weird to ensure this never accidentally clashes with a legit module name + (math, True), + ('math', True), # test that the string -> module resolver also works as intended + (json, True), + ('json', True), + (json.decoder, True), + ('json.decoder', True), + (polymerist, True), + ('polymerist.polymerist', True), + (genutils, True), + ('polymerist.genutils', True), +] + +are_packages = [ + ('--not_a_package--', False), # deliberately weird to ensure this never accidentally clashes with a legit module name + (math, False), + ('math', False), # test that the string -> module resolver also works as intended + (json, True), + ('json', True), + (json.decoder, False), + ('json.decoder', False), + (polymerist, False), + ('polymerist.polymerist', False), + (genutils, True), + ('polymerist.genutils', True), +] + + +# MODULE AND PACKAGE PERCEPTION +@pytest.mark.parametrize('module, expected_output', are_modules) +def test_is_module(module : ModuleType, expected_output : bool) -> None: + '''See if Python module perception behaves as expected''' + assert pkginspect.is_module(module) == expected_output + +@pytest.mark.parametrize('non_module_type', non_module_types) +def test_is_module_fail_on_invalid_types(non_module_type : type) -> None: + '''check that module perception fails on invalid inputs''' + with pytest.raises(AttributeError) as err_info: + instance = non_module_type() # create a default instance + _ = pkginspect.is_module(instance) + +@pytest.mark.parametrize('module, expected_output', are_packages) +def test_is_package(module : ModuleType, expected_output : bool) -> None: + '''See if Python package perception behaves as expected''' + assert pkginspect.is_package(module) == expected_output + +@pytest.mark.parametrize('non_module_type', non_module_types) # NOTE: these args are in fact deliberately NOT renamed to ".*package" from ".*module" +def test_is_module_fail_on_invalid_types(non_module_type : type) -> None: + '''check that package perception fails on invalid inputs''' + with pytest.raises(AttributeError) as err_info: + instance = non_module_type() # create a default instance + _ = pkginspect.is_package(instance) + +# FETCHING DATA FROM PACKAGES +@pytest.mark.parametrize( + 'rel_path, module', + [ + ('data', tests), + ('data/sample.dat', tests), + pytest.param('daata/simple.dat', tests, marks=pytest.mark.xfail(raises=ValueError, reason="This isn't a real file", strict=True)), + ('pkginspect.py', genutils), + pytest.param('fake/whatever.txt', pkginspect, marks=pytest.mark.xfail(raises=TypeError, reason="Module is not a package and therefore cannot contain resources", strict=True)), + ] +) +def test_get_resource_path(rel_path : str, module : ModuleType) -> None: + '''Test fetching a resource (i.e. file OR dir) from a package''' + resource_path = pkginspect.get_resource_path_within_package(rel_path, module) + assert isinstance(resource_path, Path) + +@pytest.mark.parametrize( + 'rel_path, module', + [ + pytest.param('data', tests, marks=pytest.mark.xfail(raises=FileNotFoundError, reason="This is a directory, NOT a file", strict=True)), + ('data/sample.dat', tests), + pytest.param('daata/simple.dat', tests, marks=pytest.mark.xfail(raises=ValueError, reason="This isn't a real file", strict=True)), + ('pkginspect.py', genutils), + pytest.param('fake/whatever.txt', pkginspect, marks=pytest.mark.xfail(raises=TypeError, reason="Module is not a package and therefore cannot contain resources", strict=True)), + ] +) +def test_get_file_path(rel_path : str, module : ModuleType) -> None: + '''Test fetching a file (i.e. NOT a dir) from a package''' + resource_path = pkginspect.get_file_path_within_package(rel_path, module) + assert isinstance(resource_path, Path) + +@pytest.mark.parametrize( + 'rel_path, module', + [ + ('data', tests), + pytest.param('data/sample.dat', tests, marks=pytest.mark.xfail(raises=NotADirectoryError, reason='This IS a real file, but not a directory', strict=True)), + pytest.param('daata/simple.dat', tests, marks=pytest.mark.xfail(raises=ValueError, reason="This isn't a real file", strict=True)), + pytest.param('pkginspect.py', genutils, marks=pytest.mark.xfail(raises=NotADirectoryError, reason='This IS a real file, but not a directory', strict=True)), + pytest.param('fake/whatever.txt', pkginspect, marks=pytest.mark.xfail(raises=TypeError, reason="Module is not a package and therefore cannot contain resources", strict=True)), + ] +) +def test_get_dir_path(rel_path : str, module : ModuleType) -> None: + '''Test fetching a dir (i.e. NOT a file) from a package''' + resource_path = pkginspect.get_dir_path_within_package(rel_path, module) + assert isinstance(resource_path, Path) \ No newline at end of file diff --git a/polymerist/tests/genutils/textual/__init__.py b/polymerist/tests/genutils/textual/__init__.py new file mode 100644 index 0000000..08f7241 --- /dev/null +++ b/polymerist/tests/genutils/textual/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `textual` package''' \ No newline at end of file diff --git a/polymerist/tests/genutils/treetools/__init__.py b/polymerist/tests/genutils/treetools/__init__.py new file mode 100644 index 0000000..55230fd --- /dev/null +++ b/polymerist/tests/genutils/treetools/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `treetools` package''' \ No newline at end of file diff --git a/polymerist/tests/genutils/typetools/__init__.py b/polymerist/tests/genutils/typetools/__init__.py new file mode 100644 index 0000000..30fee19 --- /dev/null +++ b/polymerist/tests/genutils/typetools/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `typetools` package''' \ No newline at end of file diff --git a/polymerist/tests/graphics/__init__.py b/polymerist/tests/graphics/__init__.py new file mode 100644 index 0000000..245b172 --- /dev/null +++ b/polymerist/tests/graphics/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `graphics` package''' \ No newline at end of file diff --git a/polymerist/tests/maths/__init__.py b/polymerist/tests/maths/__init__.py new file mode 100644 index 0000000..3a4fe3d --- /dev/null +++ b/polymerist/tests/maths/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `maths` package''' \ No newline at end of file diff --git a/polymerist/tests/maths/combinatorics/__init__.py b/polymerist/tests/maths/combinatorics/__init__.py new file mode 100644 index 0000000..cd69607 --- /dev/null +++ b/polymerist/tests/maths/combinatorics/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `combinatorics` package''' \ No newline at end of file diff --git a/polymerist/tests/maths/fractions/__init__.py b/polymerist/tests/maths/fractions/__init__.py new file mode 100644 index 0000000..6f0d592 --- /dev/null +++ b/polymerist/tests/maths/fractions/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `fractions` package''' \ No newline at end of file diff --git a/polymerist/tests/maths/greek/__init__.py b/polymerist/tests/maths/greek/__init__.py new file mode 100644 index 0000000..2abe4a8 --- /dev/null +++ b/polymerist/tests/maths/greek/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `greek` package''' \ No newline at end of file diff --git a/polymerist/tests/maths/lattices/__init__.py b/polymerist/tests/maths/lattices/__init__.py new file mode 100644 index 0000000..d23663d --- /dev/null +++ b/polymerist/tests/maths/lattices/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `lattices` package''' \ No newline at end of file diff --git a/polymerist/tests/maths/linearalg/__init__.py b/polymerist/tests/maths/linearalg/__init__.py new file mode 100644 index 0000000..79f09b2 --- /dev/null +++ b/polymerist/tests/maths/linearalg/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `linearalg` package''' \ No newline at end of file diff --git a/polymerist/tests/maths/numbersys/__init__.py b/polymerist/tests/maths/numbersys/__init__.py new file mode 100644 index 0000000..3c95aa1 --- /dev/null +++ b/polymerist/tests/maths/numbersys/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `numbersys` package''' \ No newline at end of file diff --git a/polymerist/tests/mdtools/__init__.py b/polymerist/tests/mdtools/__init__.py new file mode 100644 index 0000000..88e220b --- /dev/null +++ b/polymerist/tests/mdtools/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `mdtools` package''' \ No newline at end of file diff --git a/polymerist/tests/mdtools/lammpstools/__init__.py b/polymerist/tests/mdtools/lammpstools/__init__.py new file mode 100644 index 0000000..f105c90 --- /dev/null +++ b/polymerist/tests/mdtools/lammpstools/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `lammpstools` package''' \ No newline at end of file diff --git a/polymerist/tests/mdtools/openfftools/__init__.py b/polymerist/tests/mdtools/openfftools/__init__.py new file mode 100644 index 0000000..d2e4e9d --- /dev/null +++ b/polymerist/tests/mdtools/openfftools/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `openfftools` package''' \ No newline at end of file diff --git a/polymerist/tests/mdtools/openfftools/partialcharge/__init__.py b/polymerist/tests/mdtools/openfftools/partialcharge/__init__.py new file mode 100644 index 0000000..837792d --- /dev/null +++ b/polymerist/tests/mdtools/openfftools/partialcharge/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `partialcharge` package''' \ No newline at end of file diff --git a/polymerist/tests/mdtools/openfftools/partialcharge/rescharge/__init__.py b/polymerist/tests/mdtools/openfftools/partialcharge/rescharge/__init__.py new file mode 100644 index 0000000..af9bb9f --- /dev/null +++ b/polymerist/tests/mdtools/openfftools/partialcharge/rescharge/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `rescharge` package''' \ No newline at end of file diff --git a/polymerist/tests/mdtools/openfftools/solvation/__init__.py b/polymerist/tests/mdtools/openfftools/solvation/__init__.py new file mode 100644 index 0000000..6f5bcbc --- /dev/null +++ b/polymerist/tests/mdtools/openfftools/solvation/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `solvation` package''' \ No newline at end of file diff --git a/polymerist/tests/mdtools/openfftools/solvation/solvents/__init__.py b/polymerist/tests/mdtools/openfftools/solvation/solvents/__init__.py new file mode 100644 index 0000000..e7e7c7b --- /dev/null +++ b/polymerist/tests/mdtools/openfftools/solvation/solvents/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `solvents` package''' \ No newline at end of file diff --git a/polymerist/tests/mdtools/openmmtools/__init__.py b/polymerist/tests/mdtools/openmmtools/__init__.py new file mode 100644 index 0000000..44b2ca5 --- /dev/null +++ b/polymerist/tests/mdtools/openmmtools/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `openmmtools` package''' \ No newline at end of file diff --git a/polymerist/tests/polymers/__init__.py b/polymerist/tests/polymers/__init__.py new file mode 100644 index 0000000..7622def --- /dev/null +++ b/polymerist/tests/polymers/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `polymers` package''' \ No newline at end of file diff --git a/polymerist/tests/polymers/monomers/__init__.py b/polymerist/tests/polymers/monomers/__init__.py new file mode 100644 index 0000000..c8f2d69 --- /dev/null +++ b/polymerist/tests/polymers/monomers/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `monomers` package''' \ No newline at end of file diff --git a/polymerist/tests/polymers/smidgelib/__init__.py b/polymerist/tests/polymers/smidgelib/__init__.py new file mode 100644 index 0000000..a66a8af --- /dev/null +++ b/polymerist/tests/polymers/smidgelib/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `smidgelib` package''' \ No newline at end of file diff --git a/polymerist/tests/rdutils/__init__.py b/polymerist/tests/rdutils/__init__.py new file mode 100644 index 0000000..c518ab5 --- /dev/null +++ b/polymerist/tests/rdutils/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `rdutils` package''' \ No newline at end of file diff --git a/polymerist/tests/rdutils/bonding/__init__.py b/polymerist/tests/rdutils/bonding/__init__.py new file mode 100644 index 0000000..8ce1af8 --- /dev/null +++ b/polymerist/tests/rdutils/bonding/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `bonding` package''' \ No newline at end of file diff --git a/polymerist/tests/rdutils/labeling/__init__.py b/polymerist/tests/rdutils/labeling/__init__.py new file mode 100644 index 0000000..049964f --- /dev/null +++ b/polymerist/tests/rdutils/labeling/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `labeling` package''' \ No newline at end of file diff --git a/polymerist/tests/rdutils/rdcoords/__init__.py b/polymerist/tests/rdutils/rdcoords/__init__.py new file mode 100644 index 0000000..9adead5 --- /dev/null +++ b/polymerist/tests/rdutils/rdcoords/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `rdcoords` package''' \ No newline at end of file diff --git a/polymerist/tests/rdutils/reactions/__init__.py b/polymerist/tests/rdutils/reactions/__init__.py new file mode 100644 index 0000000..413d674 --- /dev/null +++ b/polymerist/tests/rdutils/reactions/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `reactions` package''' \ No newline at end of file diff --git a/polymerist/tests/smileslib/__init__.py b/polymerist/tests/smileslib/__init__.py new file mode 100644 index 0000000..b9c1d21 --- /dev/null +++ b/polymerist/tests/smileslib/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `smileslib` package''' \ No newline at end of file diff --git a/polymerist/tests/smileslib/functgroups/__init__.py b/polymerist/tests/smileslib/functgroups/__init__.py new file mode 100644 index 0000000..2d5efe7 --- /dev/null +++ b/polymerist/tests/smileslib/functgroups/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `functgroups` package''' \ No newline at end of file diff --git a/polymerist/tests/unitutils/__init__.py b/polymerist/tests/unitutils/__init__.py new file mode 100644 index 0000000..a222fa9 --- /dev/null +++ b/polymerist/tests/unitutils/__init__.py @@ -0,0 +1 @@ +'''Unit tests for `unitutils` package''' \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 63d0541..f645349 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -65,6 +65,12 @@ where = ["."] polymerist = [ "py.typed" ] +# "polymerist.data" = [ +# "look_and_say.dat" +# ] +"polymerist.tests.data" = [ + "*.*", # include any data files shipped in tests.data +] [tool.versioningit] default-version = "1+unknown"