diff --git a/JsonPreprocessor/CJsonPreprocessor.py b/JsonPreprocessor/CJsonPreprocessor.py index 92e58d2d..20546bc7 100644 --- a/JsonPreprocessor/CJsonPreprocessor.py +++ b/JsonPreprocessor/CJsonPreprocessor.py @@ -68,6 +68,7 @@ class CNameMangling(Enum): STRINGCONVERT = "__ConvertParameterToString__" LISTINDEX = "__IndexOfList__" SLICEINDEX = "__SlicingIndex__" + STRINGVALUE = "__StringValueMake-up__" class CPythonJSONDecoder(json.JSONDecoder): """ @@ -196,6 +197,27 @@ def __init__(self, syntax: CSyntaxType = CSyntaxType.python , currentCfg : dict self.jsonCheck = {} self.JPGlobals = {} + def __getFailedJsonDoc(self, jsonDecodeError=None, areaBeforePosition=50, areaAfterPosition=20, oneLine=True): + failedJsonDoc = None + if jsonDecodeError is None: + return failedJsonDoc + try: + jsonDoc = jsonDecodeError.doc + except: + # 'jsonDecodeError' seems not to be a JSON exception object ('doc' not available) + return failedJsonDoc + jsonDocSize = len(jsonDoc) + positionOfError = jsonDecodeError.pos + if areaBeforePosition > positionOfError: + areaBeforePosition = positionOfError + if areaAfterPosition > (jsonDocSize - positionOfError): + areaAfterPosition = jsonDocSize - positionOfError + failedJsonDoc = jsonDoc[positionOfError-areaBeforePosition:positionOfError+areaAfterPosition] + failedJsonDoc = f"... {failedJsonDoc} ..." + if oneLine is True: + failedJsonDoc = failedJsonDoc.replace("\n", r"\n") + return failedJsonDoc + def __reset(self) -> None: """ Reset initial variables which are set in constructor method after master JSON file is loaded. @@ -683,7 +705,6 @@ def __updateAndReplaceNestedParam(self, oJson : dict, bNested : bool = False, re Output JSON object as dictionary with all variables resolved. """ - def __jsonUpdated(k, v, oJson, bNested, keyNested = '', bDuplicatedHandle=False, recursive = False): if keyNested != '': if not bDuplicatedHandle and keyNested in oJson.keys(): @@ -888,116 +909,6 @@ def __loadNestedValue(initValue: str, sInputStr: str, bKey=False, key=''): del tmpJson return oJson, bNested - def __checkAndUpdateKeyValue(self, sInputStr: str, nestedKey = False) -> str: - """ -This function checks and makes up all nested parameters in JSON configuration files. - -**Arguments:** - -* ``sInputStr*`` - - / *Condition*: required / *Type*: str / - - Key or value which is parsed from JSON configuration file. - -**Returns:** - The string after nested parameters are made up. - - Ex: - - Nested param ${abc}['xyz'] -> "${abc}['xyz']" - - Nested param "${abc}['xyz']" -> "${abc}['xyz']__ConvertParameterToString__" - """ - def __recursiveNestedHandling(sInputStr: str, lNestedParam: list) -> str: - """ -This method handles nested parameters are called recursively in a string value. - """ - tmpList = [] - for item in lNestedParam: - item = re.sub(r'([$()\[\]])', r'\\\1', item) - pattern = rf"(\${{\s*[^{re.escape(self.specialCharacters)}]*" + item + \ - rf"[^{re.escape(self.specialCharacters)}]*\s*}}(\[\s*.+\s*\])*)" - if re.search(pattern, sInputStr, re.UNICODE): - sInputStr = re.sub("(" + pattern + ")", "\\1" + CNameMangling.STRINGCONVERT.value, sInputStr, re.UNICODE) - tmpResults = re.findall("(" + pattern + CNameMangling.STRINGCONVERT.value + ")", sInputStr, re.UNICODE) - for result in tmpResults: - tmpList.append(result[0]) - if tmpList != []: - sInputStr = __recursiveNestedHandling(sInputStr, tmpList) - - return sInputStr - - variablePattern = rf"[^{re.escape(self.specialCharacters)}]+" - indexPattern = r"\[[\s\-\+\d]*\]|\[.*:.*\]" - dictPattern = r"\[+\s*'.+'\s*\]+|\[+\s*\d+\s*\]+|\[+\s*\${\s*" + variablePattern + r"\s*}.*\]+|" + indexPattern - nestedPattern = r"\${\s*" + variablePattern + r"(\.*\${\s*" + variablePattern + r"\s*})*" + r"\s*}(" + dictPattern + r")*" - valueStrPattern = r"[\"|\']\s*[0-9A-Za-z_\-\s*]+[\"|\']" - valueNumberPattern = r"[0-9\.]+" - - if "${" in sInputStr: - if re.match(r"^\s*" + nestedPattern + r"[\s,\]}]*$", sInputStr, re.UNICODE): - iCheck = sInputStr.count("]") - sInputStr.count("[") - if iCheck > 0: - tmpItems = sInputStr.split("]") - index = len(tmpItems) - iCheck - sParam = "]".join(tmpItems[:index]) - dReplacements = {"$":"\$", "[":"\[", "]":"\]", "-":"\-", "+":"\+"} - paramPattern = self.__multipleReplace(sParam, dReplacements) - sInputStr = re.sub("(" + paramPattern + ")", "\"\\1\"", sInputStr, re.UNICODE) - else: - sInputStr = re.sub("(" + nestedPattern + ")", "\"\\1\"", sInputStr, re.UNICODE) - nestedParam = re.sub(r"^\s*\"(.+)\".*$", "\\1", sInputStr) - self.lNestedParams.append(nestedParam) - elif re.match(r"^\s*\"\s*" + nestedPattern + r"\"[\s,\]}]*$", sInputStr, re.UNICODE): - nestedParam = re.sub(r"^\s*\"(.+)\".*$", "\\1", sInputStr) - self.lNestedParams.append(nestedParam) - sInputStr = sInputStr.replace(nestedParam, nestedParam + CNameMangling.STRINGCONVERT.value) - elif ((re.match(r"[\s{\[]*\".+\"\s*", sInputStr) and sInputStr.count("\"")==2) \ - or (re.match(r"^\s*\${.+}[,\s]*$", sInputStr) and sInputStr.count("{")==sInputStr.count("}") \ - and not re.search(r"(? str: - items = re.split("\s*,\s*", sInput) - j=0 - newItem = "" - for item in items: - j+=1 - if j dict: listKeys = list(dInput.keys()) dictValues = {} @@ -1235,6 +1134,28 @@ def __checkKeynameFormat(oJson : dict): self.__checkNestedParam(item) elif isinstance(v, dict): __checkKeynameFormat(v) + + def __handleLastElement(sInput : str) -> str: + ''' +This function handle a last element of a list or dictionary + ''' + param = re.search(r'(' + nestedPattern + r')', sInput) + if param is not None and re.match(r'^[\s\[\]{}]*$', sInput.replace(param[0], '')): + sParam = param[0] + if sParam.count('[')1 and not re.match(r'^\[|{.+$', item.strip()): + dReplacements = {"$":"\$", "[":"\[", "]":"\]", ".":"\.", "-":"\-", "+":"\+"} + tmpPattern1 = self.__multipleReplace(preItem, dReplacements) + tmpPattern2 = self.__multipleReplace(curItem, dReplacements) + if re.search(tmpPattern1 + '\s*:\s*' + tmpPattern2, curLine): + item = re.sub(r'^\s*(.+)\s*', '"\\1"', item) + bHandle = True + if not bHandle: + subItems = item.split(',') + iSubItems = len(subItems) -1 if subItems[-1]=='' else len(subItems) + newSubItem = "" + j=1 + for subItem in subItems: + if "${" in subItem: + if iSubItems>1 and j`_ + All **JsonPreprocessor** test cases: `JPP_TestUsecases.html `_ " ] , @@ -90,9 +90,18 @@ Finally, the value of ``var1`` is 2 and the value of ``var2`` is 3. -* Self test extended by further test cases +* Self test extended by further test cases. + + Overview about **JsonPreprocessor** test cases: `JPP_TestUsecases.html `_ + +* Extended debugging support: + + In case of JSON syntax errors, the **JsonPreprocessor** exception contains an extract of the JSON content nearby the position, where the error occurred. + Line breaks in JSON content are replaced by '``\\n``'. + + | ``'Expecting ',' delimiter: line 3 column 4 (char 43)`` + | ``Nearby: '... \u007b\\n \"dict_param\" : \u007b\"A\" : 1 , \"B\" : 2\u007d\\n \"list_param\" : [\"A\", ...'`` - All JsonPreprocessor test cases: `JPP_TestUsecases.html `_ " ] } diff --git a/packagedoc/additional_docs/History.tex b/packagedoc/additional_docs/History.tex index a930fc15..44820d59 100644 --- a/packagedoc/additional_docs/History.tex +++ b/packagedoc/additional_docs/History.tex @@ -55,4 +55,7 @@ - Optimized errors handling while loading nested parameters\newline - Fixed bugs} +\historyversiondate{0.5.0}{04/2024} +\historychange{Extended debugging support. In case of JSON syntax errors, the JsonPreprocessor exception contains an extract of the JSON content nearby the position, where the error occurred.} + \end{packagehistory} diff --git a/test/JPP_TestUsecases.csv b/test/JPP_TestUsecases.csv index b4553c53..aa6cf51d 100644 --- a/test/JPP_TestUsecases.csv +++ b/test/JPP_TestUsecases.csv @@ -69,6 +69,7 @@ JPP_0500|COMPOSITE_EXPRESSIONS|GOODCASE|JSON file with composite data structure JPP_0501|COMPOSITE_EXPRESSIONS|GOODCASE|JSON file with composite data structure (nested lists and dictionaries 2) JPP_0502|COMPOSITE_EXPRESSIONS|GOODCASE|JSON file with composite data structure (nested lists and dictionaries 3 / some key names with dots inside) JPP_0503|COMPOSITE_EXPRESSIONS|GOODCASE|JSON file with composite data structure (some lists) +JPP_0504|COMPOSITE_EXPRESSIONS|GOODCASE|JSON file with composite data structure (some dictionaries) JPP_0505|COMPOSITE_EXPRESSIONS|GOODCASE|JSON file with composite strings containing several times a colon and a comma (JSON syntax elements) JPP_0506|COMPOSITE_EXPRESSIONS|GOODCASE|JSON file with composite strings containing several combinations of curly brackets and special characters before JPP_0507|COMPOSITE_EXPRESSIONS|GOODCASE|JSON file containing several string concatenations in separate lines (1) @@ -125,7 +126,8 @@ JPP_1362|BLOCKED_SLICING|BADCASE|JSON file with blocked slicing notation (0:${ne JPP_1363|BLOCKED_SLICING|BADCASE|JSON file with blocked slicing notation (left hand side of colon) JPP_1364|BLOCKED_SLICING|BADCASE|JSON file with blocked slicing notation (left hand side of colon) JPP_1365|BLOCKED_SLICING|BADCASE|JSON file with blocked slicing notation (combinations with negative integer parameter) -JPP_1500|STRING_INDICES|GOODCASE|JSON file with indices applied to a string (inside lists and inside dictionaries) +JPP_1500|STRING_INDICES|GOODCASE|JSON file with indices applied to a string (inside lists and inside dictionaries; standard notation) +JPP_1501|STRING_INDICES|GOODCASE|JSON file with indices applied to a string (inside lists and inside dictionaries; dotdict notation) JPP_1650|NOT_EXISTING_PARAMETERS|BADCASE|JSON file with not existing parameters at several positions (1) JPP_1651|NOT_EXISTING_PARAMETERS|BADCASE|JSON file with not existing parameters at several positions (2) JPP_1652|NOT_EXISTING_PARAMETERS|BADCASE|JSON file with not existing parameters at several positions (3) @@ -138,4 +140,5 @@ JPP_1660|NOT_EXISTING_PARAMETERS|BADCASE|JSON file with not existing parameters JPP_1661|NOT_EXISTING_PARAMETERS|BADCASE|JSON file with not existing parameters at several positions (12) JPP_1700|LINE_BREAKS|GOODCASE|JSON file with and without line breaks inside expressions JPP_1800|SELF_ASSIGNMENTS|GOODCASE|JSON file with self assignments of strings, lists and dictionaries +JPP_1900|ASSIGNMENTS_BY_REFERENCE|GOODCASE|JSON file with dictionary assignments (by reference) JPP_1901|ASSIGNMENTS_BY_REFERENCE|GOODCASE|JSON file with list assignments (by reference) diff --git a/test/JPP_TestUsecases.html b/test/JPP_TestUsecases.html index 578d0486..39d7c5bf 100644 --- a/test/JPP_TestUsecases.html +++ b/test/JPP_TestUsecases.html @@ -2342,6 +2342,39 @@ 70 + + + +JPP_0504 + + + + +COMPOSITE_EXPRESSIONS + + + + +GOODCASE + + + + +JSON file with composite data structure (some dictionaries)
+Expected: JsonPreprocessor returns expected value + + +
+ + + + + + + +71 + + @@ -2372,7 +2405,7 @@ -71 +72 @@ -2405,7 +2438,7 @@ -72 +73 @@ -2438,7 +2471,7 @@ -73 +74 @@ -2471,7 +2504,7 @@ -74 +75 @@ -2504,7 +2537,7 @@ -75 +76 @@ -2537,7 +2570,7 @@ -76 +77 @@ -2570,7 +2603,7 @@ -77 +78 @@ -2603,7 +2636,7 @@ -78 +79 @@ -2636,7 +2669,7 @@ -79 +80 @@ -2669,7 +2702,7 @@ -80 +81 @@ -2702,7 +2735,7 @@ -81 +82 @@ -2735,7 +2768,7 @@ -82 +83 @@ -2769,7 +2802,7 @@ -83 +84 @@ -2803,7 +2836,7 @@ -84 +85 @@ -2836,7 +2869,7 @@ -85 +86 @@ -2869,7 +2902,7 @@ -86 +87 @@ -2902,7 +2935,7 @@ -87 +88 @@ -2935,7 +2968,7 @@ -88 +89 @@ -2968,7 +3001,7 @@ -89 +90 @@ -3001,7 +3034,7 @@ -90 +91 @@ -3034,7 +3067,7 @@ -91 +92 @@ -3067,7 +3100,7 @@ -92 +93 @@ -3100,7 +3133,7 @@ -93 +94 @@ -3133,7 +3166,7 @@ -94 +95 @@ -3166,7 +3199,7 @@ -95 +96 @@ -3199,7 +3232,7 @@ -96 +97 @@ -3232,7 +3265,7 @@ -97 +98 @@ -3265,7 +3298,7 @@ -98 +99 @@ -3298,7 +3331,7 @@ -99 +100 @@ -3331,7 +3364,7 @@ -100 +101 @@ -3364,7 +3397,7 @@ -101 +102 @@ -3397,7 +3430,7 @@ -102 +103 @@ -3430,7 +3463,7 @@ -103 +104 @@ -3463,7 +3496,7 @@ -104 +105 @@ -3496,7 +3529,7 @@ -105 +106 @@ -3529,7 +3562,7 @@ -106 +107 @@ -3562,7 +3595,7 @@ -107 +108 @@ -3595,7 +3628,7 @@ -108 +109 @@ -3628,7 +3661,7 @@ -109 +110 @@ -3662,7 +3695,7 @@ -110 +111 @@ -3695,7 +3728,7 @@ -111 +112 @@ -3728,7 +3761,7 @@ -112 +113 @@ -3761,7 +3794,7 @@ -113 +114 @@ -3794,7 +3827,7 @@ -114 +115 @@ -3827,7 +3860,7 @@ -115 +116 @@ -3860,7 +3893,7 @@ -116 +117 @@ -3893,7 +3926,7 @@ -117 +118 @@ -3926,7 +3959,7 @@ -118 +119 @@ -3959,7 +3992,7 @@ -119 +120 @@ -3992,7 +4025,7 @@ -120 +121 @@ -4025,7 +4058,7 @@ -121 +122 @@ -4058,7 +4091,7 @@ -122 +123 @@ -4091,7 +4124,7 @@ -123 +124 @@ -4124,7 +4157,7 @@ -124 +125 @@ -4157,7 +4190,7 @@ -125 +126 @@ -4190,7 +4223,7 @@ -126 +127 @@ -4211,7 +4244,7 @@ -JSON file with indices applied to a string (inside lists and inside dictionaries)
+JSON file with indices applied to a string (inside lists and inside dictionaries; standard notation)
Expected: JsonPreprocessor returns expected value @@ -4223,7 +4256,40 @@ -127 +128 + + + + + +JPP_1501 + + + + +STRING_INDICES + + + + +GOODCASE + + + + +JSON file with indices applied to a string (inside lists and inside dictionaries; dotdict notation)
+Expected: JsonPreprocessor returns expected value + + +
+ + + + + + + +129 @@ -4256,7 +4322,7 @@ -128 +130 @@ -4289,7 +4355,7 @@ -129 +131 @@ -4322,7 +4388,7 @@ -130 +132 @@ -4355,7 +4421,7 @@ -131 +133 @@ -4388,7 +4454,7 @@ -132 +134 @@ -4421,7 +4487,7 @@ -133 +135 @@ -4454,7 +4520,7 @@ -134 +136 @@ -4487,7 +4553,7 @@ -135 +137 @@ -4520,7 +4586,7 @@ -136 +138 @@ -4553,7 +4619,7 @@ -137 +139 @@ -4586,7 +4652,7 @@ -138 +140 @@ -4619,7 +4685,40 @@ -139 +141 + + + + + +JPP_1900 + + + + +ASSIGNMENTS_BY_REFERENCE + + + + +GOODCASE + + + + +JSON file with dictionary assignments (by reference)
+Expected: JsonPreprocessor returns expected value + + +
+ + + + + + + +142 @@ -4652,7 +4751,7 @@
 

-
Generated: 03.04.2024 - 09:23:46
+
Generated: 08.04.2024 - 14:47:37
 
diff --git a/test/JPP_TestUsecases.rst b/test/JPP_TestUsecases.rst index cbe4c651..5b8bd426 100644 --- a/test/JPP_TestUsecases.rst +++ b/test/JPP_TestUsecases.rst @@ -767,6 +767,16 @@ Test Use Cases ---- +* **Test JPP_0504** + + [COMPOSITE_EXPRESSIONS / GOODCASE] + + **JSON file with composite data structure (some dictionaries)** + + Expected: JsonPreprocessor returns expected value + +---- + * **Test JPP_0505** [COMPOSITE_EXPRESSIONS / GOODCASE] @@ -1337,7 +1347,17 @@ Test Use Cases [STRING_INDICES / GOODCASE] - **JSON file with indices applied to a string (inside lists and inside dictionaries)** + **JSON file with indices applied to a string (inside lists and inside dictionaries; standard notation)** + + Expected: JsonPreprocessor returns expected value + +---- + +* **Test JPP_1501** + + [STRING_INDICES / GOODCASE] + + **JSON file with indices applied to a string (inside lists and inside dictionaries; dotdict notation)** Expected: JsonPreprocessor returns expected value @@ -1463,6 +1483,16 @@ Test Use Cases ---- +* **Test JPP_1900** + + [ASSIGNMENTS_BY_REFERENCE / GOODCASE] + + **JSON file with dictionary assignments (by reference)** + + Expected: JsonPreprocessor returns expected value + +---- + * **Test JPP_1901** [ASSIGNMENTS_BY_REFERENCE / GOODCASE] @@ -1473,5 +1503,5 @@ Test Use Cases ---- -Generated: 03.04.2024 - 09:23:46 +Generated: 08.04.2024 - 14:47:37 diff --git a/test/JPP_TestUsecases.txt b/test/JPP_TestUsecases.txt index d9dd958a..054356ec 100644 --- a/test/JPP_TestUsecases.txt +++ b/test/JPP_TestUsecases.txt @@ -322,6 +322,10 @@ Test JPP_0503 / COMPOSITE_EXPRESSIONS / GOODCASE Description: JSON file with composite data structure (some lists) Expectation: JsonPreprocessor returns expected value ------------------------------------------------------------------------------------------------------------------------ +Test JPP_0504 / COMPOSITE_EXPRESSIONS / GOODCASE +Description: JSON file with composite data structure (some dictionaries) +Expectation: JsonPreprocessor returns expected value +------------------------------------------------------------------------------------------------------------------------ Test JPP_0505 / COMPOSITE_EXPRESSIONS / GOODCASE Description: JSON file with composite strings containing several times a colon and a comma (JSON syntax elements) Expectation: JsonPreprocessor returns expected value @@ -550,7 +554,11 @@ Description: JSON file with blocked slicing notation (combinations with negative Expectation: No values are returned, and JsonPreprocessor throws an exception ------------------------------------------------------------------------------------------------------------------------ Test JPP_1500 / STRING_INDICES / GOODCASE -Description: JSON file with indices applied to a string (inside lists and inside dictionaries) +Description: JSON file with indices applied to a string (inside lists and inside dictionaries; standard notation) +Expectation: JsonPreprocessor returns expected value +------------------------------------------------------------------------------------------------------------------------ +Test JPP_1501 / STRING_INDICES / GOODCASE +Description: JSON file with indices applied to a string (inside lists and inside dictionaries; dotdict notation) Expectation: JsonPreprocessor returns expected value ------------------------------------------------------------------------------------------------------------------------ Test JPP_1650 / NOT_EXISTING_PARAMETERS / BADCASE @@ -601,9 +609,13 @@ Test JPP_1800 / SELF_ASSIGNMENTS / GOODCASE Description: JSON file with self assignments of strings, lists and dictionaries Expectation: JsonPreprocessor returns expected value ------------------------------------------------------------------------------------------------------------------------ +Test JPP_1900 / ASSIGNMENTS_BY_REFERENCE / GOODCASE +Description: JSON file with dictionary assignments (by reference) +Expectation: JsonPreprocessor returns expected value +------------------------------------------------------------------------------------------------------------------------ Test JPP_1901 / ASSIGNMENTS_BY_REFERENCE / GOODCASE Description: JSON file with list assignments (by reference) Expectation: JsonPreprocessor returns expected value ------------------------------------------------------------------------------------------------------------------------ -Generated: 03.04.2024 - 09:23:46 +Generated: 08.04.2024 - 14:47:37 diff --git a/test/component_test.py b/test/component_test.py index efa82851..94a285f6 100644 --- a/test/component_test.py +++ b/test/component_test.py @@ -22,8 +22,8 @@ # # -------------------------------------------------------------------------------------------------------------- # -VERSION = "0.40.0" -VERSION_DATE = "03.04.2024" +VERSION = "0.41.0" +VERSION_DATE = "08.04.2024" # # -------------------------------------------------------------------------------------------------------------- #TM*** diff --git a/test/pytest/pytestfiles/test_07_COMPOSITE_EXPRESSIONS_GOODCASE.py b/test/pytest/pytestfiles/test_07_COMPOSITE_EXPRESSIONS_GOODCASE.py index 4c3f7587..f47a71c3 100644 --- a/test/pytest/pytestfiles/test_07_COMPOSITE_EXPRESSIONS_GOODCASE.py +++ b/test/pytest/pytestfiles/test_07_COMPOSITE_EXPRESSIONS_GOODCASE.py @@ -18,7 +18,7 @@ # # XC-CT/ECA3-Queckenstedt # -# 15.03.2024 - 18:49:01 +# 08.04.2024 - 14:47:37 # # -------------------------------------------------------------------------------------------------------------- @@ -61,6 +61,14 @@ def test_JPP_0502(self, Description): def test_JPP_0503(self, Description): nReturn = CExecute.Execute("JPP_0503") assert nReturn == 0 +# -------------------------------------------------------------------------------------------------------------- + # Expected: JsonPreprocessor returns expected value + @pytest.mark.parametrize( + "Description", ["JSON file with composite data structure (some dictionaries)",] + ) + def test_JPP_0504(self, Description): + nReturn = CExecute.Execute("JPP_0504") + assert nReturn == 0 # -------------------------------------------------------------------------------------------------------------- # Expected: JsonPreprocessor returns expected value @pytest.mark.parametrize( diff --git a/test/pytest/pytestfiles/test_16_STRING_INDICES_GOODCASE.py b/test/pytest/pytestfiles/test_16_STRING_INDICES_GOODCASE.py index bff610a7..e4be40a9 100644 --- a/test/pytest/pytestfiles/test_16_STRING_INDICES_GOODCASE.py +++ b/test/pytest/pytestfiles/test_16_STRING_INDICES_GOODCASE.py @@ -18,7 +18,7 @@ # # XC-CT/ECA3-Queckenstedt # -# 25.03.2024 - 13:09:36 +# 08.04.2024 - 14:47:37 # # -------------------------------------------------------------------------------------------------------------- @@ -32,9 +32,17 @@ class Test_STRING_INDICES_GOODCASE: # -------------------------------------------------------------------------------------------------------------- # Expected: JsonPreprocessor returns expected value @pytest.mark.parametrize( - "Description", ["JSON file with indices applied to a string (inside lists and inside dictionaries)",] + "Description", ["JSON file with indices applied to a string (inside lists and inside dictionaries; standard notation)",] ) def test_JPP_1500(self, Description): nReturn = CExecute.Execute("JPP_1500") assert nReturn == 0 +# -------------------------------------------------------------------------------------------------------------- + # Expected: JsonPreprocessor returns expected value + @pytest.mark.parametrize( + "Description", ["JSON file with indices applied to a string (inside lists and inside dictionaries; dotdict notation)",] + ) + def test_JPP_1501(self, Description): + nReturn = CExecute.Execute("JPP_1501") + assert nReturn == 0 # -------------------------------------------------------------------------------------------------------------- diff --git a/test/pytest/pytestfiles/test_20_ASSIGNMENTS_BY_REFERENCE_GOODCASE.py b/test/pytest/pytestfiles/test_20_ASSIGNMENTS_BY_REFERENCE_GOODCASE.py index 431723f9..199c89ee 100644 --- a/test/pytest/pytestfiles/test_20_ASSIGNMENTS_BY_REFERENCE_GOODCASE.py +++ b/test/pytest/pytestfiles/test_20_ASSIGNMENTS_BY_REFERENCE_GOODCASE.py @@ -18,7 +18,7 @@ # # XC-CT/ECA3-Queckenstedt # -# 03.04.2024 - 09:23:46 +# 08.04.2024 - 14:47:37 # # -------------------------------------------------------------------------------------------------------------- @@ -29,6 +29,14 @@ class Test_ASSIGNMENTS_BY_REFERENCE_GOODCASE: +# -------------------------------------------------------------------------------------------------------------- + # Expected: JsonPreprocessor returns expected value + @pytest.mark.parametrize( + "Description", ["JSON file with dictionary assignments (by reference)",] + ) + def test_JPP_1900(self, Description): + nReturn = CExecute.Execute("JPP_1900") + assert nReturn == 0 # -------------------------------------------------------------------------------------------------------------- # Expected: JsonPreprocessor returns expected value @pytest.mark.parametrize( diff --git a/test/testconfig/TestConfig.py b/test/testconfig/TestConfig.py index 5b25ed3c..0fb1c674 100644 --- a/test/testconfig/TestConfig.py +++ b/test/testconfig/TestConfig.py @@ -22,7 +22,7 @@ # # -------------------------------------------------------------------------------------------------------------- # -# 03.04.2024 +# 08.04.2024 # # !!! Temporarily tests are deactivated by the following line commented out: # # # listofdictUsecases.append(dictUsecase) @@ -3023,47 +3023,68 @@ del dictUsecase # -------------------------------------------------------------------------------------------------------------- # -------------------------------------------------------------------------------------------------------------- +# +# https://github.com/test-fullautomation/python-jsonpreprocessor/issues/269 +# https://github.com/test-fullautomation/python-jsonpreprocessor/issues/253 +# dictUsecase = {} dictUsecase['TESTID'] = "JPP_1500" -dictUsecase['DESCRIPTION'] = "JSON file with indices applied to a string (inside lists and inside dictionaries)" +dictUsecase['DESCRIPTION'] = "JSON file with indices applied to a string (inside lists and inside dictionaries; standard notation)" +dictUsecase['EXPECTATION'] = "JsonPreprocessor returns expected value" +dictUsecase['SECTION'] = "STRING_INDICES" +dictUsecase['SUBSECTION'] = "GOODCASE" +dictUsecase['HINT'] = None +dictUsecase['COMMENT'] = None +dictUsecase['JSONFILE'] = r"..\testfiles\jpp-test_config_1500.jsonp" # partially commented out +dictUsecase['EXPECTEDEXCEPTION'] = None +dictUsecase['EXPECTEDRETURN'] = """ +[DICT] (8/1) > {stringParam} [STR] : 'ABCDE' +[DICT] (8/2) > {index} [INT] : 1 +[DICT] (8/3) > {indexList} [LIST] (3/1) > [INT] : 0 +[DICT] (8/3) > {indexList} [LIST] (3/2) > [INT] : 1 +[DICT] (8/3) > {indexList} [LIST] (3/3) > [INT] : 2 +[DICT] (8/4) > {indexDict} [DICT] (3/1) > {A} [INT] : 0 +[DICT] (8/4) > {indexDict} [DICT] (3/2) > {B} [INT] : 1 +[DICT] (8/4) > {indexDict} [DICT] (3/3) > {C} [INT] : 2 +[DICT] (8/5) > {keyList} [LIST] (3/1) > [STR] : 'A' +[DICT] (8/5) > {keyList} [LIST] (3/2) > [STR] : 'B' +[DICT] (8/5) > {keyList} [LIST] (3/3) > [STR] : 'C' +[DICT] (8/6) > {param01} [STR] : 'B' +[DICT] (8/7) > {param02} [STR] : 'B' +[DICT] (8/8) > {param04} [STR] : '1' +""" +listofdictUsecases.append(dictUsecase) +del dictUsecase +# -------------------------------------------------------------------------------------------------------------- +# +# https://github.com/test-fullautomation/python-jsonpreprocessor/issues/268 +# +dictUsecase = {} +dictUsecase['TESTID'] = "JPP_1501" +dictUsecase['DESCRIPTION'] = "JSON file with indices applied to a string (inside lists and inside dictionaries; dotdict notation)" dictUsecase['EXPECTATION'] = "JsonPreprocessor returns expected value" dictUsecase['SECTION'] = "STRING_INDICES" dictUsecase['SUBSECTION'] = "GOODCASE" dictUsecase['HINT'] = None dictUsecase['COMMENT'] = None -dictUsecase['JSONFILE'] = r"..\testfiles\jpp-test_config_1500.jsonp" +dictUsecase['JSONFILE'] = r"..\testfiles\jpp-test_config_1501.jsonp" # partially commented out dictUsecase['EXPECTEDEXCEPTION'] = None dictUsecase['EXPECTEDRETURN'] = """ -[DICT] (17/1) > {stringParam} [STR] : 'ABCDE' -[DICT] (17/2) > {index} [INT] : 1 -[DICT] (17/3) > {indexList} [LIST] (3/1) > [INT] : 0 -[DICT] (17/3) > {indexList} [LIST] (3/2) > [INT] : 1 -[DICT] (17/3) > {indexList} [LIST] (3/3) > [INT] : 2 -[DICT] (17/4) > {indexDict} [DICT] (3/1) > {A} [INT] : 0 -[DICT] (17/4) > {indexDict} [DICT] (3/2) > {B} [INT] : 1 -[DICT] (17/4) > {indexDict} [DICT] (3/3) > {C} [INT] : 2 -[DICT] (17/5) > {keyList} [LIST] (3/1) > [STR] : 'A' -[DICT] (17/5) > {keyList} [LIST] (3/2) > [STR] : 'B' -[DICT] (17/5) > {keyList} [LIST] (3/3) > [STR] : 'C' -[DICT] (17/6) > {param01} [STR] : 'B' -[DICT] (17/7) > {param02} [STR] : 'B' -[DICT] (17/8) > {param03} [STR] : 'B' -[DICT] (17/9) > {param04} [STR] : 'B' -[DICT] (17/10) > {param05} [LIST] (2/1) > [STR] : 'B' -[DICT] (17/10) > {param05} [LIST] (2/2) > [STR] : 'D' -[DICT] (17/11) > {param06} [LIST] (2/1) > [STR] : 'B' -[DICT] (17/11) > {param06} [LIST] (2/2) > [STR] : 'D' -[DICT] (17/12) > {param07} [LIST] (2/1) > [STR] : 'B' -[DICT] (17/12) > {param07} [LIST] (2/2) > [STR] : 'D' -[DICT] (17/13) > {param08} [LIST] (2/1) > [STR] : 'B' -[DICT] (17/13) > {param08} [LIST] (2/2) > [STR] : 'D' -[DICT] (17/14) > {param09} [DICT] (1/1) > {kA} [STR] : 'B' -[DICT] (17/15) > {param10} [DICT] (1/1) > {kA} [LIST] (2/1) > [STR] : 'B' -[DICT] (17/15) > {param10} [DICT] (1/1) > {kA} [LIST] (2/2) > [STR] : 'D' -[DICT] (17/16) > {param11} [DICT] (1/1) > {kA} [LIST] (2/1) > [STR] : 'B' -[DICT] (17/16) > {param11} [DICT] (1/1) > {kA} [LIST] (2/2) > [STR] : 'D' -[DICT] (17/17) > {param12} [DICT] (1/1) > {kA} [LIST] (2/1) > [STR] : 'B' -[DICT] (17/17) > {param12} [DICT] (1/1) > {kA} [LIST] (2/2) > [STR] : 'D' +[DICT] (9/1) > {stringParam} [STR] : 'ABCDE' +[DICT] (9/2) > {index} [INT] : 1 +[DICT] (9/3) > {indexList} [LIST] (3/1) > [INT] : 0 +[DICT] (9/3) > {indexList} [LIST] (3/2) > [INT] : 1 +[DICT] (9/3) > {indexList} [LIST] (3/3) > [INT] : 2 +[DICT] (9/4) > {indexDict} [DICT] (3/1) > {A} [INT] : 0 +[DICT] (9/4) > {indexDict} [DICT] (3/2) > {B} [INT] : 1 +[DICT] (9/4) > {indexDict} [DICT] (3/3) > {C} [INT] : 2 +[DICT] (9/5) > {keyList} [LIST] (3/1) > [STR] : 'A' +[DICT] (9/5) > {keyList} [LIST] (3/2) > [STR] : 'B' +[DICT] (9/5) > {keyList} [LIST] (3/3) > [STR] : 'C' +[DICT] (9/6) > {param02} [STR] : 'B' +[DICT] (9/7) > {param04} [STR] : '1' +[DICT] (9/8) > {param06} [STR] : 'B' +[DICT] (9/9) > {param08} [STR] : 'B' """ listofdictUsecases.append(dictUsecase) del dictUsecase @@ -3346,7 +3367,6 @@ del dictUsecase # -------------------------------------------------------------------------------------------------------------- # -------------------------------------------------------------------------------------------------------------- -# https://github.com/test-fullautomation/python-jsonpreprocessor/issues/214 dictUsecase = {} dictUsecase['TESTID'] = "JPP_1900" dictUsecase['DESCRIPTION'] = "JSON file with dictionary assignments (by reference)" diff --git a/test/testfiles/jpp-test_config_1500.jsonp b/test/testfiles/jpp-test_config_1500.jsonp index 3db0073d..2bd5e94f 100644 --- a/test/testfiles/jpp-test_config_1500.jsonp +++ b/test/testfiles/jpp-test_config_1500.jsonp @@ -13,6 +13,9 @@ // limitations under the License. //************************************************************************** +// https://github.com/test-fullautomation/python-jsonpreprocessor/issues/269 +// https://github.com/test-fullautomation/python-jsonpreprocessor/issues/253 + { "stringParam" : "ABCDE", // @@ -22,17 +25,40 @@ "keyList" : ["A", "B", "C"], // "param01" : ${stringParam}[${index}], - "param02" : ${stringParam}[${indexList}[${index}]], - "param03" : ${stringParam}[${indexList}[${indexList}[${index}]]], - "param04" : ${stringParam}[${indexDict}[${keyList}[${indexList}[${index}]]]], - // - "param05" : [${stringParam}[${index}], "D"], - "param06" : [${stringParam}[${indexList}[${index}]], "D"], - "param07" : [${stringParam}[${indexList}[${indexList}[${index}]]], "D"], - "param08" : [${stringParam}[${indexDict}[${keyList}[${indexList}[${index}]]]], "D"], - // - "param09" : {"kA" : ${stringParam}[${index}]}, - "param10" : {"kA" : [${stringParam}[${index}], "D"]}, - "param11" : {"kA" : [${stringParam}[${indexList}[${index}]], "D"]}, - "param12" : {"kA" : [${stringParam}[${indexList}[${indexList}[${index}]]], "D"]} + "param02" : "${stringParam}[${index}]", + // + // "param03" : ${indexList}[${indexList}[${index}]], // returns STR instead of INT + "param04" : "${indexList}[${indexList}[${index}]]" + // + // --> several errors (invalid param, missing delimiter): + // + // "param05" : ${stringParam}[${indexList}[${indexList}[${index}]], + // "param06" : "${stringParam}[${indexList}[${indexList}[${index}]]", + // + // "param07" : ${stringParam}[${indexDict}[${keyList}[${indexList}[${index}]]]], + // "param08" : "${stringParam}[${indexDict}[${keyList}[${indexList}[${index}]]]]", + // + // the same within lists + // "param10" : [${stringParam}[${index}], "${stringParam}[${index}]"], + // "param11" : [${indexList}[${indexList}[${index}]]], "${indexList}[${indexList}[${index}]]"], + // "param12" : [${stringParam}[${indexList}[${indexList}[${index}]]], "${stringParam}[${indexList}[${indexList}[${index}]]]"], + // "param13" : [${stringParam}[${indexDict}[${keyList}[${indexList}[${index}]]]], "${stringParam}[${indexDict}[${keyList}[${indexList}[${index}]]]]"], + // + // the same within dictionaries + // "param20" : {"k20A" : ${stringParam}[${index}], + // "k20B" : "${stringParam}[${index}]", + // "k20C" : ${indexList}[${indexList}[${index}]], + // "k20D" : "${indexList}[${indexList}[${index}]]", + // "k20E" : ${stringParam}[${indexList}[${indexList}[${index}]]], + // "k20F" : "${stringParam}[${indexList}[${indexList}[${index}]]]", + // "k20G" : ${stringParam}[${indexDict}[${keyList}[${indexList}[${index}]]]], + // "k20H" : "${stringParam}[${indexDict}[${keyList}[${indexList}[${index}]]]]"} + // + // the same with lists as dictionay key values + // "param21" : {"k21A" : [${stringParam}[${index}], "${stringParam}[${index}]"], + // "k21B" : [${indexList}[${indexList}[${index}]], "${indexList}[${indexList}[${index}]]"], + // "k21C" : [${stringParam}[${indexList}[${indexList}[${index}]]], "${stringParam}[${indexList}[${indexList}[${index}]]]"], + // "k21D" : [${stringParam}[${indexDict}[${keyList}[${indexList}[${index}]]]], "${stringParam}[${indexDict}[${keyList}[${indexList}[${index}]]]]"]} } + + diff --git a/test/testfiles/jpp-test_config_1501.jsonp b/test/testfiles/jpp-test_config_1501.jsonp new file mode 100644 index 00000000..318603c8 --- /dev/null +++ b/test/testfiles/jpp-test_config_1501.jsonp @@ -0,0 +1,61 @@ +// Copyright 2020-2024 Robert Bosch GmbH +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//************************************************************************** +// +// https://github.com/test-fullautomation/python-jsonpreprocessor/issues/268 +// +// All combinations should be valid. Combinations with quotes work, combinations without quotes throw errors. +// +{ + "stringParam" : "ABCDE", + // + "index" : 1, + "indexList" : [0,1,2], + "indexDict" : {"A" : 0, "B" : 1, "C" : 2}, + "keyList" : ["A", "B", "C"], + // + // "param01" : ${stringParam.${index}}, // 'Invalid expression found: '${stringParam.${index}}'.'! + "param02" : "${stringParam.${index}}", // {param02} [STR] : 'B' (like expected) + // + // "param03" : ${indexList.${indexList.${index}}}, // Expecting value: line 7 column 16 (char 179)'! / reference: ${stringParam}[${indexList}[${index}]] + "param04" : "${indexList.${indexList.${index}}}", // {param03} [STR] : '1' (like expected) + // + // "param05" : ${stringParam.${indexList.${indexList.${index}}}}, // Expecting value: line 7 column 16 (char 179)'! + "param06" : "${stringParam.${indexList.${indexList.${index}}}}", // {param05} [STR] : 'B' (like expected) + // + // "param07" : ${stringParam.${indexDict.${keyList.${indexList.${index}}}}}, // Expecting value: line 7 column 16 (char 179)'! + "param08" : "${stringParam.${indexDict.${keyList.${indexList.${index}}}}}" // {param07} [STR] : 'B' (like expected) + // + // the same within lists + // "param10" : [${stringParam.${index}}, "${stringParam.${index}}"], + // "param11" : [${indexList.${indexList.${index}}}, "${indexList.${indexList.${index}}}"], + // "param12" : [${stringParam.${indexList.${indexList.${index}}}}, "${stringParam.${indexList.${indexList.${index}}}}"], + // "param13" : [${stringParam.${indexDict.${keyList.${indexList.${index}}}}}, "${stringParam.${indexDict.${keyList.${indexList.${index}}}}}"], + // + // the same within dictionaries + // "param20" : {"k20A" : ${stringParam.${index}}, + // "k20B" : "${stringParam.${index}}", + // "k20C" : ${indexList.${indexList.${index}}}, + // "k20D" : "${indexList.${indexList.${index}}}", + // "k20E" : ${stringParam.${indexList.${indexList.${index}}}}, + // "k20F" : "${stringParam.${indexList.${indexList.${index}}}}", + // "k20G" : ${stringParam.${indexDict.${keyList.${indexList.${index}}}}}, + // "k20H" : "${stringParam.${indexDict.${keyList.${indexList.${index}}}}}"}, + // + // the same with lists as dictionay key values + // "param21" : {"k21A" : [${stringParam.${index}}, "${stringParam.${index}}"], + // "k21B" : [${indexList.${indexList.${index}}}, "${indexList.${indexList.${index}}}"], + // "k21C" : [${stringParam.${indexList.${indexList.${index}}}}, "${stringParam.${indexList.${indexList.${index}}}}"], + // "k21D" : [${stringParam.${indexDict.${keyList.${indexList.${index}}}}}, "${stringParam.${indexDict.${keyList.${indexList.${index}}}}}"]} +} diff --git a/test/testfiles/jpp-test_config_1900.jsonp b/test/testfiles/jpp-test_config_1900.jsonp index 6a3d5cf3..a76880be 100644 --- a/test/testfiles/jpp-test_config_1900.jsonp +++ b/test/testfiles/jpp-test_config_1900.jsonp @@ -14,8 +14,6 @@ //************************************************************************** { - // https://github.com/test-fullautomation/python-jsonpreprocessor/issues/214 - // ${testdict1.subKey1.subKey2} : 1, "testdict2" : ${testdict1}, ${testdict2.subKey1.subKey2} : 2,