moody 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/README.md +17 -2
  2. data/lib/moody.rb +8 -0
  3. data/moody.gemspec +1 -1
  4. data/test/test_moody.rb +85 -43
  5. metadata +3 -3
data/README.md CHANGED
@@ -7,7 +7,7 @@ object can change its behavior at runtime, depending on its internal state.
7
7
  If you want more information about this pattern, read [the explanation by
8
8
  SourceMaking](http://sourcemaking.com/design_patterns/state).
9
9
 
10
- For a stupid example of how you would use this, here's a traffic light:
10
+ For a stupid example of how you would use this, here is a traffic light:
11
11
 
12
12
  class Stop < Moody::State
13
13
  def color
@@ -18,6 +18,14 @@ For a stupid example of how you would use this, here's a traffic light:
18
18
  sleep 3
19
19
  switch_to Go
20
20
  end
21
+
22
+ def enter
23
+ # turn on camera tu see who crosses on a red light
24
+ end
25
+
26
+ def leave
27
+ # turn off camera
28
+ end
21
29
  end
22
30
 
23
31
  class Go < Moody::State
@@ -56,11 +64,18 @@ For a stupid example of how you would use this, here's a traffic light:
56
64
  traffic_light.next
57
65
  end
58
66
 
67
+ Callbacks
68
+ ---------
69
+
70
+ As you can see from the example above, Moody also provides callbacks when
71
+ entering and leaving a state. If your state classes define instance methods
72
+ `enter` and `leave`, then they will be called at the appropriate times.
73
+
59
74
  Inspiration
60
75
  -----------
61
76
 
62
77
  This is a reimplementation of the State Pattern gem by Daniel Cadenas. Check out
63
- his implementation at [http://github.com/dcadenas/state_pattern]().
78
+ his implementation at [his repository](http://github.com/dcadenas/state_pattern).
64
79
 
65
80
  Installing
66
81
  ----------
data/lib/moody.rb CHANGED
@@ -35,7 +35,15 @@ module Moody
35
35
  end
36
36
 
37
37
  def switch_to(next_state)
38
+ context.state.leave if context.state.respond_to?(:leave)
38
39
  context.state = next_state.new(context)
40
+ context.state.enter if context.state.respond_to?(:enter)
41
+ end
42
+
43
+ def leave
44
+ end
45
+
46
+ def enter
39
47
  end
40
48
  end
41
49
  end
data/moody.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "moody"
3
- s.version = "0.1.1"
3
+ s.version = "0.2.0"
4
4
  s.date = "2010-10-23"
5
5
 
6
6
  s.description = "Simple and straightforward implementation of the state pattern, inspired by the StatePattern gem"
data/test/test_moody.rb CHANGED
@@ -1,68 +1,110 @@
1
1
  require "test/unit"
2
2
  require "moody"
3
- require "ostruct"
4
3
 
5
- class Stop < Moody::State
6
- def color
7
- "red"
8
- end
4
+ class TestMoodyByExample < Test::Unit::TestCase
5
+ class SiegeMode < Moody::State
6
+ def strength
7
+ 50
8
+ end
9
9
 
10
- def next
11
- switch_to Go
12
- end
13
- end
10
+ def siege_mode!
11
+ end
14
12
 
15
- class Go < Moody::State
16
- def color
17
- "green"
18
- end
13
+ def tank_mode!
14
+ switch_to TankMode
15
+ end
19
16
 
20
- def next
21
- switch_to Caution
17
+ def cheat!
18
+ switch_to CheatMode
19
+ end
22
20
  end
23
- end
24
21
 
25
- class Caution < Moody::State
26
- def color
27
- "yellow"
22
+ class TankMode < Moody::State
23
+ def strength
24
+ 20
25
+ end
26
+
27
+ def siege_mode!
28
+ switch_to SiegeMode
29
+ end
30
+
31
+ def tank_mode!
32
+ end
33
+
34
+ def cheat!
35
+ switch_to CheatMode
36
+ end
28
37
  end
29
38
 
30
- def next
31
- switch_to Stop
39
+ class CheatMode < Moody::State
40
+ def strength
41
+ 100
42
+ end
43
+
44
+ def siege_mode!
45
+ switch_to SiegeMode
46
+ end
47
+
48
+ def tank_mode!
49
+ switch_to TankMode
50
+ end
51
+
52
+ def cheat!
53
+ end
54
+
55
+ def enter
56
+ $callbacks << "You're a cheat!"
57
+ end
58
+
59
+ def leave
60
+ $callbacks << "Honesty is valuable!"
61
+ end
32
62
  end
33
- end
34
63
 
35
- class TrafficLight
36
- extend Moody::Context
64
+ class SiegeTank
65
+ extend Moody::Context
37
66
 
38
- initial_state Stop
39
- delegate_to_state :color, :next
40
- end
67
+ initial_state TankMode
68
+ delegate_to_state :strength, :tank_mode!, :siege_mode!, :cheat!
69
+
70
+ def attack(target)
71
+ "dealt #{strength} to #{target}"
72
+ end
73
+ end
41
74
 
42
- class TestMoodyByExample < Test::Unit::TestCase
43
75
  def setup
44
- @context = TrafficLight.new
76
+ $callbacks = []
77
+ @context_class = Class.new(SiegeTank)
45
78
  end
46
79
 
47
80
  def test_initial_state
48
- assert @context.state.is_a?(Stop)
81
+ @context_class.initial_state SiegeMode
82
+
83
+ test_context = @context_class.new
84
+ assert test_context.state.is_a?(SiegeMode)
49
85
  end
50
86
 
51
87
  def test_switch_state
52
- @context.next
53
- assert @context.state.is_a?(Go)
54
- @context.next
55
- assert @context.state.is_a?(Caution)
56
- @context.next
57
- assert @context.state.is_a?(Stop)
88
+ test_context = @context_class.new
89
+ test_context.siege_mode!
90
+ assert test_context.state.is_a?(SiegeMode)
91
+ test_context.tank_mode!
92
+ assert test_context.state.is_a?(TankMode)
93
+ end
94
+
95
+ def test_delegates_methods
96
+ test_context = @context_class.new
97
+ test_context.siege_mode!
98
+ assert_equal "dealt 50 to target", test_context.attack("target")
99
+ test_context.tank_mode!
100
+ assert_equal "dealt 20 to target", test_context.attack("target")
58
101
  end
59
102
 
60
- def test_delegate_properties
61
- @context.next
62
- assert_equal "green", @context.color
63
- @context.next
64
- assert_equal "yellow", @context.color
65
- @context.next
66
- assert_equal "red", @context.color
103
+ def test_provides_callbacks
104
+ test_context = @context_class.new
105
+ test_context.cheat!
106
+ assert_equal "You're a cheat!", $callbacks.pop
107
+ test_context.siege_mode!
108
+ assert_equal "Honesty is valuable!", $callbacks.pop
67
109
  end
68
110
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
8
- - 1
9
- version: 0.1.1
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - "Nicol\xC3\xA1s Sanguinetti"