Merge branch '1.1.x'
[luajson.git] / tests / lunit-numbers.lua
blob2d42fd7d0a4a8dd87d969c9e109d8fd47c4b9b02
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)
11 module("lunit-numbers", lunit.testcase, package.seeall)
13 function setup()
14 -- Ensure that the decoder is reset
15 _G["decode"] = json.decode.getDecoder(false)
16 end
18 local function assert_near(expect, received)
19 local pctDiff
20 if expect == received then
21 pctDiff = 0
22 else
23 pctDiff = math.abs(1 - expect / received)
24 end
25 local msg = ("expected '%s' but was '%s' .. '%s'%% apart"):format(expect, received, pctDiff * 100)
26 assert(pctDiff < 0.000001, msg)
27 end
28 local function test_simple(num)
29 assert_near(num, decode(tostring(num)))
30 end
31 local function test_simple_w_encode(num)
32 assert_near(num, decode(encode(num)))
33 end
34 local function test_scientific(num)
35 assert_near(num, decode(string.format('%e', num)))
36 assert_near(num, decode(string.format('%E', num)))
37 end
38 local numbers = {
39 0, 1, -1, math.pi, -math.pi
41 math.randomseed(0xDEADBEEF)
42 -- Add sequence of numbers at low/high end of value-set
43 for i = -300,300,60 do
44 numbers[#numbers + 1] = math.random() * math.pow(10, i)
45 numbers[#numbers + 1] = -math.random() * math.pow(10, i)
46 end
48 local function get_number_tester(f)
49 return function ()
50 for _, v in ipairs(numbers) do
51 f(v)
52 end
53 end
54 end
56 test_simple_numbers = get_number_tester(test_simple)
57 test_simple_numbers_w_encode = get_number_tester(test_simple_w_encode)
58 test_simple_numbers_scientific = get_number_tester(test_scientific)
60 function test_infinite_nostrict()
61 assert_equal(math.huge, decode("Infinity"))
62 assert_equal(math.huge, decode("infinity"))
63 assert_equal(-math.huge, decode("-Infinity"))
64 assert_equal(-math.huge, decode("-infinity"))
65 end
67 function test_nan_nostrict()
68 local value = decode("nan")
69 assert_true(value ~= value)
70 local value = decode("NaN")
71 assert_true(value ~= value)
72 end
74 function test_expression()
75 assert_error(function()
76 decode("1 + 2")
77 end)
78 end
80 -- For strict tests, small concession must be made to allow non-array/objects as root
81 local strict = json.util.merge({}, json.decode.strict, {initialObject = false})
82 local strictDecoder = json.decode.getDecoder(strict)
84 local numberValue = {hex = true}
86 local hex = {number = numberValue}
87 local hexDecoder = json.decode.getDecoder(hex)
89 function test_hex()
90 if decode == hexDecoder then -- MUST SKIP FAIL UNTIL BETTER METHOD SETUP
91 return
92 end
93 assert_error(function()
94 decode("0x20")
95 end)
96 end
98 local hexNumbers = {
99 0xDEADBEEF,
100 0xCAFEBABE,
101 0x00000000,
102 0xFFFFFFFF,
103 0xCE,
104 0x01
107 function test_hex_only()
108 _G["decode"] = hexDecoder
109 for _, v in ipairs(hexNumbers) do
110 assert_equal(v, decode(("0x%x"):format(v)))
111 assert_equal(v, decode(("0X%X"):format(v)))
112 assert_equal(v, decode(("0x%X"):format(v)))
113 assert_equal(v, decode(("0X%x"):format(v)))
117 local decimal_hexes = {
118 "0x0.1",
119 "0x.1",
120 "0x0e+1",
121 "0x0E-1"
123 function test_no_decimal_hex_only()
124 for _, str in ipairs(decimal_hexes) do
125 assert_error(function()
126 hexDecoder(str)
127 end)
131 function test_nearly_scientific_hex_only()
132 assert_equal(0x00E1, hexDecoder("0x00e1"))
135 local function buildStrictDecoder(f)
136 return testutil.buildPatchedDecoder(f, strictDecoder)
138 local function buildFailedStrictDecoder(f)
139 return testutil.buildFailedPatchedDecoder(f, strictDecoder)
141 -- SETUP CHECKS FOR SEQUENCE OF DECODERS
142 for k, v in pairs(_M) do
143 if k:match("^test_") and not k:match("_gen$") and not k:match("_only$") then
144 if k:match("_nostrict") then
145 _M[k .. "_strict_gen"] = buildFailedStrictDecoder(v)
146 else
147 _M[k .. "_strict_gen"] = buildStrictDecoder(v)
149 _M[k .. "_hex_gen"] = testutil.buildPatchedDecoder(v, hexDecoder)