chewy 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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