wor-paginate 0.4.2 → 0.5.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 +4 -4
- data/CHANGELOG.md +3 -0
- data/README.md +33 -2
- data/lib/wor/paginate/formatters/base.rb +9 -2
- data/lib/wor/paginate/paginate.rb +8 -7
- data/lib/wor/paginate/rspec.rb +46 -9
- data/lib/wor/paginate/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: decca93406ee541c53c128fb024c0be0ba58576b47a0c9cde5e834e33365c8e2
|
|
4
|
+
data.tar.gz: baae1708bf393145b589b872e3bf2a4ba44f3215efecc1a3bae34025cac0c9c4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 75eb5ddfc44ed747a69fa797125776a4a2cdbe5e40ba9a3e7502a9af1685b844cad52d50c910d3856d591e8a31b7f6f1495a42542eabfb50a057992ba183d717
|
|
7
|
+
data.tar.gz: a140a0337bdb012c9821217f34cd2ea2099c0f8407cab21e8042c80ab5ee2c0ca8a375ad83d8931ed159f855cbc8ffc72458252c2c006694a9fa3e7da7d858a9
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
## Change log
|
|
2
2
|
|
|
3
|
+
### V0.5.0
|
|
4
|
+
* [#6](https://github.com/icoluccio/wor-paginate/pull/6) Add block serialization to `render_paginated` - [@icoluccio](https://github.com/icoluccio).
|
|
5
|
+
|
|
3
6
|
### V0.4.2
|
|
4
7
|
* [#3](https://github.com/icoluccio/wor-paginate/pull/3) Add Pagy adapter - [@icoluccio](https://github.com/icoluccio).
|
|
5
8
|
* [#4](https://github.com/icoluccio/wor-paginate/pull/4) Remove remaining rubocop:disable/:enable comments - [@icoluccio](https://github.com/icoluccio).
|
data/README.md
CHANGED
|
@@ -11,12 +11,14 @@ Wor::Paginate
|
|
|
11
11
|
- [Basic usage](#basic-usage)
|
|
12
12
|
- [Customizing output](#customizing-output)
|
|
13
13
|
- [Custom serializers](#custom-serializers)
|
|
14
|
+
- [Block serialization](#block-serialization)
|
|
14
15
|
- [Custom options](#custom-options)
|
|
15
16
|
- [Custom formatters](#custom-formatters)
|
|
16
17
|
- [Custom adapters](#custom-adapters)
|
|
17
18
|
- [Working with Kaminari, will_paginate, or Pagy](#working-with-kaminari-will_paginate-or-pagy)
|
|
18
19
|
- [Kaminari and will_paginate both define `Model.page`](#kaminari-and-will_paginate-both-define-modelpage)
|
|
19
20
|
- [Test helpers](#test-helpers)
|
|
21
|
+
- [Field value chains](#field-value-chains)
|
|
20
22
|
- [Contributing](#contributing)
|
|
21
23
|
- [Releases](#releases)
|
|
22
24
|
- [About](#about)
|
|
@@ -109,6 +111,19 @@ render_paginated DummyModel, each_serializer: CustomDummyModelSerializer
|
|
|
109
111
|
```
|
|
110
112
|
where the serializer is just an [`ActiveModel::Serializer`](https://github.com/rails-api/active_model_serializers).
|
|
111
113
|
|
|
114
|
+
#### Block serialization
|
|
115
|
+
When you need a custom per-record payload that doesn't fit a serializer class, pass a block to `render_paginated`. The block receives each record and its return value is used as the serialized entry:
|
|
116
|
+
|
|
117
|
+
```ruby
|
|
118
|
+
def index
|
|
119
|
+
render_paginated(DummyModel) { |record| { id: record.id, label: record.name.upcase } }
|
|
120
|
+
end
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
All pagination metadata (`count`, `total_pages`, `next_page_url`, etc.) is still computed and returned normally. The block only controls the content of the `page` array.
|
|
124
|
+
|
|
125
|
+
The block form works with any adapter and takes precedence over `each_serializer` when both are supplied.
|
|
126
|
+
|
|
112
127
|
#### Custom options
|
|
113
128
|
##### max_limit
|
|
114
129
|
The max amount of items is passed through the `max_limit` option. You can set the value in the initializer or in the `render_paginated` method (If none is supplied, take the default value configured in the initializer). Default is 50.
|
|
@@ -299,7 +314,7 @@ render_paginated SomeModel, adapter: KaminariRenamedAdapter
|
|
|
299
314
|
```
|
|
300
315
|
|
|
301
316
|
### Test helpers
|
|
302
|
-
You can use the `be_paginated` matcher to test your endpoints.
|
|
317
|
+
You can use the `be_paginated` matcher to test your endpoints.
|
|
303
318
|
|
|
304
319
|
You only need to add this in your rails_helper.rb
|
|
305
320
|
|
|
@@ -332,6 +347,22 @@ describe YourController do
|
|
|
332
347
|
end
|
|
333
348
|
```
|
|
334
349
|
|
|
350
|
+
#### Field value chains
|
|
351
|
+
|
|
352
|
+
You can assert specific pagination field values by chaining matchers:
|
|
353
|
+
|
|
354
|
+
```ruby
|
|
355
|
+
expect(response_body).to be_paginated
|
|
356
|
+
.with_total_count(42)
|
|
357
|
+
.with_current_page(1)
|
|
358
|
+
.with_next_page(2)
|
|
359
|
+
.with_previous_page(nil)
|
|
360
|
+
.with_total_pages(3)
|
|
361
|
+
.with_count(25)
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
Each chain is optional and independent. When a chain assertion fails, the error message names the specific field and the expected vs actual value.
|
|
365
|
+
|
|
335
366
|
### Working with panko-serializer
|
|
336
367
|
|
|
337
368
|
The default formatter is [Active Model Serializer](https://github.com/rails-api/active_model_serializers).
|
|
@@ -359,7 +390,7 @@ and next, pass the specific serializer that you can use in the specific endpoint
|
|
|
359
390
|
5. Commit your changes (`git commit -am 'Add some feature'`)
|
|
360
391
|
6. Run RuboCop lint (`bundle exec rubocop lib spec --format simple`)
|
|
361
392
|
7. Run rspec tests (`BUNDLE_GEMFILE=gemfiles/rails_8.1.gemfile bundle exec rspec`)
|
|
362
|
-
8. Push your branch (`git push origin my-new-feature`)
|
|
393
|
+
8. Push your branch (`git push origin my-new-feature`) - the pre-push hook re-verifies both automatically
|
|
363
394
|
9. Create a new Pull Request to `main` branch
|
|
364
395
|
|
|
365
396
|
## Releases
|
|
@@ -7,14 +7,15 @@ module Wor
|
|
|
7
7
|
include Utils::UriHelper
|
|
8
8
|
attr_accessor :adapter, :formatter, :options
|
|
9
9
|
|
|
10
|
-
def initialize(adapter, options = {})
|
|
10
|
+
def initialize(adapter, options = {}, &block)
|
|
11
11
|
@adapter = adapter
|
|
12
12
|
@options = options
|
|
13
|
+
@serializer_block = block
|
|
13
14
|
end
|
|
14
15
|
|
|
15
16
|
def format # rubocop: disable Metrics/MethodLength
|
|
16
17
|
{
|
|
17
|
-
page:
|
|
18
|
+
page: serialized_page,
|
|
18
19
|
count: count,
|
|
19
20
|
total_pages: total_pages,
|
|
20
21
|
total_count: options[:total_count] || total_count,
|
|
@@ -38,6 +39,12 @@ module Wor
|
|
|
38
39
|
@paginated_content ||= adapter.paginated_content
|
|
39
40
|
end
|
|
40
41
|
|
|
42
|
+
def serialized_page
|
|
43
|
+
return paginated_content.map(&@serializer_block) if @serializer_block
|
|
44
|
+
|
|
45
|
+
serialized_content
|
|
46
|
+
end
|
|
47
|
+
|
|
41
48
|
def serialized_content
|
|
42
49
|
paginated_content.as_json
|
|
43
50
|
end
|
|
@@ -2,13 +2,13 @@ require_relative 'utils/preserve_records_helper'
|
|
|
2
2
|
|
|
3
3
|
module Wor
|
|
4
4
|
module Paginate
|
|
5
|
-
def render_paginated(content, options = {})
|
|
6
|
-
return render_paginate_with_include(content, options) if includes?(options)
|
|
5
|
+
def render_paginated(content, options = {}, &block)
|
|
6
|
+
return render_paginate_with_include(content, options, &block) if includes?(options)
|
|
7
7
|
|
|
8
|
-
render json: paginate(content, options)
|
|
8
|
+
render json: paginate(content, options, &block)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
def paginate(content, options = {})
|
|
11
|
+
def paginate(content, options = {}, &block)
|
|
12
12
|
current_url = request.original_url
|
|
13
13
|
if (preserve_records = options[:preserve_records])
|
|
14
14
|
content, current_url = Wor::Paginate::Utils::PreserveRecordsHelper
|
|
@@ -18,11 +18,12 @@ module Wor
|
|
|
18
18
|
adapter = find_adapter_for_content(content, options)
|
|
19
19
|
raise Exceptions::NoPaginationAdapter if adapter.blank?
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
merged = options.merge(_current_url: current_url)
|
|
22
|
+
formatter_class(options).new(adapter, merged, &block).format
|
|
22
23
|
end
|
|
23
24
|
|
|
24
|
-
def render_paginate_with_include(content, options)
|
|
25
|
-
render json: paginate(content, options), include: options[:include]
|
|
25
|
+
def render_paginate_with_include(content, options, &block)
|
|
26
|
+
render json: paginate(content, options, &block), include: options[:include]
|
|
26
27
|
end
|
|
27
28
|
|
|
28
29
|
def formatter_class(options)
|
data/lib/wor/paginate/rspec.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
CHAINABLE_FIELDS = %w[total_count count total_pages current_page next_page previous_page].freeze
|
|
2
|
+
|
|
1
3
|
class MockedAdapter < Wor::Paginate::Adapters::Base
|
|
2
4
|
def initialize
|
|
3
5
|
super(nil, 1, 1)
|
|
@@ -28,28 +30,63 @@ class MockedAdapter < Wor::Paginate::Adapters::Base
|
|
|
28
30
|
end
|
|
29
31
|
end
|
|
30
32
|
|
|
33
|
+
class PaginatedAssertion
|
|
34
|
+
attr_reader :failures, :formatted_keys
|
|
35
|
+
|
|
36
|
+
def initialize(response, formatter, expectations)
|
|
37
|
+
@response = response
|
|
38
|
+
formatted = formatter.new(MockedAdapter.new, _current_url: 'http://example.com/')
|
|
39
|
+
@formatted_keys = formatted.format.as_json.keys
|
|
40
|
+
@failures = key_failures + field_failures(expectations)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def pass?
|
|
44
|
+
@failures.empty?
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def key_failures
|
|
50
|
+
return [] if @response.keys == @formatted_keys
|
|
51
|
+
|
|
52
|
+
["expected keys #{@formatted_keys} but got #{@response.keys}"]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def field_failures(expectations)
|
|
56
|
+
CHAINABLE_FIELDS.filter_map do |field|
|
|
57
|
+
expected = expectations[field]
|
|
58
|
+
next if expected.nil?
|
|
59
|
+
|
|
60
|
+
actual = @response[field]
|
|
61
|
+
next if actual == expected
|
|
62
|
+
|
|
63
|
+
"expected #{field} to be #{expected.inspect} but got #{actual.inspect}"
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
31
68
|
RSpec::Matchers.define :be_paginated do
|
|
32
69
|
match do |actual_response|
|
|
33
|
-
response = parse_response(actual_response)
|
|
34
70
|
formatter = @custom_formatter || Wor::Paginate::Formatters::Base
|
|
35
|
-
|
|
36
|
-
|
|
71
|
+
expectations = CHAINABLE_FIELDS.index_with { |f| instance_variable_get(:"@expected_#{f}") }
|
|
72
|
+
@assertion = PaginatedAssertion.new(parse_response(actual_response), formatter, expectations)
|
|
73
|
+
@assertion.pass?
|
|
37
74
|
end
|
|
38
75
|
|
|
39
76
|
def parse_response(response)
|
|
40
77
|
response.is_a?(Hash) ? response : JSON.parse(response.body)
|
|
41
78
|
end
|
|
42
79
|
|
|
43
|
-
chain
|
|
44
|
-
@custom_formatter = custom_formatter
|
|
45
|
-
end
|
|
80
|
+
chain(:with) { |formatter| @custom_formatter = formatter }
|
|
46
81
|
|
|
47
|
-
|
|
48
|
-
"
|
|
82
|
+
CHAINABLE_FIELDS.each do |field|
|
|
83
|
+
chain(:"with_#{field}") { |value| instance_variable_set(:"@expected_#{field}", value) }
|
|
49
84
|
end
|
|
50
85
|
|
|
86
|
+
failure_message { |_| @assertion.failures.join("\n") }
|
|
87
|
+
|
|
51
88
|
failure_message_when_negated do |actual_response|
|
|
52
89
|
"expected that #{parse_response(actual_response)} not " \
|
|
53
|
-
"to be paginated with keys #{@formatted_keys}"
|
|
90
|
+
"to be paginated with keys #{@assertion.formatted_keys}"
|
|
54
91
|
end
|
|
55
92
|
end
|
data/lib/wor/paginate/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: wor-paginate
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- icoluccio
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
- lucasVoboril
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2026-08-
|
|
13
|
+
date: 2026-08-30 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: railties
|
|
@@ -121,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
121
121
|
- !ruby/object:Gem::Version
|
|
122
122
|
version: '0'
|
|
123
123
|
requirements: []
|
|
124
|
-
rubygems_version:
|
|
124
|
+
rubygems_version: 3.6.9
|
|
125
125
|
specification_version: 4
|
|
126
126
|
summary: Simplified pagination for Rails API controllers
|
|
127
127
|
test_files: []
|