build: adds LPeg 1.0.0 and trims a build from 0.12.2 tree
[luajson.git] / tests / lunit-numbers.lua
blobcb92b45f9751887b706f8c67906f1b467e9cef62
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 local TEST_ENV
12 if not module then
13 _ENV = lunit.module("lunit-numbers", 'seeall')
14 TEST_ENV = _ENV
15 else
16 module("lunit-numbers", lunit.testcase, package.seeall)
17 TEST_ENV = _M
18 end
20 function setup()
21 -- Ensure that the decoder is reset
22 _G["decode"] = json.decode.getDecoder(false)
23 end
25 local function assert_near(expect, received)
26 local pctDiff
27 if expect == received then
28 pctDiff = 0
29 else
30 pctDiff = math.abs(1 - expect / received)
31 end
32 local msg = ("expected '%s' but was '%s' .. '%s'%% apart"):format(expect, received, pctDiff * 100)
33 assert(pctDiff < 0.000001, msg)
34 end
35 local function test_simple(num)
36 assert_near(num, decode(tostring(num)))
37 end
38 local function test_simple_w_encode(num)
39 assert_near(num, decode(encode(num)))
40 end
41 local function test_scientific(num)
42 assert_near(num, decode(string.format('%e', num)))
43 assert_near(num, decode(string.format('%E', num)))
44 end
45 local numbers = {
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)
54 end
56 local function get_number_tester(f)
57 return function ()
58 for _, v in ipairs(numbers) do
59 f(v)
60 end
61 end
62 end
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"))
73 end
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)
80 end
82 function test_expression()
83 assert_error(function()
84 decode("1 + 2")
85 end)
86 end
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)
97 function test_hex()
98 if decode == hexDecoder then -- MUST SKIP FAIL UNTIL BETTER METHOD SETUP
99 return
101 assert_error(function()
102 decode("0x20")
103 end)
106 local hexNumbers = {
107 0xDEADBEEF,
108 0xCAFEBABE,
109 0x00000000,
110 0xFFFFFFFF,
111 0xCE,
112 0x01
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 = {
126 "0x0.1",
127 "0x.1",
128 "0x0e+1",
129 "0x0E-1"
131 function test_no_decimal_hex_only()
132 for _, str in ipairs(decimal_hexes) do
133 assert_error(function()
134 hexDecoder(str)
135 end)
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)
154 else
155 TEST_ENV[k .. "_strict_gen"] = buildStrictDecoder(v)
157 TEST_ENV[k .. "_hex_gen"] = testutil.buildPatchedDecoder(v, hexDecoder)