trailblazer-finder 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.rubocop.yml +45 -0
  4. data/.rubocop_todo.yml +52 -0
  5. data/.travis.yml +15 -0
  6. data/Gemfile +12 -0
  7. data/LICENSE.txt +23 -0
  8. data/README.md +494 -0
  9. data/Rakefile +29 -0
  10. data/lib/trailblazer/finder/adapters/active_record/paging.rb +20 -0
  11. data/lib/trailblazer/finder/adapters/active_record/sorting.rb +20 -0
  12. data/lib/trailblazer/finder/adapters/active_record.rb +30 -0
  13. data/lib/trailblazer/finder/adapters/data_mapper/paging.rb +20 -0
  14. data/lib/trailblazer/finder/adapters/data_mapper/sorting.rb +25 -0
  15. data/lib/trailblazer/finder/adapters/data_mapper.rb +30 -0
  16. data/lib/trailblazer/finder/adapters/friendly_id.rb +33 -0
  17. data/lib/trailblazer/finder/adapters/kaminari.rb +18 -0
  18. data/lib/trailblazer/finder/adapters/sequel/paging.rb +20 -0
  19. data/lib/trailblazer/finder/adapters/sequel/sorting.rb +25 -0
  20. data/lib/trailblazer/finder/adapters/sequel.rb +30 -0
  21. data/lib/trailblazer/finder/adapters/will_paginate.rb +18 -0
  22. data/lib/trailblazer/finder/adapters.rb +26 -0
  23. data/lib/trailblazer/finder/base.rb +98 -0
  24. data/lib/trailblazer/finder/errors/block_ignored.rb +11 -0
  25. data/lib/trailblazer/finder/errors/invalid_defined_by_value.rb +11 -0
  26. data/lib/trailblazer/finder/errors/invalid_number.rb +16 -0
  27. data/lib/trailblazer/finder/errors/missing_entity_type.rb +11 -0
  28. data/lib/trailblazer/finder/errors/with_ignored.rb +11 -0
  29. data/lib/trailblazer/finder/features/paging.rb +55 -0
  30. data/lib/trailblazer/finder/features/sorting.rb +66 -0
  31. data/lib/trailblazer/finder/features.rb +22 -0
  32. data/lib/trailblazer/finder/filter.rb +66 -0
  33. data/lib/trailblazer/finder/find.rb +29 -0
  34. data/lib/trailblazer/finder/utils/extra.rb +31 -0
  35. data/lib/trailblazer/finder/utils/params.rb +28 -0
  36. data/lib/trailblazer/finder/utils/parse.rb +25 -0
  37. data/lib/trailblazer/finder/utils/string.rb +35 -0
  38. data/lib/trailblazer/finder/version.rb +5 -0
  39. data/lib/trailblazer/finder.rb +29 -0
  40. data/lib/trailblazer/operation/finder.rb +61 -0
  41. data/spec/spec_helper.rb +15 -0
  42. data/spec/spec_helper_active_record.rb +50 -0
  43. data/spec/spec_helper_data_mapper.rb +35 -0
  44. data/spec/spec_helper_sequel.rb +32 -0
  45. data/spec/support/paging_shared_example.rb +65 -0
  46. data/spec/support/sorting_shared_example.rb +95 -0
  47. data/spec/trailblazer/finder/adapters/active_record/base_spec.rb +112 -0
  48. data/spec/trailblazer/finder/adapters/active_record/paging_spec.rb +64 -0
  49. data/spec/trailblazer/finder/adapters/active_record/sorting_spec.rb +82 -0
  50. data/spec/trailblazer/finder/adapters/data_mapper/base_spec.rb +112 -0
  51. data/spec/trailblazer/finder/adapters/data_mapper/paging_spec.rb +64 -0
  52. data/spec/trailblazer/finder/adapters/data_mapper/sorting_spec.rb +85 -0
  53. data/spec/trailblazer/finder/adapters/friendly_id_spec.rb +46 -0
  54. data/spec/trailblazer/finder/adapters/kaminari_spec.rb +64 -0
  55. data/spec/trailblazer/finder/adapters/sequel/base_spec.rb +112 -0
  56. data/spec/trailblazer/finder/adapters/sequel/paging_spec.rb +64 -0
  57. data/spec/trailblazer/finder/adapters/sequel/sorting_spec.rb +82 -0
  58. data/spec/trailblazer/finder/adapters/will_paginate_spec.rb +71 -0
  59. data/spec/trailblazer/finder/adapters_spec.rb +110 -0
  60. data/spec/trailblazer/finder/base_spec.rb +329 -0
  61. data/spec/trailblazer/finder/features/paging_spec.rb +104 -0
  62. data/spec/trailblazer/finder/features/sorting_spec.rb +100 -0
  63. data/spec/trailblazer/finder/features_spec.rb +55 -0
  64. data/spec/trailblazer/finder/filter_spec.rb +133 -0
  65. data/spec/trailblazer/finder/find_spec.rb +72 -0
  66. data/spec/trailblazer/finder/utils/extra_spec.rb +41 -0
  67. data/spec/trailblazer/finder/utils/params_spec.rb +39 -0
  68. data/spec/trailblazer/finder/utils/parse_spec.rb +33 -0
  69. data/spec/trailblazer/finder/utils/string_spec.rb +25 -0
  70. data/spec/trailblazer/operation/finder_spec.rb +103 -0
  71. data/spec/trailblazer/operation/paging_spec.rb +68 -0
  72. data/spec/trailblazer/operation/sorting_spec.rb +80 -0
  73. data/trailblazer-finder.gemspec +41 -0
  74. metadata +402 -0
@@ -0,0 +1,112 @@
1
+ require 'spec_helper_active_record'
2
+
3
+ module Trailblazer
4
+ class Finder
5
+ module Adapters
6
+ describe ActiveRecord do
7
+ # it_behaves_like 'a base orm adapter'
8
+
9
+ after do
10
+ Product.delete_all
11
+ end
12
+
13
+ def define_finder_class(&block)
14
+ Class.new(Trailblazer::Finder) do
15
+ class_eval(&block)
16
+ end
17
+ end
18
+
19
+ def finder_class(&block) # rubocop:disable Metrics/MethodLength
20
+ define_finder_class do
21
+ adapters ActiveRecord
22
+
23
+ entity_type { Product }
24
+
25
+ filter_by :id
26
+ filter_by :name
27
+ filter_by :slug
28
+
29
+ if block.nil?
30
+ filter_by :value do |entity_type, value|
31
+ entity_type.where(slug: value)
32
+ end
33
+ else
34
+ class_eval(&block)
35
+ end
36
+ end
37
+ end
38
+
39
+ def finder_with_filter(key = nil, name = nil, &block)
40
+ finder_class(&block).new filter: { key => name }
41
+ end
42
+
43
+ describe 'filter_by' do
44
+ it 'has a default filter' do
45
+ 10.times { |i| Product.create name: "product_#{i}" }
46
+ finder = finder_with_filter :name, 'product_2'
47
+
48
+ expect(finder.results.first.name).to eq 'product_2'
49
+ end
50
+
51
+ it 'has another default filter' do
52
+ 10.times { |i| Product.create slug: "product_#{i}" }
53
+ finder = finder_with_filter :value, 'product_2'
54
+
55
+ expect(finder.results.first.slug).to eq 'product_2'
56
+ end
57
+ end
58
+
59
+ it 'can use methods from the object' do
60
+ 2.times { |i| Product.create name: "product_#{i}" }
61
+ finder1 = finder_with_filter :id, 1 do
62
+ filter_by :id do |entity_type, value|
63
+ some_instance_method(entity_type, value)
64
+ end
65
+
66
+ private
67
+
68
+ def some_instance_method(entity_type, value)
69
+ entity_type.where(id: value)
70
+ end
71
+ end
72
+
73
+ expect(finder1.results.first.id).to eq 1
74
+ end
75
+
76
+ it 'can dispatch with instance methods' do
77
+ 2.times { |i| Product.create name: "product_#{i}" }
78
+ finder = finder_with_filter :id, 3 do
79
+ filter_by :id, with: :some_instance_method
80
+
81
+ private
82
+
83
+ def some_instance_method(entity_type, value)
84
+ entity_type.where(id: value)
85
+ end
86
+ end
87
+
88
+ expect(finder.results.first.id).to eq 3
89
+ end
90
+
91
+ describe 'filter_by attributes' do
92
+ it 'accesses filter values' do
93
+ finder = finder_with_filter :value, 1
94
+ expect(finder.value).to eq 1
95
+ end
96
+
97
+ it 'returns default filter value if filter_by is not specified' do
98
+ finder = finder_with_filter do
99
+ filter_by :value, 1
100
+ end
101
+ expect(finder.value).to eq 1
102
+ end
103
+
104
+ it 'does not include invalid filters' do
105
+ finder = finder_with_filter invalid: 'option'
106
+ expect { finder.invalid }.to raise_error NoMethodError
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper_active_record'
2
+
3
+ module Trailblazer
4
+ class Finder
5
+ module Adapters
6
+ module ActiveRecord
7
+ describe Paging do
8
+ it_behaves_like 'a paging feature'
9
+
10
+ after do
11
+ Product.delete_all
12
+ end
13
+
14
+ def define_finder_class(&block)
15
+ Class.new do
16
+ include Trailblazer::Finder::Base
17
+ include Trailblazer::Finder::Features::Paging
18
+ include Trailblazer::Finder::Adapters::ActiveRecord
19
+
20
+ instance_eval(&block) if block_given?
21
+ end
22
+ end
23
+
24
+ def finder_class
25
+ define_finder_class do
26
+ entity_type { Product }
27
+
28
+ per_page 2
29
+
30
+ min_per_page 2
31
+ max_per_page 10
32
+ end
33
+ end
34
+
35
+ def finder_with_page(page = nil, per_page = nil)
36
+ finder_class.new page: page, per_page: per_page
37
+ end
38
+
39
+ it 'can be inherited' do
40
+ child_class = Class.new(finder_class)
41
+ expect(child_class.new.per_page).to eq 2
42
+ end
43
+
44
+ describe '#results' do
45
+ it 'paginates results' do
46
+ 6.times { |i| Product.create name: "product_#{i}" }
47
+ finder = finder_with_page 2, 2
48
+
49
+ expect(finder.results.map(&:name)).to eq %w[product_2 product_3]
50
+ end
51
+ end
52
+
53
+ describe '#count' do
54
+ it 'gives the real count' do
55
+ 10.times { |i| Product.create name: "product_#{i}" }
56
+ finder = finder_with_page 1
57
+ expect(finder.count).to eq 10
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,82 @@
1
+ require 'spec_helper_active_record'
2
+
3
+ module Trailblazer
4
+ class Finder
5
+ module Adapters
6
+ module ActiveRecord
7
+ describe Sorting do
8
+ def finder_class
9
+ Class.new do
10
+ include Trailblazer::Finder::Base
11
+ include Trailblazer::Finder::Features::Sorting
12
+ include Trailblazer::Finder::Adapters::ActiveRecord
13
+
14
+ entity_type { Product.all }
15
+
16
+ sortable_by :name, :price, :created_at
17
+
18
+ filter_by :name
19
+ filter_by :price
20
+ filter_by(:category) { |entity_type, _| entity_type.joins(:category) }
21
+ end
22
+ end
23
+
24
+ def finder_with_sort(sort = nil, filters = {})
25
+ finder_class.new filter: { sort: sort }.merge(filters)
26
+ end
27
+
28
+ it 'can be inherited' do
29
+ child_class = Class.new(finder_class)
30
+ expect(child_class.new.sort_attribute).to eq 'name'
31
+ end
32
+
33
+ describe 'sorting' do
34
+ after do
35
+ Product.delete_all
36
+ end
37
+
38
+ it 'sorts results based on the sort option desc' do
39
+ 5.times { |i| Product.create! price: i }
40
+
41
+ finder = finder_with_sort 'price desc'
42
+ expect(finder.results.map(&:price)).to eq [4, 3, 2, 1, 0]
43
+ end
44
+
45
+ it 'sorts results based on the sort option asc' do
46
+ 5.times { |i| Product.create! price: i }
47
+
48
+ finder = finder_with_sort 'price asc'
49
+ expect(finder.results.map(&:price)).to eq [0, 1, 2, 3, 4]
50
+ end
51
+
52
+ it 'defaults to first sort by option' do
53
+ 5.times { |i| Product.create! name: "Name#{i}" }
54
+
55
+ finder = finder_with_sort
56
+ expect(finder.results.map(&:name)).to eq %w[Name4 Name3 Name2 Name1 Name0]
57
+ end
58
+
59
+ it 'ignores invalid sort values' do
60
+ finder = finder_with_sort 'invalid attribute'
61
+ expect { finder.results.to_a }.not_to raise_error
62
+ end
63
+
64
+ it 'can handle renames of sorting in joins' do
65
+ older_category = Category.create! title: 'older'
66
+ newer_category = Category.create! title: 'newer'
67
+
68
+ product_of_newer_category = Product.create! name: 'older product', category: newer_category
69
+ product_of_older_category = Product.create! name: 'newer product', category: older_category
70
+
71
+ finder = finder_with_sort 'created_at desc', category: ''
72
+
73
+ expect(finder.results.map(&:name)).to eq [product_of_older_category.name, product_of_newer_category.name]
74
+ end
75
+ end
76
+
77
+ it_behaves_like 'a sorting feature'
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,112 @@
1
+ require 'spec_helper_data_mapper'
2
+
3
+ module Trailblazer
4
+ class Finder
5
+ module Adapters
6
+ describe DataMapper do
7
+ # it_behaves_like 'a base orm adapter'
8
+
9
+ after do
10
+ DProduct.all.destroy
11
+ end
12
+
13
+ def define_finder_class(&block)
14
+ Class.new(Trailblazer::Finder) do
15
+ class_eval(&block)
16
+ end
17
+ end
18
+
19
+ def finder_class(&block) # rubocop:disable Metrics/MethodLength
20
+ define_finder_class do
21
+ adapters DataMapper
22
+
23
+ entity_type { DProduct }
24
+
25
+ filter_by :id
26
+ filter_by :name
27
+ filter_by :slug
28
+
29
+ if block.nil?
30
+ filter_by :value do |entity_type, value|
31
+ entity_type.all(slug: value)
32
+ end
33
+ else
34
+ class_eval(&block)
35
+ end
36
+ end
37
+ end
38
+
39
+ def finder_with_filter(key = nil, name = nil, &block)
40
+ finder_class(&block).new filter: { key => name }
41
+ end
42
+
43
+ describe 'filter_by' do
44
+ it 'has a default filter' do
45
+ 10.times { |i| DProduct.create name: "product_#{i}" }
46
+ finder = finder_with_filter :name, 'product_2'
47
+
48
+ expect(finder.results.first.name).to eq 'product_2'
49
+ end
50
+
51
+ it 'has another default filter' do
52
+ 10.times { |i| DProduct.create slug: "product_#{i}" }
53
+ finder = finder_with_filter :value, 'product_2'
54
+
55
+ expect(finder.results.first.slug).to eq 'product_2'
56
+ end
57
+ end
58
+
59
+ it 'can use methods from the object' do
60
+ 2.times { |i| DProduct.create name: "product_#{i}" }
61
+ finder1 = finder_with_filter :id, 1 do
62
+ filter_by :id do |entity_type, value|
63
+ some_instance_method(entity_type, value)
64
+ end
65
+
66
+ private
67
+
68
+ def some_instance_method(entity_type, value)
69
+ entity_type.all(id: value)
70
+ end
71
+ end
72
+
73
+ expect(finder1.results.first.id).to eq 1
74
+ end
75
+
76
+ it 'can dispatch with instance methods' do
77
+ 2.times { |i| DProduct.create name: "product_#{i}" }
78
+ finder = finder_with_filter :id, 3 do
79
+ filter_by :id, with: :some_instance_method
80
+
81
+ private
82
+
83
+ def some_instance_method(entity_type, value)
84
+ entity_type.all(id: value)
85
+ end
86
+ end
87
+
88
+ expect(finder.results.first.id).to eq 3
89
+ end
90
+
91
+ describe 'filter_by attributes' do
92
+ it 'accesses filter values' do
93
+ finder = finder_with_filter :value, 1
94
+ expect(finder.value).to eq 1
95
+ end
96
+
97
+ it 'returns default filter value if filter_by is not specified' do
98
+ finder = finder_with_filter do
99
+ filter_by :value, 1
100
+ end
101
+ expect(finder.value).to eq 1
102
+ end
103
+
104
+ it 'does not include invalid filters' do
105
+ finder = finder_with_filter invalid: 'option'
106
+ expect { finder.invalid }.to raise_error NoMethodError
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper_data_mapper'
2
+
3
+ module Trailblazer
4
+ class Finder
5
+ module Adapters
6
+ module DataMapper
7
+ describe Paging do
8
+ it_behaves_like 'a paging feature'
9
+
10
+ after do
11
+ DProduct.all.destroy
12
+ end
13
+
14
+ def define_finder_class(&block)
15
+ Class.new do
16
+ include Trailblazer::Finder::Base
17
+ include Trailblazer::Finder::Features::Paging
18
+ include Trailblazer::Finder::Adapters::DataMapper
19
+
20
+ instance_eval(&block) if block_given?
21
+ end
22
+ end
23
+
24
+ def finder_class
25
+ define_finder_class do
26
+ entity_type { DProduct }
27
+
28
+ per_page 2
29
+
30
+ min_per_page 2
31
+ max_per_page 10
32
+ end
33
+ end
34
+
35
+ def finder_with_page(page = nil, per_page = nil)
36
+ finder_class.new page: page, per_page: per_page
37
+ end
38
+
39
+ it 'can be inherited' do
40
+ child_class = Class.new(finder_class)
41
+ expect(child_class.new.per_page).to eq 2
42
+ end
43
+
44
+ describe '#results' do
45
+ it 'paginates results' do
46
+ 6.times { |i| DProduct.create name: "product_#{i}" }
47
+ finder = finder_with_page 2, 2
48
+
49
+ expect(finder.results.map(&:name)).to eq %w[product_2 product_3]
50
+ end
51
+ end
52
+
53
+ describe '#count' do
54
+ it 'gives the real count' do
55
+ 10.times { |i| DProduct.create name: "product_#{i}" }
56
+ finder = finder_with_page 1
57
+ expect(finder.count).to eq 10
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,85 @@
1
+ require 'spec_helper_data_mapper'
2
+
3
+ module Trailblazer
4
+ class Finder
5
+ module Adapters
6
+ module DataMapper
7
+ describe Sorting do
8
+ def finder_class
9
+ Class.new do
10
+ include Trailblazer::Finder::Base
11
+ include Trailblazer::Finder::Features::Sorting
12
+ include Trailblazer::Finder::Adapters::DataMapper
13
+
14
+ entity_type { DProduct }
15
+
16
+ sortable_by :name, :price, :created_at
17
+
18
+ filter_by :name
19
+ filter_by :price
20
+
21
+ # # Need to find a fix for this, not sure how to handle joins with data mapper properly
22
+ # filter_by(:d_category) { |entity_type, _| entity_type }
23
+ end
24
+ end
25
+
26
+ def finder_with_sort(sort = nil, filters = {})
27
+ finder_class.new filter: { sort: sort }.merge(filters)
28
+ end
29
+
30
+ it 'can be inherited' do
31
+ child_class = Class.new(finder_class)
32
+ expect(child_class.new.sort_attribute).to eq 'name'
33
+ end
34
+
35
+ describe 'sorting' do
36
+ after do
37
+ DProduct.all.destroy
38
+ end
39
+
40
+ it 'sorts results based on the sort option desc' do
41
+ 5.times { |i| DProduct.create price: i }
42
+
43
+ finder = finder_with_sort 'price desc'
44
+ expect(finder.results.map(&:price)).to eq [4, 3, 2, 1, 0]
45
+ end
46
+
47
+ it 'sorts results based on the sort option asc' do
48
+ 5.times { |i| DProduct.create price: i }
49
+
50
+ finder = finder_with_sort 'price asc'
51
+ expect(finder.results.map(&:price)).to eq [0, 1, 2, 3, 4]
52
+ end
53
+
54
+ it 'defaults to first sort by option' do
55
+ 5.times { |i| DProduct.create name: "Name#{i}" }
56
+
57
+ finder = finder_with_sort
58
+ expect(finder.results.map(&:name)).to eq %w[Name4 Name3 Name2 Name1 Name0]
59
+ end
60
+
61
+ it 'ignores invalid sort values' do
62
+ finder = finder_with_sort 'invalid attribute'
63
+ expect { finder.results.to_a }.not_to raise_error
64
+ end
65
+
66
+ # TODO: Need to find a fix for this, not sure how to handle joins with data mapper properly
67
+ it 'can handle renames of sorting in joins' do
68
+ # older_category = DCategory.create title: 'older'
69
+ # newer_category = DCategory.create title: 'newer'
70
+ #
71
+ # product_of_newer_category = DProduct.create name: 'older product', d_category: newer_category
72
+ # product_of_older_category = DProduct.create name: 'newer product', d_category: older_category
73
+ #
74
+ # finder = finder_with_sort 'created_at desc', d_category: ''
75
+ #
76
+ # expect(finder.results.map(&:name)).to eq [product_of_older_category.name, product_of_newer_category.name]
77
+ end
78
+ end
79
+
80
+ it_behaves_like 'a sorting feature'
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper_active_record'
2
+
3
+ module Trailblazer
4
+ class Finder
5
+ module Adapters
6
+ describe FriendlyId do
7
+ after do
8
+ Product.delete_all
9
+ end
10
+
11
+ def finder_class
12
+ Class.new(Trailblazer::Finder) do
13
+ adapters ActiveRecord, FriendlyId
14
+
15
+ entity_type { Product }
16
+
17
+ filter_by :name
18
+ filter_by :price
19
+ end
20
+ end
21
+
22
+ def finder_with_slug(slug = nil, filters = {})
23
+ finder_class.new filter: { id: slug }.merge(filters)
24
+ end
25
+
26
+ it 'filters by slug' do
27
+ 2.times { |i| Product.create name: "Product #{i}", price: i, slug: "product_#{i}" }
28
+ finder = finder_with_slug 'product_1'
29
+ expect(finder.results.map(&:name)).to eq ['Product 1']
30
+ end
31
+
32
+ it 'filters by id' do
33
+ 2.times { |i| Product.create name: "Product #{i}", price: i, slug: "product_#{i}" }
34
+ finder = finder_with_slug Product.last.id
35
+ expect(finder.results.map(&:name)).to match_array([Product.last.name])
36
+ end
37
+
38
+ it 'returns no records when slug is not found' do
39
+ 2.times { |i| Product.create name: "Product #{i}", price: i, slug: "product_#{i}" }
40
+ finder = finder_with_slug 'unknown_1'
41
+ expect(finder.count).to eq 0
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper_active_record'
2
+ require 'kaminari'
3
+
4
+ module Trailblazer
5
+ class Finder
6
+ module Adapters
7
+ describe Kaminari do
8
+ it_behaves_like 'a paging feature'
9
+
10
+ after do
11
+ Product.delete_all
12
+ end
13
+
14
+ def define_finder_class(&block)
15
+ Class.new do
16
+ include Trailblazer::Finder::Base
17
+ include Trailblazer::Finder::Features::Paging
18
+ include Trailblazer::Finder::Adapters::ActiveRecord
19
+ include Trailblazer::Finder::Adapters::Kaminari
20
+
21
+ instance_eval(&block) if block_given?
22
+ end
23
+ end
24
+
25
+ def finder_class
26
+ define_finder_class do
27
+ entity_type { Product }
28
+
29
+ per_page 2
30
+
31
+ min_per_page 2
32
+ max_per_page 10
33
+ end
34
+ end
35
+
36
+ def finder_with_page(page = nil, per_page = nil)
37
+ finder_class.new page: page, per_page: per_page
38
+ end
39
+
40
+ it 'can be inherited' do
41
+ child_class = Class.new(finder_class)
42
+ expect(child_class.new.per_page).to eq 2
43
+ end
44
+
45
+ describe '#results' do
46
+ it 'paginates results' do
47
+ 6.times { |i| Product.create name: "product_#{i}" }
48
+ finder = finder_with_page 2, 2
49
+
50
+ expect(finder.results.map(&:name)).to eq %w[product_2 product_3]
51
+ end
52
+ end
53
+
54
+ describe '#count' do
55
+ it 'gives the real count' do
56
+ 10.times { |i| Product.create name: "product_#{i}" }
57
+ finder = finder_with_page 1
58
+ expect(finder.count).to eq 10
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end