Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 35 additions & 26 deletions JsonPreprocessor/CJsonPreprocessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -717,10 +717,6 @@ def __loadNestedValue(initValue: str, sInputStr: str, bKey=False, key=''):
initValue = initValue.replace(CNameMangling.STRINGCONVERT.value, '')
elif re.match(r"^\s*" + pattern + r"\s*$", sInputStr, re.UNICODE):
sInputStr = re.sub("\$", "$$", sInputStr)
if sInputStr.count("${") > sInputStr.count("}"):
self.__reset()
raise Exception(f"Invalid syntax! One or more than one opened or closed curly bracket is missing in expression '{initValue}'.\n \
Please check the configuration file of the executed test!")
sInputStr = self.__checkParamName(sInputStr)
handledValue = self.__nestedParamHandler(sInputStr) if not bValueConvertString else \
self.__nestedParamHandler(sInputStr, bKey=bKey, bConvertToStr=bValueConvertString)
Expand Down Expand Up @@ -912,12 +908,12 @@ def __recursiveNestedHandling(sInputStr: str, lNestedParam: list) -> str:
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"(?<!^)(?<!\.)[^\.]\${", sInputStr.strip()) and not nestedKey)) \
and re.search("(" + nestedPattern + ")*", sInputStr, re.UNICODE):
and re.search("(" + nestedPattern + ")", sInputStr, re.UNICODE):
if sInputStr.strip()[-1] == ",":
sInputStr = sInputStr.strip()[:-2] + CNameMangling.STRINGCONVERT.value + "\","
else:
sInputStr = sInputStr.strip()[:-1] + CNameMangling.STRINGCONVERT.value + "\""
elif "," in sInputStr:
elif "," in sInputStr.strip()[:-1]:
if not re.match(r"^\s*\".+\"\s*$", sInputStr):
self.__reset()
raise Exception(f"Invalid nested parameter format: {sInputStr} - The double quotes are missing!!!")
Expand Down Expand Up @@ -947,16 +943,13 @@ def __recursiveNestedHandling(sInputStr: str, lNestedParam: list) -> str:
self.lNestedParams.append(nestedParam)
newInputStr = newInputStr + item if tmpItem==items[len(items)-1] else newInputStr + item + ","
sInputStr = newInputStr
elif re.search(r"\${\s*}", sInputStr) \
or (nestedKey and (sInputStr.count("{") != sInputStr.count("}") or sInputStr.count("[") != sInputStr.count("]"))):
self.__reset()
raise Exception(f"Invalid parameter format: {sInputStr}")
elif nestedKey and re.match(r"^\s*\${[^\(\)\!@#%\^\&\-\+\/\\\=`~\?]+[}\[\]]+\s*$", sInputStr):
sInputStr = re.sub(r"^\s*(\${[^\(\)\!@#%\^\&\-\+\/\\\=`~\?]+[}\[\]]+)\s*$", "\"\\1\"", sInputStr)
else:
self.__reset()
raise Exception(f"Invalid nested parameter format: {sInputStr} - The double quotes are missing!!!")

elif not re.match(r"^\s*\".+\"[,\s]*$", sInputStr):
if not re.match(r"^.+,\s*$", sInputStr):
sInputStr = re.sub(r"^\s*(.+)\s*$", "\"\\1\"", sInputStr)
else:
sInputStr = re.sub(r"^\s*(.+)\s*,\s*$", "\"\\1\",", sInputStr)
sOutput = sInputStr
return sOutput

Expand Down Expand Up @@ -996,17 +989,22 @@ def __checkNestedParam(self, sInput : str, bKey=False) -> bool:

*raise exception if nested parameter format invalid*
"""
pattern = rf"^\${{\s*[^{re.escape(self.specialCharacters)}]+}}(\[.*\])+$"
pattern = rf"^\${{\s*[^{re.escape(self.specialCharacters)}]+\s*}}(\[.*\])+$"
pattern1 = rf"\${{.+}}(\[.+\])*[^\[]*\${{"
pattern2 = r"\${.*\${.*}"
if "${" not in sInput:
return True
if re.search(rf"\${{\s*[^{re.escape(self.specialCharacters)}]+\['*.+'*\].*}}", sInput, re.UNICODE):
if CNameMangling.STRINGCONVERT.value in sInput:
sInput = sInput.replace(CNameMangling.STRINGCONVERT.value, "")
errorMsg = f"Invalid syntax: Found index or sub-element inside curly brackets in the parameter '{sInput}'"
raise Exception(errorMsg)
elif re.search(r"\[[0-9\s]*[A-Za-z_]+[0-9\s]*\]", sInput, re.UNICODE):
elif re.search(r"\[[0-9\s]*[A-Za-z_]+[0-9\s]*\]", sInput, re.UNICODE) and \
CNameMangling.STRINGCONVERT.value in sInput:
errorMsg = f"Invalid syntax! A sub-element in {sInput.strip()} has to enclosed in quotes."
self.__reset()
raise Exception(errorMsg)
elif re.search(r'\[\s*\]', sInput):
elif re.search(r'\[\s*\]', sInput) and CNameMangling.STRINGCONVERT.value in sInput:
if CNameMangling.STRINGCONVERT.value not in sInput or \
re.match(pattern, sInput.replace(CNameMangling.STRINGCONVERT.value, "")):
errorMsg = f"Expression '{sInput.replace(CNameMangling.STRINGCONVERT.value, '')}' cannot be evaluated. \
Expand All @@ -1015,6 +1013,25 @@ def __checkNestedParam(self, sInput : str, bKey=False) -> bool:
raise Exception(errorMsg)
else:
return True
elif CNameMangling.STRINGCONVERT.value in sInput:
if sInput.count("${") > sInput.count("}"):
sInput = re.sub(CNameMangling.STRINGCONVERT.value, "", sInput)
errorMsg = f"Invalid nested parameter format: {sInput.strip()}"
self.__reset()
raise Exception(errorMsg)
else:
return True
elif CNameMangling.STRINGCONVERT.value not in sInput and \
CNameMangling.DUPLICATEDKEY_01.value not in sInput:
if not re.match(r"^\${.+[}\]]+$", sInput) or (re.search(pattern1, sInput) and not bKey):
errorMsg = f"Invalid nested parameter format: {sInput} - The double quotes are missing!!!"
else:
if sInput.count("{") != sInput.count("}") or sInput.count("[") != sInput.count("]"):
errorMsg = f"Invalid nested parameter format: {sInput.strip()}"
else:
return True
self.__reset()
raise Exception(errorMsg)
else:
return True

Expand Down Expand Up @@ -1150,7 +1167,7 @@ def __checkKeynameFormat(oJson : dict):
self.__reset()
raise Exception(f"\n{str(error)} in line: '{line}'")

if re.search(pattern, line, re.UNICODE):
if "${" in line:
lNestedVar = re.findall(rf"\${{\s*([^{re.escape(self.specialCharacters)}]+)\s*}}", line, re.UNICODE)
for nestedVar in lNestedVar:
if nestedVar[0].isdigit():
Expand Down Expand Up @@ -1221,14 +1238,6 @@ def __checkKeynameFormat(oJson : dict):
self.lNestedParams.remove(nestedParam)
sJsonDataUpdated = sJsonDataUpdated + newLine + "\n"
else:
if "${" in line:
self.__reset()
invalidPattern1 = r"\${\s*[0-9A-Za-z\._]*\[.+\][0-9A-Za-z\._]*\s*}"
if re.search(invalidPattern1, line):
raise Exception(f"Invalid syntax: Found index inside curly brackets in line '{line.strip()}'. \
Indices in square brackets have to be placed outside the curly brackets.")
else:
raise Exception(f"Invalid parameter format in line: {line.strip()}")
sJsonDataUpdated = sJsonDataUpdated + line + "\n"

CJSONDecoder = None
Expand Down
Binary file modified JsonPreprocessor/JsonPreprocessor.pdf
Binary file not shown.
4 changes: 2 additions & 2 deletions JsonPreprocessor/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@
#
# Version and date of JsonPreprocessor
#
VERSION = "0.3.3"
VERSION_DATE = "23.01.2024"
VERSION = "0.4.0"
VERSION_DATE = "15.03.2024"

8 changes: 8 additions & 0 deletions packagedoc/additional_docs/History.tex
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,12 @@
- Improved format of nested parameters; improved error messages\newline
- Added getVersion and getVersionDate methods to get current version and the date of the version}

\historyversiondate{0.4.0}{03/2024}
\historychange{- Optimized regular expression patterns\newline
- Improved duplicated parameters handling\newline
- Added mechanism to prevent Python application freeze\newline
- Removed globals scope out of all exec method executions\newline
- Optimized errors handling while loading nested parameters\newline
- Fixed bugs}

\end{packagehistory}
3 changes: 2 additions & 1 deletion test/JPP_TestUsecases.csv
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ JPP_0005|DATA_TYPES|GOODCASE|JSON file with string values containing dollar oper
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
JPP_0102|DATA_INTEGRITY|GOODCASE|JSON file with string containing more special characters, masked special characters and escape sequences
JPP_0103|DATA_INTEGRITY|GOODCASE|JSON file with strings containing several pairs of square brackets (that must not cause syntax issues!)
JPP_0200|PARAMETER_SUBSTITUTION|GOODCASE|JSON file with nested parameter / string parameter substitution in parameter value
JPP_0201|PARAMETER_SUBSTITUTION|GOODCASE|JSON file with nested parameter / string parameter substitution in parameter name
JPP_0202|PARAMETER_SUBSTITUTION|GOODCASE|JSON file with nested parameter / index parameter substitution in parameter name / standard notation
Expand Down Expand Up @@ -79,7 +80,7 @@ JPP_0512|COMPOSITE_EXPRESSIONS|GOODCASE|JSON file containing a nested use of lis
JPP_0513|COMPOSITE_EXPRESSIONS|GOODCASE|JSON file containing several square bracket expressions (as list index and dictionary key) with and without single quotes
JPP_0514|COMPOSITE_EXPRESSIONS|GOODCASE|JSON file containing nested dollar operator expressions
JPP_0515|COMPOSITE_EXPRESSIONS|GOODCASE|JSON file containing nested dollar operator expressions
JPP_0516|COMPOSITE_EXPRESSIONS|GOODCASE|JSON file containing string expressions with additional curly brackets and dollar characters (that must not cause syntax issues!)
JPP_0516|COMPOSITE_EXPRESSIONS|GOODCASE|JSON file containing string expressions with additional brackets and dollar characters (that must not cause syntax issues!)
JPP_0550|COMPOSITE_EXPRESSIONS|BADCASE|JSON file with composite data structure (nested lists and dictionaries / some key names with dots inside)
JPP_0551|COMPOSITE_EXPRESSIONS|BADCASE|JSON file containing a list; list index is defined by a parameter and wrapped in single quotes
JPP_0552|COMPOSITE_EXPRESSIONS|BADCASE|JSON file containing a list; list index is defined by a parameter and placed inside the curly brackets (invalid syntax)
Expand Down
Loading