~michaelforrest/use-case-mapper/trunk

« back to all changes in this revision

Viewing changes to vendor/rails/activerecord/test/cases/method_scoping_test.rb

  • Committer: Richard Lee (Canonical)
  • Date: 2010-10-15 15:17:58 UTC
  • mfrom: (190.1.3 use-case-mapper)
  • Revision ID: richard.lee@canonical.com-20101015151758-wcvmfxrexsongf9d
Merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
require "cases/helper"
2
 
require 'models/post'
3
 
require 'models/author'
4
 
require 'models/developer'
5
 
require 'models/project'
6
 
require 'models/comment'
7
 
require 'models/category'
8
 
 
9
 
class MethodScopingTest < ActiveRecord::TestCase
10
 
  fixtures :authors, :developers, :projects, :comments, :posts, :developers_projects
11
 
 
12
 
  def test_set_conditions
13
 
    Developer.with_scope(:find => { :conditions => 'just a test...' }) do
14
 
      assert_equal 'just a test...', Developer.send(:current_scoped_methods)[:find][:conditions]
15
 
    end
16
 
  end
17
 
 
18
 
  def test_scoped_find
19
 
    Developer.with_scope(:find => { :conditions => "name = 'David'" }) do
20
 
      assert_nothing_raised { Developer.find(1) }
21
 
    end
22
 
  end
23
 
 
24
 
  def test_scoped_find_first
25
 
    Developer.with_scope(:find => { :conditions => "salary = 100000" }) do
26
 
      assert_equal Developer.find(10), Developer.find(:first, :order => 'name')
27
 
    end
28
 
  end
29
 
 
30
 
  def test_scoped_find_last
31
 
    highest_salary = Developer.find(:first, :order => "salary DESC")
32
 
 
33
 
    Developer.with_scope(:find => { :order => "salary" }) do
34
 
      assert_equal highest_salary, Developer.last
35
 
    end
36
 
  end
37
 
 
38
 
  def test_scoped_find_last_preserves_scope
39
 
    lowest_salary = Developer.find(:first, :order => "salary ASC")
40
 
    highest_salary = Developer.find(:first, :order => "salary DESC")
41
 
 
42
 
    Developer.with_scope(:find => { :order => "salary" }) do
43
 
      assert_equal highest_salary, Developer.last
44
 
      assert_equal lowest_salary, Developer.first
45
 
    end
46
 
  end
47
 
 
48
 
  def test_scoped_find_combines_conditions
49
 
    Developer.with_scope(:find => { :conditions => "salary = 9000" }) do
50
 
      assert_equal developers(:poor_jamis), Developer.find(:first, :conditions => "name = 'Jamis'")
51
 
    end
52
 
  end
53
 
 
54
 
  def test_scoped_find_sanitizes_conditions
55
 
    Developer.with_scope(:find => { :conditions => ['salary = ?', 9000] }) do
56
 
      assert_equal developers(:poor_jamis), Developer.find(:first)
57
 
    end
58
 
  end
59
 
 
60
 
  def test_scoped_find_combines_and_sanitizes_conditions
61
 
    Developer.with_scope(:find => { :conditions => ['salary = ?', 9000] }) do
62
 
      assert_equal developers(:poor_jamis), Developer.find(:first, :conditions => ['name = ?', 'Jamis'])
63
 
    end
64
 
  end
65
 
 
66
 
  def test_scoped_find_all
67
 
    Developer.with_scope(:find => { :conditions => "name = 'David'" }) do
68
 
      assert_equal [developers(:david)], Developer.find(:all)
69
 
    end
70
 
  end
71
 
 
72
 
  def test_scoped_find_select
73
 
    Developer.with_scope(:find => { :select => "id, name" }) do
74
 
      developer = Developer.find(:first, :conditions => "name = 'David'")
75
 
      assert_equal "David", developer.name
76
 
      assert !developer.has_attribute?(:salary)
77
 
    end
78
 
  end
79
 
 
80
 
  def test_options_select_replaces_scope_select
81
 
    Developer.with_scope(:find => { :select => "id, name" }) do
82
 
      developer = Developer.find(:first, :select => 'id, salary', :conditions => "name = 'David'")
83
 
      assert_equal 80000, developer.salary
84
 
      assert !developer.has_attribute?(:name)
85
 
    end
86
 
  end
87
 
 
88
 
  def test_scoped_count
89
 
    Developer.with_scope(:find => { :conditions => "name = 'David'" }) do
90
 
      assert_equal 1, Developer.count
91
 
    end
92
 
 
93
 
    Developer.with_scope(:find => { :conditions => 'salary = 100000' }) do
94
 
      assert_equal 8, Developer.count
95
 
      assert_equal 1, Developer.count(:conditions => "name LIKE 'fixture_1%'")
96
 
    end
97
 
  end
98
 
 
99
 
  def test_scoped_find_include
100
 
    # with the include, will retrieve only developers for the given project
101
 
    scoped_developers = Developer.with_scope(:find => { :include => :projects }) do
102
 
      Developer.find(:all, :conditions => 'projects.id = 2')
103
 
    end
104
 
    assert scoped_developers.include?(developers(:david))
105
 
    assert !scoped_developers.include?(developers(:jamis))
106
 
    assert_equal 1, scoped_developers.size
107
 
  end
108
 
 
109
 
  def test_scoped_find_joins
110
 
    scoped_developers = Developer.with_scope(:find => { :joins => 'JOIN developers_projects ON id = developer_id' } ) do
111
 
      Developer.find(:all, :conditions => 'developers_projects.project_id = 2')
112
 
    end
113
 
    assert scoped_developers.include?(developers(:david))
114
 
    assert !scoped_developers.include?(developers(:jamis))
115
 
    assert_equal 1, scoped_developers.size
116
 
    assert_equal developers(:david).attributes, scoped_developers.first.attributes
117
 
  end
118
 
 
119
 
  def test_scoped_find_using_new_style_joins
120
 
    scoped_developers = Developer.with_scope(:find => { :joins => :projects }) do
121
 
      Developer.find(:all, :conditions => 'projects.id = 2')
122
 
    end
123
 
    assert scoped_developers.include?(developers(:david))
124
 
    assert !scoped_developers.include?(developers(:jamis))
125
 
    assert_equal 1, scoped_developers.size
126
 
    assert_equal developers(:david).attributes, scoped_developers.first.attributes
127
 
  end
128
 
 
129
 
  def test_scoped_find_merges_old_style_joins
130
 
    scoped_authors = Author.with_scope(:find => { :joins => 'INNER JOIN posts ON authors.id = posts.author_id ' }) do
131
 
      Author.find(:all, :select => 'DISTINCT authors.*', :joins => 'INNER JOIN comments ON posts.id = comments.post_id', :conditions => 'comments.id = 1')
132
 
    end
133
 
    assert scoped_authors.include?(authors(:david))
134
 
    assert !scoped_authors.include?(authors(:mary))
135
 
    assert_equal 1, scoped_authors.size
136
 
    assert_equal authors(:david).attributes, scoped_authors.first.attributes
137
 
  end
138
 
 
139
 
  def test_scoped_find_merges_new_style_joins
140
 
    scoped_authors = Author.with_scope(:find => { :joins => :posts }) do
141
 
      Author.find(:all, :select => 'DISTINCT authors.*', :joins => :comments, :conditions => 'comments.id = 1')
142
 
    end
143
 
    assert scoped_authors.include?(authors(:david))
144
 
    assert !scoped_authors.include?(authors(:mary))
145
 
    assert_equal 1, scoped_authors.size
146
 
    assert_equal authors(:david).attributes, scoped_authors.first.attributes
147
 
  end
148
 
 
149
 
  def test_scoped_find_merges_new_and_old_style_joins
150
 
    scoped_authors = Author.with_scope(:find => { :joins => :posts }) do
151
 
      Author.find(:all, :select => 'DISTINCT authors.*', :joins => 'JOIN comments ON posts.id = comments.post_id', :conditions => 'comments.id = 1')
152
 
    end
153
 
    assert scoped_authors.include?(authors(:david))
154
 
    assert !scoped_authors.include?(authors(:mary))
155
 
    assert_equal 1, scoped_authors.size
156
 
    assert_equal authors(:david).attributes, scoped_authors.first.attributes
157
 
  end
158
 
 
159
 
  def test_scoped_find_merges_string_array_style_and_string_style_joins
160
 
    scoped_authors = Author.with_scope(:find => { :joins => ["INNER JOIN posts ON posts.author_id = authors.id"]}) do
161
 
      Author.find(:all, :select => 'DISTINCT authors.*', :joins => 'INNER JOIN comments ON posts.id = comments.post_id', :conditions => 'comments.id = 1')
162
 
    end
163
 
    assert scoped_authors.include?(authors(:david))
164
 
    assert !scoped_authors.include?(authors(:mary))
165
 
    assert_equal 1, scoped_authors.size
166
 
    assert_equal authors(:david).attributes, scoped_authors.first.attributes
167
 
  end
168
 
 
169
 
  def test_scoped_find_merges_string_array_style_and_hash_style_joins
170
 
    scoped_authors = Author.with_scope(:find => { :joins => :posts}) do
171
 
      Author.find(:all, :select => 'DISTINCT authors.*', :joins => ['INNER JOIN comments ON posts.id = comments.post_id'], :conditions => 'comments.id = 1')
172
 
    end
173
 
    assert scoped_authors.include?(authors(:david))
174
 
    assert !scoped_authors.include?(authors(:mary))
175
 
    assert_equal 1, scoped_authors.size
176
 
    assert_equal authors(:david).attributes, scoped_authors.first.attributes
177
 
  end
178
 
 
179
 
  def test_scoped_find_merges_joins_and_eliminates_duplicate_string_joins
180
 
    scoped_authors = Author.with_scope(:find => { :joins => 'INNER JOIN posts ON posts.author_id = authors.id'}) do
181
 
      Author.find(:all, :select => 'DISTINCT authors.*', :joins => ["INNER JOIN posts ON posts.author_id = authors.id", "INNER JOIN comments ON posts.id = comments.post_id"], :conditions => 'comments.id = 1')
182
 
    end
183
 
    assert scoped_authors.include?(authors(:david))
184
 
    assert !scoped_authors.include?(authors(:mary))
185
 
    assert_equal 1, scoped_authors.size
186
 
    assert_equal authors(:david).attributes, scoped_authors.first.attributes
187
 
  end
188
 
 
189
 
  def test_scoped_find_strips_spaces_from_string_joins_and_eliminates_duplicate_string_joins
190
 
    scoped_authors = Author.with_scope(:find => { :joins => ' INNER JOIN posts ON posts.author_id = authors.id '}) do
191
 
      Author.find(:all, :select => 'DISTINCT authors.*', :joins => ['INNER JOIN posts ON posts.author_id = authors.id'], :conditions => 'posts.id = 1')
192
 
    end
193
 
    assert scoped_authors.include?(authors(:david))
194
 
    assert !scoped_authors.include?(authors(:mary))
195
 
    assert_equal 1, scoped_authors.size
196
 
    assert_equal authors(:david).attributes, scoped_authors.first.attributes
197
 
  end
198
 
 
199
 
  def test_scoped_count_include
200
 
    # with the include, will retrieve only developers for the given project
201
 
    Developer.with_scope(:find => { :include => :projects }) do
202
 
      assert_equal 1, Developer.count(:conditions => 'projects.id = 2')
203
 
    end
204
 
  end
205
 
 
206
 
  def test_scoped_create
207
 
    new_comment = nil
208
 
 
209
 
    VerySpecialComment.with_scope(:create => { :post_id => 1 }) do
210
 
      assert_equal({ :post_id => 1 }, VerySpecialComment.send(:current_scoped_methods)[:create])
211
 
      new_comment = VerySpecialComment.create :body => "Wonderful world"
212
 
    end
213
 
 
214
 
    assert Post.find(1).comments.include?(new_comment)
215
 
  end
216
 
 
217
 
  def test_immutable_scope
218
 
    options = { :conditions => "name = 'David'" }
219
 
    Developer.with_scope(:find => options) do
220
 
      assert_equal %w(David), Developer.find(:all).map { |d| d.name }
221
 
      options[:conditions] = "name != 'David'"
222
 
      assert_equal %w(David), Developer.find(:all).map { |d| d.name }
223
 
    end
224
 
 
225
 
    scope = { :find => { :conditions => "name = 'David'" }}
226
 
    Developer.with_scope(scope) do
227
 
      assert_equal %w(David), Developer.find(:all).map { |d| d.name }
228
 
      scope[:find][:conditions] = "name != 'David'"
229
 
      assert_equal %w(David), Developer.find(:all).map { |d| d.name }
230
 
    end
231
 
  end
232
 
 
233
 
  def test_scoped_with_duck_typing
234
 
    scoping = Struct.new(:method_scoping).new(:find => { :conditions => ["name = ?", 'David'] })
235
 
    Developer.with_scope(scoping) do
236
 
       assert_equal %w(David), Developer.find(:all).map { |d| d.name }
237
 
    end
238
 
  end
239
 
 
240
 
  def test_ensure_that_method_scoping_is_correctly_restored
241
 
    scoped_methods = Developer.instance_eval('current_scoped_methods')
242
 
 
243
 
    begin
244
 
      Developer.with_scope(:find => { :conditions => "name = 'Jamis'" }) do
245
 
        raise "an exception"
246
 
      end
247
 
    rescue
248
 
    end
249
 
    assert_equal scoped_methods, Developer.instance_eval('current_scoped_methods')
250
 
  end
251
 
end
252
 
 
253
 
class NestedScopingTest < ActiveRecord::TestCase
254
 
  fixtures :authors, :developers, :projects, :comments, :posts
255
 
 
256
 
  def test_merge_options
257
 
    Developer.with_scope(:find => { :conditions => 'salary = 80000' }) do
258
 
      Developer.with_scope(:find => { :limit => 10 }) do
259
 
        merged_option = Developer.instance_eval('current_scoped_methods')[:find]
260
 
        assert_equal({ :conditions => 'salary = 80000', :limit => 10 }, merged_option)
261
 
      end
262
 
    end
263
 
  end
264
 
 
265
 
  def test_merge_inner_scope_has_priority
266
 
    Developer.with_scope(:find => { :limit => 5 }) do
267
 
      Developer.with_scope(:find => { :limit => 10 }) do
268
 
        merged_option = Developer.instance_eval('current_scoped_methods')[:find]
269
 
        assert_equal({ :limit => 10 }, merged_option)
270
 
      end
271
 
    end
272
 
  end
273
 
 
274
 
  def test_replace_options
275
 
    Developer.with_scope(:find => { :conditions => "name = 'David'" }) do
276
 
      Developer.with_exclusive_scope(:find => { :conditions => "name = 'Jamis'" }) do
277
 
        assert_equal({:find => { :conditions => "name = 'Jamis'" }}, Developer.instance_eval('current_scoped_methods'))
278
 
        assert_equal({:find => { :conditions => "name = 'Jamis'" }}, Developer.send(:scoped_methods)[-1])
279
 
      end
280
 
    end
281
 
  end
282
 
 
283
 
  def test_append_conditions
284
 
    Developer.with_scope(:find => { :conditions => "name = 'David'" }) do
285
 
      Developer.with_scope(:find => { :conditions => 'salary = 80000' }) do
286
 
        appended_condition = Developer.instance_eval('current_scoped_methods')[:find][:conditions]
287
 
        assert_equal("(name = 'David') AND (salary = 80000)", appended_condition)
288
 
        assert_equal(1, Developer.count)
289
 
      end
290
 
      Developer.with_scope(:find => { :conditions => "name = 'Maiha'" }) do
291
 
        assert_equal(0, Developer.count)
292
 
      end
293
 
    end
294
 
  end
295
 
 
296
 
  def test_merge_and_append_options
297
 
    Developer.with_scope(:find => { :conditions => 'salary = 80000', :limit => 10 }) do
298
 
      Developer.with_scope(:find => { :conditions => "name = 'David'" }) do
299
 
        merged_option = Developer.instance_eval('current_scoped_methods')[:find]
300
 
        assert_equal({ :conditions => "(salary = 80000) AND (name = 'David')", :limit => 10 }, merged_option)
301
 
      end
302
 
    end
303
 
  end
304
 
 
305
 
  def test_nested_scoped_find
306
 
    Developer.with_scope(:find => { :conditions => "name = 'Jamis'" }) do
307
 
      Developer.with_exclusive_scope(:find => { :conditions => "name = 'David'" }) do
308
 
        assert_nothing_raised { Developer.find(1) }
309
 
        assert_equal('David', Developer.find(:first).name)
310
 
      end
311
 
      assert_equal('Jamis', Developer.find(:first).name)
312
 
    end
313
 
  end
314
 
 
315
 
  def test_nested_scoped_find_include
316
 
    Developer.with_scope(:find => { :include => :projects }) do
317
 
      Developer.with_scope(:find => { :conditions => "projects.id = 2" }) do
318
 
        assert_nothing_raised { Developer.find(1) }
319
 
        assert_equal('David', Developer.find(:first).name)
320
 
      end
321
 
    end
322
 
  end
323
 
 
324
 
  def test_nested_scoped_find_merged_include
325
 
    # :include's remain unique and don't "double up" when merging
326
 
    Developer.with_scope(:find => { :include => :projects, :conditions => "projects.id = 2" }) do
327
 
      Developer.with_scope(:find => { :include => :projects }) do
328
 
        assert_equal 1, Developer.instance_eval('current_scoped_methods')[:find][:include].length
329
 
        assert_equal('David', Developer.find(:first).name)
330
 
      end
331
 
    end
332
 
 
333
 
    # the nested scope doesn't remove the first :include
334
 
    Developer.with_scope(:find => { :include => :projects, :conditions => "projects.id = 2" }) do
335
 
      Developer.with_scope(:find => { :include => [] }) do
336
 
        assert_equal 1, Developer.instance_eval('current_scoped_methods')[:find][:include].length
337
 
        assert_equal('David', Developer.find(:first).name)
338
 
      end
339
 
    end
340
 
 
341
 
    # mixing array and symbol include's will merge correctly
342
 
    Developer.with_scope(:find => { :include => [:projects], :conditions => "projects.id = 2" }) do
343
 
      Developer.with_scope(:find => { :include => :projects }) do
344
 
        assert_equal 1, Developer.instance_eval('current_scoped_methods')[:find][:include].length
345
 
        assert_equal('David', Developer.find(:first).name)
346
 
      end
347
 
    end
348
 
  end
349
 
 
350
 
  def test_nested_scoped_find_replace_include
351
 
    Developer.with_scope(:find => { :include => :projects }) do
352
 
      Developer.with_exclusive_scope(:find => { :include => [] }) do
353
 
        assert_equal 0, Developer.instance_eval('current_scoped_methods')[:find][:include].length
354
 
      end
355
 
    end
356
 
  end
357
 
 
358
 
  def test_three_level_nested_exclusive_scoped_find
359
 
    Developer.with_scope(:find => { :conditions => "name = 'Jamis'" }) do
360
 
      assert_equal('Jamis', Developer.find(:first).name)
361
 
 
362
 
      Developer.with_exclusive_scope(:find => { :conditions => "name = 'David'" }) do
363
 
        assert_equal('David', Developer.find(:first).name)
364
 
 
365
 
        Developer.with_exclusive_scope(:find => { :conditions => "name = 'Maiha'" }) do
366
 
          assert_equal(nil, Developer.find(:first))
367
 
        end
368
 
 
369
 
        # ensure that scoping is restored
370
 
        assert_equal('David', Developer.find(:first).name)
371
 
      end
372
 
 
373
 
      # ensure that scoping is restored
374
 
      assert_equal('Jamis', Developer.find(:first).name)
375
 
    end
376
 
  end
377
 
 
378
 
  def test_merged_scoped_find
379
 
    poor_jamis = developers(:poor_jamis)
380
 
    Developer.with_scope(:find => { :conditions => "salary < 100000" }) do
381
 
      Developer.with_scope(:find => { :offset => 1, :order => 'id asc' }) do
382
 
        assert_sql /ORDER BY id asc / do
383
 
          assert_equal(poor_jamis, Developer.find(:first, :order => 'id asc'))
384
 
        end
385
 
      end
386
 
    end
387
 
  end
388
 
 
389
 
  def test_merged_scoped_find_sanitizes_conditions
390
 
    Developer.with_scope(:find => { :conditions => ["name = ?", 'David'] }) do
391
 
      Developer.with_scope(:find => { :conditions => ['salary = ?', 9000] }) do
392
 
        assert_raise(ActiveRecord::RecordNotFound) { developers(:poor_jamis) }
393
 
      end
394
 
    end
395
 
  end
396
 
 
397
 
  def test_nested_scoped_find_combines_and_sanitizes_conditions
398
 
    Developer.with_scope(:find => { :conditions => ["name = ?", 'David'] }) do
399
 
      Developer.with_exclusive_scope(:find => { :conditions => ['salary = ?', 9000] }) do
400
 
        assert_equal developers(:poor_jamis), Developer.find(:first)
401
 
        assert_equal developers(:poor_jamis), Developer.find(:first, :conditions => ['name = ?', 'Jamis'])
402
 
      end
403
 
    end
404
 
  end
405
 
 
406
 
  def test_merged_scoped_find_combines_and_sanitizes_conditions
407
 
    Developer.with_scope(:find => { :conditions => ["name = ?", 'David'] }) do
408
 
      Developer.with_scope(:find => { :conditions => ['salary > ?', 9000] }) do
409
 
        assert_equal %w(David), Developer.find(:all).map { |d| d.name }
410
 
      end
411
 
    end
412
 
  end
413
 
 
414
 
  def test_nested_scoped_create
415
 
    comment = nil
416
 
    Comment.with_scope(:create => { :post_id => 1}) do
417
 
      Comment.with_scope(:create => { :post_id => 2}) do
418
 
        assert_equal({ :post_id => 2 }, Comment.send(:current_scoped_methods)[:create])
419
 
        comment = Comment.create :body => "Hey guys, nested scopes are broken. Please fix!"
420
 
      end
421
 
    end
422
 
    assert_equal 2, comment.post_id
423
 
  end
424
 
 
425
 
  def test_nested_exclusive_scope_for_create
426
 
    comment = nil
427
 
    Comment.with_scope(:create => { :body => "Hey guys, nested scopes are broken. Please fix!" }) do
428
 
      Comment.with_exclusive_scope(:create => { :post_id => 1 }) do
429
 
        assert_equal({ :post_id => 1 }, Comment.send(:current_scoped_methods)[:create])
430
 
        comment = Comment.create :body => "Hey guys"
431
 
      end
432
 
    end
433
 
    assert_equal 1, comment.post_id
434
 
    assert_equal 'Hey guys', comment.body
435
 
  end
436
 
 
437
 
  def test_merged_scoped_find_on_blank_conditions
438
 
    [nil, " ", [], {}].each do |blank|
439
 
      Developer.with_scope(:find => {:conditions => blank}) do
440
 
        Developer.with_scope(:find => {:conditions => blank}) do
441
 
          assert_nothing_raised { Developer.find(:first) }
442
 
        end
443
 
      end
444
 
    end
445
 
  end
446
 
 
447
 
  def test_merged_scoped_find_on_blank_bind_conditions
448
 
    [ [""], ["",{}] ].each do |blank|
449
 
      Developer.with_scope(:find => {:conditions => blank}) do
450
 
        Developer.with_scope(:find => {:conditions => blank}) do
451
 
          assert_nothing_raised { Developer.find(:first) }
452
 
        end
453
 
      end
454
 
    end
455
 
  end
456
 
 
457
 
  def test_immutable_nested_scope
458
 
    options1 = { :conditions => "name = 'Jamis'" }
459
 
    options2 = { :conditions => "name = 'David'" }
460
 
    Developer.with_scope(:find => options1) do
461
 
      Developer.with_exclusive_scope(:find => options2) do
462
 
        assert_equal %w(David), Developer.find(:all).map { |d| d.name }
463
 
        options1[:conditions] = options2[:conditions] = nil
464
 
        assert_equal %w(David), Developer.find(:all).map { |d| d.name }
465
 
      end
466
 
    end
467
 
  end
468
 
 
469
 
  def test_immutable_merged_scope
470
 
    options1 = { :conditions => "name = 'Jamis'" }
471
 
    options2 = { :conditions => "salary > 10000" }
472
 
    Developer.with_scope(:find => options1) do
473
 
      Developer.with_scope(:find => options2) do
474
 
        assert_equal %w(Jamis), Developer.find(:all).map { |d| d.name }
475
 
        options1[:conditions] = options2[:conditions] = nil
476
 
        assert_equal %w(Jamis), Developer.find(:all).map { |d| d.name }
477
 
      end
478
 
    end
479
 
  end
480
 
 
481
 
  def test_ensure_that_method_scoping_is_correctly_restored
482
 
    Developer.with_scope(:find => { :conditions => "name = 'David'" }) do
483
 
      scoped_methods = Developer.instance_eval('current_scoped_methods')
484
 
      begin
485
 
        Developer.with_scope(:find => { :conditions => "name = 'Maiha'" }) do
486
 
          raise "an exception"
487
 
        end
488
 
      rescue
489
 
      end
490
 
      assert_equal scoped_methods, Developer.instance_eval('current_scoped_methods')
491
 
    end
492
 
  end
493
 
 
494
 
  def test_nested_scoped_find_merges_old_style_joins
495
 
    scoped_authors = Author.with_scope(:find => { :joins => 'INNER JOIN posts ON authors.id = posts.author_id' }) do
496
 
      Author.with_scope(:find => { :joins => 'INNER JOIN comments ON posts.id = comments.post_id' }) do
497
 
        Author.find(:all, :select => 'DISTINCT authors.*', :conditions => 'comments.id = 1')
498
 
      end
499
 
    end
500
 
    assert scoped_authors.include?(authors(:david))
501
 
    assert !scoped_authors.include?(authors(:mary))
502
 
    assert_equal 1, scoped_authors.size
503
 
    assert_equal authors(:david).attributes, scoped_authors.first.attributes
504
 
  end
505
 
 
506
 
  def test_nested_scoped_find_merges_new_style_joins
507
 
    scoped_authors = Author.with_scope(:find => { :joins => :posts }) do
508
 
      Author.with_scope(:find => { :joins => :comments }) do
509
 
        Author.find(:all, :select => 'DISTINCT authors.*', :conditions => 'comments.id = 1')
510
 
      end
511
 
    end
512
 
    assert scoped_authors.include?(authors(:david))
513
 
    assert !scoped_authors.include?(authors(:mary))
514
 
    assert_equal 1, scoped_authors.size
515
 
    assert_equal authors(:david).attributes, scoped_authors.first.attributes
516
 
  end
517
 
 
518
 
  def test_nested_scoped_find_merges_new_and_old_style_joins
519
 
    scoped_authors = Author.with_scope(:find => { :joins => :posts }) do
520
 
      Author.with_scope(:find => { :joins => 'INNER JOIN comments ON posts.id = comments.post_id' }) do
521
 
        Author.find(:all, :select => 'DISTINCT authors.*', :joins => '', :conditions => 'comments.id = 1')
522
 
      end
523
 
    end
524
 
    assert scoped_authors.include?(authors(:david))
525
 
    assert !scoped_authors.include?(authors(:mary))
526
 
    assert_equal 1, scoped_authors.size
527
 
    assert_equal authors(:david).attributes, scoped_authors.first.attributes
528
 
  end
529
 
end
530
 
 
531
 
class HasManyScopingTest< ActiveRecord::TestCase
532
 
  fixtures :comments, :posts
533
 
 
534
 
  def setup
535
 
    @welcome = Post.find(1)
536
 
  end
537
 
 
538
 
  def test_forwarding_of_static_methods
539
 
    assert_equal 'a comment...', Comment.what_are_you
540
 
    assert_equal 'a comment...', @welcome.comments.what_are_you
541
 
  end
542
 
 
543
 
  def test_forwarding_to_scoped
544
 
    assert_equal 4, Comment.search_by_type('Comment').size
545
 
    assert_equal 2, @welcome.comments.search_by_type('Comment').size
546
 
  end
547
 
 
548
 
  def test_forwarding_to_dynamic_finders
549
 
    assert_equal 4, Comment.find_all_by_type('Comment').size
550
 
    assert_equal 2, @welcome.comments.find_all_by_type('Comment').size
551
 
  end
552
 
 
553
 
  def test_nested_scope
554
 
    Comment.with_scope(:find => { :conditions => '1=1' }) do
555
 
      assert_equal 'a comment...', @welcome.comments.what_are_you
556
 
    end
557
 
  end
558
 
end
559
 
 
560
 
class HasAndBelongsToManyScopingTest< ActiveRecord::TestCase
561
 
  fixtures :posts, :categories, :categories_posts
562
 
 
563
 
  def setup
564
 
    @welcome = Post.find(1)
565
 
  end
566
 
 
567
 
  def test_forwarding_of_static_methods
568
 
    assert_equal 'a category...', Category.what_are_you
569
 
    assert_equal 'a category...', @welcome.categories.what_are_you
570
 
  end
571
 
 
572
 
  def test_forwarding_to_dynamic_finders
573
 
    assert_equal 4, Category.find_all_by_type('SpecialCategory').size
574
 
    assert_equal 0, @welcome.categories.find_all_by_type('SpecialCategory').size
575
 
    assert_equal 2, @welcome.categories.find_all_by_type('Category').size
576
 
  end
577
 
 
578
 
  def test_nested_scope
579
 
    Category.with_scope(:find => { :conditions => '1=1' }) do
580
 
      assert_equal 'a comment...', @welcome.comments.what_are_you
581
 
    end
582
 
  end
583
 
end
584
 
 
585
 
class DefaultScopingTest < ActiveRecord::TestCase
586
 
  fixtures :developers
587
 
 
588
 
  def test_default_scope
589
 
    expected = Developer.find(:all, :order => 'salary DESC').collect { |dev| dev.salary }
590
 
    received = DeveloperOrderedBySalary.find(:all).collect { |dev| dev.salary }
591
 
    assert_equal expected, received
592
 
  end
593
 
 
594
 
  def test_default_scope_with_conditions_string
595
 
    assert_equal Developer.find_all_by_name('David').map(&:id).sort, DeveloperCalledDavid.all.map(&:id).sort
596
 
    assert_equal nil, DeveloperCalledDavid.create!.name
597
 
  end
598
 
 
599
 
  def test_default_scope_with_conditions_hash
600
 
    assert_equal Developer.find_all_by_name('Jamis').map(&:id).sort, DeveloperCalledJamis.all.map(&:id).sort
601
 
    assert_equal 'Jamis', DeveloperCalledJamis.create!.name
602
 
  end
603
 
 
604
 
  def test_default_scoping_with_threads
605
 
    scope = [{ :create => {}, :find => { :order => 'salary DESC' } }]
606
 
 
607
 
    2.times do
608
 
      Thread.new { assert_equal scope, DeveloperOrderedBySalary.send(:scoped_methods) }.join
609
 
    end
610
 
  end
611
 
 
612
 
  def test_default_scoping_with_inheritance
613
 
    scope = [{ :create => {}, :find => { :order => 'salary DESC' } }]
614
 
 
615
 
    # Inherit a class having a default scope and define a new default scope
616
 
    klass = Class.new(DeveloperOrderedBySalary)
617
 
    klass.send :default_scope, {}
618
 
 
619
 
    # Scopes added on children should append to parent scope
620
 
    expected_klass_scope = [{ :create => {}, :find => { :order => 'salary DESC' }}, { :create => {}, :find => {} }]
621
 
    assert_equal expected_klass_scope, klass.send(:scoped_methods)
622
 
 
623
 
    # Parent should still have the original scope
624
 
    assert_equal scope, DeveloperOrderedBySalary.send(:scoped_methods)
625
 
  end
626
 
 
627
 
  def test_method_scope
628
 
    expected = Developer.find(:all, :order => 'name DESC').collect { |dev| dev.salary }
629
 
    received = DeveloperOrderedBySalary.all_ordered_by_name.collect { |dev| dev.salary }
630
 
    assert_equal expected, received
631
 
  end
632
 
 
633
 
  def test_nested_scope
634
 
    expected = Developer.find(:all, :order => 'name DESC').collect { |dev| dev.salary }
635
 
    received = DeveloperOrderedBySalary.with_scope(:find => { :order => 'name DESC'}) do
636
 
      DeveloperOrderedBySalary.find(:all).collect { |dev| dev.salary }
637
 
    end
638
 
    assert_equal expected, received
639
 
  end
640
 
 
641
 
  def test_named_scope_overwrites_default
642
 
    expected = Developer.find(:all, :order => 'name DESC').collect { |dev| dev.name }
643
 
    received = DeveloperOrderedBySalary.by_name.find(:all).collect { |dev| dev.name }
644
 
    assert_equal expected, received
645
 
  end
646
 
 
647
 
  def test_nested_exclusive_scope
648
 
    expected = Developer.find(:all, :limit => 100).collect { |dev| dev.salary }
649
 
    received = DeveloperOrderedBySalary.with_exclusive_scope(:find => { :limit => 100 }) do
650
 
      DeveloperOrderedBySalary.find(:all).collect { |dev| dev.salary }
651
 
    end
652
 
    assert_equal expected, received
653
 
  end
654
 
 
655
 
  def test_overwriting_default_scope
656
 
    expected = Developer.find(:all, :order => 'salary').collect { |dev| dev.salary }
657
 
    received = DeveloperOrderedBySalary.find(:all, :order => 'salary').collect { |dev| dev.salary }
658
 
    assert_equal expected, received
659
 
  end
660
 
end
661
 
 
662
 
=begin
663
 
# We disabled the scoping for has_one and belongs_to as we can't think of a proper use case
664
 
 
665
 
class BelongsToScopingTest< ActiveRecord::TestCase
666
 
  fixtures :comments, :posts
667
 
 
668
 
  def setup
669
 
    @greetings = Comment.find(1)
670
 
  end
671
 
 
672
 
  def test_forwarding_of_static_method
673
 
    assert_equal 'a post...', Post.what_are_you
674
 
    assert_equal 'a post...', @greetings.post.what_are_you
675
 
  end
676
 
 
677
 
  def test_forwarding_to_dynamic_finders
678
 
    assert_equal 4, Post.find_all_by_type('Post').size
679
 
    assert_equal 1, @greetings.post.find_all_by_type('Post').size
680
 
  end
681
 
 
682
 
end
683
 
 
684
 
class HasOneScopingTest< ActiveRecord::TestCase
685
 
  fixtures :comments, :posts
686
 
 
687
 
  def setup
688
 
    @sti_comments = Post.find(4)
689
 
  end
690
 
 
691
 
  def test_forwarding_of_static_methods
692
 
    assert_equal 'a comment...', Comment.what_are_you
693
 
    assert_equal 'a very special comment...', @sti_comments.very_special_comment.what_are_you
694
 
  end
695
 
 
696
 
  def test_forwarding_to_dynamic_finders
697
 
    assert_equal 1, Comment.find_all_by_type('VerySpecialComment').size
698
 
    assert_equal 1, @sti_comments.very_special_comment.find_all_by_type('VerySpecialComment').size
699
 
    assert_equal 0, @sti_comments.very_special_comment.find_all_by_type('Comment').size
700
 
  end
701
 
 
702
 
end
703
 
 
704
 
=end