simply_paginate 0.0.3 → 0.0.4
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/README.md +48 -29
- data/examples/data_mapper_example/Gemfile +7 -0
- data/examples/data_mapper_example/test.rb +19 -0
- data/lib/simply_paginate/page.rb +19 -17
- data/lib/simply_paginate/paginator.rb +45 -8
- data/lib/simply_paginate/version.rb +1 -1
- data/spec/page_spec.rb +22 -57
- data/spec/paginator_spec.rb +59 -32
- data/spec/spec_helper.rb +10 -0
- metadata +4 -2
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# SimplyPaginate
|
2
|
-
[](https://travis-ci.org/guiman/simply_paginate)
|
2
|
+
[](https://travis-ci.org/guiman/simply_paginate) [](https://codeclimate.com/github/guiman/simply_paginate)
|
3
3
|
|
4
4
|
Simply paginate will do just that, give me a collection and you will be able to use a pagination logic (no extra html boilerplate or dependecies).
|
5
5
|
|
@@ -19,60 +19,79 @@ Or install it yourself as:
|
|
19
19
|
|
20
20
|
## Motivation
|
21
21
|
When dealing with pagination most known gems come bundled with lots of extra functionality I usually don't need (like html boilerplate), this is my attempt to create just the pagination logic, as simple as that.
|
22
|
+
So if you need pagiation but don't want to reinvent the wheel and keep your collections Pagination Agnostic, this is the gem you need. The only
|
23
|
+
requirement is the adoption of the popular ruby Enumerable interface.
|
22
24
|
|
23
25
|
## Usage
|
24
26
|
|
25
27
|
```ruby
|
26
28
|
require 'simply_paginate'
|
27
29
|
|
28
|
-
|
30
|
+
include SimplyPaginate
|
29
31
|
|
30
|
-
|
32
|
+
collection = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
31
33
|
|
32
|
-
|
33
|
-
SimplyPaginate::Paginator.per_page 3
|
34
|
+
pages = Paginator.new(collection, 3)
|
34
35
|
|
35
36
|
# retrieve a certain page
|
36
|
-
|
37
|
+
pages[1]
|
37
38
|
|
38
39
|
#move through the pages freely
|
39
|
-
|
40
|
-
|
40
|
+
pages[1].next
|
41
|
+
pages[1].previous
|
41
42
|
|
42
43
|
#you might want the first element on the 3rd page
|
43
|
-
|
44
|
+
pages[1].next.next.next.previous.elements[0]
|
44
45
|
|
45
46
|
#or maybe all of them
|
46
|
-
|
47
|
-
```
|
47
|
+
pages[0].next.next.next.previous.elements
|
48
48
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
# By default Paginator.per_page is 10
|
49
|
+
#you can also iterate the ruby way
|
50
|
+
pages.each do |page|
|
51
|
+
puts page.elements
|
52
|
+
end
|
54
53
|
|
55
|
-
|
54
|
+
#or in a more old fashion way
|
55
|
+
pages.start
|
56
56
|
|
57
|
-
|
57
|
+
while pages.next? do
|
58
|
+
puts pages.current.elements
|
59
|
+
|
60
|
+
pages.next!
|
61
|
+
end
|
58
62
|
```
|
59
63
|
|
60
|
-
##
|
64
|
+
## Changes on this branch
|
65
|
+
Well this branch introduced a better design about the relationship between pages and page, and also
|
66
|
+
an improvement on the API.
|
61
67
|
|
62
|
-
|
63
|
-
|
68
|
+
Now a Page can be used without the need of having a Paginator, and also a Paginator could be transversed
|
69
|
+
without need to access pages directly.
|
64
70
|
|
65
|
-
|
66
|
-
|
67
|
-
so when you call ```previous``` or ```next``` or ```[]```page object representing is created on that moment, thus saving memory.
|
71
|
+
```ruby
|
72
|
+
require 'simply_paginate'
|
68
73
|
|
69
|
-
|
70
|
-
also the ```pages``` has been dropped.
|
74
|
+
include SimplyPaginate
|
71
75
|
|
72
|
-
|
73
|
-
* Dropping the each_slice in order to use a more memory efficient index algorithm for paging.
|
74
|
-
* Adding more tests to the page object.
|
76
|
+
collection = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
75
77
|
|
78
|
+
# Give me the first page of the collection with a size of 3
|
79
|
+
first_page = Page.new(1, collection, 3)
|
80
|
+
|
81
|
+
first_page.elements
|
82
|
+
#=> [1, 2, 3]
|
83
|
+
first_page.next.elements
|
84
|
+
#=> [4, 5, 6]
|
85
|
+
```
|
86
|
+
##0.0.4 - Changelog:
|
87
|
+
|
88
|
+
* Redesign on relation between paginator and pages. You can use them togheter or separately.
|
89
|
+
* Improved API for Paginator, now including:
|
90
|
+
* each iteration
|
91
|
+
* next!, next?, current and start methods for manual iteration
|
92
|
+
* first and last accessors
|
93
|
+
* Test improvement
|
94
|
+
|
76
95
|
## Contributing
|
77
96
|
|
78
97
|
1. Fork it
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler.require
|
3
|
+
|
4
|
+
DataMapper.setup :default, 'sqlite::memory:'
|
5
|
+
|
6
|
+
class Person
|
7
|
+
include DataMapper::Resource
|
8
|
+
|
9
|
+
property :id, Serial
|
10
|
+
property :age, String
|
11
|
+
end
|
12
|
+
|
13
|
+
DataMapper.auto_migrate!
|
14
|
+
|
15
|
+
100.times { Person.create age: rand(1..90) }
|
16
|
+
|
17
|
+
paginator = SimplyPaginate::Paginator.new(Person.all)
|
18
|
+
|
19
|
+
paginator[0].elements.all(:age.gt => 10)
|
data/lib/simply_paginate/page.rb
CHANGED
@@ -1,33 +1,35 @@
|
|
1
1
|
module SimplyPaginate
|
2
2
|
class Page
|
3
|
-
attr_reader :
|
3
|
+
attr_reader :index, :collection, :size
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
@
|
7
|
-
@
|
8
|
-
@
|
5
|
+
def initialize(page, collection, size = Paginator.per_page)
|
6
|
+
@index = page
|
7
|
+
@collection = collection
|
8
|
+
@size = size
|
9
|
+
|
10
|
+
@move_page = lambda do |number|
|
11
|
+
new_index = @index + number
|
12
|
+
Page.new(new_index, @collection, @size) unless (new_index == 0) || (new_index > (@collection.count.to_f / @size.to_f).ceil)
|
13
|
+
end
|
9
14
|
end
|
10
15
|
|
11
16
|
def next
|
12
|
-
|
13
|
-
last = first + Paginator.per_page - 1
|
14
|
-
|
15
|
-
(first >= @paginator.collection.count) ? nil : @paginator.current = Page.new(first, last, @paginator)
|
17
|
+
@move_page.call(1)
|
16
18
|
end
|
17
19
|
|
18
20
|
def previous
|
19
|
-
|
20
|
-
last = @first - 1
|
21
|
-
|
22
|
-
(first < 0) ? nil : @paginator.current = Page.new(first, last, @paginator)
|
21
|
+
@move_page.call(-1)
|
23
22
|
end
|
24
23
|
|
25
|
-
def
|
26
|
-
|
24
|
+
def elements
|
25
|
+
first = (@index - 1) * @size
|
26
|
+
last = first + size - 1
|
27
|
+
|
28
|
+
collection[first..last]
|
27
29
|
end
|
28
30
|
|
29
|
-
def
|
30
|
-
|
31
|
+
def ==(other)
|
32
|
+
(index == other.index) && (elements == other.elements) if other.respond_to?(:index) && other.respond_to?(:elements)
|
31
33
|
end
|
32
34
|
end
|
33
35
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module SimplyPaginate
|
2
|
+
FIRST_PAGE_INDEX = 1
|
3
|
+
|
2
4
|
class Paginator
|
3
5
|
attr_reader :collection
|
4
|
-
attr_accessor :current
|
5
6
|
|
6
7
|
def self.per_page=(amount_per_page)
|
7
8
|
raise NotInRangeError.new("Amount per page should be greater than 0") unless amount_per_page > 0
|
@@ -13,20 +14,56 @@ module SimplyPaginate
|
|
13
14
|
@@per_page
|
14
15
|
end
|
15
16
|
|
16
|
-
def initialize(collection)
|
17
|
+
def initialize(collection, per_page = self.class.per_page)
|
17
18
|
@collection = collection
|
18
|
-
@
|
19
|
+
@per_page = per_page
|
19
20
|
end
|
20
21
|
|
21
|
-
|
22
|
-
first = pos * @@per_page
|
23
|
-
last = first + @@per_page - 1
|
22
|
+
## Basic Operations
|
24
23
|
|
25
|
-
|
24
|
+
def first
|
25
|
+
self[FIRST_PAGE_INDEX]
|
26
|
+
end
|
27
|
+
|
28
|
+
def last
|
29
|
+
self[total_pages]
|
26
30
|
end
|
27
31
|
|
28
32
|
def total_pages
|
29
|
-
(@collection.count.to_f /
|
33
|
+
(@collection.count.to_f / @per_page.to_f).ceil
|
34
|
+
end
|
35
|
+
|
36
|
+
def [](pos)
|
37
|
+
Page.new(pos, @collection) unless pos == 0 || pos > total_pages
|
38
|
+
end
|
39
|
+
|
40
|
+
## Iteration
|
41
|
+
|
42
|
+
def next!
|
43
|
+
raise NoMethodError.new("You need to start before iterating") unless @current
|
44
|
+
@current = @current.next
|
45
|
+
end
|
46
|
+
|
47
|
+
def next?
|
48
|
+
@current != nil
|
49
|
+
end
|
50
|
+
|
51
|
+
def start
|
52
|
+
@current = first
|
53
|
+
end
|
54
|
+
|
55
|
+
def current
|
56
|
+
@current
|
57
|
+
end
|
58
|
+
|
59
|
+
def each
|
60
|
+
start
|
61
|
+
|
62
|
+
while next? do
|
63
|
+
yield current
|
64
|
+
|
65
|
+
next!
|
66
|
+
end
|
30
67
|
end
|
31
68
|
|
32
69
|
Paginator.per_page = 10
|
data/spec/page_spec.rb
CHANGED
@@ -1,74 +1,39 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
before do
|
5
|
-
SimplyPaginate::Paginator.per_page = 5
|
3
|
+
include SimplyPaginate
|
6
4
|
|
7
|
-
|
8
|
-
|
9
|
-
@last_page = SimplyPaginate::Page.new(5, 9, @paginator)
|
5
|
+
describe Page do
|
6
|
+
include Helpers
|
10
7
|
|
11
|
-
|
12
|
-
def paginator
|
13
|
-
@paginator
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
it "must always have an instance of paginator" do
|
19
|
-
@first_page.paginator.wont_be_nil
|
20
|
-
@last_page.paginator.wont_be_nil
|
8
|
+
let(:first_page) { build_page 1 }
|
21
9
|
|
22
|
-
|
23
|
-
@first_page.next.previous.paginator.wont_be_nil
|
24
|
-
end
|
10
|
+
let(:second_page) { build_page 2 }
|
25
11
|
|
26
|
-
|
27
|
-
@first_page.elements.must_equal [1, 2, 3, 4, 5]
|
28
|
-
@last_page.elements.must_equal [6, 7, 8, 9, 10]
|
12
|
+
let(:last_page) { build_page 4 }
|
29
13
|
|
30
|
-
|
31
|
-
|
14
|
+
it "must represent a specific page on a collection" do
|
15
|
+
first_page.elements.must_equal [1, 2, 3]
|
16
|
+
first_page.index.must_equal SimplyPaginate::FIRST_PAGE_INDEX
|
32
17
|
end
|
33
18
|
|
34
|
-
|
35
|
-
|
36
|
-
SimplyPaginate::Paginator.per_page = 2
|
37
|
-
end
|
38
|
-
|
39
|
-
it "must be able to go back and foward" do
|
40
|
-
@paginator[1].next.elements.must_equal @paginator[2].elements
|
41
|
-
@paginator[1].previous.elements.must_equal @paginator[0].elements
|
42
|
-
end
|
19
|
+
it "must be able to retrieve it's elements" do
|
20
|
+
first_page.elements.must_equal [1, 2, 3]
|
43
21
|
end
|
44
22
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
23
|
+
it "must be able to compare with other page" do
|
24
|
+
first_page.must_equal first_page
|
25
|
+
first_page.wont_equal second_page
|
26
|
+
first_page.wont_equal Page.new(1, page_array_collection, 5)
|
27
|
+
first_page.must_equal Page.new(1, [1, 2, 3], 3)
|
50
28
|
end
|
51
29
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
@first_page.previous.must_be_nil
|
56
|
-
end
|
30
|
+
it "must be able to move forward" do
|
31
|
+
first_page.next.must_equal second_page
|
32
|
+
last_page.next.must_be_nil
|
57
33
|
end
|
58
34
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
@paginator[0].current?.must_equal false
|
63
|
-
@paginator[1].current?.must_equal true
|
64
|
-
end
|
65
|
-
|
66
|
-
it "must be setted as current when landed after previous" do
|
67
|
-
@paginator[1].previous
|
68
|
-
@paginator[1].current?.must_equal false
|
69
|
-
@paginator[0].current?.must_equal true
|
70
|
-
end
|
71
|
-
|
35
|
+
it "must be able to move backwards" do
|
36
|
+
first_page.previous.must_be_nil
|
37
|
+
second_page.previous.must_equal first_page
|
72
38
|
end
|
73
|
-
|
74
39
|
end
|
data/spec/paginator_spec.rb
CHANGED
@@ -1,50 +1,77 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
+
Paginator.per_page = 3
|
3
4
|
|
4
|
-
describe
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
describe Paginator do
|
6
|
+
include Helpers
|
7
|
+
|
8
|
+
let(:pages) { Paginator.new page_array_collection }
|
9
|
+
|
10
|
+
let(:first_page) { build_page 1 }
|
11
|
+
|
12
|
+
let(:last_page) { build_page 4 }
|
9
13
|
|
10
|
-
|
11
|
-
|
12
|
-
|
14
|
+
it "must be able to iterate using each" do
|
15
|
+
count = 0
|
16
|
+
results = []
|
17
|
+
|
18
|
+
pages.each do |page|
|
19
|
+
page.wont_be_nil
|
20
|
+
results << page.elements
|
21
|
+
|
22
|
+
count += 1
|
13
23
|
end
|
24
|
+
|
25
|
+
count.must_equal 4
|
26
|
+
results.must_equal [[1,2,3], [4,5,6], [7,8,9], [10]]
|
14
27
|
end
|
15
28
|
|
16
|
-
|
17
|
-
|
18
|
-
|
29
|
+
it "must be able to tell how many pages there are" do
|
30
|
+
pages.total_pages.must_equal 4
|
31
|
+
end
|
19
32
|
|
20
|
-
|
21
|
-
|
33
|
+
it "must be able to retrieve a certain page" do
|
34
|
+
pages[0].must_be_nil
|
35
|
+
pages[1].wont_be_nil
|
36
|
+
pages[1].must_equal first_page
|
37
|
+
pages[4].must_equal last_page
|
38
|
+
pages[5].must_be_nil
|
39
|
+
end
|
22
40
|
|
23
|
-
|
24
|
-
|
41
|
+
it "must be able to retrieve the first page" do
|
42
|
+
pages.first.must_equal first_page
|
43
|
+
end
|
25
44
|
|
26
|
-
|
27
|
-
|
28
|
-
|
45
|
+
it "must be able to retrieve the last page" do
|
46
|
+
pages.last.must_equal pages[4]
|
47
|
+
end
|
29
48
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
@paginator[0].next.wont_be_nil
|
49
|
+
describe "when iterating using 'start', 'next!' and 'next?'" do
|
50
|
+
it "must need to start before moving to the next " do
|
51
|
+
lambda { pages.next! }.must_raise NoMethodError
|
34
52
|
end
|
35
53
|
|
36
|
-
it
|
37
|
-
|
54
|
+
it "must move to the next page using 'next!'" do
|
55
|
+
iteration_pages = pages
|
56
|
+
iteration_pages.start
|
57
|
+
iteration_pages.next!
|
58
|
+
iteration_pages.current.must_equal build_page(2)
|
59
|
+
end
|
38
60
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
61
|
+
it "must retrieve the current page using 'current'" do
|
62
|
+
iteration_pages = pages
|
63
|
+
iteration_pages.current.must_be_nil
|
64
|
+
iteration_pages.start
|
65
|
+
iteration_pages.current.must_equal first_page
|
66
|
+
end
|
43
67
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
68
|
+
it "must retrieve if we can get a next value using 'next?'" do
|
69
|
+
iteration_pages = pages
|
70
|
+
iteration_pages.next?.must_equal false
|
71
|
+
iteration_pages.start
|
72
|
+
iteration_pages.next?.must_equal true
|
73
|
+
4.times { iteration_pages.next! }
|
74
|
+
iteration_pages.next?.must_equal false
|
48
75
|
end
|
49
76
|
end
|
50
77
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simply_paginate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-05-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -72,6 +72,8 @@ files:
|
|
72
72
|
- LICENSE.txt
|
73
73
|
- README.md
|
74
74
|
- Rakefile
|
75
|
+
- examples/data_mapper_example/Gemfile
|
76
|
+
- examples/data_mapper_example/test.rb
|
75
77
|
- lib/simply_paginate.rb
|
76
78
|
- lib/simply_paginate/not_in_range_error.rb
|
77
79
|
- lib/simply_paginate/page.rb
|