aboutsummaryrefslogtreecommitdiff
path: root/advtrains_interlocking/spec
diff options
context:
space:
mode:
Diffstat (limited to 'advtrains_interlocking/spec')
-rw-r--r--advtrains_interlocking/spec/ars_spec.lua67
-rw-r--r--advtrains_interlocking/spec/basic_signalling_spec.lua106
l---------advtrains_interlocking/spec/fixtures/advtrains_helpers.lua1
-rw-r--r--advtrains_interlocking/spec/mineunit.conf0
-rw-r--r--advtrains_interlocking/spec/signal_group_spec.lua95
5 files changed, 269 insertions, 0 deletions
diff --git a/advtrains_interlocking/spec/ars_spec.lua b/advtrains_interlocking/spec/ars_spec.lua
new file mode 100644
index 0000000..085dbcb
--- /dev/null
+++ b/advtrains_interlocking/spec/ars_spec.lua
@@ -0,0 +1,67 @@
+-- test the serialization function
+
+
+package.path = "../?.lua;" .. package.path
+
+
+
+
+_G.advtrains = {}
+_G.advtrains.interlocking = {}
+
+require("ars")
+
+local arstb = {{ ln="Foo"}, {c="Bar"}, {n=true, rc="Boo"}}
+local arsdef = {{ ln="Foo"}, {c="Bar"}, {rc="Boo"}, default=true}
+local arstr = [[LN Foo
+#Bar
+!RC Boo]]
+local defstr = [[*
+LN Foo
+#Bar
+RC Boo]]
+il = _G.advtrains.interlocking
+
+describe("ars_to_text", function ()
+ it("read table", function ()
+ assert.equals(il.ars_to_text(arstb),arstr)
+ end)
+ it("reads back and forth", function ()
+ assert.equals(il.ars_to_text(il.text_to_ars(arstr)),arstr)
+ end)
+ it("handles default routes properly", function ()
+ assert.equals(il.ars_to_text(arsdef),defstr)
+ end)
+end)
+
+describe("text_to_ars", function ()
+ it("writes table", function()
+ assert.same(il.text_to_ars(arstr),arstb)
+ end)
+ it("handles default routes properly", function ()
+ assert.same(il.text_to_ars(defstr),arsdef)
+ end)
+end)
+
+train1 = {}
+train2 = {}
+train3 = {}
+train1.line = "Foo"
+train1.routingcode = "Boo"
+train2.line= "Bar"
+train2.routingcode = "NotBoo NotBoo"
+train3.routingcode = "Foo Boo Moo Zoo"
+
+describe("check_rule_match", function ()
+ it("matches rules correctly", function()
+ assert.equals(il.ars_check_rule_match(arstb,train1),1)
+ assert.equals(il.ars_check_rule_match(arsdef,train2),nil)
+ end)
+ it("matches negative rules", function()
+ assert.equals(il.ars_check_rule_match(arstb,train2),3)
+ assert.equals(il.ars_check_rule_match(arstb,train3),nil)
+ end)
+ it("matches RC in a list correctly", function()
+ assert.equals(il.ars_check_rule_match(arsdef,train3),3)
+ end)
+end)
diff --git a/advtrains_interlocking/spec/basic_signalling_spec.lua b/advtrains_interlocking/spec/basic_signalling_spec.lua
new file mode 100644
index 0000000..a4e1e3a
--- /dev/null
+++ b/advtrains_interlocking/spec/basic_signalling_spec.lua
@@ -0,0 +1,106 @@
+--[[
+This file tests a large part of the signaling system, as a lot of tests for the
+signaling system tend to overlap for various parts of the system.
+]]
+
+require("mineunit")
+mineunit("core")
+
+_G.advtrains = {
+ interlocking = {
+ aspect = fixture("../../aspect"),
+ },
+ ndb = {
+ get_node = minetest.get_node,
+ swap_node = minetest.swap_node,
+ }
+}
+
+fixture("advtrains_helpers")
+fixture("../../database")
+sourcefile("distant")
+sourcefile("signal_api")
+sourcefile("signal_aspect_accessors")
+fixture("../../demosignals")
+
+minetest.register_node("advtrains_interlocking:signal_sign", {
+ advtrains = {
+ get_aspcet = function() return {main = 19} end
+ }
+})
+
+local D = advtrains.distant
+local I = advtrains.interlocking
+local A = I.aspect
+
+local stub_aspect_t1 = {
+ free = {main = -1},
+ slow = {main = 6},
+ danger = {main = 0, shunt = false},
+}
+for k, v in pairs(stub_aspect_t1) do
+ stub_aspect_t1[k] = A(v)
+end
+local stub_pos_t1 = {}
+for i = 1, 4 do
+ stub_pos_t1[i] = {x = 1, y = 0, z = i}
+end
+
+world.layout {
+ {stub_pos_t1[1], "advtrains_interlocking:ds_danger"},
+ {stub_pos_t1[2], "advtrains_interlocking:ds_slow"},
+ {stub_pos_t1[3], "advtrains_interlocking:ds_free"},
+ {stub_pos_t1[4], "advtrains_interlocking:signal_sign"},
+}
+
+describe("API for supposed signal aspects", function()
+ it("should load and save data properly", function()
+ local tbl = {_foo = {}}
+ I.load_supposed_aspects(tbl)
+ assert.same(tbl, I.save_supposed_aspects())
+ end)
+ it("should set and get signals properly", function ()
+ local pos = stub_pos_t1[2]
+ local asp = stub_aspect_t1.slow
+ local newasp = A{ main = math.random(1,5) }
+ assert.equal(asp, I.signal_get_aspect(pos))
+ I.signal_set_aspect(pos, newasp)
+ assert.equal(newasp, I.signal_get_aspect(pos))
+ assert.equal(asp, I.signal_get_real_aspect(pos))
+ I.signal_set_aspect(pos, asp)
+ end)
+end)
+
+describe("Distant signaling", function()
+ it("should assign distant signals and set the distant aspect correspondingly", function()
+ for i = 1, 2 do
+ D.assign(stub_pos_t1[i], stub_pos_t1[i+1])
+ end
+ assert.equal(stub_aspect_t1.danger, I.signal_get_aspect(stub_pos_t1[1]))
+ assert.equal(A{main = 6, dst = 0}, I.signal_get_aspect(stub_pos_t1[2]))
+ assert.equal(A{main = -1, dst = 6}, I.signal_get_aspect(stub_pos_t1[3]))
+ end)
+ it("should report assignments properly", function()
+ assert.same({stub_pos_t1[1], "manual"}, {D.get_main(stub_pos_t1[2])})
+ assert.same({[advtrains.encode_pos(stub_pos_t1[3])] = "manual"}, D.get_dst(stub_pos_t1[2]))
+ end)
+ it("should update distant aspects automatically", function()
+ I.signal_set_aspect(stub_pos_t1[2], {main = 2, dst = -1})
+ assert.equal(A{main = 2, dst = 0}, I.signal_get_aspect(stub_pos_t1[2]))
+ assert.equal(A{main = -1, dst = 2}, I.signal_get_aspect(stub_pos_t1[3]))
+ end)
+ it("should unassign signals when one is removed", function()
+ world.set_node(stub_pos_t1[2], "air")
+ assert.same({}, D.get_dst(stub_pos_t1[1]))
+ assert.same({}, {D.get_main(stub_pos_t1[3])})
+ assert.same(stub_aspect_t1.free, I.signal_get_aspect(stub_pos_t1[3]))
+ end)
+ it("should reject signal signs", function()
+ D.assign(stub_pos_t1[1], stub_pos_t1[4])
+ assert.same({}, D.get_dst(stub_pos_t1[1]))
+ assert.same({}, {D.get_main(stub_pos_t1[4])})
+ D.assign(stub_pos_t1[4], stub_pos_t1[1])
+ assert.same({}, D.get_dst(stub_pos_t1[4]))
+ assert.same({}, {D.get_main(stub_pos_t1[1])})
+ end)
+end)
diff --git a/advtrains_interlocking/spec/fixtures/advtrains_helpers.lua b/advtrains_interlocking/spec/fixtures/advtrains_helpers.lua
new file mode 120000
index 0000000..9b0ab67
--- /dev/null
+++ b/advtrains_interlocking/spec/fixtures/advtrains_helpers.lua
@@ -0,0 +1 @@
+../../../advtrains/helpers.lua \ No newline at end of file
diff --git a/advtrains_interlocking/spec/mineunit.conf b/advtrains_interlocking/spec/mineunit.conf
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/advtrains_interlocking/spec/mineunit.conf
diff --git a/advtrains_interlocking/spec/signal_group_spec.lua b/advtrains_interlocking/spec/signal_group_spec.lua
new file mode 100644
index 0000000..bc9d007
--- /dev/null
+++ b/advtrains_interlocking/spec/signal_group_spec.lua
@@ -0,0 +1,95 @@
+require "mineunit"
+mineunit("core")
+
+_G.advtrains = {
+ interlocking = {
+ aspect = sourcefile("aspect"),
+ },
+ ndb = {
+ get_node = minetest.get_node,
+ swap_node = minetest.swap_node,
+ }
+}
+
+fixture("advtrains_helpers")
+sourcefile("database")
+sourcefile("signal_api")
+sourcefile("distant")
+sourcefile("signal_aspect_accessors")
+
+local A = advtrains.interlocking.aspect
+local D = advtrains.distant
+local I = advtrains.interlocking
+local N = advtrains.ndb
+
+local groupdef = {
+ name = "foo",
+ aspects = {
+ proceed = {main = -1},
+ caution = {},
+ danger = {main = 0},
+ "proceed",
+ {"caution"},
+ "danger",
+ },
+}
+
+for k, v in pairs(groupdef.aspects) do
+ minetest.register_node("advtrains_interlocking:" .. k, {
+ advtrains = {
+ supported_aspects = {
+ group = "foo",
+ },
+ get_aspect = function() return A{group = "foo", name = k} end,
+ set_aspect = function(pos, _, name)
+ N.swap_node(pos, {name = "advtrains_interlocking:" .. name})
+ end,
+ }
+ })
+end
+
+local origin = vector.new(0, 0, 0)
+local dstpos = vector.new(0, 0, 1)
+
+world.layout {
+ {origin, "advtrains_interlocking:danger"},
+ {dstpos, "advtrains_interlocking:proceed"},
+}
+
+describe("signal group registration", function()
+ it("should work", function()
+ A.register_group(groupdef)
+ assert(A.get_group_definition("foo"))
+ end)
+ it("should only be allowed once for the same group", function()
+ assert.has.errors(function() A.register_group(type2def) end)
+ end)
+ it("should handle nonexistant groups", function()
+ assert.is_nil(A.get_group_definition("something_else"))
+ end)
+ it("should reject invalid definitions", function()
+ assert.has.errors(function() A.register_group({}) end)
+ assert.has.errors(function() A.register_group({name="",label={}}) end)
+ assert.has.errors(function() A.register_group({name="",aspects={}}) end)
+ end)
+end)
+
+describe("signal aspect", function()
+ it("should handle empty fields properly", function()
+ assert.equal(A{main = 0}, A{group="foo", name="danger"}:to_group())
+ end)
+ it("should be converted properly", function()
+ assert.equal(A{main = 0}, A{group="foo", name="danger"})
+ assert.equal(A{}, A{group="foo", name="caution"})
+ assert.equal(A{main = -1}, A{group="foo", name="proceed"})
+ end)
+end)
+
+describe("signals in groups", function()
+ it("should support distant signaling", function()
+ assert.equal("caution", A():adjust_distant(A{group="foo",name="danger"}).name)
+ assert.equal("proceed", A():adjust_distant(A{group="foo",name="caution"}).name)
+ assert.equal("proceed", A():adjust_distant(A{group="foo",name="proceed"}).name)
+ assert.equal("danger", A{group="foo",name="danger"}:adjust_distant{}.name)
+ end)
+end)