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/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
- it "should be able to find element using NOM terminology" do
10
- mods_ng_doc = Mods::Record.new.from_str('<mods><note>hi</note></mods>')
11
- mods_ng_doc.note.map { |e| e.text } == "hi"
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 be able to find element using NOM terminology" do
41
- mods_ng_doc = Mods::Record.new.from_nk_node(@mods_node)
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
- end
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
@@ -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
- @rel_it1 = @mods_rec.from_str('<mods><relatedItem displayLabel="Bibliography" type="host">
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
- it ".relatedItem should be a NodeSet" do
57
- [@rel_it1, @rel_it_mult, @rel_it2, @coll_ex].each { |ri| ri.should be_an_instance_of(Nokogiri::XML::NodeSet) }
58
- end
59
- it ".relatedItem should have as many members as there are <recordInfo> elements in the xml" do
60
- [@rel_it1, @rel_it2, @coll_ex].each { |ri| ri.size.should == 1 }
61
- @rel_it_mult.size.should == 2
62
- end
63
- it "relatedItem.type_at should match type attribute" do
64
- [@rel_it1, @rel_it_mult, @coll_ex].each { |ri| ri.type_at.should == ['host'] }
65
- @rel_it2.type_at.should == ['constituent']
66
- end
67
- it "relatedItem.id_at should match ID attribute" do
68
- @rel_it2.id_at.should == ['MODSMD_ARTICLE1']
69
- [@rel_it1, @rel_it_mult, @coll_ex].each { |ri| ri.id_at.size.should == 0 }
70
- end
71
- it "relatedItem.displayLabel should match displayLabel attribute" do
72
- @rel_it1.displayLabel.should == ['Bibliography']
73
- @rel_it_mult.displayLabel.should == ['From:']
74
- [@rel_it2, @coll_ex].each { |ri| ri.displayLabel.size.should == 0 }
75
- end
76
-
77
- context "<genre> child element" do
78
- it "relatedItem.genre should match <relatedItem><genre>" do
79
- @rel_it2.genre.map { |ri| ri.text }.should == ['article']
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
- end # <genre> child element
82
-
83
- context "<identifier> child element" do
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.identifier should match <relatedItem><identifier>" do
88
- @rel_it_mult.identifier.map { |n| n.text }.should == ['(AuCNL)1669726']
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
- end # <identifier> child element
91
-
92
- context "<name> child element" do
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.personal_name.date should match <relatedItem><name type='personal'><namePart type='date'>" do
100
- @rel_it_mult.personal_name.date.map { |n| n.text }.should == ['d. 1767']
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.name_el.namePart should match <relatedItem><name><namePart>" do
103
- @rel_it_mult.name_el.namePart.map { |n| n.text }.size.should == 3
104
- @rel_it_mult.name_el.namePart.map { |n| n.text }.should include('Bowen, Emanuel,')
105
- @rel_it_mult.name_el.namePart.map { |n| n.text }.should include('d. 1767')
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
- context "<part> child element" do
111
- it "relatedItem.part.type_at should match <relatedItem><part type=''> attribute" do
112
- @rel_it2.part.type_at.should == ['paragraph', 'paragraph', 'paragraph']
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
- it "relatedItem.part.id_at should match <relatedItem><part ID=''> attribute" do
115
- @rel_it2.part.id_at.size.should == 3
116
- @rel_it2.part.id_at.should include('DIVL15')
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.part.order should match <relatedItem><part order=''> attribute" do
121
- @rel_it2.part.order.size.should == 3
122
- @rel_it2.part.order.should include('1')
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
- end # <part> child element
127
-
128
- context "<recordInfo> child element" do
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
- end # <recordInfo> child element
133
-
134
- context "<titleInfo> child element" do
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.typeOfResource.collection should access <relatedItem><typeOfResource collection='yes'> attribute" do
148
- @coll_ex.typeOfResource.collection.should == ['yes']
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
- end # <typeOfResource> child element
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