supernova 0.3.3 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.3
1
+ 0.3.4
@@ -48,6 +48,15 @@ class Supernova::SolrCriteria < Supernova::Criteria
48
48
  Supernova::SolrIndexer.solr_field_for_field_name_and_mapping(field, search_options[:attribute_mapping])
49
49
  end
50
50
 
51
+ def reverse_lookup_solr_field(solr_field)
52
+ if search_options[:attribute_mapping]
53
+ search_options[:attribute_mapping].each do |field, options|
54
+ return field if solr_field.to_s == solr_field_from_field(field)
55
+ end
56
+ end
57
+ solr_field
58
+ end
59
+
51
60
  def fq_from_with(with)
52
61
  if with.blank?
53
62
  []
@@ -85,7 +94,7 @@ class Supernova::SolrCriteria < Supernova::Criteria
85
94
  if key == "id"
86
95
  doc.id = value.to_s.split("/").last if doc.respond_to?(:id=)
87
96
  else
88
- doc.send(:"#{key}=", value) if doc.respond_to?(:"#{key}=")
97
+ set_first_responding_attribute(doc, key, value)
89
98
  end
90
99
  end
91
100
  doc.instance_variable_set("@readonly", true)
@@ -93,6 +102,16 @@ class Supernova::SolrCriteria < Supernova::Criteria
93
102
  doc
94
103
  end
95
104
 
105
+ def set_first_responding_attribute(doc, solr_key, value)
106
+ [reverse_lookup_solr_field(solr_key), solr_key].each do |key|
107
+ meth = :"#{key}="
108
+ if doc.respond_to?(meth)
109
+ doc.send(meth, value)
110
+ return
111
+ end
112
+ end
113
+ end
114
+
96
115
  def to_a
97
116
  response = Supernova::Solr.connection.get("select", :params => to_params)
98
117
  collection = Supernova::Collection.new(current_page, per_page, response["response"]["numFound"])
@@ -12,7 +12,7 @@ class Supernova::SolrIndexer
12
12
  end
13
13
 
14
14
  def has(key, attributes)
15
- field_definitions[key] = attributes
15
+ field_definitions[key] = attributes.is_a?(Hash) ? attributes : { :type => attributes }
16
16
  end
17
17
 
18
18
  def clazz(class_name =:only_return)
@@ -190,6 +190,6 @@ class Supernova::SolrIndexer
190
190
  else
191
191
  %(cd #{File.dirname(index_file_path)} && curl -s '#{solr_url}/update/json?commit=true' --data-binary @#{File.basename(index_file_path)} -H 'Content-type:application/json')
192
192
  end
193
- system(cmd)
193
+ Kernel.send(:`, cmd)
194
194
  end
195
195
  end
@@ -10,11 +10,13 @@ describe "Solr" do
10
10
  # endpoint = root.endpoint(90, 50, :units => :kms)
11
11
  e_lat = 46.9981112912042
12
12
  e_lng = 11.6587158814378
13
- Supernova::Solr.connection.add(:id => "offers/1", :type => "Offer", :user_id => 1, :enabled => false, :text => "Hans Meyer", :popularity => 10,
14
- :location => "#{root.lat},#{root.lng}", :type => "Offer"
13
+ Supernova::Solr.connection.add(:id => "offers/1", :type => "Offer", :user_id_i => 1, :enabled_b => false,
14
+ :text_t => "Hans Meyer", :popularity_i => 10,
15
+ :location_p => "#{root.lat},#{root.lng}", :type => "Offer"
15
16
  )
16
- Supernova::Solr.connection.add(:id => "offers/2", :user_id => 2, :enabled => true, :text => "Marek Mintal", :popularity => 1,
17
- :location => "#{e_lat},#{e_lng}", :type => "Offer"
17
+ Supernova::Solr.connection.add(:id => "offers/2", :user_id_i => 2, :enabled_b => true, :text_t => "Marek Mintal",
18
+ :popularity_i => 1,
19
+ :location_p => "#{e_lat},#{e_lng}", :type => "Offer"
18
20
  )
19
21
  Supernova::Solr.connection.commit
20
22
  end
@@ -48,27 +50,27 @@ describe "Solr" do
48
50
 
49
51
  describe "plain text search" do
50
52
  it "returns the correct entries for 1 term" do
51
- new_criteria.search("Hans").to_a.map { |h| h["id"] }.should == [1]
52
- new_criteria.search("Hans").search("Meyer").to_a.map { |h| h["id"] }.should == [1]
53
- new_criteria.search("Marek").to_a.map { |h| h["id"] }.should == [2]
53
+ new_criteria.search("text_t:Hans").to_a.map { |h| h["id"] }.should == [1]
54
+ new_criteria.search("text_t:Hans").search("text_t:Meyer").to_a.map { |h| h["id"] }.should == [1]
55
+ new_criteria.search("text_t:Marek").to_a.map { |h| h["id"] }.should == [2]
54
56
  end
55
57
 
56
58
  it "returns the correct options for a combined search" do
57
- new_criteria.search("Hans", "Marek").to_a.map.should == []
59
+ new_criteria.search("text_t:Hans", "text_t:Marek").to_a.map.should == []
58
60
  end
59
61
  end
60
62
 
61
63
  it "includes the returned solr_doc" do
62
- new_criteria.search("Hans").to_a.first.instance_variable_get("@solr_doc").should == {
63
- "id" => "offers/1", "type" => "Offer", "user_id" => 1, "enabled" => [false], "text" => "Hans Meyer", "popularity" => 10,
64
- "location" => "47,11", "type" => "Offer"
64
+ new_criteria.search("text_t:Hans").to_a.first.instance_variable_get("@solr_doc").should == {
65
+ "id" => "offers/1", "type" => "Offer", "user_id_i" => 1, "enabled_b" => false, "text_t" => "Hans Meyer", "popularity_i" => 10,
66
+ "location_p" => "47,11"
65
67
  }
66
68
  end
67
69
 
68
70
  describe "nearby search" do
69
71
  { 49.kms => 1, 51.kms => 2 }.each do |distance, total_entries|
70
72
  it "returns #{total_entries} for distance #{distance}" do
71
- new_criteria.near(47, 11).within(distance).to_a.total_entries.should == total_entries
73
+ new_criteria.attribute_mapping(:location => { :type => :location }).near(47, 11).within(distance).to_a.total_entries.should == total_entries
72
74
  end
73
75
  end
74
76
  end
@@ -76,54 +78,59 @@ describe "Solr" do
76
78
  describe "range search" do
77
79
  { Range.new(2, 3) => [2], Range.new(3, 10) => [], Range.new(1, 2) => [1, 2] }.each do |range, ids|
78
80
  it "returns #{ids.inspect} for range #{range.inspect}" do
79
- new_criteria.with(:user_id => range).map { |doc| doc["id"] }.sort.should == ids
81
+ new_criteria.with(:user_id_i => range).map { |doc| doc["id"] }.sort.should == ids
80
82
  end
81
83
  end
82
84
  end
83
85
 
84
86
  describe "not searches" do
85
87
  it "finds the correct documents for not nil" do
86
- Supernova::Solr.connection.add(:id => "offers/3", :enabled => true, :text => "Marek Mintal", :popularity => 1,
88
+ Supernova::Solr.connection.add(:id => "offers/3", :enabled_b => true, :text_t => "Marek Mintal", :popularity_i => 1,
87
89
  :type => "Offer"
88
90
  )
89
91
  Supernova::Solr.connection.commit
90
92
  raise "There should be 3 docs" if new_criteria.to_a.total_entries != 3
91
- new_criteria.with(:user_id.not => nil).to_a.map { |h| h["id"] }.should == [1, 2]
93
+ new_criteria.with(:user_id_i.not => nil).to_a.map { |h| h["id"] }.should == [1, 2]
92
94
  end
93
95
 
94
96
  it "finds the correct values for not specific value" do
95
- new_criteria.with(:user_id.not => 1).to_a.map { |h| h["id"] }.should == [2]
97
+ new_criteria.with(:user_id_i.not => 1).to_a.map { |h| h["id"] }.should == [2]
96
98
  end
97
99
  end
98
100
 
99
101
  describe "gt and lt searches" do
100
102
  { :gt => [2], :gte => [1, 2], :lt => [], :lte => [1] }.each do |type, ids|
101
103
  it "finds ids #{ids.inspect} for #{type}" do
102
- new_criteria.with(:user_id.send(type) => 1).to_a.map { |row| row["id"] }.sort.should == ids
104
+ new_criteria.with(:user_id_i.send(type) => 1).to_a.map { |row| row["id"] }.sort.should == ids
103
105
  end
104
106
  end
105
107
  end
106
108
 
107
109
  it "returns the correct objects" do
108
- new_criteria.with(:user_id => 1).to_a.first.should be_an_instance_of(Offer)
110
+ new_criteria.with(:user_id_i => 1).to_a.first.should be_an_instance_of(Offer)
109
111
  end
110
112
 
111
113
  { :id => 1, :user_id => 1, :enabled => false, :text => "Hans Meyer", :popularity => 10 }.each do |key, value|
112
114
  it "sets #{key} to #{value}" do
113
- doc = new_criteria.with(:id => "offers/1").to_a.first
115
+ doc = new_criteria.attribute_mapping(
116
+ :user_id => { :type => :integer },
117
+ :enabled => { :type => :boolean },
118
+ :popularity => { :type => :integer },
119
+ :text => { :type => :text}
120
+ ).with(:id => "offers/1").to_a.first
114
121
  doc.send(key).should == value
115
122
  end
116
123
  end
117
124
 
118
125
  it "combines filters" do
119
- new_criteria.with(:user_id => 1, :enabled => false).to_a.total_entries.should == 1
120
- new_criteria.with(:user_id => 1, :enabled => true).to_a.total_entries.should == 0
126
+ new_criteria.with(:user_id_i => 1, :enabled_b => false).to_a.total_entries.should == 1
127
+ new_criteria.with(:user_id_i => 1, :enabled_b => true).to_a.total_entries.should == 0
121
128
  end
122
129
 
123
130
  it "uses without correctly" do
124
- new_criteria.without(:user_id => 1).to_a.map(&:id).should == [2]
125
- new_criteria.without(:user_id => 2).to_a.map(&:id).should == [1]
126
- new_criteria.without(:user_id => 2).without(:user_id => 1).to_a.map(&:id).should == []
131
+ new_criteria.without(:user_id_i => 1).to_a.map(&:id).should == [2]
132
+ new_criteria.without(:user_id_i => 2).to_a.map(&:id).should == [1]
133
+ new_criteria.without(:user_id_i => 2).without(:user_id_i => 1).to_a.map(&:id).should == []
127
134
  end
128
135
 
129
136
  it "uses the correct orders" do
@@ -132,25 +139,25 @@ describe "Solr" do
132
139
  end
133
140
 
134
141
  it "uses the correct pagination attributes" do
135
- new_criteria.with(:user_id => 1, :enabled => false).to_a.total_entries.should == 1
136
- new_criteria.with(:user_id => 1, :enabled => false).length.should == 1
137
- new_criteria.with(:user_id => 1, :enabled => false).paginate(:page => 10).to_a.total_entries.should == 1
138
- new_criteria.with(:user_id => 1, :enabled => false).paginate(:page => 10).length.should == 0
142
+ new_criteria.with(:user_id_i => 1, :enabled_b => false).to_a.total_entries.should == 1
143
+ new_criteria.with(:user_id_i => 1, :enabled_b => false).length.should == 1
144
+ new_criteria.with(:user_id_i => 1, :enabled_b => false).paginate(:page => 10).to_a.total_entries.should == 1
145
+ new_criteria.with(:user_id_i => 1, :enabled_b => false).paginate(:page => 10).length.should == 0
139
146
 
140
147
  new_criteria.paginate(:per_page => 1, :page => 1).to_a.map(&:id).should == [1]
141
148
  new_criteria.paginate(:per_page => 1, :page => 2).to_a.map(&:id).should == [2]
142
149
  end
143
150
 
144
151
  it "handels empty results correctly" do
145
- results = new_criteria.with(:user_id => 1, :enabled => true).to_a
152
+ results = new_criteria.with(:user_id_i => 1, :enabled_b => true).to_a
146
153
  results.total_entries.should == 0
147
154
  results.current_page.should == 1
148
155
  end
149
156
 
150
157
  it "only sets specific attributes" do
151
- results = new_criteria.select(:user_id).with(:user_id => 1).to_a
158
+ results = new_criteria.select(:user_id_i).with(:user_id_i => 1).to_a
152
159
  results.length.should == 1
153
- results.first.should == { "id" => "offers/1", "user_id" => 1 }
160
+ results.first.should == { "id" => "offers/1", "user_id_i" => 1 }
154
161
  end
155
162
  end
156
163
  end
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require "ostruct"
2
3
 
3
4
  describe Supernova::SolrCriteria do
4
5
  let(:criteria) { Supernova::SolrCriteria.new }
@@ -286,6 +287,13 @@ describe Supernova::SolrCriteria do
286
287
  criteria.build_doc(docs.first).should_not be_a_new_record
287
288
  end
288
289
 
290
+ it "uses attribute_mapping when defined" do
291
+ criteria.attribute_mapping(:enabled => { :type => :boolean }, :popularity => { :type => :integer })
292
+ doc = criteria.build_doc("type" => "Offer", "id" => "offers/1", "enabled_b" => true, "popularity_i" => 10)
293
+ doc.should be_an_instance_of(Offer)
294
+ doc.popularity.should == 10
295
+ end
296
+
289
297
  class MongoOffer
290
298
  attr_accessor :id
291
299
  end
@@ -301,6 +309,35 @@ describe Supernova::SolrCriteria do
301
309
  end
302
310
  end
303
311
 
312
+ describe "#reverse_lookup_solr_field" do
313
+ it "returns the key when no mapping found" do
314
+ Supernova::SolrCriteria.new.reverse_lookup_solr_field(:artist_id_s).should == :artist_id_s
315
+ end
316
+
317
+ it "returns the correct original key when mapped" do
318
+ criteria.attribute_mapping(:artist_name => { :type => :string }).reverse_lookup_solr_field(:artist_name_s).should == :artist_name
319
+ end
320
+ end
321
+
322
+ describe "#set_first_responding_attribute" do
323
+ it "sets the reverse looked up attribute when found" do
324
+ doc = OpenStruct.new(:artist_name => nil)
325
+ criteria.attribute_mapping(:artist_name => { :type => :string }).set_first_responding_attribute(doc, :artist_name_s, "Mos Def")
326
+ doc.artist_name.should == "Mos Def"
327
+ end
328
+
329
+ it "sets the original key when no mapping defined" do
330
+ doc = OpenStruct.new(:artist_name_s => nil)
331
+ criteria.attribute_mapping(:artist_name => { :type => :string }).set_first_responding_attribute(doc, :artist_name_s, "Mos Def")
332
+ doc.artist_name_s.should == "Mos Def"
333
+ end
334
+
335
+ it "does not break on unknown keys" do
336
+ doc = double("dummy")
337
+ criteria.attribute_mapping(:artist_name => { :type => :string }).set_first_responding_attribute(doc, :artist_name_s, "Mos Def")
338
+ end
339
+ end
340
+
304
341
  describe "#current_page" do
305
342
  it "returns 1 when pagiantion is not set" do
306
343
  criteria.current_page.should == 1
@@ -25,6 +25,7 @@ describe Supernova::SolrIndexer do
25
25
 
26
26
  before(:each) do
27
27
  File.stub!(:open).and_return file_stub
28
+ Kernel.stub!(:`).and_return true
28
29
  end
29
30
 
30
31
  describe "initialize" do
@@ -238,14 +239,14 @@ describe Supernova::SolrIndexer do
238
239
 
239
240
  it "calls the correct curl command" do
240
241
  indexer.index_file_path = "/tmp/some_path.json"
241
- indexer.should_receive(:system).with("curl -s 'http://solr.xx:9333/solr/update/json?commit=true\\&stream.file=/tmp/some_path.json'")
242
+ Kernel.should_receive(:`).with("curl -s 'http://solr.xx:9333/solr/update/json?commit=true\\&stream.file=/tmp/some_path.json'")
242
243
  indexer.do_index_file(:local => true)
243
244
  end
244
245
 
245
246
  it "executes the correct curl call when not local" do
246
247
  # curl 'http://localhost:8983/solr/update/json?commit=true' --data-binary @books.json -H 'Content-type:application/json'
247
248
  indexer.index_file_path = "/tmp/some_path.json"
248
- indexer.should_receive(:system).with("cd /tmp && curl -s 'http://solr.xx:9333/solr/update/json?commit=true' --data-binary @some_path.json -H 'Content-type:application/json'")
249
+ Kernel.should_receive(:`).with("cd /tmp && curl -s 'http://solr.xx:9333/solr/update/json?commit=true' --data-binary @some_path.json -H 'Content-type:application/json'")
249
250
  indexer.do_index_file
250
251
  end
251
252
  end
@@ -262,6 +263,11 @@ describe Supernova::SolrIndexer do
262
263
  blank_indexer_clazz.field_definitions.should == { :artist_id => { :type => :integer, :sortable => true } }
263
264
  end
264
265
 
266
+ it "has can also be called with a symbol as argument and sets that to the type" do
267
+ blank_indexer_clazz.has(:artist_id, :integer)
268
+ blank_indexer_clazz.field_definitions.should == { :artist_id => { :type => :integer } }
269
+ end
270
+
265
271
  it "clazz sets indexed class" do
266
272
  blank_indexer_clazz.clazz(Integer)
267
273
  blank_indexer_clazz.instance_variable_get("@clazz").should == Integer
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{supernova}
8
- s.version = "0.3.3"
8
+ s.version = "0.3.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Tobias Schwab"]
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: supernova
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 3
9
- - 3
10
- version: 0.3.3
9
+ - 4
10
+ version: 0.3.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - Tobias Schwab