genki-dm-pagination 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -5,7 +5,7 @@ require 'merb-core'
5
5
  require 'merb-core/tasks/merb'
6
6
 
7
7
  GEM_NAME = "dm-pagination"
8
- GEM_VERSION = "0.0.1"
8
+ GEM_VERSION = "0.0.2"
9
9
  AUTHOR = "Genki Takiuchi"
10
10
  EMAIL = "genki@s21g.com"
11
11
  HOMEPAGE = "http://blog.s21g.com/genki"
data/lib/dm-pagination.rb CHANGED
@@ -20,6 +20,15 @@ if defined?(Merb::Plugins)
20
20
  extend DmPagination::Paginatable
21
21
  end
22
22
  end
23
+
24
+ require 'dm-pagination/pagination_builder'
25
+ module Merb
26
+ module GlobalHelpers
27
+ def paginate(pagination, *args, &block)
28
+ DmPagination::PaginationBuilder.new(self, pagination, *args, &block)
29
+ end
30
+ end
31
+ end
23
32
  end
24
33
 
25
34
  Merb::BootLoader.after_app_loads do
@@ -0,0 +1,9 @@
1
+ require 'dm-pagination/pagination'
2
+
3
+ module DmPagination
4
+ module Paginatable
5
+ def paginate(options = {})
6
+ Pagination.new(all, options)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,36 @@
1
+ module DmPagination
2
+ class Pagination
3
+ def initialize(collection, options)
4
+ @page = (options[:page] || 1).to_i
5
+ @per_page = (options[:per_page] || 10).to_i
6
+ @proxy_collection = collection
7
+ @collection = collection.all(
8
+ :offset => (@page - 1)*@per_page, :limit => @per_page)
9
+ end
10
+
11
+ def page
12
+ @page
13
+ end
14
+
15
+ def num_pages
16
+ (@proxy_collection.count + @per_page - 1) / @per_page
17
+ end
18
+
19
+ def pages(window = 5, left = 2, right = 2)
20
+ return [] if num_pages <= 1
21
+ (1..num_pages).inject([]) do |result, i|
22
+ i <= left || (num_pages - i) < right || (i-page).abs < window ?
23
+ result << i : (result.last.nil? ? result : result << nil)
24
+ end
25
+ end
26
+
27
+ def count
28
+ offset = (@page - 1)*@per_page
29
+ [0, [@proxy_collection.count - offset, @per_page].min].max
30
+ end
31
+
32
+ def method_missing(method, *args, &block)
33
+ @collection.send(method, *args, &block)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,83 @@
1
+ module DmPagination
2
+ class PaginationBuilder
3
+ def initialize(context, pagination, *args, &block)
4
+ @context = context
5
+ @pagination = pagination
6
+ @block = block
7
+ @options = args.last.kind_of?(Hash) ? args.pop : {}
8
+ @args = args.blank? ? [:prev, :pages, :next] : []
9
+ end
10
+
11
+ def to_s(*args)
12
+ args = @args if args.blank?
13
+ items = args.map{|i| respond_to?("link_to_#{i}") ?
14
+ send("link_to_#{i}") : []}.flatten
15
+ @context.tag(:div, items.join("\n"), :class => "pagination")
16
+ end
17
+
18
+ def link_to_pages
19
+ @pagination.pages.map{|page| link_to_page(page)}
20
+ end
21
+
22
+ def link_to_prev
23
+ if @pagination.page > 1
24
+ @context.link_to prev_label,
25
+ url(:page => @pagination.page - 1),
26
+ :class => :prev, :rel => "prev"
27
+ else
28
+ span.call(prev_label)
29
+ end
30
+ end
31
+
32
+ def link_to_next
33
+ if @pagination.page < @pagination.num_pages
34
+ @context.link_to next_label,
35
+ url(:page => @pagination.page + 1),
36
+ :class => :older, :rel => "next"
37
+ else
38
+ span.call(next_label)
39
+ end
40
+ end
41
+
42
+ def link_to_page(page)
43
+ if page.nil?
44
+ span.call truncate, @options[:style]
45
+ elsif page == @pagination.page
46
+ span.call page, [@options[:style], 'current'].compact.join(' ')
47
+ else
48
+ span.call link(page), @options[:style]
49
+ end
50
+ end
51
+
52
+ private
53
+ def span
54
+ proc do |*args|
55
+ @context.tag(:span, args[0].to_s, :class => (args[1]||"disabled"))
56
+ end
57
+ end
58
+
59
+ def link(page, *args)
60
+ if @block
61
+ @block.call(page, *args)
62
+ else
63
+ @context.link_to(page, url(:page => page))
64
+ end
65
+ end
66
+
67
+ def truncate
68
+ @options[:truncate] || '...'
69
+ end
70
+
71
+ def prev_label
72
+ @options[:prev] || '&laquo; Prev'
73
+ end
74
+
75
+ def next_label
76
+ @options[:next] || 'Next &raquo;'
77
+ end
78
+
79
+ def url(params)
80
+ @context.url(@context.params.merge(params))
81
+ end
82
+ end
83
+ end
@@ -1,34 +1,78 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
- require 'dm-core'
3
- require 'dm-pagination/paginatable'
4
2
 
5
3
  DataMapper.setup(:default, "sqlite3::memory:")
6
4
 
7
- module DataMapper
8
- module Resource
9
- module ClassMethods
10
- include DmPagination::Paginatable
11
- end
12
- end
13
- end
14
-
15
- class TestPost
16
- include DataMapper::Resource
17
-
18
- property :id, Serial
19
- end
5
+ Post.auto_migrate!
20
6
 
21
7
  describe "dm-pagination" do
22
- describe "pagination" do
8
+ describe "paginatable" do
23
9
  it "should extend DataMapper::Resource" do
24
- test = TestPost.new
10
+ test = Post.new
25
11
  test.should_not be_nil
26
- TestPost.should be_respond_to(:paginate)
27
- TestPost.all.should be_respond_to(:paginate)
12
+ Post.should be_respond_to(:paginate)
13
+ Post.all.should be_respond_to(:paginate)
28
14
  end
29
15
 
30
16
  it "should return Pagination object" do
31
- TestPost.paginate.should be_kind_of(DmPagination::Pagination)
17
+ Post.paginate.should be_kind_of(DmPagination::Pagination)
18
+ Post.all.paginate.should be_kind_of(DmPagination::Pagination)
19
+ end
20
+ end
21
+
22
+ describe "pagination" do
23
+ before :all do
24
+ Post.all.destroy!
25
+ 101.times{|i| Post.create(:index => i)}
26
+ end
27
+
28
+ it "should be specified on 101 test posts" do
29
+ Post.count.should == 101
30
+ end
31
+
32
+ it "should have 10 pages" do
33
+ Post.paginate.num_pages.should == 11
34
+ Post.all.paginate.num_pages.should == 11
35
+ end
36
+
37
+ it "should be able to calculate num pages on scope" do
38
+ Post.all(:index.gt => 50).count.should == 50
39
+ Post.all(:index.gt => 50).paginate.num_pages.should == 5
40
+ Post.all(:index.gt => 49).paginate.num_pages.should == 6
41
+ end
42
+
43
+ it "should act as Collection" do
44
+ Post.paginate(:page => 8).count.should == 10
45
+ Post.paginate(:page => 11).count.should == 1
46
+ Post.paginate(:page => 12).count.should == 0
47
+ Post.paginate(:page => 5, :per_page => 6).count.should == 6
48
+ end
49
+ end
50
+
51
+ describe "pagination builder" do
52
+ include Merb::Helpers::Tag
53
+
54
+ before :all do
55
+ Post.all.destroy!
56
+ 101.times{|i| Post.create(:index => i)}
57
+ end
58
+
59
+ it "should be tested on 101 posts" do
60
+ Post.count.should == 101
61
+ end
62
+
63
+ it "should have rendered with pagination" do
64
+ response = request "/pagination_builder/simple"
65
+ response.should be_successful
66
+ response.should have_selector("div.pagination")
67
+ response.should have_selector("ul")
68
+ response.should have_selector("li")
69
+ response.should have_selector("a[rel=next]")
70
+ end
71
+
72
+ it "should have rendered with pagination at page 2" do
73
+ response = request "/pagination_builder/simple", :params => {:page => 2}
74
+ response.should be_successful
75
+ response.should have_selector("a[rel=prev]")
32
76
  end
33
77
  end
34
78
  end
@@ -0,0 +1,6 @@
1
+ class PaginationBuilder < Merb::Controller
2
+ def simple
3
+ @posts = Post.paginate(params)
4
+ render
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ class Post
2
+ include DataMapper::Resource
3
+
4
+ property :id, Serial
5
+ property :index, Integer
6
+ end
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-us" lang="en-us">
3
+ <head>
4
+ <title>Fresh Merb App</title>
5
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
6
+ <link rel="stylesheet" href="/stylesheets/master.css" type="text/css" media="screen" charset="utf-8"/>
7
+ </head>
8
+ <body>
9
+ <%= catch_content :for_layout %>
10
+ </body>
11
+ </html>
@@ -0,0 +1,7 @@
1
+ <ul>
2
+ <% @posts.each do |post| %>
3
+ <li><%= post.index %></li>
4
+ <% end %>
5
+ </ul>
6
+
7
+ <%= paginate @posts %>
@@ -0,0 +1,13 @@
1
+ Merb::Router.prepare do |r|
2
+ # RESTful routes
3
+ # r.resources :posts
4
+
5
+ # This is the default route for /:controller/:action/:id
6
+ # This is fine for most cases. If you're heavily using resource-based
7
+ # routes, you may want to comment/remove this line to prevent
8
+ # clients from calling your create or destroy actions with a GET
9
+ r.default_routes
10
+
11
+ # Change this for your home page to be available at /
12
+ # r.match('/').to(:controller => 'whatever', :action =>'index')
13
+ end
data/spec/spec_helper.rb CHANGED
@@ -1 +1,41 @@
1
1
  $:.push File.join(File.dirname(__FILE__), '..', 'lib')
2
+ require 'rubygems'
3
+ require 'spec'
4
+ require 'merb-core'
5
+ require 'merb-helpers'
6
+ require 'merb-assets'
7
+ require 'dm-core'
8
+ require 'dm-pagination/paginatable'
9
+ require 'dm-pagination/pagination_builder'
10
+ require 'dm-aggregates'
11
+
12
+ default_options = {
13
+ :environment => 'test',
14
+ :adapter => 'runner',
15
+ :merb_root => File.dirname(__FILE__) / 'fixture',
16
+ :log_file => File.dirname(__FILE__) / "merb_test.log"
17
+ }
18
+ options = default_options.merge($START_OPTIONS || {})
19
+ DataMapper::Model.append_extensions DmPagination::Paginatable
20
+ module Merb
21
+ module GlobalHelpers
22
+ def paginate(pagination, *args, &block)
23
+ DmPagination::PaginationBuilder.new(self, pagination, *args, &block)
24
+ end
25
+ end
26
+ end
27
+
28
+ Merb.disable(:initfile)
29
+ Merb.start_environment(options)
30
+
31
+ Spec::Runner.configure do |config|
32
+ config.include Merb::Test::RequestHelper
33
+ config.include Webrat::Matchers
34
+ config.include Webrat::HaveTagMatcher
35
+
36
+ def with_level(level)
37
+ Merb.logger = Merb::Logger.new(StringIO.new, level)
38
+ yield
39
+ Merb.logger
40
+ end
41
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: genki-dm-pagination
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Genki Takiuchi
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-01-14 00:00:00 -08:00
12
+ date: 2009-01-15 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -38,8 +38,25 @@ files:
38
38
  - TODO
39
39
  - lib/dm-pagination
40
40
  - lib/dm-pagination/merbtasks.rb
41
+ - lib/dm-pagination/paginatable.rb
42
+ - lib/dm-pagination/pagination.rb
43
+ - lib/dm-pagination/pagination_builder.rb
41
44
  - lib/dm-pagination.rb
42
45
  - spec/dm-pagination_spec.rb
46
+ - spec/fixture
47
+ - spec/fixture/app
48
+ - spec/fixture/app/controllers
49
+ - spec/fixture/app/controllers/pagination_builder.rb
50
+ - spec/fixture/app/models
51
+ - spec/fixture/app/models/post.rb
52
+ - spec/fixture/app/views
53
+ - spec/fixture/app/views/layout
54
+ - spec/fixture/app/views/layout/application.html.erb
55
+ - spec/fixture/app/views/pagination_builder
56
+ - spec/fixture/app/views/pagination_builder/simple.html.erb
57
+ - spec/fixture/config
58
+ - spec/fixture/config/router.rb
59
+ - spec/merb_test.log
43
60
  - spec/spec_helper.rb
44
61
  has_rdoc: true
45
62
  homepage: http://blog.s21g.com/genki