finite_machine 0.7.0 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3ac2b8cf6f6e899a7d6b2f04c240703d45a4b67d
4
- data.tar.gz: f556b050c651d3120b5a2fe990fd1efc94abf961
3
+ metadata.gz: d0521fc82d97ac5139abe2fcea0ed72532af05fe
4
+ data.tar.gz: 260b8c31a86e2c3f80018aad2640c62222cea2af
5
5
  SHA512:
6
- metadata.gz: f5871e7adbd4a10e4a44a9bd4916f09843890490fd967d9bc8ce7b7c0a20033b72f2344d23fd7cd6bd2a3369cc5f622f343ea3ce1c2b817e8332909d754806fe
7
- data.tar.gz: a1feb862d90d7da38db41ce326ab3a9dbcc241555a4d65e216eeb4260442f5d1a942ac474551f2b41853ab7bb6b5aeb62b474e7efab2bb2571c22a0bfe0da0bf
6
+ metadata.gz: f443039daa14568b5bc2424d6346b89da989494bde20c416e6c7186d1692dd878a1a1bae3e9dcd9a6271c4bfa2bed42d7c795b24c53883a692ffc672a9ec05bc
7
+ data.tar.gz: 4cc03728f4c4694f3ebac12bb3f112622b84f877efcbea2ef0f783a0005ee93d889b9317922e09e87f2f5a0ddc189d5618baa17bf498024c8263d783f1e77e83
data/.travis.yml CHANGED
@@ -12,13 +12,13 @@ matrix:
12
12
  - rvm: jruby-20mode
13
13
  - rvm: jruby-21mode
14
14
  - rvm: jruby-head
15
- - rvm: rbx
15
+ - rvm: rbx-2
16
16
  allow_failures:
17
17
  - rvm: ruby-head
18
18
  - rvm: jruby-head
19
19
  - rvm: jruby-20mode
20
20
  - rvm: jruby-21mode
21
- - rvm: rbx
21
+ - rvm: rbx-2
22
22
  fast_finish: true
23
23
  branches:
24
24
  only: master
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ 0.7.1 (June 8, 2014)
2
+
3
+ * Change to relax callback name checks to allow for duplicate state and event names
4
+ * Change so that transition to initial state triggers callbacks
5
+
1
6
  0.7.0 (May 26, 2014)
2
7
 
3
8
  * Change Event to EventHook for callback events
data/README.md CHANGED
@@ -3,13 +3,13 @@
3
3
  [![Build Status](https://secure.travis-ci.org/peter-murach/finite_machine.png?branch=master)][travis]
4
4
  [![Code Climate](https://codeclimate.com/github/peter-murach/finite_machine.png)][codeclimate]
5
5
  [![Coverage Status](https://coveralls.io/repos/peter-murach/finite_machine/badge.png)][coverage]
6
- [![Inline docs](http://inch-pages.github.io/github/peter-murach/finite_machine.png)][inchpages]
6
+ [![Inline docs](http://inch-ci.org/github/peter-murach/finite_machine.png)][inchpages]
7
7
 
8
8
  [gem]: http://badge.fury.io/rb/finite_machine
9
9
  [travis]: http://travis-ci.org/peter-murach/finite_machine
10
10
  [codeclimate]: https://codeclimate.com/github/peter-murach/finite_machine
11
11
  [coverage]: https://coveralls.io/r/peter-murach/finite_machine
12
- [inchpages]: http://inch-pages.github.io/github/peter-murach/finite_machine
12
+ [inchpages]: http://inch-ci.org/github/peter-murach/finite_machine
13
13
 
14
14
  A minimal finite state machine with a straightforward and intuitive syntax. You can quickly model states and add callbacks that can be triggered synchronously or asynchronously. The machine is event driven with a focus on passing synchronous and asynchronous messages to trigger state transitions.
15
15
 
@@ -27,13 +27,16 @@ require "finite_machine/observer"
27
27
  require "finite_machine/listener"
28
28
 
29
29
  module FiniteMachine
30
-
30
+ # Default state name
31
31
  DEFAULT_STATE = :none
32
32
 
33
+ # Initial default event name
33
34
  DEFAULT_EVENT_NAME = :init
34
35
 
36
+ # Describe any state transition
35
37
  ANY_STATE = :any
36
38
 
39
+ # Describe any event name
37
40
  ANY_EVENT = :any
38
41
 
39
42
  # Returned when transition has successfully performed
@@ -75,6 +78,15 @@ module FiniteMachine
75
78
 
76
79
  # TODO: this should instantiate system not the state machine
77
80
  # and then delegate calls to StateMachine instance etc...
81
+ #
82
+ # @example
83
+ # FiniteMachine.define do
84
+ # ...
85
+ # end
86
+ #
87
+ # @return [FiniteMachine::StateMachine]
88
+ #
89
+ # @api public
78
90
  def define(*args, &block)
79
91
  StateMachine.new(*args, &block)
80
92
  end
@@ -68,12 +68,17 @@ module FiniteMachine
68
68
  # @api public
69
69
  def initial(value)
70
70
  state, name, self.defer = parse(value)
71
- unless defer
72
- machine.state = state
73
- machine.initial_state = state
74
- end
75
- event = proc { event name, from: FiniteMachine::DEFAULT_STATE, to: state }
76
- machine.events_dsl.call(&event)
71
+ self.initial_event = name
72
+ machine.event(name, from: FiniteMachine::DEFAULT_STATE, to: state)
73
+ end
74
+
75
+ # Trigger initial event
76
+ #
77
+ # @return [nil]
78
+ #
79
+ # @api private
80
+ def trigger_init
81
+ machine.send(:"#{initial_event}") unless defer
77
82
  end
78
83
 
79
84
  # Attach state machine to an object
@@ -3,7 +3,6 @@
3
3
  module FiniteMachine
4
4
  # Module for responsible for safety checks against known methods
5
5
  module Safety
6
-
7
6
  EVENT_CONFLICT_MESSAGE = \
8
7
  "You tried to define an event named \"%{name}\", however this would " \
9
8
  "generate \"%{type}\" method \"%{method}\", which is already defined " \
@@ -54,14 +53,12 @@ module FiniteMachine
54
53
  #
55
54
  # @api public
56
55
  def ensure_valid_callback_name!(event_type, name)
57
- message = if machine.states.include?(name) &&
58
- event_type < HookEvent::Anyaction
56
+ message = if wrong_event_name?(name, event_type)
59
57
  EVENT_CALLBACK_CONFLICT_MESSAGE % {
60
58
  type: "on_#{event_type.to_s}",
61
59
  name: name
62
60
  }
63
- elsif machine.event_names.include?(name) &&
64
- event_type < HookEvent::Anystate
61
+ elsif wrong_state_name?(name, event_type)
65
62
  STATE_CALLBACK_CONFLICT_MESSAGE % {
66
63
  type: "on_#{event_type.to_s}",
67
64
  name: name
@@ -79,6 +76,36 @@ module FiniteMachine
79
76
 
80
77
  private
81
78
 
79
+ # Check if event name exists
80
+ #
81
+ # @param [Symbol] name
82
+ #
83
+ # @param [FiniteMachine::HookEvent] event_type
84
+ #
85
+ # @return [Boolean]
86
+ #
87
+ # @api private
88
+ def wrong_event_name?(name, event_type)
89
+ machine.states.include?(name) &&
90
+ !machine.event_names.include?(name) &&
91
+ event_type < HookEvent::Anyaction
92
+ end
93
+
94
+ # Check if state name exists
95
+ #
96
+ # @param [Symbol] name
97
+ #
98
+ # @param [FiniteMachine::HookEvent] event_type
99
+ #
100
+ # @return [Boolean]
101
+ #
102
+ # @api private
103
+ def wrong_state_name?(name, event_type)
104
+ machine.event_names.include?(name) &&
105
+ !machine.states.include?(name) &&
106
+ event_type < HookEvent::Anystate
107
+ end
108
+
82
109
  def fail_invalid_callback_error(message)
83
110
  exception = InvalidCallbackNameError
84
111
  machine.catch_error(exception) || fail(exception, message)
@@ -43,7 +43,7 @@ module FiniteMachine
43
43
  # The state machine event definitions
44
44
  attr_threadsafe :events_chain
45
45
 
46
- def_delegators :@dsl, :initial, :terminal, :target
46
+ def_delegators :@dsl, :initial, :terminal, :target, :trigger_init
47
47
 
48
48
  def_delegator :@events_dsl, :event
49
49
 
@@ -63,6 +63,7 @@ module FiniteMachine
63
63
  @dsl = DSL.new(self, attributes)
64
64
 
65
65
  @dsl.call(&block) if block_given?
66
+ trigger_init
66
67
  end
67
68
 
68
69
  # @example
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module FiniteMachine
4
- VERSION = "0.7.0"
4
+ VERSION = "0.7.1"
5
5
  end
@@ -91,8 +91,9 @@ describe FiniteMachine, 'async_events' do
91
91
  expect(called).to match_array([
92
92
  'on_enter_green',
93
93
  'on_before_slow',
94
- 'on_after_go',
95
- 'on_exit_yellow'
94
+ 'on_exit_yellow',
95
+ 'on_enter_green',
96
+ 'on_after_go'
96
97
  ])
97
98
  end
98
99
  end
@@ -98,6 +98,17 @@ describe FiniteMachine, 'callbacks' do
98
98
  }
99
99
  end
100
100
 
101
+ expect(fsm.current).to eq(:green)
102
+ expect(called).to eq([
103
+ 'on_before',
104
+ 'on_exit',
105
+ 'on_transition_green',
106
+ 'on_transition',
107
+ 'on_enter_green',
108
+ 'on_enter',
109
+ 'on_after'
110
+ ])
111
+
101
112
  called = []
102
113
  fsm.slow
103
114
  expect(called).to eql([
@@ -179,6 +190,11 @@ describe FiniteMachine, 'callbacks' do
179
190
  expect(fsm.current).to eq(:previous)
180
191
  fsm.go
181
192
  expect(called).to eq([
193
+ 'before_init',
194
+ 'exit_none',
195
+ 'transition_none_previous',
196
+ 'enter_previous',
197
+ 'after_init',
182
198
  'before_go',
183
199
  'guard',
184
200
  'exit_previous',
@@ -226,6 +242,14 @@ describe FiniteMachine, 'callbacks' do
226
242
  }
227
243
  end
228
244
 
245
+ expect(fsm.current).to eql(:green)
246
+ expect(called).to eql([
247
+ 'on_before',
248
+ 'on_exit',
249
+ 'on_transition',
250
+ 'on_enter',
251
+ 'on_after'
252
+ ])
229
253
  called = []
230
254
  fsm.slow
231
255
  expect(fsm.current).to eql(:yellow)
@@ -539,14 +563,16 @@ describe FiniteMachine, 'callbacks' do
539
563
 
540
564
  once_on_transition_green do |event| called << 'once_on_transition_green' end
541
565
  once_on_transition_yellow do |event| called << 'once_on_transition_yellow' end
542
-
566
+ once_on_exit_none do |event| called << 'once_on_exit_none' end
543
567
  once_on_exit_green do |event| called << 'once_on_exit_green' end
544
568
  once_on_exit_yellow do |event| called << 'once_on_exit_yellow' end
545
569
 
546
570
  # event callbacks
571
+ once_on_before_init do |event| called << 'once_on_before_init' end
547
572
  once_on_before_slow do |event| called << 'once_on_before_slow' end
548
573
  once_on_before_go do |event| called << 'once_on_before_go' end
549
574
 
575
+ once_on_after_init do |event| called << 'once_on_after_init' end
550
576
  once_on_after_slow do |event| called << 'once_on_after_slow' end
551
577
  once_on_after_go do |event| called << 'once_on_after_go' end
552
578
  }
@@ -559,6 +585,11 @@ describe FiniteMachine, 'callbacks' do
559
585
  fsm.slow
560
586
  expect(fsm.current).to eql(:yellow)
561
587
  expect(called).to eql([
588
+ 'once_on_before_init',
589
+ 'once_on_exit_none',
590
+ 'once_on_transition_green',
591
+ 'once_on_enter_green',
592
+ 'once_on_after_init',
562
593
  'once_on_before_slow',
563
594
  'once_on_exit_green',
564
595
  'once_on_transition_yellow',
@@ -566,8 +597,6 @@ describe FiniteMachine, 'callbacks' do
566
597
  'once_on_after_slow',
567
598
  'once_on_before_go',
568
599
  'once_on_exit_yellow',
569
- 'once_on_transition_green',
570
- 'once_on_enter_green',
571
600
  'once_on_after_go'
572
601
  ])
573
602
  end
@@ -643,6 +672,10 @@ describe FiniteMachine, 'callbacks' do
643
672
  expect(fsm.current).to eq(:initial)
644
673
  fsm.bump
645
674
  expect(callbacks).to eq([
675
+ 'before_init_none_initial',
676
+ 'exit_init_none_initial',
677
+ 'enter_init_none_initial',
678
+ 'after_init_none_initial',
646
679
  'before_bump_initial_low',
647
680
  'exit_bump_initial_low',
648
681
  'enter_bump_initial_low',
@@ -650,6 +683,10 @@ describe FiniteMachine, 'callbacks' do
650
683
  ])
651
684
  fsm.bump
652
685
  expect(callbacks).to eq([
686
+ 'before_init_none_initial',
687
+ 'exit_init_none_initial',
688
+ 'enter_init_none_initial',
689
+ 'after_init_none_initial',
653
690
  'before_bump_initial_low',
654
691
  'exit_bump_initial_low',
655
692
  'enter_bump_initial_low',
@@ -661,6 +698,10 @@ describe FiniteMachine, 'callbacks' do
661
698
  ])
662
699
  fsm.bump
663
700
  expect(callbacks).to eq([
701
+ 'before_init_none_initial',
702
+ 'exit_init_none_initial',
703
+ 'enter_init_none_initial',
704
+ 'after_init_none_initial',
664
705
  'before_bump_initial_low',
665
706
  'exit_bump_initial_low',
666
707
  'enter_bump_initial_low',
@@ -699,11 +740,15 @@ describe FiniteMachine, 'callbacks' do
699
740
  expect(fsm.current).to eq(:initial)
700
741
  fsm.bump
701
742
  expect(callbacks).to eq([
743
+ 'before_init_none_initial',
744
+ 'enter_init_none_initial',
702
745
  'before_bump_initial_low',
703
746
  'enter_bump_initial_low'
704
747
  ])
705
748
  fsm.bump
706
749
  expect(callbacks).to eq([
750
+ 'before_init_none_initial',
751
+ 'enter_init_none_initial',
707
752
  'before_bump_initial_low',
708
753
  'enter_bump_initial_low',
709
754
  'before_bump_low_medium',
@@ -711,6 +756,8 @@ describe FiniteMachine, 'callbacks' do
711
756
  ])
712
757
  fsm.bump
713
758
  expect(callbacks).to eq([
759
+ 'before_init_none_initial',
760
+ 'enter_init_none_initial',
714
761
  'before_bump_initial_low',
715
762
  'enter_bump_initial_low',
716
763
  'before_bump_low_medium',
@@ -719,4 +766,33 @@ describe FiniteMachine, 'callbacks' do
719
766
  'enter_bump_medium_high'
720
767
  ])
721
768
  end
769
+
770
+ it "permits state and event with the same name" do
771
+ called = []
772
+ fsm = FiniteMachine.define do
773
+ initial :on_hook
774
+
775
+ events {
776
+ event :off_hook, :on_hook => :off_hook
777
+ event :on_hook, :off_hook => :on_hook
778
+ }
779
+
780
+ callbacks {
781
+ on_before(:on_hook) { |event| called << "on_before_#{event.name}"}
782
+ on_enter(:on_hook) { |event| called << "on_enter_#{event.to}"}
783
+ }
784
+ end
785
+ expect(fsm.current).to eq(:on_hook)
786
+ expect(called).to eq([
787
+ 'on_enter_on_hook'
788
+ ])
789
+ fsm.off_hook
790
+ expect(fsm.current).to eq(:off_hook)
791
+ fsm.on_hook
792
+ expect(called).to eq([
793
+ 'on_enter_on_hook',
794
+ 'on_before_on_hook',
795
+ 'on_enter_on_hook'
796
+ ]);
797
+ end
722
798
  end
@@ -43,7 +43,7 @@ describe FiniteMachine, 'define' do
43
43
  fsm.handle(FiniteMachine::InvalidStateError) { |exception|
44
44
  called << 'error_handler'
45
45
  }
46
-
46
+ fsm.init
47
47
  expect(fsm.current).to eql(:green)
48
48
  fsm.slow
49
49
  expect(fsm.current).to eql(:yellow)
@@ -49,11 +49,15 @@ describe FiniteMachine, 'initialize' do
49
49
  event :stop, :yellow => :red
50
50
  }
51
51
  callbacks {
52
+ on_exit :none do |event| called << 'on_exit_none' end
52
53
  on_enter :green do |event| called << 'on_enter_green' end
53
54
  }
54
55
  end
55
56
  expect(fsm.current).to eql(:green)
56
- expect(called).to be_empty
57
+ expect(called).to eq([
58
+ 'on_exit_none',
59
+ 'on_enter_green'
60
+ ])
57
61
  end
58
62
 
59
63
  it "allows to specify initial state through parameter" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: finite_machine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Murach
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-26 00:00:00.000000000 Z
11
+ date: 2014-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler