Module:TableTools/testcases

Module documentation

Yes All tests passed.

Name Expected Actual
Yes testCompressSparseArray
Yes testIsNan
Yes testIsPositiveInteger
Yes testNumData
Yes testRemoveDuplicates
Yes testSize
Yes testSparseIpairs
Yes testaffixNums
Yes testnumKeys


Yes All tests passed.

Name Expected Actual
Yes testCompressSparseArray
Yes testIsNan
Yes testIsPositiveInteger
Yes testNumData
Yes testRemoveDuplicates
Yes testSize
Yes testSparseIpairs
Yes testaffixNums
Yes testnumKeys

-- Unit tests for [[Module:TableTools]]. Click talk page to run tests.

local ScribuntoUnit = require('Module:ScribuntoUnit')
local suite = ScribuntoUnit:new()
local libName = 'TableTools'


-- Helper to run all tests using sandbox version of the library from the debug console. To run against main lib, use  =p.run()
function suite.runSandbox()
    local frame = mw.getCurrentFrame():newChild{title='testcases', args={module=libName .. '/sandbox', displayMode='log'}}
    return suite.run(frame)
end

-- Allow test runner to use the sandbox and the primary versions of the library with the same testcases
function suite:module()
    return require('Module:' .. (self.frame and self.frame.args.module or libName))
end

--[[
       Library-specific tests
]]

------------------------------------------------------------------------
-- Helper functions
------------------------------------------------------------------------

function suite.concatIpairs(t)
    local ret = ''
    for i, v in ipairs(t) do
        ret = ret .. tostring(v)
    end
    return ret
end

function suite:assertErrorEquals(expected, func, ...)
    local success, msg = pcall(func, ...)
    self:assertEquals(expected, msg)
end

function suite:assertTypeErrorEquals(argId, name, expectedType, actualType, func, ...)
    local expected = "bad argument #%d to '%s' (%s expected, got %s)"
    expected = expected:format(argId, name, expectedType, actualType)
    self:assertErrorEquals(expected, func, ...)
end

------------------------------------------------------------------------
-- Test isPositiveInteger
------------------------------------------------------------------------

function suite:testIsPositiveInteger()
    local tt = self:module()
    self:assertTrue(tt.isPositiveInteger(1))
    self:assertTrue(tt.isPositiveInteger(2))
    self:assertTrue(tt.isPositiveInteger(2323874623))
    self:assertFalse(tt.isPositiveInteger(0))
    self:assertFalse(tt.isPositiveInteger(-1))
    self:assertFalse(tt.isPositiveInteger(0.5))
    self:assertFalse(tt.isPositiveInteger(1.5))
    self:assertFalse(tt.isPositiveInteger('1'))
    self:assertFalse(tt.isPositiveInteger(math.huge))
    self:assertFalse(tt.isPositiveInteger('foo'))
end

------------------------------------------------------------------------
-- Test isNan
------------------------------------------------------------------------

function suite:testIsNan()
    local tt = self:module()
    self:assertTrue(tt.isNan(0/0))
    self:assertTrue(tt.isNan(math.huge * 0))
    self:assertTrue(tt.isNan(-math.huge * 0))
    self:assertTrue(tt.isNan(-1 * math.huge * 0))
    self:assertFalse(tt.isNan(0))
    self:assertFalse(tt.isNan(1))
    self:assertFalse(tt.isNan(6))
    self:assertFalse(tt.isNan(-100))
    self:assertFalse(tt.isNan(2^0.5))
    self:assertFalse(tt.isNan(99999999999999999999999999999999999999999999999))
    self:assertFalse(tt.isNan(math.pi))
end

------------------------------------------------------------------------
-- Test removeDuplicates
------------------------------------------------------------------------

function suite:testRemoveDuplicates()
    local tt = self:module()
    local isNan = tt.isNan
    local dupes =     {1, 2, 2, 3, 3, 3, 4, 2, 0/0, 5, 0/0, 5}
    -- Dupes removed: {1, 2,    3,       4,    NaN, 5, NaN}
    local removed = tt.removeDuplicates(dupes)
    self:assertEquals(7, #removed)
    self:assertEquals(1, removed[1])
    self:assertEquals(2, removed[2])
    self:assertEquals(3, removed[3])
    self:assertEquals(4, removed[4])
    self:assertTrue(isNan(removed[5]))
    self:assertEquals(5, removed[6])
    self:assertTrue(isNan(removed[7]))
    self:assertTypeErrorEquals(1, 'removeDuplicates', 'table', 'number', tt.removeDuplicates, 4)
    self:assertTypeErrorEquals(1, 'removeDuplicates', 'table', 'nil', tt.removeDuplicates)
end

------------------------------------------------------------------------
-- Sparse array variables
------------------------------------------------------------------------

local sparseArray = {1, nil, 2, nil, 3, nil, [math.huge] = math.huge, foo = 'bar', [1.5] = 1.5, ['4'] = 'four_string'}
local sparseArrayConcatenated = '123'
local numKeysConcatenated = '135'

------------------------------------------------------------------------
-- Test numKeys
------------------------------------------------------------------------

function suite:testnumKeys()
    local tt = self:module()
    local numKeys = tt.numKeys(sparseArray)
    self:assertEquals(numKeysConcatenated, suite.concatIpairs(numKeys))
    self:assertTypeErrorEquals(1, 'numKeys', 'table', 'number', tt.numKeys, 4)
    self:assertTypeErrorEquals(1, 'numKeys', 'table', 'nil', tt.numKeys)
end

------------------------------------------------------------------------
-- Test affixNums
------------------------------------------------------------------------

local affixArray = {1, a0 = 'a0', a001 = 'a001', a1 = 'a1', b2 = 'b2', a3 = 'a3', c4d = 'c4d', b5 = 'b5', B6 = 'B6', f7 = 'f7', c8d = 'c8d', a9 = nil, a10 = 'a10', [11] = 11, ['e-f12'] = 'e-f12'}
local aNumsConcatenated = '1310'
local aValsConcatenated = 'a1a3a10'
local bNumsConcatenated = '25'
local bValsConcatenated = 'b2b5'
local cdNumsConcatenated = '48'
local cdValsConcatenated = 'c4dc8d'
local efNumsConcatenated = '12'
local efValsConcatenated = 'e-f12'

function suite.concatAffixVals(t, nums, prefix, suffix)
    local ret = ''
    for i, num in ipairs(nums) do
        local key = (prefix or '') .. tostring(num) .. (suffix or '')
        ret = ret .. tostring(t[key])
    end
    return ret
end

function suite:testaffixNums()
    local tt = self:module()
    local aNums = tt.affixNums(affixArray, 'a')
    local bNums = tt.affixNums(affixArray, 'b')
    local cdNums = tt.affixNums(affixArray, 'c', 'd')
    local efNums = tt.affixNums(affixArray, 'e-f') -- "-" is magic, so we need to escape it.
    self:assertEquals(aNumsConcatenated, suite.concatIpairs(aNums))
    self:assertEquals(aValsConcatenated, suite.concatAffixVals(affixArray, aNums, 'a'))
    self:assertEquals(bNumsConcatenated, suite.concatIpairs(bNums))
    self:assertEquals(bValsConcatenated, suite.concatAffixVals(affixArray, bNums, 'b'))
    self:assertEquals(cdNumsConcatenated, suite.concatIpairs(cdNums))
    self:assertEquals(cdValsConcatenated, suite.concatAffixVals(affixArray, cdNums, 'c', 'd'))
    self:assertEquals(efNumsConcatenated, suite.concatIpairs(efNums))
    self:assertEquals(efValsConcatenated, suite.concatAffixVals(affixArray, efNums, 'e-f'))
    self:assertTypeErrorEquals(1, 'affixNums', 'table', 'number', tt.affixNums, 4)
    self:assertTypeErrorEquals(1, 'affixNums', 'table', 'nil', tt.affixNums)
end

------------------------------------------------------------------------
-- Test numData
------------------------------------------------------------------------

function suite:testNumData()
    local tt = self:module()
    local t = {1, 2, [5] = 5, foo = "foo", foo1 = "foo1", bar1 = "bar1", foo6 = "foo6", bar6 = "bar6"}
    local uncompressed = tt.numData(t)
    local compressed = tt.numData(t, true)

    -- Test uncompressed.
    self:assertEquals(1, uncompressed[1][1])
    self:assertEquals(2, uncompressed[2][1])
    self:assertEquals(5, uncompressed[5][1])
    self:assertEquals("foo", uncompressed.other.foo)
    self:assertEquals("foo1", uncompressed[1].foo)
    self:assertEquals("bar1", uncompressed[1].bar)
    self:assertEquals("foo6", uncompressed[6].foo)
    self:assertEquals("bar6", uncompressed[6].bar)
    self:assertEquals(nil, uncompressed[4])

    -- Test compressed.
    self:assertEquals(1, compressed[1][1])
    self:assertEquals(2, compressed[2][1])
    self:assertEquals(5, compressed[3][1])
    self:assertEquals("foo", compressed.other.foo)
    self:assertEquals("foo1", compressed[1].foo)
    self:assertEquals("bar1", compressed[1].bar)
    self:assertEquals("foo6", compressed[4].foo)
    self:assertEquals("bar6", compressed[4].bar)
    self:assertEquals(nil, compressed[5])
end

------------------------------------------------------------------------
-- Test sparse array functions
------------------------------------------------------------------------

function suite:testCompressSparseArray()
    local tt = self:module()
    local compressedArray = tt.compressSparseArray(sparseArray)
    self:assertEquals(sparseArrayConcatenated, suite.concatIpairs(compressedArray))
    self:assertTypeErrorEquals(1, 'compressSparseArray', 'table', 'number', tt.compressSparseArray, 4)
    self:assertTypeErrorEquals(1, 'compressSparseArray', 'table', 'nil', tt.compressSparseArray)
end

function suite:testSparseIpairs()
    local tt = self:module()
    local arrayText = ''
    for i, v in tt.sparseIpairs(sparseArray) do
        arrayText = arrayText .. tostring(v)
    end
    self:assertEquals(sparseArrayConcatenated, arrayText)
    self:assertTypeErrorEquals(1, 'sparseIpairs', 'table', 'number', tt.sparseIpairs, 4)
    self:assertTypeErrorEquals(1, 'sparseIpairs', 'table', 'nil', tt.sparseIpairs)
end

------------------------------------------------------------------------
-- Test size function
------------------------------------------------------------------------

function suite:testSize()
    local tt = self:module()
    self:assertEquals(0, tt.size{})
    self:assertEquals(3, tt.size{foo = 'foo', bar = 'bar', baz = 'baz'})
    self:assertEquals(1, tt.size{1})
    self:assertEquals(5, tt.size{foo = 'foo', bar = 'bar', baz = 'baz', 1, 2})
    self:assertTypeErrorEquals(1, 'size', 'table', 'number', tt.size, 4)
    self:assertTypeErrorEquals(1, 'size', 'table', 'nil', tt.size)
end

return suite