named_scope_test.rb 5.5 KB
Newer Older
1 2 3 4 5 6 7 8
require "cases/helper"
require 'models/post'
require 'models/topic'
require 'models/comment'
require 'models/reply'
require 'models/author'

class NamedScopeTest < ActiveRecord::TestCase
9
  fixtures :posts, :authors, :topics, :comments
10

11 12
  def test_implements_enumerable
    assert !Topic.find(:all).empty?
13

14 15 16 17
    assert_equal Topic.find(:all),   Topic.base
    assert_equal Topic.find(:all),   Topic.base.to_a
    assert_equal Topic.find(:first), Topic.base.first
    assert_equal Topic.find(:all),   Topic.base.each { |i| i }
18
  end
19

20 21
  def test_found_items_are_cached
    Topic.columns
22
    all_posts = Topic.base
23

24 25 26 27 28
    assert_queries(1) do
      all_posts.collect
      all_posts.collect
    end
  end
29

30
  def test_reload_expires_cache_of_found_items
31
    all_posts = Topic.base
32
    all_posts.inspect
33

34 35 36 37
    new_post = Topic.create!
    assert !all_posts.include?(new_post)
    assert all_posts.reload.include?(new_post)
  end
38

39 40
  def test_delegates_finds_and_calculations_to_the_base_class
    assert !Topic.find(:all).empty?
41

42 43 44 45
    assert_equal Topic.find(:all),               Topic.base.find(:all)
    assert_equal Topic.find(:first),             Topic.base.find(:first)
    assert_equal Topic.count,                    Topic.base.count
    assert_equal Topic.average(:replies_count), Topic.base.average(:replies_count)
46
  end
47

48
  def test_subclasses_inherit_scopes
49
    assert Topic.scopes.include?(:base)
50

51 52
    assert Reply.scopes.include?(:base)
    assert_equal Reply.find(:all), Reply.base
53
  end
54

55 56
  def test_scopes_with_options_limit_finds_to_those_matching_the_criteria_specified
    assert !Topic.find(:all, :conditions => {:approved => true}).empty?
57

58 59 60
    assert_equal Topic.find(:all, :conditions => {:approved => true}), Topic.approved
    assert_equal Topic.count(:conditions => {:approved => true}), Topic.approved.count
  end
61

62 63 64 65 66 67
  def test_scopes_with_string_name_can_be_composed
    # NOTE that scopes defined with a string as a name worked on their own
    # but when called on another scope the other scope was completely replaced
    assert_equal Topic.replied.approved, Topic.replied.approved_as_string
  end

68 69 70
  def test_scopes_are_composable
    assert_equal (approved = Topic.find(:all, :conditions => {:approved => true})), Topic.approved
    assert_equal (replied = Topic.find(:all, :conditions => 'replies_count > 0')), Topic.replied
71
    assert !(approved == replied)
72
    assert !(approved & replied).empty?
73

74 75 76 77 78 79 80
    assert_equal approved & replied, Topic.approved.replied
  end

  def test_procedural_scopes
    topics_written_before_the_third = Topic.find(:all, :conditions => ['written_on < ?', topics(:third).written_on])
    topics_written_before_the_second = Topic.find(:all, :conditions => ['written_on < ?', topics(:second).written_on])
    assert_not_equal topics_written_before_the_second, topics_written_before_the_third
81

82 83 84
    assert_equal topics_written_before_the_third, Topic.written_before(topics(:third).written_on)
    assert_equal topics_written_before_the_second, Topic.written_before(topics(:second).written_on)
  end
85

86 87 88 89
  def test_extensions
    assert_equal 1, Topic.anonymous_extension.one
    assert_equal 2, Topic.named_extension.two
  end
90

91 92
  def test_multiple_extensions
    assert_equal 2, Topic.multiple_extensions.extension_two
93
    assert_equal 1, Topic.multiple_extensions.extension_one
94
  end
95

96 97 98
  def test_has_many_associations_have_access_to_named_scopes
    assert_not_equal Post.containing_the_letter_a, authors(:david).posts
    assert !Post.containing_the_letter_a.empty?
99

100 101
    assert_equal authors(:david).posts & Post.containing_the_letter_a, authors(:david).posts.containing_the_letter_a
  end
102

103
  def test_has_many_through_associations_have_access_to_named_scopes
104
    assert_not_equal Comment.containing_the_letter_e, authors(:david).comments
105
    assert !Comment.containing_the_letter_e.empty?
106

107 108
    assert_equal authors(:david).comments & Comment.containing_the_letter_e, authors(:david).comments.containing_the_letter_e
  end
109

110 111
  def test_active_records_have_scope_named__all__
    assert !Topic.find(:all).empty?
112

113
    assert_equal Topic.find(:all), Topic.base
114
  end
115

116 117
  def test_active_records_have_scope_named__scoped__
    assert !Topic.find(:all, scope = {:conditions => "content LIKE '%Have%'"}).empty?
118

119 120
    assert_equal Topic.find(:all, scope), Topic.scoped(scope)
  end
121 122 123 124 125 126

  def test_proxy_options
    expected_proxy_options = { :conditions => { :approved => true } }
    assert_equal expected_proxy_options, Topic.approved.proxy_options
  end

127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
  def test_first_and_last_should_support_find_options
    assert_equal Topic.base.first(:order => 'title'), Topic.base.find(:first, :order => 'title')
    assert_equal Topic.base.last(:order => 'title'), Topic.base.find(:last, :order => 'title')
  end

  def test_first_and_last_should_allow_integers_for_limit
    assert_equal Topic.base.first(2), Topic.base.to_a.first(2)
    assert_equal Topic.base.last(2), Topic.base.to_a.last(2)
  end

  def test_first_and_last_should_not_use_query_when_results_are_loaded
    topics = Topic.base
    topics.reload # force load
    assert_no_queries do
      topics.first
      topics.last
    end
  end

  def test_first_and_last_find_options_should_use_query_when_results_are_loaded
    topics = Topic.base
    topics.reload # force load
    assert_queries(2) do
      topics.first(:order => 'title')
      topics.last(:order => 'title')
    end
  end

155 156 157 158 159 160 161 162
  def test_empty_should_not_load_results
    topics = Topic.base
    assert_queries(2) do
      topics.empty?  # use count query
      topics.collect # force load
      topics.empty?  # use loaded (no query)
    end
  end
163
end