zhanghd_kaminari 0.10.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/.document +5 -0
  2. data/.gemtest +0 -0
  3. data/.rspec +2 -0
  4. data/CHANGELOG +159 -0
  5. data/Gemfile +30 -0
  6. data/Gemfile.lock +141 -0
  7. data/LICENSE.txt +20 -0
  8. data/README.rdoc +177 -0
  9. data/Rakefile +57 -0
  10. data/VERSION +1 -0
  11. data/app/views/kaminari/_current_page.html.erb +9 -0
  12. data/app/views/kaminari/_current_page.html.haml +9 -0
  13. data/app/views/kaminari/_first_page_link.html.erb +12 -0
  14. data/app/views/kaminari/_first_page_link.html.haml +10 -0
  15. data/app/views/kaminari/_last_page_link.html.erb +12 -0
  16. data/app/views/kaminari/_last_page_link.html.haml +10 -0
  17. data/app/views/kaminari/_next_link.html.erb +11 -0
  18. data/app/views/kaminari/_next_link.html.haml +9 -0
  19. data/app/views/kaminari/_next_span.html.erb +8 -0
  20. data/app/views/kaminari/_next_span.html.haml +7 -0
  21. data/app/views/kaminari/_page_link.html.erb +12 -0
  22. data/app/views/kaminari/_page_link.html.haml +10 -0
  23. data/app/views/kaminari/_paginator.html.erb +29 -0
  24. data/app/views/kaminari/_paginator.html.haml +23 -0
  25. data/app/views/kaminari/_prev_link.html.erb +11 -0
  26. data/app/views/kaminari/_prev_link.html.haml +9 -0
  27. data/app/views/kaminari/_prev_span.html.erb +8 -0
  28. data/app/views/kaminari/_prev_span.html.haml +7 -0
  29. data/app/views/kaminari/_truncated_span.html.erb +8 -0
  30. data/app/views/kaminari/_truncated_span.html.haml +8 -0
  31. data/config/locales/kaminari.yml +8 -0
  32. data/kaminari.gemspec +152 -0
  33. data/lib/generators/kaminari/views_generator.rb +99 -0
  34. data/lib/kaminari.rb +2 -0
  35. data/lib/kaminari/engine.rb +4 -0
  36. data/lib/kaminari/helpers/action_view_extension.rb +25 -0
  37. data/lib/kaminari/helpers/helpers.rb +75 -0
  38. data/lib/kaminari/helpers/tags.rb +263 -0
  39. data/lib/kaminari/models/active_record_extension.rb +32 -0
  40. data/lib/kaminari/models/active_record_relation_methods.rb +12 -0
  41. data/lib/kaminari/models/array_paginate_extension.rb +17 -0
  42. data/lib/kaminari/models/configuration_methods.rb +20 -0
  43. data/lib/kaminari/models/mongoid_criteria_methods.rb +18 -0
  44. data/lib/kaminari/models/mongoid_extension.rb +30 -0
  45. data/lib/kaminari/models/page_scope_methods.rb +26 -0
  46. data/lib/kaminari/railtie.rb +34 -0
  47. data/spec/acceptance/acceptance_helper.rb +5 -0
  48. data/spec/acceptance/support/helpers.rb +5 -0
  49. data/spec/acceptance/support/paths.rb +9 -0
  50. data/spec/acceptance/users_spec.rb +44 -0
  51. data/spec/fake_app.rb +48 -0
  52. data/spec/helpers/helpers_spec.rb +126 -0
  53. data/spec/helpers/tags_spec.rb +158 -0
  54. data/spec/models/default_per_page_spec.rb +29 -0
  55. data/spec/models/mongoid_spec.rb +72 -0
  56. data/spec/models/scopes_spec.rb +109 -0
  57. data/spec/spec_helper.rb +27 -0
  58. data/spec/support/matchers.rb +46 -0
  59. metadata +344 -0
@@ -0,0 +1,32 @@
1
+ require File.join(File.dirname(__FILE__), 'active_record_relation_methods')
2
+ module Kaminari
3
+ module ActiveRecordExtension
4
+ extend ActiveSupport::Concern
5
+ included do
6
+ def self.inherited(kls) #:nodoc:
7
+ # TERRIBLE HORRIBLE NO GOOD VERY BAD HACK: inheritable_attributes is not yet set here on AR 3.0
8
+ unless kls.default_scoping
9
+ new_inheritable_attributes = Hash[inheritable_attributes.map do |key, value|
10
+ [key, value.duplicable? ? value.dup : value]
11
+ end]
12
+ kls.instance_variable_set('@inheritable_attributes', new_inheritable_attributes)
13
+ end
14
+
15
+ kls.class_eval do
16
+ include Kaminari::ConfigurationMethods
17
+
18
+ # Fetch the values at the specified page number
19
+ # Model.page(5)
20
+ scope :page, Proc.new {|num|
21
+ limit(default_per_page).offset(default_per_page * ([num.to_i, 1].max - 1))
22
+ } do
23
+ include Kaminari::ActiveRecordRelationMethods
24
+ include Kaminari::PageScopeMethods
25
+ end
26
+ end
27
+
28
+ super
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,12 @@
1
+ module Kaminari
2
+ module ActiveRecordRelationMethods
3
+ extend ActiveSupport::Concern
4
+ module InstanceMethods
5
+ def total_count #:nodoc:
6
+ c = except(:offset, :limit).count
7
+ # .group returns an OrderdHash that responds to #count
8
+ c.respond_to?(:count) ? c.count : c
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ module Kaminari
2
+ module ArrayPaginateExtension
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def current_page
7
+ params[:page] || 1
8
+ end
9
+ def num_pages
10
+ count
11
+ end
12
+ def limit_value
13
+ 10
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ module Kaminari
2
+ module ConfigurationMethods
3
+ extend ActiveSupport::Concern
4
+ module ClassMethods
5
+ # Overrides the default per_page value per model
6
+ # class Article < ActiveRecord::Base
7
+ # paginates_per 10
8
+ # end
9
+ def paginates_per(val)
10
+ @_default_per_page = val
11
+ end
12
+
13
+ # This model's default per_page value
14
+ # returns 25 unless explicitly overridden via <tt>paginates_per</tt>
15
+ def default_per_page
16
+ @_default_per_page || Kaminari::DEFAULT_PER_PAGE
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,18 @@
1
+ module Kaminari
2
+ module MongoidCriteriaMethods
3
+ extend ActiveSupport::Concern
4
+ module InstanceMethods
5
+ def limit_value #:nodoc:
6
+ options[:limit]
7
+ end
8
+
9
+ def offset_value #:nodoc:
10
+ options[:skip]
11
+ end
12
+
13
+ def total_count #:nodoc:
14
+ count
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,30 @@
1
+ require File.join(File.dirname(__FILE__), 'mongoid_criteria_methods')
2
+ module Kaminari
3
+ module MongoidExtension
4
+ module Criteria
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ def page(*args)
9
+ self.klass.page(*args).criteria.merge(self)
10
+ end
11
+ end
12
+ end
13
+
14
+ module Document
15
+ extend ActiveSupport::Concern
16
+ include Kaminari::ConfigurationMethods
17
+
18
+ included do
19
+ # Fetch the values at the specified page number
20
+ # Model.page(5)
21
+ scope :page, Proc.new {|num|
22
+ limit(default_per_page).offset(default_per_page * ([num.to_i, 1].max - 1))
23
+ } do
24
+ include Kaminari::MongoidCriteriaMethods
25
+ include Kaminari::PageScopeMethods
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,26 @@
1
+ module Kaminari
2
+ module PageScopeMethods
3
+ extend ActiveSupport::Concern
4
+ module InstanceMethods
5
+ # Specify the <tt>per_page</tt> value for the preceding <tt>page</tt> scope
6
+ # Model.page(3).per(10)
7
+ def per(num)
8
+ if (n = num.to_i) <= 0
9
+ self
10
+ else
11
+ limit(n).offset(offset_value / limit_value * n)
12
+ end
13
+ end
14
+
15
+ # Total number of pages
16
+ def num_pages
17
+ (total_count.to_f / limit_value).ceil
18
+ end
19
+
20
+ # Current page number
21
+ def current_page
22
+ (offset_value / limit_value) + 1
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,34 @@
1
+ require 'rails'
2
+ # ensure ORMs are loaded *before* initializing Kaminari
3
+ begin; require 'mongoid'; rescue LoadError; end
4
+
5
+ require File.join(File.dirname(__FILE__), 'helpers/action_view_extension')
6
+ require File.join(File.dirname(__FILE__), 'helpers/helpers')
7
+ require File.join(File.dirname(__FILE__), 'models/page_scope_methods')
8
+ require File.join(File.dirname(__FILE__), 'models/configuration_methods')
9
+
10
+ module Kaminari
11
+ DEFAULT_PER_PAGE = 25 unless defined? ::Kaminari::DEFAULT_PER_PAGE
12
+ class Railtie < ::Rails::Railtie #:nodoc:
13
+ initializer 'kaminari' do |app|
14
+ ActiveSupport.on_load(:active_record) do
15
+ require File.join(File.dirname(__FILE__), 'models/active_record_extension')
16
+ ::ActiveRecord::Base.send :include, Kaminari::ActiveRecordExtension
17
+ end
18
+
19
+ ActiveSupport.on_load("active_support/core_ext/array") do
20
+ require File.join(File.dirname(__FILE__), 'models/array_paginate_extension')
21
+ ::ActiveRecord::Base.send :include, Kaminari::ArrayPaginateExtension
22
+ end
23
+
24
+ if defined? ::Mongoid
25
+ require File.join(File.dirname(__FILE__), 'models/mongoid_extension')
26
+ ::Mongoid::Document.send :include, Kaminari::MongoidExtension::Document
27
+ ::Mongoid::Criteria.send :include, Kaminari::MongoidExtension::Criteria
28
+ end
29
+ ActiveSupport.on_load(:action_view) do
30
+ ::ActionView::Base.send :include, Kaminari::ActionViewExtension
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,5 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+ require "steak"
3
+
4
+ # Put your acceptance spec helpers inside /spec/acceptance/support
5
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
@@ -0,0 +1,5 @@
1
+ module HelperMethods
2
+ # Put helper methods you need to be available in all tests here.
3
+ end
4
+
5
+ RSpec.configuration.include HelperMethods, :type => :acceptance
@@ -0,0 +1,9 @@
1
+ module NavigationHelpers
2
+ # Put helper methods related to the paths in your application here.
3
+
4
+ def homepage
5
+ "/"
6
+ end
7
+ end
8
+
9
+ RSpec.configuration.include NavigationHelpers, :type => :acceptance
@@ -0,0 +1,44 @@
1
+ # encoding: UTF-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/acceptance_helper')
3
+
4
+ feature 'Users' do
5
+ background do
6
+ 1.upto(100) {|i| User.create! :name => "user#{'%03d' % i}" }
7
+ end
8
+ scenario 'navigating by pagination links' do
9
+ visit users_path
10
+
11
+ within 'nav.pagination' do
12
+ within 'span.page.current' do
13
+ page.should have_content '1'
14
+ end
15
+ within 'span.next' do
16
+ click_link 'Next »'
17
+ end
18
+ end
19
+
20
+ within 'nav.pagination' do
21
+ within 'span.page.current' do
22
+ page.should have_content '2'
23
+ end
24
+ within 'span.page.last' do
25
+ click_link '4'
26
+ end
27
+ end
28
+
29
+ within 'nav.pagination' do
30
+ within 'span.page.current' do
31
+ page.should have_content '4'
32
+ end
33
+ within 'span.prev' do
34
+ click_link '« Prev'
35
+ end
36
+ end
37
+
38
+ within 'nav.pagination' do
39
+ within 'span.page.current' do
40
+ page.should have_content '3'
41
+ end
42
+ end
43
+ end
44
+ end
data/spec/fake_app.rb ADDED
@@ -0,0 +1,48 @@
1
+ require 'active_record'
2
+ require 'action_controller/railtie'
3
+ require 'action_view/railtie'
4
+
5
+ # database
6
+ ActiveRecord::Base.configurations = {'test' => {:adapter => 'sqlite3', :database => ':memory:'}}
7
+ ActiveRecord::Base.establish_connection('test')
8
+
9
+ # config
10
+ app = Class.new(Rails::Application)
11
+ app.config.secret_token = "3b7cd727ee24e8444053437c36cc66c4"
12
+ app.config.session_store :cookie_store, :key => "_myapp_session"
13
+ app.config.active_support.deprecation = :log
14
+ app.initialize!
15
+
16
+ # routes
17
+ app.routes.draw do
18
+ resources :users
19
+ end
20
+
21
+ # models
22
+ class User < ActiveRecord::Base
23
+ default_scope order(:name)
24
+ end
25
+ class Book < ActiveRecord::Base; end
26
+
27
+ # controllers
28
+ class ApplicationController < ActionController::Base; end
29
+ class UsersController < ApplicationController
30
+ def index
31
+ @users = User.page params[:page]
32
+ render :inline => <<-ERB
33
+ <%= @users.map(&:name).join("\n") %>
34
+ <%= paginate @users %>
35
+ ERB
36
+ end
37
+ end
38
+
39
+ # helpers
40
+ Object.const_set(:ApplicationHelper, Module.new)
41
+
42
+ #migrations
43
+ class CreateAllTables < ActiveRecord::Migration
44
+ def self.up
45
+ create_table(:users) {|t| t.string :name; t.integer :age}
46
+ create_table(:books) {|t| t.string :title}
47
+ end
48
+ end
@@ -0,0 +1,126 @@
1
+ require File.expand_path('../spec_helper', File.dirname(__FILE__))
2
+ include Kaminari::Helpers
3
+
4
+ describe 'Kaminari::Helpers::PaginationRenderer' do
5
+ let :template do
6
+ stub(r = Object.new) do
7
+ render.with_any_args
8
+ params { {} }
9
+ url_for {|h| "/foo?page=#{h[:page]}"}
10
+ end
11
+ r
12
+ end
13
+
14
+ describe '#params' do
15
+ before do
16
+ @renderer = PaginationRenderer.new(template, :params => {:controller => 'foo', :action => 'bar'})
17
+ end
18
+ subject { @renderer.instance_variable_get '@template' }
19
+ its(:params) { should == {:controller => 'foo', :action => 'bar'} }
20
+ end
21
+
22
+ #TODO test somehow...
23
+ # describe '#tagify_links' do
24
+ # def tags_with(options)
25
+ # PaginationRenderer.new(template, options).tagify_links
26
+ # end
27
+
28
+ # context '1 page in total' do
29
+ # subject { tags_with :num_pages => 1, :current_page => 1 }
30
+ # it { should have(0).tags }
31
+ # end
32
+
33
+ # context '10 pages in total' do
34
+ # context 'first page' do
35
+ # subject { tags_with :num_pages => 10, :current_page => 1 }
36
+ # it { should_not contain_tag PrevLink }
37
+ # it { should contain_tag PrevSpan }
38
+ # it { should contain_tag CurrentPage }
39
+ # it { should_not contain_tag FirstPageLink }
40
+ # it { should contain_tag LastPageLink }
41
+ # it { should contain_tag PageLink }
42
+ # it { should contain_tag NextLink }
43
+ # it { should_not contain_tag NextSpan }
44
+ # it { should contain_tag TruncatedSpan }
45
+ # end
46
+
47
+ # context 'second page' do
48
+ # subject { tags_with :num_pages => 10, :current_page => 2 }
49
+ # it { should contain_tag PrevLink }
50
+ # it { should_not contain_tag PrevSpan }
51
+ # it { should contain_tag CurrentPage }
52
+ # it { should contain_tag FirstPageLink }
53
+ # it { should contain_tag LastPageLink }
54
+ # it { should contain_tag PageLink }
55
+ # it { should contain_tag NextLink }
56
+ # it { should_not contain_tag NextSpan }
57
+ # it { should contain_tag TruncatedSpan }
58
+ # end
59
+
60
+ # context 'third page' do
61
+ # subject { tags_with :num_pages => 10, :current_page => 3 }
62
+ # it { should contain_tag PrevLink }
63
+ # it { should_not contain_tag PrevSpan }
64
+ # it { should contain_tag CurrentPage }
65
+ # it { should contain_tag FirstPageLink }
66
+ # it { should contain_tag LastPageLink }
67
+ # it { should contain_tag PageLink }
68
+ # it { should contain_tag NextLink }
69
+ # it { should_not contain_tag NextSpan }
70
+ # it { should contain_tag TruncatedSpan }
71
+ # end
72
+
73
+ # context 'fourth page(no truncation)' do
74
+ # subject { tags_with :num_pages => 10, :current_page => 4 }
75
+ # it { should contain_tag PrevLink }
76
+ # it { should_not contain_tag PrevSpan }
77
+ # it { should contain_tag CurrentPage }
78
+ # it { should contain_tag FirstPageLink }
79
+ # it { should contain_tag LastPageLink }
80
+ # it { should contain_tag PageLink }
81
+ # it { should contain_tag NextLink }
82
+ # it { should_not contain_tag NextSpan }
83
+ # it { should_not contain_tag TruncatedSpan }
84
+ # end
85
+
86
+ # context 'seventh page(no truncation)' do
87
+ # subject { tags_with :num_pages => 10, :current_page => 7 }
88
+ # it { should contain_tag PrevLink }
89
+ # it { should_not contain_tag PrevSpan }
90
+ # it { should contain_tag CurrentPage }
91
+ # it { should contain_tag FirstPageLink }
92
+ # it { should contain_tag LastPageLink }
93
+ # it { should contain_tag PageLink }
94
+ # it { should contain_tag NextLink }
95
+ # it { should_not contain_tag NextSpan }
96
+ # it { should_not contain_tag TruncatedSpan }
97
+ # end
98
+
99
+ # context 'eighth page' do
100
+ # subject { tags_with :num_pages => 10, :current_page => 8 }
101
+ # it { should contain_tag PrevLink }
102
+ # it { should_not contain_tag PrevSpan }
103
+ # it { should contain_tag CurrentPage }
104
+ # it { should contain_tag FirstPageLink }
105
+ # it { should contain_tag LastPageLink }
106
+ # it { should contain_tag PageLink }
107
+ # it { should contain_tag NextLink }
108
+ # it { should_not contain_tag NextSpan }
109
+ # it { should contain_tag TruncatedSpan }
110
+ # end
111
+
112
+ # context 'last page' do
113
+ # subject { tags_with :num_pages => 10, :current_page => 10 }
114
+ # it { should contain_tag PrevLink }
115
+ # it { should_not contain_tag PrevSpan }
116
+ # it { should contain_tag CurrentPage }
117
+ # it { should contain_tag FirstPageLink }
118
+ # it { should_not contain_tag LastPageLink }
119
+ # it { should contain_tag PageLink }
120
+ # it { should_not contain_tag NextLink }
121
+ # it { should contain_tag NextSpan }
122
+ # it { should contain_tag TruncatedSpan }
123
+ # end
124
+ # end
125
+ # end
126
+ end