trailblazer-finder 0.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.
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,133 @@
1
+ require 'spec_helper'
2
+ require 'ostruct'
3
+
4
+ module Trailblazer
5
+ class Finder
6
+ describe Filter do
7
+ class TestFind
8
+ include Trailblazer::Finder::Base
9
+ include Trailblazer::Finder::Filter
10
+
11
+ entity_type { [1, 2, 3, 4, 5] }
12
+
13
+ filter_by :filter, defined_by: %w[odd even]
14
+
15
+ private
16
+
17
+ def apply_filter_with_odd(entity_type)
18
+ entity_type.select(&:odd?)
19
+ end
20
+
21
+ def apply_filter_with_even(entity_type)
22
+ entity_type.select(&:even?)
23
+ end
24
+
25
+ def handle_invalid_filter(_entity_type, value)
26
+ "invalid filter - #{value}"
27
+ end
28
+ end
29
+
30
+ it 'can filter by defined values' do
31
+ expect(TestFind.results(filter: { filter: 'odd' })).to eq [1, 3, 5]
32
+ expect(TestFind.results(filter: { filter: 'even' })).to eq [2, 4]
33
+ end
34
+
35
+ it 'ignores blank values' do
36
+ expect(TestFind.results(filter: { filter: nil })).to eq [1, 2, 3, 4, 5]
37
+ expect(TestFind.results(filter: { filter: '' })).to eq [1, 2, 3, 4, 5]
38
+ end
39
+
40
+ it 'handles wrongly defined values' do
41
+ expect(TestFind.results(filter: { filter: 'foo' })).to eq 'invalid filter - foo'
42
+ end
43
+
44
+ it 'raises when block is passed with defined filter' do
45
+ expect do
46
+ Class.new do
47
+ include Trailblazer::Finder::Base
48
+ include Trailblazer::Finder::Filter
49
+
50
+ filter_by(:filter, defined_by: %w[a b]) { |_entity_type, _value| nil }
51
+ end
52
+ end.to raise_error Trailblazer::Finder::Error::BlockIgnored
53
+ end
54
+
55
+ it 'raises when :with is passed with defined filter_by' do
56
+ expect do
57
+ Class.new do
58
+ include Trailblazer::Finder::Base
59
+ include Trailblazer::Finder::Filter
60
+
61
+ filter_by :filter, defined_by: %w[a b], with: :method_name
62
+ end
63
+ end.to raise_error Trailblazer::Finder::Error::WithIgnored
64
+ end
65
+ end
66
+
67
+ describe Filter::Handler do
68
+ describe 'apply_filter' do
69
+ def new_object(&block)
70
+ klass = Class.new(&block)
71
+ klass.new
72
+ end
73
+
74
+ def call(object: nil, filter_by: nil, defined_bys: nil, entity_type: nil, value:)
75
+ described_class.apply_filter(
76
+ object: object || new_object,
77
+ filter_by: filter_by || 'filter_by',
78
+ defined_bys: defined_bys || [value],
79
+ entity_type: entity_type || [],
80
+ value: value
81
+ )
82
+ end
83
+
84
+ it 'filters by methods based on the defined value' do
85
+ object = new_object do
86
+ private
87
+
88
+ def apply_select_with_name(entity_type)
89
+ entity_type.select { |value| value == 'name' }
90
+ end
91
+
92
+ def apply_select_with_age(entity_type)
93
+ entity_type.select { |value| value == 'age' }
94
+ end
95
+ end
96
+
97
+ entity_type = %w[name age location]
98
+
99
+ expect(call(object: object, filter_by: 'select', entity_type: entity_type, value: 'name')).to eq %w[name]
100
+ expect(call(object: object, filter_by: 'select', entity_type: entity_type, value: 'age')).to eq %w[age]
101
+ end
102
+
103
+ it 'raises NoMethodError when object can not handle defined method' do
104
+ expect { call(defined_bys: ['a'], value: 'a') }.to raise_error NoMethodError
105
+ end
106
+
107
+ it 'raises error when value is not defined' do
108
+ expect { call(defined_bys: [], value: 'invalid') }.to raise_error Trailblazer::Finder::Error::InvalidDefinedByValue
109
+ end
110
+
111
+ it 'can delegate missing defined value to object' do
112
+ object = new_object do
113
+ def handle_invalid_filter_by(_entity_type, value)
114
+ "handles #{value} value"
115
+ end
116
+ end
117
+
118
+ expect(call(object: object, defined_bys: [], value: 'invalid')).to eq 'handles invalid value'
119
+ end
120
+
121
+ it 'can delegate missing defined value to object (cath all)' do
122
+ object = new_object do
123
+ def handle_invalid_defined_by(filter_by, _entity_type, value)
124
+ "handles #{value} value for #{filter_by}"
125
+ end
126
+ end
127
+
128
+ expect(call(object: object, defined_bys: [], value: 'invalid')).to eq 'handles invalid value for filter_by'
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+ require 'ostruct'
3
+
4
+ module Trailblazer
5
+ describe Finder::Find do
6
+ describe '.params' do
7
+ it 'returns the passed params' do
8
+ finder = Finder::Find.new('entity_type', 'params', {})
9
+ expect(finder.params).to eq 'params'
10
+ end
11
+ end
12
+
13
+ describe '.param' do
14
+ it 'returns the param value' do
15
+ finder = Finder::Find.new('entity_type', { name: 'value' }, {})
16
+ expect(finder.param(:name)).to eq 'value'
17
+ end
18
+ end
19
+
20
+ describe '.query' do
21
+ it 'returns filtered result' do
22
+ actions = {
23
+ min: ->(entity_type, min) { entity_type.select { |v| v > min } }
24
+ }
25
+
26
+ finder = Finder::Find.new [1, 2, 3], { min: 2 }, actions
27
+ expect(finder.query(Object.new)).to eq [3]
28
+ end
29
+
30
+ it 'applies actions to params' do
31
+ actions = {
32
+ min: ->(entity_type, min) { entity_type.select { |v| v > min } },
33
+ max: ->(entity_type, max) { entity_type.select { |v| v < max } }
34
+ }
35
+
36
+ finder = Finder::Find.new [1, 2, 3, 4, 5], { min: 2, max: 5 }, actions
37
+ expect(finder.query(Object.new)).to eq [3, 4]
38
+ end
39
+
40
+ it 'handles nil returned from action' do
41
+ actions = {
42
+ odd: ->(entity_type, odd) { entity_type.select(&:odd?) if odd }
43
+ }
44
+
45
+ finder = Finder::Find.new [1, 2, 3, 4, 5], { odd: false }, actions
46
+ expect(finder.query(Object.new)).to eq [1, 2, 3, 4, 5]
47
+ end
48
+
49
+ it 'executes action in the passed context' do
50
+ actions = {
51
+ finder: ->(entity_type, _) { entity_type.select { |v| v == target_value } }
52
+ }
53
+
54
+ context = OpenStruct.new target_value: 2
55
+
56
+ finder = Finder::Find.new [1, 2, 3, 4, 5], { finder: true }, actions
57
+ expect(finder.query(context)).to eq [2]
58
+ end
59
+ end
60
+
61
+ describe '.count' do
62
+ it 'counts the results of the query' do
63
+ actions = {
64
+ value: ->(entity_type, value) { entity_type.select { |v| v == value } }
65
+ }
66
+
67
+ finder = Finder::Find.new [1, 2, 3], { value: 2 }, actions
68
+ expect(finder.count(Object.new)).to eq 1
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ module Trailblazer
4
+ class Finder
5
+ module Utils
6
+ describe Extra do
7
+ describe '.deep_copy' do
8
+ it 'returns a deep copy on the given object' do
9
+ original = {
10
+ array: [1, 2, 3],
11
+ hash: { key: 'value' },
12
+ boolean: true,
13
+ number: 1,
14
+ null: nil
15
+ }
16
+
17
+ deep_copy = Finder::Utils::Extra.deep_copy(original)
18
+
19
+ original[:array][0] = 42
20
+ original[:hash][:key] = 'other value'
21
+
22
+ expect(deep_copy).to eq(
23
+ array: [1, 2, 3],
24
+ hash: { key: 'value' },
25
+ boolean: true,
26
+ number: 1,
27
+ null: nil
28
+ )
29
+ end
30
+ end
31
+
32
+ describe '.ensure_included' do
33
+ it 'works' do
34
+ str = Utils::Extra.ensure_included '1 2'.to_s.split(' ', 2).last, %w[1]
35
+ expect(str).to eq('1')
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ module Trailblazer
4
+ class Finder
5
+ module Utils
6
+ describe Params do
7
+ describe '.slice_keys' do
8
+ it 'selects only given keys' do
9
+ hash = Finder::Utils::Params.slice_keys({ a: 1, b: 2, c: 3 }, %i[a b])
10
+ expect(hash).to eq a: 1, b: 2
11
+ end
12
+
13
+ it 'ignores not existing keys' do
14
+ hash = Finder::Utils::Params.slice_keys({}, %i[a b])
15
+ expect(hash).to eq({})
16
+ end
17
+ end
18
+
19
+ describe '.normalize_params' do
20
+ it 'combines defaults and filters' do
21
+ expect(Finder::Utils::Params.normalize_params({ 'a' => 1, 'b' => 2 }, { a: 2 }, %w[a b])).to eq 'a' => 2, 'b' => 2
22
+ end
23
+
24
+ it 'excludes non specified keys' do
25
+ expect(Finder::Utils::Params.normalize_params({ 'a' => 1 }, { b: 2 }, %w[a])).to eq 'a' => 1
26
+ end
27
+
28
+ it 'handles missing defaults' do
29
+ expect(Finder::Utils::Params.normalize_params(nil, { a: 1 }, %w[a])).to eq 'a' => 1
30
+ end
31
+
32
+ it 'handles missing filters' do
33
+ expect(Finder::Utils::Params.normalize_params(nil, nil, ['a'])).to eq({})
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ module Trailblazer
4
+ class Finder
5
+ module Utils
6
+ describe Parse do
7
+ describe '.parse_date' do
8
+ it 'returns when value is a date' do
9
+ expect(Finder::Utils::Parse.date('2018-01-01')).to eq '2018-01-01'
10
+ end
11
+
12
+ it 'returns when value is a screwed up date like 02-2018-01 10:10:10' do
13
+ expect(Finder::Utils::Parse.date('02-2018-01 10:10')).to eq '2018-01-02'
14
+ end
15
+
16
+ it 'returns nil value is not date worthy' do
17
+ expect(Finder::Utils::Parse.date('Unknown')).to eq nil
18
+ end
19
+ end
20
+
21
+ describe '.escape_term' do
22
+ it 'returns escaped value' do
23
+ expect(Finder::Utils::Parse.term('term')).to eq '%term%'
24
+ end
25
+
26
+ it 'returns mutliple escaped values' do
27
+ expect(Finder::Utils::Parse.term('term term')).to eq '%term%term%'
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ module Trailblazer
4
+ class Finder
5
+ module Utils
6
+ describe String do
7
+ describe '.camelize' do
8
+ it "transforms :paging to 'Paging'" do
9
+ expect(Finder::Utils::String.camelize(:paging)).to eq 'Paging'
10
+ end
11
+ end
12
+
13
+ describe '.underscore' do
14
+ it "transforms 'veryPopular' to 'very_popular'" do
15
+ expect(Finder::Utils::String.underscore(:veryPopular)).to eq 'very_popular'
16
+ end
17
+
18
+ it "transforms 'Very Popular' to 'very_popular'" do
19
+ expect(Finder::Utils::String.underscore('Very Popular')).to eq 'very_popular'
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,103 @@
1
+ require 'delegate'
2
+ require 'trailblazer'
3
+ require 'spec_helper_active_record'
4
+
5
+ class Product::FinderNoEntity < Trailblazer::Finder
6
+ adapters ActiveRecord
7
+
8
+ filter_by :id
9
+ filter_by :name
10
+ filter_by :escaped_name, with: :apply_escaped_name
11
+
12
+ def apply_escaped_name(entity_type, value)
13
+ return unless value.present?
14
+ entity_type.where 'lower(name) LIKE ?', Utils::Parse.term(value.downcase)
15
+ end
16
+ end
17
+
18
+ class Product::FinderWithEntity < Trailblazer::Finder
19
+ adapters ActiveRecord
20
+
21
+ entity_type { Product }
22
+
23
+ filter_by :id
24
+ filter_by :name
25
+ filter_by :escaped_name, with: :apply_escaped_name
26
+
27
+ def apply_escaped_name(entity_type, value)
28
+ return unless value.present?
29
+ entity_type.where 'lower(name) LIKE ?', Utils::Parse.term(value.downcase)
30
+ end
31
+ end
32
+
33
+ class Product::Index < Trailblazer::Operation
34
+ step Finder(Product::FinderNoEntity, :all, Product)
35
+ end
36
+
37
+ class Product::Show < Trailblazer::Operation
38
+ step Finder(Product::FinderNoEntity, :single, Product)
39
+ end
40
+
41
+ class Product::IndexNoEntity < Trailblazer::Operation
42
+ step Finder(Product::FinderWithEntity, :all)
43
+ end
44
+
45
+ class Product::ShowNoEntity < Trailblazer::Operation
46
+ step Finder(Product::FinderWithEntity, :single)
47
+ end
48
+
49
+
50
+ describe 'Trailblazer::Operation - Finder Macro' do
51
+ before do
52
+ Product.destroy_all
53
+ Product.reset_pk_sequence
54
+ 20.times { |i| Product.create name: "product_#{i}" }
55
+ end
56
+
57
+ after do
58
+ Product.destroy_all
59
+ Product.reset_pk_sequence
60
+ end
61
+
62
+ it 'Can find a single row by id' do
63
+ params = { id: 5 }
64
+ result = Product::Show.call(params: params)
65
+
66
+ expect(result[:finder].name).to eq 'product_4'
67
+ end
68
+
69
+ it 'Can find a single row by name' do
70
+ params = { f: { name: 'product_2' } }
71
+ result = Product::Show.call(params: params)
72
+
73
+ expect(result[:finder].name).to eq 'product_2'
74
+ end
75
+
76
+ it 'Can find multiple rows by escaped name' do
77
+ params = { f: { escaped_name: 'product_1' } }
78
+ result = Product::Index.call(params: params)
79
+
80
+ expect(result[:finder].results.last.name).to eq 'product_19'
81
+ end
82
+
83
+ it 'Can find a single row by id when no entity type is given in macro' do
84
+ params = { id: 8 }
85
+ result = Product::ShowNoEntity.call(params: params)
86
+
87
+ expect(result[:finder].name).to eq 'product_7'
88
+ end
89
+
90
+ it 'Can find a single row by name when no entity type is given in macro' do
91
+ params = { f: { name: 'product_2' } }
92
+ result = Product::ShowNoEntity.call(params: params)
93
+
94
+ expect(result[:finder].name).to eq 'product_2'
95
+ end
96
+
97
+ it 'Can find multiple rows by escaped name when no entity type is given in macro' do
98
+ params = { f: { escaped_name: 'product_1' } }
99
+ result = Product::IndexNoEntity.call(params: params)
100
+
101
+ expect(result[:finder].results.last.name).to eq 'product_19'
102
+ end
103
+ end
@@ -0,0 +1,68 @@
1
+ require 'delegate'
2
+ require 'trailblazer'
3
+ require 'spec_helper_active_record'
4
+
5
+ class Product::PagingFinderNoEntity < Trailblazer::Finder
6
+ features Paging
7
+
8
+ adapters ActiveRecord
9
+
10
+ per_page 2
11
+ min_per_page 2
12
+ max_per_page 10
13
+
14
+ filter_by :id
15
+ filter_by :name
16
+ end
17
+
18
+ class Product::PagingFinderWithEntity < Trailblazer::Finder
19
+ features Paging
20
+
21
+ adapters ActiveRecord
22
+
23
+ entity_type { Product }
24
+
25
+ per_page 2
26
+ min_per_page 2
27
+ max_per_page 10
28
+
29
+ filter_by :id
30
+ filter_by :name
31
+ end
32
+
33
+ class Product::PagingIndex < Trailblazer::Operation
34
+ step Finder(Product::PagingFinderNoEntity, :all, Product)
35
+ end
36
+
37
+ class Product::PagingIndexNoEntity < Trailblazer::Operation
38
+ step Finder(Product::PagingFinderWithEntity, :all)
39
+ end
40
+
41
+ describe 'Trailblazer::Operation - Finder Macro - Paging' do
42
+ before do
43
+ Product.destroy_all
44
+ Product.reset_pk_sequence
45
+ 20.times { |i| Product.create name: "product_#{i}" }
46
+ end
47
+
48
+ after do
49
+ Product.destroy_all
50
+ Product.reset_pk_sequence
51
+ end
52
+
53
+ it 'Can paginate results' do
54
+ params = { page: 2 }
55
+ result = Product::PagingIndex.call(params: params)
56
+
57
+ expect(result[:finder].count).to eq 20
58
+ expect(result[:finder].results).to eq Product.limit(2).offset(2)
59
+ end
60
+
61
+ it 'Can paginate results when no entity type is given in macro' do
62
+ params = { page: 2 }
63
+ result = Product::PagingIndexNoEntity.call(params: params)
64
+
65
+ expect(result[:finder].count).to eq 20
66
+ expect(result[:finder].results).to eq Product.limit(2).offset(2)
67
+ end
68
+ end
@@ -0,0 +1,80 @@
1
+ require 'delegate'
2
+ require 'trailblazer'
3
+ require 'spec_helper_active_record'
4
+
5
+ class Product::SortFinderNoEntity < Trailblazer::Finder
6
+ features Sorting
7
+
8
+ adapters ActiveRecord
9
+
10
+ sortable_by :id, :name
11
+
12
+ filter_by :id
13
+ filter_by :name
14
+ end
15
+
16
+ class Product::SortFinderWithEntity < Trailblazer::Finder
17
+ features Sorting
18
+
19
+ adapters ActiveRecord
20
+
21
+ entity_type { Product }
22
+
23
+ sortable_by :id, :name
24
+
25
+ filter_by :id
26
+ filter_by :name
27
+ end
28
+
29
+ class Product::SortIndex < Trailblazer::Operation
30
+ step Finder(Product::SortFinderNoEntity, :all, Product)
31
+ end
32
+
33
+ class Product::SortIndexNoEntity < Trailblazer::Operation
34
+ step Finder(Product::SortFinderWithEntity, :all)
35
+ end
36
+
37
+ describe 'Trailblazer::Operation - Finder Macro - Sorting' do
38
+ before do
39
+ Product.destroy_all
40
+ Product.reset_pk_sequence
41
+ 20.times { |i| Product.create name: "product_#{i}" }
42
+ end
43
+
44
+ after do
45
+ Product.destroy_all
46
+ Product.reset_pk_sequence
47
+ end
48
+
49
+ it 'Can sort results by name descending' do
50
+ params = { f: { sort: 'name desc' } }
51
+ result = Product::SortIndex.call(params: params)
52
+
53
+ expect(result[:finder].count).to eq 20
54
+ expect(result[:finder].results.last.name).to eq 'product_0'
55
+ end
56
+
57
+ it 'Can sort results by name descending when no entity type is given in macro' do
58
+ params = { f: { sort: 'name desc' } }
59
+ result = Product::SortIndexNoEntity.call(params: params)
60
+
61
+ expect(result[:finder].count).to eq 20
62
+ expect(result[:finder].results.last.name).to eq 'product_0'
63
+ end
64
+
65
+ it 'Can sort results by id ascending' do
66
+ params = { f: { sort: 'id asc' } }
67
+ result = Product::SortIndex.call(params: params)
68
+
69
+ expect(result[:finder].count).to eq 20
70
+ expect(result[:finder].results.last.name).to eq 'product_19'
71
+ end
72
+
73
+ it 'Can sort results by id ascending when no entity type is given in macro' do
74
+ params = { f: { sort: 'id asc' } }
75
+ result = Product::SortIndexNoEntity.call(params: params)
76
+
77
+ expect(result[:finder].count).to eq 20
78
+ expect(result[:finder].results.last.name).to eq 'product_19'
79
+ end
80
+ end
@@ -0,0 +1,41 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'trailblazer/finder/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'trailblazer-finder'
7
+ spec.version = Trailblazer::Finder::VERSION
8
+ spec.date = '2018-03-11'
9
+ spec.description = %q{Trailblazer Finder object DSL}
10
+ spec.summary = %q{Provides DSL for creating trailblazer based finder objects}
11
+ spec.authors = ["Nick Sutterer", "Marc Tich"]
12
+ spec.email = ["apotonick@gmail.com", "marc@mudsu.com"]
13
+ spec.homepage = 'http://trailblazer.to'
14
+ spec.license = 'MIT'
15
+ spec.files = `git ls-files`.split($/)
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.add_dependency 'hashie', '~> 3.5'
21
+
22
+ spec.add_development_dependency 'bundler'
23
+ spec.add_development_dependency 'rake'
24
+ spec.add_development_dependency 'sequel'
25
+ spec.add_development_dependency 'activerecord'
26
+ spec.add_development_dependency 'sqlite3'
27
+ spec.add_development_dependency 'will_paginate'
28
+ spec.add_development_dependency 'kaminari'
29
+ spec.add_development_dependency 'kaminari-activerecord'
30
+ spec.add_development_dependency 'rspec', '~> 3.5'
31
+ spec.add_development_dependency 'rspec-mocks', '~> 3.5'
32
+ spec.add_development_dependency 'rubocop'
33
+ spec.add_development_dependency 'rubocop-rspec'
34
+ spec.add_development_dependency 'data_mapper'
35
+ spec.add_development_dependency 'dm-sqlite-adapter'
36
+ spec.add_development_dependency 'simplecov'
37
+ spec.add_development_dependency 'trailblazer', '>= 2.1.0.beta4'
38
+ spec.add_development_dependency 'rspec_junit_formatter'
39
+
40
+ spec.required_ruby_version = '>= 2.1.0'
41
+ end