PageRenderTime 54ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/activesupport/test/new_callbacks_test.rb

https://bitbucket.org/nicksieger/rails
Ruby | 384 lines | 320 code | 59 blank | 5 comment | 6 complexity | 009e439811e82907da3c6b2e5d935ce3 MD5 | raw file
  1. # require 'abstract_unit'
  2. require 'test/unit'
  3. $:.unshift "#{File.dirname(__FILE__)}/../lib"
  4. require 'active_support'
  5. module NewCallbacksTest
  6. class Record
  7. include ActiveSupport::NewCallbacks
  8. define_callbacks :save
  9. def self.before_save(*filters, &blk)
  10. save_callback(:before, *filters, &blk)
  11. end
  12. def self.after_save(*filters, &blk)
  13. save_callback(:after, *filters, &blk)
  14. end
  15. class << self
  16. def callback_symbol(callback_method)
  17. method_name = :"#{callback_method}_method"
  18. define_method(method_name) do
  19. history << [callback_method, :symbol]
  20. end
  21. method_name
  22. end
  23. def callback_string(callback_method)
  24. "history << [#{callback_method.to_sym.inspect}, :string]"
  25. end
  26. def callback_proc(callback_method)
  27. Proc.new { |model| model.history << [callback_method, :proc] }
  28. end
  29. def callback_object(callback_method)
  30. klass = Class.new
  31. klass.send(:define_method, callback_method) do |model|
  32. model.history << [callback_method, :object]
  33. end
  34. klass.new
  35. end
  36. end
  37. def history
  38. @history ||= []
  39. end
  40. end
  41. class Person < Record
  42. [:before_save, :after_save].each do |callback_method|
  43. callback_method_sym = callback_method.to_sym
  44. send(callback_method, callback_symbol(callback_method_sym))
  45. send(callback_method, callback_string(callback_method_sym))
  46. send(callback_method, callback_proc(callback_method_sym))
  47. send(callback_method, callback_object(callback_method_sym))
  48. send(callback_method) { |model| model.history << [callback_method_sym, :block] }
  49. end
  50. def save
  51. _run_save_callbacks {}
  52. end
  53. end
  54. class PersonSkipper < Person
  55. skip_save_callback :before, :before_save_method, :if => :yes
  56. skip_save_callback :after, :before_save_method, :unless => :yes
  57. skip_save_callback :after, :before_save_method, :if => :no
  58. skip_save_callback :before, :before_save_method, :unless => :no
  59. def yes; true; end
  60. def no; false; end
  61. end
  62. class ParentController
  63. include ActiveSupport::NewCallbacks
  64. define_callbacks :dispatch
  65. dispatch_callback :before, :log, :per_key => {:unless => proc {|c| c.action_name == :index || c.action_name == :show }}
  66. dispatch_callback :after, :log2
  67. attr_reader :action_name, :logger
  68. def initialize(action_name)
  69. @action_name, @logger = action_name, []
  70. end
  71. def log
  72. @logger << action_name
  73. end
  74. def log2
  75. @logger << action_name
  76. end
  77. def dispatch
  78. _run_dispatch_callbacks(action_name) {
  79. @logger << "Done"
  80. }
  81. self
  82. end
  83. end
  84. class Child < ParentController
  85. skip_dispatch_callback :before, :log, :per_key => {:if => proc {|c| c.action_name == :update} }
  86. skip_dispatch_callback :after, :log2
  87. end
  88. class OneTimeCompile < Record
  89. @@starts_true, @@starts_false = true, false
  90. def initialize
  91. super
  92. end
  93. before_save Proc.new {|r| r.history << [:before_save, :starts_true, :if] }, :per_key => {:if => :starts_true}
  94. before_save Proc.new {|r| r.history << [:before_save, :starts_false, :if] }, :per_key => {:if => :starts_false}
  95. before_save Proc.new {|r| r.history << [:before_save, :starts_true, :unless] }, :per_key => {:unless => :starts_true}
  96. before_save Proc.new {|r| r.history << [:before_save, :starts_false, :unless] }, :per_key => {:unless => :starts_false}
  97. def starts_true
  98. if @@starts_true
  99. @@starts_true = false
  100. return true
  101. end
  102. @@starts_true
  103. end
  104. def starts_false
  105. unless @@starts_false
  106. @@starts_false = true
  107. return false
  108. end
  109. @@starts_false
  110. end
  111. def save
  112. _run_save_callbacks(:action) {}
  113. end
  114. end
  115. class OneTimeCompileTest < Test::Unit::TestCase
  116. def test_optimized_first_compile
  117. around = OneTimeCompile.new
  118. around.save
  119. assert_equal [
  120. [:before_save, :starts_true, :if],
  121. [:before_save, :starts_true, :unless]
  122. ], around.history
  123. end
  124. end
  125. class ConditionalPerson < Record
  126. # proc
  127. before_save Proc.new { |r| r.history << [:before_save, :proc] }, :if => Proc.new { |r| true }
  128. before_save Proc.new { |r| r.history << "b00m" }, :if => Proc.new { |r| false }
  129. before_save Proc.new { |r| r.history << [:before_save, :proc] }, :unless => Proc.new { |r| false }
  130. before_save Proc.new { |r| r.history << "b00m" }, :unless => Proc.new { |r| true }
  131. # symbol
  132. before_save Proc.new { |r| r.history << [:before_save, :symbol] }, :if => :yes
  133. before_save Proc.new { |r| r.history << "b00m" }, :if => :no
  134. before_save Proc.new { |r| r.history << [:before_save, :symbol] }, :unless => :no
  135. before_save Proc.new { |r| r.history << "b00m" }, :unless => :yes
  136. # string
  137. before_save Proc.new { |r| r.history << [:before_save, :string] }, :if => 'yes'
  138. before_save Proc.new { |r| r.history << "b00m" }, :if => 'no'
  139. before_save Proc.new { |r| r.history << [:before_save, :string] }, :unless => 'no'
  140. before_save Proc.new { |r| r.history << "b00m" }, :unless => 'yes'
  141. # Combined if and unless
  142. before_save Proc.new { |r| r.history << [:before_save, :combined_symbol] }, :if => :yes, :unless => :no
  143. before_save Proc.new { |r| r.history << "b00m" }, :if => :yes, :unless => :yes
  144. def yes; true; end
  145. def other_yes; true; end
  146. def no; false; end
  147. def other_no; false; end
  148. def save
  149. _run_save_callbacks {}
  150. end
  151. end
  152. class MySuper
  153. include ActiveSupport::NewCallbacks
  154. define_callbacks :save
  155. end
  156. class AroundPerson < MySuper
  157. attr_reader :history
  158. save_callback :before, :nope, :if => :no
  159. save_callback :before, :nope, :unless => :yes
  160. save_callback :after, :tweedle
  161. save_callback :before, "tweedle_dee"
  162. save_callback :before, proc {|m| m.history << "yup" }
  163. save_callback :before, :nope, :if => proc { false }
  164. save_callback :before, :nope, :unless => proc { true }
  165. save_callback :before, :yup, :if => proc { true }
  166. save_callback :before, :yup, :unless => proc { false }
  167. save_callback :around, :tweedle_dum
  168. save_callback :around, :w0tyes, :if => :yes
  169. save_callback :around, :w0tno, :if => :no
  170. save_callback :around, :tweedle_deedle
  171. def no; false; end
  172. def yes; true; end
  173. def nope
  174. @history << "boom"
  175. end
  176. def yup
  177. @history << "yup"
  178. end
  179. def w0tyes
  180. @history << "w0tyes before"
  181. yield
  182. @history << "w0tyes after"
  183. end
  184. def w0tno
  185. @history << "boom"
  186. yield
  187. end
  188. def tweedle_dee
  189. @history << "tweedle dee"
  190. end
  191. def tweedle_dum
  192. @history << "tweedle dum pre"
  193. yield
  194. @history << "tweedle dum post"
  195. end
  196. def tweedle
  197. @history << "tweedle"
  198. end
  199. def tweedle_deedle
  200. @history << "tweedle deedle pre"
  201. yield
  202. @history << "tweedle deedle post"
  203. end
  204. def initialize
  205. @history = []
  206. end
  207. def save
  208. _run_save_callbacks do
  209. @history << "running"
  210. end
  211. end
  212. end
  213. class AroundCallbacksTest < Test::Unit::TestCase
  214. def test_save_around
  215. around = AroundPerson.new
  216. around.save
  217. assert_equal [
  218. "tweedle dee",
  219. "yup", "yup",
  220. "tweedle dum pre",
  221. "w0tyes before",
  222. "tweedle deedle pre",
  223. "running",
  224. "tweedle deedle post",
  225. "w0tyes after",
  226. "tweedle dum post",
  227. "tweedle"
  228. ], around.history
  229. end
  230. end
  231. class SkipCallbacksTest < Test::Unit::TestCase
  232. def test_skip_person
  233. person = PersonSkipper.new
  234. assert_equal [], person.history
  235. person.save
  236. assert_equal [
  237. [:before_save, :string],
  238. [:before_save, :proc],
  239. [:before_save, :object],
  240. [:before_save, :block],
  241. [:after_save, :block],
  242. [:after_save, :object],
  243. [:after_save, :proc],
  244. [:after_save, :string],
  245. [:after_save, :symbol]
  246. ], person.history
  247. end
  248. end
  249. class CallbacksTest < Test::Unit::TestCase
  250. def test_save_person
  251. person = Person.new
  252. assert_equal [], person.history
  253. person.save
  254. assert_equal [
  255. [:before_save, :symbol],
  256. [:before_save, :string],
  257. [:before_save, :proc],
  258. [:before_save, :object],
  259. [:before_save, :block],
  260. [:after_save, :block],
  261. [:after_save, :object],
  262. [:after_save, :proc],
  263. [:after_save, :string],
  264. [:after_save, :symbol]
  265. ], person.history
  266. end
  267. end
  268. class ConditionalCallbackTest < Test::Unit::TestCase
  269. def test_save_conditional_person
  270. person = ConditionalPerson.new
  271. person.save
  272. assert_equal [
  273. [:before_save, :proc],
  274. [:before_save, :proc],
  275. [:before_save, :symbol],
  276. [:before_save, :symbol],
  277. [:before_save, :string],
  278. [:before_save, :string],
  279. [:before_save, :combined_symbol],
  280. ], person.history
  281. end
  282. end
  283. class CallbackTerminator
  284. include ActiveSupport::NewCallbacks
  285. define_callbacks :save, "result == :halt"
  286. save_callback :before, :first
  287. save_callback :before, :second
  288. save_callback :around, :around_it
  289. save_callback :before, :third
  290. save_callback :after, :first
  291. save_callback :around, :around_it
  292. save_callback :after, :second
  293. save_callback :around, :around_it
  294. save_callback :after, :third
  295. attr_reader :history
  296. def initialize
  297. @history = []
  298. end
  299. def around_it
  300. @history << "around1"
  301. yield
  302. @history << "around2"
  303. end
  304. def first
  305. @history << "first"
  306. end
  307. def second
  308. @history << "second"
  309. :halt
  310. end
  311. def third
  312. @history << "third"
  313. end
  314. def save
  315. _run_save_callbacks
  316. end
  317. end
  318. class CallbackTerminatorTest < Test::Unit::TestCase
  319. def test_termination
  320. terminator = CallbackTerminator.new
  321. terminator.save
  322. assert_equal ["first", "second", "third", "second", "first"], terminator.history
  323. end
  324. end
  325. end