spec/util_fsm_spec.lua
author Kim Alvefur <zash@zash.se>
Sat, 23 Mar 2024 20:48:19 +0100
changeset 13465 c673ff1075bd
parent 13023 8a2f75e38eb2
permissions -rw-r--r--
mod_posix: Move everything to util.startup This allows greater control over the order of events. Notably, the internal ordering between daemonization, initialization of libunbound and setup of signal handling is sensitive. libunbound starts a separate thread for processing DNS requests. If this thread is started before signal handling has been set up, it will not inherit the signal handlers and instead behave as it would have before signal handlers were set up, i.e. cause the whole process to immediately exit. libunbound is usually initialized on the first DNS request, usually triggered by an outgoing s2s connection attempt. If daemonization happens before signals have been set up, signals may not be processed at all.
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);