mods 2.4.1 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +24 -0
  3. data/.gitignore +1 -0
  4. data/README.md +0 -1
  5. data/lib/mods/date.rb +54 -17
  6. data/lib/mods/marc_country_codes.rb +12 -10
  7. data/lib/mods/nom_terminology.rb +109 -845
  8. data/lib/mods/reader.rb +9 -39
  9. data/lib/mods/record.rb +13 -28
  10. data/lib/mods/version.rb +1 -1
  11. data/mods.gemspec +2 -2
  12. data/spec/fixture_data/hp566jq8781.xml +334 -0
  13. data/spec/integration/parker_spec.rb +217 -0
  14. data/spec/{date_spec.rb → lib/date_spec.rb} +9 -1
  15. data/spec/lib/language_spec.rb +123 -0
  16. data/spec/lib/location_spec.rb +175 -0
  17. data/spec/lib/name_spec.rb +368 -0
  18. data/spec/lib/origin_info_spec.rb +134 -0
  19. data/spec/lib/part_spec.rb +162 -0
  20. data/spec/lib/physical_description_spec.rb +72 -0
  21. data/spec/{reader_spec.rb → lib/reader_spec.rb} +1 -41
  22. data/spec/lib/record_info_spec.rb +114 -0
  23. data/spec/lib/record_spec.rb +287 -0
  24. data/spec/lib/related_item_spec.rb +124 -0
  25. data/spec/lib/subject_spec.rb +427 -0
  26. data/spec/lib/title_spec.rb +108 -0
  27. data/spec/lib/top_level_elmnts_simple_spec.rb +169 -0
  28. data/spec/spec_helper.rb +86 -5
  29. data/spec/support/fixtures.rb +9 -0
  30. metadata +49 -44
  31. data/.travis.yml +0 -16
  32. data/spec/language_spec.rb +0 -118
  33. data/spec/location_spec.rb +0 -295
  34. data/spec/name_spec.rb +0 -759
  35. data/spec/origin_info_spec.rb +0 -447
  36. data/spec/part_spec.rb +0 -471
  37. data/spec/physical_description_spec.rb +0 -144
  38. data/spec/record_info_spec.rb +0 -493
  39. data/spec/record_spec.rb +0 -356
  40. data/spec/related_item_spec.rb +0 -305
  41. data/spec/subject_spec.rb +0 -809
  42. data/spec/title_spec.rb +0 -226
  43. data/spec/top_level_elmnts_simple_spec.rb +0 -369
@@ -0,0 +1,368 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe "Mods <name> Element" do
4
+ context 'with a record with a provided language' do
5
+ subject(:record) do
6
+ mods_record(<<-XML)
7
+ <name type='personal'><namePart xml:lang='fr-FR' type='given'>Jean</namePart><namePart xml:lang='en-US' type='given'>John</namePart></name>
8
+ XML
9
+ end
10
+
11
+ it "has the expected attributes" do
12
+ expect(record.personal_name.namePart).to match_array([
13
+ have_attributes(text: 'Jean', lang: 'fr-FR', type_at: 'given'),
14
+ have_attributes(text: 'John', lang: 'en-US', type_at: 'given'),
15
+ ])
16
+ end
17
+ end
18
+
19
+ context 'with a recod without a role' do
20
+ subject(:record) do
21
+ mods_record(<<-XML)
22
+ <name type='personal'><namePart>Crusty</namePart></name>
23
+ XML
24
+ end
25
+
26
+ it 'does not have a role' do
27
+ expect(record.personal_name.role).to be_empty
28
+ expect(record.personal_name.role.code).to be_empty
29
+ expect(record.personal_name.role.authority).to be_empty
30
+ end
31
+ end
32
+
33
+ context 'with a record with a text role' do
34
+ subject(:record) do
35
+ mods_record(<<-XML)
36
+ <name type='personal'><namePart>Crusty</namePart>
37
+ <role><roleTerm authority='marcrelator' type='text'>creator</roleTerm><role></name>
38
+ XML
39
+ end
40
+
41
+ it 'has the expected attributes' do
42
+ expect(record.plain_name.first).to have_attributes(
43
+ type_at: 'personal',
44
+ namePart: match_array([
45
+ have_attributes(text: 'Crusty')
46
+ ]),
47
+ role: have_attributes(
48
+ roleTerm: have_attributes(
49
+ text: 'creator',
50
+ type_at: ['text'],
51
+ authority: ['marcrelator']
52
+ ),
53
+ authority: ['marcrelator'],
54
+ code: [],
55
+ value: ['creator']
56
+ )
57
+ )
58
+ end
59
+ end
60
+
61
+ context 'with a record with a code role' do
62
+ subject(:record) do
63
+ mods_record(<<-XML)
64
+ <name type='personal'>
65
+ <namePart type='given'>John</namePart>
66
+ <namePart type='family'>Huston</namePart>
67
+ <role>
68
+ <roleTerm type='code' authority='marcrelator'>drt</roleTerm>
69
+ </role>
70
+ </name>
71
+ XML
72
+ end
73
+
74
+ it 'has the expected attributes' do
75
+ expect(record.plain_name.first).to have_attributes(
76
+ type_at: 'personal',
77
+ display_value: 'Huston, John',
78
+ namePart: match_array([
79
+ have_attributes(text: 'John', type_at: 'given'),
80
+ have_attributes(text: 'Huston', type_at: 'family'),
81
+ ]),
82
+ role: have_attributes(
83
+ roleTerm: match_array([
84
+ have_attributes(
85
+ text: 'drt',
86
+ type_at: 'code',
87
+ authority: 'marcrelator',
88
+ value: 'Director'
89
+ )
90
+ ]),
91
+ authority: ['marcrelator'],
92
+ code: ['drt'],
93
+ value: ['Director']
94
+ )
95
+ )
96
+ end
97
+ end
98
+
99
+ context 'with an alternate name' do
100
+ subject(:record) do
101
+ mods_record(<<-XML)
102
+ <name>
103
+ <namePart>Claudia Alta Johnson</namePart>
104
+ <alternativeName altType="nickname">
105
+ <namePart>Lady Bird Johnson</namePart>
106
+ </alternativeName>
107
+ </name>
108
+ XML
109
+ end
110
+
111
+ it 'has the expected attributes' do
112
+ expect(record.plain_name.first).to have_attributes(
113
+ namePart: have_attributes(text: 'Claudia Alta Johnson'),
114
+ alternative_name: match_array([
115
+ have_attributes(
116
+ altType: 'nickname',
117
+ namePart: have_attributes(text: 'Lady Bird Johnson')
118
+ )
119
+ ])
120
+ )
121
+ end
122
+ end
123
+
124
+ context 'with both a personal and corporate name' do
125
+ subject(:record) do
126
+ mods_record(<<-XML)
127
+ <name type='corporate'><namePart>ABC Corp</namePart></name>
128
+ <name type='personal'><namePart>Crusty</namePart></name>
129
+ XML
130
+ end
131
+
132
+ describe '#personal_name' do
133
+ it 'selects the name with the type "personal"' do
134
+ expect(record.personal_name).to match_array([
135
+ have_attributes(text: 'Crusty')
136
+ ])
137
+ end
138
+ end
139
+
140
+ describe '#corporate_name' do
141
+ it 'selects the name with the type "corporate"' do
142
+ expect(record.corporate_name).to match_array([
143
+ have_attributes(text: 'ABC Corp')
144
+ ])
145
+ end
146
+ end
147
+ end
148
+
149
+ context 'with a role with both text and a code' do
150
+ subject(:record) do
151
+ mods_record <<-XML
152
+ <name><namePart>anyone</namePart>
153
+ <role>
154
+ <roleTerm type='text' authority='marcrelator'>CreatorFake</roleTerm>
155
+ <roleTerm type='code' authority='marcrelator'>cre</roleTerm>
156
+ </role>
157
+ </name>
158
+ XML
159
+ end
160
+
161
+ it 'prefers the value of the text term' do
162
+ expect(record.plain_name.role.value).to eq ['CreatorFake']
163
+ end
164
+
165
+ it 'can return the code' do
166
+ expect(record.plain_name.role.code).to eq ['cre']
167
+ end
168
+ end
169
+
170
+ context 'with multiple roles' do
171
+ subject(:record) do
172
+ mods_record <<-XML
173
+ <name><namePart>Fats Waller</namePart>
174
+ <role>
175
+ <roleTerm type='text' authority='marcrelator'>CreatorFake</roleTerm>
176
+ <roleTerm type='code' authority='marcrelator'>cre</roleTerm>
177
+ </role>
178
+ <role>
179
+ <roleTerm type='text'>Performer</roleTerm>
180
+ </role>
181
+ </name>
182
+ XML
183
+ end
184
+
185
+ it 'returns both values' do
186
+ expect(record.plain_name.role.value).to eq ['CreatorFake', 'Performer']
187
+ end
188
+
189
+ it 'can return the code' do
190
+ expect(record.plain_name.role.code).to eq ['cre']
191
+ end
192
+ end
193
+
194
+ context 'with additional name metadata' do
195
+ subject(:record) do
196
+ mods_record <<-XML
197
+ <name>
198
+ <namePart>Exciting Prints</namePart>
199
+ <affiliation>whatever</affiliation>
200
+ <description>anything</description>
201
+ <role><roleTerm type='text'>some role</roleTerm></role>
202
+ </name>
203
+ XML
204
+ end
205
+
206
+ describe '#display_value' do
207
+ it 'has the expected value' do
208
+ expect(record.plain_name.first.display_value).to eq 'Exciting Prints'
209
+ end
210
+ end
211
+ end
212
+
213
+ context 'with an empty name' do
214
+ subject(:record) do
215
+ mods_record <<-XML
216
+ <name>
217
+ <namePart></namePart>
218
+ </name>
219
+ XML
220
+ end
221
+
222
+ describe '#display_value' do
223
+ it 'is blank' do
224
+ expect(record.plain_name.first.display_value).to be_nil
225
+ end
226
+ end
227
+ end
228
+
229
+ context 'with a displayForm' do
230
+ subject(:record) do
231
+ mods_record <<-XML
232
+ <name type='personal'>
233
+ <namePart>Alterman, Eric</namePart>
234
+ <displayForm>Eric Alterman</displayForm>
235
+ </name>
236
+ XML
237
+ end
238
+
239
+ describe '#display_value' do
240
+ it 'is the displayForm' do
241
+ expect(record.plain_name.first.display_value).to eq 'Eric Alterman'
242
+ end
243
+ end
244
+ end
245
+
246
+ context 'with a record with a displayForm that includes some dates' do
247
+ subject(:record) do
248
+ mods_record <<-XML
249
+ <name>
250
+ <namePart>Woolf, Virginia</namePart>
251
+ <namePart type='date'>1882-1941</namePart>
252
+ <displayForm>Woolf, Virginia, 1882-1941</namePart>
253
+ </name>
254
+ XML
255
+ end
256
+
257
+ describe '#display_value_w_dates' do
258
+ it 'does not duplicate the dates' do
259
+ expect(record.plain_name.first.display_value).to eq 'Woolf, Virginia, 1882-1941'
260
+ expect(record.plain_name.first.display_value_w_date).to eq 'Woolf, Virginia, 1882-1941'
261
+ end
262
+ end
263
+ end
264
+
265
+ context 'with a record with a namePart for dates' do
266
+ subject(:record) do
267
+ mods_record(<<-XML)
268
+ <name>
269
+ <namePart>Suzy</namePart>
270
+ <namePart type='date'>1920-</namePart>
271
+ </name>
272
+ XML
273
+ end
274
+
275
+ it 'has the expected attributes' do
276
+ expect(record.plain_name.first).to have_attributes(
277
+ display_value: 'Suzy',
278
+ display_value_w_date: 'Suzy, 1920-'
279
+ )
280
+ end
281
+ end
282
+
283
+ context 'without a family name and given name' do
284
+ subject(:record) do
285
+ mods_record("<name type='personal'>
286
+ <namePart type='given'>John Paul</namePart>
287
+ <namePart type='termsOfAddress'>II</namePart>
288
+ <namePart type='termsOfAddress'>Pope</namePart>
289
+ <namePart type='date'>1920-2005</namePart>
290
+ </name>")
291
+ end
292
+
293
+ describe '#display_value' do
294
+ it 'just concatenates the name parts' do
295
+ expect(record.personal_name.first.display_value).to eq 'John Paul II, Pope'
296
+ end
297
+ end
298
+
299
+ describe '#display_value_w_date' do
300
+ it 'includes the dates' do
301
+ expect(record.personal_name.first.display_value_w_date).to eq 'John Paul II, Pope, 1920-2005'
302
+ end
303
+ end
304
+ end
305
+
306
+ context 'with a bunch of untyped name parts' do
307
+ subject(:record) do
308
+ mods_record("<name type='personal'>
309
+ <namePart>Crusty</namePart>
310
+ <namePart>The Clown</namePart>
311
+ <namePart type='date'>1920-2005</namePart>
312
+ </name>")
313
+ end
314
+
315
+ describe '#display_value' do
316
+ it 'concatenates the untyped name parts' do
317
+ expect(record.personal_name.first.display_value).to eq('Crusty The Clown')
318
+ end
319
+ end
320
+ end
321
+
322
+ context 'with a corporate name' do
323
+ subject(:record) do
324
+ mods_record("<name type='corporate'>
325
+ <namePart>United States</namePart>
326
+ <namePart>Court of Appeals (2nd Circuit)</namePart>
327
+ </name>")
328
+ end
329
+
330
+ it 'concatenates the untyped name parts' do
331
+ expect(record.corporate_name.first.display_value).to eq('United States Court of Appeals (2nd Circuit)')
332
+ end
333
+ end
334
+
335
+ context 'with a complex example' do
336
+ subject(:record) do
337
+ mods_record <<-XML
338
+ <name>
339
+ <namePart>Sean Connery</namePart>
340
+ <role><roleTerm type='code' authority='marcrelator'>drt</roleTerm></role>
341
+ </name>
342
+ <name>
343
+ <namePart>Pierce Brosnan</namePart>
344
+ <role>
345
+ <roleTerm type='text'>CreatorFake</roleTerm>
346
+ <roleTerm type='code' authority='marcrelator'>cre</roleTerm>
347
+ </role>
348
+ <role><roleTerm type='text' authority='marcrelator'>Actor</roleTerm></role>
349
+ </name>
350
+ <name>
351
+ <namePart>Daniel Craig</namePart>
352
+ <role>
353
+ <roleTerm type='text' authority='marcrelator'>Actor</roleTerm>
354
+ <roleTerm type='code' authority='marcrelator'>cre</roleTerm>
355
+ </role>
356
+ </name>
357
+ XML
358
+ end
359
+
360
+ it 'has the expected attributes' do
361
+ expect(record.plain_name).to match_array([
362
+ have_attributes(role: have_attributes(value: ['Director'], code: ['drt'], authority: ['marcrelator'], size: 1)),
363
+ have_attributes(role: have_attributes(value: ['CreatorFake', 'Actor'], code: ['cre'], authority: ['marcrelator', 'marcrelator'], size: 2)),
364
+ have_attributes(role: have_attributes(value: ['Actor'], code: ['cre'], authority: ['marcrelator'], size: 1)),
365
+ ])
366
+ end
367
+ end
368
+ end
@@ -0,0 +1,134 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe "Mods <originInfo> Element" do
5
+ describe "#place" do
6
+ describe "#place_term" do
7
+ context 'with a single value' do
8
+ let(:terms) do
9
+ mods_record(<<-XML).origin_info.place.placeTerm
10
+ <originInfo><place><placeTerm authority='marccountry' type='code'>fr</placeTerm></place></originInfo>
11
+ XML
12
+ end
13
+
14
+ it 'has the expected attributes' do
15
+ expect(terms.first).to have_attributes(
16
+ authority: 'marccountry',
17
+ type_at: 'code',
18
+ text: 'fr'
19
+ )
20
+ end
21
+ end
22
+
23
+ context 'with a multi-valued place' do
24
+ let(:terms) do
25
+ mods_record(<<-XML).origin_info.place.placeTerm
26
+ <originInfo>
27
+ <place><placeTerm>France</placeTerm></place>
28
+ <place><placeTerm>Italy</placeTerm></place>
29
+ </originInfo>
30
+ XML
31
+ end
32
+
33
+ it 'has elements for each place' do
34
+ expect(terms.map(&:text)).to eq ['France', 'Italy']
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ describe "#publisher" do
41
+ subject(:publishers) do
42
+ mods_record(<<-XML).origin_info.publisher
43
+ <originInfo><publisher>Olney</publisher></origin_info>
44
+ XML
45
+ end
46
+
47
+ it "should get element values" do
48
+ expect(publishers.map(&:text)).to eq(["Olney"])
49
+ end
50
+ end
51
+
52
+ describe '#as_object' do
53
+ describe '#key_dates' do
54
+ it 'should extract the date with the keyDate attribute' do
55
+ origin_info = mods_record("<originInfo><dateCreated>other date</dateCreated><dateCreated keyDate='yes'>key date</dateCreated></originInfo>").origin_info
56
+ expect(origin_info.as_object.first.key_dates.first.text).to eq 'key date'
57
+ end
58
+ it 'should extract a date range when the keyDate attribute is on the start of the range' do
59
+ origin_info = mods_record("<originInfo><dateCreated point='end'>other date</dateCreated><dateCreated keyDate='yes' point='start'>key date</dateCreated></originInfo>").origin_info
60
+ expect(origin_info.as_object.first.key_dates.map(&:text)).to eq ['key date', 'other date']
61
+ end
62
+ end
63
+ end
64
+
65
+ Mods::ORIGIN_INFO_DATE_ELEMENTS.each do |elname|
66
+ context "<#{elname}> child elements" do
67
+ it "should recognize each element" do
68
+ origin_info = mods_record("<originInfo><#{elname}>date</#{elname}></originInfo>").origin_info.send(elname.to_sym)
69
+ expect(origin_info.map(&:text)).to eq(["date"])
70
+ end
71
+ it "should recognize encoding attribute on each element" do
72
+ origin_info = mods_record("<originInfo><#{elname} encoding='foo'>date</#{elname}></originInfo>").origin_info.send(elname.to_sym)
73
+ expect(origin_info.encoding).to eq(["foo"])
74
+ end
75
+ it "should recognize keyDate attribute" do
76
+ origin_info = mods_record("<originInfo><#{elname} keyDate='foo'>date</#{elname}></originInfo>").origin_info.send(elname.to_sym)
77
+ expect(origin_info.keyDate).to eq(["foo"])
78
+ end
79
+ it "should recognize point attribute" do
80
+ # NOTE: values allowed are 'start' and 'end'
81
+ origin_info = mods_record("<originInfo><#{elname} point='foo'>date</#{elname}></originInfo>").origin_info.send(elname.to_sym)
82
+ expect(origin_info.point).to eq(["foo"])
83
+ end
84
+ it "should recognize qualifier attribute" do
85
+ origin_info = mods_record("<originInfo><#{elname} qualifier='foo'>date</#{elname}></originInfo>").origin_info.send(elname.to_sym)
86
+ expect(origin_info.qualifier).to eq(["foo"])
87
+ end
88
+ it "should recognize type attribute only on dateOther" do
89
+ origin_info = mods_record("<originInfo><#{elname} type='foo'>date</#{elname}></originInfo>").origin_info.send(elname.to_sym)
90
+ if elname == 'dateOther'
91
+ expect(origin_info.type_at).to eq(["foo"])
92
+ else
93
+ expect { origin_info.type_at}.to raise_exception(NoMethodError, /type_at/)
94
+ end
95
+ end
96
+ end # <xxxDate> child elements
97
+ end
98
+
99
+ context 'edition' do
100
+ subject(:origin_info) do
101
+ mods_record(<<-XML).origin_info
102
+ <originInfo><edition>7th ed.</edition></originInfo>
103
+ XML
104
+ end
105
+
106
+ it "gets element value" do
107
+ expect(origin_info.edition).to have_attributes(text: '7th ed.')
108
+ end
109
+ end
110
+
111
+ context "<issuance> child element" do
112
+ subject(:origin_info) do
113
+ mods_record(<<-XML).origin_info
114
+ <originInfo><issuance>monographic</issuance></originInfo>
115
+ XML
116
+ end
117
+
118
+ it "gets element value" do
119
+ expect(origin_info.issuance).to have_attributes(text: 'monographic')
120
+ end
121
+ end
122
+
123
+ context "<frequency> child element" do
124
+ subject(:origin_info) do
125
+ mods_record(<<-XML).origin_info
126
+ <originInfo><frequency authority='marcfrequency'>Annual</frequency></originInfo>
127
+ XML
128
+ end
129
+
130
+ it "has the right attributes" do
131
+ expect(origin_info.frequency).to have_attributes(text: 'Annual', authority: ['marcfrequency'])
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,162 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe "Mods <part> Element" do
4
+ context 'with a basicpart' do
5
+ subject(:part) do
6
+ mods_record("<part>
7
+ <detail>
8
+ <title>Wayfarers (Poem)</title>
9
+ </detail>
10
+ <extent unit='pages'>
11
+ <start>97</start>
12
+ <end>98</end>
13
+ </extent>
14
+ </part>").part
15
+ end
16
+
17
+ it 'has the expected attributes' do
18
+ expect(part.first).to have_attributes(
19
+ detail: match_array([
20
+ have_attributes(
21
+ title: match_array([have_attributes(text: 'Wayfarers (Poem)')]),
22
+ number: [],
23
+ )
24
+ ]),
25
+ extent: match_array([
26
+ have_attributes(
27
+ unit: 'pages',
28
+ start: have_attributes(text: '97'),
29
+ end: have_attributes(text: '98'),
30
+ )
31
+ ])
32
+ )
33
+ end
34
+ end
35
+ context 'with a part with a detail number' do
36
+ subject(:part) do
37
+ mods_record("<part>
38
+ <detail type='page number'>
39
+ <number>3</number>
40
+ </detail>
41
+ <extent unit='pages'>
42
+ <start>3</start>
43
+ </extent>
44
+ </part>").part
45
+ end
46
+
47
+ it 'has the expected attributes' do
48
+ expect(part.first).to have_attributes(
49
+ detail: match_array([
50
+ have_attributes(
51
+ type_at: 'page number',
52
+ number: match_array([have_attributes(text: '3')])
53
+ )
54
+ ]),
55
+ extent: match_array([
56
+ have_attributes(
57
+ unit: 'pages',
58
+ start: have_attributes(text: '3')
59
+ )
60
+ ])
61
+ )
62
+ end
63
+ end
64
+ context 'with a part with a number and caption' do
65
+ subject(:part) do
66
+ mods_record("<part>
67
+ <detail type='issue'>
68
+ <number>1</number>
69
+ <caption>no.</caption>
70
+ </detail>
71
+ </part>").part
72
+ end
73
+
74
+ it 'has the expected attributes' do
75
+ expect(part.first).to have_attributes(
76
+ detail: match_array([
77
+ have_attributes(
78
+ type_at: 'issue',
79
+ number: match_array([have_attributes(text: '1')]),
80
+ caption: match_array([have_attributes(text: 'no.')])
81
+ )
82
+ ])
83
+ )
84
+ end
85
+ end
86
+
87
+ context 'with a typed part' do
88
+ subject(:part) do
89
+ mods_record("<part ID='p1' order='1' type='paragraph'>anything</part>").part
90
+ end
91
+
92
+ it 'has the expected attributes' do
93
+ expect(part.first).to have_attributes(
94
+ id_at: 'p1',
95
+ order: '1',
96
+ type_at: 'paragraph',
97
+ text: 'anything'
98
+ )
99
+ end
100
+ end
101
+
102
+ context 'with a level attribute' do
103
+ subject(:part) { mods_record("<part><detail level='val'>anything</detail></part>").part }
104
+
105
+ it 'has the expected attributes' do
106
+ expect(part.first).to have_attributes(
107
+ detail: match_array([have_attributes(level: 'val')])
108
+ )
109
+ end
110
+ end
111
+
112
+ context 'with a total element' do
113
+ subject(:part) { mods_record("<part><extent><total>anything</total></extent></part>").part }
114
+
115
+ it 'has the expected attributes' do
116
+ expect(part.first).to have_attributes(
117
+ extent: match_array([have_attributes(total: match_array([have_attributes(text: 'anything')]))])
118
+ )
119
+ end
120
+ end
121
+
122
+ context 'with a list element' do
123
+ subject(:part) { mods_record("<part><extent><list>anything</list></extent></part>").part }
124
+
125
+ it 'has the expected attributes' do
126
+ expect(part.first).to have_attributes(
127
+ extent: match_array([have_attributes(list: match_array([have_attributes(text: 'anything')]))])
128
+ )
129
+ end
130
+ end
131
+
132
+ context "<date> child element" do
133
+ subject(:date) do
134
+ mods_record("<part><date encoding='w3cdtf'>1999</date></part>").part.date
135
+ end
136
+
137
+ it 'has the expected date attributes' do
138
+ expect(date.first).to have_attributes(
139
+ encoding: 'w3cdtf',
140
+ text: '1999',
141
+ point: [],
142
+ qualifier: []
143
+ )
144
+ end
145
+
146
+ it 'does not have a keyDate attribute' do
147
+ expect(date.first).not_to respond_to(:keyDate)
148
+ end
149
+ end
150
+
151
+ context "<text> child element as .text_el term" do
152
+ subject(:part) do
153
+ mods_record("<part><text type='bar' displayLabel='foo'>1999</text></part>").part
154
+ end
155
+
156
+ describe '#text_el' do
157
+ it "has the expected attributes" do
158
+ expect(part.first.text_el).to have_attributes(text: '1999', displayLabel: ['foo'], type_at: ['bar'])
159
+ end
160
+ end
161
+ end
162
+ end