slaw 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,543 @@
1
+ require 'spec_helper'
2
+ require 'slaw'
3
+
4
+ describe Slaw::Parse::Builder do
5
+ describe '#nest_blocklists' do
6
+ it 'should nest simple blocks' do
7
+ doc = xml2doc(subsection(<<XML
8
+ <blockList id="section-10.1.lst0">
9
+ <item id="section-10.1.lst0.a">
10
+ <num>(a)</num>
11
+ <p>foo</p>
12
+ </item>
13
+ <item id="section-10.1.lst0.i">
14
+ <num>(i)</num>
15
+ <p>item-i</p>
16
+ </item>
17
+ <item id="section-10.1.lst0.ii">
18
+ <num>(ii)</num>
19
+ <p>item-ii</p>
20
+ </item>
21
+ <item id="section-10.1.lst0.iii">
22
+ <num>(iii)</num>
23
+ <p>item-iii</p>
24
+ </item>
25
+ <item id="section-10.1.lst0.aa">
26
+ <num>(aa)</num>
27
+ <p>item-aa</p>
28
+ </item>
29
+ <item id="section-10.1.lst0.bb">
30
+ <num>(bb)</num>
31
+ <p>item-bb</p>
32
+ </item>
33
+ </blockList>
34
+ XML
35
+ ))
36
+
37
+ subject.nest_blocklists(doc)
38
+ doc.to_s.should == subsection(<<XML
39
+ <blockList id="section-10.1.lst0">
40
+ <item id="section-10.1.lst0.a">
41
+ <num>(a)</num>
42
+ <blockList id="section-10.1.lst0.a.list0">
43
+ <listIntroduction>foo</listIntroduction>
44
+ <item id="section-10.1.lst0.a.list0.i">
45
+ <num>(i)</num>
46
+ <p>item-i</p>
47
+ </item>
48
+ <item id="section-10.1.lst0.a.list0.ii">
49
+ <num>(ii)</num>
50
+ <p>item-ii</p>
51
+ </item>
52
+ <item id="section-10.1.lst0.a.list0.iii">
53
+ <num>(iii)</num>
54
+ <blockList id="section-10.1.lst0.a.list0.iii.list0">
55
+ <listIntroduction>item-iii</listIntroduction>
56
+ <item id="section-10.1.lst0.a.list0.iii.list0.aa">
57
+ <num>(aa)</num>
58
+ <p>item-aa</p>
59
+ </item>
60
+ <item id="section-10.1.lst0.a.list0.iii.list0.bb">
61
+ <num>(bb)</num>
62
+ <p>item-bb</p>
63
+ </item>
64
+ </blockList>
65
+ </item>
66
+ </blockList>
67
+ </item>
68
+ </blockList>
69
+ XML
70
+ )
71
+ end
72
+
73
+ # -------------------------------------------------------------------------
74
+
75
+ it 'should jump back up a level' do
76
+ doc = xml2doc(subsection(<<XML
77
+ <blockList id="section-10.1.lst0">
78
+ <item id="section-10.1.lst0.a">
79
+ <num>(a)</num>
80
+ <p>foo</p>
81
+ </item>
82
+ <item id="section-10.1.lst0.i">
83
+ <num>(i)</num>
84
+ <p>item-i</p>
85
+ </item>
86
+ <item id="section-10.1.lst0.ii">
87
+ <num>(ii)</num>
88
+ <p>item-ii</p>
89
+ </item>
90
+ <item id="section-10.1.lst0.c">
91
+ <num>(c)</num>
92
+ <p>item-c</p>
93
+ </item>
94
+ </blockList>
95
+ XML
96
+ ))
97
+
98
+ subject.nest_blocklists(doc)
99
+ doc.to_s.should == subsection(<<XML
100
+ <blockList id="section-10.1.lst0">
101
+ <item id="section-10.1.lst0.a">
102
+ <num>(a)</num>
103
+ <blockList id="section-10.1.lst0.a.list0">
104
+ <listIntroduction>foo</listIntroduction>
105
+ <item id="section-10.1.lst0.a.list0.i">
106
+ <num>(i)</num>
107
+ <p>item-i</p>
108
+ </item>
109
+ <item id="section-10.1.lst0.a.list0.ii">
110
+ <num>(ii)</num>
111
+ <p>item-ii</p>
112
+ </item>
113
+ </blockList>
114
+ </item>
115
+ <item id="section-10.1.lst0.c">
116
+ <num>(c)</num>
117
+ <p>item-c</p>
118
+ </item>
119
+ </blockList>
120
+ XML
121
+ )
122
+ end
123
+
124
+ # -------------------------------------------------------------------------
125
+
126
+ it 'should handle (i) correctly' do
127
+ doc = xml2doc(subsection(<<XML
128
+ <blockList id="section-10.1.lst0">
129
+ <item id="section-10.1.lst0.h">
130
+ <num>(h)</num>
131
+ <p>foo</p>
132
+ </item>
133
+ <item id="section-10.1.lst0.i">
134
+ <num>(i)</num>
135
+ <p>item-i</p>
136
+ </item>
137
+ <item id="section-10.1.lst0.j">
138
+ <num>(j)</num>
139
+ <p>item-ii</p>
140
+ </item>
141
+ </blockList>
142
+ XML
143
+ ))
144
+
145
+ subject.nest_blocklists(doc)
146
+ doc.to_s.should == subsection(<<XML
147
+ <blockList id="section-10.1.lst0">
148
+ <item id="section-10.1.lst0.h">
149
+ <num>(h)</num>
150
+ <p>foo</p>
151
+ </item>
152
+ <item id="section-10.1.lst0.i">
153
+ <num>(i)</num>
154
+ <p>item-i</p>
155
+ </item>
156
+ <item id="section-10.1.lst0.j">
157
+ <num>(j)</num>
158
+ <p>item-ii</p>
159
+ </item>
160
+ </blockList>
161
+ XML
162
+ )
163
+ end
164
+
165
+ # -------------------------------------------------------------------------
166
+
167
+ it 'should handle (u) (v) and (x) correctly' do
168
+ doc = xml2doc(subsection(<<XML
169
+ <blockList id="section-10.1.lst0">
170
+ <item id="section-10.1.lst0.t">
171
+ <num>(t)</num>
172
+ <p>foo</p>
173
+ </item>
174
+ <item id="section-10.1.lst0.u">
175
+ <num>(u)</num>
176
+ <p>item-i</p>
177
+ </item>
178
+ <item id="section-10.1.lst0.v">
179
+ <num>(v)</num>
180
+ <p>item-ii</p>
181
+ </item>
182
+ <item id="section-10.1.lst0.w">
183
+ <num>(w)</num>
184
+ <p>item-ii</p>
185
+ </item>
186
+ <item id="section-10.1.lst0.x">
187
+ <num>(x)</num>
188
+ <p>item-ii</p>
189
+ </item>
190
+ </blockList>
191
+ XML
192
+ ))
193
+
194
+ subject.nest_blocklists(doc)
195
+ doc.to_s.should == subsection(<<XML
196
+ <blockList id="section-10.1.lst0">
197
+ <item id="section-10.1.lst0.t">
198
+ <num>(t)</num>
199
+ <p>foo</p>
200
+ </item>
201
+ <item id="section-10.1.lst0.u">
202
+ <num>(u)</num>
203
+ <p>item-i</p>
204
+ </item>
205
+ <item id="section-10.1.lst0.v">
206
+ <num>(v)</num>
207
+ <p>item-ii</p>
208
+ </item>
209
+ <item id="section-10.1.lst0.w">
210
+ <num>(w)</num>
211
+ <p>item-ii</p>
212
+ </item>
213
+ <item id="section-10.1.lst0.x">
214
+ <num>(x)</num>
215
+ <p>item-ii</p>
216
+ </item>
217
+ </blockList>
218
+ XML
219
+ )
220
+ end
221
+
222
+
223
+ # -------------------------------------------------------------------------
224
+
225
+ it 'should handle (j) correctly' do
226
+ doc = xml2doc(subsection(<<XML
227
+ <blockList id="section-28.3.list2">
228
+ <item id="section-28.3.list2.g">
229
+ <num>(g)</num>
230
+ <p>all <term refersTo="#term-memorial_work" id="trm381">memorial work</term> up to 150 mm in thickness must be securely attached to the base;</p>
231
+ </item>
232
+ <item id="section-28.3.list2.h">
233
+ <num>(h)</num>
234
+ <p>all the components of <term refersTo="#term-memorial_work" id="trm382">memorial work</term> must be completed before being brought into a <term refersTo="#term-cemetery" id="trm383">cemetery</term>;</p>
235
+ </item>
236
+ <item id="section-28.3.list2.i">
237
+ <num>(i)</num>
238
+ <p>footstones must consist of one solid piece;</p>
239
+ </item>
240
+ <item id="section-28.3.list2.j">
241
+ <num>(j)</num>
242
+ <p>in all cases where <term refersTo="#term-memorial_work" id="trm384">memorial work</term> rests on a base -</p>
243
+ </item>
244
+ <item id="section-28.3.list2.i">
245
+ <num>(i)</num>
246
+ <p>such <term refersTo="#term-memorial_work" id="trm385">memorial work</term> must have a foundation;</p>
247
+ </item>
248
+ <item id="section-28.3.list2.ii">
249
+ <num>(ii)</num>
250
+ <p>such <term refersTo="#term-memorial_work" id="trm386">memorial work</term> must be set with cement mortar;</p>
251
+ </item>
252
+ <item id="section-28.3.list2.iii">
253
+ <num>(iii)</num>
254
+ <p>the bottom base of a single <term refersTo="#term-memorial_work" id="trm387">memorial work</term> must not be less than 900mm long 220 mm wide x 250 mm thick and that of a double <term refersTo="#term-memorial_work" id="trm388">memorial work</term> not less than 2 286 mm long x 200 mm wide x 250 mm thick; and</p>
255
+ </item>
256
+ </blockList>
257
+ XML
258
+ ))
259
+
260
+ subject.nest_blocklists(doc)
261
+ doc.to_s.should == subsection(<<XML
262
+ <blockList id="section-28.3.list2">
263
+ <item id="section-28.3.list2.g">
264
+ <num>(g)</num>
265
+ <p>all <term refersTo="#term-memorial_work" id="trm381">memorial work</term> up to 150 mm in thickness must be securely attached to the base;</p>
266
+ </item>
267
+ <item id="section-28.3.list2.h">
268
+ <num>(h)</num>
269
+ <p>all the components of <term refersTo="#term-memorial_work" id="trm382">memorial work</term> must be completed before being brought into a <term refersTo="#term-cemetery" id="trm383">cemetery</term>;</p>
270
+ </item>
271
+ <item id="section-28.3.list2.i">
272
+ <num>(i)</num>
273
+ <p>footstones must consist of one solid piece;</p>
274
+ </item>
275
+ <item id="section-28.3.list2.j">
276
+ <num>(j)</num>
277
+ <blockList id="section-28.3.list2.j.list0">
278
+ <listIntroduction>in all cases where <term refersTo="#term-memorial_work" id="trm384">memorial work</term> rests on a base -</listIntroduction>
279
+ <item id="section-28.3.list2.j.list0.i">
280
+ <num>(i)</num>
281
+ <p>such <term refersTo="#term-memorial_work" id="trm385">memorial work</term> must have a foundation;</p>
282
+ </item>
283
+ <item id="section-28.3.list2.j.list0.ii">
284
+ <num>(ii)</num>
285
+ <p>such <term refersTo="#term-memorial_work" id="trm386">memorial work</term> must be set with cement mortar;</p>
286
+ </item>
287
+ <item id="section-28.3.list2.j.list0.iii">
288
+ <num>(iii)</num>
289
+ <p>the bottom base of a single <term refersTo="#term-memorial_work" id="trm387">memorial work</term> must not be less than 900mm long 220 mm wide x 250 mm thick and that of a double <term refersTo="#term-memorial_work" id="trm388">memorial work</term> not less than 2 286 mm long x 200 mm wide x 250 mm thick; and</p>
290
+ </item>
291
+ </blockList>
292
+ </item>
293
+ </blockList>
294
+ XML
295
+ )
296
+ end
297
+
298
+ # -------------------------------------------------------------------------
299
+
300
+ it 'should handle deeply nested lists' do
301
+ doc = xml2doc(subsection(<<XML
302
+ <blockList id="list0">
303
+ <item id="list0.a">
304
+ <num>(a)</num>
305
+ <p>foo</p>
306
+ </item>
307
+ <item id="list0.b">
308
+ <num>(b)</num>
309
+ <p>item-b</p>
310
+ </item>
311
+ <item id="list0.i">
312
+ <num>(i)</num>
313
+ <p>item-b-i</p>
314
+ </item>
315
+ <item id="list0.aa">
316
+ <num>(aa)</num>
317
+ <p>item-i-aa</p>
318
+ </item>
319
+ <item id="list0.bb">
320
+ <num>(bb)</num>
321
+ <p>item-i-bb</p>
322
+ </item>
323
+ <item id="list0.ii">
324
+ <num>(ii)</num>
325
+ <p>item-b-ii</p>
326
+ </item>
327
+ <item id="list0.c">
328
+ <num>(c)</num>
329
+ <p>item-c</p>
330
+ </item>
331
+ <item id="list0.i">
332
+ <num>(i)</num>
333
+ <p>item-c-i</p>
334
+ </item>
335
+ <item id="list0.ii">
336
+ <num>(ii)</num>
337
+ <p>item-c-ii</p>
338
+ </item>
339
+ <item id="list0.iii">
340
+ <num>(iii)</num>
341
+ <p>item-c-iii</p>
342
+ </item>
343
+ </blockList>
344
+ XML
345
+ ))
346
+
347
+ subject.nest_blocklists(doc)
348
+ doc.to_s.should == subsection(<<XML
349
+ <blockList id="list0">
350
+ <item id="list0.a">
351
+ <num>(a)</num>
352
+ <p>foo</p>
353
+ </item>
354
+ <item id="list0.b">
355
+ <num>(b)</num>
356
+ <blockList id="list0.b.list0">
357
+ <listIntroduction>item-b</listIntroduction>
358
+ <item id="list0.b.list0.i">
359
+ <num>(i)</num>
360
+ <blockList id="list0.b.list0.i.list0">
361
+ <listIntroduction>item-b-i</listIntroduction>
362
+ <item id="list0.b.list0.i.list0.aa">
363
+ <num>(aa)</num>
364
+ <p>item-i-aa</p>
365
+ </item>
366
+ <item id="list0.b.list0.i.list0.bb">
367
+ <num>(bb)</num>
368
+ <p>item-i-bb</p>
369
+ </item>
370
+ </blockList>
371
+ </item>
372
+ <item id="list0.b.list0.ii">
373
+ <num>(ii)</num>
374
+ <p>item-b-ii</p>
375
+ </item>
376
+ </blockList>
377
+ </item>
378
+ <item id="list0.c">
379
+ <num>(c)</num>
380
+ <blockList id="list0.c.list1">
381
+ <listIntroduction>item-c</listIntroduction>
382
+ <item id="list0.c.list1.i">
383
+ <num>(i)</num>
384
+ <p>item-c-i</p>
385
+ </item>
386
+ <item id="list0.c.list1.ii">
387
+ <num>(ii)</num>
388
+ <p>item-c-ii</p>
389
+ </item>
390
+ <item id="list0.c.list1.iii">
391
+ <num>(iii)</num>
392
+ <p>item-c-iii</p>
393
+ </item>
394
+ </blockList>
395
+ </item>
396
+ </blockList>
397
+ XML
398
+ )
399
+ end
400
+
401
+ # -------------------------------------------------------------------------
402
+
403
+ it 'should jump back up a level when finding (i) near (h)' do
404
+ doc = xml2doc(subsection(<<XML
405
+ <blockList id="section-10.1.lst0">
406
+ <item id="section-10.1.lst0.h">
407
+ <num>(h)</num>
408
+ <p>foo</p>
409
+ </item>
410
+ <item id="section-10.1.lst0.i">
411
+ <num>(i)</num>
412
+ <p>item-i</p>
413
+ </item>
414
+ <item id="section-10.1.lst0.ii">
415
+ <num>(ii)</num>
416
+ <p>item-ii</p>
417
+ </item>
418
+ <item id="section-10.1.lst0.i">
419
+ <num>(i)</num>
420
+ <p>item-i</p>
421
+ </item>
422
+ </blockList>
423
+ XML
424
+ ))
425
+
426
+ subject.nest_blocklists(doc)
427
+ doc.to_s.should == subsection(<<XML
428
+ <blockList id="section-10.1.lst0">
429
+ <item id="section-10.1.lst0.h">
430
+ <num>(h)</num>
431
+ <blockList id="section-10.1.lst0.h.list0">
432
+ <listIntroduction>foo</listIntroduction>
433
+ <item id="section-10.1.lst0.h.list0.i">
434
+ <num>(i)</num>
435
+ <p>item-i</p>
436
+ </item>
437
+ <item id="section-10.1.lst0.h.list0.ii">
438
+ <num>(ii)</num>
439
+ <p>item-ii</p>
440
+ </item>
441
+ </blockList>
442
+ </item>
443
+ <item id="section-10.1.lst0.i">
444
+ <num>(i)</num>
445
+ <p>item-i</p>
446
+ </item>
447
+ </blockList>
448
+ XML
449
+ )
450
+ end
451
+
452
+ # -------------------------------------------------------------------------
453
+
454
+ it 'should handle dotted numbers correctly' do
455
+ doc = xml2doc(subsection(<<XML
456
+ <blockList id="section-9.subsection-2.list2">
457
+ <item id="section-9.subsection-2.list2.9.2.1">
458
+ <num>9.2.1</num>
459
+ <p>is incapable of trading because of an illness, provided that:</p>
460
+ </item>
461
+ <item id="section-9.subsection-2.list2.9.2.1.1">
462
+ <num>9.2.1.1</num>
463
+ <p>proof from a medical practitioner is provided to the City which certifies that the permit-holder is unable to trade; and</p>
464
+ </item>
465
+ <item id="section-9.subsection-2.list2.9.2.1.2">
466
+ <num>9.2.1.2</num>
467
+ <p>the dependent or assistant is only permitted to replace the permit-</p>
468
+ </item>
469
+ </blockList>
470
+ XML
471
+ ))
472
+
473
+ subject.nest_blocklists(doc)
474
+ doc.to_s.should == subsection(<<XML
475
+ <blockList id="section-9.subsection-2.list2">
476
+ <item id="section-9.subsection-2.list2.9.2.1">
477
+ <num>9.2.1</num>
478
+ <blockList id="section-9.subsection-2.list2.9.2.1.list0">
479
+ <listIntroduction>is incapable of trading because of an illness, provided that:</listIntroduction>
480
+ <item id="section-9.subsection-2.list2.9.2.1.list0.9.2.1.1">
481
+ <num>9.2.1.1</num>
482
+ <p>proof from a medical practitioner is provided to the City which certifies that the permit-holder is unable to trade; and</p>
483
+ </item>
484
+ <item id="section-9.subsection-2.list2.9.2.1.list0.9.2.1.2">
485
+ <num>9.2.1.2</num>
486
+ <p>the dependent or assistant is only permitted to replace the permit-</p>
487
+ </item>
488
+ </blockList>
489
+ </item>
490
+ </blockList>
491
+ XML
492
+ )
493
+ end
494
+ end
495
+
496
+ describe '#guess_at_definitions' do
497
+ it 'should find definitions in p elements' do
498
+ doc = xml2doc(section(<<XML
499
+ <heading>Definitions</heading>
500
+ <subsection id="section-1.subsection-1">
501
+ <content>
502
+ <p>“authorised official” means any official of the Council who has been authorised by it to administer, implement and enforce the provisions of these By-laws;</p>
503
+ </content>
504
+ </subsection>
505
+ <subsection id="section-1.subsection-2">
506
+ <content>
507
+ <blockList id="section-1.subsection-2.list2">
508
+ <listIntroduction>
509
+ “Council” means – </listIntroduction>
510
+ <item id="section-1.subsection-2.list2.a">
511
+ <num>(a)</num>
512
+ <p>the Metropolitan Municipality of the City of Johannesburg established by Provincial Notice No. 6766 of 2000 dated 1 October 2000, as amended, exercising its legislative and executive authority through its municipal Council; or</p>
513
+ </item>
514
+ </blockList>
515
+ </content>
516
+ </subsection>
517
+ XML
518
+ ))
519
+
520
+ subject.guess_at_definitions(doc)
521
+ doc.to_s.should == section(<<XML
522
+ <heading>Definitions</heading>
523
+ <subsection id="def-term-authorised_official">
524
+ <content>
525
+ <p>"<def refersTo="#term-authorised_official">authorised official</def>" means any official of the Council who has been authorised by it to administer, implement and enforce the provisions of these By-laws;</p>
526
+ </content>
527
+ </subsection>
528
+ <subsection id="section-1.subsection-2">
529
+ <content>
530
+ <blockList id="def-term-Council">
531
+ <listIntroduction>"<def refersTo="#term-Council">Council</def>" means – </listIntroduction>
532
+ <item id="section-1.subsection-2.list2.a">
533
+ <num>(a)</num>
534
+ <p>the Metropolitan Municipality of the City of Johannesburg established by Provincial Notice No. 6766 of 2000 dated 1 October 2000, as amended, exercising its legislative and executive authority through its municipal Council; or</p>
535
+ </item>
536
+ </blockList>
537
+ </content>
538
+ </subsection>
539
+ XML
540
+ )
541
+ end
542
+ end
543
+ end