1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
# Copyright (c) 2024, the cclib development team
#
# This file is part of cclib (http://cclib.github.io) and is distributed under
# the terms of the BSD 3-Clause License.
"""Unit tests for main scripts (ccget, ccwrite)."""
import os
from unittest import mock
import cclib
import pytest
__filedir__ = os.path.dirname(__file__)
__filepath__ = os.path.realpath(__filedir__)
__datadir__ = os.path.join(__filepath__, "..", "..", "data")
INPUT_FILE = os.path.join(__datadir__, "ADF/basicADF2007.01/dvb_gopt.adfout")
CJSON_OUTPUT_FILENAME = "dvb_gopt.cjson"
@mock.patch("cclib.scripts.ccget.ccread")
class ccgetTest:
def setup_method(self) -> None:
try:
from cclib.scripts import ccget
except ImportError:
self.fail("ccget cannot be imported")
self.main = ccget.ccget
@mock.patch("cclib.scripts.ccget.sys.argv", ["ccget"])
def test_empty_argv(self, mock_ccread) -> None:
"""Does the script fail as expected if called without parameters?"""
with pytest.raises(SystemExit):
self.main()
@mock.patch("cclib.scripts.ccget.sys.argv", ["ccget", "atomcoords", INPUT_FILE])
def test_ccread_invocation(self, mock_ccread) -> None:
self.main()
assert mock_ccread.call_count == 1
ccread_call_args, ccread_call_kwargs = mock_ccread.call_args
assert ccread_call_args[0] == INPUT_FILE
@mock.patch("logging.Logger.warning")
@mock.patch("cclib.scripts.ccget.sys.argv", ["ccget", "atomcoord", INPUT_FILE])
def test_ccread_invocation_matching_args(self, mock_warn, mock_ccread):
self.main()
assert mock_warn.call_count == 1
warn_call_args, warn_call_kwargs = mock_warn.call_args
warn_message = warn_call_args[0]
assert (
warn_message
== "Attribute 'atomcoord' not found, but attribute 'atomcoords' is close. Using 'atomcoords' instead."
)
assert mock_ccread.call_count == 1
ccread_call_args, ccread_call_kwargs = mock_ccread.call_args
assert ccread_call_args[0] == INPUT_FILE
@mock.patch("cclib.scripts.ccwrite.ccwrite")
class ccwriteTest:
def setup_method(self) -> None:
try:
from cclib.scripts import ccwrite
except ImportError:
self.fail("ccwrite cannot be imported")
self.main = ccwrite.main
@mock.patch("cclib.scripts.ccwrite.sys.argv", ["ccwrite"])
def test_empty_argv(self, mock_ccwrite) -> None:
"""Does the script fail as expected if called without parameters?"""
with pytest.raises(SystemExit):
self.main()
@mock.patch("cclib.scripts.ccwrite.sys.argv", ["ccwrite", "cjson", INPUT_FILE])
def test_ccwrite_call(self, mock_ccwrite) -> None:
"""is ccwrite called with the given parameters?"""
self.main()
assert mock_ccwrite.call_count == 1
ccwrite_call_args, ccwrite_call_kwargs = mock_ccwrite.call_args
assert ccwrite_call_args[1] == "cjson"
assert ccwrite_call_args[2] == CJSON_OUTPUT_FILENAME
class ccframeTest:
def setup_method(self) -> None:
# It would be best to test with Pandas and not a mock!
if not hasattr(cclib.io.ccio, "pd"):
cclib.io.ccio.pd = mock.MagicMock()
def test_main_empty_argv(self) -> None:
"""Does main() fail as expected if called without arguments?"""
with pytest.raises(SystemExit):
cclib.scripts.ccframe.main()
@mock.patch("cclib.scripts.ccframe.sys.argv", ["ccframe", INPUT_FILE])
@mock.patch("cclib.io.ccio._has_pandas", False)
def test_main_without_pandas(self) -> None:
"""Does ccframe fail if Pandas can't be imported?"""
with pytest.raises(ImportError, match="You must install `pandas` to use this function"):
cclib.scripts.ccframe.main()
@mock.patch("cclib.scripts.ccframe.sys.argv", ["ccframe", INPUT_FILE])
@mock.patch("cclib.io.ccio._has_pandas", True)
def test_main(self) -> None:
"""Is ccframe called with the given parameters?"""
with mock.patch("sys.stdout") as mock_stdout:
cclib.scripts.ccframe.main()
assert mock_stdout.write.call_count == 2
df, newline = mock_stdout.write.call_args_list
if isinstance(df[0][0], mock.MagicMock):
assert df[0][0].name == "mock.DataFrame()"
else:
# TODO: this is what we really should be testing
pass
assert newline[0][0] == "\n"
|