om 1.8.1 → 1.9.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/container_spec.rb +14 -14
- data/lib/om.rb +12 -9
- data/lib/om/samples/mods_article.rb +9 -9
- data/lib/om/tree_node.rb +6 -6
- data/lib/om/version.rb +1 -1
- data/lib/om/xml.rb +33 -31
- data/lib/om/xml/container.rb +12 -12
- data/lib/om/xml/document.rb +19 -18
- data/lib/om/xml/dynamic_node.rb +50 -45
- data/lib/om/xml/named_term_proxy.rb +13 -13
- data/lib/om/xml/node_generator.rb +3 -3
- data/lib/om/xml/template_registry.rb +26 -18
- data/lib/om/xml/term.rb +46 -30
- data/lib/om/xml/term_value_operators.rb +56 -52
- data/lib/om/xml/term_xpath_generator.rb +57 -51
- data/lib/om/xml/terminology.rb +10 -8
- data/lib/om/xml/terminology_based_solrizer.rb +90 -0
- data/lib/om/xml/validation.rb +19 -19
- data/lib/om/xml/vocabulary.rb +4 -4
- data/lib/tasks/om.rake +6 -4
- data/om.gemspec +2 -1
- data/spec/fixtures/mods_article.rb +90 -0
- data/spec/fixtures/mods_articles/hydrangea_article1.xml +2 -2
- data/spec/integration/differentiated_elements_spec.rb +2 -2
- data/spec/integration/element_value_spec.rb +13 -13
- data/spec/integration/proxies_and_ref_spec.rb +15 -15
- data/spec/integration/querying_documents_spec.rb +18 -24
- data/spec/integration/rights_metadata_integration_example_spec.rb +18 -18
- data/spec/integration/selective_querying_spec.rb +1 -1
- data/spec/integration/serialization_spec.rb +13 -13
- data/spec/integration/set_reentrant_terminology_spec.rb +10 -10
- data/spec/integration/xpathy_stuff_spec.rb +16 -16
- data/spec/spec_helper.rb +2 -2
- data/spec/unit/container_spec.rb +29 -28
- data/spec/unit/document_spec.rb +50 -49
- data/spec/unit/dynamic_node_spec.rb +45 -57
- data/spec/unit/named_term_proxy_spec.rb +16 -16
- data/spec/unit/node_generator_spec.rb +7 -7
- data/spec/unit/nokogiri_sanity_spec.rb +30 -30
- data/spec/unit/om_spec.rb +5 -5
- data/spec/unit/template_registry_spec.rb +69 -69
- data/spec/unit/term_builder_spec.rb +77 -77
- data/spec/unit/term_spec.rb +73 -79
- data/spec/unit/term_value_operators_spec.rb +191 -186
- data/spec/unit/term_xpath_generator_spec.rb +43 -37
- data/spec/unit/terminology_builder_spec.rb +85 -85
- data/spec/unit/terminology_spec.rb +98 -98
- data/spec/unit/validation_spec.rb +22 -22
- data/spec/unit/xml_serialization_spec.rb +22 -21
- data/spec/unit/xml_spec.rb +7 -7
- data/spec/unit/xml_terminology_based_solrizer_spec.rb +109 -0
- metadata +57 -17
- checksums.yaml +0 -7
- data/.rspec +0 -1
- data/.rubocop.yml +0 -1
- data/.rubocop_todo.yml +0 -382
- data/.travis.yml +0 -10
- data/gemfiles/gemfile.rails3 +0 -11
- data/gemfiles/gemfile.rails4 +0 -10
@@ -1,55 +1,55 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe "OM::XML::TermValueOperators" do
|
4
|
-
|
4
|
+
|
5
5
|
before(:each) do
|
6
|
-
@sample
|
7
|
-
@article
|
8
|
-
@empty_sample = OM::Samples::ModsArticle.from_xml(
|
6
|
+
@sample = OM::Samples::ModsArticle.from_xml( fixture( File.join("test_dummy_mods.xml") ) )
|
7
|
+
@article = OM::Samples::ModsArticle.from_xml( fixture( File.join("mods_articles","hydrangea_article1.xml") ) )
|
8
|
+
@empty_sample = OM::Samples::ModsArticle.from_xml("")
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
describe ".term_values" do
|
12
12
|
|
13
13
|
it "should return build an array of values from the nodeset corresponding to the given term" do
|
14
14
|
expected_values = ["Berners-Lee", "Jobs", "Wozniak", "Klimt"]
|
15
15
|
result = @sample.term_values(:person, :last_name)
|
16
|
-
|
17
|
-
expected_values.each {|v|
|
16
|
+
result.length.should == expected_values.length
|
17
|
+
expected_values.each {|v| result.should include(v)}
|
18
18
|
end
|
19
19
|
|
20
20
|
it "should ignore whitespace elements for a term pointing to a text() node for an element that contains children" do
|
21
|
-
|
21
|
+
@article.term_values(:name, :name_content).should == ["Describes a person"]
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
end
|
25
|
-
|
26
|
-
|
25
|
+
|
26
|
+
|
27
27
|
describe ".update_values" do
|
28
28
|
it "should update the xml according to the find_by_terms_and_values in the given hash" do
|
29
29
|
terms_update_hash = {[{":person"=>"0"}, "affiliation"]=>{"0"=>"affiliation1", "1"=>"affiliation2".freeze, "2"=>"affiliation3"}, [{:person=>1}, :last_name]=>"Andronicus", [{"person"=>"1"},:first_name]=>["Titus"],[{:person=>1},:role]=>["otherrole1","otherrole2"] }
|
30
30
|
result = @article.update_values(terms_update_hash)
|
31
|
-
|
31
|
+
result.should == {"person_0_affiliation"=>{"0"=>"affiliation1", "1"=>"affiliation2", "2"=>"affiliation3"}, "person_1_last_name"=>{"0"=>"Andronicus"},"person_1_first_name"=>{"0"=>"Titus"}, "person_1_role"=>{"0"=>"otherrole1","1"=>"otherrole2"}}
|
32
32
|
person_0_affiliation = @article.find_by_terms({:person=>0}, :affiliation)
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
person_0_affiliation[0].text.should == "affiliation1"
|
34
|
+
person_0_affiliation[1].text.should == "affiliation2"
|
35
|
+
person_0_affiliation[2].text.should == "affiliation3"
|
36
|
+
|
37
37
|
person_1_last_names = @article.find_by_terms({:person=>1}, :last_name)
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
person_1_last_names.length.should == 1
|
39
|
+
person_1_last_names.first.text.should == "Andronicus"
|
40
|
+
|
41
41
|
person_1_first_names = @article.find_by_terms({:person=>1}, :first_name)
|
42
|
-
|
43
|
-
|
42
|
+
person_1_first_names.first.text.should == "Titus"
|
43
|
+
|
44
44
|
person_1_roles = @article.find_by_terms({:person=>1}, :role)
|
45
|
-
|
46
|
-
|
45
|
+
person_1_roles[0].text.should == "otherrole1"
|
46
|
+
person_1_roles[1].text.should == "otherrole2"
|
47
47
|
end
|
48
48
|
it "should call term_value_update if the corresponding node already exists" do
|
49
|
-
|
49
|
+
@article.should_receive(:term_value_update).with('//oxns:titleInfo/oxns:title', 0, "My New Title")
|
50
50
|
@article.update_values( {[:title_info, :main_title] => "My New Title"} )
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
it "should call term_values_append if the corresponding node does not already exist or if the requested index is -1" do
|
54
54
|
expected_args = {
|
55
55
|
# :parent_select => OM::Samples::ModsArticle.terminology.xpath_with_indexes(*[{:person=>0}]) ,
|
@@ -58,200 +58,204 @@ describe "OM::XML::TermValueOperators" do
|
|
58
58
|
:template => [:person, :role],
|
59
59
|
:values => "My New Role"
|
60
60
|
}
|
61
|
-
|
61
|
+
@article.should_receive(:term_values_append).with(expected_args).twice
|
62
62
|
@article.update_values( {[{:person=>0}, :role] => {"6"=>"My New Role"}} )
|
63
63
|
@article.update_values( {[{:person=>0}, :role] => {"-1"=>"My New Role"}} )
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
it "should support updating attribute values" do
|
67
67
|
pointer = [:title_info, :language]
|
68
68
|
test_val = "language value"
|
69
69
|
@article.update_values( {pointer=>{"0"=>test_val}} )
|
70
|
-
|
70
|
+
@article.term_values(*pointer).first.should == test_val
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
it "should not get tripped up on root nodes" do
|
74
74
|
@article.update_values([:title_info]=>{"0"=>"york", "1"=>"mangle","2"=>"mork"})
|
75
|
-
|
75
|
+
@article.term_values(*[:title_info]).should == ["york", "mangle", "mork"]
|
76
76
|
end
|
77
77
|
|
78
78
|
it "should destringify the field key/find_by_terms_and_value pointer" do
|
79
|
-
|
80
|
-
|
79
|
+
OM::Samples::ModsArticle.terminology.should_receive(:xpath_with_indexes).with( *[{:person=>0}, :role]).exactly(10).times.and_return("//oxns:name[@type=\"personal\"][1]/oxns:role")
|
80
|
+
OM::Samples::ModsArticle.terminology.stub(:xpath_with_indexes).with( *[{:person=>0}]).and_return("//oxns:name[@type=\"personal\"][1]")
|
81
81
|
@article.update_values( { [{":person"=>"0"}, "role"]=>"the role" } )
|
82
82
|
@article.update_values( { [{"person"=>"0"}, "role"]=>"the role" } )
|
83
83
|
@article.update_values( { [{:person=>0}, :role]=>"the role" } )
|
84
84
|
end
|
85
|
-
|
85
|
+
|
86
86
|
it "should traverse named term proxies transparently" do
|
87
|
-
|
87
|
+
@article.term_values( :journal, :issue, :start_page).should_not == ["108"]
|
88
88
|
@article.update_values( { ["journal", "issue", "start_page"]=>"108" } )
|
89
|
-
|
90
|
-
|
89
|
+
@article.term_values( :journal, :issue, :start_page).should == ["108"]
|
90
|
+
@article.term_values( :journal, :issue, :pages, :start).should == ["108"]
|
91
91
|
end
|
92
|
-
|
92
|
+
|
93
93
|
it "should create the necessary ancestor nodes when necessary" do
|
94
|
-
|
94
|
+
@sample.find_by_terms(:person).length.should == 4
|
95
95
|
@sample.update_values([{:person=>8}, :role, :text]=>"my role")
|
96
96
|
person_entries = @sample.find_by_terms(:person)
|
97
|
-
|
98
|
-
|
97
|
+
person_entries.length.should == 5
|
98
|
+
person_entries[4].search("./ns3:role").first.text.should == "my role"
|
99
99
|
end
|
100
|
-
|
100
|
+
|
101
101
|
it "should create deep trees of ancestor nodes" do
|
102
102
|
result = @article.update_values( {[{:journal=>0}, {:issue=>3}, :pages, :start]=>{"0"=>"434"} })
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
#
|
108
|
-
|
109
|
-
|
103
|
+
@article.find_by_terms({:journal=>0}, :issue).length.should == 2
|
104
|
+
@article.find_by_terms({:journal=>0}, {:issue=>1}, :pages).length.should == 1
|
105
|
+
@article.find_by_terms({:journal=>0}, {:issue=>1}, :pages, :start).length.should == 1
|
106
|
+
@article.find_by_terms({:journal=>0}, {:issue=>1}, :pages, :start).first.text.should == "434"
|
107
|
+
#Last argument is a filter, we must explicitly pass no filter
|
108
|
+
@article.class.terminology.xpath_with_indexes(:subject, {:topic=>1}, {}).should == '//oxns:subject/oxns:topic[2]'
|
109
|
+
@article.find_by_terms(:subject, {:topic => 1}, {}).text.should == "TOPIC 2"
|
110
110
|
end
|
111
|
-
|
111
|
+
|
112
112
|
it "should accommodate appending term values with apostrophes in them" do
|
113
|
-
|
113
|
+
@article.find_by_terms(:person, :description).should be_empty # making sure that there's no description node -- forces a value_append
|
114
114
|
terms_update_hash = {[:person, :description]=>" 'phrul gyi lde mig"}
|
115
115
|
result = @article.update_values(terms_update_hash)
|
116
|
-
|
116
|
+
@article.term_values(:person, :description).should include(" 'phrul gyi lde mig")
|
117
117
|
end
|
118
|
-
|
118
|
+
|
119
119
|
it "should support inserting nodes with namespaced attributes" do
|
120
120
|
@sample.update_values({['title_info', 'french_title']=>'Le Titre'})
|
121
|
-
|
121
|
+
@sample.term_values('title_info', 'french_title').should == ['Le Titre']
|
122
122
|
end
|
123
123
|
|
124
124
|
it "should support inserting attributes" do
|
125
|
-
|
125
|
+
pending "HYDRA-415"
|
126
126
|
@sample.update_values({['title_info', 'language']=>'Le Titre'})
|
127
|
-
|
127
|
+
@sample.term_values('title_info', 'french_title').should == ['Le Titre']
|
128
128
|
end
|
129
|
-
|
129
|
+
|
130
130
|
it "should support inserting namespaced attributes" do
|
131
|
-
|
131
|
+
pending "HYDRA-415"
|
132
132
|
@sample.update_values({['title_info', 'main_title', 'main_title_lang']=>'eng'})
|
133
|
-
|
133
|
+
@sample.term_values('title_info', 'main_title', 'main_title_lang').should == ['eng']
|
134
134
|
## After a proxy
|
135
|
-
|
135
|
+
@article.term_values(:title,:main_title_lang).should == ['eng']
|
136
136
|
end
|
137
|
-
|
137
|
+
|
138
138
|
### Examples copied over form nokogiri_datastream_spec
|
139
|
-
|
139
|
+
|
140
140
|
it "should apply submitted hash to corresponding datastream field values" do
|
141
141
|
result = @article.update_values( {[{":person"=>"0"}, "first_name"]=>{"0"=>"Billy", "1"=>"Bob", "2"=>"Joe"} })
|
142
|
-
|
142
|
+
result.should == {"person_0_first_name"=>{"0"=>"Billy", "1"=>"Bob", "2"=>"Joe"}}
|
143
143
|
# xpath = ds.class.xpath_with_indexes(*field_key)
|
144
144
|
# result = ds.term_values(xpath)
|
145
|
-
|
146
|
-
|
145
|
+
@article.term_values({:person=>0}, :first_name).should == ["Billy","Bob","Joe"]
|
146
|
+
@article.term_values('//oxns:name[@type="personal"][1]/oxns:namePart[@type="given"]').should == ["Billy","Bob","Joe"]
|
147
147
|
end
|
148
148
|
it "should support single-value arguments (as opposed to a hash of values with array indexes as keys)" do
|
149
149
|
# In other words, { [:journal, :title_info]=>"dork" } should have the same effect as { [:journal, :title_info]=>{"0"=>"dork"} }
|
150
150
|
result = @article.update_values( { [{":person"=>"0"}, "role"]=>"the role" } )
|
151
|
-
|
152
|
-
|
153
|
-
|
151
|
+
result.should == {"person_0_role"=>{"0"=>"the role"}}
|
152
|
+
@article.term_values({:person=>0}, :role).first.should == "the role"
|
153
|
+
@article.term_values('//oxns:name[@type="personal"][1]/oxns:role').first.should == "the role"
|
154
154
|
end
|
155
155
|
it "should do nothing if field key is a string (must be an array or symbol). Will not accept xpath queries!" do
|
156
156
|
xml_before = @article.to_xml
|
157
|
-
|
158
|
-
|
157
|
+
@article.update_values( { "fubar"=>"the role" } ).should == {}
|
158
|
+
@article.to_xml.should == xml_before
|
159
159
|
end
|
160
160
|
it "should do nothing if there is no term corresponding to the given field key" do
|
161
161
|
xml_before = @article.to_xml
|
162
|
-
|
163
|
-
|
162
|
+
@article.update_values( { [{"fubar"=>"0"}]=>"the role" } ).should == {}
|
163
|
+
@article.to_xml.should == xml_before
|
164
164
|
end
|
165
|
-
|
166
|
-
it "should work for text fields" do
|
167
|
-
att
|
165
|
+
|
166
|
+
it "should work for text fields" do
|
167
|
+
att= {[{"person"=>"0"},"description"]=>{"-1"=>"mork", "1"=>"york"}}
|
168
168
|
result = @article.update_values(att)
|
169
|
-
|
170
|
-
|
171
|
-
att
|
169
|
+
result.should == {"person_0_description"=>{"0"=>"mork","1"=>"york"}}
|
170
|
+
@article.term_values({:person=>0},:description).should == ['mork', 'york']
|
171
|
+
att= {[{"person"=>"0"},"description"]=>{"-1"=>"dork"}}
|
172
172
|
result2 = @article.update_values(att)
|
173
|
-
|
174
|
-
|
173
|
+
result2.should == {"person_0_description"=>{"2"=>"dork"}}
|
174
|
+
@article.term_values({:person=>0},:description).should == ['mork', 'york', 'dork']
|
175
175
|
end
|
176
|
-
|
176
|
+
|
177
177
|
it "should return the new index of any added values" do
|
178
|
-
|
178
|
+
@article.term_values({:title_info=>0},:main_title).should == ["ARTICLE TITLE HYDRANGEA ARTICLE 1", "TITLE OF HOST JOURNAL"]
|
179
179
|
result = @article.update_values [{"title_info"=>"0"},"main_title"]=>{"-1"=>"mork"}
|
180
|
-
|
180
|
+
result.should == {"title_info_0_main_title"=>{"2"=>"mork"}}
|
181
181
|
end
|
182
|
-
|
182
|
+
|
183
183
|
it "should return accurate response when multiple values have been added in a single run" do
|
184
|
-
|
184
|
+
pending "THIS SHOULD BE FIXED"
|
185
185
|
att= {[:journal, :title_info]=>{"-1"=>"mork", "0"=>"york"}}
|
186
|
-
|
187
|
-
|
186
|
+
@article.update_values(att).should == {"journal_title_info"=>{"0"=>"york", "1"=>"mork"}}
|
187
|
+
@article.term_values(*att.keys.first).should == ["york", "mork"]
|
188
188
|
end
|
189
|
-
|
189
|
+
|
190
190
|
it "should append nodes at the specified index if possible" do
|
191
191
|
@article.update_values([:journal, :title_info]=>["all", "for", "the"])
|
192
192
|
att = {[:journal, :title_info]=>{"3"=>'glory'}}
|
193
193
|
result = @article.update_values(att)
|
194
|
-
|
195
|
-
|
194
|
+
result.should == {"journal_title_info"=>{"3"=>"glory"}}
|
195
|
+
@article.term_values(:journal, :title_info).should == ["all", "for", "the", "glory"]
|
196
196
|
end
|
197
|
-
|
197
|
+
|
198
198
|
it "should append values to the end of the array if the specified index is higher than the length of the values array" do
|
199
199
|
att = {[:journal, :issue, :pages, :end]=>{"3"=>'108'}}
|
200
|
-
|
200
|
+
@article.term_values(:journal, :issue, :pages, :end).should == []
|
201
201
|
result = @article.update_values(att)
|
202
|
-
|
203
|
-
|
202
|
+
result.should == {"journal_issue_pages_end"=>{"0"=>"108"}}
|
203
|
+
@article.term_values(:journal, :issue, :pages, :end).should == ["108"]
|
204
204
|
end
|
205
|
-
|
205
|
+
|
206
206
|
it "should allow deleting of values and should delete values so that to_xml does not return emtpy nodes" do
|
207
207
|
att= {[:journal, :title_info]=>{"0"=>"york", "1"=>"mangle","2"=>"mork"}}
|
208
208
|
@article.update_values(att)
|
209
|
-
|
210
|
-
|
209
|
+
@article.term_values(:journal, :title_info).should == ['york', 'mangle', 'mork']
|
210
|
+
|
211
211
|
@article.update_values({[:journal, :title_info]=>{"1"=>""}})
|
212
|
-
|
213
|
-
|
212
|
+
@article.term_values(:journal, :title_info).should == ['york', 'mork']
|
213
|
+
|
214
214
|
@article.update_values({[:journal, :title_info]=>{"0"=>:delete}})
|
215
|
-
|
215
|
+
@article.term_values(:journal, :title_info).should == ['mork']
|
216
216
|
end
|
217
217
|
|
218
218
|
describe "delete_on_update?" do
|
219
|
+
|
219
220
|
before(:each) do
|
220
221
|
att= {[:journal, :title_info]=>{"0"=>"york", "1"=>"mangle","2"=>"mork"}}
|
221
222
|
@article.update_values(att)
|
222
|
-
|
223
|
+
@article.term_values(:journal, :title_info).should == ['york', 'mangle', 'mork']
|
223
224
|
end
|
225
|
+
|
224
226
|
it "by default, setting to empty string deletes the node" do
|
225
227
|
@article.update_values({[:journal, :title_info]=>{"1"=>""}})
|
226
|
-
|
228
|
+
@article.term_values(:journal, :title_info).should == ['york', 'mork']
|
227
229
|
end
|
230
|
+
|
228
231
|
it "if delete_on_update? returns false, setting to empty string won't delete node" do
|
229
|
-
|
232
|
+
@article.stub('delete_on_update?').and_return(false)
|
230
233
|
@article.update_values({[:journal, :title_info]=>{"1"=>""}})
|
231
|
-
|
234
|
+
@article.term_values(:journal, :title_info).should == ['york', '', 'mork']
|
232
235
|
end
|
236
|
+
|
233
237
|
end
|
234
238
|
|
235
239
|
it "should retain other child nodes when updating a text content term and shoud not append an additional text node but update text in place" do
|
236
|
-
|
240
|
+
@article.term_values(:name,:name_content).should == ["Describes a person"]
|
237
241
|
@article.update_values({[:name, :name_content]=>"Test text"})
|
238
|
-
|
239
|
-
|
242
|
+
@article.term_values(:name,:name_content).should == ["Test text"]
|
243
|
+
@article.find_by_terms(:name).children.length().should == 35
|
240
244
|
end
|
241
|
-
|
245
|
+
|
242
246
|
end
|
243
|
-
|
247
|
+
|
244
248
|
describe ".term_values_append" do
|
245
|
-
|
246
|
-
it "looks up the parent using :parent_select, uses :parent_index to choose the parent node from the result set, uses :template to build the node(s) to be inserted, inserts the :values(s) into the node(s) and adds the node(s) to the parent" do
|
249
|
+
|
250
|
+
it "looks up the parent using :parent_select, uses :parent_index to choose the parent node from the result set, uses :template to build the node(s) to be inserted, inserts the :values(s) into the node(s) and adds the node(s) to the parent" do
|
247
251
|
@sample.term_values_append(
|
248
252
|
:parent_select => [:person, {:first_name=>"Tim", :last_name=>"Berners-Lee"}] ,
|
249
253
|
:parent_index => :first,
|
250
254
|
:template => [:person, :affiliation],
|
251
|
-
:values => ["my new value", "another new value"]
|
255
|
+
:values => ["my new value", "another new value"]
|
252
256
|
)
|
253
257
|
end
|
254
|
-
|
258
|
+
|
255
259
|
it "should accept parent_select and template [term_reference, find_by_terms_and_value_opts] as argument arrays for generators/find_by_terms_and_values" do
|
256
260
|
# this appends two affiliation nodes into the first person node whose name is Tim Berners-Lee
|
257
261
|
expected_result = '<ns3:name type="personal">
|
@@ -262,192 +266,193 @@ describe "OM::XML::TermValueOperators" do
|
|
262
266
|
<ns3:roleTerm type="code" authority="marcrelator">cre</ns3:roleTerm>
|
263
267
|
</ns3:role>
|
264
268
|
<ns3:affiliation>my new value</ns3:affiliation><ns3:affiliation>another new value</ns3:affiliation></ns3:name>'
|
265
|
-
|
266
|
-
|
269
|
+
|
270
|
+
@sample.term_values_append(
|
267
271
|
:parent_select => [:person, {:first_name=>"Tim", :last_name=>"Berners-Lee"}] ,
|
268
272
|
:parent_index => :first,
|
269
273
|
:template => [:person, :affiliation],
|
270
|
-
:values => ["my new value", "another new value"]
|
271
|
-
).to_xml
|
272
|
-
|
273
|
-
|
274
|
+
:values => ["my new value", "another new value"]
|
275
|
+
).to_xml.should == expected_result
|
276
|
+
|
277
|
+
@sample.find_by_terms(:person, {:first_name=>"Tim", :last_name=>"Berners-Lee"}).first.to_xml.should == expected_result
|
274
278
|
end
|
275
|
-
|
279
|
+
|
276
280
|
it "should support adding attribute values" do
|
277
281
|
pointer = [{:title_info=>0}, :language]
|
278
282
|
test_val = "language value"
|
279
|
-
@article.term_values_append(
|
283
|
+
@article.term_values_append(
|
280
284
|
:parent_select => [{:title_info=>0}],
|
281
285
|
:parent_index => 0,
|
282
286
|
:template => [{:title_info=>0}, :language],
|
283
287
|
:values => test_val
|
284
288
|
)
|
285
|
-
|
289
|
+
@article.term_values(*pointer).first.should == test_val
|
286
290
|
end
|
287
|
-
|
291
|
+
|
288
292
|
it "should accept symbols as arguments for generators/find_by_terms_and_values" do
|
289
293
|
# this appends a role of "my role" into the third "person" node in the document
|
290
294
|
@sample.term_values_append(
|
291
295
|
:parent_select => :person ,
|
292
296
|
:parent_index => 3,
|
293
297
|
:template => :role,
|
294
|
-
:values => "my role"
|
295
|
-
)
|
296
|
-
|
298
|
+
:values => "my role"
|
299
|
+
).to_xml.should #== expected_result
|
300
|
+
@sample.find_by_terms(:person)[3].search("./ns3:role[3]").first.text.should == "my role"
|
297
301
|
end
|
298
|
-
|
302
|
+
|
299
303
|
it "should accept parent_select as an (xpath) string and template as a (template) string" do
|
300
304
|
# this uses the provided template to add a node into the first node resulting from the xpath '//oxns:name[@type="personal"]'
|
301
305
|
expected_result = "<ns3:name type=\"personal\">\n <ns3:namePart type=\"family\">Berners-Lee</ns3:namePart>\n <ns3:namePart type=\"given\">Tim</ns3:namePart>\n <ns3:role>\n <ns3:roleTerm type=\"text\" authority=\"marcrelator\">creator</ns3:roleTerm>\n <ns3:roleTerm type=\"code\" authority=\"marcrelator\">cre</ns3:roleTerm>\n </ns3:role>\n <ns3:role type=\"code\" authority=\"marcrelator\"><ns3:roleTerm>creator</ns3:roleTerm></ns3:role></ns3:name>"
|
302
|
-
|
303
|
-
|
304
|
-
|
306
|
+
|
307
|
+
@sample.ng_xml.xpath('//oxns:name[@type="personal" and position()=1]/oxns:role', @sample.ox_namespaces).length.should == 1
|
308
|
+
|
305
309
|
@sample.term_values_append(
|
306
310
|
:parent_select =>'//oxns:name[@type="personal"]',
|
307
311
|
:parent_index => 0,
|
308
312
|
:template => 'xml.role { xml.roleTerm( \'#{builder_new_value}\', :type=>\'code\', :authority=>\'marcrelator\') }',
|
309
|
-
:values => "founder"
|
313
|
+
:values => "founder"
|
310
314
|
)
|
311
315
|
|
312
|
-
|
313
|
-
|
316
|
+
@sample.ng_xml.xpath('//oxns:name[@type="personal" and position()=1]/oxns:role', @sample.ox_namespaces).length.should == 2
|
317
|
+
@sample.ng_xml.xpath('//oxns:name[@type="personal" and position()=1]/oxns:role[last()]/oxns:roleTerm', @sample.ox_namespaces).first.text.should == "founder"
|
314
318
|
|
315
319
|
# @sample.find_by_terms_and_value(:person).first.to_xml.should == expected_result
|
316
320
|
end
|
317
|
-
|
321
|
+
|
318
322
|
it "should support more complex mixing & matching" do
|
319
|
-
|
320
|
-
|
323
|
+
pending "not working because builder_template is not returning the correct template (returns builder for role instead of roleTerm)"
|
324
|
+
@sample.ng_xml.xpath('//oxns:name[@type="personal"][2]/oxns:role[1]/oxns:roleTerm', @sample.ox_namespaces).length.should == 2
|
321
325
|
@sample.term_values_append(
|
322
326
|
:parent_select =>'//oxns:name[@type="personal"][2]/oxns:role',
|
323
327
|
:parent_index => 0,
|
324
328
|
:template => [ :person, :role, :text, {:attributes=>{"authority"=>"marcrelator"}} ],
|
325
|
-
:values => "foo"
|
329
|
+
:values => "foo"
|
326
330
|
)
|
327
331
|
|
328
|
-
|
329
|
-
|
332
|
+
@sample.ng_xml.xpath('//oxns:name[@type="personal"][2]/oxns:role[1]/oxns:roleTerm', @sample.ox_namespaces).length.should == 3
|
333
|
+
@sample.find_by_terms({:person=>1},:role)[0].search("./oxns:roleTerm[@type=\"text\" and @authority=\"marcrelator\"]", @sample.ox_namespaces).first.text.should == "foo"
|
330
334
|
end
|
331
|
-
|
335
|
+
|
332
336
|
it "should create the necessary ancestor nodes when you insert a new term value" do
|
333
|
-
|
337
|
+
@sample.find_by_terms(:person).length.should == 4
|
334
338
|
@sample.term_values_append(
|
335
339
|
:parent_select => :person ,
|
336
340
|
:parent_index => 8,
|
337
341
|
:template => :role,
|
338
|
-
:values => "my role"
|
342
|
+
:values => "my role"
|
339
343
|
)
|
340
344
|
person_entries = @sample.find_by_terms(:person)
|
341
|
-
|
342
|
-
|
345
|
+
person_entries.length.should == 5
|
346
|
+
person_entries[4].search("./ns3:role").first.text.should == "my role"
|
343
347
|
end
|
344
|
-
|
348
|
+
|
345
349
|
it "should create the necessary ancestor nodes for deep trees of ancestors" do
|
346
350
|
deep_pointer = [{:journal=>0}, {:issue=>3}, :pages, :start]
|
347
|
-
|
348
|
-
|
351
|
+
@article.find_by_terms({:journal=>0}).length.should == 1
|
352
|
+
@article.find_by_terms({:journal=>0}, :issue).length.should == 1
|
349
353
|
@article.term_values_append(
|
350
354
|
:parent_select => deep_pointer[0..deep_pointer.length-2] ,
|
351
355
|
:parent_index => 0,
|
352
356
|
:template => deep_pointer,
|
353
|
-
:values => "451"
|
357
|
+
:values => "451"
|
354
358
|
)
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
+
@article.find_by_terms({:journal=>0}, :issue).length.should == 2
|
360
|
+
@article.find_by_terms({:journal=>0}, {:issue=>1}, :pages).length.should == 1
|
361
|
+
@article.find_by_terms({:journal=>0}, {:issue=>1}, :pages, :start).length.should == 1
|
362
|
+
@article.find_by_terms({:journal=>0}, {:issue=>1}, :pages, :start).first.text.should == "451"
|
363
|
+
|
359
364
|
end
|
360
|
-
|
365
|
+
|
361
366
|
end
|
362
|
-
|
367
|
+
|
363
368
|
describe ".term_value_update" do
|
364
|
-
|
369
|
+
|
365
370
|
it "should accept an xpath as :parent_select" do
|
366
371
|
sample_xpath = '//oxns:name[@type="personal"][4]/oxns:role/oxns:roleTerm[@type="text"]'
|
367
372
|
@sample.term_value_update(sample_xpath,1,"artist")
|
368
|
-
|
373
|
+
@sample.ng_xml.xpath(sample_xpath, @sample.ox_namespaces)[1].text.should == "artist"
|
369
374
|
end
|
370
|
-
|
375
|
+
|
371
376
|
it "if :select is provided, should update the first node provided by that xpath statement" do
|
372
377
|
sample_xpath = '//oxns:name[@type="personal"][1]/oxns:namePart[@type="given"]'
|
373
378
|
@sample.term_value_update(sample_xpath,0,"Timmeh")
|
374
|
-
|
379
|
+
@sample.ng_xml.xpath(sample_xpath, @sample.ox_namespaces).first.text.should == "Timmeh"
|
375
380
|
end
|
376
|
-
|
381
|
+
|
377
382
|
it "should replace the existing node if you pass a template and values" do
|
378
|
-
|
383
|
+
pending
|
379
384
|
@sample.term_value_update(
|
380
385
|
:parent_select =>'//oxns:name[@type="personal"]',
|
381
386
|
:parent_index => 1,
|
382
387
|
:template => [ :person, :role, {:attributes=>{"type"=>"code", "authority"=>"marcrelator"}} ],
|
383
388
|
:value => "foo"
|
384
389
|
)
|
385
|
-
|
390
|
+
1.should == 2
|
386
391
|
end
|
387
392
|
it "should delete nodes if value is :delete or empty string" do
|
388
393
|
@article.update_values([:title_info]=>{"0"=>"york", "1"=>"mangle","2"=>"mork"})
|
389
394
|
xpath = @article.class.terminology.xpath_for(:title_info)
|
390
|
-
|
395
|
+
|
391
396
|
@article.term_value_update([:title_info], 1, "")
|
392
|
-
|
393
|
-
|
397
|
+
@article.term_values(:title_info).should == ['york', 'mork']
|
398
|
+
|
394
399
|
@article.term_value_update([:title_info], 1, :delete)
|
395
|
-
|
400
|
+
@article.term_values(:title_info).should == ['york']
|
396
401
|
end
|
397
402
|
it "should create empty nodes if value is nil" do
|
398
403
|
@article.update_values([:title_info]=>{"0"=>"york", "1"=>nil,"2"=>"mork"})
|
399
|
-
|
404
|
+
@article.term_values(:title_info).should == ['york', "", "mork"]
|
400
405
|
end
|
401
406
|
end
|
402
|
-
|
407
|
+
|
403
408
|
describe ".term_value_delete" do
|
404
409
|
it "should accept an xpath query as :select option" do
|
405
410
|
generic_xpath = '//oxns:name[@type="personal" and position()=4]/oxns:role'
|
406
411
|
specific_xpath = '//oxns:name[@type="personal" and position()=4]/oxns:role[oxns:roleTerm="visionary"]'
|
407
412
|
select_xpath = '//oxns:name[@type="personal" and position()=4]/oxns:role[last()]'
|
408
|
-
|
413
|
+
|
409
414
|
# Check that we're starting with 2 roles
|
410
415
|
# Check that the specific node we want to delete exists
|
411
|
-
|
412
|
-
|
416
|
+
@sample.find_by_terms_and_value(generic_xpath).length.should == 2
|
417
|
+
@sample.find_by_terms_and_value(specific_xpath).length.should == 1
|
413
418
|
|
414
419
|
@sample.term_value_delete(
|
415
420
|
:select =>select_xpath
|
416
421
|
)
|
417
422
|
# Check that we're finishing with 1 role
|
418
|
-
|
423
|
+
@sample.find_by_terms_and_value(generic_xpath).length.should == 1
|
419
424
|
# Check that the specific node we want to delete no longer exists
|
420
|
-
|
421
|
-
end
|
425
|
+
@sample.find_by_terms_and_value(specific_xpath).length.should == 0
|
426
|
+
end
|
422
427
|
it "should accept :parent_select, :parent_index and :parent_index options instead of a :select" do
|
423
|
-
|
428
|
+
|
424
429
|
generic_xpath = '//oxns:name[@type="personal" and position()=4]/oxns:role/oxns:roleTerm'
|
425
430
|
specific_xpath = '//oxns:name[@type="personal" and position()=4]/oxns:role[oxns:roleTerm="visionary"]'
|
426
|
-
|
431
|
+
|
427
432
|
# Check that we're starting with 2 roles
|
428
433
|
# Check that the specific node we want to delete exists
|
429
|
-
|
430
|
-
|
434
|
+
@sample.find_by_terms_and_value(generic_xpath).length.should == 4
|
435
|
+
@sample.find_by_terms_and_value(specific_xpath).length.should == 1
|
431
436
|
|
432
|
-
# this is attempting to delete the last child (in this case roleTerm) from the 3rd role in the document.
|
437
|
+
# this is attempting to delete the last child (in this case roleTerm) from the 3rd role in the document.
|
433
438
|
@sample.term_value_delete(
|
434
439
|
:parent_select => [:person, :role],
|
435
440
|
:parent_index => 3,
|
436
441
|
:child_index => :last
|
437
442
|
)
|
438
|
-
|
443
|
+
|
439
444
|
# Check that we're finishing with 1 role
|
440
|
-
|
445
|
+
@sample.find_by_terms_and_value(generic_xpath).length.should == 3
|
441
446
|
# Check that the specific node we want to delete no longer exists
|
442
|
-
|
447
|
+
@sample.find_by_terms_and_value(specific_xpath).length.should == 1
|
443
448
|
end
|
444
449
|
it "should work if only :parent_select and :parent_index are provided" do
|
445
450
|
generic_xpath = '//oxns:name[@type="personal"]/oxns:role'
|
446
451
|
# specific_xpath = '//oxns:name[@type="personal"]/oxns:role'
|
447
|
-
|
452
|
+
|
448
453
|
# Check that we're starting with 2 roles
|
449
454
|
# Check that the specific node we want to delete exists
|
450
|
-
|
455
|
+
@sample.find_by_terms_and_value(generic_xpath).length.should == 4
|
451
456
|
# @sample.find_by_terms_and_value(specific_xpath).length.should == 1
|
452
457
|
|
453
458
|
@sample.term_value_delete(
|
@@ -455,14 +460,14 @@ describe "OM::XML::TermValueOperators" do
|
|
455
460
|
:child_index => 3
|
456
461
|
)
|
457
462
|
# Check that we're finishing with 1 role
|
458
|
-
|
463
|
+
@sample.find_by_terms_and_value(generic_xpath).length.should == 3
|
459
464
|
end
|
460
465
|
end
|
461
|
-
|
466
|
+
|
462
467
|
describe "build_ancestors" do
|
463
468
|
it "should raise an error if it cant find a starting point for building from" do
|
464
|
-
|
469
|
+
lambda { @empty_sample.build_ancestors( [:journal, :issue], 0) }.should raise_error(OM::XML::TemplateMissingException, "Cannot insert nodes into the document because it is empty. Try defining self.xml_template on the OM::Samples::ModsArticle class.")
|
465
470
|
end
|
466
471
|
end
|
467
|
-
|
472
|
+
|
468
473
|
end
|