statesman 3.0.0 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +388 -0
- data/.rubocop.yml +13 -1
- data/.rubocop_todo.yml +17 -0
- data/CHANGELOG.md +6 -0
- data/CONTRIBUTING.md +0 -7
- data/Gemfile +1 -1
- data/Guardfile +2 -2
- data/LICENSE.txt +1 -1
- data/README.md +38 -15
- data/Rakefile +9 -1
- data/lib/generators/statesman/active_record_transition_generator.rb +0 -4
- data/lib/generators/statesman/generator_helpers.rb +4 -0
- data/lib/generators/statesman/templates/active_record_transition_model.rb.erb +2 -2
- data/lib/generators/statesman/templates/create_migration.rb.erb +2 -2
- data/lib/generators/statesman/templates/update_migration.rb.erb +2 -2
- data/lib/statesman.rb +2 -1
- data/lib/statesman/adapters/active_record.rb +2 -2
- data/lib/statesman/config.rb +0 -1
- data/lib/statesman/machine.rb +3 -2
- data/lib/statesman/utils.rb +15 -0
- data/lib/statesman/version.rb +1 -1
- data/spec/generators/statesman/active_record_transition_generator_spec.rb +4 -4
- data/spec/generators/statesman/migration_generator_spec.rb +1 -1
- data/spec/generators/statesman/mongoid_transition_generator_spec.rb +2 -2
- data/spec/spec_helper.rb +2 -2
- data/spec/statesman/adapters/active_record_queries_spec.rb +2 -2
- data/spec/statesman/adapters/active_record_spec.rb +8 -1
- data/spec/statesman/callback_spec.rb +1 -1
- data/spec/statesman/machine_spec.rb +11 -11
- data/spec/statesman/utils_spec.rb +51 -0
- data/spec/support/active_record.rb +31 -22
- data/spec/support/generators_shared_examples.rb +2 -2
- data/statesman.gemspec +17 -14
- metadata +31 -14
- data/.travis.yml +0 -37
data/CONTRIBUTING.md
CHANGED
@@ -1,13 +1,6 @@
|
|
1
1
|
Thanks for taking an interest in contributing to Statesman, here are a few
|
2
2
|
ways you can help make this project better!
|
3
3
|
|
4
|
-
# Contribute.md
|
5
|
-
|
6
|
-
## Team members
|
7
|
-
|
8
|
-
- [Andy Appleton](https://twitter.com/appltn)
|
9
|
-
- [Harry Marr](https://twitter.com/harrymarr)
|
10
|
-
|
11
4
|
## Contributing
|
12
5
|
|
13
6
|
- Generally we welcome new features but please first open an issue where we
|
data/Gemfile
CHANGED
data/Guardfile
CHANGED
@@ -4,11 +4,11 @@
|
|
4
4
|
guard :rspec, all_on_start: true, cmd: 'bundle exec rspec --color' do
|
5
5
|
watch(%r{^spec/.+_spec\.rb$})
|
6
6
|
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
7
|
-
watch('spec/spec_helper.rb')
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
8
|
end
|
9
9
|
|
10
10
|
guard :rubocop, all_on_start: true, cli: ['--format', 'clang'] do
|
11
|
-
watch(
|
11
|
+
watch(/.+\.rb$/)
|
12
12
|
watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
|
13
13
|
watch(%r{(?:.+/)?\rubocop-todo\.yml$}) { |m| File.dirname(m[0]) }
|
14
14
|
end
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -5,7 +5,7 @@ A statesmanlike state machine library.
|
|
5
5
|
For our policy on compatibility with Ruby and Rails versions, see [COMPATIBILITY.md](docs/COMPATIBILITY.md).
|
6
6
|
|
7
7
|
[![Gem Version](https://badge.fury.io/rb/statesman.svg)](http://badge.fury.io/rb/statesman)
|
8
|
-
[![
|
8
|
+
[![CircleCI](https://circleci.com/gh/gocardless/statesman.svg?style=svg)](https://circleci.com/gh/gocardless/statesman)
|
9
9
|
[![Code Climate](https://codeclimate.com/github/gocardless/statesman.svg)](https://codeclimate.com/github/gocardless/statesman)
|
10
10
|
[![Gitter](https://badges.gitter.im/join.svg)](https://gitter.im/gocardless/statesman?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
11
11
|
|
@@ -24,13 +24,19 @@ include JSON metadata set during a transition.
|
|
24
24
|
- Database indices are used to offer database-level transaction duplication
|
25
25
|
protection.
|
26
26
|
|
27
|
-
##
|
27
|
+
## Installation
|
28
|
+
|
29
|
+
To get started, just add Statesman to your `Gemfile`, and then run `bundle`:
|
28
30
|
|
29
31
|
```ruby
|
32
|
+
gem 'statesman', '~> 3.1.0'
|
33
|
+
```
|
34
|
+
|
35
|
+
## Usage
|
30
36
|
|
31
|
-
|
32
|
-
|
33
|
-
|
37
|
+
First, create a state machine based on `Statesman::Machine`:
|
38
|
+
|
39
|
+
```ruby
|
34
40
|
class OrderStateMachine
|
35
41
|
include Statesman::Machine
|
36
42
|
|
@@ -63,10 +69,11 @@ class OrderStateMachine
|
|
63
69
|
MailerService.order_confirmation(order).deliver
|
64
70
|
end
|
65
71
|
end
|
72
|
+
```
|
73
|
+
|
74
|
+
Then, link it to your model:
|
66
75
|
|
67
|
-
|
68
|
-
# Your Model #
|
69
|
-
##############
|
76
|
+
```ruby
|
70
77
|
class Order < ActiveRecord::Base
|
71
78
|
include Statesman::Adapters::ActiveRecordQueries
|
72
79
|
|
@@ -85,19 +92,20 @@ class Order < ActiveRecord::Base
|
|
85
92
|
end
|
86
93
|
private_class_method :initial_state
|
87
94
|
end
|
95
|
+
```
|
88
96
|
|
89
|
-
|
90
|
-
|
91
|
-
|
97
|
+
Next, you'll need to create a further model to represent state transitions:
|
98
|
+
|
99
|
+
```ruby
|
92
100
|
class OrderTransition < ActiveRecord::Base
|
93
101
|
include Statesman::Adapters::ActiveRecordTransition
|
94
102
|
|
95
103
|
belongs_to :order, inverse_of: :order_transitions
|
96
104
|
end
|
97
105
|
|
98
|
-
|
99
|
-
|
100
|
-
|
106
|
+
Now, you can start working with your state machine:
|
107
|
+
|
108
|
+
```ruby
|
101
109
|
Order.first.state_machine.current_state # => "pending"
|
102
110
|
Order.first.state_machine.allowed_transitions # => ["checking_out", "cancelled"]
|
103
111
|
Order.first.state_machine.can_transition_to?(:cancelled) # => true/false
|
@@ -106,7 +114,6 @@ Order.first.state_machine.transition_to!(:cancelled) # => true/exception
|
|
106
114
|
|
107
115
|
Order.in_state(:cancelled) # => [#<Order id: "123">]
|
108
116
|
Order.not_in_state(:checking_out) # => [#<Order id: "123">]
|
109
|
-
|
110
117
|
```
|
111
118
|
|
112
119
|
## Persistence
|
@@ -254,6 +261,22 @@ If you know you want to retry a transition if it fails due to a race condition
|
|
254
261
|
call it from within this block. Takes an (optional) argument for the maximum
|
255
262
|
number of retry attempts (defaults to 1).
|
256
263
|
|
264
|
+
#### `Machine.states`
|
265
|
+
Returns an array of all possible state names as strings.
|
266
|
+
|
267
|
+
#### `Machine.successors`
|
268
|
+
Returns a hash of states and the states it is valid for them to transition to.
|
269
|
+
```ruby
|
270
|
+
Machine.successors
|
271
|
+
|
272
|
+
{
|
273
|
+
"pending" => ["checking_out", "cancelled"],
|
274
|
+
"checking_out" => ["purchased", "cancelled"],
|
275
|
+
"purchased" => ["shipped", "failed"],
|
276
|
+
"shipped" => ["refunded"]
|
277
|
+
}
|
278
|
+
```
|
279
|
+
|
257
280
|
## Instance methods
|
258
281
|
|
259
282
|
#### `Machine#current_state`
|
data/Rakefile
CHANGED
@@ -2,8 +2,16 @@ require "bundler/gem_tasks"
|
|
2
2
|
require "rspec/core/rake_task"
|
3
3
|
|
4
4
|
RSpec::Core::RakeTask.new(:spec) do |task|
|
5
|
+
task.rspec_opts = []
|
6
|
+
|
5
7
|
if ENV["EXCLUDE_MONGOID"]
|
6
|
-
task.rspec_opts
|
8
|
+
task.rspec_opts += ["--tag ~mongo", "--exclude-pattern **/*mongo*"]
|
9
|
+
end
|
10
|
+
|
11
|
+
if ENV["CIRCLECI"]
|
12
|
+
task.rspec_opts += ["--format RspecJunitFormatter",
|
13
|
+
"--out /tmp/test-results/rspec.xml",
|
14
|
+
"--format progress"]
|
7
15
|
end
|
8
16
|
end
|
9
17
|
|
@@ -1,7 +1,7 @@
|
|
1
|
-
class <%= klass %> < ActiveRecord::Base
|
1
|
+
class <%= klass %> < <%= Statesman::Utils.rails_5_or_higher? ? 'ApplicationRecord' : 'ActiveRecord::Base' %>
|
2
2
|
include Statesman::Adapters::ActiveRecordTransition
|
3
3
|
|
4
|
-
<%- unless rails_4_or_higher? -%>
|
4
|
+
<%- unless Statesman::Utils.rails_4_or_higher? -%>
|
5
5
|
attr_accessible :to_state, :metadata, :sort_key
|
6
6
|
|
7
7
|
<%- end -%>
|
@@ -1,8 +1,8 @@
|
|
1
|
-
class Create<%= migration_class_name %> < ActiveRecord::Migration
|
1
|
+
class Create<%= migration_class_name %> < ActiveRecord::Migration<%= "[#{ActiveRecord::Migration.current_version}]" if Statesman::Utils.rails_5_or_higher? %>
|
2
2
|
def change
|
3
3
|
create_table :<%= table_name %> do |t|
|
4
4
|
t.string :to_state, null: false
|
5
|
-
t.text :metadata<%= ", default:
|
5
|
+
t.text :metadata<%= ", default: #{metadata_default_value}" unless mysql? %>
|
6
6
|
t.integer :sort_key, null: false
|
7
7
|
t.integer :<%= parent_id %>, null: false
|
8
8
|
t.boolean :most_recent<%= ", null: false" if database_supports_partial_indexes? %>
|
@@ -1,7 +1,7 @@
|
|
1
|
-
class AddStatesmanTo<%= migration_class_name %> < ActiveRecord::Migration
|
1
|
+
class AddStatesmanTo<%= migration_class_name %> < ActiveRecord::Migration<%= "[#{ActiveRecord::Migration.current_version}]" if Statesman::Utils.rails_5_or_higher? %>
|
2
2
|
def change
|
3
3
|
add_column :<%= table_name %>, :to_state, :string, null: false
|
4
|
-
add_column :<%= table_name %>, :metadata, :text<%= ", default:
|
4
|
+
add_column :<%= table_name %>, :metadata, :text<%= ", default: #{metadata_default_value}" unless mysql? %>
|
5
5
|
add_column :<%= table_name %>, :sort_key, :integer, null: false
|
6
6
|
add_column :<%= table_name %>, :<%= parent_id %>, :integer, null: false
|
7
7
|
add_column :<%= table_name %>, :most_recent, null: false
|
data/lib/statesman.rb
CHANGED
@@ -3,6 +3,7 @@ module Statesman
|
|
3
3
|
autoload :Machine, 'statesman/machine'
|
4
4
|
autoload :Callback, 'statesman/callback'
|
5
5
|
autoload :Guard, 'statesman/guard'
|
6
|
+
autoload :Utils, 'statesman/utils'
|
6
7
|
autoload :Version, 'statesman/version'
|
7
8
|
module Adapters
|
8
9
|
autoload :Memory, "statesman/adapters/memory"
|
@@ -11,7 +12,7 @@ module Statesman
|
|
11
12
|
"statesman/adapters/active_record_transition"
|
12
13
|
autoload :ActiveRecordQueries,
|
13
14
|
"statesman/adapters/active_record_queries"
|
14
|
-
autoload :Mongoid,
|
15
|
+
autoload :Mongoid, "statesman/adapters/mongoid"
|
15
16
|
autoload :MongoidTransition,
|
16
17
|
"statesman/adapters/mongoid_transition"
|
17
18
|
end
|
@@ -6,7 +6,7 @@ module Statesman
|
|
6
6
|
attr_reader :transition_class
|
7
7
|
attr_reader :parent_model
|
8
8
|
|
9
|
-
JSON_COLUMN_TYPES = %w
|
9
|
+
JSON_COLUMN_TYPES = %w[json jsonb].freeze
|
10
10
|
|
11
11
|
def self.database_supports_partial_indexes?
|
12
12
|
# Rails 3 doesn't implement `supports_partial_index?`
|
@@ -66,7 +66,7 @@ module Statesman
|
|
66
66
|
sort_key: next_sort_key,
|
67
67
|
metadata: metadata }
|
68
68
|
|
69
|
-
transition_attributes
|
69
|
+
transition_attributes[:most_recent] = true
|
70
70
|
|
71
71
|
transition = transitions_for_parent.build(transition_attributes)
|
72
72
|
|
data/lib/statesman/config.rb
CHANGED
data/lib/statesman/machine.rb
CHANGED
@@ -175,7 +175,8 @@ module Statesman
|
|
175
175
|
@object = object
|
176
176
|
@transition_class = options[:transition_class]
|
177
177
|
@storage_adapter = adapter_class(@transition_class).new(
|
178
|
-
@transition_class, object, self, options
|
178
|
+
@transition_class, object, self, options
|
179
|
+
)
|
179
180
|
send(:after_initialize) if respond_to? :after_initialize
|
180
181
|
end
|
181
182
|
|
@@ -230,7 +231,7 @@ module Statesman
|
|
230
231
|
end
|
231
232
|
|
232
233
|
def transition_to(new_state, metadata = {})
|
233
|
-
|
234
|
+
transition_to!(new_state, metadata)
|
234
235
|
rescue TransitionFailedError, GuardFailedError
|
235
236
|
false
|
236
237
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Statesman
|
2
|
+
module Utils
|
3
|
+
def self.rails_major_version
|
4
|
+
Rails.version.split(".").map(&:to_i).first
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.rails_5_or_higher?
|
8
|
+
rails_major_version >= 5
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.rails_4_or_higher?
|
12
|
+
rails_major_version >= 4
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/statesman/version.rb
CHANGED
@@ -11,7 +11,7 @@ describe Statesman::ActiveRecordTransitionGenerator, type: :generator do
|
|
11
11
|
subject { file("db/migrate/#{time}_create_bacon_transitions.rb") }
|
12
12
|
|
13
13
|
before { allow(Time).to receive(:now).and_return(mock_time) }
|
14
|
-
before { run_generator %w
|
14
|
+
before { run_generator %w[Yummy::Bacon Yummy::BaconTransition] }
|
15
15
|
|
16
16
|
let(:mock_time) { double('Time', utc: double('UTCTime', strftime: time)) }
|
17
17
|
let(:time) { '5678309' }
|
@@ -22,7 +22,7 @@ describe Statesman::ActiveRecordTransitionGenerator, type: :generator do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
describe 'properly adds class names' do
|
25
|
-
before { run_generator %w
|
25
|
+
before { run_generator %w[Yummy::Bacon Yummy::BaconTransition] }
|
26
26
|
subject { file('app/models/yummy/bacon_transition.rb') }
|
27
27
|
|
28
28
|
it { is_expected.to contain(/:bacon_transition/) }
|
@@ -31,7 +31,7 @@ describe Statesman::ActiveRecordTransitionGenerator, type: :generator do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
describe 'properly formats without class names' do
|
34
|
-
before { run_generator %w
|
34
|
+
before { run_generator %w[Bacon BaconTransition] }
|
35
35
|
subject { file('app/models/bacon_transition.rb') }
|
36
36
|
|
37
37
|
it { is_expected.not_to contain(/class_name:/) }
|
@@ -39,7 +39,7 @@ describe Statesman::ActiveRecordTransitionGenerator, type: :generator do
|
|
39
39
|
end
|
40
40
|
|
41
41
|
describe "it doesn't create any double-spacing" do
|
42
|
-
before { run_generator %w
|
42
|
+
before { run_generator %w[Yummy::Bacon Yummy::BaconTransition] }
|
43
43
|
subject { file('app/models/yummy/bacon_transition.rb') }
|
44
44
|
|
45
45
|
it { is_expected.to_not contain(/\n\n\n/) }
|
@@ -22,7 +22,7 @@ describe Statesman::MigrationGenerator, type: :generator do
|
|
22
22
|
|
23
23
|
before do
|
24
24
|
allow(Time).to receive(:now).and_return(mock_time)
|
25
|
-
run_generator %w
|
25
|
+
run_generator %w[Yummy::Bacon Yummy::BaconTransition]
|
26
26
|
end
|
27
27
|
|
28
28
|
it { is_expected.to contain(/:bacon_transition/) }
|
@@ -4,7 +4,7 @@ require "generators/statesman/mongoid_transition_generator"
|
|
4
4
|
|
5
5
|
describe Statesman::MongoidTransitionGenerator, type: :generator do
|
6
6
|
describe 'the model contains the correct words' do
|
7
|
-
before { run_generator %w
|
7
|
+
before { run_generator %w[Yummy::Bacon Yummy::BaconTransition] }
|
8
8
|
subject { file('app/models/yummy/bacon_transition.rb') }
|
9
9
|
|
10
10
|
it { is_expected.not_to contain(%r{:yummy/bacon}) }
|
@@ -12,7 +12,7 @@ describe Statesman::MongoidTransitionGenerator, type: :generator do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
describe 'the model contains the correct words' do
|
15
|
-
before { run_generator %w
|
15
|
+
before { run_generator %w[Bacon BaconTransition] }
|
16
16
|
subject { file('app/models/bacon_transition.rb') }
|
17
17
|
|
18
18
|
it { is_expected.not_to contain(/class_name:/) }
|
data/spec/spec_helper.rb
CHANGED
@@ -67,14 +67,14 @@ RSpec.configure do |config|
|
|
67
67
|
end
|
68
68
|
|
69
69
|
config.before(:each, active_record: true) do
|
70
|
-
tables = %w
|
70
|
+
tables = %w[
|
71
71
|
my_active_record_models
|
72
72
|
my_active_record_model_transitions
|
73
73
|
my_namespace_my_active_record_models
|
74
74
|
my_namespace_my_active_record_model_transitions
|
75
75
|
other_active_record_models
|
76
76
|
other_active_record_model_transitions
|
77
|
-
|
77
|
+
]
|
78
78
|
tables.each do |table_name|
|
79
79
|
sql = "DROP TABLE IF EXISTS #{table_name};"
|
80
80
|
ActiveRecord::Base.connection.execute(sql)
|
@@ -84,7 +84,7 @@ describe Statesman::Adapters::ActiveRecordQueries, active_record: true do
|
|
84
84
|
end
|
85
85
|
|
86
86
|
context "given an array of states" do
|
87
|
-
subject { MyActiveRecordModel.in_state([
|
87
|
+
subject { MyActiveRecordModel.in_state(%i[succeeded failed]) }
|
88
88
|
|
89
89
|
it { is_expected.to include model }
|
90
90
|
it { is_expected.to include other_model }
|
@@ -117,7 +117,7 @@ describe Statesman::Adapters::ActiveRecordQueries, active_record: true do
|
|
117
117
|
end
|
118
118
|
|
119
119
|
context "given an array of states" do
|
120
|
-
subject { MyActiveRecordModel.not_in_state([
|
120
|
+
subject { MyActiveRecordModel.not_in_state(%i[succeeded failed]) }
|
121
121
|
it do
|
122
122
|
is_expected.to match_array([initial_state_model,
|
123
123
|
returned_to_initial_model])
|
@@ -123,7 +123,14 @@ describe Statesman::Adapters::ActiveRecord, active_record: true do
|
|
123
123
|
end
|
124
124
|
|
125
125
|
context "ActiveRecord::RecordNotUnique unrelated to this transition" do
|
126
|
-
let(:error)
|
126
|
+
let(:error) do
|
127
|
+
if ::ActiveRecord.respond_to?(:gem_version) &&
|
128
|
+
::ActiveRecord.gem_version >= Gem::Version.new('4.0.0')
|
129
|
+
ActiveRecord::RecordNotUnique.new("unrelated")
|
130
|
+
else
|
131
|
+
ActiveRecord::RecordNotUnique.new("unrelated", nil)
|
132
|
+
end
|
133
|
+
end
|
127
134
|
it { is_expected.to raise_exception(ActiveRecord::RecordNotUnique) }
|
128
135
|
end
|
129
136
|
|
@@ -70,7 +70,7 @@ describe Statesman::Callback do
|
|
70
70
|
|
71
71
|
context "with any from value on the callback" do
|
72
72
|
let(:callback) do
|
73
|
-
Statesman::Callback.new(to: [
|
73
|
+
Statesman::Callback.new(to: %i[y z], callback: cb_lambda)
|
74
74
|
end
|
75
75
|
let(:from) { :x }
|
76
76
|
|
@@ -7,7 +7,7 @@ describe Statesman::Machine do
|
|
7
7
|
describe ".state" do
|
8
8
|
before { machine.state(:x) }
|
9
9
|
before { machine.state(:y) }
|
10
|
-
specify { expect(machine.states).to eq(%w
|
10
|
+
specify { expect(machine.states).to eq(%w[x y]) }
|
11
11
|
|
12
12
|
context "initial" do
|
13
13
|
before { machine.state(:x, initial: true) }
|
@@ -151,7 +151,7 @@ describe Statesman::Machine do
|
|
151
151
|
it "records the transition" do
|
152
152
|
machine.transition(from: :x, to: :y)
|
153
153
|
machine.transition(from: :x, to: :z)
|
154
|
-
expect(machine.successors).to eq("x" => %w
|
154
|
+
expect(machine.successors).to eq("x" => %w[y z])
|
155
155
|
end
|
156
156
|
end
|
157
157
|
end
|
@@ -208,7 +208,7 @@ describe Statesman::Machine do
|
|
208
208
|
state :x, initial: true
|
209
209
|
state :y
|
210
210
|
state :z
|
211
|
-
transition from: :x, to: [
|
211
|
+
transition from: :x, to: %i[y z]
|
212
212
|
end
|
213
213
|
end
|
214
214
|
|
@@ -262,12 +262,12 @@ describe Statesman::Machine do
|
|
262
262
|
end
|
263
263
|
|
264
264
|
context "from a terminal state and to multiple states" do
|
265
|
-
let(:options) { { from: :y, to: [
|
265
|
+
let(:options) { { from: :y, to: %i[x z] } }
|
266
266
|
it_behaves_like "fails", Statesman::InvalidTransitionError
|
267
267
|
end
|
268
268
|
|
269
269
|
context "to an initial state and other states" do
|
270
|
-
let(:options) { { from: nil, to: [
|
270
|
+
let(:options) { { from: nil, to: %i[y x z] } }
|
271
271
|
it_behaves_like "fails", Statesman::InvalidTransitionError
|
272
272
|
end
|
273
273
|
end
|
@@ -284,12 +284,12 @@ describe Statesman::Machine do
|
|
284
284
|
end
|
285
285
|
|
286
286
|
context "to several" do
|
287
|
-
let(:options) { { from: :x, to: [
|
287
|
+
let(:options) { { from: :x, to: %i[y z] } }
|
288
288
|
it_behaves_like "adds callback"
|
289
289
|
end
|
290
290
|
|
291
291
|
context "from any to several" do
|
292
|
-
let(:options) { { from: nil, to: [
|
292
|
+
let(:options) { { from: nil, to: %i[y z] } }
|
293
293
|
it_behaves_like "adds callback"
|
294
294
|
end
|
295
295
|
end
|
@@ -417,12 +417,12 @@ describe Statesman::Machine do
|
|
417
417
|
|
418
418
|
context "when given an array" do
|
419
419
|
context "when one of the states is the current state" do
|
420
|
-
subject { instance.in_state?([
|
420
|
+
subject { instance.in_state?(%i[x y]) }
|
421
421
|
it { is_expected.to eq(true) }
|
422
422
|
end
|
423
423
|
|
424
424
|
context "when none of the states are the current state" do
|
425
|
-
subject { instance.in_state?([
|
425
|
+
subject { instance.in_state?(%i[x z]) }
|
426
426
|
it { is_expected.to eq(false) }
|
427
427
|
end
|
428
428
|
end
|
@@ -435,7 +435,7 @@ describe Statesman::Machine do
|
|
435
435
|
state :x, initial: true
|
436
436
|
state :y
|
437
437
|
state :z
|
438
|
-
transition from: :x, to: [
|
438
|
+
transition from: :x, to: %i[y z]
|
439
439
|
transition from: :y, to: :z
|
440
440
|
end
|
441
441
|
end
|
@@ -444,7 +444,7 @@ describe Statesman::Machine do
|
|
444
444
|
subject { instance.allowed_transitions }
|
445
445
|
|
446
446
|
context "with multiple possible states" do
|
447
|
-
it { is_expected.to eq(%w
|
447
|
+
it { is_expected.to eq(%w[y z]) }
|
448
448
|
end
|
449
449
|
|
450
450
|
context "with one possible state" do
|