443 lines
16 KiB
Python
443 lines
16 KiB
Python
# Copyright 2026 jCloud Services GbR
|
|
#
|
|
# 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
|
|
#
|
|
# https://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.
|
|
|
|
from src.config_parser.parse.json import parse_escape_sequences, JSONNumber, JSONString, JSONBoolean, JSONNull, JSONArray, JSONObject, parse_type, parse_json
|
|
from src.config_parser.exceptions import EscapeSequenceSyntaxError, JSONNumberSyntaxError, JSONStringSyntaxError, JSONBooleanSyntaxError, JSONNullSyntaxError, JSONArraySyntaxError, JSONObjectSyntaxError, JSONValueSyntaxError
|
|
import os
|
|
|
|
def test_parse_escape_sequences():
|
|
# Test valid escape sequences
|
|
assert parse_escape_sequences(r'Hello\nWorld') == 'Hello\nWorld'
|
|
assert parse_escape_sequences(r'Hello\tWorld') == 'Hello\tWorld'
|
|
assert parse_escape_sequences(r'Hello\\World') == 'Hello\\World'
|
|
assert parse_escape_sequences(r'Hello\"World\"') == 'Hello"World"'
|
|
assert parse_escape_sequences(r'Hello\/World') == 'Hello/World'
|
|
assert parse_escape_sequences(r'Hello\bWorld') == 'Hello\bWorld'
|
|
assert parse_escape_sequences(r'Hello\fWorld') == 'Hello\fWorld'
|
|
assert parse_escape_sequences(r'Hello\rWorld') == 'Hello\rWorld'
|
|
assert parse_escape_sequences(r'Hello\u0041World') == 'HelloAWorld'
|
|
|
|
# Test invalid escape sequences
|
|
try:
|
|
parse_escape_sequences(r'Hello\qWorld')
|
|
assert False, 'Expected EscapeSequenceSyntaxError'
|
|
except EscapeSequenceSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
parse_escape_sequences(r'Hello\u00G1World')
|
|
assert False, 'Expected EscapeSequenceSyntaxError'
|
|
except EscapeSequenceSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
parse_escape_sequences(r'\u123')
|
|
assert False, 'Expected EscapeSequenceSyntaxError'
|
|
except EscapeSequenceSyntaxError:
|
|
pass
|
|
|
|
def test_parse_number():
|
|
# Test parsing integers
|
|
assert JSONNumber.parse('0').value == 0
|
|
assert JSONNumber.parse('42').value == 42
|
|
assert JSONNumber.parse('-42').value == -42
|
|
|
|
# Test parsing floats
|
|
assert JSONNumber.parse('0.0').value == 0.0
|
|
assert JSONNumber.parse('3.14').value == 3.14
|
|
assert JSONNumber.parse('-3.14').value == -3.14
|
|
|
|
# Test exceptions
|
|
try:
|
|
JSONNumber.parse('abc')
|
|
assert False, 'Expected JSONNumberSyntaxError'
|
|
except JSONNumberSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
JSONNumber.parse('01')
|
|
assert False, 'Expected JSONNumberSyntaxError'
|
|
except JSONNumberSyntaxError:
|
|
pass
|
|
|
|
def test_parse_str():
|
|
# Test parsing strings
|
|
assert JSONString.parse('"Hello, World!"').value == 'Hello, World!'
|
|
assert JSONString.parse(r'"Hello,\nWorld!"').value == 'Hello,\nWorld!'
|
|
assert JSONString.parse(r'"Hello,\\World!"').value == 'Hello,\\World!'
|
|
|
|
# Test exceptions
|
|
try:
|
|
JSONString.parse('\'Hello, World!\'')
|
|
assert False, 'Excepted JSONStringSyntaxError'
|
|
except JSONStringSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
JSONString.parse('"Hello, World!')
|
|
assert False, 'Excepted JSONStringSyntaxError'
|
|
except JSONStringSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
JSONString.parse('Hello, World!"')
|
|
assert False, 'Excepted JSONStringSyntaxError'
|
|
except JSONStringSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
JSONString.parse('Hello, World!')
|
|
assert False, 'Excepted JSONStringSyntaxError'
|
|
except JSONStringSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
JSONString.parse('""Hello, World!"')
|
|
assert False, 'Excepted JSONStringSyntaxError'
|
|
except JSONStringSyntaxError:
|
|
pass
|
|
|
|
def test_parse_boolean():
|
|
# Test parsing booleans
|
|
assert JSONBoolean.parse('true').value == True
|
|
assert JSONBoolean.parse('false').value == False
|
|
|
|
# Test exceptions
|
|
try:
|
|
JSONBoolean.parse('True')
|
|
assert False, 'Expected JSONBooleanSyntaxError'
|
|
except JSONBooleanSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
JSONBoolean.parse('False')
|
|
assert False, 'Expected JSONBooleanSyntaxError'
|
|
except JSONBooleanSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
JSONBoolean.parse('')
|
|
assert False, 'Expected JSONBooleanSyntaxError'
|
|
except JSONBooleanSyntaxError:
|
|
pass
|
|
|
|
def test_parse_null():
|
|
# Test parsing null
|
|
assert JSONNull.parse('null').value is None
|
|
|
|
# Test exceptions
|
|
try:
|
|
JSONNull.parse('NULL')
|
|
assert False, 'Expected JSONNullSyntaxError'
|
|
except JSONNullSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
JSONNull.parse('Null')
|
|
assert False, 'Expected JSONNullSyntaxError'
|
|
except JSONNullSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
JSONNull.parse('')
|
|
assert False, 'Expected JSONNullSyntaxError'
|
|
except JSONNullSyntaxError:
|
|
pass
|
|
|
|
def test_parse_array():
|
|
# Test parsing arrays
|
|
assert JSONArray.parse('[]').value == []
|
|
assert JSONArray.parse('[1, 2, 3]').value == [1, 2, 3]
|
|
assert JSONArray.parse('[1, "2", true, null]').value == [1, '2', True, None]
|
|
assert JSONArray.parse(r'[1, "2", true, null]').value == [1, '2', True, None]
|
|
|
|
# Test exceptions
|
|
try:
|
|
JSONArray.parse('[')
|
|
assert False, 'Expected JSONArraySyntaxError'
|
|
except JSONArraySyntaxError:
|
|
pass
|
|
|
|
try:
|
|
JSONArray.parse('[1, 2')
|
|
assert False, 'Expected JSONArraySyntaxError'
|
|
except JSONArraySyntaxError:
|
|
pass
|
|
|
|
def test_parse_object():
|
|
# Test parsing objects
|
|
assert JSONObject.parse('{}').value == {}
|
|
assert JSONObject.parse('{"key": "value"}').value == {'key': 'value'}
|
|
assert JSONObject.parse('{"key1": 1, "key2": "value2", "key3": true, "key4": null}').value == {'key1': 1, 'key2': 'value2', 'key3': True, 'key4': None}
|
|
assert JSONObject.parse(r'{"key1": 1, "key2": "value2", "key3": true, "key4": null}').value == {'key1': 1, 'key2': 'value2', 'key3': True, 'key4': None}
|
|
|
|
with open(os.path.dirname(__file__) + '/test.json') as jsonf:
|
|
assert JSONObject.parse(jsonf.read()).value == {
|
|
"level_1": {
|
|
"meta": {
|
|
"version": "1.0",
|
|
"generated": True,
|
|
"tags": ["test", "deep", "nested", "json"],
|
|
},
|
|
"level_2": {
|
|
"array": [
|
|
{
|
|
"id": 1,
|
|
"level_3": {
|
|
"level_4": {
|
|
"level_5": {
|
|
"config": {
|
|
"enabled": True,
|
|
"thresholds": {
|
|
"low": 0.1,
|
|
"medium": 0.5,
|
|
"high": 0.9,
|
|
},
|
|
"modes": [
|
|
{
|
|
"name": "alpha",
|
|
"params": {
|
|
"retry": 3,
|
|
"timeout": {
|
|
"connect": 1000,
|
|
"read": 5000,
|
|
"deep": {
|
|
"even_deeper": {
|
|
"flag": False,
|
|
"notes": [
|
|
"still",
|
|
"going",
|
|
{
|
|
"deeper": {
|
|
"than": {
|
|
"most": {
|
|
"humans": {
|
|
"expect": {
|
|
"value": 42
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
],
|
|
}
|
|
},
|
|
},
|
|
},
|
|
}
|
|
],
|
|
}
|
|
}
|
|
}
|
|
},
|
|
}
|
|
],
|
|
"level_2_object": {
|
|
"a": {
|
|
"b": {
|
|
"c": {
|
|
"d": {
|
|
"e": {
|
|
"f": {
|
|
"g": {
|
|
"h": {
|
|
"i": {
|
|
"j": {
|
|
"k": "bottom"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
},
|
|
},
|
|
"level3": {
|
|
"root": [
|
|
[
|
|
[
|
|
[
|
|
{
|
|
"a": [
|
|
{
|
|
"b": [
|
|
{
|
|
"c": [
|
|
{
|
|
"d": [
|
|
{
|
|
"e": [
|
|
{
|
|
"f": "bottom"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
]
|
|
]
|
|
]
|
|
},
|
|
"4": {
|
|
"level": {
|
|
"level": {
|
|
"level": {
|
|
"level": {
|
|
"level": {
|
|
"items": [
|
|
{"x": {"y": {"z": [1, 2, 3, 4, 5]}}},
|
|
{"x": {"y": {"z": [1, 2, 3, 4, 5]}}},
|
|
{"x": {"y": {"z": [1, 2, 3, 4, 5]}}},
|
|
{"x": {"y": {"z": [1, 2, 3, 4, 5]}}},
|
|
{"x": {"y": {"z": [1, 2, 3, 4, 5]}}},
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"0": {
|
|
"n0": {
|
|
"n1": {
|
|
"n2": {
|
|
"n3": {
|
|
"n4": {
|
|
"n5": {
|
|
"n6": {
|
|
"n7": {
|
|
"n8": {
|
|
"n9": {
|
|
"n10": {
|
|
"n11": {
|
|
"n12": {
|
|
"n13": {
|
|
"n14": {
|
|
"n15": {
|
|
"n16": {
|
|
"n17": {
|
|
"n18": {
|
|
"n19": {
|
|
"n20": "bottom"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
}
|
|
|
|
jsonf.close()
|
|
|
|
# Test exceptions
|
|
|
|
def test_parse_type():
|
|
# Test detecting types
|
|
assert parse_type('42') == JSONNumber
|
|
assert parse_type('"abc"') == JSONString
|
|
assert parse_type('true') == JSONBoolean
|
|
assert parse_type('false') == JSONBoolean
|
|
assert parse_type('null') == JSONNull
|
|
assert parse_type('[1, 2, 3, "4", "5", "6", true, false, null]') == JSONArray
|
|
assert parse_type('{"1": 2}') == JSONObject
|
|
assert parse_type('{"1": \n\t 2 }') == JSONObject # test whitespaces
|
|
|
|
# Test very large data
|
|
with open(os.path.dirname(__file__) + '/test.json', 'r') as jsonf:
|
|
assert parse_type('[' + jsonf.read() + ']') == JSONArray
|
|
jsonf.close()
|
|
|
|
# Test exceptions
|
|
try:
|
|
parse_type('abc')
|
|
assert False, 'Expected JSONValueSyntaxError'
|
|
except JSONValueSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
parse_type('1s')
|
|
assert False, 'Expected JSONValueSyntaxError'
|
|
except JSONValueSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
parse_type('[')
|
|
assert False, 'Expected JSONArraySyntaxError'
|
|
except JSONArraySyntaxError:
|
|
pass
|
|
|
|
try:
|
|
parse_type('[a b]')
|
|
assert False, 'Expected JSONValueSyntaxError'
|
|
except JSONValueSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
parse_type('"abc"abc')
|
|
assert False, 'Expected JSONStringSyntaxError'
|
|
except JSONStringSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
parse_type('\'abc\'abc')
|
|
assert False, 'Expected JSONValueSyntaxError'
|
|
except JSONValueSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
parse_type('{1: 2}')
|
|
assert False, 'Expected JSONObjectSyntaxError'
|
|
except JSONObjectSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
parse_type('{"1"}')
|
|
assert False, 'Expected JSONObjectSyntaxError'
|
|
except JSONObjectSyntaxError:
|
|
pass
|
|
|
|
def test_parse_json():
|
|
# Test parsing JSON
|
|
assert parse_json('{"key": "value"}') == {'key': 'value'}
|
|
assert parse_json('[1, 2, 3]') == [1, 2, 3]
|
|
assert parse_json('{"key1": 1, "key2": "value2", "key3": true, "key4": null}') == {'key1': 1, 'key2': 'value2', 'key3': True, 'key4': None}
|
|
assert parse_json(r'{"key1": 1, "key2": "value2", "key3": true, "key4": null}') == {'key1': 1, 'key2': 'value2', 'key3': True, 'key4': None} |