aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Pulford <mark@kyne.com.au>2011-05-03 23:04:22 +0930
committerMark Pulford <mark@kyne.com.au>2011-05-03 23:04:22 +0930
commit4146070e69475d5eedcf7a9e3d990e511f46ec7a (patch)
tree5e6bfa66ee9a1fc4ac4125f349c55a3d7c551e35
parentce3a769dbdd13571b5b761d933e17e8fe5771739 (diff)
downloadlua-cjson-4146070e69475d5eedcf7a9e3d990e511f46ec7a.tar.gz
lua-cjson-4146070e69475d5eedcf7a9e3d990e511f46ec7a.tar.bz2
lua-cjson-4146070e69475d5eedcf7a9e3d990e511f46ec7a.zip
Add basic JSON tests and benchmark
-rw-r--r--tests/README2
-rwxr-xr-xtests/bench.lua39
-rw-r--r--tests/common.lua79
-rw-r--r--tests/example1.json24
-rw-r--r--tests/example2.json11
-rw-r--r--tests/example3.json26
-rw-r--r--tests/example4.json90
-rw-r--r--tests/example5.json27
-rw-r--r--tests/rfc-example1.json13
-rw-r--r--tests/rfc-example2.json22
-rwxr-xr-xtests/test.lua132
11 files changed, 465 insertions, 0 deletions
diff --git a/tests/README b/tests/README
new file mode 100644
index 0000000..58e7655
--- /dev/null
+++ b/tests/README
@@ -0,0 +1,2 @@
1These JSON examples were taken from the JSON website
2(http://json.org/example.html) and RFC 4627.
diff --git a/tests/bench.lua b/tests/bench.lua
new file mode 100755
index 0000000..b5b1a77
--- /dev/null
+++ b/tests/bench.lua
@@ -0,0 +1,39 @@
1#!/usr/bin/env lua
2
3-- Simple JSON benchmark.
4--
5-- Your Mileage May Vary.
6
7require "common"
8local json = require "cjson"
9--local json = require "json"
10--local json = require "dkjson"
11
12function bench_file(filename)
13 local data_json = file_load(filename)
14 local data_obj = json.decode(data_json)
15
16 local function test_encode ()
17 json.encode(data_obj)
18 end
19 local function test_decode ()
20 json.decode(data_json)
21 end
22
23 local tests = {
24 encode = test_encode,
25 decode = test_decode
26 }
27
28 return benchmark(tests, 5000, 5)
29end
30
31i = 1
32while arg[i] do
33 local results = {}
34 results[arg[i]] = bench_file(arg[i])
35 dump_value(results)
36 i = i + 1
37end
38
39-- vi:ai et sw=4 ts=4:
diff --git a/tests/common.lua b/tests/common.lua
new file mode 100644
index 0000000..e935032
--- /dev/null
+++ b/tests/common.lua
@@ -0,0 +1,79 @@
1require "cjson"
2require "posix"
3
4function dump_value(value, indent)
5 if indent == nil then
6 indent = ""
7 end
8
9 if value == cjson.null then
10 value = "<cjson.null>"
11 end
12
13 if type(value) == "string" or type(value) == "number" or
14 type(value) == "boolean" then
15 print(indent .. tostring(value))
16 elseif type(value) == "table" then
17 local count = 0
18 for k, v in pairs(value) do
19 dump_value(v, indent .. k .. ": ")
20 count = count + 1
21 end
22 if count == 0 then
23 print(indent .. ": <empty>")
24 end
25 else
26 print(indent .. "<" .. type(value) .. ">")
27 end
28
29end
30
31function file_load(filename)
32 local file, err = io.open(filename)
33 if file == nil then
34 error("Unable to read " .. filename)
35 end
36 local data = file:read("*a")
37 file:close()
38
39 return data
40end
41
42function gettimeofday()
43 local tv_sec, tv_usec = posix.gettimeofday()
44
45 return tv_sec + tv_usec / 1000000
46end
47
48function benchmark(tests, iter, rep)
49 local function bench(func, iter)
50 collectgarbage("collect")
51 local t = gettimeofday()
52 for i = 1, iter do
53 func(i)
54 end
55 t = gettimeofday() - t
56 return (iter / t)
57 end
58
59 local test_results = {}
60 for name, func in pairs(tests) do
61 -- k(number), v(string)
62 -- k(string), v(function)
63 -- k(number), v(function)
64 if type(func) == "string" then
65 name = func
66 func = _G[name]
67 end
68 local result = {}
69 for i = 1, rep do
70 result[i] = bench(func, iter)
71 end
72 table.sort(result)
73 test_results[name] = result[rep]
74 end
75
76 return test_results
77end
78
79-- vi:ai et sw=4 ts=4:
diff --git a/tests/example1.json b/tests/example1.json
new file mode 100644
index 0000000..53ec437
--- /dev/null
+++ b/tests/example1.json
@@ -0,0 +1,24 @@
1{
2 "glossary": {
3 "title": "example glossary",
4 "GlossDiv": {
5 "title": "S",
6 "GlossList": {
7 "GlossEntry": {
8 "ID": "SGML",
9 "SortAs": "SGML",
10 "GlossTerm": "Standard Generalized Mark
11up Language",
12 "Acronym": "SGML",
13 "Abbrev": "ISO 8879:1986",
14 "GlossDef": {
15 "para": "A meta-markup language, used to create markup
16languages such as DocBook.",
17 "GlossSeeAlso": ["GML", "XML"]
18 },
19 "GlossSee": "markup"
20 }
21 }
22 }
23 }
24}
diff --git a/tests/example2.json b/tests/example2.json
new file mode 100644
index 0000000..5600991
--- /dev/null
+++ b/tests/example2.json
@@ -0,0 +1,11 @@
1{"menu": {
2 "id": "file",
3 "value": "File",
4 "popup": {
5 "menuitem": [
6 {"value": "New", "onclick": "CreateNewDoc()"},
7 {"value": "Open", "onclick": "OpenDoc()"},
8 {"value": "Close", "onclick": "CloseDoc()"}
9 ]
10 }
11}}
diff --git a/tests/example3.json b/tests/example3.json
new file mode 100644
index 0000000..d7237a5
--- /dev/null
+++ b/tests/example3.json
@@ -0,0 +1,26 @@
1{"widget": {
2 "debug": "on",
3 "window": {
4 "title": "Sample Konfabulator Widget",
5 "name": "main_window",
6 "width": 500,
7 "height": 500
8 },
9 "image": {
10 "src": "Images/Sun.png",
11 "name": "sun1",
12 "hOffset": 250,
13 "vOffset": 250,
14 "alignment": "center"
15 },
16 "text": {
17 "data": "Click Here",
18 "size": 36,
19 "style": "bold",
20 "name": "text1",
21 "hOffset": 250,
22 "vOffset": 100,
23 "alignment": "center",
24 "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
25 }
26}}
diff --git a/tests/example4.json b/tests/example4.json
new file mode 100644
index 0000000..16335b2
--- /dev/null
+++ b/tests/example4.json
@@ -0,0 +1,90 @@
1{"web-app": {
2 "servlet": [
3 {
4 "servlet-name": "cofaxCDS",
5 "servlet-class": "org.cofax.cds.CDSServlet",
6 "init-param": {
7 "configGlossary:installationAt": "Philadelphia, PA",
8 "configGlossary:adminEmail": "ksm@pobox.com",
9 "configGlossary:poweredBy": "Cofax",
10 "configGlossary:poweredByIcon": "/images/cofax.gif",
11 "configGlossary:staticPath": "/content/static",
12 "templateProcessorClass": "org.cofax.WysiwygTemplate",
13 "templateLoaderClass": "org.cofax.FilesTemplateLoader",
14 "templatePath": "templates",
15 "templateOverridePath": "",
16 "defaultListTemplate": "listTemplate.htm",
17 "defaultFileTemplate": "articleTemplate.htm",
18 "useJSP": false,
19 "jspListTemplate": "listTemplate.jsp",
20 "jspFileTemplate": "articleTemplate.jsp",
21 "cachePackageTagsTrack": 200,
22 "cachePackageTagsStore": 200,
23 "cachePackageTagsRefresh": 60,
24 "cacheTemplatesTrack": 100,
25 "cacheTemplatesStore": 50,
26 "cacheTemplatesRefresh": 15,
27 "cachePagesTrack": 200,
28 "cachePagesStore": 100,
29 "cachePagesRefresh": 10,
30 "cachePagesDirtyRead": 10,
31 "searchEngineListTemplate": "forSearchEnginesList.htm",
32 "searchEngineFileTemplate": "forSearchEngines.htm",
33 "searchEngineRobotsDb": "WEB-INF/robots.db",
34 "useDataStore": true,
35 "dataStoreClass": "org.cofax.SqlDataStore",
36 "redirectionClass": "org.cofax.SqlRedirection",
37 "dataStoreName": "cofax",
38 "dataStoreDriver": "com.microsoft.jdbc.sqlserver.SQLServerDriver",
39 "dataStoreUrl": "jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName
40=goon",
41 "dataStoreUser": "sa",
42 "dataStorePassword": "dataStoreTestQuery",
43 "dataStoreTestQuery": "SET NOCOUNT ON;select test='test';",
44 "dataStoreLogFile": "/usr/local/tomcat/logs/datastore.log",
45 "dataStoreInitConns": 10,
46 "dataStoreMaxConns": 100,
47 "dataStoreConnUsageLimit": 100,
48 "dataStoreLogLevel": "debug",
49 "maxUrlLength": 500}},
50 {
51 "servlet-name": "cofaxEmail",
52 "servlet-class": "org.cofax.cds.EmailServlet",
53 "init-param": {
54 "mailHost": "mail1",
55 "mailHostOverride": "mail2"}},
56 {
57 "servlet-name": "cofaxAdmin",
58 "servlet-class": "org.cofax.cds.AdminServlet"},
59
60 {
61 "servlet-name": "fileServlet",
62 "servlet-class": "org.cofax.cds.FileServlet"},
63 {
64 "servlet-name": "cofaxTools",
65 "servlet-class": "org.cofax.cms.CofaxToolsServlet",
66 "init-param": {
67 "templatePath": "toolstemplates/",
68 "log": 1,
69 "logLocation": "/usr/local/tomcat/logs/CofaxTools.log",
70 "logMaxSize": "",
71 "dataLog": 1,
72 "dataLogLocation": "/usr/local/tomcat/logs/dataLog.log",
73 "dataLogMaxSize": "",
74 "removePageCache": "/content/admin/remove?cache=pages&id=",
75 "removeTemplateCache": "/content/admin/remove?cache=templates&id=",
76 "fileTransferFolder": "/usr/local/tomcat/webapps/content/fileTransferFo
77lder",
78 "lookInContext": 1,
79 "adminGroupID": 4,
80 "betaServer": true}}],
81 "servlet-mapping": {
82 "cofaxCDS": "/",
83 "cofaxEmail": "/cofaxutil/aemail/*",
84 "cofaxAdmin": "/admin/*",
85 "fileServlet": "/static/*",
86 "cofaxTools": "/tools/*"},
87
88 "taglib": {
89 "taglib-uri": "cofax.tld",
90 "taglib-location": "/WEB-INF/tlds/cofax.tld"}}}
diff --git a/tests/example5.json b/tests/example5.json
new file mode 100644
index 0000000..49980ca
--- /dev/null
+++ b/tests/example5.json
@@ -0,0 +1,27 @@
1{"menu": {
2 "header": "SVG Viewer",
3 "items": [
4 {"id": "Open"},
5 {"id": "OpenNew", "label": "Open New"},
6 null,
7 {"id": "ZoomIn", "label": "Zoom In"},
8 {"id": "ZoomOut", "label": "Zoom Out"},
9 {"id": "OriginalView", "label": "Original View"},
10 null,
11 {"id": "Quality"},
12 {"id": "Pause"},
13 {"id": "Mute"},
14 null,
15 {"id": "Find", "label": "Find..."},
16 {"id": "FindAgain", "label": "Find Again"},
17 {"id": "Copy"},
18 {"id": "CopyAgain", "label": "Copy Again"},
19 {"id": "CopySVG", "label": "Copy SVG"},
20 {"id": "ViewSVG", "label": "View SVG"},
21 {"id": "ViewSource", "label": "View Source"},
22 {"id": "SaveAs", "label": "Save As"},
23 null,
24 {"id": "Help"},
25 {"id": "About", "label": "About Adobe CVG Viewer..."}
26 ]
27}}
diff --git a/tests/rfc-example1.json b/tests/rfc-example1.json
new file mode 100644
index 0000000..73532fa
--- /dev/null
+++ b/tests/rfc-example1.json
@@ -0,0 +1,13 @@
1{
2 "Image": {
3 "Width": 800,
4 "Height": 600,
5 "Title": "View from 15th Floor",
6 "Thumbnail": {
7 "Url": "http://www.example.com/image/481989943",
8 "Height": 125,
9 "Width": "100"
10 },
11 "IDs": [116, 943, 234, 38793]
12 }
13}
diff --git a/tests/rfc-example2.json b/tests/rfc-example2.json
new file mode 100644
index 0000000..2a0cb68
--- /dev/null
+++ b/tests/rfc-example2.json
@@ -0,0 +1,22 @@
1[
2 {
3 "precision": "zip",
4 "Latitude": 37.7668,
5 "Longitude": -122.3959,
6 "Address": "",
7 "City": "SAN FRANCISCO",
8 "State": "CA",
9 "Zip": "94107",
10 "Country": "US"
11 },
12 {
13 "precision": "zip",
14 "Latitude": 37.371991,
15 "Longitude": -122.026020,
16 "Address": "",
17 "City": "SUNNYVALE",
18 "State": "CA",
19 "Zip": "94085",
20 "Country": "US"
21 }
22]
diff --git a/tests/test.lua b/tests/test.lua
new file mode 100755
index 0000000..9424e8f
--- /dev/null
+++ b/tests/test.lua
@@ -0,0 +1,132 @@
1#!/usr/bin/env lua
2
3require "common"
4local json = require "cjson"
5
6local cjson_test_non_default = true
7
8function run_tests(tests, func)
9 for k, v in ipairs(tests) do
10 local success, msg = pcall(func, v)
11 if not success then
12 print("Error: " .. msg)
13 end
14 print()
15 end
16end
17
18local simple_value_tests = {
19 [[ "test string" ]],
20 [[ -5e3 ]],
21 [[ null ]],
22 [[ true ]],
23 [[ false ]],
24 [[ { "1": "one", "3": "three" } ]]
25}
26
27local numeric_tests = {
28 "[ 0.0, -1, 0.3e-3, 1023.2 ]",
29 "[ 00123 ]",
30 "[ 05.2 ]",
31 "[ 0e10 ]",
32 "[ 0x6 ]",
33 "[ +Inf ]",
34 "[ Inf ]",
35 "[ -Inf ]",
36 "[ +Infinity ]",
37 "[ Infinity ]",
38 "[ -Infinity ]",
39 "[ +NaN ]",
40 "[ NaN ]",
41 "[ -NaN ]",
42 "[ Infrared ]",
43 "[ Noodle ]"
44}
45
46local object_tests = {
47 { [5] = "sparse test" },
48 { [6] = "sparse test" },
49 {{{{{{{{{{{{{{{{{{{{{ "nested" }}}}}}}}}}}}}}}}}}}}}
50}
51
52local decode_error_tests = {
53 '{ "unexpected eof": ',
54 '{ "extra data": true }, false',
55 [[ { "bad escape \q code" } ]],
56 [[ { "bad unicode \u0f6 escape" } ]],
57 [[ [ "bad barewood", test ] ]],
58 "[ -+12 ]",
59 "-v",
60 "[ 0.4eg10 ]",
61}
62
63local simple_encode_tests = {
64 json.null, true, false, { }, 10, "hello"
65}
66
67
68local function gen_ascii(max)
69 local chars = {}
70 for i = 0, max do
71 chars[i] = string.char(i)
72 end
73 return table.concat(chars)
74end
75
76local function decode_encode(text)
77 print("==JSON=> " .. text)
78 local obj_data = json.decode(text)
79 dump_value(obj_data)
80 local obj_json = json.encode(obj_data)
81 print(obj_json)
82end
83local function encode_decode(obj)
84 print("==OBJ==> ")
85 dump_value(obj)
86 local obj_json = json.encode(obj)
87 print(obj_json)
88 local obj_data = json.decode(obj_json)
89 dump_value(obj_data)
90end
91
92run_tests(simple_value_tests, decode_encode)
93run_tests(decode_error_tests, decode_encode)
94
95run_tests(numeric_tests, decode_encode)
96
97if cjson_test_non_default then
98 print("=== Disabling strict numbers ===")
99 json.strict_numbers(false)
100 run_tests(numeric_tests, decode_encode)
101 json.strict_numbers(true)
102end
103
104run_tests(object_tests, encode_decode)
105print ("Encode tests..")
106
107run_tests(simple_encode_tests, encode_decode)
108
109if cjson_test_non_default then
110 print("=== Setting max_depth to 21, sparse_ratio to 5 ===")
111 json.max_depth(21)
112 json.sparse_ratio(5)
113 run_tests(object_tests, encode_decode)
114end
115
116local ascii1 = gen_ascii(255)
117print("Unprintable escapes:")
118print(json.encode(ascii1))
119print("===")
120local ascii2 = json.decode(json.encode(ascii))
121
122print("8bit clean encode/decode: " .. tostring(ascii1 ~= ascii2))
123
124for i = 1, #arg do
125 print(arg[i] .. " enc->dec..")
126 local obj1 = json.decode(file_load(arg[i]))
127 local obj2 = json.decode(json.encode(obj1))
128 -- obj_compare(obj_json1, obj_json2)
129 print(".. unimplemented")
130end
131
132-- vi:ai et sw=4 ts=4: