File: machine_with_callbacks_test.rb

package info (click to toggle)
ruby-state-machines-activerecord 0.9.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 340 kB
  • sloc: ruby: 1,922; makefile: 5
file content (172 lines) | stat: -rw-r--r-- 4,709 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
require_relative 'test_helper'

class MachineWithCallbacksTest < BaseTestCase
  def setup
    @model = new_model
    @machine = StateMachines::Machine.new(@model, :initial => :parked)
    @machine.other_states :idling
    @machine.event :ignite

    @record = @model.new(:state => 'parked')
    @transition = StateMachines::Transition.new(@record, @machine, :ignite, :parked, :idling)
  end

  def test_should_run_before_callbacks
    called = false
    @machine.before_transition { called = true }

    @transition.perform
    assert called
  end

  def test_should_pass_record_to_before_callbacks_with_one_argument
    record = nil
    @machine.before_transition { |arg| record = arg }

    @transition.perform
    assert_equal @record, record
  end

  def test_should_pass_record_and_transition_to_before_callbacks_with_multiple_arguments
    callback_args = nil
    @machine.before_transition { |*args| callback_args = args }

    @transition.perform
    assert_equal [@record, @transition], callback_args
  end

  def test_should_run_before_callbacks_outside_the_context_of_the_record
    context = nil
    @machine.before_transition { context = self }

    @transition.perform
    assert_equal self, context
  end

  def test_should_run_after_callbacks
    called = false
    @machine.after_transition { called = true }

    @transition.perform
    assert called
  end

  def test_should_pass_record_to_after_callbacks_with_one_argument
    record = nil
    @machine.after_transition { |arg| record = arg }

    @transition.perform
    assert_equal @record, record
  end

  def test_should_pass_record_and_transition_to_after_callbacks_with_multiple_arguments
    callback_args = nil
    @machine.after_transition { |*args| callback_args = args }

    @transition.perform
    assert_equal [@record, @transition], callback_args
  end

  def test_should_run_after_callbacks_outside_the_context_of_the_record
    context = nil
    @machine.after_transition { context = self }

    @transition.perform
    assert_equal self, context
  end

  def test_should_run_after_callbacks_if_model_callback_added_prior_to_state_machine_definition
    model = new_model do
      after_save { nil }
    end
    machine = StateMachines::Machine.new(model, :initial => :parked)
    machine.other_states :idling
    machine.event :ignite
    after_called = false
    machine.after_transition { after_called = true }

    record = model.new(:state => 'parked')
    transition = StateMachines::Transition.new(record, machine, :ignite, :parked, :idling)
    transition.perform
    assert_equal true, after_called
  end

  def test_should_run_around_callbacks
    before_called = false
    after_called = false
    ensure_called = 0
    @machine.around_transition do |block|
      before_called = true
      begin
        block.call
      ensure
        ensure_called += 1
      end
      after_called = true
    end

    @transition.perform
    assert before_called
    assert after_called
    assert_equal ensure_called, 1
  end

  def test_should_include_transition_states_in_known_states
    @machine.before_transition :to => :first_gear, :do => lambda {}

    assert_equal [:parked, :idling, :first_gear], @machine.states.map { |state| state.name }
  end

  def test_should_allow_symbolic_callbacks
    callback_args = nil

    klass = class << @record;
      self;
    end
    klass.send(:define_method, :after_ignite) do |*args|
      callback_args = args
    end

    @machine.before_transition(:after_ignite)

    @transition.perform
    assert_equal [@transition], callback_args
  end

  def test_should_allow_string_callbacks
    class << @record
      attr_reader :callback_result
    end

    @machine.before_transition('@callback_result = [1, 2, 3]')
    @transition.perform

    assert_equal [1, 2, 3], @record.callback_result
  end

  def test_should_run_in_expected_order
    expected = [
        :before_transition, :before_validation, :after_validation,
        :before_save, :before_create, :after_create, :after_save,
        :after_transition
    ]

    callbacks = []
    @model.before_validation { callbacks << :before_validation }
    @model.after_validation { callbacks << :after_validation }
    @model.before_save { callbacks << :before_save }
    @model.before_create { callbacks << :before_create }
    @model.after_create { callbacks << :after_create }
    @model.after_save { callbacks << :after_save }
    @model.after_commit { callbacks << :after_commit }
    expected << :after_commit

    @machine.before_transition { callbacks << :before_transition }
    @machine.after_transition { callbacks << :after_transition }

    @transition.perform

    assert_equal expected, callbacks
  end
end