From 56913de450dc986482dd4e7f676ded259dc4ce79 Mon Sep 17 00:00:00 2001 From: Matthew Rudy Jacobs Date: Sat, 3 May 2008 18:06:02 +0100 Subject: [PATCH] tests and documentation - now uses "safe_to_array" - added a fixture to "topics" - proper testing on single and multiple :through scopes --- activerecord/lib/active_record/named_scope.rb | 11 ++++++++- activerecord/test/cases/base_test.rb | 2 +- activerecord/test/cases/finder_test.rb | 2 +- activerecord/test/cases/fixtures_test.rb | 2 +- activerecord/test/cases/named_scope_test.rb | 27 ++++++++++++++++++++++++- activerecord/test/fixtures/topics.yml | 11 +++++++++- activerecord/test/models/topic.rb | 4 ++- 7 files changed, 51 insertions(+), 8 deletions(-) diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb index 0d3190f..ae7ea3f 100644 --- a/activerecord/lib/active_record/named_scope.rb +++ b/activerecord/lib/active_record/named_scope.rb @@ -70,10 +70,17 @@ module ActiveRecord # end # end # end + # + # Named scopes can be scoped through another existing named scope: + # + # class Shirt < ActiveRecord::Base + # named_scope :red, :conditions => {:color => 'red'} + # named_scope :shrunk_red, :through => :red, :conditions => {:shrunk => true} + # end # def named_scope(name, options = {}, &block) through_scopes = [] - through_scopes = [options.delete(:through)].flatten.compact if options.is_a?(Hash) + through_scopes = safe_to_array(options.delete(:through)) if options.is_a?(Hash) scopes[name] = lambda do |parent_scope, *args| Scope.new(parent_scope, case options when Hash @@ -129,4 +136,4 @@ module ActiveRecord end end end -end \ No newline at end of file +end diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index e07ec50..10c93e6 100755 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -502,7 +502,7 @@ class BasicsTest < ActiveRecord::TestCase def test_load topics = Topic.find(:all, :order => 'id') - assert_equal(4, topics.size) + assert_equal(5, topics.size) assert_equal(topics(:first).title, topics.first.title) end diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index b7f87fe..024471b 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -559,7 +559,7 @@ class FinderTest < ActiveRecord::TestCase assert topics.include?(topics(:first)) topics = Topic.find_all_by_approved(true) - assert_equal 3, topics.size + assert_equal 4, topics.size assert topics.include?(topics(:second)) end diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb index 2787b9a..eefee63 100755 --- a/activerecord/test/cases/fixtures_test.rb +++ b/activerecord/test/cases/fixtures_test.rb @@ -127,7 +127,7 @@ class FixturesTest < ActiveRecord::TestCase end def test_complete_instantiation - assert_equal 4, @topics.size + assert_equal 5, @topics.size assert_equal "The First Topic", @first.title end diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/named_scope_test.rb index fc42796..effd7d9 100644 --- a/activerecord/test/cases/named_scope_test.rb +++ b/activerecord/test/cases/named_scope_test.rb @@ -66,7 +66,32 @@ class NamedScopeTest < ActiveRecord::TestCase assert !(approved & replied).empty? assert_equal approved & replied, Topic.approved.replied - assert_equal Topic.approved.replied, Topic.approved_and_replied + end + + def test_scopes_can_be_defined_through_another + assert_equal (top_level = Topic.find(:all, :conditions => ['parent_id IS NULL'])), Topic.top_level + assert_not_equal (trolls = Topic.find(:all, :conditions => "content LIKE '%troll%'")), Topic.top_level_trolls + assert !(top_level == trolls) + assert !(top_level & trolls).empty? + assert_equal top_level & trolls, Topic.find(:all, :conditions => "parent_id IS NULL AND content LIKE '%troll%'") + + assert_equal top_level & trolls, Topic.top_level_trolls + assert_equal (top_level & trolls).length, Topic.top_level_trolls.count + end + + def test_scopes_can_be_defined_through_multiple_others + assert_equal (approved = Topic.find(:all, :conditions => {:approved => true})), Topic.approved + assert_equal (top_level = Topic.find(:all, :conditions => ['parent_id IS NULL'])), Topic.top_level + assert_not_equal (not_replied = Topic.find(:all, :conditions => ['replies_count IS NULL OR replies_count = 0'])), Topic.fresh + + assert !(top_level == approved) + assert !(top_level == not_replied) + assert !(approved == not_replied) + assert !(top_level & approved & not_replied).empty? + assert_equal top_level & approved & not_replied, Topic.find(:all, :conditions => ["parent_id IS NULL AND approved = ? AND NOT(replies_count > ?)", true, 0]) + + assert_equal top_level & approved & not_replied, Topic.fresh + assert_equal (top_level & approved & not_replied).length, Topic.fresh.count end def test_procedural_scopes diff --git a/activerecord/test/fixtures/topics.yml b/activerecord/test/fixtures/topics.yml index 1769152..b8ffbcf 100644 --- a/activerecord/test/fixtures/topics.yml +++ b/activerecord/test/fixtures/topics.yml @@ -35,8 +35,17 @@ fourth: title: The Fourth Topic of the day author_name: Carl written_on: 2006-07-15t15:28:00.0099+01:00 - content: Why not? + content: Why not? It's fine to be a troll approved: true type: Reply parent_id: 3 + replies_count: 1 +fifth: + id: 5 + title: The Fifth Topic of the day + author_name: Wei San + written_on: 2006-08-01t16:29:00.0099+01:00 + last_read: 2006-08-02 + content: No one's going to reply to this. Not even trolls. + approved: true \ No newline at end of file diff --git a/activerecord/test/models/topic.rb b/activerecord/test/models/topic.rb index 4085e88..c595944 100755 --- a/activerecord/test/models/topic.rb +++ b/activerecord/test/models/topic.rb @@ -5,8 +5,10 @@ class Topic < ActiveRecord::Base } named_scope :approved, :conditions => {:approved => true} named_scope :replied, :conditions => ['replies_count > 0'] + named_scope :top_level, :conditions => {:parent_id => nil} - named_scope :approved_and_replied, :conditions => ['replies_count > 0'], :through => :approved + named_scope :top_level_trolls, :through => :top_level, :conditions => ['content LIKE ?', '%troll%'] + named_scope :fresh, :through => [:top_level, :approved], :conditions => ['NOT(replies_count > ?)', 0] named_scope :anonymous_extension do def one 1 -- 1.5.4.3