diff options
author | leaf corcoran <leafot@gmail.com> | 2019-09-22 13:21:45 -0700 |
---|---|---|
committer | leaf <leafot@gmail.com> | 2020-04-25 14:24:18 -0700 |
commit | 461c7ef23a49062d4b1bf0e1afb3be294d007861 (patch) | |
tree | 36b4e13561dd53d40bd87676c9aaf3fb5f1eea74 | |
parent | dbcfb92e12e9016060d1907a2556cc61e82f467d (diff) | |
download | lua-cjson-461c7ef23a49062d4b1bf0e1afb3be294d007861.tar.gz lua-cjson-461c7ef23a49062d4b1bf0e1afb3be294d007861.tar.bz2 lua-cjson-461c7ef23a49062d4b1bf0e1afb3be294d007861.zip |
write sort_json, use it on perl tests to prevent hash table ordering failures
-rw-r--r-- | tests/agentzh.t | 13 | ||||
-rw-r--r-- | tests/sort_json.lua | 61 |
2 files changed, 69 insertions, 5 deletions
diff --git a/tests/agentzh.t b/tests/agentzh.t index 7591902..2e7c8ce 100644 --- a/tests/agentzh.t +++ b/tests/agentzh.t | |||
@@ -66,8 +66,9 @@ print(cjson.encode({arr = empty_arr})) | |||
66 | === TEST 6: empty_array_mt and empty tables as objects (explicit) | 66 | === TEST 6: empty_array_mt and empty tables as objects (explicit) |
67 | --- lua | 67 | --- lua |
68 | local cjson = require "cjson" | 68 | local cjson = require "cjson" |
69 | local sort_json = require "tests.sort_json" | ||
69 | local empty_arr = setmetatable({}, cjson.empty_array_mt) | 70 | local empty_arr = setmetatable({}, cjson.empty_array_mt) |
70 | print(cjson.encode({obj = {}, arr = empty_arr})) | 71 | print(sort_json(cjson.encode({obj = {}, arr = empty_arr}))) |
71 | --- out | 72 | --- out |
72 | {"arr":[],"obj":{}} | 73 | {"arr":[],"obj":{}} |
73 | 74 | ||
@@ -76,6 +77,7 @@ print(cjson.encode({obj = {}, arr = empty_arr})) | |||
76 | === TEST 7: empty_array_mt and empty tables as objects (explicit) | 77 | === TEST 7: empty_array_mt and empty tables as objects (explicit) |
77 | --- lua | 78 | --- lua |
78 | local cjson = require "cjson" | 79 | local cjson = require "cjson" |
80 | local sort_json = require "tests.sort_json" | ||
79 | cjson.encode_empty_table_as_object(true) | 81 | cjson.encode_empty_table_as_object(true) |
80 | local empty_arr = setmetatable({}, cjson.empty_array_mt) | 82 | local empty_arr = setmetatable({}, cjson.empty_array_mt) |
81 | local data = { | 83 | local data = { |
@@ -88,15 +90,16 @@ local data = { | |||
88 | } | 90 | } |
89 | } | 91 | } |
90 | } | 92 | } |
91 | print(cjson.encode(data)) | 93 | print(sort_json(cjson.encode(data))) |
92 | --- out | 94 | --- out |
93 | {"foo":{"foobar":{"obj":{},"arr":[]},"obj":{}},"arr":[]} | 95 | {"arr":[],"foo":{"foobar":{"arr":[],"obj":{}},"obj":{}}} |
94 | 96 | ||
95 | 97 | ||
96 | 98 | ||
97 | === TEST 8: empty_array_mt on non-empty tables | 99 | === TEST 8: empty_array_mt on non-empty tables |
98 | --- lua | 100 | --- lua |
99 | local cjson = require "cjson" | 101 | local cjson = require "cjson" |
102 | local sort_json = require "tests.sort_json" | ||
100 | cjson.encode_empty_table_as_object(true) | 103 | cjson.encode_empty_table_as_object(true) |
101 | local array = {"hello", "world", "lua"} | 104 | local array = {"hello", "world", "lua"} |
102 | setmetatable(array, cjson.empty_array_mt) | 105 | setmetatable(array, cjson.empty_array_mt) |
@@ -110,9 +113,9 @@ local data = { | |||
110 | } | 113 | } |
111 | } | 114 | } |
112 | } | 115 | } |
113 | print(cjson.encode(data)) | 116 | print(sort_json(cjson.encode(data))) |
114 | --- out | 117 | --- out |
115 | {"foo":{"foobar":{"obj":{},"arr":[]},"obj":{}},"arr":["hello","world","lua"]} | 118 | {"arr":["hello","world","lua"],"foo":{"foobar":{"arr":[],"obj":{}},"obj":{}}} |
116 | 119 | ||
117 | 120 | ||
118 | 121 | ||
diff --git a/tests/sort_json.lua b/tests/sort_json.lua new file mode 100644 index 0000000..c95ab3c --- /dev/null +++ b/tests/sort_json.lua | |||
@@ -0,0 +1,61 @@ | |||
1 | -- NOTE: This will only work for simple tests. It doesn't parse strings so if | ||
2 | -- you put any symbols like {?[], inside of a string literal then it will break | ||
3 | -- The point of this function is to test basic structures, and not test JSON | ||
4 | -- strings | ||
5 | |||
6 | local function sort_callback(str) | ||
7 | local inside = str:sub(2, -2) | ||
8 | |||
9 | local parts = {} | ||
10 | local buffer = "" | ||
11 | local pos = 1 | ||
12 | |||
13 | while true do | ||
14 | if pos > #inside then | ||
15 | break | ||
16 | end | ||
17 | |||
18 | local append | ||
19 | |||
20 | local parens = inside:match("^%b{}", pos) | ||
21 | if parens then | ||
22 | pos = pos + #parens | ||
23 | append = sort_callback(parens) | ||
24 | else | ||
25 | local array = inside:match("^%b[]", pos) | ||
26 | if array then | ||
27 | pos = pos + #array | ||
28 | append = array | ||
29 | else | ||
30 | local front = inside:sub(pos, pos) | ||
31 | pos = pos + 1 | ||
32 | |||
33 | if front == "," then | ||
34 | table.insert(parts, buffer) | ||
35 | buffer = "" | ||
36 | else | ||
37 | append = front | ||
38 | end | ||
39 | end | ||
40 | end | ||
41 | |||
42 | if append then | ||
43 | buffer = buffer .. append | ||
44 | end | ||
45 | end | ||
46 | |||
47 | if buffer ~= "" then | ||
48 | table.insert(parts, buffer) | ||
49 | end | ||
50 | |||
51 | table.sort(parts) | ||
52 | |||
53 | return "{" .. table.concat(parts, ",") .. "}" | ||
54 | end | ||
55 | |||
56 | local function sort_json(str) | ||
57 | return (str:gsub("%b{}", sort_callback)) | ||
58 | end | ||
59 | |||
60 | |||
61 | return sort_json | ||