4 require 'models/comment'
6 require 'models/author'
7 require 'models/developer'
9 class NamedScopeTest
< ActiveRecord
::TestCase
10 fixtures
:posts, :authors, :topics, :comments, :author_addresses
12 def test_implements_enumerable
13 assert
!Topic
.find(:all).empty
?
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
.each
{ |i
| i
}
21 def test_found_items_are_cached
23 all_posts
= Topic
.base
31 def test_reload_expires_cache_of_found_items
32 all_posts
= Topic
.base
35 new_post
= Topic
.create
!
36 assert
!all_posts
.include?(new_post
)
37 assert all_posts
.reload
.include?(new_post
)
40 def test_delegates_finds_and_calculations_to_the_base_class
41 assert
!Topic
.find(:all).empty
?
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)
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)
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)
60 def test_subclasses_inherit_scopes
61 assert Topic
.scopes
.include?(:base)
63 assert Reply
.scopes
.include?(:base)
64 assert_equal Reply
.find(:all), Reply
.base
67 def test_scopes_with_options_limit_finds_to_those_matching_the_criteria_specified
68 assert
!Topic
.find(:all, :conditions => {:approved => true}).empty
?
70 assert_equal Topic
.find(:all, :conditions => {:approved => true}), Topic
.approved
71 assert_equal Topic
.count(:conditions => {:approved => true}), Topic
.approved
.count
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
80 def test_scopes_can_be_specified_with_deep_hash_conditions
81 assert_equal Topic
.replied
.approved
, Topic
.replied
.approved_as_hash_condition
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
?
90 assert_equal approved
& replied
, Topic
.approved
.replied
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
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
)
102 def test_scopes_with_joins
103 address
= author_addresses(:david_address)
104 posts_with_authors_at_address
= Post
.find(
105 :all, :joins => 'JOIN authors ON authors.id = posts.author_id',
106 :conditions => [ 'authors.author_address_id = ?', address
.id
]
108 assert_equal posts_with_authors_at_address
, Post
.with_authors_at_address(address
)
111 def test_scopes_with_joins_respects_custom_select
112 address
= author_addresses(:david_address)
113 posts_with_authors_at_address_titles
= Post
.find(:all,
115 :joins => 'JOIN authors ON authors.id = posts.author_id',
116 :conditions => [ 'authors.author_address_id = ?', address
.id
]
118 assert_equal posts_with_authors_at_address_titles
, Post
.with_authors_at_address(address
).find(:all, :select => 'title')
122 assert_equal
1, Topic
.anonymous_extension
.one
123 assert_equal
2, Topic
.named_extension
.two
126 def test_multiple_extensions
127 assert_equal
2, Topic
.multiple_extensions
.extension_two
128 assert_equal
1, Topic
.multiple_extensions
.extension_one
131 def test_has_many_associations_have_access_to_named_scopes
132 assert_not_equal Post
.containing_the_letter_a
, authors(:david).posts
133 assert
!Post
.containing_the_letter_a
.empty
?
135 assert_equal
authors(:david).posts
& Post
.containing_the_letter_a
, authors(:david).posts
.containing_the_letter_a
138 def test_has_many_through_associations_have_access_to_named_scopes
139 assert_not_equal Comment
.containing_the_letter_e
, authors(:david).comments
140 assert
!Comment
.containing_the_letter_e
.empty
?
142 assert_equal
authors(:david).comments
& Comment
.containing_the_letter_e
, authors(:david).comments
.containing_the_letter_e
145 def test_active_records_have_scope_named__all__
146 assert
!Topic
.find(:all).empty
?
148 assert_equal Topic
.find(:all), Topic
.base
151 def test_active_records_have_scope_named__scoped__
152 assert
!Topic
.find(:all, scope
= {:conditions => "content LIKE '%Have%'"}).empty
?
154 assert_equal Topic
.find(:all, scope
), Topic
.scoped(scope
)
157 def test_proxy_options
158 expected_proxy_options
= { :conditions => { :approved => true } }
159 assert_equal expected_proxy_options
, Topic
.approved
.proxy_options
162 def test_first_and_last_should_support_find_options
163 assert_equal Topic
.base
.first(:order => 'title'), Topic
.base
.find(:first, :order => 'title')
164 assert_equal Topic
.base
.last(:order => 'title'), Topic
.base
.find(:last, :order => 'title')
167 def test_first_and_last_should_allow_integers_for_limit
168 assert_equal Topic
.base
.first(2), Topic
.base
.to_a
.first(2)
169 assert_equal Topic
.base
.last(2), Topic
.base
.to_a
.last(2)
172 def test_first_and_last_should_not_use_query_when_results_are_loaded
174 topics
.reload
# force load
181 def test_first_and_last_find_options_should_use_query_when_results_are_loaded
183 topics
.reload
# force load
185 topics
.first(:order => 'title')
186 topics
.last(:order => 'title')
190 def test_empty_should_not_load_results
193 topics
.empty
? # use count query
194 topics
.collect
# force load
195 topics
.empty
? # use loaded (no query)
199 def test_any_should_not_load_results
202 topics
.any
? # use count query
203 topics
.collect
# force load
204 topics
.any
? # use loaded (no query)
208 def test_any_should_call_proxy_found_if_using_a_block
211 topics
.expects(:empty?).never
216 def test_any_should_not_fire_query_if_named_scope_loaded
218 topics
.collect
# force load
219 assert_no_queries
{ assert topics
.any
? }
222 def test_should_build_with_proxy_options
223 topic
= Topic
.approved
.build({})
224 assert topic
.approved
227 def test_should_build_new_with_proxy_options
228 topic
= Topic
.approved
.new
229 assert topic
.approved
232 def test_should_create_with_proxy_options
233 topic
= Topic
.approved
.create({})
234 assert topic
.approved
237 def test_should_create_with_bang_with_proxy_options
238 topic
= Topic
.approved
.create
!({})
239 assert topic
.approved
242 def test_should_build_with_proxy_options_chained
243 topic
= Topic
.approved
.by_lifo
.build({})
244 assert topic
.approved
245 assert_equal
'lifo', topic
.author_name
248 def test_find_all_should_behave_like_select
249 assert_equal Topic
.base
.select(&:approved), Topic
.base
.find_all(&:approved)
252 def test_rand_should_select_a_random_object_from_proxy
253 assert Topic
.approved
.rand
.is_a
?(Topic
)
256 def test_should_use_where_in_query_for_named_scope
257 assert_equal Developer
.find_all_by_name('Jamis'), Developer
.find_all_by_id(Developer
.jamises
)
260 def test_size_should_use_count_when_results_are_not_loaded
263 assert_sql(/COUNT/i
) { topics
.size
}
267 def test_size_should_use_length_when_results_are_loaded
269 topics
.reload
# force load
271 topics
.size
# use loaded (no query)
275 def test_chaining_with_duplicate_joins
276 join
= "INNER JOIN comments ON comments.post_id = posts.id"
278 assert_equal post
.comments
.size
, Post
.scoped(:joins => join
).scoped(:joins => join
, :conditions => "posts.id = #{post.id}").size