chewy 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +3 -0
  4. data/.rvmrc +1 -0
  5. data/.travis.yml +7 -0
  6. data/Gemfile +12 -0
  7. data/Guardfile +24 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +208 -0
  10. data/Rakefile +6 -0
  11. data/chewy.gemspec +32 -0
  12. data/lib/chewy.rb +55 -0
  13. data/lib/chewy/config.rb +48 -0
  14. data/lib/chewy/fields/base.rb +49 -0
  15. data/lib/chewy/fields/default.rb +10 -0
  16. data/lib/chewy/fields/root.rb +10 -0
  17. data/lib/chewy/index.rb +71 -0
  18. data/lib/chewy/index/actions.rb +43 -0
  19. data/lib/chewy/index/client.rb +13 -0
  20. data/lib/chewy/index/search.rb +26 -0
  21. data/lib/chewy/query.rb +141 -0
  22. data/lib/chewy/query/criteria.rb +81 -0
  23. data/lib/chewy/query/loading.rb +27 -0
  24. data/lib/chewy/query/pagination.rb +39 -0
  25. data/lib/chewy/rspec.rb +1 -0
  26. data/lib/chewy/rspec/update_index.rb +121 -0
  27. data/lib/chewy/type.rb +22 -0
  28. data/lib/chewy/type/adapter/active_record.rb +27 -0
  29. data/lib/chewy/type/adapter/object.rb +22 -0
  30. data/lib/chewy/type/base.rb +41 -0
  31. data/lib/chewy/type/import.rb +67 -0
  32. data/lib/chewy/type/mapping.rb +50 -0
  33. data/lib/chewy/type/observe.rb +37 -0
  34. data/lib/chewy/type/wrapper.rb +35 -0
  35. data/lib/chewy/version.rb +3 -0
  36. data/spec/chewy/config_spec.rb +50 -0
  37. data/spec/chewy/fields/base_spec.rb +70 -0
  38. data/spec/chewy/fields/default_spec.rb +6 -0
  39. data/spec/chewy/fields/root_spec.rb +6 -0
  40. data/spec/chewy/index/actions_spec.rb +53 -0
  41. data/spec/chewy/index/client_spec.rb +18 -0
  42. data/spec/chewy/index/search_spec.rb +54 -0
  43. data/spec/chewy/index_spec.rb +65 -0
  44. data/spec/chewy/query/criteria_spec.rb +73 -0
  45. data/spec/chewy/query/loading_spec.rb +37 -0
  46. data/spec/chewy/query/pagination_spec.rb +40 -0
  47. data/spec/chewy/query_spec.rb +110 -0
  48. data/spec/chewy/rspec/update_index_spec.rb +149 -0
  49. data/spec/chewy/type/import_spec.rb +68 -0
  50. data/spec/chewy/type/mapping_spec.rb +54 -0
  51. data/spec/chewy/type/observe_spec.rb +55 -0
  52. data/spec/chewy/type/wrapper_spec.rb +35 -0
  53. data/spec/chewy/type_spec.rb +43 -0
  54. data/spec/chewy_spec.rb +36 -0
  55. data/spec/spec_helper.rb +48 -0
  56. data/spec/support/class_helpers.rb +16 -0
  57. data/spec/support/fail_helpers.rb +13 -0
  58. metadata +249 -0
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe Chewy::Query::Loading do
4
+ include ClassHelpers
5
+ before { Chewy::Index.client.indices.delete }
6
+
7
+ before do
8
+ stub_model(:city)
9
+ stub_model(:country)
10
+ end
11
+
12
+ context 'multiple types' do
13
+ let(:cities) { 6.times.map { |i| City.create!(rating: i) } }
14
+ let(:countries) { 6.times.map { |i| Country.create!(rating: i) } }
15
+
16
+ before do
17
+ stub_index(:places) do
18
+ define_type City do
19
+ field :rating, type: 'number', value: ->(o){ o.rating }
20
+ end
21
+ define_type Country do
22
+ field :rating, type: 'number', value: ->(o){ o.rating }
23
+ end
24
+ end
25
+ end
26
+
27
+ before do
28
+ PlacesIndex.city.import(cities)
29
+ PlacesIndex.country.import(countries)
30
+ end
31
+
32
+ specify { PlacesIndex.search.order(:rating).limit(6).load.should =~ cities.first(3) + countries.first(3) }
33
+ specify { PlacesIndex.search.order(:rating).limit(6).load(scopes: {city: ->(i){ where('rating < 2') }})
34
+ .should =~ cities.first(2) + countries.first(3) }
35
+ specify { PlacesIndex.search.order(:rating).limit(6).load.total_count.should == 12 }
36
+ end
37
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe Chewy::Query::Pagination do
4
+ include ClassHelpers
5
+
6
+ before do
7
+ stub_index(:products) do
8
+ define_type(:product) do
9
+ field :name, :age
10
+ end
11
+ end
12
+ end
13
+ let(:data) { 10.times.map { |i| {id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next}.stringify_keys! } }
14
+
15
+ before { ProductsIndex.types['product'].import(data.map { |h| double(h) }) }
16
+ before { Kaminari.config.stub(default_per_page: 3) }
17
+
18
+ let(:search) { ProductsIndex.search.order(:age) }
19
+
20
+ describe '#per, #page' do
21
+ specify { search.map { |e| e.attributes.except('_score') }.should == data }
22
+ specify { search.page(1).map { |e| e.attributes.except('_score') }.should == data[0..2] }
23
+ specify { search.page(2).map { |e| e.attributes.except('_score') }.should == data[3..5] }
24
+ specify { search.page(2).per(4).map { |e| e.attributes.except('_score') }.should == data[4..7] }
25
+ specify { search.per(2).page(3).map { |e| e.attributes.except('_score') }.should == data[4..5] }
26
+ specify { search.per(5).page.map { |e| e.attributes.except('_score') }.should == data[0..4] }
27
+ specify { search.page.per(4).map { |e| e.attributes.except('_score') }.should == data[0..3] }
28
+ end
29
+
30
+ describe '#total_pages' do
31
+ specify { search.total_pages.should == 4 }
32
+ specify { search.per(5).page(2).total_pages.should == 2 }
33
+ specify { search.per(2).page(3).total_pages.should == 5 }
34
+ end
35
+
36
+ describe '#total_count' do
37
+ specify { search.per(4).page(1).total_count.should == 10 }
38
+ specify { search.filter(numeric_range: {age: {gt: 20}}).limit(3).total_count.should == 8 }
39
+ end
40
+ end
@@ -0,0 +1,110 @@
1
+ require 'spec_helper'
2
+
3
+ describe Chewy::Query do
4
+ include ClassHelpers
5
+
6
+ before do
7
+ stub_index(:products) do
8
+ define_type :product do
9
+ field :name, :age
10
+ end
11
+ end
12
+ end
13
+
14
+ subject { described_class.new(ProductsIndex, type: :product) }
15
+
16
+ describe '#==' do
17
+ let(:data) { 3.times.map { |i| {id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next}.stringify_keys! } }
18
+ before { ProductsIndex.types['product'].import(data.map { |h| double(h) }) }
19
+
20
+ specify { subject.query(match: 'hello').should == subject.query(match: 'hello') }
21
+ specify { subject.query(match: 'hello').should_not == subject.query(match: 'world') }
22
+ specify { subject.limit(10).should == subject.limit(10) }
23
+ specify { subject.limit(10).should_not == subject.limit(11) }
24
+ specify { subject.limit(2).should == subject.limit(2).to_a }
25
+ end
26
+
27
+ describe '#_request_query' do
28
+ specify { subject.send(:_request_query).should == {} }
29
+ specify { subject.filter(term: {field: 'hello'}).send(:_request_query)
30
+ .should == {query: {filtered: {query: {match_all: {}}, filter: {term: {field: "hello"}}}}} }
31
+ specify { subject.filter(term: {field: 'hello'}).filter(term: {field: 'world'}).send(:_request_query)
32
+ .should == {query: {filtered: {query: {match_all: {}}, filter: {and: [
33
+ {term: {field: "hello"}}, {term: {field: "world"}}
34
+ ]}}}} }
35
+ specify { subject.query(term: {field: 'hello'}).send(:_request_query)
36
+ .should == {query: {term: {field: "hello"}}} }
37
+ specify { subject.filter(term: {field: 'hello'}).query(term: {field: 'world'}).send(:_request_query)
38
+ .should == {query: {filtered: {query: {term: {field: "world"}}, filter: {term: {field: "hello"}}}}} }
39
+ end
40
+
41
+ describe '#limit' do
42
+ specify { subject.limit(10).should be_a described_class }
43
+ specify { subject.limit(10).should_not == subject }
44
+ specify { subject.limit(10).criteria.search.should include(size: 10) }
45
+ specify { expect { subject.limit(10) }.not_to change { subject.criteria.search } }
46
+ end
47
+
48
+ describe '#offset' do
49
+ specify { subject.offset(10).should be_a described_class }
50
+ specify { subject.offset(10).should_not == subject }
51
+ specify { subject.offset(10).criteria.search.should include(from: 10) }
52
+ specify { expect { subject.offset(10) }.not_to change { subject.criteria.search } }
53
+ end
54
+
55
+ describe '#query' do
56
+ specify { subject.query(match: 'hello').should be_a described_class }
57
+ specify { subject.query(match: 'hello').should_not == subject }
58
+ specify { subject.query(match: 'hello').criteria.query.should include(match: 'hello') }
59
+ specify { expect { subject.query(match: 'hello') }.not_to change { subject.criteria.query } }
60
+ end
61
+
62
+ describe '#facets' do
63
+ specify { subject.facets(term: {field: 'hello'}).should be_a described_class }
64
+ specify { subject.facets(term: {field: 'hello'}).should_not == subject }
65
+ specify { subject.facets(term: {field: 'hello'}).criteria.facets.should include(term: {field: 'hello'}) }
66
+ specify { expect { subject.facets(term: {field: 'hello'}) }.not_to change { subject.criteria.facets } }
67
+ end
68
+
69
+ describe '#filter' do
70
+ specify { subject.filter(term: {field: 'hello'}).should be_a described_class }
71
+ 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
+ specify { expect { subject.filter(term: {field: 'hello'}) }.not_to change { subject.criteria.filters } }
76
+ end
77
+
78
+ describe '#order' do
79
+ specify { subject.order(field: 'hello').should be_a described_class }
80
+ specify { subject.order(field: 'hello').should_not == subject }
81
+ specify { subject.order(field: 'hello').criteria.sort.should include(field: 'hello') }
82
+ specify { expect { subject.order(field: 'hello') }.not_to change { subject.criteria.sort } }
83
+
84
+ specify { subject.order(:field).criteria.sort.should == [:field] }
85
+ specify { subject.order([:field1, :field2]).criteria.sort.should == [:field1, :field2] }
86
+ specify { subject.order(field: :asc).criteria.sort.should == [{field: :asc}] }
87
+ specify { subject.order({field1: {order: :asc}, field2: :desc}).order([:field3], :field4).criteria.sort.should == [{field1: {order: :asc}}, {field2: :desc}, :field3, :field4] }
88
+ end
89
+
90
+ describe '#reorder' do
91
+ specify { subject.reorder(field: 'hello').should be_a described_class }
92
+ specify { subject.reorder(field: 'hello').should_not == subject }
93
+ specify { subject.reorder(field: 'hello').criteria.sort.should include(field: 'hello') }
94
+ specify { expect { subject.reorder(field: 'hello') }.not_to change { subject.criteria.sort } }
95
+
96
+ specify { subject.order(:field1).reorder(:field2).criteria.sort.should == [:field2] }
97
+ specify { subject.order(:field1).reorder(:field2).order(:field3).criteria.sort.should == [:field2, :field3] }
98
+ specify { subject.order(:field1).reorder(:field2).reorder(:field3).criteria.sort.should == [:field3] }
99
+ end
100
+
101
+ describe '#only' do
102
+ specify { subject.only(:field).should be_a described_class }
103
+ specify { subject.only(:field).should_not == subject }
104
+ specify { subject.only(:field).criteria.fields.should include('field') }
105
+ specify { expect { subject.only(:field) }.not_to change { subject.criteria.fields } }
106
+
107
+ specify { subject.only(:field1, :field2).criteria.fields.should =~ ['field1', 'field2'] }
108
+ specify { subject.only([:field1, :field2]).only(:field3).criteria.fields.should =~ ['field1', 'field2', 'field3'] }
109
+ end
110
+ end
@@ -0,0 +1,149 @@
1
+ require 'spec_helper'
2
+
3
+ describe :update_index do
4
+ include ClassHelpers
5
+ before { Chewy::Index.client.indices.delete }
6
+
7
+ before do
8
+ stub_index(:dummies) do
9
+ define_type :dummy do
10
+ root value: ->(o){{}}
11
+ end
12
+ end
13
+ end
14
+
15
+ specify { expect { }.not_to update_index(DummiesIndex.dummy) }
16
+ specify { expect { DummiesIndex.dummy.bulk body: [] }.not_to update_index(DummiesIndex.dummy) }
17
+
18
+ specify { expect { expect { DummiesIndex.dummy.bulk body: [{index: {_id: 42}}] }.not_to update_index(DummiesIndex.dummy) }
19
+ .to fail_with(/Expected index .* not to be updated, but it was with/) }
20
+
21
+ context do
22
+ let(:expectation) do
23
+ expect { expect {
24
+ DummiesIndex.dummy.bulk body: [{index: {_id: 42}}, {index: {_id: 41}}, {index: {_id: 42}}]
25
+ }.not_to update_index(DummiesIndex.dummy) }
26
+ end
27
+
28
+ specify { expectation.to fail_matching 'document id `42` (2 times)' }
29
+ specify { expectation.to fail_matching 'document id `41` (1 times)' }
30
+ end
31
+
32
+ context '#and_reindex' do
33
+ specify { expect { DummiesIndex.dummy.bulk body: [{index: {_id: 42}}] }.to update_index(DummiesIndex.dummy) }
34
+ specify { expect { DummiesIndex.dummy.bulk body: [{index: {_id: 42, data: {}}}] }
35
+ .to update_index(DummiesIndex.dummy).and_reindex(42) }
36
+ specify { expect { DummiesIndex.dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 43, data: {}}}] }
37
+ .to update_index(DummiesIndex.dummy).and_reindex(double(id: 42)) }
38
+ specify { expect { DummiesIndex.dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 43, data: {}}}] }
39
+ .to update_index(DummiesIndex.dummy).and_reindex(double(id: 42), double(id: 43)) }
40
+ specify { expect { DummiesIndex.dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 43, data: {}}}] }
41
+ .to update_index(DummiesIndex.dummy).and_reindex([double(id: 42), 43]) }
42
+
43
+ specify do
44
+ expect {
45
+ expect {
46
+ DummiesIndex.dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 43, data: {}}}]
47
+ }.to update_index(DummiesIndex.dummy).and_reindex([44, 43])
48
+ }.to fail_matching 'Expected document with id `44` to be reindexed, but it was not'
49
+ end
50
+
51
+ context do
52
+ let(:expectation) do
53
+ expect { expect {
54
+ DummiesIndex.dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 43, data: {}}}]
55
+ }.to update_index(DummiesIndex.dummy).and_reindex(44, double(id: 47)) }
56
+ end
57
+
58
+ specify { expectation.to fail_matching('Expected document with id `44` to be reindexed, but it was not') }
59
+ specify { expectation.to fail_matching('Expected document with id `47` to be reindexed, but it was not') }
60
+ end
61
+
62
+ context ':times' do
63
+ specify { expect {
64
+ DummiesIndex.dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 43, data: {}}}]
65
+ DummiesIndex.dummy.bulk body: [{index: {_id: 43, data: {}}}, {index: {_id: 44, data: {}}}]
66
+ }.to update_index(DummiesIndex.dummy).and_reindex(42, 44, times: 1).and_reindex(43, times: 2) }
67
+
68
+ specify { expect {
69
+ expect {
70
+ DummiesIndex.dummy.bulk body: [{index: {_id: 43, data: {a: '1'}}}]
71
+ }.to update_index(DummiesIndex.dummy).and_reindex(42, times: 3)
72
+ }.to fail_matching('Expected document with id `42` to be reindexed, but it was not') }
73
+
74
+ context do
75
+ let(:expectation) do
76
+ expect { expect {
77
+ DummiesIndex.dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 43, data: {}}}]
78
+ DummiesIndex.dummy.bulk body: [{index: {_id: 43, data: {}}}, {index: {_id: 44, data: {}}}]
79
+ }.to update_index(DummiesIndex.dummy).and_reindex(42, times: 3).and_reindex(44, 43, times: 4) }
80
+ end
81
+
82
+ specify { expectation.to fail_matching 'Expected document with id `44` to be reindexed' }
83
+ specify { expectation.to fail_matching 'Expected document with id `43` to be reindexed' }
84
+ specify { expectation.to fail_matching '3 times, but was reindexed 1 times' }
85
+ specify { expectation.to fail_matching '4 times, but was reindexed 2 times' }
86
+ end
87
+ end
88
+
89
+ context ':with' do
90
+ specify { expect {
91
+ DummiesIndex.dummy.bulk body: [{index: {_id: 42, data: {a: '1'}}}, {index: {_id: 42, data: {'a' => 2}}}]
92
+ }.to update_index(DummiesIndex.dummy).and_reindex(42, with: {a: 2}) }
93
+
94
+ specify { expect {
95
+ DummiesIndex.dummy.bulk body: [{index: {_id: 42, data: {a: '1'}}}, {index: {_id: 42, data: {'b' => 2}}}]
96
+ }.to update_index(DummiesIndex.dummy).and_reindex(42, with: {a: '1', b: 2}) }
97
+
98
+ specify { expect {
99
+ expect {
100
+ DummiesIndex.dummy.bulk body: [{index: {_id: 43, data: {a: '1'}}}]
101
+ }.to update_index(DummiesIndex.dummy).and_reindex(42, with: {a: 1})
102
+ }.to fail_matching('Expected document with id `42` to be reindexed, but it was not') }
103
+
104
+ context do
105
+ let(:expectation) do
106
+ expect { expect {
107
+ DummiesIndex.dummy.bulk body: [{index: {_id: 43, data: {a: '1'}}}, {index: {_id: 42, data: {'a' => 2}}}]
108
+ }.to update_index(DummiesIndex.dummy).and_reindex(43, times: 2, with: {a: 2}) }
109
+ end
110
+
111
+ specify { expectation.to fail_matching 'Expected document with id `43` to be reindexed' }
112
+ specify { expectation.to fail_matching '2 times, but was reindexed 1 times' }
113
+ specify { expectation.to fail_matching 'with {:a=>2}, but it was reindexed with {:a=>"1"}' }
114
+ end
115
+ end
116
+ end
117
+
118
+ context '#and_delete' do
119
+ specify { expect { DummiesIndex.dummy.bulk body: [{index: {_id: 42, data: {}}}, {delete: {_id: 43}}] }
120
+ .to update_index(DummiesIndex.dummy).and_reindex(42).and_delete(double(id: 43)) }
121
+ specify { expect { DummiesIndex.dummy.bulk body: [{delete: {_id: 42}}, {delete: {_id: 43}}] }
122
+ .to update_index(DummiesIndex.dummy).and_delete(42).and_delete(double(id: 43)) }
123
+ specify { expect { DummiesIndex.dummy.bulk body: [{delete: {_id: 42}}, {delete: {_id: 43}}] }
124
+ .to update_index(DummiesIndex.dummy).and_delete(42, double(id: 43)) }
125
+ specify { expect { DummiesIndex.dummy.bulk body: [{delete: {_id: 42}}, {delete: {_id: 43}}] }
126
+ .to update_index(DummiesIndex.dummy).and_delete([43, double(id: 42)]) }
127
+
128
+ context do
129
+ let(:expectation) do
130
+ expect { expect { DummiesIndex.dummy.bulk body: [{index: {_id: 42, data: {}}}, {delete: {_id: 43}}] }
131
+ .to update_index(DummiesIndex.dummy).and_reindex(43).and_delete(double(id: 42)) }
132
+ end
133
+
134
+ specify { expectation.to fail_matching 'Expected document with id `43` to be reindexed, but it was not' }
135
+ specify { expectation.to fail_matching 'Expected document with id `42` to be deleted, but it was not' }
136
+ end
137
+
138
+ context do
139
+ let(:expectation) do
140
+ expect { expect { DummiesIndex.dummy.bulk body: [{delete: {_id: 42, data: {}}}, {delete: {_id: 42}}] }
141
+ .to update_index(DummiesIndex.dummy).and_delete(44, times: 2).and_delete(double(id: 42), times: 3) }
142
+ end
143
+
144
+ specify { expectation.to fail_matching 'Expected document with id `44` to be deleted, but it was not' }
145
+ specify { expectation.to fail_matching 'Expected document with id `42` to be deleted' }
146
+ specify { expectation.to fail_matching '3 times, but was deleted 2 times' }
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+
3
+ describe Chewy::Type::Import do
4
+ include ClassHelpers
5
+
6
+ before do
7
+ stub_model(:city)
8
+ end
9
+
10
+ before do
11
+ stub_index(:cities) do
12
+ define_type City do
13
+ field :name
14
+ end
15
+ end
16
+ end
17
+
18
+ let!(:dummy_cities) { 3.times.map { |i| City.create(name: "name#{i}") } }
19
+ let(:city) { CitiesIndex::City }
20
+
21
+ describe '.import' do
22
+ specify { expect { city.import([]) }.not_to update_index(city) }
23
+ specify { expect { city.import }.to update_index(city).and_reindex(dummy_cities) }
24
+ specify { expect { city.import dummy_cities }.to update_index(city).and_reindex(dummy_cities) }
25
+ specify { expect { city.import dummy_cities.map(&:id) }.to update_index(city).and_reindex(dummy_cities) }
26
+ specify { expect { city.import(City.where(name: ['name0', 'name1'])) }
27
+ .to update_index(city).and_reindex(dummy_cities.first(2)) }
28
+ specify { expect { city.import(City.where(name: ['name0', 'name1']).map(&:id)) }
29
+ .to update_index(city).and_reindex(dummy_cities.first(2)) }
30
+
31
+ specify do
32
+ dummy_cities.first.destroy
33
+ expect { city.import dummy_cities }
34
+ .to update_index(city).and_reindex(dummy_cities.from(1)).and_delete(dummy_cities.first)
35
+ end
36
+
37
+ specify do
38
+ dummy_cities.first.destroy
39
+ expect { city.import dummy_cities.map(&:id) }
40
+ .to update_index(city).and_reindex(dummy_cities.from(1)).and_delete(dummy_cities.first)
41
+ end
42
+
43
+ specify do
44
+ dummy_cities.first.destroy
45
+ expect(CitiesIndex.client).to receive(:bulk).with(hash_including(
46
+ body: [{delete: {_index: 'cities', _type: 'city', _id: dummy_cities.first.id}}]
47
+ ))
48
+ dummy_cities.from(1).each.with_index do |c, i|
49
+ expect(CitiesIndex.client).to receive(:bulk).with(hash_including(
50
+ body: [{index: {_id: c.id, _index: 'cities', _type: 'city', data: {'name' => "name#{i+1}"}}}]
51
+ ))
52
+ end
53
+ city.import dummy_cities.map(&:id), batch_size: 1
54
+ end
55
+
56
+ context 'scoped' do
57
+ before do
58
+ stub_index(:cities) do
59
+ define_type City.where(name: ['name0', 'name1']) do
60
+ field :name
61
+ end
62
+ end
63
+ end
64
+
65
+ specify { expect { CitiesIndex.import }.to update_index(city).and_reindex(dummy_cities.first(2)) }
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ describe Chewy::Type::Mapping do
4
+ include ClassHelpers
5
+
6
+ let(:product) { ProductsIndex.product }
7
+
8
+ before do
9
+ stub_index(:products) do
10
+ define_type :product do
11
+ root do
12
+ field :name, 'surname'
13
+ field :title, type: 'string' do
14
+ field :subfield1
15
+ end
16
+ field 'price', type: 'float' do
17
+ field :subfield2
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ describe '.field' do
25
+ specify { product.root_object.nested.keys.should =~ [:name, :surname, :title, :price] }
26
+ specify { product.root_object.nested.values.should satisfy { |v| v.all? { |f| f.is_a? Chewy::Fields::Default } } }
27
+
28
+ specify { product.root_object.nested[:title].nested.keys.should == [:subfield1] }
29
+ specify { product.root_object.nested[:title].nested[:subfield1].should be_a Chewy::Fields::Default }
30
+
31
+ specify { product.root_object.nested[:price].nested.keys.should == [:subfield2] }
32
+ specify { product.root_object.nested[:price].nested[:subfield2].should be_a Chewy::Fields::Default }
33
+ end
34
+
35
+ describe '.mappings_hash' do
36
+ specify { Class.new(Chewy::Type::Base).mappings_hash.should == {} }
37
+ specify { product.mappings_hash.should == product.root_object.mappings_hash }
38
+ end
39
+
40
+ context "no root element call" do
41
+ before do
42
+ stub_index(:products) do
43
+ define_type :product do
44
+ field :title, type: 'string' do
45
+ field :subfield1
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ specify { product.root_object.nested[:title].nested.keys.should == [:subfield1] }
52
+ specify { product.root_object.nested[:title].nested[:subfield1].should be_a Chewy::Fields::Default }
53
+ end
54
+ end