supernova 0.6.7 → 0.6.8

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.
@@ -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