From b1573034c957c31b589df1c0b19d56c169ce2ba0 Mon Sep 17 00:00:00 2001
From: Daniel <d.hornung@indiscale.com>
Date: Wed, 6 Mar 2024 13:43:40 +0100
Subject: [PATCH] ENH: More extensive testing data, better foreign key naming.

---
 .../table_json_conversion/table_generator.py  |  14 +-
 .../example_template.xlsx                     | Bin 9592 -> 9855 bytes
 .../model_multiple_refs.yml                   |   5 +-
 .../table_json_conversion/multiple_refs.xlsx  | Bin 0 -> 12238 bytes
 .../schema_multiple_refs.json                 | 140 +++++-------------
 .../test_table_template_generator.py          |  81 ++++++----
 6 files changed, 105 insertions(+), 135 deletions(-)
 create mode 100644 unittests/table_json_conversion/multiple_refs.xlsx

diff --git a/src/caosadvancedtools/table_json_conversion/table_generator.py b/src/caosadvancedtools/table_json_conversion/table_generator.py
index 07fac819..8794496f 100644
--- a/src/caosadvancedtools/table_json_conversion/table_generator.py
+++ b/src/caosadvancedtools/table_json_conversion/table_generator.py
@@ -198,13 +198,15 @@ class TableTemplateGenerator(ABC):
                 )
                 # and add the foreign keys that are necessary up to this point
                 for array_path in array_paths:
-                    keys = self._get_foreign_keys(foreign_keys, array_path)
-                    for key in keys:
-                        if key in sheets[sheetname]:
+                    foreigns = self._get_foreign_keys(foreign_keys, array_path)
+                    for foreign in foreigns:
+                        internal_key = ".".join(array_path + [foreign])
+                        if internal_key in sheets[sheetname]:
                             raise ValueError("The schema would lead to two columns with the same "
-                                             f"name which is forbidden: {key}")
-                        sheets[sheetname][key] = (ColumnType.FOREIGN, f"see sheet '{path[0]}'",
-                                                  array_path + [key])
+                                             f"name, which is forbidden: {internal_key}")
+                        ref_sheet = ".".join(array_path)
+                        sheets[sheetname][internal_key] = (
+                            ColumnType.FOREIGN, f"see sheet '{ref_sheet}'", array_path + [foreign])
                 # Columns are added to the new sheet, thus we do not return any columns for the
                 # current sheet.
                 return {}
diff --git a/unittests/table_json_conversion/example_template.xlsx b/unittests/table_json_conversion/example_template.xlsx
index 6d9c7627e724144e7748dcfb36f2292be49b036e..1b8a8cd3d4e68c17d7d9d3fc2cb8c54236b39c22 100644
GIT binary patch
delta 6786
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
I+n?6|0IK~St^fc4

delta 6509
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
OBQ%*9F=}WZo&O(pJ;TNT

diff --git a/unittests/table_json_conversion/model_multiple_refs.yml b/unittests/table_json_conversion/model_multiple_refs.yml
index c95a97ac..576ff1d5 100644
--- a/unittests/table_json_conversion/model_multiple_refs.yml
+++ b/unittests/table_json_conversion/model_multiple_refs.yml
@@ -4,7 +4,6 @@ Person:
       datatype: TEXT
     email:
       datatype: TEXT
-    Organisation:
 Training:
   recommended_properties:
     date:
@@ -21,6 +20,8 @@ Training:
       datatype: Person
     responsible:
       datatype: Person
+    Organisation:
+      datatype: LIST<Organisation>
     supervisor_inherit:
       inherit_from_suggested:
         - Person
@@ -31,3 +32,5 @@ Organisation:
   recommended_properties:
     Country:
       datatype: TEXT
+    Person:
+      datatype: LIST<Person>
diff --git a/unittests/table_json_conversion/multiple_refs.xlsx b/unittests/table_json_conversion/multiple_refs.xlsx
new file mode 100644
index 0000000000000000000000000000000000000000..34bea9b9b9d29c9308ec5cff496c91e7ecaa45c9
GIT binary patch
literal 12238
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
Zf5NlMa*$B3S3!Qct-Q>nMf%rw{{;qPXUPBn

literal 0
HcmV?d00001

diff --git a/unittests/table_json_conversion/schema_multiple_refs.json b/unittests/table_json_conversion/schema_multiple_refs.json
index 5678f72c..7acf5e0d 100644
--- a/unittests/table_json_conversion/schema_multiple_refs.json
+++ b/unittests/table_json_conversion/schema_multiple_refs.json
@@ -45,21 +45,6 @@
               },
               "email": {
                 "type": "string"
-              },
-              "Organisation": {
-                "type": "object",
-                "required": [],
-                "additionalProperties": false,
-                "title": "Organisation",
-                "properties": {
-                  "name": {
-                    "type": "string",
-                    "description": "The name of the Record to be created"
-                  },
-                  "Country": {
-                    "type": "string"
-                  }
-                }
               }
             }
           }
@@ -81,21 +66,6 @@
               },
               "email": {
                 "type": "string"
-              },
-              "Organisation": {
-                "type": "object",
-                "required": [],
-                "additionalProperties": false,
-                "title": "Organisation",
-                "properties": {
-                  "name": {
-                    "type": "string",
-                    "description": "The name of the Record to be created"
-                  },
-                  "Country": {
-                    "type": "string"
-                  }
-                }
               }
             }
           }
@@ -115,21 +85,6 @@
             },
             "email": {
               "type": "string"
-            },
-            "Organisation": {
-              "type": "object",
-              "required": [],
-              "additionalProperties": false,
-              "title": "Organisation",
-              "properties": {
-                "name": {
-                  "type": "string",
-                  "description": "The name of the Record to be created"
-                },
-                "Country": {
-                  "type": "string"
-                }
-              }
             }
           }
         },
@@ -148,19 +103,43 @@
             },
             "email": {
               "type": "string"
-            },
-            "Organisation": {
-              "type": "object",
-              "required": [],
-              "additionalProperties": false,
-              "title": "Organisation",
-              "properties": {
-                "name": {
-                  "type": "string",
-                  "description": "The name of the Record to be created"
-                },
-                "Country": {
-                  "type": "string"
+            }
+          }
+        },
+        "Organisation": {
+          "type": "array",
+          "items": {
+            "type": "object",
+            "required": [],
+            "additionalProperties": false,
+            "title": "Organisation",
+            "properties": {
+              "name": {
+                "type": "string",
+                "description": "The name of the Record to be created"
+              },
+              "Country": {
+                "type": "string"
+              },
+              "Person": {
+                "type": "array",
+                "items": {
+                  "type": "object",
+                  "required": [],
+                  "additionalProperties": false,
+                  "title": "Person",
+                  "properties": {
+                    "name": {
+                      "type": "string",
+                      "description": "The name of the Record to be created"
+                    },
+                    "full_name": {
+                      "type": "string"
+                    },
+                    "email": {
+                      "type": "string"
+                    }
+                  }
                 }
               }
             }
@@ -181,21 +160,6 @@
             },
             "email": {
               "type": "string"
-            },
-            "Organisation": {
-              "type": "object",
-              "required": [],
-              "additionalProperties": false,
-              "title": "Organisation",
-              "properties": {
-                "name": {
-                  "type": "string",
-                  "description": "The name of the Record to be created"
-                },
-                "Country": {
-                  "type": "string"
-                }
-              }
             }
           }
         },
@@ -214,21 +178,6 @@
             },
             "email": {
               "type": "string"
-            },
-            "Organisation": {
-              "type": "object",
-              "required": [],
-              "additionalProperties": false,
-              "title": "Organisation",
-              "properties": {
-                "name": {
-                  "type": "string",
-                  "description": "The name of the Record to be created"
-                },
-                "Country": {
-                  "type": "string"
-                }
-              }
             }
           }
         }
@@ -250,21 +199,6 @@
         },
         "email": {
           "type": "string"
-        },
-        "Organisation": {
-          "type": "object",
-          "required": [],
-          "additionalProperties": false,
-          "title": "Organisation",
-          "properties": {
-            "name": {
-              "type": "string",
-              "description": "The name of the Record to be created"
-            },
-            "Country": {
-              "type": "string"
-            }
-          }
         }
       },
       "$schema": "https://json-schema.org/draft/2020-12/schema"
diff --git a/unittests/table_json_conversion/test_table_template_generator.py b/unittests/table_json_conversion/test_table_template_generator.py
index af3b3a2d..8115c187 100644
--- a/unittests/table_json_conversion/test_table_template_generator.py
+++ b/unittests/table_json_conversion/test_table_template_generator.py
@@ -22,6 +22,7 @@
 import json
 import os
 import tempfile
+from typing import Tuple
 
 import pytest
 from caosadvancedtools.table_json_conversion.table_generator import (
@@ -37,6 +38,47 @@ def rfp(*pathcomponents):
     return os.path.join(os.path.dirname(__file__), *pathcomponents)
 
 
+def _compare_generated_to_known_good(schema_file: str, known_good: str, foreign_keys: dict = None,
+                                     outfile: str = None) -> Tuple:
+    """Generate an XLSX from the schema, then compare to known good output.
+
+Returns
+-------
+out: tuple
+  The generated and known good workbook objects.
+    """
+    generator = XLSXTemplateGenerator()
+    if foreign_keys is None:
+        foreign_keys = {}
+    with open(schema_file, encoding="utf-8") as schema_input:
+        schema = json.load(schema_input)
+    if outfile is None:
+        outpath = os.path.join(tempfile.mkdtemp(), 'generated.xlsx')
+    else:
+        outpath = outfile
+    assert not os.path.exists(outpath)
+    generator.generate(schema=schema,
+                       foreign_keys=foreign_keys,
+                       filepath=outpath)
+    assert os.path.exists(outpath)
+    generated = load_workbook(outpath)  # workbook can be read
+    good = load_workbook(known_good)
+    assert generated.sheetnames == good.sheetnames
+    for sheetname in good.sheetnames:
+        gen_sheet = generated[sheetname]
+        good_sheet = good[sheetname]
+        for irow, (erow, grow) in enumerate(zip(good_sheet.iter_rows(), gen_sheet.iter_rows())):
+            assert (good_sheet.row_dimensions[irow].hidden
+                    == gen_sheet.row_dimensions[irow].hidden), f"row: {sheetname}, {irow}"
+            for icol, (ecol, gcol) in enumerate(zip(erow, grow)):
+                assert (good_sheet.column_dimensions[ecol.column_letter].hidden
+                        == gen_sheet.column_dimensions[ecol.column_letter].hidden), (
+                            f"col: {sheetname}, {icol}")
+                cell = gen_sheet.cell(irow+1, icol+1)
+                assert ecol.value == gcol.value, f"Sheet: {sheetname}, cell: {cell.coordinate}"
+    return generated, good
+
+
 def test_generate_sheets_from_schema():
     # trivial case; we do not support this
     schema = {}
@@ -133,8 +175,8 @@ def test_generate_sheets_from_schema():
     assert cdef['given_name'] == (ColumnType.SCALAR, None, ["Training", 'coach', 'given_name'])
     assert cdef['Organisation'] == (ColumnType.SCALAR, None, ["Training", 'coach',
                                                               'Organisation'])
-    assert cdef['date'] == (ColumnType.FOREIGN, "see sheet 'Training'", ["Training", 'date'])
-    assert cdef['url'] == (ColumnType.FOREIGN, "see sheet 'Training'", ["Training", 'url'])
+    assert cdef['Training.date'] == (ColumnType.FOREIGN, "see sheet 'Training'", ["Training", 'date'])
+    assert cdef['Training.url'] == (ColumnType.FOREIGN, "see sheet 'Training'", ["Training", 'url'])
 
 
 def test_get_foreign_keys():
@@ -163,29 +205,10 @@ def test_get_max_path_length():
 
 
 def test_template_generator():
-    generator = XLSXTemplateGenerator()
-    with open(rfp("model_schema.json")) as sfi:
-        schema = json.load(sfi)
-    path = os.path.join(tempfile.mkdtemp(), 'test.xlsx')
-    assert not os.path.exists(path)
-    generator.generate(schema=schema,
-                       foreign_keys={'Training': {"__this__": ['date', 'url']}},
-                       filepath=path)
-    assert os.path.exists(path)
-    generated = load_workbook(path)  # workbook can be read
-    example = load_workbook(rfp("example_template.xlsx"))
-    assert generated.sheetnames == example.sheetnames
-    for sheetname in example.sheetnames:
-        gen_sheet = generated[sheetname]
-        ex_sheet = example[sheetname]
-        for irow, (erow, grow) in enumerate(zip(ex_sheet.iter_rows(), gen_sheet.iter_rows())):
-            assert ex_sheet.row_dimensions[irow].hidden == gen_sheet.row_dimensions[irow].hidden
-            for icol, (ecol, gcol) in enumerate(zip(erow, grow)):
-                assert (ex_sheet.column_dimensions[ecol.column_letter].hidden
-                        == gen_sheet.column_dimensions[ecol.column_letter].hidden)
-                cell = gen_sheet.cell(irow+1, icol+1)
-                assert ecol.value == gcol.value, f"Sheet: {sheetname}, cell: {cell.coordinate}"
-
+    generated, _ = _compare_generated_to_known_good(
+        schema_file=rfp("model_schema.json"), known_good=rfp("example_template.xlsx"),
+        foreign_keys={'Training': {"__this__": ['date', 'url']}},
+        outfile=None)
     # test some hidden
     ws = generated.active
     assert ws.row_dimensions[1].hidden is True
@@ -212,3 +235,11 @@ def test_template_generator():
     # TODO test escaping of values
 
     # TODO finish enum example
+
+
+def test_model_with_multiple_refs():
+    _compare_generated_to_known_good(
+        schema_file=rfp("schema_multiple_refs.json"), known_good=rfp("multiple_refs.xlsx"),
+        foreign_keys={'Training': {"__this__": ['date', 'url'],
+                                   "Organisation": ["name"]}},
+        outfile=None)
-- 
GitLab