ssickles-tire 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +14 -0
- data/.travis.yml +13 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE +20 -0
- data/README.markdown +760 -0
- data/Rakefile +78 -0
- data/examples/rails-application-template.rb +249 -0
- data/examples/tire-dsl.rb +876 -0
- data/lib/tire.rb +52 -0
- data/lib/tire/alias.rb +296 -0
- data/lib/tire/configuration.rb +30 -0
- data/lib/tire/dsl.rb +43 -0
- data/lib/tire/http/client.rb +62 -0
- data/lib/tire/http/clients/curb.rb +61 -0
- data/lib/tire/http/response.rb +27 -0
- data/lib/tire/index.rb +345 -0
- data/lib/tire/logger.rb +60 -0
- data/lib/tire/model/callbacks.rb +40 -0
- data/lib/tire/model/import.rb +26 -0
- data/lib/tire/model/indexing.rb +128 -0
- data/lib/tire/model/naming.rb +100 -0
- data/lib/tire/model/percolate.rb +99 -0
- data/lib/tire/model/persistence.rb +72 -0
- data/lib/tire/model/persistence/attributes.rb +143 -0
- data/lib/tire/model/persistence/finders.rb +66 -0
- data/lib/tire/model/persistence/storage.rb +71 -0
- data/lib/tire/model/search.rb +305 -0
- data/lib/tire/results/collection.rb +114 -0
- data/lib/tire/results/item.rb +83 -0
- data/lib/tire/results/pagination.rb +54 -0
- data/lib/tire/rubyext/hash.rb +8 -0
- data/lib/tire/rubyext/ruby_1_8.rb +54 -0
- data/lib/tire/rubyext/symbol.rb +11 -0
- data/lib/tire/search.rb +160 -0
- data/lib/tire/search/facet.rb +70 -0
- data/lib/tire/search/filter.rb +28 -0
- data/lib/tire/search/highlight.rb +37 -0
- data/lib/tire/search/query.rb +151 -0
- data/lib/tire/search/scan.rb +114 -0
- data/lib/tire/search/sort.rb +25 -0
- data/lib/tire/tasks.rb +135 -0
- data/lib/tire/utils.rb +17 -0
- data/lib/tire/version.rb +22 -0
- data/test/fixtures/articles/1.json +1 -0
- data/test/fixtures/articles/2.json +1 -0
- data/test/fixtures/articles/3.json +1 -0
- data/test/fixtures/articles/4.json +1 -0
- data/test/fixtures/articles/5.json +1 -0
- data/test/integration/active_model_indexing_test.rb +51 -0
- data/test/integration/active_model_searchable_test.rb +114 -0
- data/test/integration/active_record_searchable_test.rb +446 -0
- data/test/integration/boolean_queries_test.rb +43 -0
- data/test/integration/count_test.rb +34 -0
- data/test/integration/custom_score_queries_test.rb +88 -0
- data/test/integration/dsl_search_test.rb +22 -0
- data/test/integration/explanation_test.rb +44 -0
- data/test/integration/facets_test.rb +232 -0
- data/test/integration/filtered_queries_test.rb +66 -0
- data/test/integration/filters_test.rb +63 -0
- data/test/integration/fuzzy_queries_test.rb +20 -0
- data/test/integration/highlight_test.rb +64 -0
- data/test/integration/index_aliases_test.rb +122 -0
- data/test/integration/index_mapping_test.rb +43 -0
- data/test/integration/index_store_test.rb +96 -0
- data/test/integration/mongoid_searchable_test.rb +309 -0
- data/test/integration/percolator_test.rb +111 -0
- data/test/integration/persistent_model_test.rb +117 -0
- data/test/integration/query_return_version_test.rb +70 -0
- data/test/integration/query_string_test.rb +52 -0
- data/test/integration/range_queries_test.rb +36 -0
- data/test/integration/reindex_test.rb +46 -0
- data/test/integration/results_test.rb +39 -0
- data/test/integration/scan_test.rb +56 -0
- data/test/integration/sort_test.rb +36 -0
- data/test/integration/text_query_test.rb +39 -0
- data/test/models/active_model_article.rb +31 -0
- data/test/models/active_model_article_with_callbacks.rb +49 -0
- data/test/models/active_model_article_with_custom_document_type.rb +7 -0
- data/test/models/active_model_article_with_custom_index_name.rb +7 -0
- data/test/models/active_record_models.rb +122 -0
- data/test/models/article.rb +15 -0
- data/test/models/mongoid_models.rb +97 -0
- data/test/models/persistent_article.rb +11 -0
- data/test/models/persistent_article_in_namespace.rb +12 -0
- data/test/models/persistent_article_with_casting.rb +28 -0
- data/test/models/persistent_article_with_defaults.rb +11 -0
- data/test/models/persistent_articles_with_custom_index_name.rb +10 -0
- data/test/models/supermodel_article.rb +17 -0
- data/test/models/validated_model.rb +11 -0
- data/test/test_helper.rb +88 -0
- data/test/unit/active_model_lint_test.rb +17 -0
- data/test/unit/configuration_test.rb +74 -0
- data/test/unit/http_client_test.rb +76 -0
- data/test/unit/http_response_test.rb +49 -0
- data/test/unit/index_alias_test.rb +275 -0
- data/test/unit/index_test.rb +841 -0
- data/test/unit/logger_test.rb +125 -0
- data/test/unit/model_callbacks_test.rb +116 -0
- data/test/unit/model_import_test.rb +71 -0
- data/test/unit/model_persistence_test.rb +516 -0
- data/test/unit/model_search_test.rb +899 -0
- data/test/unit/results_collection_test.rb +281 -0
- data/test/unit/results_item_test.rb +155 -0
- data/test/unit/rubyext_test.rb +60 -0
- data/test/unit/search_facet_test.rb +153 -0
- data/test/unit/search_filter_test.rb +42 -0
- data/test/unit/search_highlight_test.rb +46 -0
- data/test/unit/search_query_test.rb +242 -0
- data/test/unit/search_scan_test.rb +113 -0
- data/test/unit/search_sort_test.rb +50 -0
- data/test/unit/search_test.rb +455 -0
- data/test/unit/tire_test.rb +126 -0
- data/tire.gemspec +85 -0
- metadata +506 -0
@@ -0,0 +1,281 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Tire
|
4
|
+
|
5
|
+
class ResultsCollectionTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Collection" do
|
8
|
+
setup do
|
9
|
+
begin; Object.send(:remove_const, :Rails); rescue; end
|
10
|
+
Configuration.reset
|
11
|
+
@default_response = { 'hits' => { 'hits' => [{'_id' => 1, '_score' => 1, '_source' => {:title => 'Test'}},
|
12
|
+
{'_id' => 2},
|
13
|
+
{'_id' => 3}] } }
|
14
|
+
end
|
15
|
+
|
16
|
+
should "be iterable" do
|
17
|
+
assert_respond_to Results::Collection.new(@default_response), :each
|
18
|
+
assert_respond_to Results::Collection.new(@default_response), :size
|
19
|
+
assert_nothing_raised do
|
20
|
+
Results::Collection.new(@default_response).each { |item| item.id + 1 }
|
21
|
+
Results::Collection.new(@default_response).map { |item| item.id + 1 }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
should "have size/length" do
|
26
|
+
assert_equal 3, Results::Collection.new(@default_response).size
|
27
|
+
assert_equal 3, Results::Collection.new(@default_response).length
|
28
|
+
end
|
29
|
+
|
30
|
+
should "allow access to items" do
|
31
|
+
assert_not_nil Results::Collection.new(@default_response)[1]
|
32
|
+
assert_equal 2, Results::Collection.new(@default_response)[1][:id]
|
33
|
+
end
|
34
|
+
|
35
|
+
should "be initialized with parsed json" do
|
36
|
+
assert_nothing_raised do
|
37
|
+
collection = Results::Collection.new( @default_response )
|
38
|
+
assert_equal 3, collection.results.count
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
should "be populated lazily" do
|
43
|
+
collection = Results::Collection.new(@default_response)
|
44
|
+
assert_nil collection.instance_variable_get(:@results)
|
45
|
+
end
|
46
|
+
|
47
|
+
should "store passed options" do
|
48
|
+
collection = Results::Collection.new( @default_response, :per_page => 20, :page => 2 )
|
49
|
+
assert_equal 20, collection.options[:per_page]
|
50
|
+
assert_equal 2, collection.options[:page]
|
51
|
+
end
|
52
|
+
|
53
|
+
should "be will_paginate compatible" do
|
54
|
+
collection = Results::Collection.new(@default_response)
|
55
|
+
%w(total_pages offset current_page per_page total_entries).each do |method|
|
56
|
+
assert_respond_to collection, method
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
should "be kaminari compatible" do
|
61
|
+
collection = Results::Collection.new(@default_response)
|
62
|
+
%w(limit_value total_count num_pages offset_value).each do |method|
|
63
|
+
assert_respond_to collection, method
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context "wrapping results" do
|
68
|
+
|
69
|
+
setup do
|
70
|
+
@response = { 'hits' => { 'hits' => [ { '_id' => 1, '_score' => 0.5, '_index' => 'testing', '_type' => 'article', '_source' => { :title => 'Test', :body => 'Lorem' } } ] } }
|
71
|
+
end
|
72
|
+
|
73
|
+
should "wrap hits in Item by default" do
|
74
|
+
document = Results::Collection.new(@response).first
|
75
|
+
assert_kind_of Results::Item, document
|
76
|
+
assert_equal 'Test', document.title
|
77
|
+
end
|
78
|
+
|
79
|
+
should "NOT allow access to raw underlying Hash in Item" do
|
80
|
+
document = Results::Collection.new(@response).first
|
81
|
+
assert_nil document[:_source]
|
82
|
+
assert_nil document['_source']
|
83
|
+
end
|
84
|
+
|
85
|
+
should "allow wrapping hits in a Hash" do
|
86
|
+
Configuration.wrapper(Hash)
|
87
|
+
|
88
|
+
document = Results::Collection.new(@response).first
|
89
|
+
assert_kind_of Hash, document
|
90
|
+
assert_raise(NoMethodError) { document.title }
|
91
|
+
assert_equal 'Test', document['_source'][:title]
|
92
|
+
end
|
93
|
+
|
94
|
+
should "allow wrapping hits in custom class" do
|
95
|
+
Configuration.wrapper(Article)
|
96
|
+
|
97
|
+
article = Results::Collection.new(@response).first
|
98
|
+
assert_kind_of Article, article
|
99
|
+
assert_equal 'Test', article.title
|
100
|
+
end
|
101
|
+
|
102
|
+
should "return score" do
|
103
|
+
document = Results::Collection.new(@response).first
|
104
|
+
assert_equal 0.5, document._score
|
105
|
+
end
|
106
|
+
|
107
|
+
should "return id" do
|
108
|
+
document = Results::Collection.new(@response).first
|
109
|
+
assert_equal 1, document.id
|
110
|
+
end
|
111
|
+
|
112
|
+
should "return index" do
|
113
|
+
document = Results::Collection.new(@response).first
|
114
|
+
assert_equal "testing", document._index
|
115
|
+
end
|
116
|
+
|
117
|
+
should "return type" do
|
118
|
+
document = Results::Collection.new(@response).first
|
119
|
+
assert_equal "article", document._type
|
120
|
+
end
|
121
|
+
|
122
|
+
should "properly decode type" do
|
123
|
+
@response = { 'hits' => { 'hits' => [ { '_id' => 1, '_type' => 'foo%2Fbar' } ] } }
|
124
|
+
document = Results::Collection.new(@response).first
|
125
|
+
assert_equal "foo/bar", document._type
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
context "wrapping results with selected fields" do
|
131
|
+
# When limiting fields from _source to return ES returns them prefixed, not as "real" Hashes.
|
132
|
+
# Underlying issue: https://github.com/karmi/tire/pull/31#issuecomment-1340967
|
133
|
+
#
|
134
|
+
setup do
|
135
|
+
Configuration.reset
|
136
|
+
@default_response = { 'hits' => { 'hits' =>
|
137
|
+
[ { '_id' => 1, '_score' => 0.5, '_index' => 'testing', '_type' => 'article',
|
138
|
+
'fields' => {
|
139
|
+
'title' => 'Knee Deep in JSON',
|
140
|
+
'crazy.field' => 'CRAAAAZY!',
|
141
|
+
'_source.artist' => {
|
142
|
+
'name' => 'Elastiq',
|
143
|
+
'meta' => {
|
144
|
+
'favorited' => 1000,
|
145
|
+
'url' => 'http://first.fm/abc123/xyz567'
|
146
|
+
}
|
147
|
+
},
|
148
|
+
'_source.track.info.duration' => {
|
149
|
+
'minutes' => 3
|
150
|
+
}
|
151
|
+
} } ] } }
|
152
|
+
collection = Results::Collection.new(@default_response)
|
153
|
+
@item = collection.first
|
154
|
+
end
|
155
|
+
|
156
|
+
should "return fields from the first level" do
|
157
|
+
assert_equal 'Knee Deep in JSON', @item.title
|
158
|
+
end
|
159
|
+
|
160
|
+
should "return fields from the _source prefixed and nested fields" do
|
161
|
+
assert_equal 'Elastiq', @item.artist.name
|
162
|
+
assert_equal 1000, @item.artist.meta.favorited
|
163
|
+
assert_equal 3, @item.track.info.duration.minutes
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
|
168
|
+
context "while paginating results" do
|
169
|
+
|
170
|
+
setup do
|
171
|
+
@default_response = { 'hits' => { 'hits' => [{'_id' => 1, '_score' => 1, '_source' => {:title => 'Test'}},
|
172
|
+
{'_id' => 2},
|
173
|
+
{'_id' => 3},
|
174
|
+
{'_id' => 4}],
|
175
|
+
'total' => 4 },
|
176
|
+
'took' => 1 }
|
177
|
+
@collection = Results::Collection.new( @default_response, :per_page => 1, :page => 2 )
|
178
|
+
end
|
179
|
+
|
180
|
+
should "return total entries" do
|
181
|
+
assert_equal 4, @collection.total
|
182
|
+
assert_equal 4, @collection.total_entries
|
183
|
+
end
|
184
|
+
|
185
|
+
should "return total pages" do
|
186
|
+
assert_equal 4, @collection.total_pages
|
187
|
+
@collection = Results::Collection.new( @default_response, :per_page => 2, :page => 2 )
|
188
|
+
assert_equal 2, @collection.total_pages
|
189
|
+
@collection = Results::Collection.new( @default_response, :per_page => 3, :page => 2 )
|
190
|
+
assert_equal 2, @collection.total_pages
|
191
|
+
end
|
192
|
+
|
193
|
+
should "return total pages when per_page option not set" do
|
194
|
+
collection = Results::Collection.new( @default_response, :page => 1 )
|
195
|
+
assert_equal 1, collection.total_pages
|
196
|
+
end
|
197
|
+
|
198
|
+
should "return current page" do
|
199
|
+
assert_equal 2, @collection.current_page
|
200
|
+
end
|
201
|
+
|
202
|
+
should "return current page for empty result" do
|
203
|
+
collection = Results::Collection.new( { 'hits' => { 'hits' => [], 'total' => 0 } } )
|
204
|
+
assert_equal 1, collection.current_page
|
205
|
+
end
|
206
|
+
|
207
|
+
should "return previous page" do
|
208
|
+
assert_equal 1, @collection.previous_page
|
209
|
+
end
|
210
|
+
|
211
|
+
should "return next page" do
|
212
|
+
assert_equal 3, @collection.next_page
|
213
|
+
end
|
214
|
+
|
215
|
+
end
|
216
|
+
|
217
|
+
context "with eager loading" do
|
218
|
+
setup do
|
219
|
+
@response = { 'hits' => { 'hits' => [ {'_id' => 1, '_type' => 'active_record_article'},
|
220
|
+
{'_id' => 2, '_type' => 'active_record_article'},
|
221
|
+
{'_id' => 3, '_type' => 'active_record_article'}] } }
|
222
|
+
ActiveRecordArticle.stubs(:inspect).returns("<ActiveRecordArticle>")
|
223
|
+
end
|
224
|
+
|
225
|
+
should "load the records via model find method from database" do
|
226
|
+
ActiveRecordArticle.expects(:find).with([1,2,3]).
|
227
|
+
returns([ Results::Item.new(:id => 3),
|
228
|
+
Results::Item.new(:id => 1),
|
229
|
+
Results::Item.new(:id => 2) ])
|
230
|
+
Results::Collection.new(@response, :load => true).results
|
231
|
+
end
|
232
|
+
|
233
|
+
should "pass the :load option Hash to model find metod" do
|
234
|
+
ActiveRecordArticle.expects(:find).with([1,2,3], :include => 'comments').
|
235
|
+
returns([ Results::Item.new(:id => 3),
|
236
|
+
Results::Item.new(:id => 1),
|
237
|
+
Results::Item.new(:id => 2) ])
|
238
|
+
Results::Collection.new(@response, :load => { :include => 'comments' }).results
|
239
|
+
end
|
240
|
+
|
241
|
+
should "preserve the order of records returned from search" do
|
242
|
+
ActiveRecordArticle.expects(:find).with([1,2,3]).
|
243
|
+
returns([ Results::Item.new(:id => 3),
|
244
|
+
Results::Item.new(:id => 1),
|
245
|
+
Results::Item.new(:id => 2) ])
|
246
|
+
assert_equal [1,2,3], Results::Collection.new(@response, :load => true).results.map(&:id)
|
247
|
+
end
|
248
|
+
|
249
|
+
should "raise error when model class cannot be inferred from _type" do
|
250
|
+
assert_raise(NameError) do
|
251
|
+
response = { 'hits' => { 'hits' => [ {'_id' => 1, '_type' => 'hic_sunt_leones'}] } }
|
252
|
+
Results::Collection.new(response, :load => true).results
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
should "raise error when _type is missing" do
|
257
|
+
assert_raise(NoMethodError) do
|
258
|
+
response = { 'hits' => { 'hits' => [ {'_id' => 1}] } }
|
259
|
+
Results::Collection.new(response, :load => true).results
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
should "return empty array for empty hits" do
|
264
|
+
response = { 'hits' => {
|
265
|
+
'hits' => [],
|
266
|
+
'total' => 4
|
267
|
+
},
|
268
|
+
'took' => 1 }
|
269
|
+
@collection = Results::Collection.new( response, :load => true )
|
270
|
+
assert @collection.empty?, 'Collection should be empty'
|
271
|
+
assert @collection.results.empty?, 'Collection results should be empty'
|
272
|
+
assert_equal 0, @collection.size
|
273
|
+
end
|
274
|
+
|
275
|
+
end
|
276
|
+
|
277
|
+
end
|
278
|
+
|
279
|
+
end
|
280
|
+
|
281
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Tire
|
4
|
+
class ResultsItemTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
# ActiveModel compatibility tests
|
7
|
+
#
|
8
|
+
def setup
|
9
|
+
super
|
10
|
+
begin; Object.send(:remove_const, :Rails); rescue; end
|
11
|
+
@model = Results::Item.new :title => 'Test'
|
12
|
+
end
|
13
|
+
include ActiveModel::Lint::Tests
|
14
|
+
|
15
|
+
context "Item" do
|
16
|
+
|
17
|
+
setup do
|
18
|
+
@document = Results::Item.new :title => 'Test', :author => { :name => 'Kafka' }
|
19
|
+
end
|
20
|
+
|
21
|
+
should "be initialized with a Hash or Hash like object" do
|
22
|
+
assert_raise(ArgumentError) { Results::Item.new('FUUUUUUU') }
|
23
|
+
|
24
|
+
assert_nothing_raised do
|
25
|
+
d = Results::Item.new(:id => 1)
|
26
|
+
assert_instance_of Results::Item, d
|
27
|
+
end
|
28
|
+
|
29
|
+
assert_nothing_raised do
|
30
|
+
class AlmostHash < Hash; end
|
31
|
+
d = Results::Item.new(AlmostHash.new(:id => 1))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
should "have an 'id' method" do
|
36
|
+
a = Results::Item.new(:_id => 1)
|
37
|
+
b = Results::Item.new(:id => 1)
|
38
|
+
assert_equal 1, a.id
|
39
|
+
assert_equal 1, b.id
|
40
|
+
end
|
41
|
+
|
42
|
+
should "have a 'type' method" do
|
43
|
+
a = Results::Item.new(:_type => 'foo')
|
44
|
+
b = Results::Item.new(:type => 'foo')
|
45
|
+
assert_equal 'foo', a.type
|
46
|
+
assert_equal 'foo', b.type
|
47
|
+
end
|
48
|
+
|
49
|
+
should "respond to :to_indexed_json" do
|
50
|
+
assert_respond_to Results::Item.new, :to_indexed_json
|
51
|
+
end
|
52
|
+
|
53
|
+
should "retrieve simple values from underlying hash" do
|
54
|
+
assert_equal 'Test', @document[:title]
|
55
|
+
end
|
56
|
+
|
57
|
+
should "retrieve hash values from underlying hash" do
|
58
|
+
assert_equal 'Kafka', @document[:author][:name]
|
59
|
+
end
|
60
|
+
|
61
|
+
should "allow to retrieve value by methods" do
|
62
|
+
assert_not_nil @document.title
|
63
|
+
assert_equal 'Test', @document.title
|
64
|
+
end
|
65
|
+
|
66
|
+
should "return nil for non-existing keys/methods" do
|
67
|
+
assert_nothing_raised { @document.whatever }
|
68
|
+
assert_nil @document.whatever
|
69
|
+
end
|
70
|
+
|
71
|
+
should "not care about symbols or strings in keys" do
|
72
|
+
@document = Results::Item.new 'title' => 'Test'
|
73
|
+
assert_not_nil @document.title
|
74
|
+
assert_equal 'Test', @document.title
|
75
|
+
end
|
76
|
+
|
77
|
+
should "not care about symbols or strings in composite keys" do
|
78
|
+
@document = Results::Item.new :highlight => { 'name.ngrams' => 'abc' }
|
79
|
+
|
80
|
+
assert_not_nil @document.highlight['name.ngrams']
|
81
|
+
assert_equal 'abc', @document.highlight['name.ngrams']
|
82
|
+
assert_equal @document.highlight['name.ngrams'], @document.highlight['name.ngrams'.to_sym]
|
83
|
+
end
|
84
|
+
|
85
|
+
should "allow to retrieve values from nested hashes" do
|
86
|
+
assert_not_nil @document.author.name
|
87
|
+
assert_equal 'Kafka', @document.author.name
|
88
|
+
end
|
89
|
+
|
90
|
+
should "wrap arrays" do
|
91
|
+
@document = Results::Item.new :stats => [1, 2, 3]
|
92
|
+
assert_equal [1, 2, 3], @document.stats
|
93
|
+
end
|
94
|
+
|
95
|
+
should "wrap hashes in arrays" do
|
96
|
+
@document = Results::Item.new :comments => [{:title => 'one'}, {:title => 'two'}]
|
97
|
+
assert_equal 2, @document.comments.size
|
98
|
+
assert_instance_of Results::Item, @document.comments.first
|
99
|
+
assert_equal 'one', @document.comments.first.title
|
100
|
+
assert_equal 'two', @document.comments.last.title
|
101
|
+
end
|
102
|
+
|
103
|
+
should "be an Item instance" do
|
104
|
+
assert_instance_of Tire::Results::Item, @document
|
105
|
+
end
|
106
|
+
|
107
|
+
should "be convertible to hash" do
|
108
|
+
assert_instance_of Hash, @document.to_hash
|
109
|
+
end
|
110
|
+
|
111
|
+
should "be inspectable" do
|
112
|
+
assert_match /<Item title|Item author/, @document.inspect
|
113
|
+
end
|
114
|
+
|
115
|
+
context "within Rails" do
|
116
|
+
|
117
|
+
setup do
|
118
|
+
module ::Rails
|
119
|
+
end
|
120
|
+
|
121
|
+
class ::FakeRailsModel
|
122
|
+
extend ActiveModel::Naming
|
123
|
+
include ActiveModel::Conversion
|
124
|
+
def self.find(id, options); new; end
|
125
|
+
end
|
126
|
+
|
127
|
+
@document = Results::Item.new :id => 1, :_type => 'fake_rails_model', :title => 'Test'
|
128
|
+
end
|
129
|
+
|
130
|
+
should "be an instance of model, based on _type" do
|
131
|
+
assert_equal FakeRailsModel, @document.class
|
132
|
+
end
|
133
|
+
|
134
|
+
should "be inspectable with masquerade" do
|
135
|
+
assert_match /<Item \(FakeRailsModel\)/, @document.inspect
|
136
|
+
end
|
137
|
+
|
138
|
+
should "return proper singular and plural forms" do
|
139
|
+
assert_equal 'fake_rails_model', ActiveModel::Naming.singular(@document)
|
140
|
+
assert_equal 'fake_rails_models', ActiveModel::Naming.plural(@document)
|
141
|
+
end
|
142
|
+
|
143
|
+
should "instantiate itself for deep hashes, not a Ruby class corresponding to type" do
|
144
|
+
document = Results::Item.new :_type => 'my_model', :title => 'Test', :author => { :name => 'John' }
|
145
|
+
|
146
|
+
assert_equal Tire::Results::Item, document.class
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Tire
|
4
|
+
|
5
|
+
class RubyCoreExtensionsTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Hash" do
|
8
|
+
|
9
|
+
context "with no to_json method provided" do
|
10
|
+
|
11
|
+
setup do
|
12
|
+
@hash = { :one => 1}
|
13
|
+
# Undefine the `to_json` method...
|
14
|
+
::Hash.class_eval { remove_method(:to_json) rescue nil }
|
15
|
+
# ... and reload the extension, so it's added
|
16
|
+
load 'tire/rubyext/hash.rb'
|
17
|
+
end
|
18
|
+
|
19
|
+
should "have its own to_json method" do
|
20
|
+
assert_respond_to( @hash, :to_json )
|
21
|
+
assert_equal '{"one":1}', @hash.to_json
|
22
|
+
end
|
23
|
+
|
24
|
+
should "allow to pass options to to_json for compatibility" do
|
25
|
+
assert_nothing_raised do
|
26
|
+
assert_equal '{"one":1}', @hash.to_json({})
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
should "have a to_json method from a JSON serialization library" do
|
33
|
+
assert_respond_to( {}, :to_json )
|
34
|
+
assert_equal '{"one":1}', { :one => 1}.to_json
|
35
|
+
end
|
36
|
+
|
37
|
+
should "have to_indexed_json method doing the same as to_json" do
|
38
|
+
[{}, { 1 => 2 }, { 3 => 4, 5 => 6 }, { nil => [7,8,9] }].each do |h|
|
39
|
+
assert_equal MultiJson.decode(h.to_json), MultiJson.decode(h.to_indexed_json)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
should "properly serialize Time into JSON" do
|
44
|
+
json = { :time => Time.mktime(2011, 01, 01, 11, 00).to_json }.to_json
|
45
|
+
assert_match /"2011-01-01T11:00:00.*"/, MultiJson.decode(json)['time']
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
context "Array" do
|
51
|
+
|
52
|
+
should "encode itself to JSON" do
|
53
|
+
assert_equal '["one","two"]', ['one','two'].to_json
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|