diff --git a/test/JPP_TestUsecases.csv b/test/JPP_TestUsecases.csv index 128e0e46..33d21733 100644 --- a/test/JPP_TestUsecases.csv +++ b/test/JPP_TestUsecases.csv @@ -3,6 +3,7 @@ TESTID|SECTION|SUBSECTION|DESCRIPTION JPP_0001|DATA_TYPES|GOODCASE|JSON file with parameters of different data types (basic and composite) JPP_0002|DATA_TYPES|GOODCASE|JSON file containing parameters with dollar operator syntax at right hand side of colon, basic data types JPP_0003|DATA_TYPES|GOODCASE|JSON file containing parameters with dollar operator syntax at right hand side of colon, composite data type: list +JPP_0004|DATA_TYPES|GOODCASE|JSON file containing parameters with dollar operator syntax at right hand side of colon, composite data type: dict JPP_0005|DATA_TYPES|GOODCASE|JSON file with string values containing dollar operators JPP_0100|DATA_INTEGRITY|GOODCASE|JSON file is empty (single pair of brackets only) JPP_0101|DATA_INTEGRITY|GOODCASE|JSON file with string containing several separator characters and blanks; no parameters @@ -35,6 +36,7 @@ JPP_0264|PARAMETER_SUBSTITUTION|BADCASE|JSON file with list parameter substituti JPP_0265|PARAMETER_SUBSTITUTION|BADCASE|JSON file with list parameter substitution in key name (composite data types not allowed in names) / (2) JPP_0266|PARAMETER_SUBSTITUTION|BADCASE|JSON file with dictionary parameter substitution in key name (composite data types not allowed in names) / (1) JPP_0267|PARAMETER_SUBSTITUTION|BADCASE|JSON file with dictionary parameter substitution in key name (composite data types not allowed in names) / (2) +JPP_0268|PARAMETER_SUBSTITUTION|BADCASE|JSON file containing a list; list index is defined by a parameter and wrapped in single quotes JPP_0300|VALUE_DETECTION|GOODCASE|JSON file with parameter of type 'list' / index (in square brackets) defined outside the curly brackets (valid syntax) JPP_0301|VALUE_DETECTION|GOODCASE|JSON file with expression containing more closing elements '}' than opening elements '${' (valid syntax) JPP_0302|VALUE_DETECTION|GOODCASE|JSON file with expression starting with '${' and ending with '}' / no further matching '${' and '}' in between (valid syntax) diff --git a/test/JPP_TestUsecases.html b/test/JPP_TestUsecases.html index 0d6a24ac..940fe1ce 100644 --- a/test/JPP_TestUsecases.html +++ b/test/JPP_TestUsecases.html @@ -133,6 +133,39 @@ 4 + + + +JPP_0004 + + + + +DATA_TYPES + + + + +GOODCASE + + + + +JSON file containing parameters with dollar operator syntax at right hand side of colon, composite data type: dict
+Expected: All parameters referenced by dollar operator are resolved correctly, with their correct data types + + +
+ + + + + + + +5 + + @@ -163,7 +196,7 @@ -5 +6 @@ -196,7 +229,7 @@ -6 +7 @@ -229,7 +262,7 @@ -7 +8 @@ -262,7 +295,7 @@ -8 +9 @@ -295,7 +328,7 @@ -9 +10 @@ -328,7 +361,7 @@ -10 +11 @@ -361,7 +394,7 @@ -11 +12 @@ -394,7 +427,7 @@ -12 +13 @@ -427,7 +460,7 @@ -13 +14 @@ -460,7 +493,7 @@ -14 +15 @@ -493,7 +526,7 @@ -15 +16 @@ -526,7 +559,7 @@ -16 +17 @@ -559,7 +592,7 @@ -17 +18 @@ -592,7 +625,7 @@ -18 +19 @@ -625,7 +658,7 @@ -19 +20 @@ -658,7 +691,7 @@ -20 +21 @@ -691,7 +724,7 @@ -21 +22 @@ -724,7 +757,7 @@ -22 +23 @@ -757,7 +790,7 @@ -23 +24 @@ -790,7 +823,7 @@ -24 +25 @@ -823,7 +856,7 @@ -25 +26 @@ -856,7 +889,7 @@ -26 +27 @@ -889,7 +922,7 @@ -27 +28 @@ -922,7 +955,7 @@ -28 +29 @@ -955,7 +988,7 @@ -29 +30 @@ -988,7 +1021,7 @@ -30 +31 @@ -1021,7 +1054,7 @@ -31 +32 @@ -1054,7 +1087,7 @@ -32 +33 @@ -1087,7 +1120,7 @@ -33 +34 @@ -1120,7 +1153,7 @@ -34 +35 @@ -1153,7 +1186,7 @@ -35 +36 @@ -1186,7 +1219,41 @@ -36 +37 + + + + + +JPP_0268 + + + + +PARAMETER_SUBSTITUTION + + + + +BADCASE + + + + +JSON file containing a list; list index is defined by a parameter and wrapped in single quotes
+Expected: No values are returned, and JsonPreprocessor throws an exception + +
+List indices must be of type 'int' +
+ + + + + + + +38 @@ -1220,7 +1287,7 @@ -37 +39 @@ -1254,7 +1321,7 @@ -38 +40 @@ -1288,7 +1355,7 @@ -39 +41 @@ -1322,7 +1389,7 @@ -40 +42 @@ -1356,7 +1423,7 @@ -41 +43 @@ -1390,7 +1457,7 @@ -42 +44 @@ -1424,7 +1491,7 @@ -43 +45 @@ -1458,7 +1525,7 @@ -44 +46 @@ -1492,7 +1559,7 @@ -45 +47 @@ -1526,7 +1593,7 @@ -46 +48 @@ -1560,7 +1627,7 @@ -47 +49 @@ -1594,7 +1661,7 @@ -48 +50 @@ -1628,7 +1695,7 @@ -49 +51 @@ -1662,7 +1729,7 @@ -50 +52 @@ -1696,7 +1763,7 @@ -51 +53 @@ -1730,7 +1797,7 @@ -52 +54 @@ -1764,7 +1831,7 @@ -53 +55 @@ -1798,7 +1865,7 @@ -54 +56 @@ -1832,7 +1899,7 @@ -55 +57 @@ -1866,7 +1933,7 @@ -56 +58 @@ -1900,7 +1967,7 @@ -57 +59 @@ -1934,7 +2001,7 @@ -58 +60 @@ -1968,7 +2035,7 @@ -59 +61 @@ -2002,7 +2069,7 @@ -60 +62 @@ -2036,7 +2103,7 @@ -61 +63 @@ -2070,7 +2137,7 @@ -62 +64 @@ -2104,7 +2171,7 @@ -63 +65 @@ -2138,7 +2205,7 @@ -64 +66 @@ -2172,7 +2239,7 @@ -65 +67 @@ -2206,7 +2273,7 @@ -66 +68 @@ -2239,7 +2306,7 @@ -67 +69 @@ -2272,7 +2339,7 @@ -68 +70 @@ -2305,7 +2372,7 @@ -69 +71 @@ -2338,7 +2405,7 @@ -70 +72 @@ -2371,7 +2438,7 @@ -71 +73 @@ -2404,7 +2471,7 @@ -72 +74 @@ -2437,7 +2504,7 @@ -73 +75 @@ -2470,7 +2537,7 @@ -74 +76 @@ -2503,7 +2570,7 @@ -75 +77 @@ -2536,7 +2603,7 @@ -76 +78 @@ -2569,7 +2636,7 @@ -77 +79 @@ -2602,7 +2669,7 @@ -78 +80 @@ -2635,7 +2702,7 @@ -79 +81 @@ -2669,7 +2736,7 @@ -80 +82 @@ -2703,7 +2770,7 @@ -81 +83 @@ -2736,7 +2803,7 @@ -82 +84 @@ -2769,7 +2836,7 @@ -83 +85 @@ -2802,7 +2869,7 @@ -84 +86 @@ -2835,7 +2902,7 @@ -85 +87 @@ -2868,7 +2935,7 @@ -86 +88 @@ -2901,7 +2968,7 @@ -87 +89 @@ -2934,7 +3001,7 @@ -88 +90 @@ -2967,7 +3034,7 @@ -89 +91 @@ -3000,7 +3067,7 @@ -90 +92 @@ -3033,7 +3100,7 @@ -91 +93 @@ -3066,7 +3133,7 @@ -92 +94 @@ -3099,7 +3166,7 @@ -93 +95 @@ -3132,7 +3199,7 @@ -94 +96 @@ -3165,7 +3232,7 @@ -95 +97 @@ -3198,7 +3265,7 @@ -96 +98 @@ -3231,7 +3298,7 @@ -97 +99 @@ -3264,7 +3331,7 @@ -98 +100 @@ -3297,7 +3364,7 @@ -99 +101 @@ -3330,7 +3397,7 @@ -100 +102 @@ -3363,7 +3430,7 @@ -101 +103 @@ -3396,7 +3463,7 @@ -102 +104 @@ -3429,7 +3496,7 @@ -103 +105 @@ -3462,7 +3529,7 @@ -104 +106 @@ -3495,7 +3562,7 @@ -105 +107 @@ -3528,7 +3595,7 @@ -106 +108 @@ -3562,7 +3629,7 @@
 

-
Generated: 07.03.2024 - 14:58:30
+
Generated: 14.03.2024 - 15:46:24
 
diff --git a/test/JPP_TestUsecases.rst b/test/JPP_TestUsecases.rst index 6df52fa5..49398c3b 100644 --- a/test/JPP_TestUsecases.rst +++ b/test/JPP_TestUsecases.rst @@ -45,6 +45,16 @@ Test Use Cases ---- +* **Test JPP_0004** + + [DATA_TYPES / GOODCASE] + + **JSON file containing parameters with dollar operator syntax at right hand side of colon, composite data type: dict** + + Expected: All parameters referenced by dollar operator are resolved correctly, with their correct data types + +---- + * **Test JPP_0005** [DATA_TYPES / GOODCASE] @@ -365,6 +375,18 @@ Test Use Cases ---- +* **Test JPP_0268** + + [PARAMETER_SUBSTITUTION / BADCASE] + + **JSON file containing a list; list index is defined by a parameter and wrapped in single quotes** + + Expected: No values are returned, and JsonPreprocessor throws an exception + + *Hint: List indices must be of type 'int'* + +---- + * **Test JPP_0300** [VALUE_DETECTION / GOODCASE] @@ -1141,5 +1163,5 @@ Test Use Cases ---- -Generated: 07.03.2024 - 14:58:30 +Generated: 14.03.2024 - 15:46:24 diff --git a/test/JPP_TestUsecases.txt b/test/JPP_TestUsecases.txt index cbb9dd45..3015ab33 100644 --- a/test/JPP_TestUsecases.txt +++ b/test/JPP_TestUsecases.txt @@ -27,6 +27,10 @@ Test JPP_0003 / DATA_TYPES / GOODCASE Description: JSON file containing parameters with dollar operator syntax at right hand side of colon, composite data type: list Expectation: All parameters referenced by dollar operator are resolved correctly, with their correct data types ------------------------------------------------------------------------------------------------------------------------ +Test JPP_0004 / DATA_TYPES / GOODCASE +Description: JSON file containing parameters with dollar operator syntax at right hand side of colon, composite data type: dict +Expectation: All parameters referenced by dollar operator are resolved correctly, with their correct data types +------------------------------------------------------------------------------------------------------------------------ Test JPP_0005 / DATA_TYPES / GOODCASE Description: JSON file with string values containing dollar operators Expectation: All parameters referenced by dollar operator are resolved correctly, outcome is a string containing the values of all referenced parameters @@ -155,6 +159,11 @@ Test JPP_0267 / PARAMETER_SUBSTITUTION / BADCASE Description: JSON file with dictionary parameter substitution in key name (composite data types not allowed in names) / (2) Expectation: No values are returned, and JsonPreprocessor throws an exception ------------------------------------------------------------------------------------------------------------------------ +Test JPP_0268 / PARAMETER_SUBSTITUTION / BADCASE +Description: JSON file containing a list; list index is defined by a parameter and wrapped in single quotes +Expectation: No values are returned, and JsonPreprocessor throws an exception +Hint.......: List indices must be of type 'int' +------------------------------------------------------------------------------------------------------------------------ Test JPP_0300 / VALUE_DETECTION / GOODCASE Description: JSON file with parameter of type 'list' / index (in square brackets) defined outside the curly brackets (valid syntax) Expectation: JsonPreprocessor returns values @@ -472,5 +481,5 @@ Description: Relative path to JSON file Expectation: JsonPreprocessor resolves the relative path and returns values from JSON file Hint.......: Works with raw path to JSON file (path not normalized internally) ------------------------------------------------------------------------------------------------------------------------ -Generated: 07.03.2024 - 14:58:30 +Generated: 14.03.2024 - 15:46:24 diff --git a/test/component_test.py b/test/component_test.py index 07c4b497..cedf4cc5 100644 --- a/test/component_test.py +++ b/test/component_test.py @@ -1,6 +1,6 @@ # ************************************************************************************************************** # -# Copyright 2020-2023 Robert Bosch GmbH +# 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. @@ -18,12 +18,12 @@ # # component_test.py # -# XC-CT/ECA3-Queckenstedt +# XC-HWP/ESW3-Queckenstedt # # -------------------------------------------------------------------------------------------------------------- # -VERSION = "0.28.0" -VERSION_DATE = "07.03.2024" +VERSION = "0.29.0" +VERSION_DATE = "14.03.2024" # # -------------------------------------------------------------------------------------------------------------- #TM*** diff --git a/test/libs/CCodePatterns.py b/test/libs/CCodePatterns.py index 80729ccd..1bdef07a 100644 --- a/test/libs/CCodePatterns.py +++ b/test/libs/CCodePatterns.py @@ -1,6 +1,6 @@ # ************************************************************************************************************** # -# Copyright 2020-2023 Robert Bosch GmbH +# 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. @@ -18,7 +18,7 @@ # # CCodePatterns.py # -# XC-CT/ECA3-Queckenstedt +# XC-HWP/ESW3-Queckenstedt # # 24.03.2023 # diff --git a/test/libs/CConfig.py b/test/libs/CConfig.py index b8a6ea9d..a1f79ffb 100644 --- a/test/libs/CConfig.py +++ b/test/libs/CConfig.py @@ -1,6 +1,6 @@ # ************************************************************************************************************** # -# Copyright 2020-2023 Robert Bosch GmbH +# 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. @@ -18,7 +18,7 @@ # # CConfig.py # -# XC-CT/ECA3-Queckenstedt +# XC-HWP/ESW3-Queckenstedt # # 13.09.2023 # diff --git a/test/libs/CGenCode.py b/test/libs/CGenCode.py index d40d3930..422bb123 100644 --- a/test/libs/CGenCode.py +++ b/test/libs/CGenCode.py @@ -1,6 +1,6 @@ # ************************************************************************************************************** # -# Copyright 2020-2023 Robert Bosch GmbH +# 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. @@ -18,7 +18,7 @@ # # CGenCode.py # -# XC-CT/ECA3-Queckenstedt +# XC-HWP/ESW3-Queckenstedt # # 27.09.2023 # diff --git a/test/pytest/pytestfiles/test_01_DATA_TYPES_GOODCASE.py b/test/pytest/pytestfiles/test_01_DATA_TYPES_GOODCASE.py index 7700bea0..e83f6412 100644 --- a/test/pytest/pytestfiles/test_01_DATA_TYPES_GOODCASE.py +++ b/test/pytest/pytestfiles/test_01_DATA_TYPES_GOODCASE.py @@ -18,7 +18,7 @@ # # XC-CT/ECA3-Queckenstedt # -# 10.10.2023 - 13:31:11 +# 14.03.2024 - 15:46:24 # # -------------------------------------------------------------------------------------------------------------- @@ -53,6 +53,14 @@ def test_JPP_0002(self, Description): def test_JPP_0003(self, Description): nReturn = CExecute.Execute("JPP_0003") assert nReturn == 0 +# -------------------------------------------------------------------------------------------------------------- + # Expected: All parameters referenced by dollar operator are resolved correctly, with their correct data types + @pytest.mark.parametrize( + "Description", ["JSON file containing parameters with dollar operator syntax at right hand side of colon, composite data type: dict",] + ) + def test_JPP_0004(self, Description): + nReturn = CExecute.Execute("JPP_0004") + assert nReturn == 0 # -------------------------------------------------------------------------------------------------------------- # Expected: All parameters referenced by dollar operator are resolved correctly, outcome is a string containing the values of all referenced parameters @pytest.mark.parametrize( diff --git a/test/pytest/pytestfiles/test_04_PARAMETER_SUBSTITUTION_BADCASE.py b/test/pytest/pytestfiles/test_04_PARAMETER_SUBSTITUTION_BADCASE.py index 56b853f7..94bf9df2 100644 --- a/test/pytest/pytestfiles/test_04_PARAMETER_SUBSTITUTION_BADCASE.py +++ b/test/pytest/pytestfiles/test_04_PARAMETER_SUBSTITUTION_BADCASE.py @@ -18,7 +18,7 @@ # # XC-CT/ECA3-Queckenstedt # -# 24.01.2024 - 13:56:16 +# 14.03.2024 - 15:46:24 # # -------------------------------------------------------------------------------------------------------------- @@ -173,4 +173,12 @@ def test_JPP_0266(self, Description): def test_JPP_0267(self, Description): nReturn = CExecute.Execute("JPP_0267") assert nReturn == 0 +# -------------------------------------------------------------------------------------------------------------- + # Expected: No values are returned, and JsonPreprocessor throws an exception + @pytest.mark.parametrize( + "Description", ["JSON file containing a list; list index is defined by a parameter and wrapped in single quotes",] + ) + def test_JPP_0268(self, Description): + nReturn = CExecute.Execute("JPP_0268") + assert nReturn == 0 # -------------------------------------------------------------------------------------------------------------- diff --git a/test/testconfig/TestConfig.py b/test/testconfig/TestConfig.py index f5623e04..8cac0685 100644 --- a/test/testconfig/TestConfig.py +++ b/test/testconfig/TestConfig.py @@ -1,6 +1,6 @@ # ************************************************************************************************************** # -# Copyright 2020-2023 Robert Bosch GmbH +# 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. @@ -18,11 +18,11 @@ # # TestConfig.py # -# XC-CT/ECA3-Queckenstedt +# XC-HWP/ESW3-Queckenstedt # # -------------------------------------------------------------------------------------------------------------- # -# 07.03.2024 +# 14.03.2024 # # !!! Temporarily tests are deactivated by the following line commented out: # # # listofdictUsecases.append(dictUsecase) @@ -446,40 +446,40 @@ [DICT] (53/53) > {param_103} [DICT] (51/17) > {key_17} [STR] : 'None' [DICT] (53/53) > {param_103} [DICT] (51/18) > {key_18} [STR] : 'string' [DICT] (53/53) > {param_103} [DICT] (51/19) > {key_19} [STR] : 'string' -[DICT] (53/53) > {param_103} [DICT] (51/20) > {key_20} [INT] : 123 +[DICT] (53/53) > {param_103} [DICT] (51/20) > {key_20} [STR] : '123' [DICT] (53/53) > {param_103} [DICT] (51/21) > {key_21} [STR] : '123' [DICT] (53/53) > {param_103} [DICT] (51/22) > {key_22} [STR] : '123' [DICT] (53/53) > {param_103} [DICT] (51/23) > {key_23} [STR] : '123' -[DICT] (53/53) > {param_103} [DICT] (51/24) > {key_24} [FLOAT] : 4.56 +[DICT] (53/53) > {param_103} [DICT] (51/24) > {key_24} [STR] : '4.56' [DICT] (53/53) > {param_103} [DICT] (51/25) > {key_25} [STR] : '4.56' [DICT] (53/53) > {param_103} [DICT] (51/26) > {key_26} [STR] : '4.56' [DICT] (53/53) > {param_103} [DICT] (51/27) > {key_27} [STR] : '4.56' -[DICT] (53/53) > {param_103} [DICT] (51/28) > {key_28} [BOOL] : True -[DICT] (53/53) > {param_103} [DICT] (51/29) > {key_29} [STR] : 'true' +[DICT] (53/53) > {param_103} [DICT] (51/28) > {key_28} [STR] : 'True' +[DICT] (53/53) > {param_103} [DICT] (51/29) > {key_29} [STR] : 'True' [DICT] (53/53) > {param_103} [DICT] (51/30) > {key_30} [STR] : 'true' [DICT] (53/53) > {param_103} [DICT] (51/31) > {key_31} [STR] : 'true' -[DICT] (53/53) > {param_103} [DICT] (51/32) > {key_32} [BOOL] : False -[DICT] (53/53) > {param_103} [DICT] (51/33) > {key_33} [STR] : 'false' +[DICT] (53/53) > {param_103} [DICT] (51/32) > {key_32} [STR] : 'False' +[DICT] (53/53) > {param_103} [DICT] (51/33) > {key_33} [STR] : 'False' [DICT] (53/53) > {param_103} [DICT] (51/34) > {key_34} [STR] : 'false' [DICT] (53/53) > {param_103} [DICT] (51/35) > {key_35} [STR] : 'false' -[DICT] (53/53) > {param_103} [DICT] (51/36) > {key_36} [BOOL] : None -[DICT] (53/53) > {param_103} [DICT] (51/37) > {key_37} [STR] : 'null' +[DICT] (53/53) > {param_103} [DICT] (51/36) > {key_36} [STR] : 'None' +[DICT] (53/53) > {param_103} [DICT] (51/37) > {key_37} [STR] : 'None' [DICT] (53/53) > {param_103} [DICT] (51/38) > {key_38} [STR] : 'null' [DICT] (53/53) > {param_103} [DICT] (51/39) > {key_39} [STR] : 'null' -[DICT] (53/53) > {param_103} [DICT] (51/40) > {key_40} [BOOL] : True +[DICT] (53/53) > {param_103} [DICT] (51/40) > {key_40} [STR] : 'True' [DICT] (53/53) > {param_103} [DICT] (51/41) > {key_41} [STR] : 'True' [DICT] (53/53) > {param_103} [DICT] (51/42) > {key_42} [STR] : 'True' [DICT] (53/53) > {param_103} [DICT] (51/43) > {key_43} [STR] : 'True' -[DICT] (53/53) > {param_103} [DICT] (51/44) > {key_44} [BOOL] : False +[DICT] (53/53) > {param_103} [DICT] (51/44) > {key_44} [STR] : 'False' [DICT] (53/53) > {param_103} [DICT] (51/45) > {key_45} [STR] : 'False' [DICT] (53/53) > {param_103} [DICT] (51/46) > {key_46} [STR] : 'False' [DICT] (53/53) > {param_103} [DICT] (51/47) > {key_47} [STR] : 'False' -[DICT] (53/53) > {param_103} [DICT] (51/48) > {key_48} [BOOL] : None +[DICT] (53/53) > {param_103} [DICT] (51/48) > {key_48} [STR] : 'None' [DICT] (53/53) > {param_103} [DICT] (51/49) > {key_49} [STR] : 'None' [DICT] (53/53) > {param_103} [DICT] (51/50) > {key_50} [STR] : 'None' [DICT] (53/53) > {param_103} [DICT] (51/51) > {key_51} [STR] : 'None' """ -# # # listofdictUsecases.append(dictUsecase) +listofdictUsecases.append(dictUsecase) del dictUsecase # -------------------------------------------------------------------------------------------------------------- dictUsecase = {} @@ -1290,9 +1290,9 @@ dictUsecase['HINT'] = "List indices must be of type 'int'" dictUsecase['COMMENT'] = None dictUsecase['JSONFILE'] = r"..\testfiles\jpp-test_config_0268.jsonp" -dictUsecase['EXPECTEDEXCEPTION'] = "List indices must be of type 'int' (error message placeholder)" +dictUsecase['EXPECTEDEXCEPTION'] = "The variable '${listval}['1']' is not available!" # but not the desired one; better: list incices must be of type int dictUsecase['EXPECTEDRETURN'] = None -# # # listofdictUsecases.append(dictUsecase) +listofdictUsecases.append(dictUsecase) del dictUsecase # -------------------------------------------------------------------------------------------------------------- # -------------------------------------------------------------------------------------------------------------- @@ -1737,7 +1737,7 @@ dictUsecase['JSONFILE'] = r"..\testfiles\jpp-test_config_0450.jsonp" dictUsecase['EXPECTEDEXCEPTION'] = "detected unexpected characters in parameter name (placeholder)" dictUsecase['EXPECTEDRETURN'] = None -# # # listofdictUsecases.append(dictUsecase) +# # # listofdictUsecases.append(dictUsecase) # still naming convention issue del dictUsecase # -------------------------------------------------------------------------------------------------------------- # -------------------------------------------------------------------------------------------------------------- @@ -2426,13 +2426,14 @@ dictUsecase['JSONFILE'] = r"..\testfiles\jpp-test_config_1003.jsonp" dictUsecase['EXPECTEDEXCEPTION'] = None dictUsecase['EXPECTEDRETURN'] = """ -[DICT] (7/1) > {testdict2} [DICT] (1/1) > {subKey1} [DICT] (1/1) > {subKey2} [DICT] (1/1) > {subKey3} [DICT] (1/1) > {subKey4} [INT] : 3 -[DICT] (7/2) > {param1} [STR] : 'subKey1' -[DICT] (7/3) > {param2} [STR] : 'subKey2' -[DICT] (7/4) > {param3} [STR] : 'subKey3' -[DICT] (7/5) > {param4} [STR] : 'subKey4' -[DICT] (7/6) > {param5} [INT] : 3 -[DICT] (7/7) > {testdict1} [DICT] (1/1) > {subKey1} [DICT] (1/1) > {subKey2} [DICT] (1/1) > {subKey3} [DICT] (1/1) > {subKey4} [INT] : 3 +[DICT] (8/1) > {testdict2} [DICT] (1/1) > {subKey1} [DICT] (1/1) > {subKey2} [DICT] (1/1) > {subKey3} [DICT] (1/1) > {subKey4} [INT] : 3 +[DICT] (8/2) > {param1} [STR] : 'subKey1' +[DICT] (8/3) > {param2} [STR] : 'subKey2' +[DICT] (8/4) > {param3} [STR] : 'subKey3' +[DICT] (8/5) > {param4} [STR] : 'subKey4' +[DICT] (8/6) > {param5} [INT] : 3 +[DICT] (8/7) > {param7} [STR] : '3' +[DICT] (8/8) > {testdict1} [DICT] (1/1) > {subKey1} [DICT] (1/1) > {subKey2} [DICT] (1/1) > {subKey3} [DICT] (1/1) > {subKey4} [INT] : 3 """ listofdictUsecases.append(dictUsecase) del dictUsecase diff --git a/test/testfiles/jpp-test_config_1003.jsonp b/test/testfiles/jpp-test_config_1003.jsonp index b0c5715a..22078b70 100644 --- a/test/testfiles/jpp-test_config_1003.jsonp +++ b/test/testfiles/jpp-test_config_1003.jsonp @@ -29,9 +29,10 @@ // access to implicitly created keys by parameters (dotdict notation) ${testdict2.${param1}.subKey2.${param3}.subKey4} : 3, // assign modified values to new parameters - "param5" : ${testdict1}[${param1}]['${param2}']['subKey3'][${param4}] + "param5" : ${testdict1}[${param1}]['${param2}']['subKey3'][${param4}], - // still issue: + // still issue: https://github.com/test-fullautomation/python-jsonpreprocessor/issues/232 // "param6" : ${testdict2.${param1}.subKey2.${param3}.subKey4} // Expecting value: line 11 column 15 (char 412)'! + "param7" : "${testdict2.${param1}.subKey2.${param3}.subKey4}" } diff --git a/test/testtools/GenSnippetsJPP.py b/test/testtools/GenSnippetsJPP.py new file mode 100644 index 00000000..ffc97e8f --- /dev/null +++ b/test/testtools/GenSnippetsJPP.py @@ -0,0 +1,1982 @@ +# ************************************************************************************************************** +# +# 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. +# +# ************************************************************************************************************** +# +# GenSnippetsJPP.py +# +# XC-HWP/ESW3-Queckenstedt +# +# ************************************************************************************************************** +# +VERSION = "0.11.0" +VERSION_DATE = "14.03.2024" +# +# ************************************************************************************************************** + +# History + +# ************************************************************************************************************** +# TM*** +# +# -- TOC +#[DEFCONFIG] +#[DEFCOUNTER] +#[DEFCLISTVALUES] +#[DEFLOGGER] +#[DEFEXECUTOR] +#[HTMLPATTERN] +#[CSNIPPETS] +#[INITCONFIG] +#[INITLOGGER] +#[INITCOUNTER] +#[INITJPP] +#[INITEXECUTOR] +#[STARTOFEXECUTION] +#[ENDOFEXECUTION] +# +# TM*** +# ************************************************************************************************************** + + +# -- import standard Python modules +import os, sys, shlex, subprocess, ctypes, time, platform, json, pprint, itertools +import colorama as col + +# -- import own Python modules +from PythonExtensionsCollection.String.CString import CString +from PythonExtensionsCollection.Folder.CFolder import CFolder +from PythonExtensionsCollection.File.CFile import CFile +from PythonExtensionsCollection.Utils.CUtils import * + +# -- import module under test +from JsonPreprocessor.CJsonPreprocessor import CJsonPreprocessor + +col.init(autoreset=True) + +COLBR = col.Style.BRIGHT + col.Fore.RED +COLBY = col.Style.BRIGHT + col.Fore.YELLOW +COLBG = col.Style.BRIGHT + col.Fore.GREEN +COLBB = col.Style.BRIGHT + col.Fore.BLUE + +SUCCESS = 0 +ERROR = 1 + +# -------------------------------------------------------------------------------------------------------------- + +def printfailure(sMsg, prefix=None): + if prefix is None: + sMsg = COLBR + f"{sMsg}!\n\n" + else: + sMsg = COLBR + f"{prefix}:\n{sMsg}!\n\n" + sys.stderr.write(sMsg) + + +# -------------------------------------------------------------------------------------------------------------- +#[DEFCONFIG] +# -------------------------------------------------------------------------------------------------------------- +#TM*** + +class CConfig(): + + def __init__(self, sCalledBy=None): + + sMethod = "CConfig.__init__" + + # -- configuration init + self.__dictConfig = {} + + if sCalledBy is None: + raise Exception(CString.FormatResult(sMethod, None, "sCalledBy is None")) + + THISAPP = CString.NormalizePath(sCalledBy) + self.__dictConfig['THISAPP'] = THISAPP + self.__dictConfig['THISAPPNAME'] = os.path.basename(THISAPP) + REFERENCEPATH = os.path.dirname(THISAPP) # position of main() app is reference for all relative paths + self.__dictConfig['REFERENCEPATH'] = REFERENCEPATH + self.__dictConfig['TMPFILESPATH'] = f"{REFERENCEPATH}/tmp_files" + self.__dictConfig['OUTPUTPATH'] = f"{REFERENCEPATH}" # /output + self.__dictConfig['LOGFILE'] = f"{self.__dictConfig['OUTPUTPATH']}/GenSnippetLogJPP.log" + self.__dictConfig['REPORTFILE'] = f"{self.__dictConfig['OUTPUTPATH']}/GenSnippetReportJPP.html" + self.__dictConfig['JPPJSONFILE'] = f"{self.__dictConfig['TMPFILESPATH']}/JPPSnippetFile.jsonp" + OSNAME = os.name + self.__dictConfig['OSNAME'] = OSNAME + self.__dictConfig['PLATFORMSYSTEM'] = platform.system() + PYTHON = CString.NormalizePath(sys.executable) + self.__dictConfig['PYTHON'] = PYTHON + self.__dictConfig['PYTHONPATH'] = os.path.dirname(PYTHON) + self.__dictConfig['PYTHONVERSION'] = sys.version + self.__dictConfig['NOW'] = time.strftime('%d.%m.%Y - %H:%M:%S') + + # -------------------------------------------------------------------------------------------------------------- + #TM*** + + def __del__(self): + del self.__dictConfig + + # -------------------------------------------------------------------------------------------------------------- + #TM*** + + def DumpConfig(self): + """Prints all configuration values to console.""" + listFormattedOutputLines = [] + # -- printing configuration to console + print() + # PrettyPrint(self.__dictConfig, sPrefix="Config") + nJust = 32 + for key, value in self.__dictConfig.items(): + if isinstance(value, list): + nCnt = 0 + for element in value: + nCnt = nCnt + 1 + element_cnt = f"{key} ({nCnt})" + sLine = element_cnt.rjust(nJust, ' ') + " : " + str(element) + print(sLine) + listFormattedOutputLines.append(sLine) + else: + sLine = key.rjust(nJust, ' ') + " : " + str(value) + print(sLine) + listFormattedOutputLines.append(sLine) + print() + return listFormattedOutputLines + # eof def DumpConfig(self): + + # -------------------------------------------------------------------------------------------------------------- + #TM*** + + def Get(self, sName=None): + """Returns the configuration value belonging to a key name.""" + if ( (sName is None) or (sName not in self.__dictConfig) ): + print() + printfailure(f"Configuration parameter '{sName}' not existing") + return None # returning 'None' in case of key is not existing !!! + else: + return self.__dictConfig[sName] + # eof def Get(self, sName=None): + + # -------------------------------------------------------------------------------------------------------------- + #TM*** + + def Set(self, sName=None, sValue=None): + """Sets a new configuration parameter.""" + sName = f"{sName}" + self.__dictConfig[sName] = sValue + # eof def Set(self, sName=None, sValue=None): + +# eof class CConfig(): + + +# -------------------------------------------------------------------------------------------------------------- +#[DEFCOUNTER] +# -------------------------------------------------------------------------------------------------------------- +#TM*** + +class CCounter(): + + def __init__(self, nCntSection=0,nCntSubSection=0,nCntGlobal=0): + self.__nCntSection = nCntSection + self.__nCntSubSection = nCntSubSection + self.__nCntGlobal = nCntGlobal + + def IncSection(self): + self.__nCntSection = self.__nCntSection + 1 + self.__nCntSubSection = 0 # => 'IncSection' requires a separate 'IncSubSection'; advantage: 'IncSubSection' can run separately in loop + return f"[ {self.__nCntSection}.{self.__nCntSubSection} ]" + + def IncSubSection(self): + self.__nCntSubSection = self.__nCntSubSection + 1 + self.__nCntGlobal = self.__nCntGlobal + 1 + return f"( {self.__nCntGlobal} ) - [ {self.__nCntSection}.{self.__nCntSubSection} ]" + + def GetCntString(self): + return f"( {self.__nCntGlobal} ) - [ {self.__nCntSection}.{self.__nCntSubSection} ]" + + def GetCntSection(self): + return self.__nCntSection + + def GetCntClobal(self): + return self.__nCntGlobal + +# eof class CCounter(): + + +# -------------------------------------------------------------------------------------------------------------- +#[DEFCLISTVALUES] +# -------------------------------------------------------------------------------------------------------------- +#TM*** + +class CListElements(): + + def __init__(self, listElements=[]): + self.listElements = listElements + self.nNrOfElements = len(self.listElements) + self.nCurrentIndex = 0 + + def GetElement(self): + oElement = self.listElements[self.nCurrentIndex] + self.nCurrentIndex = self.nCurrentIndex + 1 + if self.nCurrentIndex >= self.nNrOfElements: + self.nCurrentIndex = 0 + return oElement + +# eof class CListElements(): + + +# -------------------------------------------------------------------------------------------------------------- +#[DEFLOGGER] +# -------------------------------------------------------------------------------------------------------------- +#TM*** + +class CLogger(): + + def __init__(self, oConfig=None): + + sMethod = "CLogger.__init__" + + self.__oLogfile = None + self.__oReportfile = None + self.__oConfig = None + + if oConfig is None: + raise Exception(CString.FormatResult(sMethod, None, "oConfig is None")) + self.__oConfig = oConfig + + LOGFILE = self.__oConfig.Get('LOGFILE') + REPORTFILE = self.__oConfig.Get('REPORTFILE') + + self.__oLogfile = CFile(LOGFILE) + self.__oReportfile = CFile(REPORTFILE) + + def __del__(self): + del self.__oConfig + del self.__oLogfile + del self.__oReportfile + + def WriteLog(self, content=None): + if type(content) == list: + for element in content: + self.__oLogfile.Write(element) + else: + self.__oLogfile.Write(f"{content}") + + def WriteReport(self, content=None): + if type(content) == list: + for element in content: + self.__oReportfile.Write(element) + else: + self.__oReportfile.Write(f"{content}") + +# eof class CLogger(oConfig): + + +# -------------------------------------------------------------------------------------------------------------- +#[DEFEXECUTOR] +# -------------------------------------------------------------------------------------------------------------- +#TM*** + +class CExecutor(): + + def __init__(self, oConfig=None, oCounter=None, oLogger=None, oJsonPreprocessor=None): + + sMethod = "CExecutor.__init__" + + self.__oConfig = None + self.__oCounter = None + self.__oLogger = None + self.__oJsonPreprocessor = None + self.__oSnippets = None + self.__oHTMLPattern = None + + if oConfig is None: + raise Exception(CString.FormatResult(sMethod, None, "oConfig is None")) + self.__oConfig = oConfig + + if oCounter is None: + raise Exception(CString.FormatResult(sMethod, None, "oCounter is None")) + self.__oCounter = oCounter + + if oLogger is None: + raise Exception(CString.FormatResult(sMethod, None, "oLogger is None")) + self.__oLogger = oLogger + + # if defined outside CExecutor(), every JPP snippet execution works with the same oJsonPreprocessor object; + # otherwise every JPP snippet execution works with his own oJsonPreprocessor object + self.__oJsonPreprocessor = oJsonPreprocessor + + # access to code snippets (required for HTML report file) + self.__oSnippets = CSnippets() + + # access to HTML pattern (required for HTML report file) + self.__oHTMLPattern = CHTMLPattern() + + # create the tmp files folder + TMPFILESPATH = oConfig.Get('TMPFILESPATH') + oTMPFILESPATH = CFolder(TMPFILESPATH) + oTMPFILESPATH.Create(bOverwrite=False, bRecursive=True) + del oTMPFILESPATH + + #eof def __init__(self, oConfig=None, oCounter=None, oJsonPreprocessor=None): + + + def __del__(self): + del self.__oConfig + del self.__oCounter + del self.__oLogger + del self.__oJsonPreprocessor + del self.__oSnippets + del self.__oHTMLPattern + + # -------------------------------------------------------------------------------------------------------------- + + def Execute(self, sHeadline=None, listCodeSnippets=None, sType="JPP"): + + sMethod = "Execute" + + bSuccess = None + sResult = "UNKNOWN" + + if sHeadline is None: + bSuccess = None + sResult = "sHeadline is None" + sResult = CString.FormatResult(sMethod, bSuccess, sResult) + return bSuccess, sResult + + if listCodeSnippets is None: + bSuccess = None + sResult = "listCodeSnippets is None" + sResult = CString.FormatResult(sMethod, bSuccess, sResult) + return bSuccess, sResult + + if len(listCodeSnippets) == 0: + bSuccess = None + sResult = "List of code snippets is empty" + sResult = CString.FormatResult(sMethod, bSuccess, sResult) + return bSuccess, sResult + + tupleSupportedTypes = ("JPP") # , "TSM" >> TODO: enumeration type + if sType not in tupleSupportedTypes: + bSuccess = None + sResult = f"Unexpected application type '{sType}'. Expected is one of '{tupleSupportedTypes}'" + sResult = CString.FormatResult(sMethod, bSuccess, sResult) + return bSuccess, sResult + + if sType == "JPP": + bSuccess, sResult = self.__ExecuteJPPSnippets(sHeadline, listCodeSnippets) + if bSuccess is not True: + sResult = CString.FormatResult(sMethod, bSuccess, sResult) + else: + bSuccess = False + sResult = f"Types other than 'JPP' are currently not supported" + sResult = CString.FormatResult(sMethod, bSuccess, sResult) + + return bSuccess, sResult + + # eof def Execute(self, listCodeSnippets=None, sType="JPP"): + + # -------------------------------------------------------------------------------------------------------------- + + def __ExecuteJPPSnippets(self, sHeadline="UNKNOWN", listCodeSnippets=[]): + + sMethod = "__ExecuteJPPSnippets" + + bSuccess = None + sResult = "UNKNOWN" + + # increment section counter and write headline to log file and to report file + self.__oCounter.IncSection() + nSectionNumber = self.__oCounter.GetCntSection() + print(COLBY + f"{nSectionNumber}. {sHeadline}\n") + self.__oLogger.WriteLog(120*"-") + self.__oLogger.WriteLog(f"{nSectionNumber}. {sHeadline}") + self.__oLogger.WriteReport(self.__oHTMLPattern.GetHTMLHeadline1(f"{nSectionNumber}. {sHeadline}")) + self.__oLogger.WriteLog(120*"-" + "\n") + self.__oLogger.WriteReport(self.__oHTMLPattern.GetHTMLHLine()) + + for sCodeSnippet in listCodeSnippets: + # for every code snippet increment subsection counter and write current counter string to log file and to report file + self.__oCounter.IncSubSection() + print(COLBY + self.__oCounter.GetCntString() + "\n") + self.__oLogger.WriteLog(self.__oCounter.GetCntString() + "\n") + self.__oLogger.WriteReport(self.__oHTMLPattern.GetHTMLCounter(self.__oCounter.GetCntString())) + # write code snippet to log file and to report file + print(COLBG + sCodeSnippet) + self.__oLogger.WriteLog(sCodeSnippet) + self.__oLogger.WriteReport(self.__oHTMLPattern.GetHTMLSnippetCode(self.__oHTMLPattern.Txt2HTML(sCodeSnippet))) + # write code snippet to temporary JSON file for execution + NOW = self.__oConfig.Get('NOW') + JPPJSONFILE = self.__oConfig.Get('JPPJSONFILE') + oJPPJSONFILE = CFile(JPPJSONFILE) + oJPPJSONFILE.Write(f"// created at {NOW}") + oJPPJSONFILE.Write(sCodeSnippet) + del oJPPJSONFILE + # execute temporary JSON file + dictReturned, sException, bSuccess, sResult = self.__ExecuteJPPFile(JPPJSONFILE) + # PrettyPrint(bSuccess, sPrefix="(bSuccess)") + # PrettyPrint(sResult, sPrefix="(sResult)") + # PrettyPrint(dictReturned, sPrefix="(dictReturned)") + # PrettyPrint(sException, sPrefix="(sException)") + + # if available write returned value to log file and to report file + if dictReturned is not None: + listValuesReturned = PrettyPrint(dictReturned, bToConsole=True) #, sPrefix="(dictReturned)") + print() + self.__oLogger.WriteLog(listValuesReturned) + self.__oLogger.WriteLog("") + self.__oLogger.WriteReport(self.__oHTMLPattern.GetHTMLValuesReturned(self.__oHTMLPattern.Txt2HTML("\n".join(listValuesReturned)))) + + # if available write exception to log file and to report file + if sException is not None: + printfailure(sException) + self.__oLogger.WriteLog(sException) + self.__oLogger.WriteLog("") + self.__oLogger.WriteReport(self.__oHTMLPattern.GetHTMLException(self.__oHTMLPattern.Txt2HTML(sException))) + + self.__oLogger.WriteLog(120*"-" + "\n") + self.__oLogger.WriteReport(self.__oHTMLPattern.GetHTMLHLine()) + + # eof for sCodeSnippet in listCodeSnippets: + + bSuccess = True + sResult = "done" + + return bSuccess, sResult + + # -------------------------------------------------------------------------------------------------------------- + + def __ExecuteJPPFile(self, sJSONFile=None): + + sMethod = "__ExecuteJPPFile" + + bSuccess = None + sResult = "UNKNOWN" + dictReturned = None + sException = None + + if sJSONFile is None: + sResult = CString.FormatResult(sMethod, None, "sJSONFile is None") + return dictReturned, sException, bSuccess, sResult + + if not os.path.isfile(sJSONFile): + sResult = f"Input JSON file does not exist: '{sJSONFile}'" + sResult = CString.FormatResult(sMethod, None, sResult) + return dictReturned, sException, bSuccess, sResult + + # print(f"* '{sJSONFile}'") + + # use either own or common JsonPreprocessor object + oJsonPreprocessor = None + if self.__oJsonPreprocessor is None: + oJsonPreprocessor = CJsonPreprocessor() + else: + oJsonPreprocessor = self.__oJsonPreprocessor + + # execute JsonPreprocessor + dictReturned = None + sException = None + try: + dictReturned = oJsonPreprocessor.jsonLoad(sJSONFile) + except Exception as reason: + sException = f"'{reason}'" + + del oJsonPreprocessor + + bSuccess = True + sResult = "done" + return dictReturned, sException, bSuccess, sResult + + # eof def __ExecuteJPPFile(self, sJSONFile=None): + + # -------------------------------------------------------------------------------------------------------------- + +# eof class CExecutor(): + + +# -------------------------------------------------------------------------------------------------------------- +#[HTMLPATTERN] +# -------------------------------------------------------------------------------------------------------------- +#TM*** + +class CHTMLPattern(): + + sHTMLHeader = """ + + + + Code Snippets + + + +
+""" + + sHTMLFooter = """ +
###NOW###
+ + +""" + + sHTMLHLine = """ +
+""" + + sHTMLHeadline1 = """ +

###HTMLHEADLINE1###

+""" + + sHTMLHeadline2 = """ +

###HTMLHEADLINE2###

+""" + + sHTMLText = """ +

###HTMLTEXT###

+""" + + sHTMLCounter = """ +

###HTMLCOUNTER###

+""" + + sHTMLSnippetCode = """ +

###HTMLSNIPPETCODE###

+""" + + sHTMLValuesReturned = """ +

###HTMLVALUESRETURNED###

+""" + + sHTMLException = """ +

###HTMLEXCEPTION###

+""" + + + def Txt2HTML(self, sText=None): + listHTML = sText.splitlines() + listLinesHTMLindent = [] + for sLine in listHTML: + sLine = sLine.rstrip() # remove unnecessary trailing blanks + sLine = sLine.replace("<", "<") # replace HTML special characters + sLine = sLine.replace(">", ">") # replace HTML special characters + sLine = sLine.replace(" ", " ") # replace spaces by non breaking HTML spaces + listLinesHTMLindent.append(sLine) + # eof for sLine in listHTML: + print() + sHTML = "
\n".join(listLinesHTMLindent) + return sHTML + + def GetHTMLHeader(self): + return CHTMLPattern.sHTMLHeader + + def GetHTMLFooter(self, NOW=None): + sHTML = CHTMLPattern.sHTMLFooter.replace("###NOW###", f"{NOW}") + return sHTML + + def GetHTMLHLine(self): + return CHTMLPattern.sHTMLHLine + + def GetHTMLHeadline1(self, sHTML=None): + sHTML = CHTMLPattern.sHTMLHeadline1.replace("###HTMLHEADLINE1###", f"{sHTML}") + return sHTML + + def GetHTMLHeadline2(self, sHTML=None): + sHTML = CHTMLPattern.sHTMLHeadline2.replace("###HTMLHEADLINE2###", f"{sHTML}") + return sHTML + + def GetHTMLText(self, sHTML=None): + sHTML = CHTMLPattern.sHTMLText.replace("###HTMLTEXT###", f"{sHTML}") + return sHTML + + def GetHTMLCounter(self, sHTML=None): + sHTML = CHTMLPattern.sHTMLCounter.replace("###HTMLCOUNTER###", f"{sHTML}") + return sHTML + + def GetHTMLSnippetCode(self, sHTML=None): + sHTML = CHTMLPattern.sHTMLSnippetCode.replace("###HTMLSNIPPETCODE###", f"{sHTML}") + return sHTML + + def GetHTMLValuesReturned(self, sHTML=None): + sHTML = CHTMLPattern.sHTMLValuesReturned.replace("###HTMLVALUESRETURNED###", f"{sHTML}") + return sHTML + + def GetHTMLException(self, sHTML=None): + sHTML = CHTMLPattern.sHTMLException.replace("###HTMLEXCEPTION###", f"{sHTML}") + return sHTML + +# eof class CHTMLPattern(): + + +# -------------------------------------------------------------------------------------------------------------- +#[CSNIPPETS] +# -------------------------------------------------------------------------------------------------------------- +#TM*** + +class CSnippets(): + + def GetSeveralParticularSnippets(self): + """Several particular snippets covering different topics + """ + + sHeadline = "Several particular snippets covering different topics" + + listCodeSnippets = [] + + listCodeSnippets.append("""{ + ${testdict1.subKey1.subKey2.subKey3} : {"subKey4" : 1}, + ${testdict2.subKey1.subKey2} : {"subKey3" : {"subKey4" : 2}}, + ${testdict3.subKey1} : {"subKey2" : {"subKey3" : {"subKey4" : 3}}}, + ${testdict4} : {"subKey1" : {"subKey2" : {"subKey3" : {"subKey4" : 4}}}} +} +""") + + listCodeSnippets.append("""{ + ${testdict1.subKey1.subKey2.subKey3} : {"subKey4" : 1} +} +""") + + listCodeSnippets.append("""{ + ${testdict5.subKey1.subKey2.subKey3} : {"subKey4" : 1}, + ${testdict5.subKey1} : 2 +} +""") + + listCodeSnippets.append("""{ + "par${1}am2" : "123" +} +""") + + listCodeSnippets.append("""{ + "par${...}am2" : "123" +} +""") + + listCodeSnippets.append("""{ + "testlist" : [1,2,3], + "value" : ${testlist}[] +} +""") + + listCodeSnippets.append("""{ + "testlist" : [1,2,3], + "value" : ${testlist}[${}] +} +""") + + listCodeSnippets.append("""{ + "param1" : {}, + ${param1}['subkey']['subkey']['subkey'] : "subkey value", + "param1" : {}, + ${param1}['subkey2']['subkey2']['subkey2'] : "subkey value 2" +} +""") + + listCodeSnippets.append("""{ + "key1" : "keyA", + "testdict" : {"keyA" : "A", "keyB" : "B"}, + "param1" : ${testdict}['keyA'], + "param2" : ${testdict}[${key1}], + "param3" : ${testdict}['${key1}'], + ${testdict}[${key1}] : "C", + ${testdict}['${key1}'] : "D" +} +""") + + listCodeSnippets.append("""{ + "intparam" : 0, + "stringparam" : "A", + "listparam" : ["A", "B"], + "dictparam" : {"0" : 0, "A" : 1, "B" : 2}, + // + "val01" : ${listparam}[${intparam}], + "val02" : ${listparam}[1], + "val03" : ${dictparam}['${intparam}'], + "val04" : ${dictparam}[${stringparam}], + "val05" : ${dictparam}['${stringparam}'], + "val06" : ${dictparam}['A'], + // + "val07" : "${listparam}[${intparam}]", + "val08" : "${listparam}[1]", + "val09" : "${dictparam}['${intparam}']", + "val10" : "${dictparam}[${stringparam}]", + "val11" : "${dictparam}['${stringparam}']", + "val12" : "${dictparam}['A']" +} +""") + + listCodeSnippets.append("""{ + ${testdict9.subKey1.subKey2.subKey3} : "ABC", + "param1" : "subKey1", + "param2" : "subKey2", + "param3" : "subKey3", + ${testdict9.${param1}.subKey2.subKey3} : "123", + ${testdict9.subKey1.${param2}.subKey3} : "456", + ${testdict9.subKey1.subKey2.${param3}} : "789" +} +""") + + listCodeSnippets.append("""{ + "dict_param" : {"A" : 1 , "B" : 2} + "list_param" : ["A", "B", "C"] + "val1" : "${list_param[1]}" +} +""") + + listCodeSnippets.append("""{ + "dict_param" : {"A" : 1 , "B" : 2} + "list_param" : ["A", "B", "C"] + "val3" : "${list_param[${dict_param}['A']]}" +} +""") + + listCodeSnippets.append("""{ + "dict_param" : {"A" : 1 , "B" : 2}, + "list_param" : ["A", "B", "C"], + "val3" : "${list_param[${dict_param}['A']]}" +} +""") + + listCodeSnippets.append("""{ + "dict_param" : {"A" : 1 , "B" : 2}, + "list_param" : ["A", "B", "C"], + "val4" : "${list_param[${dict_param}[${list_param}[0]]]}" +} +""") + + listCodeSnippets.append("""{ + "dict_param" : {"A" : 1 , "B" : 2}, + "list_param" : ["A", "B", "C"], + "val4" : "${list_param[${dict_param}['${list_param}[0]']]}" +} +""") + + listCodeSnippets.append("""{ + "intval" : 1, + "testlist" : ["B", 2], + "param_${testlist}['${intval}']}" : 3 +} +""") + + listCodeSnippets.append("""{ + "intval" : 1, + "testlist" : ["B", 2], + ${testlist}[${intval}] : 4 +} +""") + + listCodeSnippets.append("""{ + "testdict_1" : {}, + ${testdict_1.subKey.subKey.paramA} : {"A" : 1}, + ${testdict_2.subKey.subKey.paramA} : {"B" : 2}, + ${testdict_2.subKey.subKey.paramA.paramB} : {"C" : 3}, + ${testdict_2.subKey.subKey.paramA}['paramC'] : {"D" : 4}, + "paramD" : "D", + "paramE" : "E", + ${testdict_3.paramD.paramE.paramD} : {"E" : 5}, + ${testdict_3.paramD.paramE.paramD}[${paramE}] : {"F" : 6} +} +""") + + listCodeSnippets.append("""{ + ${testdict1.subKey1.subKey2.subKey3.subKey4} : 1, + ${testdict1.subKey1.subKey2.subKey3} : {"subKey4" : 2}, + "testdict2" : ${testdict1}, + "param1" : "subKey1", + "param2" : "subKey2", + "param3" : "subKey3", + "param4" : "subKey4", + ${testdict1}[${param1}]['${param2}']['subKey3'][${param4}] : 3, + ${testdict2.${param1}.subKey2.${param3}.subKey4} : 4, + ${testdict2.subKey1.${param2}.subKey3.${param4}} : 5, + "param5" : ${testdict1}[${param1}]['${param2}']['subKey3'][${param4}], + "param6" : ${testdict2.${param1}.subKey2.${param3}.subKey4} +} +""") + + listCodeSnippets.append("""{ + // implicitly created data structure + ${testdict1.subKey1.subKey2.subKey3} : {"subKey4" : 1}, + "testdict2" : ${testdict1}, // by reference + // + // parameters containing names of existing keys + "param1" : "subKey1", + "param2" : "subKey2", + "param3" : "subKey3", + "param4" : "subKey4", + // + // access to implicitly created keys by parameters (standard notation); all are strings, therefore single quotes do not matter + ${testdict1}[${param1}]['${param2}']['subKey3'][${param4}] : 2, + // access to implicitly created keys by parameters (dotdict notation) + ${testdict2.${param1}.subKey2.${param3}.subKey4} : 3, + // assign modified values to new parameters + "param5" : ${testdict1}[${param1}]['${param2}']['subKey3'][${param4}], + // still issue: https://github.com/test-fullautomation/python-jsonpreprocessor/issues/232 + "param6" : ${testdict2.${param1}.subKey2.${param3}.subKey4} // Expecting value: line 11 column 15 (char 412)'! +} +""") + + listCodeSnippets.append("""{ + ${testdict1.subKey1.subKey2} : 1, + "testdict2" : ${testdict1} + ${testdict1.subKey1.subKey2} : 2 +} +""") + + listCodeSnippets.append("""{ + ${testdict1.subKey1.subKey2} : 1, + "testdict2" : ${testdict1}, + ${testdict2.subKey1.subKey2} : 2 +} +""") + + listCodeSnippets.append("""{ + "intval" : 1, + "testlist" : ["B", 2], + ${testlist[${intval}]} : 4 +} +""") + + listCodeSnippets.append("""{ + "intval" : 1, + "testlist" : ["B", 2], + ${testlist}['${intval}'] : 4 +} +""") + + listCodeSnippets.append("""{ + "teststring" : "ABC", + "${teststring}___${teststring}" : "DEF" +} +""") + + listCodeSnippets.append("""{ + "param1" : "prefix", + "param2" : [1,2,3], + "param3" : {"${param1}_${param2}_suffix" : "value"} +} +""") + + listCodeSnippets.append("""{ + "testlist" : ["A", "B", "C", "D"], + "index1" : 1, + "index2" : 3, + "param3" : ${testlist}[${index1}:${index2}] +} +""") + + listCodeSnippets.append("""{ + "testlist" : ["A", "B", "C", "D"], + "param1" : ${testlist}[1:3] +} +""") + + listCodeSnippets.append("""{ + "testlist" : ["A", "B", "C", "D"], + "param2" : ${testlist}[:-1] +} +""") + + listCodeSnippets.append("""{ + "testlist" : ["A", "B", "C", "D"], + "param2" : ${testlist}[-1] +} +""") + + listCodeSnippets.append("""{ + "testlist" : ["A", "B", "C", "D"], + "param2" : ${testlist}[+1] +} +""") + + listCodeSnippets.append("""{ + "testlist" : ["A", "B", "C", "D"], + "param2" : ${testlist}[1:] +} +""") + + listCodeSnippets.append("""{ + "testlist" : ["A", "B", "C", "D"], + "param2" : ${testlist}[50] +} +""") + + listCodeSnippets.append("""{ + "testlist" : ["A", "B", "C", "D"], + "param2" : ${testlist}[X] +} +""") + + listCodeSnippets.append("""{ + "param1" : "string", + "param2" : ${param1}[50] +} +""") + + listCodeSnippets.append("""{ + "param" : "value", + ${param} : ${param} +} +""") + + listCodeSnippets.append("""{ + "params" : {"global" : {"param" : "value", + ${params.global.param} : ${params.global.param} + } + } +} +""") + + listCodeSnippets.append("""{ + "param" : {"A" : 1}, + ${param} : ${param} +} +""") + + listCodeSnippets.append("""{ + "params" : {"global" : {"param" : {"A" : 1}, + ${params.global.param} : ${params.global.param} + } + } +} +""") + + listCodeSnippets.append("""{ + "param" : ["A" , 1], + ${param} : ${param} +} +""") + + listCodeSnippets.append("""{ + "params" : {"global" : {"param" : ["A" , 1], + ${params.global.param} : ${params.global.param} + } + } +} +""") + + listCodeSnippets.append("""{ + ${testdict1.subKey1.subKey2_1} : 1, + ${testdict1.subKey1} : {"subKey2_2" : 2} +} +""") + + listCodeSnippets.append("""{ + ${testdict1.subKey1.subKey2_1} : 1, + ${testdict1.subKey1} : 2 +} +""") + + listCodeSnippets.append("""{ + "ara" : "ara", + "param" : 123, + "val1" : ${p${ara}m} +} +""") + + listCodeSnippets.append("""{ + "ara" : "ara", + "param" : 123, + "val1" : "${p${ara}m}" +} +""") + + listCodeSnippets.append("""{ + "teststring-1" : "teststring-1 value", + ${teststring-1} : "${teststring-1} extended" +} +""") + + listCodeSnippets.append("""{ + "intval" : 1, + "testlist" : ["B", 2], + ${testlist}['${intval}'] : 4 +} +""") + + listCodeSnippets.append("""{ + "intparam" : 0, + "stringparam" : "A", + "listparam" : ["A", "B"], + "dictparam" : {"0" : 0, "A" : 1, "B" : 2}, + "val01" : ${listparam}[${intparam}], + "val02" : ${listparam}[1], + "val03" : ${dictparam}['${intparam}'], + "val04" : ${dictparam}[${stringparam}], + "val05" : ${dictparam}['${stringparam}'], + "val06" : ${dictparam}['A'] +} +""") + + listCodeSnippets.append("""{ + "intparam" : 0, + "stringparam" : "A", + "listparam" : ["A", "B"], + "dictparam" : {"0" : 0, "A" : 1, "B" : 2}, + "val07" : "${listparam}[${intparam}]", + "val08" : "${listparam}[1]", + "val09" : "${dictparam}['${intparam}']", + "val10" : "${dictparam}[${stringparam}]", + "val11" : "${dictparam}['${stringparam}']", + "val12" : "${dictparam}['A']" +} +""") + + listCodeSnippets.append("""{ + "dictparam" : {"A" : 1}, + "listparam" : ["A", "B"], + ${IAMNOTEXISTING.${dictparam}}['${listparam}'] : 2 +} +""") + + listCodeSnippets.append("""{ + "listparam" : ["A", "B"], + "stringparam" : "string", + ${IAMNOTEXISTING.${stringparam}}['${listparam}'] : 2 +} +""") + + listCodeSnippets.append("""{ + "stringparam" : "string", + "intparam" : 0, + ${IAMNOTEXISTING.${stringparam}}['${intparam}'] : 2 +} +""") + + listCodeSnippets.append("""{ + "stringparam" : "string", + "intparam" : 0, + ${IAMNOTEXISTING.${stringparam}}[${intparam}] : 2 +} +""") + + listCodeSnippets.append("""{ + "intval" : 1, + "testlist" : ["B", 2], + ${testlist}[${intval}] : 4 +} +""") + + listCodeSnippets.append("""{ +${testdict.subKey.subKey.subKey} : {"A" : 1}, +"testdict": {"subKey": {"subKey": {"subKey": {"A": 2}}}} +} +""") + + listCodeSnippets.append("""{ + ${testdict.subKey.subKey.subKey} : {"A" : 1}, + "subKey" : "A", + ${testdict.subKey.subKey.subKey}[${subKey}] : 2 +} +""") + + listCodeSnippets.append("""{ + ${testdict.subKey.subKey.subKey} : {"A" : 1}, + "subKey" : "B", + ${testdict.subKey.subKey.subKey}[${subKey}] : "2" +} +""") + + listCodeSnippets.append("""{ + ${testdict1} : {"subKey1" : {"subKey2" : {"subKey3" : {"subKey4" : 0}}}}, + ${testdict1.subKey1} : {"subKey2" : {"subKey3" : {"subKey4" : 1}}}, + ${testdict1.subKey1.subKey2} : {"subKey3" : {"subKey4" : 2}}, + ${testdict1.subKey1.subKey2.subKey3} : {"subKey4" : 3}, + ${testdict1.subKey1.subKey2.subKey3.subKey4} : 4, + // + ${testdict2.subKey1.subKey2.subKey3.subKey4} : 5, + ${testdict2.subKey1.subKey2.subKey3} : {"subKey4" : 6}, + ${testdict2.subKey1.subKey2} : {"subKey3" : {"subKey4" : 7}}, + ${testdict2.subKey1} : {"subKey2" : {"subKey3" : {"subKey4" : 8}}}, + ${testdict2} : {"subKey1" : {"subKey2" : {"subKey3" : {"subKey4" : 9}}}}, + // + ${testdict3} : {"subKey1" : {"subKey2" : {"subKey3" : {"subKey4" : 10}}}}, + "testdict4" : {"subKey1" : {"subKey2" : {"subKey3" : {"subKey4" : 20}}}} +} +""") + + listCodeSnippets.append("""{ + "dict_param" : {"A" : 0 , "B" : 1}, + "list_param" : ["A", "B"], + "param1" : "${list_param}[${dict_param}[${list_param}[${dict_param}[${list_param}[${dict_param}[${list_param}[${dict_param}[${list_param}[0]]]]]]]]]", + "param2" : "${dict_param}[${list_param}[${dict_param}[${list_param}[${dict_param}[${list_param}[${dict_param}[${list_param}[${dict_param}['A']]]]]]]]]" +} +""") + + listCodeSnippets.append("""{ + "keyP" : "A", + "dictP" : {"A" : "B", "C" : 2}, + "newparam" : "${dictP[${keyP}]}" +} +""") + + listCodeSnippets.append("""{ + "keyP" : "A", + "B" : 1, + "dictP" : {"A" : "B", "C" : 2}, + "newparam" : "${${dictP}[${keyP}]}" +} +""") + + listCodeSnippets.append("""{ + "keyP" : "A", + "B" : "keyP", + "dictP" : {"A" : "B"}, + // + "newparam_1" : "${dictP}['${keyP}']", // => "${dictP}['A']" -> 'B' + "newparam_2" : "${${dictP}['${keyP}']}", // => "${B}" -> 'keyP' + "newparam_3" : "${${${dictP}['${keyP}']}}", // => "${keyP}" -> 'A' + "newparam_4" : "${dictP}['${${${dictP}['${keyP}']}}']", // => "${dictP}['A']" -> 'B' + "newparam_5" : "${${dictP}['${${${dictP}['${keyP}']}}']}", // => "${B}" -> 'keyP' + "newparam_6" : "${${${dictP}['${${${dictP}['${keyP}']}}']}}", // => "${keyP}" -> 'A' + "newparam_7" : "${dictP}['${${${dictP}['${${${dictP}['${keyP}']}}']}}']", // => "${dictP}['A']" -> 'B' + "newparam_8" : "${${dictP}['${${${dictP}['${${${dictP}['${keyP}']}}']}}']}", // => "${B}" -> 'keyP' + "newparam_9" : "${${${dictP}['${${${dictP}['${${${dictP}['${keyP}']}}']}}']}}" // => "${keyP}" -> 'A' +} +""") + + listCodeSnippets.append("""{ + "keyP" : "A", + "dictP" : {"A" : "B", "C" : 2}, + "newparam" : "${dictP['${keyP}']}" +} +""") + + listCodeSnippets.append("""{ + "listparam" : ["A","B","C"], + "param_1" : "}${listparam}[0]{", + "param_2" : "{${listparam}[0]}", + "param_3" : "$}${listparam}[0]$}", + "param_4" : "{$}${listparam}[0]{$}", + "param_5" : "}{$}${listparam}[0]{$}{", + "param_6" : "{}{$}${listparam}[0]{$}{}", + "param_7" : "{}${listparam}[0]{$}${listparam}[1]{$}${listparam}[2]{}", + "param_8" : "{}$${listparam}[0]{$$}$${listparam}[1]{$$}$${listparam}[2]{}", + "param_9" : "{[}$${listparam}[0]]{$[$}$${listparam}[1]}{$$}$${listparam}[2]{}()" +} +""") + + listCodeSnippets.append("""{ +"param" : "Hello empty bracket []" +} +""") + + listCodeSnippets.append("""{ +"param" : "Hello spaced bracket [ ]" +} +""") + + listCodeSnippets.append("""{ +"param" : "Hello filled bracket [selftest]" +} +""") + + listCodeSnippets.append("""{ +"param" : "Hello filled bracket with spaces [self test]" +} +""") + + listCodeSnippets.append("""{ +"param1" : "value", +"param" : "Hello bracket [${param1}]" +} +""") + + listCodeSnippets.append("""{ +"param1" : "value", +"param" : "Hello bracket {}[${param1}]" +} +""") + + listCodeSnippets.append("""{ + ${testdict1.subKey1.subKey2} : 1, + "testdict2" : ${testdict1}, + ${testdict2.subKey1.subKey2} : 2, + ${testdict1.subKey1.subKey2} : 3 +} +""") + + listCodeSnippets.append("""{ + ${testdict3.subKey1.subKey2} : 4, + "testdict4" : ${testdict3}, + ${testdict3.subKey1.subKey2} : 5, + ${testdict4.subKey1.subKey2} : 6 +} +""") + + listCodeSnippets.append("""{ + "testlist1" : [1,2], + "testlist2" : ${testlist1}, + ${testlist1}[0] : 3, + ${testlist2}[1] : 4 +} +""") + + listCodeSnippets.append("""{ + "testlist3" : [5,6], + "testlist4" : ${testlist3}, + ${testlist4}[0] : 7, + ${testlist3}[1] : 8 +} +""") + + # listCodeSnippets.append("""{ +# } +# """) + + # listCodeSnippets.append("""{ +# } +# """) + + + # -------------------------------------------------------------------------------------------------------------- + # TODO: check: several different expressions in square brackets inside curly brackets + # TODO: check: invalid bracket content + # TODO: check: usage of single quotes + # TODO: check: substitution with not supported (composite) data types + # TODO: automate: several combinations with not existing parameters + # TODO: ${dict} : ${dict} -> by value or by reference? + # TODO: several comments wit different content: "testlist" : ["A1", /*"B2", "C3",*/ "D4"] + # TODO: slicing: make autogenerated code in separate section + # TODO: composite data types in ${} substitutions + + # -------------------------------------------------------------------------------------------------------------- + + return sHeadline, listCodeSnippets + + # eof def GetSeveralParticularSnippets(self): + + # -------------------------------------------------------------------------------------------------------------- + + def GetBracketMismatch(self): + """Assignments with missing brackets + """ + + sHeadline = "Assignments with missing brackets" + + listCodeSnippets = [] + + listCodeSnippets.append("""{ + "param1" : "value1", + "param2" : ${param1} +} +""") + + listCodeSnippets.append("""{ + "param1" : "value1", + "param2" : ${param1 +} +""") + + listCodeSnippets.append("""{ + "param1" : "value1", + "param2" : "${param1" +} +""") + + listCodeSnippets.append("""{ + "param1" : "value1", + "param2" : param1" +} +""") + + listCodeSnippets.append("""{ + "param1" : "value1", + "param2" : "param1}" +} +""") + + listCodeSnippets.append("""{ + "listparam" : ["A","B","C"], + "param" : ${listparam[0] +} +""") + + listCodeSnippets.append("""{ + "listparam" : ["A","B","C"], + "param" : "${listparam[0]" +} +""") + + listCodeSnippets.append("""{ + "listparam" : ["A","B","C"], + "param" : ${listparam}0] +} +""") + + listCodeSnippets.append("""{ + "listparam" : ["A","B","C"], + "param" : "${listparam}0]" +} +""") + + listCodeSnippets.append("""{ + "listparam" : ["A","B","C"], + "param" : ${listparam}[0 +} +""") + + listCodeSnippets.append("""{ + "listparam" : ["A","B","C"], + "param" : "${listparam}[0" +} +""") + + listCodeSnippets.append("""{ + "listparam" : ["A","B","C"], + "param" : ${${listparam}[0] +} +""") + + listCodeSnippets.append("""{ + "listparam" : ["A","B","C"], + "param" : "${${listparam}[0]" +} +""") + + listCodeSnippets.append("""{ + "listparam" : ["A","B","C"], + "param" : $}${listparam}[0] +} +""") + + listCodeSnippets.append("""{ + "listparam" : ["A","B","C"], + "param" : "$}${listparam}[0]" +} +""") + + listCodeSnippets.append("""{ + "listparam" : ["A","B","C"], + ${listparam}[0] : "value" +} +""") + + listCodeSnippets.append("""{ + "listparam" : ["A","B","C"], + ${listparam[0] : "value" +} +""") + + listCodeSnippets.append("""{ + "listparam" : ["A","B","C"], + ${listparam}0] : "value" +} +""") + + listCodeSnippets.append("""{ + "listparam" : ["A","B","C"], + ${{listparam}[0] : "value" +} +""") + + listCodeSnippets.append("""{ + "listparam" : ["A","B","C"], + ${listparam}[}0] : "value" +} +""") + + return sHeadline, listCodeSnippets + + # eof def GetBracketMismatch(self): + + # -------------------------------------------------------------------------------------------------------------- + + def GetDatatypePermutations(self): + """Data type permutations in a fix pattern. Parameter types: int, str, list, dict. + """ + + sHeadline = "Data type permutations in a fix pattern. Parameter types: int, str, list, dict." + + sDefinitions = """ "indexP" : 0, + "keyP" : "A", + "dictP" : {"A" : 1, "B" : 2}, + "listP" : ["A", "B"], +""" + + sCodeSnippetPattern = """{ +####DEFINITIONS#### +####ASSIGNMENT#### +} +""" + + listofDataTypeTuples = [] + # listofDataTypeTuples.append(("indexP", "indexP")) + # listofDataTypeTuples.append(("indexP", "keyP")) + # listofDataTypeTuples.append(("indexP", "dictP")) + # listofDataTypeTuples.append(("indexP", "listP")) + # listofDataTypeTuples.append(("keyP", "indexP")) + # listofDataTypeTuples.append(("keyP", "keyP")) + # listofDataTypeTuples.append(("keyP", "dictP")) + # listofDataTypeTuples.append(("keyP", "listP")) + # listofDataTypeTuples.append(("dictP", "indexP")) + listofDataTypeTuples.append(("dictP", "keyP")) + # listofDataTypeTuples.append(("dictP", "dictP")) + # listofDataTypeTuples.append(("dictP", "listP")) + # listofDataTypeTuples.append(("listP", "indexP")) + # listofDataTypeTuples.append(("listP", "keyP")) + # listofDataTypeTuples.append(("listP", "dictP")) + # listofDataTypeTuples.append(("listP", "listP")) + + listAssignments = [] + + listAssignments.append(" \"newparam\" : ${XXXX}[${YYYY}]") + listAssignments.append(" \"newparam\" : \"${XXXX}[${YYYY}]\"") + listAssignments.append(" \"newparam\" : ${XXXX}['${YYYY}']") + listAssignments.append(" \"newparam\" : \"${XXXX}['${YYYY}']\"") + + listAssignments.append(" \"newparam\" : ${XXXX[${YYYY}]}") + listAssignments.append(" \"newparam\" : \"${XXXX[${YYYY}]}\"") + listAssignments.append(" \"newparam\" : ${XXXX['${YYYY}']}") + listAssignments.append(" \"newparam\" : \"${XXXX['${YYYY}']}\"") + + listAssignments.append(" \"newparam\" : ${XXXX[${YYYY}]}") + listAssignments.append(" \"newparam\" : \"${XXXX[${YYYY}]}\"") + listAssignments.append(" \"newparam\" : ${XXXX['${YYYY}']}") + listAssignments.append(" \"newparam\" : \"${XXXX['${YYYY}']}\"") + + listAssignments.append(" \"newparam\" : ${XXXX.${YYYY}}") + listAssignments.append(" \"newparam\" : \"${XXXX.${YYYY}}\"") + + listAssignments.append(" ${XXXX}[${YYYY}] : \"newvalue\"") + listAssignments.append(" \"${XXXX}[${YYYY}]\" : \"newvalue\"") + listAssignments.append(" ${XXXX}['${YYYY}'] : \"newvalue\"") + listAssignments.append(" \"${XXXX}['${YYYY}']\" : \"newvalue\"") + + listAssignments.append(" ${XXXX[${YYYY}]} : \"newvalue\"") + listAssignments.append(" \"${XXXX[${YYYY}]}\" : \"newvalue\"") + listAssignments.append(" ${XXXX['${YYYY}']} : \"newvalue\"") + listAssignments.append(" \"${XXXX['${YYYY}']}\" : \"newvalue\"") + + listAssignments.append(" ${XXXX[${YYYY}]} : \"newvalue\"") + listAssignments.append(" \"${XXXX[${YYYY}]}\" : \"newvalue\"") + listAssignments.append(" ${XXXX['${YYYY}']} : \"newvalue\"") + listAssignments.append(" \"${XXXX['${YYYY}']}\" : \"newvalue\"") + + listAssignments.append(" ${XXXX.${YYYY}} : \"newvalue\"") + listAssignments.append(" \"${XXXX.${YYYY}}\" : \"newvalue\"") + + # put all things together + + listCodeSnippets = [] + + for sAssignment in listAssignments: + for tupleDataTypes in listofDataTypeTuples: + sAssignment_repl = sAssignment.replace("XXXX", tupleDataTypes[0]) + sAssignment_repl = sAssignment_repl.replace("YYYY", tupleDataTypes[1]) + + sCodeSnippet = sCodeSnippetPattern.replace("####DEFINITIONS####", sDefinitions) + sCodeSnippet = sCodeSnippet.replace("####ASSIGNMENT####", sAssignment_repl) + listCodeSnippets.append(sCodeSnippet) + + return sHeadline, listCodeSnippets + + # eof def GetDatatypePermutations(self): + + # -------------------------------------------------------------------------------------------------------------- + + def GetNestedDataTypes(self): + """Combinations of several expressions within a data structure of multiple nested dictionaries and lists + """ + + sHeadline = "Combinations of several expressions within a data structure of multiple nested dictionaries and lists" + + # 1. data structure without additional blanks around brackets, sub elements at end of parent elements + sDataStructure1 = """ "params" : {*01* : *02*, + *03* : [*04*, {*05* : *06*, + *07* : [*08*, [*09*, *10*]], + *11* : [*12*, {*13* : *14*}], + *15* : {*16* : [*17*, *18*]}, + *19* : {*20* : {*21* : *22*}} + } + ] + }""" + + # 2. data structure containing additional blanks around brackets, sub elements at end of parent elements + sDataStructure2 = """ "params" : { *01* : *02*, + *03* : [ *04*, { *05* : *06*, + *07* : [ *08*, [ *09*, *10* ]], + *11* : [ *12*, { *13* : *14* }], + *15* : { *16* : [ *17*, *18* ]}, + *19* : { *20* : { *21* : *22* }} + } + ] + }""" + + sDefinitions = """ "indexP" : 0, + "keyP" : "A", + "dictP" : {"A" : 0, "B" : 1}, + "listP" : ["A", "B"], +""" + + sCodeSnippetPattern = """{ +####DEFINITIONS#### +####DATASTRUCTURE#### +} +""" + + # We have a list of expressions and we have a list of placeholders like used in sDataStructure1 and sDataStructure2. + # The followig code runs in a nested loop: Every expression is placed at every placeholder position. Only one single + # expression and placeholder per iteration. All remaining placeholders in current iteration are replaced by elements + # from a list of filler expressions (simple letters) that are only used to complete the code snippet, but are not in focus. + # The expressions are of different complexity. + # The impact on several expressions at several positions within the entire JSON code is to have successive brackets + # in several combinations: [[, [{, {[, {{, }}, ]}, }], ]] + + listExpressions = ["${indexP}", "${keyP}", "${dictP}", "${listP}", "\"${indexP}\"", "\"${keyP}\"", "\"${dictP}\"", "\"${listP}\"", "123", "\"ABC\"", + "${listP}[${indexP}]", "${dictP}[${keyP}]", "${listP}[${dictP}[${keyP}]]", "${dictP}[${listP}[${indexP}]]", + "\"${listP}[${indexP}]\"", "\"${dictP}[${keyP}]\"", "\"${listP}[${dictP}[${keyP}]]\"", "\"${dictP}[${listP}[${indexP}]]\""] + + listPlaceholders = ["*01*", "*02*", "*03*", "*04*", "*05*", "*06*", "*07*", "*08*", "*09*", "*10*", "*11*", + "*12*", "*13*", "*14*", "*15*", "*16*", "*17*", "*18*", "*19*", "*20*", "*21*", "*22*"] + + listPositions = listPlaceholders[:] # to support a nested iteration of the same list; better readibility of code because of different names + + listFiller = ["001","002","003","004","005","006","007","008","009","010", + "011","012","013","014","015","016","017","018","019","020","021","022"] # as much elements as in listPlaceholders + + # put all things together + + listCodeSnippets = [] + + # 1. data structure without additional blanks around brackets, sub elements at end of parent elements + + # sDataStructure1 + + for sExpression in listExpressions: + for sPosition in listPositions: + sDataStructure = sDataStructure1 # init a new data structure from pattern sDataStructure1 + sCodeSnippet = sCodeSnippetPattern # init a new code snippet from code snippet pattern + oFiller = CListElements(listFiller) # init a new filler object (= content for remaining placeholders) + for sPlaceholder in listPlaceholders: + sFiller = oFiller.GetElement() + if sPosition == sPlaceholder: + sDataStructure = sDataStructure.replace(sPlaceholder, sExpression) + else: + sDataStructure = sDataStructure.replace(sPlaceholder, f"\"{sFiller}\"") + # eof for sPlaceholder in listPlaceholders: + sCodeSnippet = sCodeSnippet.replace("####DEFINITIONS####", sDefinitions) + sCodeSnippet = sCodeSnippet.replace("####DATASTRUCTURE####", sDataStructure) + listCodeSnippets.append(sCodeSnippet) + # eof for sPosition in listPositions: + # eof for sExpression in listExpressions: + + # 2. data structure containing additional blanks around brackets, sub elements at end of parent elements + + # sDataStructure2 + + for sExpression in listExpressions: + for sPosition in listPositions: + sDataStructure = sDataStructure2 # init a new data structure from pattern sDataStructure2 + sCodeSnippet = sCodeSnippetPattern # init a new code snippet from code snippet pattern + oFiller = CListElements(listFiller) # init a new filler object (= content for remaining placeholders) + for sPlaceholder in listPlaceholders: + sFiller = oFiller.GetElement() + if sPosition == sPlaceholder: + sDataStructure = sDataStructure.replace(sPlaceholder, sExpression) + else: + sDataStructure = sDataStructure.replace(sPlaceholder, f"\"{sFiller}\"") + # eof for sPlaceholder in listPlaceholders: + sCodeSnippet = sCodeSnippet.replace("####DEFINITIONS####", sDefinitions) + sCodeSnippet = sCodeSnippet.replace("####DATASTRUCTURE####", sDataStructure) + listCodeSnippets.append(sCodeSnippet) + # eof for sPosition in listPositions: + # eof for sExpression in listExpressions: + + return sHeadline, listCodeSnippets + + # eof def GetNestedDataTypes(self): + + # -------------------------------------------------------------------------------------------------------------- + + def GetNotExistingParams(self): + """Not existing params at several positions within a complex data structure + """ + + sHeadline = "Not existing params at several positions within a complex data structure" + + # data structure 1 + sDataStructure1 = """ "params" : {*01* : *02*, + *03* : [*04*, {*05* : *06*, + *07* : [*08*, [*09*, *10*]], + *11* : [*12*, {*13* : *14*}], + *15* : {*16* : [*17*, *18*]}, + *19* : {*20* : {*21* : *22*}} + } + ] + }""" + + sDefinitions = """ "indexP" : 0, + "keyP" : "A", + "dictP" : {"A" : 0, "B" : 1}, + "listP" : ["A", "B"], +""" + + sCodeSnippetPattern = """{ +####DEFINITIONS#### +####DATASTRUCTURE#### +} +""" + + # We have a list of expressions and we have a list of placeholders like used in sDataStructure1. + # The followig code runs in a nested loop: Every expression is placed at every placeholder position. Only one single + # expression and placeholder per iteration. All remaining placeholders in current iteration are replaced by elements + # from a list of filler expressions (simple letters) that are only used to complete the code snippet, but are not in focus. + + listExpressions = ["${IAMNOTEXISTING}", "${dictP}[${IAMNOTEXISTING}]", "${listP}[${IAMNOTEXISTING}]"] + + listPlaceholders = ["*01*", "*02*", "*03*", "*04*", "*05*", "*06*", "*07*", "*08*", "*09*", "*10*", "*11*", + "*12*", "*13*", "*14*", "*15*", "*16*", "*17*", "*18*", "*19*", "*20*", "*21*", "*22*"] + + listPositions = listPlaceholders[:] # to support a nested iteration of the same list; better readibility of code because of different names + + listFiller = ["001","002","003","004","005","006","007","008","009","010", + "011","012","013","014","015","016","017","018","019","020","021","022"] # as much elements as in listPlaceholders + + # put all things together + + listCodeSnippets = [] + + # sDataStructure1 + + for sExpression in listExpressions: + for sPosition in listPositions: + sDataStructure = sDataStructure1 # init a new data structure from pattern sDataStructure1 + sCodeSnippet = sCodeSnippetPattern # init a new code snippet from code snippet pattern + oFiller = CListElements(listFiller) # init a new filler object (= content for remaining placeholders) + for sPlaceholder in listPlaceholders: + sFiller = oFiller.GetElement() + if sPosition == sPlaceholder: + sDataStructure = sDataStructure.replace(sPlaceholder, sExpression) + else: + sDataStructure = sDataStructure.replace(sPlaceholder, f"\"{sFiller}\"") + # eof for sPlaceholder in listPlaceholders: + sCodeSnippet = sCodeSnippet.replace("####DEFINITIONS####", sDefinitions) + sCodeSnippet = sCodeSnippet.replace("####DATASTRUCTURE####", sDataStructure) + listCodeSnippets.append(sCodeSnippet) + # eof for sPosition in listPositions: + # eof for sExpression in listExpressions: + + return sHeadline, listCodeSnippets + + # eof def GetNotExistingParams(self): + + # -------------------------------------------------------------------------------------------------------------- + + def GetKeywords(self): + """Python keywords at several positions within a complex data structure + """ + + sHeadline = "Python keywords at several positions within a complex data structure" + + # data structure 1 + sDataStructure1 = """ "params" : {*01* : *02*, + *03* : [*04*, {*05* : *06*, + *07* : [*08*, [*09*, *10*]], + *11* : [*12*, {*13* : *14*}], + *15* : {*16* : [*17*, *18*]}, + *19* : {*20* : {*21* : *22*}} + } + ] + }""" + + sDefinitions = """ "indexP" : 0, + "keyP" : "A", + "dictP" : {"A" : 0, "B" : 1}, + "listP" : ["A", "B"], +""" + + sCodeSnippetPattern = """{ +####DEFINITIONS#### +####DATASTRUCTURE#### +} +""" + + # We have a list of expressions and we have a list of placeholders like used in sDataStructure1. + # The followig code runs in a nested loop: Every expression is placed at every placeholder position. Only one single + # expression and placeholder per iteration. All remaining placeholders in current iteration are replaced by elements + # from a list of filler expressions (simple letters) that are only used to complete the code snippet, but are not in focus. + + # results mostly not interesting: # listExpressions = ["True", "False", "None", "true", "false", "null"] + listExpressions = ["None", "${True}", "${None}", "\"${False}\"", "\"${None}\""] + + listPlaceholders = ["*01*", "*02*", "*03*", "*04*", "*05*", "*06*", "*07*", "*08*", "*09*", "*10*", "*11*", + "*12*", "*13*", "*14*", "*15*", "*16*", "*17*", "*18*", "*19*", "*20*", "*21*", "*22*"] + + listPositions = listPlaceholders[:] # to support a nested iteration of the same list; better readibility of code because of different names + + listFiller = ["001","002","003","004","005","006","007","008","009","010", + "011","012","013","014","015","016","017","018","019","020","021","022"] # as much elements as in listPlaceholders + + # put all things together + + listCodeSnippets = [] + + # sDataStructure1 + + for sExpression in listExpressions: + for sPosition in listPositions: + sDataStructure = sDataStructure1 # init a new data structure from pattern sDataStructure1 + sCodeSnippet = sCodeSnippetPattern # init a new code snippet from code snippet pattern + oFiller = CListElements(listFiller) # init a new filler object (= content for remaining placeholders) + for sPlaceholder in listPlaceholders: + sFiller = oFiller.GetElement() + if sPosition == sPlaceholder: + sDataStructure = sDataStructure.replace(sPlaceholder, sExpression) + else: + sDataStructure = sDataStructure.replace(sPlaceholder, f"\"{sFiller}\"") + # eof for sPlaceholder in listPlaceholders: + sCodeSnippet = sCodeSnippet.replace("####DEFINITIONS####", sDefinitions) + sCodeSnippet = sCodeSnippet.replace("####DATASTRUCTURE####", sDataStructure) + listCodeSnippets.append(sCodeSnippet) + # eof for sPosition in listPositions: + # eof for sExpression in listExpressions: + + return sHeadline, listCodeSnippets + + # eof def GetKeywords(self): + + # -------------------------------------------------------------------------------------------------------------- + + def GetMissingBrackets(self): + """Missing brackets at several positions within a complex data structure + """ + + sHeadline = "Missing brackets at several positions within a complex data structure" + + # data structure 1 + sDataStructure1 = """ "params" : {*01* : *02*, + *03* : [*04*, {*05* : *06*, + *07* : [*08*, [*09*, *10*]], + *11* : [*12*, {*13* : *14*}], + *15* : {*16* : [*17*, *18*]}, + *19* : {*20* : {*21* : *22*}} + } + ] + }""" + + sDefinitions = """ "indexP" : 0, + "keyP" : "A", + "dictP" : {"A" : 0, "B" : 1}, + "listP" : ["A", "B"], +""" + + sCodeSnippetPattern = """{ +####DEFINITIONS#### +####DATASTRUCTURE#### +} +""" + + # We have a list of expressions and we have a list of placeholders like used in sDataStructure1. + # The followig code runs in a nested loop: Every expression is placed at every placeholder position. Only one single + # expression and placeholder per iteration. All remaining placeholders in current iteration are replaced by elements + # from a list of filler expressions (simple letters) that are only used to complete the code snippet, but are not in focus. + + listExpressions = ["${keyP", "$dictP}", "${listP", "\"$indexP}\"", "\"${keyP\"", "\"$dictP}\"", "\"${listP\"", + "${listP}${indexP}]", "${dictP}[${keyP}", "${listP}${dictP}[${keyP}]]", "${dictP}[${listP}[${indexP}]", + "\"${listP}${indexP}]\"", "\"${dictP}[${keyP]\"", "\"${listP}${dictP}[${keyP]]\"", "\"${dictP}[${listP[${indexP}]\""] + + listPlaceholders = ["*01*", "*02*", "*03*", "*04*", "*05*", "*06*", "*07*", "*08*", "*09*", "*10*", "*11*", + "*12*", "*13*", "*14*", "*15*", "*16*", "*17*", "*18*", "*19*", "*20*", "*21*", "*22*"] + + listPositions = listPlaceholders[:] # to support a nested iteration of the same list; better readibility of code because of different names + + listFiller = ["001","002","003","004","005","006","007","008","009","010", + "011","012","013","014","015","016","017","018","019","020","021","022"] # as much elements as in listPlaceholders + + # put all things together + + listCodeSnippets = [] + + # sDataStructure1 + + for sExpression in listExpressions: + for sPosition in listPositions: + sDataStructure = sDataStructure1 # init a new data structure from pattern sDataStructure1 + sCodeSnippet = sCodeSnippetPattern # init a new code snippet from code snippet pattern + oFiller = CListElements(listFiller) # init a new filler object (= content for remaining placeholders) + for sPlaceholder in listPlaceholders: + sFiller = oFiller.GetElement() + if sPosition == sPlaceholder: + sDataStructure = sDataStructure.replace(sPlaceholder, sExpression) + else: + sDataStructure = sDataStructure.replace(sPlaceholder, f"\"{sFiller}\"") + # eof for sPlaceholder in listPlaceholders: + sCodeSnippet = sCodeSnippet.replace("####DEFINITIONS####", sDefinitions) + sCodeSnippet = sCodeSnippet.replace("####DATASTRUCTURE####", sDataStructure) + listCodeSnippets.append(sCodeSnippet) + # eof for sPosition in listPositions: + # eof for sExpression in listExpressions: + + return sHeadline, listCodeSnippets + + # eof def GetMissingBrackets(self): + +# eof class CSnippets(): + + +# -------------------------------------------------------------------------------------------------------------- +# eof class definitions +# -------------------------------------------------------------------------------------------------------------- + + +# -------------------------------------------------------------------------------------------------------------- +#[INITCONFIG] +# -------------------------------------------------------------------------------------------------------------- +#TM*** + +# -- configuration setup (relative to the path of this app) +oConfig = None +try: + oConfig = CConfig(os.path.abspath(sys.argv[0])) +except Exception as reason: + sResult = CString.FormatResult(sMethod="(main)", bSuccess=None, sResult=str(reason)) + print() + printfailure(sResult) + print() + sys.exit(ERROR) + +# update version and date of this app +oConfig.Set("APP_VERSION", VERSION) +oConfig.Set("APP_VERSION_DATE", VERSION_DATE) +THISAPPNAME = oConfig.Get('THISAPPNAME') +THISAPPFULLNAME = f"{THISAPPNAME} v. {VERSION} / {VERSION_DATE}" +oConfig.Set("THISAPPFULLNAME", THISAPPFULLNAME) + + +# -------------------------------------------------------------------------------------------------------------- +#[INITLOGGER] +# -------------------------------------------------------------------------------------------------------------- +#TM*** + +oLogger = None +try: + oLogger = CLogger(oConfig) +except Exception as reason: + sResult = CString.FormatResult(sMethod="(main)", bSuccess=None, sResult=str(reason)) + print() + printfailure(sResult) + print() + sys.exit(ERROR) + + +# -------------------------------------------------------------------------------------------------------------- + +# ---- prepare initial output + +# dump configuration values to log file +listFormattedOutputLines = oConfig.DumpConfig() +oLogger.WriteLog(120*"*") +oLogger.WriteLog(listFormattedOutputLines) +oLogger.WriteLog(120*"*" + "\n") + +# write HTML header to report file +oHTMLPattern = CHTMLPattern() +oLogger.WriteReport(oHTMLPattern.GetHTMLHeader()) +del oHTMLPattern + +# -------------------------------------------------------------------------------------------------------------- + + +# -------------------------------------------------------------------------------------------------------------- +#[INITCOUNTER] +# -------------------------------------------------------------------------------------------------------------- +#TM*** + +oCounter = CCounter() + + +# -------------------------------------------------------------------------------------------------------------- +#[INITJPP] +# -------------------------------------------------------------------------------------------------------------- +#TM*** + +# If oJsonPreprocessor is created here, all JSON snippets will be executed with the same JsonPreprocessor object. +# If oJsonPreprocessor is set to None, every JSON snippet is executed with an own object (that is createed within CExecutor). +# oJsonPreprocessor = None +oJsonPreprocessor = CJsonPreprocessor() + + +# -------------------------------------------------------------------------------------------------------------- +#[INITEXECUTOR] +# -------------------------------------------------------------------------------------------------------------- +#TM*** + +oExecutor = None +try: + oExecutor = CExecutor(oConfig, oCounter, oLogger, oJsonPreprocessor) +except Exception as reason: + sResult = CString.FormatResult(sMethod="(main)", bSuccess=None, sResult=str(reason)) + print() + printfailure(sResult) + print() + sys.exit(ERROR) + + +# -------------------------------------------------------------------------------------------------------------- +#[STARTOFEXECUTION] +# -------------------------------------------------------------------------------------------------------------- +#TM*** + +oSnippets = CSnippets() + +sHeadline, listCodeSnippets = oSnippets.GetSeveralParticularSnippets() +bSuccess, sResult = oExecutor.Execute(sHeadline, listCodeSnippets, "JPP") + +sHeadline, listCodeSnippets = oSnippets.GetBracketMismatch() +bSuccess, sResult = oExecutor.Execute(sHeadline, listCodeSnippets, "JPP") + +sHeadline, listCodeSnippets = oSnippets.GetDatatypePermutations() +bSuccess, sResult = oExecutor.Execute(sHeadline, listCodeSnippets, "JPP") + +sHeadline, listCodeSnippets = oSnippets.GetNestedDataTypes() +bSuccess, sResult = oExecutor.Execute(sHeadline, listCodeSnippets, "JPP") + +sHeadline, listCodeSnippets = oSnippets.GetNotExistingParams() +bSuccess, sResult = oExecutor.Execute(sHeadline, listCodeSnippets, "JPP") + +sHeadline, listCodeSnippets = oSnippets.GetKeywords() +bSuccess, sResult = oExecutor.Execute(sHeadline, listCodeSnippets, "JPP") + +sHeadline, listCodeSnippets = oSnippets.GetMissingBrackets() +bSuccess, sResult = oExecutor.Execute(sHeadline, listCodeSnippets, "JPP") + +print() +print(COLBG + "done") +print() + + +# -------------------------------------------------------------------------------------------------------------- + +# PrettyPrint(sHeadline, sPrefix="(sHeadline)") +# PrettyPrint(listCodeSnippets, sPrefix="(listCodeSnippets)") + +# -------------------------------------------------------------------------------------------------------------- +#[ENDOFEXECUTION] +# -------------------------------------------------------------------------------------------------------------- +#TM*** + + +# write HTML footer to report file +oHTMLPattern = CHTMLPattern() +oLogger.WriteReport(oHTMLPattern.GetHTMLFooter(oConfig.Get('NOW'))) +del oHTMLPattern + +del oConfig +del oLogger +del oCounter +del oExecutor + +sys.exit(SUCCESS) + +# -------------------------------------------------------------------------------------------------------------- +# -------------------------------------------------------------------------------------------------------------- + diff --git a/test/testtools/readme.rst b/test/testtools/readme.rst new file mode 100644 index 00000000..f4aca874 --- /dev/null +++ b/test/testtools/readme.rst @@ -0,0 +1,41 @@ +.. 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. + + +Code snippet generator +====================== + +GenSnippetsJPP.py + +XC-HWP/ESW3-Queckenstedt + +01.03.2024 + +**GenSnippetsJPP** generates JSONP code snippets and executes the **JsonPreprocessor** with these snippets. + +The base of the JSONP code snippets generation is mainly a combination of code patterns and lists of expressions +that are combined under several conditions. The goal is to have *stuff* to stimulate the **JsonPreprocessor**. + +The snippets together with the answers from **JsonPreprocessor** are written to a log file in text format (to support diffs) +and to a report file in HTML format (to support better readibility by colored text). + +Currently **GenSnippetsJPP** is a one-file tool; no separate configuration files, no command line parameter. + +All code pattern are defined directly within class 'CSnippets()'. + +Output files are written to script folder. + +The purpose behind this script is not to have an automated test. No valuation of results is done. +It's on the user to interprete the results. **GenSnippetsJPP** only produces these results. +