diff --git a/src/caosadvancedtools/table_json_conversion/fill_xlsx.py b/src/caosadvancedtools/table_json_conversion/fill_xlsx.py index 46c55ab15678962c96310e71e3e6741b1a111ef1..f2e0abc3fc684172065d683c99c1c4309c80d6c0 100644 --- a/src/caosadvancedtools/table_json_conversion/fill_xlsx.py +++ b/src/caosadvancedtools/table_json_conversion/fill_xlsx.py @@ -209,10 +209,19 @@ out: union[dict, None] assert len(set(type(entry) for entry in content)) == 1 if isinstance(content[0], dict): # all elements are dicts - # An array of objects: must go into exploded sheet - for entry in content: - self._handle_data(data=entry, current_path=path, context=next_context) - continue + # Heuristic to detect enum entries (only id and name): + if all(set(entry.keys()) == {"id", "name"} for entry in content): + # Convert to list of names, do not recurse + content = [entry["name"] for entry in content] + else: + # An array of objects: must go into exploded sheet + for entry in content: + self._handle_data(data=entry, current_path=path, context=next_context) + continue + # Heuristic to detect enum entries (dict with only id and name): + elif isinstance(content, dict) and set(content.keys()) == {"id", "name"}: + content = [content["name"]] + # "Normal" dicts elif isinstance(content, dict): # we recurse and simply use the result if not current_path: # Special handling for top level self._handle_data(content, current_path=path, context=next_context) @@ -259,7 +268,8 @@ out: union[dict, None] sheet = None for path_str, value in insertables.items(): if self._graceful and path_str not in self._sheet_index: - warn(f"Ignoring path with missing sheet index: {path_str}") + if not (value is None or path_str.endswith(".id") or path_str.endswith(".name")): + warn(f"Ignoring path with missing sheet index: {path_str}") continue sheet_meta = self._sheet_index[path_str] if sheet is None: @@ -346,6 +356,7 @@ validation_schema: dict, optional if validation_schema is not None: validation_schema = array_schema_from_model_schema(read_or_dict(validation_schema)) try: + # FIXME redefine checker for datetime validate(data, validation_schema, format_checker=FormatChecker()) except ValidationError as verr: print(verr.message) diff --git a/src/caosadvancedtools/table_json_conversion/xlsx_utils.py b/src/caosadvancedtools/table_json_conversion/xlsx_utils.py index 7cedd391087b386c5e0b194301191f2d4881ddf6..5002f3ac7fe4bd78accffe0697cd7ecc7273dc27 100644 --- a/src/caosadvancedtools/table_json_conversion/xlsx_utils.py +++ b/src/caosadvancedtools/table_json_conversion/xlsx_utils.py @@ -235,8 +235,6 @@ proper_name: str if ii > len(parent): parent = foreign_path[:ii] - # print(data_paths, ii) - # breakpoint() return parent, data_paths[0][ii] diff --git a/unittests/table_json_conversion/test_fill_xlsx.py b/unittests/table_json_conversion/test_fill_xlsx.py index f580fdbf867f08db0d72ade3537d4f2c1e8301d6..899bb81ef1f91f3326f214f49f135a55b97d299f 100644 --- a/unittests/table_json_conversion/test_fill_xlsx.py +++ b/unittests/table_json_conversion/test_fill_xlsx.py @@ -19,6 +19,7 @@ # 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/>. +import datetime import json import os import re @@ -33,6 +34,7 @@ from caosadvancedtools.table_json_conversion.fill_xlsx import fill_template from caosadvancedtools.table_json_conversion.xlsx_utils import ( get_row_type_column_index, get_path_rows, + read_or_dict, ) from .utils import compare_workbooks @@ -149,6 +151,32 @@ def test_fill_xlsx(): schema=rfp("data/multiple_choice_schema.json")) +def test_datetime(): + """Datetime values from LinkAhead are not serialized as strings.""" + json_file = rfp("data/simple_data.json") + template_file = rfp("data/simple_template.xlsx") + known_good = rfp("data/simple_data_datetime.xlsx") + # TODO Implement checker for datetime + # schema = rfp("data/simple_schema.json") + + # Set datetime explicitly + json_data = read_or_dict(json_file) + json_data["Training"][0]["date"] = datetime.datetime(2023, 1, 1) + + # Code copied mostly from `fill_and_compare(...)` + with tempfile.TemporaryDirectory() as tmpdir: + outfile = os.path.join(tmpdir, 'test.xlsx') + assert not os.path.exists(outfile) + fill_template(data=json_data, template=template_file, result=outfile, + # validation_schema=schema + ) + assert os.path.exists(outfile) + generated = load_workbook(outfile) # workbook can be read + + known_good_wb = load_workbook(known_good) + compare_workbooks(generated, known_good_wb) + + def test_errors(): with pytest.raises(AssertionError) as exc: fill_and_compare(json_file=rfp("data/error_simple_data.json"),