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.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.rubocop.yml +45 -0
- data/.rubocop_todo.yml +52 -0
- data/.travis.yml +15 -0
- data/Gemfile +12 -0
- data/LICENSE.txt +23 -0
- data/README.md +494 -0
- data/Rakefile +29 -0
- data/lib/trailblazer/finder/adapters/active_record/paging.rb +20 -0
- data/lib/trailblazer/finder/adapters/active_record/sorting.rb +20 -0
- data/lib/trailblazer/finder/adapters/active_record.rb +30 -0
- data/lib/trailblazer/finder/adapters/data_mapper/paging.rb +20 -0
- data/lib/trailblazer/finder/adapters/data_mapper/sorting.rb +25 -0
- data/lib/trailblazer/finder/adapters/data_mapper.rb +30 -0
- data/lib/trailblazer/finder/adapters/friendly_id.rb +33 -0
- data/lib/trailblazer/finder/adapters/kaminari.rb +18 -0
- data/lib/trailblazer/finder/adapters/sequel/paging.rb +20 -0
- data/lib/trailblazer/finder/adapters/sequel/sorting.rb +25 -0
- data/lib/trailblazer/finder/adapters/sequel.rb +30 -0
- data/lib/trailblazer/finder/adapters/will_paginate.rb +18 -0
- data/lib/trailblazer/finder/adapters.rb +26 -0
- data/lib/trailblazer/finder/base.rb +98 -0
- data/lib/trailblazer/finder/errors/block_ignored.rb +11 -0
- data/lib/trailblazer/finder/errors/invalid_defined_by_value.rb +11 -0
- data/lib/trailblazer/finder/errors/invalid_number.rb +16 -0
- data/lib/trailblazer/finder/errors/missing_entity_type.rb +11 -0
- data/lib/trailblazer/finder/errors/with_ignored.rb +11 -0
- data/lib/trailblazer/finder/features/paging.rb +55 -0
- data/lib/trailblazer/finder/features/sorting.rb +66 -0
- data/lib/trailblazer/finder/features.rb +22 -0
- data/lib/trailblazer/finder/filter.rb +66 -0
- data/lib/trailblazer/finder/find.rb +29 -0
- data/lib/trailblazer/finder/utils/extra.rb +31 -0
- data/lib/trailblazer/finder/utils/params.rb +28 -0
- data/lib/trailblazer/finder/utils/parse.rb +25 -0
- data/lib/trailblazer/finder/utils/string.rb +35 -0
- data/lib/trailblazer/finder/version.rb +5 -0
- data/lib/trailblazer/finder.rb +29 -0
- data/lib/trailblazer/operation/finder.rb +61 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/spec_helper_active_record.rb +50 -0
- data/spec/spec_helper_data_mapper.rb +35 -0
- data/spec/spec_helper_sequel.rb +32 -0
- data/spec/support/paging_shared_example.rb +65 -0
- data/spec/support/sorting_shared_example.rb +95 -0
- data/spec/trailblazer/finder/adapters/active_record/base_spec.rb +112 -0
- data/spec/trailblazer/finder/adapters/active_record/paging_spec.rb +64 -0
- data/spec/trailblazer/finder/adapters/active_record/sorting_spec.rb +82 -0
- data/spec/trailblazer/finder/adapters/data_mapper/base_spec.rb +112 -0
- data/spec/trailblazer/finder/adapters/data_mapper/paging_spec.rb +64 -0
- data/spec/trailblazer/finder/adapters/data_mapper/sorting_spec.rb +85 -0
- data/spec/trailblazer/finder/adapters/friendly_id_spec.rb +46 -0
- data/spec/trailblazer/finder/adapters/kaminari_spec.rb +64 -0
- data/spec/trailblazer/finder/adapters/sequel/base_spec.rb +112 -0
- data/spec/trailblazer/finder/adapters/sequel/paging_spec.rb +64 -0
- data/spec/trailblazer/finder/adapters/sequel/sorting_spec.rb +82 -0
- data/spec/trailblazer/finder/adapters/will_paginate_spec.rb +71 -0
- data/spec/trailblazer/finder/adapters_spec.rb +110 -0
- data/spec/trailblazer/finder/base_spec.rb +329 -0
- data/spec/trailblazer/finder/features/paging_spec.rb +104 -0
- data/spec/trailblazer/finder/features/sorting_spec.rb +100 -0
- data/spec/trailblazer/finder/features_spec.rb +55 -0
- data/spec/trailblazer/finder/filter_spec.rb +133 -0
- data/spec/trailblazer/finder/find_spec.rb +72 -0
- data/spec/trailblazer/finder/utils/extra_spec.rb +41 -0
- data/spec/trailblazer/finder/utils/params_spec.rb +39 -0
- data/spec/trailblazer/finder/utils/parse_spec.rb +33 -0
- data/spec/trailblazer/finder/utils/string_spec.rb +25 -0
- data/spec/trailblazer/operation/finder_spec.rb +103 -0
- data/spec/trailblazer/operation/paging_spec.rb +68 -0
- data/spec/trailblazer/operation/sorting_spec.rb +80 -0
- data/trailblazer-finder.gemspec +41 -0
- 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
|