yasm 0.0.1 → 0.0.2
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.
- data/README.markdown +64 -4
- data/VERSION +1 -1
- data/lib/yasm.rb +2 -0
- data/lib/yasm/context.rb +2 -5
- data/lib/yasm/context/state_container.rb +2 -0
- data/lib/yasm/exceptions.rb +3 -0
- data/lib/yasm/exceptions/final_state_exception.rb +3 -0
- data/lib/yasm/exceptions/invalid_action_exception.rb +3 -0
- data/lib/yasm/exceptions/time_limit_not_yet_reached.rb +4 -0
- data/lib/yasm/manager.rb +11 -3
- data/lib/yasm/state.rb +39 -0
- data/spec/yasm/manager_spec.rb +79 -46
- data/spec/yasm/state_container_spec.rb +37 -0
- data/spec/yasm/state_spec.rb +77 -0
- data/yasm.gemspec +6 -2
- metadata +8 -4
data/README.markdown
CHANGED
@@ -93,7 +93,7 @@ invalid actions to the context, `Yasm` will raise an exception.
|
|
93
93
|
#==> Waiting
|
94
94
|
|
95
95
|
vending_machine.do! RetrieveSelection
|
96
|
-
#==>
|
96
|
+
#==> InvalidActionException: We're sorry, but the action `RetrieveSelection`
|
97
97
|
is not possible given the current state `Waiting`.
|
98
98
|
|
99
99
|
vending_machine.do! InputMoney
|
@@ -101,7 +101,8 @@ invalid actions to the context, `Yasm` will raise an exception.
|
|
101
101
|
vending_machine.state.value
|
102
102
|
#==> Waiting
|
103
103
|
|
104
|
-
|
104
|
+
|
105
|
+
### Side Effects
|
105
106
|
|
106
107
|
How can we take our simulation farther? A real vending machine would verify that when you make a selection,
|
107
108
|
you actually have input enough money to pay for that selection. How can we model this?
|
@@ -197,7 +198,7 @@ pay for our selection).
|
|
197
198
|
#==> Waiting
|
198
199
|
|
199
200
|
|
200
|
-
|
201
|
+
### End states
|
201
202
|
|
202
203
|
Sometimes, a state is final. Like, what if, out of frustration, you threw the vending machine off the top of a 10 story building? It's probably not going
|
203
204
|
to work again after that. You can use the `final!` macro on a state to denote that this is the end.
|
@@ -219,8 +220,67 @@ to work again after that. You can use the `final!` macro on a state to denote th
|
|
219
220
|
vending_machine.do! TossOffBuilding
|
220
221
|
|
221
222
|
vending_machine.do! MakeSelection.new(SnickersBar)
|
222
|
-
#==>
|
223
|
+
#==> Yasm::FinalStateException: We're sorry, but the current state `Obliterated` is final. It does not accept any actions.
|
224
|
+
|
225
|
+
|
226
|
+
### State Timers
|
227
|
+
|
228
|
+
When a vending machine vends an item, it takes about 10 seconds for the item to work it's way off the rack and fall to the bottom. We can simulate this
|
229
|
+
by placing a `minimum` constraint on the `Vending` state.
|
230
|
+
|
231
|
+
class Vending
|
232
|
+
include Yasm::State
|
233
|
+
|
234
|
+
minimum 10.seconds
|
235
|
+
end
|
236
|
+
|
237
|
+
|
238
|
+
Now, when we go into the vending state, we won't be able to retrieve our selection until 10 seconds have passed.
|
239
|
+
|
240
|
+
vending_machine.do! MakeSelection.new(SnickersBar)
|
241
|
+
|
242
|
+
vending_machine.state.value
|
243
|
+
#==> Vending
|
244
|
+
|
245
|
+
vending_machine.do! RetrieveSelection
|
246
|
+
#==> Yasm::TimeLimitNotYetReached: We're sorry, but the time limit on the state `Vending` has not yet been reached.
|
247
|
+
|
248
|
+
sleep 10
|
249
|
+
|
250
|
+
vending_machine.do! RetrieveSelection
|
251
|
+
|
252
|
+
vending_machine.state.value
|
253
|
+
#==> Waiting
|
254
|
+
|
255
|
+
You can also create maximum time limits. For example, suppose we want our vending machine to self destruct, out of frustration, if it goes
|
256
|
+
an entire minute without any action.
|
257
|
+
|
258
|
+
class Waiting
|
259
|
+
include Yasm::State
|
260
|
+
|
261
|
+
maximum 1.minute, :action => :self_destruct
|
262
|
+
end
|
263
|
+
|
264
|
+
class SelfDestruct
|
265
|
+
include Yasm::Action
|
266
|
+
|
267
|
+
triggers :obliterated
|
223
268
|
|
269
|
+
def execute
|
270
|
+
puts "KABOOM!"
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
Now, if we create a vending machine, then wait at least a minute, next time we try to do something to it, it will execute the `SelfDestruct` action.
|
275
|
+
|
276
|
+
|
277
|
+
v = VendingMachine.new
|
278
|
+
|
279
|
+
sleep 60
|
280
|
+
|
281
|
+
v.do! InputMoney.new(10)
|
282
|
+
#==> "KABOOM!"
|
283
|
+
#==> Yasm::FinalStateException: We're sorry, but the current state `Obliterated` is final. It does not accept any actions.
|
224
284
|
|
225
285
|
|
226
286
|
## PUBLIC DOMAIN
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
data/lib/yasm.rb
CHANGED
data/lib/yasm/context.rb
CHANGED
@@ -45,11 +45,8 @@ module Yasm
|
|
45
45
|
|
46
46
|
def state_container(id)
|
47
47
|
unless state_containers[id]
|
48
|
-
state_containers[id] =
|
49
|
-
|
50
|
-
:context => self,
|
51
|
-
:state => self.class.state_configurations[id].start_state.to_class.new
|
52
|
-
)
|
48
|
+
state_containers[id] = StateContainer.new :context => self
|
49
|
+
Yasm::Manager.change_state :to => self.class.state_configurations[id].start_state, :on => state_containers[id]
|
53
50
|
end
|
54
51
|
|
55
52
|
state_containers[id]
|
data/lib/yasm/manager.rb
CHANGED
@@ -5,9 +5,17 @@ module Yasm
|
|
5
5
|
def change_state(options)
|
6
6
|
new_state = options[:to]
|
7
7
|
state_container = options[:on]
|
8
|
+
|
9
|
+
raise(
|
10
|
+
Yasm::TimeLimitNotYetReached,
|
11
|
+
"We're sorry, but the time limit on the state `#{state_container.state}` has not yet been reached."
|
12
|
+
) if state_container.state and !state_container.state.reached_minimum_time_limit?
|
13
|
+
|
8
14
|
new_state = new_state.to_class if new_state.respond_to? :to_class
|
15
|
+
new_state = new_state.new
|
16
|
+
new_state.instantiated_at = Time.now
|
9
17
|
|
10
|
-
state_container.state = new_state
|
18
|
+
state_container.state = new_state
|
11
19
|
end
|
12
20
|
|
13
21
|
def execute(options)
|
@@ -23,9 +31,9 @@ module Yasm
|
|
23
31
|
|
24
32
|
# Verify that the action is possible given the current state
|
25
33
|
if state_container.state.class.final?
|
26
|
-
raise "We're sorry, but the current state `#{state_container.state}` is final. It does not accept any actions."
|
34
|
+
raise Yasm::FinalStateException, "We're sorry, but the current state `#{state_container.state}` is final. It does not accept any actions."
|
27
35
|
elsif !state_container.state.class.is_allowed?(action.class)
|
28
|
-
raise "We're sorry, but the action `#{action.class}` is not possible given the current state `#{state_container.state}`."
|
36
|
+
raise Yasm::InvalidActionException, "We're sorry, but the action `#{action.class}` is not possible given the current state `#{state_container.state}`."
|
29
37
|
end
|
30
38
|
|
31
39
|
change_state :to => action.triggers.to_class, :on => state_container if action.triggers
|
data/lib/yasm/state.rb
CHANGED
@@ -25,10 +25,49 @@ module Yasm
|
|
25
25
|
def final?
|
26
26
|
@allowed_actions == []
|
27
27
|
end
|
28
|
+
|
29
|
+
def minimum(time)
|
30
|
+
raise(
|
31
|
+
ArgumentError,
|
32
|
+
"You must provide a Fixnum to the ##minimum method (represents number of seconds). For example: 2.minutes"
|
33
|
+
) unless time.kind_of?(Fixnum)
|
34
|
+
|
35
|
+
@state_minimum_duration = time
|
36
|
+
end
|
37
|
+
|
38
|
+
def minimum_duration
|
39
|
+
@state_minimum_duration
|
40
|
+
end
|
41
|
+
|
42
|
+
def maximum(maximum_duration, action_hash)
|
43
|
+
@maximum_duration = maximum_duration
|
44
|
+
@maximum_duration_action = action_hash[:action]
|
45
|
+
end
|
46
|
+
|
47
|
+
def maximum_duration
|
48
|
+
@maximum_duration
|
49
|
+
end
|
50
|
+
|
51
|
+
def maximum_duration_action
|
52
|
+
return @maximum_duration_action.call if @maximum_duration_action.respond_to? :call
|
53
|
+
@maximum_duration_action.to_class
|
54
|
+
end
|
28
55
|
end
|
56
|
+
|
57
|
+
attr_accessor :instantiated_at
|
29
58
|
|
30
59
|
def to_s
|
31
60
|
self.class.to_s
|
32
61
|
end
|
62
|
+
|
63
|
+
def reached_minimum_time_limit?
|
64
|
+
return true unless self.class.minimum_duration
|
65
|
+
(Time.now - instantiated_at) >= self.class.minimum_duration
|
66
|
+
end
|
67
|
+
|
68
|
+
def passed_maximum_time_limit?
|
69
|
+
return false unless self.class.maximum_duration
|
70
|
+
(Time.now - instantiated_at) >= self.class.maximum_duration
|
71
|
+
end
|
33
72
|
end
|
34
73
|
end
|
data/spec/yasm/manager_spec.rb
CHANGED
@@ -1,53 +1,82 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Yasm::Manager do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
4
|
+
before do
|
5
|
+
class VendingMachine
|
6
|
+
include Yasm::Context
|
7
|
+
|
8
|
+
start :on
|
9
|
+
end
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
class Unplug
|
12
|
+
include Yasm::Action
|
13
|
+
|
14
|
+
triggers :off
|
15
|
+
end
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
17
|
+
class PlugIn
|
18
|
+
include Yasm::Action
|
19
|
+
|
20
|
+
triggers :on
|
21
|
+
end
|
23
22
|
|
24
|
-
|
25
|
-
|
23
|
+
class Destroy
|
24
|
+
include Yasm::Action
|
26
25
|
|
27
|
-
|
28
|
-
|
26
|
+
triggers :destroyed
|
27
|
+
end
|
29
28
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
29
|
+
class On
|
30
|
+
include Yasm::State
|
31
|
+
|
32
|
+
actions :unplug, :destroy
|
33
|
+
end
|
35
34
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
35
|
+
class Off
|
36
|
+
include Yasm::State
|
37
|
+
|
38
|
+
actions :plug_in, :destroy
|
39
|
+
end
|
40
|
+
|
41
|
+
class Destroyed
|
42
|
+
include Yasm::State
|
43
|
+
|
44
|
+
final!
|
45
|
+
end
|
46
|
+
|
47
|
+
@vending_machine = VendingMachine.new
|
48
|
+
end
|
49
|
+
|
41
50
|
|
42
|
-
|
51
|
+
|
52
|
+
describe "##change_state" do
|
53
|
+
it "should convert the state to a class if we pass an object that respond to :to_class" do
|
54
|
+
Destroyed.should_receive(:to_class).and_return Destroyed
|
55
|
+
Yasm::Manager.change_state :to => Destroyed, :on => @vending_machine.state
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should set the instantiated_at property on the state to the current time" do
|
59
|
+
seconds_since_the_epoch = Time.now
|
60
|
+
Time.should_receive(:now).twice.and_return seconds_since_the_epoch
|
61
|
+
Yasm::Manager.change_state :to => On, :on => @vending_machine.state
|
62
|
+
@vending_machine.state.value.instantiated_at.should == seconds_since_the_epoch
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should raise an exception if the current state has not yet reached it's time limit" do
|
66
|
+
class TenSeconds
|
43
67
|
include Yasm::State
|
44
68
|
|
45
|
-
|
69
|
+
minimum 10.seconds
|
46
70
|
end
|
47
|
-
|
48
|
-
|
71
|
+
|
72
|
+
proc {
|
73
|
+
Yasm::Manager.change_state :to => TenSeconds, :on => @vending_machine.state
|
74
|
+
Yasm::Manager.change_state :to => On, :on => @vending_machine.state
|
75
|
+
}.should raise_exception(Yasm::TimeLimitNotYetReached, "We're sorry, but the time limit on the state `TenSeconds` has not yet been reached.")
|
49
76
|
end
|
50
|
-
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "##execute" do
|
51
80
|
it "should apply each action, sequentially, to the appropriate state_container within the context" do
|
52
81
|
@vending_machine.state.value.class.should == On
|
53
82
|
|
@@ -58,7 +87,7 @@ describe Yasm::Manager do
|
|
58
87
|
@vending_machine.state.value.class.should == On
|
59
88
|
end
|
60
89
|
|
61
|
-
it "should
|
90
|
+
it "should raise an exception if you attempt to execute an action that isn't allowed by a state" do
|
62
91
|
@vending_machine.state.value.class.should == On
|
63
92
|
|
64
93
|
proc {
|
@@ -67,8 +96,20 @@ describe Yasm::Manager do
|
|
67
96
|
:state_container => @vending_machine.state,
|
68
97
|
:actions => [PlugIn]
|
69
98
|
)
|
70
|
-
}.should raise_exception("We're sorry, but the action `PlugIn` is not possible given the current state `On`.")
|
99
|
+
}.should raise_exception(Yasm::InvalidActionException, "We're sorry, but the action `PlugIn` is not possible given the current state `On`.")
|
100
|
+
end
|
71
101
|
|
102
|
+
it "should raise an exception if you attempt to execute an action on a final state." do
|
103
|
+
proc {
|
104
|
+
Yasm::Manager.execute(
|
105
|
+
:context => @vending_machine,
|
106
|
+
:state_container => @vending_machine.state,
|
107
|
+
:actions => [Destroy, PlugIn]
|
108
|
+
)
|
109
|
+
}.should raise_exception(Yasm::FinalStateException, "We're sorry, but the current state `Destroyed` is final. It does not accept any actions.")
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should not raise an exception if the action is allowed by the state" do
|
72
113
|
proc {
|
73
114
|
Yasm::Manager.execute(
|
74
115
|
:context => @vending_machine,
|
@@ -76,14 +117,6 @@ describe Yasm::Manager do
|
|
76
117
|
:actions => [Unplug]
|
77
118
|
)
|
78
119
|
}.should_not raise_exception
|
79
|
-
|
80
|
-
proc {
|
81
|
-
Yasm::Manager.execute(
|
82
|
-
:context => @vending_machine,
|
83
|
-
:state_container => @vending_machine.state,
|
84
|
-
:actions => [Destroy, PlugIn]
|
85
|
-
)
|
86
|
-
}.should raise_exception("We're sorry, but the current state `Destroyed` is final. It does not accept any actions.")
|
87
120
|
end
|
88
121
|
end
|
89
122
|
end
|
@@ -4,11 +4,39 @@ describe Yasm::Context::StateContainer do
|
|
4
4
|
before do
|
5
5
|
class VendingMachine
|
6
6
|
include Yasm::Context
|
7
|
+
|
8
|
+
start :waiting
|
7
9
|
end
|
8
10
|
|
9
11
|
class Waiting
|
10
12
|
include Yasm::State
|
11
13
|
end
|
14
|
+
|
15
|
+
class Hit
|
16
|
+
include Yasm::Action
|
17
|
+
|
18
|
+
triggers :jammed
|
19
|
+
end
|
20
|
+
|
21
|
+
class Jammed
|
22
|
+
include Yasm::State
|
23
|
+
|
24
|
+
maximum 10.seconds, :action => :explode
|
25
|
+
end
|
26
|
+
|
27
|
+
class Exploded
|
28
|
+
include Yasm::State
|
29
|
+
|
30
|
+
actions :clean_up
|
31
|
+
end
|
32
|
+
|
33
|
+
class CleanUp
|
34
|
+
include Yasm::Action
|
35
|
+
end
|
36
|
+
|
37
|
+
class Explode
|
38
|
+
include Yasm::Action
|
39
|
+
end
|
12
40
|
|
13
41
|
class InputMoney
|
14
42
|
include Yasm::Action
|
@@ -21,5 +49,14 @@ describe Yasm::Context::StateContainer do
|
|
21
49
|
Yasm::Manager.should_receive(:execute).with(:context => v, :state_container => v.state, :actions => [InputMoney, InputMoney])
|
22
50
|
v.state.do! InputMoney, InputMoney
|
23
51
|
end
|
52
|
+
|
53
|
+
it "should add the maximum action to the front of the action list if the maximum time limit has been reached" do
|
54
|
+
v = VendingMachine.new
|
55
|
+
v.do! Hit
|
56
|
+
Yasm::Manager.should_receive(:execute).with(:context => v, :state_container => v.state, :actions => [Explode, CleanUp])
|
57
|
+
time = 10.seconds.from_now
|
58
|
+
Time.stub!(:now).and_return time
|
59
|
+
v.do! CleanUp
|
60
|
+
end
|
24
61
|
end
|
25
62
|
end
|
data/spec/yasm/state_spec.rb
CHANGED
@@ -30,4 +30,81 @@ describe Yasm::State do
|
|
30
30
|
TestState.final?.should be_true
|
31
31
|
end
|
32
32
|
end
|
33
|
+
|
34
|
+
describe "##minimum" do
|
35
|
+
it "should require an integer" do
|
36
|
+
proc { TestState.minimum "10 minutes" }.should raise_exception("You must provide a Fixnum to the ##minimum method (represents number of seconds). For example: 2.minutes")
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should set the @state_minimum_duration to the number input" do
|
40
|
+
TestState.minimum 1.minute
|
41
|
+
TestState.minimum_duration.should == 60
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#reached_minimum_time_limit?" do
|
46
|
+
before do
|
47
|
+
class MinState
|
48
|
+
include Yasm::State
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should return true if there is no minimum time limit for the state" do
|
53
|
+
MinState.new.reached_minimum_time_limit?.should be_true
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should return false if there is a time limit that hasn't been reached yet" do
|
57
|
+
MinState.minimum 10.seconds
|
58
|
+
state = MinState.new
|
59
|
+
state.instantiated_at = Time.now
|
60
|
+
state.reached_minimum_time_limit?.should be_false
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should return true if the state has reached it's time limit" do
|
64
|
+
MinState.minimum 10.seconds
|
65
|
+
state = MinState.new
|
66
|
+
state.instantiated_at = Time.now
|
67
|
+
ten_seconds_from_now = 10.seconds.from_now
|
68
|
+
Time.should_receive(:now).and_return ten_seconds_from_now
|
69
|
+
state.reached_minimum_time_limit?
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "##maximum" do
|
74
|
+
it "should require both a time limit and an action" do
|
75
|
+
proc { TestState.maximum }.should raise_exception(ArgumentError)
|
76
|
+
proc { TestState.maximum 10.seconds }.should raise_exception(ArgumentError)
|
77
|
+
proc { TestState.maximum 10.seconds, :action => :action1 }.should_not raise_exception
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should store the time limit and action" do
|
81
|
+
TestState.maximum 20.seconds, :action => :action2
|
82
|
+
TestState.maximum_duration.should == 20.seconds
|
83
|
+
TestState.maximum_duration_action.should == Action2
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "##passed_maximum_time_limit?" do
|
88
|
+
it "should return false if no time limit has been set" do
|
89
|
+
class UnlimitedState
|
90
|
+
include Yasm::State
|
91
|
+
end
|
92
|
+
|
93
|
+
UnlimitedState.new.passed_maximum_time_limit?.should be_false
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should return true if a time limit was set, and that limit has been passed" do
|
97
|
+
class LimitedState
|
98
|
+
include Yasm::State
|
99
|
+
|
100
|
+
maximum 10.seconds, :action => :action2
|
101
|
+
end
|
102
|
+
|
103
|
+
s = LimitedState.new
|
104
|
+
s.instantiated_at = Time.now
|
105
|
+
ten_seconds_from_now = 10.seconds.from_now
|
106
|
+
Time.stub!(:now).and_return ten_seconds_from_now
|
107
|
+
s.passed_maximum_time_limit?.should be_true
|
108
|
+
end
|
109
|
+
end
|
33
110
|
end
|
data/yasm.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{yasm}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Matt Parker"]
|
12
|
-
s.date = %q{2011-02-
|
12
|
+
s.date = %q{2011-02-13}
|
13
13
|
s.description = %q{Breaks up states, actions, and contexts into seperate classes.moonmaster9000@gmail.com}
|
14
14
|
s.email = %q{moonmaster9000@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -26,6 +26,10 @@ Gem::Specification.new do |s|
|
|
26
26
|
"lib/yasm/conversions.rb",
|
27
27
|
"lib/yasm/conversions/class.rb",
|
28
28
|
"lib/yasm/conversions/symbol.rb",
|
29
|
+
"lib/yasm/exceptions.rb",
|
30
|
+
"lib/yasm/exceptions/final_state_exception.rb",
|
31
|
+
"lib/yasm/exceptions/invalid_action_exception.rb",
|
32
|
+
"lib/yasm/exceptions/time_limit_not_yet_reached.rb",
|
29
33
|
"lib/yasm/manager.rb",
|
30
34
|
"lib/yasm/state.rb",
|
31
35
|
"lib/yasm/version.rb",
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yasm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Matt Parker
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-02-
|
18
|
+
date: 2011-02-13 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -68,6 +68,10 @@ files:
|
|
68
68
|
- lib/yasm/conversions.rb
|
69
69
|
- lib/yasm/conversions/class.rb
|
70
70
|
- lib/yasm/conversions/symbol.rb
|
71
|
+
- lib/yasm/exceptions.rb
|
72
|
+
- lib/yasm/exceptions/final_state_exception.rb
|
73
|
+
- lib/yasm/exceptions/invalid_action_exception.rb
|
74
|
+
- lib/yasm/exceptions/time_limit_not_yet_reached.rb
|
71
75
|
- lib/yasm/manager.rb
|
72
76
|
- lib/yasm/state.rb
|
73
77
|
- lib/yasm/version.rb
|