Skip to content

Commit

Permalink
Add tests for JSON decoder
Browse files Browse the repository at this point in the history
  • Loading branch information
dev0x13 committed Oct 8, 2023
1 parent 7a747b6 commit 84194ed
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 0 deletions.
1 change: 1 addition & 0 deletions test/json/invalid1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
'123'
1 change: 1 addition & 0 deletions test/json/invalid2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name": "Joe", "age": null, }
4 changes: 4 additions & 0 deletions test/json/invalid3.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"1234": "123",
123
}
4 changes: 4 additions & 0 deletions test/json/non-string-map-key.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"key": "value",
2: "value"
}
7 changes: 7 additions & 0 deletions test/json/simple.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"key": "value",
"key1": 0,
"key2": 1.0,
"key3": ["123", 123, {"test": 1}, []],
"key4": {"123": 123, "456": []}
}
1 change: 1 addition & 0 deletions test/json/valid1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"123"
107 changes: 107 additions & 0 deletions test/test_aux_json_decoder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import os
import json
import pytest

from pywuffs import *
from pywuffs.aux import *

JSON_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "json/")

# Positive test cases


def assert_decoded(result, encoded=None, file=None):
assert encoded or file
assert len(result.error_message) == 0
assert result.cursor_position != 0
if file:
with open(file, "rb") as f:
encoded = f.read()
if encoded:
assert result.parsed == json.loads(encoded.decode("utf-8"))


@pytest.mark.parametrize("file_path", [
(JSON_PATH + "/simple.json"),
(JSON_PATH + "/valid1.json"),
])
def test_decode_default_config(file_path):
config = JsonDecoderConfig()
decoder = JsonDecoder(config)
decoding_result_from_file = decoder.decode(file_path)
assert_decoded(decoding_result_from_file, file=file_path)
with open(file_path, "rb") as f:
data = f.read()
decoding_result_from_bytes = decoder.decode(data)
assert_decoded(decoding_result_from_bytes, encoded=data)
assert decoding_result_from_bytes.error_message == decoding_result_from_file.error_message
assert decoding_result_from_bytes.parsed == decoding_result_from_file.parsed
assert decoding_result_from_bytes.cursor_position == decoding_result_from_file.cursor_position


def test_decode_json_quirks():
config = JsonDecoderConfig()
config.quirks = [JsonDecoderQuirks.ALLOW_COMMENT_BLOCK,
JsonDecoderQuirks.ALLOW_EXTRA_COMMA]
decoder = JsonDecoder(config)
data = b"{\"test\": \"value\", \"test1\": 123,}"
decoding_result = decoder.decode(data)
assert_decoded(decoding_result, encoded=data[:-2] + b"}")


def test_decode_json_pointer():
data = {"key1": 1, "key2": [2, 3], "key3": "value"}
config = JsonDecoderConfig()
config.json_pointer = "/key2"
decoder = JsonDecoder(config)
decoding_result = decoder.decode(bytes(json.dumps(data), "utf-8"))
assert_decoded(decoding_result, encoded=bytes(
json.dumps(data["key2"]), "utf-8"))

# Negative test cases


def assert_not_decoded(result, expected_error_message=None):
assert len(result.error_message) != 0
if expected_error_message:
assert result.error_message == expected_error_message
assert result.parsed is None


def test_decode_non_existent_file():
decoder = JsonDecoder(JsonDecoderConfig())
decoding_result = decoder.decode("random123")
assert_not_decoded(decoding_result, JsonDecoderError.FailedToOpenFile)


@pytest.mark.parametrize("param", [
(b"+(=)", JsonDecoderError.BadDepth),
(b"test", JsonDecoderError.BadDepth),
(b"{\"val\":" + b"1"*130 + b"}", JsonDecoderError.UnsupportedNumberLength),
(b"{\"val\": 1, \"val\": 2}", JsonDecoderError.DuplicateMapKey + "val"),
])
def test_decode_invalid_bytes(param):
decoder = JsonDecoder(JsonDecoderConfig())
decoding_result = decoder.decode(param[0])
assert_not_decoded(decoding_result, param[1])


@pytest.mark.parametrize("param", [
(JSON_PATH + "/invalid1.json", JsonDecoderError.BadDepth),
(JSON_PATH + "/invalid2.json", JsonDecoderError.BadInput),
(JSON_PATH + "/invalid3.json", JsonDecoderError.BadInput),
(JSON_PATH + "/non-string-map-key.json", JsonDecoderError.BadInput)
])
def test_decode_invalid_file(param):
decoder = JsonDecoder(JsonDecoderConfig())
decoding_result = decoder.decode(param[0])
assert_not_decoded(decoding_result, param[1])


def test_decode_invalid_json_pointer():
data = {"key1": 1, "key2": [2, 3], "key3": "value"}
config = JsonDecoderConfig()
config.json_pointer = "/random"
decoder = JsonDecoder(config)
decoding_result = decoder.decode(bytes(json.dumps(data), "utf-8"))
assert_not_decoded(decoding_result, JsonDecoderError.BadDepth)

0 comments on commit 84194ed

Please sign in to comment.