search_flip 2.3.2 → 3.0.0.beta

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.
@@ -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