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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
- Customizable parser strictness including support for non-standard extensions
- Well-defined handling of malformed / malicious inputs with configurable parsing limits
- Fuzzing and comprehensive manual test coverage
- Since v0.4.4, compile time encode/decode is supported. This means you can initialize a const value using decode. It is also ok to use it inside a static block or other Nim VM code.

<!-- ANCHOR_END: Features -->

Expand Down
1 change: 1 addition & 0 deletions json_serialization.nimble
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ license = "Apache License 2.0"
skipDirs = @["tests", "fuzzer"]

requires "nim >= 1.6.0",
"faststreams >= 0.5.0",
"serialization",
"stew >= 0.2.0",
"results"
Expand Down
13 changes: 0 additions & 13 deletions tests/test_lexer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -279,11 +279,7 @@ suite "lexer test suite":
var conf = defaultJsonReaderConf
conf.fractionDigitsLimit = 3
testScanNumber(".1234", ".123", error = errFracDigitLimit, conf = conf)

testScanNumber("1234.5555", "1234.5555")

conf = defaultJsonReaderConf
conf.fractionDigitsLimit = 3
testScanNumber("1234.1234", "1234.123", error = errFracDigitLimit, conf = conf)

test "scanNumber exponent part string":
Expand Down Expand Up @@ -343,11 +339,7 @@ suite "lexer test suite":
var conf = defaultJsonReaderConf
conf.fractionDigitsLimit = 3
testScanNumber(".1234", JsonVoid(), error = errFracDigitLimit, conf = conf)

testScanNumber("1234.5555", JsonVoid())

conf = defaultJsonReaderConf
conf.fractionDigitsLimit = 3
testScanNumber("1234.1234", JsonVoid(), error = errFracDigitLimit, conf = conf)

test "scanNumber exponent part JsonVoid":
Expand Down Expand Up @@ -411,11 +403,7 @@ suite "lexer test suite":
conf.fractionDigitsLimit = 3
testScanNumber(".1234", JsonNumber[string](fraction: "123"),
error = errFracDigitLimit, conf = conf)

testScanNumber("1234.5555", JsonNumber[string](integer: "1234", fraction: "5555"))

conf = defaultJsonReaderConf
conf.fractionDigitsLimit = 3
testScanNumber("1234.1234", JsonNumber[string](integer: "1234", fraction: "123"),
error = errFracDigitLimit, conf = conf)

Expand Down Expand Up @@ -501,7 +489,6 @@ suite "lexer test suite":

testScanNumber("1234.5555", JsonNumber[uint64](integer: 1234, fraction: "5555"))

conf = defaultJsonReaderConf
conf.fractionDigitsLimit = 3
testScanNumber("1234.1234", JsonNumber[uint64](integer: 1234, fraction: "123"),
error = errFracDigitLimit, conf = conf)
Expand Down
32 changes: 22 additions & 10 deletions tests/test_parser.nim
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,18 @@ suite "Custom iterators":
exponent == 789

test "customStringValueIt":
var text: string
var r = toReader "\"hello \\t world\""
r.customStringValueIt:
text.add it

expect JsonReaderError:
r.customStringValueIt(10):
proc customTest() =
var text: string
var r = toReader "\"hello \\t world\""
r.customStringValueIt:
text.add it

check text == "hello \t world"
expect JsonReaderError:
r.customStringValueIt(10):
text.add it

check text == "hello \t world"
customTest()

suite "Public parser":
test "parseArray":
Expand Down Expand Up @@ -222,16 +224,26 @@ suite "Public parser":
val = r.parseFloat(float64)
check val == -56009000.0

proc inputFile(fileName: string): InputStream =
when nimvm:
let data = staticRead(pathRelativeTo(fileName, "tests"))
unsafeMemoryInput(data)
else:
memFileInput(fileName)

template testParseAsString(fileName: string) =
try:
var stream = memFileInput(fileName)
var stream = inputFile(fileName)
var r = JsonReader[DefaultFlavor].init(stream)
let val = r.parseAsString()
var xr = toReader val.string
let xval = xr.parseAsString()
check val == xval
except JsonReaderError as ex:
debugEcho ex.formatMsg(fileName)
when nimvm:
debugEcho fileName, ex.msg
else:
debugEcho ex.formatMsg(fileName)
check false

test "parseAsString":
Expand Down
5 changes: 4 additions & 1 deletion tests/test_reader.nim
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,10 @@ suite "JsonReader basic test":
val.fourteen == SecondObject(one: "world", two: false)

except JsonReaderError as ex:
debugEcho ex.formatMsg("jsonText3")
when nimvm:
debugEcho "jsonText3", ex.msg
else:
debugEcho ex.formatMsg("jsonText3")
check false

test "Special Types":
Expand Down
55 changes: 38 additions & 17 deletions tests/test_spec.nim
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,15 @@ import
include
../json_serialization/lexer

proc yCase(fileName, name: string): bool {.raises:[IOError].} =
var stream = memFileInput(fileName)
proc inputFile(fileName: string): InputStream {.raises: [IOError].} =
when nimvm:
let data = staticRead(pathRelativeTo(fileName, "tests"))
unsafeMemoryInput(data)
else:
memFileInput(fileName)

proc yCase(fileName, name: string): bool {.raises: [IOError].} =
var stream = inputFile(fileName)
var lex = init(JsonLexer, stream)
var value: string
lex.scanValue(value)
Expand All @@ -28,8 +35,8 @@ proc yCase(fileName, name: string): bool {.raises:[IOError].} =
return false
true

proc nCase(fileName, name: string): bool {.raises:[IOError].} =
var stream = memFileInput(fileName)
proc nCase(fileName, name: string): bool {.raises: [IOError].} =
var stream = inputFile(fileName)
var lex = init(JsonLexer, stream, {})
var value: string
lex.scanValue(value)
Expand All @@ -43,19 +50,33 @@ proc nCase(fileName, name: string): bool {.raises:[IOError].} =
return false
true

for fileName in walkDirRec(parsingPath):
let (_, name) = fileName.splitPath()
if name.startsWith("y_"):
doAssert yCase(fileName, name)
elif name.startsWith("n_"):
doAssert nCase(fileName, name)
# test cases starts with i_ are allowed to
# fail or success depending on the implementation details
elif name.startsWith("i_"):
proc test() {.raises: [OSError, IOError].} =
var checked = 0
for fileName in walkDirRec(parsingPath):
let (_, name) = fileName.splitPath()
if name.startsWith("y_"):
doAssert yCase(fileName, name)
inc checked
elif name.startsWith("n_"):
doAssert nCase(fileName, name)
inc checked
# test cases starts with i_ are allowed to
# fail or success depending on the implementation details
elif name.startsWith("i_"):
if name notin allowedToFail:
doAssert yCase(fileName, name)
inc checked

for fileName in walkDirRec(transformPath):
let (_, name) = fileName.splitPath()
if name notin allowedToFail:
doAssert yCase(fileName, name)
inc checked

doAssert checked == 328, $checked

for fileName in walkDirRec(transformPath):
let (_, name) = fileName.splitPath()
if name notin allowedToFail:
doAssert yCase(fileName, name)
static:
test()
echo "static ok"
test()
echo "ok"
5 changes: 4 additions & 1 deletion tests/test_valueref.nim
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func jsonBool(x: bool): JsonValueRef[uint64] =
func jsonNull(): JsonValueRef[uint64] =
JsonValueRef[uint64](kind: JsonValueKind.Null)

suite "Test JsonValueRef":
template valueRefVars() {.dirty.} =
let objA = JsonValueRef[uint64](
kind: JsonValueKind.Object,
objVal: [
Expand Down Expand Up @@ -105,7 +105,9 @@ suite "Test JsonValueRef":
].toOrderedTable
)

suite "Test JsonValueRef":
test "Test table keys equality":
valueRefVars()
check objA != objAB
check objA == objA2
check objA != objABNull
Expand All @@ -122,6 +124,7 @@ suite "Test JsonValueRef":
check objInObjAB != objInObjABNull

test "Test compare":
valueRefVars()
check compare(objA, objAB) == false
check compare(objA, objA2) == true
check compare(objA, objABNull) == true
Expand Down
8 changes: 7 additions & 1 deletion tests/utils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# those terms.

import
strutils
strutils, os

# `dedent` exists in newer Nim version and doesn't behave the same
func test_dedent*(s: string): string =
Expand All @@ -21,6 +21,12 @@ func test_dedent*(s: string): string =
if indent < minIndent: minIndent = indent
s.unindent(minIndent)

proc pathRelativeTo*(fileName, base: string): string =
try:
relativePath(fileName, base)
except Exception as err:
raise newException(Defect, err.msg)

const
parsingPath* = "tests/test_vectors/test_parsing"
transformPath* = "tests/test_vectors/test_transform"
Expand Down