supernova 0.6.7 → 0.6.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,24 +1,25 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
3
 
3
4
  describe "Solr" do
4
5
  before(:each) do
5
6
  Supernova::Solr.instance_variable_set("@connection", nil)
6
- Supernova::Solr.url = "http://localhost:8985/solr/"
7
+ Supernova::Solr.url = "http://localhost:8983/solr/supernova_test"
7
8
  Supernova::Solr.truncate!
8
9
  Offer.criteria_class = Supernova::SolrCriteria
9
10
  root = Geokit::LatLng.new(47, 11)
10
11
  # endpoint = root.endpoint(90, 50, :units => :kms)
11
12
  e_lat = 46.9981112912042
12
13
  e_lng = 11.6587158814378
13
- Supernova::Solr.connection.add(:id => "offers/1", :type => "Offer", :user_id_i => 1, :enabled_b => false,
14
+ Supernova::Solr.add(:id => "offers/1", :type => "Offer", :user_id_i => 1, :enabled_b => false,
14
15
  :text_t => "Hans Meyer", :popularity_i => 10,
15
16
  :location_p => "#{root.lat},#{root.lng}", :type => "Offer"
16
17
  )
17
- Supernova::Solr.connection.add(:id => "offers/2", :user_id_i => 2, :enabled_b => true, :text_t => "Marek Mintal",
18
+ Supernova::Solr.add(:id => "offers/2", :user_id_i => 2, :enabled_b => true, :text_t => "Marek Mintal",
18
19
  :popularity_i => 1,
19
20
  :location_p => "#{e_lat},#{e_lng}", :type => "Offer"
20
21
  )
21
- Supernova::Solr.connection.commit
22
+ Supernova::Solr.commit!
22
23
  end
23
24
 
24
25
  after(:each) do
@@ -40,7 +41,7 @@ describe "Solr" do
40
41
  { :title_s => "Title2", :id => 2, :type => "Record" }
41
42
  ]
42
43
  )
43
- response = Supernova::Solr.connection.get('select', :params => { :q=>'*:*', :start=>0, :rows=>10, :sort => "id asc" })
44
+ response = JSON.parse(Typhoeus::Request.post(Supernova::Solr.select_url, :params => { :q=>'*:*', :start=>0, :rows=>10, :sort => "id asc", :wt => "json" }).body)
44
45
  response["response"]["docs"].first.should == { "title_s" => "Title1", "id" => "1", "type" => "Record" }
45
46
  response["response"]["docs"].at(1).should == { "title_s" => "Title2", "id" => "2", "type" => "Record" }
46
47
  end
@@ -49,7 +50,7 @@ describe "Solr" do
49
50
  describe "#indexing" do
50
51
  before(:each) do
51
52
  Supernova::Solr.truncate!
52
- Supernova::Solr.connection.commit
53
+ Supernova::Solr.commit!
53
54
  end
54
55
 
55
56
  class OfferIndex < Supernova::SolrIndexer
@@ -182,10 +183,10 @@ describe "Solr" do
182
183
 
183
184
  describe "not searches" do
184
185
  it "finds the correct documents for not nil" do
185
- Supernova::Solr.connection.add(:id => "offers/3", :enabled_b => true, :text_t => "Marek Mintal", :popularity_i => 1,
186
+ Supernova::Solr.add(:id => "offers/3", :enabled_b => true, :text_t => "Marek Mintal", :popularity_i => 1,
186
187
  :type => "Offer"
187
188
  )
188
- Supernova::Solr.connection.commit
189
+ Supernova::Solr.commit!
189
190
  raise "There should be 3 docs" if new_criteria.total_entries != 3
190
191
  new_criteria.with(:user_id_i.not => nil).map { |h| h["id"] }.should == [1, 2]
191
192
  end
@@ -261,11 +262,25 @@ describe "Solr" do
261
262
  describe "#facets" do
262
263
  it "returns the correct facets hash" do
263
264
  # pending "fix me"
264
- Supernova::Solr.connection.add(:id => "offers/3", :type => "Offer", :user_id_i => 3, :enabled_b => false,
265
+ Supernova::Solr.add(:id => "offers/3", :type => "Offer", :user_id_i => 3, :enabled_b => false,
265
266
  :text_t => "Hans Müller", :popularity_i => 10, :type => "Offer"
266
267
  )
267
- Supernova::Solr.connection.commit
268
- new_criteria.facet_fields(:text_t).execute.facets.should == {"text_t"=>{"mintal"=>1, "marek"=>1, "meyer"=>1, "m\303\274ller"=>1, "han"=>2}}
268
+ Supernova::Solr.commit!
269
+ new_criteria.facet_fields(:text_t).execute.facets.should == {"text_t"=>{"mintal"=>1, "marek"=>1, "meyer"=>1, "müller"=>1, "han"=>2}}
270
+ end
271
+ end
272
+
273
+ describe "#execute_raw" do
274
+ it "returns a hash" do
275
+ new_criteria.execute_raw.should be_kind_of(Hash)
276
+ end
277
+
278
+ it "should not be empty" do
279
+ new_criteria.execute_raw.keys.should_not be_empty
280
+ end
281
+
282
+ it "includes th ecorrect headers" do
283
+ new_criteria.execute_raw.keys.sort.should == %w(responseHeader response).sort
269
284
  end
270
285
  end
271
286
 
@@ -310,7 +325,7 @@ describe "Solr" do
310
325
  row3 = { "id" => 3, "location" => "Berlin", "type" => "Offer" }
311
326
  row4 = { "id" => 4, "location" => "München", "type" => "Offer" }
312
327
  Supernova::Solr.truncate!
313
- Supernova::Solr.connection.commit
328
+ Supernova::Solr.commit!
314
329
  @clazz.new.index_rows([row1, row2, row3, row4])
315
330
  end
316
331
 
data/spec/spec_helper.rb CHANGED
@@ -25,6 +25,7 @@ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
25
25
  RSpec.configure do |config|
26
26
  config.before(:each) do
27
27
  ActiveRecord::Base.connection.execute("TRUNCATE offers")
28
+ Supernova::Criteria.mutable_by_default!
28
29
  end
29
30
  end
30
31
 
@@ -15,6 +15,18 @@ describe "Supernova::Criteria" do
15
15
  it "sets the clazz_name" do
16
16
  Supernova::Criteria.new(Offer).clazz.should == Offer
17
17
  end
18
+
19
+ it "allows setting immutable!" do
20
+ a = Supernova::Criteria.new
21
+ a.immutable!
22
+ a.should be_immutable
23
+ end
24
+
25
+ it "automatically sets the criteria to immutable when globally enabled" do
26
+ Supernova::Criteria.immutable_by_default!
27
+ a = Supernova::Criteria.new
28
+ a.should be_immutable
29
+ end
18
30
  end
19
31
 
20
32
  [
@@ -52,7 +64,7 @@ describe "Supernova::Criteria" do
52
64
 
53
65
  describe "#order" do
54
66
  it "sets the order statement" do
55
- scope.order("popularity desc").search_options[:order].should == "popularity desc"
67
+ scope.order("popularity desc").search_options[:order].should == ["popularity desc"]
56
68
  end
57
69
  end
58
70
 
@@ -147,6 +159,7 @@ describe "Supernova::Criteria" do
147
159
 
148
160
  it "returns the results" do
149
161
  res = double("results")
162
+ scope.stub!(:populate)
150
163
  scope.instance_variable_set("@results", res)
151
164
  scope.to_a.should == res
152
165
  end
@@ -230,6 +243,130 @@ describe "Supernova::Criteria" do
230
243
  end
231
244
  end
232
245
 
246
+ describe "#clone" do
247
+ it "returns a new Supernova::Criteria" do
248
+ Supernova::Criteria.new.clone.should be_kind_of(Supernova::Criteria)
249
+ end
250
+
251
+ it "also clones the attributes" do
252
+ a = Supernova::Criteria.new
253
+ b = a.clone
254
+ b.immutable?.should == false
255
+ a.search_options[:a] = 1
256
+ b.search_options[:a].should be_nil
257
+ end
258
+
259
+ it "makes the cloned collection immutable" do
260
+ a = Supernova::Criteria.new
261
+ a.immutable!
262
+ b = a.clone
263
+ b.immutable?.should == true
264
+ end
265
+ end
266
+
267
+ describe "#self_or_clone" do
268
+ it "returns self when immutable is off" do
269
+ a = Supernova::Criteria.new
270
+ a.self_or_clone.should == a
271
+ end
272
+
273
+ it "returns a clone when immutable is on" do
274
+ a = Supernova::Criteria.new
275
+ a.immutable!
276
+ b = a.self_or_clone
277
+ b.should be_kind_of(Supernova::Criteria)
278
+ b.should_not == a
279
+ end
280
+ end
281
+
282
+ describe "#merge_filters_array" do
283
+ describe "when mutable" do
284
+ it "returns self" do
285
+ a = Supernova::Criteria.new
286
+ a.merge_filters_array(:a, [1, 2, 3]).should == a
287
+ a.search_options[:a].should == [1, 2, 3]
288
+ end
289
+ end
290
+
291
+ describe "when immutable" do
292
+ it "returns self" do
293
+ a = Supernova::Criteria.new
294
+ a.immutable!
295
+ b = a.merge_filters_array(:a, [1, 2, 3])
296
+ b.should_not == a
297
+ a.search_options[:a].should be_nil
298
+ b.search_options[:a].should == [1, 2, 3]
299
+ end
300
+ end
301
+ end
302
+
303
+ describe "#without" do
304
+ describe "when mutable" do
305
+ it "returns self" do
306
+ a = Supernova::Criteria.new
307
+ a.without(:a => 1).should == a
308
+ a.filters[:without].should == { :a => [1] }
309
+ end
310
+ end
311
+
312
+ describe "when immutable" do
313
+ it "returns self" do
314
+ a = Supernova::Criteria.new
315
+ a.immutable!
316
+ b = a.without(:a => 2)
317
+ b.should_not == a
318
+ a.filters[:without].should be_nil
319
+ b.filters[:without].should == { :a => [2] }
320
+ end
321
+ end
322
+ end
323
+
324
+
325
+ describe "#merge_filters_or_search_options" do
326
+ describe "when mutable" do
327
+ it "returns self" do
328
+ a = Supernova::Criteria.new
329
+ a.merge_filters_or_search_options(:search_options, :per_page, 1).should == a
330
+ a.search_options[:per_page].should == 1
331
+ end
332
+ end
333
+
334
+ describe "when immutable" do
335
+ it "returns a new criteria" do
336
+ a = Supernova::Criteria.new
337
+ a.immutable!
338
+ b = a.merge_filters_or_search_options(:search_options, :per_page, 3)
339
+ a.search_options[:per_page].should be_nil
340
+ b.search_options[:per_page].should == 3
341
+ end
342
+ end
343
+ end
344
+
345
+ describe "#except" do
346
+ describe "being mutable" do
347
+ it "returns the criteria" do
348
+ a = Supernova::Criteria.new
349
+ a.except(:order).should be_kind_of(Supernova::Criteria)
350
+ end
351
+
352
+ it "removes the specified field" do
353
+ a = Supernova::Criteria.new
354
+ a.order("id").except(:order).search_options[:order].should be_nil
355
+ end
356
+ end
357
+
358
+ describe "being immutable" do
359
+ it "returns a different criteria with the field removed" do
360
+ a = Supernova::Criteria.new.order("id").where(:a => 1)
361
+ a.immutable!
362
+ b = a.except(:order)
363
+ b.search_options[:order].should be_nil
364
+ b.filters[:with].should == { :a => 1 }
365
+ a.search_options[:order].should == ["id"]
366
+ end
367
+ end
368
+ end
369
+
233
370
  describe "#method_missing" do
234
371
  it "raises a no method error when methd not defined" do
235
372
  lambda {
@@ -240,7 +377,7 @@ describe "Supernova::Criteria" do
240
377
  it "forwards all array methods to @results" do
241
378
  results = double("results")
242
379
  scope.instance_variable_set("@results", results)
243
- results.should_receive(:index, "1")
380
+ results.should_receive(:index).with("1")
244
381
  scope.index("1")
245
382
  end
246
383
 
@@ -292,10 +429,6 @@ describe "Supernova::Criteria" do
292
429
  new_crit.merge(criteria).should == new_crit
293
430
  end
294
431
 
295
- it "merges e.g. the order" do
296
- new_crit.merge(criteria).search_options[:order].should == "popularity asc"
297
- end
298
-
299
432
  it "merges e.g. the with filters" do
300
433
  new_crit.merge(criteria).filters[:with].should == { :c => 8, :a => 1 }
301
434
  end
@@ -333,18 +466,33 @@ describe "Supernova::Criteria" do
333
466
  it "calls merge on options" do
334
467
  criteria.stub!(:search_options).and_return({ :x => 2, :y => 9 })
335
468
  new_crit.stub!(:search_options).and_return({ :z => 3, :c => 1 })
336
- new_crit.should_receive(:merge_search_options).with(:x, 2)
337
- new_crit.should_receive(:merge_search_options).with(:y, 9)
469
+ new_crit.should_receive(:merge_search_options).with(:x, 2).and_return(new_crit)
470
+ new_crit.should_receive(:merge_search_options).with(:y, 9).and_return(new_crit)
338
471
  new_crit.merge(criteria)
339
472
  end
340
473
 
341
474
  it "calls merge filters on all filters" do
342
475
  criteria.stub!(:filters).and_return({ :a => 1, :c => 3 })
343
476
  new_crit.stub!(:filters).and_return({ :b => 2, :e => 1 })
344
- new_crit.should_receive(:merge_filters).with(:a, 1)
345
- new_crit.should_receive(:merge_filters).with(:c, 3)
477
+ new_crit.should_receive(:merge_filters).with(:a, 1).and_return(new_crit)
478
+ new_crit.should_receive(:merge_filters).with(:c, 3).and_return(new_crit)
346
479
  new_crit.merge(criteria)
347
480
  end
481
+
482
+ describe "when immutable" do
483
+ it "merges two filters but does not break " do
484
+ a = Supernova::Criteria.new.with(:a => 1)
485
+ a.immutable!
486
+ b = Supernova::Criteria.new.with(:b => 2)
487
+ b.immutable!
488
+ c = a.merge(b)
489
+ c.should_not == a
490
+ c.should_not == b
491
+ a.filters[:with].should == { :a => 1 }
492
+ b.filters[:with].should == { :b => 2 }
493
+ c.filters[:with].should == { :a => 1, :b => 2 }
494
+ end
495
+ end
348
496
  end
349
497
 
350
498
  describe "#near" do
@@ -3,7 +3,6 @@ require "ostruct"
3
3
 
4
4
  describe Supernova::SolrCriteria do
5
5
  let(:criteria) { Supernova::SolrCriteria.new }
6
- let(:rsolr) { double("rsolr").as_null_object }
7
6
  let(:docs) do
8
7
  [
9
8
  {"popularity"=>10, "location"=>"47,11", "text"=>"Hans Meyer", "id"=>"offers/1", "enabled"=>false, "user_id"=>1, "type"=>"Offer"},
@@ -16,10 +15,6 @@ describe Supernova::SolrCriteria do
16
15
  }
17
16
  end
18
17
 
19
- before(:each) do
20
- Supernova::Solr.stub!(:connection).and_return rsolr
21
- end
22
-
23
18
  describe "#fq_from_with" do
24
19
  it "returns the correct filter for with ranges" do
25
20
  criteria.fq_from_with(:user_id => Range.new(10, 12)).should == ["user_id:[10 TO 12]"]
@@ -63,6 +58,16 @@ describe Supernova::SolrCriteria do
63
58
  end
64
59
  end
65
60
 
61
+ describe "#convert_search_order" do
62
+ it "returns a string" do
63
+ criteria.convert_search_order("title asc").should == "title asc"
64
+ end
65
+
66
+ it "returns a complex string" do
67
+ criteria.convert_search_order("title asc, name desc").should == "title asc,name desc"
68
+ end
69
+ end
70
+
66
71
  describe "#to_params" do
67
72
  it "returns a Hash" do
68
73
  criteria.to_params.should be_an_instance_of(Hash)
@@ -77,13 +82,36 @@ describe Supernova::SolrCriteria do
77
82
  end
78
83
 
79
84
  it "sets the order field" do
80
- criteria.order("title").to_params[:sort].should == "title"
85
+ criteria.order("title asc").to_params[:sort].should == "title asc"
86
+ end
87
+
88
+ it "allows more complex order fields" do
89
+ criteria.order("title asc, name desc").to_params[:sort].should == "title asc,name desc"
90
+ end
91
+
92
+ it "adds raw fields when not able to extract asc or desc" do
93
+ criteria.order("some_order_func, test asc").to_params[:sort].should == "some_order_func,test asc"
94
+ end
95
+
96
+ it "chains order statements" do
97
+ criteria.order("name asc").order("title desc").to_params[:sort].should == "name asc,title desc"
81
98
  end
82
99
 
83
100
  it "uses a mapped field for order" do
84
- criteria.attribute_mapping(:title => { :type => :string }).order("title").to_params[:sort].should == "title_s"
101
+ criteria.attribute_mapping(:title => { :type => :string }).order("title asc").to_params[:sort].should == "title_s asc"
102
+ end
103
+
104
+ it "allows multi mappings of order criteria when given in one string" do
105
+ scope = criteria.attribute_mapping(:title => { :type => :string }, :visits => { :type => :integer })
106
+ scope.order("title asc, visits desc").to_params[:sort].should == "title_s asc,visits_i desc"
85
107
  end
86
108
 
109
+ it "allows multi mappings of order criteria when chained" do
110
+ scope = criteria.attribute_mapping(:title => { :type => :string }, :visits => { :type => :integer })
111
+ scope.order("title asc").order("visits desc").to_params[:sort].should == "title_s asc,visits_i desc"
112
+ end
113
+
114
+
87
115
  %w(asc desc).each do |order|
88
116
  it "uses a mapped field for order even when #{order} is present" do
89
117
  criteria.attribute_mapping(:title => { :type => :string }).order("title #{order}").to_params[:sort].should == "title_s #{order}"
@@ -162,6 +190,10 @@ describe Supernova::SolrCriteria do
162
190
  end
163
191
  end
164
192
 
193
+ it "allows setting of rows" do
194
+ criteria.rows(11).to_params[:rows].should == 11
195
+ end
196
+
165
197
  describe "pagination" do
166
198
  it "sets the correct rows" do
167
199
  criteria.paginate(:page => 1, :per_page => 10).to_params[:rows].should == 10
@@ -211,9 +243,10 @@ describe Supernova::SolrCriteria do
211
243
 
212
244
  describe "#ids" do
213
245
  it "sets the select fields to id only" do
214
- criteria.should_receive(:select).with("id")
215
- criteria.stub!(:execute).and_return([])
216
- criteria.ids
246
+ scope = double("scope")
247
+ criteria.should_receive(:only_ids).and_return(scope)
248
+ scope.should_receive(:execute).and_return([])
249
+ criteria.ids.should == []
217
250
  end
218
251
 
219
252
  it "calls execute" do
@@ -223,16 +256,45 @@ describe Supernova::SolrCriteria do
223
256
 
224
257
  it "maps the id hashes to ids" do
225
258
  criteria.stub(:execute).and_return([ { "id" => "offer/1" }, { "id" => "offer/3" } ])
226
- criteria.ids
259
+ criteria.ids.should == [1, 3]
260
+ end
261
+ end
262
+
263
+ describe "#format" do
264
+ it "sets the correct search_options" do
265
+ criteria.format("csv").search_options[:wt].should == "csv"
266
+ end
267
+
268
+ it "includes the format in the params" do
269
+ criteria.format("csv").to_params[:wt].should == "csv"
270
+ end
271
+
272
+ it "allows overriding of formats" do
273
+ criteria.format("csv").format("json").to_params[:wt].should == "json"
227
274
  end
228
275
  end
276
+
277
+ describe "#only_ids" do
278
+ it "returns a criteria" do
279
+ criteria.only_ids.should be_kind_of(Supernova::SolrCriteria)
280
+ end
281
+
282
+ it "only selects the id column" do
283
+ a = criteria.select("name_s").only_ids
284
+ a.to_params[:fl].should == "id"
285
+ end
286
+
287
+ # it "does something" do
288
+ #
289
+ # end
290
+ end
229
291
 
230
292
  describe "#execute" do
231
- let(:params) { double("params") }
293
+ let(:params) { {} }
232
294
 
233
295
  before(:each) do
296
+ criteria.stub(:execute_raw).and_return(solr_response)
234
297
  criteria.stub(:to_params).and_return params
235
- rsolr.stub!(:post).and_return solr_response
236
298
  end
237
299
 
238
300
  it "sets the original response" do
@@ -240,12 +302,7 @@ describe Supernova::SolrCriteria do
240
302
  end
241
303
 
242
304
  it "calls to_params" do
243
- criteria.should_receive(:to_params).and_return params
244
- criteria.execute
245
- end
246
-
247
- it "calls get with select and params" do
248
- rsolr.should_receive(:post).with("select", :data => params).and_return solr_response
305
+ criteria.should_receive(:execute_raw).and_return solr_response
249
306
  criteria.execute
250
307
  end
251
308
 
@@ -292,7 +349,7 @@ describe Supernova::SolrCriteria do
292
349
  end
293
350
 
294
351
  it "sets the correct facets" do
295
- rsolr.stub!(:post).and_return facet_response
352
+ criteria.stub!(:execute_raw).and_return(facet_response)
296
353
  criteria.should_receive(:hashify_facets_from_response).with(facet_response).and_return({ :a => 1 })
297
354
  criteria.execute.facets.should == {:a => 1}
298
355
  end