PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/rails/activerecord/test/method_scoping_test.rb

https://github.com/bricooke/my-biz-expenses
Ruby | 416 lines | 307 code | 57 blank | 52 comment | 2 complexity | 86ca8b47252ab139938edcc39c05e248 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, BSD-3-Clause
  1. require 'abstract_unit'
  2. require 'fixtures/developer'
  3. require 'fixtures/project'
  4. require 'fixtures/comment'
  5. require 'fixtures/post'
  6. require 'fixtures/category'
  7. class MethodScopingTest < Test::Unit::TestCase
  8. fixtures :developers, :projects, :comments, :posts
  9. def test_set_conditions
  10. Developer.with_scope(:find => { :conditions => 'just a test...' }) do
  11. assert_equal 'just a test...', Developer.send(:current_scoped_methods)[:find][:conditions]
  12. end
  13. end
  14. def test_scoped_find
  15. Developer.with_scope(:find => { :conditions => "name = 'David'" }) do
  16. assert_nothing_raised { Developer.find(1) }
  17. end
  18. end
  19. def test_scoped_find_first
  20. Developer.with_scope(:find => { :conditions => "salary = 100000" }) do
  21. assert_equal Developer.find(10), Developer.find(:first, :order => 'name')
  22. end
  23. end
  24. def test_scoped_find_combines_conditions
  25. Developer.with_scope(:find => { :conditions => "salary = 9000" }) do
  26. assert_equal developers(:poor_jamis), Developer.find(:first, :conditions => "name = 'Jamis'")
  27. end
  28. end
  29. def test_scoped_find_sanitizes_conditions
  30. Developer.with_scope(:find => { :conditions => ['salary = ?', 9000] }) do
  31. assert_equal developers(:poor_jamis), Developer.find(:first)
  32. end
  33. end
  34. def test_scoped_find_combines_and_sanitizes_conditions
  35. Developer.with_scope(:find => { :conditions => ['salary = ?', 9000] }) do
  36. assert_equal developers(:poor_jamis), Developer.find(:first, :conditions => ['name = ?', 'Jamis'])
  37. end
  38. end
  39. def test_scoped_find_all
  40. Developer.with_scope(:find => { :conditions => "name = 'David'" }) do
  41. assert_equal [developers(:david)], Developer.find(:all)
  42. end
  43. end
  44. def test_scoped_count
  45. Developer.with_scope(:find => { :conditions => "name = 'David'" }) do
  46. assert_equal 1, Developer.count
  47. end
  48. Developer.with_scope(:find => { :conditions => 'salary = 100000' }) do
  49. assert_equal 8, Developer.count
  50. assert_equal 1, Developer.count(:conditions => "name LIKE 'fixture_1%'")
  51. end
  52. end
  53. def test_scoped_find_include
  54. # with the include, will retrieve only developers for the given project
  55. scoped_developers = Developer.with_scope(:find => { :include => :projects }) do
  56. Developer.find(:all, :conditions => 'projects.id = 2')
  57. end
  58. assert scoped_developers.include?(developers(:david))
  59. assert !scoped_developers.include?(developers(:jamis))
  60. assert_equal 1, scoped_developers.size
  61. end
  62. def test_scoped_count_include
  63. # with the include, will retrieve only developers for the given project
  64. Developer.with_scope(:find => { :include => :projects }) do
  65. assert_equal 1, Developer.count(:conditions => 'projects.id = 2')
  66. end
  67. end
  68. def test_scoped_create
  69. new_comment = nil
  70. VerySpecialComment.with_scope(:create => { :post_id => 1 }) do
  71. assert_equal({ :post_id => 1 }, VerySpecialComment.send(:current_scoped_methods)[:create])
  72. new_comment = VerySpecialComment.create :body => "Wonderful world"
  73. end
  74. assert Post.find(1).comments.include?(new_comment)
  75. end
  76. def test_immutable_scope
  77. options = { :conditions => "name = 'David'" }
  78. Developer.with_scope(:find => options) do
  79. assert_equal %w(David), Developer.find(:all).map { |d| d.name }
  80. options[:conditions] = "name != 'David'"
  81. assert_equal %w(David), Developer.find(:all).map { |d| d.name }
  82. end
  83. scope = { :find => { :conditions => "name = 'David'" }}
  84. Developer.with_scope(scope) do
  85. assert_equal %w(David), Developer.find(:all).map { |d| d.name }
  86. scope[:find][:conditions] = "name != 'David'"
  87. assert_equal %w(David), Developer.find(:all).map { |d| d.name }
  88. end
  89. end
  90. def test_scoped_with_duck_typing
  91. scoping = Struct.new(:method_scoping).new(:find => { :conditions => ["name = ?", 'David'] })
  92. Developer.with_scope(scoping) do
  93. assert_equal %w(David), Developer.find(:all).map { |d| d.name }
  94. end
  95. end
  96. def test_ensure_that_method_scoping_is_correctly_restored
  97. scoped_methods = Developer.instance_eval('current_scoped_methods')
  98. begin
  99. Developer.with_scope(:find => { :conditions => "name = 'Jamis'" }) do
  100. raise "an exception"
  101. end
  102. rescue
  103. end
  104. assert_equal scoped_methods, Developer.instance_eval('current_scoped_methods')
  105. end
  106. end
  107. class NestedScopingTest < Test::Unit::TestCase
  108. fixtures :developers, :projects, :comments, :posts
  109. def test_merge_options
  110. Developer.with_scope(:find => { :conditions => 'salary = 80000' }) do
  111. Developer.with_scope(:find => { :limit => 10 }) do
  112. merged_option = Developer.instance_eval('current_scoped_methods')[:find]
  113. assert_equal({ :conditions => 'salary = 80000', :limit => 10 }, merged_option)
  114. end
  115. end
  116. end
  117. def test_replace_options
  118. Developer.with_scope(:find => { :conditions => "name = 'David'" }) do
  119. Developer.with_exclusive_scope(:find => { :conditions => "name = 'Jamis'" }) do
  120. assert_equal({:find => { :conditions => "name = 'Jamis'" }}, Developer.instance_eval('current_scoped_methods'))
  121. assert_equal({:find => { :conditions => "name = 'Jamis'" }}, Developer.send(:scoped_methods)[-1])
  122. end
  123. end
  124. end
  125. def test_append_conditions
  126. Developer.with_scope(:find => { :conditions => "name = 'David'" }) do
  127. Developer.with_scope(:find => { :conditions => 'salary = 80000' }) do
  128. appended_condition = Developer.instance_eval('current_scoped_methods')[:find][:conditions]
  129. assert_equal("( name = 'David' ) AND ( salary = 80000 )", appended_condition)
  130. assert_equal(1, Developer.count)
  131. end
  132. Developer.with_scope(:find => { :conditions => "name = 'Maiha'" }) do
  133. assert_equal(0, Developer.count)
  134. end
  135. end
  136. end
  137. def test_merge_and_append_options
  138. Developer.with_scope(:find => { :conditions => 'salary = 80000', :limit => 10 }) do
  139. Developer.with_scope(:find => { :conditions => "name = 'David'" }) do
  140. merged_option = Developer.instance_eval('current_scoped_methods')[:find]
  141. assert_equal({ :conditions => "( salary = 80000 ) AND ( name = 'David' )", :limit => 10 }, merged_option)
  142. end
  143. end
  144. end
  145. def test_nested_scoped_find
  146. Developer.with_scope(:find => { :conditions => "name = 'Jamis'" }) do
  147. Developer.with_exclusive_scope(:find => { :conditions => "name = 'David'" }) do
  148. assert_nothing_raised { Developer.find(1) }
  149. assert_equal('David', Developer.find(:first).name)
  150. end
  151. assert_equal('Jamis', Developer.find(:first).name)
  152. end
  153. end
  154. def test_nested_scoped_find_include
  155. Developer.with_scope(:find => { :include => :projects }) do
  156. Developer.with_scope(:find => { :conditions => "projects.id = 2" }) do
  157. assert_nothing_raised { Developer.find(1) }
  158. assert_equal('David', Developer.find(:first).name)
  159. end
  160. end
  161. end
  162. def test_nested_scoped_find_merged_include
  163. # :include's remain unique and don't "double up" when merging
  164. Developer.with_scope(:find => { :include => :projects, :conditions => "projects.id = 2" }) do
  165. Developer.with_scope(:find => { :include => :projects }) do
  166. assert_equal 1, Developer.instance_eval('current_scoped_methods')[:find][:include].length
  167. assert_equal('David', Developer.find(:first).name)
  168. end
  169. end
  170. # the nested scope doesn't remove the first :include
  171. Developer.with_scope(:find => { :include => :projects, :conditions => "projects.id = 2" }) do
  172. Developer.with_scope(:find => { :include => [] }) do
  173. assert_equal 1, Developer.instance_eval('current_scoped_methods')[:find][:include].length
  174. assert_equal('David', Developer.find(:first).name)
  175. end
  176. end
  177. # mixing array and symbol include's will merge correctly
  178. Developer.with_scope(:find => { :include => [:projects], :conditions => "projects.id = 2" }) do
  179. Developer.with_scope(:find => { :include => :projects }) do
  180. assert_equal 1, Developer.instance_eval('current_scoped_methods')[:find][:include].length
  181. assert_equal('David', Developer.find(:first).name)
  182. end
  183. end
  184. end
  185. def test_nested_scoped_find_replace_include
  186. Developer.with_scope(:find => { :include => :projects }) do
  187. Developer.with_exclusive_scope(:find => { :include => [] }) do
  188. assert_equal 0, Developer.instance_eval('current_scoped_methods')[:find][:include].length
  189. end
  190. end
  191. end
  192. def test_three_level_nested_exclusive_scoped_find
  193. Developer.with_scope(:find => { :conditions => "name = 'Jamis'" }) do
  194. assert_equal('Jamis', Developer.find(:first).name)
  195. Developer.with_exclusive_scope(:find => { :conditions => "name = 'David'" }) do
  196. assert_equal('David', Developer.find(:first).name)
  197. Developer.with_exclusive_scope(:find => { :conditions => "name = 'Maiha'" }) do
  198. assert_equal(nil, Developer.find(:first))
  199. end
  200. # ensure that scoping is restored
  201. assert_equal('David', Developer.find(:first).name)
  202. end
  203. # ensure that scoping is restored
  204. assert_equal('Jamis', Developer.find(:first).name)
  205. end
  206. end
  207. def test_merged_scoped_find
  208. poor_jamis = developers(:poor_jamis)
  209. Developer.with_scope(:find => { :conditions => "salary < 100000" }) do
  210. Developer.with_scope(:find => { :offset => 1 }) do
  211. assert_equal(poor_jamis, Developer.find(:first, :order => 'id asc'))
  212. end
  213. end
  214. end
  215. def test_merged_scoped_find_sanitizes_conditions
  216. Developer.with_scope(:find => { :conditions => ["name = ?", 'David'] }) do
  217. Developer.with_scope(:find => { :conditions => ['salary = ?', 9000] }) do
  218. assert_raise(ActiveRecord::RecordNotFound) { developers(:poor_jamis) }
  219. end
  220. end
  221. end
  222. def test_nested_scoped_find_combines_and_sanitizes_conditions
  223. Developer.with_scope(:find => { :conditions => ["name = ?", 'David'] }) do
  224. Developer.with_exclusive_scope(:find => { :conditions => ['salary = ?', 9000] }) do
  225. assert_equal developers(:poor_jamis), Developer.find(:first)
  226. assert_equal developers(:poor_jamis), Developer.find(:first, :conditions => ['name = ?', 'Jamis'])
  227. end
  228. end
  229. end
  230. def test_merged_scoped_find_combines_and_sanitizes_conditions
  231. Developer.with_scope(:find => { :conditions => ["name = ?", 'David'] }) do
  232. Developer.with_scope(:find => { :conditions => ['salary > ?', 9000] }) do
  233. assert_equal %w(David), Developer.find(:all).map { |d| d.name }
  234. end
  235. end
  236. end
  237. def test_immutable_nested_scope
  238. options1 = { :conditions => "name = 'Jamis'" }
  239. options2 = { :conditions => "name = 'David'" }
  240. Developer.with_scope(:find => options1) do
  241. Developer.with_exclusive_scope(:find => options2) do
  242. assert_equal %w(David), Developer.find(:all).map { |d| d.name }
  243. options1[:conditions] = options2[:conditions] = nil
  244. assert_equal %w(David), Developer.find(:all).map { |d| d.name }
  245. end
  246. end
  247. end
  248. def test_immutable_merged_scope
  249. options1 = { :conditions => "name = 'Jamis'" }
  250. options2 = { :conditions => "salary > 10000" }
  251. Developer.with_scope(:find => options1) do
  252. Developer.with_scope(:find => options2) do
  253. assert_equal %w(Jamis), Developer.find(:all).map { |d| d.name }
  254. options1[:conditions] = options2[:conditions] = nil
  255. assert_equal %w(Jamis), Developer.find(:all).map { |d| d.name }
  256. end
  257. end
  258. end
  259. def test_ensure_that_method_scoping_is_correctly_restored
  260. Developer.with_scope(:find => { :conditions => "name = 'David'" }) do
  261. scoped_methods = Developer.instance_eval('current_scoped_methods')
  262. begin
  263. Developer.with_scope(:find => { :conditions => "name = 'Maiha'" }) do
  264. raise "an exception"
  265. end
  266. rescue
  267. end
  268. assert_equal scoped_methods, Developer.instance_eval('current_scoped_methods')
  269. end
  270. end
  271. end
  272. class HasManyScopingTest< Test::Unit::TestCase
  273. fixtures :comments, :posts
  274. def setup
  275. @welcome = Post.find(1)
  276. end
  277. def test_forwarding_of_static_methods
  278. assert_equal 'a comment...', Comment.what_are_you
  279. assert_equal 'a comment...', @welcome.comments.what_are_you
  280. end
  281. def test_forwarding_to_scoped
  282. assert_equal 4, Comment.search_by_type('Comment').size
  283. assert_equal 2, @welcome.comments.search_by_type('Comment').size
  284. end
  285. def test_forwarding_to_dynamic_finders
  286. assert_equal 4, Comment.find_all_by_type('Comment').size
  287. assert_equal 2, @welcome.comments.find_all_by_type('Comment').size
  288. end
  289. def test_nested_scope
  290. Comment.with_scope(:find => { :conditions => '1=1' }) do
  291. assert_equal 'a comment...', @welcome.comments.what_are_you
  292. end
  293. end
  294. end
  295. class HasAndBelongsToManyScopingTest< Test::Unit::TestCase
  296. fixtures :posts, :categories, :categories_posts
  297. def setup
  298. @welcome = Post.find(1)
  299. end
  300. def test_forwarding_of_static_methods
  301. assert_equal 'a category...', Category.what_are_you
  302. assert_equal 'a category...', @welcome.categories.what_are_you
  303. end
  304. def test_forwarding_to_dynamic_finders
  305. assert_equal 4, Category.find_all_by_type('SpecialCategory').size
  306. assert_equal 0, @welcome.categories.find_all_by_type('SpecialCategory').size
  307. assert_equal 2, @welcome.categories.find_all_by_type('Category').size
  308. end
  309. def test_nested_scope
  310. Category.with_scope(:find => { :conditions => '1=1' }) do
  311. assert_equal 'a comment...', @welcome.comments.what_are_you
  312. end
  313. end
  314. end
  315. =begin
  316. # We disabled the scoping for has_one and belongs_to as we can't think of a proper use case
  317. class BelongsToScopingTest< Test::Unit::TestCase
  318. fixtures :comments, :posts
  319. def setup
  320. @greetings = Comment.find(1)
  321. end
  322. def test_forwarding_of_static_method
  323. assert_equal 'a post...', Post.what_are_you
  324. assert_equal 'a post...', @greetings.post.what_are_you
  325. end
  326. def test_forwarding_to_dynamic_finders
  327. assert_equal 4, Post.find_all_by_type('Post').size
  328. assert_equal 1, @greetings.post.find_all_by_type('Post').size
  329. end
  330. end
  331. class HasOneScopingTest< Test::Unit::TestCase
  332. fixtures :comments, :posts
  333. def setup
  334. @sti_comments = Post.find(4)
  335. end
  336. def test_forwarding_of_static_methods
  337. assert_equal 'a comment...', Comment.what_are_you
  338. assert_equal 'a very special comment...', @sti_comments.very_special_comment.what_are_you
  339. end
  340. def test_forwarding_to_dynamic_finders
  341. assert_equal 1, Comment.find_all_by_type('VerySpecialComment').size
  342. assert_equal 1, @sti_comments.very_special_comment.find_all_by_type('VerySpecialComment').size
  343. assert_equal 0, @sti_comments.very_special_comment.find_all_by_type('Comment').size
  344. end
  345. end
  346. =end