bluebird75 / luaunit

LuaUnit is a popular unit-testing framework for Lua, with an interface typical of xUnit libraries (Python unittest, Junit, NUnit, ...). It supports several output formats (Text, TAP, JUnit, ...) to be used directly or work with Continuous Integration platforms (Jenkins, Maven, ...).
Other
572 stars 137 forks source link

assertEquals can't handle non-sequential arrays #122

Closed mz-gh closed 5 years ago

mz-gh commented 5 years ago

Hi!

Given the following script:

#!/usr/bin/env lua

luaunit = require("luaunit")

TestLuaUnit = {}

function TestLuaUnit:testNonSeqArray()
    local actual = {1, nil, 2}
    local expected = {1, [3]=2}

    luaunit.assertEquals(actual[1], expected[1])
    luaunit.assertEquals(actual[2], expected[2])
    luaunit.assertEquals(actual[3], expected[3])
    luaunit.assertEquals(actual, expected)
end

luaunit.LuaUnit.run()

The last assert fails with the following output:

Started on Fri Apr 26 17:41:40 2019
    TestLuaUnit.testNonSeqArray ... FAIL
./luaunit_non_seq_array.lua:14: expected: {1, 3=2}
actual: {1, 3=2}
=========================================================
Failed tests:
-------------
1) TestLuaUnit.testNonSeqArray
./luaunit_non_seq_array.lua:14: expected: {1, 3=2}
actual: {1, 3=2}
stack traceback:
    ./luaunit_non_seq_array.lua:14: in upvalue 'TestLuaUnit.testNonSeqArray'

Ran 1 tests in 0.001 seconds, 0 successes, 1 failure

So, the elements are equal, yet the arrays are not.

The reason why it fails is most probably that when checking the equality of arrays the length operator is used, which isn't reliable if the arrays are non-sequential (contains 'nil' somewhere "in the middle").

Another issue for me here is, that according to the output, the arrays seem to be equal, so no clue is given, why the test has failed.

bluebird75 commented 5 years ago

Ok. I clearly missed that the length of an array is a non-deterministic thing. The lua language will never cease to surprise me.

The documentation of Lua precisely reads :

If the array has "holes" (that is, nil values between other non-nil values), then #t can be any of the indices that directly precedes a nil value (that is, it may consider any such nil value as the end of the array).

So, the table {1, nil, 3} may have length 1 or 3 and both of them are legitimate lengths. How not convienent !

I'll update luaunit to deal with this, thanks for spotting it.

bluebird75 commented 5 years ago

You can use the luaunit from master to get the correct behavior. Or you can also just remove the offending length comparison in line 1120 of luaunit.lua