chewy 0.0.1

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 (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