Модуль:Luagravity/test

Материал из свободной русской энциклопедии «Традиция»
Перейти к навигации Перейти к поиску
  • 1: ===> OK
  • 2: ===> OK
  • activate: ===> OK
  • call: ===> OK
  • cycle: ===> OK
  • expr: Ошибка Lua в Модуль:Luagravity на строке 99: Модуль:Luagravity:274: assertion failed!.
  • height: ===> OK
  • meta: Ошибка Lua в Модуль:Luagravity на строке 99: Модуль:Luagravity/test:226: attempt to call local 's' (a table value). (TODO: allowEnvFuncs = true)
  • multi: ===> OK

local env = {
	nextEvent = function ()
    	return 'dt', 5
	end
}

local gvt = require 'Module:luagravity'
local expr = require 'Module:luagravity/expr'
local meta = require 'Module:luagravity/meta'
--local env = require 'luagravity.env.simple'

local p = {}
function p.multi (frame)
	local a = 0
	
	local A = gvt.loop(env.nextEvent,
	    function ()
	        a = a + 1
	        gvt.await(0)
	        a = a + 1
	    end)
	
	assert(a == 2)
	
	local B = gvt.loop(env.nextEvent,
	    function ()
	        a = a + 1
	        gvt.await(0)
	        a = a + 1
	    end)
	
	assert(a == 4)
	
	local b, c = 0, 0
	
	local B = gvt.start(
	    function ()
	        b = b + 1
	        gvt.await('x')
	        b = b + 1
	    end)
	
	local C = gvt.start(
	    function ()
	        c = c + 1
	        gvt.await('x')
	        c = c + 1
	    end)
	
	assert(b == 1)
	assert(c == 1)
	
	gvt.step(B, 'x')
	assert(b == 2)
	assert(c == 1)
	
	gvt.step(C, 'x')
	assert(b == 2)
	assert(c == 2)
	
	return '===> OK'
end

local type, assert = type, assert

function p.meta (frame)
	gvt.loop(env.nextEvent, meta.apply(
	    function ()
	
	        -- REACTORS
	
	        local tot = 1
	
	        function f1   (v) end
	        function _f2  (v) tot=tot+1 end
	        function __f3 (v) await(_f4) tot=tot*2 end
	        function _f4  (v) tot=tot+1 end
	
	        assert(type(f1) == 'function')
	        assert(_f2.zero == true)
	        assert(__f3.zero == false)
	
	        link(_f2, __f3)
	        _f2()
	        assert(tot == 2)
	        _f4()
	        assert(tot == 6)
	        spawn(__f3)
	        await(0)
	        _f4()
	        assert(tot == 14, tot)
	        unlink(_f2, __f3)
	        _f2()
	        assert(tot == 15)
	
	        -- meta.new
	        do
	            local t = meta.new{1,2,3,_a=1}
	            assert(t._a() == 1)
	            assert(meta.len(t) == 3)
	            local len = 0
	            for k,v in meta.pairs(t) do len 
	            = len+1 end
	            assert(len == 4)
	
	            local t2 = meta.new(nil, t, false)
	            assert(t2[2] == 2)
	            t._a = 1
	            assert(t2._a() == 1)
	            t._a = 2
	            assert(t2._a() == 2)
	        end
	
	        -- BEHAVIORS
	
	        _a = 1
	        _b = 2
	        _c = _a + _b
	        assert(_c() == 3)
	        _a = 3
	        _b = 4
	        assert(_c() == 7)
	
	        _v1 = 1
	        _v2 = 2
	        _v2 = _v1
	        _v1 = 3
	        assert((_v1() == 3) and (_v2() == 3))
	
	        -- LIFT
	
	        local fadd = function (a, b) return a+b end
	        local ladd = L(fadd)
	        _v3 = ladd(_v1, _v2)
	        _v4 = ladd(_v1, 2)
	        _v1 = 5
	        assert((_v1() == 5) and (_v2() == 5) and
	               (_v3() == 10) and (_v4() ==7))
	
	        local fnear = function (cur, exp)
	            return assert((cur >= exp*0.90) and (cur <= exp*1.10),
	                          exp..' vs '..cur)
	        end
	        local lnear = L(fnear)
	
	        local fequal = function (v1, v2)
	            return assert(v1 == v2)
	        end
	        local lequal = L(fequal)
	
	        local flt = function (v1, v2)
	            return assert(v1 < v2)
	        end
	        local llt = L(flt)
	
	--[[
	        -- IDX
	        do
	            _k1 = 1
	            local t1 = { 1, 2 }
	            local _v1 = IDX(t1, _k1)
	            assert(_v1() == 1)
	            _k1 = 2
	            assert(_v1() == 2)
	            _k2 = 1
	            local t2 = { 1, _v1 }
	            local _v2 = IDX(t2, _k2)
	            assert(_v2() == 1)
	            _k2 = 2
	            assert(_v2()() == 2)
	            _k1 = 1
	            assert(_v2()() == 1)
	        end
	]]
	
	        -- GLITCHES
	
	        _x = 1
	        local xx
	        local x1 = _x
	        for i=1, 50 do
	            local x2 = x1 + 1
	            llt(x1, x2)
	            x1 = x2
	            xx = x2
	        end
	        for i=1, 50 do
	            _x = i
	        end
	        assert(xx() == 100, xx())
	
	        -- VAR
	
	        _v5 = 1
	        _v6 = 2
	        _v6 = _v5
	        assert(_v6() == _v5())
	        _v5 = _v4
	        assert(_v5() == _v4() and _v6() == 7)
	        _v1 = 10
	        assert(_v5() == _v4() and _v6() == 12)
	
	        local fadd = function (a, b) return a+b end
	        local ladd = L(fadd)
	        _v3 = ladd(_v1, _v2)
	        local _v4 = ladd(_v1, 2)
	        _v1 = 5
	        assert((_v1() == 5) and (_v2() == 5) and
	               (_v3() == 10) and (_v4() ==7))
	
	        --[[local]] _v5 = expr.var(1)
	        --[[local]] _v6 = expr.var(2)
	        _v6:attr(_v5)
	        assert(_v6() == _v5())
	        _v5:attr(_v4)
	        assert(_v5() == _v4() and _v6() == 7)
	        _v1 = 10
	        assert(_v5() == _v4() and _v6() == 12)
	
	        -- INTEGRAL / DERIVATIVE
	
	        local s  = gvt.S(3) -- corrected for Traditio
	        local ss = gvt.S(3) -- corrected for Traditio
	        lequal(s, ss)
	        await(500)
	        fnear(s(), 1500)
	        local s1 = s + 1
	        llt(s, s1)
	        local d1 = D(s1)
	        local d2 = D(10000)
	        await(100) -- para ter derivada
	        await(100) -- para ter derivada
	        await(100) -- para ter derivada
	        lnear(d1, 3)
	        lequal(d2, 0)
	        await(1200)
	        fnear(s(), 6000)
	
	        -- OO
	        local t = meta.new({}, nil, true)
	        t.v = 3
	        function t:_inc (v)
	            self.v = self.v + (v or 1)
	        end
	        function t:_double ()
	            self.v = self.v * 2
	        end
	        link(t._inc, t._double)
	        t:_inc()
	        assert(t.v == 8)
	        t._inc(2)
	        assert(t.v == 20)
	
	        local _s = gvt.S(10) -- corrected for Traditio
	        local _d = D(_s)
	        await(5000)
	        await(0)
	        assert(_s() >= 50000 and _s() <= 51000)
	        assert(_d() == 10)
	
	        -- COND
	 
	        local lt = expr.lift(function(a,b) return a < b end)
	        local x = false
	        local s = gvt.S(1) -- corrected for Traditio
	        gvt.spawn(function()
	            gvt.await(500)
	            x = true
	        end)
	        gvt.await(cond(lt(1000,s)))
	        assert(x)
	
	        -- ACCUM
	        _a = 1
	        _b = 2
	        _c = 3
	        local t = { _a, _b, _c }
	        _all = 0
	        for i, _v in ipairs(t) do
	            _all = _all.src + _v
	        end
	        assert(_all() == 6)
	        _a = 2
	        _b = 4
	        assert(_all() == 9)
	    end))
	
	return '===> OK'
end

function p.test1 (frame)
	local _start, _stop = 0, 0
	
	local f_start = function(v)
	    v = v or 0
	    _start = _start + 1
	    return v + 1
	end
	
	start = gvt.create(f_start, {name='start',zero=true})
	
	local f_stop = function(v)
	    v = v or 0
	    _stop = _stop + 1
	    return v + 1
	end
	
	stop = gvt.create(f_stop, {name='stop',zero=true})
	
	gvt.loop(env.nextEvent,
	    function ()
	
	        -- Reacoes
	        gvt.call(start)
	        gvt.call(stop)
	        gvt.call(start)
	        gvt.call(stop)
	        assert((_start==2) and (_stop==2))
	
	        local rm = gvt.link(start, stop)
	
	        gvt.call(start)
	        assert((_start==3) and (_stop==3), _stop)
	
	        -- Quebra de elo "explicita"
	        gvt.unlink(start, stop)
	        gvt.call(start)
	        assert((_start==4) and (_stop==3))
	
	        gvt.link(start, stop)
	        gvt.link(stop, function (v)
	            assert(v == 3, v)
	        end)
	        gvt.call(start, 1)
	        assert((_start==5) and (_stop==4))
	
	        -- STRINGS
	        gvt.link('start', f_start)
	        gvt.link('stop',  f_stop)
	        gvt.post('start', 1)
	        gvt.post('stop', 1)
	        gvt.post('start', 1)
	        gvt.post('stop', 1)
	        assert((_start==7) and (_stop==6))
	
	    end)
	
	return '===> OK'
end

function p.test2 (frame)
	-- testing if `s_f1()` call is synchronous
	local _ret
	
	f1 = gvt.create(function()
	    gvt.await(10)
	    _ret = true
	end)
	
	f = gvt.create(function()end)
	
	gvt.loop(env.nextEvent,
	    function ()
	        gvt.spawn(function()
	            gvt.call(f1)
	            assert(_ret == true)
	        end)
	
	        -- testing if one call to `f` awakes exactly one `gvt.await(f)`
	        local _fs = 0
	        gvt.spawn(function()
	            gvt.await(f)
	            _fs = _fs + 1
	            gvt.await(f)
	            _fs = _fs + 1
	            gvt.await(f)
	            _fs = _fs + 1
	        end)
	        gvt.await(0)
	        gvt.call(f)
	        gvt.call(f)
	        assert(_fs == 2, _fs)
	
	        -- testing reaction nesting
	        local _ret = {}
	        gvt.spawn(function()
	            -- it is finished before `_ret[1]=true`
	            local r = gvt.spawn(function()
	                gvt.await(10)
	                _ret[1] = true
	            end)
	
	            -- it is not finished
	            gvt.spawn(function()
	                gvt.await(10)
	                _ret[2] = true
	            end)
	
	            gvt.await(0)
	            gvt.kill(r)
	
	        end)
	        gvt.await(20)
	        assert(not _ret[1])
	        assert(_ret[2])
	    end)
	
	-- testing inner reaction terminating outer reaction
	--[[
	g = function () end
	gvt.spawn(function()
	    gvt.spawn(function()
	        gvt.await(0)
	        g()
	gvt.await(0)
	error'oi'
	    end)
	    gvt.await(g)
	end)
	gvt.await(0.1)
	]]
	
	return '===> OK'
end

function p.activate (frame)
	local state
	
	local app = gvt.start(function()
	    state = 0
	    gvt.await(10)
	    state = 1
	    gvt.await(10)
	    state = 2
	end)
	
	assert(state == 0)
	
	gvt.step(app, 'dt', 10)
	gvt.step(app, 'dt', 0)
	assert(state == 1)
	
	gvt.deactivate(app)
	gvt.step(app, 'dt', 10)
	gvt.step(app, 'dt', 0)
	assert(state == 1)
	gvt.step(app, 'dt', 10)
	gvt.step(app, 'dt', 0)
	assert(state == 1)
	
	gvt.reactivate(app)
	gvt.step(app, 'dt', 10)
	gvt.step(app, 'dt', 0)
	assert(state == 2, state)
	
	return '===> OK'
end

function p.call (frame)
	gvt.loop(env.nextEvent,
	    function ()
	        local tot = 0
	        local r = gvt.create(function() gvt.await(0.2) end)
	        local a = gvt.create(function() tot=tot+1 gvt.await(0) end)
	        local b = gvt.create(function() tot=tot+1 gvt.await(0) end)
	        local c = gvt.create(function() tot=tot+1 gvt.await(0) end)
	        local d = gvt.create(function() tot=tot+1 gvt.await(0) end)
	        local e = gvt.create(function() tot=tot+1 gvt.await(0) end)
	        local f = gvt.create(function() tot=tot+1 gvt.await(0) end)
	        local g = gvt.create(function() tot=tot+1 gvt.await(0) end)
	        local h = gvt.create(function() tot=tot+1 gvt.await(0) end)
	        local i = gvt.create(function() tot=tot+1 gvt.await(0) end)
	        gvt.link(r, a)
	        gvt.link(r, b)
	        gvt.link(r, c)
	        gvt.link(r, d)
	        gvt.link(r, e)
	        gvt.link(r, f)
	        gvt.link(r, g)
	        gvt.link(r, h)
	        gvt.link(r, i)
	        gvt.call(r)
	        assert(tot == 9, tot)
	    end)
	
	return '===> OK'
end

function p.cycle (frame)
	gvt.loop(env.nextEvent,
	    function ()
	        -- Testing timer accuracy
	        local tot = 0
	        local f = gvt.create(
	            function ()
	                tot = tot + 1
	                gvt.await(30)
	            end)
	        gvt.link(f, f)
	        gvt.spawn(f)
	        gvt.await(100)
	        assert(tot == 4, tot)
	
	        -- tight cycle
	        local a = gvt.create(function()end, {zero=true})
	        local b = gvt.create(function()end, {zero=true})
	        gvt.link(a, b)
	        local ret, msg = pcall(gvt.link, b, a)
	        assert((not ret) and string.match(msg, 'tight cycle detected'))
	    end)
	
	return '===> OK'
end

function p.expr (frame)
	local fnear = function (cur, exp)
		return assert((cur >= exp*0.90) and (cur <= exp*1.10), cur)
	end
	local lnear = expr.lift(fnear)
	
	local fequal = function (v1, v2)
	    return assert(v1 == v2)
	end
	local lequal = expr.lift(fequal)
	
	local flt = function (v1, v2)
	    return assert(v1 < v2)
	end
	local llt = expr.lift(flt)
	
	local app = function ()
		local v1 = expr.new(1)
        local v2 = expr.new(2)
        gvt.link(v1._set, v2._set)
        gvt.call(v1._set, 3)
        assert((v1.value == 3) and (v2.value == 3))

        local tot = 0
        local a = expr.new(1)
        gvt.link(a._set, function () tot = tot+1 end)
        assert((tot == 0) and (a.value == 1), tot)
        gvt.call(a._set, 2)
        gvt.call(a._set, 2)  -- CANCEL
        assert(a.value == 2)
        assert(tot == 1, tot)

        local b = expr.new(0)
        gvt.link(b._set, function () tot = tot+1 end)
        assert(tot == 1)
        gvt.link(a._set, b._set)
        gvt.call(a._set, 3)
        gvt.call(a._set, 3)  -- CANCEL
        assert(tot == 3, tot)
        assert((a.value==3) and (b.value==3))
        gvt.unlink(a._set, b._set)
        gvt.call(a._set, 4)
        assert(tot == 4)
        assert((a.value==4) and (b.value==3))

        -- LIFT

        local fadd = function (a, b) return a+b end
        local ladd = expr.lift(fadd)
        local v3 = ladd(v1, v2)
        local v4 = ladd(v1, 2)
        gvt.call(v1._set, 5)
        assert((v1.value == 5) and (v2.value == 5) and
               (v3.value == 10) and (v4.value ==7))

        -- GLITCHES

        local x = expr.var(1)
        local xx
        local x1 = x
        for i=1, 50 do
            local x2 = ladd(x1, 1)
            llt(x1, x2)
            x1 = x2
            xx = x2
        end
        for i=1, 50 do
            gvt.call(x._set, i)
        end
        assert(xx.value == 100, xx.value)

        -- VAR

        local v5 = expr.var(1)
        local v6 = expr.var(2)
        v6:attr(v5)
        assert(v6.value == v5.value)
        v5:attr(v4)
        assert(v5.value == v4.value and v6.value == 7)
        gvt.call(v1._set, 10)
        assert(v5.value == v4.value and v6.value == 12)

        local fadd = function (a, b) return a+b end
        local ladd = expr.lift(fadd)
        local v3 = ladd(v1, v2)
        local v4 = ladd(v1, 2)
        gvt.call(v1._set, 5)
        assert((v1.value == 5) and (v2.value == 5) and
               (v3.value == 10) and (v4.value ==7))

        local v5 = expr.var(1)
        local v6 = expr.var(2)
        v6:attr(v5)
        assert(v6.value == v5.value)
        v5:attr(v4)
        assert(v5.value == v4.value and v6.value == 7)
        gvt.call(v1._set, 10)
        assert(v5.value == v4.value and v6.value == 12)
        v6:attr(10)
        gvt.call(v5._set, 1)
        assert(v5.value==1 and v6.value==10)

        -- INTEGRAL / DERIVATIVE

        local s  = expr.integral(3)
        local ss = expr.integral(3)
        lequal(s, ss)
        gvt.await(500)
        fnear(s.value, 1500)
        local s1 = ladd(s, 1)
        llt(s, s1)
        local d1 = expr.derivative(s1)
        local d2 = expr.derivative(10000)
        gvt.await(0) -- para ter derivada
        gvt.await(0) -- para ter derivada
        gvt.await(0) -- para ter derivada
        lnear(d1, 3)
        lequal(d2, 0)
        gvt.await(1500)
        fnear(s.value, 6000)

        -- DELAY
        local a = expr.new(0)
        local d = expr.delay(a, 250)
        local b = expr.var()
        b:attr(d)
        gvt.await(100)
        gvt.call(a._set, 1)
        gvt.call(a._set, 2)
        assert(d.value == nil)
        assert(b.value == nil)
        gvt.await(200)
        assert(d.value == 0, d.value)
        assert(b.value == 0)
        gvt.await(100)
        assert(d.value == 2, d.value)
        assert(b.value == 2)

        -- COND
 
        local lt = expr.lift(function(a,b) return a < b end)
        local x = false
        local s = expr.integral(1)
        gvt.spawn(function()
            gvt.await(500)
            x = true
        end)
        gvt.await(expr.condition(lt(1000,s))._true)
        assert(x)
    end
		
	gvt.loop(env.nextEvent, app)
	
	return '===> OK'
end

function p.height (frame)
	gvt.loop(env.nextEvent,
	    function ()
	        local zero = gvt.create(function()end, {zero=true})
	        local ret, msg = pcall(gvt.link, zero, zero)
	        assert((not ret) and string.match(msg, 'tight cycle detected'))
	
	        local tot = 0
	        local a = gvt.create(function() return 'o' end, {zero=true})
	        local b = gvt.create(function() return 22 end, {zero=true})
	        local c = gvt.create(
	            function (p1)
	                -- TODO: se der erro, testar o inverso (OU)
	                assert(p1 == 22)
	                tot = tot + 1
	            end, {zero=true})
	        gvt.link(a, b)
	        gvt.link(a, c)
	        gvt.link(b, c)
	        gvt.call(a)
	        assert(tot == 1)
	
	        local x = gvt.create(function () return nil end, {zero=true})
	        local y = gvt.create(function () return false end, {zero=true})
	        gvt.link(a, x)
	        gvt.link(a, y)
	        local d = gvt.create(
	            function ()
	                local ret = gvt.await(x, y)
	                assert(ret==nil or ret==false)
	            end)
	        gvt.spawn(d)
	        gvt.await(0)
	        gvt.call(a)
	
	        --[[
	        -- a1 --> s_a2 ==> a1
	        local a1 = gvt.create('a1',nil,true,function()end)
	        local a2 = gvt.create('a2',nil,false,function() gvt.await(a1) end)
	        gvt.spawn(a2)
	        gvt.await(0)
	        local ret, msg = pcall(gvt.link,a2, a1)
	        assert((not ret) and string.match(msg, 'tight cycle detected'))
	        ]]
	
	        -- b2 --> s_b1 ==> s_b1
	        local b2 = gvt.create(function()end, {zero=true})
	        local b1 = gvt.create(function() gvt.await(b2) end)
	        gvt.spawn(b1)
	        gvt.link(b1, b1)
	        gvt.await(0)
	        gvt.call(b2)
	        -- bb2 --> s_bb1 ==> s_bb1
	        local bb2 = gvt.create(function()end, {zero=true})
	        local bb1 = gvt.create(function() gvt.await(bb2) end)
	        gvt.link(bb1, bb1) -- diferenca em relacao ao anterior
	        gvt.spawn(bb1)       -- diferenca em relacao ao anterior
	        gvt.await(0)
	        gvt.call(bb2)
	
	--[[
	        local f1 = gvt.create('f1',nil,false,function() gvt.await(x) end)
	        local f2 = gvt.create('f2',nil,true,function()end)
	        gvt.link(f1, f2)
	        assert(f1.heightOut < f2.heightIn)
	        gvt.link(f2, f1)
	        assert(f1.heightIn > f2.heightOut)
	]]
	
	        -- s_1 <-- x1
	        -- s_2 <-- x2
	        -- s_1 ==> s_2
	        -- s_2 ==> x1
	        local t1, t2 = 0, 0
	        local x1 = gvt.create(function()end, {zero=true})
	        local x2 = gvt.create(function()end, {zero=true})
	        local z1 = gvt.create(function() gvt.await(x1) t1=t1+1 end)
	        local z2 = gvt.create(function() gvt.await(x2) t2=t2+1 end)
	        gvt.link(z1, z2)
	        gvt.link(z2, x1)
	        for i=0, 10 do
	            gvt.spawn(z1)
	            gvt.await(0)
	            assert(t1 == i)
	            assert(t2 == i)
	            gvt.call(x1)
	            assert(t1 == i+1)
	            assert(t2 == i)
	            gvt.call(x2)
	            assert(t1 == i+1)
	            assert(t2 == i+1)
	        end
	    end)
	
	return '===> OK'
end


return p