Skip to content
Snippets Groups Projects
Select Git revision
  • 955a7e144969a53024ae2391d6b5086db02a744d
  • main default protected
  • f-yaml-parser-enums
  • dev protected
  • f-fix-paths
  • f-fix-validate-to-dict
  • f-labfolder-converter
  • f-state-machine-script
  • f-xlsx-converter-warnings-errors
  • f-rename
  • f-extra-deps
  • f-more-jsonschema-export
  • f-henrik
  • f-fix-89
  • f-trigger-advanced-user-tools
  • f-real-rename-test
  • f-linkahead-rename
  • f-register-integrationtests
  • f-fix-id
  • f-h5-files
  • f-json-schema
  • v0.14.0
  • v0.13.0
  • v0.12.0
  • v0.11.0
  • v0.10.0-numpy2
  • v0.10.0
  • v0.9.0
  • v0.8.0
  • v0.7.0
  • v0.6.1
  • v0.6.0
  • v0.5.0
  • v0.4.1
  • v0.4.0
  • v0.3.1
  • v0.3.0
37 results

test_read_data.py

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    test_read_data.py 5.10 KiB
    # encoding: utf-8
    #
    # This file is a part of the LinkAhead Project.
    #
    # Copyright (C) 2024 Indiscale GmbH <info@indiscale.com>
    # Copyright (C) 2024 Daniel Hornung <d.hornung@indiscale.com>
    #
    # This program is free software: you can redistribute it and/or modify
    # it under the terms of the GNU Affero General Public License as
    # published by the Free Software Foundation, either version 3 of the
    # License, or (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # GNU Affero General Public License for more details.
    #
    # You should have received a copy of the GNU Affero General Public License
    # along with this program. If not, see <https://www.gnu.org/licenses/>.
    """Testing the conversion from XLSX to JSON"""
    
    
    import json
    import os
    import re
    
    from types import SimpleNamespace
    
    import pytest
    from caosadvancedtools.table_json_conversion import convert
    
    from .utils import assert_equal_jsons
    
    
    def rfp(*pathcomponents):
        """Return full path, a shorthand convenience function.
        """
        return os.path.join(os.path.dirname(__file__), *pathcomponents)
    
    
    def convert_and_compare(xlsx_file: str, schema_file: str, known_good_file: str) -> dict:
        """Convert an XLSX file and compare to a known result.
    
    Returns
    -------
    json: dict
      The result of the conversion.
        """
        result = convert.to_dict(xlsx=xlsx_file, schema=schema_file)
        with open(known_good_file, encoding="utf-8") as myfile:
            expected = json.load(myfile)
        assert_equal_jsons(result, expected)
        return result
    
    
    def test_conversions():
        """Test conversion from XLSX to JSON."""
        convert_and_compare(xlsx_file=rfp("data/simple_data.xlsx"),
                            schema_file=rfp("data/simple_schema.json"),
                            known_good_file=rfp("data/simple_data.json"))
        convert_and_compare(xlsx_file=rfp("data/multiple_refs_data.xlsx"),
                            schema_file=rfp("data/multiple_refs_schema.json"),
                            known_good_file=rfp("data/multiple_refs_data.json"))
        convert_and_compare(xlsx_file=rfp("data/indirect_data.xlsx"),
                            schema_file=rfp("data/indirect_schema.json"),
                            known_good_file=rfp("data/indirect_data.json"))
        convert_and_compare(xlsx_file=rfp("data/simple_data_ascii_chars.xlsx"),
                            schema_file=rfp("data/simple_schema.json"),
                            known_good_file=rfp("data/simple_data_ascii_chars.json"))
        convert_and_compare(xlsx_file=rfp("data/multiple_choice_data.xlsx"),
                            schema_file=rfp("data/multiple_choice_schema.json"),
                            known_good_file=rfp("data/multiple_choice_data.json"))
    
    
    def test_set_in_nested():
        """Test the ``_set_in_nested`` function."""
        set_in_nested = convert._set_in_nested  # pylint: disable=protected-access
    
        test_data_in = [
            {"mydict": {}, "path": ["a", 1], "value": 3},
            {"mydict": {"a": 1}, "path": ["a"], "value": 3, "overwrite": True},
            {"mydict": {"a": 1}, "path": ["a", 1], "value": 3, "overwrite": True},
            {"mydict": {"b": 2}, "path": ["a", 1, 3.141], "value": 3},
            {"mydict": {}, "path": ["X", "Y", "a", 1], "value": 3, "prefix": ["X", "Y"]},
        ]
        test_data_out = [
            {"a": {1: 3}},
            {"a": 3},
            {"a": {1: 3}},
            {"a": {1: {3.141: 3}}, "b": 2},
            {"a": {1: 3}},
        ]
    
        for data_in, data_out in zip(test_data_in, test_data_out):
            assert set_in_nested(**data_in) == data_out
    
        # Testing exceptions
        test_data_in = [
            {"mydict": {"a": 1}, "path": ["a"], "value": 3},
            {"mydict": {"a": 1}, "path": ["a", 1], "value": 3},
            {"mydict": {}, "path": ["a", 1], "value": 3, "prefix": ["X", "Y", "Z"]},
        ]
        exceptions = [
            [ValueError, r"There is already some value at \[a\]"],
            [ValueError, r"There is already some value at \[1\]"],
            [KeyError, r"Path does not start with prefix: \['X', 'Y', 'Z'\] not in \['a', 1\]"],
        ]
    
        for data_in, (exc_out, match) in zip(test_data_in, exceptions):
            with pytest.raises(exc_out, match=match):
                set_in_nested(**data_in)
    
    
    def test_group_foreign_paths():
        """Test the ``_group_foreign_paths`` function."""
        group = convert._group_foreign_paths  # pylint: disable=protected-access
    
        foreign = [
            ["A", "x", 1.1],
            ["A", "y", "z", "some text"],
            ["A", "B", "CC", "x", 42],
        ]
        common = ["A", "B", "CC"]
        common_wrong = ["A", "B", "C"]
        expected = [
            SimpleNamespace(stringpath="A", path=["A"], subpath=["A"],
                            definitions=[["x", 1.1], ["y", "z", "some text"]]),
            SimpleNamespace(stringpath="A.B.CC", path=["A", "B", "CC"], subpath=["B", "CC"],
                            definitions=[["x", 42]]),
        ]
    
        with pytest.raises(ValueError, match=re.escape(
                "Foreign keys must cover the complete `common` depth.")):
            result = group(foreign=foreign, common=common_wrong)
        result = group(foreign=foreign, common=common)
        assert result == expected