hifsm 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/README.md +1 -1
- data/hifsm.gemspec +2 -0
- data/lib/hifsm/callbacks.rb +7 -16
- data/lib/hifsm/dsl/abstract_builder.rb +36 -0
- data/lib/hifsm/dsl/event_builder.rb +31 -0
- data/lib/hifsm/dsl/state_builder.rb +34 -0
- data/lib/hifsm/event.rb +4 -9
- data/lib/hifsm/fsm.rb +50 -44
- data/lib/hifsm/state.rb +14 -31
- data/lib/hifsm/version.rb +1 -1
- data/lib/hifsm.rb +3 -0
- data/test/test_groupped_transitions.rb +58 -0
- data/test/test_two_machines.rb +5 -3
- metadata +8 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 58e7c452cb3f0ebfce493c75f0130b191807daae
|
|
4
|
+
data.tar.gz: 973378be201d7957f7fc22231d0d86e34896825a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2093aab1fc0253c749fd3b352560ad517a64f4b6a6d14a437197b61e77b7aa8364cf38a269b6455ed2b7eb4c5bb130442ca938fd21a2bfcc86e6d98ae359b30a
|
|
7
|
+
data.tar.gz: 4730e63e2f71fa653e7c487953da10b0415c00a26a2a005578f92d24178882d9e09b271ac8f1f9715e848ee5078f44ae4428ff99420b84cdf700a92ccf1e0ee9
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
|
@@ -192,7 +192,7 @@ On event:
|
|
|
192
192
|
|
|
193
193
|
If any of `before...` callbacks returns `false` then no further processing is done, no exceptions raised, machine state is not changed.
|
|
194
194
|
|
|
195
|
-
On `act!` state's actions called from top state to nested. If [several FSMs defined]
|
|
195
|
+
On `act!` state's actions called from top state to nested. If [several FSMs defined](https://github.com/stiff/hifsm/blob/master/test/test_two_machines.rb), object's `act!` invokes them all in order as they were defined and returns value from last action.
|
|
196
196
|
|
|
197
197
|
## ActiveRecord integration
|
|
198
198
|
|
data/hifsm.gemspec
CHANGED
|
@@ -18,6 +18,8 @@ Gem::Specification.new do |spec|
|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
19
19
|
spec.require_paths = ["lib"]
|
|
20
20
|
|
|
21
|
+
spec.required_ruby_version = '>= 1.9'
|
|
22
|
+
|
|
21
23
|
spec.add_development_dependency "bundler", "~> 1.3"
|
|
22
24
|
spec.add_development_dependency "rake"
|
|
23
25
|
spec.add_development_dependency "minitest"
|
data/lib/hifsm/callbacks.rb
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
class Callbacks
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
def initialize(listeners = [])
|
|
4
|
+
@listeners = listeners
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def trigger(target, *args)
|
|
8
|
+
@listeners.map do |cb|
|
|
5
9
|
if cb.nil?
|
|
10
|
+
# raise something maybe? :)
|
|
6
11
|
elsif cb.is_a? Symbol
|
|
7
12
|
if target.method(cb).arity.zero?
|
|
8
13
|
target.send(cb)
|
|
@@ -14,18 +19,4 @@ class Callbacks
|
|
|
14
19
|
end
|
|
15
20
|
end
|
|
16
21
|
end
|
|
17
|
-
|
|
18
|
-
def initialize
|
|
19
|
-
@listeners = []
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def add(symbol = nil, &callback)
|
|
23
|
-
@listeners.push symbol || callback
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def trigger(target, *args)
|
|
27
|
-
@listeners.map do |callback|
|
|
28
|
-
Callbacks.invoke target, callback, *args
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
22
|
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Hifsm
|
|
2
|
+
module DSL
|
|
3
|
+
class AbstractBuilder
|
|
4
|
+
|
|
5
|
+
def self.define_dsl_callback(cb)
|
|
6
|
+
define_method(cb) do |symbol = nil, &block|
|
|
7
|
+
@defs.each do |ev_def|
|
|
8
|
+
ev_def[cb].push symbol || block
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def initialize
|
|
14
|
+
@defs = []
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def each(&block)
|
|
18
|
+
@defs.each(&block)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
protected
|
|
22
|
+
def defs
|
|
23
|
+
@defs
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def slice_callbacks(options, names)
|
|
27
|
+
Hash[names.map {|n| [n, array_wrap(options[n])]}]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# like in ActiveSupport
|
|
31
|
+
def array_wrap(anything)
|
|
32
|
+
anything.is_a?(Array) ? anything : [anything].compact
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Hifsm
|
|
2
|
+
module DSL
|
|
3
|
+
# Normalizes event definitions to form
|
|
4
|
+
# {:from => [], :to => ..., :guard => ..., before, after}
|
|
5
|
+
class EventBuilder < AbstractBuilder
|
|
6
|
+
|
|
7
|
+
def initialize(options, &block)
|
|
8
|
+
super()
|
|
9
|
+
build_def(options) if options[:to]
|
|
10
|
+
instance_eval(&block) if block
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
Hifsm::Event::CALLBACKS.each do |cb|
|
|
14
|
+
define_dsl_callback(cb)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# from :state, :to => :state
|
|
18
|
+
def from(state, options)
|
|
19
|
+
build_def(options.dup.merge(:from => state))
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
def build_def(options)
|
|
24
|
+
defs << slice_callbacks(options, Hifsm::Event::CALLBACKS).merge(
|
|
25
|
+
:from => array_wrap(options[:from]),
|
|
26
|
+
:to => options[:to]
|
|
27
|
+
)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module Hifsm
|
|
2
|
+
module DSL
|
|
3
|
+
# Normalizes state definitions
|
|
4
|
+
class StateBuilder < AbstractBuilder
|
|
5
|
+
|
|
6
|
+
def initialize(options = {}, &block)
|
|
7
|
+
super()
|
|
8
|
+
build_def(options)
|
|
9
|
+
instance_eval(&block) if block
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
Hifsm::State::CALLBACKS.each do |cb|
|
|
13
|
+
define_dsl_callback(cb)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def state(*args, &block)
|
|
17
|
+
defs.first[:sub_states].push [args, block]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def event(*args, &block)
|
|
21
|
+
defs.first[:sub_events].push [args, block]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
def build_def(options)
|
|
26
|
+
defs << slice_callbacks(options, Hifsm::State::CALLBACKS).merge(
|
|
27
|
+
:initial => options[:initial],
|
|
28
|
+
:sub_states => [],
|
|
29
|
+
:sub_events => []
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
data/lib/hifsm/event.rb
CHANGED
|
@@ -4,20 +4,15 @@ module Hifsm
|
|
|
4
4
|
|
|
5
5
|
attr_reader :name, :to
|
|
6
6
|
|
|
7
|
-
def initialize(name, to,
|
|
7
|
+
def initialize(name, to, callbacks_options)
|
|
8
8
|
@name = name
|
|
9
9
|
@to = to
|
|
10
|
-
@callbacks =
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@callbacks[:guard].add g
|
|
10
|
+
@callbacks = {}
|
|
11
|
+
CALLBACKS.each do |cb|
|
|
12
|
+
@callbacks[cb] = Callbacks.new(callbacks_options[cb])
|
|
14
13
|
end
|
|
15
14
|
end
|
|
16
15
|
|
|
17
|
-
CALLBACKS.each do |cb|
|
|
18
|
-
define_method(cb) { |&block| @callbacks[cb].add(&block) }
|
|
19
|
-
end
|
|
20
|
-
|
|
21
16
|
def trigger(target, cb, *args)
|
|
22
17
|
@callbacks[cb].trigger(target, *args)
|
|
23
18
|
end
|
data/lib/hifsm/fsm.rb
CHANGED
|
@@ -12,33 +12,42 @@ module Hifsm
|
|
|
12
12
|
|
|
13
13
|
instance_eval(&block) if block
|
|
14
14
|
|
|
15
|
-
@fsm_module =
|
|
16
|
-
@machine_class =
|
|
17
|
-
include fsm_module
|
|
18
|
-
define_method("#{name}_machine") { self }
|
|
19
|
-
end
|
|
15
|
+
@fsm_module = nil
|
|
16
|
+
@machine_class = nil
|
|
20
17
|
end
|
|
21
18
|
|
|
22
19
|
def instantiate(target = nil, initial_state = nil)
|
|
20
|
+
fsm_module = get_fsm_module
|
|
21
|
+
machine_name = "#{name}_machine"
|
|
22
|
+
@machine_class ||= Class.new(Hifsm::Machine) do
|
|
23
|
+
include fsm_module
|
|
24
|
+
define_method(machine_name) { self }
|
|
25
|
+
end
|
|
23
26
|
@machine_class.new(self, target, initial_state)
|
|
24
27
|
end
|
|
25
28
|
|
|
26
29
|
#DSL
|
|
27
|
-
def event(name, options, &block)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
def event(name, options = {}, &block)
|
|
31
|
+
Hifsm::DSL::EventBuilder.new(options, &block).each do |ev_def|
|
|
32
|
+
ev = Hifsm::Event.new name,
|
|
33
|
+
get_state!(ev_def[:to]),
|
|
34
|
+
ev_def
|
|
35
|
+
|
|
36
|
+
from_states = ev_def[:from]
|
|
37
|
+
from_states = @states.keys if from_states.empty?
|
|
38
|
+
from_states.each do |from|
|
|
39
|
+
st = get_state!(from)
|
|
40
|
+
st.add_transition(ev)
|
|
41
|
+
end
|
|
42
|
+
|
|
34
43
|
end
|
|
35
|
-
ev.instance_eval(&block) if block
|
|
36
44
|
end
|
|
37
45
|
|
|
38
46
|
def state(name, options = {}, &block)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
47
|
+
Hifsm::DSL::StateBuilder.new(options, &block).each do |st_def|
|
|
48
|
+
st = @states[name.to_s] = Hifsm::State.new(name, @parent, st_def)
|
|
49
|
+
@initial_state = st if options[:initial]
|
|
50
|
+
end
|
|
42
51
|
end
|
|
43
52
|
|
|
44
53
|
# internals
|
|
@@ -68,41 +77,38 @@ module Hifsm
|
|
|
68
77
|
end
|
|
69
78
|
|
|
70
79
|
def to_module
|
|
71
|
-
|
|
80
|
+
get_fsm_module
|
|
72
81
|
end
|
|
73
82
|
|
|
74
83
|
private
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
Module.new do
|
|
86
|
-
define_singleton_method :included do |base|
|
|
87
|
-
base.send(:define_singleton_method, "#{machine_name}_definition") { fsm }
|
|
88
|
-
end
|
|
84
|
+
def get_fsm_module
|
|
85
|
+
@fsm_module ||= begin
|
|
86
|
+
fsm = self # capture self
|
|
87
|
+
machine_var = "@#{name}_machine"
|
|
88
|
+
machine_name = "#{name}_machine"
|
|
89
|
+
|
|
90
|
+
Module.new do
|
|
91
|
+
define_singleton_method :included do |base|
|
|
92
|
+
base.send(:define_singleton_method, "#{machine_name}_definition") { fsm }
|
|
93
|
+
end
|
|
89
94
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
# <state>_machine returns machine instance
|
|
96
|
+
define_method(machine_name) do
|
|
97
|
+
if instance_variable_defined?(machine_var)
|
|
98
|
+
instance_variable_get(machine_var)
|
|
99
|
+
else
|
|
100
|
+
machine = fsm.instantiate(self)
|
|
101
|
+
instance_variable_set(machine_var, machine)
|
|
102
|
+
end
|
|
97
103
|
end
|
|
98
|
-
end
|
|
99
104
|
|
|
100
|
-
|
|
101
|
-
|
|
105
|
+
# <state> returns string representation of the current state
|
|
106
|
+
define_method(fsm.name) { send(machine_name).to_s }
|
|
102
107
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
108
|
+
# <event> fires event
|
|
109
|
+
fsm.all_events.each do |event_name, event|
|
|
110
|
+
define_method(event_name) {|*args| send(machine_name).fire(event_name, *args) }
|
|
111
|
+
end
|
|
106
112
|
end
|
|
107
113
|
end
|
|
108
114
|
end
|
data/lib/hifsm/state.rb
CHANGED
|
@@ -1,41 +1,30 @@
|
|
|
1
1
|
module Hifsm
|
|
2
2
|
class State
|
|
3
|
-
CALLBACKS = [:before_enter, :before_exit, :after_enter, :after_exit].freeze
|
|
3
|
+
CALLBACKS = [:before_enter, :before_exit, :after_enter, :after_exit, :action].freeze
|
|
4
4
|
|
|
5
5
|
attr_reader :sub_fsm
|
|
6
6
|
|
|
7
|
-
def initialize(
|
|
8
|
-
@fsm = fsm
|
|
7
|
+
def initialize(name, parent = nil, options)
|
|
9
8
|
@name = name
|
|
10
9
|
@parent = parent
|
|
11
|
-
@
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
@callbacks = {}
|
|
11
|
+
CALLBACKS.each do |cb|
|
|
12
|
+
@callbacks[cb] = Callbacks.new(options[cb])
|
|
13
|
+
end
|
|
15
14
|
@transitions = Hash.new {|h, key| h[key] = Array.new }
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
# DSL
|
|
19
|
-
def action(&block)
|
|
20
|
-
@action = block
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def state(*args, &block)
|
|
24
|
-
sub_fsm!.state(*args, &block)
|
|
25
|
-
end
|
|
26
15
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
16
|
+
if options[:sub_states].empty?
|
|
17
|
+
@sub_fsm = nil
|
|
18
|
+
else
|
|
19
|
+
@sub_fsm = Hifsm::FSM.new(nil, self)
|
|
20
|
+
options[:sub_states].each {|args, block| @sub_fsm.state(*args, &block) }
|
|
21
|
+
options[:sub_events].each {|args, block| @sub_fsm.event(*args, &block) }
|
|
22
|
+
end
|
|
33
23
|
end
|
|
34
24
|
|
|
35
|
-
# internals
|
|
36
25
|
def act!(target, *args)
|
|
37
26
|
@parent.act!(target, *args) if @parent
|
|
38
|
-
|
|
27
|
+
trigger(target, :action, *args).last
|
|
39
28
|
end
|
|
40
29
|
|
|
41
30
|
def add_transition(ev)
|
|
@@ -94,11 +83,5 @@ module Hifsm
|
|
|
94
83
|
@name.to_s
|
|
95
84
|
end
|
|
96
85
|
end
|
|
97
|
-
|
|
98
|
-
private
|
|
99
|
-
def sub_fsm!
|
|
100
|
-
# FIXME .name = too much coupling
|
|
101
|
-
@sub_fsm ||= Hifsm::FSM.new(@fsm.name, self)
|
|
102
|
-
end
|
|
103
86
|
end
|
|
104
87
|
end
|
data/lib/hifsm/version.rb
CHANGED
data/lib/hifsm.rb
CHANGED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'setup_tests'
|
|
2
|
+
|
|
3
|
+
class TestGrouppedTransitions < Minitest::Test
|
|
4
|
+
class Button
|
|
5
|
+
include Hifsm
|
|
6
|
+
|
|
7
|
+
hifsm do
|
|
8
|
+
state :active, :initial => true
|
|
9
|
+
state :alternative
|
|
10
|
+
state :disabled
|
|
11
|
+
|
|
12
|
+
# each :to generates new event
|
|
13
|
+
event :click, :to => :disabled, :guard => :disable_on_click
|
|
14
|
+
event :click, :from => :disabled, :to => :disabled
|
|
15
|
+
event :click do
|
|
16
|
+
from :active, :to => :alternative
|
|
17
|
+
from :alternative, :to => :active
|
|
18
|
+
|
|
19
|
+
after do
|
|
20
|
+
log << "alternated"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
attr_accessor :disable_on_click, :log
|
|
26
|
+
|
|
27
|
+
def initialize
|
|
28
|
+
self.log = []
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def setup
|
|
33
|
+
@button = Button.new
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_click_from_active
|
|
37
|
+
@button.click
|
|
38
|
+
assert_equal 'alternative', @button.state
|
|
39
|
+
assert_equal ['alternated'], @button.log
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def test_click_with_disable_on_click
|
|
43
|
+
@button.disable_on_click = true
|
|
44
|
+
@button.click
|
|
45
|
+
assert_equal 'disabled', @button.state
|
|
46
|
+
assert_equal [], @button.log
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def test_click_from_disabled
|
|
50
|
+
@button.disable_on_click = true
|
|
51
|
+
@button.click
|
|
52
|
+
@button.disable_on_click = false
|
|
53
|
+
@button.click
|
|
54
|
+
assert_equal 'disabled', @button.state
|
|
55
|
+
assert_equal [], @button.log
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
data/test/test_two_machines.rb
CHANGED
|
@@ -13,9 +13,11 @@ class TestTwoMachines < Minitest::Test
|
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
event :cycle_color
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
event :cycle_color! do
|
|
17
|
+
from :red, :to => :green
|
|
18
|
+
from :green, :to => :blue
|
|
19
|
+
from :blue, :to => :red
|
|
20
|
+
end
|
|
19
21
|
end
|
|
20
22
|
|
|
21
23
|
hifsm :working_state do
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hifsm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Vladimir Meremyanin
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2014-09-
|
|
11
|
+
date: 2014-09-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -111,6 +111,9 @@ files:
|
|
|
111
111
|
- lib/hifsm.rb
|
|
112
112
|
- lib/hifsm/adapters/active_record_adapter.rb
|
|
113
113
|
- lib/hifsm/callbacks.rb
|
|
114
|
+
- lib/hifsm/dsl/abstract_builder.rb
|
|
115
|
+
- lib/hifsm/dsl/event_builder.rb
|
|
116
|
+
- lib/hifsm/dsl/state_builder.rb
|
|
114
117
|
- lib/hifsm/event.rb
|
|
115
118
|
- lib/hifsm/fsm.rb
|
|
116
119
|
- lib/hifsm/machine.rb
|
|
@@ -124,6 +127,7 @@ files:
|
|
|
124
127
|
- test/test_basic_fsm.rb
|
|
125
128
|
- test/test_dynamic_initial_state.rb
|
|
126
129
|
- test/test_event_guard.rb
|
|
130
|
+
- test/test_groupped_transitions.rb
|
|
127
131
|
- test/test_hierarchical.rb
|
|
128
132
|
- test/test_ifless_factorial.rb
|
|
129
133
|
- test/test_many_states.rb
|
|
@@ -141,7 +145,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
141
145
|
requirements:
|
|
142
146
|
- - ">="
|
|
143
147
|
- !ruby/object:Gem::Version
|
|
144
|
-
version: '
|
|
148
|
+
version: '1.9'
|
|
145
149
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
146
150
|
requirements:
|
|
147
151
|
- - ">="
|
|
@@ -162,6 +166,7 @@ test_files:
|
|
|
162
166
|
- test/test_basic_fsm.rb
|
|
163
167
|
- test/test_dynamic_initial_state.rb
|
|
164
168
|
- test/test_event_guard.rb
|
|
169
|
+
- test/test_groupped_transitions.rb
|
|
165
170
|
- test/test_hierarchical.rb
|
|
166
171
|
- test/test_ifless_factorial.rb
|
|
167
172
|
- test/test_many_states.rb
|