mods 0.0.14 → 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
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