classic_pagination 1.0.2 → 1.0.3

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.
@@ -0,0 +1,135 @@
1
+ module ActionView
2
+ module Helpers
3
+ # Provides methods for linking to ActionController::Pagination objects using a simple generator API. You can optionally
4
+ # also build your links manually using ActionView::Helpers::AssetHelper#link_to like so:
5
+ #
6
+ # <%= link_to "Previous page", { :page => paginator.current.previous } if paginator.current.previous %>
7
+ # <%= link_to "Next page", { :page => paginator.current.next } if paginator.current.next %>
8
+ module PaginationHelper
9
+ unless const_defined?(:DEFAULT_OPTIONS)
10
+ DEFAULT_OPTIONS = {
11
+ :name => :page,
12
+ :window_size => 2,
13
+ :always_show_anchors => true,
14
+ :link_to_current_page => false,
15
+ :params => {}
16
+ }
17
+ end
18
+
19
+ # Creates a basic HTML link bar for the given +paginator+. Links will be created
20
+ # for the next and/or previous page and for a number of other pages around the current
21
+ # pages position. The +html_options+ hash is passed to +link_to+ when the links are created.
22
+ #
23
+ # ==== Options
24
+ # <tt>:name</tt>:: the routing name for this paginator
25
+ # (defaults to +page+)
26
+ # <tt>:prefix</tt>:: prefix for pagination links
27
+ # (i.e. Older Pages: 1 2 3 4)
28
+ # <tt>:suffix</tt>:: suffix for pagination links
29
+ # (i.e. 1 2 3 4 <- Older Pages)
30
+ # <tt>:window_size</tt>:: the number of pages to show around
31
+ # the current page (defaults to <tt>2</tt>)
32
+ # <tt>:always_show_anchors</tt>:: whether or not the first and last
33
+ # pages should always be shown
34
+ # (defaults to +true+)
35
+ # <tt>:link_to_current_page</tt>:: whether or not the current page
36
+ # should be linked to (defaults to
37
+ # +false+)
38
+ # <tt>:params</tt>:: any additional routing parameters
39
+ # for page URLs
40
+ #
41
+ # ==== Examples
42
+ # # We'll assume we have a paginator setup in @person_pages...
43
+ #
44
+ # pagination_links(@person_pages)
45
+ # # => 1 <a href="/?page=2/">2</a> <a href="/?page=3/">3</a> ... <a href="/?page=10/">10</a>
46
+ #
47
+ # pagination_links(@person_pages, :link_to_current_page => true)
48
+ # # => <a href="/?page=1/">1</a> <a href="/?page=2/">2</a> <a href="/?page=3/">3</a> ... <a href="/?page=10/">10</a>
49
+ #
50
+ # pagination_links(@person_pages, :always_show_anchors => false)
51
+ # # => 1 <a href="/?page=2/">2</a> <a href="/?page=3/">3</a>
52
+ #
53
+ # pagination_links(@person_pages, :window_size => 1)
54
+ # # => 1 <a href="/?page=2/">2</a> ... <a href="/?page=10/">10</a>
55
+ #
56
+ # pagination_links(@person_pages, :params => { :viewer => "flash" })
57
+ # # => 1 <a href="/?page=2&amp;viewer=flash/">2</a> <a href="/?page=3&amp;viewer=flash/">3</a> ...
58
+ # # <a href="/?page=10&amp;viewer=flash/">10</a>
59
+ def pagination_links(paginator, options={}, html_options={})
60
+ name = options[:name] || DEFAULT_OPTIONS[:name]
61
+ params = (options[:params] || DEFAULT_OPTIONS[:params]).clone
62
+
63
+ prefix = options[:prefix] || ''
64
+ suffix = options[:suffix] || ''
65
+
66
+ pagination_links_each(paginator, options, prefix, suffix) do |n|
67
+ params[name] = n
68
+ link_to(n.to_s, params, html_options)
69
+ end
70
+ end
71
+
72
+ # Iterate through the pages of a given +paginator+, invoking a
73
+ # block for each page number that needs to be rendered as a link.
74
+ #
75
+ # ==== Options
76
+ # <tt>:window_size</tt>:: the number of pages to show around
77
+ # the current page (defaults to +2+)
78
+ # <tt>:always_show_anchors</tt>:: whether or not the first and last
79
+ # pages should always be shown
80
+ # (defaults to +true+)
81
+ # <tt>:link_to_current_page</tt>:: whether or not the current page
82
+ # should be linked to (defaults to
83
+ # +false+)
84
+ #
85
+ # ==== Example
86
+ # # Turn paginated links into an Ajax call
87
+ # pagination_links_each(paginator, page_options) do |link|
88
+ # options = { :url => {:action => 'list'}, :update => 'results' }
89
+ # html_options = { :href => url_for(:action => 'list') }
90
+ #
91
+ # link_to_remote(link.to_s, options, html_options)
92
+ # end
93
+ def pagination_links_each(paginator, options, prefix = nil, suffix = nil)
94
+ options = DEFAULT_OPTIONS.merge(options)
95
+ link_to_current_page = options[:link_to_current_page]
96
+ always_show_anchors = options[:always_show_anchors]
97
+
98
+ current_page = paginator.current_page
99
+ window_pages = current_page.window(options[:window_size]).pages
100
+ return if window_pages.length <= 1 unless link_to_current_page
101
+
102
+ first, last = paginator.first, paginator.last
103
+
104
+ html = ''
105
+
106
+ html << prefix if prefix
107
+
108
+ if always_show_anchors and not (wp_first = window_pages[0]).first?
109
+ html << yield(first.number)
110
+ html << ' ... ' if wp_first.number - first.number > 1
111
+ html << ' '
112
+ end
113
+
114
+ window_pages.each do |page|
115
+ if current_page == page && !link_to_current_page
116
+ html << page.number.to_s
117
+ else
118
+ html << yield(page.number)
119
+ end
120
+ html << ' '
121
+ end
122
+
123
+ if always_show_anchors and not (wp_last = window_pages[-1]).last?
124
+ html << ' ... ' if last.number - wp_last.number > 1
125
+ html << yield(last.number)
126
+ end
127
+
128
+ html << suffix if suffix
129
+
130
+ html
131
+ end
132
+
133
+ end # PaginationHelper
134
+ end # Helpers
135
+ end # ActionView
@@ -0,0 +1,24 @@
1
+ thirty_seven_signals:
2
+ id: 1
3
+ name: 37Signals
4
+ rating: 4
5
+
6
+ TextDrive:
7
+ id: 2
8
+ name: TextDrive
9
+ rating: 4
10
+
11
+ PlanetArgon:
12
+ id: 3
13
+ name: Planet Argon
14
+ rating: 4
15
+
16
+ Google:
17
+ id: 4
18
+ name: Google
19
+ rating: 4
20
+
21
+ Ionist:
22
+ id: 5
23
+ name: Ioni.st
24
+ rating: 4
@@ -0,0 +1,9 @@
1
+ class Company < ActiveRecord::Base
2
+ attr_protected :rating
3
+ set_sequence_name :companies_nonstd_seq
4
+
5
+ validates_presence_of :name
6
+ def validate
7
+ errors.add('rating', 'rating should not be 2') if rating == 2
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ class Developer < ActiveRecord::Base
2
+ has_and_belongs_to_many :projects
3
+ end
4
+
5
+ class DeVeLoPeR < ActiveRecord::Base
6
+ set_table_name "developers"
7
+ end
@@ -0,0 +1,21 @@
1
+ david:
2
+ id: 1
3
+ name: David
4
+ salary: 80000
5
+
6
+ jamis:
7
+ id: 2
8
+ name: Jamis
9
+ salary: 150000
10
+
11
+ <% for digit in 3..10 %>
12
+ dev_<%= digit %>:
13
+ id: <%= digit %>
14
+ name: fixture_<%= digit %>
15
+ salary: 100000
16
+ <% end %>
17
+
18
+ poor_jamis:
19
+ id: 11
20
+ name: Jamis
21
+ salary: 9000
@@ -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,3 @@
1
+ class Project < ActiveRecord::Base
2
+ has_and_belongs_to_many :developers, :uniq => true
3
+ end
@@ -0,0 +1,7 @@
1
+ action_controller:
2
+ id: 2
3
+ name: Active Controller
4
+
5
+ active_record:
6
+ id: 1
7
+ name: Active Record
@@ -0,0 +1,13 @@
1
+ witty_retort:
2
+ id: 1
3
+ topic_id: 1
4
+ content: Birdman is better!
5
+ created_at: <%= 6.hours.ago.to_s(:db) %>
6
+ updated_at: nil
7
+
8
+ another:
9
+ id: 2
10
+ topic_id: 2
11
+ content: Nuh uh!
12
+ created_at: <%= 1.hour.ago.to_s(:db) %>
13
+ updated_at: nil
@@ -0,0 +1,5 @@
1
+ class Reply < ActiveRecord::Base
2
+ belongs_to :topic, :include => [:replies]
3
+
4
+ validates_presence_of :content
5
+ end
@@ -0,0 +1,42 @@
1
+ CREATE TABLE 'companies' (
2
+ 'id' INTEGER PRIMARY KEY NOT NULL,
3
+ 'name' TEXT DEFAULT NULL,
4
+ 'rating' INTEGER DEFAULT 1
5
+ );
6
+
7
+ CREATE TABLE 'replies' (
8
+ 'id' INTEGER PRIMARY KEY NOT NULL,
9
+ 'content' text,
10
+ 'created_at' datetime,
11
+ 'updated_at' datetime,
12
+ 'topic_id' integer
13
+ );
14
+
15
+ CREATE TABLE 'topics' (
16
+ 'id' INTEGER PRIMARY KEY NOT NULL,
17
+ 'title' varchar(255),
18
+ 'subtitle' varchar(255),
19
+ 'content' text,
20
+ 'created_at' datetime,
21
+ 'updated_at' datetime
22
+ );
23
+
24
+ CREATE TABLE 'developers' (
25
+ 'id' INTEGER PRIMARY KEY NOT NULL,
26
+ 'name' TEXT DEFAULT NULL,
27
+ 'salary' INTEGER DEFAULT 70000,
28
+ 'created_at' DATETIME DEFAULT NULL,
29
+ 'updated_at' DATETIME DEFAULT NULL
30
+ );
31
+
32
+ CREATE TABLE 'projects' (
33
+ 'id' INTEGER PRIMARY KEY NOT NULL,
34
+ 'name' TEXT DEFAULT NULL
35
+ );
36
+
37
+ CREATE TABLE 'developers_projects' (
38
+ 'developer_id' INTEGER NOT NULL,
39
+ 'project_id' INTEGER NOT NULL,
40
+ 'joined_on' DATE DEFAULT NULL,
41
+ 'access_level' INTEGER DEFAULT 1
42
+ );
@@ -0,0 +1,3 @@
1
+ class Topic < ActiveRecord::Base
2
+ has_many :replies, :include => [:user], :dependent => :destroy
3
+ end
@@ -0,0 +1,22 @@
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.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: It really is
14
+ created_at: <%= 2.hours.ago.to_s(:db) %>
15
+ updated_at:
16
+
17
+ rails:
18
+ id: 3
19
+ title: Rails is nice
20
+ subtitle: It makes me happy
21
+ content: except when I have to hack internals to fix pagination. even then really.
22
+ created_at: <%= 20.minutes.ago.to_s(:db) %>
data/test/helper.rb ADDED
@@ -0,0 +1,117 @@
1
+ require 'test/unit'
2
+
3
+ unless defined?(ActiveRecord)
4
+ plugin_root = File.join(File.dirname(__FILE__), '..')
5
+
6
+ # first look for a symlink to a copy of the framework
7
+ if framework_root = ["#{plugin_root}/rails", "#{plugin_root}/../../rails"].find { |p| File.directory? p }
8
+ puts "found framework root: #{framework_root}"
9
+ # this allows for a plugin to be tested outside an app
10
+ $:.unshift "#{framework_root}/activesupport/lib", "#{framework_root}/activerecord/lib", "#{framework_root}/actionpack/lib"
11
+ else
12
+ # is the plugin installed in an application?
13
+ app_root = plugin_root + '/../../..'
14
+
15
+ if File.directory? app_root + '/config'
16
+ puts 'using config/boot.rb'
17
+ ENV['RAILS_ENV'] = 'test'
18
+ require File.expand_path(app_root + '/config/boot')
19
+ else
20
+ # simply use installed gems if available
21
+ puts 'using rubygems'
22
+ require 'rubygems'
23
+ gem 'actionpack'; gem 'activerecord'
24
+ end
25
+ end
26
+
27
+ %w(action_pack active_record action_controller active_record/fixtures action_controller/test_process).each {|f| require f}
28
+
29
+ Dependencies.load_paths.unshift "#{plugin_root}/lib"
30
+ end
31
+
32
+ # Define the connector
33
+ class ActiveRecordTestConnector
34
+ cattr_accessor :able_to_connect
35
+ cattr_accessor :connected
36
+
37
+ # Set our defaults
38
+ self.connected = false
39
+ self.able_to_connect = true
40
+
41
+ class << self
42
+ def setup
43
+ unless self.connected || !self.able_to_connect
44
+ setup_connection
45
+ load_schema
46
+ require_fixture_models
47
+ self.connected = true
48
+ end
49
+ rescue Exception => e # errors from ActiveRecord setup
50
+ $stderr.puts "\nSkipping ActiveRecord assertion tests: #{e}"
51
+ #$stderr.puts " #{e.backtrace.join("\n ")}\n"
52
+ self.able_to_connect = false
53
+ end
54
+
55
+ private
56
+
57
+ def setup_connection
58
+ if Object.const_defined?(:ActiveRecord)
59
+ defaults = { :database => ':memory:' }
60
+ begin
61
+ options = defaults.merge :adapter => 'sqlite3', :timeout => 500
62
+ ActiveRecord::Base.establish_connection(options)
63
+ ActiveRecord::Base.configurations = { 'sqlite3_ar_integration' => options }
64
+ ActiveRecord::Base.connection
65
+ rescue Exception # errors from establishing a connection
66
+ $stderr.puts 'SQLite 3 unavailable; trying SQLite 2.'
67
+ options = defaults.merge :adapter => 'sqlite'
68
+ ActiveRecord::Base.establish_connection(options)
69
+ ActiveRecord::Base.configurations = { 'sqlite2_ar_integration' => options }
70
+ ActiveRecord::Base.connection
71
+ end
72
+
73
+ Object.send(:const_set, :QUOTED_TYPE, ActiveRecord::Base.connection.quote_column_name('type')) unless Object.const_defined?(:QUOTED_TYPE)
74
+ else
75
+ raise "Can't setup connection since ActiveRecord isn't loaded."
76
+ end
77
+ end
78
+
79
+ # Load actionpack sqlite tables
80
+ def load_schema
81
+ File.read(File.dirname(__FILE__) + "/fixtures/schema.sql").split(';').each do |sql|
82
+ ActiveRecord::Base.connection.execute(sql) unless sql.blank?
83
+ end
84
+ end
85
+
86
+ def require_fixture_models
87
+ Dir.glob(File.dirname(__FILE__) + "/fixtures/*.rb").each {|f| require f}
88
+ end
89
+ end
90
+ end
91
+
92
+ # Test case for inheritance
93
+ class ActiveRecordTestCase < Test::Unit::TestCase
94
+ # Set our fixture path
95
+ if ActiveRecordTestConnector.able_to_connect
96
+ self.fixture_path = "#{File.dirname(__FILE__)}/fixtures/"
97
+ self.use_transactional_fixtures = false
98
+ end
99
+
100
+ def self.fixtures(*args)
101
+ super if ActiveRecordTestConnector.connected
102
+ end
103
+
104
+ def run(*args)
105
+ super if ActiveRecordTestConnector.connected
106
+ end
107
+
108
+ # Default so Test::Unit::TestCase doesn't complain
109
+ def test_truth
110
+ end
111
+ end
112
+
113
+ ActiveRecordTestConnector.setup
114
+ ActionController::Routing::Routes.reload rescue nil
115
+ ActionController::Routing::Routes.draw do |map|
116
+ map.connect ':controller/:action/:id'
117
+ end
@@ -0,0 +1,38 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+ require File.dirname(__FILE__) + '/../init'
3
+
4
+ class PaginationHelperTest < Test::Unit::TestCase
5
+ include ActionController::Pagination
6
+ include ActionView::Helpers::PaginationHelper
7
+ include ActionView::Helpers::UrlHelper
8
+ include ActionView::Helpers::TagHelper
9
+
10
+ def setup
11
+ @controller = Class.new do
12
+ attr_accessor :url, :request
13
+ def url_for(options, *parameters_for_method_reference)
14
+ url
15
+ end
16
+ end
17
+ @controller = @controller.new
18
+ @controller.url = "http://www.example.com"
19
+ end
20
+
21
+ def test_pagination_links
22
+ total, per_page, page = 30, 10, 1
23
+ output = pagination_links Paginator.new(@controller, total, per_page, page)
24
+ assert_equal "1 <a href=\"http://www.example.com\">2</a> <a href=\"http://www.example.com\">3</a> ", output
25
+ end
26
+
27
+ def test_pagination_links_with_prefix
28
+ total, per_page, page = 30, 10, 1
29
+ output = pagination_links Paginator.new(@controller, total, per_page, page), :prefix => 'Newer '
30
+ assert_equal "Newer 1 <a href=\"http://www.example.com\">2</a> <a href=\"http://www.example.com\">3</a> ", output
31
+ end
32
+
33
+ def test_pagination_links_with_suffix
34
+ total, per_page, page = 30, 10, 1
35
+ output = pagination_links Paginator.new(@controller, total, per_page, page), :suffix => 'Older'
36
+ assert_equal "1 <a href=\"http://www.example.com\">2</a> <a href=\"http://www.example.com\">3</a> Older", output
37
+ end
38
+ end
@@ -0,0 +1,177 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+ require File.dirname(__FILE__) + '/../init'
3
+
4
+ class PaginationTest < ActiveRecordTestCase
5
+ fixtures :topics, :replies, :developers, :projects, :developers_projects
6
+
7
+ class PaginationController < ActionController::Base
8
+ if respond_to? :view_paths=
9
+ self.view_paths = [ "#{File.dirname(__FILE__)}/../fixtures/" ]
10
+ else
11
+ self.template_root = [ "#{File.dirname(__FILE__)}/../fixtures/" ]
12
+ end
13
+
14
+ def simple_paginate
15
+ @topic_pages, @topics = paginate(:topics)
16
+ render :nothing => true
17
+ end
18
+
19
+ def paginate_with_per_page
20
+ @topic_pages, @topics = paginate(:topics, :per_page => 1)
21
+ render :nothing => true
22
+ end
23
+
24
+ def paginate_with_order
25
+ @topic_pages, @topics = paginate(:topics, :order => 'created_at asc')
26
+ render :nothing => true
27
+ end
28
+
29
+ def paginate_with_order_by
30
+ @topic_pages, @topics = paginate(:topics, :order_by => 'created_at asc')
31
+ render :nothing => true
32
+ end
33
+
34
+ def paginate_with_include_and_order
35
+ @topic_pages, @topics = paginate(:topics, :include => :replies, :order => 'replies.created_at asc, topics.created_at asc')
36
+ render :nothing => true
37
+ end
38
+
39
+ def paginate_with_conditions
40
+ @topic_pages, @topics = paginate(:topics, :conditions => ["created_at > ?", 30.minutes.ago])
41
+ render :nothing => true
42
+ end
43
+
44
+ def paginate_with_class_name
45
+ @developer_pages, @developers = paginate(:developers, :class_name => "DeVeLoPeR")
46
+ render :nothing => true
47
+ end
48
+
49
+ def paginate_with_singular_name
50
+ @developer_pages, @developers = paginate()
51
+ render :nothing => true
52
+ end
53
+
54
+ def paginate_with_joins
55
+ @developer_pages, @developers = paginate(:developers,
56
+ :joins => 'LEFT JOIN developers_projects ON developers.id = developers_projects.developer_id',
57
+ :conditions => 'project_id=1')
58
+ render :nothing => true
59
+ end
60
+
61
+ def paginate_with_join
62
+ @developer_pages, @developers = paginate(:developers,
63
+ :join => 'LEFT JOIN developers_projects ON developers.id = developers_projects.developer_id',
64
+ :conditions => 'project_id=1')
65
+ render :nothing => true
66
+ end
67
+
68
+ def paginate_with_join_and_count
69
+ @developer_pages, @developers = paginate(:developers,
70
+ :join => 'd LEFT JOIN developers_projects ON d.id = developers_projects.developer_id',
71
+ :conditions => 'project_id=1',
72
+ :count => "d.id")
73
+ render :nothing => true
74
+ end
75
+
76
+ def paginate_with_join_and_group
77
+ @developer_pages, @developers = paginate(:developers,
78
+ :join => 'INNER JOIN developers_projects ON developers.id = developers_projects.developer_id',
79
+ :group => 'developers.id')
80
+ render :nothing => true
81
+ end
82
+
83
+ def rescue_errors(e) raise e end
84
+
85
+ def rescue_action(e) raise end
86
+
87
+ end
88
+
89
+ def setup
90
+ @controller = PaginationController.new
91
+ @request = ActionController::TestRequest.new
92
+ @response = ActionController::TestResponse.new
93
+ super
94
+ end
95
+
96
+ # Single Action Pagination Tests
97
+
98
+ def test_simple_paginate
99
+ get :simple_paginate
100
+ assert_equal 1, assigns(:topic_pages).page_count
101
+ assert_equal 3, assigns(:topics).size
102
+ end
103
+
104
+ def test_paginate_with_per_page
105
+ get :paginate_with_per_page
106
+ assert_equal 1, assigns(:topics).size
107
+ assert_equal 3, assigns(:topic_pages).page_count
108
+ end
109
+
110
+ def test_paginate_with_order
111
+ get :paginate_with_order
112
+ expected = [topics(:futurama),
113
+ topics(:harvey_birdman),
114
+ topics(:rails)]
115
+ assert_equal expected, assigns(:topics)
116
+ assert_equal 1, assigns(:topic_pages).page_count
117
+ end
118
+
119
+ def test_paginate_with_order_by
120
+ get :paginate_with_order
121
+ expected = assigns(:topics)
122
+ get :paginate_with_order_by
123
+ assert_equal expected, assigns(:topics)
124
+ assert_equal 1, assigns(:topic_pages).page_count
125
+ end
126
+
127
+ def test_paginate_with_conditions
128
+ get :paginate_with_conditions
129
+ expected = [topics(:rails)]
130
+ assert_equal expected, assigns(:topics)
131
+ assert_equal 1, assigns(:topic_pages).page_count
132
+ end
133
+
134
+ def test_paginate_with_class_name
135
+ get :paginate_with_class_name
136
+
137
+ assert assigns(:developers).size > 0
138
+ assert_equal DeVeLoPeR, assigns(:developers).first.class
139
+ end
140
+
141
+ def test_paginate_with_joins
142
+ get :paginate_with_joins
143
+ assert_equal 2, assigns(:developers).size
144
+ developer_names = assigns(:developers).map { |d| d.name }
145
+ assert developer_names.include?('David')
146
+ assert developer_names.include?('Jamis')
147
+ end
148
+
149
+ def test_paginate_with_join_and_conditions
150
+ get :paginate_with_joins
151
+ expected = assigns(:developers)
152
+ get :paginate_with_join
153
+ assert_equal expected, assigns(:developers)
154
+ end
155
+
156
+ def test_paginate_with_join_and_count
157
+ get :paginate_with_joins
158
+ expected = assigns(:developers)
159
+ get :paginate_with_join_and_count
160
+ assert_equal expected, assigns(:developers)
161
+ end
162
+
163
+ def test_paginate_with_include_and_order
164
+ get :paginate_with_include_and_order
165
+ expected = Topic.find(:all, :include => 'replies', :order => 'replies.created_at asc, topics.created_at asc', :limit => 10)
166
+ assert_equal expected, assigns(:topics)
167
+ end
168
+
169
+ def test_paginate_with_join_and_group
170
+ get :paginate_with_join_and_group
171
+ assert_equal 2, assigns(:developers).size
172
+ assert_equal 2, assigns(:developer_pages).item_count
173
+ developer_names = assigns(:developers).map { |d| d.name }
174
+ assert developer_names.include?('David')
175
+ assert developer_names.include?('Jamis')
176
+ end
177
+ end