{
"id": "urn:ngsi-ld:Building:randomUUID",
"type": "Building",
"scope": "/CompanyA/OrganizationB/UnitC"
}
\ No newline at end of file
{
"id": "urn:ngsi-ld:Building:randomUUID",
"type": "Building",
"scope": ["/Madrid/Gardens/ParqueNorte", "/CompanyA/OrganizationB/UnitC"]
}
\ No newline at end of file
{
"id": "urn:ngsi-ld:Vehicle:randomUUID",
"type": "Vehicle",
"brandName": {
"type": "Property",
"value": "Mercedes"
},
"speed": [
{
"type": "Property",
"source": {
"type": "Property",
"value": "Speedometer"
},
"datasetId": "urn:ngsi-ld:Property:speedometer",
"value": 55
},
{
"type": "Property",
"source": {
"type": "Property",
"value": "GPS"
},
"datasetId": "urn:ngsi-ld:Property:gpsBxyz123-speed",
"value": 54.5
}
],
"street": {
"type": "LanguageProperty",
"languageMap": {
"fr": "Grand Place",
"nl": "Grote Markt"
}
},
"isParked": {
"type": "Relationship",
"providedBy": {
"type": "Relationship",
"object": "urn:ngsi-ld:Person:Bob"
},
"object": "urn:ngsi-ld:OffStreetParking:Downtown1",
"observedAt": "2017-07-29T12:00:04Z"
},
"@context": [
"https://forge.etsi.org/rep/cim/ngsi-ld-test-suite/-/raw/develop/resources/jsonld-contexts/ngsi-ld-test-suite-compound.jsonld"
]
}
\ No newline at end of file
{
"languageMap": {
"fr": "Grand Place",
"es": "Gran Lugar"
},
"providedBy": {
"type": "Relationship",
"object": "urn:ngsi-ld:Person:JohnDoe"
},
"@context": [
"https://forge.etsi.org/rep/cim/ngsi-ld-test-suite/-/raw/develop/resources/jsonld-contexts/ngsi-ld-test-suite-compound.jsonld"
]
}
{
"scope": "/CompanyA/OrganizationB/UnitC"
}
\ No newline at end of file
{
"street": {
"type": "LanguageProperty",
"languageMap": {
"fr": "Grand Place",
"nl": "Grote Markt"
}
},
"@context": [
"https://forge.etsi.org/rep/cim/ngsi-ld-test-suite/-/raw/develop/resources/jsonld-contexts/ngsi-ld-test-suite-compound.jsonld"
]
}
\ No newline at end of file
{
"id":"urn:ngsi-ld:Subscription:randomUUID",
"type":"Subscription",
"entities":[
{
"type":"(Building|Tower)"
}
],
"notificationTrigger": ["entityCreated"],
"notification":{
"endpoint":{
"uri":"http://my.endpoint.org/notify"
}
},
"@context":[
"https://forge.etsi.org/rep/cim/ngsi-ld-test-suite/-/raw/develop/resources/jsonld-contexts/ngsi-ld-test-suite-compound.jsonld"
]
}
\ No newline at end of file
{
"id":"urn:ngsi-ld:Vehicle:randomUUID",
"type":"Vehicle",
"street":[
{
"type": "LanguageProperty",
"languageMap": {
"fr": "Grand Place",
"nl": "Grote Markt"
},
"observedAt":"2020-08-01T12:03:00Z"
},
{
"type": "LanguageProperty",
"languageMap": {
"fr": "Grand Place",
"nl": "Grote Markt",
"es": "Gran Mercado"
},
"observedAt":"2020-08-01T12:05:00Z"
},
{
"type": "LanguageProperty",
"languageMap": {
"fr": "Grand Marché",
"nl": "Grote Markt",
"es": "Gran Lugar",
"it": "Grande Mercato"
},
"observedAt":"2020-08-01T12:07:00Z"
}
]
}
\ No newline at end of file
{
"id": "urn:ngsi-ld:Vehicle:randomUUID",
"type": "Vehicle",
"street": {
"type": "LanguageProperty",
"languageMaps": [
[
{
"languageMap": {
"fr": "Grand Place", "nl": "Grote Markt"
}
},
"2020-08-01T12:03:00Z"
],
[
{
"languageMap": {
"fr": "Grand Place", "nl": "Grote Markt", "es": "Gran Mercado" }
},
"2020-08-01T12:05:00Z"
],
[
{
"languageMap": {
"fr": "Grand Marché", "nl": "Grote Markt", "es": "Gran Lugar", "it": "Grande Mercato"
}
},
"2020-08-01T12:07:00Z"
]
]
}
}
\ No newline at end of file
{
"id": "urn:ngsi-ld:Vehicle:4656271219750725",
"type": "Vehicle",
"speed": {
"type": "Property",
"avg": [
[
100.0,
"2020-08-01T12:03:00Z",
"2020-08-01T13:03:00Z"
]
]
},
"fuelLevel": {
"type": "Property",
"avg": [
[
67.0,
"2020-08-01T12:03:00Z",
"2020-08-01T13:03:00Z"
],
[
53.0,
"2020-08-01T13:03:00Z",
"2020-08-01T14:03:00Z"
],
[
40.0,
"2020-08-01T14:03:00Z",
"2020-08-01T15:03:00Z"
]
]
}
}
\ No newline at end of file
{
"id": "urn:ngsi-ld:Vehicle:4656271219750725",
"type": "Vehicle",
"fuelLevel": {
"type": "Property",
"avg": [
[
67.0,
"2020-08-01T12:03:00Z",
"2020-08-01T13:03:00Z"
],
[
53.0,
"2020-08-01T13:03:00Z",
"2020-08-01T14:03:00Z"
],
[
40.0,
"2020-08-01T14:03:00Z",
"2020-08-01T15:03:00Z"
]
]
}
}
\ No newline at end of file
{
"id": "urn:ngsi-ld:Vehicle:4656271219750725",
"type": "Vehicle",
"speed": {
"type": "Property",
"avg": [
[
100.0,
"2020-08-01T12:03:00Z",
"2020-08-01T13:03:00Z"
]
],
"max": [
[
120.0,
"2020-08-01T12:03:00Z",
"2020-08-01T13:03:00Z"
]
]
},
"fuelLevel": {
"type": "Property",
"avg": [
[
67.0,
"2020-08-01T12:03:00Z",
"2020-08-01T13:03:00Z"
],
[
53.0,
"2020-08-01T13:03:00Z",
"2020-08-01T14:03:00Z"
],
[
40.0,
"2020-08-01T14:03:00Z",
"2020-08-01T15:03:00Z"
]
],
"max": [
[
67.0,
"2020-08-01T12:03:00Z",
"2020-08-01T13:03:00Z"
],
[
53.0,
"2020-08-01T13:03:00Z",
"2020-08-01T14:03:00Z"
],
[
40.0,
"2020-08-01T14:03:00Z",
"2020-08-01T15:03:00Z"
]
]
}
}
\ No newline at end of file
{
"id": "urn:ngsi-ld:Vehicle:7599642734962554",
"type": "Vehicle",
"speed": {
"type": "Property",
"min": [
[
80.0,
"2020-08-01T12:03:00Z",
"2020-08-02T12:03:00Z"
]
],
"max": [
[
120.0,
"2020-08-01T12:03:00Z",
"2020-08-02T12:03:00Z"
]
]
},
"fuelLevel": {
"type": "Property",
"min": [
[
40.0,
"2020-08-01T12:03:00Z",
"2020-08-02T12:03:00Z"
]
],
"max": [
[
67.0,
"2020-08-01T12:03:00Z",
"2020-08-02T12:03:00Z"
]
]
}
}
\ No newline at end of file
{
"id":"urn:ngsi-ld:Vehicle:randomUUID",
"type":"Vehicle",
"street":[
{
"type": "LanguageProperty",
"languageMap": {
"fr": "Grand Place",
"nl": "Grote Markt"
},
"observedAt":"2020-08-01T12:03:00Z"
},
{
"type": "LanguageProperty",
"languageMap": {
"fr": "Grand Place",
"nl": "Grote Markt",
"es": "Gran Mercado"
},
"observedAt":"2020-08-01T12:05:00Z"
},
{
"type": "LanguageProperty",
"languageMap": {
"fr": "Grand Marché",
"nl": "Grote Markt",
"es": "Gran Lugar",
"it": "Grande Mercato"
},
"observedAt":"2020-08-01T12:07:00Z"
}
],
"@context":[
"https://forge.etsi.org/rep/cim/ngsi-ld-test-suite/-/raw/develop/resources/jsonld-contexts/ngsi-ld-test-suite-compound.jsonld"
]
}
\ No newline at end of file
......@@ -8,6 +8,8 @@ class Checks:
Checks.check_response_status_code,
'Check Response Body Containing Array Of URIs set to':
Checks.check_response_body_containing_array_of_uris_set_to,
'Check Response Body Containing Entities URIS set to' :
Checks.check_response_body_containing_entities_uris_set_to,
'Check Created Resources Set To':
Checks.check_created_resources_set_to,
'Check Response Headers Containing Content-Type set to':
......@@ -56,8 +58,14 @@ class Checks:
Checks.check_response_body_containing_problemdetails_element_containing_type_element_set_to,
'Check Response Body Title When Using Session Request':
Checks.check_response_body_title_when_using_session_request,
'Check Response Body Containing a Boolean Attribute set to':
Checks.check_response_body_containing_a_boolean_attribute_set_to,
'Check Response Body Contains DateTime Value':
Checks.check_response_body_contains_datetime_value,
'Check Response Body Containing ProblemDetails Element Containing Title Element':
Checks.check_response_body_containing_problemdetails_element_containing_title_element,
'Check Dictionary Might Contain Additional Members of the NotificationParams':
Checks.check_dictionary_might_contain_additional_members,
'Check Response Body Containing ProblemDetails Element':
Checks.check_response_body_containing_problemdetails_element,
'Check RL Response Body Containing ProblemDetails Element Containing Type Element set to':
......@@ -106,6 +114,10 @@ class Checks:
Checks.check_response_reason_set_to,
'Check Response Does Not Contain Body':
Checks.check_response_does_not_contain_body,
'Check Response Header is Empty':
Checks.check_response_header_is_empty,
'Check Response Headers Link set to':
Checks.check_response_headers_link_set_to,
'Check Response Headers Containing NGSILD-Results-Count Equals To' :
Checks.check_response_header_contains_ngsild_results_count_equals_to,
}
......@@ -119,6 +131,10 @@ class Checks:
'params': ['expected_entities_ids', 'response_body'],
'position': [0, 1]
},
'Check Response Body Containing Entities URIS set to': {
'params': ['expected_entities_ids', 'response_body'],
'position': [0, 1]
},
'Check Response Body Containing ProblemDetails Element Containing Type Element set to': {
'params': ['type'],
'position': [1]
......@@ -139,6 +155,10 @@ class Checks:
'params': ['response_body'],
'position': [0]
},
'Check Dictionary Might Contain Additional Members of the NotificationParams': {
'params': ['dictionary', 'key'],
'position': [0, 1]
},
'Check Response Headers Containing URI set to': {
'params': ['expected_entity_id', 'response_headers'],
'position': [0, 1]
......@@ -183,6 +203,14 @@ class Checks:
'params': ['response_body'],
'position': [0]
},
'Check Response Body Containing a Boolean Attribute set to': {
'params': ['expected_attribute_name', 'response_body', 'expected_attribute_value'],
'position': [0, 1, 2]
},
'Check Response Body Contains DateTime Value': {
'params': ['dictionary', 'key', 'expected value'],
'position': [0, 1, 2]
},
'Check Response Body Containing List Containing Subscription elements': {
'params': ['file', 'id', 'response'],
'position': [0, 1, 2]
......@@ -304,6 +332,14 @@ class Checks:
'Check Response Does Not Contain Body': {
'params': ['response'],
'position': [0]
},
'Check Response Header is Empty': {
'params': ['response_headers'],
'position': [0]
},
'Check Response Headers Link set to': {
'params': ['response_headers', 'expected_link_header'],
'position': [0, 1]
}
,
'Check Response Headers Containing NGSILD-Results-Count Equals To': {
......@@ -367,6 +403,14 @@ class Checks:
return response
@staticmethod
def check_response_header_is_empty(kwargs: list) -> str:
return "The response header contains an empty dictionary"
@staticmethod
def check_response_headers_link_set_to(kwargs: list) -> str:
return f"The response headers Link is set to '{kwargs['expected_link_header']}'"
@staticmethod
def wait_for_no_notification(kwargs: list) -> str:
expected_parameters = ['timeout']
......@@ -401,6 +445,10 @@ class Checks:
def check_response_body_containing_array_of_uris_set_to(kwargs: list) -> str:
return 'Response Body set to an array of created entities ids'
@staticmethod
def check_response_body_containing_entities_uris_set_to(kwargs: list) -> str:
return 'Response Body contains entities ids'
@staticmethod
def check_created_resources_set_to(kwargs: list) -> str:
return 'Created resources set to ${entities}'
......@@ -434,6 +482,11 @@ class Checks:
else:
raise Exception(f'ERROR, Expected status_code parameter but received: {kwargs}')
@staticmethod
def check_response_body_containing_a_boolean_attribute_set_to(kwargs: list) -> str:
return (f"Check that the payload body contains a boolean attribute with name "
f"'{kwargs['expected_attribute_name']}' and value '{kwargs['expected_attribute_value']}")
@staticmethod
def check_response_headers_link_not_empty(kwargs: list) -> str:
return f'Response Header: Link is not Empty'
......@@ -450,6 +503,13 @@ class Checks:
def check_response_headers_id_not_empty(kwargs: list) -> str:
return 'Response Header: Location is not Empty'
@staticmethod
def check_dictionary_might_contain_additional_members(kwargs: list) -> str:
if 'dictionary' in kwargs and 'key' in kwargs:
return f"The dictionary `{kwargs['dictionary']}' might contain the key '{kwargs['key']}'"
else:
raise Exception(f"ERROR, Expected 'dictionary' and 'key' parameters but received: {kwargs}")
@staticmethod
def check_response_body_containing_an_attribute_set_to(kwargs: list) -> str:
expected_parameters = ['checks', 'expected_attribute_name', 'response_body', 'expected_attribute_value']
......@@ -577,6 +637,12 @@ class Checks:
else:
raise Exception(f"ERROR, expected parameters 'filename' and 'entity_ids', but received '{kwargs}'")
@staticmethod
def check_response_body_contains_datetime_value(kwargs: list) -> str:
# ${dictionary} ${key} ${expected value}
return (f"Check that the dictionary contains the key '{kwargs['key']}' with type DateTime and value set "
f"to '{kwargs['expected value']}'")
@staticmethod
def check_response_body_containing_subscription_element(kwargs: list) -> str:
if 'filename' in kwargs and 'subscription_id' in kwargs and 'response_body' in kwargs:
......@@ -765,7 +831,7 @@ class Checks:
case 'response_body':
response = f"{response} and\n Query Parameter: '{key}' set to '{value}'"
case 'ignored_keys':
response = f"{response} and\n Query Parameter: '{key}' set to '{value}'"
response = f"{response} and\n Query Parameter: '{key}' set to '{value}' list of keys"
# If an exact match is not confirmed, this last case will be used if provided
case 'checks':
pass
......@@ -911,6 +977,7 @@ if __name__ == "__main__":
print(data.get_checks(checks='Check Response Status Code',
status_code=201))
print(data.get_checks(checks='Check Response Body Containing Array Of URIs set to'))
print(data.get_checks(checks='Check Response Body Containing Entities URIS set to'))
print(data.get_checks(checks='Check Created Resources Set To'))
print(data.get_checks(checks='Check Response Headers Containing Content-Type set to',
content_type='application/json'))
......
......@@ -15,7 +15,6 @@ class GenerateRobotData:
self.config_variables = ParseVariablesFile()
self.robot = ParseRobotFile(filename=robot_file, execdir=execdir, config_file=self.config_variables)
# TODO: the robot file can provide several ApiUtils not only one
self.apiutils = [ParseApiUtilsFile(filename=file) for file in self.robot.resource_files]
self.robot.set_apiutils(self.apiutils)
......@@ -122,7 +121,39 @@ class GenerateRobotData:
# Generate the initial_condition of the test suite
self.test_suite['initial_condition'] = self.generate_initial_condition()
def generate_initial_condition(self) -> str :
# Generate the parent release and correct the reference in case that the tags include information since_v1.x.y
self.get_version()
def get_version(self):
data = [x['tags'] for x in self.test_suite['test_cases']]
aux = [item for sublist in data for item in sublist if item.startswith('since')]
if len(aux) == 0:
has_since = False
else:
has_since = True
are_all_same = all(item == aux[0] for item in aux)
if are_all_same and has_since:
aux = aux[0]
aux = aux.split('since_')[1]
else:
if has_since:
print('Error not all the tags have the same version. Select default v1.3.1')
aux = 'v1.3.1'
if 'clauses' in self.test_suite['reference']:
self.test_suite['reference'] = \
f"ETSI GS CIM 009 V{aux.split('v')[1]} [], clauses {self.test_suite['reference'].split('clauses ')[1]}"
else:
self.test_suite['reference'] = \
f"ETSI GS CIM 009 V{aux.split('v')[1]} [], clause {self.test_suite['reference'].split('clause ')[1]}"
self.test_suite['parent_release'] = aux
def generate_initial_condition(self) -> str:
aux = [x['setup'] for x in self.test_cases]
if all(element == aux[0] for element in aux[1:]):
aux = self.initial_setup.get_initial_condition(initial_condition=aux[0])
......@@ -131,7 +162,8 @@ class GenerateRobotData:
print(f'Something went wrong, the test suite {self.suite.resource.source} '
f'has different "setup" values for its test cases.')
def get_permutation_keys(self, data):
@staticmethod
def get_permutation_keys(data):
all_keys = set().union(*data)
excluded_keys = ['doc', 'permutation_tp_id', 'setup', 'teardown', 'name', 'tags']
all_keys = [x for x in all_keys if x not in excluded_keys]
......@@ -154,7 +186,7 @@ class GenerateRobotData:
def get_params(self, test_case: str):
test_case = self.get_data_template(string=test_case)
lines_starting_response = findall(r'^\s*\$\{response\}.*|^\s*\$\{notification\}.*', test_case, MULTILINE)
lines_starting_response = findall(r'^\s*\$\{response}.*|^\s*\$\{notification}.*', test_case, MULTILINE)
# If there is more than one line, it means that the test case has several operations, all of them to
# create the environment content to execute the last one, which is the correct one to test the Test Case
......@@ -171,7 +203,7 @@ class GenerateRobotData:
aux = [x for x in aux if x != '']
params = list()
request = str()
request = list()
# Get the list of params of the function, they are the keys
if ' ... ' in aux[1]:
......@@ -181,7 +213,7 @@ class GenerateRobotData:
# We are in the case that the attributes are in following lines
for i in range(1, len(aux)):
if ' ... ' in aux[i]:
regex = '(\s{4})*\s{4}\.{3}\s{4}(.*)'
regex = r'(\s{4})*\s{4}\.{3}\s{4}(.*)'
param = match(pattern=regex, string=aux[i])
if aux:
params.append(param.groups()[1])
......@@ -215,6 +247,9 @@ class GenerateRobotData:
request, params = self.get_params(test_case=string)
verb = str()
query_param = str()
url = str()
for data in self.apiutils:
verb, url, query_param = data.get_response(keyword=request)
if verb != '':
......@@ -245,6 +280,7 @@ class GenerateRobotData:
key = header_key[0]
value = self.get_header_value(key=key)
else:
aux = list()
# 2nd case, maybe the params are defined in the way <param>=<value>
for k in self.headers:
aux = [x for x in params if k in x]
......@@ -271,9 +307,9 @@ class GenerateRobotData:
data = [self.get_value_url(key=x, request=request, params=params) for x in keys]
if not query_param:
data = '/'.join(data).replace('//', '/').replace('?/','?')
data = '/'.join(data).replace('//', '/').replace('?/', '?')
else:
aux = '/'.join(data[:-1]).replace('//', '/').replace('?/','?')
aux = '/'.join(data[:-1]).replace('//', '/').replace('?/', '?')
data = f"{aux}?{data[-1]}"
return data
......@@ -374,6 +410,8 @@ class GenerateRobotData:
tp_id = self.generate_name()
reference, clauses = self.generate_reference(version=version)
# TODO: robotframework==7.0 has not property keywords in the class TestSuite(), we can get the data from
# [x.to_dict()['name'] for x in list(self.suite.resource.keywords)] but with some differences in execution code
self.test_suite = {
'tp_id': tp_id,
'test_objective': self.suite.doc,
......@@ -382,7 +420,8 @@ class GenerateRobotData:
'parent_release': version,
'clauses': clauses,
'pics_selection': str(),
'keywords': [str(x) for x in self.suite.keywords],
# 'keywords': [str(x) for x in self.suite.keywords],
'keywords': [x.to_dict()['name'] for x in list(self.suite.resource.keywords)],
'teardown': str(self.suite.teardown),
'initial_condition': str(),
'test_cases': list()
......@@ -540,7 +579,8 @@ class GenerateRobotData:
return reference, clauses
def get_substring(self, string: str, key: str):
@staticmethod
def get_substring(string: str, key: str):
pos1 = string.find(key) - 1
pos2 = string[pos1:].find('\n')
result = string[pos1:pos1+pos2].split(' ')
......
......@@ -227,12 +227,12 @@ class InitialSetup:
if len(deleted_setup) != 0:
print(f" WARNING: Some of the Setup functions were deleted:\n{deleted_setup}")
else:
print(" INFO: All current Setup functions are used in the Robot files")
print(f" INFO: All current Setup functions are used in the Robot files")
if len(not_included_keys) != 0:
print(f" ERROR: Some Setup functions are not include in the Class:\n{not_included_keys}")
else:
print(" INFO: All the current Setup functions used in Robot files are included in the Class")
print(f" INFO: All the current Setup functions used in Robot files are included in the Class")
print()
......@@ -264,14 +264,20 @@ class InitialSetup:
def get_initial_condition(self, initial_condition: str) -> str:
try:
return self.init[initial_condition]
if initial_condition is not None:
data = self.init[initial_condition]
else:
data = '''with {
the SUT containing an initial state
}'''
except KeyError:
print(f"ERROR: the initial condition '{initial_condition}' is not defined in the dictionary. "
f"Please check it and add the new initial condition.")
data = '''with {
the SUT containing an initial state
}'''
return data
return data
if __name__ == "__main__":
......
......@@ -21,10 +21,9 @@ class ParseApiUtilsFile:
string = string[index:]
string = string.split('\n')
index = None
for i, item in enumerate(string):
if 'response' in item:
regex = "\s{4}\$\{response\}=\s{4}(POST|GET|PUT|PATCH|DELETE).*"
regex = r"\s{4}\$\{response\}=\s{4}(POST|GET|PUT|PATCH|DELETE).*"
match = re.match(pattern=regex, string=item)
if match:
......@@ -35,8 +34,8 @@ class ParseApiUtilsFile:
return verb, url, query_param
@staticmethod
def get_url_request(url: str) -> list:
# We have two options, the url is defined in the same line of the response or it is defined in the following
def get_url_request(url: str) -> [list, bool]:
# We have two options, the url is defined in the same line of the response, or it is defined in the following
# lines with '...'
keys = list()
parameters = list()
......@@ -57,7 +56,7 @@ class ParseApiUtilsFile:
aux = parameters[0]
query_param = True
keys = re.split(r'\$|/', aux)
keys = re.split(r'[$/]', aux)
keys = [k for k in keys if k != '']
if len(parameters) != 0:
......@@ -68,7 +67,7 @@ class ParseApiUtilsFile:
match = re.match(pattern=regex, string=url)
if match:
aux = match.groups()[0]
keys = re.split(r'\$|/', aux)
keys = re.split(r'[$/]', aux)
keys = [k for k in keys if k != '']
return keys, query_param
......@@ -81,7 +80,7 @@ class ParseApiUtilsFile:
def get_variables_data_variables(self, string):
# Get the simple variables from the file
regex = "^(\$\{.*\})\s*(.*)\n"
regex = r"^(\$\{.*\})\s*(.*)\n"
matches = re.finditer(regex, string, re.MULTILINE)
for match in matches:
......@@ -94,7 +93,7 @@ class ParseApiUtilsFile:
def get_variables_data_dictionaries(self, string):
# Get the dictionary variables from the file
regex = '(\&\{.*\})'
regex = r'(\&\{.*\})'
matches = re.finditer(regex, string, re.MULTILINE)
for match in matches:
# Check that we have two groups matched
......@@ -109,7 +108,7 @@ class ParseApiUtilsFile:
index = aux.find('\n${')
aux = aux[:index + 1]
regex = '\.{3}[ ]*([a-zA-Z]+)=(.*)\n'
regex = r'\.{3}[ ]*([a-zA-Z]+)=(.*)\n'
matches2 = re.finditer(regex, aux, re.MULTILINE)
dict_values = dict()
for match2 in matches2:
......
......@@ -11,9 +11,16 @@ class ParseVariablesFile:
# Read the contents of the file
file_content = file.read()
# Generate a list of lines from the file content
file_content = file_content.split('\n')
# Dismiss the blank lines and the lines starting with # -> comments
file_content = [x for x in file_content if x != '' and x[0] != '#']
# Extract the key = value format of the variables
file_content = [x.split('=') for x in file_content if x != '']
# Delete the ' characters from the keys and delete blank spaces
self.variables = {x[0].strip(): x[1].replace("'", "").strip() for x in file_content}
def get_variable(self, variable: str) -> str:
......