-
-
Notifications
You must be signed in to change notification settings - Fork 101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix #532 by sorting table keys when processing content #974
Conversation
simoncozens
commented
Jul 22, 2020
- This could do with a test.
- I tried to find other examples where we are using pairs() on AST content, but didn't see any. A review would be helpful.
I take back what I said, this does seem to fix #532. The project in question there has an elaborate work around for #355 that basically pre-processes everything with input filter fixing potential hyphenation issues at apostrophes. That does explain why it turned up regularly in a few projects and never in others. As for tests ... I'm not to confident we have a way to reliably test non-determinism. The most likely candidate would be a Busted test unit that iterated over something a bunch of times and make sure it was the same every time. Hmmmm, yes let me try that.... |
I haven't come up a test that fails using Here'se what tried (plain in SILE = require("core/sile")
describe("The #utilities library ", function()
it("should have a short alias", function() assert.is.equal(SU, SILE.utilities) end)
describe("sortedpairs() function", function()
local input = { "a", _ = true, "c", "b", foo = "bar", "E" }
it("avoid Lua’s non-determinism", function ()
local testit = function ()
for _ = 1, 1000 do
local i = 1
-- for k, v in SU.sortedpairs(input) do
for k, v in pairs(input) do
if type(k) == "number" and k ~= i then return false
elseif k == 1 and v ~= "a" then return false
elseif k == 2 and v ~= "c" then return false
elseif k == 3 and v ~= "b" then return false
elseif k == 4 and v ~= "E" then return false
elseif k == "_" and v ~= true then return false
elseif k == "foo" and v ~= "bar" then return false
end
i = i + 1
end
end
return true
end
assert.is.truthy(testit())
end)
end)
end) |
So I've still completely failed to create a test that reproduces the problem. It's hard to test that you're doing it right when you can't get a test you know in wrong to reliably fail as a starting point. However I did some digging and came up with a few more instances of For reference if this comes up again, I found these by first adding a wrapper to debugpairs = function (var)
if var[1] then
utilities.error("called pairs() on what looks like a sequential table")
end
return pairs(var)
end Then aggressively replaced our use of
Then I worked through running tests & building the manual replacing the bad lines with |
In retrospect we could/should probably have just used |