slaw 0.1.2

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.
@@ -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