1 local json
= require("json")
2 local lunit
= require("lunit")
3 local math
= require("math")
4 local testutil
= require("testutil")
5 local string = require("string")
7 local encode
= json
.encode
8 -- DECODE NOT 'local' due to requirement for testutil to access it
9 decode
= json
.decode
.getDecoder(false)
13 _ENV
= lunit
.module("lunit-numbers", 'seeall')
16 module("lunit-numbers", lunit
.testcase
, package
.seeall
)
21 -- Ensure that the decoder is reset
22 _G
["decode"] = json
.decode
.getDecoder(false)
25 local function assert_near(expect
, received
)
27 if expect
== received
then
30 pctDiff
= math
.abs(1 - expect
/ received
)
32 local msg
= ("expected '%s' but was '%s' .. '%s'%% apart"):format(expect
, received
, pctDiff
* 100)
33 assert(pctDiff
< 0.000001, msg
)
35 local function test_simple(num
)
36 assert_near(num
, decode(tostring(num
)))
38 local function test_simple_w_encode(num
)
39 assert_near(num
, decode(encode(num
)))
41 local function test_scientific(num
)
42 assert_near(num
, decode(string.format('%e', num
)))
43 assert_near(num
, decode(string.format('%E', num
)))
46 0, 1, -1, math
.pi
, -math
.pi
48 math
.randomseed(0xDEADBEEF)
49 local pow
= math
.pow
or load("return function(a, b) return a ^ b end")()
50 -- Add sequence of numbers at low/high end of value-set
51 for i
= -300,300,60 do
52 numbers
[#numbers
+ 1] = math
.random() * pow(10, i
)
53 numbers
[#numbers
+ 1] = -math
.random() * pow(10, i
)
56 local function get_number_tester(f
)
58 for _
, v
in ipairs(numbers
) do
64 test_simple_numbers
= get_number_tester(test_simple
)
65 test_simple_numbers_w_encode
= get_number_tester(test_simple_w_encode
)
66 test_simple_numbers_scientific
= get_number_tester(test_scientific
)
68 function test_infinite_nostrict()
69 assert_equal(math
.huge
, decode("Infinity"))
70 assert_equal(math
.huge
, decode("infinity"))
71 assert_equal(-math
.huge
, decode("-Infinity"))
72 assert_equal(-math
.huge
, decode("-infinity"))
75 function test_nan_nostrict()
76 local value
= decode("nan")
77 assert_true(value
~= value
)
78 local value
= decode("NaN")
79 assert_true(value
~= value
)
82 function test_expression()
83 assert_error(function()
88 -- For strict tests, small concession must be made to allow non-array/objects as root
89 local strict
= json
.util
.merge({}, json
.decode
.strict
, {initialObject
= false})
90 local strictDecoder
= json
.decode
.getDecoder(strict
)
92 local numberValue
= {hex
= true}
94 local hex
= {number = numberValue
}
95 local hexDecoder
= json
.decode
.getDecoder(hex
)
98 if decode
== hexDecoder
then -- MUST SKIP FAIL UNTIL BETTER METHOD SETUP
101 assert_error(function()
115 function test_hex_only()
116 _G
["decode"] = hexDecoder
117 for _
, v
in ipairs(hexNumbers
) do
118 assert_equal(v
, decode(("0x%x"):format(v
)))
119 assert_equal(v
, decode(("0X%X"):format(v
)))
120 assert_equal(v
, decode(("0x%X"):format(v
)))
121 assert_equal(v
, decode(("0X%x"):format(v
)))
125 local decimal_hexes
= {
131 function test_no_decimal_hex_only()
132 for _
, str
in ipairs(decimal_hexes
) do
133 assert_error(function()
139 function test_nearly_scientific_hex_only()
140 assert_equal(0x00E1, hexDecoder("0x00e1"))
143 local function buildStrictDecoder(f
)
144 return testutil
.buildPatchedDecoder(f
, strictDecoder
)
146 local function buildFailedStrictDecoder(f
)
147 return testutil
.buildFailedPatchedDecoder(f
, strictDecoder
)
149 -- SETUP CHECKS FOR SEQUENCE OF DECODERS
150 for k
, v
in pairs(TEST_ENV
) do
151 if k
:match("^test_") and not k
:match("_gen$") and not k
:match("_only$") then
152 if k
:match("_nostrict") then
153 TEST_ENV
[k
.. "_strict_gen"] = buildFailedStrictDecoder(v
)
155 TEST_ENV
[k
.. "_strict_gen"] = buildStrictDecoder(v
)
157 TEST_ENV
[k
.. "_hex_gen"] = testutil
.buildPatchedDecoder(v
, hexDecoder
)