From 3c5c5a1ca3c9d9be4290e6ce23c7925d70af927e Mon Sep 17 00:00:00 2001 From: Daniel <d.hornung@indiscale.com> Date: Mon, 11 Mar 2024 11:34:27 +0100 Subject: [PATCH] WIP: Added (failing) test for indirect reference. Note: It could be that the real issue is just a problem of reference resolution order.. --- .../create_jsonschema.py | 2 + .../data/indirect_data.json | 18 +++++ .../data/indirect_model.yml | 18 +++++ .../data/indirect_schema.json | 63 ++++++++++++++++++ .../data/indirect_template.xlsx | Bin 0 -> 5853 bytes .../table_json_conversion/test_fill_xlsx.py | 4 ++ .../test_table_template_generator.py | 21 +++++- 7 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 unittests/table_json_conversion/data/indirect_data.json create mode 100644 unittests/table_json_conversion/data/indirect_model.yml create mode 100644 unittests/table_json_conversion/data/indirect_schema.json create mode 100644 unittests/table_json_conversion/data/indirect_template.xlsx diff --git a/unittests/table_json_conversion/create_jsonschema.py b/unittests/table_json_conversion/create_jsonschema.py index 07264649..9585f545 100755 --- a/unittests/table_json_conversion/create_jsonschema.py +++ b/unittests/table_json_conversion/create_jsonschema.py @@ -67,6 +67,8 @@ def main(): do_not_create=["Organisation"]) prepare_datamodel("data/multiple_refs_model.yml", ["Training", "Person"], "data/multiple_refs_schema.json") + prepare_datamodel("data/indirect_model.yml", ["Wrapper"], + "data/indirect_schema.json") if __name__ == "__main__": diff --git a/unittests/table_json_conversion/data/indirect_data.json b/unittests/table_json_conversion/data/indirect_data.json new file mode 100644 index 00000000..c77dd1ff --- /dev/null +++ b/unittests/table_json_conversion/data/indirect_data.json @@ -0,0 +1,18 @@ +{ + "Wrapper": { + "Results": [ + { + "year": 2022, + "avg_score": 2.4 + }, + { + "year": 2023, + "avg_score": 4.2 + } + ], + "Training": { + "name": "Basic Training", + "url": "www.example.com/training/basic" + } + } +} diff --git a/unittests/table_json_conversion/data/indirect_model.yml b/unittests/table_json_conversion/data/indirect_model.yml new file mode 100644 index 00000000..2a7f4f98 --- /dev/null +++ b/unittests/table_json_conversion/data/indirect_model.yml @@ -0,0 +1,18 @@ +Training: + recommended_properties: + url: + datatype: TEXT + description: 'The URL' +Results: + description: "Results for a training" + recommended_properties: + year: + datatype: INTEGER + avg_score: + description: The average score for the linked training. + datatype: DOUBLE +Wrapper: + recommended_properties: + Training: + Results: + datatype: LIST<Results> diff --git a/unittests/table_json_conversion/data/indirect_schema.json b/unittests/table_json_conversion/data/indirect_schema.json new file mode 100644 index 00000000..64b6ff27 --- /dev/null +++ b/unittests/table_json_conversion/data/indirect_schema.json @@ -0,0 +1,63 @@ +{ + "type": "object", + "properties": { + "Wrapper": { + "type": "object", + "required": [], + "additionalProperties": false, + "title": "Wrapper", + "properties": { + "name": { + "type": "string", + "description": "The name of the Record to be created" + }, + "Training": { + "type": "object", + "required": [], + "additionalProperties": false, + "title": "Training", + "properties": { + "name": { + "type": "string", + "description": "The name of the Record to be created" + }, + "url": { + "type": "string", + "description": "The URL" + } + } + }, + "Results": { + "description": "Results for a training", + "type": "array", + "items": { + "type": "object", + "required": [], + "additionalProperties": false, + "description": "Results for a training", + "title": "Results", + "properties": { + "name": { + "type": "string", + "description": "The name of the Record to be created" + }, + "year": { + "type": "integer" + }, + "avg_score": { + "description": "The average score for the linked training.", + "type": "number" + } + } + } + } + }, + "$schema": "https://json-schema.org/draft/2020-12/schema" + } + }, + "required": [ + "Wrapper" + ], + "additionalProperties": false, + "$schema": "https://json-schema.org/draft/2020-12/schema" +} diff --git a/unittests/table_json_conversion/data/indirect_template.xlsx b/unittests/table_json_conversion/data/indirect_template.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..cc614acb75b36e10143a29f28dff9fce7d5e006f GIT binary patch literal 5853 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 literal 0 HcmV?d00001 diff --git a/unittests/table_json_conversion/test_fill_xlsx.py b/unittests/table_json_conversion/test_fill_xlsx.py index edc723d8..4af73e4d 100644 --- a/unittests/table_json_conversion/test_fill_xlsx.py +++ b/unittests/table_json_conversion/test_fill_xlsx.py @@ -78,6 +78,10 @@ def test_fill_xlsx(): template_file=rfp("data/multiple_refs_template.xlsx"), known_good=rfp("data/multiple_refs_data.xlsx"), schema=rfp("data/multiple_refs_schema.json")) + fill_and_compare(json_file=rfp("data/indirect_data.json"), + template_file=rfp("data/indirect_template.xlsx"), + known_good=rfp("data/multiple_refs_data.xlsx"), + schema=rfp("data/indirect_schema.json")) def test_errors(): diff --git a/unittests/table_json_conversion/test_table_template_generator.py b/unittests/table_json_conversion/test_table_template_generator.py index b7a2dafc..19cdff2a 100644 --- a/unittests/table_json_conversion/test_table_template_generator.py +++ b/unittests/table_json_conversion/test_table_template_generator.py @@ -232,6 +232,25 @@ def test_model_with_multiple_refs(): _compare_generated_to_known_good( schema_file=rfp("data/multiple_refs_schema.json"), known_good=rfp("data/multiple_refs_template.xlsx"), - foreign_keys={'Training': {"__this__": ['date', 'url'], + foreign_keys={"Training": {"__this__": ["date", "url"], "Organisation": ["name"]}}, outfile=None) + + +def test_model_with_indirect_reference(): + _compare_generated_to_known_good( + schema_file=rfp("data/indirect_schema.json"), + known_good=rfp("data/indirect_template.xlsx"), + foreign_keys={"Wrapper": ["Training.name", "Training.url"]}, + outfile=None) + + +def test_exceptions(): + # Foreign keys must be lists + with pytest.raises(ValueError, match="Foreign keys must be a list of strings, but a single " + r"string was given:\n\['Wrapper'\] -> name"): + _compare_generated_to_known_good( + schema_file=rfp("data/indirect_schema.json"), + known_good=rfp("data/multiple_refs_template.xlsx"), + foreign_keys={"Wrapper": {"__this__": "name"}}, + outfile=None) -- GitLab