chewy 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +13 -5
- data/.gitignore +1 -0
- data/.travis.yml +5 -3
- data/CHANGELOG.md +75 -0
- data/README.md +487 -92
- data/Rakefile +3 -2
- data/chewy.gemspec +2 -2
- data/filters +76 -0
- data/lib/chewy.rb +5 -3
- data/lib/chewy/config.rb +36 -19
- data/lib/chewy/fields/base.rb +5 -1
- data/lib/chewy/index.rb +22 -10
- data/lib/chewy/index/actions.rb +13 -13
- data/lib/chewy/index/search.rb +7 -2
- data/lib/chewy/query.rb +382 -64
- data/lib/chewy/query/context.rb +174 -0
- data/lib/chewy/query/criteria.rb +127 -34
- data/lib/chewy/query/loading.rb +9 -9
- data/lib/chewy/query/nodes/and.rb +25 -0
- data/lib/chewy/query/nodes/base.rb +17 -0
- data/lib/chewy/query/nodes/bool.rb +32 -0
- data/lib/chewy/query/nodes/equal.rb +34 -0
- data/lib/chewy/query/nodes/exists.rb +20 -0
- data/lib/chewy/query/nodes/expr.rb +28 -0
- data/lib/chewy/query/nodes/field.rb +106 -0
- data/lib/chewy/query/nodes/missing.rb +20 -0
- data/lib/chewy/query/nodes/not.rb +25 -0
- data/lib/chewy/query/nodes/or.rb +25 -0
- data/lib/chewy/query/nodes/prefix.rb +18 -0
- data/lib/chewy/query/nodes/query.rb +20 -0
- data/lib/chewy/query/nodes/range.rb +63 -0
- data/lib/chewy/query/nodes/raw.rb +15 -0
- data/lib/chewy/query/nodes/regexp.rb +31 -0
- data/lib/chewy/query/nodes/script.rb +20 -0
- data/lib/chewy/query/pagination.rb +28 -22
- data/lib/chewy/railtie.rb +23 -0
- data/lib/chewy/rspec/update_index.rb +20 -3
- data/lib/chewy/type/adapter/active_record.rb +78 -5
- data/lib/chewy/type/adapter/base.rb +46 -0
- data/lib/chewy/type/adapter/object.rb +40 -8
- data/lib/chewy/type/base.rb +1 -1
- data/lib/chewy/type/import.rb +18 -44
- data/lib/chewy/type/observe.rb +24 -14
- data/lib/chewy/version.rb +1 -1
- data/lib/tasks/chewy.rake +27 -0
- data/spec/chewy/config_spec.rb +30 -12
- data/spec/chewy/fields/base_spec.rb +11 -5
- data/spec/chewy/index/actions_spec.rb +20 -20
- data/spec/chewy/index/search_spec.rb +5 -5
- data/spec/chewy/index_spec.rb +28 -8
- data/spec/chewy/query/context_spec.rb +173 -0
- data/spec/chewy/query/criteria_spec.rb +219 -12
- data/spec/chewy/query/loading_spec.rb +6 -4
- data/spec/chewy/query/nodes/and_spec.rb +16 -0
- data/spec/chewy/query/nodes/bool_spec.rb +22 -0
- data/spec/chewy/query/nodes/equal_spec.rb +32 -0
- data/spec/chewy/query/nodes/exists_spec.rb +18 -0
- data/spec/chewy/query/nodes/missing_spec.rb +15 -0
- data/spec/chewy/query/nodes/not_spec.rb +16 -0
- data/spec/chewy/query/nodes/or_spec.rb +16 -0
- data/spec/chewy/query/nodes/prefix_spec.rb +16 -0
- data/spec/chewy/query/nodes/query_spec.rb +12 -0
- data/spec/chewy/query/nodes/range_spec.rb +32 -0
- data/spec/chewy/query/nodes/raw_spec.rb +11 -0
- data/spec/chewy/query/nodes/regexp_spec.rb +31 -0
- data/spec/chewy/query/nodes/script_spec.rb +15 -0
- data/spec/chewy/query/pagination_spec.rb +3 -2
- data/spec/chewy/query_spec.rb +83 -26
- data/spec/chewy/rspec/update_index_spec.rb +20 -0
- data/spec/chewy/type/adapter/active_record_spec.rb +102 -0
- data/spec/chewy/type/adapter/object_spec.rb +82 -0
- data/spec/chewy/type/import_spec.rb +30 -1
- data/spec/chewy/type/mapping_spec.rb +1 -1
- data/spec/chewy/type/observe_spec.rb +46 -12
- data/spec/spec_helper.rb +7 -6
- data/spec/support/class_helpers.rb +2 -2
- metadata +98 -48
- data/.rvmrc +0 -1
- data/lib/chewy/index/client.rb +0 -13
- data/spec/chewy/index/client_spec.rb +0 -18
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Chewy::Query::Nodes::Range do
|
4
|
+
describe '#__render__' do
|
5
|
+
def render &block
|
6
|
+
Chewy::Query::Context.new(&block).__render__
|
7
|
+
end
|
8
|
+
|
9
|
+
specify { render { age > nil }.should == {range: {'age' => {gt: nil}}} }
|
10
|
+
specify { render { age == (nil..nil) }.should == {range: {'age' => {gt: nil, lt: nil}}} }
|
11
|
+
|
12
|
+
specify { render { age > 42 }.should == {range: {'age' => {gt: 42}}} }
|
13
|
+
specify { render { age == (42..45) }.should == {range: {'age' => {gt: 42, lt: 45}}} }
|
14
|
+
specify { render { age == [42..45] }.should == {range: {'age' => {gte: 42, lte: 45}}} }
|
15
|
+
specify { render { (age > 42) & (age <= 45) }.should == {range: {'age' => {gt: 42, lte: 45}}} }
|
16
|
+
|
17
|
+
specify { render { ~age > 42 }.should == {range: {'age' => {gt: 42}, _cache: true}} }
|
18
|
+
specify { render { ~age == (42..45) }.should == {range: {'age' => {gt: 42, lt: 45}, _cache: true}} }
|
19
|
+
specify { render { ~age == [42..45] }.should == {range: {'age' => {gte: 42, lte: 45}, _cache: true}} }
|
20
|
+
specify { render { (age > 42) & ~(age <= 45) }.should == {range: {'age' => {gt: 42, lte: 45}, _cache: true}} }
|
21
|
+
specify { render { (~age > 42) & (age <= 45) }.should == {range: {'age' => {gt: 42, lte: 45}, _cache: true}} }
|
22
|
+
|
23
|
+
specify { render { age(:i) > 42 }.should == {range: {'age' => {gt: 42}, execution: :index}} }
|
24
|
+
specify { render { age(:index) > 42 }.should == {range: {'age' => {gt: 42}, execution: :index}} }
|
25
|
+
specify { render { age(:f) > 42 }.should == {range: {'age' => {gt: 42}, execution: :fielddata}} }
|
26
|
+
specify { render { age(:fielddata) > 42 }.should == {range: {'age' => {gt: 42}, execution: :fielddata}} }
|
27
|
+
specify { render { (age(:f) > 42) & (age <= 45) }.should == {range: {'age' => {gt: 42, lte: 45}, execution: :fielddata}} }
|
28
|
+
|
29
|
+
specify { render { ~age(:f) > 42 }.should == {range: {'age' => {gt: 42}, execution: :fielddata, _cache: true}} }
|
30
|
+
specify { render { (age(:f) > 42) & (~age <= 45) }.should == {range: {'age' => {gt: 42, lte: 45}, execution: :fielddata, _cache: true}} }
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Chewy::Query::Nodes::Raw do
|
4
|
+
describe '#__render__' do
|
5
|
+
def render &block
|
6
|
+
Chewy::Query::Context.new(&block).__render__
|
7
|
+
end
|
8
|
+
|
9
|
+
specify { render { r(term: {name: 'name'}) }.should == {term: {name: 'name'}} }
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Chewy::Query::Nodes::Regexp do
|
4
|
+
describe '#__render__' do
|
5
|
+
def render &block
|
6
|
+
Chewy::Query::Context.new(&block).__render__
|
7
|
+
end
|
8
|
+
|
9
|
+
specify { render { names.first == /nam.*/ }.should == {regexp: {'names.first' => 'nam.*'}} }
|
10
|
+
specify { render { names.first =~ /nam.*/ }.should == {regexp: {'names.first' => 'nam.*'}} }
|
11
|
+
specify { render { name != /nam.*/ }.should == {not: {regexp: {'name' => 'nam.*'}}} }
|
12
|
+
specify { render { name !~ /nam.*/ }.should == {not: {regexp: {'name' => 'nam.*'}}} }
|
13
|
+
|
14
|
+
specify { render { names.first(flags: [:anystring, :intersection, :borogoves]) == /nam.*/ }
|
15
|
+
.should == {regexp: {'names.first' => {value: 'nam.*', flags: 'ANYSTRING|INTERSECTION'}}} }
|
16
|
+
specify { render { names.first(:anystring, :intersection, :borogoves) == /nam.*/ }
|
17
|
+
.should == {regexp: {'names.first' => {value: 'nam.*', flags: 'ANYSTRING|INTERSECTION'}}} }
|
18
|
+
|
19
|
+
specify { render { names.first(flags: [:anystring, :intersection, :borogoves]) =~ /nam.*/ }
|
20
|
+
.should == {regexp: {'names.first' => {value: 'nam.*', flags: 'ANYSTRING|INTERSECTION'}}} }
|
21
|
+
specify { render { names.first(:anystring, :intersection, :borogoves) =~ /nam.*/ }
|
22
|
+
.should == {regexp: {'names.first' => {value: 'nam.*', flags: 'ANYSTRING|INTERSECTION'}}} }
|
23
|
+
|
24
|
+
specify { render { ~names.first == /nam.*/ }.should == {regexp: {'names.first' => 'nam.*', _cache: true, _cache_key: 'nam.*'}} }
|
25
|
+
specify { render { names.first(cache: 'name') == /nam.*/ }.should == {regexp: {'names.first' => 'nam.*', _cache: true, _cache_key: 'name'}} }
|
26
|
+
specify { render { ~names.first(:anystring) =~ /nam.*/ }
|
27
|
+
.should == {regexp: {'names.first' => {value: 'nam.*', flags: 'ANYSTRING'}, _cache: true, _cache_key: 'nam.*'}} }
|
28
|
+
specify { render { names.first(:anystring, cache: 'name') =~ /nam.*/ }
|
29
|
+
.should == {regexp: {'names.first' => {value: 'nam.*', flags: 'ANYSTRING'}, _cache: true, _cache_key: 'name'}} }
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Chewy::Query::Nodes::Script do
|
4
|
+
describe '#__render__' do
|
5
|
+
def render &block
|
6
|
+
Chewy::Query::Context.new(&block).__render__
|
7
|
+
end
|
8
|
+
|
9
|
+
specify { render { s('var = val') }.should == {script: {script: 'var = val'}} }
|
10
|
+
specify { render { s('var = val', val: 42) }.should == {script: {script: 'var = val', params: {val: 42}}} }
|
11
|
+
|
12
|
+
specify { render { ~s('var = val') }.should == {script: {script: 'var = val', _cache: true}} }
|
13
|
+
specify { render { ~s('var = val', val: 42) }.should == {script: {script: 'var = val', params: {val: 42}, _cache: true}} }
|
14
|
+
end
|
15
|
+
end
|
@@ -2,6 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Chewy::Query::Pagination do
|
4
4
|
include ClassHelpers
|
5
|
+
before { Chewy::Index.client.indices.delete }
|
5
6
|
|
6
7
|
before do
|
7
8
|
stub_index(:products) do
|
@@ -12,10 +13,10 @@ describe Chewy::Query::Pagination do
|
|
12
13
|
end
|
13
14
|
let(:data) { 10.times.map { |i| {id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next}.stringify_keys! } }
|
14
15
|
|
15
|
-
before { ProductsIndex.
|
16
|
+
before { ProductsIndex::Product.import(data.map { |h| double(h) }) }
|
16
17
|
before { Kaminari.config.stub(default_per_page: 3) }
|
17
18
|
|
18
|
-
let(:search) { ProductsIndex.
|
19
|
+
let(:search) { ProductsIndex.order(:age) }
|
19
20
|
|
20
21
|
describe '#per, #page' do
|
21
22
|
specify { search.map { |e| e.attributes.except('_score') }.should == data }
|
data/spec/chewy/query_spec.rb
CHANGED
@@ -3,19 +3,39 @@ require 'spec_helper'
|
|
3
3
|
describe Chewy::Query do
|
4
4
|
include ClassHelpers
|
5
5
|
|
6
|
+
before { Chewy::Index.client.indices.delete }
|
6
7
|
before do
|
7
8
|
stub_index(:products) do
|
8
9
|
define_type :product do
|
9
10
|
field :name, :age
|
10
11
|
end
|
12
|
+
define_type :city
|
13
|
+
define_type :country
|
11
14
|
end
|
12
15
|
end
|
13
16
|
|
14
|
-
subject { described_class.new(ProductsIndex
|
17
|
+
subject { described_class.new(ProductsIndex) }
|
18
|
+
|
19
|
+
context 'integration' do
|
20
|
+
let(:products) { 3.times.map { |i| {id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next}.stringify_keys! } }
|
21
|
+
let(:cities) { 3.times.map { |i| {id: i.next.to_s}.stringify_keys! } }
|
22
|
+
let(:countries) { 3.times.map { |i| {id: i.next.to_s}.stringify_keys! } }
|
23
|
+
before { ProductsIndex::Product.import(products.map { |h| double(h) }) }
|
24
|
+
before { ProductsIndex::City.import(cities.map { |h| double(h) }) }
|
25
|
+
before { ProductsIndex::Country.import(countries.map { |h| double(h) }) }
|
26
|
+
|
27
|
+
specify { subject.count.should == 9 }
|
28
|
+
specify { subject.limit(6).count.should == 6 }
|
29
|
+
specify { subject.offset(6).count.should == 3 }
|
30
|
+
specify { subject.types(:product).count.should == 3 }
|
31
|
+
specify { subject.types(:product, :country).count.should == 6 }
|
32
|
+
specify { subject.filter(term: {age: 10}).count.should == 1 }
|
33
|
+
specify { subject.query(term: {age: 10}).count.should == 1 }
|
34
|
+
end
|
15
35
|
|
16
36
|
describe '#==' do
|
17
37
|
let(:data) { 3.times.map { |i| {id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next}.stringify_keys! } }
|
18
|
-
before { ProductsIndex.
|
38
|
+
before { ProductsIndex::Product.import(data.map { |h| double(h) }) }
|
19
39
|
|
20
40
|
specify { subject.query(match: 'hello').should == subject.query(match: 'hello') }
|
21
41
|
specify { subject.query(match: 'hello').should_not == subject.query(match: 'world') }
|
@@ -24,39 +44,39 @@ describe Chewy::Query do
|
|
24
44
|
specify { subject.limit(2).should == subject.limit(2).to_a }
|
25
45
|
end
|
26
46
|
|
27
|
-
describe '#
|
28
|
-
specify { subject.
|
29
|
-
specify { subject.
|
30
|
-
|
31
|
-
specify { subject.
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
specify { subject.
|
36
|
-
|
37
|
-
specify { subject.
|
38
|
-
|
47
|
+
describe '#query_mode' do
|
48
|
+
specify { subject.query_mode(:should).should be_a described_class }
|
49
|
+
specify { subject.query_mode(:should).should_not == subject }
|
50
|
+
specify { subject.query_mode(:should).criteria.options.should include(query_mode: :should) }
|
51
|
+
specify { expect { subject.query_mode(:should) }.not_to change { subject.criteria.options } }
|
52
|
+
end
|
53
|
+
|
54
|
+
describe '#filter_mode' do
|
55
|
+
specify { subject.filter_mode(:or).should be_a described_class }
|
56
|
+
specify { subject.filter_mode(:or).should_not == subject }
|
57
|
+
specify { subject.filter_mode(:or).criteria.options.should include(filter_mode: :or) }
|
58
|
+
specify { expect { subject.filter_mode(:or) }.not_to change { subject.criteria.options } }
|
39
59
|
end
|
40
60
|
|
41
61
|
describe '#limit' do
|
42
62
|
specify { subject.limit(10).should be_a described_class }
|
43
63
|
specify { subject.limit(10).should_not == subject }
|
44
|
-
specify { subject.limit(10).criteria.
|
45
|
-
specify { expect { subject.limit(10) }.not_to change { subject.criteria.
|
64
|
+
specify { subject.limit(10).criteria.options.should include(size: 10) }
|
65
|
+
specify { expect { subject.limit(10) }.not_to change { subject.criteria.options } }
|
46
66
|
end
|
47
67
|
|
48
68
|
describe '#offset' do
|
49
69
|
specify { subject.offset(10).should be_a described_class }
|
50
70
|
specify { subject.offset(10).should_not == subject }
|
51
|
-
specify { subject.offset(10).criteria.
|
52
|
-
specify { expect { subject.offset(10) }.not_to change { subject.criteria.
|
71
|
+
specify { subject.offset(10).criteria.options.should include(from: 10) }
|
72
|
+
specify { expect { subject.offset(10) }.not_to change { subject.criteria.options } }
|
53
73
|
end
|
54
74
|
|
55
75
|
describe '#query' do
|
56
76
|
specify { subject.query(match: 'hello').should be_a described_class }
|
57
77
|
specify { subject.query(match: 'hello').should_not == subject }
|
58
|
-
specify { subject.query(match: 'hello').criteria.
|
59
|
-
specify { expect { subject.query(match: 'hello') }.not_to change { subject.criteria.
|
78
|
+
specify { subject.query(match: 'hello').criteria.queries.should include(match: 'hello') }
|
79
|
+
specify { expect { subject.query(match: 'hello') }.not_to change { subject.criteria.queries } }
|
60
80
|
end
|
61
81
|
|
62
82
|
describe '#facets' do
|
@@ -69,16 +89,17 @@ describe Chewy::Query do
|
|
69
89
|
describe '#filter' do
|
70
90
|
specify { subject.filter(term: {field: 'hello'}).should be_a described_class }
|
71
91
|
specify { subject.filter(term: {field: 'hello'}).should_not == subject }
|
72
|
-
specify { subject.filter(term: {field: 'hello'}).criteria.filters.should include(term: {field: 'hello'}) }
|
73
|
-
specify { subject.filter([{term: {field: 'hello'}}, {term: {field: 'world'}}]).criteria.filters.should include(term: {field: 'hello'}) }
|
74
|
-
specify { subject.filter([{term: {field: 'hello'}}, {term: {field: 'world'}}]).criteria.filters.should include(term: {field: 'world'}) }
|
75
92
|
specify { expect { subject.filter(term: {field: 'hello'}) }.not_to change { subject.criteria.filters } }
|
93
|
+
specify { subject.filter([{term: {field: 'hello'}}, {term: {field: 'world'}}]).criteria.filters
|
94
|
+
.should == [{term: {field: 'hello'}}, {term: {field: 'world'}}] }
|
95
|
+
|
96
|
+
specify { expect { subject.filter{ name == 'John' } }.not_to change { subject.criteria.filters } }
|
97
|
+
specify { subject.filter{ name == 'John' }.criteria.filters.should == [{term: {'name' => 'John'}}] }
|
76
98
|
end
|
77
99
|
|
78
100
|
describe '#order' do
|
79
101
|
specify { subject.order(field: 'hello').should be_a described_class }
|
80
102
|
specify { subject.order(field: 'hello').should_not == subject }
|
81
|
-
specify { subject.order(field: 'hello').criteria.sort.should include(field: 'hello') }
|
82
103
|
specify { expect { subject.order(field: 'hello') }.not_to change { subject.criteria.sort } }
|
83
104
|
|
84
105
|
specify { subject.order(:field).criteria.sort.should == [:field] }
|
@@ -90,7 +111,6 @@ describe Chewy::Query do
|
|
90
111
|
describe '#reorder' do
|
91
112
|
specify { subject.reorder(field: 'hello').should be_a described_class }
|
92
113
|
specify { subject.reorder(field: 'hello').should_not == subject }
|
93
|
-
specify { subject.reorder(field: 'hello').criteria.sort.should include(field: 'hello') }
|
94
114
|
specify { expect { subject.reorder(field: 'hello') }.not_to change { subject.criteria.sort } }
|
95
115
|
|
96
116
|
specify { subject.order(:field1).reorder(:field2).criteria.sort.should == [:field2] }
|
@@ -101,10 +121,47 @@ describe Chewy::Query do
|
|
101
121
|
describe '#only' do
|
102
122
|
specify { subject.only(:field).should be_a described_class }
|
103
123
|
specify { subject.only(:field).should_not == subject }
|
104
|
-
specify { subject.only(:field).criteria.fields.should include('field') }
|
105
124
|
specify { expect { subject.only(:field) }.not_to change { subject.criteria.fields } }
|
106
125
|
|
107
126
|
specify { subject.only(:field1, :field2).criteria.fields.should =~ ['field1', 'field2'] }
|
108
127
|
specify { subject.only([:field1, :field2]).only(:field3).criteria.fields.should =~ ['field1', 'field2', 'field3'] }
|
109
128
|
end
|
129
|
+
|
130
|
+
describe '#only!' do
|
131
|
+
specify { subject.only!(:field).should be_a described_class }
|
132
|
+
specify { subject.only!(:field).should_not == subject }
|
133
|
+
specify { expect { subject.only!(:field) }.not_to change { subject.criteria.fields } }
|
134
|
+
|
135
|
+
specify { subject.only!(:field1, :field2).criteria.fields.should =~ ['field1', 'field2'] }
|
136
|
+
specify { subject.only!([:field1, :field2]).only!(:field3).criteria.fields.should =~ ['field3'] }
|
137
|
+
specify { subject.only([:field1, :field2]).only!(:field3).criteria.fields.should =~ ['field3'] }
|
138
|
+
end
|
139
|
+
|
140
|
+
describe '#types' do
|
141
|
+
specify { subject.types(:product).should be_a described_class }
|
142
|
+
specify { subject.types(:product).should_not == subject }
|
143
|
+
specify { expect { subject.types(:product) }.not_to change { subject.criteria.types } }
|
144
|
+
|
145
|
+
specify { subject.types(:user).criteria.types.should == ['user'] }
|
146
|
+
specify { subject.types(:product, :city).criteria.types.should =~ ['product', 'city'] }
|
147
|
+
specify { subject.types([:product, :city]).types(:country).criteria.types.should =~ ['product', 'city', 'country'] }
|
148
|
+
end
|
149
|
+
|
150
|
+
describe '#types!' do
|
151
|
+
specify { subject.types!(:product).should be_a described_class }
|
152
|
+
specify { subject.types!(:product).should_not == subject }
|
153
|
+
specify { expect { subject.types!(:product) }.not_to change { subject.criteria.types } }
|
154
|
+
|
155
|
+
specify { subject.types!(:user).criteria.types.should == ['user'] }
|
156
|
+
specify { subject.types!(:product, :city).criteria.types.should =~ ['product', 'city'] }
|
157
|
+
specify { subject.types!([:product, :city]).types!(:country).criteria.types.should =~ ['country'] }
|
158
|
+
specify { subject.types([:product, :city]).types!(:country).criteria.types.should =~ ['country'] }
|
159
|
+
end
|
160
|
+
|
161
|
+
describe '#merge' do
|
162
|
+
let(:query) { described_class.new(ProductsIndex) }
|
163
|
+
|
164
|
+
specify { subject.filter { name == 'name' }.merge(query.filter { age == 42 }).criteria.filters
|
165
|
+
.should == [{term: {'name' => 'name'}}, {term: {'age' => 42}}] }
|
166
|
+
end
|
110
167
|
end
|
@@ -29,6 +29,26 @@ describe :update_index do
|
|
29
29
|
specify { expectation.to fail_matching 'document id `41` (1 times)' }
|
30
30
|
end
|
31
31
|
|
32
|
+
context '#only' do
|
33
|
+
specify { expect { DummiesIndex.dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 41, data: {}}}] }
|
34
|
+
.to update_index(DummiesIndex.dummy).and_reindex(41, 42).only }
|
35
|
+
specify { expect { expect { DummiesIndex.dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 41, data: {}}}] }
|
36
|
+
.to update_index(DummiesIndex.dummy).and_reindex(41).only }
|
37
|
+
.to fail_matching 'to update documents ["41"] only, but ["42"] was updated also' }
|
38
|
+
specify { expect { expect { DummiesIndex.dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 41, data: {}}}] }
|
39
|
+
.to update_index(DummiesIndex.dummy).and_reindex(41, times: 2).only }
|
40
|
+
.to fail_matching 'to update documents ["41"] only, but ["42"] was updated also' }
|
41
|
+
|
42
|
+
specify { expect { DummiesIndex.dummy.bulk body: [{delete: {_id: 42}}, {delete: {_id: 41}}] }
|
43
|
+
.to update_index(DummiesIndex.dummy).and_delete(41, 42).only }
|
44
|
+
specify { expect { expect { DummiesIndex.dummy.bulk body: [{delete: {_id: 42}}, {delete: {_id: 41}}] }
|
45
|
+
.to update_index(DummiesIndex.dummy).and_delete(41).only }
|
46
|
+
.to fail_matching 'to delete documents ["41"] only, but ["42"] was deleted also' }
|
47
|
+
specify { expect { expect { DummiesIndex.dummy.bulk body: [{delete: {_id: 42}}, {delete: {_id: 41}}] }
|
48
|
+
.to update_index(DummiesIndex.dummy).and_delete(41, times: 2).only }
|
49
|
+
.to fail_matching 'to delete documents ["41"] only, but ["42"] was deleted also' }
|
50
|
+
end
|
51
|
+
|
32
52
|
context '#and_reindex' do
|
33
53
|
specify { expect { DummiesIndex.dummy.bulk body: [{index: {_id: 42}}] }.to update_index(DummiesIndex.dummy) }
|
34
54
|
specify { expect { DummiesIndex.dummy.bulk body: [{index: {_id: 42, data: {}}}] }
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Chewy::Type::Adapter::ActiveRecord do
|
4
|
+
before { stub_model(:city) }
|
5
|
+
|
6
|
+
describe '#name' do
|
7
|
+
specify { described_class.new(City).name.should == 'City' }
|
8
|
+
specify { described_class.new(City.order(:id)).name.should == 'City' }
|
9
|
+
specify { described_class.new(City, name: 'town').name.should == 'Town' }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#type_name' do
|
13
|
+
specify { described_class.new(City).type_name.should == 'city' }
|
14
|
+
specify { described_class.new(City.order(:id)).type_name.should == 'city' }
|
15
|
+
specify { described_class.new(City, name: 'town').type_name.should == 'town' }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#import' do
|
19
|
+
def import(*args)
|
20
|
+
result = []
|
21
|
+
subject.import(*args) { |data| result.push data }
|
22
|
+
result
|
23
|
+
end
|
24
|
+
|
25
|
+
specify { subject.import(3.times.map { |i| City.create! }) { |data| true }.should be_true }
|
26
|
+
specify { subject.import(3.times.map { |i| City.create! }) { |data| false }.should be_false }
|
27
|
+
|
28
|
+
context do
|
29
|
+
let!(:cities) { 3.times.map { |i| City.create! } }
|
30
|
+
let!(:deleted) { 3.times.map { |i| City.create!.tap(&:destroy!) } }
|
31
|
+
subject { described_class.new(City) }
|
32
|
+
|
33
|
+
specify { import.should == [{index: cities}] }
|
34
|
+
|
35
|
+
specify { import(City.order(:id)).should == [{index: cities}] }
|
36
|
+
specify { import(City.order(:id), batch_size: 2)
|
37
|
+
.should == [{index: cities.first(2)}, {index: cities.last(1)}] }
|
38
|
+
|
39
|
+
specify { import(cities).should == [{index: cities}] }
|
40
|
+
specify { import(cities, batch_size: 2)
|
41
|
+
.should == [{index: cities.first(2)}, {index: cities.last(1)}] }
|
42
|
+
specify { import(cities, deleted).should == [{index: cities, delete: deleted}] }
|
43
|
+
specify { import(cities, deleted, batch_size: 2).should == [
|
44
|
+
{index: cities.first(2)},
|
45
|
+
{index: cities.last(1), delete: deleted.first(1)},
|
46
|
+
{delete: deleted.last(2)}] }
|
47
|
+
|
48
|
+
specify { import(cities.map(&:id)).should == [{index: cities}] }
|
49
|
+
specify { import(cities.map(&:id), batch_size: 2)
|
50
|
+
.should == [{index: cities.first(2)}, {index: cities.last(1)}] }
|
51
|
+
specify { import(cities.map(&:id), deleted.map(&:id))
|
52
|
+
.should == [{index: cities}, {delete: deleted.map(&:id)}] }
|
53
|
+
specify { import(cities.map(&:id), deleted.map(&:id), batch_size: 2).should == [
|
54
|
+
{index: cities.first(2)},
|
55
|
+
{index: cities.last(1)},
|
56
|
+
{delete: deleted.first(2).map(&:id)},
|
57
|
+
{delete: deleted.last(1).map(&:id)}] }
|
58
|
+
end
|
59
|
+
|
60
|
+
context do
|
61
|
+
let!(:cities) { 3.times.map { |i| City.create!(country_id: i/2) } }
|
62
|
+
let!(:deleted) { 2.times.map { |i| City.create!.tap(&:destroy!) } }
|
63
|
+
subject { described_class.new(City.where(country_id: 0)) }
|
64
|
+
|
65
|
+
specify { import.should == [{index: cities.first(2)}] }
|
66
|
+
|
67
|
+
specify { import(City.order(:id)).should == [{index: cities.first(2)}] }
|
68
|
+
specify { import(City.order(:id), batch_size: 1)
|
69
|
+
.should == [{index: [cities.first]}, {index: [cities.second]}] }
|
70
|
+
|
71
|
+
specify { import(cities).should == [{index: cities}] }
|
72
|
+
specify { import(cities, batch_size: 2)
|
73
|
+
.should == [{index: cities.first(2)}, {index: cities.last(1)}] }
|
74
|
+
|
75
|
+
specify { import(cities.map(&:id))
|
76
|
+
.should == [{index: cities.first(2)}, {delete: [cities.last.id]}] }
|
77
|
+
specify { import(cities.map(&:id), batch_size: 1)
|
78
|
+
.should == [{index: [cities.first]}, {index: [cities.second]}, {delete: [cities.last.id]}] }
|
79
|
+
specify { import(cities.map(&:id), deleted.map(&:id))
|
80
|
+
.should == [{index: cities.first(2)}, {delete: [cities.last.id] + deleted.map(&:id)}] }
|
81
|
+
specify { import(cities.map(&:id), deleted.map(&:id), batch_size: 2).should == [
|
82
|
+
{index: cities.first(2)},
|
83
|
+
{delete: [cities.last.id] + deleted.first(1).map(&:id)},
|
84
|
+
{delete: deleted.last(1).map(&:id)}] }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe '#load' do
|
89
|
+
let!(:cities) { 3.times.map { |i| City.create!(country_id: i/2) } }
|
90
|
+
let!(:deleted) { 2.times.map { |i| City.create!.tap(&:destroy!) } }
|
91
|
+
subject { described_class.new(City) }
|
92
|
+
|
93
|
+
specify { subject.load(cities.map { |c| double(id: c.id) }).should == cities }
|
94
|
+
specify { subject.load(cities.map { |c| double(id: c.id) }.reverse).should == cities.reverse }
|
95
|
+
specify { subject.load(deleted.map { |c| double(id: c.id) }).should == [nil, nil] }
|
96
|
+
specify { subject.load((cities + deleted).map { |c| double(id: c.id) }).should == [*cities, nil, nil] }
|
97
|
+
specify { subject.load(cities.map { |c| double(id: c.id) }, scope: ->(_) { where(country_id: 0) })
|
98
|
+
.should == cities.first(2) + [nil] }
|
99
|
+
specify { subject.load(cities.map { |c| double(id: c.id) }, scope: City.where(country_id: 1))
|
100
|
+
.should == [nil, nil] + cities.last(1) }
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Chewy::Type::Adapter::Object do
|
4
|
+
before { stub_class(:product) }
|
5
|
+
|
6
|
+
describe '#name' do
|
7
|
+
specify { described_class.new('product').name.should == 'Product' }
|
8
|
+
specify { described_class.new(:products).name.should == 'Products' }
|
9
|
+
specify { described_class.new(Product).name.should == 'Product' }
|
10
|
+
specify { described_class.new(Product, name: 'house').name.should == 'House' }
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#type_name' do
|
14
|
+
specify { described_class.new('product').type_name.should == 'product' }
|
15
|
+
specify { described_class.new(:products).type_name.should == 'products' }
|
16
|
+
specify { described_class.new(Product).type_name.should == 'product' }
|
17
|
+
specify { described_class.new(Product, name: 'house').type_name.should == 'house' }
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#import' do
|
21
|
+
def import(*args)
|
22
|
+
result = []
|
23
|
+
subject.import(*args) { |data| result.push data }
|
24
|
+
result
|
25
|
+
end
|
26
|
+
|
27
|
+
specify { subject.import(3.times.map { |i| double }) { |data| true }.should be_true }
|
28
|
+
specify { subject.import(3.times.map { |i| double }) { |data| false }.should be_false }
|
29
|
+
|
30
|
+
context do
|
31
|
+
let(:objects) { 3.times.map { |i| double } }
|
32
|
+
let(:deleted) { 2.times.map { |i| double(destroyed?: true) } }
|
33
|
+
subject { described_class.new('product') }
|
34
|
+
|
35
|
+
specify { import.should == [] }
|
36
|
+
specify { import(objects).should == [{index: objects}] }
|
37
|
+
specify { import(objects, batch_size: 2)
|
38
|
+
.should == [{index: objects.first(2)}, {index: objects.last(1)}] }
|
39
|
+
specify { import(objects, deleted).should == [{index: objects, delete: deleted}] }
|
40
|
+
specify { import(objects, deleted, batch_size: 2).should == [
|
41
|
+
{index: objects.first(2)},
|
42
|
+
{index: objects.last(1), delete: deleted.first(1)},
|
43
|
+
{delete: deleted.last(1)}] }
|
44
|
+
end
|
45
|
+
|
46
|
+
context do
|
47
|
+
let(:products) { 3.times.map { |i| double.tap { |product|
|
48
|
+
product.stub(:is_a?).with(Product).and_return(true)
|
49
|
+
} } }
|
50
|
+
let(:non_product) { double }
|
51
|
+
subject { described_class.new(Product) }
|
52
|
+
|
53
|
+
specify { import(products).should == [{index: products}] }
|
54
|
+
specify { expect { import(products, non_product) {} }.to raise_error }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#load' do
|
59
|
+
context do
|
60
|
+
subject { described_class.new('product') }
|
61
|
+
let(:objects) { 3.times.map { |i| double } }
|
62
|
+
|
63
|
+
specify { subject.load(objects).should == objects }
|
64
|
+
end
|
65
|
+
|
66
|
+
context do
|
67
|
+
before { Product.stub(:wrap) { |object| object.stub(wrapped?: true); object } }
|
68
|
+
subject { described_class.new(Product) }
|
69
|
+
let(:objects) { 3.times.map { |i| double(wrapped?: false) } }
|
70
|
+
|
71
|
+
specify { subject.load(objects).should satisfy { |objects| objects.all?(&:wrapped?) } }
|
72
|
+
end
|
73
|
+
|
74
|
+
context do
|
75
|
+
before { Product.stub(:wrap) { |object| nil } }
|
76
|
+
subject { described_class.new(Product) }
|
77
|
+
let(:objects) { 3.times.map { |i| double(wrapped?: false) } }
|
78
|
+
|
79
|
+
specify { subject.load(objects).should satisfy { |objects| objects.all?(&:nil?) } }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|