;]
[askyou.git] / vendor / rails / activesupport / test / callbacks_test.rb
blob2bc2e1eaf06d26b4e8557ddb9d4eb31c268184c9
1 require 'abstract_unit'
3 class Record
4   include ActiveSupport::Callbacks
6   define_callbacks :before_save, :after_save
8   class << self
9     def callback_symbol(callback_method)
10       returning("#{callback_method}_method") do |method_name|
11         define_method(method_name) do
12           history << [callback_method, :symbol]
13         end
14       end
15     end
17     def callback_string(callback_method)
18       "history << [#{callback_method.to_sym.inspect}, :string]"
19     end
21     def callback_proc(callback_method)
22       Proc.new { |model| model.history << [callback_method, :proc] }
23     end
25     def callback_object(callback_method)
26       klass = Class.new
27       klass.send(:define_method, callback_method) do |model|
28         model.history << [callback_method, :object]
29       end
30       klass.new
31     end
32   end
34   def history
35     @history ||= []
36   end
37 end
39 class Person < Record
40   [:before_save, :after_save].each do |callback_method|
41     callback_method_sym = callback_method.to_sym
42     send(callback_method, callback_symbol(callback_method_sym))
43     send(callback_method, callback_string(callback_method_sym))
44     send(callback_method, callback_proc(callback_method_sym))
45     send(callback_method, callback_object(callback_method_sym))
46     send(callback_method) { |model| model.history << [callback_method_sym, :block] }
47   end
49   def save
50     run_callbacks(:before_save)
51     run_callbacks(:after_save)
52   end
53 end
55 class ConditionalPerson < Record
56   # proc
57   before_save Proc.new { |r| r.history << [:before_save, :proc] }, :if => Proc.new { |r| true }
58   before_save Proc.new { |r| r.history << "b00m" }, :if => Proc.new { |r| false }
59   before_save Proc.new { |r| r.history << [:before_save, :proc] }, :unless => Proc.new { |r| false }
60   before_save Proc.new { |r| r.history << "b00m" }, :unless => Proc.new { |r| true }
61   # symbol
62   before_save Proc.new { |r| r.history << [:before_save, :symbol] }, :if => :yes
63   before_save Proc.new { |r| r.history << "b00m" }, :if => :no
64   before_save Proc.new { |r| r.history << [:before_save, :symbol] }, :unless => :no
65   before_save Proc.new { |r| r.history << "b00m" }, :unless => :yes
66   # string
67   before_save Proc.new { |r| r.history << [:before_save, :string] }, :if => 'yes'
68   before_save Proc.new { |r| r.history << "b00m" }, :if => 'no'
69   before_save Proc.new { |r| r.history << [:before_save, :string] }, :unless => 'no'
70   before_save Proc.new { |r| r.history << "b00m" }, :unless => 'yes'
71   # Array with conditions
72   before_save Proc.new { |r| r.history << [:before_save, :symbol_array] }, :if => [:yes, :other_yes]
73   before_save Proc.new { |r| r.history << "b00m" }, :if => [:yes, :no]
74   before_save Proc.new { |r| r.history << [:before_save, :symbol_array] }, :unless => [:no, :other_no]
75   before_save Proc.new { |r| r.history << "b00m" }, :unless => [:yes, :no]
76   # Combined if and unless
77   before_save Proc.new { |r| r.history << [:before_save, :combined_symbol] }, :if => :yes, :unless => :no
78   before_save Proc.new { |r| r.history << "b00m" }, :if => :yes, :unless => :yes
79   # Array with different types of conditions
80   before_save Proc.new { |r| r.history << [:before_save, :symbol_proc_string_array] }, :if => [:yes, Proc.new { |r| true }, 'yes']
81   before_save Proc.new { |r| r.history << "b00m" }, :if => [:yes, Proc.new { |r| true }, 'no']
82   # Array with different types of conditions comibned if and unless
83   before_save Proc.new { |r| r.history << [:before_save, :combined_symbol_proc_string_array] },
84               :if => [:yes, Proc.new { |r| true }, 'yes'], :unless => [:no, 'no']
85   before_save Proc.new { |r| r.history << "b00m" }, :if => [:yes, Proc.new { |r| true }, 'no'], :unless => [:no, 'no']
87   def yes; true; end
88   def other_yes; true; end
89   def no; false; end
90   def other_no; false; end
92   def save
93     run_callbacks(:before_save)
94     run_callbacks(:after_save)
95   end
96 end
98 class CallbacksTest < Test::Unit::TestCase
99   def test_save_person
100     person = Person.new
101     assert_equal [], person.history
102     person.save
103     assert_equal [
104       [:before_save, :symbol],
105       [:before_save, :string],
106       [:before_save, :proc],
107       [:before_save, :object],
108       [:before_save, :block],
109       [:after_save, :symbol],
110       [:after_save, :string],
111       [:after_save, :proc],
112       [:after_save, :object],
113       [:after_save, :block]
114     ], person.history
115   end
118 class ConditionalCallbackTest < Test::Unit::TestCase
119   def test_save_conditional_person
120     person = ConditionalPerson.new
121     person.save
122     assert_equal [
123       [:before_save, :proc],
124       [:before_save, :proc],
125       [:before_save, :symbol],
126       [:before_save, :symbol],
127       [:before_save, :string],
128       [:before_save, :string],
129       [:before_save, :symbol_array],
130       [:before_save, :symbol_array],
131       [:before_save, :combined_symbol],
132       [:before_save, :symbol_proc_string_array],
133       [:before_save, :combined_symbol_proc_string_array]
134     ], person.history
135   end
138 class CallbackTest < Test::Unit::TestCase
139   include ActiveSupport::Callbacks
141   def test_eql
142     callback = Callback.new(:before, :save, :identifier => :lifesaver)
143     assert callback.eql?(Callback.new(:before, :save, :identifier => :lifesaver))
144     assert callback.eql?(Callback.new(:before, :save))
145     assert callback.eql?(:lifesaver)
146     assert callback.eql?(:save)
147     assert !callback.eql?(Callback.new(:before, :destroy))
148     assert !callback.eql?(:destroy)
149   end
151   def test_dup
152     a = Callback.new(:before, :save)
153     assert_equal({}, a.options)
154     b = a.dup
155     b.options[:unless] = :pigs_fly
156     assert_equal({:unless => :pigs_fly}, b.options)
157     assert_equal({}, a.options)
158   end
161 class CallbackChainTest < Test::Unit::TestCase
162   include ActiveSupport::Callbacks
164   def setup
165     @chain = CallbackChain.build(:make, :bacon, :lettuce, :tomato)
166   end
168   def test_build
169     assert_equal 3, @chain.size
170     assert_equal [:bacon, :lettuce, :tomato], @chain.map(&:method)
171   end
173   def test_find
174     assert_equal :bacon, @chain.find(:bacon).method
175   end
177   def test_replace_or_append
178     assert_equal [:bacon, :lettuce, :tomato], (@chain.replace_or_append!(Callback.new(:make, :bacon))).map(&:method)
179     assert_equal [:bacon, :lettuce, :tomato, :turkey], (@chain.replace_or_append!(Callback.new(:make, :turkey))).map(&:method)
180     assert_equal [:bacon, :lettuce, :tomato, :turkey, :mayo], (@chain.replace_or_append!(Callback.new(:make, :mayo))).map(&:method)
181   end
183   def test_delete
184     assert_equal [:bacon, :lettuce, :tomato], @chain.map(&:method)
185     @chain.delete(:bacon)
186     assert_equal [:lettuce, :tomato], @chain.map(&:method)
187   end