Skip to content
This repository
tree: 76886789ac
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 203 lines (162 sloc) 7.156 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 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 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
require "cases/helper"
require 'models/post'
require 'models/topic'
require 'models/comment'
require 'models/reply'
require 'models/author'
require 'models/developer'

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

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

    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 }
  end

  def test_found_items_are_cached
    Topic.columns
    all_posts = Topic.base

    assert_queries(1) do
      all_posts.collect
      all_posts.collect
    end
  end

  def test_reload_expires_cache_of_found_items
    all_posts = Topic.base
    all_posts.inspect

    new_post = Topic.create!
    assert !all_posts.include?(new_post)
    assert all_posts.reload.include?(new_post)
  end

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

    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)
  end

  def test_scope_should_respond_to_own_methods_and_methods_of_the_proxy
    assert Topic.approved.respond_to?(:proxy_found)
    assert Topic.approved.respond_to?(:count)
    assert Topic.approved.respond_to?(:length)
  end

  def test_respond_to_respects_include_private_parameter
    assert !Topic.approved.respond_to?(:load_found)
    assert Topic.approved.respond_to?(:load_found, true)
  end

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

    assert Reply.scopes.include?(:base)
    assert_equal Reply.find(:all), Reply.base
  end

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

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

  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

  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
    assert !(approved == replied)
    assert !(approved & replied).empty?

    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

    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

  def test_scopes_with_joins
    address = author_addresses(:david_address)
    posts_with_authors_at_address = Post.find(
      :all, :joins => 'JOIN authors ON authors.id = posts.author_id',
      :conditions => [ 'authors.author_address_id = ?', address.id ]
    )
    assert_equal posts_with_authors_at_address, Post.with_authors_at_address(address)
  end

  def test_scopes_with_joins_respects_custom_select
    address = author_addresses(:david_address)
    posts_with_authors_at_address_titles = Post.find(:all,
      :select => 'title',
      :joins => 'JOIN authors ON authors.id = posts.author_id',
      :conditions => [ 'authors.author_address_id = ?', address.id ]
    )
    assert_equal posts_with_authors_at_address_titles, Post.with_authors_at_address(address).find(:all, :select => 'title')
  end

  def test_extensions
    assert_equal 1, Topic.anonymous_extension.one
    assert_equal 2, Topic.named_extension.two
  end

  def test_multiple_extensions
    assert_equal 2, Topic.multiple_extensions.extension_two
    assert_equal 1, Topic.multiple_extensions.extension_one
  end

  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?

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

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

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

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

    assert_equal Topic.find(:all), Topic.base
  end

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

    assert_equal Topic.find(:all, scope), Topic.scoped(scope)
  end

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

  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

  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

  def test_find_all_should_behave_like_select
    assert_equal Topic.base.select(&:approved), Topic.base.find_all(&:approved)
  end

  def test_should_use_where_in_query_for_named_scope
    assert_equal Developer.find_all_by_name('Jamis'), Developer.find_all_by_id(Developer.jamises)
  end
end
Something went wrong with that request. Please try again.