citeproc 1.0.0.pre12 → 1.0.0
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.
- checksums.yaml +7 -0
- data/.simplecov +4 -0
- data/AGPL +1 -1
- data/BSDL +2 -2
- data/Gemfile +39 -19
- data/README.md +123 -14
- data/Rakefile +22 -8
- data/cucumber.yml +1 -1
- data/features/step_definitions/processor.rb +59 -0
- data/features/support/env.rb +45 -2
- data/lib/citeproc.rb +8 -8
- data/lib/citeproc/abbreviate.rb +5 -4
- data/lib/citeproc/assets.rb +109 -109
- data/lib/citeproc/attributes.rb +11 -11
- data/lib/citeproc/bibliography.rb +107 -71
- data/lib/citeproc/citation_data.rb +175 -150
- data/lib/citeproc/compatibility.rb +5 -108
- data/lib/citeproc/date.rb +23 -12
- data/lib/citeproc/engine.rb +9 -4
- data/lib/citeproc/errors.rb +6 -6
- data/lib/citeproc/extensions.rb +66 -66
- data/lib/citeproc/item.rb +60 -2
- data/lib/citeproc/names.rb +103 -24
- data/lib/citeproc/number.rb +27 -8
- data/lib/citeproc/processor.rb +31 -41
- data/lib/citeproc/selector.rb +132 -126
- data/lib/citeproc/utilities.rb +6 -6
- data/lib/citeproc/variable.rb +5 -4
- data/lib/citeproc/version.rb +1 -1
- data/spec/citeproc/assets_spec.rb +17 -15
- data/spec/citeproc/bibliography_spec.rb +17 -17
- data/spec/citeproc/citation_data_spec.rb +90 -90
- data/spec/citeproc/engine_spec.rb +3 -4
- data/spec/citeproc/item_spec.rb +76 -68
- data/spec/citeproc/names_spec.rb +187 -148
- data/spec/citeproc/processor_spec.rb +119 -115
- data/spec/citeproc/selector_spec.rb +87 -78
- data/spec/citeproc/variable_spec.rb +30 -30
- data/spec/fixtures/locales/locales-en-US.xml +304 -0
- data/spec/spec_helper.rb +32 -1
- data/tasks/testsuite.rb +209 -0
- metadata +19 -87
- data/.gitignore +0 -6
- data/.travis.yml +0 -21
- data/citeproc.gemspec +0 -40
data/spec/citeproc/names_spec.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
module CiteProc
|
6
|
-
|
6
|
+
|
7
7
|
describe 'CiteProc Names' do
|
8
8
|
|
9
9
|
let(:poe) { Name.new(:family => 'Poe', :given => 'Edgar Allen') }
|
@@ -11,7 +11,7 @@ module CiteProc
|
|
11
11
|
let(:plato) { Name.new(:given => 'Plato') }
|
12
12
|
let(:aristotle) { Name.new(:given => 'Ἀριστοτέλης') }
|
13
13
|
let(:dostoyevksy) { Name.new(:given => 'Фёдор Михайлович', :family => 'Достоевский') }
|
14
|
-
|
14
|
+
|
15
15
|
let(:utf) { Name.new(
|
16
16
|
:given => 'Gérard',
|
17
17
|
:'dropping-particle' => 'de',
|
@@ -60,20 +60,20 @@ module CiteProc
|
|
60
60
|
"suffix" => "Jr.",
|
61
61
|
"comma-suffix" => "true")
|
62
62
|
}
|
63
|
-
|
63
|
+
|
64
64
|
let(:ramses) { Name.new(
|
65
65
|
:family => 'Ramses',
|
66
66
|
:given => 'Horatio',
|
67
67
|
:suffix => 'III')
|
68
68
|
}
|
69
|
-
|
69
|
+
|
70
70
|
describe Name do
|
71
71
|
|
72
72
|
|
73
73
|
it { should_not be_nil }
|
74
74
|
|
75
75
|
describe 'formatting options' do
|
76
|
-
|
76
|
+
|
77
77
|
it 'does not always demote particle by default' do
|
78
78
|
Name.new.always_demote_particle?.should be false
|
79
79
|
Name.new.always_demote_non_dropping_particle?.should be false
|
@@ -97,262 +97,301 @@ module CiteProc
|
|
97
97
|
it 'demotes particle in sort order if option is set to sort-only' do
|
98
98
|
Name.new({}, :'demote-non-dropping-particle' => 'display-and-sort').sort_order!.demote_particle?.should be true
|
99
99
|
end
|
100
|
-
|
100
|
+
|
101
101
|
it 'never demotes particle by default' do
|
102
102
|
Name.new.never_demote_particle?.should be true
|
103
103
|
Name.new.never_demote_non_dropping_particle?.should be true
|
104
104
|
end
|
105
|
-
|
105
|
+
|
106
106
|
it 'is not in sort order by default' do
|
107
107
|
Name.new.sort_order?.should be false
|
108
108
|
end
|
109
|
-
|
109
|
+
|
110
110
|
it 'uses the long form by default' do
|
111
111
|
Name.new.should be_long_form
|
112
112
|
end
|
113
|
-
|
113
|
+
|
114
114
|
it 'does not use short form by default' do
|
115
115
|
Name.new.should_not be_short_form
|
116
116
|
end
|
117
|
-
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
describe '#initials' do
|
121
|
+
let(:name) { Name.new(nil, :'initialize-with' => '. ') }
|
122
|
+
|
123
|
+
it 'returns the given name initials' do
|
124
|
+
name.given = 'Edgar A'
|
125
|
+
name.initials.should == 'E. A.'
|
126
|
+
|
127
|
+
name.options[:initialize] = 'false'
|
128
|
+
name.initials.should == 'Edgar A.'
|
129
|
+
end
|
130
|
+
|
131
|
+
describe 'private helpers' do
|
132
|
+
it '#initials_of initializes the given string' do
|
133
|
+
name.send(:initials_of, 'James T.').should == 'J. T.'
|
134
|
+
name.send(:initials_of, 'JT').should == 'J. T.'
|
135
|
+
name.send(:initials_of, 'James T').should == 'J. T.'
|
136
|
+
name.send(:initials_of, 'Jean-Luc').should == 'J.-L.'
|
137
|
+
name.send(:initials_of, 'Vérité Äpfel').should == 'V. Ä.'
|
138
|
+
|
139
|
+
name.initialize_without_hyphen!
|
140
|
+
name.send(:initials_of, 'Jean-Luc').should == 'J. L.'
|
141
|
+
|
142
|
+
name.options[:'initialize-with'] = '.'
|
143
|
+
name.send(:initials_of, 'James T.').should == 'J.T.'
|
144
|
+
name.send(:initials_of, 'James T').should == 'J.T.'
|
145
|
+
name.send(:initials_of, 'Jean-Luc').should == 'J.L.'
|
146
|
+
|
147
|
+
name.options[:'initialize-with-hyphen'] = true
|
148
|
+
name.send(:initials_of, 'Jean-Luc').should == 'J.-L.'
|
149
|
+
end
|
150
|
+
|
151
|
+
it '#initialize_existing_only initializes only current initials' do
|
152
|
+
name.send(:existing_initials_of, 'James T. Kirk').should == 'James T. Kirk'
|
153
|
+
name.send(:existing_initials_of, 'James T.Kirk').should == 'James T. Kirk'
|
154
|
+
name.send(:existing_initials_of, 'James T').should == 'James T.'
|
155
|
+
name.send(:existing_initials_of, 'Jean-Luc').should == 'Jean-Luc'
|
156
|
+
name.send(:existing_initials_of, 'J.-L.M.').should == 'J.-L. M.'
|
157
|
+
name.send(:existing_initials_of, 'J-L').should == 'J.-L.'
|
158
|
+
name.send(:existing_initials_of, 'J-LM').should == 'J.-L. M.'
|
159
|
+
name.send(:existing_initials_of, 'JT').should == 'J. T.'
|
160
|
+
end
|
161
|
+
end
|
118
162
|
end
|
119
163
|
|
120
164
|
describe 'constructing' do
|
121
|
-
|
165
|
+
|
122
166
|
describe '.new' do
|
123
|
-
|
167
|
+
|
124
168
|
it 'accepts a symbolized hash' do
|
125
|
-
Name.new(:family => 'Doe').
|
169
|
+
Name.new(:family => 'Doe').format.should == 'Doe'
|
126
170
|
end
|
127
171
|
|
128
172
|
it 'accepts a stringified hash' do
|
129
|
-
Name.new('family' => 'Doe').
|
173
|
+
Name.new('family' => 'Doe').format.should == 'Doe'
|
130
174
|
end
|
131
|
-
|
132
|
-
|
175
|
+
|
133
176
|
end
|
134
|
-
|
177
|
+
|
135
178
|
end
|
136
179
|
|
137
180
|
describe '#dup' do
|
138
|
-
|
181
|
+
|
139
182
|
it 'returns a new name copied by value' do
|
140
|
-
poe.dup.upcase!.
|
183
|
+
poe.dup.upcase!.format.should_not == poe.format
|
141
184
|
end
|
142
|
-
|
185
|
+
|
143
186
|
end
|
144
|
-
|
187
|
+
|
145
188
|
describe 'script awareness' do
|
146
|
-
|
189
|
+
|
147
190
|
it 'english names are romanesque' do
|
148
191
|
frank.should be_romanesque
|
149
192
|
end
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
aristotle.should be_romanesque
|
154
|
-
end
|
155
|
-
|
156
|
-
it 'russian names are romanesque' do
|
157
|
-
dostoyevksy.should be_romanesque
|
158
|
-
end
|
193
|
+
|
194
|
+
it 'ancient greek names are romanesque' do
|
195
|
+
aristotle.should be_romanesque
|
159
196
|
end
|
160
|
-
|
197
|
+
|
198
|
+
it 'russian names are romanesque' do
|
199
|
+
dostoyevksy.should be_romanesque
|
200
|
+
end
|
201
|
+
|
161
202
|
it 'japanese names are not romanesque' do
|
162
203
|
japanese.should_not be_romanesque
|
163
204
|
end
|
164
|
-
|
205
|
+
|
165
206
|
it 'german names are romanesque' do
|
166
|
-
Name.new(:given => '
|
207
|
+
Name.new(:given => 'Friedrich', :family => 'Hölderlin').should be_romanesque
|
167
208
|
end
|
168
|
-
|
209
|
+
|
169
210
|
it 'french names are romanesque' do
|
170
211
|
utf.should be_romanesque
|
171
212
|
end
|
172
|
-
|
213
|
+
|
173
214
|
it 'markup does not interfere with romanesque test' do
|
174
215
|
markup.should be_romanesque
|
175
216
|
end
|
176
|
-
|
217
|
+
|
177
218
|
end
|
178
|
-
|
219
|
+
|
179
220
|
describe 'literals' do
|
180
|
-
|
221
|
+
|
181
222
|
it 'is a literal if the literal attribute is set' do
|
182
223
|
Name.new(:literal => 'GNU/Linux').should be_literal
|
183
224
|
end
|
184
|
-
|
225
|
+
|
185
226
|
it 'is not literal by default' do
|
186
227
|
Name.new.should_not be_literal
|
187
228
|
end
|
188
|
-
|
229
|
+
|
189
230
|
it 'is literal even if other name parts are set' do
|
190
231
|
Name.new(:family => 'Tux', :literal => 'GNU/Linux').should be_literal
|
191
232
|
end
|
192
|
-
|
233
|
+
|
193
234
|
end
|
194
|
-
|
235
|
+
|
195
236
|
describe 'in-place manipulation (bang! methods)' do
|
196
|
-
|
237
|
+
|
197
238
|
it 'delegates to string for family name' do
|
198
|
-
plato.swapcase!.
|
239
|
+
plato.swapcase!.format.should == 'pLATO'
|
199
240
|
end
|
200
|
-
|
241
|
+
|
201
242
|
it 'delegates to string for given name' do
|
202
|
-
humboldt.gsub!(/^Alex\w*/, 'Wilhelm').
|
243
|
+
humboldt.gsub!(/^Alex\w*/, 'Wilhelm').format.should == 'Wilhelm von Humboldt'
|
203
244
|
end
|
204
|
-
|
245
|
+
|
205
246
|
it 'delegates to string for dropping particle' do
|
206
247
|
humboldt.upcase!.dropping_particle.should == 'VON'
|
207
248
|
end
|
208
|
-
|
249
|
+
|
209
250
|
it 'delegates to string for non dropping particle' do
|
210
251
|
van_gogh.upcase!.non_dropping_particle.should == 'VAN'
|
211
252
|
end
|
212
|
-
|
253
|
+
|
213
254
|
it 'delegates to string for suffix' do
|
214
|
-
frank.sub!(/jr./i, 'Sr.').
|
255
|
+
frank.sub!(/jr./i, 'Sr.').format.should == 'Frank G. Bennett, Sr.'
|
215
256
|
end
|
216
|
-
|
257
|
+
|
217
258
|
it 'returns the name object' do
|
218
259
|
poe.upcase!.should be_a(Name)
|
219
260
|
end
|
220
|
-
|
261
|
+
|
221
262
|
end
|
222
|
-
|
223
|
-
|
224
|
-
describe '#
|
263
|
+
|
264
|
+
|
265
|
+
describe '#format' do
|
225
266
|
|
226
267
|
it 'returns an empty string by default' do
|
227
|
-
Name.new.
|
268
|
+
Name.new.format.should be_empty
|
228
269
|
end
|
229
270
|
|
230
271
|
it 'returns the last name if only last name is set' do
|
231
|
-
Name.new(:family => 'Doe').
|
272
|
+
Name.new(:family => 'Doe').format.should == 'Doe'
|
232
273
|
end
|
233
274
|
|
234
275
|
it 'returns the first name if only the first name is set' do
|
235
|
-
Name.new(:given => 'John').
|
276
|
+
Name.new(:given => 'John').format.should == 'John'
|
236
277
|
end
|
237
278
|
|
238
279
|
it 'prints japanese names using static ordering' do
|
239
|
-
japanese.
|
280
|
+
japanese.format.should == '穂積 陳重'
|
240
281
|
end
|
241
282
|
|
242
283
|
it 'returns the literal if the name is a literal' do
|
243
|
-
Name.new(:literal => 'GNU/Linux').
|
284
|
+
Name.new(:literal => 'GNU/Linux').format == 'GNU/Linux'
|
244
285
|
end
|
245
286
|
|
246
287
|
it 'returns the name in display order by default' do
|
247
|
-
Name.new(:family => 'Doe', :given => 'John').
|
288
|
+
Name.new(:family => 'Doe', :given => 'John').format.should == 'John Doe'
|
248
289
|
end
|
249
290
|
|
250
291
|
it 'returns the name in sort order if the sort order option is active' do
|
251
|
-
Name.new(:family => 'Doe', :given => 'John').sort_order!.
|
292
|
+
Name.new(:family => 'Doe', :given => 'John').sort_order!.format.should == 'Doe, John'
|
252
293
|
end
|
253
294
|
|
254
295
|
it 'returns the full given name' do
|
255
|
-
saunders.
|
296
|
+
saunders.format.should == 'John Bertrand de Cusance Morant Saunders'
|
256
297
|
end
|
257
298
|
|
258
299
|
it 'includes dropping particles' do
|
259
|
-
humboldt.
|
300
|
+
humboldt.format.should == 'Alexander von Humboldt'
|
260
301
|
end
|
261
302
|
|
262
303
|
it 'includes non dropping particles' do
|
263
|
-
van_gogh.
|
304
|
+
van_gogh.format.should == 'Vincent van Gogh'
|
264
305
|
end
|
265
306
|
|
266
307
|
it 'includes suffices' do
|
267
|
-
jr.
|
308
|
+
jr.format.should == 'James Stephens Jr.'
|
268
309
|
end
|
269
310
|
|
270
311
|
it 'uses the comma suffix option' do
|
271
|
-
frank.
|
312
|
+
frank.format.should == 'Frank G. Bennett, Jr.'
|
272
313
|
end
|
273
314
|
|
274
315
|
it 'prints unicode characters' do
|
275
|
-
utf.
|
316
|
+
utf.format.should == "Gérard de la Martinière III"
|
276
317
|
end
|
277
318
|
|
278
|
-
|
279
|
-
|
280
|
-
dostoyevksy.to_s.should == 'Фёдор Михайлович Достоевский'
|
281
|
-
end
|
319
|
+
it 'prints russian names normally' do
|
320
|
+
dostoyevksy.format.should == 'Фёдор Михайлович Достоевский'
|
282
321
|
end
|
283
322
|
|
284
323
|
describe 'when static ordering is active' do
|
285
|
-
|
324
|
+
|
286
325
|
it 'always prints the family name first' do
|
287
|
-
poe.static_order!.
|
326
|
+
poe.static_order!.format.should == 'Poe Edgar Allen'
|
288
327
|
end
|
289
|
-
|
328
|
+
|
290
329
|
end
|
291
|
-
|
330
|
+
|
292
331
|
describe 'when the sort order option is active' do
|
293
332
|
|
294
333
|
it 'returns an empty string by default' do
|
295
|
-
Name.new.sort_order!.
|
334
|
+
Name.new.sort_order!.format.should be_empty
|
296
335
|
end
|
297
336
|
|
298
337
|
it 'returns the last name if only last name is set' do
|
299
|
-
Name.new({:family => 'Doe'}, { :'name-as-sort-order' => true }).
|
338
|
+
Name.new({:family => 'Doe'}, { :'name-as-sort-order' => true }).format.should == 'Doe'
|
300
339
|
end
|
301
340
|
|
302
341
|
it 'returns the first name if only the first name is set' do
|
303
|
-
Name.new(:given => 'John').sort_order!.
|
342
|
+
Name.new(:given => 'John').sort_order!.format.should == 'John'
|
304
343
|
end
|
305
344
|
|
306
345
|
it 'prints japanese names using static ordering' do
|
307
|
-
japanese.sort_order!.
|
346
|
+
japanese.sort_order!.format.should == '穂積 陳重'
|
308
347
|
end
|
309
348
|
|
310
349
|
it 'returns the literal if the name is a literal' do
|
311
|
-
Name.new(:literal => 'GNU/Linux').sort_order!.
|
350
|
+
Name.new(:literal => 'GNU/Linux').sort_order!.format == 'GNU/Linux'
|
312
351
|
end
|
313
352
|
|
314
353
|
it 'uses comma for suffix if comma suffix is set' do
|
315
|
-
frank.sort_order!.
|
354
|
+
frank.sort_order!.format.should == 'Bennett, Frank G., Jr.'
|
316
355
|
end
|
317
|
-
|
356
|
+
|
318
357
|
it 'also uses comma for suffix if comma suffix is *not* set' do
|
319
|
-
jr.sort_order!.
|
358
|
+
jr.sort_order!.format.should == 'Stephens, James, Jr.'
|
320
359
|
end
|
321
360
|
|
322
361
|
it 'for normal names it prints them as "family, given"' do
|
323
|
-
poe.sort_order!.
|
362
|
+
poe.sort_order!.format.should == 'Poe, Edgar Allen'
|
324
363
|
end
|
325
|
-
|
364
|
+
|
326
365
|
it 'particles come after given name by default' do
|
327
|
-
van_gogh.sort_order!.
|
366
|
+
van_gogh.sort_order!.format.should == 'van Gogh, Vincent'
|
328
367
|
end
|
329
368
|
|
330
369
|
it 'particles come after given name if demote option is active' do
|
331
|
-
van_gogh.sort_order!.demote_particle!.
|
370
|
+
van_gogh.sort_order!.demote_particle!.format.should == 'Gogh, Vincent van'
|
332
371
|
end
|
333
|
-
|
372
|
+
|
334
373
|
it 'dropping particles come after given name' do
|
335
|
-
humboldt.sort_order!.
|
374
|
+
humboldt.sort_order!.format.should == 'Humboldt, Alexander von'
|
336
375
|
end
|
337
|
-
|
376
|
+
|
338
377
|
it 'by default if all parts are set they are returned as "particle family, first dropping-particle, suffix"' do
|
339
|
-
utf.sort_order!.
|
378
|
+
utf.sort_order!.format.should == 'la Martinière, Gérard de, III'
|
340
379
|
end
|
341
|
-
|
380
|
+
|
342
381
|
end
|
343
|
-
|
382
|
+
|
344
383
|
end
|
345
|
-
|
384
|
+
|
346
385
|
describe '#sort_order' do
|
347
|
-
|
386
|
+
|
348
387
|
it 'returns only a single token for literal names' do
|
349
388
|
Name.new(:literal => 'ACME Corp.').sort_order.should have(1).element
|
350
389
|
end
|
351
|
-
|
390
|
+
|
352
391
|
it 'strips leading "the" off literal names' do
|
353
392
|
Name.new(:literal => 'The ACME Corp.').sort_order[0].should == 'ACME Corp.'
|
354
393
|
end
|
355
|
-
|
394
|
+
|
356
395
|
it 'strips leading "a" off literal names' do
|
357
396
|
Name.new(:literal => 'A Company').sort_order[0].should == 'Company'
|
358
397
|
end
|
@@ -360,11 +399,11 @@ module CiteProc
|
|
360
399
|
it 'strips leading "an" off literal names' do
|
361
400
|
Name.new(:literal => 'an ACME Corp.').sort_order[0].should == 'ACME Corp.'
|
362
401
|
end
|
363
|
-
|
402
|
+
|
364
403
|
it 'strips leading "l\'" off literal names' do
|
365
404
|
Name.new(:literal => "L'Augustine").sort_order[0].should == 'Augustine'
|
366
405
|
end
|
367
|
-
|
406
|
+
|
368
407
|
it 'always returns four tokens for non literal names' do
|
369
408
|
poe.sort_order.should have(4).elements
|
370
409
|
joe.sort_order.should have(4).elements
|
@@ -373,7 +412,7 @@ module CiteProc
|
|
373
412
|
frank.sort_order.should have(4).elements
|
374
413
|
japanese.sort_order.should have(4).elements
|
375
414
|
end
|
376
|
-
|
415
|
+
|
377
416
|
it 'demotes non dropping particles if option is set' do
|
378
417
|
van_gogh.demote_particle!.sort_order.should == ['Gogh', 'van', 'Vincent', '']
|
379
418
|
end
|
@@ -389,35 +428,35 @@ module CiteProc
|
|
389
428
|
it 'demotes dropping particles' do
|
390
429
|
humboldt.sort_order.should == ['Humboldt', 'von', 'Alexander', '']
|
391
430
|
end
|
392
|
-
|
431
|
+
|
393
432
|
it 'combines non dropping particles with family name if option demote-non-dropping-particles is not active' do
|
394
433
|
van_gogh.never_demote_particle!.sort_order.should == ['van Gogh', '', 'Vincent', '']
|
395
434
|
end
|
396
|
-
|
435
|
+
|
397
436
|
end
|
398
|
-
|
437
|
+
|
399
438
|
describe 'sorting' do
|
400
|
-
|
439
|
+
|
401
440
|
it 'sorts by sort order by default' do
|
402
441
|
[poe, utf, joe, plato].sort.should == [joe, plato, utf, poe]
|
403
442
|
end
|
404
|
-
|
443
|
+
|
405
444
|
end
|
406
|
-
|
407
|
-
|
445
|
+
|
446
|
+
|
408
447
|
end
|
409
|
-
|
448
|
+
|
410
449
|
describe Names do
|
411
|
-
|
450
|
+
|
412
451
|
let(:gang_of_four) {
|
413
452
|
Names.parse!('Erich Gamma and Richard Helm and Ralph Johnson and John Vlissides')
|
414
453
|
}
|
415
|
-
|
454
|
+
|
416
455
|
it { should_not be nil }
|
417
456
|
it { should_not be_numeric }
|
418
|
-
|
457
|
+
|
419
458
|
describe 'constructing' do
|
420
|
-
|
459
|
+
|
421
460
|
it 'accepts a single name' do
|
422
461
|
lambda { Names.new(joe) }.should_not raise_error
|
423
462
|
end
|
@@ -425,7 +464,7 @@ module CiteProc
|
|
425
464
|
it 'accepts a single name as hash' do
|
426
465
|
Names.new(:given => 'Jim').should have(1).names
|
427
466
|
end
|
428
|
-
|
467
|
+
|
429
468
|
it 'accepts two names' do
|
430
469
|
Names.new(joe, poe).should have(2).names
|
431
470
|
end
|
@@ -437,7 +476,7 @@ module CiteProc
|
|
437
476
|
it 'accepts an array of names' do
|
438
477
|
Names.new([joe, poe]).should have(2).names
|
439
478
|
end
|
440
|
-
|
479
|
+
|
441
480
|
end
|
442
481
|
|
443
482
|
describe 'parsing' do
|
@@ -453,47 +492,47 @@ module CiteProc
|
|
453
492
|
Names.parse('Edgar A. Poe and Hawthorne, Nathaniel and Herman Melville').map { |n|
|
454
493
|
n.values_at(:family) }.flatten.should == %w{ Poe Hawthorne Melville }
|
455
494
|
end
|
456
|
-
|
495
|
+
|
457
496
|
it '#parse returns nil on error' do
|
458
497
|
Names.parse(23).should be_nil
|
459
498
|
end
|
460
|
-
|
499
|
+
|
461
500
|
it '#parse! raises an error on bad input' do
|
462
501
|
expect { Names.parse!('23') }.to raise_error(ParseError)
|
463
502
|
end
|
464
|
-
|
503
|
+
|
465
504
|
end
|
466
|
-
|
505
|
+
|
467
506
|
describe '#strip_markup' do
|
468
|
-
|
507
|
+
|
469
508
|
it 'strips markup off string representation' do
|
470
509
|
Names.new(markup).strip_markup.should == utf.to_s
|
471
510
|
end
|
472
|
-
|
511
|
+
|
473
512
|
it 'when using the bang! version, strips markup off each name part' do
|
474
513
|
Names.new(markup).strip_markup![0].should == utf
|
475
514
|
end
|
476
|
-
|
477
|
-
|
515
|
+
|
516
|
+
|
478
517
|
end
|
479
|
-
|
518
|
+
|
480
519
|
describe 'bang! methods' do
|
481
520
|
it 'delegate to the individual names and return self' do
|
482
521
|
Names.new(poe, plato, joe).upcase!.map(&:given).should == ['EDGAR ALLEN', 'PLATO', 'JOE']
|
483
|
-
end
|
522
|
+
end
|
484
523
|
end
|
485
|
-
|
524
|
+
|
486
525
|
[:never, :always, :contextually].each do |setting|
|
487
526
|
setter = "delimiter_#{setting}_precedes_last!"
|
488
527
|
predicate = "delimiter_#{setting}_precedes_last?"
|
489
|
-
|
528
|
+
|
490
529
|
describe "##{setter}" do
|
491
530
|
it 'sets the delimiter precedes last option accordingly' do
|
492
531
|
Names.new.send(setter).send(predicate).should == true
|
493
532
|
end
|
494
533
|
end
|
495
534
|
end
|
496
|
-
|
535
|
+
|
497
536
|
describe '#delimiter_precedes_last' do
|
498
537
|
it 'returns false by default' do
|
499
538
|
Names.new(joe).should_not be_delimiter_precedes_last
|
@@ -519,41 +558,41 @@ module CiteProc
|
|
519
558
|
Names.new(joe, poe, plato).delimiter_never_precedes_last!.should_not be_delimiter_precedes_last
|
520
559
|
end
|
521
560
|
end
|
522
|
-
|
561
|
+
|
523
562
|
describe '#to_bibtex' do
|
524
|
-
|
563
|
+
|
525
564
|
describe 'when there is only a single name' do
|
526
565
|
it 'prints the name in sort order' do
|
527
566
|
Names.new(poe).to_bibtex.should == 'Poe, Edgar Allen'
|
528
567
|
end
|
529
568
|
end
|
530
|
-
|
569
|
+
|
531
570
|
describe 'when there are two or more names' do
|
532
571
|
it 'prints the names in sort order connected with the word "and"' do
|
533
572
|
Names.new(poe, plato, humboldt).to_bibtex.should == 'Poe, Edgar Allen and Plato and Humboldt, Alexander von'
|
534
573
|
end
|
535
574
|
end
|
536
|
-
|
575
|
+
|
537
576
|
end
|
538
|
-
|
577
|
+
|
539
578
|
describe '#to_s' do
|
540
|
-
|
579
|
+
|
541
580
|
describe 'when the number of names exceeds the et-al-min option' do
|
542
581
|
before do
|
543
582
|
gang_of_four.options[:'et-al-min'] = 3
|
544
583
|
gang_of_four.options[:'et-al-use-first'] = 2
|
545
584
|
gang_of_four.options[:'et-al'] = 'FOO'
|
546
585
|
end
|
547
|
-
|
586
|
+
|
548
587
|
it 'prints only the et-al-use-first names' do
|
549
588
|
gang_of_four.to_s.should match(/gamma.+helm/i)
|
550
589
|
gang_of_four.to_s.should_not match(/johnson|vlissides/i)
|
551
590
|
end
|
552
|
-
|
591
|
+
|
553
592
|
it 'adds et-al at the end' do
|
554
593
|
gang_of_four.to_s.should end_with('FOO')
|
555
594
|
end
|
556
|
-
|
595
|
+
|
557
596
|
it 'adds the delimiter before et-al when multiple names are printed' do
|
558
597
|
gang_of_four.to_s.should end_with(', FOO')
|
559
598
|
end
|
@@ -562,26 +601,26 @@ module CiteProc
|
|
562
601
|
gang_of_four.options[:'et-al-use-first'] = 1
|
563
602
|
gang_of_four.to_s.should_not end_with(', FOO')
|
564
603
|
end
|
565
|
-
|
604
|
+
|
566
605
|
end
|
567
|
-
|
606
|
+
|
568
607
|
it 'squeezes multiple whitespace between delimiter and connector' do
|
569
608
|
Names.new(poe, humboldt, van_gogh, joe).to_s.should_not match(/\s{2}/)
|
570
|
-
end
|
609
|
+
end
|
571
610
|
end
|
572
|
-
|
611
|
+
|
573
612
|
describe '#each' do
|
574
613
|
it 'returns an enumerator when no block given' do
|
575
614
|
gang_of_four.each.should respond_to(:each)
|
576
615
|
end
|
577
616
|
end
|
578
|
-
|
617
|
+
|
579
618
|
describe '#to_citeproc' do
|
580
619
|
it 'returns a list of hashes' do
|
581
620
|
gang_of_four.to_citeproc.map(&:class).uniq.should == [Hash]
|
582
621
|
end
|
583
622
|
end
|
584
|
-
|
623
|
+
|
585
624
|
describe 'sorting' do
|
586
625
|
it 'accepts other Names instance' do
|
587
626
|
(Names.new(poe, plato) <=> Names.new(plato)).should equal(1)
|
@@ -599,9 +638,9 @@ module CiteProc
|
|
599
638
|
gang_of_four.inspect.should be_a(String)
|
600
639
|
end
|
601
640
|
end
|
602
|
-
|
641
|
+
|
603
642
|
end
|
604
|
-
|
643
|
+
|
605
644
|
end
|
606
|
-
|
607
|
-
end
|
645
|
+
|
646
|
+
end
|