statesman 3.0.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +388 -0
  3. data/.rubocop.yml +13 -1
  4. data/.rubocop_todo.yml +17 -0
  5. data/CHANGELOG.md +6 -0
  6. data/CONTRIBUTING.md +0 -7
  7. data/Gemfile +1 -1
  8. data/Guardfile +2 -2
  9. data/LICENSE.txt +1 -1
  10. data/README.md +38 -15
  11. data/Rakefile +9 -1
  12. data/lib/generators/statesman/active_record_transition_generator.rb +0 -4
  13. data/lib/generators/statesman/generator_helpers.rb +4 -0
  14. data/lib/generators/statesman/templates/active_record_transition_model.rb.erb +2 -2
  15. data/lib/generators/statesman/templates/create_migration.rb.erb +2 -2
  16. data/lib/generators/statesman/templates/update_migration.rb.erb +2 -2
  17. data/lib/statesman.rb +2 -1
  18. data/lib/statesman/adapters/active_record.rb +2 -2
  19. data/lib/statesman/config.rb +0 -1
  20. data/lib/statesman/machine.rb +3 -2
  21. data/lib/statesman/utils.rb +15 -0
  22. data/lib/statesman/version.rb +1 -1
  23. data/spec/generators/statesman/active_record_transition_generator_spec.rb +4 -4
  24. data/spec/generators/statesman/migration_generator_spec.rb +1 -1
  25. data/spec/generators/statesman/mongoid_transition_generator_spec.rb +2 -2
  26. data/spec/spec_helper.rb +2 -2
  27. data/spec/statesman/adapters/active_record_queries_spec.rb +2 -2
  28. data/spec/statesman/adapters/active_record_spec.rb +8 -1
  29. data/spec/statesman/callback_spec.rb +1 -1
  30. data/spec/statesman/machine_spec.rb +11 -11
  31. data/spec/statesman/utils_spec.rb +51 -0
  32. data/spec/support/active_record.rb +31 -22
  33. data/spec/support/generators_shared_examples.rb +2 -2
  34. data/statesman.gemspec +17 -14
  35. metadata +31 -14
  36. data/.travis.yml +0 -37
@@ -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
@@ -2,7 +2,7 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- gem "rails", "~> #{ENV["RAILS_VERSION"]}" if ENV["RAILS_VERSION"]
5
+ gem "rails", "~> #{ENV['RAILS_VERSION']}" if ENV["RAILS_VERSION"]
6
6
 
7
7
  group :development do
8
8
  gem "mongoid", ">= 3.1" unless ENV["EXCLUDE_MONGOID"]
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') { "spec" }
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(%r{.+\.rb$})
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
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013 Harry Marr
1
+ Copyright (c) 2013-2017 GoCardless
2
2
 
3
3
  MIT License
4
4
 
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
- [![Build Status](https://travis-ci.org/gocardless/statesman.svg?branch=master)](https://travis-ci.org/gocardless/statesman)
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
- ## TL;DR Usage
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
- # State Machine Class #
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
- # Transition Model #
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
- # Example method calls #
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 = "--tag ~mongo --exclude-pattern **/*mongo*"
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
 
@@ -23,9 +23,5 @@ module Statesman
23
23
  def migration_file_name
24
24
  "db/migrate/#{next_migration_number}_create_#{table_name}.rb"
25
25
  end
26
-
27
- def rails_4_or_higher?
28
- Rails.version.split(".").map(&:to_i).first >= 4
29
- end
30
26
  end
31
27
  end
@@ -44,5 +44,9 @@ module Statesman
44
44
  def database_supports_partial_indexes?
45
45
  Statesman::Adapters::ActiveRecord.database_supports_partial_indexes?
46
46
  end
47
+
48
+ def metadata_default_value
49
+ Utils.rails_5_or_higher? ? "{}" : "{}".inspect
50
+ end
47
51
  end
48
52
  end
@@ -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: \"{}\"" unless mysql? %>
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: \"{}\"" unless mysql? %>
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
@@ -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, "statesman/adapters/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(json jsonb).freeze
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.merge!(most_recent: true)
69
+ transition_attributes[:most_recent] = true
70
70
 
71
71
  transition = transitions_for_parent.build(transition_attributes)
72
72
 
@@ -9,7 +9,6 @@ module Statesman
9
9
  instance_eval(&block) unless block.nil?
10
10
  end
11
11
 
12
- # rubocop:disable TrivialAccessors
13
12
  def storage_adapter(adapter_class)
14
13
  @adapter_class = adapter_class
15
14
  end
@@ -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
- self.transition_to!(new_state, metadata)
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
@@ -1,3 +1,3 @@
1
1
  module Statesman
2
- VERSION = "3.0.0"
2
+ VERSION = "3.1.0".freeze
3
3
  end
@@ -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(Yummy::Bacon Yummy::BaconTransition) }
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(Yummy::Bacon Yummy::BaconTransition) }
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(Bacon BaconTransition) }
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(Yummy::Bacon Yummy::BaconTransition) }
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(Yummy::Bacon Yummy::BaconTransition)
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(Yummy::Bacon Yummy::BaconTransition) }
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(Bacon BaconTransition) }
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:/) }
@@ -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([:succeeded, :failed]) }
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([:succeeded, :failed]) }
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) { ActiveRecord::RecordNotUnique.new("unrelated", nil) }
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: [:y, :z], callback: cb_lambda)
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(x y)) }
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(y z))
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: [:y, :z]
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: [:x, :z] } }
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: [:y, :x, :z] } }
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: [:y, :z] } }
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: [:y, :z] } }
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?([:x, :y]) }
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?([:x, :z]) }
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: [:y, :z]
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(y z)) }
447
+ it { is_expected.to eq(%w[y z]) }
448
448
  end
449
449
 
450
450
  context "with one possible state" do