paged_scopes 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,72 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe "Resources" do
4
+ before(:each) do
5
+ ActionController::Routing::Routes.clear!
6
+ end
7
+
8
+ after(:each) do
9
+ ActionController::Routing::Routes.clear!
10
+ end
11
+
12
+ it "should not affect normal resource mapping if :paged option is not specified" do
13
+ drawing_routes { |map| map.resources :articles }.should change { number_of_routes }.by(7)
14
+ end
15
+
16
+ it "should add a paged index route if a :paged option is specified" do
17
+ drawing_routes { |map| map.resources :articles, :paged => true }.should change { number_of_routes }.by(7+1)
18
+ end
19
+
20
+ context "with a :paged options" do
21
+ it "should map a paged index route for GET only" do
22
+ draw_routes { |map| map.resources :articles, :paged => true }
23
+ recognise_path( :get, "/pages/1/articles").should == { :controller => "articles", :action => "index", :page_id => "1" }
24
+ recognise_path( :put, "/pages/1/articles").should be_nil
25
+ recognise_path( :post, "/pages/1/articles").should be_nil
26
+ recognise_path(:delete, "/pages/1/articles").should be_nil
27
+ end
28
+
29
+ it "should add a named route for the paged index route" do
30
+ draw_routes { |map| map.resources :articles, :paged => true }
31
+ named_routes.names.should include(:page_articles)
32
+ end
33
+
34
+ it "should observe the :path_prefix option in the paged route" do
35
+ draw_routes { |map| map.resources :articles, :paged => true, :path_prefix => "foo" }
36
+ recognise_path(:get, "/foo/pages/1/articles").should == { :controller => "articles", :action => "index", :page_id => "1" }
37
+ end
38
+
39
+ it "should observe a :namespace option in the paged route" do
40
+ draw_routes { |map| map.resources :articles, :paged => true, :namespace => "bar/" }
41
+ recognise_path(:get, "/pages/1/articles").should == { :controller => "bar/articles", :action => "index", :page_id => "1" }
42
+ end
43
+
44
+ it "should accept an :as option in the :paged option" do
45
+ draw_routes { |map| map.resources :articles, :paged => { :as => "page" } }
46
+ recognise_path(:get, "/page/1/articles").should == { :controller => "articles", :action => "index", :page_id => "1" }
47
+ end
48
+
49
+ it "should accept a :name option in the :paged option" do
50
+ draw_routes { |map| map.resources :articles, :paged => { :name => :groups } }
51
+ recognise_path(:get, "/groups/1/articles").should == { :controller => "articles", :action => "index", :group_id => "1" }
52
+ end
53
+
54
+ it "should accept a :path_prefix hash as the :paged option" do
55
+ draw_routes { |map| map.resources :articles, :paged => true, :name_prefix => "baz_" }
56
+ named_routes.names.should include(:baz_page_articles)
57
+ end
58
+
59
+ context "and nested resources" do
60
+ it "should not change the nested routes" do
61
+ drawing_routes do |map|
62
+ map.resources :articles, :paged => true do |article|
63
+ article.resources :comments
64
+ end
65
+ end.should change { number_of_routes }.by(7+1+7)
66
+ drawing_routes do |map|
67
+ map.resources :articles, :paged => true, :has_many => :comments
68
+ end.should change { number_of_routes }.by(7+1+7)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,160 @@
1
+ require 'spec'
2
+
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+ require 'rubygems'
6
+ require 'active_support'
7
+ require 'active_record'
8
+ require 'action_controller'
9
+ require 'action_controller/test_process'
10
+ require 'action_view/test_case'
11
+ require 'paged_scopes'
12
+
13
+ ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :dbfile => ':memory:')
14
+ ActiveRecord::Schema.define do
15
+ create_table "users", :force => true do |t|
16
+ t.column "name", :text
17
+ end
18
+ create_table "articles", :force => true do |t|
19
+ t.column "user_id", :integer
20
+ t.column "title", :text
21
+ t.column "published_at", :datetime
22
+ end
23
+ create_table "comments", :force => true do |t|
24
+ t.column "article_id", :integer
25
+ t.column "user_id", :integer
26
+ end
27
+ create_table "contributions", :force => true do |t|
28
+ t.column "article_id", :integer
29
+ t.column "user_id", :integer
30
+ end
31
+ end
32
+
33
+ class ::User < ActiveRecord::Base
34
+ has_many :articles
35
+ has_many :recent_articles, :order => "published_at DESC", :conditions => [ "published_at IS NOT :nil", { :nil => nil } ], :class_name => "Article"
36
+ has_many :contributions
37
+ has_many :shared_articles, :through => :contributions, :source => :article
38
+ end
39
+ class ::Article < ActiveRecord::Base
40
+ belongs_to :user
41
+ has_many :comments
42
+ named_scope :untitled, :conditions => { :title => nil }
43
+ named_scope :including_user, :include => :user
44
+ named_scope :with_user, :joins => 'INNER JOIN users ON users.id = articles.user_id'
45
+ named_scope :with_named_user, :joins => 'INNER JOIN users ON users.id = articles.user_id', :conditions => [ 'users.name IS NOT :nil', { :nil => nil } ]
46
+ named_scope :ordered_by_user_name, :joins => 'INNER JOIN users ON users.id = articles.user_id', :conditions => [ 'users.name IS NOT :nil', { :nil => nil } ], :order => 'users.name'
47
+ named_scope :with_comments, :joins => 'INNER JOIN comments AS article_comments ON article_comments.article_id = articles.id', :group => 'articles.id'
48
+ named_scope :first_three_with_comments, :joins => 'INNER JOIN comments AS article_comments ON article_comments.article_id = articles.id', :group => 'articles.id', :limit => 3
49
+ named_scope :with_multiple_comments, :include => :comments, :joins => 'INNER JOIN (SELECT count(id) AS count, article_id FROM comments GROUP BY article_id) article_comments ON article_comments.article_id = articles.id', :conditions => 'article_comments.count > 1'
50
+ named_scope :first_three, :limit => 3
51
+ named_scope :two_through_four, :limit => 3, :offset => 1
52
+ named_scope :descending_id, :order => 'articles.id DESC'
53
+ end
54
+ class ::Comment < ActiveRecord::Base
55
+ belongs_to :article
56
+ end
57
+ class ::Contribution < ActiveRecord::Base
58
+ belongs_to :article
59
+ belongs_to :user
60
+ end
61
+
62
+ User.create(:name => "user #1")
63
+ User.create(:name => nil)
64
+ User.create(:name => "user #3")
65
+ 9.times do |n|
66
+ shared_article = User.first.articles.create
67
+ User.all.each_with_index do |user, i|
68
+ user.articles.create
69
+ user.articles.create(:title => "Article #%03d" % Article.count)
70
+ published_article = user.articles.create(:title => "Article #%03d" % Article.count, :published_at => n.weeks.ago)
71
+ n.times { published_article.comments << Comment.new }
72
+ user.articles.create(:published_at => n.weeks.ago)
73
+ user.shared_articles << shared_article unless user == User.first
74
+ end
75
+ n.times { shared_article.comments << Comment.new }
76
+ end
77
+
78
+ module ControllerHelpers
79
+ def in_instance(instance, &block)
80
+ instance.instance_eval do
81
+ extend Spec::Matchers
82
+ instance_eval(&block)
83
+ end
84
+ end
85
+
86
+ def in_controller(controller, &block)
87
+ controller.copy_instance_variables_from(self)
88
+ in_instance controller do
89
+ stub!(:params).and_return({})
90
+ instance_eval(&block)
91
+ end
92
+ end
93
+ end
94
+
95
+ module RoutingHelpers
96
+ def draw_routes(&block)
97
+ ActionController::Routing::Routes.draw(&block)
98
+ end
99
+
100
+ def drawing_routes(&block)
101
+ lambda { draw_routes(&block) }
102
+ end
103
+
104
+ def number_of_routes
105
+ ActionController::Routing::Routes.routes.size
106
+ end
107
+
108
+ def named_routes
109
+ ActionController::Routing::Routes.named_routes
110
+ end
111
+
112
+ def recognise_path(method, path)
113
+ request = ActionController::TestRequest.new
114
+ request.request_method = method
115
+ ActionController::Routing::Routes.recognize_path(path, ActionController::Routing::Routes.extract_request_environment(request))
116
+ rescue ActionController::RoutingError, ActionController::MethodNotAllowed
117
+ nil
118
+ end
119
+ end
120
+
121
+ module Contexts
122
+ def in_contexts(&block)
123
+ [
124
+ [ "a scoped ActiveRecord class", "Article.scoped({})" ],
125
+ [ "a has_many association", "User.last.articles" ],
126
+ [ "an ordered has_many association", "User.last.recent_articles" ],
127
+ [ "a has_many, :through association", "User.last.shared_articles" ] # not tested for habtm!
128
+ ].each do |base_type, base|
129
+ [
130
+ [ "", "" ],
131
+ [ "scoped with :conditions", ".untitled" ],
132
+ [ "scoped with :include", ".including_user" ],
133
+ [ "scoped with :joins", ".with_user" ],
134
+ [ "scoped with :joins & :conditions", ".with_named_user" ],
135
+ [ "scoped with :joins, :conditions & :order", ".ordered_by_user_name" ],
136
+ [ "scoped with :joins & :group", ".with_comments" ],
137
+ [ "scoped with :joins, :group & :limit", ".first_three_with_comments" ],
138
+ [ "scoped with :includes, :joins & subquery", ".with_multiple_comments" ],
139
+ [ "scoped with :limit", ".first_three" ],
140
+ [ "scoped with :limit & :offset", ".two_through_four" ],
141
+ [ "scoped with :order", ".descending_id" ]
142
+ ].each do |scope_type, scope|
143
+ context "for #{base_type} #{scope_type}" do
144
+ before(:each) do
145
+ @articles = eval("#{base}#{scope}")
146
+ @articles.all.should_not be_empty # sanity check: make sure our collection actually has some elements!
147
+ @articles.all.should == @articles.all.uniq # don't want duplicate items in our test collection
148
+ end
149
+ instance_eval(&block)
150
+ end
151
+ end
152
+ end
153
+ end
154
+ end
155
+
156
+ Spec::Runner.configure do |config|
157
+ config.extend Contexts
158
+ config.include RoutingHelpers
159
+ config.include ControllerHelpers
160
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: paged_scopes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Matthew Hollingworth
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-10 00:00:00 +11:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activerecord
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 2.2.1
24
+ version:
25
+ description:
26
+ email: mdholling@gmail.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - LICENSE
33
+ - README.textile
34
+ files:
35
+ - .document
36
+ - .gitignore
37
+ - LICENSE
38
+ - README.textile
39
+ - Rakefile
40
+ - VERSION.yml
41
+ - lib/paged_scopes.rb
42
+ - lib/paged_scopes/collection.rb
43
+ - lib/paged_scopes/context.rb
44
+ - lib/paged_scopes/controller.rb
45
+ - lib/paged_scopes/index.rb
46
+ - lib/paged_scopes/pages.rb
47
+ - lib/paged_scopes/paginator.rb
48
+ - lib/paged_scopes/resources.rb
49
+ - paged_scopes.gemspec
50
+ - rails/init.rb
51
+ - spec/collection_spec.rb
52
+ - spec/context_spec.rb
53
+ - spec/controller_spec.rb
54
+ - spec/index_spec.rb
55
+ - spec/page_spec.rb
56
+ - spec/paginator_spec.rb
57
+ - spec/resources_spec.rb
58
+ - spec/spec_helper.rb
59
+ has_rdoc: true
60
+ homepage: http://github.com/mholling/paged_scopes
61
+ licenses: []
62
+
63
+ post_install_message:
64
+ rdoc_options:
65
+ - --charset=UTF-8
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: "0"
73
+ version:
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: "0"
79
+ version:
80
+ requirements: []
81
+
82
+ rubyforge_project:
83
+ rubygems_version: 1.3.5
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: PagedScopes is an ActiveRecord pagination gem. It lets you easily paginate collection associations and named scopes. It also paginates collections which already have :limit and :offset scopes in place. You can also find the page containing a given object in a collection, and find the next and previous objects for each object in the collection.
87
+ test_files:
88
+ - spec/collection_spec.rb
89
+ - spec/context_spec.rb
90
+ - spec/controller_spec.rb
91
+ - spec/index_spec.rb
92
+ - spec/page_spec.rb
93
+ - spec/paginator_spec.rb
94
+ - spec/resources_spec.rb
95
+ - spec/spec_helper.rb