Skip to content

Commit 2974b65

Browse files
committed
tests/lapi: add math tests
The patch adds a tests for Lua math standard unctions. Also, the patch introduces a helper `lua_current_version_ge_than()` for convenient versions comparisons and a helper `approx_equal()` for convenient numbers comparisons. Rules from trigonometric identities [1] has been used as invariants for trigonometric functions. 1. https://en.wikipedia.org/wiki/List_of_trigonometric_identities
1 parent d4b91f6 commit 2974b65

21 files changed

+741
-4
lines changed

tests/lapi/lib.lua

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,31 @@ Test helpers.
77

88
-- The function determines a Lua version.
99
local function lua_version()
10+
local major, minor = _VERSION:match("([%d]+)%.(%d+)")
11+
local version = {
12+
major = tonumber(major),
13+
minor = tonumber(minor),
14+
}
1015
local is_luajit, _ = pcall(require, "jit")
11-
if is_luajit then
12-
return "LuaJIT"
16+
local lua_name = is_luajit and "LuaJIT" or "PUC Rio Lua"
17+
return lua_name, version
18+
end
19+
20+
local function version_ge(version1, version2)
21+
if version1.major ~= version2.major then
22+
return version1.major > version2.major
23+
else
24+
return version1.minor >= version2.minor
1325
end
26+
end
1427

15-
return _VERSION
28+
local function lua_current_version_ge_than(major, minor)
29+
local _, current_version = lua_version()
30+
return version_ge(current_version, { major = major, minor = minor })
31+
end
32+
33+
local function lua_current_version_lt_than(major, minor)
34+
return not lua_current_version_ge_than(major, minor)
1635
end
1736

1837
-- By default `lua_Integer` is ptrdiff_t in Lua 5.1 and Lua 5.2
@@ -56,9 +75,22 @@ local function bitwise_op(op_name)
5675
end
5776
end
5877

78+
local function math_pow(x, y)
79+
return x ^ y
80+
end
81+
82+
local function approx_equal(a, b, epsilon)
83+
local abs = math.abs
84+
return abs(a - b) <= ((abs(a) < abs(b) and abs(b) or abs(a)) * epsilon)
85+
end
86+
5987
return {
60-
lua_version = lua_version,
88+
approx_equal = approx_equal,
6189
bitwise_op = bitwise_op,
90+
lua_version = lua_version,
91+
lua_current_version_ge_than = lua_current_version_ge_than,
92+
lua_current_version_lt_than = lua_current_version_lt_than,
93+
math_pow = math_pow,
6294
MAX_INT64 = MAX_INT64,
6395
MIN_INT64 = MIN_INT64,
6496
MAX_INT = MAX_INT,

tests/lapi/math_abs_test.lua

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--[[
2+
SPDX-License-Identifier: ISC
3+
Copyright (c) 2023-2025, Sergey Bronnikov.
4+
5+
18 – The Mathematical Library
6+
https://www.lua.org/pil/18.html
7+
8+
6.7 – Mathematical Functions
9+
https://www.lua.org/manual/5.3/manual.html#6.7
10+
11+
Misleading assertion in asm_fload() for mips,
12+
https://github.com/LuaJIT/LuaJIT/issues/1043
13+
14+
Synopsis: math.abs(x)
15+
]]
16+
17+
local luzer = require("luzer")
18+
local test_lib = require("lib")
19+
20+
local function TestOneInput(buf)
21+
local fdp = luzer.FuzzedDataProvider(buf)
22+
local n = fdp:consume_number(test_lib.MIN_INT, test_lib.MAX_INT)
23+
local abs = n
24+
if abs < 0 then
25+
abs = -abs
26+
end
27+
assert(math.abs(n) == abs)
28+
end
29+
30+
local args = {
31+
artifact_prefix = "math_abs_",
32+
}
33+
luzer.Fuzz(TestOneInput, nil, args)

tests/lapi/math_acos_test.lua

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--[[
2+
SPDX-License-Identifier: ISC
3+
Copyright (c) 2023-2025, Sergey Bronnikov.
4+
5+
18 – The Mathematical Library
6+
https://www.lua.org/pil/18.html
7+
8+
6.7 – Mathematical Functions
9+
https://www.lua.org/manual/5.3/manual.html#6.7
10+
11+
Synopsis: math.acos(x)
12+
]]
13+
14+
local luzer = require("luzer")
15+
local test_lib = require("lib")
16+
17+
local function TestOneInput(buf)
18+
local fdp = luzer.FuzzedDataProvider(buf)
19+
local x = fdp:consume_number(-1, 1)
20+
local y = math.acos(x)
21+
assert(y >= 0)
22+
assert(y <= math.pi)
23+
local epsilon = 1^-10
24+
if x ~= 0 then
25+
assert(test_lib.approx_equal(y, math.pi - math.acos(-x), epsilon))
26+
assert(test_lib.approx_equal(math.cos(y), x, epsilon))
27+
end
28+
end
29+
30+
local args = {
31+
artifact_prefix = "math_acos_",
32+
}
33+
luzer.Fuzz(TestOneInput, nil, args)

tests/lapi/math_asin_test.lua

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
--[[
2+
SPDX-License-Identifier: ISC
3+
Copyright (c) 2023-2025, Sergey Bronnikov.
4+
5+
18 – The Mathematical Library
6+
https://www.lua.org/pil/18.html
7+
8+
6.7 – Mathematical Functions
9+
https://www.lua.org/manual/5.3/manual.html#6.7
10+
11+
Synopsis: math.asin(x)
12+
]]
13+
14+
local luzer = require("luzer")
15+
local test_lib = require("lib")
16+
17+
local function TestOneInput(buf)
18+
local fdp = luzer.FuzzedDataProvider(buf)
19+
local x = fdp:consume_number(-1, 1)
20+
local y = math.asin(x)
21+
assert(type(y) == "number")
22+
assert(y >= -math.pi / 2)
23+
assert(y <= math.pi / 2)
24+
local epsilon = 1^-10
25+
assert(test_lib.approx_equal(math.sin(y), x, epsilon))
26+
end
27+
28+
local args = {
29+
artifact_prefix = "math_asin_",
30+
}
31+
luzer.Fuzz(TestOneInput, nil, args)

tests/lapi/math_atan_test.lua

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
--[[
2+
SPDX-License-Identifier: ISC
3+
Copyright (c) 2023-2025, Sergey Bronnikov.
4+
5+
18 – The Mathematical Library
6+
https://www.lua.org/pil/18.html
7+
8+
6.7 – Mathematical Functions
9+
https://www.lua.org/manual/5.3/manual.html#6.7
10+
11+
Synopsis: math.atan(y [, x])
12+
]]
13+
14+
local luzer = require("luzer")
15+
local test_lib = require("lib")
16+
17+
local function TestOneInput(buf)
18+
local fdp = luzer.FuzzedDataProvider(buf)
19+
local x = fdp:consume_number(test_lib.MIN_INT, test_lib.MAX_INT)
20+
local y = math.atan(x)
21+
assert(type(y) == "number")
22+
assert(y >= -math.pi / 2)
23+
assert(y <= math.pi / 2)
24+
assert(math.atan(-x) == -y)
25+
end
26+
27+
local args = {
28+
artifact_prefix = "math_atan_",
29+
}
30+
luzer.Fuzz(TestOneInput, nil, args)

tests/lapi/math_ceil_test.lua

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
--[[
2+
SPDX-License-Identifier: ISC
3+
Copyright (c) 2023-2025, Sergey Bronnikov.
4+
5+
18 – The Mathematical Library
6+
https://www.lua.org/pil/18.html
7+
8+
6.7 – Mathematical Functions
9+
https://www.lua.org/manual/5.3/manual.html#6.7
10+
11+
vm_mips.dasc assumes 32-bit FPU register model,
12+
https://github.com/LuaJIT/LuaJIT/issues/1040
13+
14+
math.ceil fails to return -0 for -1 < x < -0.5,
15+
https://github.com/LuaJIT/LuaJIT/issues/859
16+
17+
ARM64 - corrupted local variable on trace exit / snapshot replay,
18+
https://github.com/LuaJIT/LuaJIT/issues/579
19+
20+
x86/x64: Fix math.ceil(-0.9) result sign,
21+
https://github.com/LuaJIT/LuaJIT/issues/859
22+
23+
Synopsis: math.ceil(x)
24+
]]
25+
26+
local luzer = require("luzer")
27+
local test_lib = require("lib")
28+
29+
local function TestOneInput(buf)
30+
local fdp = luzer.FuzzedDataProvider(buf)
31+
local x = fdp:consume_number(test_lib.MIN_INT, test_lib.MAX_INT)
32+
local res = math.ceil(x)
33+
assert(type(res) == "number")
34+
end
35+
36+
local args = {
37+
artifact_prefix = "math_ceil_",
38+
}
39+
luzer.Fuzz(TestOneInput, nil, args)

tests/lapi/math_cos_test.lua

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--[[
2+
SPDX-License-Identifier: ISC
3+
Copyright (c) 2023-2025, Sergey Bronnikov.
4+
5+
18 – The Mathematical Library
6+
https://www.lua.org/pil/18.html
7+
8+
6.7 – Mathematical Functions
9+
https://www.lua.org/manual/5.3/manual.html#6.7
10+
11+
Synopsis: math.cos(x)
12+
]]
13+
14+
local luzer = require("luzer")
15+
local test_lib = require("lib")
16+
17+
local function TestOneInput(buf)
18+
local fdp = luzer.FuzzedDataProvider(buf)
19+
local x = fdp:consume_number(test_lib.MIN_INT, test_lib.MAX_INT)
20+
local cos_x = math.cos(x)
21+
assert(type(cos_x) == "number")
22+
assert(cos_x >= -1 and cos_x <= 1)
23+
local epsilon = 1^-10
24+
25+
local n = fdp:consume_number(0, 100)
26+
-- Calculate the functions of the form `cos(i*pi - x), where
27+
-- i = 1, 3, 5, etc. These functions are equivalent, given the
28+
-- trigonometric identity.
29+
for i = 1, n do
30+
assert(test_lib.approx_equal(
31+
math.abs(math.cos(i * math.pi - x)), math.abs(cos_x), epsilon))
32+
end
33+
end
34+
35+
local args = {
36+
artifact_prefix = "math_cos_",
37+
}
38+
luzer.Fuzz(TestOneInput, nil, args)

tests/lapi/math_deg_test.lua

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--[[
2+
SPDX-License-Identifier: ISC
3+
Copyright (c) 2023-2025, Sergey Bronnikov.
4+
5+
18 – The Mathematical Library
6+
https://www.lua.org/pil/18.html
7+
8+
6.7 – Mathematical Functions
9+
https://www.lua.org/manual/5.3/manual.html#6.7
10+
11+
Synopsis: math.deg(x)
12+
]]
13+
14+
local luzer = require("luzer")
15+
local test_lib = require("lib")
16+
17+
local function TestOneInput(buf)
18+
local fdp = luzer.FuzzedDataProvider(buf)
19+
local a = fdp:consume_number(test_lib.MIN_INT, test_lib.MAX_INT)
20+
local res = math.deg(a)
21+
assert(type(res) == "number")
22+
end
23+
24+
local args = {
25+
artifact_prefix = "math_deg_",
26+
}
27+
luzer.Fuzz(TestOneInput, nil, args)

tests/lapi/math_exp_test.lua

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--[[
2+
SPDX-License-Identifier: ISC
3+
Copyright (c) 2023-2025, Sergey Bronnikov.
4+
5+
18 – The Mathematical Library
6+
https://www.lua.org/pil/18.html
7+
8+
6.7 – Mathematical Functions
9+
https://www.lua.org/manual/5.3/manual.html#6.7
10+
11+
Synopsis: math.exp(x)
12+
]]
13+
14+
local luzer = require("luzer")
15+
local test_lib = require("lib")
16+
17+
local function TestOneInput(buf)
18+
local fdp = luzer.FuzzedDataProvider(buf)
19+
local a = fdp:consume_number(test_lib.MIN_INT, test_lib.MAX_INT)
20+
local res = math.exp(a)
21+
assert(type(res) == "number")
22+
end
23+
24+
local args = {
25+
artifact_prefix = "math_exp_",
26+
}
27+
luzer.Fuzz(TestOneInput, nil, args)

tests/lapi/math_floor_test.lua

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--[[
2+
SPDX-License-Identifier: ISC
3+
Copyright (c) 2023-2025, Sergey Bronnikov.
4+
5+
18 – The Mathematical Library
6+
https://www.lua.org/pil/18.html
7+
8+
6.7 – Mathematical Functions
9+
https://www.lua.org/manual/5.3/manual.html#6.7
10+
11+
Synopsis: math.floor(x)
12+
]]
13+
14+
local luzer = require("luzer")
15+
local test_lib = require("lib")
16+
17+
local function TestOneInput(buf)
18+
local fdp = luzer.FuzzedDataProvider(buf)
19+
local a = fdp:consume_number(test_lib.MIN_INT, test_lib.MAX_INT)
20+
local res = math.floor(a)
21+
assert(type(res) == "number")
22+
end
23+
24+
local args = {
25+
artifact_prefix = "math_floor_",
26+
}
27+
luzer.Fuzz(TestOneInput, nil, args)

0 commit comments

Comments
 (0)