Added tests for configoptions.py

This commit is contained in:
Rhet Turnbull
2020-12-12 07:25:50 -08:00
parent 09687cfca4
commit 0262e0d97e
5 changed files with 145 additions and 2 deletions

View File

@@ -2247,6 +2247,7 @@ For additional details about how osxphotos is implemented or if you would like t
- [bpylist2](https://pypi.org/project/bpylist2/) - [bpylist2](https://pypi.org/project/bpylist2/)
- [pathvalidate](https://pypi.org/project/pathvalidate/) - [pathvalidate](https://pypi.org/project/pathvalidate/)
- [wurlitzer](https://pypi.org/project/wurlitzer/) - [wurlitzer](https://pypi.org/project/wurlitzer/)
- [toml](https://github.com/uiri/toml)
## Acknowledgements ## Acknowledgements

View File

@@ -27,6 +27,7 @@ class ConfigOptions:
Args: Args:
name: name for these options, will be used for section heading in TOML file when saving/loading from file name: name for these options, will be used for section heading in TOML file when saving/loading from file
attrs: dict with name and default value for all allowed attributes attrs: dict with name and default value for all allowed attributes
ignore: optional list of strings of keys to ignore from attrs dict
""" """
self._name = name self._name = name
self._attrs = attrs.copy() self._attrs = attrs.copy()
@@ -113,7 +114,7 @@ class ConfigOptions:
strb = ", ".join(prefix + x.replace("_", "-") for x in b) strb = ", ".join(prefix + x.replace("_", "-") for x in b)
else: else:
stra = a stra = a
strb = ", ".join(x for x in b) strb = ", ".join(b)
raise ConfigOptionsInvalidError( raise ConfigOptionsInvalidError(
f"{stra} must be used with at least one of: {strb}." f"{stra} must be used with at least one of: {strb}."
) )
@@ -166,7 +167,7 @@ class ConfigOptions:
if type(self._attrs[attr]) == tuple: if type(self._attrs[attr]) == tuple:
val = tuple(val) val = tuple(val)
setattr(self, attr, val) setattr(self, attr, val)
return self, None return self
def asdict(self): def asdict(self):
return {attr: getattr(self, attr) for attr in sorted(self._attrs.keys())} return {attr: getattr(self, attr) for attr in sorted(self._attrs.keys())}

View File

@@ -80,6 +80,7 @@ setup(
"dataclasses==0.7;python_version<'3.7'", "dataclasses==0.7;python_version<'3.7'",
"wurlitzer>=2.0.1", "wurlitzer>=2.0.1",
"photoscript>=0.1.0", "photoscript>=0.1.0",
"toml>=0.10.0",
], ],
entry_points={"console_scripts": ["osxphotos=osxphotos.__main__:cli"]}, entry_points={"console_scripts": ["osxphotos=osxphotos.__main__:cli"]},
include_package_data=True, include_package_data=True,

View File

@@ -3974,6 +3974,7 @@ def test_save_load_config():
cwd = os.getcwd() cwd = os.getcwd()
# pylint: disable=not-context-manager # pylint: disable=not-context-manager
with runner.isolated_filesystem(): with runner.isolated_filesystem():
# test save config file
result = runner.invoke( result = runner.invoke(
export, export,
[ [
@@ -3993,6 +3994,7 @@ def test_save_load_config():
files = glob.glob("*") files = glob.glob("*")
assert "config.toml" in files assert "config.toml" in files
# test load config file
result = runner.invoke( result = runner.invoke(
export, export,
[ [
@@ -4007,3 +4009,55 @@ def test_save_load_config():
assert "Loaded options from file" in result.output assert "Loaded options from file" in result.output
assert "Skipped up to date XMP sidecar" in result.output assert "Skipped up to date XMP sidecar" in result.output
# test overwrite existing config file
result = runner.invoke(
export,
[
os.path.join(cwd, CLI_PHOTOS_DB),
".",
"-V",
"--sidecar",
"XMP",
"--touch-file",
"--not-live",
"--update",
"--save-config",
"config.toml",
],
)
assert result.exit_code == 0
assert "Saving options to file" in result.output
files = glob.glob("*")
assert "config.toml" in files
# test load config file with incompat command line option
result = runner.invoke(
export,
[
os.path.join(cwd, CLI_PHOTOS_DB),
".",
"-V",
"--load-config",
"config.toml",
"--live",
],
)
assert result.exit_code != 0
assert "Incompatible export options" in result.output
# test load config file with command line override
result = runner.invoke(
export,
[
os.path.join(cwd, CLI_PHOTOS_DB),
".",
"-V",
"--load-config",
"config.toml",
"--sidecar",
"json",
],
)
assert result.exit_code == 0
assert "Writing exiftool JSON sidecar" in result.output
assert "Writing XMP sidecar" not in result.output

View File

@@ -0,0 +1,86 @@
""" test ConfigOptions class """
import pathlib
import pytest
import toml
from osxphotos.configoptions import (
ConfigOptions,
ConfigOptionsInvalidError,
ConfigOptionsLoadError,
)
VARS = {"foo": "bar", "bar": False, "test1": (), "test2": None, "test2_setting": False}
def test_init():
cfg = ConfigOptions("test", VARS)
assert isinstance(cfg, ConfigOptions)
assert cfg.foo is "bar"
assert cfg.bar == False
assert type(cfg.test1) == tuple
def test_init_with_ignore():
cfg = ConfigOptions("test", VARS, ignore=["test2"])
assert isinstance(cfg, ConfigOptions)
assert hasattr(cfg, "test1")
assert not hasattr(cfg, "test2")
def test_write_to_file_load_from_file(tmpdir):
cfg = ConfigOptions("test", VARS)
cfg.bar = True
cfg_file = pathlib.Path(str(tmpdir)) / "test.toml"
cfg.write_to_file(str(cfg_file))
assert cfg_file.is_file()
cfg_dict = toml.load(str(cfg_file))
assert cfg_dict["test"]["foo"] == "bar"
cfg2 = ConfigOptions("test", VARS).load_from_file(str(cfg_file))
assert cfg2.foo == "bar"
assert cfg2.bar
def test_load_from_file_error(tmpdir):
cfg_file = pathlib.Path(str(tmpdir)) / "test.toml"
cfg = ConfigOptions("test", VARS)
cfg.write_to_file(str(cfg_file))
# try to load with a section that doesn't exist in the TOML file
with pytest.raises(ConfigOptionsLoadError):
cfg2 = ConfigOptions("FOO", VARS).load_from_file(str(cfg_file))
def test_asdict():
cfg = ConfigOptions("test", VARS)
cfg_dict = cfg.asdict()
assert cfg_dict["foo"] == "bar"
assert cfg_dict["bar"] == False
assert cfg_dict["test1"] == ()
def test_validate():
cfg = ConfigOptions("test", VARS)
# test exclusive
assert cfg.validate(exclusive=[("foo", "bar")])
cfg.bar = True
with pytest.raises(ConfigOptionsInvalidError):
assert cfg.validate(exclusive=[("foo", "bar")])
# test dependent
cfg.test2 = True
cfg.test2_setting = 1.0
assert cfg.validate(dependent=[("test2_setting", ("test2"))])
cfg.test2 = False
with pytest.raises(ConfigOptionsInvalidError):
assert cfg.validate(dependent=[("test2_setting", ("test2"))])
# test inclusive
cfg.foo = "foo"
cfg.bar = True
assert cfg.validate(inclusive=[("foo", "bar")])
cfg.foo = None
with pytest.raises(ConfigOptionsInvalidError):
assert cfg.validate(inclusive=[("foo", "bar")])