search_flip 2.3.2 → 3.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,3 @@
1
-
2
1
  require File.expand_path("../spec_helper", __dir__)
3
2
 
4
3
  RSpec.describe SearchFlip::Criteria do
@@ -19,6 +18,62 @@ RSpec.describe SearchFlip::Criteria do
19
18
  it { should delegate(:connection).to(:target) }
20
19
  end
21
20
 
21
+ describe "#to_query" do
22
+ it "returns the added must, filter and must_not clauses" do
23
+ query =
24
+ ProductIndex
25
+ .must(term: { category: "category1" })
26
+ .filter(term: { category: "category2" })
27
+ .must_not(term: { category: "category3" })
28
+
29
+ expect(query.to_query).to eq(
30
+ bool: {
31
+ must: [{ term: { category: "category1" } }],
32
+ filter: [{ term: { category: "category2" } }],
33
+ must_not: [{ term: { category: "category3" } }]
34
+ }
35
+ )
36
+ end
37
+
38
+ it "generates an executable query for must, filter and must_not clauses" do
39
+ query =
40
+ ProductIndex
41
+ .must(term: { category: "category1" })
42
+ .filter(term: { category: "category2" })
43
+ .must_not(term: { category: "category3" })
44
+
45
+ expect { ProductIndex.must(query.to_query).execute }.not_to raise_error
46
+ end
47
+
48
+ it "returns the added post_must, post_filter and post_must_not clauses" do
49
+ query =
50
+ ProductIndex
51
+ .post_must(term: { category: "category1" })
52
+ .post_filter(term: { category: "category2" })
53
+ .post_must_not(term: { category: "category3" })
54
+
55
+ expect(query.to_query).to eq(
56
+ bool: {
57
+ must_not: [{ term: { category: "category3" } }],
58
+ filter: [
59
+ { term: { category: "category1" } },
60
+ { term: { category: "category2" } }
61
+ ]
62
+ }
63
+ )
64
+ end
65
+
66
+ it "generates an executable query for post_must, post_filter and post_must_not clauses" do
67
+ query =
68
+ ProductIndex
69
+ .post_must(term: { category: "category1" })
70
+ .post_filter(term: { category: "category2" })
71
+ .post_must_not(term: { category: "category3" })
72
+
73
+ expect { ProductIndex.must(query.to_query).execute }.not_to raise_error
74
+ end
75
+ end
76
+
22
77
  describe "#merge" do
23
78
  it "merges criterias" do
24
79
  product1 = create(:product, price: 100, category: "category1")
@@ -54,9 +109,9 @@ RSpec.describe SearchFlip::Criteria do
54
109
 
55
110
  describe "array concatenations" do
56
111
  methods = [
57
- :sort_values, :includes_values, :preload_values, :eager_load_values, :search_values,
58
- :must_values, :must_not_values, :should_values, :filter_values, :post_search_values,
59
- :post_must_values, :post_must_not_values, :post_should_values, :post_filter_values
112
+ :sort_values, :includes_values, :preload_values, :eager_load_values,
113
+ :must_values, :must_not_values, :filter_values,
114
+ :post_must_values, :post_must_not_values, :post_filter_values
60
115
  ]
61
116
 
62
117
  methods.each do |method|
@@ -103,6 +158,14 @@ RSpec.describe SearchFlip::Criteria do
103
158
  end
104
159
  end
105
160
 
161
+ describe "#all" do
162
+ it "returns self" do
163
+ criteria = ProductIndex.criteria
164
+
165
+ expect(criteria.all.object_id).to eq(criteria.object_id)
166
+ end
167
+ end
168
+
106
169
  describe "#timeout" do
107
170
  it "sets the query timeout" do
108
171
  query = ProductIndex.timeout("1s")
@@ -299,11 +362,12 @@ RSpec.describe SearchFlip::Criteria do
299
362
 
300
363
  ProductIndex.import [product1, product2, product3]
301
364
 
302
- query1 = ProductIndex.should(range: { price: { gte: 100, lt: 200 } })
303
- query2 = query1.should(term: { category: "category2" })
365
+ query = ProductIndex.should([
366
+ { range: { price: { gte: 100, lt: 200 } } },
367
+ { term: { category: "category2" } }
368
+ ])
304
369
 
305
- expect(query1.records.to_set).to eq([product1].to_set)
306
- expect(query2.records.to_set).to eq([product1, product2].to_set)
370
+ expect(query.records.to_set).to eq([product1, product2].to_set)
307
371
  end
308
372
  end
309
373
 
@@ -442,6 +506,21 @@ RSpec.describe SearchFlip::Criteria do
442
506
  aggregations = query.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
443
507
  expect(aggregations).to eq("category1" => 2, "category2" => 1)
444
508
  end
509
+
510
+ it "works with nil" do
511
+ expected1 = create(:product, price: nil, category: "category1")
512
+ expected2 = create(:product, price: nil, category: "category2")
513
+ rejected = create(:product, price: 300, category: "category1")
514
+
515
+ ProductIndex.import [expected1, expected2, rejected]
516
+
517
+ query = ProductIndex.aggregate(:category).post_where(price: nil)
518
+
519
+ expect(query.records.to_set).to eq([expected1, expected2].to_set)
520
+
521
+ aggregations = query.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
522
+ expect(aggregations).to eq("category1" => 2, "category2" => 1)
523
+ end
445
524
  end
446
525
 
447
526
  describe "#post_where_not" do
@@ -494,6 +573,21 @@ RSpec.describe SearchFlip::Criteria do
494
573
  aggregations = query.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
495
574
  expect(aggregations).to eq("category1" => 2, "category2" => 1)
496
575
  end
576
+
577
+ it "works with nils" do
578
+ expected = create(:product, price: 100, category: "category1")
579
+ rejected1 = create(:product, price: nil, category: "category2")
580
+ rejected2 = create(:product, price: nil, category: "category1")
581
+
582
+ ProductIndex.import [expected, rejected1, rejected2]
583
+
584
+ query = ProductIndex.aggregate(:category).post_where_not(price: nil)
585
+
586
+ expect(query.records).to eq([expected])
587
+
588
+ aggregations = query.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
589
+ expect(aggregations).to eq("category1" => 2, "category2" => 1)
590
+ end
497
591
  end
498
592
 
499
593
  describe "#post_filter" do
@@ -518,6 +612,80 @@ RSpec.describe SearchFlip::Criteria do
518
612
  end
519
613
  end
520
614
 
615
+ describe "#post_must" do
616
+ it "sets up the constraints correctly and is chainable" do
617
+ product1 = create(:product, price: 100, category: "category1")
618
+ product2 = create(:product, price: 200, category: "category2")
619
+ product3 = create(:product, price: 300, category: "category1")
620
+
621
+ ProductIndex.import [product1, product2, product3]
622
+
623
+ query1 = ProductIndex.aggregate(:category).post_must(range: { price: { gte: 100, lte: 200 } })
624
+ query2 = query1.post_must(term: { category: "category1" })
625
+
626
+ expect(query1.records.to_set).to eq([product1, product2].to_set)
627
+ expect(query2.records).to eq([product1])
628
+
629
+ aggregations = query1.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
630
+ expect(aggregations).to eq("category1" => 2, "category2" => 1)
631
+
632
+ aggregations = query2.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
633
+ expect(aggregations).to eq("category1" => 2, "category2" => 1)
634
+ end
635
+ end
636
+
637
+ describe "#post_must_not" do
638
+ it "sets up the constraints correctly and is chainable" do
639
+ product1 = create(:product, price: 100, category: "category1")
640
+ product2 = create(:product, price: 200, category: "category2")
641
+ product3 = create(:product, price: 300, category: "category1")
642
+
643
+ ProductIndex.import [product1, product2, product3]
644
+
645
+ query1 = ProductIndex.aggregate(:category).post_must_not(range: { price: { gte: 50, lte: 150 } })
646
+ query2 = query1.post_must_not(term: { category: "category1" })
647
+
648
+ expect(query1.records.to_set).to eq([product2, product3].to_set)
649
+ expect(query2.records).to eq([product2])
650
+
651
+ aggregations = query1.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
652
+ expect(aggregations).to eq("category1" => 2, "category2" => 1)
653
+
654
+ aggregations = query2.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
655
+ expect(aggregations).to eq("category1" => 2, "category2" => 1)
656
+ end
657
+ end
658
+
659
+ describe "#post_should" do
660
+ it "sets up the constraints correctly and is chainable" do
661
+ product1 = create(:product, price: 100, category: "category1")
662
+ product2 = create(:product, price: 200, category: "category3")
663
+ product3 = create(:product, price: 300, category: "category2")
664
+ product4 = create(:product, price: 400, category: "category1")
665
+
666
+ ProductIndex.import [product1, product2, product3, product4]
667
+
668
+ query1 = ProductIndex.aggregate(:category).post_should([
669
+ { term: { category: "category1" } },
670
+ { term: { category: "category2" } }
671
+ ])
672
+
673
+ query2 = query1.post_should([
674
+ { range: { price: { gte: 50, lte: 150 } } },
675
+ { range: { price: { gte: 250, lte: 350 } } }
676
+ ])
677
+
678
+ expect(query1.records.to_set).to eq([product1, product3, product4].to_set)
679
+ expect(query2.records.to_set).to eq([product1, product3].to_set)
680
+
681
+ aggregations = query1.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
682
+ expect(aggregations).to eq("category1" => 2, "category2" => 1, "category3" => 1)
683
+
684
+ aggregations = query2.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
685
+ expect(aggregations).to eq("category1" => 2, "category2" => 1, "category3" => 1)
686
+ end
687
+ end
688
+
521
689
  describe "#post_range" do
522
690
  it "sets up the constraints correctly and is chainable" do
523
691
  product1 = create(:product, price: 100, category: "category1")
@@ -797,7 +965,7 @@ RSpec.describe SearchFlip::Criteria do
797
965
 
798
966
  ProductIndex.import [product1, product2, product3, product4]
799
967
 
800
- expect(ProductIndex.sort({ rank: :desc }, { price: :asc }).records).to eq([product2, product1, product3, product4])
968
+ expect(ProductIndex.sort({ rank: :desc }, price: :asc).records).to eq([product2, product1, product3, product4])
801
969
  expect(ProductIndex.sort(rank: :desc).sort(:price).records).to eq([product2, product1, product3, product4])
802
970
  expect(ProductIndex.sort(:price).sort(rank: :desc).records).to eq([product2, product1, product4, product3])
803
971
  end
@@ -812,7 +980,7 @@ RSpec.describe SearchFlip::Criteria do
812
980
 
813
981
  ProductIndex.import [product1, product2, product3, product4]
814
982
 
815
- expect(ProductIndex.sort(:price).resort({ rank: :desc }, { price: :asc }).records).to eq([product2, product1, product3, product4])
983
+ expect(ProductIndex.sort(:price).resort({ rank: :desc }, price: :asc).records).to eq([product2, product1, product3, product4])
816
984
  expect(ProductIndex.sort(rank: :desc).resort(:price).records).to eq([product2, product1, product4, product3])
817
985
  end
818
986
  end
@@ -891,19 +1059,6 @@ RSpec.describe SearchFlip::Criteria do
891
1059
  end
892
1060
  end
893
1061
 
894
- describe "#unscope" do
895
- it "removes the specified constraints and is chainable" do
896
- product1 = create(:product, title: "Title1", description: "Description1", price: 10)
897
- product2 = create(:product, title: "Title2", description: "Description2", price: 20)
898
- product3 = create(:product, title: "Title3", description: "Description2", price: 30)
899
-
900
- ProductIndex.import [product1, product2, product3]
901
-
902
- expect(ProductIndex.search("Title1 OR Title2").search("Title1 OR Title3").records).to eq([product1])
903
- expect(ProductIndex.search("Title1 OR Title2").unscope(:search).search("Title1 OR Title3").records.to_set).to eq([product1, product3].to_set)
904
- end
905
- end
906
-
907
1062
  describe "#highlight" do
908
1063
  it "adds highlighting to the query and is chainable" do
909
1064
  product1 = create(:product, title: "Title1 highlight", description: "Description1 highlight")
@@ -1127,4 +1282,3 @@ RSpec.describe SearchFlip::Criteria do
1127
1282
  end
1128
1283
  end
1129
1284
  end
1130
-
@@ -1,4 +1,3 @@
1
-
2
1
  require File.expand_path("../spec_helper", __dir__)
3
2
 
4
3
  class HttpTestRequest
@@ -1,4 +1,3 @@
1
-
2
1
  require File.expand_path("../spec_helper", __dir__)
3
2
 
4
3
  RSpec.describe SearchFlip::Index do
@@ -6,14 +5,14 @@ RSpec.describe SearchFlip::Index do
6
5
  subject { ProductIndex }
7
6
 
8
7
  methods = [
9
- :profile, :where, :where_not, :filter, :range, :match_all, :exists,
8
+ :all, :profile, :where, :where_not, :filter, :range, :match_all, :exists,
10
9
  :exists_not, :post_where, :post_where_not, :post_filter, :post_must,
11
10
  :post_must_not, :post_should, :post_range, :post_exists, :post_exists_not,
12
11
  :aggregate, :scroll, :source, :includes, :eager_load, :preload, :sort, :resort,
13
12
  :order, :reorder, :offset, :limit, :paginate, :page, :per, :search,
14
13
  :find_in_batches, :highlight, :suggest, :custom, :find_each, :failsafe,
15
14
  :total_entries, :total_count, :terminate_after, :timeout, :records, :results,
16
- :should, :should_not, :must, :must_not, :find_each_result,
15
+ :must, :must_not, :should, :find_each_result,
17
16
  :find_results_in_batches, :preference, :search_type, :routing,
18
17
  :track_total_hits, :explain
19
18
  ]
@@ -68,7 +67,7 @@ RSpec.describe SearchFlip::Index do
68
67
 
69
68
  TestIndex.create_index
70
69
 
71
- expect(TestIndex.connection).to have_received(:create_index).with("test", { settings: { number_of_shards: 2 } })
70
+ expect(TestIndex.connection).to have_received(:create_index).with("test", settings: { number_of_shards: 2 })
72
71
  end
73
72
  end
74
73
 
@@ -96,10 +95,8 @@ RSpec.describe SearchFlip::Index do
96
95
 
97
96
  describe ".close_index" do
98
97
  it "delegates to connection" do
99
- allow(TestIndex.connection).to receive(:close_index).and_call_original
98
+ allow(TestIndex.connection).to receive(:close_index)
100
99
 
101
- TestIndex.create_index
102
- sleep(0.1) while TestIndex.connection.cluster_health["status"] == "red"
103
100
  TestIndex.close_index
104
101
 
105
102
  expect(TestIndex.connection).to have_received(:close_index).with("test")
@@ -108,11 +105,7 @@ RSpec.describe SearchFlip::Index do
108
105
 
109
106
  describe ".open_index" do
110
107
  it "delegates to connection" do
111
- allow(TestIndex.connection).to receive(:open_index).and_call_original
112
-
113
- TestIndex.create_index
114
- sleep(0.1) while TestIndex.connection.cluster_health["status"] == "red"
115
- TestIndex.close_index
108
+ allow(TestIndex.connection).to receive(:open_index)
116
109
 
117
110
  TestIndex.open_index
118
111
 
@@ -120,6 +113,26 @@ RSpec.describe SearchFlip::Index do
120
113
  end
121
114
  end
122
115
 
116
+ describe ".freeze_index" do
117
+ it "delegates to connection" do
118
+ allow(TestIndex.connection).to receive(:freeze_index)
119
+
120
+ TestIndex.freeze_index
121
+
122
+ expect(TestIndex.connection).to have_received(:freeze_index).with("test")
123
+ end
124
+ end
125
+
126
+ describe ".unfreeze_index" do
127
+ it "delegates to connection" do
128
+ allow(TestIndex.connection).to receive(:unfreeze_index)
129
+
130
+ TestIndex.unfreeze_index
131
+
132
+ expect(TestIndex.connection).to have_received(:unfreeze_index).with("test")
133
+ end
134
+ end
135
+
123
136
  describe ".index_exists?" do
124
137
  it "delegates to connection" do
125
138
  TestIndex.create_index
@@ -618,4 +631,3 @@ RSpec.describe SearchFlip::Index do
618
631
  end
619
632
  end
620
633
  end
621
-
@@ -1,4 +1,3 @@
1
-
2
1
  require File.expand_path("../spec_helper", __dir__)
3
2
 
4
3
  class TestProduct < Product
@@ -1,4 +1,3 @@
1
-
2
1
  require File.expand_path("../spec_helper", __dir__)
3
2
 
4
3
  RSpec.describe SearchFlip::Response do
@@ -13,8 +12,6 @@ RSpec.describe SearchFlip::Response do
13
12
 
14
13
  describe "#current_page" do
15
14
  it "returns the current page number" do
16
- expect(ProductIndex.match_all.current_page).to eq(1)
17
-
18
15
  ProductIndex.import create_list(:product, 3)
19
16
 
20
17
  expect(ProductIndex.paginate(page: 1, per_page: 2).current_page).to eq(1)
@@ -182,4 +179,3 @@ RSpec.describe SearchFlip::Response do
182
179
  end
183
180
  end
184
181
  end
185
-
@@ -1,4 +1,3 @@
1
-
2
1
  require File.expand_path("../spec_helper", __dir__)
3
2
  require "search_flip/to_json"
4
3
 
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  require "search_flip"
3
2
  require "webmock/rspec"
4
3
  require "active_record"
@@ -130,7 +129,7 @@ class ProductIndex
130
129
  }
131
130
  }
132
131
  else
133
- { }
132
+ {}
134
133
  end
135
134
  end
136
135
 
@@ -189,4 +188,3 @@ class TestIndex
189
188
  end
190
189
 
191
190
  TestIndex.delete_index if TestIndex.index_exists?
192
-
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: search_flip
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.2
4
+ version: 3.0.0.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin Vetter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-19 00:00:00.000000000 Z
11
+ date: 2020-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -81,7 +81,7 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: sqlite3
84
+ name: rubocop
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
@@ -95,7 +95,7 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: timecop
98
+ name: sqlite3
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ">="
@@ -109,7 +109,7 @@ dependencies:
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
- name: webmock
112
+ name: timecop
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - ">="
@@ -123,13 +123,13 @@ dependencies:
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
125
  - !ruby/object:Gem::Dependency
126
- name: ruby2_keywords
126
+ name: webmock
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - ">="
130
130
  - !ruby/object:Gem::Version
131
131
  version: '0'
132
- type: :runtime
132
+ type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
@@ -204,6 +204,7 @@ files:
204
204
  - lib/search_flip/criteria.rb
205
205
  - lib/search_flip/exceptions.rb
206
206
  - lib/search_flip/filterable.rb
207
+ - lib/search_flip/helper.rb
207
208
  - lib/search_flip/http_client.rb
208
209
  - lib/search_flip/index.rb
209
210
  - lib/search_flip/json.rb
@@ -243,11 +244,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
243
244
  version: '0'
244
245
  required_rubygems_version: !ruby/object:Gem::Requirement
245
246
  requirements:
246
- - - ">="
247
+ - - ">"
247
248
  - !ruby/object:Gem::Version
248
- version: '0'
249
+ version: 1.3.1
249
250
  requirements: []
250
- rubygems_version: 3.1.2
251
+ rubyforge_project:
252
+ rubygems_version: 2.7.3
251
253
  signing_key:
252
254
  specification_version: 4
253
255
  summary: Full-Featured Elasticsearch Ruby Client with a Chainable DSL