mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 03:53:09 +00:00
rewrite client demo by lua, remove old C version client demo
This commit is contained in:
4
3rd/lua-cjson/tests/README
Normal file
4
3rd/lua-cjson/tests/README
Normal file
@@ -0,0 +1,4 @@
|
||||
These JSON examples were taken from the JSON website
|
||||
(http://json.org/example.html) and RFC 4627.
|
||||
|
||||
Used with permission.
|
||||
131
3rd/lua-cjson/tests/bench.lua
Executable file
131
3rd/lua-cjson/tests/bench.lua
Executable file
@@ -0,0 +1,131 @@
|
||||
#!/usr/bin/env lua
|
||||
|
||||
-- This benchmark script measures wall clock time and should be
|
||||
-- run on an unloaded system.
|
||||
--
|
||||
-- Your Mileage May Vary.
|
||||
--
|
||||
-- Mark Pulford <mark@kyne.com.au>
|
||||
|
||||
local json_module = os.getenv("JSON_MODULE") or "cjson"
|
||||
|
||||
require "socket"
|
||||
local json = require(json_module)
|
||||
local util = require "cjson.util"
|
||||
|
||||
local function find_func(mod, funcnames)
|
||||
for _, v in ipairs(funcnames) do
|
||||
if mod[v] then
|
||||
return mod[v]
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
local json_encode = find_func(json, { "encode", "Encode", "to_string", "stringify", "json" })
|
||||
local json_decode = find_func(json, { "decode", "Decode", "to_value", "parse" })
|
||||
|
||||
local function average(t)
|
||||
local total = 0
|
||||
for _, v in ipairs(t) do
|
||||
total = total + v
|
||||
end
|
||||
return total / #t
|
||||
end
|
||||
|
||||
function benchmark(tests, seconds, rep)
|
||||
local function bench(func, iter)
|
||||
-- Use socket.gettime() to measure microsecond resolution
|
||||
-- wall clock time.
|
||||
local t = socket.gettime()
|
||||
for i = 1, iter do
|
||||
func(i)
|
||||
end
|
||||
t = socket.gettime() - t
|
||||
|
||||
-- Don't trust any results when the run lasted for less than a
|
||||
-- millisecond - return nil.
|
||||
if t < 0.001 then
|
||||
return nil
|
||||
end
|
||||
|
||||
return (iter / t)
|
||||
end
|
||||
|
||||
-- Roughly calculate the number of interations required
|
||||
-- to obtain a particular time period.
|
||||
local function calc_iter(func, seconds)
|
||||
local iter = 1
|
||||
local rate
|
||||
-- Warm up the bench function first.
|
||||
func()
|
||||
while not rate do
|
||||
rate = bench(func, iter)
|
||||
iter = iter * 10
|
||||
end
|
||||
return math.ceil(seconds * rate)
|
||||
end
|
||||
|
||||
local test_results = {}
|
||||
for name, func in pairs(tests) do
|
||||
-- k(number), v(string)
|
||||
-- k(string), v(function)
|
||||
-- k(number), v(function)
|
||||
if type(func) == "string" then
|
||||
name = func
|
||||
func = _G[name]
|
||||
end
|
||||
|
||||
local iter = calc_iter(func, seconds)
|
||||
|
||||
local result = {}
|
||||
for i = 1, rep do
|
||||
result[i] = bench(func, iter)
|
||||
end
|
||||
|
||||
-- Remove the slowest half (round down) of the result set
|
||||
table.sort(result)
|
||||
for i = 1, math.floor(#result / 2) do
|
||||
table.remove(result, 1)
|
||||
end
|
||||
|
||||
test_results[name] = average(result)
|
||||
end
|
||||
|
||||
return test_results
|
||||
end
|
||||
|
||||
function bench_file(filename)
|
||||
local data_json = util.file_load(filename)
|
||||
local data_obj = json_decode(data_json)
|
||||
|
||||
local function test_encode()
|
||||
json_encode(data_obj)
|
||||
end
|
||||
local function test_decode()
|
||||
json_decode(data_json)
|
||||
end
|
||||
|
||||
local tests = {}
|
||||
if json_encode then tests.encode = test_encode end
|
||||
if json_decode then tests.decode = test_decode end
|
||||
|
||||
return benchmark(tests, 0.1, 5)
|
||||
end
|
||||
|
||||
-- Optionally load any custom configuration required for this module
|
||||
local success, data = pcall(util.file_load, ("bench-%s.lua"):format(json_module))
|
||||
if success then
|
||||
util.run_script(data, _G)
|
||||
configure(json)
|
||||
end
|
||||
|
||||
for i = 1, #arg do
|
||||
local results = bench_file(arg[i])
|
||||
for k, v in pairs(results) do
|
||||
print(("%s\t%s\t%d"):format(arg[i], k, v))
|
||||
end
|
||||
end
|
||||
|
||||
-- vi:ai et sw=4 ts=4:
|
||||
22
3rd/lua-cjson/tests/example1.json
Normal file
22
3rd/lua-cjson/tests/example1.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"glossary": {
|
||||
"title": "example glossary",
|
||||
"GlossDiv": {
|
||||
"title": "S",
|
||||
"GlossList": {
|
||||
"GlossEntry": {
|
||||
"ID": "SGML",
|
||||
"SortAs": "SGML",
|
||||
"GlossTerm": "Standard Generalized Mark up Language",
|
||||
"Acronym": "SGML",
|
||||
"Abbrev": "ISO 8879:1986",
|
||||
"GlossDef": {
|
||||
"para": "A meta-markup language, used to create markup languages such as DocBook.",
|
||||
"GlossSeeAlso": ["GML", "XML"]
|
||||
},
|
||||
"GlossSee": "markup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
3rd/lua-cjson/tests/example2.json
Normal file
11
3rd/lua-cjson/tests/example2.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{"menu": {
|
||||
"id": "file",
|
||||
"value": "File",
|
||||
"popup": {
|
||||
"menuitem": [
|
||||
{"value": "New", "onclick": "CreateNewDoc()"},
|
||||
{"value": "Open", "onclick": "OpenDoc()"},
|
||||
{"value": "Close", "onclick": "CloseDoc()"}
|
||||
]
|
||||
}
|
||||
}}
|
||||
26
3rd/lua-cjson/tests/example3.json
Normal file
26
3rd/lua-cjson/tests/example3.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{"widget": {
|
||||
"debug": "on",
|
||||
"window": {
|
||||
"title": "Sample Konfabulator Widget",
|
||||
"name": "main_window",
|
||||
"width": 500,
|
||||
"height": 500
|
||||
},
|
||||
"image": {
|
||||
"src": "Images/Sun.png",
|
||||
"name": "sun1",
|
||||
"hOffset": 250,
|
||||
"vOffset": 250,
|
||||
"alignment": "center"
|
||||
},
|
||||
"text": {
|
||||
"data": "Click Here",
|
||||
"size": 36,
|
||||
"style": "bold",
|
||||
"name": "text1",
|
||||
"hOffset": 250,
|
||||
"vOffset": 100,
|
||||
"alignment": "center",
|
||||
"onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
|
||||
}
|
||||
}}
|
||||
88
3rd/lua-cjson/tests/example4.json
Normal file
88
3rd/lua-cjson/tests/example4.json
Normal file
@@ -0,0 +1,88 @@
|
||||
{"web-app": {
|
||||
"servlet": [
|
||||
{
|
||||
"servlet-name": "cofaxCDS",
|
||||
"servlet-class": "org.cofax.cds.CDSServlet",
|
||||
"init-param": {
|
||||
"configGlossary:installationAt": "Philadelphia, PA",
|
||||
"configGlossary:adminEmail": "ksm@pobox.com",
|
||||
"configGlossary:poweredBy": "Cofax",
|
||||
"configGlossary:poweredByIcon": "/images/cofax.gif",
|
||||
"configGlossary:staticPath": "/content/static",
|
||||
"templateProcessorClass": "org.cofax.WysiwygTemplate",
|
||||
"templateLoaderClass": "org.cofax.FilesTemplateLoader",
|
||||
"templatePath": "templates",
|
||||
"templateOverridePath": "",
|
||||
"defaultListTemplate": "listTemplate.htm",
|
||||
"defaultFileTemplate": "articleTemplate.htm",
|
||||
"useJSP": false,
|
||||
"jspListTemplate": "listTemplate.jsp",
|
||||
"jspFileTemplate": "articleTemplate.jsp",
|
||||
"cachePackageTagsTrack": 200,
|
||||
"cachePackageTagsStore": 200,
|
||||
"cachePackageTagsRefresh": 60,
|
||||
"cacheTemplatesTrack": 100,
|
||||
"cacheTemplatesStore": 50,
|
||||
"cacheTemplatesRefresh": 15,
|
||||
"cachePagesTrack": 200,
|
||||
"cachePagesStore": 100,
|
||||
"cachePagesRefresh": 10,
|
||||
"cachePagesDirtyRead": 10,
|
||||
"searchEngineListTemplate": "forSearchEnginesList.htm",
|
||||
"searchEngineFileTemplate": "forSearchEngines.htm",
|
||||
"searchEngineRobotsDb": "WEB-INF/robots.db",
|
||||
"useDataStore": true,
|
||||
"dataStoreClass": "org.cofax.SqlDataStore",
|
||||
"redirectionClass": "org.cofax.SqlRedirection",
|
||||
"dataStoreName": "cofax",
|
||||
"dataStoreDriver": "com.microsoft.jdbc.sqlserver.SQLServerDriver",
|
||||
"dataStoreUrl": "jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName=goon",
|
||||
"dataStoreUser": "sa",
|
||||
"dataStorePassword": "dataStoreTestQuery",
|
||||
"dataStoreTestQuery": "SET NOCOUNT ON;select test='test';",
|
||||
"dataStoreLogFile": "/usr/local/tomcat/logs/datastore.log",
|
||||
"dataStoreInitConns": 10,
|
||||
"dataStoreMaxConns": 100,
|
||||
"dataStoreConnUsageLimit": 100,
|
||||
"dataStoreLogLevel": "debug",
|
||||
"maxUrlLength": 500}},
|
||||
{
|
||||
"servlet-name": "cofaxEmail",
|
||||
"servlet-class": "org.cofax.cds.EmailServlet",
|
||||
"init-param": {
|
||||
"mailHost": "mail1",
|
||||
"mailHostOverride": "mail2"}},
|
||||
{
|
||||
"servlet-name": "cofaxAdmin",
|
||||
"servlet-class": "org.cofax.cds.AdminServlet"},
|
||||
|
||||
{
|
||||
"servlet-name": "fileServlet",
|
||||
"servlet-class": "org.cofax.cds.FileServlet"},
|
||||
{
|
||||
"servlet-name": "cofaxTools",
|
||||
"servlet-class": "org.cofax.cms.CofaxToolsServlet",
|
||||
"init-param": {
|
||||
"templatePath": "toolstemplates/",
|
||||
"log": 1,
|
||||
"logLocation": "/usr/local/tomcat/logs/CofaxTools.log",
|
||||
"logMaxSize": "",
|
||||
"dataLog": 1,
|
||||
"dataLogLocation": "/usr/local/tomcat/logs/dataLog.log",
|
||||
"dataLogMaxSize": "",
|
||||
"removePageCache": "/content/admin/remove?cache=pages&id=",
|
||||
"removeTemplateCache": "/content/admin/remove?cache=templates&id=",
|
||||
"fileTransferFolder": "/usr/local/tomcat/webapps/content/fileTransferFolder",
|
||||
"lookInContext": 1,
|
||||
"adminGroupID": 4,
|
||||
"betaServer": true}}],
|
||||
"servlet-mapping": {
|
||||
"cofaxCDS": "/",
|
||||
"cofaxEmail": "/cofaxutil/aemail/*",
|
||||
"cofaxAdmin": "/admin/*",
|
||||
"fileServlet": "/static/*",
|
||||
"cofaxTools": "/tools/*"},
|
||||
|
||||
"taglib": {
|
||||
"taglib-uri": "cofax.tld",
|
||||
"taglib-location": "/WEB-INF/tlds/cofax.tld"}}}
|
||||
27
3rd/lua-cjson/tests/example5.json
Normal file
27
3rd/lua-cjson/tests/example5.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{"menu": {
|
||||
"header": "SVG Viewer",
|
||||
"items": [
|
||||
{"id": "Open"},
|
||||
{"id": "OpenNew", "label": "Open New"},
|
||||
null,
|
||||
{"id": "ZoomIn", "label": "Zoom In"},
|
||||
{"id": "ZoomOut", "label": "Zoom Out"},
|
||||
{"id": "OriginalView", "label": "Original View"},
|
||||
null,
|
||||
{"id": "Quality"},
|
||||
{"id": "Pause"},
|
||||
{"id": "Mute"},
|
||||
null,
|
||||
{"id": "Find", "label": "Find..."},
|
||||
{"id": "FindAgain", "label": "Find Again"},
|
||||
{"id": "Copy"},
|
||||
{"id": "CopyAgain", "label": "Copy Again"},
|
||||
{"id": "CopySVG", "label": "Copy SVG"},
|
||||
{"id": "ViewSVG", "label": "View SVG"},
|
||||
{"id": "ViewSource", "label": "View Source"},
|
||||
{"id": "SaveAs", "label": "Save As"},
|
||||
null,
|
||||
{"id": "Help"},
|
||||
{"id": "About", "label": "About Adobe CVG Viewer..."}
|
||||
]
|
||||
}}
|
||||
23
3rd/lua-cjson/tests/genutf8.pl
Executable file
23
3rd/lua-cjson/tests/genutf8.pl
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
# Create test comparison data using a different UTF-8 implementation.
|
||||
|
||||
# The generated utf8.dat file must have the following MD5 sum:
|
||||
# cff03b039d850f370a7362f3313e5268
|
||||
|
||||
use strict;
|
||||
|
||||
# 0xD800 - 0xDFFF are used to encode supplementary codepoints
|
||||
# 0x10000 - 0x10FFFF are supplementary codepoints
|
||||
my (@codepoints) = (0 .. 0xD7FF, 0xE000 .. 0x10FFFF);
|
||||
|
||||
my $utf8 = pack("U*", @codepoints);
|
||||
defined($utf8) or die "Unable create UTF-8 string\n";
|
||||
|
||||
open(FH, ">:utf8", "utf8.dat")
|
||||
or die "Unable to open utf8.dat: $!\n";
|
||||
print FH $utf8
|
||||
or die "Unable to write utf8.dat\n";
|
||||
close(FH);
|
||||
|
||||
# vi:ai et sw=4 ts=4:
|
||||
7
3rd/lua-cjson/tests/numbers.json
Normal file
7
3rd/lua-cjson/tests/numbers.json
Normal file
@@ -0,0 +1,7 @@
|
||||
[ 0.110001,
|
||||
0.12345678910111,
|
||||
0.412454033640,
|
||||
2.6651441426902,
|
||||
2.718281828459,
|
||||
3.1415926535898,
|
||||
2.1406926327793 ]
|
||||
1
3rd/lua-cjson/tests/octets-escaped.dat
Normal file
1
3rd/lua-cjson/tests/octets-escaped.dat
Normal file
@@ -0,0 +1 @@
|
||||
"\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-.\/0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f€亗儎厗噲墛媽崕彁憭摂晼棙櫄洔潪煚、¥ウЖ┆<D096><E29486><EFBFBD>辈炒刀犯购患骄坷谅媚牌侨墒颂臀闲岩釉罩棕仝圮蒉哙徕沅彐玷殛腱眍镳耱篝貊鼬<E8B28A><E9BCAC><EFBFBD><EFBFBD>"
|
||||
13
3rd/lua-cjson/tests/rfc-example1.json
Normal file
13
3rd/lua-cjson/tests/rfc-example1.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"Image": {
|
||||
"Width": 800,
|
||||
"Height": 600,
|
||||
"Title": "View from 15th Floor",
|
||||
"Thumbnail": {
|
||||
"Url": "http://www.example.com/image/481989943",
|
||||
"Height": 125,
|
||||
"Width": "100"
|
||||
},
|
||||
"IDs": [116, 943, 234, 38793]
|
||||
}
|
||||
}
|
||||
22
3rd/lua-cjson/tests/rfc-example2.json
Normal file
22
3rd/lua-cjson/tests/rfc-example2.json
Normal file
@@ -0,0 +1,22 @@
|
||||
[
|
||||
{
|
||||
"precision": "zip",
|
||||
"Latitude": 37.7668,
|
||||
"Longitude": -122.3959,
|
||||
"Address": "",
|
||||
"City": "SAN FRANCISCO",
|
||||
"State": "CA",
|
||||
"Zip": "94107",
|
||||
"Country": "US"
|
||||
},
|
||||
{
|
||||
"precision": "zip",
|
||||
"Latitude": 37.371991,
|
||||
"Longitude": -122.026020,
|
||||
"Address": "",
|
||||
"City": "SUNNYVALE",
|
||||
"State": "CA",
|
||||
"Zip": "94085",
|
||||
"Country": "US"
|
||||
}
|
||||
]
|
||||
423
3rd/lua-cjson/tests/test.lua
Executable file
423
3rd/lua-cjson/tests/test.lua
Executable file
@@ -0,0 +1,423 @@
|
||||
#!/usr/bin/env lua
|
||||
|
||||
-- Lua CJSON tests
|
||||
--
|
||||
-- Mark Pulford <mark@kyne.com.au>
|
||||
--
|
||||
-- Note: The output of this script is easier to read with "less -S"
|
||||
|
||||
local json = require "cjson"
|
||||
local json_safe = require "cjson.safe"
|
||||
local util = require "cjson.util"
|
||||
|
||||
local function gen_raw_octets()
|
||||
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 = ('\\u%04X'):format(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 load_testdata()
|
||||
local data = {}
|
||||
|
||||
-- Data for 8bit raw <-> escaped octets tests
|
||||
data.octets_raw = gen_raw_octets()
|
||||
data.octets_escaped = util.file_load("octets-escaped.dat")
|
||||
|
||||
-- Data for \uXXXX -> UTF-8 test
|
||||
data.utf16_escaped = gen_utf16_escaped()
|
||||
|
||||
-- Load matching data for utf16_escaped
|
||||
local utf8_loaded
|
||||
utf8_loaded, data.utf8_raw = pcall(util.file_load, "utf8.dat")
|
||||
if not utf8_loaded then
|
||||
data.utf8_raw = "Failed to load utf8.dat - please run genutf8.pl"
|
||||
end
|
||||
|
||||
data.table_cycle = {}
|
||||
data.table_cycle[1] = data.table_cycle
|
||||
|
||||
local big = {}
|
||||
for i = 1, 1100 do
|
||||
big = { { 10, false, true, json.null }, "string", a = big }
|
||||
end
|
||||
data.deeply_nested_data = big
|
||||
|
||||
return data
|
||||
end
|
||||
|
||||
function test_decode_cycle(filename)
|
||||
local obj1 = json.decode(util.file_load(filename))
|
||||
local obj2 = json.decode(json.encode(obj1))
|
||||
return util.compare_values(obj1, obj2)
|
||||
end
|
||||
|
||||
-- Set up data used in tests
|
||||
local Inf = math.huge;
|
||||
local NaN = math.huge * 0;
|
||||
|
||||
local testdata = load_testdata()
|
||||
|
||||
local cjson_tests = {
|
||||
-- Test API variables
|
||||
{ "Check module name, version",
|
||||
function () return json._NAME, json._VERSION end, { },
|
||||
true, { "cjson", "2.1.0" } },
|
||||
|
||||
-- Test decoding simple types
|
||||
{ "Decode string",
|
||||
json.decode, { '"test string"' }, true, { "test string" } },
|
||||
{ "Decode numbers",
|
||||
json.decode, { '[ 0.0, -5e3, -1, 0.3e-3, 1023.2, 0e10 ]' },
|
||||
true, { { 0.0, -5000, -1, 0.0003, 1023.2, 0 } } },
|
||||
{ "Decode null",
|
||||
json.decode, { 'null' }, true, { json.null } },
|
||||
{ "Decode true",
|
||||
json.decode, { 'true' }, true, { true } },
|
||||
{ "Decode false",
|
||||
json.decode, { 'false' }, true, { false } },
|
||||
{ "Decode object with numeric keys",
|
||||
json.decode, { '{ "1": "one", "3": "three" }' },
|
||||
true, { { ["1"] = "one", ["3"] = "three" } } },
|
||||
{ "Decode object with string keys",
|
||||
json.decode, { '{ "a": "a", "b": "b" }' },
|
||||
true, { { a = "a", b = "b" } } },
|
||||
{ "Decode array",
|
||||
json.decode, { '[ "one", null, "three" ]' },
|
||||
true, { { "one", json.null, "three" } } },
|
||||
|
||||
-- Test decoding errors
|
||||
{ "Decode UTF-16BE [throw error]",
|
||||
json.decode, { '\0"\0"' },
|
||||
false, { "JSON parser does not support UTF-16 or UTF-32" } },
|
||||
{ "Decode UTF-16LE [throw error]",
|
||||
json.decode, { '"\0"\0' },
|
||||
false, { "JSON parser does not support UTF-16 or UTF-32" } },
|
||||
{ "Decode UTF-32BE [throw error]",
|
||||
json.decode, { '\0\0\0"' },
|
||||
false, { "JSON parser does not support UTF-16 or UTF-32" } },
|
||||
{ "Decode UTF-32LE [throw error]",
|
||||
json.decode, { '"\0\0\0' },
|
||||
false, { "JSON parser does not support UTF-16 or UTF-32" } },
|
||||
{ "Decode partial JSON [throw error]",
|
||||
json.decode, { '{ "unexpected eof": ' },
|
||||
false, { "Expected value but found T_END at character 21" } },
|
||||
{ "Decode with extra comma [throw error]",
|
||||
json.decode, { '{ "extra data": true }, false' },
|
||||
false, { "Expected the end but found T_COMMA at character 23" } },
|
||||
{ "Decode invalid escape code [throw error]",
|
||||
json.decode, { [[ { "bad escape \q code" } ]] },
|
||||
false, { "Expected object key string but found invalid escape code at character 16" } },
|
||||
{ "Decode invalid unicode escape [throw error]",
|
||||
json.decode, { [[ { "bad unicode \u0f6 escape" } ]] },
|
||||
false, { "Expected object key string but found invalid unicode escape code at character 17" } },
|
||||
{ "Decode invalid keyword [throw error]",
|
||||
json.decode, { ' [ "bad barewood", test ] ' },
|
||||
false, { "Expected value but found invalid token at character 20" } },
|
||||
{ "Decode invalid number #1 [throw error]",
|
||||
json.decode, { '[ -+12 ]' },
|
||||
false, { "Expected value but found invalid number at character 3" } },
|
||||
{ "Decode invalid number #2 [throw error]",
|
||||
json.decode, { '-v' },
|
||||
false, { "Expected value but found invalid number at character 1" } },
|
||||
{ "Decode invalid number exponent [throw error]",
|
||||
json.decode, { '[ 0.4eg10 ]' },
|
||||
false, { "Expected comma or array end but found invalid token at character 6" } },
|
||||
|
||||
-- Test decoding nested arrays / objects
|
||||
{ "Set decode_max_depth(5)",
|
||||
json.decode_max_depth, { 5 }, true, { 5 } },
|
||||
{ "Decode array at nested limit",
|
||||
json.decode, { '[[[[[ "nested" ]]]]]' },
|
||||
true, { {{{{{ "nested" }}}}} } },
|
||||
{ "Decode array over nested limit [throw error]",
|
||||
json.decode, { '[[[[[[ "nested" ]]]]]]' },
|
||||
false, { "Found too many nested data structures (6) at character 6" } },
|
||||
{ "Decode object at nested limit",
|
||||
json.decode, { '{"a":{"b":{"c":{"d":{"e":"nested"}}}}}' },
|
||||
true, { {a={b={c={d={e="nested"}}}}} } },
|
||||
{ "Decode object over nested limit [throw error]",
|
||||
json.decode, { '{"a":{"b":{"c":{"d":{"e":{"f":"nested"}}}}}}' },
|
||||
false, { "Found too many nested data structures (6) at character 26" } },
|
||||
{ "Set decode_max_depth(1000)",
|
||||
json.decode_max_depth, { 1000 }, true, { 1000 } },
|
||||
{ "Decode deeply nested array [throw error]",
|
||||
json.decode, { string.rep("[", 1100) .. '1100' .. string.rep("]", 1100)},
|
||||
false, { "Found too many nested data structures (1001) at character 1001" } },
|
||||
|
||||
-- Test encoding nested tables
|
||||
{ "Set encode_max_depth(5)",
|
||||
json.encode_max_depth, { 5 }, true, { 5 } },
|
||||
{ "Encode nested table as array at nested limit",
|
||||
json.encode, { {{{{{"nested"}}}}} }, true, { '[[[[["nested"]]]]]' } },
|
||||
{ "Encode nested table as array after nested limit [throw error]",
|
||||
json.encode, { { {{{{{"nested"}}}}} } },
|
||||
false, { "Cannot serialise, excessive nesting (6)" } },
|
||||
{ "Encode nested table as object at nested limit",
|
||||
json.encode, { {a={b={c={d={e="nested"}}}}} },
|
||||
true, { '{"a":{"b":{"c":{"d":{"e":"nested"}}}}}' } },
|
||||
{ "Encode nested table as object over nested limit [throw error]",
|
||||
json.encode, { {a={b={c={d={e={f="nested"}}}}}} },
|
||||
false, { "Cannot serialise, excessive nesting (6)" } },
|
||||
{ "Encode table with cycle [throw error]",
|
||||
json.encode, { testdata.table_cycle },
|
||||
false, { "Cannot serialise, excessive nesting (6)" } },
|
||||
{ "Set encode_max_depth(1000)",
|
||||
json.encode_max_depth, { 1000 }, true, { 1000 } },
|
||||
{ "Encode deeply nested data [throw error]",
|
||||
json.encode, { testdata.deeply_nested_data },
|
||||
false, { "Cannot serialise, excessive nesting (1001)" } },
|
||||
|
||||
-- Test encoding simple types
|
||||
{ "Encode null",
|
||||
json.encode, { json.null }, true, { 'null' } },
|
||||
{ "Encode true",
|
||||
json.encode, { true }, true, { 'true' } },
|
||||
{ "Encode false",
|
||||
json.encode, { false }, true, { 'false' } },
|
||||
{ "Encode empty object",
|
||||
json.encode, { { } }, true, { '{}' } },
|
||||
{ "Encode integer",
|
||||
json.encode, { 10 }, true, { '10' } },
|
||||
{ "Encode string",
|
||||
json.encode, { "hello" }, true, { '"hello"' } },
|
||||
{ "Encode Lua function [throw error]",
|
||||
json.encode, { function () end },
|
||||
false, { "Cannot serialise function: type not supported" } },
|
||||
|
||||
-- Test decoding invalid numbers
|
||||
{ "Set decode_invalid_numbers(true)",
|
||||
json.decode_invalid_numbers, { true }, true, { true } },
|
||||
{ "Decode hexadecimal",
|
||||
json.decode, { '0x6.ffp1' }, true, { 13.9921875 } },
|
||||
{ "Decode numbers with leading zero",
|
||||
json.decode, { '[ 0123, 00.33 ]' }, true, { { 123, 0.33 } } },
|
||||
{ "Decode +-Inf",
|
||||
json.decode, { '[ +Inf, Inf, -Inf ]' }, true, { { Inf, Inf, -Inf } } },
|
||||
{ "Decode +-Infinity",
|
||||
json.decode, { '[ +Infinity, Infinity, -Infinity ]' },
|
||||
true, { { Inf, Inf, -Inf } } },
|
||||
{ "Decode +-NaN",
|
||||
json.decode, { '[ +NaN, NaN, -NaN ]' }, true, { { NaN, NaN, NaN } } },
|
||||
{ "Decode Infrared (not infinity) [throw error]",
|
||||
json.decode, { 'Infrared' },
|
||||
false, { "Expected the end but found invalid token at character 4" } },
|
||||
{ "Decode Noodle (not NaN) [throw error]",
|
||||
json.decode, { 'Noodle' },
|
||||
false, { "Expected value but found invalid token at character 1" } },
|
||||
{ "Set decode_invalid_numbers(false)",
|
||||
json.decode_invalid_numbers, { false }, true, { false } },
|
||||
{ "Decode hexadecimal [throw error]",
|
||||
json.decode, { '0x6' },
|
||||
false, { "Expected value but found invalid number at character 1" } },
|
||||
{ "Decode numbers with leading zero [throw error]",
|
||||
json.decode, { '[ 0123, 00.33 ]' },
|
||||
false, { "Expected value but found invalid number at character 3" } },
|
||||
{ "Decode +-Inf [throw error]",
|
||||
json.decode, { '[ +Inf, Inf, -Inf ]' },
|
||||
false, { "Expected value but found invalid token at character 3" } },
|
||||
{ "Decode +-Infinity [throw error]",
|
||||
json.decode, { '[ +Infinity, Infinity, -Infinity ]' },
|
||||
false, { "Expected value but found invalid token at character 3" } },
|
||||
{ "Decode +-NaN [throw error]",
|
||||
json.decode, { '[ +NaN, NaN, -NaN ]' },
|
||||
false, { "Expected value but found invalid token at character 3" } },
|
||||
{ 'Set decode_invalid_numbers("on")',
|
||||
json.decode_invalid_numbers, { "on" }, true, { true } },
|
||||
|
||||
-- Test encoding invalid numbers
|
||||
{ "Set encode_invalid_numbers(false)",
|
||||
json.encode_invalid_numbers, { false }, true, { false } },
|
||||
{ "Encode NaN [throw error]",
|
||||
json.encode, { NaN },
|
||||
false, { "Cannot serialise number: must not be NaN or Inf" } },
|
||||
{ "Encode Infinity [throw error]",
|
||||
json.encode, { Inf },
|
||||
false, { "Cannot serialise number: must not be NaN or Inf" } },
|
||||
{ "Set encode_invalid_numbers(\"null\")",
|
||||
json.encode_invalid_numbers, { "null" }, true, { "null" } },
|
||||
{ "Encode NaN as null",
|
||||
json.encode, { NaN }, true, { "null" } },
|
||||
{ "Encode Infinity as null",
|
||||
json.encode, { Inf }, true, { "null" } },
|
||||
{ "Set encode_invalid_numbers(true)",
|
||||
json.encode_invalid_numbers, { true }, true, { true } },
|
||||
{ "Encode NaN",
|
||||
json.encode, { NaN }, true, { "nan" } },
|
||||
{ "Encode Infinity",
|
||||
json.encode, { Inf }, true, { "inf" } },
|
||||
{ 'Set encode_invalid_numbers("off")',
|
||||
json.encode_invalid_numbers, { "off" }, true, { false } },
|
||||
|
||||
-- Test encoding tables
|
||||
{ "Set encode_sparse_array(true, 2, 3)",
|
||||
json.encode_sparse_array, { true, 2, 3 }, true, { true, 2, 3 } },
|
||||
{ "Encode sparse table as array #1",
|
||||
json.encode, { { [3] = "sparse test" } },
|
||||
true, { '[null,null,"sparse test"]' } },
|
||||
{ "Encode sparse table as array #2",
|
||||
json.encode, { { [1] = "one", [4] = "sparse test" } },
|
||||
true, { '["one",null,null,"sparse test"]' } },
|
||||
{ "Encode sparse array as object",
|
||||
json.encode, { { [1] = "one", [5] = "sparse test" } },
|
||||
true, { '{"1":"one","5":"sparse test"}' } },
|
||||
{ "Encode table with numeric string key as object",
|
||||
json.encode, { { ["2"] = "numeric string key test" } },
|
||||
true, { '{"2":"numeric string key test"}' } },
|
||||
{ "Set encode_sparse_array(false)",
|
||||
json.encode_sparse_array, { false }, true, { false, 2, 3 } },
|
||||
{ "Encode table with incompatible key [throw error]",
|
||||
json.encode, { { [false] = "wrong" } },
|
||||
false, { "Cannot serialise boolean: table key must be a number or string" } },
|
||||
|
||||
-- Test escaping
|
||||
{ "Encode all octets (8-bit clean)",
|
||||
json.encode, { testdata.octets_raw }, true, { testdata.octets_escaped } },
|
||||
{ "Decode all escaped octets",
|
||||
json.decode, { testdata.octets_escaped }, true, { testdata.octets_raw } },
|
||||
{ "Decode single UTF-16 escape",
|
||||
json.decode, { [["\uF800"]] }, true, { "\239\160\128" } },
|
||||
{ "Decode all UTF-16 escapes (including surrogate combinations)",
|
||||
json.decode, { testdata.utf16_escaped }, true, { testdata.utf8_raw } },
|
||||
{ "Decode swapped surrogate pair [throw error]",
|
||||
json.decode, { [["\uDC00\uD800"]] },
|
||||
false, { "Expected value but found invalid unicode escape code at character 2" } },
|
||||
{ "Decode duplicate high surrogate [throw error]",
|
||||
json.decode, { [["\uDB00\uDB00"]] },
|
||||
false, { "Expected value but found invalid unicode escape code at character 2" } },
|
||||
{ "Decode duplicate low surrogate [throw error]",
|
||||
json.decode, { [["\uDB00\uDB00"]] },
|
||||
false, { "Expected value but found invalid unicode escape code at character 2" } },
|
||||
{ "Decode missing low surrogate [throw error]",
|
||||
json.decode, { [["\uDB00"]] },
|
||||
false, { "Expected value but found invalid unicode escape code at character 2" } },
|
||||
{ "Decode invalid low surrogate [throw error]",
|
||||
json.decode, { [["\uDB00\uD"]] },
|
||||
false, { "Expected value but found invalid unicode escape code at character 2" } },
|
||||
|
||||
-- Test locale support
|
||||
--
|
||||
-- The standard Lua interpreter is ANSI C online doesn't support locales
|
||||
-- by default. Force a known problematic locale to test strtod()/sprintf().
|
||||
{ "Set locale to cs_CZ (comma separator)", function ()
|
||||
os.setlocale("cs_CZ")
|
||||
json.new()
|
||||
end },
|
||||
{ "Encode number under comma locale",
|
||||
json.encode, { 1.5 }, true, { '1.5' } },
|
||||
{ "Decode number in array under comma locale",
|
||||
json.decode, { '[ 10, "test" ]' }, true, { { 10, "test" } } },
|
||||
{ "Revert locale to POSIX", function ()
|
||||
os.setlocale("C")
|
||||
json.new()
|
||||
end },
|
||||
|
||||
-- Test encode_keep_buffer() and enable_number_precision()
|
||||
{ "Set encode_keep_buffer(false)",
|
||||
json.encode_keep_buffer, { false }, true, { false } },
|
||||
{ "Set encode_number_precision(3)",
|
||||
json.encode_number_precision, { 3 }, true, { 3 } },
|
||||
{ "Encode number with precision 3",
|
||||
json.encode, { 1/3 }, true, { "0.333" } },
|
||||
{ "Set encode_number_precision(14)",
|
||||
json.encode_number_precision, { 14 }, true, { 14 } },
|
||||
{ "Set encode_keep_buffer(true)",
|
||||
json.encode_keep_buffer, { true }, true, { true } },
|
||||
|
||||
-- Test config API errors
|
||||
-- Function is listed as '?' due to pcall
|
||||
{ "Set encode_number_precision(0) [throw error]",
|
||||
json.encode_number_precision, { 0 },
|
||||
false, { "bad argument #1 to '?' (expected integer between 1 and 14)" } },
|
||||
{ "Set encode_number_precision(\"five\") [throw error]",
|
||||
json.encode_number_precision, { "five" },
|
||||
false, { "bad argument #1 to '?' (number expected, got string)" } },
|
||||
{ "Set encode_keep_buffer(nil, true) [throw error]",
|
||||
json.encode_keep_buffer, { nil, true },
|
||||
false, { "bad argument #2 to '?' (found too many arguments)" } },
|
||||
{ "Set encode_max_depth(\"wrong\") [throw error]",
|
||||
json.encode_max_depth, { "wrong" },
|
||||
false, { "bad argument #1 to '?' (number expected, got string)" } },
|
||||
{ "Set decode_max_depth(0) [throw error]",
|
||||
json.decode_max_depth, { "0" },
|
||||
false, { "bad argument #1 to '?' (expected integer between 1 and 2147483647)" } },
|
||||
{ "Set encode_invalid_numbers(-2) [throw error]",
|
||||
json.encode_invalid_numbers, { -2 },
|
||||
false, { "bad argument #1 to '?' (invalid option '-2')" } },
|
||||
{ "Set decode_invalid_numbers(true, false) [throw error]",
|
||||
json.decode_invalid_numbers, { true, false },
|
||||
false, { "bad argument #2 to '?' (found too many arguments)" } },
|
||||
{ "Set encode_sparse_array(\"not quite on\") [throw error]",
|
||||
json.encode_sparse_array, { "not quite on" },
|
||||
false, { "bad argument #1 to '?' (invalid option 'not quite on')" } },
|
||||
|
||||
{ "Reset Lua CJSON configuration", function () json = json.new() end },
|
||||
-- Wrap in a function to ensure the table returned by json.new() is used
|
||||
{ "Check encode_sparse_array()",
|
||||
function (...) return json.encode_sparse_array(...) end, { },
|
||||
true, { false, 2, 10 } },
|
||||
|
||||
{ "Encode (safe) simple value",
|
||||
json_safe.encode, { true },
|
||||
true, { "true" } },
|
||||
{ "Encode (safe) argument validation [throw error]",
|
||||
json_safe.encode, { "arg1", "arg2" },
|
||||
false, { "bad argument #1 to '?' (expected 1 argument)" } },
|
||||
{ "Decode (safe) error generation",
|
||||
json_safe.decode, { "Oops" },
|
||||
true, { nil, "Expected value but found invalid token at character 1" } },
|
||||
{ "Decode (safe) error generation after new()",
|
||||
function(...) return json_safe.new().decode(...) end, { "Oops" },
|
||||
true, { nil, "Expected value but found invalid token at character 1" } },
|
||||
}
|
||||
|
||||
print(("==> Testing Lua CJSON version %s\n"):format(json._VERSION))
|
||||
|
||||
util.run_test_group(cjson_tests)
|
||||
|
||||
for _, filename in ipairs(arg) do
|
||||
util.run_test("Decode cycle " .. filename, test_decode_cycle, { filename },
|
||||
true, { true })
|
||||
end
|
||||
|
||||
local pass, total = util.run_test_summary()
|
||||
|
||||
if pass == total then
|
||||
print("==> Summary: all tests succeeded")
|
||||
else
|
||||
print(("==> Summary: %d/%d tests failed"):format(total - pass, total))
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
-- vi:ai et sw=4 ts=4:
|
||||
1
3rd/lua-cjson/tests/types.json
Normal file
1
3rd/lua-cjson/tests/types.json
Normal file
@@ -0,0 +1 @@
|
||||
{ "array": [ 10, true, null ] }
|
||||
Reference in New Issue
Block a user