246 lines
6.9 KiB
Python
246 lines
6.9 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.jcloud_config_parser.json import JSONConfiguration
|
|
from src.jcloud_config_parser.exceptions import JSONObjectSyntaxError, JSONValueSyntaxError, JSONStringSyntaxError, JSONArraySyntaxError, EscapeSequenceSyntaxError
|
|
from src.jcloud_config_parser import set_mutability
|
|
|
|
def test_json_configuration():
|
|
# Test valid JSON configuration parsing
|
|
assert dict(JSONConfiguration.from_string('{"key1": "value1", "key2": 42, "key3": true, "key4": {"k1": 42, "k2": [1, null, true]}}')) == {"key1": "value1", "key2": 42, "key3": True, "key4": {"k1": 42, "k2": [1, None, True]}}
|
|
assert dict(JSONConfiguration.from_string('''{
|
|
"name": "John Doe",
|
|
"active": true,
|
|
"score": 99.5,
|
|
"roles": ["admin", "developer"],
|
|
"meta": null
|
|
}''')) == {'name': 'John Doe', 'active': True, 'score': 99.5, 'roles': ['admin', 'developer'], 'meta': None}
|
|
assert dict(JSONConfiguration.from_string('''{
|
|
"items": [],
|
|
"config": {},
|
|
"enabled": false
|
|
}''')) == {'items': [], 'config': {}, 'enabled': False}
|
|
assert dict(JSONConfiguration.from_string('''{
|
|
"int": 1,
|
|
"float": 1.0,
|
|
"scientific": 1e3,
|
|
"negative": -42
|
|
}''')) == {
|
|
'int': 1,
|
|
'float': 1.0,
|
|
'scientific': 1000.0,
|
|
'negative': -42
|
|
}
|
|
assert dict(JSONConfiguration.from_string('''{
|
|
"text": "🌍",
|
|
"escaped": "Line1\\nLine2\\tTabbed",
|
|
"unicode_escape": "\u263A"
|
|
}''')) == {
|
|
'text': '🌍',
|
|
'escaped': 'Line1\nLine2\tTabbed',
|
|
'unicode_escape': '☺'
|
|
}
|
|
assert dict(JSONConfiguration.from_string('''{"m": [
|
|
{ "id": 1, "value": "a" },
|
|
{ "id": 2, "value": "b" },
|
|
{ "id": 3, "value": null }
|
|
]}
|
|
''')) == {
|
|
'm': [
|
|
{'id': 1, 'value': 'a'},
|
|
{'id': 2, 'value': 'b'},
|
|
{'id': 3, 'value': None},
|
|
]
|
|
}
|
|
assert dict(JSONConfiguration.from_string('''{
|
|
"1": "one",
|
|
"true": "yes",
|
|
"null": "nothing"
|
|
}
|
|
''')) == {
|
|
'1': 'one',
|
|
'true': 'yes',
|
|
'null': 'nothing'
|
|
}
|
|
assert dict(JSONConfiguration.from_string('''{
|
|
"a": {
|
|
"b": {
|
|
"c": {
|
|
"d": [1, 2, {"e": false}]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
''')) == {
|
|
'a': {
|
|
'b': {
|
|
'c': {
|
|
'd': [1, 2, {'e': False}]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
assert dict(JSONConfiguration.from_string('''{
|
|
"x": 1,
|
|
"x": 2,
|
|
"x": 3
|
|
}
|
|
''')) == {'x': 3}
|
|
assert dict(JSONConfiguration.from_string('''{"nested": [[[[[[[[[[[[[[[[[[[[0]]]]]]]]]]]]]]]]]]]]}''')) == {'nested': [[[[[[[[[[[[[[[[[[[[0]]]]]]]]]]]]]]]]]]]]}
|
|
assert dict(JSONConfiguration.from_string('''{
|
|
"id": 9007199254740993
|
|
}
|
|
''')) == {'id': 9007199254740993}
|
|
assert dict(JSONConfiguration.from_string('''{
|
|
"value": 0.1
|
|
}''')) == {'value': 0.1}
|
|
assert dict(JSONConfiguration.from_string('{ "x": null }')) == {'x': None}
|
|
assert dict(JSONConfiguration.from_string('{}')) == {}
|
|
assert dict(JSONConfiguration.from_string('''{
|
|
"a": "",
|
|
"b": null
|
|
}
|
|
|
|
''')) == {'a': '', 'b': None}
|
|
assert dict(JSONConfiguration.from_string('''{
|
|
"char1": "é",
|
|
"char2": "e\u0301"
|
|
}''')) == {
|
|
'char1': 'é',
|
|
'char2': 'é'
|
|
}
|
|
assert dict(JSONConfiguration.from_string('''{
|
|
"text": "hello\u0000world"
|
|
}''')) == {'text': 'hello\x00world'}
|
|
assert dict(JSONConfiguration.from_string('''{
|
|
"enabled": "false"
|
|
}
|
|
''')) == {'enabled': 'false'}
|
|
assert dict(JSONConfiguration.from_string('''{"array": [1, "1", true, null, {}, []]
|
|
}''')) == {'array': [1, '1', True, None, {}, []]}
|
|
assert dict(JSONConfiguration.from_string('''{ "a" :
|
|
[ 1 ,2
|
|
,3 ] }
|
|
|
|
''')) == {'a': [1, 2, 3]}
|
|
|
|
# Test exceptions
|
|
try:
|
|
JSONConfiguration.from_string('{"a": 1,}')
|
|
assert False, 'Excepted JSONObjectSyntaxError'
|
|
except JSONObjectSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
JSONConfiguration.from_string('''{
|
|
// Comment
|
|
"a": 1
|
|
}''')
|
|
assert False, 'Excepted JSONObjectSyntaxError'
|
|
except JSONObjectSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
JSONConfiguration.from_string('{"a": 1 /* Comment */}')
|
|
assert False, 'Excepted JSONObjectSyntaxError'
|
|
except JSONObjectSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
JSONConfiguration.from_string('{a: 1}')
|
|
assert False, 'Excepted JSONValueSyntaxError'
|
|
except JSONValueSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
JSONConfiguration.from_string('{\'a\': \'b\'}')
|
|
assert False, 'Excepted JSONObjectSyntaxError'
|
|
except JSONObjectSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
JSONConfiguration.from_string('{"x": 012}')
|
|
assert False, 'Excepted JSONValueSyntaxError'
|
|
except JSONValueSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
JSONConfiguration.from_string('{"x": NaN, "y": Infinity}')
|
|
assert False, 'Excepted JSONValueSyntaxError'
|
|
except JSONValueSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
JSONConfiguration.from_string('{"text": "hello\nworld"}') # This is not a JSON escape sequence!
|
|
assert False, 'Excepted JSONStringSyntaxError'
|
|
except JSONStringSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
JSONConfiguration.from_string('{"x": "\q"}')
|
|
assert False, 'Excepted EscapeSequenceSyntaxError'
|
|
except EscapeSequenceSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
JSONConfiguration.from_string('{"x": "\\u123"}')
|
|
assert False, 'Excepted EscapeSequenceSyntaxError'
|
|
except EscapeSequenceSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
JSONConfiguration.from_string('{ "a": 1 } { "b": 2 }')
|
|
assert False, 'Excepted JSONObjectSyntaxError'
|
|
except JSONObjectSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
JSONConfiguration.from_string('{"a": 1 "b": 2}')
|
|
assert False, 'Excepted JSONObjectSyntaxError'
|
|
except JSONObjectSyntaxError:
|
|
pass
|
|
|
|
try:
|
|
JSONConfiguration.from_string('{"a": [1, 2, 3}')
|
|
assert False, 'Excepted JSONArraySyntaxError'
|
|
except JSONArraySyntaxError:
|
|
pass
|
|
|
|
try:
|
|
JSONConfiguration.from_string('')
|
|
assert False, 'Excepted JSONValueSyntaxError'
|
|
except JSONValueSyntaxError:
|
|
pass
|
|
|
|
def test_mutability():
|
|
config = JSONConfiguration(mutable=False)
|
|
try:
|
|
config.key = 'value'
|
|
assert False, 'Expected TypeError'
|
|
except TypeError:
|
|
pass
|
|
|
|
set_mutability(config, True)
|
|
assert config._mutable == True
|
|
|
|
config.key = 'value'
|
|
|
|
set_mutability(config, False)
|
|
assert config._mutable == False
|
|
|
|
try:
|
|
del config.key
|
|
assert False, 'Expected TypeError'
|
|
except TypeError:
|
|
pass |