will_paginate_seo 3.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +18 -0
  3. data/README.md +61 -0
  4. data/lib/will_paginate.rb +25 -0
  5. data/lib/will_paginate/active_record.rb +261 -0
  6. data/lib/will_paginate/array.rb +33 -0
  7. data/lib/will_paginate/collection.rb +136 -0
  8. data/lib/will_paginate/core_ext.rb +30 -0
  9. data/lib/will_paginate/data_mapper.rb +100 -0
  10. data/lib/will_paginate/deprecation.rb +55 -0
  11. data/lib/will_paginate/i18n.rb +22 -0
  12. data/lib/will_paginate/locale/en.yml +33 -0
  13. data/lib/will_paginate/mongoid.rb +46 -0
  14. data/lib/will_paginate/page_number.rb +57 -0
  15. data/lib/will_paginate/per_page.rb +27 -0
  16. data/lib/will_paginate/railtie.rb +68 -0
  17. data/lib/will_paginate/sequel.rb +39 -0
  18. data/lib/will_paginate/version.rb +9 -0
  19. data/lib/will_paginate/view_helpers.rb +162 -0
  20. data/lib/will_paginate/view_helpers/action_view.rb +152 -0
  21. data/lib/will_paginate/view_helpers/link_renderer.rb +131 -0
  22. data/lib/will_paginate/view_helpers/link_renderer_base.rb +77 -0
  23. data/lib/will_paginate/view_helpers/merb.rb +26 -0
  24. data/lib/will_paginate/view_helpers/sinatra.rb +41 -0
  25. data/spec/collection_spec.rb +139 -0
  26. data/spec/console +12 -0
  27. data/spec/console_fixtures.rb +28 -0
  28. data/spec/database.yml +22 -0
  29. data/spec/fake_rubygems.rb +18 -0
  30. data/spec/finders/active_record_spec.rb +517 -0
  31. data/spec/finders/activerecord_test_connector.rb +119 -0
  32. data/spec/finders/data_mapper_spec.rb +116 -0
  33. data/spec/finders/data_mapper_test_connector.rb +54 -0
  34. data/spec/finders/mongoid_spec.rb +140 -0
  35. data/spec/finders/sequel_spec.rb +67 -0
  36. data/spec/finders/sequel_test_connector.rb +15 -0
  37. data/spec/fixtures/admin.rb +3 -0
  38. data/spec/fixtures/developer.rb +16 -0
  39. data/spec/fixtures/developers_projects.yml +13 -0
  40. data/spec/fixtures/project.rb +13 -0
  41. data/spec/fixtures/projects.yml +6 -0
  42. data/spec/fixtures/replies.yml +29 -0
  43. data/spec/fixtures/reply.rb +8 -0
  44. data/spec/fixtures/schema.rb +38 -0
  45. data/spec/fixtures/topic.rb +8 -0
  46. data/spec/fixtures/topics.yml +30 -0
  47. data/spec/fixtures/user.rb +2 -0
  48. data/spec/fixtures/users.yml +35 -0
  49. data/spec/matchers/deprecation_matcher.rb +27 -0
  50. data/spec/matchers/phrase_matcher.rb +19 -0
  51. data/spec/matchers/query_count_matcher.rb +36 -0
  52. data/spec/page_number_spec.rb +65 -0
  53. data/spec/per_page_spec.rb +41 -0
  54. data/spec/spec_helper.rb +46 -0
  55. data/spec/view_helpers/action_view_spec.rb +441 -0
  56. data/spec/view_helpers/base_spec.rb +142 -0
  57. data/spec/view_helpers/link_renderer_base_spec.rb +87 -0
  58. data/spec/view_helpers/view_example_group.rb +125 -0
  59. metadata +106 -0
@@ -0,0 +1,15 @@
1
+ require 'sequel'
2
+
3
+ Symbol.class_eval do
4
+ # Active Record calculations tries `as` on some objects but chokes when that
5
+ # object was a Symbol and it gets a Sequel::SQL::AliasedExpression.
6
+ undef as if method_defined? :as
7
+ end
8
+
9
+ db = Sequel.sqlite
10
+
11
+ db.create_table :cars do
12
+ primary_key :id, :integer, :auto_increment => true
13
+ column :name, :text
14
+ column :notes, :text
15
+ end
@@ -0,0 +1,3 @@
1
+ class Admin < User
2
+ has_many :companies, :finder_sql => 'SELECT * FROM companies'
3
+ end
@@ -0,0 +1,16 @@
1
+ class Developer < User
2
+ has_and_belongs_to_many :projects, :order => 'projects.name', :join_table => 'developers_projects'
3
+
4
+ def self.with_poor_ones(&block)
5
+ options = { :conditions => ['salary <= ?', 80000], :order => 'salary' }
6
+ with_scope({ :find => options }, :overwrite) do
7
+ yield
8
+ end
9
+ end
10
+
11
+ scope :poor, lambda {
12
+ where(['salary <= ?', 80000]).order('salary')
13
+ }
14
+
15
+ def self.per_page() 10 end
16
+ end
@@ -0,0 +1,13 @@
1
+ david_action_controller:
2
+ developer_id: 1
3
+ project_id: 2
4
+ joined_on: 2004-10-10
5
+
6
+ david_active_record:
7
+ developer_id: 1
8
+ project_id: 1
9
+ joined_on: 2004-10-10
10
+
11
+ jamis_active_record:
12
+ developer_id: 2
13
+ project_id: 1
@@ -0,0 +1,13 @@
1
+ class Project < ActiveRecord::Base
2
+ has_and_belongs_to_many :developers, :uniq => true, :join_table => 'developers_projects'
3
+
4
+ has_many :topics
5
+ # :finder_sql => 'SELECT * FROM topics WHERE (topics.project_id = #{id})',
6
+ # :counter_sql => 'SELECT COUNT(*) FROM topics WHERE (topics.project_id = #{id})'
7
+
8
+ has_many :replies, :through => :topics do
9
+ def only_recent(params = {})
10
+ where(['replies.created_at > ?', 15.minutes.ago])
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,6 @@
1
+ active_record:
2
+ id: 1
3
+ name: Active Record
4
+ action_controller:
5
+ id: 2
6
+ name: Action Controller
@@ -0,0 +1,29 @@
1
+ witty_retort:
2
+ id: 1
3
+ topic_id: 1
4
+ content: Birdman is better!
5
+ created_at: <%= 6.hours.ago.utc.to_s(:db) %>
6
+
7
+ another:
8
+ id: 2
9
+ topic_id: 2
10
+ content: Nuh uh!
11
+ created_at: <%= 1.hour.ago.utc.to_s(:db) %>
12
+
13
+ spam:
14
+ id: 3
15
+ topic_id: 1
16
+ content: Nice site!
17
+ created_at: <%= 1.hour.ago.utc.to_s(:db) %>
18
+
19
+ decisive:
20
+ id: 4
21
+ topic_id: 4
22
+ content: "I'm getting to the bottom of this"
23
+ created_at: <%= 30.minutes.ago.utc.to_s(:db) %>
24
+
25
+ brave:
26
+ id: 5
27
+ topic_id: 4
28
+ content: "AR doesn't scare me a bit"
29
+ created_at: <%= 10.minutes.ago.utc.to_s(:db) %>
@@ -0,0 +1,8 @@
1
+ class Reply < ActiveRecord::Base
2
+ scope :recent, lambda {
3
+ where(['replies.created_at > ?', 15.minutes.ago]).
4
+ order('replies.created_at DESC')
5
+ }
6
+
7
+ validates_presence_of :content
8
+ end
@@ -0,0 +1,38 @@
1
+ ActiveRecord::Schema.define do
2
+
3
+ create_table "users", :force => true do |t|
4
+ t.column "name", :text
5
+ t.column "salary", :integer, :default => 70000
6
+ t.column "created_at", :datetime
7
+ t.column "updated_at", :datetime
8
+ t.column "type", :text
9
+ end
10
+
11
+ create_table "projects", :force => true do |t|
12
+ t.column "name", :text
13
+ end
14
+
15
+ create_table "developers_projects", :id => false, :force => true do |t|
16
+ t.column "developer_id", :integer, :null => false
17
+ t.column "project_id", :integer, :null => false
18
+ t.column "joined_on", :date
19
+ t.column "access_level", :integer, :default => 1
20
+ end
21
+
22
+ create_table "topics", :force => true do |t|
23
+ t.column "project_id", :integer
24
+ t.column "title", :string
25
+ t.column "subtitle", :string
26
+ t.column "content", :text
27
+ t.column "created_at", :datetime
28
+ t.column "updated_at", :datetime
29
+ end
30
+
31
+ create_table "replies", :force => true do |t|
32
+ t.column "content", :text
33
+ t.column "created_at", :datetime
34
+ t.column "updated_at", :datetime
35
+ t.column "topic_id", :integer
36
+ end
37
+
38
+ end
@@ -0,0 +1,8 @@
1
+ class Topic < ActiveRecord::Base
2
+ has_many :replies, :dependent => :destroy
3
+ belongs_to :project
4
+
5
+ scope :mentions_activerecord, lambda {
6
+ where(['topics.title LIKE ?', '%ActiveRecord%'])
7
+ }
8
+ end
@@ -0,0 +1,30 @@
1
+ futurama:
2
+ id: 1
3
+ title: Isnt futurama awesome?
4
+ subtitle: It really is, isnt it.
5
+ content: I like futurama
6
+ created_at: <%= 1.day.ago.utc.to_s(:db) %>
7
+ updated_at:
8
+
9
+ harvey_birdman:
10
+ id: 2
11
+ title: Harvey Birdman is the king of all men
12
+ subtitle: yup
13
+ content: He really is
14
+ created_at: <%= 2.hours.ago.utc.to_s(:db) %>
15
+ updated_at:
16
+
17
+ rails:
18
+ id: 3
19
+ project_id: 1
20
+ title: Rails is nice
21
+ subtitle: It makes me happy
22
+ content: except when I have to hack internals to fix pagination. even then really.
23
+ created_at: <%= 20.minutes.ago.utc.to_s(:db) %>
24
+
25
+ ar:
26
+ id: 4
27
+ project_id: 1
28
+ title: ActiveRecord sometimes freaks me out
29
+ content: "I mean, what's the deal with eager loading?"
30
+ created_at: <%= 15.minutes.ago.utc.to_s(:db) %>
@@ -0,0 +1,2 @@
1
+ class User < ActiveRecord::Base
2
+ end
@@ -0,0 +1,35 @@
1
+ david:
2
+ id: 1
3
+ name: David
4
+ salary: 80000
5
+ type: Developer
6
+
7
+ jamis:
8
+ id: 2
9
+ name: Jamis
10
+ salary: 150000
11
+ type: Developer
12
+
13
+ <% for digit in 3..10 %>
14
+ dev_<%= digit %>:
15
+ id: <%= digit %>
16
+ name: fixture_<%= digit %>
17
+ salary: 100000
18
+ type: Developer
19
+ <% end %>
20
+
21
+ poor_jamis:
22
+ id: 11
23
+ name: Jamis
24
+ salary: 9000
25
+ type: Developer
26
+
27
+ admin:
28
+ id: 12
29
+ name: admin
30
+ type: Admin
31
+
32
+ goofy:
33
+ id: 13
34
+ name: Goofy
35
+ type: Admin
@@ -0,0 +1,27 @@
1
+ require 'stringio'
2
+
3
+ class DeprecationMatcher
4
+ def initialize(message)
5
+ @message = message
6
+ end
7
+
8
+ def matches?(block)
9
+ @actual = hijack_stderr(&block)
10
+ PhraseMatcher.new("DEPRECATION WARNING: #{@message}").matches?(@actual)
11
+ end
12
+
13
+ def failure_message
14
+ "expected deprecation warning #{@message.inspect}, got #{@actual.inspect}"
15
+ end
16
+
17
+ private
18
+
19
+ def hijack_stderr
20
+ err = $stderr
21
+ $stderr = StringIO.new
22
+ yield
23
+ $stderr.string.rstrip
24
+ ensure
25
+ $stderr = err
26
+ end
27
+ end
@@ -0,0 +1,19 @@
1
+ class PhraseMatcher
2
+ def initialize(string)
3
+ @string = string
4
+ @pattern = /\b#{Regexp.escape string}\b/
5
+ end
6
+
7
+ def matches?(actual)
8
+ @actual = actual.to_s
9
+ @actual =~ @pattern
10
+ end
11
+
12
+ def failure_message
13
+ "expected #{@actual.inspect} to contain phrase #{@string.inspect}"
14
+ end
15
+
16
+ def negative_failure_message
17
+ "expected #{@actual.inspect} not to contain phrase #{@string.inspect}"
18
+ end
19
+ end
@@ -0,0 +1,36 @@
1
+ class QueryCountMatcher
2
+ def initialize(num)
3
+ @expected_count = num
4
+ end
5
+
6
+ def matches?(block)
7
+ run(block)
8
+
9
+ if @expected_count.respond_to? :include?
10
+ @expected_count.include? @count
11
+ else
12
+ @count == @expected_count
13
+ end
14
+ end
15
+
16
+ def run(block)
17
+ $query_count = 0
18
+ $query_sql = []
19
+ block.call
20
+ ensure
21
+ @queries = $query_sql.dup
22
+ @count = $query_count
23
+ end
24
+
25
+ def performed_queries
26
+ @queries
27
+ end
28
+
29
+ def failure_message
30
+ "expected #{@expected_count} queries, got #{@count}\n#{@queries.join("\n")}"
31
+ end
32
+
33
+ def negative_failure_message
34
+ "expected query count not to be #{@expected_count}"
35
+ end
36
+ end
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+ require 'will_paginate/page_number'
3
+
4
+ describe WillPaginate::PageNumber do
5
+ describe "valid" do
6
+ subject { described_class.new('12', 'page') }
7
+
8
+ it { should eq(12) }
9
+ its(:inspect) { should eq('page 12') }
10
+ it { should be_a(WillPaginate::PageNumber) }
11
+ it { should be_instance_of(WillPaginate::PageNumber) }
12
+ it { should be_a(Numeric) }
13
+ it { should be_a(Fixnum) }
14
+ it { should_not be_instance_of(Fixnum) }
15
+
16
+ it "passes the PageNumber=== type check" do |variable|
17
+ (WillPaginate::PageNumber === subject).should be
18
+ end
19
+
20
+ it "passes the Numeric=== type check" do |variable|
21
+ (Numeric === subject).should be
22
+ (Fixnum === subject).should be
23
+ end
24
+ end
25
+
26
+ describe "invalid" do
27
+ def create(value, name = 'page')
28
+ described_class.new(value, name)
29
+ end
30
+
31
+ it "errors out on non-int values" do
32
+ lambda { create(nil) }.should raise_error(WillPaginate::InvalidPage)
33
+ lambda { create('') }.should raise_error(WillPaginate::InvalidPage)
34
+ lambda { create('Schnitzel') }.should raise_error(WillPaginate::InvalidPage)
35
+ end
36
+
37
+ it "errors out on zero or less" do
38
+ lambda { create(0) }.should raise_error(WillPaginate::InvalidPage)
39
+ lambda { create(-1) }.should raise_error(WillPaginate::InvalidPage)
40
+ end
41
+
42
+ it "doesn't error out on zero for 'offset'" do
43
+ lambda { create(0, 'offset') }.should_not raise_error
44
+ lambda { create(-1, 'offset') }.should raise_error(WillPaginate::InvalidPage)
45
+ end
46
+ end
47
+
48
+ describe "coercion method" do
49
+ it "defaults to 'page' name" do
50
+ num = WillPaginate::PageNumber(12)
51
+ num.inspect.should eq('page 12')
52
+ end
53
+
54
+ it "accepts a custom name" do
55
+ num = WillPaginate::PageNumber(12, 'monkeys')
56
+ num.inspect.should eq('monkeys 12')
57
+ end
58
+
59
+ it "doesn't affect PageNumber instances" do
60
+ num = WillPaginate::PageNumber(12)
61
+ num2 = WillPaginate::PageNumber(num)
62
+ num2.object_id.should eq(num.object_id)
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+ require 'will_paginate/per_page'
3
+
4
+ describe WillPaginate::PerPage do
5
+
6
+ class MyModel
7
+ extend WillPaginate::PerPage
8
+ end
9
+
10
+ it "has the default value" do
11
+ MyModel.per_page.should == 30
12
+
13
+ WillPaginate.per_page = 10
14
+ begin
15
+ MyModel.per_page.should == 10
16
+ ensure
17
+ WillPaginate.per_page = 30
18
+ end
19
+ end
20
+
21
+ it "casts values to int" do
22
+ WillPaginate.per_page = '10'
23
+ begin
24
+ MyModel.per_page.should == 10
25
+ ensure
26
+ WillPaginate.per_page = 30
27
+ end
28
+ end
29
+
30
+ it "has an explicit value" do
31
+ MyModel.per_page = 12
32
+ begin
33
+ MyModel.per_page.should == 12
34
+ subclass = Class.new(MyModel)
35
+ subclass.per_page.should == 12
36
+ ensure
37
+ MyModel.send(:remove_instance_variable, '@per_page')
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,46 @@
1
+ require 'rspec'
2
+ require 'view_helpers/view_example_group'
3
+ begin
4
+ require 'ruby-debug'
5
+ rescue LoadError
6
+ # no debugger available
7
+ end
8
+
9
+ Dir[File.expand_path('../matchers/*_matcher.rb', __FILE__)].each { |matcher| require matcher }
10
+
11
+ RSpec.configure do |config|
12
+ config.include Module.new {
13
+ protected
14
+
15
+ def include_phrase(string)
16
+ PhraseMatcher.new(string)
17
+ end
18
+
19
+ def have_deprecation(msg)
20
+ DeprecationMatcher.new(msg)
21
+ end
22
+
23
+ def run_queries(num)
24
+ QueryCountMatcher.new(num)
25
+ end
26
+
27
+ def ignore_deprecation
28
+ ActiveSupport::Deprecation.silence { yield }
29
+ end
30
+
31
+ def show_queries(&block)
32
+ counter = QueryCountMatcher.new(nil)
33
+ counter.run block
34
+ ensure
35
+ queries = counter.performed_queries
36
+ if queries.any?
37
+ puts queries
38
+ else
39
+ puts "no queries"
40
+ end
41
+ end
42
+ }
43
+
44
+ config.mock_with :mocha
45
+ config.backtrace_clean_patterns << /view_example_group/
46
+ end