Module:TableTools/testcases

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

local tt = require('Module:TableTools/sandbox') -- the module to be tested
local ScribuntoUnit = require('Module:ScribuntoUnit')
local suite = ScribuntoUnit:new()

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

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

suite.isNan = tt.isNan

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:assertThrows(func, expected, nil, ...)
end

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

function suite:testIsPositiveInteger()
	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()
	self:assertTrue(tt.isNan(0/0))
	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 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(suite.isNan(removed[5]))
	self:assertEquals(5, removed[6])
	self:assertTrue(suite.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'
local reverseSparseArrayConcatenated = '321'
local reverseNumKeysConcatenated = '531'

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

function suite:testnumKeys()
	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 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 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 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 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()
	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

------------------------------------------------------------------------
-- Test binaryLength function
------------------------------------------------------------------------

function suite:testLengthOfEmptyTableIsZero()
	self:assertEquals(0, tt.length{})
end

function suite:testLengthOfArray()
	local data = {"a","b","c","d","e","f"}
	self:assertEquals(6, tt.length(data))
	local meta = setmetatable({}, {__index = data})
	self:assertEquals(6, tt.length(meta))
end

function suite:testLengthOfQuasiArrayWithPrefixes()
	local data = {key1 = "value1", key2 = "value2", key3 = "value3"}
	self:assertEquals(3, tt.length(data, "key"))
	local meta = setmetatable({}, {__index = data})
	self:assertEquals(3, tt.length(meta, "key"))
end

function suite:testLengthChecksForTypeErrors()
	self:assertTypeErrorEquals(1, 'length', 'table', 'number', tt.length, 1)
	self:assertTypeErrorEquals(2, 'length', 'string', 'number', tt.length, {}, 2)
end

function suite:testInArray()
	self:assertTrue(tt.inArray({"a", "b", "c", "d"}, "b"))
	self:assertTrue(tt.inArray({"a", "b", "c", "d"}, "b", 0))
	self:assertTrue(tt.inArray({"a", "b", "c", "d"}, "b", 1))
	self:assertTrue(tt.inArray({"a", "b", "c", "d"}, "b", 2))
	self:assertTrue(tt.inArray({"a", "b", "c", "d"}, "b", -3))
	self:assertTrue(tt.inArray({"a", "b", "c", "d"}, "b", -5))
	self:assertTrue(tt.inArray({[1] = "a",[100] = "b",[101] = "c"}, "b"))
	self:assertTrue(tt.inArray({[1] = "a",[2] = "b",[3] = "c"}, "b", 0))
	self:assertTrue(tt.inArray({first = "a", second = "b", third = "c"}, "b"))
	self:assertFalse(tt.inArray({"a", "b", "c", "d"})) -- value missing
	self:assertFalse(tt.inArray({"a", "b", "c", "d"}, "e")) -- "e" is not in array
	self:assertFalse(tt.inArray({"a", "b", "c", "d"}, "b", 3)) -- "b" is before position 3
	self:assertFalse(tt.inArray({"a", "b", "c", "d"}, "b", 5)) -- 5 is larger than #array
	self:assertFalse(tt.inArray({"a", "b", "c", "d"}, "b", -2)) -- "b" is not in the last two positions
	self:assertFalse(tt.inArray({[1] = "a", [100] = "b", [101] = "c"}, "b", 0)) -- key 100 is non-consecutive
	self:assertFalse(tt.inArray({first = "a", second = "b", third = "c"}, "b", 0)) -- key "second" is not an integer
end

function suite:testMerge()
	self:assertDeepEquals({}, tt.merge())
	local function f() return "foo" end
	self:assertDeepEquals({"a",1,2,f,3}, tt.merge({"a",1,2,f,3}))
	self:assertDeepEquals({0.1,f,2,"3",{foo="bar"}}, tt.merge({0.1,f}, {[0.0]=f,2,"3",[1.0]="y"}, {{foo="bar"},f=f}))
	self:assertThrows(tt.merge, "bad argument #1 to 'merge' (table expected, got number)", nil, 2, 3)
end

function suite:testExtend()
	local t = {Z=1,{"Z"}}
	tt.extend(t, {[0.1]="k",-1})
	self:assertDeepEquals({{"Z"},Z=1,-1}, t)
	self:assertThrows(tt.extend, "bad argument #2 to 'extend' (table expected, got string)", nil, t, "banana")
	self:assertThrows(tt.extend, "bad argument #1 to 'extend' (table expected, got function)", nil, tt.extend, t)
end

return suite

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.