very_tiny_state_machine 2.1.0 → 2.2.0

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
- SHA1:
3
- metadata.gz: 94a25d93f5afee99439408cf0a390a8538508077
4
- data.tar.gz: 4c1724c530df3c19cd534635ac5ec8a729045387
2
+ SHA256:
3
+ metadata.gz: 47c8e65c48168e9aba7851fb1b26946a3e518c607f3df930bed9e0128d0b6c7e
4
+ data.tar.gz: 7d42d1daf4ac34a2c699df150b9a845321d3e853cf9e998183f75e3551077e2e
5
5
  SHA512:
6
- metadata.gz: 55fd29f305d0c1fb00493718eb99b4e452754827701ffbeebfffdeef9c9f761bbb55f68a8462d603c0fd2ad4cabc20586d1f2c15c857b78adbf26762575149d7
7
- data.tar.gz: 7aebb517f575428b6ac920db643dd16742a707723ba860aa242fdc55a748fca895f04aecbbfae49bccaf96e41b39b0437dfe90e31d79fe01f9ce62187bdee273
6
+ metadata.gz: e9370fa9aa20c27e9469b84e9960a5f2a9f6c35973dbc8dd51b38020fee1a0c8fd729b6fa3b8c70b4b066304451849c92ed9cb9e795bc8dea653b1950fcd775b
7
+ data.tar.gz: bd669ece20c891094f82eed1fcf511897809ed0b7dc94de36108482f15e08e042e1374e99e29d81d32e3489163ac83e61cb86ecf4f20693b3ddbbac631cd3a9d
@@ -0,0 +1,50 @@
1
+ # rcov generated
2
+ coverage
3
+ coverage.data
4
+
5
+ # rdoc generated
6
+ rdoc
7
+
8
+ # yard generated
9
+ doc
10
+ .yardoc
11
+
12
+ # bundler
13
+ .bundle
14
+ Gemfile.lock
15
+
16
+ # jeweler generated
17
+ pkg
18
+
19
+ # Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
20
+ #
21
+ # * Create a file at ~/.gitignore
22
+ # * Include files you want ignored
23
+ # * Run: git config --global core.excludesfile ~/.gitignore
24
+ #
25
+ # After doing this, these files will be ignored in all your git projects,
26
+ # saving you from having to 'pollute' every project you touch with them
27
+ #
28
+ # Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
29
+ #
30
+ # For MacOS:
31
+ #
32
+ #.DS_Store
33
+
34
+ # For TextMate
35
+ #*.tmproj
36
+ #tmtags
37
+
38
+ # For emacs:
39
+ #*~
40
+ #\#*
41
+ #.\#*
42
+
43
+ # For vim:
44
+ #*.swp
45
+
46
+ # For redcar:
47
+ #.redcar
48
+
49
+ # For rubinius:
50
+ #*.rbc
@@ -0,0 +1,10 @@
1
+ inherit_gem:
2
+ wetransfer_style: ruby/default.yml
3
+ AllCops:
4
+ TargetRubyVersion: 2.1
5
+ Style/GuardClause:
6
+ Enabled: false
7
+ Style/GuardClause:
8
+ Enabled: false
9
+ Metrics/LineLength:
10
+ Enabled: false
@@ -1,6 +1,5 @@
1
1
  rvm:
2
- - 2.0.0
3
- - 2.1.5
4
- - 2.2.0
2
+ - 2.1.0
3
+ - 2.6.5
5
4
  cache: bundler
6
- sudo: false
5
+ sudo: false
data/Gemfile CHANGED
@@ -1,9 +1,5 @@
1
- source "http://rubygems.org"
1
+ # frozen_string_literal: true
2
2
 
3
- group :development do
4
- gem "rspec", "~> 3.2.0"
5
- gem "rdoc", "~> 3.12"
6
- gem "bundler", "~> 1.0"
7
- gem "jeweler", "~> 2.0.1"
8
- gem 'simplecov', '~> 0.10'
9
- end
3
+ source 'http://rubygems.org'
4
+
5
+ gemspec
data/README.md CHANGED
@@ -9,9 +9,9 @@ The state machine has the ability to dispatch callbacks when states are switched
9
9
  are dispatched to the given object as messages.
10
10
 
11
11
  @automaton = VeryTinyStateMachine.new(:initialized, self)
12
- @automaton.permit_state :processing, :closing, :closed
13
- @automaton.permit_transition :initialized => :processing, :processing => :closing
14
- @automaton.permit_transition :closing => :closed
12
+ @automaton.permit_states_and_transitions(:initialized => :processing, :processing => :closing, :closing => [:closed])
13
+ @automaton.permit_state :failed
14
+ @automaton.permit_transition :closing => :failed
15
15
 
16
16
  # Then, lower down the code
17
17
  @automaton.transition! :processing
data/Rakefile CHANGED
@@ -1,51 +1,18 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require 'rubygems'
4
- require 'bundler'
5
- begin
6
- Bundler.setup(:default, :development)
7
- rescue Bundler::BundlerError => e
8
- $stderr.puts e.message
9
- $stderr.puts "Run `bundle install` to install missing gems"
10
- exit e.status_code
11
- end
12
- require 'rake'
13
- require_relative 'lib/very_tiny_state_machine'
14
- require 'jeweler'
15
- Jeweler::Tasks.new do |gem|
16
- # gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
17
- gem.version = VeryTinyStateMachine::VERSION
18
- gem.name = "very_tiny_state_machine"
19
- gem.homepage = "http://github.com/WeTransfer/very_tiny_state_machine"
20
- gem.license = "MIT"
21
- gem.description = %Q{You wouldn't beleive how tiny it is}
22
- gem.summary = %Q{A minuscule state machine for storing state of interesting objects}
23
- gem.email = "me@julik.nl"
24
- gem.authors = ["Julik Tarkhanov"]
25
- # dependencies defined in Gemfile
26
- end
27
- Jeweler::RubygemsDotOrgTasks.new
28
-
29
- require 'rspec/core'
3
+ require 'bundler/gem_tasks'
30
4
  require 'rspec/core/rake_task'
31
- RSpec::Core::RakeTask.new(:spec) do |spec|
32
- spec.pattern = FileList['spec/**/*_spec.rb']
33
- end
5
+ require 'yard'
6
+ require 'rubocop/rake_task'
34
7
 
35
- desc "Code coverage detail"
36
- task :simplecov do
37
- ENV['COVERAGE'] = "true"
38
- Rake::Task['spec'].execute
8
+ YARD::Rake::YardocTask.new(:doc) do |t|
9
+ # The dash has to be between the two to "divide" the source files and
10
+ # miscellaneous documentation files that contain no code
11
+ t.files = ['lib/**/*.rb', '-', 'LICENSE.txt']
39
12
  end
40
13
 
41
- task :default => :spec
14
+ RSpec::Core::RakeTask.new(:spec)
42
15
 
43
- require 'rdoc/task'
44
- Rake::RDocTask.new do |rdoc|
45
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
16
+ RuboCop::RakeTask.new(:rubocop)
46
17
 
47
- rdoc.rdoc_dir = 'rdoc'
48
- rdoc.title = "very_tiny_state_machine #{version}"
49
- rdoc.rdoc_files.include('README*')
50
- rdoc.rdoc_files.include('lib/**/*.rb')
51
- end
18
+ task default: %i[spec rubocop]
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'set'
2
4
 
3
5
  # A mini state machine object that can be used to track a state flow.
@@ -11,13 +13,13 @@ require 'set'
11
13
  # @automaton.permit_state :processing, :closing, :closed
12
14
  # @automaton.permit_transition :initialized => :processing, :processing => :closing
13
15
  # @automaton.permit_transition :closing => :closed
14
- #
16
+ #
15
17
  # # Then, lower down the code
16
18
  # @automaton.transition! :processing
17
- #
19
+ #
18
20
  # # This switches the internal state of the machine, and dispatches the following method
19
21
  # # calls on the object given as the second argument to the constructor, in the following order:
20
- #
22
+ #
21
23
  # # self.leaving_initialized_state
22
24
  # # self.entering_processing_state
23
25
  # # self.transitioning_from_initialized_to_processing_state
@@ -28,15 +30,15 @@ require 'set'
28
30
  #
29
31
  # @automaton.transition :initialized # Will raise TinyStateMachine::InvalidFlow
30
32
  # @automaton.transition :something_odd # Will raise TinyStateMachine::UnknownState
31
- #
33
+ #
32
34
  # @automaton.in_state?(:processing) #=> true
33
35
  # @automaton.in_state?(:initialized) #=> false
34
36
  class VeryTinyStateMachine
35
- VERSION = '2.1.0'
36
-
37
+ VERSION = '2.2.0'
38
+ INCLUDE_PRIVATES = true
37
39
  InvalidFlow = Class.new(StandardError) # Gets raised when an impossible transition gets requested
38
40
  UnknownState = Class.new(StandardError) # Gets raised when an unknown state gets requested
39
-
41
+
40
42
  # Initialize a new TinyStateMachine, with the initial state and the object that will receive callbacks.
41
43
  #
42
44
  # @param initial_state[#to_sym] the initial state of the state machine
@@ -48,7 +50,7 @@ class VeryTinyStateMachine
48
50
  @permitted_transitions = Set.new
49
51
  @callbacks_via = object_handling_callbacks
50
52
  end
51
-
53
+
52
54
  # Permit a single state or multiple states
53
55
  #
54
56
  # @param states [Array] states to permit
@@ -59,7 +61,25 @@ class VeryTinyStateMachine
59
61
  @permitted_states += states_to_permit
60
62
  will_be_added
61
63
  end
62
-
64
+
65
+ # Permit states and transitions between them, all in one call
66
+ #
67
+ # @param **states_to_states [Hash] a mapping from one state the machine may go into and one or multiple states that can be reached from that state
68
+ # @return self
69
+ def permit_states_and_transitions(**initial_states_to_destination_states)
70
+ initial_states_to_destination_states.each_pair do |one_or_more_source_states, one_or_more_destination_states|
71
+ sources = Array(one_or_more_source_states)
72
+ destinations = Array(one_or_more_destination_states)
73
+ sources.each do |src|
74
+ destinations.each do |dest|
75
+ permit_state(src, dest)
76
+ permit_transition(src => dest)
77
+ end
78
+ end
79
+ end
80
+ self
81
+ end
82
+
63
83
  # Permit a transition from one state to another. If you need to add multiple transitions
64
84
  # from the same state, just call the method multiple times:
65
85
  #
@@ -70,16 +90,17 @@ class VeryTinyStateMachine
70
90
  # @return [Array] the list of states added to permitted states
71
91
  def permit_transition(from_to_hash)
72
92
  transitions_to_permit = Set.new
73
- from_to_hash.each_pair do | from_state, to_state |
93
+ from_to_hash.each_pair do |from_state, to_state|
74
94
  raise UnknownState, from_state unless @permitted_states.include?(from_state.to_sym)
75
95
  raise UnknownState, to_state unless @permitted_states.include?(to_state.to_sym)
76
- transitions_to_permit << {from_state.to_sym => to_state.to_sym}
96
+
97
+ transitions_to_permit << { from_state.to_sym => to_state.to_sym }
77
98
  end
78
99
  additions = transitions_to_permit - @permitted_transitions
79
100
  @permitted_transitions += transitions_to_permit
80
101
  additions
81
102
  end
82
-
103
+
83
104
  # Tells whether the state is known to this state machine
84
105
  #
85
106
  # @param state[Symbol,String] the state to check for
@@ -87,17 +108,17 @@ class VeryTinyStateMachine
87
108
  def known?(state)
88
109
  @permitted_states.include?(state.to_sym)
89
110
  end
90
-
111
+
91
112
  # Tells whether a transition is permitted to the given state.
92
113
  #
93
114
  # @param to_state[Symbol,String] state to transition to
94
115
  # @return [Boolean] whether the state can be transitioned to
95
116
  def may_transition_to?(to_state)
96
117
  to_state = to_state.to_sym
97
- transition = {@state => to_state.to_sym}
118
+ transition = { @state => to_state.to_sym }
98
119
  @permitted_states.include?(to_state) && @permitted_transitions.include?(transition)
99
120
  end
100
-
121
+
101
122
  # Tells whether the state machine is in a given state at the moment
102
123
  #
103
124
  # @param requisite_state [Symbol,String] name of the state to check for
@@ -105,7 +126,7 @@ class VeryTinyStateMachine
105
126
  def in_state?(requisite_state)
106
127
  @state == requisite_state.to_sym
107
128
  end
108
-
129
+
109
130
  # Ensure the machine is in a given state, and if it isn't raise an InvalidFlow
110
131
  #
111
132
  # @param requisite_state[#to_sym] the state to verify
@@ -115,6 +136,7 @@ class VeryTinyStateMachine
115
136
  unless requisite_state.to_sym == @state
116
137
  raise InvalidFlow, "Must be in #{requisite_state.inspect} state, but was in #{@state.inspect}"
117
138
  end
139
+
118
140
  true
119
141
  end
120
142
 
@@ -123,7 +145,7 @@ class VeryTinyStateMachine
123
145
  # be raised if you did not permit this transition explicitly. If you want to transition to a state OR
124
146
  # stay in it if it is already active use {TinyStateMachine#transition_or_maintain!}
125
147
  #
126
- #
148
+ #
127
149
  # During transitions the before callbacks will be called on the @callbacks_via instance variable. If you are
128
150
  # transitioning from "initialized" to "processing" for instance, the following callbacks will be dispatched:
129
151
  #
@@ -142,23 +164,24 @@ class VeryTinyStateMachine
142
164
  # @raise InvalidFlow
143
165
  def transition!(new_state)
144
166
  new_state = new_state.to_sym
145
-
167
+
146
168
  raise UnknownState, new_state.inspect unless known?(new_state)
169
+
147
170
  if may_transition_to?(new_state)
148
171
  dispatch_callbacks_before_transition(new_state) if @callbacks_via
149
-
172
+
150
173
  previous = @state
151
174
  @state = new_state.to_sym
152
175
  @flow << new_state.to_sym
153
-
176
+
154
177
  dispatch_callbacks_after_transition(previous) if @callbacks_via
155
178
  previous
156
179
  else
157
- raise InvalidFlow,
158
- "Cannot change states from #{@state} to #{new_state} (flow so far: #{@flow.join(' > ')})"
180
+ raise InvalidFlow,
181
+ "Cannot change states from #{@state} to #{new_state} (flow so far: #{@flow.join(' > ')})"
159
182
  end
160
183
  end
161
-
184
+
162
185
  # Transition to a given state. If the machine already is in that state, do nothing.
163
186
  # If the transition has to happen (the requested state is different than the current)
164
187
  # transition! will be called instead.
@@ -169,54 +192,55 @@ class VeryTinyStateMachine
169
192
  # @return [void]
170
193
  def transition_or_maintain!(new_state)
171
194
  return if in_state?(new_state)
195
+
172
196
  transition! new_state
173
197
  end
174
-
198
+
175
199
  # Returns the flow of the transitions the machine went through so far
176
200
  #
177
201
  # @return [Array] the array of states
178
202
  def flow_so_far
179
203
  @flow.dup
180
204
  end
181
-
205
+
182
206
  private
183
-
207
+
184
208
  def dispatch_callbacks_after_transition(from)
185
209
  to = @state
186
- if @callbacks_via.respond_to?("after_transitioning_from_#{from}_to_#{to}_state", also_protected_and_private=true)
210
+ if @callbacks_via.respond_to?("after_transitioning_from_#{from}_to_#{to}_state", INCLUDE_PRIVATES)
187
211
  @callbacks_via.send("after_transitioning_from_#{from}_to_#{to}_state")
188
212
  end
189
-
190
- if @callbacks_via.respond_to?("after_leaving_#{from}_state", also_protected_and_private=true)
213
+
214
+ if @callbacks_via.respond_to?("after_leaving_#{from}_state", INCLUDE_PRIVATES)
191
215
  @callbacks_via.send("after_leaving_#{from}_state")
192
216
  end
193
-
194
- if @callbacks_via.respond_to?("after_entering_#{to}_state", also_protected_and_private=true)
217
+
218
+ if @callbacks_via.respond_to?("after_entering_#{to}_state", INCLUDE_PRIVATES)
195
219
  @callbacks_via.send("after_entering_#{to}_state")
196
220
  end
197
-
198
- if @callbacks_via.respond_to?(:after_every_transition, also_protected_and_private=true)
221
+
222
+ if @callbacks_via.respond_to?(:after_every_transition, INCLUDE_PRIVATES)
199
223
  @callbacks_via.send(:after_every_transition, from, to)
200
224
  end
201
225
  end
202
-
226
+
203
227
  def dispatch_callbacks_before_transition(to)
204
228
  from = @state
205
-
206
- if @callbacks_via.respond_to?(:before_every_transition, also_protected_and_private=true)
229
+
230
+ if @callbacks_via.respond_to?(:before_every_transition, INCLUDE_PRIVATES)
207
231
  @callbacks_via.send(:before_every_transition, from, to)
208
232
  end
209
-
210
- if @callbacks_via.respond_to?("leaving_#{from}_state", also_protected_and_private=true)
233
+
234
+ if @callbacks_via.respond_to?("leaving_#{from}_state", INCLUDE_PRIVATES)
211
235
  @callbacks_via.send("leaving_#{from}_state")
212
236
  end
213
-
214
- if @callbacks_via.respond_to?("entering_#{to}_state", also_protected_and_private=true)
237
+
238
+ if @callbacks_via.respond_to?("entering_#{to}_state", INCLUDE_PRIVATES)
215
239
  @callbacks_via.send("entering_#{to}_state")
216
240
  end
217
-
218
- if @callbacks_via.respond_to?("transitioning_from_#{from}_to_#{to}", also_protected_and_private=true)
241
+
242
+ if @callbacks_via.respond_to?("transitioning_from_#{from}_to_#{to}", INCLUDE_PRIVATES)
219
243
  @callbacks_via.send("transitioning_from_#{from}_to_#{to}")
220
244
  end
221
245
  end
222
- end
246
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
4
  $LOAD_PATH.unshift(File.dirname(__FILE__))
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
4
 
3
5
  describe VeryTinyStateMachine do
@@ -7,126 +9,151 @@ describe VeryTinyStateMachine do
7
9
  expect(machine).to be_known(:started)
8
10
  expect(machine).to be_in_state(:started)
9
11
  end
10
-
12
+
11
13
  it 'accepts a second argument' do
12
14
  acceptor = double('Callbacks')
13
- machine = described_class.new(:started, acceptor)
15
+ described_class.new(:started, acceptor)
14
16
  end
15
17
  end
16
-
18
+
17
19
  describe '#permit_state' do
18
20
  it 'makes the state known to the state machine' do
19
21
  machine = described_class.new(:started)
20
-
22
+
21
23
  first_result_of_permission = machine.permit_state :closed
22
24
  second_result_of_permission = machine.permit_state :closed, :open
23
-
25
+
24
26
  expect(first_result_of_permission).to eq(Set.new([:closed]))
25
27
  expect(second_result_of_permission).to eq(Set.new([:open]))
26
-
28
+
27
29
  expect(machine).to be_known(:started)
28
30
  expect(machine).to be_known(:closed)
29
31
  expect(machine).to be_known(:open)
30
32
  end
31
-
33
+
32
34
  it 'does not permit transitions to the newly added state by default' do
33
35
  machine = described_class.new(:started)
34
36
  machine.permit_state :running
35
-
37
+
36
38
  expect(machine).not_to be_may_transition_to(:running)
37
-
38
- expect {
39
+
40
+ expect do
39
41
  machine.transition! :running
40
- }.to raise_error(described_class::InvalidFlow, /Cannot change states from started to running/)
42
+ end.to raise_error(described_class::InvalidFlow, /Cannot change states from started to running/)
41
43
  end
42
44
  end
43
-
45
+
44
46
  describe '#permit_transition' do
45
47
  it 'raises on an unknown state specified as source' do
46
48
  machine = described_class.new(:started)
47
- expect {
48
- machine.permit_transition :unknown => :started
49
- }.to raise_error(VeryTinyStateMachine::UnknownState)
49
+ expect do
50
+ machine.permit_transition unknown: :started
51
+ end.to raise_error(VeryTinyStateMachine::UnknownState)
50
52
  end
51
-
53
+
52
54
  it 'raises on an unknwon state specified as destination' do
53
55
  machine = described_class.new(:started)
54
- expect {
55
- machine.permit_transition :started => :unknown
56
- }.to raise_error(VeryTinyStateMachine::UnknownState)
56
+ expect do
57
+ machine.permit_transition started: :unknown
58
+ end.to raise_error(VeryTinyStateMachine::UnknownState)
57
59
  end
58
-
60
+
59
61
  it 'returns a Set of transitions permitted after the call' do
60
62
  machine = described_class.new(:started)
61
63
  machine.permit_state :running
62
-
63
- result = machine.permit_transition :started => :running
64
-
64
+
65
+ result = machine.permit_transition started: :running
66
+
65
67
  expect(result).to be_kind_of(Set)
66
- expect(result).to eq(Set.new([{:started => :running}]))
67
-
68
- adding_second_time = machine.permit_transition :started => :running
68
+ expect(result).to eq(Set.new([{ started: :running }]))
69
+
70
+ adding_second_time = machine.permit_transition started: :running
69
71
  expect(adding_second_time).to be_kind_of(Set)
70
72
  expect(adding_second_time).to be_empty
71
73
  end
72
-
74
+
73
75
  it 'is able to perform the transition after it has been defined' do
74
76
  machine = described_class.new(:started)
75
77
  machine.permit_state :running
76
- machine.permit_transition :started => :running
78
+ machine.permit_transition started: :running
77
79
  machine.transition! :running
78
80
  end
79
-
81
+
80
82
  it 'allows the transition from a state to itself only explicitly' do
81
83
  machine = described_class.new(:started)
82
- expect {
84
+ expect do
83
85
  machine.transition! :started
84
- }.to raise_error(described_class::InvalidFlow)
85
-
86
- machine.permit_transition :started => :started
86
+ end.to raise_error(described_class::InvalidFlow)
87
+
88
+ machine.permit_transition started: :started
87
89
  machine.transition! :started
88
- expect(machine.flow_so_far).to eq([:started, :started])
90
+ expect(machine.flow_so_far).to eq(%i[started started])
89
91
  end
90
92
  end
91
-
93
+
94
+ describe '#permit_states_and_transitions' do
95
+ it 'accepts any states and sets up transitions' do
96
+ machine = described_class.new(:started)
97
+
98
+ same_machine = machine.permit_states_and_transitions(started: [:running, :overheat], running: [:stopped])
99
+
100
+ expect(same_machine).to eq(machine)
101
+ expect(machine.may_transition_to?(:running)).to eq(true)
102
+ expect(machine.may_transition_to?(:stopped)).to eq(false)
103
+
104
+ machine.transition! :running
105
+ expect(machine.may_transition_to?(:stopped)).to eq(true)
106
+ expect(machine.may_transition_to?(:overheat)).to eq(false)
107
+ end
108
+
109
+ it 'accepts same transitions and states multiple times' do
110
+ machine = described_class.new(:started)
111
+
112
+ machine.permit_states_and_transitions(started: [:running, :overheat], running: [:stopped])
113
+ machine.permit_states_and_transitions(started: [:running, :overheat], running: [:stopped])
114
+
115
+ expect(machine.may_transition_to?(:running)).to eq(true)
116
+ end
117
+ end
118
+
92
119
  describe '#flow_so_far' do
93
120
  it 'records the flow' do
94
121
  machine = described_class.new(:started)
95
122
  machine.permit_state :running, :stopped
96
- machine.permit_transition :started => :running, :running => :stopped, :stopped => :started
97
-
123
+ machine.permit_transition started: :running, running: :stopped, stopped: :started
124
+
98
125
  machine.transition! :running
99
126
  machine.transition! :stopped
100
127
  machine.transition! :started
101
-
128
+
102
129
  flow = machine.flow_so_far
103
- expect(flow).to eq([:started, :running, :stopped, :started])
104
-
130
+ expect(flow).to eq(%i[started running stopped started])
131
+
105
132
  flow << nil
106
- expect(flow).not_to eq(machine.flow_so_far), "The flow returned should not link to the mutable array in the machine"
133
+ expect(flow).not_to eq(machine.flow_so_far), 'The flow returned should not link to the mutable array in the machine'
107
134
  end
108
135
  end
109
-
136
+
110
137
  describe '#transition!' do
111
138
  it 'returns the previous state the object was in' do
112
139
  machine = described_class.new(:started)
113
140
  machine.permit_state :running
114
- machine.permit_transition :started => :running
141
+ machine.permit_transition started: :running
115
142
  transitioned_from = machine.transition! :running
116
143
  expect(transitioned_from).to eq(:started)
117
144
  end
118
-
145
+
119
146
  it 'sends all of the callbacks if the object responds to them' do
120
147
  fake_acceptor = double('Callback handler')
121
- allow(fake_acceptor).to receive(:respond_to?) {|method_name, honor_private_and_public|
148
+ allow(fake_acceptor).to receive(:respond_to?) { |_method_name, honor_private_and_public|
122
149
  expect(honor_private_and_public).to eq(true)
123
150
  true
124
151
  }
125
-
152
+
126
153
  machine = described_class.new(:started, fake_acceptor)
127
154
  machine.permit_state :running, :stopped
128
- machine.permit_transition :started => :running, :running => :stopped, :stopped => :started
129
-
155
+ machine.permit_transition started: :running, running: :stopped, stopped: :started
156
+
130
157
  expect(fake_acceptor).to receive(:before_every_transition).with(:started, :running)
131
158
  expect(fake_acceptor).to receive(:leaving_started_state)
132
159
  expect(fake_acceptor).to receive(:entering_running_state)
@@ -138,70 +165,71 @@ describe VeryTinyStateMachine do
138
165
 
139
166
  machine.transition! :running
140
167
  end
141
-
168
+
142
169
  it 'dispatches callbacks to private methods as well' do
143
170
  acceptor = Class.new do
144
171
  def called?
145
172
  @entered_state
146
173
  end
147
-
148
- private
174
+
175
+ private
176
+
149
177
  def entering_running_state
150
178
  @entered_state = true
151
179
  end
152
180
  end.new
153
-
181
+
154
182
  machine = described_class.new(:started, acceptor)
155
183
  machine.permit_state :running, :stopped
156
- machine.permit_transition :started => :running, :running => :stopped, :stopped => :started
157
-
184
+ machine.permit_transition started: :running, running: :stopped, stopped: :started
185
+
158
186
  machine.transition! :running
159
187
  expect(acceptor).to be_called
160
188
  end
161
-
189
+
162
190
  it 'does not send the messages to an acceptor that does not respond to those messages' do
163
191
  fake_acceptor = double('Callback handler')
164
- allow(fake_acceptor).to receive(:respond_to?) {|method_name, honor_private_and_public|
192
+ allow(fake_acceptor).to receive(:respond_to?) { |_method_name, honor_private_and_public|
165
193
  expect(honor_private_and_public).to eq(true)
166
194
  false
167
195
  }
168
-
196
+
169
197
  machine = described_class.new(:started, fake_acceptor)
170
198
  machine.permit_state :running, :stopped
171
- machine.permit_transition :started => :running, :running => :stopped, :stopped => :started
172
-
199
+ machine.permit_transition started: :running, running: :stopped, stopped: :started
200
+
173
201
  machine.transition! :running
174
202
  end
175
203
  end
176
-
204
+
177
205
  describe '#transition_or_maintain!' do
178
206
  it 'does not perform any transitions if the object is already in the requisite state' do
179
207
  machine = described_class.new(:perfect)
180
208
  machine.transition_or_maintain! :perfect
181
209
  expect(machine.flow_so_far).to eq([:perfect])
182
210
  end
183
-
211
+
184
212
  it 'does perform a transition if the object is not in the requisite state' do
185
213
  machine = described_class.new(:perfect)
186
214
  machine.permit_state :perfect, :improving
187
- machine.permit_transition :perfect => :improving, :improving => :perfect
188
-
215
+ machine.permit_transition perfect: :improving, improving: :perfect
216
+
189
217
  machine.transition_or_maintain! :improving
190
- expect(machine.flow_so_far).to eq([:perfect, :improving])
218
+ expect(machine.flow_so_far).to eq(%i[perfect improving])
191
219
  end
192
220
  end
193
-
221
+
194
222
  describe '#expect!' do
195
223
  it 'returns true when the machine is in the requisite state' do
196
224
  machine = described_class.new(:started)
197
225
  expect(machine.expect!(:started)).to eq(true)
198
226
  end
199
-
227
+
200
228
  it 'raises an exception if the machine is not in that state' do
201
229
  machine = described_class.new(:started)
202
- expect {
230
+ expect do
203
231
  machine.expect!(:running)
204
- }.to raise_error(VeryTinyStateMachine::InvalidFlow, 'Must be in :running state, but was in :started')
232
+ end.to raise_error(VeryTinyStateMachine::InvalidFlow, 'Must be in :running state, but was in :started')
205
233
  end
206
234
  end
207
235
  end
@@ -1,63 +1,34 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
- # -*- encoding: utf-8 -*-
5
- # stub: very_tiny_state_machine 2.1.0 ruby lib
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'very_tiny_state_machine'
6
6
 
7
7
  Gem::Specification.new do |s|
8
- s.name = "very_tiny_state_machine"
9
- s.version = "2.1.0"
8
+ s.name = 'very_tiny_state_machine'
9
+ s.version = VeryTinyStateMachine::VERSION
10
10
 
11
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
- s.require_paths = ["lib"]
13
- s.authors = ["Julik Tarkhanov"]
14
- s.date = "2016-11-01"
11
+ s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ['lib']
13
+ s.authors = ['Julik Tarkhanov']
15
14
  s.description = "You wouldn't beleive how tiny it is"
16
- s.email = "me@julik.nl"
15
+ s.email = 'me@julik.nl'
17
16
  s.extra_rdoc_files = [
18
- "LICENSE.txt",
19
- "README.md"
20
- ]
21
- s.files = [
22
- ".document",
23
- ".rspec",
24
- ".travis.yml",
25
- "Gemfile",
26
- "LICENSE.txt",
27
- "README.md",
28
- "Rakefile",
29
- "lib/very_tiny_state_machine.rb",
30
- "spec/spec_helper.rb",
31
- "spec/very_tiny_state_machine_spec.rb",
32
- "very_tiny_state_machine.gemspec"
17
+ 'LICENSE.txt',
18
+ 'README.md'
33
19
  ]
34
- s.homepage = "http://github.com/WeTransfer/very_tiny_state_machine"
35
- s.licenses = ["MIT"]
36
- s.rubygems_version = "2.4.5.1"
37
- s.summary = "A minuscule state machine for storing state of interesting objects"
20
+ s.files = `git ls-files -z`.split("\x0")
21
+ s.homepage = 'http://github.com/WeTransfer/very_tiny_state_machine'
22
+ s.licenses = ['MIT']
23
+ s.rubygems_version = '2.4.5.1'
24
+ s.summary = 'A minuscule state machine for storing state of interesting objects'
38
25
 
39
- if s.respond_to? :specification_version then
40
- s.specification_version = 4
41
-
42
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
43
- s.add_development_dependency(%q<rspec>, ["~> 3.2.0"])
44
- s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
45
- s.add_development_dependency(%q<bundler>, ["~> 1.0"])
46
- s.add_development_dependency(%q<jeweler>, ["~> 2.0.1"])
47
- s.add_development_dependency(%q<simplecov>, ["~> 0.10"])
48
- else
49
- s.add_dependency(%q<rspec>, ["~> 3.2.0"])
50
- s.add_dependency(%q<rdoc>, ["~> 3.12"])
51
- s.add_dependency(%q<bundler>, ["~> 1.0"])
52
- s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
53
- s.add_dependency(%q<simplecov>, ["~> 0.10"])
54
- end
55
- else
56
- s.add_dependency(%q<rspec>, ["~> 3.2.0"])
57
- s.add_dependency(%q<rdoc>, ["~> 3.12"])
58
- s.add_dependency(%q<bundler>, ["~> 1.0"])
59
- s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
60
- s.add_dependency(%q<simplecov>, ["~> 0.10"])
61
- end
26
+ s.specification_version = 4
27
+ s.add_development_dependency('bundler')
28
+ s.add_development_dependency('rake', '~> 12')
29
+ s.add_development_dependency('rdoc', ['~> 3'])
30
+ s.add_development_dependency('rspec', ['~> 3'])
31
+ s.add_development_dependency('simplecov', ['~> 0.10'])
32
+ s.add_development_dependency('wetransfer_style', '0.6.0') # Lock since we want to be backwards-compat down to Ruby 2.1
33
+ s.add_development_dependency('yard')
62
34
  end
63
-
metadata CHANGED
@@ -1,71 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: very_tiny_state_machine
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julik Tarkhanov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-01 00:00:00.000000000 Z
11
+ date: 2020-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rspec
14
+ name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 3.2.0
19
+ version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 3.2.0
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rdoc
28
+ name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '3.12'
33
+ version: '12'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '3.12'
40
+ version: '12'
41
41
  - !ruby/object:Gem::Dependency
42
- name: bundler
42
+ name: rdoc
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.0'
47
+ version: '3'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.0'
54
+ version: '3'
55
55
  - !ruby/object:Gem::Dependency
56
- name: jeweler
56
+ name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 2.0.1
61
+ version: '3'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 2.0.1
68
+ version: '3'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: simplecov
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +80,34 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0.10'
83
+ - !ruby/object:Gem::Dependency
84
+ name: wetransfer_style
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '='
88
+ - !ruby/object:Gem::Version
89
+ version: 0.6.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '='
95
+ - !ruby/object:Gem::Version
96
+ version: 0.6.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: yard
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
83
111
  description: You wouldn't beleive how tiny it is
84
112
  email: me@julik.nl
85
113
  executables: []
@@ -89,7 +117,9 @@ extra_rdoc_files:
89
117
  - README.md
90
118
  files:
91
119
  - ".document"
120
+ - ".gitignore"
92
121
  - ".rspec"
122
+ - ".rubocop.yml"
93
123
  - ".travis.yml"
94
124
  - Gemfile
95
125
  - LICENSE.txt
@@ -118,8 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
118
148
  - !ruby/object:Gem::Version
119
149
  version: '0'
120
150
  requirements: []
121
- rubyforge_project:
122
- rubygems_version: 2.4.5.1
151
+ rubygems_version: 3.0.3
123
152
  signing_key:
124
153
  specification_version: 4
125
154
  summary: A minuscule state machine for storing state of interesting objects