pursuit 0.4.3 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/rubygem.yaml +46 -0
- data/.ruby-version +1 -1
- data/Gemfile +15 -0
- data/Gemfile.lock +127 -86
- data/LICENSE +174 -21
- data/README.md +210 -27
- data/bin/console +10 -0
- data/config.ru +2 -3
- data/lib/pursuit/aggregate_modifier_not_found.rb +20 -0
- data/lib/pursuit/aggregate_modifier_required.rb +20 -0
- data/lib/pursuit/aggregate_modifiers_not_available.rb +13 -0
- data/lib/pursuit/attribute_not_found.rb +20 -0
- data/lib/pursuit/constants.rb +1 -1
- data/lib/pursuit/error.rb +7 -0
- data/lib/pursuit/predicate_parser.rb +181 -0
- data/lib/pursuit/predicate_search.rb +83 -0
- data/lib/pursuit/predicate_transform.rb +231 -0
- data/lib/pursuit/query_error.rb +7 -0
- data/lib/pursuit/simple_search.rb +64 -0
- data/lib/pursuit/term_parser.rb +44 -0
- data/lib/pursuit/term_search.rb +69 -0
- data/lib/pursuit/term_transform.rb +35 -0
- data/lib/pursuit.rb +19 -5
- data/pursuit.gemspec +5 -18
- data/spec/internal/app/models/application_record.rb +5 -0
- data/spec/internal/app/models/product.rb +25 -9
- data/spec/internal/app/models/product_category.rb +23 -1
- data/spec/internal/app/models/product_variation.rb +26 -1
- data/spec/lib/pursuit/predicate_parser_spec.rb +1604 -0
- data/spec/lib/pursuit/predicate_search_spec.rb +80 -0
- data/spec/lib/pursuit/predicate_transform_spec.rb +624 -0
- data/spec/lib/pursuit/simple_search_spec.rb +59 -0
- data/spec/lib/pursuit/term_parser_spec.rb +271 -0
- data/spec/lib/pursuit/term_search_spec.rb +71 -0
- data/spec/lib/pursuit/term_transform_spec.rb +105 -0
- data/spec/spec_helper.rb +2 -3
- data/travis/gemfiles/{5.2.gemfile → 7.1.gemfile} +2 -2
- metadata +38 -197
- data/.travis.yml +0 -25
- data/lib/pursuit/dsl.rb +0 -28
- data/lib/pursuit/railtie.rb +0 -13
- data/lib/pursuit/search.rb +0 -172
- data/lib/pursuit/search_options.rb +0 -86
- data/lib/pursuit/search_term_parser.rb +0 -46
- data/spec/lib/pursuit/dsl_spec.rb +0 -22
- data/spec/lib/pursuit/search_options_spec.rb +0 -146
- data/spec/lib/pursuit/search_spec.rb +0 -516
- data/spec/lib/pursuit/search_term_parser_spec.rb +0 -34
- data/travis/gemfiles/6.0.gemfile +0 -8
- data/travis/gemfiles/6.1.gemfile +0 -8
- data/travis/gemfiles/7.0.gemfile +0 -8
@@ -1,22 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
RSpec.describe Pursuit::DSL do
|
4
|
-
subject(:record) { Product.new }
|
5
|
-
|
6
|
-
describe '.search_options' do
|
7
|
-
subject(:search_options) { record.class.search_options }
|
8
|
-
|
9
|
-
it { is_expected.to be_a(Pursuit::SearchOptions) }
|
10
|
-
end
|
11
|
-
|
12
|
-
describe '.search' do
|
13
|
-
subject(:search) { record.class.search('funky') }
|
14
|
-
|
15
|
-
let(:product_a) { Product.create!(title: 'Plain Shirt') }
|
16
|
-
let(:product_b) { Product.create!(title: 'Funky Shirt') }
|
17
|
-
|
18
|
-
it 'is expected to return the matching records' do
|
19
|
-
expect(search).to contain_exactly(product_b)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,146 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
RSpec.describe Pursuit::SearchOptions do
|
4
|
-
subject(:search_options) { described_class.new(Product) }
|
5
|
-
|
6
|
-
let(:title_length_node_builder) do
|
7
|
-
proc do
|
8
|
-
Arel::Nodes::NamedFunction.new('LENGTH', [Product.arel_table[:title]])
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
describe '#record_class' do
|
13
|
-
subject(:record_class) { search_options.record_class }
|
14
|
-
|
15
|
-
it 'is expected to eq the class passed during initialization' do
|
16
|
-
expect(record_class).to eq(Product)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
describe '#relations' do
|
21
|
-
subject(:relations) { search_options.relations }
|
22
|
-
|
23
|
-
before do
|
24
|
-
search_options.relation :variations, :title, :stock_status
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'is expected to contain the correct relations' do
|
28
|
-
expect(relations).to eq(variations: %i[title stock_status])
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
describe '#keyed_attributes' do
|
33
|
-
subject(:keyed_attributes) { search_options.keyed_attributes }
|
34
|
-
|
35
|
-
before do
|
36
|
-
search_options.attribute :title, keyed: false
|
37
|
-
search_options.attribute :title_length, &title_length_node_builder
|
38
|
-
search_options.attribute :description
|
39
|
-
search_options.attribute :rating, unkeyed: false
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'is expected to contain the correct keyed attributes' do
|
43
|
-
expect(keyed_attributes.keys).to contain_exactly(:title_length, :description, :rating)
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'is expected to set a default node builder for attributes declared without a block' do
|
47
|
-
expect(keyed_attributes[:description].call).to eq(Product.arel_table[:description])
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'is expected to set a custom node builder for attributes declared with a block' do
|
51
|
-
expect(keyed_attributes[:title_length]).to eq(title_length_node_builder)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
describe '#unkeyed_attributes' do
|
56
|
-
subject(:unkeyed_attributes) { search_options.unkeyed_attributes }
|
57
|
-
|
58
|
-
before do
|
59
|
-
search_options.attribute :title, keyed: false
|
60
|
-
search_options.attribute :title_length, &title_length_node_builder
|
61
|
-
search_options.attribute :description
|
62
|
-
search_options.attribute :rating, unkeyed: false
|
63
|
-
end
|
64
|
-
|
65
|
-
it 'is expected to contain the correct unkeyed attributes' do
|
66
|
-
expect(unkeyed_attributes.keys).to contain_exactly(:title, :title_length, :description)
|
67
|
-
end
|
68
|
-
|
69
|
-
it 'is expected to set a default node builder for attributes declared without a block' do
|
70
|
-
expect(unkeyed_attributes[:title].call).to eq(Product.arel_table[:title])
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'is expected to set a custom node builder for attributes declared with a block' do
|
74
|
-
expect(unkeyed_attributes[:title_length]).to eq(title_length_node_builder)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
describe '#relation' do
|
79
|
-
subject(:relation) { search_options.relation(:variations, :title, :stock_status) }
|
80
|
-
|
81
|
-
it 'is expected to add the relation to #relations' do
|
82
|
-
expect { relation }.to change(search_options, :relations).from({}).to(variations: %i[title stock_status])
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
describe '#attribute' do
|
87
|
-
subject(:attribute) { search_options.attribute(:description) }
|
88
|
-
|
89
|
-
it { is_expected.to be_nil }
|
90
|
-
|
91
|
-
it 'is expected to add the attribute to #attributes' do
|
92
|
-
expect { attribute }.to change(search_options.attributes, :keys).from([]).to(%i[description])
|
93
|
-
end
|
94
|
-
|
95
|
-
it 'is expected to allow keyed searching by default' do
|
96
|
-
attribute
|
97
|
-
expect(search_options.attributes[:description].keyed).to be(true)
|
98
|
-
end
|
99
|
-
|
100
|
-
it 'is expected to allow unkeyed searching by default' do
|
101
|
-
attribute
|
102
|
-
expect(search_options.attributes[:description].unkeyed).to be(true)
|
103
|
-
end
|
104
|
-
|
105
|
-
it 'is expected to query the #term_name attribute' do
|
106
|
-
attribute
|
107
|
-
expect(search_options.attributes[:description].block.call).to eq(Product.arel_table[:description])
|
108
|
-
end
|
109
|
-
|
110
|
-
context 'when passing the attribute name to search' do
|
111
|
-
subject(:attribute) { search_options.attribute(:desc, :description) }
|
112
|
-
|
113
|
-
it 'is expected to query the #attribute_name attribute' do
|
114
|
-
attribute
|
115
|
-
expect(search_options.attributes[:desc].block.call).to eq(Product.arel_table[:description])
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
context 'when passing :keyed eq false' do
|
120
|
-
subject(:attribute) { search_options.attribute(:description, keyed: false) }
|
121
|
-
|
122
|
-
it 'is expected to disallow keyed searching' do
|
123
|
-
attribute
|
124
|
-
expect(search_options.attributes[:description].keyed).to be(false)
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
context 'when passing :unkeyed eq false' do
|
129
|
-
subject(:attribute) { search_options.attribute(:description, unkeyed: false) }
|
130
|
-
|
131
|
-
it 'is expected to disallow unkeyed searching' do
|
132
|
-
attribute
|
133
|
-
expect(search_options.attributes[:description].unkeyed).to be(false)
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
context 'when passing a block' do
|
138
|
-
subject(:attribute) { search_options.attribute(:description, &title_length_node_builder) }
|
139
|
-
|
140
|
-
it 'is expected to query the result of the passed block' do
|
141
|
-
attribute
|
142
|
-
expect(search_options.attributes[:description].block).to eq(title_length_node_builder)
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|
@@ -1,516 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
RSpec.describe Pursuit::Search do
|
4
|
-
subject(:search) { described_class.new(search_options) }
|
5
|
-
|
6
|
-
let(:search_options) do
|
7
|
-
Pursuit::SearchOptions.new(Product) do |o|
|
8
|
-
o.relation :category, :name
|
9
|
-
o.relation :variations, :title, :stock_status
|
10
|
-
|
11
|
-
o.attribute :title
|
12
|
-
o.attribute :description
|
13
|
-
o.attribute :rating, unkeyed: false
|
14
|
-
o.attribute :title_length, unkeyed: false do
|
15
|
-
Arel::Nodes::NamedFunction.new('LENGTH', [Product.arel_table[:title]])
|
16
|
-
end
|
17
|
-
|
18
|
-
o.attribute :cat, :category_id
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
describe '#perform' do
|
23
|
-
subject(:perform) { search.perform(query) }
|
24
|
-
|
25
|
-
context 'when passed a blank query' do
|
26
|
-
let(:query) { '' }
|
27
|
-
|
28
|
-
let(:product_a) { Product.create!(title: 'Alpha') }
|
29
|
-
let(:product_b) { Product.create!(title: 'Beta') }
|
30
|
-
|
31
|
-
before do
|
32
|
-
product_a
|
33
|
-
product_b
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'is expected to contain all records' do
|
37
|
-
expect(perform).to contain_exactly(product_a, product_b)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
context 'when passed an unkeyed query' do
|
42
|
-
let(:query) { 'shirt' }
|
43
|
-
|
44
|
-
let(:product_a) { Product.create!(title: 'Plain Shirt') }
|
45
|
-
let(:product_b) { Product.create!(title: 'Funky Shirt') }
|
46
|
-
let(:product_c) { Product.create!(title: 'Socks') }
|
47
|
-
|
48
|
-
before do
|
49
|
-
product_a
|
50
|
-
product_b
|
51
|
-
product_c
|
52
|
-
end
|
53
|
-
|
54
|
-
it 'is expected to contain the matching records' do
|
55
|
-
expect(perform).to contain_exactly(product_a, product_b)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
context 'when passed an `equal to` keyed attribute query' do
|
60
|
-
let(:query) { 'title=="Funky Shirt"' }
|
61
|
-
|
62
|
-
let(:product_a) { Product.create!(title: 'Plain Shirt', rating: 2) }
|
63
|
-
let(:product_b) { Product.create!(title: 'Funky Shirt', rating: 4) }
|
64
|
-
let(:product_c) { Product.create!(title: 'Socks - Pack of 4') }
|
65
|
-
|
66
|
-
before do
|
67
|
-
product_a
|
68
|
-
product_b
|
69
|
-
product_c
|
70
|
-
end
|
71
|
-
|
72
|
-
it 'is expected to contain the matching records' do
|
73
|
-
expect(perform).to contain_exactly(product_b)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
context 'when passed a `not equal to` keyed attribute query' do
|
78
|
-
let(:query) { 'title!="Funky Shirt"' }
|
79
|
-
|
80
|
-
let(:product_a) { Product.create!(title: 'Plain Shirt', rating: 2) }
|
81
|
-
let(:product_b) { Product.create!(title: 'Funky Shirt', rating: 4) }
|
82
|
-
let(:product_c) { Product.create!(title: 'Socks - Pack of 4') }
|
83
|
-
|
84
|
-
before do
|
85
|
-
product_a
|
86
|
-
product_b
|
87
|
-
product_c
|
88
|
-
end
|
89
|
-
|
90
|
-
it 'is expected to contain the matching records' do
|
91
|
-
expect(perform).to contain_exactly(product_a, product_c)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
context 'when passed a `match` keyed attribute query' do
|
96
|
-
let(:query) { 'title*=shirt' }
|
97
|
-
|
98
|
-
let(:product_a) { Product.create!(title: 'Plain Shirt', rating: 2) }
|
99
|
-
let(:product_b) { Product.create!(title: 'Funky Shirt', rating: 4) }
|
100
|
-
let(:product_c) { Product.create!(title: 'Socks - Pack of 4') }
|
101
|
-
|
102
|
-
before do
|
103
|
-
product_a
|
104
|
-
product_b
|
105
|
-
product_c
|
106
|
-
end
|
107
|
-
|
108
|
-
it 'is expected to contain the matching records' do
|
109
|
-
expect(perform).to contain_exactly(product_a, product_b)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
context 'when passed a `not match` keyed attribute query' do
|
114
|
-
let(:query) { 'title!*=socks' }
|
115
|
-
|
116
|
-
let(:product_a) { Product.create!(title: 'Plain Shirt', rating: 2) }
|
117
|
-
let(:product_b) { Product.create!(title: 'Funky Shirt', rating: 4) }
|
118
|
-
let(:product_c) { Product.create!(title: 'Socks - Pack of 4') }
|
119
|
-
|
120
|
-
before do
|
121
|
-
product_a
|
122
|
-
product_b
|
123
|
-
product_c
|
124
|
-
end
|
125
|
-
|
126
|
-
it 'is expected to contain the matching records' do
|
127
|
-
expect(perform).to contain_exactly(product_a, product_b)
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
context 'when passed a numeric `not equal to` keyed attribute query' do
|
132
|
-
let(:query) { 'rating!=2' }
|
133
|
-
|
134
|
-
let(:product_a) { Product.create!(title: 'Plain Shirt', rating: 2) }
|
135
|
-
let(:product_b) { Product.create!(title: 'Funky Shirt', rating: 4) }
|
136
|
-
let(:product_c) { Product.create!(title: 'Socks - Pack of 4', rating: 5) }
|
137
|
-
|
138
|
-
before do
|
139
|
-
product_a
|
140
|
-
product_b
|
141
|
-
product_c
|
142
|
-
end
|
143
|
-
|
144
|
-
it 'is expected to contain the matching records' do
|
145
|
-
expect(perform).to contain_exactly(product_b, product_c)
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
context 'when passed a `greater than` keyed attribute query' do
|
150
|
-
let(:query) { 'rating>2' }
|
151
|
-
|
152
|
-
let(:product_a) { Product.create!(title: 'Plain Shirt', rating: 2) }
|
153
|
-
let(:product_b) { Product.create!(title: 'Funky Shirt', rating: 4) }
|
154
|
-
let(:product_c) { Product.create!(title: 'Socks - Pack of 4', rating: 5) }
|
155
|
-
|
156
|
-
before do
|
157
|
-
product_a
|
158
|
-
product_b
|
159
|
-
product_c
|
160
|
-
end
|
161
|
-
|
162
|
-
it 'is expected to contain the matching records' do
|
163
|
-
expect(perform).to contain_exactly(product_b, product_c)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
context 'when passed a `greater than or equal to` keyed attribute query' do
|
168
|
-
let(:query) { 'rating>=4' }
|
169
|
-
|
170
|
-
let(:product_a) { Product.create!(title: 'Plain Shirt', rating: 2) }
|
171
|
-
let(:product_b) { Product.create!(title: 'Funky Shirt', rating: 4) }
|
172
|
-
let(:product_c) { Product.create!(title: 'Socks - Pack of 4', rating: 5) }
|
173
|
-
|
174
|
-
before do
|
175
|
-
product_a
|
176
|
-
product_b
|
177
|
-
product_c
|
178
|
-
end
|
179
|
-
|
180
|
-
it 'is expected to contain the matching records' do
|
181
|
-
expect(perform).to contain_exactly(product_b, product_c)
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
context 'when passed a `less than` keyed attribute query' do
|
186
|
-
let(:query) { 'rating<5' }
|
187
|
-
|
188
|
-
let(:product_a) { Product.create!(title: 'Plain Shirt', rating: 2) }
|
189
|
-
let(:product_b) { Product.create!(title: 'Funky Shirt', rating: 4) }
|
190
|
-
let(:product_c) { Product.create!(title: 'Socks - Pack of 4', rating: 5) }
|
191
|
-
|
192
|
-
before do
|
193
|
-
product_a
|
194
|
-
product_b
|
195
|
-
product_c
|
196
|
-
end
|
197
|
-
|
198
|
-
it 'is expected to contain the matching records' do
|
199
|
-
expect(perform).to contain_exactly(product_a, product_b)
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
context 'when passed a `less than or equal to` keyed attribute query' do
|
204
|
-
let(:query) { 'rating<=4' }
|
205
|
-
|
206
|
-
let(:product_a) { Product.create!(title: 'Plain Shirt', rating: 2) }
|
207
|
-
let(:product_b) { Product.create!(title: 'Funky Shirt', rating: 4) }
|
208
|
-
let(:product_c) { Product.create!(title: 'Socks - Pack of 4', rating: 5) }
|
209
|
-
|
210
|
-
before do
|
211
|
-
product_a
|
212
|
-
product_b
|
213
|
-
product_c
|
214
|
-
end
|
215
|
-
|
216
|
-
it 'is expected to contain the matching records' do
|
217
|
-
expect(perform).to contain_exactly(product_a, product_b)
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
|
-
context 'when passed a `greater than` and `less than` keyed attribute query' do
|
222
|
-
let(:query) { 'rating>2 rating<5' }
|
223
|
-
|
224
|
-
let(:product_a) { Product.create!(title: 'Plain Shirt', rating: 2) }
|
225
|
-
let(:product_b) { Product.create!(title: 'Funky Shirt', rating: 4) }
|
226
|
-
let(:product_c) { Product.create!(title: 'Socks - Pack of 4', rating: 5) }
|
227
|
-
|
228
|
-
before do
|
229
|
-
product_a
|
230
|
-
product_b
|
231
|
-
product_c
|
232
|
-
end
|
233
|
-
|
234
|
-
it 'is expected to contain the matching records' do
|
235
|
-
expect(perform).to contain_exactly(product_b)
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
|
-
context 'when passed a virtual keyed attribute query' do
|
240
|
-
let(:query) { 'title_length==5' }
|
241
|
-
|
242
|
-
let(:product_a) { Product.create!(title: 'Plain Shirt') }
|
243
|
-
let(:product_b) { Product.create!(title: 'Socks') }
|
244
|
-
|
245
|
-
before do
|
246
|
-
product_a
|
247
|
-
product_b
|
248
|
-
end
|
249
|
-
|
250
|
-
it 'is expected to contain the matching records' do
|
251
|
-
expect(perform).to contain_exactly(product_b)
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
context 'when querying a custom attribute whose name matches a reflection' do
|
256
|
-
let(:query) { 'cat==shirts' }
|
257
|
-
|
258
|
-
let(:shirts_category) { ProductCategory.create!(id: 'shirts', name: 'The Shirt Collection') }
|
259
|
-
let(:socks_category) { ProductCategory.create!(id: 'socks', name: 'The Sock Collection') }
|
260
|
-
|
261
|
-
let(:product_a) { Product.create!(title: 'Plain Shirt', category: shirts_category) }
|
262
|
-
let(:product_b) { Product.create!(title: 'Funky Shirt', category: shirts_category) }
|
263
|
-
let(:product_c) { Product.create!(title: 'Socks - Pack of 4', category: socks_category) }
|
264
|
-
|
265
|
-
before do
|
266
|
-
product_a
|
267
|
-
product_b
|
268
|
-
product_c
|
269
|
-
end
|
270
|
-
|
271
|
-
it 'is expected to contain the matching records' do
|
272
|
-
expect(perform).to contain_exactly(product_a, product_b)
|
273
|
-
end
|
274
|
-
end
|
275
|
-
|
276
|
-
context 'when searching a #has_many relationship' do
|
277
|
-
context 'when passed a `match` relationship search query' do
|
278
|
-
let(:query) { 'variations*=green' }
|
279
|
-
|
280
|
-
let(:product_a) { Product.create!(title: 'Plain Shirt') }
|
281
|
-
let(:product_b) { Product.create!(title: 'Funky Shirt') }
|
282
|
-
|
283
|
-
let(:product_variation_a) { ProductVariation.create!(product: product_a, title: 'Red') }
|
284
|
-
let(:product_variation_b) { ProductVariation.create!(product: product_b, title: 'Green') }
|
285
|
-
let(:product_variation_c) { ProductVariation.create!(product: product_b, title: 'Blue') }
|
286
|
-
|
287
|
-
before do
|
288
|
-
product_a
|
289
|
-
product_b
|
290
|
-
|
291
|
-
product_variation_a
|
292
|
-
product_variation_b
|
293
|
-
product_variation_c
|
294
|
-
end
|
295
|
-
|
296
|
-
it 'is expected to contain the matching records' do
|
297
|
-
expect(perform).to contain_exactly(product_b)
|
298
|
-
end
|
299
|
-
end
|
300
|
-
|
301
|
-
context 'when passed an `equal to` relationship count query' do
|
302
|
-
let(:query) { 'variations==1' }
|
303
|
-
|
304
|
-
let(:product_a) { Product.create!(title: 'Plain Shirt') }
|
305
|
-
let(:product_b) { Product.create!(title: 'Funky Shirt') }
|
306
|
-
let(:product_c) { Product.create!(title: 'Socks') }
|
307
|
-
|
308
|
-
let(:product_variation_a) { ProductVariation.create!(product: product_b, title: 'Red') }
|
309
|
-
let(:product_variation_b) { ProductVariation.create!(product: product_b, title: 'Green') }
|
310
|
-
let(:product_variation_c) { ProductVariation.create!(product: product_b, title: 'Blue') }
|
311
|
-
let(:product_variation_d) { ProductVariation.create!(product: product_c, title: 'White') }
|
312
|
-
|
313
|
-
before do
|
314
|
-
product_a
|
315
|
-
product_b
|
316
|
-
product_c
|
317
|
-
|
318
|
-
product_variation_a
|
319
|
-
product_variation_b
|
320
|
-
product_variation_c
|
321
|
-
product_variation_d
|
322
|
-
end
|
323
|
-
|
324
|
-
it 'is expected to contain the matching records' do
|
325
|
-
expect(perform).to contain_exactly(product_c)
|
326
|
-
end
|
327
|
-
end
|
328
|
-
|
329
|
-
context 'when passed a `greater than` relationship count query' do
|
330
|
-
let(:query) { 'variations>1' }
|
331
|
-
|
332
|
-
let(:product_a) { Product.create!(title: 'Plain Shirt') }
|
333
|
-
let(:product_b) { Product.create!(title: 'Funky Shirt') }
|
334
|
-
let(:product_c) { Product.create!(title: 'Socks') }
|
335
|
-
|
336
|
-
let(:product_variation_a) { ProductVariation.create!(product: product_b, title: 'Red') }
|
337
|
-
let(:product_variation_b) { ProductVariation.create!(product: product_b, title: 'Green') }
|
338
|
-
let(:product_variation_c) { ProductVariation.create!(product: product_b, title: 'Blue') }
|
339
|
-
let(:product_variation_d) { ProductVariation.create!(product: product_c, title: 'White') }
|
340
|
-
let(:product_variation_e) { ProductVariation.create!(product: product_a, title: 'Black') }
|
341
|
-
let(:product_variation_f) { ProductVariation.create!(product: product_a, title: 'Gray') }
|
342
|
-
|
343
|
-
before do
|
344
|
-
product_a
|
345
|
-
product_b
|
346
|
-
product_c
|
347
|
-
|
348
|
-
product_variation_a
|
349
|
-
product_variation_b
|
350
|
-
product_variation_c
|
351
|
-
product_variation_d
|
352
|
-
product_variation_e
|
353
|
-
product_variation_f
|
354
|
-
end
|
355
|
-
|
356
|
-
it 'is expected to contain the matching records' do
|
357
|
-
expect(perform).to contain_exactly(product_a, product_b)
|
358
|
-
end
|
359
|
-
end
|
360
|
-
|
361
|
-
context 'when passed a `greater than or equal to` relationship count query' do
|
362
|
-
let(:query) { 'variations>=2' }
|
363
|
-
|
364
|
-
let(:product_a) { Product.create!(title: 'Plain Shirt') }
|
365
|
-
let(:product_b) { Product.create!(title: 'Funky Shirt') }
|
366
|
-
let(:product_c) { Product.create!(title: 'Socks') }
|
367
|
-
|
368
|
-
let(:product_variation_a) { ProductVariation.create!(product: product_b, title: 'Red') }
|
369
|
-
let(:product_variation_b) { ProductVariation.create!(product: product_b, title: 'Green') }
|
370
|
-
let(:product_variation_c) { ProductVariation.create!(product: product_b, title: 'Blue') }
|
371
|
-
let(:product_variation_d) { ProductVariation.create!(product: product_c, title: 'White') }
|
372
|
-
let(:product_variation_e) { ProductVariation.create!(product: product_a, title: 'Black') }
|
373
|
-
let(:product_variation_f) { ProductVariation.create!(product: product_a, title: 'Gray') }
|
374
|
-
|
375
|
-
before do
|
376
|
-
product_a
|
377
|
-
product_b
|
378
|
-
product_c
|
379
|
-
|
380
|
-
product_variation_a
|
381
|
-
product_variation_b
|
382
|
-
product_variation_c
|
383
|
-
product_variation_d
|
384
|
-
product_variation_e
|
385
|
-
product_variation_f
|
386
|
-
end
|
387
|
-
|
388
|
-
it 'is expected to contain the matching records' do
|
389
|
-
expect(perform).to contain_exactly(product_a, product_b)
|
390
|
-
end
|
391
|
-
end
|
392
|
-
|
393
|
-
context 'when passed a `less than` relationship count query' do
|
394
|
-
let(:query) { 'variations<3' }
|
395
|
-
|
396
|
-
let(:product_a) { Product.create!(title: 'Plain Shirt') }
|
397
|
-
let(:product_b) { Product.create!(title: 'Funky Shirt') }
|
398
|
-
let(:product_c) { Product.create!(title: 'Socks') }
|
399
|
-
|
400
|
-
let(:product_variation_a) { ProductVariation.create!(product: product_b, title: 'Red') }
|
401
|
-
let(:product_variation_b) { ProductVariation.create!(product: product_b, title: 'Green') }
|
402
|
-
let(:product_variation_c) { ProductVariation.create!(product: product_b, title: 'Blue') }
|
403
|
-
let(:product_variation_d) { ProductVariation.create!(product: product_c, title: 'White') }
|
404
|
-
let(:product_variation_e) { ProductVariation.create!(product: product_a, title: 'Black') }
|
405
|
-
let(:product_variation_f) { ProductVariation.create!(product: product_a, title: 'Gray') }
|
406
|
-
|
407
|
-
before do
|
408
|
-
product_a
|
409
|
-
product_b
|
410
|
-
product_c
|
411
|
-
|
412
|
-
product_variation_a
|
413
|
-
product_variation_b
|
414
|
-
product_variation_c
|
415
|
-
product_variation_d
|
416
|
-
product_variation_e
|
417
|
-
product_variation_f
|
418
|
-
end
|
419
|
-
|
420
|
-
it 'is expected to contain the matching records' do
|
421
|
-
expect(perform).to contain_exactly(product_a, product_c)
|
422
|
-
end
|
423
|
-
end
|
424
|
-
|
425
|
-
context 'when passed a `less than or equal to` relationship count query' do
|
426
|
-
let(:query) { 'variations<=2' }
|
427
|
-
|
428
|
-
let(:product_a) { Product.create!(title: 'Plain Shirt') }
|
429
|
-
let(:product_b) { Product.create!(title: 'Funky Shirt') }
|
430
|
-
let(:product_c) { Product.create!(title: 'Socks') }
|
431
|
-
|
432
|
-
let(:product_variation_a) { ProductVariation.create!(product: product_b, title: 'Red') }
|
433
|
-
let(:product_variation_b) { ProductVariation.create!(product: product_b, title: 'Green') }
|
434
|
-
let(:product_variation_c) { ProductVariation.create!(product: product_b, title: 'Blue') }
|
435
|
-
let(:product_variation_d) { ProductVariation.create!(product: product_c, title: 'White') }
|
436
|
-
let(:product_variation_e) { ProductVariation.create!(product: product_a, title: 'Black') }
|
437
|
-
let(:product_variation_f) { ProductVariation.create!(product: product_a, title: 'Gray') }
|
438
|
-
|
439
|
-
before do
|
440
|
-
product_a
|
441
|
-
product_b
|
442
|
-
product_c
|
443
|
-
|
444
|
-
product_variation_a
|
445
|
-
product_variation_b
|
446
|
-
product_variation_c
|
447
|
-
product_variation_d
|
448
|
-
product_variation_e
|
449
|
-
product_variation_f
|
450
|
-
end
|
451
|
-
|
452
|
-
it 'is expected to contain the matching records' do
|
453
|
-
expect(perform).to contain_exactly(product_a, product_c)
|
454
|
-
end
|
455
|
-
end
|
456
|
-
|
457
|
-
context 'when passed a `greater than` and `less than` relationship count query' do
|
458
|
-
let(:query) { 'variations>1 variations<3' }
|
459
|
-
|
460
|
-
let(:product_a) { Product.create!(title: 'Plain Shirt') }
|
461
|
-
let(:product_b) { Product.create!(title: 'Funky Shirt') }
|
462
|
-
let(:product_c) { Product.create!(title: 'Socks') }
|
463
|
-
|
464
|
-
let(:product_variation_a) { ProductVariation.create!(product: product_b, title: 'Red') }
|
465
|
-
let(:product_variation_b) { ProductVariation.create!(product: product_b, title: 'Green') }
|
466
|
-
let(:product_variation_c) { ProductVariation.create!(product: product_b, title: 'Blue') }
|
467
|
-
let(:product_variation_d) { ProductVariation.create!(product: product_c, title: 'White') }
|
468
|
-
let(:product_variation_e) { ProductVariation.create!(product: product_a, title: 'Black') }
|
469
|
-
let(:product_variation_f) { ProductVariation.create!(product: product_a, title: 'Gray') }
|
470
|
-
|
471
|
-
before do
|
472
|
-
product_a
|
473
|
-
product_b
|
474
|
-
product_c
|
475
|
-
|
476
|
-
product_variation_a
|
477
|
-
product_variation_b
|
478
|
-
product_variation_c
|
479
|
-
product_variation_d
|
480
|
-
product_variation_e
|
481
|
-
product_variation_f
|
482
|
-
end
|
483
|
-
|
484
|
-
it 'is expected to contain the matching records' do
|
485
|
-
expect(perform).to contain_exactly(product_a)
|
486
|
-
end
|
487
|
-
end
|
488
|
-
end
|
489
|
-
|
490
|
-
context 'when searching a #belongs_to relationship' do
|
491
|
-
context 'when passed a `match` relationship search query' do
|
492
|
-
let(:query) { 'category*=shirt' }
|
493
|
-
|
494
|
-
let(:product_category_a) { ProductCategory.create!(id: 'one', name: 'Shirts') }
|
495
|
-
let(:product_category_b) { ProductCategory.create!(id: 'two', name: 'Socks') }
|
496
|
-
|
497
|
-
let(:product_a) { Product.create!(category: product_category_a, title: 'Plain Shirt') }
|
498
|
-
let(:product_b) { Product.create!(category: product_category_a, title: 'Funky Shirt') }
|
499
|
-
let(:product_c) { Product.create!(category: product_category_b, title: 'White Socks') }
|
500
|
-
|
501
|
-
before do
|
502
|
-
product_category_a
|
503
|
-
product_category_b
|
504
|
-
|
505
|
-
product_a
|
506
|
-
product_b
|
507
|
-
product_c
|
508
|
-
end
|
509
|
-
|
510
|
-
it 'is expected to contain the matching records' do
|
511
|
-
expect(perform).to contain_exactly(product_a, product_b)
|
512
|
-
end
|
513
|
-
end
|
514
|
-
end
|
515
|
-
end
|
516
|
-
end
|