spec/util_fsm_spec.lua
author Kim Alvefur <zash@zash.se>
Sun, 24 Mar 2024 21:32:00 +0100
changeset 13468 2dbc169aae6a
parent 13023 8a2f75e38eb2
permissions -rw-r--r--
util.startup: Abort before initialization of logging when started as root Prevents creation of log files owned by the root user which could be inaccessible once started correctly.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
13023
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);