PageRenderTime 56ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/activesupport/test/callbacks_test.rb

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