solrizer 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,48 +3,57 @@ require 'solrizer'
3
3
 
4
4
  describe Solrizer::Extractor do
5
5
 
6
- before(:each) do
6
+ before(:all) do
7
7
  @extractor = Solrizer::Extractor.new
8
8
  end
9
9
 
10
- describe ".xml_to_solr" do
11
- it "should turn simple xml into a solr document" do
12
- desc_meta = fixture("druid-bv448hq0314-descMetadata.xml")
13
- result = @extractor.xml_to_solr(desc_meta)
14
- result[:type_t].should == "text"
15
- result[:medium_t].should == "Paper Document"
16
- result[:rights_t].should == "Presumed under copyright. Do not publish."
17
- result[:date_t].should == "1985-12-30"
18
- result[:format_t].should == "application/tiff"
19
- result[:title_t].should == "This is a Sample Title"
20
- result[:publisher_t].should == "Sample Unversity"
21
-
22
- # ... and a hacky way of making sure that it added a field for each of the dc:medium values
23
- result.inspect.include?('@value="application/tiff"').should be_true
24
- result.inspect.include?('@value="application/pdf"').should be_true
10
+ describe "extract_hash" do
11
+ it "should convert a hash to a solr doc" do
12
+ example_hash = {"box"=>"Box 51A", "city"=>["Ann Arbor", "Hyderabad", "Palo Alto"], "person"=>["ELLIE ENGELMORE", "Reddy", "EDWARD FEIGENBAUM"], "title"=>"Letter from Ellie Engelmore to Professor K. C. Reddy", "series"=>"eaf7000", "folder"=>"Folder 15", "technology"=>["artificial intelligence"], "year"=>"1985", "organization"=>["Heuristic Programming Project", "Mathematics and Computer/Information Sciences University of Hyderabad Central University P. O. Hyder", "Professor K. C. Reddy School of Mathematics and Computer/Information Sciences"], "collection"=>"e-a-feigenbaum-collection", "state"=>["Michigan", "California"]}
13
+
14
+ example_result = @extractor.extract_hash( example_hash )
15
+ example_result.should be_kind_of Solr::Document
16
+ example_hash.each_pair do |key,values|
17
+ if values.class == String
18
+ example_result["#{key}_facet"].should == values
19
+ else
20
+ values.each do |v|
21
+ example_result.inspect.include?("@name=\"#{key}_facet\"").should be_true
22
+ example_result.inspect.include?("@value=\"#{v}\"").should be_true
23
+ end
24
+ end
25
+ end
25
26
  end
26
- end
27
-
28
- describe "extract_rels_ext" do
29
- it "should extract the content model of the RELS-EXT datastream of a Fedora object and set hydra_type using hydra_types mapping" do
30
- rels_ext = fixture("rels_ext_cmodel.xml")
31
- result = @extractor.extract_rels_ext( rels_ext )
32
- result[:cmodel_t].should == "info:fedora/fedora-system:ContentModel-3.0"
33
- result[:hydra_type_t].should == "salt_document"
27
+
28
+ it "should handle hashes with facets listed in a sub-hash" do
29
+ simple_hash = Hash[:facets => {'technology'=>["t1", "t2"], 'company'=>"c1", "person"=>["p1", "p2"]}]
30
+ result = @extractor.extract_hash( simple_hash )
31
+ result.should be_kind_of Solr::Document
32
+ result["technology_facet"].should == "t1"
33
+ result.inspect.include?('@boost=nil').should be_true
34
+ result.inspect.include?('@name="technology_facet"').should be_true
35
+ result.inspect.include?('@value="t2"').should be_true
36
+ result["company_facet"].should == "c1"
37
+ result["person_facet"].should == "p1"
38
+ result.inspect.include?('@name="person_facet"').should be_true
39
+ result.inspect.include?('@value="p2"').should be_true
34
40
 
35
- # ... and a hacky way of making sure that it added a field for each of the dc:medium values
36
- result.inspect.include?('@value="info:fedora/afmodel:SaltDocument"').should be_true
37
- result.inspect.include?('@value="jp2_document"').should be_true
38
41
  end
39
- end
42
+
43
+ it "should create symbols from the :symbols subhash" do
44
+ simple_hash = Hash[:facets => {'technology'=>["t1", "t2"], 'company'=>"c1", "person"=>["p1", "p2"]}, :symbols=>{'technology'=>["t1", "t2"], 'company'=>"c1", "person"=>["p1", "p2"]}]
45
+ result = @extractor.extract_hash( simple_hash )
46
+ result.should be_kind_of Solr::Document
47
+ result["technology_s"].should == "t1"
48
+ result.inspect.include?('@name="technology_s"').should be_true
49
+ result.inspect.include?('@value="t2"').should be_true
50
+
51
+ result["company_s"].should == "c1"
52
+ result["person_s"].should == "p1"
53
+ result.inspect.include?('@name="person_s"').should be_true
54
+ result.inspect.include?('@value="p2"').should be_true
40
55
 
41
- describe "extract_hydra_types" do
42
- it "should extract the hydra_type of a Fedora object" do
43
- rels_ext = fixture("rels_ext_cmodel.xml")
44
- result = @extractor.extract_rels_ext( rels_ext )
45
- result[:hydra_type_t].should == "salt_document"
46
56
  end
47
57
  end
48
58
 
49
-
50
59
  end
@@ -0,0 +1,227 @@
1
+ require File.join( File.dirname(__FILE__), "..", "spec_helper" )
2
+
3
+ describe Solrizer::FieldMapper do
4
+
5
+ # --- Test Mappings ----
6
+
7
+ class TestMapper0 < Solrizer::FieldMapper
8
+ id_field 'ident'
9
+ index_as :searchable, :suffix => '_s', :default => true
10
+ index_as :edible, :suffix => '_food'
11
+ index_as :laughable, :suffix => '_haha', :default => true do |type|
12
+ type.integer :suffix => '_ihaha' do |value, field_name|
13
+ "How many #{field_name}s does it take to screw in a light bulb? #{value.capitalize}."
14
+ end
15
+ type.default do |value|
16
+ "Knock knock. Who's there? #{value.capitalize}. #{value.capitalize} who?"
17
+ end
18
+ end
19
+ index_as :fungible, :suffix => '_f0' do |type|
20
+ type.integer :suffix => '_f1'
21
+ type.date
22
+ type.default :suffix => '_f2'
23
+ end
24
+ index_as :unstemmed_searchable, :suffix => '_s' do |type|
25
+ type.date do |value|
26
+ "#{value} o'clock"
27
+ end
28
+ end
29
+ end
30
+
31
+ class TestMapper1 < TestMapper0
32
+ index_as :searchable do |type|
33
+ type.date :suffix => '_d'
34
+ end
35
+ index_as :fungible, :suffix => '_f3' do |type|
36
+ type.garble :suffix => '_f4'
37
+ type.integer :suffix => '_f5'
38
+ end
39
+ end
40
+
41
+ before(:each) do
42
+ @mapper = TestMapper0.new
43
+ end
44
+
45
+ after(:all) do
46
+ end
47
+
48
+ # --- Tests ----
49
+
50
+ it "should handle the id field" do
51
+ @mapper.id_field.should == 'ident'
52
+ end
53
+
54
+ describe '.solr_name' do
55
+ it "should map based on index_as" do
56
+ @mapper.solr_name('bar', :string, :edible).should == 'bar_food'
57
+ @mapper.solr_name('bar', :string, :laughable).should == 'bar_haha'
58
+ end
59
+
60
+ it "should default the index_type to :searchable" do
61
+ @mapper.solr_name('foo', :string).should == 'foo_s'
62
+ end
63
+
64
+ it "should map based on data type" do
65
+ @mapper.solr_name('foo', :integer, :fungible).should == 'foo_f1'
66
+ @mapper.solr_name('foo', :garble, :fungible).should == 'foo_f2' # based on type.default
67
+ @mapper.solr_name('foo', :date, :fungible).should == 'foo_f0' # type.date falls through to container
68
+ end
69
+
70
+ it "should return nil for an unknown index types" do
71
+ silence do
72
+ @mapper.solr_name('foo', :string, :blargle).should == nil
73
+ end
74
+ end
75
+
76
+ it "should allow subclasses to selectively override suffixes" do
77
+ @mapper = TestMapper1.new
78
+ @mapper.solr_name('foo', :date).should == 'foo_d' # override
79
+ @mapper.solr_name('foo', :string).should == 'foo_s' # from super
80
+ @mapper.solr_name('foo', :integer, :fungible).should == 'foo_f5' # override on data type
81
+ @mapper.solr_name('foo', :garble, :fungible).should == 'foo_f4' # override on data type
82
+ @mapper.solr_name('foo', :fratz, :fungible).should == 'foo_f2' # from super
83
+ @mapper.solr_name('foo', :date, :fungible).should == 'foo_f3' # super definition picks up override on index type
84
+ end
85
+
86
+ it "should support field names as symbols" do
87
+ @mapper.solr_name(:active_fedora_model, :symbol).should == "active_fedora_model_s"
88
+ end
89
+
90
+ it "should support scenarios where field_type is nil" do
91
+ mapper = Solrizer::FieldMapper::Default.new
92
+ mapper.solr_name(:heifer, nil, :searchable).should == "heifer_t"
93
+ end
94
+ end
95
+
96
+ describe '.solr_names_and_values' do
97
+ it "should map values based on index_as" do
98
+ @mapper.solr_names_and_values('foo', 'bar', :string, [:searchable, :laughable, :edible]).should == {
99
+ 'foo_s' => ['bar'],
100
+ 'foo_food' => ['bar'],
101
+ 'foo_haha' => ["Knock knock. Who's there? Bar. Bar who?"]
102
+ }
103
+ end
104
+
105
+ it "should apply default index_as mapping unless excluded with not_" do
106
+ @mapper.solr_names_and_values('foo', 'bar', :string, []).should == {
107
+ 'foo_s' => ['bar'],
108
+ 'foo_haha' => ["Knock knock. Who's there? Bar. Bar who?"]
109
+ }
110
+ @mapper.solr_names_and_values('foo', 'bar', :string, [:edible, :not_laughable]).should == {
111
+ 'foo_s' => ['bar'],
112
+ 'foo_food' => ['bar']
113
+ }
114
+ @mapper.solr_names_and_values('foo', 'bar', :string, [:not_searchable, :not_laughable]).should == {}
115
+ end
116
+
117
+ it "should apply mappings based on data type" do
118
+ @mapper.solr_names_and_values('foo', 'bar', :integer, [:searchable, :laughable]).should == {
119
+ 'foo_s' => ['bar'],
120
+ 'foo_ihaha' => ["How many foos does it take to screw in a light bulb? Bar."]
121
+ }
122
+ end
123
+
124
+ it "should skip unknown index types" do
125
+ silence do
126
+ @mapper.solr_names_and_values('foo', 'bar', :string, [:blargle]).should == {
127
+ 'foo_s' => ['bar'],
128
+ 'foo_haha' => ["Knock knock. Who's there? Bar. Bar who?"]
129
+ }
130
+ end
131
+ end
132
+
133
+ it "should generate multiple mappings when two return the _same_ solr name but _different_ values" do
134
+ @mapper.solr_names_and_values('roll', 'rock', :date, [:unstemmed_searchable, :not_laughable]).should == {
135
+ 'roll_s' => ["rock o'clock", 'rock']
136
+ }
137
+ end
138
+
139
+ it "should not generate multiple mappings when two return the _same_ solr name and the _same_ value" do
140
+ @mapper.solr_names_and_values('roll', 'rock', :string, [:unstemmed_searchable, :not_laughable]).should == {
141
+ 'roll_s' => ['rock'],
142
+ }
143
+ end
144
+ end
145
+
146
+ describe "#load_mappings" do
147
+ before(:each) do
148
+ class TestMapperLoading < Solrizer::FieldMapper
149
+ end
150
+ end
151
+ it "should take mappings file as an optional argument" do
152
+ file_path = File.join(File.dirname(__FILE__), "..", "fixtures","test_solr_mappings.yml")
153
+ TestMapperLoading.load_mappings(file_path)
154
+ mapper = TestMapperLoading.new
155
+ mappings_from_file = YAML::load(File.open(file_path))
156
+ mapper.id_field.should == "pid"
157
+ mapper.mappings[:edible].opts[:default].should == true
158
+ mapper.mappings[:edible].data_types[:boolean].opts[:suffix].should == "_edible_bool"
159
+ mappings_from_file["edible"].each_pair do |k,v|
160
+ mapper.mappings[:edible].data_types[k.to_sym].opts[:suffix].should == v
161
+ end
162
+ mapper.mappings[:displayable].opts[:suffix].should == mappings_from_file["displayable"]
163
+ mapper.mappings[:facetable].opts[:suffix].should == mappings_from_file["facetable"]
164
+ mapper.mappings[:sortable].opts[:suffix].should == mappings_from_file["sortable"]
165
+ end
166
+ it 'should default to using the mappings from config/solr_mappings.yml' do
167
+ TestMapperLoading.load_mappings
168
+ mapper = TestMapperLoading.new
169
+ default_file_path = File.join(File.dirname(__FILE__), "..", "..","config","solr_mappings.yml")
170
+ mappings_from_file = YAML::load(File.open(default_file_path))
171
+ mapper.id_field.should == mappings_from_file["id"]
172
+ mappings_from_file["searchable"].each_pair do |k,v|
173
+ mapper.mappings[:searchable].data_types[k.to_sym].opts[:suffix].should == v
174
+ end
175
+ mapper.mappings[:displayable].opts[:suffix].should == mappings_from_file["displayable"]
176
+ mapper.mappings[:facetable].opts[:suffix].should == mappings_from_file["facetable"]
177
+ mapper.mappings[:sortable].opts[:suffix].should == mappings_from_file["sortable"]
178
+ end
179
+ it "should wipe out pre-existing mappings without affecting other FieldMappers" do
180
+ TestMapperLoading.load_mappings
181
+ file_path = File.join(File.dirname(__FILE__), "..", "fixtures","test_solr_mappings.yml")
182
+ TestMapperLoading.load_mappings(file_path)
183
+ mapper = TestMapperLoading.new
184
+ mapper.mappings[:searchable].should be_nil
185
+ default_mapper = Solrizer::FieldMapper::Default.new
186
+ default_mapper.mappings[:searchable].should_not be_nil
187
+ end
188
+ it "should raise an informative error if the yaml file is structured improperly"
189
+ it "should raise an informative error if there is no YAML file"
190
+ end
191
+
192
+ describe Solrizer::FieldMapper::Default do
193
+ before(:each) do
194
+ @mapper = Solrizer::FieldMapper::Default.new
195
+ end
196
+
197
+ it "should call the id field 'id'" do
198
+ @mapper.id_field.should == 'id'
199
+ end
200
+
201
+ it "should apply mappings for searchable by default" do
202
+ # Just sanity check a couple; copy & pasting all data types is silly
203
+ @mapper.solr_names_and_values('foo', 'bar', :string, []).should == { 'foo_t' => ['bar'] }
204
+ @mapper.solr_names_and_values('foo', 'bar', :date, []).should == { 'foo_dt' => ['bar'] }
205
+ end
206
+
207
+ it "should support displayable, facetable, sortable, unstemmed" do
208
+ @mapper.solr_names_and_values('foo', 'bar', :string, [:displayable, :facetable, :sortable, :unstemmed_searchable]).should == {
209
+ 'foo_t' => ['bar'],
210
+ 'foo_display' => ['bar'],
211
+ 'foo_facet' => ['bar'],
212
+ 'foo_sort' => ['bar'],
213
+ 'foo_unstem_search' => ['bar'],
214
+ }
215
+ end
216
+ end
217
+
218
+ def silence
219
+ old_level = @mapper.logger.level
220
+ @mapper.logger.level = 100
221
+ begin
222
+ yield
223
+ ensure
224
+ @mapper.logger.level = old_level
225
+ end
226
+ end
227
+ end
@@ -1,41 +1,28 @@
1
1
  require File.join( File.dirname(__FILE__), "..", "spec_helper" )
2
2
 
3
- # require 'solrizer'
4
- # require 'solrizer/field_name_mapper'
5
-
6
- class FieldNameMapperTest
7
- include Solrizer::FieldNameMapper
8
- end
9
-
10
- def helper
11
- @test_instance
12
- end
13
-
14
3
  describe Solrizer::FieldNameMapper do
15
4
 
16
- before(:each) do
17
- @test_instance = FieldNameMapperTest.new
5
+ before(:all) do
6
+ class TestFieldNameMapper
7
+ include Solrizer::FieldNameMapper
8
+ end
9
+ end
10
+
11
+ describe "#mappings" do
12
+ it "should return at least an id_field value" do
13
+ TestFieldNameMapper.id_field.should == "id"
14
+ end
18
15
  end
19
16
 
20
- after(:all) do
21
- # Revert to default mappings after running tests
22
- Solrizer::FieldNameMapper.load_mappings
17
+ describe '#solr_name' do
18
+ it "should generate solr field names" do
19
+ TestFieldNameMapper.solr_name(:active_fedora_model, :symbol).should == "active_fedora_model_s"
20
+ end
23
21
  end
24
22
 
25
23
  describe ".solr_name" do
26
- it "should generate solr field names from settings in solr_mappings" do
27
- helper.solr_name(:system_create, :date).should == :system_create_dt
28
- end
29
- it "should format the response based on the class of the input" do
30
- helper.solr_name(:system_create, :date).should == :system_create_dt
31
- helper.solr_name("system_create", :date).should == "system_create_dt"
32
- end
33
- it "should rely on whichever mappings have been loaded into the SolrService" do
34
- helper.solr_name(:system_create, :date).should == :system_create_dt
35
- helper.solr_name(:foo, :text).should == :foo_t
36
- Solrizer::FieldNameMapper.load_mappings(File.join(File.dirname(__FILE__), "..", "fixtures", "solr_mappings_af_0.1.yml"))
37
- helper.solr_name(:system_create, :date).should == :system_create_date
38
- helper.solr_name(:foo, :text).should == :foo_field
24
+ it "should generate solr field names" do
25
+ TestFieldNameMapper.new.solr_name(:active_fedora_model, :symbol).should == "active_fedora_model_s"
39
26
  end
40
27
  end
41
28
  end
@@ -0,0 +1,28 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'solrizer'
3
+
4
+ describe Solrizer::XML::Extractor do
5
+
6
+ before(:all) do
7
+ @extractor = Solrizer::Extractor.new
8
+ end
9
+
10
+ describe ".xml_to_solr" do
11
+ it "should turn simple xml into a solr document" do
12
+ desc_meta = fixture("druid-bv448hq0314-descMetadata.xml")
13
+ result = @extractor.xml_to_solr(desc_meta)
14
+ result[:type_t].should == "text"
15
+ result[:medium_t].should == "Paper Document"
16
+ result[:rights_t].should == "Presumed under copyright. Do not publish."
17
+ result[:date_t].should == "1985-12-30"
18
+ result[:format_t].should == "application/tiff"
19
+ result[:title_t].should == "This is a Sample Title"
20
+ result[:publisher_t].should == "Sample Unversity"
21
+
22
+ # ... and a hacky way of making sure that it added a field for each of the dc:medium values
23
+ result.inspect.include?('@value="application/tiff"').should be_true
24
+ result.inspect.include?('@value="application/pdf"').should be_true
25
+ end
26
+ end
27
+
28
+ end
@@ -34,8 +34,9 @@ describe Solrizer::XML::TerminologyBasedSolrizer do
34
34
  # mock_terms = {:name1=>:term1, :name2=>:term2}
35
35
  # ActiveFedora::NokogiriDatastream.stubs(:accessors).returns(mock_accessors)
36
36
  solr_doc = Solr::Document.new
37
+ @mods_article.field_mapper = Solrizer::FieldMapper::Default.new
37
38
  OM::Samples::ModsArticle.terminology.terms.each_pair do |k,v|
38
- @mods_article.expects(:solrize_term).with(v, solr_doc)
39
+ @mods_article.expects(:solrize_term).with(v, solr_doc, @mods_article.field_mapper)
39
40
  end
40
41
  @mods_article.to_solr(solr_doc)
41
42
  end
@@ -49,7 +50,7 @@ describe Solrizer::XML::TerminologyBasedSolrizer do
49
50
  solr_doc[:abstract_t].should == "ABSTRACT"
50
51
  solr_doc[:title_info_1_language_t].should == "finnish"
51
52
  solr_doc[:person_1_role_0_text_t].should == "teacher"
52
-
53
+
53
54
  # These are a holdover from an old verison of OM
54
55
  # solr_doc[:finnish_title_info_language_t].should == "finnish"
55
56
  # solr_doc[:finnish_title_info_main_title_t].should == "Artikkelin otsikko Hydrangea artiklan 1"
@@ -62,7 +63,7 @@ describe Solrizer::XML::TerminologyBasedSolrizer do
62
63
  # solr_doc.should == ""
63
64
 
64
65
  end
65
-
66
+
66
67
  end
67
68
 
68
69
  describe ".solrize_term" do
@@ -73,7 +74,18 @@ describe Solrizer::XML::TerminologyBasedSolrizer do
73
74
  result.should == solr_doc
74
75
  # @mods_article.solrize_term(:title_info, OM::Samples::ModsArticle.terminology.retrieve_term(:title_info), :solr_doc=>solr_doc).should == ""
75
76
  end
76
-
77
+
78
+ it "should add multiple fields based on index_as" do
79
+ fake_solr_doc = [] # duck typing cheat: test will break if solrize_term decides to use methods other than <<
80
+ @mods_article.solrize_term(OM::Samples::ModsArticle.terminology.retrieve_term(:name), fake_solr_doc)
81
+
82
+ expected_names = ["DR.", "FAMILY NAME", "GIVEN NAMES"]
83
+ %w(_t _display _facet).each do |suffix|
84
+ actual_names = fake_solr_doc.select { |field| field.name == 'name_0_namePart' + suffix }.map { |field| field.value }.sort
85
+ {suffix => actual_names}.should == {suffix => expected_names}
86
+ end
87
+ end
88
+
77
89
  end
78
90
 
79
91
  describe ".solrize_node" do
@@ -81,8 +93,9 @@ describe Solrizer::XML::TerminologyBasedSolrizer do
81
93
  doc = Solr::Document.new
82
94
  # @mods_article.solrize_node(node, term_pointer, term, solr_doc).should equal(doc)
83
95
  end
96
+
84
97
  it "should create a solr field containing node.text"
85
98
  it "should create hierarchical field entries if parents is not empty"
86
99
  it "should only create one node if parents is empty"
87
100
  end
88
- end
101
+ end