very_tiny_state_machine 2.1.0 → 2.2.0

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 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