cisco_acl_intp 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +13 -0
  5. data/.travis.yml +3 -0
  6. data/.yardopts +4 -0
  7. data/Gemfile +19 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +132 -0
  10. data/Rakefile +78 -0
  11. data/acl_examples/err-acl.txt +49 -0
  12. data/acl_examples/named-ext-acl.txt +12 -0
  13. data/acl_examples/named-std-acl.txt +6 -0
  14. data/acl_examples/numd-acl.txt +21 -0
  15. data/cisco_acl_intp.gemspec +31 -0
  16. data/lib/cisco_acl_intp/ace.rb +432 -0
  17. data/lib/cisco_acl_intp/ace_ip.rb +136 -0
  18. data/lib/cisco_acl_intp/ace_other_qualifiers.rb +102 -0
  19. data/lib/cisco_acl_intp/ace_port.rb +146 -0
  20. data/lib/cisco_acl_intp/ace_proto.rb +319 -0
  21. data/lib/cisco_acl_intp/ace_srcdst.rb +114 -0
  22. data/lib/cisco_acl_intp/ace_tcp_flags.rb +65 -0
  23. data/lib/cisco_acl_intp/acl.rb +272 -0
  24. data/lib/cisco_acl_intp/acl_base.rb +111 -0
  25. data/lib/cisco_acl_intp/parser.rb +3509 -0
  26. data/lib/cisco_acl_intp/parser.ry +1397 -0
  27. data/lib/cisco_acl_intp/scanner.rb +176 -0
  28. data/lib/cisco_acl_intp/scanner_special_token_handler.rb +66 -0
  29. data/lib/cisco_acl_intp/version.rb +5 -0
  30. data/lib/cisco_acl_intp.rb +9 -0
  31. data/spec/cisco_acl_intp/ace_ip_spec.rb +111 -0
  32. data/spec/cisco_acl_intp/ace_other_qualifier_spec.rb +63 -0
  33. data/spec/cisco_acl_intp/ace_port_spec.rb +214 -0
  34. data/spec/cisco_acl_intp/ace_proto_spec.rb +200 -0
  35. data/spec/cisco_acl_intp/ace_spec.rb +605 -0
  36. data/spec/cisco_acl_intp/ace_srcdst_spec.rb +296 -0
  37. data/spec/cisco_acl_intp/ace_tcp_flags_spec.rb +38 -0
  38. data/spec/cisco_acl_intp/acl_spec.rb +523 -0
  39. data/spec/cisco_acl_intp/cisco_acl_intp_spec.rb +7 -0
  40. data/spec/cisco_acl_intp/parser_spec.rb +53 -0
  41. data/spec/cisco_acl_intp/scanner_spec.rb +122 -0
  42. data/spec/conf/extacl_objgrp_token_seq.yml +36 -0
  43. data/spec/conf/extacl_token_seq.yml +88 -0
  44. data/spec/conf/extended_acl.yml +226 -0
  45. data/spec/conf/scanner_spec_data.yml +120 -0
  46. data/spec/conf/single_tokens.yml +235 -0
  47. data/spec/conf/stdacl_token_seq.yml +8 -0
  48. data/spec/conf/tokens1.yml +158 -0
  49. data/spec/conf/tokens2.yml +206 -0
  50. data/spec/parser_fullfill_patterns.rb +145 -0
  51. data/spec/spec_helper.rb +54 -0
  52. data/tools/check_acl.rb +48 -0
  53. metadata +159 -0
@@ -0,0 +1,523 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe NamedExtAcl do
5
+ describe '#add_entry' do
6
+ before do
7
+ @acl = NamedExtAcl.new 'test-ext-acl'
8
+ end
9
+
10
+ it 'should be zero when initialized' do
11
+ @acl.size.should be_zero
12
+ end
13
+
14
+ it 'should be size 1 and matches aclstr when added a acl entry' do
15
+ ea = ExtendedAce.new(
16
+ action: 'permit',
17
+ protocol: 'udp',
18
+ src: {
19
+ ipaddr: '192.168.3.3',
20
+ wildcard: '0.0.0.127'
21
+ },
22
+ dst: {
23
+ ipaddr: '192.168.4.4',
24
+ wildcard: '0.0.0.255'
25
+ }
26
+ )
27
+ @acl.add_entry ea
28
+ @acl.size.should eq 1
29
+ aclstr = <<'EOL'
30
+ ip access-list extended test-ext-acl
31
+ permit udp 192.168.3.0 0.0.0.127 192.168.4.0 0.0.0.255
32
+ EOL
33
+ @acl.to_s.should be_aclstr(aclstr)
34
+ end
35
+ end
36
+
37
+ describe '#add_entry_by_params' do
38
+ before do
39
+ @acl = NamedExtAcl.new 'test-ext-acl2'
40
+ @acl.add_entry_by_params(
41
+ action: 'permit',
42
+ protocol: 'udp',
43
+ src: {
44
+ ipaddr: '192.168.3.3',
45
+ wildcard: '0.0.0.127'
46
+ },
47
+ dst: {
48
+ ipaddr: '192.168.4.4',
49
+ wildcard: '0.0.0.255'
50
+ }
51
+ )
52
+ @acl.add_entry_by_params(
53
+ action: 'deny',
54
+ protocol: 'tcp',
55
+ src: {
56
+ ipaddr: '192.168.3.3',
57
+ wildcard: '0.0.0.0'
58
+ },
59
+ dst: {
60
+ ipaddr: '192.168.4.4',
61
+ wildcard: '0.0.0.255',
62
+ operator: 'gt',
63
+ port: AceUdpProtoSpec.new(
64
+ number: 32_768
65
+ )
66
+ }
67
+ )
68
+ end
69
+
70
+ it 'should be size 2' do
71
+ @acl.size.should eq 2
72
+ end
73
+
74
+ it 'mutches aclstr' do
75
+ aclstr = <<'EOL'
76
+ ip access-list extended test-ext-acl2
77
+ permit udp 192.168.3.0 0.0.0.127 192.168.4.0 0.0.0.255
78
+ deny tcp host 192.168.3.3 192.168.4.0 0.0.0.255 gt 32768
79
+ EOL
80
+ @acl.to_s.should be_aclstr(aclstr)
81
+ end
82
+
83
+ it 'mutches aclstr with remark' do
84
+ rmk = RemarkAce.new ' this is remark!!'
85
+ @acl.add_entry rmk
86
+ aclstr = <<'EOL'
87
+ ip access-list extended test-ext-acl2
88
+ permit udp 192.168.3.0 0.0.0.127 192.168.4.0 0.0.0.255
89
+ deny tcp host 192.168.3.3 192.168.4.0 0.0.0.255 gt 32768
90
+ remark this is remark!!
91
+ EOL
92
+ @acl.to_s.should be_aclstr(aclstr)
93
+ end
94
+
95
+ end
96
+
97
+ describe '#search_ace' do
98
+ # for extended ace, it is same as named/numbered ace.
99
+ # so that, tests only named-extended-ace
100
+ # and omit numbered-extended-acl
101
+ before do
102
+ @acl = NamedExtAcl.new 'test-ext-acl2'
103
+ @acl.add_entry_by_params(
104
+ action: 'permit',
105
+ protocol: 'udp',
106
+ src: {
107
+ ipaddr: '192.168.3.3',
108
+ wildcard: '0.0.0.127'
109
+ },
110
+ dst: {
111
+ ipaddr: '192.168.4.4',
112
+ wildcard: '0.0.0.255'
113
+ }
114
+ )
115
+ @acl.add_entry_by_params(
116
+ action: 'deny',
117
+ protocol: 'tcp',
118
+ src: {
119
+ ipaddr: '192.168.10.3',
120
+ wildcard: '0.0.0.0'
121
+ },
122
+ dst: {
123
+ ipaddr: '192.168.4.4',
124
+ wildcard: '0.0.0.255',
125
+ operator: 'gt',
126
+ port: AceUdpProtoSpec.new(
127
+ number: 32_768
128
+ )
129
+ }
130
+ )
131
+ @acl.add_entry_by_params(
132
+ action: 'deny',
133
+ protocol: 'ip',
134
+ src: {
135
+ ipaddr: '0.0.0.0',
136
+ wildcard: '255.255.255.255'
137
+ },
138
+ dst: {
139
+ ipaddr: '10.0.0.0',
140
+ wildcard: '0.0.0.255'
141
+ }
142
+ )
143
+ end
144
+
145
+ it 'should be match 2nd entry' do
146
+ ace = @acl.search_ace(
147
+ protocol: 'tcp',
148
+ src_ip: '192.168.10.3',
149
+ src_port: 64_332,
150
+ dst_ip: '192.168.4.5',
151
+ dst_port: 32_889
152
+ )
153
+ ace.to_s.should be_aclstr(
154
+ 'deny tcp host 192.168.10.3 192.168.4.0 0.0.0.255 gt 32768'
155
+ )
156
+ end
157
+
158
+ it 'should be last entry' do
159
+ ace = @acl.search_ace(
160
+ protocol: 'udp',
161
+ src_ip: '192.168.10.3',
162
+ src_port: 64_332,
163
+ dst_ip: '10.0.0.3',
164
+ dst_port: 33_890
165
+ )
166
+ ace.to_s.should be_aclstr('deny ip any 10.0.0.0 0.0.0.255')
167
+ end
168
+
169
+ it 'should be nil if not found match entry' do
170
+ @acl.search_ace(
171
+ protocol: 'udp',
172
+ src_ip: '192.168.10.3',
173
+ src_port: 62_223,
174
+ dst_ip: '11.0.0.3',
175
+ dst_port: 33_333
176
+ ).should be_nil
177
+ end
178
+ end
179
+ end
180
+
181
+ describe NumberedExtAcl do
182
+ describe '#add_entry' do
183
+ before do
184
+ @acl = NumberedExtAcl.new 102
185
+ end
186
+
187
+ it 'should be zero when initialized' do
188
+ @acl.size.should be_zero
189
+ end
190
+
191
+ it 'should be size 1 and matches aclstr when added a acl entry' do
192
+ ea = ExtendedAce.new(
193
+ action: 'permit',
194
+ protocol: 'udp',
195
+ src: {
196
+ ipaddr: '192.168.3.3',
197
+ wildcard: '0.0.0.127'
198
+ },
199
+ dst: {
200
+ ipaddr: '192.168.4.4',
201
+ wildcard: '0.0.0.255'
202
+ }
203
+ )
204
+ @acl.add_entry ea
205
+ @acl.size.should eq 1
206
+ aclstr = <<'EOL'
207
+ access-list 102 permit udp 192.168.3.0 0.0.0.127 192.168.4.0 0.0.0.255
208
+ EOL
209
+ @acl.to_s.should be_aclstr(aclstr)
210
+ end
211
+ end
212
+
213
+ describe '#add_entry_by_params' do
214
+ before do
215
+ @acl = NumberedExtAcl.new 104
216
+ @acl.add_entry_by_params(
217
+ action: 'permit',
218
+ protocol: 'udp',
219
+ src: {
220
+ ipaddr: '192.168.3.3',
221
+ wildcard: '0.0.0.127'
222
+ },
223
+ dst: {
224
+ ipaddr: '192.168.4.4',
225
+ wildcard: '0.0.0.255'
226
+ }
227
+ )
228
+ @acl.add_entry_by_params(
229
+ action: 'deny',
230
+ protocol: 'tcp',
231
+ src: {
232
+ ipaddr: '192.168.3.3',
233
+ wildcard: '0.0.0.0'
234
+ },
235
+ dst: {
236
+ ipaddr: '192.168.4.4',
237
+ wildcard: '0.0.0.255',
238
+ operator: 'gt',
239
+ port: AceUdpProtoSpec.new(
240
+ number: 32_768
241
+ )
242
+ }
243
+ )
244
+ end
245
+
246
+ it 'should be size 2' do
247
+ @acl.size.should eq 2
248
+ end
249
+
250
+ it 'mutches aclstr' do
251
+ aclstr = <<'EOL'
252
+ access-list 104 permit udp 192.168.3.0 0.0.0.127 192.168.4.0 0.0.0.255
253
+ access-list 104 deny tcp host 192.168.3.3 192.168.4.0 0.0.0.255 gt 32768
254
+ EOL
255
+ @acl.to_s.should be_aclstr(aclstr)
256
+ end
257
+
258
+ it 'mutches aclstr with remark' do
259
+ rmk = RemarkAce.new ' this is remark!!'
260
+ @acl.add_entry rmk
261
+ aclstr = <<'EOL'
262
+ access-list 104 permit udp 192.168.3.0 0.0.0.127 192.168.4.0 0.0.0.255
263
+ access-list 104 deny tcp host 192.168.3.3 192.168.4.0 0.0.0.255 gt 32768
264
+ access-list 104 remark this is remark!!
265
+ EOL
266
+ @acl.to_s.should be_aclstr(aclstr)
267
+ end
268
+ end
269
+ end
270
+
271
+ describe NamedStdAcl do
272
+ describe '#add_entry' do
273
+ before do
274
+ @acl = NamedStdAcl.new 'test-std-acl'
275
+ end
276
+
277
+ it 'should be zero when initialized' do
278
+ @acl.size.should be_zero
279
+ end
280
+
281
+ it 'should be size 1 and matches aclstr when added a acl entry' do
282
+ sa = StandardAce.new(
283
+ action: 'permit',
284
+ src: {
285
+ ipaddr: '192.168.3.3',
286
+ wildcard: '0.0.0.127'
287
+ }
288
+ )
289
+ @acl.add_entry sa
290
+ @acl.size.should eq 1
291
+ aclstr = <<'EOL'
292
+ ip access-list standard test-std-acl
293
+ permit 192.168.3.0 0.0.0.127
294
+ EOL
295
+ @acl.to_s.should be_aclstr(aclstr)
296
+ end
297
+ end
298
+
299
+ describe '#add_entry_by_params' do
300
+ before do
301
+ @acl = NamedStdAcl.new 'test-std-acl2'
302
+ @acl.add_entry_by_params(
303
+ action: 'permit',
304
+ src: {
305
+ ipaddr: '192.168.3.3',
306
+ wildcard: '0.0.0.127'
307
+ }
308
+ )
309
+ @acl.add_entry_by_params(
310
+ action: 'deny',
311
+ src: {
312
+ ipaddr: '192.168.4.4',
313
+ wildcard: '0.0.0.255'
314
+ }
315
+ )
316
+ end
317
+
318
+ it 'should be size 2' do
319
+ @acl.size.should eq 2
320
+ end
321
+
322
+ it 'mutches aclstr' do
323
+ aclstr = <<'EOL'
324
+ ip access-list standard test-std-acl2
325
+ permit 192.168.3.0 0.0.0.127
326
+ deny 192.168.4.0 0.0.0.255
327
+ EOL
328
+ @acl.to_s.should be_aclstr(aclstr)
329
+ end
330
+
331
+ it 'mutches aclstr with remark' do
332
+ rmk = RemarkAce.new ' this is remark!!'
333
+ @acl.add_entry rmk
334
+ aclstr = <<'EOL'
335
+ ip access-list standard test-std-acl2
336
+ permit 192.168.3.0 0.0.0.127
337
+ deny 192.168.4.0 0.0.0.255
338
+ remark this is remark!!
339
+ EOL
340
+ @acl.to_s.should be_aclstr(aclstr)
341
+ end
342
+ end
343
+
344
+ describe '#search_ace' do
345
+ # for standard ace, it is same as named/numbered ace.
346
+ # so that, tests only named-standard-ace
347
+ # and omit numbered-standard-acl
348
+ before do
349
+ @acl = NamedStdAcl.new 'test-stdacl3'
350
+ @acl.add_entry_by_params(
351
+ action: 'permit',
352
+ src: {
353
+ ipaddr: '192.168.3.3',
354
+ wildcard: '0.0.0.127'
355
+ }
356
+ )
357
+ @acl.add_entry_by_params(
358
+ action: 'deny',
359
+ src: {
360
+ ipaddr: '192.168.10.3',
361
+ wildcard: '0.0.0.0'
362
+ }
363
+ )
364
+ @acl.add_entry_by_params(
365
+ action: 'deny',
366
+ src: {
367
+ ipaddr: '10.0.0.0',
368
+ wildcard: '0.0.0.255'
369
+ }
370
+ )
371
+ end
372
+
373
+ it 'should be match 2nd entry' do
374
+ ace = @acl.search_ace(
375
+ src_ip: '192.168.10.3',
376
+ src_port: 64_332
377
+ )
378
+ ace.to_s.should be_aclstr('deny host 192.168.10.3')
379
+ end
380
+
381
+ it 'should be last entry' do
382
+ ace = @acl.search_ace(
383
+ src_ip: '10.0.0.3',
384
+ src_port: 33_890
385
+ )
386
+ ace.to_s.should be_aclstr('deny 10.0.0.0 0.0.0.255')
387
+ end
388
+
389
+ it 'should be nil if not found match entry' do
390
+ @acl.search_ace(
391
+ protocol: 'udp',
392
+ src_ip: '11.0.0.3',
393
+ src_port: 33_333
394
+ ).should be_nil
395
+ end
396
+
397
+ end
398
+
399
+ end
400
+
401
+ describe NumberedStdAcl do
402
+ describe '#add_entry' do
403
+ before do
404
+ @acl = NumberedStdAcl.new 10
405
+ end
406
+
407
+ it 'should be zero when initialized' do
408
+ @acl.size.should be_zero
409
+ end
410
+
411
+ it 'should be size 1 and matches aclstr when added a acl entry' do
412
+ sa = StandardAce.new(
413
+ action: 'permit',
414
+ src: {
415
+ ipaddr: '192.168.3.3',
416
+ wildcard: '0.0.0.127'
417
+ }
418
+ )
419
+ @acl.add_entry sa
420
+ @acl.size.should eq 1
421
+ aclstr = <<'EOL'
422
+ access-list 10 permit 192.168.3.0 0.0.0.127
423
+ EOL
424
+ @acl.to_s.should be_aclstr(aclstr)
425
+ end
426
+ end
427
+
428
+ describe '#add_entry_by_params' do
429
+ before do
430
+ @acl = NumberedStdAcl.new 14
431
+ @acl.add_entry_by_params(
432
+ action: 'permit',
433
+ src: {
434
+ ipaddr: '192.168.3.3',
435
+ wildcard: '0.0.0.127'
436
+ }
437
+ )
438
+ @acl.add_entry_by_params(
439
+ action: 'deny',
440
+ src: {
441
+ ipaddr: '192.168.4.4',
442
+ wildcard: '0.0.0.255'
443
+ }
444
+ )
445
+ end
446
+
447
+ it 'should be size 2' do
448
+ @acl.size.should eq 2
449
+ end
450
+
451
+ it 'mutches aclstr' do
452
+ aclstr = <<'EOL'
453
+ access-list 14 permit 192.168.3.0 0.0.0.127
454
+ access-list 14 deny 192.168.4.0 0.0.0.255
455
+ EOL
456
+ @acl.to_s.should be_aclstr(aclstr)
457
+ end
458
+
459
+ it 'mutches aclstr with remark' do
460
+ rmk = RemarkAce.new ' this is remark!!'
461
+ @acl.add_entry rmk
462
+ aclstr = <<'EOL'
463
+ access-list 14 permit 192.168.3.0 0.0.0.127
464
+ access-list 14 deny 192.168.4.0 0.0.0.255
465
+ access-list 14 remark this is remark!!
466
+ EOL
467
+ @acl.to_s.should be_aclstr(aclstr)
468
+ end
469
+ end
470
+
471
+ context 'list operations' do
472
+ before do
473
+ @acl = NumberedStdAcl.new 15
474
+ @acl.add_entry RemarkAce.new('entry 1')
475
+ @acl.add_entry RemarkAce.new('entry 2')
476
+ @acl.add_entry RemarkAce.new('entry 3')
477
+ @acl.add_entry RemarkAce.new('entry 4')
478
+ end
479
+
480
+ describe '#renumber' do
481
+ it 'should has seq number by add_entry' do
482
+ @acl.renumber
483
+ @acl.reduce(10) do |num, each|
484
+ each.seq_number.should eq num
485
+ num + 10
486
+ end
487
+ end
488
+ end
489
+
490
+ describe '#sort' do
491
+ it 'should be sorted by seq number' do
492
+ @acl.renumber # initialize seq number
493
+
494
+ last_ace = @acl.pop
495
+ last_ace.seq_number = 15
496
+ @acl.add_entry last_ace
497
+ acl_new = @acl.dup_with_list(@acl.sort)
498
+
499
+ aclstr = <<'EOL'
500
+ access-list 15 remark entry 1
501
+ access-list 15 remark entry 2
502
+ access-list 15 remark entry 3
503
+ access-list 15 remark entry 4
504
+ EOL
505
+ aclstr_new = <<'EOL'
506
+ access-list 15 remark entry 1
507
+ access-list 15 remark entry 4
508
+ access-list 15 remark entry 2
509
+ access-list 15 remark entry 3
510
+ EOL
511
+ @acl.name.should eq acl_new.name
512
+ @acl.acl_type.should eq acl_new.acl_type
513
+ @acl.to_s.should be_aclstr(aclstr)
514
+ acl_new.to_s.should be_aclstr(aclstr_new)
515
+ end
516
+ end
517
+ end
518
+ end
519
+ ### Local variables:
520
+ ### mode: Ruby
521
+ ### coding: utf-8-unix
522
+ ### indent-tabs-mode: nil
523
+ ### End:
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe CiscoAclIntp do
4
+ it 'should have a version number' do
5
+ CiscoAclIntp::VERSION.should_not be_nil
6
+ end
7
+ end
@@ -0,0 +1,53 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+ require 'yaml'
4
+
5
+ describe 'Parser' do
6
+ describe '#parse_file' do
7
+ before do
8
+ @parser = CiscoAclIntp::Parser.new(color: false)
9
+ end
10
+
11
+ # test data file
12
+ data_files = [
13
+ 'extended_acl.yml',
14
+ # 'object_group.yml'
15
+ ]
16
+
17
+ data_files.each do |each_file|
18
+ tests = YAML.load_file(_spec_conf_dir(each_file))
19
+ # puts YAML.dump data
20
+
21
+ tests.each do |each_test|
22
+ # filename
23
+ acl_file_base = [each_test[:symbol], '.acl.yml'].join
24
+ acl_file = _spec_data_dir(acl_file_base)
25
+
26
+ # write acl to file
27
+ File.open(acl_file, 'w') do |file|
28
+ file.puts each_test[:acl]
29
+ end
30
+
31
+ if each_test[:correct]
32
+ it "should be parsed #{acl_file} with no error" do
33
+ @parser.parse_file(acl_file)
34
+ @parser.contains_error?.should be_false
35
+ end
36
+ else
37
+ it "should be parsed #{acl_file} with error" do
38
+ @parser.parse_file(acl_file)
39
+ @parser.contains_error?.should be_true
40
+ end
41
+ end
42
+ end
43
+
44
+ end
45
+
46
+ end # parse_file
47
+ end # Parser
48
+
49
+ ### Local variables:
50
+ ### mode: Ruby
51
+ ### coding: utf-8-unix
52
+ ### indent-tabs-mode: nil
53
+ ### End:
@@ -0,0 +1,122 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+ require 'yaml'
4
+
5
+ describe 'Scanner' do
6
+ describe '#scan_line' do
7
+ before do
8
+ @s = Scanner.new
9
+ end
10
+
11
+ it 'should be parsed correct tokens as 1-line acl' do
12
+ acl = <<'EOL'
13
+ ip access-list extended FA8-OUT
14
+ deny udp any any eq bootpc
15
+ permit ip any any
16
+ EOL
17
+ @s.scan_line(acl).should == [
18
+ [:NAMED_ACL, 'ip access-list'],
19
+ %w[extended extended],
20
+ [:STRING, 'FA8-OUT'],
21
+ [:EOS, nil],
22
+ %w[deny deny],
23
+ %w[udp udp],
24
+ %w[any any],
25
+ %w[any any],
26
+ %w[eq eq],
27
+ %w[bootpc bootpc],
28
+ [:EOS, nil],
29
+ %w[permit permit],
30
+ %w[ip ip],
31
+ %w[any any],
32
+ %w[any any],
33
+ [:EOS, nil],
34
+ [:EOS, nil], # last, empty line
35
+ [false, 'EOF']
36
+ ]
37
+ end
38
+
39
+ tokens = YAML.load_file(_spec_conf_dir('single_tokens.yml'))
40
+ tokens.each do |each|
41
+ # run test
42
+ it "should be parsed single token: #{each}" do
43
+ @s.scan_line(each).should
44
+ eq [
45
+ [each, each],
46
+ [:EOS, nil],
47
+ [:EOS, nil],
48
+ [false, 'EOF']
49
+ ]
50
+ end
51
+ end
52
+ end # scan_line
53
+
54
+ describe '#scan_file' do
55
+ before do
56
+ @s = Scanner.new
57
+ end
58
+
59
+ tests = YAML.load_file(_spec_conf_dir('scanner_spec_data.yml'))
60
+
61
+ # generate test data (yaml file)
62
+ tests.each do |each_test|
63
+ tokens = []
64
+ lines = each_test[:test_data]
65
+
66
+ # filename
67
+ acl_file_base = [each_test[:test_symbol], '.acl.yml'].join
68
+ acl_file = _spec_data_dir(acl_file_base)
69
+
70
+ # generate access list string data file
71
+ # (input for scanner)
72
+ File.open(acl_file, 'w') do |file|
73
+ lines.each do |each_line|
74
+ file.puts each_line[:line]
75
+
76
+ # make tokens data
77
+ if each_line[:tokens]
78
+ each_line[:tokens].each do |each_token|
79
+ case each_token
80
+ when Array
81
+ (symbstr, val) = each_token
82
+ tokens.push [symbstr.intern, val] # symbolize
83
+ when String
84
+ tokens.push [each_token, each_token]
85
+ end
86
+ end
87
+ tokens.push [:EOS, nil] # End of String
88
+ end
89
+ end
90
+ tokens.push [false, 'EOF'] # last token (End of File)
91
+ end
92
+
93
+ # filename
94
+ token_file_base = [each_test[:test_symbol], '.token.yml'].join
95
+ token_file = _spec_data_dir(token_file_base)
96
+
97
+ # generate access list token data file
98
+ # (expected output of scanner)
99
+ File.open(token_file, 'w') do |file|
100
+ YAML.dump(tokens, file)
101
+ end
102
+
103
+ # run test
104
+ it "should be parsed #{File.basename(acl_file)} as \
105
+ #{File.basename(token_file)} in tests of \
106
+ #{each_test[:test_description]}" do
107
+ tokens = YAML.load_file(token_file)
108
+ File.open(acl_file) do |file|
109
+ @s.scan_file(file).should eq tokens
110
+ end
111
+ end
112
+ end # tests.each
113
+
114
+ end # scan_file
115
+
116
+ end # describe Scanner
117
+
118
+ ### Local variables:
119
+ ### mode: Ruby
120
+ ### coding: utf-8-unix
121
+ ### indent-tabs-mode: nil
122
+ ### End: