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,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