Initial commit of foodsoft 2

This commit is contained in:
Benjamin Meichsner 2009-01-06 11:49:19 +01:00
commit 5b9a7e05df
657 changed files with 70444 additions and 0 deletions

View file

@ -0,0 +1,21 @@
plugin_root = File.join(File.dirname(__FILE__), '..')
version = ENV['RAILS_VERSION']
version = nil if version and version == ""
# first look for a symlink to a copy of the framework
if !version and framework_root = ["#{plugin_root}/rails", "#{plugin_root}/../../rails"].find { |p| File.directory? p }
puts "found framework root: #{framework_root}"
# this allows for a plugin to be tested outside of an app and without Rails gems
$:.unshift "#{framework_root}/activesupport/lib", "#{framework_root}/activerecord/lib", "#{framework_root}/actionpack/lib"
else
# simply use installed gems if available
puts "using Rails#{version ? ' ' + version : nil} gems"
require 'rubygems'
if version
gem 'rails', version
else
gem 'actionpack'
gem 'activerecord'
end
end

View file

@ -0,0 +1,140 @@
require 'helper'
require 'will_paginate/array'
class ArrayPaginationTest < Test::Unit::TestCase
def test_simple
collection = ('a'..'e').to_a
[{ :page => 1, :per_page => 3, :expected => %w( a b c ) },
{ :page => 2, :per_page => 3, :expected => %w( d e ) },
{ :page => 1, :per_page => 5, :expected => %w( a b c d e ) },
{ :page => 3, :per_page => 5, :expected => [] },
].
each do |conditions|
expected = conditions.delete :expected
assert_equal expected, collection.paginate(conditions)
end
end
def test_defaults
result = (1..50).to_a.paginate
assert_equal 1, result.current_page
assert_equal 30, result.size
end
def test_deprecated_api
assert_raise(ArgumentError) { [].paginate(2) }
assert_raise(ArgumentError) { [].paginate(2, 10) }
end
def test_total_entries_has_precedence
result = %w(a b c).paginate :total_entries => 5
assert_equal 5, result.total_entries
end
def test_argument_error_with_params_and_another_argument
assert_raise ArgumentError do
[].paginate({}, 5)
end
end
def test_paginated_collection
entries = %w(a b c)
collection = create(2, 3, 10) do |pager|
assert_equal entries, pager.replace(entries)
end
assert_equal entries, collection
assert_respond_to_all collection, %w(total_pages each offset size current_page per_page total_entries)
assert_kind_of Array, collection
assert_instance_of Array, collection.entries
assert_equal 3, collection.offset
assert_equal 4, collection.total_pages
assert !collection.out_of_bounds?
end
def test_previous_next_pages
collection = create(1, 1, 3)
assert_nil collection.previous_page
assert_equal 2, collection.next_page
collection = create(2, 1, 3)
assert_equal 1, collection.previous_page
assert_equal 3, collection.next_page
collection = create(3, 1, 3)
assert_equal 2, collection.previous_page
assert_nil collection.next_page
end
def test_out_of_bounds
entries = create(2, 3, 2){}
assert entries.out_of_bounds?
entries = create(1, 3, 2){}
assert !entries.out_of_bounds?
end
def test_guessing_total_count
entries = create do |pager|
# collection is shorter than limit
pager.replace array
end
assert_equal 8, entries.total_entries
entries = create(2, 5, 10) do |pager|
# collection is shorter than limit, but we have an explicit count
pager.replace array
end
assert_equal 10, entries.total_entries
entries = create do |pager|
# collection is the same as limit; we can't guess
pager.replace array(5)
end
assert_equal nil, entries.total_entries
entries = create do |pager|
# collection is empty; we can't guess
pager.replace array(0)
end
assert_equal nil, entries.total_entries
entries = create(1) do |pager|
# collection is empty and we're on page 1,
# so the whole thing must be empty, too
pager.replace array(0)
end
assert_equal 0, entries.total_entries
end
def test_invalid_page
bad_inputs = [0, -1, nil, '', 'Schnitzel']
bad_inputs.each do |bad|
assert_raise(WillPaginate::InvalidPage) { create bad }
end
end
def test_invalid_per_page_setting
assert_raise(ArgumentError) { create(1, -1) }
end
def test_page_count_was_removed
assert_raise(NoMethodError) { create.page_count }
# It's `total_pages` now.
end
private
def create(page = 2, limit = 5, total = nil, &block)
if block_given?
WillPaginate::Collection.create(page, limit, total, &block)
else
WillPaginate::Collection.new(page, limit, total)
end
end
def array(size = 3)
Array.new(size)
end
end

8
vendor/plugins/will_paginate/test/console vendored Executable file
View file

@ -0,0 +1,8 @@
#!/usr/bin/env ruby
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
libs = []
libs << 'irb/completion'
libs << File.join('lib', 'load_fixtures')
exec "#{irb} -Ilib:test#{libs.map{ |l| " -r #{l}" }.join} --simple-prompt"

View file

@ -0,0 +1,22 @@
sqlite3:
database: ":memory:"
adapter: sqlite3
timeout: 500
sqlite2:
database: ":memory:"
adapter: sqlite2
mysql:
adapter: mysql
username: root
password:
encoding: utf8
database: will_paginate_unittest
postgres:
adapter: postgresql
username: mislav
password: mislav
database: will_paginate_unittest
min_messages: warning

View file

@ -0,0 +1,434 @@
require 'helper'
require 'lib/activerecord_test_case'
require 'will_paginate'
WillPaginate.enable_activerecord
WillPaginate.enable_named_scope
class FinderTest < ActiveRecordTestCase
fixtures :topics, :replies, :users, :projects, :developers_projects
def test_new_methods_presence
assert_respond_to_all Topic, %w(per_page paginate paginate_by_sql)
end
def test_simple_paginate
assert_queries(1) do
entries = Topic.paginate :page => nil
assert_equal 1, entries.current_page
assert_equal 1, entries.total_pages
assert_equal 4, entries.size
end
assert_queries(2) do
entries = Topic.paginate :page => 2
assert_equal 1, entries.total_pages
assert entries.empty?
end
end
def test_parameter_api
# :page parameter in options is required!
assert_raise(ArgumentError){ Topic.paginate }
assert_raise(ArgumentError){ Topic.paginate({}) }
# explicit :all should not break anything
assert_equal Topic.paginate(:page => nil), Topic.paginate(:all, :page => 1)
# :count could be nil and we should still not cry
assert_nothing_raised { Topic.paginate :page => 1, :count => nil }
end
def test_paginate_with_per_page
entries = Topic.paginate :page => 1, :per_page => 1
assert_equal 1, entries.size
assert_equal 4, entries.total_pages
# Developer class has explicit per_page at 10
entries = Developer.paginate :page => 1
assert_equal 10, entries.size
assert_equal 2, entries.total_pages
entries = Developer.paginate :page => 1, :per_page => 5
assert_equal 11, entries.total_entries
assert_equal 5, entries.size
assert_equal 3, entries.total_pages
end
def test_paginate_with_order
entries = Topic.paginate :page => 1, :order => 'created_at desc'
expected = [topics(:futurama), topics(:harvey_birdman), topics(:rails), topics(:ar)].reverse
assert_equal expected, entries.to_a
assert_equal 1, entries.total_pages
end
def test_paginate_with_conditions
entries = Topic.paginate :page => 1, :conditions => ["created_at > ?", 30.minutes.ago]
expected = [topics(:rails), topics(:ar)]
assert_equal expected, entries.to_a
assert_equal 1, entries.total_pages
end
def test_paginate_with_include_and_conditions
entries = Topic.paginate \
:page => 1,
:include => :replies,
:conditions => "replies.content LIKE 'Bird%' ",
:per_page => 10
expected = Topic.find :all,
:include => 'replies',
:conditions => "replies.content LIKE 'Bird%' ",
:limit => 10
assert_equal expected, entries.to_a
assert_equal 1, entries.total_entries
end
def test_paginate_with_include_and_order
entries = nil
assert_queries(2) do
entries = Topic.paginate \
:page => 1,
:include => :replies,
:order => 'replies.created_at asc, topics.created_at asc',
:per_page => 10
end
expected = Topic.find :all,
:include => 'replies',
:order => 'replies.created_at asc, topics.created_at asc',
:limit => 10
assert_equal expected, entries.to_a
assert_equal 4, entries.total_entries
end
def test_paginate_associations_with_include
entries, project = nil, projects(:active_record)
assert_nothing_raised "THIS IS A BUG in Rails 1.2.3 that was fixed in [7326]. " +
"Please upgrade to a newer version of Rails." do
entries = project.topics.paginate \
:page => 1,
:include => :replies,
:conditions => "replies.content LIKE 'Nice%' ",
:per_page => 10
end
expected = Topic.find :all,
:include => 'replies',
:conditions => "project_id = #{project.id} AND replies.content LIKE 'Nice%' ",
:limit => 10
assert_equal expected, entries.to_a
end
def test_paginate_associations
dhh = users :david
expected_name_ordered = [projects(:action_controller), projects(:active_record)]
expected_id_ordered = [projects(:active_record), projects(:action_controller)]
assert_queries(2) do
# with association-specified order
entries = dhh.projects.paginate(:page => 1)
assert_equal expected_name_ordered, entries
assert_equal 2, entries.total_entries
end
# with explicit order
entries = dhh.projects.paginate(:page => 1, :order => 'projects.id')
assert_equal expected_id_ordered, entries
assert_equal 2, entries.total_entries
assert_nothing_raised { dhh.projects.find(:all, :order => 'projects.id', :limit => 4) }
entries = dhh.projects.paginate(:page => 1, :order => 'projects.id', :per_page => 4)
assert_equal expected_id_ordered, entries
# has_many with implicit order
topic = Topic.find(1)
expected = [replies(:spam), replies(:witty_retort)]
assert_equal expected.map(&:id).sort, topic.replies.paginate(:page => 1).map(&:id).sort
assert_equal expected.reverse, topic.replies.paginate(:page => 1, :order => 'replies.id ASC')
end
def test_paginate_association_extension
project = Project.find(:first)
assert_queries(2) do
entries = project.replies.paginate_recent :page => 1
assert_equal [replies(:brave)], entries
end
end
def test_paginate_with_joins
entries = nil
assert_queries(1) do
entries = Developer.paginate :page => 1,
:joins => 'LEFT JOIN developers_projects ON users.id = developers_projects.developer_id',
:conditions => 'project_id = 1'
assert_equal 2, entries.size
developer_names = entries.map &:name
assert developer_names.include?('David')
assert developer_names.include?('Jamis')
end
assert_queries(1) do
expected = entries.to_a
entries = Developer.paginate :page => 1,
:joins => 'LEFT JOIN developers_projects ON users.id = developers_projects.developer_id',
:conditions => 'project_id = 1', :count => { :select => "users.id" }
assert_equal expected, entries.to_a
assert_equal 2, entries.total_entries
end
end
def test_paginate_with_group
entries = nil
assert_queries(1) do
entries = Developer.paginate :page => 1, :per_page => 10,
:group => 'salary', :select => 'salary', :order => 'salary'
end
expected = [ users(:david), users(:jamis), users(:dev_10), users(:poor_jamis) ].map(&:salary).sort
assert_equal expected, entries.map(&:salary)
end
def test_paginate_with_dynamic_finder
expected = [replies(:witty_retort), replies(:spam)]
assert_equal expected, Reply.paginate_by_topic_id(1, :page => 1)
entries = Developer.paginate :conditions => { :salary => 100000 }, :page => 1, :per_page => 5
assert_equal 8, entries.total_entries
assert_equal entries, Developer.paginate_by_salary(100000, :page => 1, :per_page => 5)
# dynamic finder + conditions
entries = Developer.paginate_by_salary(100000, :page => 1,
:conditions => ['id > ?', 6])
assert_equal 4, entries.total_entries
assert_equal (7..10).to_a, entries.map(&:id)
assert_raises NoMethodError do
Developer.paginate_by_inexistent_attribute 100000, :page => 1
end
end
def test_scoped_paginate
entries = Developer.with_poor_ones { Developer.paginate :page => 1 }
assert_equal 2, entries.size
assert_equal 2, entries.total_entries
end
## named_scope ##
def test_paginate_in_named_scope
entries = Developer.poor.paginate :page => 1, :per_page => 1
assert_equal 1, entries.size
assert_equal 2, entries.total_entries
end
def test_paginate_in_named_scope_on_habtm_association
project = projects(:active_record)
assert_queries(2) do
entries = project.developers.poor.paginate :page => 1, :per_page => 1
assert_equal 1, entries.size, 'one developer should be found'
assert_equal 1, entries.total_entries, 'only one developer should be found'
end
end
def test_paginate_in_named_scope_on_hmt_association
project = projects(:active_record)
expected = [replies(:brave)]
assert_queries(2) do
entries = project.replies.recent.paginate :page => 1, :per_page => 1
assert_equal expected, entries
assert_equal 1, entries.total_entries, 'only one reply should be found'
end
end
def test_paginate_in_named_scope_on_has_many_association
project = projects(:active_record)
expected = [topics(:ar)]
assert_queries(2) do
entries = project.topics.mentions_activerecord.paginate :page => 1, :per_page => 1
assert_equal expected, entries
assert_equal 1, entries.total_entries, 'only one topic should be found'
end
end
## misc ##
def test_count_and_total_entries_options_are_mutually_exclusive
e = assert_raise ArgumentError do
Developer.paginate :page => 1, :count => {}, :total_entries => 1
end
assert_match /exclusive/, e.to_s
end
def test_readonly
assert_nothing_raised { Developer.paginate :readonly => true, :page => 1 }
end
# this functionality is temporarily removed
def xtest_pagination_defines_method
pager = "paginate_by_created_at"
assert !User.methods.include?(pager), "User methods should not include `#{pager}` method"
# paginate!
assert 0, User.send(pager, nil, :page => 1).total_entries
# the paging finder should now be defined
assert User.methods.include?(pager), "`#{pager}` method should be defined on User"
end
# Is this Rails 2.0? Find out by testing find_all which was removed in [6998]
unless ActiveRecord::Base.respond_to? :find_all
def test_paginate_array_of_ids
# AR finders also accept arrays of IDs
# (this was broken in Rails before [6912])
assert_queries(1) do
entries = Developer.paginate((1..8).to_a, :per_page => 3, :page => 2, :order => 'id')
assert_equal (4..6).to_a, entries.map(&:id)
assert_equal 8, entries.total_entries
end
end
end
uses_mocha 'internals' do
def test_implicit_all_with_dynamic_finders
Topic.expects(:find_all_by_foo).returns([])
Topic.expects(:count).returns(0)
Topic.paginate_by_foo :page => 2
end
def test_guessing_the_total_count
Topic.expects(:find).returns(Array.new(2))
Topic.expects(:count).never
entries = Topic.paginate :page => 2, :per_page => 4
assert_equal 6, entries.total_entries
end
def test_guessing_that_there_are_no_records
Topic.expects(:find).returns([])
Topic.expects(:count).never
entries = Topic.paginate :page => 1, :per_page => 4
assert_equal 0, entries.total_entries
end
def test_extra_parameters_stay_untouched
Topic.expects(:find).with(:all, {:foo => 'bar', :limit => 4, :offset => 0 }).returns(Array.new(5))
Topic.expects(:count).with({:foo => 'bar'}).returns(1)
Topic.paginate :foo => 'bar', :page => 1, :per_page => 4
end
def test_count_skips_select
Developer.stubs(:find).returns([])
Developer.expects(:count).with({}).returns(0)
Developer.paginate :select => 'salary', :page => 2
end
def test_count_select_when_distinct
Developer.stubs(:find).returns([])
Developer.expects(:count).with(:select => 'DISTINCT salary').returns(0)
Developer.paginate :select => 'DISTINCT salary', :page => 2
end
def test_should_use_scoped_finders_if_present
# scope-out compatibility
Topic.expects(:find_best).returns(Array.new(5))
Topic.expects(:with_best).returns(1)
Topic.paginate_best :page => 1, :per_page => 4
end
def test_paginate_by_sql
assert_respond_to Developer, :paginate_by_sql
Developer.expects(:find_by_sql).with(regexp_matches(/sql LIMIT 3(,| OFFSET) 3/)).returns([])
Developer.expects(:count_by_sql).with('SELECT COUNT(*) FROM (sql) AS count_table').returns(0)
entries = Developer.paginate_by_sql 'sql', :page => 2, :per_page => 3
end
def test_paginate_by_sql_respects_total_entries_setting
Developer.expects(:find_by_sql).returns([])
Developer.expects(:count_by_sql).never
entries = Developer.paginate_by_sql 'sql', :page => 1, :total_entries => 999
assert_equal 999, entries.total_entries
end
def test_paginate_by_sql_strips_order_by_when_counting
Developer.expects(:find_by_sql).returns([])
Developer.expects(:count_by_sql).with("SELECT COUNT(*) FROM (sql\n ) AS count_table").returns(0)
Developer.paginate_by_sql "sql\n ORDER\nby foo, bar, `baz` ASC", :page => 2
end
# TODO: counts are still wrong
def test_ability_to_use_with_custom_finders
# acts_as_taggable defines find_tagged_with(tag, options)
Topic.expects(:find_tagged_with).with('will_paginate', :offset => 5, :limit => 5).returns([])
Topic.expects(:count).with({}).returns(0)
Topic.paginate_tagged_with 'will_paginate', :page => 2, :per_page => 5
end
def test_array_argument_doesnt_eliminate_count
ids = (1..8).to_a
Developer.expects(:find_all_by_id).returns([])
Developer.expects(:count).returns(0)
Developer.paginate_by_id(ids, :per_page => 3, :page => 2, :order => 'id')
end
def test_paginating_finder_doesnt_mangle_options
Developer.expects(:find).returns([])
options = { :page => 1 }
options.expects(:delete).never
options_before = options.dup
Developer.paginate(options)
assert_equal options, options_before
end
def test_paginated_each
collection = stub('collection', :size => 5, :empty? => false, :per_page => 5)
collection.expects(:each).times(2).returns(collection)
last_collection = stub('collection', :size => 4, :empty? => false, :per_page => 5)
last_collection.expects(:each).returns(last_collection)
params = { :order => 'id', :total_entries => 0 }
Developer.expects(:paginate).with(params.merge(:page => 2)).returns(collection)
Developer.expects(:paginate).with(params.merge(:page => 3)).returns(collection)
Developer.expects(:paginate).with(params.merge(:page => 4)).returns(last_collection)
assert_equal 14, Developer.paginated_each(:page => '2') { }
end
# detect ActiveRecord 2.1
if ActiveRecord::Base.private_methods.include?('references_eager_loaded_tables?')
def test_removes_irrelevant_includes_in_count
Developer.expects(:find).returns([1])
Developer.expects(:count).with({}).returns(0)
Developer.paginate :page => 1, :per_page => 1, :include => :projects
end
def test_doesnt_remove_referenced_includes_in_count
Developer.expects(:find).returns([1])
Developer.expects(:count).with({ :include => :projects, :conditions => 'projects.id > 2' }).returns(0)
Developer.paginate :page => 1, :per_page => 1,
:include => :projects, :conditions => 'projects.id > 2'
end
end
end
end

View file

@ -0,0 +1,3 @@
class Admin < User
has_many :companies, :finder_sql => 'SELECT * FROM companies'
end

View file

@ -0,0 +1,13 @@
class Developer < User
has_and_belongs_to_many :projects, :include => :topics, :order => 'projects.name'
def self.with_poor_ones(&block)
with_scope :find => { :conditions => ['salary <= ?', 80000], :order => 'salary' } do
yield
end
end
named_scope :poor, :conditions => ['salary <= ?', 80000], :order => 'salary'
def self.per_page() 10 end
end

View file

@ -0,0 +1,13 @@
david_action_controller:
developer_id: 1
project_id: 2
joined_on: 2004-10-10
david_active_record:
developer_id: 1
project_id: 1
joined_on: 2004-10-10
jamis_active_record:
developer_id: 2
project_id: 1

View file

@ -0,0 +1,15 @@
class Project < ActiveRecord::Base
has_and_belongs_to_many :developers, :uniq => true
has_many :topics
# :finder_sql => 'SELECT * FROM topics WHERE (topics.project_id = #{id})',
# :counter_sql => 'SELECT COUNT(*) FROM topics WHERE (topics.project_id = #{id})'
has_many :replies, :through => :topics do
def find_recent(params = {})
with_scope :find => { :conditions => ['replies.created_at > ?', 15.minutes.ago] } do
find :all, params
end
end
end
end

View file

@ -0,0 +1,6 @@
active_record:
id: 1
name: Active Record
action_controller:
id: 2
name: Active Controller

View file

@ -0,0 +1,29 @@
witty_retort:
id: 1
topic_id: 1
content: Birdman is better!
created_at: <%= 6.hours.ago.to_s(:db) %>
another:
id: 2
topic_id: 2
content: Nuh uh!
created_at: <%= 1.hour.ago.to_s(:db) %>
spam:
id: 3
topic_id: 1
content: Nice site!
created_at: <%= 1.hour.ago.to_s(:db) %>
decisive:
id: 4
topic_id: 4
content: "I'm getting to the bottom of this"
created_at: <%= 30.minutes.ago.to_s(:db) %>
brave:
id: 5
topic_id: 4
content: "AR doesn't scare me a bit"
created_at: <%= 10.minutes.ago.to_s(:db) %>

View file

@ -0,0 +1,7 @@
class Reply < ActiveRecord::Base
belongs_to :topic, :include => [:replies]
named_scope :recent, :conditions => ['replies.created_at > ?', 15.minutes.ago]
validates_presence_of :content
end

View file

@ -0,0 +1,38 @@
ActiveRecord::Schema.define do
create_table "users", :force => true do |t|
t.column "name", :text
t.column "salary", :integer, :default => 70000
t.column "created_at", :datetime
t.column "updated_at", :datetime
t.column "type", :text
end
create_table "projects", :force => true do |t|
t.column "name", :text
end
create_table "developers_projects", :id => false, :force => true do |t|
t.column "developer_id", :integer, :null => false
t.column "project_id", :integer, :null => false
t.column "joined_on", :date
t.column "access_level", :integer, :default => 1
end
create_table "topics", :force => true do |t|
t.column "project_id", :integer
t.column "title", :string
t.column "subtitle", :string
t.column "content", :text
t.column "created_at", :datetime
t.column "updated_at", :datetime
end
create_table "replies", :force => true do |t|
t.column "content", :text
t.column "created_at", :datetime
t.column "updated_at", :datetime
t.column "topic_id", :integer
end
end

View file

@ -0,0 +1,6 @@
class Topic < ActiveRecord::Base
has_many :replies, :dependent => :destroy, :order => 'replies.created_at DESC'
belongs_to :project
named_scope :mentions_activerecord, :conditions => ['topics.title LIKE ?', '%ActiveRecord%']
end

View file

@ -0,0 +1,30 @@
futurama:
id: 1
title: Isnt futurama awesome?
subtitle: It really is, isnt it.
content: I like futurama
created_at: <%= 1.day.ago.to_s(:db) %>
updated_at:
harvey_birdman:
id: 2
title: Harvey Birdman is the king of all men
subtitle: yup
content: He really is
created_at: <%= 2.hours.ago.to_s(:db) %>
updated_at:
rails:
id: 3
project_id: 1
title: Rails is nice
subtitle: It makes me happy
content: except when I have to hack internals to fix pagination. even then really.
created_at: <%= 20.minutes.ago.to_s(:db) %>
ar:
id: 4
project_id: 1
title: ActiveRecord sometimes freaks me out
content: "I mean, what's the deal with eager loading?"
created_at: <%= 15.minutes.ago.to_s(:db) %>

View file

@ -0,0 +1,2 @@
class User < ActiveRecord::Base
end

View file

@ -0,0 +1,35 @@
david:
id: 1
name: David
salary: 80000
type: Developer
jamis:
id: 2
name: Jamis
salary: 150000
type: Developer
<% for digit in 3..10 %>
dev_<%= digit %>:
id: <%= digit %>
name: fixture_<%= digit %>
salary: 100000
type: Developer
<% end %>
poor_jamis:
id: 11
name: Jamis
salary: 9000
type: Developer
admin:
id: 12
name: admin
type: Admin
goofy:
id: 13
name: Goofy
type: Admin

View file

@ -0,0 +1,37 @@
require 'test/unit'
require 'rubygems'
# gem install redgreen for colored test output
begin require 'redgreen'; rescue LoadError; end
require 'boot' unless defined?(ActiveRecord)
class Test::Unit::TestCase
protected
def assert_respond_to_all object, methods
methods.each do |method|
[method.to_s, method.to_sym].each { |m| assert_respond_to object, m }
end
end
def collect_deprecations
old_behavior = WillPaginate::Deprecation.behavior
deprecations = []
WillPaginate::Deprecation.behavior = Proc.new do |message, callstack|
deprecations << message
end
result = yield
[result, deprecations]
ensure
WillPaginate::Deprecation.behavior = old_behavior
end
end
# Wrap tests that use Mocha and skip if unavailable.
def uses_mocha(test_name)
require 'mocha' unless Object.const_defined?(:Mocha)
rescue LoadError => load_error
$stderr.puts "Skipping #{test_name} tests. `gem install mocha` and try again."
else
yield
end

View file

@ -0,0 +1,36 @@
require 'lib/activerecord_test_connector'
class ActiveRecordTestCase < Test::Unit::TestCase
# Set our fixture path
if ActiveRecordTestConnector.able_to_connect
self.fixture_path = File.join(File.dirname(__FILE__), '..', 'fixtures')
self.use_transactional_fixtures = true
end
def self.fixtures(*args)
super if ActiveRecordTestConnector.connected
end
def run(*args)
super if ActiveRecordTestConnector.connected
end
# Default so Test::Unit::TestCase doesn't complain
def test_truth
end
protected
def assert_queries(num = 1)
$query_count = 0
yield
ensure
assert_equal num, $query_count, "#{$query_count} instead of #{num} queries were executed."
end
def assert_no_queries(&block)
assert_queries(0, &block)
end
end
ActiveRecordTestConnector.setup

View file

@ -0,0 +1,69 @@
require 'active_record'
require 'active_record/version'
require 'active_record/fixtures'
class ActiveRecordTestConnector
cattr_accessor :able_to_connect
cattr_accessor :connected
FIXTURES_PATH = File.join(File.dirname(__FILE__), '..', 'fixtures')
# Set our defaults
self.connected = false
self.able_to_connect = true
def self.setup
unless self.connected || !self.able_to_connect
setup_connection
load_schema
Dependencies.load_paths.unshift FIXTURES_PATH
self.connected = true
end
rescue Exception => e # errors from ActiveRecord setup
$stderr.puts "\nSkipping ActiveRecord tests: #{e}"
$stderr.puts "Install SQLite3 to run the full test suite for will_paginate.\n\n"
self.able_to_connect = false
end
private
def self.setup_connection
db = ENV['DB'].blank?? 'sqlite3' : ENV['DB']
configurations = YAML.load_file(File.join(File.dirname(__FILE__), '..', 'database.yml'))
raise "no configuration for '#{db}'" unless configurations.key? db
configuration = configurations[db]
ActiveRecord::Base.logger = Logger.new(STDOUT) if $0 == 'irb'
puts "using #{configuration['adapter']} adapter" unless ENV['DB'].blank?
ActiveRecord::Base.establish_connection(configuration)
ActiveRecord::Base.configurations = { db => configuration }
prepare ActiveRecord::Base.connection
unless Object.const_defined?(:QUOTED_TYPE)
Object.send :const_set, :QUOTED_TYPE, ActiveRecord::Base.connection.quote_column_name('type')
end
end
def self.load_schema
ActiveRecord::Base.silence do
ActiveRecord::Migration.verbose = false
load File.join(FIXTURES_PATH, 'schema.rb')
end
end
def self.prepare(conn)
class << conn
IGNORED_SQL = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SHOW FIELDS /]
def execute_with_counting(sql, name = nil, &block)
$query_count ||= 0
$query_count += 1 unless IGNORED_SQL.any? { |r| sql =~ r }
execute_without_counting(sql, name, &block)
end
alias_method_chain :execute, :counting
end
end
end

View file

@ -0,0 +1,11 @@
require 'boot'
require 'lib/activerecord_test_connector'
# setup the connection
ActiveRecordTestConnector.setup
# load all fixtures
Fixtures.create_fixtures(ActiveRecordTestConnector::FIXTURES_PATH, ActiveRecord::Base.connection.tables)
require 'will_paginate'
WillPaginate.enable_activerecord

View file

@ -0,0 +1,165 @@
require 'action_controller'
require 'action_controller/test_process'
require 'will_paginate'
WillPaginate.enable_actionpack
ActionController::Routing::Routes.draw do |map|
map.connect 'dummy/page/:page', :controller => 'dummy'
map.connect 'dummy/dots/page.:page', :controller => 'dummy', :action => 'dots'
map.connect 'ibocorp/:page', :controller => 'ibocorp',
:requirements => { :page => /\d+/ },
:defaults => { :page => 1 }
map.connect ':controller/:action/:id'
end
ActionController::Base.perform_caching = false
class WillPaginate::ViewTestCase < Test::Unit::TestCase
def setup
super
@controller = DummyController.new
@request = @controller.request
@html_result = nil
@template = '<%= will_paginate collection, options %>'
@view = ActionView::Base.new
@view.assigns['controller'] = @controller
@view.assigns['_request'] = @request
@view.assigns['_params'] = @request.params
end
def test_no_complain; end
protected
def paginate(collection = {}, options = {}, &block)
if collection.instance_of? Hash
page_options = { :page => 1, :total_entries => 11, :per_page => 4 }.merge(collection)
collection = [1].paginate(page_options)
end
locals = { :collection => collection, :options => options }
if defined? ActionView::InlineTemplate
# Rails 2.1
args = [ ActionView::InlineTemplate.new(@view, @template, locals) ]
else
# older Rails versions
args = [nil, @template, nil, locals]
end
@html_result = @view.render_template(*args)
@html_document = HTML::Document.new(@html_result, true, false)
if block_given?
classname = options[:class] || WillPaginate::ViewHelpers.pagination_options[:class]
assert_select("div.#{classname}", 1, 'no main DIV', &block)
end
end
def response_from_page_or_rjs
@html_document.root
end
def validate_page_numbers expected, links, param_name = :page
param_pattern = /\W#{CGI.escape(param_name.to_s)}=([^&]*)/
assert_equal(expected, links.map { |e|
e['href'] =~ param_pattern
$1 ? $1.to_i : $1
})
end
def assert_links_match pattern, links = nil, numbers = nil
links ||= assert_select 'div.pagination a[href]' do |elements|
elements
end
pages = [] if numbers
links.each do |el|
assert_match pattern, el['href']
if numbers
el['href'] =~ pattern
pages << ($1.nil?? nil : $1.to_i)
end
end
assert_equal numbers, pages, "page numbers don't match" if numbers
end
def assert_no_links_match pattern
assert_select 'div.pagination a[href]' do |elements|
elements.each do |el|
assert_no_match pattern, el['href']
end
end
end
end
class DummyRequest
attr_accessor :symbolized_path_parameters
def initialize
@get = true
@params = {}
@symbolized_path_parameters = { :controller => 'foo', :action => 'bar' }
end
def get?
@get
end
def post
@get = false
end
def relative_url_root
''
end
def params(more = nil)
@params.update(more) if more
@params
end
end
class DummyController
attr_reader :request
attr_accessor :controller_name
def initialize
@request = DummyRequest.new
@url = ActionController::UrlRewriter.new(@request, @request.params)
end
def params
@request.params
end
def url_for(params)
@url.rewrite(params)
end
end
module HTML
Node.class_eval do
def inner_text
children.map(&:inner_text).join('')
end
end
Text.class_eval do
def inner_text
self.to_s
end
end
Tag.class_eval do
def inner_text
childless?? '' : super
end
end
end

View file

@ -0,0 +1,59 @@
require 'rake/testtask'
desc 'Test the will_paginate plugin.'
Rake::TestTask.new(:test) do |t|
t.pattern = 'test/**/*_test.rb'
t.verbose = true
t.libs << 'test'
end
# I want to specify environment variables at call time
class EnvTestTask < Rake::TestTask
attr_accessor :env
def ruby(*args)
env.each { |key, value| ENV[key] = value } if env
super
env.keys.each { |key| ENV.delete key } if env
end
end
for configuration in %w( sqlite3 mysql postgres )
EnvTestTask.new("test_#{configuration}") do |t|
t.pattern = 'test/finder_test.rb'
t.verbose = true
t.env = { 'DB' => configuration }
t.libs << 'test'
end
end
task :test_databases => %w(test_mysql test_sqlite3 test_postgres)
desc %{Test everything on SQLite3, MySQL and PostgreSQL}
task :test_full => %w(test test_mysql test_postgres)
desc %{Test everything with Rails 2.1.x, 2.0.x & 1.2.x gems}
task :test_all do
all = Rake::Task['test_full']
versions = %w(2.1.0 2.0.2 1.2.6)
versions.each do |version|
ENV['RAILS_VERSION'] = "~> #{version}"
all.invoke
reset_invoked unless version == versions.last
end
end
def reset_invoked
%w( test_full test test_mysql test_postgres ).each do |name|
Rake::Task[name].instance_variable_set '@already_invoked', false
end
end
task :rcov do
excludes = %w( lib/will_paginate/named_scope*
lib/will_paginate/core_ext.rb
lib/will_paginate.rb
rails* )
system %[rcov -Itest:lib test/*.rb -x #{excludes.join(',')}]
end

View file

@ -0,0 +1,363 @@
require 'helper'
require 'lib/view_test_process'
class AdditionalLinkAttributesRenderer < WillPaginate::LinkRenderer
def initialize(link_attributes = nil)
super()
@additional_link_attributes = link_attributes || { :default => 'true' }
end
def page_link(page, text, attributes = {})
@template.link_to text, url_for(page), attributes.merge(@additional_link_attributes)
end
end
class ViewTest < WillPaginate::ViewTestCase
## basic pagination ##
def test_will_paginate
paginate do |pagination|
assert_select 'a[href]', 3 do |elements|
validate_page_numbers [2,3,2], elements
assert_select elements.last, ':last-child', "Next &raquo;"
end
assert_select 'span', 2
assert_select 'span.disabled:first-child', '&laquo; Previous'
assert_select 'span.current', '1'
assert_equal '&laquo; Previous 1 2 3 Next &raquo;', pagination.first.inner_text
end
end
def test_no_pagination_when_page_count_is_one
paginate :per_page => 30
assert_equal '', @html_result
end
def test_will_paginate_with_options
paginate({ :page => 2 },
:class => 'will_paginate', :previous_label => 'Prev', :next_label => 'Next') do
assert_select 'a[href]', 4 do |elements|
validate_page_numbers [1,1,3,3], elements
# test rel attribute values:
assert_select elements[1], 'a', '1' do |link|
assert_equal 'prev start', link.first['rel']
end
assert_select elements.first, 'a', "Prev" do |link|
assert_equal 'prev start', link.first['rel']
end
assert_select elements.last, 'a', "Next" do |link|
assert_equal 'next', link.first['rel']
end
end
assert_select 'span.current', '2'
end
end
def test_will_paginate_using_renderer_class
paginate({}, :renderer => AdditionalLinkAttributesRenderer) do
assert_select 'a[default=true]', 3
end
end
def test_will_paginate_using_renderer_instance
renderer = WillPaginate::LinkRenderer.new
renderer.gap_marker = '<span class="my-gap">~~</span>'
paginate({ :per_page => 2 }, :inner_window => 0, :outer_window => 0, :renderer => renderer) do
assert_select 'span.my-gap', '~~'
end
renderer = AdditionalLinkAttributesRenderer.new(:title => 'rendered')
paginate({}, :renderer => renderer) do
assert_select 'a[title=rendered]', 3
end
end
def test_prev_next_links_have_classnames
paginate do |pagination|
assert_select 'span.disabled.prev_page:first-child'
assert_select 'a.next_page[href]:last-child'
end
end
def test_prev_label_deprecated
assert_deprecated ':previous_label' do
paginate({ :page => 2 }, :prev_label => 'Deprecated') do
assert_select 'a[href]:first-child', 'Deprecated'
end
end
end
def test_full_output
paginate
expected = <<-HTML
<div class="pagination"><span class="disabled prev_page">&laquo; Previous</span>
<span class="current">1</span>
<a href="/foo/bar?page=2" rel="next">2</a>
<a href="/foo/bar?page=3">3</a>
<a href="/foo/bar?page=2" class="next_page" rel="next">Next &raquo;</a></div>
HTML
expected.strip!.gsub!(/\s{2,}/, ' ')
assert_dom_equal expected, @html_result
end
def test_escaping_of_urls
paginate({:page => 1, :per_page => 1, :total_entries => 2},
:page_links => false, :params => { :tag => '<br>' })
assert_select 'a[href]', 1 do |links|
query = links.first['href'].split('?', 2)[1]
assert_equal %w(page=2 tag=%3Cbr%3E), query.split('&amp;').sort
end
end
## advanced options for pagination ##
def test_will_paginate_without_container
paginate({}, :container => false)
assert_select 'div.pagination', 0, 'main DIV present when it shouldn\'t'
assert_select 'a[href]', 3
end
def test_will_paginate_without_page_links
paginate({ :page => 2 }, :page_links => false) do
assert_select 'a[href]', 2 do |elements|
validate_page_numbers [1,3], elements
end
end
end
def test_will_paginate_windows
paginate({ :page => 6, :per_page => 1 }, :inner_window => 1) do |pagination|
assert_select 'a[href]', 8 do |elements|
validate_page_numbers [5,1,2,5,7,10,11,7], elements
assert_select elements.first, 'a', '&laquo; Previous'
assert_select elements.last, 'a', 'Next &raquo;'
end
assert_select 'span.current', '6'
assert_equal '&laquo; Previous 1 2 &hellip; 5 6 7 &hellip; 10 11 Next &raquo;', pagination.first.inner_text
end
end
def test_will_paginate_eliminates_small_gaps
paginate({ :page => 6, :per_page => 1 }, :inner_window => 2) do
assert_select 'a[href]', 12 do |elements|
validate_page_numbers [5,1,2,3,4,5,7,8,9,10,11,7], elements
end
end
end
def test_container_id
paginate do |div|
assert_nil div.first['id']
end
# magic ID
paginate({}, :id => true) do |div|
assert_equal 'fixnums_pagination', div.first['id']
end
# explicit ID
paginate({}, :id => 'custom_id') do |div|
assert_equal 'custom_id', div.first['id']
end
end
## other helpers ##
def test_paginated_section
@template = <<-ERB
<% paginated_section collection, options do %>
<%= content_tag :div, '', :id => "developers" %>
<% end %>
ERB
paginate
assert_select 'div.pagination', 2
assert_select 'div.pagination + div#developers', 1
end
def test_page_entries_info
@template = '<%= page_entries_info collection %>'
array = ('a'..'z').to_a
paginate array.paginate(:page => 2, :per_page => 5)
assert_equal %{Displaying strings <b>6&nbsp;-&nbsp;10</b> of <b>26</b> in total},
@html_result
paginate array.paginate(:page => 7, :per_page => 4)
assert_equal %{Displaying strings <b>25&nbsp;-&nbsp;26</b> of <b>26</b> in total},
@html_result
end
def test_page_entries_info_with_longer_class_name
@template = '<%= page_entries_info collection %>'
collection = ('a'..'z').to_a.paginate
collection.first.stubs(:class).returns(mock('class', :name => 'ProjectType'))
paginate collection
assert @html_result.index('project types'), "expected <#{@html_result.inspect}> to mention 'project types'"
end
def test_page_entries_info_with_single_page_collection
@template = '<%= page_entries_info collection %>'
paginate(('a'..'d').to_a.paginate(:page => 1, :per_page => 5))
assert_equal %{Displaying <b>all 4</b> strings}, @html_result
paginate(['a'].paginate(:page => 1, :per_page => 5))
assert_equal %{Displaying <b>1</b> string}, @html_result
paginate([].paginate(:page => 1, :per_page => 5))
assert_equal %{No entries found}, @html_result
end
def test_page_entries_info_with_custom_entry_name
@template = '<%= page_entries_info collection, :entry_name => "author" %>'
entries = (1..20).to_a
paginate(entries.paginate(:page => 1, :per_page => 5))
assert_equal %{Displaying authors <b>1&nbsp;-&nbsp;5</b> of <b>20</b> in total}, @html_result
paginate(entries.paginate(:page => 1, :per_page => 20))
assert_equal %{Displaying <b>all 20</b> authors}, @html_result
paginate(['a'].paginate(:page => 1, :per_page => 5))
assert_equal %{Displaying <b>1</b> author}, @html_result
paginate([].paginate(:page => 1, :per_page => 5))
assert_equal %{No authors found}, @html_result
end
## parameter handling in page links ##
def test_will_paginate_preserves_parameters_on_get
@request.params :foo => { :bar => 'baz' }
paginate
assert_links_match /foo%5Bbar%5D=baz/
end
def test_will_paginate_doesnt_preserve_parameters_on_post
@request.post
@request.params :foo => 'bar'
paginate
assert_no_links_match /foo=bar/
end
def test_adding_additional_parameters
paginate({}, :params => { :foo => 'bar' })
assert_links_match /foo=bar/
end
def test_adding_anchor_parameter
paginate({}, :params => { :anchor => 'anchor' })
assert_links_match /#anchor$/
end
def test_removing_arbitrary_parameters
@request.params :foo => 'bar'
paginate({}, :params => { :foo => nil })
assert_no_links_match /foo=bar/
end
def test_adding_additional_route_parameters
paginate({}, :params => { :controller => 'baz', :action => 'list' })
assert_links_match %r{\Wbaz/list\W}
end
def test_will_paginate_with_custom_page_param
paginate({ :page => 2 }, :param_name => :developers_page) do
assert_select 'a[href]', 4 do |elements|
validate_page_numbers [1,1,3,3], elements, :developers_page
end
end
end
def test_complex_custom_page_param
@request.params :developers => { :page => 2 }
paginate({ :page => 2 }, :param_name => 'developers[page]') do
assert_select 'a[href]', 4 do |links|
assert_links_match /\?developers%5Bpage%5D=\d+$/, links
validate_page_numbers [1,1,3,3], links, 'developers[page]'
end
end
end
def test_custom_routing_page_param
@request.symbolized_path_parameters.update :controller => 'dummy', :action => nil
paginate :per_page => 2 do
assert_select 'a[href]', 6 do |links|
assert_links_match %r{/page/(\d+)$}, links, [2, 3, 4, 5, 6, 2]
end
end
end
def test_custom_routing_page_param_with_dot_separator
@request.symbolized_path_parameters.update :controller => 'dummy', :action => 'dots'
paginate :per_page => 2 do
assert_select 'a[href]', 6 do |links|
assert_links_match %r{/page\.(\d+)$}, links, [2, 3, 4, 5, 6, 2]
end
end
end
def test_custom_routing_with_first_page_hidden
@request.symbolized_path_parameters.update :controller => 'ibocorp', :action => nil
paginate :page => 2, :per_page => 2 do
assert_select 'a[href]', 7 do |links|
assert_links_match %r{/ibocorp(?:/(\d+))?$}, links, [nil, nil, 3, 4, 5, 6, 3]
end
end
end
## internal hardcore stuff ##
class LegacyCollection < WillPaginate::Collection
alias :page_count :total_pages
undef :total_pages
end
def test_deprecation_notices_with_page_count
collection = LegacyCollection.new(1, 1, 2)
assert_deprecated collection.class.name do
paginate collection
end
end
uses_mocha 'view internals' do
def test_collection_name_can_be_guessed
collection = mock
collection.expects(:total_pages).returns(1)
@template = '<%= will_paginate options %>'
@controller.controller_name = 'developers'
@view.assigns['developers'] = collection
paginate(nil)
end
end
def test_inferred_collection_name_raises_error_when_nil
@template = '<%= will_paginate options %>'
@controller.controller_name = 'developers'
e = assert_raise ArgumentError do
paginate(nil)
end
assert e.message.include?('@developers')
end
if ActionController::Base.respond_to? :rescue_responses
# only on Rails 2
def test_rescue_response_hook_presence
assert_equal :not_found,
ActionController::Base.rescue_responses['WillPaginate::InvalidPage']
end
end
end