chewy 0.0.1 → 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.
Files changed (80) hide show
  1. checksums.yaml +13 -5
  2. data/.gitignore +1 -0
  3. data/.travis.yml +5 -3
  4. data/CHANGELOG.md +75 -0
  5. data/README.md +487 -92
  6. data/Rakefile +3 -2
  7. data/chewy.gemspec +2 -2
  8. data/filters +76 -0
  9. data/lib/chewy.rb +5 -3
  10. data/lib/chewy/config.rb +36 -19
  11. data/lib/chewy/fields/base.rb +5 -1
  12. data/lib/chewy/index.rb +22 -10
  13. data/lib/chewy/index/actions.rb +13 -13
  14. data/lib/chewy/index/search.rb +7 -2
  15. data/lib/chewy/query.rb +382 -64
  16. data/lib/chewy/query/context.rb +174 -0
  17. data/lib/chewy/query/criteria.rb +127 -34
  18. data/lib/chewy/query/loading.rb +9 -9
  19. data/lib/chewy/query/nodes/and.rb +25 -0
  20. data/lib/chewy/query/nodes/base.rb +17 -0
  21. data/lib/chewy/query/nodes/bool.rb +32 -0
  22. data/lib/chewy/query/nodes/equal.rb +34 -0
  23. data/lib/chewy/query/nodes/exists.rb +20 -0
  24. data/lib/chewy/query/nodes/expr.rb +28 -0
  25. data/lib/chewy/query/nodes/field.rb +106 -0
  26. data/lib/chewy/query/nodes/missing.rb +20 -0
  27. data/lib/chewy/query/nodes/not.rb +25 -0
  28. data/lib/chewy/query/nodes/or.rb +25 -0
  29. data/lib/chewy/query/nodes/prefix.rb +18 -0
  30. data/lib/chewy/query/nodes/query.rb +20 -0
  31. data/lib/chewy/query/nodes/range.rb +63 -0
  32. data/lib/chewy/query/nodes/raw.rb +15 -0
  33. data/lib/chewy/query/nodes/regexp.rb +31 -0
  34. data/lib/chewy/query/nodes/script.rb +20 -0
  35. data/lib/chewy/query/pagination.rb +28 -22
  36. data/lib/chewy/railtie.rb +23 -0
  37. data/lib/chewy/rspec/update_index.rb +20 -3
  38. data/lib/chewy/type/adapter/active_record.rb +78 -5
  39. data/lib/chewy/type/adapter/base.rb +46 -0
  40. data/lib/chewy/type/adapter/object.rb +40 -8
  41. data/lib/chewy/type/base.rb +1 -1
  42. data/lib/chewy/type/import.rb +18 -44
  43. data/lib/chewy/type/observe.rb +24 -14
  44. data/lib/chewy/version.rb +1 -1
  45. data/lib/tasks/chewy.rake +27 -0
  46. data/spec/chewy/config_spec.rb +30 -12
  47. data/spec/chewy/fields/base_spec.rb +11 -5
  48. data/spec/chewy/index/actions_spec.rb +20 -20
  49. data/spec/chewy/index/search_spec.rb +5 -5
  50. data/spec/chewy/index_spec.rb +28 -8
  51. data/spec/chewy/query/context_spec.rb +173 -0
  52. data/spec/chewy/query/criteria_spec.rb +219 -12
  53. data/spec/chewy/query/loading_spec.rb +6 -4
  54. data/spec/chewy/query/nodes/and_spec.rb +16 -0
  55. data/spec/chewy/query/nodes/bool_spec.rb +22 -0
  56. data/spec/chewy/query/nodes/equal_spec.rb +32 -0
  57. data/spec/chewy/query/nodes/exists_spec.rb +18 -0
  58. data/spec/chewy/query/nodes/missing_spec.rb +15 -0
  59. data/spec/chewy/query/nodes/not_spec.rb +16 -0
  60. data/spec/chewy/query/nodes/or_spec.rb +16 -0
  61. data/spec/chewy/query/nodes/prefix_spec.rb +16 -0
  62. data/spec/chewy/query/nodes/query_spec.rb +12 -0
  63. data/spec/chewy/query/nodes/range_spec.rb +32 -0
  64. data/spec/chewy/query/nodes/raw_spec.rb +11 -0
  65. data/spec/chewy/query/nodes/regexp_spec.rb +31 -0
  66. data/spec/chewy/query/nodes/script_spec.rb +15 -0
  67. data/spec/chewy/query/pagination_spec.rb +3 -2
  68. data/spec/chewy/query_spec.rb +83 -26
  69. data/spec/chewy/rspec/update_index_spec.rb +20 -0
  70. data/spec/chewy/type/adapter/active_record_spec.rb +102 -0
  71. data/spec/chewy/type/adapter/object_spec.rb +82 -0
  72. data/spec/chewy/type/import_spec.rb +30 -1
  73. data/spec/chewy/type/mapping_spec.rb +1 -1
  74. data/spec/chewy/type/observe_spec.rb +46 -12
  75. data/spec/spec_helper.rb +7 -6
  76. data/spec/support/class_helpers.rb +2 -2
  77. metadata +98 -48
  78. data/.rvmrc +0 -1
  79. data/lib/chewy/index/client.rb +0 -13
  80. data/spec/chewy/index/client_spec.rb +0 -18
@@ -4,9 +4,21 @@ module Chewy
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  module ActiveRecordMethods
7
- def update_elasticsearch(type_name, &block)
7
+ def update_index(type_name, *args, &block)
8
+ options = args.extract_options!
9
+ method = args.first
10
+
8
11
  update = Proc.new do
9
- Chewy.derive_type(type_name).update_index(instance_eval(&block))
12
+ backreference = if method && method.to_s == 'self'
13
+ self
14
+ elsif method
15
+ send(method)
16
+ else
17
+ instance_eval(&block)
18
+ end
19
+
20
+ Chewy.derive_type(type_name).update_index(backreference,
21
+ options.reverse_merge(urgent: Chewy.urgent_update))
10
22
  end
11
23
 
12
24
  after_save &update
@@ -15,19 +27,17 @@ module Chewy
15
27
  end
16
28
 
17
29
  module ClassMethods
18
- def update_index(objects)
19
- if Chewy.observing_enabled
20
- if Chewy.atomic?
21
- ids = if objects.is_a?(::ActiveRecord::Relation)
22
- objects.pluck(:id)
23
- else
24
- Array.wrap(objects).map { |object| object.respond_to?(:id) ? object.id : object.to_i }
25
- end
26
- Chewy.atomic_stash self, ids
30
+ def update_index(objects, options = {})
31
+ if Chewy.atomic?
32
+ ids = if objects.is_a?(::ActiveRecord::Relation)
33
+ objects.pluck(:id)
27
34
  else
28
- import objects
29
- end if objects
30
- end
35
+ Array.wrap(objects).map { |object| object.respond_to?(:id) ? object.id : object.to_i }
36
+ end
37
+ Chewy.stash self, ids
38
+ else
39
+ import(objects) if options[:urgent]
40
+ end if objects
31
41
 
32
42
  true
33
43
  end
data/lib/chewy/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Chewy
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -0,0 +1,27 @@
1
+ namespace :chewy do
2
+ namespace :reset do
3
+ desc 'Destroy, recreate and import data for all found indexes'
4
+ task all: :environment do
5
+ Rails.application.config.paths['app/chewy'].existent.each do |dir|
6
+ Dir.glob(File.join(dir, '**/*.rb')).each { |file| require file }
7
+ end
8
+
9
+ Chewy::Index.descendants.each do |index|
10
+ puts "Resetting #{index}"
11
+ index.reset
12
+ end
13
+ end
14
+ end
15
+
16
+ desc 'Destroy, recreate and import data to specified index'
17
+ task :reset, [:index] => :environment do |task, args|
18
+ "#{args[:index].camelize}Index".constantize.reset
19
+ end
20
+
21
+ desc 'Updates specified index'
22
+ task :update, [:index] => :environment do |task, args|
23
+ index = "#{args[:index].camelize}Index".constantize
24
+ raise "Index `#{index.index_name}` does not exists. Use rake chewy:reset[index] to create and update it." unless index.exists?
25
+ index.import
26
+ end
27
+ end
@@ -4,7 +4,17 @@ describe Chewy::Config do
4
4
  include ClassHelpers
5
5
  subject { described_class.send(:new) }
6
6
 
7
- its(:observing_enabled) { should be_true }
7
+ its(:query_mode) { should == :must }
8
+ its(:filter_mode) { should == :and }
9
+ its(:logger) { should be_nil }
10
+ its(:client_options) { should_not have_key :logger }
11
+
12
+ describe '#logger' do
13
+ before { subject.logger = double(:logger) }
14
+
15
+ its(:logger) { should_not be_nil }
16
+ its(:client_options) { should have_key :logger }
17
+ end
8
18
 
9
19
  describe '#atomic?' do
10
20
  its(:atomic?) { should be_false }
@@ -21,30 +31,38 @@ describe Chewy::Config do
21
31
  let(:dummy_type) { DummiesIndex::Dummy }
22
32
 
23
33
  specify { subject.atomic { 42 }.should == 42 }
24
- specify { expect { subject.atomic { subject.atomic_stash Class.new, 42 } }.to raise_error ArgumentError }
25
- specify { subject.atomic { subject.atomic { subject.atomic_stash.should == [{}, {}] } } }
34
+ specify { expect { subject.atomic { subject.stash Class.new, 42 } }.to raise_error ArgumentError }
35
+ specify { subject.atomic { subject.atomic { subject.stash.should == [{}, {}] } } }
26
36
 
27
37
  specify do
28
- expect(dummy_type).to receive(:import).with([1,2,3]).once
38
+ expect(dummy_type).to receive(:import).with([1, 2, 3]).once
29
39
  subject.atomic do
30
- subject.atomic_stash dummy_type, 1, 2
31
- subject.atomic_stash dummy_type, [2, 3]
40
+ subject.stash dummy_type, [1, 2]
41
+ subject.stash dummy_type, [2, 3]
32
42
  end
33
43
  end
34
44
 
35
45
  specify do
36
- expect(dummy_type).to receive(:import).with([2,3]).once
37
- expect(dummy_type).to receive(:import).with([1,2]).once
46
+ expect(dummy_type).to receive(:import).with([1, 2]).once
47
+ subject.atomic do
48
+ subject.stash dummy_type, [1, 2]
49
+ raise
50
+ end rescue nil
51
+ end
52
+
53
+ specify do
54
+ expect(dummy_type).to receive(:import).with([2, 3]).once
55
+ expect(dummy_type).to receive(:import).with([1, 2]).once
38
56
  subject.atomic do
39
- subject.atomic_stash dummy_type, [2, 3]
57
+ subject.stash dummy_type, [2, 3]
40
58
  subject.atomic do
41
- subject.atomic_stash dummy_type, 1, 2
59
+ subject.stash dummy_type, [1, 2]
42
60
  end
43
61
  end
44
62
  end
45
63
  end
46
64
 
47
- describe '#atomic_stash' do
48
- specify { subject.atomic { subject.atomic_stash.should == [{}] } }
65
+ describe '#stash' do
66
+ specify { subject.atomic { subject.stash.should == [{}] } }
49
67
  end
50
68
  end
@@ -15,13 +15,19 @@ describe Chewy::Fields::Base do
15
15
  context do
16
16
  before do
17
17
  field.nested(described_class.new(:subname1, value: ->(o){ o.subvalue1 }))
18
- field.nested(described_class.new(:subname2))
18
+ field.nested(described_class.new(:subname2, value: ->{ subvalue2 }))
19
+ field.nested(described_class.new(:subname3))
19
20
  end
20
21
 
21
- specify { field.compose(double(value: double(subvalue1: 'hello', subname2: 'world')))
22
- .should == {name: {'subname1' => 'hello', 'subname2' => 'world'}} }
23
- specify { field.compose(double(value: [double(subvalue1: 'hello1', subname2: 'world1'), double(subvalue1: 'hello2', subname2: 'world2')]))
24
- .should == {name: [{'subname1' => 'hello1', 'subname2' => 'world1'}, {'subname1' => 'hello2', 'subname2' => 'world2'}]} }
22
+ specify { field.compose(double(value: double(subvalue1: 'hello', subvalue2: 'value', subname3: 'world')))
23
+ .should == {name: {'subname1' => 'hello', 'subname2' => 'value', 'subname3' => 'world'}} }
24
+ specify { field.compose(double(value: [
25
+ double(subvalue1: 'hello1', subvalue2: 'value1', subname3: 'world1'),
26
+ double(subvalue1: 'hello2', subvalue2: 'value2', subname3: 'world2')
27
+ ])).should == {name: [
28
+ {'subname1' => 'hello1', 'subname2' => 'value1', 'subname3' => 'world1'},
29
+ {'subname1' => 'hello2', 'subname2' => 'value2', 'subname3' => 'world2'}
30
+ ]} }
25
31
  end
26
32
 
27
33
  context do
@@ -6,48 +6,48 @@ describe Chewy::Index::Actions do
6
6
 
7
7
  before { stub_index :dummies }
8
8
 
9
- describe '.index_exists?' do
10
- specify { DummiesIndex.index_exists?.should be_false }
9
+ describe '.exists?' do
10
+ specify { DummiesIndex.exists?.should be_false }
11
11
 
12
12
  context do
13
- before { DummiesIndex.index_create }
14
- specify { DummiesIndex.index_exists?.should be_true }
13
+ before { DummiesIndex.create }
14
+ specify { DummiesIndex.exists?.should be_true }
15
15
  end
16
16
  end
17
17
 
18
- describe '.index_create' do
19
- specify { DummiesIndex.index_create.should be_true }
18
+ describe '.create' do
19
+ specify { DummiesIndex.create.should be_true }
20
20
 
21
21
  context do
22
- before { DummiesIndex.index_create }
23
- specify { DummiesIndex.index_create.should be_false }
22
+ before { DummiesIndex.create }
23
+ specify { DummiesIndex.create.should be_false }
24
24
  end
25
25
  end
26
26
 
27
- describe '.index_create!' do
28
- specify { expect { DummiesIndex.index_create! }.not_to raise_error }
27
+ describe '.create!' do
28
+ specify { expect { DummiesIndex.create! }.not_to raise_error }
29
29
 
30
30
  context do
31
- before { DummiesIndex.index_create }
32
- specify { expect { DummiesIndex.index_create! }.to raise_error }
31
+ before { DummiesIndex.create }
32
+ specify { expect { DummiesIndex.create! }.to raise_error }
33
33
  end
34
34
  end
35
35
 
36
- describe '.index_delete' do
37
- specify { DummiesIndex.index_delete.should be_false }
36
+ describe '.delete' do
37
+ specify { DummiesIndex.delete.should be_false }
38
38
 
39
39
  context do
40
- before { DummiesIndex.index_create }
41
- specify { DummiesIndex.index_delete.should be_true }
40
+ before { DummiesIndex.create }
41
+ specify { DummiesIndex.delete.should be_true }
42
42
  end
43
43
  end
44
44
 
45
- describe '.index_delete!' do
46
- specify { expect { DummiesIndex.index_delete! }.to raise_error }
45
+ describe '.delete!' do
46
+ specify { expect { DummiesIndex.delete! }.to raise_error }
47
47
 
48
48
  context do
49
- before { DummiesIndex.index_create }
50
- specify { expect { DummiesIndex.index_delete! }.not_to raise_error }
49
+ before { DummiesIndex.create }
50
+ specify { expect { DummiesIndex.delete! }.not_to raise_error }
51
51
  end
52
52
  end
53
53
  end
@@ -10,12 +10,12 @@ describe Chewy::Index::Search do
10
10
  end
11
11
  end
12
12
 
13
- let(:product) { ProductsIndex.product }
13
+ let(:product) { ProductsIndex::Product }
14
14
 
15
- describe '.search' do
16
- specify do
17
- product.search.should be_a Chewy::Query
18
- end
15
+ describe '.all' do
16
+ specify { product.all.should be_a Chewy::Query }
17
+ specify { product.all.object_id.should_not == product.all.object_id }
18
+ specify { product.all.should == product.all }
19
19
  end
20
20
 
21
21
  describe '.search_string' do
@@ -3,20 +3,40 @@ require 'spec_helper'
3
3
  describe Chewy::Index do
4
4
  include ClassHelpers
5
5
 
6
- describe '.define_type' do
7
- context 'blank name' do
6
+ before do
7
+ stub_index(:dummies) do
8
+ define_type :dummy
9
+ end
10
+ end
11
+
12
+ describe '.client' do
13
+ specify { stub_index(:dummies1).client.should == stub_index(:dummies2).client }
14
+
15
+ context do
8
16
  before do
9
- stub_index(:dummies) do
10
- define_type :dummy
11
- end
17
+ stub_index(:dummies1)
18
+ stub_index(:dummies2, Dummies1Index)
12
19
  end
13
20
 
14
- specify { DummiesIndex.types.should have_key 'dummy' }
15
- specify { DummiesIndex.types['dummy'].should be < Chewy::Type::Base }
16
- specify { DummiesIndex.types['dummy'].type_name.should == 'dummy' }
21
+ specify { Dummies1Index.client.should == Dummies2Index.client }
17
22
  end
18
23
  end
19
24
 
25
+ describe '.type_hash' do
26
+ specify { DummiesIndex.type_hash['dummy'].should == DummiesIndex::Dummy }
27
+ specify { DummiesIndex.type_hash.should have_key 'dummy' }
28
+ specify { DummiesIndex.type_hash['dummy'].should be < Chewy::Type::Base }
29
+ specify { DummiesIndex.type_hash['dummy'].type_name.should == 'dummy' }
30
+ end
31
+
32
+ specify { DummiesIndex.type_names.should == DummiesIndex.type_hash.keys }
33
+
34
+ describe '.types' do
35
+ specify { DummiesIndex.types.should == DummiesIndex.type_hash.values }
36
+ specify { DummiesIndex.types(:dummy).should be_a Chewy::Query }
37
+ specify { DummiesIndex.types(:user).should be_a Chewy::Query }
38
+ end
39
+
20
40
  describe '.index_name' do
21
41
  specify { expect { Class.new(Chewy::Index).index_name }.to raise_error Chewy::UndefinedIndex }
22
42
  specify { Class.new(Chewy::Index) { index_name :myindex }.index_name.should == 'myindex' }
@@ -0,0 +1,173 @@
1
+ require 'spec_helper'
2
+
3
+ describe Chewy::Query::Context do
4
+ def Bool options
5
+ Chewy::Query::Nodes::Bool.new.tap do |bool|
6
+ bool.must(*options[:must]) if options[:must].present?
7
+ bool.must_not(*options[:must_not]) if options[:must_not].present?
8
+ bool.should(*options[:should]) if options[:should].present?
9
+ end
10
+ end
11
+
12
+ %w(field group and or not raw exists missing prefix regexp range equal query script).each do |method|
13
+ define_method method.camelize do |*args|
14
+ "Chewy::Query::Nodes::#{method.camelize}".constantize.new *args
15
+ end
16
+ end
17
+
18
+ def query &block
19
+ Chewy::Query::Context.new(&block).__result__
20
+ end
21
+
22
+ context 'outer scope' do
23
+ let(:email) { 'email' }
24
+ specify { query { email }.should be_eql Field(:email) }
25
+ specify { query { o{email} }.should == 'email' }
26
+ end
27
+
28
+ context 'field' do
29
+ let(:email) { 'email' }
30
+ specify { query { f(:email) }.should be_eql Field(:email) }
31
+ specify { query { f{ :email } }.should be_eql Field(:email) }
32
+ specify { query { f{ email } }.should be_eql Field(:email) }
33
+ specify { query { email }.should be_eql Field(:email) }
34
+ specify { query { emails.first }.should be_eql Field('emails.first') }
35
+ specify { query { emails.first.second }.should be_eql Field('emails.first.second') }
36
+ end
37
+
38
+ context 'term' do
39
+ specify { query { email == 'email' }.should be_eql Equal(:email, 'email') }
40
+ specify { query { name != 'name' }.should be_eql Not(Equal(:name, 'name')) }
41
+ specify { query { email == ['email1', 'email2'] }.should be_eql Equal(:email, ['email1', 'email2']) }
42
+ specify { query { email != ['email1', 'email2'] }.should be_eql Not(Equal(:email, ['email1', 'email2'])) }
43
+ specify { query { email(execution: :bool) == ['email1', 'email2'] }
44
+ .should be_eql Equal(:email, ['email1', 'email2'], execution: :bool) }
45
+ specify { query { email(:bool) == ['email1', 'email2'] }
46
+ .should be_eql Equal(:email, ['email1', 'email2'], execution: :bool) }
47
+ specify { query { email(:b) == ['email1', 'email2'] }
48
+ .should be_eql Equal(:email, ['email1', 'email2'], execution: :bool) }
49
+ end
50
+
51
+ context 'bool' do
52
+ specify { query { must(email == 'email') }.should be_eql Bool(must: [Equal(:email, 'email')]) }
53
+ specify { query { must_not(email == 'email') }.should be_eql Bool(must_not: [Equal(:email, 'email')]) }
54
+ specify { query { should(email == 'email') }.should be_eql Bool(should: [Equal(:email, 'email')]) }
55
+ specify { query {
56
+ must(email == 'email').should(address != 'address', age == 42)
57
+ .must_not(sex == 'm').must(name == 'name')
58
+ }.should be_eql Bool(
59
+ must: [Equal(:email, 'email'), Equal(:name, 'name')],
60
+ must_not: [Equal(:sex, 'm')],
61
+ should: [Not(Equal(:address, 'address')), Equal(:age, 42)]
62
+ ) }
63
+ end
64
+
65
+ context 'exists' do
66
+ specify { query { email? }.should be_eql Exists(:email) }
67
+ specify { query { !!email? }.should be_eql Exists(:email) }
68
+ specify { query { emails.first? }.should be_eql Exists('emails.first') }
69
+ specify { query { !!emails.first? }.should be_eql Exists('emails.first') }
70
+ specify { query { emails != nil }.should be_eql Exists('emails') }
71
+ specify { query { !(emails == nil) }.should be_eql Exists('emails') }
72
+ end
73
+
74
+ context 'missing' do
75
+ specify { query { !email }.should be_eql Missing(:email) }
76
+ specify { query { !email? }.should be_eql Missing(:email, null_value: true) }
77
+ specify { query { !emails.first }.should be_eql Missing('emails.first') }
78
+ specify { query { !emails.first? }.should be_eql Missing('emails.first', null_value: true) }
79
+ specify { query { emails == nil }.should be_eql Missing('emails', existence: false, null_value: true) }
80
+ specify { query { emails.first == nil }.should be_eql Missing('emails.first', existence: false, null_value: true) }
81
+ end
82
+
83
+ context 'range' do
84
+ specify { query { age > 42 }.should be_eql Range(:age, gt: 42) }
85
+ specify { query { age >= 42 }.should be_eql Range(:age, gt: 42, left_closed: true) }
86
+ specify { query { age < 42 }.should be_eql Range(:age, lt: 42) }
87
+ specify { query { age <= 42 }.should be_eql Range(:age, lt: 42, right_closed: true) }
88
+
89
+ specify { query { age == (30..42) }.should be_eql Range(:age, gt: 30, lt: 42) }
90
+ specify { query { age == [30..42] }.should be_eql Range(:age, gt: 30, lt: 42, left_closed: true, right_closed: true) }
91
+ specify { query { (age > 30) & (age < 42) }.should be_eql Range(:age, gt: 30, lt: 42) }
92
+ specify { query { (age > 30) & (age <= 42) }.should be_eql Range(:age, gt: 30, lt: 42, right_closed: true) }
93
+ specify { query { (age >= 30) & (age < 42) }.should be_eql Range(:age, gt: 30, lt: 42, left_closed: true) }
94
+ specify { query { (age >= 30) & (age <= 42) }.should be_eql Range(:age, gt: 30, lt: 42, right_closed: true, left_closed: true) }
95
+ specify { query { (age > 30) | (age < 42) }.should be_eql Or(Range(:age, gt: 30), Range(:age, lt: 42)) }
96
+ end
97
+
98
+ context 'prefix' do
99
+ specify { query { name =~ 'nam' }.should be_eql Prefix(:name, 'nam') }
100
+ specify { query { name !~ 'nam' }.should be_eql Not(Prefix(:name, 'nam')) }
101
+ end
102
+
103
+ context 'regexp' do
104
+ specify { query { name =~ /name/ }.should be_eql Regexp(:name, 'name') }
105
+ specify { query { name == /name/ }.should be_eql Regexp(:name, 'name') }
106
+ specify { query { name !~ /name/ }.should be_eql Not(Regexp(:name, 'name')) }
107
+ specify { query { name != /name/ }.should be_eql Not(Regexp(:name, 'name')) }
108
+ specify { query { name(:anystring, :intersection) =~ /name/ }.should be_eql Regexp(:name, 'name', flags: %w(anystring intersection)) }
109
+ end
110
+
111
+ context 'query' do
112
+ let(:some_query) { 'some query' }
113
+ specify { query { q('some query') }.should be_eql Query('some query') }
114
+ specify { query { q{'some query'} }.should be_eql Query('some query') }
115
+ specify { query { q{ some_query } }.should be_eql Query('some query') }
116
+ end
117
+
118
+ context 'raw' do
119
+ let(:raw_query) { {term: {name: 'name'}} }
120
+ specify { query { r(term: {name: 'name'}) }.should be_eql Raw(term: {name: 'name'}) }
121
+ specify { query { r{ {term: {name: 'name'}} } }.should be_eql Raw(term: {name: 'name'}) }
122
+ specify { query { r{ raw_query } }.should be_eql Raw(term: {name: 'name'}) }
123
+ end
124
+
125
+ context 'script' do
126
+ let(:some_script) { 'some script' }
127
+ specify { query { s('some script') }.should be_eql Script('some script') }
128
+ specify { query { s('some script', param1: 42) }.should be_eql Script('some script', param1: 42) }
129
+ specify { query { s{'some script'} }.should be_eql Script('some script') }
130
+ specify { query { s(param1: 42) { some_script } }.should be_eql Script('some script', param1: 42) }
131
+ end
132
+
133
+ context 'and or not' do
134
+ specify { query { (email == 'email') & (name == 'name') }
135
+ .should be_eql And(Equal(:email, 'email'), Equal(:name, 'name')) }
136
+ specify { query { (email == 'email') | (name == 'name') }
137
+ .should be_eql Or(Equal(:email, 'email'), Equal(:name, 'name')) }
138
+ specify { query { !(email == 'email') }.should be_eql Not(Equal(:email, 'email')) }
139
+
140
+ specify { query { (email == 'email') & (name == 'name') | (address != 'address') }
141
+ .should be_eql Or(
142
+ And(
143
+ Equal(:email, 'email'),
144
+ Equal(:name, 'name')
145
+ ),
146
+ Not(Equal(:address, 'address'))
147
+ ) }
148
+ specify { query { (email == 'email') & ((name == 'name') | (address != 'address')) }
149
+ .should be_eql And(
150
+ Equal(:email, 'email'),
151
+ Or(
152
+ Equal(:name, 'name'),
153
+ Not(Equal(:address, 'address')),
154
+ )
155
+ ) }
156
+ specify { query { (email == 'email') & ((name == 'name') & (address != 'address')) }
157
+ .should be_eql And(
158
+ Equal(:email, 'email'),
159
+ Equal(:name, 'name'),
160
+ Not(Equal(:address, 'address')),
161
+ ) }
162
+ specify { query { ((email == 'email') | (name == 'name')) | (address != 'address') }
163
+ .should be_eql Or(
164
+ Equal(:email, 'email'),
165
+ Equal(:name, 'name'),
166
+ Not(Equal(:address, 'address')),
167
+ ) }
168
+ specify { query { !((email == 'email') | (name == 'name')) }
169
+ .should be_eql Not(Or(Equal(:email, 'email'), Equal(:name, 'name'))) }
170
+ specify { query { !!((email == 'email') | (name == 'name')) }
171
+ .should be_eql Or(Equal(:email, 'email'), Equal(:name, 'name')) }
172
+ end
173
+ end