local math = require("math") local function assert_close(a, b, tolerance) tolerance = tolerance or 1e-10 if math.abs(a - b) > tolerance then error(string.format("Expected %g, got %g (diff: %g)", a, b, math.abs(a - b))) end end local function assert_equal(a, b) if a ~= b then error(string.format("Expected %s, got %s", tostring(a), tostring(b))) end end local passed = 0 local total = 0 local function test(name, fn) print("Testing " .. name .. "...") total = total + 1 local ok, err = pcall(fn) if ok then passed = passed + 1 print(" ✓ PASS") else print(" ✗ FAIL: " .. err) end end -- Test constants test("Constants", function() assert_close(math.pi, 3.14159265358979323846) assert_close(math.tau, 6.28318530717958647693) assert_close(math.e, 2.71828182845904523536) assert_close(math.phi, 1.61803398874989484820) assert_equal(math.infinity, 1/0) assert_equal(math.isnan(math.nan), true) end) -- Test extended functions test("Extended Functions", function() assert_close(math.cbrt(8), 2) assert_close(math.cbrt(-8), -2) assert_close(math.hypot(3, 4), 5) assert_equal(math.isnan(0/0), true) assert_equal(math.isnan(5), false) assert_equal(math.isfinite(5), true) assert_equal(math.isfinite(math.infinity), false) assert_equal(math.sign(5), 1) assert_equal(math.sign(-5), -1) assert_equal(math.sign(0), 0) assert_equal(math.clamp(5, 0, 3), 3) assert_equal(math.clamp(-1, 0, 3), 0) assert_close(math.lerp(0, 10, 0.5), 5) assert_close(math.map(5, 0, 10, 0, 100), 50) assert_equal(math.round(2.7), 3) assert_equal(math.round(-2.7), -3) assert_close(math.roundto(3.14159, 2), 3.14) assert_close(math.distance(0, 0, 3, 4), 5) end) -- Test random functions test("Random Functions", function() local r = math.randomf(0, 1) assert_equal(r >= 0 and r < 1, true) local i = math.randint(1, 10) assert_equal(i >= 1 and i <= 10, true) assert_equal(type(math.randboolean()), "boolean") end) -- Test statistics test("Statistics", function() local data = {1, 2, 3, 4, 5} assert_equal(math.sum(data), 15) assert_equal(math.mean(data), 3) assert_equal(math.median(data), 3) assert_close(math.variance(data), 2) assert_close(math.stdev(data), math.sqrt(2)) local min, max = math.minmax(data) assert_equal(min, 1) assert_equal(max, 5) assert_equal(math.mode({1, 2, 2, 3}), 2) end) -- Test 2D vectors test("2D Vectors", function() local v1 = math.vec2.new(3, 4) local v2 = math.vec2.new(1, 2) assert_equal(v1.x, 3) assert_equal(v1.y, 4) assert_close(math.vec2.length(v1), 5) assert_equal(math.vec2.length_squared(v1), 25) local v3 = math.vec2.add(v1, v2) assert_equal(v3.x, 4) assert_equal(v3.y, 6) local v4 = math.vec2.sub(v1, v2) assert_equal(v4.x, 2) assert_equal(v4.y, 2) local v5 = math.vec2.mul(v1, 2) assert_equal(v5.x, 6) assert_equal(v5.y, 8) assert_equal(math.vec2.dot(v1, v2), 11) assert_close(math.vec2.distance(v1, v2), math.sqrt(8)) local normalized = math.vec2.normalize(v1) assert_close(math.vec2.length(normalized), 1) end) -- Test 3D vectors test("3D Vectors", function() local v1 = math.vec3.new(1, 2, 3) local v2 = math.vec3.new(4, 5, 6) assert_close(math.vec3.length(v1), math.sqrt(14)) assert_equal(math.vec3.dot(v1, v2), 32) local cross = math.vec3.cross(v1, v2) assert_equal(cross.x, -3) assert_equal(cross.y, 6) assert_equal(cross.z, -3) local add = math.vec3.add(v1, v2) assert_equal(add.x, 5) assert_equal(add.y, 7) assert_equal(add.z, 9) end) -- Test 2x2 matrices test("2x2 Matrices", function() local m1 = math.mat2.new(1, 2, 3, 4) local m2 = math.mat2.new(2, 0, 1, 3) assert_equal(math.mat2.det(m1), -2) local product = math.mat2.mul(m1, m2) assert_equal(product[1][1], 4) assert_equal(product[1][2], 6) assert_equal(product[2][1], 10) assert_equal(product[2][2], 12) local rotation = math.mat2.rotation(math.pi/2) assert_close(rotation[1][1], 0, 1e-10) assert_close(rotation[1][2], -1) assert_close(rotation[2][1], 1) assert_close(rotation[2][2], 0, 1e-10) end) -- Test 3x3 matrices test("3x3 Matrices", function() local identity = math.mat3.identity() assert_equal(identity[1][1], 1) assert_equal(identity[2][2], 1) assert_equal(identity[3][3], 1) assert_equal(identity[1][2], 0) local translation = math.mat3.translation(5, 10) assert_equal(translation[1][3], 5) assert_equal(translation[2][3], 10) local point = {x = 1, y = 2} local transformed = math.mat3.transform_point(translation, point) assert_equal(transformed.x, 6) assert_equal(transformed.y, 12) end) -- Test geometry functions test("Geometry", function() assert_close(math.geometry.triangle_area(0, 0, 4, 0, 0, 3), 6) assert_equal(math.geometry.point_in_triangle(1, 1, 0, 0, 4, 0, 0, 3), true) assert_equal(math.geometry.point_in_triangle(5, 5, 0, 0, 4, 0, 0, 3), false) local intersects, x, y = math.geometry.line_intersect(0, 0, 2, 2, 0, 2, 2, 0) assert_equal(intersects, true) assert_close(x, 1) assert_close(y, 1) local closest_x, closest_y = math.geometry.closest_point_on_segment(1, 3, 0, 0, 4, 0) assert_close(closest_x, 1) assert_close(closest_y, 0) end) -- Test interpolation test("Interpolation", function() assert_close(math.interpolation.bezier(0.5, 0, 1, 2, 3), 1.5) assert_close(math.interpolation.quadratic_bezier(0.5, 0, 2, 4), 2) assert_close(math.interpolation.smoothstep(0, 1, 0.5), 0.5) assert_close(math.interpolation.smootherstep(0, 1, 0.5), 0.5) assert_close(math.interpolation.catmull_rom(0.5, 0, 1, 2, 3), 1.5) end) print("=" .. string.rep("=", 50)) print(string.format("Test Results: %d/%d passed", passed, total)) if passed == total then print("🎉 All tests passed!") os.exit(0) else print("❌ Some tests failed!") os.exit(1) end