aquam 0.0.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 +7 -0
- data/README.md +1 -0
- data/aquam.gemspec +19 -0
- data/lib/aquam.rb +7 -0
- data/lib/aquam/errors.rb +14 -0
- data/lib/aquam/event_transitions.rb +13 -0
- data/lib/aquam/machine.rb +48 -0
- data/lib/aquam/machine_class_methods.rb +39 -0
- data/lib/aquam/state.rb +46 -0
- data/rakefile +8 -0
- data/test/door_state_machine.rb +43 -0
- data/test/helper.rb +8 -0
- data/test/machine_class_methods_test.rb +144 -0
- data/test/machine_test.rb +68 -0
- data/test/state_test.rb +82 -0
- metadata +63 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 756ccfa62e8a668e3f79a7a14d86a3d754a1f9fe
|
4
|
+
data.tar.gz: ddcad78f959438aecdba5ceab40e851b8dbcd95e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3c30391f82ffa5d1291a9d54ac0d76ca3dadbbbadec02e6a9ac1e369b406534ae968b2901c8650fa401d6391eec81089d7abb249d5e529d520959038dac824f6
|
7
|
+
data.tar.gz: 134d43c549081bd25537ee095fabb793843d4d859ac33ca17014a4c64e37888a30dfee6d02dca0cf03b42d0c56cdb2dc676b7fbda2e195b1eeeea93740d93be8
|
data/README.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# aquam
|
data/aquam.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'aquam'
|
3
|
+
s.version = '0.0.1'
|
4
|
+
s.date = Time.now.strftime('%Y-%m-%d')
|
5
|
+
s.summary = 'DSL to define State Machines'
|
6
|
+
s.description = 'Aquam adds a DSL and validations to define a State Machine'
|
7
|
+
s.authors = ['Emiliano Mancuso']
|
8
|
+
s.email = ['emiliano.mancuso@gmail.com']
|
9
|
+
s.homepage = 'http://github.com/emancu/aquam'
|
10
|
+
s.license = 'MIT'
|
11
|
+
|
12
|
+
s.files = Dir[
|
13
|
+
'README.md',
|
14
|
+
'rakefile',
|
15
|
+
'lib/**/*.rb',
|
16
|
+
'*.gemspec'
|
17
|
+
]
|
18
|
+
s.test_files = Dir['test/*.*']
|
19
|
+
end
|
data/lib/aquam.rb
ADDED
data/lib/aquam/errors.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
module Aquam
|
2
|
+
class InvalidStateError < StandardError; end
|
3
|
+
class InvalidEventError < StandardError; end
|
4
|
+
class InvalidTransitionError < StandardError; end
|
5
|
+
class InvalidStateMachineError < StandardError; end
|
6
|
+
|
7
|
+
class FailedTransitionError < StandardError
|
8
|
+
attr_reader :errors
|
9
|
+
|
10
|
+
def initialize(errors = {})
|
11
|
+
@errors = errors
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Aquam
|
2
|
+
class EventTransitions
|
3
|
+
def initialize(machine, event_name, &block)
|
4
|
+
@machine = machine
|
5
|
+
@event_name = event_name
|
6
|
+
instance_eval(&block)
|
7
|
+
end
|
8
|
+
|
9
|
+
def transition(from:, to:)
|
10
|
+
@machine.transition(from, to, @event_name)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require_relative 'machine_class_methods'
|
2
|
+
|
3
|
+
module Aquam
|
4
|
+
class Machine
|
5
|
+
extend Aquam::MachineClassMethods
|
6
|
+
|
7
|
+
attr_accessor :object
|
8
|
+
|
9
|
+
def initialize(object)
|
10
|
+
@object = object
|
11
|
+
end
|
12
|
+
|
13
|
+
def valid_state?
|
14
|
+
self.class.valid_state? attribute
|
15
|
+
end
|
16
|
+
|
17
|
+
def valid_event?(event)
|
18
|
+
self.class.valid_event? event
|
19
|
+
end
|
20
|
+
|
21
|
+
def valid_transition?(event)
|
22
|
+
self.class.events[event].key? attribute
|
23
|
+
end
|
24
|
+
|
25
|
+
def current_state
|
26
|
+
fail Aquam::InvalidStateError unless valid_state?
|
27
|
+
|
28
|
+
self.class.states[attribute].new object
|
29
|
+
end
|
30
|
+
|
31
|
+
def trigger(event, *args)
|
32
|
+
state = current_state
|
33
|
+
|
34
|
+
fail Aquam::InvalidEventError unless valid_event? event
|
35
|
+
fail Aquam::InvalidTransitionError unless valid_transition? event
|
36
|
+
|
37
|
+
state.send event, *args
|
38
|
+
|
39
|
+
current_state
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def attribute
|
45
|
+
object.send(self.class.attribute.to_sym).to_sym
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative 'event_transitions'
|
2
|
+
|
3
|
+
module Aquam
|
4
|
+
module MachineClassMethods
|
5
|
+
def attribute(name = nil)
|
6
|
+
name ? @attribute = name : @attribute ||= :state
|
7
|
+
end
|
8
|
+
|
9
|
+
def states
|
10
|
+
@states ||= {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def events
|
14
|
+
@event ||= Hash.new { |hash, key| hash[key] = {} }
|
15
|
+
end
|
16
|
+
|
17
|
+
def state(name, klass)
|
18
|
+
states[name] = klass
|
19
|
+
end
|
20
|
+
|
21
|
+
def event(name, &block)
|
22
|
+
Aquam::EventTransitions.new self, name, &block
|
23
|
+
end
|
24
|
+
|
25
|
+
def transition(from, to, event_name)
|
26
|
+
fail Aquam::InvalidStateError if !valid_state?(from) || !valid_state?(to)
|
27
|
+
|
28
|
+
events[event_name][from] = to
|
29
|
+
end
|
30
|
+
|
31
|
+
def valid_state?(state)
|
32
|
+
states.keys.include? state
|
33
|
+
end
|
34
|
+
|
35
|
+
def valid_event?(event)
|
36
|
+
events.keys.include? event
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/aquam/state.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
module Aquam
|
2
|
+
class State
|
3
|
+
# I have to use a class variable because it **must** be the same value
|
4
|
+
# across all the children calsses.
|
5
|
+
#
|
6
|
+
# Also I need it defined always
|
7
|
+
@@state_machine = nil
|
8
|
+
|
9
|
+
def self.state_machine(state_machine = nil)
|
10
|
+
if state_machine && !@@state_machine
|
11
|
+
validate_state_machine state_machine
|
12
|
+
|
13
|
+
@@state_machine = state_machine
|
14
|
+
define_event_methods
|
15
|
+
end
|
16
|
+
|
17
|
+
@@state_machine
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(object)
|
21
|
+
@object = object
|
22
|
+
end
|
23
|
+
|
24
|
+
def state_machine
|
25
|
+
self.class.state_machine || fail(Aquam::InvalidStateMachineError)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def self.define_event_methods
|
31
|
+
state_machine.events.keys.each do |event|
|
32
|
+
define_method event do
|
33
|
+
fail Aquam::InvalidTransitionError
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
private_class_method :define_event_methods
|
38
|
+
|
39
|
+
def self.validate_state_machine(state_machine)
|
40
|
+
unless state_machine.ancestors.include? Aquam::Machine
|
41
|
+
fail Aquam::InvalidStateMachineError
|
42
|
+
end
|
43
|
+
end
|
44
|
+
private_class_method :validate_state_machine
|
45
|
+
end
|
46
|
+
end
|
data/rakefile
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'aquam'
|
2
|
+
|
3
|
+
class DoorState < Aquam::State; end
|
4
|
+
|
5
|
+
class OpenedDoorState < DoorState
|
6
|
+
def close
|
7
|
+
@object.state = :closed
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class ClosedDoorState < DoorState
|
12
|
+
def open
|
13
|
+
@object.state = :opened
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class DoorStateMachine < Aquam::Machine
|
18
|
+
state :opened, OpenedDoorState
|
19
|
+
state :closed, ClosedDoorState
|
20
|
+
|
21
|
+
event :open do
|
22
|
+
transition from: :closed, to: :opened
|
23
|
+
end
|
24
|
+
|
25
|
+
event :close do
|
26
|
+
transition from: :opened, to: :closed
|
27
|
+
end
|
28
|
+
|
29
|
+
event :knock do
|
30
|
+
transition from: :opened, to: :opened
|
31
|
+
transition from: :closed, to: :closed
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class Door
|
36
|
+
attr_accessor :state
|
37
|
+
attr_reader :machine
|
38
|
+
|
39
|
+
def initialize
|
40
|
+
@state = :closed
|
41
|
+
@machine = DoorStateMachine.new self
|
42
|
+
end
|
43
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
require_relative 'door_state_machine'
|
3
|
+
|
4
|
+
describe Aquam::MachineClassMethods do
|
5
|
+
describe 'attribute' do
|
6
|
+
it 'uses :state as default' do
|
7
|
+
assert_equal :state, DoorStateMachine.attribute
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'defines the proper attribute to access the state name' do
|
11
|
+
class NewStateMachine < Aquam::Machine
|
12
|
+
attribute :state_name
|
13
|
+
end
|
14
|
+
|
15
|
+
assert_equal :state_name, NewStateMachine.attribute
|
16
|
+
|
17
|
+
Object.send(:remove_const, :NewStateMachine)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'states' do
|
22
|
+
it 'returns a hash with all the states as keys' do
|
23
|
+
assert_equal [:opened, :closed], DoorStateMachine.states.keys
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'returns a hash with all the states defined' do
|
27
|
+
assert_equal OpenedDoorState, DoorStateMachine.states[:opened]
|
28
|
+
assert_equal ClosedDoorState, DoorStateMachine.states[:closed]
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'checks if it is a valid state' do
|
32
|
+
assert DoorStateMachine.valid_state? :opened
|
33
|
+
deny DoorStateMachine.valid_state? :not_a_valid_state
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe 'events' do
|
38
|
+
it 'returns a hash with the events as keys' do
|
39
|
+
assert_equal [:open, :close, :knock], DoorStateMachine.events.keys
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'returns a hash with the transitions of each event' do
|
43
|
+
close = { opened: :closed }
|
44
|
+
open = { closed: :opened }
|
45
|
+
knock = { opened: :opened, closed: :closed }
|
46
|
+
|
47
|
+
assert_equal close, DoorStateMachine.events[:close]
|
48
|
+
assert_equal open, DoorStateMachine.events[:open]
|
49
|
+
assert_equal knock, DoorStateMachine.events[:knock]
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'checks if it is a valid event' do
|
53
|
+
assert DoorStateMachine.valid_event? :open
|
54
|
+
deny DoorStateMachine.valid_event? :not_a_valid_event
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe 'state' do
|
59
|
+
before do
|
60
|
+
class AState < Aquam::State; end
|
61
|
+
class StateMachine < Aquam::Machine; end
|
62
|
+
end
|
63
|
+
|
64
|
+
after do
|
65
|
+
Object.send(:remove_const, :AState)
|
66
|
+
Object.send(:remove_const, :StateMachine)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'defines a new state into the Machine' do
|
70
|
+
assert_equal [], StateMachine.states.keys
|
71
|
+
|
72
|
+
StateMachine.state :a, AState
|
73
|
+
|
74
|
+
assert_equal [:a], StateMachine.states.keys
|
75
|
+
assert_equal AState, StateMachine.states[:a]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe 'event' do
|
80
|
+
before do
|
81
|
+
class AState < Aquam::State; end
|
82
|
+
class BState < Aquam::State; end
|
83
|
+
|
84
|
+
class StateMachine < Aquam::Machine
|
85
|
+
state :a, AState
|
86
|
+
state :b, BState
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
after do
|
91
|
+
Object.send(:remove_const, :AState)
|
92
|
+
Object.send(:remove_const, :BState)
|
93
|
+
Object.send(:remove_const, :StateMachine)
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'defines an event with transitions' do
|
97
|
+
assert_equal [], StateMachine.events.keys
|
98
|
+
|
99
|
+
StateMachine.event :toggle do
|
100
|
+
transition from: :a, to: :b
|
101
|
+
transition from: :b, to: :a
|
102
|
+
end
|
103
|
+
|
104
|
+
assert_equal [:toggle], StateMachine.events.keys
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe 'transition' do
|
109
|
+
before do
|
110
|
+
class AState < Aquam::State; end
|
111
|
+
class BState < Aquam::State; end
|
112
|
+
|
113
|
+
class StateMachine < Aquam::Machine
|
114
|
+
state :a, AState
|
115
|
+
state :b, BState
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
after do
|
120
|
+
Object.send(:remove_const, :AState)
|
121
|
+
Object.send(:remove_const, :BState)
|
122
|
+
Object.send(:remove_const, :StateMachine)
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'fails defining a transition between invalid states' do
|
126
|
+
assert_raises Aquam::InvalidStateError do
|
127
|
+
StateMachine.transition :undefined, :b, :event
|
128
|
+
end
|
129
|
+
|
130
|
+
assert_raises Aquam::InvalidStateError do
|
131
|
+
StateMachine.transition :a, :undefined, :event
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'defines a new transition' do
|
136
|
+
assert_equal Hash.new, StateMachine.events[:event]
|
137
|
+
|
138
|
+
StateMachine.transition :a, :b, :event
|
139
|
+
expected_transition = { a: :b }
|
140
|
+
|
141
|
+
assert_equal expected_transition, StateMachine.events[:event]
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
require_relative 'door_state_machine'
|
3
|
+
|
4
|
+
describe Aquam::Machine do
|
5
|
+
before do
|
6
|
+
@door = Door.new
|
7
|
+
@machine = @door.machine
|
8
|
+
end
|
9
|
+
|
10
|
+
describe 'valid_*? methods' do
|
11
|
+
it 'returns a boolean if is a valid state' do
|
12
|
+
assert @machine.valid_state?
|
13
|
+
|
14
|
+
@door.state = :wrong_state
|
15
|
+
|
16
|
+
deny @machine.valid_state?
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'returns a boolean if is a valid event' do
|
20
|
+
assert @machine.valid_event? :open
|
21
|
+
deny @machine.valid_event? :lock
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'returns a boolean if is a valid transition from the current state' do
|
25
|
+
deny @machine.valid_transition? :close
|
26
|
+
assert @machine.valid_transition? :open
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'current_state' do
|
31
|
+
it 'returns an instance of the current state object' do
|
32
|
+
assert @machine.current_state.instance_of? ClosedDoorState
|
33
|
+
|
34
|
+
@door.state = :opened
|
35
|
+
|
36
|
+
assert @machine.current_state.instance_of? OpenedDoorState
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'fails if the current state was not defined into the machine' do
|
40
|
+
assert_raises Aquam::InvalidStateError do
|
41
|
+
@door.state = :must_fail
|
42
|
+
@machine.current_state
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'trigger' do
|
48
|
+
it 'fires the event and returns the new state' do
|
49
|
+
assert @machine.current_state.instance_of? ClosedDoorState
|
50
|
+
|
51
|
+
new_state = @machine.trigger(:open)
|
52
|
+
|
53
|
+
assert new_state.instance_of? OpenedDoorState
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'fails if is not a valid event' do
|
57
|
+
assert_raises Aquam::InvalidEventError do
|
58
|
+
@machine.trigger :lock
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'fails if is not a valid transition' do
|
63
|
+
assert_raises Aquam::InvalidTransitionError do
|
64
|
+
@machine.trigger :close
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/test/state_test.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
require_relative 'door_state_machine'
|
3
|
+
|
4
|
+
describe Aquam::State do
|
5
|
+
after do
|
6
|
+
DoorState.class_variable_set :@@state_machine, nil
|
7
|
+
end
|
8
|
+
|
9
|
+
describe 'state_machine class method' do
|
10
|
+
it 'fails if it is not a valid Aquam::Machine class' do
|
11
|
+
assert_raises Aquam::InvalidStateMachineError do
|
12
|
+
DoorState.state_machine String
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'defines the state machine that will be used in the entire hierarchy' do
|
17
|
+
assert_equal nil, DoorState.state_machine
|
18
|
+
|
19
|
+
DoorState.state_machine DoorStateMachine
|
20
|
+
|
21
|
+
assert_equal DoorStateMachine, DoorState.state_machine
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'defines the state machine for every sublcass' do
|
25
|
+
class OpenedDoorState < DoorState; end
|
26
|
+
|
27
|
+
DoorState.state_machine DoorStateMachine
|
28
|
+
|
29
|
+
assert_equal DoorStateMachine, OpenedDoorState.state_machine
|
30
|
+
assert_equal DoorStateMachine, OpenedDoorState.new(nil).state_machine
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'defines the state machine only once' do
|
34
|
+
class WindowStateMachine < Aquam::Machine; end
|
35
|
+
|
36
|
+
DoorState.state_machine DoorStateMachine
|
37
|
+
DoorState.state_machine WindowStateMachine
|
38
|
+
|
39
|
+
assert_equal DoorStateMachine, DoorState.state_machine
|
40
|
+
|
41
|
+
Object.send(:remove_const, :WindowStateMachine)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'defines all the events as methods' do
|
45
|
+
DoorState.state_machine DoorStateMachine
|
46
|
+
|
47
|
+
assert DoorState.instance_methods.include? :open
|
48
|
+
assert DoorState.instance_methods.include? :close
|
49
|
+
assert DoorState.instance_methods.include? :knock
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'fails by default on every event method' do
|
53
|
+
DoorState.state_machine DoorStateMachine
|
54
|
+
|
55
|
+
assert_raises Aquam::InvalidTransitionError do
|
56
|
+
DoorState.new(nil).open
|
57
|
+
end
|
58
|
+
|
59
|
+
assert_raises Aquam::InvalidTransitionError do
|
60
|
+
DoorState.new(nil).close
|
61
|
+
end
|
62
|
+
|
63
|
+
assert_raises Aquam::InvalidTransitionError do
|
64
|
+
DoorState.new(nil).knock
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe 'state_machine instance method' do
|
70
|
+
it 'returns the state machine class defined' do
|
71
|
+
DoorState.state_machine DoorStateMachine
|
72
|
+
|
73
|
+
assert_equal DoorStateMachine, DoorState.new(nil).state_machine
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'fails if the state machine was not defined' do
|
77
|
+
assert_raises Aquam::InvalidStateMachineError do
|
78
|
+
DoorState.new(nil).state_machine
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: aquam
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Emiliano Mancuso
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-01-15 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Aquam adds a DSL and validations to define a State Machine
|
14
|
+
email:
|
15
|
+
- emiliano.mancuso@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- README.md
|
21
|
+
- aquam.gemspec
|
22
|
+
- lib/aquam.rb
|
23
|
+
- lib/aquam/errors.rb
|
24
|
+
- lib/aquam/event_transitions.rb
|
25
|
+
- lib/aquam/machine.rb
|
26
|
+
- lib/aquam/machine_class_methods.rb
|
27
|
+
- lib/aquam/state.rb
|
28
|
+
- rakefile
|
29
|
+
- test/door_state_machine.rb
|
30
|
+
- test/helper.rb
|
31
|
+
- test/machine_class_methods_test.rb
|
32
|
+
- test/machine_test.rb
|
33
|
+
- test/state_test.rb
|
34
|
+
homepage: http://github.com/emancu/aquam
|
35
|
+
licenses:
|
36
|
+
- MIT
|
37
|
+
metadata: {}
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options: []
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
requirements: []
|
53
|
+
rubyforge_project:
|
54
|
+
rubygems_version: 2.4.5
|
55
|
+
signing_key:
|
56
|
+
specification_version: 4
|
57
|
+
summary: DSL to define State Machines
|
58
|
+
test_files:
|
59
|
+
- test/door_state_machine.rb
|
60
|
+
- test/helper.rb
|
61
|
+
- test/machine_class_methods_test.rb
|
62
|
+
- test/machine_test.rb
|
63
|
+
- test/state_test.rb
|