Skip to content

Commit

Permalink
Add unit tests for dic2owl CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
CasperWA committed Aug 30, 2021
1 parent 4a29d8e commit 90184f0
Show file tree
Hide file tree
Showing 6 changed files with 610 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ __pycache__
*.cif

!test-cif/**/*.cif
!tests/**/*.dic
2 changes: 2 additions & 0 deletions dic2owl/requirements_dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ bandit~=1.7.0
mypy==0.910
pre-commit>=2.14.0,<3
pylint>=2.10.1,<3
pytest>=6.2.4,<7
pytest-cov>=2.12.1,<3
149 changes: 149 additions & 0 deletions tests/dic2owl/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
"""PyTest fixtures for `dic2owl`."""
# pylint: disable=import-outside-toplevel,consider-using-with,too-many-branches
# pylint: disable=redefined-outer-name,inconsistent-return-statements
from enum import Enum
from pathlib import Path
from typing import List, Optional, TYPE_CHECKING, Union

import pytest


class CLI(Enum):
"""Enumeration of CLIs."""

CIF2OWL = "cif2owl"
DIC2OWL = "dic2owl"


if TYPE_CHECKING:
from subprocess import CompletedProcess
from typing import Callable

CLIRunner = Callable[
[
Optional[List[str]],
Optional[Union[CLI, str]],
Optional[str],
Optional[Union[Path, str]],
],
CompletedProcess,
]


@pytest.fixture(scope="session")
def clirunner() -> "CLIRunner":
"""Call `dic2owl` CLI"""
from subprocess import run, CalledProcessError
from tempfile import TemporaryDirectory

def _clirunner(
options: Optional[List[str]] = None,
cli: Optional[Union[CLI, str]] = None,
expected_error: Optional[str] = None,
run_dir: Optional[Union[Path, str]] = None,
) -> Union["CompletedProcess", CalledProcessError]:
"""Call `dic2owl` CLI
Parameters:
options: Options with which to call `cli`, e.g., `--version`.
cli: The CLI to call, defaults to `dic2owl`.
expected_error: Sub-string expected in error output, if an error is
expected.
run_dir: The directory to use as current work directory when
running the CLI.
Returns:
The return class for a successful call to `subprocess.run()`.
"""
options = options or []

if not isinstance(options, list):
try:
options = list(options)
except TypeError as exc:
raise TypeError("options must be a list of strings.") from exc

if cli is not None:
try:
cli = CLI(cli)
except ValueError as exc:
raise ValueError(
f"{cli!r} is not a recognized CLI. Recognized CLIs: "
f"{list(CLI.__members__)}"
) from exc
else:
cli = CLI.DIC2OWL

if run_dir is None:
run_dir = TemporaryDirectory()
elif isinstance(run_dir, Path):
run_dir = run_dir.resolve()
else:
try:
run_dir = Path(run_dir).resolve()
except TypeError as exc:
raise TypeError(f"{run_dir} is not a valid path.") from exc

try:
output = run(
args=[cli.value] + options,
capture_output=True,
check=True,
cwd=run_dir.name
if isinstance(run_dir, TemporaryDirectory)
else run_dir,
text=True,
)
if expected_error:
pytest.fail(
"Expected the CLI call to fail with an error containing "
f"the sub-string: {expected_error}"
)
except CalledProcessError as error:
if expected_error:
if (
expected_error in error.stdout
or expected_error in error.stderr
):
# Expected error, found expected sub-string as well.
return error

pytest.fail(
"The CLI call failed as expected, but the expected "
"error sub-string could not be found in stdout or "
f"stderr. Sub-string: {expected_error}"
)
else:
pytest.fail(
"The CLI call failed when it didn't expect to.\n"
f"Information: {error}"
)
else:
return output
finally:
if isinstance(run_dir, TemporaryDirectory):
run_dir.cleanup()

return _clirunner


@pytest.fixture(scope="session")
def top_dir() -> Path:
"""Return repository path."""
return Path(__file__).parent.parent.parent.resolve()


@pytest.fixture(scope="session")
def cif_ttl(top_dir: Path) -> str:
"""Read and return CIF-Core minimized Turtle file (generated from the
accompanying dictionary).
NOTE: The commend conerning the file location has been removed manually
from this file.
"""
with open(
top_dir / "tests/dic2owl/static/cif_core_minimized.ttl", "r"
) as handle:
content = handle.read()
return content
185 changes: 185 additions & 0 deletions tests/dic2owl/static/cif_core_minimized.dic
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
#\#CIF_2.0
##########################################################################
# #
# CIF CORE DICTIONARY #
# #
##########################################################################

data_CORE_DIC

_dictionary.title CORE_DIC
_dictionary.class Instance
_dictionary.version 3.1.0
_dictionary.date 2021-08-18
_dictionary.uri
https://raw.githubusercontent.com/COMCIFS/cif_core/master/cif_core.dic
_dictionary.ddl_conformance 4.0.1
_dictionary.namespace CifCore
_description.text
;
The CIF_CORE dictionary records all the CORE data items defined
and used with in the Crystallographic Information Framework (CIF).
;

save_CIF_CORE

_definition.id CIF_CORE
_definition.scope Category
_definition.class Head
_definition.update 2014-06-18
_description.text
;
The CIF_CORE group contains the definitions of data items that
are common to all domains of crystallographic studies.
;
_name.category_id CORE_DIC
_name.object_id CIF_CORE

save_

save_DIFFRACTION

_definition.id DIFFRACTION
_definition.scope Category
_definition.class Set
_definition.update 2012-11-26
_description.text
;
The DICTIONARY group encompassing the CORE DIFFRACTION data items defined
and used with in the Crystallographic Information Framework (CIF).
;
_name.category_id CIF_CORE
_name.object_id DIFFRACTION

save_

save_DIFFRN

_definition.id DIFFRN
_definition.scope Category
_definition.class Set
_definition.update 2012-12-13
_description.text
;
The CATEGORY of data items used to describe the diffraction experiment.
;
_name.category_id DIFFRACTION
_name.object_id DIFFRN

save_

save_diffrn.ambient_environment

_definition.id '_diffrn.ambient_environment'
_alias.definition_id '_diffrn_ambient_environment'
_definition.update 2012-11-26
_description.text
;
The gas or liquid environment of the crystal sample, if not air.
;
_name.category_id diffrn
_name.object_id ambient_environment
_type.purpose Describe
_type.source Recorded
_type.container Single
_type.contents Text

loop_
_description_example.case
'He'
'vacuum'
'mother liquor'

save_

save_diffrn.ambient_pressure

_definition.id '_diffrn.ambient_pressure'
_alias.definition_id '_diffrn_ambient_pressure'
_definition.update 2012-11-26
_description.text
;
Mean hydrostatic pressure at which intensities were measured.
;
_name.category_id diffrn
_name.object_id ambient_pressure
_type.purpose Measurand
_type.source Recorded
_type.container Single
_type.contents Real
_enumeration.range 0.0:
_units.code kilopascals

save_

save_diffrn.ambient_pressure_su

_definition.id '_diffrn.ambient_pressure_su'

loop_
_alias.definition_id
'_diffrn_ambient_pressure_su'
'_diffrn.ambient_pressure_esd'

_definition.update 2021-03-03
_description.text
;
Standard uncertainty of the mean hydrostatic pressure
at which intensities were measured.
;
_name.category_id diffrn
_name.object_id ambient_pressure_su
_name.linked_item_id '_diffrn.ambient_pressure'
_type.purpose SU
_type.source Recorded
_type.container Single
_type.contents Real
_units.code kilopascals

save_

save_diffrn.ambient_pressure_gt

_definition.id '_diffrn.ambient_pressure_gt'
_alias.definition_id '_diffrn_ambient_pressure_gt'
_definition.update 2012-12-13
_description.text
;
Mean hydrostatic pressure above which intensities were measured.
These items allow for a pressure range to be given.
_diffrn.ambient_pressure should be used in preference to this
item when possible.
;
_name.category_id diffrn
_name.object_id ambient_pressure_gt
_type.purpose Number
_type.source Recorded
_type.container Single
_type.contents Real
_enumeration.range 0.0:
_units.code kilopascals

save_

save_diffrn.ambient_pressure_lt

_definition.id '_diffrn.ambient_pressure_lt'
_alias.definition_id '_diffrn_ambient_pressure_lt'
_definition.update 2012-12-13
_description.text
;
Mean hydrostatic pressure below which intensities were measured.
These items allow for a pressure range to be given.
_diffrn.ambient_pressure should be used in preference to this
item when possible.
;
_name.category_id diffrn
_name.object_id ambient_pressure_lt
_type.purpose Number
_type.source Recorded
_type.container Single
_type.contents Real
_enumeration.range 0.0:
_units.code kilopascals

save_
Loading

0 comments on commit 90184f0

Please sign in to comment.