weaschem: finish write tests for parse_data_table

glad I did, 'cause I found a bunch of subtle bugs
This commit is contained in:
Starbeamrainbowlabs 2023-08-18 20:27:00 +01:00
parent 25ae2fd7ee
commit 78ec40b6be
Signed by: sbrl
GPG key ID: 1BE5172E637709C2
2 changed files with 169 additions and 13 deletions

View file

@ -92,6 +92,60 @@ describe("parse.file.weaschem.parse_data_table type full", function()
[3] = -1 [3] = -1
}, result) }, result)
end) end)
it("should not parse a valid data table type full with special value -2", function()
local content = '4,2,5,-2'
local success, code, result = weaschem.parse_data_table(content, false)
assert.are.same(false, success)
assert.are.same("DATA_TABLE_INVALID_NODE_ID", code)
assert.are.same("string", type(result))
end)
it("should not parse a valid data table type full with special value -99", function()
local content = '4,2,5,-99'
local success, code, result = weaschem.parse_data_table(content, false)
assert.are.same(false, success)
assert.are.same("DATA_TABLE_INVALID_NODE_ID", code)
assert.are.same("string", type(result))
end)
it("should parse a valid data table type delta with special value -2", function()
local content = '4,2,5,-2'
local success, code, result = weaschem.parse_data_table(content, true)
assert.are.same(true, success)
assert.are.same("SUCCESS", code)
assert.are.same("table", type(result))
validate_data_table(result, true)
assert.are.same({
[0] = 4,
[1] = 2,
[2] = 5,
[3] = -2
}, result)
end)
it("should parse a valid data table type delta with special value -1", function()
local content = '4,2,5,-1'
local success, code, result = weaschem.parse_data_table(content, true)
assert.are.same(true, success)
assert.are.same("SUCCESS", code)
assert.are.same("table", type(result))
validate_data_table(result, true)
assert.are.same({
[0] = 4,
[1] = 2,
[2] = 5,
[3] = -1
}, result)
end)
it("should not parse a valid data table type delta with special value -99", function()
local content = '4,2,5,-99'
local success, code, result = weaschem.parse_data_table(content, true)
assert.are.same(false, success)
assert.are.same("DATA_TABLE_INVALID_NODE_ID", code)
assert.are.same("string", type(result))
end)
it("should parse a valid data table with run-length encoding", function() it("should parse a valid data table with run-length encoding", function()
local content = '4,2,5x5' local content = '4,2,5x5'
local success, code, result = weaschem.parse_data_table(content) local success, code, result = weaschem.parse_data_table(content)
@ -110,5 +164,95 @@ describe("parse.file.weaschem.parse_data_table type full", function()
[6] = 5 [6] = 5
}, result) }, result)
end) end)
it("should not parse a data table with invalid run-length count", function()
local content = '4,cheesex2,5'
local success, code, result = weaschem.parse_data_table(content, false)
assert.are.same(false, success)
assert.are.same("DATA_TABLE_INVALID_VALUE", code)
assert.are.same("string", type(result))
end)
it("should not parse a data table with invalid node id", function()
local content = '4,rocket,5'
local success, code, result = weaschem.parse_data_table(content, false)
assert.are.same(false, success)
assert.are.same("DATA_TABLE_INVALID_NODE_ID", code)
assert.are.same("string", type(result))
end)
it("should not parse a data table with invalid run-length node id", function()
local content = '4,3xrocket,5'
local success, code, result = weaschem.parse_data_table(content, false)
assert.are.same(false, success)
assert.are.same("DATA_TABLE_INVALID_VALUE", code)
assert.are.same("string", type(result))
end)
it("should not parse a data table with invalid run-length node id with multiple minus signs", function()
local content = '4,3x3-3,5'
local success, code, result = weaschem.parse_data_table(content, false)
assert.are.same(false, success)
assert.are.same("DATA_TABLE_INVALID_VALUE", code)
assert.are.same("string", type(result))
end)
it("should not parse a valid data table type full run-length encoding with special value -2", function()
local content = '4,2,5,2x-2'
local success, code, result = weaschem.parse_data_table(content, false)
assert.are.same(false, success)
assert.are.same("DATA_TABLE_INVALID_NODE_ID", code)
assert.are.same("string", type(result))
end)
it("should not parse a valid data table type full run-length encoding with special value -99", function()
local content = '4,2,5,2x-99'
local success, code, result = weaschem.parse_data_table(content, false)
assert.are.same(false, success)
assert.are.same("DATA_TABLE_INVALID_NODE_ID", code)
assert.are.same("string", type(result))
end)
it("should parse a valid data table type delta run-length encoding with special value -2", function()
local content = '4,2,5,2x-2'
local success, code, result = weaschem.parse_data_table(content, true)
assert.are.same(true, success)
assert.are.same("SUCCESS", code)
assert.are.same("table", type(result))
validate_data_table(result, true)
assert.are.same({
[0] = 4,
[1] = 2,
[2] = 5,
[3] = -2,
[4] = -2
}, result)
end)
it("should parse a valid data table type delta run-length encoding with special value -1", function()
local content = '4,2,5,2x-1'
local success, code, result = weaschem.parse_data_table(content, true)
assert.are.same(true, success)
assert.are.same("SUCCESS", code)
assert.are.same("table", type(result))
validate_data_table(result, true)
assert.are.same({
[0] = 4,
[1] = 2,
[2] = 5,
[3] = -1,
[4] = -1
}, result)
end)
it("should not parse a valid data table type delta run-length encoding with special value -99", function()
local content = '4,2,5,2x-99'
local success, code, result = weaschem.parse_data_table(content, true)
assert.are.same(false, success)
assert.are.same("DATA_TABLE_INVALID_NODE_ID", code)
assert.are.same("string", type(result))
end)
end) end)

View file

@ -153,15 +153,16 @@ function weaschem.parse_data_table(source, is_delta)
local i = 0 local i = 0
for _, next_val in pairs(values) do for _, next_val in pairs(values) do
if next_val:find("x") ~= nil then if next_val:find("x") ~= nil then
local multi_count, multi_node_id = string.match(next_val, "(%d+)x(%d+)") local multi_count, multi_node_id = string.match(next_val, "^(%d+)x(-?[%d]+)$")
-- print("DEBUG:parse_data_table next_val", next_val, "multi_count", multi_count, "multi_node_id", multi_node_id)
if multi_count == nil or multi_node_id == nil then
return false, "DATA_TABLE_INVALID_VALUE", "Error: Encountered an invalid node id / count pair at position '"..tostring(i).."'."
end
-- These tonumber() calls are guaranteed to work since we only pass a number here
multi_count = tonumber(multi_count) multi_count = tonumber(multi_count)
if type(multi_count) ~= "number" then
return false, "DATA_TABLE_INVALID_COUNT", "Encountered count value in data table at position '"..tostring(i).."'."
end
multi_node_id = tonumber(multi_node_id) multi_node_id = tonumber(multi_node_id)
if type(multi_node_id) ~= "number" then
return false, "DATA_TABLE_INVALID_NODE_ID", "Encountered node id value in data table at position '"..tostring(i).."'."
end
if is_delta then if is_delta then
if multi_node_id < -2 then if multi_node_id < -2 then
return false, "DATA_TABLE_INVALID_NODE_ID", "Error: When type=delta, then node ids must not be less then -2." return false, "DATA_TABLE_INVALID_NODE_ID", "Error: When type=delta, then node ids must not be less then -2."
@ -182,6 +183,17 @@ function weaschem.parse_data_table(source, is_delta)
return false, "DATA_TABLE_INVALID_NODE_ID", return false, "DATA_TABLE_INVALID_NODE_ID",
"Encountered node id value in data table at position '" .. tostring(i) .. "'." "Encountered node id value in data table at position '" .. tostring(i) .. "'."
end end
if is_delta then
if node_id < -2 then
return false, "DATA_TABLE_INVALID_NODE_ID",
"Error: When type=delta, then node ids must not be less then -2."
end
else
if node_id < -1 then
return false, "DATA_TABLE_INVALID_NODE_ID",
"Error: When type=delta, then node ids must not be less then -1."
end
end
data_table[i] = node_id data_table[i] = node_id
i = i + 1 i = i + 1
@ -236,13 +248,13 @@ function weaschem.parse(handle, delta_which)
if header["type"] == "full" then if header["type"] == "full" then
temp = handle:read("*l") temp = handle:read("*l")
if temp == nil then return false, "NO_DATA_TABLE", "Unable to read the data table full:data from the file." end if temp == nil then return false, "NO_DATA_TABLE", "Unable to read the data table full:data from the file." end
success, code, temp2 = weaschem.parse_data_table(temp) success, code, temp2 = weaschem.parse_data_table(temp, false)
if not success then return success, code, temp2 end if not success then return success, code, temp2 end
data_tables["data"] = temp2 data_tables["data"] = temp2
temp = handle:read("*l") temp = handle:read("*l")
if temp == nil then return false, "NO_DATA_TABLE", "Unable to read the data table full:param2 from the file." end if temp == nil then return false, "NO_DATA_TABLE", "Unable to read the data table full:param2 from the file." end
success, code, temp2 = weaschem.parse_data_table(temp) success, code, temp2 = weaschem.parse_data_table(temp, false)
if not success then return success, code, temp2 end if not success then return success, code, temp2 end
data_tables["param2"] = temp2 data_tables["param2"] = temp2
else else
@ -250,7 +262,7 @@ function weaschem.parse(handle, delta_which)
if temp == nil then return false, "NO_DATA_TABLE", "Unable to read the data table delta:data_previous from the file." end if temp == nil then return false, "NO_DATA_TABLE", "Unable to read the data table delta:data_previous from the file." end
-- delta_which="current" is the only state in which we would NOT want to parse the previous state. Regardless, we still need to read the line in though even if we immediately discard it otherwise we'll be out of sync. -- delta_which="current" is the only state in which we would NOT want to parse the previous state. Regardless, we still need to read the line in though even if we immediately discard it otherwise we'll be out of sync.
if delta_which ~= "current" then if delta_which ~= "current" then
success, code, temp2 = weaschem.parse_data_table(temp) success, code, temp2 = weaschem.parse_data_table(temp, true)
if not success then return success, code, temp2 end if not success then return success, code, temp2 end
data_tables["data_prev"] = temp2 data_tables["data_prev"] = temp2
end end
@ -258,7 +270,7 @@ function weaschem.parse(handle, delta_which)
temp = handle:read("*l") temp = handle:read("*l")
if temp == nil then return false, "NO_DATA_TABLE", "Unable to read the data table delta:param2_previous from the file." end if temp == nil then return false, "NO_DATA_TABLE", "Unable to read the data table delta:param2_previous from the file." end
if delta_which ~= "current" then if delta_which ~= "current" then
success, code, temp2 = weaschem.parse_data_table(temp) success, code, temp2 = weaschem.parse_data_table(temp, true)
if not success then return success, code, temp2 end if not success then return success, code, temp2 end
data_tables["param2_prev"] = temp2 data_tables["param2_prev"] = temp2
end end
@ -266,7 +278,7 @@ function weaschem.parse(handle, delta_which)
temp = handle:read("*l") temp = handle:read("*l")
if temp == nil then return false, "NO_DATA_TABLE", "Unable to read the data table delta:data_current from the file." end if temp == nil then return false, "NO_DATA_TABLE", "Unable to read the data table delta:data_current from the file." end
if delta_which ~= "prev" then if delta_which ~= "prev" then
success, code, temp2 = weaschem.parse_data_table(temp) success, code, temp2 = weaschem.parse_data_table(temp, true)
if not success then return success, code, temp2 end if not success then return success, code, temp2 end
data_tables["data_current"] = temp2 data_tables["data_current"] = temp2
end end
@ -274,7 +286,7 @@ function weaschem.parse(handle, delta_which)
temp = handle:read("*l") temp = handle:read("*l")
if temp == nil then return false, "NO_DATA_TABLE", "Unable to read the data table delta:param2_current from the file." end if temp == nil then return false, "NO_DATA_TABLE", "Unable to read the data table delta:param2_current from the file." end
if delta_which ~= "prev" then if delta_which ~= "prev" then
success, code, temp2 = weaschem.parse_data_table(temp) success, code, temp2 = weaschem.parse_data_table(temp, true)
if not success then return success, code, temp2 end if not success then return success, code, temp2 end
data_tables["param2_current"] = temp2 data_tables["param2_current"] = temp2
end end