genki-dm-pagination 0.0.1 → 0.0.2

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.
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