Annotate

spec/util_fsm_spec.lua @ 13200:150e3bbec1bd

tools: Fix file ending of mod2spec.sh (thanks buildbot) Accidentally .lua ?
author Kim Alvefur <zash@zash.se>
date Sun, 16 Jul 2023 20:29:06 +0200
parent 13019:8a2f75e38eb2
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
13019
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
1 describe("util.fsm", function ()
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
2 local new_fsm = require "util.fsm".new;
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
3
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
4 do
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
5 local fsm = new_fsm({
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
6 transitions = {
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
7 { name = "melt", from = "solid", to = "liquid" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
8 { name = "freeze", from = "liquid", to = "solid" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
9 };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
10 });
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
11
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
12 it("works", function ()
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
13 local water = fsm:init("liquid");
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
14 water:freeze();
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
15 assert.equal("solid", water.state);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
16 water:melt();
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
17 assert.equal("liquid", water.state);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
18 end);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
19
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
20 it("does not allow invalid transitions", function ()
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
21 local water = fsm:init("liquid");
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
22 assert.has_errors(function ()
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
23 water:melt();
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
24 end, "Invalid state transition: liquid cannot melt");
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
25
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
26 water:freeze();
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
27 assert.equal("solid", water.state);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
28
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
29 water:melt();
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
30 assert.equal("liquid", water.state);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
31
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
32 assert.has_errors(function ()
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
33 water:melt();
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
34 end, "Invalid state transition: liquid cannot melt");
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
35 end);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
36 end
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
37
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
38 it("notifies observers", function ()
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
39 local n = 0;
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
40 local has_become_solid = spy.new(function (transition)
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
41 assert.is_table(transition);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
42 assert.equal("solid", transition.to);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
43 assert.is_not_nil(transition.instance);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
44 n = n + 1;
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
45 if n == 1 then
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
46 assert.is_nil(transition.from);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
47 assert.is_nil(transition.from_attr);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
48 elseif n == 2 then
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
49 assert.equal("liquid", transition.from);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
50 assert.is_nil(transition.from_attr);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
51 assert.equal("freeze", transition.name);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
52 end
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
53 end);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
54 local is_melting = spy.new(function (transition)
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
55 assert.is_table(transition);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
56 assert.equal("melt", transition.name);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
57 assert.is_not_nil(transition.instance);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
58 end);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
59 local fsm = new_fsm({
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
60 transitions = {
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
61 { name = "melt", from = "solid", to = "liquid" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
62 { name = "freeze", from = "liquid", to = "solid" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
63 };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
64 state_handlers = {
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
65 solid = has_become_solid;
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
66 };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
67
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
68 transition_handlers = {
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
69 melt = is_melting;
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
70 };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
71 });
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
72
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
73 local water = fsm:init("liquid");
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
74 assert.spy(has_become_solid).was_not_called();
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
75
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
76 local ice = fsm:init("solid"); --luacheck: ignore 211/ice
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
77 assert.spy(has_become_solid).was_called(1);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
78
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
79 water:freeze();
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
80
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
81 assert.spy(is_melting).was_not_called();
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
82 water:melt();
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
83 assert.spy(is_melting).was_called(1);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
84 end);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
85
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
86 local function test_machine(fsm_spec, expected_transitions, test_func)
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
87 fsm_spec.handlers = fsm_spec.handlers or {};
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
88 fsm_spec.handlers.transitioned = function (transition)
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
89 local expected_transition = table.remove(expected_transitions, 1);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
90 assert.same(expected_transition, {
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
91 name = transition.name;
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
92 to = transition.to;
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
93 to_attr = transition.to_attr;
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
94 from = transition.from;
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
95 from_attr = transition.from_attr;
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
96 });
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
97 end;
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
98 local fsm = new_fsm(fsm_spec);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
99 test_func(fsm);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
100 assert.equal(0, #expected_transitions);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
101 end
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
102
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
103
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
104 it("handles transitions with the same name", function ()
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
105 local expected_transitions = {
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
106 { name = nil , from = "none", to = "A" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
107 { name = "step", from = "A", to = "B" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
108 { name = "step", from = "B", to = "C" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
109 { name = "step", from = "C", to = "D" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
110 };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
111
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
112 test_machine({
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
113 default_state = "none";
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
114 transitions = {
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
115 { name = "step", from = "A", to = "B" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
116 { name = "step", from = "B", to = "C" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
117 { name = "step", from = "C", to = "D" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
118 };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
119 }, expected_transitions, function (fsm)
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
120 local i = fsm:init("A");
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
121 i:step(); -- B
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
122 i:step(); -- C
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
123 i:step(); -- D
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
124 assert.has_errors(function ()
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
125 i:step();
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
126 end, "Invalid state transition: D cannot step");
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
127 end);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
128 end);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
129
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
130 it("handles supports wildcard transitions", function ()
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
131 local expected_transitions = {
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
132 { name = nil , from = "none", to = "A" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
133 { name = "step", from = "A", to = "B" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
134 { name = "step", from = "B", to = "C" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
135 { name = "reset", from = "C", to = "A" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
136 { name = "step", from = "A", to = "B" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
137 { name = "step", from = "B", to = "C" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
138 { name = "step", from = "C", to = "D" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
139 };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
140
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
141 test_machine({
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
142 default_state = "none";
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
143 transitions = {
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
144 { name = "step", from = "A", to = "B" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
145 { name = "step", from = "B", to = "C" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
146 { name = "step", from = "C", to = "D" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
147 { name = "reset", from = "*", to = "A" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
148 };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
149 }, expected_transitions, function (fsm)
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
150 local i = fsm:init("A");
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
151 i:step(); -- B
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
152 i:step(); -- C
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
153 i:reset(); -- A
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
154 i:step(); -- B
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
155 i:step(); -- C
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
156 i:step(); -- D
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
157 assert.has_errors(function ()
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
158 i:step();
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
159 end, "Invalid state transition: D cannot step");
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
160 end);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
161 end);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
162
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
163 it("supports specifying multiple from states", function ()
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
164 local expected_transitions = {
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
165 { name = nil , from = "none", to = "A" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
166 { name = "step", from = "A", to = "B" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
167 { name = "step", from = "B", to = "C" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
168 { name = "reset", from = "C", to = "A" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
169 { name = "step", from = "A", to = "B" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
170 { name = "step", from = "B", to = "C" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
171 { name = "step", from = "C", to = "D" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
172 };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
173
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
174 test_machine({
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
175 default_state = "none";
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
176 transitions = {
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
177 { name = "step", from = "A", to = "B" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
178 { name = "step", from = "B", to = "C" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
179 { name = "step", from = "C", to = "D" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
180 { name = "reset", from = {"B", "C", "D"}, to = "A" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
181 };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
182 }, expected_transitions, function (fsm)
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
183 local i = fsm:init("A");
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
184 i:step(); -- B
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
185 i:step(); -- C
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
186 i:reset(); -- A
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
187 assert.has_errors(function ()
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
188 i:reset();
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
189 end, "Invalid state transition: A cannot reset");
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
190 i:step(); -- B
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
191 i:step(); -- C
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
192 i:step(); -- D
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
193 assert.has_errors(function ()
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
194 i:step();
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
195 end, "Invalid state transition: D cannot step");
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
196 end);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
197 end);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
198
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
199 it("handles transitions with the same start/end state", function ()
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
200 local expected_transitions = {
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
201 { name = nil , from = "none", to = "A" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
202 { name = "step", from = "A", to = "B" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
203 { name = "step", from = "B", to = "B" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
204 { name = "step", from = "B", to = "B" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
205 };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
206
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
207 test_machine({
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
208 default_state = "none";
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
209 transitions = {
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
210 { name = "step", from = "A", to = "B" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
211 { name = "step", from = "B", to = "B" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
212 };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
213 }, expected_transitions, function (fsm)
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
214 local i = fsm:init("A");
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
215 i:step(); -- B
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
216 i:step(); -- B
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
217 i:step(); -- B
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
218 end);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
219 end);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
220
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
221 it("can identify instances of a specific fsm", function ()
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
222 local fsm1 = new_fsm({ default_state = "a" });
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
223 local fsm2 = new_fsm({ default_state = "a" });
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
224
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
225 local i1 = fsm1:init();
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
226 local i2 = fsm2:init();
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
227
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
228 assert.truthy(fsm1:is_instance(i1));
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
229 assert.truthy(fsm2:is_instance(i2));
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
230
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
231 assert.falsy(fsm1:is_instance(i2));
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
232 assert.falsy(fsm2:is_instance(i1));
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
233 end);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
234
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
235 it("errors when an invalid initial state is passed", function ()
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
236 local fsm1 = new_fsm({
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
237 transitions = {
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
238 { name = "", from = "A", to = "B" };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
239 };
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
240 });
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
241
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
242 assert.has_no_errors(function ()
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
243 fsm1:init("A");
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
244 end);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
245
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
246 assert.has_errors(function ()
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
247 fsm1:init("C");
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
248 end);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
249 end);
8a2f75e38eb2 util.fsm: New utility lib for finite state machines
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
250 end);