From 74c8152cf32899e079b29c7a70931b7b80ca2f20 Mon Sep 17 00:00:00 2001 From: Satoru SATOH Date: Tue, 7 May 2024 09:31:33 +0900 Subject: [PATCH] fix: do not override constants and functions from tests.api.load{,single_load}.common --- tests/api/load/multi_load/common.py | 13 +++ tests/api/load/multi_load/test_basics.py | 105 ++++++++++++++++++ tests/api/load/multi_load/test_multi_types.py | 35 ++++++ tests/api/load/multi_load/test_query.py | 53 +++++++++ tests/api/load/multi_load/test_schema.py | 72 ++++++++++++ tests/api/load/multi_load/test_template.py | 43 +++++++ tests/api/multi_load/common.py | 1 - tests/res/1/api/load/multi_load | 1 + 8 files changed, 322 insertions(+), 1 deletion(-) create mode 100644 tests/api/load/multi_load/common.py create mode 100644 tests/api/load/multi_load/test_basics.py create mode 100644 tests/api/load/multi_load/test_multi_types.py create mode 100644 tests/api/load/multi_load/test_query.py create mode 100644 tests/api/load/multi_load/test_schema.py create mode 100644 tests/api/load/multi_load/test_template.py create mode 120000 tests/res/1/api/load/multi_load diff --git a/tests/api/load/multi_load/common.py b/tests/api/load/multi_load/common.py new file mode 100644 index 00000000..ca1bde07 --- /dev/null +++ b/tests/api/load/multi_load/common.py @@ -0,0 +1,13 @@ +# +# Copyright (C) 2021 - 2024 Satoru SATOH +# SPDX-License-Identifier: MIT +# +# pylint: disable=missing-docstring +# pylint: disable=unused-import +"""Common module for tests.api.load.""" +from __future__ import annotations + +from ...multi_load.common import ( # noqa: F401 + NAMES, GLOB_PATTERN, + load_data_for_testfile, get_test_ids +) diff --git a/tests/api/load/multi_load/test_basics.py b/tests/api/load/multi_load/test_basics.py new file mode 100644 index 00000000..33996a1f --- /dev/null +++ b/tests/api/load/multi_load/test_basics.py @@ -0,0 +1,105 @@ +# +# Copyright (C) 2021 - 2024 Satoru SATOH +# SPDX-License-Identifier: MIT +# +# pylint: disable=missing-docstring +"""Test cases for anyconfig.api.load (multi_load).""" +from __future__ import annotations + +import collections +import typing + +import pytest + +import anyconfig.api._load as TT + +from .common import ( + NAMES, GLOB_PATTERN, load_data_for_testfile, get_test_ids +) + +if typing.TYPE_CHECKING: + import pathlib + + +DATA = load_data_for_testfile(__file__) +DATA_IDS: list[str] = get_test_ids(DATA) + +DATA_W_GLOB = [ + (inputs[0].parent / GLOB_PATTERN, opts, exp) + for inputs, opts, exp in DATA +] + + +def test_data() -> None: + assert DATA + + +def test_load_with_empty_list() -> None: + with pytest.raises(ValueError): + TT.load([]) + + +@pytest.mark.parametrize(NAMES, DATA, ids=DATA_IDS) +def test_load_for_a_list_of_path_objects( + inputs: list[pathlib.Path], opts: dict, exp +) -> None: + assert TT.load(inputs, **opts) == exp + assert TT.load((i for i in inputs), **opts) == exp + + +@pytest.mark.parametrize(NAMES, DATA, ids=DATA_IDS) +def test_load_for_a_list_of_path_strings( + inputs: list[pathlib.Path], opts: dict, exp +) -> None: + assert TT.load([str(i) for i in inputs], **opts) == exp + assert TT.load((str(i) for i in inputs), **opts) == exp + + +@pytest.mark.parametrize( + NAMES, DATA_W_GLOB, ids=get_test_ids(DATA_W_GLOB) +) +def test_load_for_glob_patterns( + inputs: list[pathlib.Path], opts: dict, exp +) -> None: + assert TT.load(inputs, **opts) == exp + + +@pytest.mark.parametrize(NAMES, DATA, ids=DATA_IDS) +def test_load_for_a_list_of_streams( + inputs: list[pathlib.Path], opts: dict, exp +) -> None: + assert TT.load([i.open() for i in inputs], **opts) == exp + + +class MyDict(collections.OrderedDict): + pass + + +@pytest.mark.parametrize(NAMES, DATA, ids=DATA_IDS) +def test_load_with_ac_dict_option( + inputs: list[pathlib.Path], opts: dict, exp +) -> None: + res = TT.load(inputs, ac_dict=MyDict, **opts) + assert res == exp + assert isinstance(res, MyDict) + + +@pytest.mark.parametrize(NAMES, DATA[:1], ids=DATA_IDS[:1]) +def test_load_with_wrong_merge_strategy( + inputs: list[pathlib.Path], opts: dict, exp +) -> None: + assert exp # dummy to avoid an error of unused argument. + with pytest.raises(ValueError): + TT.load(inputs, ac_merge="wrong_merge_strategy", **opts) + + +def test_load_with_ignore_missing_option(): + paths = [ + "/path/to/file_not_exist_0.json", + "/path/to/file_not_exist_1.json", + "/path/to/file_not_exist_2.json", + ] + with pytest.raises(FileNotFoundError): + TT.load(paths) + + assert TT.load(paths, ac_ignore_missing=True) == {} diff --git a/tests/api/load/multi_load/test_multi_types.py b/tests/api/load/multi_load/test_multi_types.py new file mode 100644 index 00000000..b2851759 --- /dev/null +++ b/tests/api/load/multi_load/test_multi_types.py @@ -0,0 +1,35 @@ +# +# Copyright (C) 2021 - 2024 Satoru SATOH +# SPDX-License-Identifier: MIT +# +# pylint: disable=missing-docstring +"""Test cases for anyconfig.api.load with multi type inputs.""" +from __future__ import annotations + +import typing + +import pytest + +import anyconfig.api._load as TT + +from .common import ( + NAMES, load_data_for_testfile, get_test_ids +) + +if typing.TYPE_CHECKING: + import pathlib + + +DATA = load_data_for_testfile(__file__) +DATA_IDS: list[str] = get_test_ids(DATA) + + +def test_data() -> None: + assert DATA + + +@pytest.mark.parametrize(NAMES, DATA, ids=DATA_IDS) +def test_load( + inputs: list[pathlib.Path], opts: dict, exp +) -> None: + assert TT.load(inputs, **opts) == exp diff --git a/tests/api/load/multi_load/test_query.py b/tests/api/load/multi_load/test_query.py new file mode 100644 index 00000000..8d7ffc3e --- /dev/null +++ b/tests/api/load/multi_load/test_query.py @@ -0,0 +1,53 @@ +# +# Copyright (C) 2021 - 2024 Satoru SATOH +# SPDX-License-Identifier: MIT +# +# pylint: disable=missing-docstring +"""Test cases for anyconfig.api.load with query options.""" +from __future__ import annotations + +import typing + +import pytest + +import anyconfig.api._load as TT +import anyconfig.query + +from .common import ( + load_data_for_testfile, get_test_ids +) + +if typing.TYPE_CHECKING: + import pathlib + + +if not anyconfig.query.SUPPORTED: + pytest.skip( + "jmespath lib to neede for query is not available.", + allow_module_level=True + ) + +NAMES: tuple[str, ...] = ("inputs", "query", "exp") +DATA = load_data_for_testfile(__file__, values=(("q", ""), ("e", None))) +DATA_IDS: list[str] = get_test_ids(DATA) + + +def test_data() -> None: + assert DATA + + +@pytest.mark.parametrize(NAMES, DATA, ids=DATA_IDS) +def test_load( + inputs: list[pathlib.Path], query: str, exp +) -> None: + assert TT.load(inputs, ac_query=query) == exp + + +@pytest.mark.parametrize(NAMES, DATA[:1], ids=DATA_IDS[:1]) +def test_load_with_invalid_query( + inputs: list[pathlib.Path], query: str, exp +) -> None: + assert query or exp # To avoid an error not using them. + assert TT.load( + inputs, ac_query="" + ) == TT.load(inputs) diff --git a/tests/api/load/multi_load/test_schema.py b/tests/api/load/multi_load/test_schema.py new file mode 100644 index 00000000..8b951a84 --- /dev/null +++ b/tests/api/load/multi_load/test_schema.py @@ -0,0 +1,72 @@ +# +# Copyright (C) 2021 - 2024 Satoru SATOH +# SPDX-License-Identifier: MIT +# +# pylint: disable=missing-docstring +"""Test cases for anyconfig.api.load with schema validation.""" +from __future__ import annotations + +import typing + +import pytest + +import anyconfig.api._load as TT +import anyconfig.schema + +from anyconfig.api import ValidationError + +from . import common + +if typing.TYPE_CHECKING: + import pathlib + + +if "jsonschema" not in anyconfig.schema.VALIDATORS: + pytest.skip( + "jsonschema lib is not available.", + allow_module_level=True + ) + + +def scm_path_from_inputs(inputs: list[pathlib.Path]) -> pathlib.Path: + path = inputs[0] + name = path.name[:-len(path.suffix)] + return list((path.parent / "s").glob(f"{name}.*"))[0] + + +NAMES: tuple[str, ...] = (*common.NAMES, "scm") +DATA = [ + (inputs, *rest, scm_path_from_inputs(inputs)) + for inputs, *rest in common.load_data_for_testfile(__file__) +] +DATA_IDS: list[str] = common.get_test_ids(DATA) + + +def test_data() -> None: + assert DATA + + +@pytest.mark.parametrize(NAMES, DATA, ids=DATA_IDS) +def test_load( + inputs: list[pathlib.Path], opts: dict, exp, scm: pathlib.Path +) -> None: + assert TT.load(inputs, ac_schema=scm, **opts) == exp + + +SCM_NG_0 = '{"type": "object", "properties": {"a": {"type": "string"}}}' + + +@pytest.mark.parametrize(NAMES, DATA[:1], ids=DATA_IDS[:1]) +def test_load_with_validation_failure( + inputs: list[pathlib.Path], opts: dict, exp, scm: pathlib.Path, + tmp_path: pathlib.Path +) -> None: + assert exp or scm # dummy + + scm = tmp_path / "scm.json" + scm.write_text(SCM_NG_0) + + with pytest.raises(ValidationError): + TT.load( + inputs, ac_schema=scm, ac_schema_safe=False, **opts + ) diff --git a/tests/api/load/multi_load/test_template.py b/tests/api/load/multi_load/test_template.py new file mode 100644 index 00000000..9aa566ff --- /dev/null +++ b/tests/api/load/multi_load/test_template.py @@ -0,0 +1,43 @@ +# +# Copyright (C) 2021 - 2024 Satoru SATOH +# SPDX-License-Identifier: MIT +# +# pylint: disable=missing-docstring +"""Test cases for anyconfig.api.load with template options.""" +from __future__ import annotations + +import typing + +import pytest + +import anyconfig.api._load as TT +import anyconfig.template + +from . import common + +if typing.TYPE_CHECKING: + import pathlib + +if not anyconfig.template.SUPPORTED: + pytest.skip( + "jinja2 lib neede for template option is not available", + allow_module_level=True + ) + + +NAMES: tuple[str, ...] = (*common.NAMES, "ctx") +DATA: list = common.load_data_for_testfile( + __file__, values=(("o", {}), ("e", None), ("c", {})) +) +DATA_IDS: list[str] = common.get_test_ids(DATA) + + +def test_data() -> None: + assert DATA + + +@pytest.mark.parametrize(NAMES, DATA, ids=DATA_IDS) +def test_load( + inputs: list[pathlib.Path], opts: dict, exp, ctx: dict +) -> None: + assert TT.load(inputs, ac_context=ctx, **opts) == exp diff --git a/tests/api/multi_load/common.py b/tests/api/multi_load/common.py index 1fcf0430..5d58692f 100644 --- a/tests/api/multi_load/common.py +++ b/tests/api/multi_load/common.py @@ -8,7 +8,6 @@ """ from __future__ import annotations -import anyconfig.api._load as TT import anyconfig.api.utils from ... import common diff --git a/tests/res/1/api/load/multi_load b/tests/res/1/api/load/multi_load new file mode 120000 index 00000000..c389992e --- /dev/null +++ b/tests/res/1/api/load/multi_load @@ -0,0 +1 @@ +../multi_load \ No newline at end of file