~michaelforrest/use-case-mapper/trunk

« back to all changes in this revision

Viewing changes to vendor/rails/activerecord/test/cases/named_scope_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/topic'
4
 
require 'models/comment'
5
 
require 'models/reply'
6
 
require 'models/author'
7
 
require 'models/developer'
8
 
 
9
 
class NamedScopeTest < ActiveRecord::TestCase
10
 
  fixtures :posts, :authors, :topics, :comments, :author_addresses
11
 
 
12
 
  def test_implements_enumerable
13
 
    assert !Topic.find(:all).empty?
14
 
 
15
 
    assert_equal Topic.find(:all),   Topic.base
16
 
    assert_equal Topic.find(:all),   Topic.base.to_a
17
 
    assert_equal Topic.find(:first), Topic.base.first
18
 
    assert_equal Topic.find(:all),   Topic.base.map { |i| i }
19
 
  end
20
 
 
21
 
  def test_found_items_are_cached
22
 
    Topic.columns
23
 
    all_posts = Topic.base
24
 
 
25
 
    assert_queries(1) do
26
 
      all_posts.collect
27
 
      all_posts.collect
28
 
    end
29
 
  end
30
 
 
31
 
  def test_reload_expires_cache_of_found_items
32
 
    all_posts = Topic.base
33
 
    all_posts.inspect
34
 
 
35
 
    new_post = Topic.create!
36
 
    assert !all_posts.include?(new_post)
37
 
    assert all_posts.reload.include?(new_post)
38
 
  end
39
 
 
40
 
  def test_delegates_finds_and_calculations_to_the_base_class
41
 
    assert !Topic.find(:all).empty?
42
 
 
43
 
    assert_equal Topic.find(:all),               Topic.base.find(:all)
44
 
    assert_equal Topic.find(:first),             Topic.base.find(:first)
45
 
    assert_equal Topic.count,                    Topic.base.count
46
 
    assert_equal Topic.average(:replies_count), Topic.base.average(:replies_count)
47
 
  end
48
 
 
49
 
  def test_scope_should_respond_to_own_methods_and_methods_of_the_proxy
50
 
    assert Topic.approved.respond_to?(:proxy_found)
51
 
    assert Topic.approved.respond_to?(:count)
52
 
    assert Topic.approved.respond_to?(:length)
53
 
  end
54
 
 
55
 
  def test_respond_to_respects_include_private_parameter
56
 
    assert !Topic.approved.respond_to?(:load_found)
57
 
    assert Topic.approved.respond_to?(:load_found, true)
58
 
  end
59
 
 
60
 
  def test_subclasses_inherit_scopes
61
 
    assert Topic.scopes.include?(:base)
62
 
 
63
 
    assert Reply.scopes.include?(:base)
64
 
    assert_equal Reply.find(:all), Reply.base
65
 
  end
66
 
 
67
 
  def test_scopes_with_options_limit_finds_to_those_matching_the_criteria_specified
68
 
    assert !Topic.find(:all, :conditions => {:approved => true}).empty?
69
 
 
70
 
    assert_equal Topic.find(:all, :conditions => {:approved => true}), Topic.approved
71
 
    assert_equal Topic.count(:conditions => {:approved => true}), Topic.approved.count
72
 
  end
73
 
 
74
 
  def test_scopes_with_string_name_can_be_composed
75
 
    # NOTE that scopes defined with a string as a name worked on their own
76
 
    # but when called on another scope the other scope was completely replaced
77
 
    assert_equal Topic.replied.approved, Topic.replied.approved_as_string
78
 
  end
79
 
 
80
 
  def test_scopes_can_be_specified_with_deep_hash_conditions
81
 
    assert_equal Topic.replied.approved, Topic.replied.approved_as_hash_condition
82
 
  end
83
 
 
84
 
  def test_scopes_are_composable
85
 
    assert_equal (approved = Topic.find(:all, :conditions => {:approved => true})), Topic.approved
86
 
    assert_equal (replied = Topic.find(:all, :conditions => 'replies_count > 0')), Topic.replied
87
 
    assert !(approved == replied)
88
 
    assert !(approved & replied).empty?
89
 
 
90
 
    assert_equal approved & replied, Topic.approved.replied
91
 
  end
92
 
 
93
 
  def test_procedural_scopes
94
 
    topics_written_before_the_third = Topic.find(:all, :conditions => ['written_on < ?', topics(:third).written_on])
95
 
    topics_written_before_the_second = Topic.find(:all, :conditions => ['written_on < ?', topics(:second).written_on])
96
 
    assert_not_equal topics_written_before_the_second, topics_written_before_the_third
97
 
 
98
 
    assert_equal topics_written_before_the_third, Topic.written_before(topics(:third).written_on)
99
 
    assert_equal topics_written_before_the_second, Topic.written_before(topics(:second).written_on)
100
 
  end
101
 
 
102
 
  def test_procedural_scopes_returning_nil
103
 
    all_topics = Topic.find(:all)
104
 
 
105
 
    assert_equal all_topics, Topic.written_before(nil)
106
 
  end
107
 
 
108
 
  def test_scopes_with_joins
109
 
    address = author_addresses(:david_address)
110
 
    posts_with_authors_at_address = Post.find(
111
 
      :all, :joins => 'JOIN authors ON authors.id = posts.author_id',
112
 
      :conditions => [ 'authors.author_address_id = ?', address.id ]
113
 
    )
114
 
    assert_equal posts_with_authors_at_address, Post.with_authors_at_address(address)
115
 
  end
116
 
 
117
 
  def test_scopes_with_joins_respects_custom_select
118
 
    address = author_addresses(:david_address)
119
 
    posts_with_authors_at_address_titles = Post.find(:all,
120
 
      :select => 'title',
121
 
      :joins => 'JOIN authors ON authors.id = posts.author_id',
122
 
      :conditions => [ 'authors.author_address_id = ?', address.id ]
123
 
    )
124
 
    assert_equal posts_with_authors_at_address_titles, Post.with_authors_at_address(address).find(:all, :select => 'title')
125
 
  end
126
 
 
127
 
  def test_extensions
128
 
    assert_equal 1, Topic.anonymous_extension.one
129
 
    assert_equal 2, Topic.named_extension.two
130
 
  end
131
 
 
132
 
  def test_multiple_extensions
133
 
    assert_equal 2, Topic.multiple_extensions.extension_two
134
 
    assert_equal 1, Topic.multiple_extensions.extension_one
135
 
  end
136
 
 
137
 
  def test_has_many_associations_have_access_to_named_scopes
138
 
    assert_not_equal Post.containing_the_letter_a, authors(:david).posts
139
 
    assert !Post.containing_the_letter_a.empty?
140
 
 
141
 
    assert_equal authors(:david).posts & Post.containing_the_letter_a, authors(:david).posts.containing_the_letter_a
142
 
  end
143
 
 
144
 
  def test_has_many_through_associations_have_access_to_named_scopes
145
 
    assert_not_equal Comment.containing_the_letter_e, authors(:david).comments
146
 
    assert !Comment.containing_the_letter_e.empty?
147
 
 
148
 
    assert_equal authors(:david).comments & Comment.containing_the_letter_e, authors(:david).comments.containing_the_letter_e
149
 
  end
150
 
 
151
 
  def test_named_scopes_honor_current_scopes_from_when_defined
152
 
    assert !Post.ranked_by_comments.limit(5).empty?
153
 
    assert !authors(:david).posts.ranked_by_comments.limit(5).empty?
154
 
    assert_not_equal Post.ranked_by_comments.limit(5), authors(:david).posts.ranked_by_comments.limit(5)
155
 
    assert_not_equal Post.top(5), authors(:david).posts.top(5)
156
 
    assert_equal authors(:david).posts.ranked_by_comments.limit(5), authors(:david).posts.top(5)
157
 
    assert_equal Post.ranked_by_comments.limit(5), Post.top(5)
158
 
  end
159
 
 
160
 
  def test_active_records_have_scope_named__all__
161
 
    assert !Topic.find(:all).empty?
162
 
 
163
 
    assert_equal Topic.find(:all), Topic.base
164
 
  end
165
 
 
166
 
  def test_active_records_have_scope_named__scoped__
167
 
    assert !Topic.find(:all, scope = {:conditions => "content LIKE '%Have%'"}).empty?
168
 
 
169
 
    assert_equal Topic.find(:all, scope), Topic.scoped(scope)
170
 
  end
171
 
 
172
 
  def test_proxy_options
173
 
    expected_proxy_options = { :conditions => { :approved => true } }
174
 
    assert_equal expected_proxy_options, Topic.approved.proxy_options
175
 
  end
176
 
 
177
 
  def test_first_and_last_should_support_find_options
178
 
    assert_equal Topic.base.first(:order => 'title'), Topic.base.find(:first, :order => 'title')
179
 
    assert_equal Topic.base.last(:order => 'title'), Topic.base.find(:last, :order => 'title')
180
 
  end
181
 
 
182
 
  def test_first_and_last_should_allow_integers_for_limit
183
 
    assert_equal Topic.base.first(2), Topic.base.to_a.first(2)
184
 
    assert_equal Topic.base.last(2), Topic.base.to_a.last(2)
185
 
  end
186
 
 
187
 
  def test_first_and_last_should_not_use_query_when_results_are_loaded
188
 
    topics = Topic.base
189
 
    topics.reload # force load
190
 
    assert_no_queries do
191
 
      topics.first
192
 
      topics.last
193
 
    end
194
 
  end
195
 
 
196
 
  def test_first_and_last_find_options_should_use_query_when_results_are_loaded
197
 
    topics = Topic.base
198
 
    topics.reload # force load
199
 
    assert_queries(2) do
200
 
      topics.first(:order => 'title')
201
 
      topics.last(:order => 'title')
202
 
    end
203
 
  end
204
 
 
205
 
  def test_empty_should_not_load_results
206
 
    topics = Topic.base
207
 
    assert_queries(2) do
208
 
      topics.empty?  # use count query
209
 
      topics.collect # force load
210
 
      topics.empty?  # use loaded (no query)
211
 
    end
212
 
  end
213
 
 
214
 
  def test_any_should_not_load_results
215
 
    topics = Topic.base
216
 
    assert_queries(2) do
217
 
      topics.any?    # use count query
218
 
      topics.collect # force load
219
 
      topics.any?    # use loaded (no query)
220
 
    end
221
 
  end
222
 
 
223
 
  def test_any_should_call_proxy_found_if_using_a_block
224
 
    topics = Topic.base
225
 
    assert_queries(1) do
226
 
      topics.expects(:empty?).never
227
 
      topics.any? { true }
228
 
    end
229
 
  end
230
 
 
231
 
  def test_any_should_not_fire_query_if_named_scope_loaded
232
 
    topics = Topic.base
233
 
    topics.collect # force load
234
 
    assert_no_queries { assert topics.any? }
235
 
  end
236
 
 
237
 
  def test_should_build_with_proxy_options
238
 
    topic = Topic.approved.build({})
239
 
    assert topic.approved
240
 
  end
241
 
 
242
 
  def test_should_build_new_with_proxy_options
243
 
    topic = Topic.approved.new
244
 
    assert topic.approved
245
 
  end
246
 
 
247
 
  def test_should_create_with_proxy_options
248
 
    topic = Topic.approved.create({})
249
 
    assert topic.approved
250
 
  end
251
 
 
252
 
  def test_should_create_with_bang_with_proxy_options
253
 
    topic = Topic.approved.create!({})
254
 
    assert topic.approved
255
 
  end
256
 
 
257
 
  def test_should_build_with_proxy_options_chained
258
 
    topic = Topic.approved.by_lifo.build({})
259
 
    assert topic.approved
260
 
    assert_equal 'lifo', topic.author_name
261
 
  end
262
 
 
263
 
  def test_find_all_should_behave_like_select
264
 
    assert_equal Topic.base.select(&:approved), Topic.base.find_all(&:approved)
265
 
  end
266
 
 
267
 
  def test_rand_should_select_a_random_object_from_proxy
268
 
    assert Topic.approved.rand.is_a?(Topic)
269
 
  end
270
 
 
271
 
  def test_should_use_where_in_query_for_named_scope
272
 
    assert_equal Developer.find_all_by_name('Jamis').to_set, Developer.find_all_by_id(Developer.jamises).to_set
273
 
  end
274
 
 
275
 
  def test_size_should_use_count_when_results_are_not_loaded
276
 
    topics = Topic.base
277
 
    assert_queries(1) do
278
 
      assert_sql(/COUNT/i) { topics.size }
279
 
    end
280
 
  end
281
 
 
282
 
  def test_size_should_use_length_when_results_are_loaded
283
 
    topics = Topic.base
284
 
    topics.reload # force load
285
 
    assert_no_queries do
286
 
      topics.size # use loaded (no query)
287
 
    end
288
 
  end
289
 
 
290
 
  def test_chaining_with_duplicate_joins
291
 
    join = "INNER JOIN comments ON comments.post_id = posts.id"
292
 
    post = Post.find(1)
293
 
    assert_equal post.comments.size, Post.scoped(:joins => join).scoped(:joins => join, :conditions => "posts.id = #{post.id}").size
294
 
  end
295
 
 
296
 
  def test_chaining_should_use_latest_conditions_when_creating
297
 
    post = Topic.rejected.new
298
 
    assert !post.approved?
299
 
 
300
 
    post = Topic.rejected.approved.new
301
 
    assert post.approved?
302
 
 
303
 
    post = Topic.approved.rejected.new
304
 
    assert !post.approved?
305
 
 
306
 
    post = Topic.approved.rejected.approved.new
307
 
    assert post.approved?
308
 
  end
309
 
 
310
 
  def test_chaining_should_use_latest_conditions_when_searching
311
 
    # Normal hash conditions
312
 
    assert_equal Topic.all(:conditions => {:approved => true}), Topic.rejected.approved.all
313
 
    assert_equal Topic.all(:conditions => {:approved => false}), Topic.approved.rejected.all
314
 
 
315
 
    # Nested hash conditions with same keys
316
 
    assert_equal [posts(:sti_comments)], Post.with_special_comments.with_very_special_comments.all
317
 
 
318
 
    # Nested hash conditions with different keys
319
 
    assert_equal [posts(:sti_comments)], Post.with_special_comments.with_post(4).all.uniq
320
 
  end
321
 
 
322
 
  def test_named_scopes_batch_finders
323
 
    assert_equal 3, Topic.approved.count
324
 
 
325
 
    assert_queries(4) do
326
 
      Topic.approved.find_each(:batch_size => 1) {|t| assert t.approved? }
327
 
    end
328
 
 
329
 
    assert_queries(2) do
330
 
      Topic.approved.find_in_batches(:batch_size => 2) do |group|
331
 
        group.each {|t| assert t.approved? }
332
 
      end
333
 
    end
334
 
  end
335
 
 
336
 
  def test_table_names_for_chaining_scopes_with_and_without_table_name_included
337
 
    assert_nothing_raised do
338
 
      Comment.for_first_post.for_first_author.all
339
 
    end
340
 
  end
341
 
end
342
 
 
343
 
class DynamicScopeMatchTest < ActiveRecord::TestCase  
344
 
  def test_scoped_by_no_match
345
 
    assert_nil ActiveRecord::DynamicScopeMatch.match("not_scoped_at_all")
346
 
  end
347
 
 
348
 
  def test_scoped_by
349
 
    match = ActiveRecord::DynamicScopeMatch.match("scoped_by_age_and_sex_and_location")
350
 
    assert_not_nil match
351
 
    assert match.scope?
352
 
    assert_equal %w(age sex location), match.attribute_names
353
 
  end
354
 
end
355
 
 
356
 
class DynamicScopeTest < ActiveRecord::TestCase
357
 
  def test_dynamic_scope
358
 
    assert_equal Post.scoped_by_author_id(1).find(1), Post.find(1)
359
 
    assert_equal Post.scoped_by_author_id_and_title(1, "Welcome to the weblog").first, Post.find(:first, :conditions => { :author_id => 1, :title => "Welcome to the weblog"})
360
 
  end
361
 
end