From 461c7ef23a49062d4b1bf0e1afb3be294d007861 Mon Sep 17 00:00:00 2001 From: leaf corcoran Date: Sun, 22 Sep 2019 13:21:45 -0700 Subject: write sort_json, use it on perl tests to prevent hash table ordering failures --- tests/agentzh.t | 13 +++++++----- tests/sort_json.lua | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 tests/sort_json.lua 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})) === TEST 6: empty_array_mt and empty tables as objects (explicit) --- lua local cjson = require "cjson" +local sort_json = require "tests.sort_json" local empty_arr = setmetatable({}, cjson.empty_array_mt) -print(cjson.encode({obj = {}, arr = empty_arr})) +print(sort_json(cjson.encode({obj = {}, arr = empty_arr}))) --- out {"arr":[],"obj":{}} @@ -76,6 +77,7 @@ print(cjson.encode({obj = {}, arr = empty_arr})) === TEST 7: empty_array_mt and empty tables as objects (explicit) --- lua local cjson = require "cjson" +local sort_json = require "tests.sort_json" cjson.encode_empty_table_as_object(true) local empty_arr = setmetatable({}, cjson.empty_array_mt) local data = { @@ -88,15 +90,16 @@ local data = { } } } -print(cjson.encode(data)) +print(sort_json(cjson.encode(data))) --- out -{"foo":{"foobar":{"obj":{},"arr":[]},"obj":{}},"arr":[]} +{"arr":[],"foo":{"foobar":{"arr":[],"obj":{}},"obj":{}}} === TEST 8: empty_array_mt on non-empty tables --- lua local cjson = require "cjson" +local sort_json = require "tests.sort_json" cjson.encode_empty_table_as_object(true) local array = {"hello", "world", "lua"} setmetatable(array, cjson.empty_array_mt) @@ -110,9 +113,9 @@ local data = { } } } -print(cjson.encode(data)) +print(sort_json(cjson.encode(data))) --- out -{"foo":{"foobar":{"obj":{},"arr":[]},"obj":{}},"arr":["hello","world","lua"]} +{"arr":["hello","world","lua"],"foo":{"foobar":{"arr":[],"obj":{}},"obj":{}}} 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 @@ +-- NOTE: This will only work for simple tests. It doesn't parse strings so if +-- you put any symbols like {?[], inside of a string literal then it will break +-- The point of this function is to test basic structures, and not test JSON +-- strings + +local function sort_callback(str) + local inside = str:sub(2, -2) + + local parts = {} + local buffer = "" + local pos = 1 + + while true do + if pos > #inside then + break + end + + local append + + local parens = inside:match("^%b{}", pos) + if parens then + pos = pos + #parens + append = sort_callback(parens) + else + local array = inside:match("^%b[]", pos) + if array then + pos = pos + #array + append = array + else + local front = inside:sub(pos, pos) + pos = pos + 1 + + if front == "," then + table.insert(parts, buffer) + buffer = "" + else + append = front + end + end + end + + if append then + buffer = buffer .. append + end + end + + if buffer ~= "" then + table.insert(parts, buffer) + end + + table.sort(parts) + + return "{" .. table.concat(parts, ",") .. "}" +end + +local function sort_json(str) + return (str:gsub("%b{}", sort_callback)) +end + + +return sort_json -- cgit v1.2.3-55-g6feb