j1_paginator 2019.1.0
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.
- checksums.yaml +7 -0
- data/CODE_OF_CONDUCT.md +86 -0
- data/Gemfile +14 -0
- data/LICENSE +22 -0
- data/README-AUTOPAGES.md +141 -0
- data/README-GENERATOR.md +708 -0
- data/README.md +82 -0
- data/Rakefile +16 -0
- data/j1_paginator.gemspec +34 -0
- data/lib/j1_paginator.rb +34 -0
- data/lib/j1_paginator/autopages/autoPages.rb +77 -0
- data/lib/j1_paginator/autopages/defaults.rb +40 -0
- data/lib/j1_paginator/autopages/pages/baseAutoPage.rb +60 -0
- data/lib/j1_paginator/autopages/pages/categoryAutoPage.rb +32 -0
- data/lib/j1_paginator/autopages/pages/collectionAutoPage.rb +31 -0
- data/lib/j1_paginator/autopages/pages/tagAutoPage.rb +32 -0
- data/lib/j1_paginator/autopages/utils.rb +76 -0
- data/lib/j1_paginator/generator/compatibilityUtils.rb +121 -0
- data/lib/j1_paginator/generator/defaults.rb +27 -0
- data/lib/j1_paginator/generator/paginationGenerator.rb +146 -0
- data/lib/j1_paginator/generator/paginationIndexer.rb +116 -0
- data/lib/j1_paginator/generator/paginationModel.rb +377 -0
- data/lib/j1_paginator/generator/paginationPage.rb +66 -0
- data/lib/j1_paginator/generator/paginator.rb +107 -0
- data/lib/j1_paginator/generator/utils.rb +181 -0
- data/lib/j1_paginator/version.rb +10 -0
- data/spec/generator/defaults_spec.rb +34 -0
- data/spec/generator/paginationPage_spec.rb +12 -0
- data/spec/generator/paginator_spec.rb +197 -0
- data/spec/generator/utils_spec.rb +67 -0
- data/spec/spec_helper.rb +13 -0
- metadata +144 -0
@@ -0,0 +1,181 @@
|
|
1
|
+
module Jekyll
|
2
|
+
module J1Paginator::Generator
|
3
|
+
|
4
|
+
#
|
5
|
+
# Static utility functions that are used in the code and
|
6
|
+
# don't belong in once place in particular
|
7
|
+
#
|
8
|
+
class Utils
|
9
|
+
|
10
|
+
# Static: Calculate the number of pages.
|
11
|
+
#
|
12
|
+
# all_posts - The Array of all Posts.
|
13
|
+
# per_page - The Integer of entries per page.
|
14
|
+
#
|
15
|
+
# Returns the Integer number of pages.
|
16
|
+
def self.calculate_number_of_pages(all_posts, per_page)
|
17
|
+
(all_posts.size.to_f / per_page.to_i).ceil
|
18
|
+
end
|
19
|
+
|
20
|
+
# Static: returns a fully formatted string with the current (:num) page number and maximum (:max) page count replaced if configured
|
21
|
+
#
|
22
|
+
def self.format_page_number(toFormat, cur_page_nr, total_page_count=nil)
|
23
|
+
s = toFormat.sub(':num', cur_page_nr.to_s)
|
24
|
+
if !total_page_count.nil?
|
25
|
+
s = s.sub(':max', total_page_count.to_s)
|
26
|
+
end
|
27
|
+
return s
|
28
|
+
end #function format_page_number
|
29
|
+
|
30
|
+
# Static: returns a fully formatted string with the :title variable and the current (:num) page number and maximum (:max) page count replaced
|
31
|
+
#
|
32
|
+
def self.format_page_title(toFormat, title, cur_page_nr=nil, total_page_count=nil)
|
33
|
+
return format_page_number(toFormat.sub(':title', title.to_s), cur_page_nr, total_page_count)
|
34
|
+
end #function format_page_title
|
35
|
+
|
36
|
+
# Static: Return a String version of the input which has a leading dot.
|
37
|
+
# If the input already has a dot in position zero, it will be
|
38
|
+
# returned unchanged.
|
39
|
+
#
|
40
|
+
# path - a String path
|
41
|
+
#
|
42
|
+
# Returns the path with a leading slash
|
43
|
+
def self.ensure_leading_dot(path)
|
44
|
+
path[0..0] == "." ? path : ".#{path}"
|
45
|
+
end
|
46
|
+
|
47
|
+
# Static: Return a String version of the input which has a leading slash.
|
48
|
+
# If the input already has a forward slash in position zero, it will be
|
49
|
+
# returned unchanged.
|
50
|
+
#
|
51
|
+
# path - a String path
|
52
|
+
#
|
53
|
+
# Returns the path with a leading slash
|
54
|
+
def self.ensure_leading_slash(path)
|
55
|
+
path[0..0] == "/" ? path : "/#{path}"
|
56
|
+
end
|
57
|
+
|
58
|
+
# Static: Return a String version of the input without a leading slash.
|
59
|
+
#
|
60
|
+
# path - a String path
|
61
|
+
#
|
62
|
+
# Returns the input without the leading slash
|
63
|
+
def self.remove_leading_slash(path)
|
64
|
+
path[0..0] == "/" ? path[1..-1] : path
|
65
|
+
end
|
66
|
+
|
67
|
+
# Static: Return a String version of the input which has a trailing slash.
|
68
|
+
# If the input already has a forward slash at the end, it will be
|
69
|
+
# returned unchanged.
|
70
|
+
#
|
71
|
+
# path - a String path
|
72
|
+
#
|
73
|
+
# Returns the path with a trailing slash
|
74
|
+
def self.ensure_trailing_slash(path)
|
75
|
+
path[-1] == "/" ? path : "#{path}/"
|
76
|
+
end
|
77
|
+
|
78
|
+
#
|
79
|
+
# Sorting routine used for ordering posts by custom fields.
|
80
|
+
# Handles Strings separately as we want a case-insenstive sorting
|
81
|
+
#
|
82
|
+
def self.sort_values(a, b)
|
83
|
+
if a.nil? && !b.nil?
|
84
|
+
return -1
|
85
|
+
elsif !a.nil? && b.nil?
|
86
|
+
return 1
|
87
|
+
end
|
88
|
+
|
89
|
+
if a.is_a?(String)
|
90
|
+
return a.downcase <=> b.downcase
|
91
|
+
end
|
92
|
+
|
93
|
+
if a.respond_to?('to_datetime') && b.respond_to?('to_datetime')
|
94
|
+
return a.to_datetime <=> b.to_datetime
|
95
|
+
end
|
96
|
+
|
97
|
+
# By default use the built in sorting for the data type
|
98
|
+
return a <=> b
|
99
|
+
end
|
100
|
+
|
101
|
+
# Retrieves the given sort field from the given post
|
102
|
+
# the sort_field variable can be a hierarchical value on the form "parent_field:child_field" repeated as many times as needed
|
103
|
+
# only the leaf child_field will be retrieved
|
104
|
+
def self.sort_get_post_data(post_data, sort_field)
|
105
|
+
|
106
|
+
# Begin by splitting up the sort_field by (;,:.)
|
107
|
+
sort_split = sort_field.split(":")
|
108
|
+
sort_value = post_data
|
109
|
+
|
110
|
+
sort_split.each do |r_key|
|
111
|
+
key = r_key.downcase.strip # Remove any erronious whitespace and convert to lower case
|
112
|
+
if !sort_value.has_key?(key)
|
113
|
+
return nil
|
114
|
+
end
|
115
|
+
# Work my way through the hash
|
116
|
+
sort_value = sort_value[key]
|
117
|
+
end
|
118
|
+
|
119
|
+
# If the sort value is a hash then return nil else return the value
|
120
|
+
if( sort_value.is_a?(Hash) )
|
121
|
+
return nil
|
122
|
+
else
|
123
|
+
return sort_value
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# Ensures that the passed in url has a index and extension applied
|
128
|
+
def self.ensure_full_path(url, default_index, default_ext)
|
129
|
+
if( url.end_with?('/'))
|
130
|
+
return url + default_index + default_ext
|
131
|
+
elsif !url.include?('.')
|
132
|
+
return url + default_index
|
133
|
+
end
|
134
|
+
# Default
|
135
|
+
return url
|
136
|
+
end
|
137
|
+
|
138
|
+
# Constructs the plural for a key
|
139
|
+
def self.plural(config_key)
|
140
|
+
(config_key =~ /s$/) ? config_key :
|
141
|
+
(config_key.dup.sub!(/y$/, 'ies') || "#{config_key}s")
|
142
|
+
end
|
143
|
+
|
144
|
+
# Converts a string or array to a downcased, stripped array
|
145
|
+
def self.config_array(config, key, keepcase = nil)
|
146
|
+
[ config[key] ].flatten.compact.uniq.map { |c|
|
147
|
+
c.split(/[,;]\s*/).map { |v|
|
148
|
+
keepcase ? v.to_s.strip : v.to_s.downcase.strip
|
149
|
+
}
|
150
|
+
}.flatten.uniq
|
151
|
+
end
|
152
|
+
|
153
|
+
# Merges singular and plural config values into an array
|
154
|
+
def self.config_values(config, key, keepcase = nil)
|
155
|
+
singular = config_array(config, key, keepcase)
|
156
|
+
plural = config_array(config, plural(key), keepcase)
|
157
|
+
[ singular, plural ].flatten.uniq
|
158
|
+
end
|
159
|
+
|
160
|
+
def self.validate_url(template)
|
161
|
+
url = template.url
|
162
|
+
ext = template.output_ext
|
163
|
+
path = Jekyll::URL.unescape_path(url)
|
164
|
+
path = File.join(path, "index") if url.end_with?("/")
|
165
|
+
path << ext unless path.end_with?(ext)
|
166
|
+
|
167
|
+
dirname = File.dirname(path)
|
168
|
+
valid_values = [
|
169
|
+
File.join(dirname, "/"),
|
170
|
+
File.join(dirname, "index#{ext}")
|
171
|
+
]
|
172
|
+
|
173
|
+
return url if valid_values.include?(url)
|
174
|
+
Jekyll.logger.error "Pagination Error:",
|
175
|
+
"Detected invalid url #{url.inspect} for #{template.relative_path.inspect}"
|
176
|
+
Jekyll.logger.abort_with "", "Expected #{valid_values.map(&:inspect).join(' or ')}"
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
end # module J1Paginator
|
181
|
+
end # module Jekyll
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Jekyll
|
2
|
+
module J1Paginator
|
3
|
+
VERSION = "2019.1.0"
|
4
|
+
# When modifying remember to issue a new tag command in git before committing, then push the new tag
|
5
|
+
# git tag -a v2.1.0 -m "Gem v2.1.0"
|
6
|
+
# git push origin --tags
|
7
|
+
# Yanking a published Gem
|
8
|
+
# gem yank j1_paginator -v VERSION
|
9
|
+
end # module J1Paginator
|
10
|
+
end # module Jekyll
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require_relative '../spec_helper.rb'
|
2
|
+
|
3
|
+
module Jekyll::J1Paginator::Generator
|
4
|
+
describe "checking default config" do
|
5
|
+
|
6
|
+
it "should always contain the following keys" do
|
7
|
+
DEFAULT.must_include 'enabled'
|
8
|
+
DEFAULT.must_include 'collection'
|
9
|
+
DEFAULT.must_include 'per_page'
|
10
|
+
DEFAULT.must_include 'permalink'
|
11
|
+
DEFAULT.must_include 'title'
|
12
|
+
DEFAULT.must_include 'page_num'
|
13
|
+
DEFAULT.must_include 'sort_reverse'
|
14
|
+
DEFAULT.must_include 'sort_field'
|
15
|
+
DEFAULT.must_include 'limit'
|
16
|
+
DEFAULT.must_include 'debug'
|
17
|
+
DEFAULT.size.must_be :>=, 10
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should always contain the following key defaults" do
|
21
|
+
DEFAULT['enabled'].must_equal false
|
22
|
+
DEFAULT['collection'].must_equal 'posts'
|
23
|
+
DEFAULT['per_page'].must_equal 10
|
24
|
+
DEFAULT['permalink'].must_equal '/page:num/'
|
25
|
+
DEFAULT['title'].must_equal ':title - page :num'
|
26
|
+
DEFAULT['page_num'].must_equal 1
|
27
|
+
DEFAULT['sort_reverse'].must_equal false
|
28
|
+
DEFAULT['sort_field'].must_equal 'date'
|
29
|
+
DEFAULT['limit'].must_equal 0
|
30
|
+
DEFAULT['debug'].must_equal false
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require_relative '../spec_helper.rb'
|
2
|
+
|
3
|
+
module Jekyll::J1Paginator::Generator
|
4
|
+
describe "tesing pagination page implementation" do
|
5
|
+
|
6
|
+
it "sould always read the template file into itself" do
|
7
|
+
# DUE TO THE JEKYLL:PAGE CLASS ACCESSING FILE IO DIRECTLY
|
8
|
+
# I AM UNABLE TO MOCK OUT THE FILE OPERATIONS TO CREATE UNIT TESTS FOR THIS CLASS :/
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
require_relative '../spec_helper.rb'
|
2
|
+
|
3
|
+
module Jekyll::J1Paginator::Generator
|
4
|
+
describe Paginator do
|
5
|
+
|
6
|
+
it "must include the necessary paginator attributes" do
|
7
|
+
|
8
|
+
# config_per_page, first_index_page_url, paginated_page_url, posts, cur_page_nr, num_pages
|
9
|
+
pager = Paginator.new(10, "index.html", "/page:num/", [], 1, 10, 'index', '.html')
|
10
|
+
|
11
|
+
# None of these accessors should throw errors, just run through them to test
|
12
|
+
val = pager.page
|
13
|
+
val = pager.per_page
|
14
|
+
val = pager.posts
|
15
|
+
val = pager.total_posts
|
16
|
+
val = pager.total_pages
|
17
|
+
val = pager.previous_page
|
18
|
+
val = pager.previous_page_path
|
19
|
+
val = pager.next_page
|
20
|
+
val = pager.next_page_path
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
it "must throw an error if the current page number is greater than the total pages" do
|
25
|
+
err = -> { pager = Paginator.new(10, "index.html", "/page:num/", [], 10, 8, 'index', '.html') }.must_raise RuntimeError
|
26
|
+
|
27
|
+
# No error should be raised below
|
28
|
+
pager = Paginator.new(10, "index.html", "/page:num/", [], 8, 10, 'index', '.html')
|
29
|
+
end
|
30
|
+
|
31
|
+
it "must trim the list of posts correctly based on the cur_page_nr and per_page" do
|
32
|
+
# Create a dummy list of posts that is easy to track
|
33
|
+
posts = [
|
34
|
+
'1','2','3','4','5',
|
35
|
+
'6','7','8','9','10',
|
36
|
+
'11','12','13','14','15',
|
37
|
+
'16','17','18','19','20',
|
38
|
+
'21','22','23','24','25',
|
39
|
+
'26','27','28','29','30',
|
40
|
+
'31','32','33','34','35'
|
41
|
+
]
|
42
|
+
|
43
|
+
# Initialize a pager with
|
44
|
+
# 5 posts per page
|
45
|
+
# at page 2 out of 5 pages
|
46
|
+
pager = Paginator.new(5, "index.html", "/page:num/", posts, 2, 5, '', '')
|
47
|
+
|
48
|
+
pager.page.must_equal 2
|
49
|
+
pager.per_page.must_equal 5
|
50
|
+
pager.total_pages.must_equal 5
|
51
|
+
|
52
|
+
pager.total_posts.must_equal 35
|
53
|
+
|
54
|
+
pager.posts.size.must_equal 5
|
55
|
+
pager.posts[0].must_equal '6'
|
56
|
+
pager.posts[4].must_equal '10'
|
57
|
+
|
58
|
+
pager.previous_page.must_equal 1
|
59
|
+
pager.previous_page_path.must_equal 'index.html'
|
60
|
+
pager.next_page.must_equal 3
|
61
|
+
pager.next_page_path.must_equal '/page3/'
|
62
|
+
end
|
63
|
+
|
64
|
+
it "must not create a previous page if we're at first page" do
|
65
|
+
# Create a dummy list of posts that is easy to track
|
66
|
+
posts = [
|
67
|
+
'1','2','3','4','5',
|
68
|
+
'6','7','8','9','10',
|
69
|
+
'11','12','13','14','15',
|
70
|
+
'16','17','18','19','20',
|
71
|
+
'21','22','23','24','25',
|
72
|
+
'26','27','28','29','30',
|
73
|
+
'31','32','33','34','35'
|
74
|
+
]
|
75
|
+
|
76
|
+
# Initialize a pager with
|
77
|
+
# 5 posts per page
|
78
|
+
# at page 1 out of 5 pages
|
79
|
+
pager = Paginator.new(5, "index.html", "/page:num/", posts, 1, 5, '', '')
|
80
|
+
|
81
|
+
pager.page.must_equal 1
|
82
|
+
pager.per_page.must_equal 5
|
83
|
+
pager.total_pages.must_equal 5
|
84
|
+
|
85
|
+
pager.total_posts.must_equal 35
|
86
|
+
|
87
|
+
pager.posts.size.must_equal 5
|
88
|
+
pager.posts[0].must_equal '1'
|
89
|
+
pager.posts[4].must_equal '5'
|
90
|
+
|
91
|
+
pager.previous_page.must_be_nil
|
92
|
+
pager.previous_page_path.must_be_nil
|
93
|
+
pager.next_page.must_equal 2
|
94
|
+
pager.next_page_path.must_equal '/page2/'
|
95
|
+
end
|
96
|
+
|
97
|
+
it "must not create a next page if we're at the final page" do
|
98
|
+
# Create a dummy list of posts that is easy to track
|
99
|
+
posts = [
|
100
|
+
'1','2','3','4','5',
|
101
|
+
'6','7','8','9','10',
|
102
|
+
'11','12','13','14','15',
|
103
|
+
'16','17','18','19','20',
|
104
|
+
'21','22','23','24','25',
|
105
|
+
'26','27','28','29','30',
|
106
|
+
'31','32','33','34','35'
|
107
|
+
]
|
108
|
+
|
109
|
+
# Initialize a pager with
|
110
|
+
# 5 posts per page
|
111
|
+
# at page 5 out of 5 pages
|
112
|
+
pager = Paginator.new(5, "index.html", "/page:num/", posts, 5, 5, '', '')
|
113
|
+
|
114
|
+
pager.page.must_equal 5
|
115
|
+
pager.per_page.must_equal 5
|
116
|
+
pager.total_pages.must_equal 5
|
117
|
+
|
118
|
+
pager.total_posts.must_equal 35
|
119
|
+
|
120
|
+
pager.posts.size.must_equal 5
|
121
|
+
pager.posts[0].must_equal '21'
|
122
|
+
pager.posts[4].must_equal '25'
|
123
|
+
|
124
|
+
pager.previous_page.must_equal 4
|
125
|
+
pager.previous_page_path.must_equal '/page4/'
|
126
|
+
pager.next_page.must_be_nil
|
127
|
+
pager.next_page_path.must_be_nil
|
128
|
+
end
|
129
|
+
|
130
|
+
it "must create the explicit index page and index extension when specified" do
|
131
|
+
# Create a dummy list of posts that is easy to track
|
132
|
+
posts = [
|
133
|
+
'1','2','3','4','5',
|
134
|
+
'6','7','8','9','10',
|
135
|
+
'11','12','13','14','15',
|
136
|
+
'16','17','18','19','20',
|
137
|
+
'21','22','23','24','25',
|
138
|
+
'26','27','28','29','30',
|
139
|
+
'31','32','33','34','35'
|
140
|
+
]
|
141
|
+
|
142
|
+
# Initialize a pager with
|
143
|
+
# 5 posts per page
|
144
|
+
# at page 2 out of 5 pages
|
145
|
+
pager = Paginator.new(5, "index.html", "/page:num/", posts, 2, 5, 'index', '.html')
|
146
|
+
|
147
|
+
pager.page.must_equal 2
|
148
|
+
pager.per_page.must_equal 5
|
149
|
+
pager.total_pages.must_equal 5
|
150
|
+
|
151
|
+
pager.total_posts.must_equal 35
|
152
|
+
|
153
|
+
pager.posts.size.must_equal 5
|
154
|
+
pager.posts[0].must_equal '6'
|
155
|
+
pager.posts[4].must_equal '10'
|
156
|
+
|
157
|
+
pager.previous_page.must_equal 1
|
158
|
+
pager.previous_page_path.must_equal 'index.html'
|
159
|
+
pager.next_page.must_equal 3
|
160
|
+
pager.next_page_path.must_equal '/page3/index.html'
|
161
|
+
end
|
162
|
+
|
163
|
+
it "must create the explicit index page and index extension when specified" do
|
164
|
+
# Create a dummy list of posts that is easy to track
|
165
|
+
posts = [
|
166
|
+
'1','2','3','4','5',
|
167
|
+
'6','7','8','9','10',
|
168
|
+
'11','12','13','14','15',
|
169
|
+
'16','17','18','19','20',
|
170
|
+
'21','22','23','24','25',
|
171
|
+
'26','27','28','29','30',
|
172
|
+
'31','32','33','34','35'
|
173
|
+
]
|
174
|
+
|
175
|
+
# Initialize a pager with
|
176
|
+
# 5 posts per page
|
177
|
+
# at page 2 out of 5 pages
|
178
|
+
pager = Paginator.new(5, "/", "/", posts, 2, 5, 'feed:num', '.json')
|
179
|
+
|
180
|
+
pager.page.must_equal 2
|
181
|
+
pager.per_page.must_equal 5
|
182
|
+
pager.total_pages.must_equal 5
|
183
|
+
|
184
|
+
pager.total_posts.must_equal 35
|
185
|
+
|
186
|
+
pager.posts.size.must_equal 5
|
187
|
+
pager.posts[0].must_equal '6'
|
188
|
+
pager.posts[4].must_equal '10'
|
189
|
+
|
190
|
+
pager.previous_page.must_equal 1
|
191
|
+
pager.previous_page_path.must_equal '/feed1.json'
|
192
|
+
pager.next_page.must_equal 3
|
193
|
+
pager.next_page_path.must_equal '/feed3.json'
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
197
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require_relative '../spec_helper.rb'
|
2
|
+
|
3
|
+
module Jekyll::J1Paginator::Generator
|
4
|
+
describe Utils do
|
5
|
+
|
6
|
+
it "should always replace num format with the specified number" do
|
7
|
+
Utils.format_page_number( ":num", 7).must_equal "7"
|
8
|
+
Utils.format_page_number( ":num", 13).must_equal "13"
|
9
|
+
Utils.format_page_number( ":num", -2).must_equal "-2"
|
10
|
+
Utils.format_page_number( ":num", 0).must_equal "0"
|
11
|
+
Utils.format_page_number( ":num", 1000).must_equal "1000"
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should always replace num format with the specified number and keep rest of formatting" do
|
15
|
+
Utils.format_page_number( "/page:num/", 7).must_equal "/page7/"
|
16
|
+
Utils.format_page_number( "/page:num/", 50).must_equal "/page50/"
|
17
|
+
Utils.format_page_number( "/page:num/", -5).must_equal "/page-5/"
|
18
|
+
|
19
|
+
Utils.format_page_number( "/car/:num/", 1).must_equal "/car/1/"
|
20
|
+
Utils.format_page_number( "/car/:num", 1).must_equal "/car/1"
|
21
|
+
Utils.format_page_number( "car/:num", 1).must_equal "car/1"
|
22
|
+
Utils.format_page_number( "/car//:num", 1).must_equal "/car//1"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "make sure there is a leading slash in path" do
|
26
|
+
Utils.ensure_leading_slash("path/to/file/wow").must_equal "/path/to/file/wow"
|
27
|
+
Utils.ensure_leading_slash("/no/place/wow/").must_equal "/no/place/wow/"
|
28
|
+
Utils.ensure_leading_slash("/no").must_equal "/no"
|
29
|
+
Utils.ensure_leading_slash("no").must_equal "/no"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "make sure there is never a leading slash in path" do
|
33
|
+
Utils.remove_leading_slash("path/to/file/wow").must_equal "path/to/file/wow"
|
34
|
+
Utils.remove_leading_slash("/no/place/wow/").must_equal "no/place/wow/"
|
35
|
+
Utils.remove_leading_slash("/no").must_equal "no"
|
36
|
+
Utils.remove_leading_slash("no").must_equal "no"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "sort must sort strings lowercase" do
|
40
|
+
Utils.sort_values( "AARON", "Aaron").must_equal 0
|
41
|
+
Utils.sort_values( "AARON", "aaron").must_equal 0
|
42
|
+
Utils.sort_values( "aaron", "AARON").must_equal 0
|
43
|
+
end
|
44
|
+
|
45
|
+
it "when sorting by nested post data the values must be resolved fully" do
|
46
|
+
data = {'book'=>{ 'name' => { 'first'=> 'John', 'last'=> 'Smith'}, 'rank'=>20}}
|
47
|
+
Utils.sort_get_post_data(data, "book:rank").must_equal 20
|
48
|
+
Utils.sort_get_post_data(data, "book:name:first").must_equal "John"
|
49
|
+
Utils.sort_get_post_data(data, "book:name:last").must_equal "Smith"
|
50
|
+
|
51
|
+
Utils.sort_get_post_data(data, "book:name").must_be_nil
|
52
|
+
Utils.sort_get_post_data(data, "name").must_be_nil
|
53
|
+
Utils.sort_get_post_data(data, "book").must_be_nil
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should always replace max format with the specified number if specified" do
|
57
|
+
Utils.format_page_number( ":num-:max", 7, 16).must_equal "7-16"
|
58
|
+
Utils.format_page_number( ":num-:max", 13, 20).must_equal "13-20"
|
59
|
+
Utils.format_page_number( ":num-:max", -2, -4).must_equal "-2--4"
|
60
|
+
Utils.format_page_number( ":num_of_:max", 0, 10).must_equal "0_of_10"
|
61
|
+
Utils.format_page_number( ":num/:max", 1000, 2000).must_equal "1000/2000"
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|