]> git.lizzy.rs Git - minetest.git/blobdiff - builtin/common/tests/vector_spec.lua
Serialization spec: Fix number fuzzing (#12496)
[minetest.git] / builtin / common / tests / vector_spec.lua
index 104c656e91c81350a12e717c2b3e0251f9a87876..6a0b81a89128de8f3e6edb7e709fa7c9e5339b36 100644 (file)
@@ -1,17 +1,23 @@
-_G.vector = {}
+_G.vector = {metatable = {}}
 dofile("builtin/common/vector.lua")
 
 describe("vector", function()
        describe("new()", function()
                it("constructs", function()
-                       assert.same({ x = 0, y = 0, z = 0 }, vector.new())
-                       assert.same({ x = 1, y = 2, z = 3 }, vector.new(1, 2, 3))
-                       assert.same({ x = 3, y = 2, z = 1 }, vector.new({ x = 3, y = 2, z = 1 }))
+                       assert.same({x = 0, y = 0, z = 0}, vector.new())
+                       assert.same({x = 1, y = 2, z = 3}, vector.new(1, 2, 3))
+                       assert.same({x = 3, y = 2, z = 1}, vector.new({x = 3, y = 2, z = 1}))
+
+                       assert.is_true(vector.check(vector.new()))
+                       assert.is_true(vector.check(vector.new(1, 2, 3)))
+                       assert.is_true(vector.check(vector.new({x = 3, y = 2, z = 1})))
 
                        local input = vector.new({ x = 3, y = 2, z = 1 })
                        local output = vector.new(input)
                        assert.same(input, output)
-                       assert.are_not.equal(input, output)
+                       assert.equal(input, output)
+                       assert.is_false(rawequal(input, output))
+                       assert.equal(input, input:new())
                end)
 
                it("throws on invalid input", function()
@@ -25,36 +31,284 @@ describe("vector", function()
                end)
        end)
 
-       it("equal()", function()
-                       local function assertE(a, b)
-                               assert.is_true(vector.equals(a, b))
-                       end
-                       local function assertNE(a, b)
-                               assert.is_false(vector.equals(a, b))
-                       end
+       it("zero()", function()
+               assert.same({x = 0, y = 0, z = 0}, vector.zero())
+               assert.same(vector.new(), vector.zero())
+               assert.equal(vector.new(), vector.zero())
+               assert.is_true(vector.check(vector.zero()))
+       end)
 
-                       assertE({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0})
-                       assertE({x = -1, y = 0, z = 1}, {x = -1, y = 0, z = 1})
-                       local a = { x = 2, y = 4, z = -10 }
-                       assertE(a, a)
-                       assertNE({x = -1, y = 0, z = 1}, a)
+       it("copy()", function()
+               local v = vector.new(1, 2, 3)
+               assert.same(v, vector.copy(v))
+               assert.same(vector.new(v), vector.copy(v))
+               assert.equal(vector.new(v), vector.copy(v))
+               assert.is_true(vector.check(vector.copy(v)))
        end)
 
-       it("add()", function()
-               assert.same({ x = 2, y = 4, z = 6 }, vector.add(vector.new(1, 2, 3), { x = 1, y = 2, z = 3 }))
+       it("indexes", function()
+               local some_vector = vector.new(24, 42, 13)
+               assert.equal(24, some_vector[1])
+               assert.equal(24, some_vector.x)
+               assert.equal(42, some_vector[2])
+               assert.equal(42, some_vector.y)
+               assert.equal(13, some_vector[3])
+               assert.equal(13, some_vector.z)
+
+               some_vector[1] = 100
+               assert.equal(100, some_vector.x)
+               some_vector.x = 101
+               assert.equal(101, some_vector[1])
+
+               some_vector[2] = 100
+               assert.equal(100, some_vector.y)
+               some_vector.y = 102
+               assert.equal(102, some_vector[2])
+
+               some_vector[3] = 100
+               assert.equal(100, some_vector.z)
+               some_vector.z = 103
+               assert.equal(103, some_vector[3])
+       end)
+
+       it("direction()", function()
+               local a = vector.new(1, 0, 0)
+               local b = vector.new(1, 42, 0)
+               assert.equal(vector.new(0, 1, 0), vector.direction(a, b))
+               assert.equal(vector.new(0, 1, 0), a:direction(b))
+       end)
+
+       it("distance()", function()
+               local a = vector.new(1, 0, 0)
+               local b = vector.new(3, 42, 9)
+               assert.is_true(math.abs(43 - vector.distance(a, b)) < 1.0e-12)
+               assert.is_true(math.abs(43 - a:distance(b)) < 1.0e-12)
+               assert.equal(0, vector.distance(a, a))
+               assert.equal(0, b:distance(b))
+       end)
+
+       it("length()", function()
+               local a = vector.new(0, 0, -23)
+               assert.equal(0, vector.length(vector.new()))
+               assert.equal(23, vector.length(a))
+               assert.equal(23, a:length())
+       end)
+
+       it("normalize()", function()
+               local a = vector.new(0, 0, -23)
+               assert.equal(vector.new(0, 0, -1), vector.normalize(a))
+               assert.equal(vector.new(0, 0, -1), a:normalize())
+               assert.equal(vector.new(), vector.normalize(vector.new()))
+       end)
+
+       it("floor()", function()
+               local a = vector.new(0.1, 0.9, -0.5)
+               assert.equal(vector.new(0, 0, -1), vector.floor(a))
+               assert.equal(vector.new(0, 0, -1), a:floor())
+       end)
+
+       it("round()", function()
+               local a = vector.new(0.1, 0.9, -0.5)
+               assert.equal(vector.new(0, 1, -1), vector.round(a))
+               assert.equal(vector.new(0, 1, -1), a:round())
+       end)
+
+       it("apply()", function()
+               local i = 0
+               local f = function(x)
+                       i = i + 1
+                       return x + i
+               end
+               local a = vector.new(0.1, 0.9, -0.5)
+               assert.equal(vector.new(1, 1, 0), vector.apply(a, math.ceil))
+               assert.equal(vector.new(1, 1, 0), a:apply(math.ceil))
+               assert.equal(vector.new(0.1, 0.9, 0.5), vector.apply(a, math.abs))
+               assert.equal(vector.new(0.1, 0.9, 0.5), a:apply(math.abs))
+               assert.equal(vector.new(1.1, 2.9, 2.5), vector.apply(a, f))
+               assert.equal(vector.new(4.1, 5.9, 5.5), a:apply(f))
+       end)
+
+       it("combine()", function()
+               local a = vector.new(1, 2, 3)
+               local b = vector.new(3, 2, 1)
+               assert.equal(vector.add(a, b), vector.combine(a, b, function(x, y) return x + y end))
+               assert.equal(vector.new(3, 2, 3), vector.combine(a, b, math.max))
+               assert.equal(vector.new(1, 2, 1), vector.combine(a, b, math.min))
+       end)
+
+       it("equals()", function()
+               local function assertE(a, b)
+                       assert.is_true(vector.equals(a, b))
+               end
+               local function assertNE(a, b)
+                       assert.is_false(vector.equals(a, b))
+               end
+
+               assertE({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0})
+               assertE({x = -1, y = 0, z = 1}, {x = -1, y = 0, z = 1})
+               assertE({x = -1, y = 0, z = 1}, vector.new(-1, 0, 1))
+               local a = {x = 2, y = 4, z = -10}
+               assertE(a, a)
+               assertNE({x = -1, y = 0, z = 1}, a)
+
+               assert.equal(vector.new(1, 2, 3), vector.new(1, 2, 3))
+               assert.is_true(vector.new(1, 2, 3):equals(vector.new(1, 2, 3)))
+               assert.not_equal(vector.new(1, 2, 3), vector.new(1, 2, 4))
+               assert.is_true(vector.new(1, 2, 3) == vector.new(1, 2, 3))
+               assert.is_false(vector.new(1, 2, 3) == vector.new(1, 3, 3))
+       end)
+
+       it("metatable is same", function()
+               local a = vector.new()
+               local b = vector.new(1, 2, 3)
+
+               assert.equal(true, vector.check(a))
+               assert.equal(true, vector.check(b))
+
+               assert.equal(vector.metatable, getmetatable(a))
+               assert.equal(vector.metatable, getmetatable(b))
+               assert.equal(vector.metatable, a.metatable)
+       end)
+
+       it("sort()", function()
+               local a = vector.new(1, 2, 3)
+               local b = vector.new(0.5, 232, -2)
+               local sorted = {vector.new(0.5, 2, -2), vector.new(1, 232, 3)}
+               assert.same(sorted, {vector.sort(a, b)})
+               assert.same(sorted, {a:sort(b)})
+       end)
+
+       it("angle()", function()
+               assert.equal(math.pi, vector.angle(vector.new(-1, -2, -3), vector.new(1, 2, 3)))
+               assert.equal(math.pi/2, vector.new(0, 1, 0):angle(vector.new(1, 0, 0)))
+       end)
+
+       it("dot()", function()
+               assert.equal(-14, vector.dot(vector.new(-1, -2, -3), vector.new(1, 2, 3)))
+               assert.equal(0, vector.new():dot(vector.new(1, 2, 3)))
+       end)
+
+       it("cross()", function()
+               local a = vector.new(-1, -2, 0)
+               local b = vector.new(1, 2, 3)
+               assert.equal(vector.new(-6, 3, 0), vector.cross(a, b))
+               assert.equal(vector.new(-6, 3, 0), a:cross(b))
        end)
 
        it("offset()", function()
-               assert.same({ x = 41, y = 52, z = 63 }, vector.offset(vector.new(1, 2, 3), 40, 50, 60))
+               assert.same({x = 41, y = 52, z = 63}, vector.offset(vector.new(1, 2, 3), 40, 50, 60))
+               assert.equal(vector.new(41, 52, 63), vector.offset(vector.new(1, 2, 3), 40, 50, 60))
+               assert.equal(vector.new(41, 52, 63), vector.new(1, 2, 3):offset(40, 50, 60))
+       end)
+
+       it("is()", function()
+               local some_table1 = {foo = 13, [42] = 1, "bar", 2}
+               local some_table2 = {1, 2, 3}
+               local some_table3 = {x = 1, 2, 3}
+               local some_table4 = {1, 2, z = 3}
+               local old = {x = 1, y = 2, z = 3}
+               local real = vector.new(1, 2, 3)
+
+               assert.is_false(vector.check(nil))
+               assert.is_false(vector.check(1))
+               assert.is_false(vector.check(true))
+               assert.is_false(vector.check("foo"))
+               assert.is_false(vector.check(some_table1))
+               assert.is_false(vector.check(some_table2))
+               assert.is_false(vector.check(some_table3))
+               assert.is_false(vector.check(some_table4))
+               assert.is_false(vector.check(old))
+               assert.is_true(vector.check(real))
+               assert.is_true(real:check())
+       end)
+
+       it("global pairs", function()
+               local out = {}
+               local vec = vector.new(10, 20, 30)
+               for k, v in pairs(vec) do
+                       out[k] = v
+               end
+               assert.same({x = 10, y = 20, z = 30}, out)
+       end)
+
+       it("abusing works", function()
+               local v = vector.new(1, 2, 3)
+               v.a = 1
+               assert.equal(1, v.a)
+
+               local a_is_there = false
+               for key, value in pairs(v) do
+                       if key == "a" then
+                               a_is_there = true
+                               assert.equal(value, 1)
+                               break
+                       end
+               end
+               assert.is_true(a_is_there)
+       end)
+
+       it("add()", function()
+               local a = vector.new(1, 2, 3)
+               local b = vector.new(1, 4, 3)
+               local c = vector.new(2, 6, 6)
+               assert.equal(c, vector.add(a, {x = 1, y = 4, z = 3}))
+               assert.equal(c, vector.add(a, b))
+               assert.equal(c, a:add(b))
+               assert.equal(c, a + b)
+               assert.equal(c, b + a)
+       end)
+
+       it("subtract()", function()
+               local a = vector.new(1, 2, 3)
+               local b = vector.new(2, 4, 3)
+               local c = vector.new(-1, -2, 0)
+               assert.equal(c, vector.subtract(a, {x = 2, y = 4, z = 3}))
+               assert.equal(c, vector.subtract(a, b))
+               assert.equal(c, a:subtract(b))
+               assert.equal(c, a - b)
+               assert.equal(c, -b + a)
+       end)
+
+       it("multiply()", function()
+               local a = vector.new(1, 2, 3)
+               local b = vector.new(2, 4, 3)
+               local c = vector.new(2, 8, 9)
+               local s = 2
+               local d = vector.new(2, 4, 6)
+               assert.equal(c, vector.multiply(a, {x = 2, y = 4, z = 3}))
+               assert.equal(c, vector.multiply(a, b))
+               assert.equal(d, vector.multiply(a, s))
+               assert.equal(d, a:multiply(s))
+               assert.equal(d, a * s)
+               assert.equal(d, s * a)
+               assert.equal(-a, -1 * a)
+       end)
+
+       it("divide()", function()
+               local a = vector.new(1, 2, 3)
+               local b = vector.new(2, 4, 3)
+               local c = vector.new(0.5, 0.5, 1)
+               local s = 2
+               local d = vector.new(0.5, 1, 1.5)
+               assert.equal(c, vector.divide(a, {x = 2, y = 4, z = 3}))
+               assert.equal(c, vector.divide(a, b))
+               assert.equal(d, vector.divide(a, s))
+               assert.equal(d, a:divide(s))
+               assert.equal(d, a / s)
+               assert.equal(d, 1/s * a)
+               assert.equal(-a, a / -1)
        end)
 
        it("to_string()", function()
                local v = vector.new(1, 2, 3.14)
                assert.same("(1, 2, 3.14)", vector.to_string(v))
+               assert.same("(1, 2, 3.14)", v:to_string())
+               assert.same("(1, 2, 3.14)", tostring(v))
        end)
 
        it("from_string()", function()
                local v = vector.new(1, 2, 3.14)
+               assert.is_true(vector.check(vector.from_string("(1, 2, 3.14)")))
                assert.same({v, 13}, {vector.from_string("(1, 2, 3.14)")})
                assert.same({v, 12}, {vector.from_string("(1,2 ,3.14)")})
                assert.same({v, 12}, {vector.from_string("(1,2,3.14,)")})