statesman 7.4.0 → 12.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +7 -0
  3. data/.github/workflows/tests.yml +112 -0
  4. data/.gitignore +65 -15
  5. data/.rspec +1 -0
  6. data/.rubocop.yml +14 -1
  7. data/.rubocop_todo.yml +37 -28
  8. data/.ruby-version +1 -0
  9. data/CHANGELOG.md +262 -41
  10. data/CONTRIBUTING.md +23 -4
  11. data/Gemfile +4 -6
  12. data/README.md +243 -43
  13. data/docs/COMPATIBILITY.md +2 -2
  14. data/lib/generators/statesman/active_record_transition_generator.rb +1 -1
  15. data/lib/generators/statesman/generator_helpers.rb +12 -4
  16. data/lib/statesman/adapters/active_record.rb +84 -55
  17. data/lib/statesman/adapters/active_record_queries.rb +19 -7
  18. data/lib/statesman/adapters/active_record_transition.rb +5 -1
  19. data/lib/statesman/adapters/memory.rb +5 -1
  20. data/lib/statesman/adapters/type_safe_active_record_queries.rb +21 -0
  21. data/lib/statesman/callback.rb +2 -2
  22. data/lib/statesman/config.rb +3 -10
  23. data/lib/statesman/exceptions.rb +13 -7
  24. data/lib/statesman/guard.rb +1 -1
  25. data/lib/statesman/machine.rb +68 -0
  26. data/lib/statesman/version.rb +1 -1
  27. data/lib/statesman.rb +5 -5
  28. data/lib/tasks/statesman.rake +5 -5
  29. data/spec/generators/statesman/active_record_transition_generator_spec.rb +7 -1
  30. data/spec/generators/statesman/migration_generator_spec.rb +5 -1
  31. data/spec/spec_helper.rb +44 -7
  32. data/spec/statesman/adapters/active_record_queries_spec.rb +34 -12
  33. data/spec/statesman/adapters/active_record_spec.rb +176 -51
  34. data/spec/statesman/adapters/active_record_transition_spec.rb +5 -2
  35. data/spec/statesman/adapters/memory_spec.rb +0 -1
  36. data/spec/statesman/adapters/memory_transition_spec.rb +0 -1
  37. data/spec/statesman/adapters/shared_examples.rb +3 -4
  38. data/spec/statesman/adapters/type_safe_active_record_queries_spec.rb +206 -0
  39. data/spec/statesman/callback_spec.rb +0 -2
  40. data/spec/statesman/config_spec.rb +0 -2
  41. data/spec/statesman/exceptions_spec.rb +17 -4
  42. data/spec/statesman/guard_spec.rb +0 -2
  43. data/spec/statesman/machine_spec.rb +252 -15
  44. data/spec/statesman/utils_spec.rb +0 -2
  45. data/spec/support/active_record.rb +156 -24
  46. data/spec/support/exactly_query_databases.rb +35 -0
  47. data/statesman.gemspec +9 -10
  48. metadata +32 -59
  49. data/.circleci/config.yml +0 -187
@@ -0,0 +1,206 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Statesman::Adapters::TypeSafeActiveRecordQueries, :active_record do
4
+ def configure(klass, transition_class)
5
+ klass.send(:extend, described_class)
6
+ klass.configure_state_machine(
7
+ transition_class: transition_class,
8
+ initial_state: :initial,
9
+ )
10
+ end
11
+
12
+ before do
13
+ prepare_model_table
14
+ prepare_transitions_table
15
+ prepare_other_model_table
16
+ prepare_other_transitions_table
17
+
18
+ Statesman.configure do
19
+ storage_adapter(Statesman::Adapters::ActiveRecord)
20
+ end
21
+ end
22
+
23
+ after { Statesman.configure { storage_adapter(Statesman::Adapters::Memory) } }
24
+
25
+ let!(:model) do
26
+ model = MyActiveRecordModel.create
27
+ model.state_machine.transition_to(:succeeded)
28
+ model
29
+ end
30
+
31
+ let!(:other_model) do
32
+ model = MyActiveRecordModel.create
33
+ model.state_machine.transition_to(:failed)
34
+ model
35
+ end
36
+
37
+ let!(:initial_state_model) { MyActiveRecordModel.create }
38
+
39
+ let!(:returned_to_initial_model) do
40
+ model = MyActiveRecordModel.create
41
+ model.state_machine.transition_to(:failed)
42
+ model.state_machine.transition_to(:initial)
43
+ model
44
+ end
45
+
46
+ shared_examples "testing methods" do
47
+ before do
48
+ configure(MyActiveRecordModel, MyActiveRecordModelTransition)
49
+ configure(OtherActiveRecordModel, OtherActiveRecordModelTransition)
50
+
51
+ MyActiveRecordModel.send(:has_one, :other_active_record_model)
52
+ OtherActiveRecordModel.send(:belongs_to, :my_active_record_model)
53
+ end
54
+
55
+ describe ".in_state" do
56
+ context "given a single state" do
57
+ subject { MyActiveRecordModel.in_state(:succeeded) }
58
+
59
+ it { is_expected.to include model }
60
+ it { is_expected.to_not include other_model }
61
+ end
62
+
63
+ context "given multiple states" do
64
+ subject { MyActiveRecordModel.in_state(:succeeded, :failed) }
65
+
66
+ it { is_expected.to include model }
67
+ it { is_expected.to include other_model }
68
+ end
69
+
70
+ context "given the initial state" do
71
+ subject { MyActiveRecordModel.in_state(:initial) }
72
+
73
+ it { is_expected.to include initial_state_model }
74
+ it { is_expected.to include returned_to_initial_model }
75
+ end
76
+
77
+ context "given an array of states" do
78
+ subject { MyActiveRecordModel.in_state(%i[succeeded failed]) }
79
+
80
+ it { is_expected.to include model }
81
+ it { is_expected.to include other_model }
82
+ end
83
+
84
+ context "merging two queries" do
85
+ subject do
86
+ MyActiveRecordModel.in_state(:succeeded).
87
+ joins(:other_active_record_model).
88
+ merge(OtherActiveRecordModel.in_state(:initial))
89
+ end
90
+
91
+ it { is_expected.to be_empty }
92
+ end
93
+ end
94
+
95
+ describe ".not_in_state" do
96
+ context "given a single state" do
97
+ subject { MyActiveRecordModel.not_in_state(:failed) }
98
+
99
+ it { is_expected.to include model }
100
+ it { is_expected.to_not include other_model }
101
+ end
102
+
103
+ context "given multiple states" do
104
+ subject(:not_in_state) { MyActiveRecordModel.not_in_state(:succeeded, :failed) }
105
+
106
+ it do
107
+ expect(not_in_state).to contain_exactly(initial_state_model,
108
+ returned_to_initial_model)
109
+ end
110
+ end
111
+
112
+ context "given an array of states" do
113
+ subject(:not_in_state) { MyActiveRecordModel.not_in_state(%i[succeeded failed]) }
114
+
115
+ it do
116
+ expect(not_in_state).to contain_exactly(initial_state_model,
117
+ returned_to_initial_model)
118
+ end
119
+ end
120
+ end
121
+
122
+ context "with a custom name for the transition association" do
123
+ before do
124
+ # Switch to using OtherActiveRecordModelTransition, so the existing
125
+ # relation with MyActiveRecordModelTransition doesn't interfere with
126
+ # this spec.
127
+ MyActiveRecordModel.send(:has_many,
128
+ :custom_name,
129
+ class_name: "OtherActiveRecordModelTransition")
130
+
131
+ MyActiveRecordModel.class_eval do
132
+ def self.transition_class
133
+ OtherActiveRecordModelTransition
134
+ end
135
+ end
136
+ end
137
+
138
+ describe ".in_state" do
139
+ subject(:query) { MyActiveRecordModel.in_state(:succeeded) }
140
+
141
+ specify { expect { query }.to_not raise_error }
142
+ end
143
+ end
144
+
145
+ context "with a custom primary key for the model" do
146
+ before do
147
+ # Switch to using OtherActiveRecordModelTransition, so the existing
148
+ # relation with MyActiveRecordModelTransition doesn't interfere with
149
+ # this spec.
150
+ # Configure the relationship to use a different primary key,
151
+ MyActiveRecordModel.send(:has_many,
152
+ :custom_name,
153
+ class_name: "OtherActiveRecordModelTransition",
154
+ primary_key: :external_id)
155
+
156
+ MyActiveRecordModel.class_eval do
157
+ def self.transition_class
158
+ OtherActiveRecordModelTransition
159
+ end
160
+ end
161
+ end
162
+
163
+ describe ".in_state" do
164
+ subject(:query) { MyActiveRecordModel.in_state(:succeeded) }
165
+
166
+ specify { expect { query }.to_not raise_error }
167
+ end
168
+ end
169
+
170
+ context "after_commit transactional integrity" do
171
+ before do
172
+ MyStateMachine.class_eval do
173
+ cattr_accessor(:after_commit_callback_executed) { false }
174
+
175
+ after_transition(from: :initial, to: :succeeded, after_commit: true) do
176
+ # This leaks state in a testable way if transactional integrity is broken.
177
+ MyStateMachine.after_commit_callback_executed = true
178
+ end
179
+ end
180
+ end
181
+
182
+ after do
183
+ MyStateMachine.class_eval do
184
+ callbacks[:after_commit] = []
185
+ end
186
+ end
187
+
188
+ let!(:model) do
189
+ MyActiveRecordModel.create
190
+ end
191
+
192
+ it do
193
+ expect do
194
+ ActiveRecord::Base.transaction do
195
+ model.state_machine.transition_to!(:succeeded)
196
+ raise ActiveRecord::Rollback
197
+ end
198
+ end.to_not change(MyStateMachine, :after_commit_callback_executed)
199
+ end
200
+ end
201
+ end
202
+
203
+ context "using configuration method" do
204
+ include_examples "testing methods"
205
+ end
206
+ end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "spec_helper"
4
-
5
3
  describe Statesman::Callback do
6
4
  let(:cb_lambda) { -> {} }
7
5
  let(:callback) do
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "spec_helper"
4
-
5
3
  describe Statesman::Config do
6
4
  let(:instance) { described_class.new }
7
5
 
@@ -1,12 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "spec_helper"
4
-
5
- describe Statesman do
3
+ describe "Exceptions" do
6
4
  describe "InvalidStateError" do
7
5
  subject(:error) { Statesman::InvalidStateError.new }
8
6
 
9
7
  its(:message) { is_expected.to eq("Statesman::InvalidStateError") }
8
+
10
9
  its "string matches its message" do
11
10
  expect(error.to_s).to eq(error.message)
12
11
  end
@@ -16,6 +15,7 @@ describe Statesman do
16
15
  subject(:error) { Statesman::InvalidTransitionError.new }
17
16
 
18
17
  its(:message) { is_expected.to eq("Statesman::InvalidTransitionError") }
18
+
19
19
  its "string matches its message" do
20
20
  expect(error.to_s).to eq(error.message)
21
21
  end
@@ -25,6 +25,7 @@ describe Statesman do
25
25
  subject(:error) { Statesman::InvalidTransitionError.new }
26
26
 
27
27
  its(:message) { is_expected.to eq("Statesman::InvalidTransitionError") }
28
+
28
29
  its "string matches its message" do
29
30
  expect(error.to_s).to eq(error.message)
30
31
  end
@@ -34,6 +35,7 @@ describe Statesman do
34
35
  subject(:error) { Statesman::TransitionConflictError.new }
35
36
 
36
37
  its(:message) { is_expected.to eq("Statesman::TransitionConflictError") }
38
+
37
39
  its "string matches its message" do
38
40
  expect(error.to_s).to eq(error.message)
39
41
  end
@@ -43,6 +45,7 @@ describe Statesman do
43
45
  subject(:error) { Statesman::MissingTransitionAssociation.new }
44
46
 
45
47
  its(:message) { is_expected.to eq("Statesman::MissingTransitionAssociation") }
48
+
46
49
  its "string matches its message" do
47
50
  expect(error.to_s).to eq(error.message)
48
51
  end
@@ -52,17 +55,25 @@ describe Statesman do
52
55
  subject(:error) { Statesman::TransitionFailedError.new("from", "to") }
53
56
 
54
57
  its(:message) { is_expected.to eq("Cannot transition from 'from' to 'to'") }
58
+
55
59
  its "string matches its message" do
56
60
  expect(error.to_s).to eq(error.message)
57
61
  end
58
62
  end
59
63
 
60
64
  describe "GuardFailedError" do
61
- subject(:error) { Statesman::GuardFailedError.new("from", "to") }
65
+ subject(:error) { Statesman::GuardFailedError.new("from", "to", callback) }
66
+
67
+ let(:callback) { -> { "hello" } }
62
68
 
63
69
  its(:message) do
64
70
  is_expected.to eq("Guard on transition from: 'from' to 'to' returned false")
65
71
  end
72
+
73
+ its(:backtrace) do
74
+ is_expected.to eq([callback.source_location.join(":")])
75
+ end
76
+
66
77
  its "string matches its message" do
67
78
  expect(error.to_s).to eq(error.message)
68
79
  end
@@ -72,6 +83,7 @@ describe Statesman do
72
83
  subject(:error) { Statesman::UnserializedMetadataError.new("foo") }
73
84
 
74
85
  its(:message) { is_expected.to match(/foo#metadata is not serialized/) }
86
+
75
87
  its "string matches its message" do
76
88
  expect(error.to_s).to eq(error.message)
77
89
  end
@@ -81,6 +93,7 @@ describe Statesman do
81
93
  subject(:error) { Statesman::IncompatibleSerializationError.new("foo") }
82
94
 
83
95
  its(:message) { is_expected.to match(/foo#metadata column type cannot be json/) }
96
+
84
97
  its "string matches its message" do
85
98
  expect(error.to_s).to eq(error.message)
86
99
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "spec_helper"
4
-
5
3
  describe Statesman::Guard do
6
4
  let(:callback) { -> {} }
7
5
  let(:guard) { described_class.new(from: nil, to: nil, callback: callback) }
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "spec_helper"
4
-
5
3
  describe Statesman::Machine do
6
4
  let(:machine) { Class.new { include Statesman::Machine } }
7
5
  let(:my_model) { Class.new { attr_accessor :current_state }.new }
@@ -27,6 +25,112 @@ describe Statesman::Machine do
27
25
  end
28
26
  end
29
27
 
28
+ describe ".remove_state" do
29
+ subject(:remove_state) { machine.remove_state(:x) }
30
+
31
+ before do
32
+ machine.class_eval do
33
+ state :x
34
+ state :y
35
+ state :z
36
+ end
37
+ end
38
+
39
+ it "removes the state" do
40
+ expect { remove_state }.
41
+ to change(machine, :states).
42
+ from(match_array(%w[x y z])).
43
+ to(%w[y z])
44
+ end
45
+
46
+ context "with a transition from the removed state" do
47
+ before { machine.transition from: :x, to: :y }
48
+
49
+ it "removes the transition" do
50
+ expect { remove_state }.
51
+ to change(machine, :successors).
52
+ from({ "x" => ["y"] }).
53
+ to({})
54
+ end
55
+
56
+ context "with multiple transitions" do
57
+ before { machine.transition from: :x, to: :z }
58
+
59
+ it "removes all transitions" do
60
+ expect { remove_state }.
61
+ to change(machine, :successors).
62
+ from({ "x" => %w[y z] }).
63
+ to({})
64
+ end
65
+ end
66
+ end
67
+
68
+ context "with a transition to the removed state" do
69
+ before { machine.transition from: :y, to: :x }
70
+
71
+ it "removes the transition" do
72
+ expect { remove_state }.
73
+ to change(machine, :successors).
74
+ from({ "y" => ["x"] }).
75
+ to({})
76
+ end
77
+
78
+ context "with multiple transitions" do
79
+ before { machine.transition from: :z, to: :x }
80
+
81
+ it "removes all transitions" do
82
+ expect { remove_state }.
83
+ to change(machine, :successors).
84
+ from({ "y" => ["x"], "z" => ["x"] }).
85
+ to({})
86
+ end
87
+ end
88
+ end
89
+
90
+ context "with a callback from the removed state" do
91
+ before do
92
+ machine.class_eval do
93
+ transition from: :x, to: :y
94
+ transition from: :x, to: :z
95
+ guard_transition(from: :x) { return false }
96
+ guard_transition(from: :x, to: :z) { return true }
97
+ end
98
+ end
99
+
100
+ let(:guards) do
101
+ [having_attributes(from: "x", to: []), having_attributes(from: "x", to: ["z"])]
102
+ end
103
+
104
+ it "removes the guard" do
105
+ expect { remove_state }.
106
+ to change(machine, :callbacks).
107
+ from(a_hash_including(guards: match_array(guards))).
108
+ to(a_hash_including(guards: []))
109
+ end
110
+ end
111
+
112
+ context "with a callback to the removed state" do
113
+ before do
114
+ machine.class_eval do
115
+ transition from: :y, to: :x
116
+ guard_transition(to: :x) { return false }
117
+ guard_transition(from: :y, to: :x) { return true }
118
+ end
119
+ end
120
+
121
+ let(:guards) do
122
+ [having_attributes(from: nil, to: ["x"]), having_attributes(from: "y", to: ["x"])]
123
+ end
124
+
125
+ it "removes the guard" do
126
+ expect { remove_state }.
127
+ to change(machine, :callbacks).
128
+ from(a_hash_including(guards: match_array(guards))).
129
+ to(a_hash_including(guards: []))
130
+ end
131
+ end
132
+ end
133
+
30
134
  describe ".retry_conflicts" do
31
135
  subject(:transition_state) do
32
136
  described_class.retry_conflicts(retry_attempts) do
@@ -170,6 +274,42 @@ describe Statesman::Machine do
170
274
  end
171
275
  end
172
276
 
277
+ describe ".remove_transitions" do
278
+ before do
279
+ machine.class_eval do
280
+ state :x
281
+ state :y
282
+ state :z
283
+ transition from: :x, to: :y
284
+ transition from: :x, to: :z
285
+ transition from: :y, to: :z
286
+ end
287
+ end
288
+
289
+ let(:initial_successors) { { "x" => %w[y z], "y" => ["z"] } }
290
+
291
+ it "removes the correct transitions when given a from state" do
292
+ expect { machine.remove_transitions(from: :x) }.
293
+ to change(machine, :successors).
294
+ from(initial_successors).
295
+ to({ "y" => ["z"] })
296
+ end
297
+
298
+ it "removes the correct transitions when given a to state" do
299
+ expect { machine.remove_transitions(to: :z) }.
300
+ to change(machine, :successors).
301
+ from(initial_successors).
302
+ to({ "x" => ["y"] })
303
+ end
304
+
305
+ it "removes the correct transitions when given a from and to state" do
306
+ expect { machine.remove_transitions(from: :x, to: :z) }.
307
+ to change(machine, :successors).
308
+ from(initial_successors).
309
+ to({ "x" => ["y"], "y" => ["z"] })
310
+ end
311
+ end
312
+
173
313
  describe ".validate_callback_condition" do
174
314
  before do
175
315
  machine.class_eval do
@@ -234,11 +374,9 @@ describe Statesman::Machine do
234
374
 
235
375
  it "does not add a callback" do
236
376
  expect do
237
- begin
238
- set_callback
239
- rescue error_type
240
- nil
241
- end
377
+ set_callback
378
+ rescue error_type
379
+ nil
242
380
  end.to_not change(machine.callbacks[callback_store], :count)
243
381
  end
244
382
  end
@@ -340,12 +478,83 @@ describe Statesman::Machine do
340
478
  it_behaves_like "a callback store", :after_guard_failure, :after_guard_failure
341
479
  end
342
480
 
481
+ shared_examples "initial transition is not created" do
482
+ it "doesn't call .create on storage adapter" do
483
+ expect_any_instance_of(Statesman.storage_adapter).to_not receive(:create)
484
+ machine.new(my_model, options)
485
+ end
486
+ end
487
+
488
+ shared_examples "initial transition is created" do
489
+ it "calls .create on storage adapter" do
490
+ expect_any_instance_of(Statesman.storage_adapter).to receive(:create).with(nil, "x")
491
+ machine.new(my_model, options)
492
+ end
493
+
494
+ it "creates a new transition object" do
495
+ instance = machine.new(my_model, options)
496
+
497
+ expect(instance.history.count).to eq(1)
498
+ expect(instance.history.first.to_state).to eq("x")
499
+ end
500
+ end
501
+
343
502
  describe "#initialize" do
344
503
  it "accepts an object to manipulate" do
345
504
  machine_instance = machine.new(my_model)
346
505
  expect(machine_instance.object).to be(my_model)
347
506
  end
348
507
 
508
+ context "initial_transition is not provided" do
509
+ let(:options) { {} }
510
+
511
+ it_behaves_like "initial transition is not created"
512
+ end
513
+
514
+ context "initial_transition is provided" do
515
+ context "initial_transition is true" do
516
+ let(:options) do
517
+ { initial_transition: true,
518
+ transition_class: Statesman::Adapters::MemoryTransition }
519
+ end
520
+
521
+ context "history is empty" do
522
+ context "initial state is defined" do
523
+ before { machine.state(:x, initial: true) }
524
+
525
+ it_behaves_like "initial transition is created"
526
+ end
527
+
528
+ context "initial state is not defined" do
529
+ it_behaves_like "initial transition is not created"
530
+ end
531
+ end
532
+
533
+ context "history is not empty" do
534
+ before do
535
+ allow_any_instance_of(Statesman.storage_adapter).to receive(:history).
536
+ and_return([{}])
537
+ end
538
+
539
+ context "initial state is defined" do
540
+ before { machine.state(:x, initial: true) }
541
+
542
+ it_behaves_like "initial transition is not created"
543
+ end
544
+
545
+ context "initial state is not defined" do
546
+ it_behaves_like "initial transition is not created"
547
+ end
548
+ end
549
+ end
550
+
551
+ context "initial_transition is false" do
552
+ let(:options) { { initial_transition: false } }
553
+
554
+ it_behaves_like "initial transition is not created"
555
+ end
556
+ end
557
+
349
558
  context "transition class" do
350
559
  it "sets a default" do
351
560
  expect(Statesman.storage_adapter).to receive(:new).once.
@@ -537,6 +746,34 @@ describe Statesman::Machine do
537
746
  end
538
747
  end
539
748
 
749
+ describe "#last_transition_to" do
750
+ subject { instance.last_transition_to(:y) }
751
+
752
+ before do
753
+ machine.class_eval do
754
+ state :x, initial: true
755
+ state :y
756
+ state :z
757
+ transition from: :x, to: :y
758
+ transition from: :y, to: :z
759
+ transition from: :z, to: :y
760
+ end
761
+
762
+ instance.transition_to!(:y)
763
+ instance.transition_to!(:z)
764
+ end
765
+
766
+ let(:instance) { machine.new(my_model) }
767
+
768
+ it { is_expected.to have_attributes(to_state: "y") }
769
+
770
+ context "when there are 2 transitions to the state" do
771
+ before { instance.transition_to!(:y) }
772
+
773
+ it { is_expected.to eq(instance.last_transition) }
774
+ end
775
+ end
776
+
540
777
  describe "#can_transition_to?" do
541
778
  subject(:can_transition_to?) { instance.can_transition_to?(new_state, metadata) }
542
779
 
@@ -767,10 +1004,10 @@ describe Statesman::Machine do
767
1004
  it { is_expected.to be(:some_state) }
768
1005
  end
769
1006
 
770
- context "when it is unsuccesful" do
1007
+ context "when it is unsuccessful" do
771
1008
  before do
772
1009
  allow(instance).to receive(:transition_to!).
773
- and_raise(Statesman::GuardFailedError.new(:x, :some_state))
1010
+ and_raise(Statesman::GuardFailedError.new(:x, :some_state, nil))
774
1011
  end
775
1012
 
776
1013
  it { is_expected.to be_falsey }
@@ -808,20 +1045,20 @@ describe Statesman::Machine do
808
1045
  end
809
1046
 
810
1047
  context "with defined callbacks" do
811
- let(:callback_1) { -> { "Hi" } }
812
- let(:callback_2) { -> { "Bye" } }
1048
+ let(:callback_one) { -> { "Hi" } }
1049
+ let(:callback_two) { -> { "Bye" } }
813
1050
 
814
1051
  before do
815
- machine.send(definer, from: :x, to: :y, &callback_1)
816
- machine.send(definer, from: :y, to: :z, &callback_2)
1052
+ machine.send(definer, from: :x, to: :y, &callback_one)
1053
+ machine.send(definer, from: :y, to: :z, &callback_two)
817
1054
  end
818
1055
 
819
1056
  it "contains the relevant callback" do
820
- expect(callbacks.map(&:callback)).to include(callback_1)
1057
+ expect(callbacks.map(&:callback)).to include(callback_one)
821
1058
  end
822
1059
 
823
1060
  it "does not contain the irrelevant callback" do
824
- expect(callbacks.map(&:callback)).to_not include(callback_2)
1061
+ expect(callbacks.map(&:callback)).to_not include(callback_two)
825
1062
  end
826
1063
  end
827
1064
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "spec_helper"
4
-
5
3
  describe Statesman::Utils do
6
4
  describe ".rails_major_version" do
7
5
  subject { described_class.rails_major_version }