om 1.8.1 → 1.9.0.pre1
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.
- 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
|