<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://stockhub.co/index.php?action=history&amp;feed=atom&amp;title=Module%3AMath%2Ftestcases</id>
	<title>Module:Math/testcases - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://stockhub.co/index.php?action=history&amp;feed=atom&amp;title=Module%3AMath%2Ftestcases"/>
	<link rel="alternate" type="text/html" href="https://stockhub.co/index.php?title=Module:Math/testcases&amp;action=history"/>
	<updated>2026-06-07T00:49:53Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://stockhub.co/index.php?title=Module:Math/testcases&amp;diff=143943&amp;oldid=prev</id>
		<title>imported&gt;Pppery: Import test cases by Trigenibinion from Module:PassMath/testcases</title>
		<link rel="alternate" type="text/html" href="https://stockhub.co/index.php?title=Module:Math/testcases&amp;diff=143943&amp;oldid=prev"/>
		<updated>2021-03-10T05:12:11Z</updated>

		<summary type="html">&lt;p&gt;Import test cases by Trigenibinion from &lt;a href=&quot;/index.php?title=Module:PassMath/testcases&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;Module:PassMath/testcases (page does not exist)&quot;&gt;Module:PassMath/testcases&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- Unit tests for [[Module:Math/sandbox]]. Click talk page to run tests.&lt;br /&gt;
&lt;br /&gt;
local moduleName = &amp;#039;Math/sandbox&amp;#039; -- assigning this to a variable as it is later used to generate an #invoke statement.&lt;br /&gt;
local mm = require(&amp;#039;Module:&amp;#039; .. moduleName)&lt;br /&gt;
local ScribuntoUnit = require(&amp;#039;Module:ScribuntoUnit&amp;#039;)&lt;br /&gt;
local suite = ScribuntoUnit:new()&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Helper functions&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
function suite.err(msg) &lt;br /&gt;
	return mw.ustring.format(&amp;#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;Formatting error: %s&amp;lt;/strong&amp;gt;&amp;#039;, msg)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite.getLuaResult(funcName, args)&lt;br /&gt;
	args = args or {}&lt;br /&gt;
	local result = mm[&amp;#039;_&amp;#039; .. funcName](unpack(args))&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:assertLuaEquals(expected, funcName, args)&lt;br /&gt;
	args = args or {}&lt;br /&gt;
	self:assertEquals(expected, self.getLuaResult(funcName, args))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite.buildInvocation(funcName, args)&lt;br /&gt;
	args = args or {}&lt;br /&gt;
	local argsClone = mw.clone(args)&lt;br /&gt;
	-- Build a module invocation equivalent to the args table. Taken from [[Module:Unsubst]].&lt;br /&gt;
	-- Numbered args first.&lt;br /&gt;
	local ret = &amp;#039;{{#invoke:&amp;#039; .. moduleName .. &amp;#039;|&amp;#039; .. funcName&lt;br /&gt;
	for k, v in ipairs(argsClone) do&lt;br /&gt;
		v = tostring(v)&lt;br /&gt;
		if string.find(v, &amp;#039;=&amp;#039;, 1, true) then&lt;br /&gt;
			-- likely something like 1=foo=bar, we need to do it as a named arg&lt;br /&gt;
			break&lt;br /&gt;
		end&lt;br /&gt;
		ret = ret .. &amp;#039;|&amp;#039; .. v&lt;br /&gt;
		argsClone[k] = nil&lt;br /&gt;
	end&lt;br /&gt;
	for k, v in pairs(argsClone) do&lt;br /&gt;
		k = tostring(k)&lt;br /&gt;
		v = tostring(v)&lt;br /&gt;
		ret = ret .. &amp;#039;|&amp;#039; .. k .. &amp;#039;=&amp;#039; .. v&lt;br /&gt;
	end&lt;br /&gt;
	return ret .. &amp;#039;}}&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:getInvokeResult(funcName, args, convertNumber) -- Unless convertNumber is false, the number is converted to a number, if possible, on re-entry to Lua.&lt;br /&gt;
	args = args or {}&lt;br /&gt;
	local invocation = self.buildInvocation(funcName, args)&lt;br /&gt;
	local result = self.frame:preprocess(invocation)&lt;br /&gt;
	if convertNumber ~= false and tonumber(result) then&lt;br /&gt;
		return tonumber(result)&lt;br /&gt;
	else&lt;br /&gt;
		return result&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:assertInvokeEquals(expected, funcName, args, convertNumber)&lt;br /&gt;
	args = args or {}&lt;br /&gt;
	local invokeResult = self:getInvokeResult(funcName, args, convertNumber)&lt;br /&gt;
	self:assertEquals(expected, invokeResult)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:assertLuaAndInvokeTrue(trueFunc, funcName, args, convertNumber)&lt;br /&gt;
	args = args or {}&lt;br /&gt;
	local invokeResult = self:getInvokeResult(funcName, args, convertNumber)&lt;br /&gt;
	local luaResult = self.getLuaResult(funcName, args)&lt;br /&gt;
	self:assertTrue(trueFunc(invokeResult))&lt;br /&gt;
	self:assertTrue(trueFunc(luaResult))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:assertLuaAndInvokeEqual(funcName, testTable, convertNumber)&lt;br /&gt;
	local expected = testTable[1]&lt;br /&gt;
	local args = testTable[2] or {}&lt;br /&gt;
	self:assertLuaEquals(expected, funcName, args)&lt;br /&gt;
	self:assertInvokeEquals(expected, funcName, args, convertNumber)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:assertLuaAndInvokeEqualMany(funcName, testTables, convertNumber)&lt;br /&gt;
	for i, testTable in ipairs(testTables) do&lt;br /&gt;
		self:assertLuaAndInvokeEqual(funcName, testTable, convertNumber)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Test random&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
function suite:test_random()&lt;br /&gt;
	self:assertLuaAndInvokeTrue(function (n) return n &amp;gt;= 0 and n &amp;lt; 1 end, &amp;#039;random&amp;#039;)&lt;br /&gt;
	self:assertLuaAndInvokeTrue(function (n) return n == 1 or n == 2 end, &amp;#039;random&amp;#039;, {2})&lt;br /&gt;
	self:assertLuaAndInvokeTrue(function (n) return n &amp;gt;= 1 and n &amp;lt;= 10 and math.floor(n) == n end, &amp;#039;random&amp;#039;, {10})&lt;br /&gt;
	self:assertLuaAndInvokeTrue(function (n) return n &amp;gt;= 10 and n &amp;lt;= 20 and math.floor(n) == n end, &amp;#039;random&amp;#039;, {10, 20})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Test max&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
 &lt;br /&gt;
function suite:test_max()&lt;br /&gt;
	local tests = {&lt;br /&gt;
		{9, {5, 6, 9}},&lt;br /&gt;
		{-5, {-5, -6, -9}},&lt;br /&gt;
	}&lt;br /&gt;
	self:assertLuaAndInvokeEqualMany(&amp;#039;max&amp;#039;, tests)&lt;br /&gt;
	self:assertLuaEquals(nil, &amp;#039;max&amp;#039;, {})&lt;br /&gt;
	self:assertInvokeEquals(&amp;#039;&amp;#039;, &amp;#039;max&amp;#039;, {})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Test average&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
function suite:test_average()&lt;br /&gt;
	local tests = {&lt;br /&gt;
		{6, {5, 6, 7}},&lt;br /&gt;
		{-7, {-7}},&lt;br /&gt;
		{10000000002, {10000000001, 10000000002, 10000000003}},&lt;br /&gt;
	}&lt;br /&gt;
	self:assertLuaAndInvokeEqualMany(&amp;#039;average&amp;#039;, tests)&lt;br /&gt;
end&lt;br /&gt;
 &lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Test min&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
function suite:test_min()&lt;br /&gt;
	local tests = {&lt;br /&gt;
		{1, {1, 2, 3}},&lt;br /&gt;
		{-3, {-1, -2, -3}},&lt;br /&gt;
	}&lt;br /&gt;
	self:assertLuaAndInvokeEqualMany(&amp;#039;min&amp;#039;, tests)&lt;br /&gt;
	self:assertLuaEquals(nil, &amp;#039;min&amp;#039;, {})&lt;br /&gt;
	self:assertInvokeEquals(&amp;#039;&amp;#039;, &amp;#039;min&amp;#039;, {})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Test gcd&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
function suite:test_gcd()&lt;br /&gt;
	local tests = {&lt;br /&gt;
		{4, {12, 8}},&lt;br /&gt;
		{2, {12, 8, 6}},&lt;br /&gt;
		{4, {-12, -8}},&lt;br /&gt;
		{2, {-12, -8, -6}},&lt;br /&gt;
		{8, {0, 8}},&lt;br /&gt;
		{8, {0, -8}},&lt;br /&gt;
		{0, {0}},&lt;br /&gt;
		{0, {0, 0}},&lt;br /&gt;
		{4, {12, nil, 8}},&lt;br /&gt;
	}&lt;br /&gt;
	self:assertLuaAndInvokeEqualMany(&amp;#039;gcd&amp;#039;, tests)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Test order&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
function suite:test_order()&lt;br /&gt;
	local tests = {&lt;br /&gt;
		{0, {2}},&lt;br /&gt;
		{1, {20}},&lt;br /&gt;
		{2, {200}},&lt;br /&gt;
		{0, {5}},&lt;br /&gt;
	}&lt;br /&gt;
	self:assertLuaAndInvokeEqualMany(&amp;#039;order&amp;#039;, tests)&lt;br /&gt;
	self:assertInvokeEquals(suite.err(&amp;#039;order of magnitude input appears non-numeric&amp;#039;), &amp;#039;order&amp;#039;, {&amp;#039;string&amp;#039;})&lt;br /&gt;
	self:assertInvokeEquals(0, &amp;#039;order&amp;#039;, {x = 5})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Test precision&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
function suite:test_precison()&lt;br /&gt;
	local tests = {&lt;br /&gt;
		{4, {1.9856}},&lt;br /&gt;
		{1, {1.1}},&lt;br /&gt;
		{10, {1.9999999999}},&lt;br /&gt;
	}&lt;br /&gt;
	self:assertLuaAndInvokeEqualMany(&amp;#039;precision&amp;#039;, tests)&lt;br /&gt;
	self:assertInvokeEquals(suite.err(&amp;#039;precision input appears non-numeric&amp;#039;), &amp;#039;precision&amp;#039;, {&amp;#039;letra&amp;#039;})&lt;br /&gt;
	self:assertInvokeEquals(4, &amp;#039;precision&amp;#039;, {x = &amp;#039;1.9888&amp;#039;})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Test round&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
function suite:test_round()&lt;br /&gt;
	local tests = {&lt;br /&gt;
		{2, {1.99999}},&lt;br /&gt;
		{2, {1.99999, 0}},&lt;br /&gt;
		{1.9, {1.94, 1}},&lt;br /&gt;
		{20, {15, -1}},&lt;br /&gt;
	}&lt;br /&gt;
	self:assertLuaAndInvokeEqualMany(&amp;#039;round&amp;#039;, tests)&lt;br /&gt;
	self:assertInvokeEquals(3, &amp;#039;round&amp;#039;, {value = &amp;#039;2.99999&amp;#039;, precision = &amp;#039;2&amp;#039;})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Test mod&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
function suite:test_mod()&lt;br /&gt;
	local tests = {&lt;br /&gt;
		{0, {10, 2}},&lt;br /&gt;
		{1, {11, 2}},&lt;br /&gt;
		{0, {525000000000000120000000000, 3}}, -- With the plain % operator this returns 68719476736 due to floating point error.&lt;br /&gt;
	}&lt;br /&gt;
	self:assertLuaAndInvokeEqualMany(&amp;#039;mod&amp;#039;, tests)&lt;br /&gt;
	self:assertInvokeEquals(suite.err(&amp;#039;first argument to mod appears non-numeric&amp;#039;), &amp;#039;mod&amp;#039;, {})&lt;br /&gt;
	self:assertInvokeEquals(suite.err(&amp;#039;second argument to mod appears non-numeric&amp;#039;), &amp;#039;mod&amp;#039;, {1})&lt;br /&gt;
	local successNoArgs = pcall(mm._mod)&lt;br /&gt;
	self:assertFalse(successNoArgs)&lt;br /&gt;
	local successOneArg = pcall(mm._mod, 1)&lt;br /&gt;
	self:assertFalse(successOneArg)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Test precision format&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
function suite:test_precison_format()&lt;br /&gt;
	local tests = {&lt;br /&gt;
		{&amp;#039;10.00&amp;#039;, {10, 2}}&lt;br /&gt;
	}&lt;br /&gt;
	self:assertLuaAndInvokeEqualMany(&amp;#039;precision_format&amp;#039;, tests, false) -- the &amp;quot;false&amp;quot; stops string values being converted to numbers on re-entry from #invoke.&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Test cleanNumber&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
function suite:assertCleanNumberEquals(expectedTable, inputString)&lt;br /&gt;
	local expectedNum, expectedNumString = expectedTable[1], expectedTable[2]&lt;br /&gt;
	local actualNum, actualNumString = mm._cleanNumber(inputString)&lt;br /&gt;
	self:assertEquals(expectedNum, actualNum)&lt;br /&gt;
	self:assertEquals(expectedNumString, actualNumString)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function suite:test_cleanNumber()&lt;br /&gt;
	self:assertCleanNumberEquals({0, &amp;#039;0&amp;#039;}, &amp;#039;0&amp;#039;)&lt;br /&gt;
	self:assertCleanNumberEquals({1, &amp;#039;1&amp;#039;}, 1)&lt;br /&gt;
	self:assertCleanNumberEquals({2, &amp;#039;2&amp;#039;}, &amp;#039;  2  &amp;#039;)&lt;br /&gt;
	self:assertCleanNumberEquals({3, &amp;#039;3&amp;#039;}, &amp;#039;4-1&amp;#039;)&lt;br /&gt;
	self:assertCleanNumberEquals({4, &amp;#039;4&amp;#039;}, &amp;#039;2 + 2&amp;#039;)&lt;br /&gt;
	self:assertCleanNumberEquals({5, &amp;#039;5&amp;#039;}, &amp;#039;  2 + 3  &amp;#039;)&lt;br /&gt;
	self:assertCleanNumberEquals({6, &amp;#039;6&amp;#039;}, &amp;#039;+6&amp;#039;)&lt;br /&gt;
	self:assertCleanNumberEquals({-7, &amp;#039;-7&amp;#039;}, &amp;#039;-7&amp;#039;)&lt;br /&gt;
	self:assertCleanNumberEquals({88, &amp;#039;88&amp;#039;}, &amp;#039;0x58&amp;#039;)&lt;br /&gt;
	self:assertCleanNumberEquals({1000000000, &amp;#039;1e+9&amp;#039;}, &amp;#039;1e+9&amp;#039;)&lt;br /&gt;
	self:assertCleanNumberEquals({-88, &amp;#039;-88&amp;#039;}, &amp;#039;-0x58&amp;#039;)&lt;br /&gt;
	self:assertCleanNumberEquals({0.16667, &amp;#039;0.16667&amp;#039;}, &amp;#039;1/6 round 5&amp;#039;)&lt;br /&gt;
	self:assertCleanNumberEquals({nil, nil}, &amp;#039;1 foo 2&amp;#039;) -- invalid expression&lt;br /&gt;
	self:assertCleanNumberEquals({nil, nil}, &amp;#039;1+&amp;#039;) -- missing expr operand&lt;br /&gt;
	self:assertCleanNumberEquals({nil, nil}, &amp;#039;&amp;#039;)&lt;br /&gt;
	self:assertCleanNumberEquals({nil, nil}, &amp;#039;  &amp;#039;)&lt;br /&gt;
	self:assertCleanNumberEquals({nil, nil}, &amp;#039;string&amp;#039;)&lt;br /&gt;
	self:assertCleanNumberEquals({nil, nil}, &amp;#039;  string with padding  &amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Test divide&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
function suite:test_divide() &lt;br /&gt;
	self:assertInvokeEquals(&amp;#039;1&amp;#039;,&amp;#039;divide&amp;#039;,{1, 2, round = &amp;#039;yes&amp;#039;}, false)&lt;br /&gt;
	self:assertInvokeEquals(&amp;#039;0.5&amp;#039;,&amp;#039;divide&amp;#039;,{1, 2, round = &amp;#039;no&amp;#039;}, false)&lt;br /&gt;
	self:assertInvokeEquals(&amp;#039;0&amp;#039;,&amp;#039;divide&amp;#039;,{1, 3, round = &amp;#039;yes&amp;#039;, precision=2}, false)&lt;br /&gt;
	self:assertInvokeEquals(&amp;#039;0.33&amp;#039;,&amp;#039;divide&amp;#039;,{1, 3, precision=2}, false)&lt;br /&gt;
	self:assertInvokeEquals(suite.err(&amp;#039;Empty dividend&amp;#039;),&amp;#039;divide&amp;#039;,{&amp;#039;&amp;#039;,2},false)&lt;br /&gt;
	self:assertInvokeEquals(suite.err(&amp;#039;Empty divisor&amp;#039;),&amp;#039;divide&amp;#039;,{1,&amp;#039;&amp;#039;},false)&lt;br /&gt;
	self:assertInvokeEquals(suite.err(&amp;#039;Empty divisor&amp;#039;),&amp;#039;divide&amp;#039;,{},false)&lt;br /&gt;
	self:assertInvokeEquals(suite.err(&amp;#039;Empty divisor&amp;#039;),&amp;#039;divide&amp;#039;,{&amp;#039;&amp;#039;,&amp;#039;&amp;#039;},false)&lt;br /&gt;
	self:assertInvokeEquals(suite.err(&amp;#039;Not a number: a&amp;#039;),&amp;#039;divide&amp;#039;,{&amp;#039;a&amp;#039;,2},false)&lt;br /&gt;
	self:assertInvokeEquals(suite.err(&amp;#039;Not a number: b&amp;#039;),&amp;#039;divide&amp;#039;,{1,&amp;#039;b&amp;#039;},false)&lt;br /&gt;
	self:assertInvokeEquals(suite.err(&amp;#039;Not a number: b&amp;#039;),&amp;#039;divide&amp;#039;,{&amp;#039;a&amp;#039;,&amp;#039;b&amp;#039;},false)&lt;br /&gt;
	self:assertInvokeEquals(&amp;#039;&amp;lt;big&amp;gt;Bad&amp;lt;/big&amp;gt;&amp;#039;,&amp;#039;divide&amp;#039;,{&amp;#039;&amp;lt;big&amp;gt;Bad&amp;lt;/big&amp;gt;&amp;#039;,2},false)&lt;br /&gt;
	self:assertInvokeEquals(&amp;#039;&amp;lt;big&amp;gt;Bad&amp;lt;/big&amp;gt;&amp;#039;,&amp;#039;divide&amp;#039;,{1,&amp;#039;&amp;lt;big&amp;gt;Bad&amp;lt;/big&amp;gt;&amp;#039;},false)&lt;br /&gt;
	self:assertInvokeEquals(&amp;#039;&amp;lt;big&amp;gt;Bad2&amp;lt;/big&amp;gt;&amp;#039;,&amp;#039;divide&amp;#039;,{&amp;#039;&amp;lt;big&amp;gt;Bad1&amp;lt;/big&amp;gt;&amp;#039;,&amp;#039;&amp;lt;big&amp;gt;Bad2&amp;lt;/big&amp;gt;&amp;#039;},false)&lt;br /&gt;
end&lt;br /&gt;
return suite&lt;/div&gt;</summary>
		<author><name>imported&gt;Pppery</name></author>
	</entry>
</feed>