Welcome to mirror list, hosted at ThFree Co, Russian Federation.

test.lua « tests - github.com/mpx/lua-cjson.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: be6ef67e20e1226ab70b5759395baa3033a65d1c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
#!/usr/bin/env lua

-- CJSON tests
--
-- Mark Pulford <mark@kyne.com.au>
--
-- Note: The output of this script is easier to read with "less -S"

require "common"
local json = require "cjson"

local function gen_ascii()
    local chars = {}
    for i = 0, 255 do chars[i + 1] = string.char(i) end
    return table.concat(chars)
end

-- Generate every UTF-16 codepoint, including supplementary codes
local function gen_utf16_escaped()
    -- Create raw table escapes
    local utf16_escaped = {}
    local count = 0

    local function append_escape(code)
        local esc = string.format('\\u%04X', code)
        table.insert(utf16_escaped, esc)
    end

    table.insert(utf16_escaped, '"')
    for i = 0, 0xD7FF do
        append_escape(i)
    end
    -- Skip 0xD800 - 0xDFFF since they are used to encode supplementary
    -- codepoints
    for i = 0xE000, 0xFFFF do
        append_escape(i)
    end
    -- Append surrogate pair for each supplementary codepoint
    for high = 0xD800, 0xDBFF do
        for low = 0xDC00, 0xDFFF do
            append_escape(high)
            append_escape(low)
        end
    end
    table.insert(utf16_escaped, '"')

    return table.concat(utf16_escaped)
end

function test_decode_cycle(filename)
    local obj1 = json.decode(file_load(filename))
    local obj2 = json.decode(json.encode(obj1))
    return compare_values(obj1, obj2)
end

local Inf = math.huge;
local NaN = math.huge * 0;
local octets_raw = gen_ascii()
local octets_escaped = file_load("octets-escaped.dat")
local utf8_loaded, utf8_raw = pcall(file_load, "utf8.dat")
if not utf8_loaded then
    utf8_raw = "Failed to load utf8.dat"
end
local utf16_escaped = gen_utf16_escaped()
local nested5 = {{{{{ "nested" }}}}}
local table_cycle = {}
local table_cycle2 = { table_cycle }
table_cycle[1] = table_cycle2

local decode_simple_tests = {
    { json.decode, { '"test string"' }, true, { "test string" } },
    { json.decode, { '-5e3' }, true, { -5000 } },
    { json.decode, { 'null' }, true, { json.null } },
    { json.decode, { 'true' }, true, { true } },
    { json.decode, { 'false' }, true, { false } },
    { json.decode, { '{ "1": "one", "3": "three" }' },
      true, { { ["1"] = "one", ["3"] = "three" } } },
    { json.decode, { '[ "one", null, "three" ]' },
      true, { { "one", json.null, "three" } } }
}

local encode_simple_tests = {
    { json.encode, { json.null }, true, { 'null' } },
    { json.encode, { true }, true, { 'true' } },
    { json.encode, { false }, true, { 'false' } },
    { json.encode, { { } }, true, { '{}' } },
    { json.encode, { 10 }, true, { '10' } },
    { json.encode, { NaN },
      false, { "Cannot serialise number: must not be NaN or Inf" } },
    { json.encode, { Inf },
      false, { "Cannot serialise number: must not be NaN or Inf" } },
    { json.encode, { "hello" }, true, { '"hello"' } },
}


local decode_numeric_tests = {
    { json.decode, { '[ 0.0, -1, 0.3e-3, 1023.2 ]' },
      true, { { 0.0, -1, 0.0003, 1023.2 } } },
    { json.decode, { '00123' }, true, { 123 } },
    { json.decode, { '05.2' }, true, { 5.2 } },
    { json.decode, { '0e10' }, true, { 0 } },
    { json.decode, { '0x6' }, true, { 6 } },
    { json.decode, { '[ +Inf, Inf, -Inf ]' }, true, { { Inf, Inf, -Inf } } },
    { json.decode, { '[ +Infinity, Infinity, -Infinity ]' },
      true, { { Inf, Inf, -Inf } } },
    { json.decode, { '[ +NaN, NaN, -NaN ]' }, true, { { NaN, NaN, NaN } } },
    { json.decode, { 'Infrared' },
      false, { "Expected the end but found invalid token at character 4" } },
    { json.decode, { 'Noodle' },
      false, { "Expected value but found invalid token at character 1" } },
}

local encode_table_tests = {
    function()
        cjson.encode_sparse_array(true, 2, 3)
        cjson.encode_max_depth(5)
        return "Setting sparse array (true, 2, 3) / max depth (5)"
    end,
    { json.encode, { { [3] = "sparse test" } },
      true, { '[null,null,"sparse test"]' } },

    { json.encode, { { [1] = "one", [4] = "sparse test" } },
      true, { '["one",null,null,"sparse test"]' } },

    { json.encode, { { [1] = "one", [5] = "sparse test" } },
      true, { '{"1":"one","5":"sparse test"}' } },

    { json.encode, { nested5 }, true, { '[[[[["nested"]]]]]' } },
    { json.encode, { { nested5 } },
      false, { "Cannot serialise, excessive nesting (6)" } },
    { json.encode, { table_cycle },
      false, { "Cannot serialise, excessive nesting (6)" } }
}

local encode_error_tests = {
    { json.encode, { { [false] = "wrong" } },
      false, { "Cannot serialise boolean: table key must be a number or string" } },
    { json.encode, { function () end },
      false, { "Cannot serialise function: type not supported" } },
    function ()
        json.refuse_invalid_numbers("encode")
        return 'Setting refuse_invalid_numbers("encode")'
    end,
    { json.encode, { NaN },
      false, { "Cannot serialise number: must not be NaN or Inf" } },
    { json.encode, { Inf },
      false, { "Cannot serialise number: must not be NaN or Inf" } },
    function ()
        json.refuse_invalid_numbers(false)
        return 'Setting refuse_invalid_numbers(false).'
    end,
    function ()
        print('NOTE: receiving "-nan" is ok..')
        return
    end,
    { json.encode, { NaN }, true, { "nan" } },
    { json.encode, { Inf }, true, { "inf" } },
    function ()
        json.refuse_invalid_numbers("encode")
        return 'Setting refuse_invalid_numbers("encode")'
    end,
}

local json_nested = string.rep("[", 100000) .. string.rep("]", 100000)

local decode_error_tests = {
    { json.decode, { '\0"\0"' },
      false, { "JSON parser does not support UTF-16 or UTF-32" } },
    { json.decode, { '"\0"\0' },
      false, { "JSON parser does not support UTF-16 or UTF-32" } },
    { json.decode, { '{ "unexpected eof": ' },
      false, { "Expected value but found T_END at character 21" } },
    { json.decode, { '{ "extra data": true }, false' },
      false, { "Expected the end but found T_COMMA at character 23" } },
    { json.decode, { ' { "bad escape \\q code" } ' },
      false, { "Expected object key string but found invalid escape code at character 16" } },
    { json.decode, { ' { "bad unicode \\u0f6 escape" } ' },
      false, { "Expected object key string but found invalid unicode escape code at character 17" } },
    { json.decode, { ' [ "bad barewood", test ] ' },
      false, { "Expected value but found invalid token at character 20" } },
    { json.decode, { '[ -+12 ]' },
      false, { "Expected value but found invalid number at character 3" } },
    { json.decode, { '-v' },
      false, { "Expected value but found invalid number at character 1" } },
    { json.decode, { '[ 0.4eg10 ]' },
      false, { "Expected comma or array end but found invalid token at character 6" } },
    { json.decode, { json_nested },
      false, { "Too many nested data structures" } }
}

local escape_tests = {
    -- Test 8bit clean
    { json.encode, { octets_raw }, true, { octets_escaped } },
    { json.decode, { octets_escaped }, true, { octets_raw } },
    -- Ensure high bits are removed from surrogate codes
    { json.decode, { '"\\uF800"' }, true, { "\239\160\128" } },
    -- Test inverted surrogate pairs
    { json.decode, { '"\\uDB00\\uD800"' },
      false, { "Expected value but found invalid unicode escape code at character 2" } },
    -- Test 2x high surrogate code units
    { json.decode, { '"\\uDB00\\uDB00"' },
      false, { "Expected value but found invalid unicode escape code at character 2" } },
    -- Test invalid 2nd escape
    { json.decode, { '"\\uDB00\\"' },
      false, { "Expected value but found invalid unicode escape code at character 2" } },
    { json.decode, { '"\\uDB00\\uD"' },
      false, { "Expected value but found invalid unicode escape code at character 2" } },
    -- Test decoding of all UTF-16 escapes
    { json.decode, { utf16_escaped }, true, { utf8_raw } }
}

run_test_group("decode simple value", decode_simple_tests)
run_test_group("encode simple value", encode_simple_tests)
run_test_group("decode numeric", decode_numeric_tests)

-- INCLUDE:
-- - Sparse array exception..
-- - ..
-- cjson.encode_sparse_array(true, 2, 3)

run_test_group("encode table", encode_table_tests)
run_test_group("decode error", decode_error_tests)
run_test_group("encode error", encode_error_tests)
run_test_group("escape", escape_tests)

cjson.refuse_invalid_numbers(false)
cjson.encode_max_depth(20)
for i = 1, #arg do
    run_test("decode cycle " .. arg[i], test_decode_cycle, { arg[i] },
             true, { true })
end

-- vi:ai et sw=4 ts=4: