mods 0.0.14 → 0.0.15
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/README.rdoc +1 -1
- data/lib/mods/nom_terminology.rb +445 -8
- data/lib/mods/reader.rb +3 -3
- data/lib/mods/record.rb +6 -7
- data/lib/mods/version.rb +1 -1
- data/spec/language_spec.rb +100 -73
- data/spec/location_spec.rb +269 -119
- data/spec/name_spec.rb +223 -197
- data/spec/origin_info_spec.rb +315 -190
- data/spec/part_spec.rb +411 -176
- data/spec/physical_description_spec.rb +120 -55
- data/spec/reader_spec.rb +76 -61
- data/spec/record_info_spec.rb +448 -206
- data/spec/record_spec.rb +192 -7
- data/spec/related_item_spec.rb +275 -124
- data/spec/subject_spec.rb +666 -339
- data/spec/title_spec.rb +204 -89
- data/spec/top_level_elmnts_simple_spec.rb +324 -145
- metadata +79 -98
data/spec/record_spec.rb
CHANGED
@@ -3,12 +3,30 @@ require 'spec_helper'
|
|
3
3
|
describe "Mods::Record" do
|
4
4
|
before(:all) do
|
5
5
|
@ns_hash = {'mods' => Mods::MODS_NS}
|
6
|
+
@def_ns_decl = "xmlns='#{Mods::MODS_NS}'"
|
7
|
+
@example_ns_str = "<mods #{@def_ns_decl}><note>default ns</note></mods>"
|
8
|
+
@example_no_ns_str = '<mods><note>no ns</note></mods>'
|
9
|
+
@doc_from_str_ns = Mods::Reader.new.from_str(@example_ns_str)
|
10
|
+
@doc_from_str_no_ns = Mods::Reader.new.from_str(@example_no_ns_str)
|
6
11
|
end
|
7
12
|
|
8
13
|
context "from_str" do
|
9
|
-
|
10
|
-
|
11
|
-
|
14
|
+
before(:all) do
|
15
|
+
@mods_ng_doc_w_ns = Mods::Record.new.from_str(@example_ns_str)
|
16
|
+
end
|
17
|
+
it "should have namespace aware parsing turned on by default" do
|
18
|
+
@mods_ng_doc_w_ns.namespaces.size.should > 0
|
19
|
+
end
|
20
|
+
it "terminology should work with Record object defaults when mods string has namespaces" do
|
21
|
+
@mods_ng_doc_w_ns.note.map { |e| e.text }.should == ['default ns']
|
22
|
+
end
|
23
|
+
it "terminology should not work with Record object defaults when mods string has NO namespaces" do
|
24
|
+
mods_ng_doc = Mods::Record.new.from_str(@example_no_ns_str)
|
25
|
+
mods_ng_doc.note.size.should == 0
|
26
|
+
end
|
27
|
+
it "should be allowed not to care about namespaces" do
|
28
|
+
mods_ng_doc = Mods::Record.new.from_str(@example_no_ns_str, false)
|
29
|
+
mods_ng_doc.note.map { |e| e.text }.should == ['no ns']
|
12
30
|
end
|
13
31
|
end
|
14
32
|
|
@@ -36,11 +54,178 @@ describe "Mods::Record" do
|
|
36
54
|
</OAI-PMH>'
|
37
55
|
ng_xml = Nokogiri::XML(oai_resp)
|
38
56
|
@mods_node = ng_xml.xpath('//mods:mods', @ns_hash).first
|
57
|
+
@mods_ng_doc = Mods::Record.new.from_nk_node(@mods_node)
|
58
|
+
bad_ns_wrapped = '<?xml version="1.0" encoding="UTF-8"?>
|
59
|
+
<metadata>
|
60
|
+
<n:mods xmlns:n="http://www.not.mods.org">
|
61
|
+
<n:titleInfo>
|
62
|
+
<n:title>What? No namespaces?</n:title>
|
63
|
+
</n:titleInfo>
|
64
|
+
</n:mods>
|
65
|
+
</metadata>'
|
66
|
+
ng_xml = Nokogiri::XML(bad_ns_wrapped)
|
67
|
+
@mods_node_no_ns = ng_xml.xpath('//n:mods', {'n'=>'http://www.not.mods.org'}).first
|
39
68
|
end
|
40
|
-
it "should
|
41
|
-
mods_ng_doc
|
42
|
-
mods_ng_doc.title_info.title.map { |e| e.text } == "boo"
|
69
|
+
it "should have namespace aware parsing turned on by default" do
|
70
|
+
@mods_ng_doc.namespaces.size.should > 0
|
43
71
|
end
|
44
|
-
|
72
|
+
it "terminology should work with Record object defaults when mods string has namespaces" do
|
73
|
+
@mods_ng_doc.title_info.title.map { |e| e.text }.should == ["boo"]
|
74
|
+
end
|
75
|
+
it "terminology should not work with Record object defaults when mods node has NO namespaces" do
|
76
|
+
mods_ng_doc = Mods::Record.new.from_nk_node(@mods_node_no_ns)
|
77
|
+
mods_ng_doc.title_info.title.size.should == 0
|
78
|
+
end
|
79
|
+
it "should be allowed not to care about namespaces" do
|
80
|
+
mods_ng_doc = Mods::Record.new.from_nk_node(@mods_node_no_ns, false)
|
81
|
+
mods_ng_doc.title_info.title.map { |e| e.text }.should == ["What? No namespaces?"]
|
82
|
+
end
|
83
|
+
end # context from_nk_node
|
84
|
+
|
85
|
+
context "convenience methods for accessing tricky bits of terminology" do
|
86
|
+
before(:all) do
|
87
|
+
@mods_rec = Mods::Record.new
|
88
|
+
end
|
89
|
+
context "title methods" do
|
90
|
+
it "short_titles should return an Array of Strings (multiple titles are legal in Mods)" do
|
91
|
+
@mods_rec.from_str("<mods #{@def_ns_decl}><titleInfo><title>Jerk</title><nonSort>The</nonSort></titleInfo><titleInfo><title>Joke</title></titleInfo></mods>")
|
92
|
+
@mods_rec.short_titles.should == ["The Jerk", "Joke"]
|
93
|
+
end
|
94
|
+
it "full_titles should return an Array of Strings (multiple titles are legal in Mods)" do
|
95
|
+
@mods_rec.from_str("<mods #{@def_ns_decl}><titleInfo><title>Jerk</title><nonSort>The</nonSort></titleInfo><titleInfo><title>Joke</title></titleInfo></mods>")
|
96
|
+
@mods_rec.full_titles.should == ["The Jerk", "Joke"]
|
97
|
+
end
|
98
|
+
it "sort_title should return a String (sortable fields are single valued)" do
|
99
|
+
@mods_rec.from_str("<mods #{@def_ns_decl}><titleInfo><title>Jerk</title><subTitle>A Tale of Tourettes</subTitle><nonSort>The</nonSort></titleInfo></mods>")
|
100
|
+
@mods_rec.sort_title.should == "Jerk A Tale of Tourettes"
|
101
|
+
end
|
102
|
+
it "alternative_titles should return an Array of Strings (multiple alternative titles when there are multiple titleInfo elements)" do
|
103
|
+
@mods_rec.from_str("<mods #{@def_ns_decl}><titleInfo type='alternative'><title>1</title></titleInfo><titleInfo type='alternative'><title>2</title></titleInfo></mods>")
|
104
|
+
@mods_rec.alternative_titles.should == ['1', '2']
|
105
|
+
@mods_rec.from_str("<mods #{@def_ns_decl}><titleInfo type='alternative'><title>1</title><title>2</title></titleInfo></mods>")
|
106
|
+
@mods_rec.alternative_titles.should == ['12']
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "personal_names" do
|
111
|
+
before(:all) do
|
112
|
+
@pers_name = 'Crusty'
|
113
|
+
@mods_w_pers_name = "<mods #{@def_ns_decl}><name type='personal'><namePart>#{@pers_name}</namePart></name></mods>"
|
114
|
+
@pers_role = 'creator'
|
115
|
+
@mods_w_pers_name_role = "<mods #{@def_ns_decl}><name type='personal'><namePart>#{@pers_name}</namePart>"
|
116
|
+
@given_family = '<mods xmlns="http://www.loc.gov/mods/v3"><name type="personal"><namePart type="given">Jorge Luis</namePart>
|
117
|
+
<namePart type="family">Borges</namePart></name></mods>'
|
118
|
+
@given_family_date = '<mods xmlns="http://www.loc.gov/mods/v3"><name type="personal"><namePart type="given">Zaphod</namePart>
|
119
|
+
<namePart type="family">Beeblebrox</namePart>
|
120
|
+
<namePart type="date">1912-2362</namePart></name></mods>'
|
121
|
+
@all_name_parts = '<mods xmlns="http://www.loc.gov/mods/v3"><name type="personal"><namePart type="given">Given</namePart>
|
122
|
+
<namePart type="family">Family</namePart>
|
123
|
+
<namePart type="termsOfAddress">Mr.</namePart>
|
124
|
+
<namePart type="date">date</namePart></name></mods>'
|
125
|
+
@family_only = '<mods xmlns="http://www.loc.gov/mods/v3"><name type="personal"><namePart type="family">Family</namePart></name></mods>'
|
126
|
+
@given_only = '<mods xmlns="http://www.loc.gov/mods/v3"><name type="personal"><namePart type="given">Given</namePart></name></mods>'
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should return an Array of Strings" do
|
130
|
+
@mods_rec.from_str(@mods_w_pers_name)
|
131
|
+
@mods_rec.personal_names.should == [@pers_name]
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should not include the role text" do
|
135
|
+
@mods_rec.from_str(@mods_w_pers_name_role)
|
136
|
+
@mods_rec.personal_names.first.should_not match(@pers_role)
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should prefer displayForm over namePart pieces" do
|
140
|
+
display_form_and_name_parts = '<mods xmlns="http://www.loc.gov/mods/v3"><name type="personal"><namePart type="given">Jorge Luis</namePart>
|
141
|
+
<namePart type="family">Borges</namePart>
|
142
|
+
<displayForm>display form</displayForm></name></mods>'
|
143
|
+
@mods_rec.from_str(display_form_and_name_parts)
|
144
|
+
@mods_rec.personal_names.should include("display form")
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should put the family namePart first" do
|
148
|
+
@mods_rec.from_str(@given_family)
|
149
|
+
@mods_rec.personal_names.first.should match(/^Borges/)
|
150
|
+
@mods_rec.from_str(@given_family_date)
|
151
|
+
@mods_rec.personal_names.first.should match(/^Beeblebrox/)
|
152
|
+
end
|
153
|
+
it "should not include date" do
|
154
|
+
@mods_rec.from_str(@given_family_date)
|
155
|
+
@mods_rec.personal_names.first.should_not match(/19/)
|
156
|
+
@mods_rec.from_str(@all_name_parts)
|
157
|
+
@mods_rec.personal_names.first.should_not match('date')
|
158
|
+
end
|
159
|
+
it "should include a comma when there is both a family and a given name" do
|
160
|
+
@mods_rec.from_str(@all_name_parts)
|
161
|
+
@mods_rec.personal_names.should include("Family, Given")
|
162
|
+
end
|
163
|
+
it "should include multiple words in a namePart" do
|
164
|
+
@mods_rec.from_str(@given_family)
|
165
|
+
@mods_rec.personal_names.should include("Borges, Jorge Luis")
|
166
|
+
end
|
167
|
+
it "should not include a comma when there is only a family or given name" do
|
168
|
+
[@family_only, @given_only].each { |mods_str|
|
169
|
+
@mods_rec.from_str(mods_str)
|
170
|
+
@mods_rec.personal_names.first.should_not match(/,/)
|
171
|
+
}
|
172
|
+
end
|
173
|
+
it "should not include terms of address" do
|
174
|
+
@mods_rec.from_str(@all_name_parts)
|
175
|
+
@mods_rec.personal_names.first.should_not match(/Mr./)
|
176
|
+
end
|
177
|
+
end # personal_names
|
178
|
+
|
179
|
+
context "corporate_names" do
|
180
|
+
before(:all) do
|
181
|
+
@corp_name = 'ABC corp'
|
182
|
+
end
|
183
|
+
it "should return an Array of Strings" do
|
184
|
+
@mods_rec.from_str("<mods #{@def_ns_decl}><name type='corporate'><namePart>#{@corp_name}</namePart></name></mods>")
|
185
|
+
@mods_rec.corporate_names.should == [@corp_name]
|
186
|
+
end
|
187
|
+
it "should not include the role text" do
|
188
|
+
corp_role = 'lithographer'
|
189
|
+
mods_w_corp_name_role = "<mods #{@def_ns_decl}><name type='corporate'><namePart>#{@corp_name}</namePart>
|
190
|
+
<role><roleTerm type='text'>#{corp_role}</roleTerm></role></name></mods>"
|
191
|
+
@mods_rec.from_str(mods_w_corp_name_role)
|
192
|
+
@mods_rec.corporate_names.first.should_not match(corp_role)
|
193
|
+
end
|
194
|
+
|
195
|
+
it "should prefer displayForm over namePart pieces" do
|
196
|
+
display_form_and_name_parts = "<mods #{@def_ns_decl}><name type='corporate'><namePart>Food, Inc.</namePart>
|
197
|
+
<displayForm>display form</displayForm></name></mods>"
|
198
|
+
@mods_rec.from_str(display_form_and_name_parts)
|
199
|
+
@mods_rec.corporate_names.should include("display form")
|
200
|
+
end
|
201
|
+
end # corporate_names
|
202
|
+
|
203
|
+
context "languages" do
|
204
|
+
before(:all) do
|
205
|
+
@simple = "<mods #{@def_ns_decl}><language>Greek</language></mods>"
|
206
|
+
@iso639_2b_code = "<mods #{@def_ns_decl}><language><languageTerm authority='iso639-2b' type='code'>fre</languageTerm></language></mods>"
|
207
|
+
@iso639_2b_text = "<mods #{@def_ns_decl}><language><languageTerm authority='iso639-2b' type='text'>English</languageTerm></language></mods>"
|
208
|
+
@mult_codes = "<mods #{@def_ns_decl}><language><languageTerm authority='iso639-2b' type='code'>per ara, dut</languageTerm></language></mods>"
|
209
|
+
end
|
210
|
+
it "should translate iso639-2b codes to English" do
|
211
|
+
@mods_rec.from_str(@iso639_2b_code)
|
212
|
+
@mods_rec.languages.should == ["French"]
|
213
|
+
end
|
214
|
+
it "should pass thru language values that are already text (not code)" do
|
215
|
+
@mods_rec.from_str(@iso639_2b_text)
|
216
|
+
@mods_rec.languages.should == ["English"]
|
217
|
+
end
|
218
|
+
it "should keep values that are not inside <languageTerm> elements" do
|
219
|
+
@mods_rec.from_str(@simple)
|
220
|
+
@mods_rec.languages.should == ["Greek"]
|
221
|
+
end
|
222
|
+
it "should create a separate value for each language in a comma, space, or | separated list " do
|
223
|
+
@mods_rec.from_str(@mult_codes)
|
224
|
+
@mods_rec.languages.should include("Arabic")
|
225
|
+
@mods_rec.languages.should include("Persian")
|
226
|
+
@mods_rec.languages.should include("Dutch; Flemish")
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end # convenience methods
|
45
230
|
|
46
231
|
end
|
data/spec/related_item_spec.rb
CHANGED
@@ -3,48 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe "Mods <relatedItem> Element" do
|
4
4
|
before(:all) do
|
5
5
|
@mods_rec = Mods::Record.new
|
6
|
-
@
|
7
|
-
<titleInfo>
|
8
|
-
<title/>
|
9
|
-
</titleInfo>
|
10
|
-
<recordInfo>
|
11
|
-
<recordIdentifier source="Gallica ARK"/>
|
12
|
-
</recordInfo>
|
13
|
-
<typeOfResource>text</typeOfResource>
|
14
|
-
</relatedItem></mods>').related_item
|
15
|
-
@rel_it_mult = @mods_rec.from_str('<mods><relatedItem>
|
16
|
-
<titleInfo>
|
17
|
-
<title>Complete atlas, or, Distinct view of the known world</title>
|
18
|
-
</titleInfo>
|
19
|
-
<name type="personal">
|
20
|
-
<namePart>Bowen, Emanuel,</namePart>
|
21
|
-
<namePart type="date">d. 1767</namePart>
|
22
|
-
</name>
|
23
|
-
</relatedItem>
|
24
|
-
<relatedItem type="host" displayLabel="From:">
|
25
|
-
<titleInfo>
|
26
|
-
<title>Complete atlas, or, Distinct view of the known world</title>
|
27
|
-
</titleInfo>
|
28
|
-
<name>
|
29
|
-
<namePart>Bowen, Emanuel, d. 1767.</namePart>
|
30
|
-
</name>
|
31
|
-
<identifier type="local">(AuCNL)1669726</identifier>
|
32
|
-
</relatedItem></mods>').related_item
|
33
|
-
@rel_it2 = @mods_rec.from_str('<mods><relatedItem type="constituent" ID="MODSMD_ARTICLE1">
|
34
|
-
<titleInfo>
|
35
|
-
<title>Nuppineula.</title>
|
36
|
-
</titleInfo>
|
37
|
-
<genre>article</genre>
|
38
|
-
<part ID="DIVL15" type="paragraph" order="1"/>
|
39
|
-
<part ID="DIVL17" type="paragraph" order="2"/>
|
40
|
-
<part ID="DIVL19" type="paragraph" order="3"/>
|
41
|
-
</relatedItem></mods>').related_item
|
42
|
-
@coll_ex = @mods_rec.from_str('<mods><relatedItem type="host">
|
43
|
-
<titleInfo>
|
44
|
-
<title>The Collier Collection of the Revs Institute for Automotive Research</title>
|
45
|
-
</titleInfo>
|
46
|
-
<typeOfResource collection="yes"/>
|
47
|
-
</relatedItem></mods>').related_item
|
6
|
+
@ns_decl = "xmlns='#{Mods::MODS_NS}'"
|
48
7
|
end
|
49
8
|
|
50
9
|
it "should associate the right pieces with the right <relatedItem> elements" do
|
@@ -53,101 +12,293 @@ describe "Mods <relatedItem> Element" do
|
|
53
12
|
|
54
13
|
context "basic <related_item> terminology pieces" do
|
55
14
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
15
|
+
context "WITH namespaces" do
|
16
|
+
before(:all) do
|
17
|
+
@rel_it1 = @mods_rec.from_str("<mods #{@ns_decl}><relatedItem displayLabel='Bibliography' type='host'>
|
18
|
+
<titleInfo>
|
19
|
+
<title/>
|
20
|
+
</titleInfo>
|
21
|
+
<recordInfo>
|
22
|
+
<recordIdentifier source='Gallica ARK'/>
|
23
|
+
</recordInfo>
|
24
|
+
<typeOfResource>text</typeOfResource>
|
25
|
+
</relatedItem></mods>").related_item
|
26
|
+
@rel_it_mult = @mods_rec.from_str("<mods #{@ns_decl}><relatedItem>
|
27
|
+
<titleInfo>
|
28
|
+
<title>Complete atlas, or, Distinct view of the known world</title>
|
29
|
+
</titleInfo>
|
30
|
+
<name type='personal'>
|
31
|
+
<namePart>Bowen, Emanuel,</namePart>
|
32
|
+
<namePart type='date'>d. 1767</namePart>
|
33
|
+
</name>
|
34
|
+
</relatedItem>
|
35
|
+
<relatedItem type='host' displayLabel='From:'>
|
36
|
+
<titleInfo>
|
37
|
+
<title>Complete atlas, or, Distinct view of the known world</title>
|
38
|
+
</titleInfo>
|
39
|
+
<name>
|
40
|
+
<namePart>Bowen, Emanuel, d. 1767.</namePart>
|
41
|
+
</name>
|
42
|
+
<identifier type='local'>(AuCNL)1669726</identifier>
|
43
|
+
</relatedItem></mods>").related_item
|
44
|
+
@rel_it2 = @mods_rec.from_str("<mods #{@ns_decl}><relatedItem type='constituent' ID='MODSMD_ARTICLE1'>
|
45
|
+
<titleInfo>
|
46
|
+
<title>Nuppineula.</title>
|
47
|
+
</titleInfo>
|
48
|
+
<genre>article</genre>
|
49
|
+
<part ID='DIVL15' type='paragraph' order='1'/>
|
50
|
+
<part ID='DIVL17' type='paragraph' order='2'/>
|
51
|
+
<part ID='DIVL19' type='paragraph' order='3'/>
|
52
|
+
</relatedItem></mods>").related_item
|
53
|
+
@coll_ex = @mods_rec.from_str("<mods #{@ns_decl}><relatedItem type='host'>
|
54
|
+
<titleInfo>
|
55
|
+
<title>The Collier Collection of the Revs Institute for Automotive Research</title>
|
56
|
+
</titleInfo>
|
57
|
+
<typeOfResource collection='yes'/>
|
58
|
+
</relatedItem></mods>").related_item
|
80
59
|
end
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
it "relatedItem.identifier.type_at should match <relatedItem><identifier type=''> attribute" do
|
85
|
-
@rel_it_mult.identifier.type_at.should == ['local']
|
60
|
+
|
61
|
+
it ".relatedItem should be a NodeSet" do
|
62
|
+
[@rel_it1, @rel_it_mult, @rel_it2, @coll_ex].each { |ri| ri.should be_an_instance_of(Nokogiri::XML::NodeSet) }
|
86
63
|
end
|
87
|
-
it "relatedItem
|
88
|
-
|
64
|
+
it ".relatedItem should have as many members as there are <recordInfo> elements in the xml" do
|
65
|
+
[@rel_it1, @rel_it2, @coll_ex].each { |ri| ri.size.should == 1 }
|
66
|
+
@rel_it_mult.size.should == 2
|
89
67
|
end
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
it "relatedItem.personal_name.namePart should match <relatedItem><name type='personal'><namePart>" do
|
94
|
-
@rel_it_mult.personal_name.namePart.map { |n| n.text }.size.should == 2
|
95
|
-
@rel_it_mult.personal_name.namePart.map { |n| n.text }.should include('Bowen, Emanuel,')
|
96
|
-
@rel_it_mult.personal_name.namePart.map { |n| n.text }.should include('d. 1767')
|
97
|
-
@rel_it_mult.personal_name.namePart.map { |n| n.text }.should_not include('Bowen, Emanuel, d. 1767.')
|
68
|
+
it "relatedItem.type_at should match type attribute" do
|
69
|
+
[@rel_it1, @rel_it_mult, @coll_ex].each { |ri| ri.type_at.should == ['host'] }
|
70
|
+
@rel_it2.type_at.should == ['constituent']
|
98
71
|
end
|
99
|
-
it "relatedItem.
|
100
|
-
@
|
72
|
+
it "relatedItem.id_at should match ID attribute" do
|
73
|
+
@rel_it2.id_at.should == ['MODSMD_ARTICLE1']
|
74
|
+
[@rel_it1, @rel_it_mult, @coll_ex].each { |ri| ri.id_at.size.should == 0 }
|
101
75
|
end
|
102
|
-
it "relatedItem.
|
103
|
-
@
|
104
|
-
@rel_it_mult.
|
105
|
-
@
|
106
|
-
@rel_it_mult.name_el.namePart.map { |n| n.text }.should include('Bowen, Emanuel, d. 1767.')
|
76
|
+
it "relatedItem.displayLabel should match displayLabel attribute" do
|
77
|
+
@rel_it1.displayLabel.should == ['Bibliography']
|
78
|
+
@rel_it_mult.displayLabel.should == ['From:']
|
79
|
+
[@rel_it2, @coll_ex].each { |ri| ri.displayLabel.size.should == 0 }
|
107
80
|
end
|
108
|
-
end # <name> child element
|
109
81
|
|
110
|
-
|
111
|
-
|
112
|
-
|
82
|
+
context "<genre> child element" do
|
83
|
+
it "relatedItem.genre should match <relatedItem><genre>" do
|
84
|
+
@rel_it2.genre.map { |ri| ri.text }.should == ['article']
|
85
|
+
end
|
86
|
+
end # <genre> child element
|
87
|
+
|
88
|
+
context "<identifier> child element" do
|
89
|
+
it "relatedItem.identifier.type_at should match <relatedItem><identifier type=''> attribute" do
|
90
|
+
@rel_it_mult.identifier.type_at.should == ['local']
|
91
|
+
end
|
92
|
+
it "relatedItem.identifier should match <relatedItem><identifier>" do
|
93
|
+
@rel_it_mult.identifier.map { |n| n.text }.should == ['(AuCNL)1669726']
|
94
|
+
end
|
95
|
+
end # <identifier> child element
|
96
|
+
|
97
|
+
context "<name> child element" do
|
98
|
+
it "relatedItem.personal_name.namePart should match <relatedItem><name type='personal'><namePart>" do
|
99
|
+
@rel_it_mult.personal_name.namePart.map { |n| n.text }.size.should == 2
|
100
|
+
@rel_it_mult.personal_name.namePart.map { |n| n.text }.should include('Bowen, Emanuel,')
|
101
|
+
@rel_it_mult.personal_name.namePart.map { |n| n.text }.should include('d. 1767')
|
102
|
+
@rel_it_mult.personal_name.namePart.map { |n| n.text }.should_not include('Bowen, Emanuel, d. 1767.')
|
103
|
+
end
|
104
|
+
it "relatedItem.personal_name.date should match <relatedItem><name type='personal'><namePart type='date'>" do
|
105
|
+
@rel_it_mult.personal_name.date.map { |n| n.text }.should == ['d. 1767']
|
106
|
+
end
|
107
|
+
it "relatedItem.name_el.namePart should match <relatedItem><name><namePart>" do
|
108
|
+
@rel_it_mult.name_el.namePart.map { |n| n.text }.size.should == 3
|
109
|
+
@rel_it_mult.name_el.namePart.map { |n| n.text }.should include('Bowen, Emanuel,')
|
110
|
+
@rel_it_mult.name_el.namePart.map { |n| n.text }.should include('d. 1767')
|
111
|
+
@rel_it_mult.name_el.namePart.map { |n| n.text }.should include('Bowen, Emanuel, d. 1767.')
|
112
|
+
end
|
113
|
+
end # <name> child element
|
114
|
+
|
115
|
+
context "<part> child element" do
|
116
|
+
it "relatedItem.part.type_at should match <relatedItem><part type=''> attribute" do
|
117
|
+
@rel_it2.part.type_at.should == ['paragraph', 'paragraph', 'paragraph']
|
118
|
+
end
|
119
|
+
it "relatedItem.part.id_at should match <relatedItem><part ID=''> attribute" do
|
120
|
+
@rel_it2.part.id_at.size.should == 3
|
121
|
+
@rel_it2.part.id_at.should include('DIVL15')
|
122
|
+
@rel_it2.part.id_at.should include('DIVL17')
|
123
|
+
@rel_it2.part.id_at.should include('DIVL19')
|
124
|
+
end
|
125
|
+
it "relatedItem.part.order should match <relatedItem><part order=''> attribute" do
|
126
|
+
@rel_it2.part.order.size.should == 3
|
127
|
+
@rel_it2.part.order.should include('1')
|
128
|
+
@rel_it2.part.order.should include('2')
|
129
|
+
@rel_it2.part.order.should include('3')
|
130
|
+
end
|
131
|
+
end # <part> child element
|
132
|
+
|
133
|
+
context "<recordInfo> child element" do
|
134
|
+
it "relatedItem.recordInfo.recordIdentifier.source should match <relatedItem><recordInfo><recordIdentifier source> attribute" do
|
135
|
+
@rel_it1.recordInfo.recordIdentifier.source.should == ['Gallica ARK']
|
136
|
+
end
|
137
|
+
end # <recordInfo> child element
|
138
|
+
|
139
|
+
context "<titleInfo> child element" do
|
140
|
+
it "relatedItem.titleInfo.title should access <relatedItem><titleInfo><title>" do
|
141
|
+
@rel_it1.titleInfo.title.map { |n| n.text }.should == ['']
|
142
|
+
@rel_it_mult.titleInfo.title.map { |n| n.text }.should == ['Complete atlas, or, Distinct view of the known world', 'Complete atlas, or, Distinct view of the known world']
|
143
|
+
@rel_it2.titleInfo.title.map { |n| n.text }.should == ['Nuppineula.']
|
144
|
+
@coll_ex.titleInfo.title.map { |n| n.text }.should == ['The Collier Collection of the Revs Institute for Automotive Research']
|
145
|
+
end
|
146
|
+
end # <titleInfo> child element
|
147
|
+
|
148
|
+
context "<typeOfResource> child element" do
|
149
|
+
it "relatedItem.typeOfResource should access <relatedItem><typeOfResource>" do
|
150
|
+
@rel_it1.typeOfResource.map { |n| n.text }.should == ['text']
|
151
|
+
end
|
152
|
+
it "relatedItem.typeOfResource.collection should access <relatedItem><typeOfResource collection='yes'> attribute" do
|
153
|
+
@coll_ex.typeOfResource.collection.should == ['yes']
|
154
|
+
end
|
155
|
+
end # <typeOfResource> child element
|
156
|
+
|
157
|
+
end # WITH namespaces
|
158
|
+
|
159
|
+
context "WITHOUT namespaces" do
|
160
|
+
before(:all) do
|
161
|
+
@rel_it1 = @mods_rec.from_str("<mods><relatedItem displayLabel='Bibliography' type='host'>
|
162
|
+
<titleInfo>
|
163
|
+
<title/>
|
164
|
+
</titleInfo>
|
165
|
+
<recordInfo>
|
166
|
+
<recordIdentifier source='Gallica ARK'/>
|
167
|
+
</recordInfo>
|
168
|
+
<typeOfResource>text</typeOfResource>
|
169
|
+
</relatedItem></mods>", false).related_item
|
170
|
+
@rel_it_mult = @mods_rec.from_str("<mods><relatedItem>
|
171
|
+
<titleInfo>
|
172
|
+
<title>Complete atlas, or, Distinct view of the known world</title>
|
173
|
+
</titleInfo>
|
174
|
+
<name type='personal'>
|
175
|
+
<namePart>Bowen, Emanuel,</namePart>
|
176
|
+
<namePart type='date'>d. 1767</namePart>
|
177
|
+
</name>
|
178
|
+
</relatedItem>
|
179
|
+
<relatedItem type='host' displayLabel='From:'>
|
180
|
+
<titleInfo>
|
181
|
+
<title>Complete atlas, or, Distinct view of the known world</title>
|
182
|
+
</titleInfo>
|
183
|
+
<name>
|
184
|
+
<namePart>Bowen, Emanuel, d. 1767.</namePart>
|
185
|
+
</name>
|
186
|
+
<identifier type='local'>(AuCNL)1669726</identifier>
|
187
|
+
</relatedItem></mods>", false).related_item
|
188
|
+
@rel_it2 = @mods_rec.from_str("<mods><relatedItem type='constituent' ID='MODSMD_ARTICLE1'>
|
189
|
+
<titleInfo>
|
190
|
+
<title>Nuppineula.</title>
|
191
|
+
</titleInfo>
|
192
|
+
<genre>article</genre>
|
193
|
+
<part ID='DIVL15' type='paragraph' order='1'/>
|
194
|
+
<part ID='DIVL17' type='paragraph' order='2'/>
|
195
|
+
<part ID='DIVL19' type='paragraph' order='3'/>
|
196
|
+
</relatedItem></mods>", false).related_item
|
197
|
+
@coll_ex = @mods_rec.from_str("<mods><relatedItem type='host'>
|
198
|
+
<titleInfo>
|
199
|
+
<title>The Collier Collection of the Revs Institute for Automotive Research</title>
|
200
|
+
</titleInfo>
|
201
|
+
<typeOfResource collection='yes'/>
|
202
|
+
</relatedItem></mods>", false).related_item
|
113
203
|
end
|
114
|
-
|
115
|
-
|
116
|
-
@rel_it2.
|
117
|
-
@rel_it2.part.id_at.should include('DIVL17')
|
118
|
-
@rel_it2.part.id_at.should include('DIVL19')
|
204
|
+
|
205
|
+
it ".relatedItem should be a NodeSet" do
|
206
|
+
[@rel_it1, @rel_it_mult, @rel_it2, @coll_ex].each { |ri| ri.should be_an_instance_of(Nokogiri::XML::NodeSet) }
|
119
207
|
end
|
120
|
-
it "relatedItem
|
121
|
-
|
122
|
-
|
123
|
-
@rel_it2.part.order.should include('2')
|
124
|
-
@rel_it2.part.order.should include('3')
|
208
|
+
it ".relatedItem should have as many members as there are <recordInfo> elements in the xml" do
|
209
|
+
[@rel_it1, @rel_it2, @coll_ex].each { |ri| ri.size.should == 1 }
|
210
|
+
@rel_it_mult.size.should == 2
|
125
211
|
end
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
it "relatedItem.recordInfo.recordIdentifier.source should match <relatedItem><recordInfo><recordIdentifier source> attribute" do
|
130
|
-
@rel_it1.recordInfo.recordIdentifier.source.should == ['Gallica ARK']
|
212
|
+
it "relatedItem.type_at should match type attribute" do
|
213
|
+
[@rel_it1, @rel_it_mult, @coll_ex].each { |ri| ri.type_at.should == ['host'] }
|
214
|
+
@rel_it2.type_at.should == ['constituent']
|
131
215
|
end
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
it "relatedItem.titleInfo.title should access <relatedItem><titleInfo><title>" do
|
136
|
-
@rel_it1.titleInfo.title.map { |n| n.text }.should == ['']
|
137
|
-
@rel_it_mult.titleInfo.title.map { |n| n.text }.should == ['Complete atlas, or, Distinct view of the known world', 'Complete atlas, or, Distinct view of the known world']
|
138
|
-
@rel_it2.titleInfo.title.map { |n| n.text }.should == ['Nuppineula.']
|
139
|
-
@coll_ex.titleInfo.title.map { |n| n.text }.should == ['The Collier Collection of the Revs Institute for Automotive Research']
|
140
|
-
end
|
141
|
-
end # <titleInfo> child element
|
142
|
-
|
143
|
-
context "<typeOfResource> child element" do
|
144
|
-
it "relatedItem.typeOfResource should access <relatedItem><typeOfResource>" do
|
145
|
-
@rel_it1.typeOfResource.map { |n| n.text }.should == ['text']
|
216
|
+
it "relatedItem.id_at should match ID attribute" do
|
217
|
+
@rel_it2.id_at.should == ['MODSMD_ARTICLE1']
|
218
|
+
[@rel_it1, @rel_it_mult, @coll_ex].each { |ri| ri.id_at.size.should == 0 }
|
146
219
|
end
|
147
|
-
it "relatedItem.
|
148
|
-
@
|
220
|
+
it "relatedItem.displayLabel should match displayLabel attribute" do
|
221
|
+
@rel_it1.displayLabel.should == ['Bibliography']
|
222
|
+
@rel_it_mult.displayLabel.should == ['From:']
|
223
|
+
[@rel_it2, @coll_ex].each { |ri| ri.displayLabel.size.should == 0 }
|
149
224
|
end
|
150
|
-
|
225
|
+
|
226
|
+
context "<genre> child element" do
|
227
|
+
it "relatedItem.genre should match <relatedItem><genre>" do
|
228
|
+
@rel_it2.genre.map { |ri| ri.text }.should == ['article']
|
229
|
+
end
|
230
|
+
end # <genre> child element
|
231
|
+
|
232
|
+
context "<identifier> child element" do
|
233
|
+
it "relatedItem.identifier.type_at should match <relatedItem><identifier type=''> attribute" do
|
234
|
+
@rel_it_mult.identifier.type_at.should == ['local']
|
235
|
+
end
|
236
|
+
it "relatedItem.identifier should match <relatedItem><identifier>" do
|
237
|
+
@rel_it_mult.identifier.map { |n| n.text }.should == ['(AuCNL)1669726']
|
238
|
+
end
|
239
|
+
end # <identifier> child element
|
240
|
+
|
241
|
+
context "<name> child element" do
|
242
|
+
it "relatedItem.personal_name.namePart should match <relatedItem><name type='personal'><namePart>" do
|
243
|
+
@rel_it_mult.personal_name.namePart.map { |n| n.text }.size.should == 2
|
244
|
+
@rel_it_mult.personal_name.namePart.map { |n| n.text }.should include('Bowen, Emanuel,')
|
245
|
+
@rel_it_mult.personal_name.namePart.map { |n| n.text }.should include('d. 1767')
|
246
|
+
@rel_it_mult.personal_name.namePart.map { |n| n.text }.should_not include('Bowen, Emanuel, d. 1767.')
|
247
|
+
end
|
248
|
+
it "relatedItem.personal_name.date should match <relatedItem><name type='personal'><namePart type='date'>" do
|
249
|
+
@rel_it_mult.personal_name.date.map { |n| n.text }.should == ['d. 1767']
|
250
|
+
end
|
251
|
+
it "relatedItem.name_el.namePart should match <relatedItem><name><namePart>" do
|
252
|
+
@rel_it_mult.name_el.namePart.map { |n| n.text }.size.should == 3
|
253
|
+
@rel_it_mult.name_el.namePart.map { |n| n.text }.should include('Bowen, Emanuel,')
|
254
|
+
@rel_it_mult.name_el.namePart.map { |n| n.text }.should include('d. 1767')
|
255
|
+
@rel_it_mult.name_el.namePart.map { |n| n.text }.should include('Bowen, Emanuel, d. 1767.')
|
256
|
+
end
|
257
|
+
end # <name> child element
|
258
|
+
|
259
|
+
context "<part> child element" do
|
260
|
+
it "relatedItem.part.type_at should match <relatedItem><part type=''> attribute" do
|
261
|
+
@rel_it2.part.type_at.should == ['paragraph', 'paragraph', 'paragraph']
|
262
|
+
end
|
263
|
+
it "relatedItem.part.id_at should match <relatedItem><part ID=''> attribute" do
|
264
|
+
@rel_it2.part.id_at.size.should == 3
|
265
|
+
@rel_it2.part.id_at.should include('DIVL15')
|
266
|
+
@rel_it2.part.id_at.should include('DIVL17')
|
267
|
+
@rel_it2.part.id_at.should include('DIVL19')
|
268
|
+
end
|
269
|
+
it "relatedItem.part.order should match <relatedItem><part order=''> attribute" do
|
270
|
+
@rel_it2.part.order.size.should == 3
|
271
|
+
@rel_it2.part.order.should include('1')
|
272
|
+
@rel_it2.part.order.should include('2')
|
273
|
+
@rel_it2.part.order.should include('3')
|
274
|
+
end
|
275
|
+
end # <part> child element
|
276
|
+
|
277
|
+
context "<recordInfo> child element" do
|
278
|
+
it "relatedItem.recordInfo.recordIdentifier.source should match <relatedItem><recordInfo><recordIdentifier source> attribute" do
|
279
|
+
@rel_it1.recordInfo.recordIdentifier.source.should == ['Gallica ARK']
|
280
|
+
end
|
281
|
+
end # <recordInfo> child element
|
282
|
+
|
283
|
+
context "<titleInfo> child element" do
|
284
|
+
it "relatedItem.titleInfo.title should access <relatedItem><titleInfo><title>" do
|
285
|
+
@rel_it1.titleInfo.title.map { |n| n.text }.should == ['']
|
286
|
+
@rel_it_mult.titleInfo.title.map { |n| n.text }.should == ['Complete atlas, or, Distinct view of the known world', 'Complete atlas, or, Distinct view of the known world']
|
287
|
+
@rel_it2.titleInfo.title.map { |n| n.text }.should == ['Nuppineula.']
|
288
|
+
@coll_ex.titleInfo.title.map { |n| n.text }.should == ['The Collier Collection of the Revs Institute for Automotive Research']
|
289
|
+
end
|
290
|
+
end # <titleInfo> child element
|
291
|
+
|
292
|
+
context "<typeOfResource> child element" do
|
293
|
+
it "relatedItem.typeOfResource should access <relatedItem><typeOfResource>" do
|
294
|
+
@rel_it1.typeOfResource.map { |n| n.text }.should == ['text']
|
295
|
+
end
|
296
|
+
it "relatedItem.typeOfResource.collection should access <relatedItem><typeOfResource collection='yes'> attribute" do
|
297
|
+
@coll_ex.typeOfResource.collection.should == ['yes']
|
298
|
+
end
|
299
|
+
end # <typeOfResource> child element
|
300
|
+
|
301
|
+
end # WITHOUT namespaces
|
151
302
|
|
152
303
|
end # basic <related_item> terminology pieces
|
153
304
|
|