casty 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,1196 @@
1
+ ######################################################################
2
+ #
3
+ # Tests for Node core functionality.
4
+ #
5
+ ######################################################################
6
+
7
+ require 'test_helper'
8
+
9
+ Chain = C::NodeChain
10
+
11
+ #
12
+ # Some Node classes.
13
+ #
14
+ class X < C::Node
15
+ child :a
16
+ initializer :a
17
+ end
18
+ class Y < C::Node
19
+ child :a
20
+ child :b
21
+ initializer :a, :b
22
+ end
23
+ class Z < C::Node
24
+ child :a
25
+ field :b
26
+ child :c
27
+ field :d
28
+ child :e
29
+ initializer :a, :b, :c, :d, :e
30
+ end
31
+ class W < C::Node
32
+ field :a
33
+ field :b, 0
34
+ initializer :a, :b
35
+ end
36
+ class V < C::Node
37
+ child :a, lambda{C::NodeArray.new}
38
+ initializer :a
39
+ end
40
+
41
+ class NodeInitializeTest < Test::Unit::TestCase
42
+
43
+ # ------------------------------------------------------------------
44
+ # initialize
45
+ # ------------------------------------------------------------------
46
+
47
+ def test_initialize_w
48
+ w = W.new
49
+ assert_nil(w.a)
50
+ assert_same(0, w.b)
51
+
52
+ w = W.new(1, true)
53
+ assert_same(1, w.a)
54
+ assert_same(true, w.b)
55
+
56
+ w = W.new(1, :b => true)
57
+ assert_same(1, w.a)
58
+ assert_same(true, w.b)
59
+
60
+ w = W.new(:a => 1, :b => true)
61
+ assert_same(1, w.a)
62
+ assert_same(true, w.b)
63
+ end
64
+
65
+ def test_initialize_v
66
+ v = V.new
67
+ assert_same_list([], v.a)
68
+ assert_same(C::NodeArray, v.a.class)
69
+
70
+ v = V.new(C::NodeChain[])
71
+ assert_same_list([], v.a)
72
+ assert_same(C::NodeChain, v.a.class)
73
+ end
74
+
75
+ def test_initialize_attached
76
+ x1, x2 = 2.of{X.new}
77
+ list = C::NodeArray[x1, x2]
78
+ z = Z.new(x1, x2)
79
+ assert_same_list([x1, x2], list)
80
+ assert_copy(x1, z.a)
81
+ assert_same(x2, z.b)
82
+ end
83
+
84
+ # ------------------------------------------------------------------
85
+ # Node.new_at
86
+ # ------------------------------------------------------------------
87
+
88
+ def test_new_at
89
+ pos = C::Node::Pos.new('somefile', 5, 10)
90
+ xa = X.new
91
+ x = X.new_at(pos, xa)
92
+ assert_same(pos, x.pos)
93
+ assert_same(xa, x.a)
94
+ end
95
+ end
96
+
97
+ class NodeEqualTest < Test::Unit::TestCase
98
+ def str
99
+ "(struct s){.a = 1, [2] = {3, 4}, .b [5] = 6, 7}"
100
+ end
101
+ def node
102
+ ma = C::Member.new('a')
103
+ mb = C::Member.new('b')
104
+ one = C::IntLiteral.new(1)
105
+ two = C::IntLiteral.new(2)
106
+ three = C::IntLiteral.new(3)
107
+ four = C::IntLiteral.new(4)
108
+ five = C::IntLiteral.new(5)
109
+ six = C::IntLiteral.new(6)
110
+ seven = C::IntLiteral.new(7)
111
+
112
+ mi0 = C::MemberInit.new(Chain[ma], one)
113
+ mi10 = C::MemberInit.new(nil, three)
114
+ mi11 = C::MemberInit.new(nil, four)
115
+ mi1 = C::MemberInit.new(Chain[two],
116
+ C::CompoundLiteral.new(nil, Chain[mi10, mi11]))
117
+ mi2 = C::MemberInit.new(Chain[mb, five], six)
118
+ mi3 = C::MemberInit.new(nil, seven)
119
+
120
+ c = C::CompoundLiteral.new(C::Struct.new('s'),
121
+ Chain[mi0, mi1, mi2, mi3])
122
+ return c
123
+ end
124
+
125
+ # ------------------------------------------------------------------
126
+ # ==, eql?
127
+ # ------------------------------------------------------------------
128
+
129
+ def test_eq
130
+ # copy should be equal
131
+ assert_equal(node, node)
132
+ assert(node.eql?(node))
133
+
134
+ # change any one field and it should be not_equal
135
+ n = node
136
+ n.type = nil
137
+ assert_not_equal(node, n)
138
+ assert(!node.eql?(n))
139
+
140
+ n = node
141
+ n.member_inits[0].member[0] = C::Member.new('c')
142
+ assert_not_equal(node, n)
143
+ assert(!node.eql?(n))
144
+ copy = node.dup
145
+
146
+ n = node
147
+ n.member_inits[2].member[1] = C::IntLiteral.new(8)
148
+ assert_not_equal(node, n)
149
+ assert(!node.eql?(n))
150
+
151
+ # add a member's init and it should be not_equal
152
+ n = node
153
+ n.member_inits[3].init = C::IntLiteral.new(9)
154
+ assert_not_equal(node, n)
155
+ assert(!node.eql?(n))
156
+
157
+ # change a member's init and it should be not_equal
158
+ n = node
159
+ n.member_inits[0].init = C::IntLiteral.new(10)
160
+ assert_not_equal(node, n)
161
+ assert(!node.eql?(n))
162
+
163
+ # add a member specifier and it should be not_equal
164
+ n = node
165
+ n.member_inits[3].member = Chain[C::Member.new('d')]
166
+ assert_not_equal(node, n)
167
+ assert(!node.eql?(n))
168
+
169
+ # pop a member and it should be not_equal
170
+ n = node
171
+ n.member_inits.pop
172
+ assert_not_equal(node, n)
173
+ assert(!node.eql?(n))
174
+
175
+ # assign a field a copy of what's there and it should still be
176
+ # equal
177
+ n = node
178
+ n.member_inits[0].member[0] = C::Member.new('a')
179
+ assert_equal(node, n)
180
+ assert(node.eql?(n))
181
+
182
+ n = node
183
+ n.member_inits[0].init = C::IntLiteral.new(1)
184
+ assert_equal(node, n)
185
+ assert(node.eql?(n))
186
+ end
187
+
188
+ # ------------------------------------------------------------------
189
+ # hash
190
+ # ------------------------------------------------------------------
191
+
192
+ def test_hash
193
+ # copy should be equal
194
+ assert_equal(node.hash, node.hash)
195
+
196
+ # should be equal after assigning to a field a copy of what's
197
+ # there
198
+ n = node
199
+ n.member_inits[0].member[0] = C::Member.new('a')
200
+ assert_equal(node.hash, n.hash)
201
+
202
+ n = node
203
+ n.member_inits[0].init = C::IntLiteral.new(1)
204
+ assert_equal(node.hash, n.hash)
205
+ end
206
+ end
207
+
208
+ class NodeCopyTest < Test::Unit::TestCase
209
+ def setup
210
+ # (struct s){.a = 1, [2] = {3, 4}, .b [5] = 6, 7}
211
+
212
+ @c_t_n = 's'
213
+ @c_t = C::Struct.new(@c_t_n)
214
+
215
+ @c_mis0_m0_n = 'a'
216
+ @c_mis0_m0 = C::Member.new(@c_mis0_m0_n)
217
+ @c_mis0_m = Chain[@c_mis0_m0]
218
+ @c_mis0_i = C::IntLiteral.new(1)
219
+ @c_mis0 = C::MemberInit.new(@c_mis0_m, @c_mis0_i)
220
+
221
+ @c_mis1_m0 = C::IntLiteral.new(2)
222
+ @c_mis1_m = Chain[@c_mis1_m0]
223
+ @c_mis1_i_mis0_i = C::IntLiteral.new(3)
224
+ @c_mis1_i_mis0 = C::MemberInit.new(nil, @c_mis1_i_mis0_i)
225
+ @c_mis1_i_mis1_i = C::IntLiteral.new(4)
226
+ @c_mis1_i_mis1 = C::MemberInit.new(nil, @c_mis1_i_mis1_i)
227
+ @c_mis1_i_mis = Chain[@c_mis1_i_mis0, @c_mis1_i_mis1]
228
+ @c_mis1_i = C::CompoundLiteral.new(nil, @c_mis1_i_mis)
229
+ @c_mis1 = C::MemberInit.new(@c_mis1_m, @c_mis1_i)
230
+
231
+ @c_mis2_m0_n
232
+ @c_mis2_m0 = C::Member.new(@c_mis2_m0_n)
233
+ @c_mis2_m1 = C::IntLiteral.new(5)
234
+ @c_mis2_m = Chain[@c_mis2_m0, @c_mis2_m1]
235
+ @c_mis2_i = C::IntLiteral.new(6)
236
+ @c_mis2 = C::MemberInit.new(@c_mis2_m, @c_mis2_i)
237
+
238
+ @c_mis3_i = C::IntLiteral.new(7)
239
+ @c_mis3 = C::MemberInit.new(nil, @c_mis3_i)
240
+ @c_mis = Chain[@c_mis0, @c_mis1, @c_mis2, @c_mis3]
241
+
242
+ @c = C::CompoundLiteral.new(@c_t, @c_mis)
243
+
244
+ class << @c
245
+ def new_method
246
+ 100
247
+ end
248
+ end
249
+ class << @c_mis1_i_mis0
250
+ def new_method
251
+ 100
252
+ end
253
+ end
254
+
255
+ @d = c.dup
256
+ @e = c.clone
257
+ end
258
+ attr_accessor :c, :d, :e
259
+
260
+ # ------------------------------------------------------------------
261
+ # dup, clone
262
+ # ------------------------------------------------------------------
263
+
264
+ def check_node value
265
+ cres = yield(c)
266
+ dres = yield(d)
267
+ eres = yield(e)
268
+ assert_same(value, cres)
269
+ if value.is_a? C::Node
270
+ assert_copy(value, dres)
271
+ assert_copy(value, eres)
272
+ else
273
+ assert_same(value, dres)
274
+ assert_same(value, eres)
275
+ end
276
+ assert_raise(NoMethodError){dres.new_method}
277
+ case value.object_id
278
+ when @c.object_id, @c_mis1_i_mis0.object_id
279
+ assert_same(100, eres.new_method)
280
+ else
281
+ assert_raise(NoMethodError){eres.new_method}
282
+ end
283
+ end
284
+
285
+ def test_copy
286
+ # each element should be equal, but not the same, except for
287
+ # immediate values
288
+ #
289
+ # (struct s){.a = 1, [2] = {3, 4}, .b [5] = 6, 7}
290
+ assert_tree(c)
291
+ assert_tree(d)
292
+ assert_tree(e)
293
+ check_node(@c ){|x| x}
294
+ check_node(@c_t ){|x| x.type}
295
+ check_node(@c_t_n ){|x| x.type.name}
296
+ check_node(nil ){|x| x.type.members}
297
+ check_node(@c_mis ){|x| x.member_inits}
298
+ check_node(@c_mis0 ){|x| x.member_inits[0]}
299
+ check_node(@c_mis0_m ){|x| x.member_inits[0].member}
300
+ check_node(@c_mis0_m0 ){|x| x.member_inits[0].member[0]}
301
+ check_node(@c_mis0_m0_n ){|x| x.member_inits[0].member[0].name}
302
+ check_node(@c_mis0_i ){|x| x.member_inits[0].init}
303
+ check_node(1 ){|x| x.member_inits[0].init.val}
304
+ check_node(@c_mis1 ){|x| x.member_inits[1]}
305
+ check_node(@c_mis1_m ){|x| x.member_inits[1].member}
306
+ check_node(@c_mis1_m0 ){|x| x.member_inits[1].member[0]}
307
+ check_node(2 ){|x| x.member_inits[1].member[0].val}
308
+ check_node(@c_mis1_i ){|x| x.member_inits[1].init}
309
+ check_node(nil ){|x| x.member_inits[1].init.type}
310
+ check_node(@c_mis1_i_mis ){|x| x.member_inits[1].init.member_inits}
311
+ check_node(@c_mis1_i_mis0 ){|x| x.member_inits[1].init.member_inits[0]}
312
+ check_node(nil ){|x| x.member_inits[1].init.member_inits[0].member}
313
+ check_node(@c_mis1_i_mis0_i){|x| x.member_inits[1].init.member_inits[0].init}
314
+ check_node(3 ){|x| x.member_inits[1].init.member_inits[0].init.val}
315
+ check_node(@c_mis1_i_mis1 ){|x| x.member_inits[1].init.member_inits[1]}
316
+ check_node(nil ){|x| x.member_inits[1].init.member_inits[1].member}
317
+ check_node(@c_mis1_i_mis1_i){|x| x.member_inits[1].init.member_inits[1].init}
318
+ check_node(4 ){|x| x.member_inits[1].init.member_inits[1].init.val}
319
+ check_node(@c_mis2 ){|x| x.member_inits[2]}
320
+ check_node(@c_mis2_m ){|x| x.member_inits[2].member}
321
+ check_node(@c_mis2_m0 ){|x| x.member_inits[2].member[0]}
322
+ check_node(@c_mis2_m0_n ){|x| x.member_inits[2].member[0].name}
323
+ check_node(@c_mis2_m1 ){|x| x.member_inits[2].member[1]}
324
+ check_node(5 ){|x| x.member_inits[2].member[1].val}
325
+ check_node(@c_mis2_i ){|x| x.member_inits[2].init}
326
+ check_node(6 ){|x| x.member_inits[2].init.val}
327
+ check_node(@c_mis3 ){|x| x.member_inits[3]}
328
+ check_node(nil ){|x| x.member_inits[3].member}
329
+ check_node(@c_mis3_i ){|x| x.member_inits[3].init}
330
+ check_node(7 ){|x| x.member_inits[3].init.val}
331
+ end
332
+ end
333
+
334
+ class NodeWalkTest < Test::Unit::TestCase
335
+ #
336
+ # Collect and return the args yielded to `node.send(method)' as an
337
+ # Array, each element of which is an array of args yielded.
338
+ #
339
+ # Also, assert that the return value of the method is `exp'.
340
+ #
341
+ def yields(method, node, exp)
342
+ ret = []
343
+ out = node.send(method) do |*args|
344
+ ret << args
345
+ yield *args if block_given?
346
+ end
347
+ assert_same(exp, out)
348
+ return ret
349
+ end
350
+
351
+ #
352
+ # Assert exp and out are equal, where elements are compared with
353
+ # Array#same_list?. That is, exp[i].same_list?(out[i]) for all i.
354
+ #
355
+ def assert_equal_yields(exp, out)
356
+ if exp.zip(out).all?{|a,b| a.same_list?(b)}
357
+ assert(true)
358
+ else
359
+ flunk("walk not equal: #{walk_str(out)} (expected #{walk_str(exp)})")
360
+ end
361
+ end
362
+ def walk_str(walk)
363
+ walk.is_a? ::Array or
364
+ raise "walk_str: expected ::Array"
365
+ if walk.empty?
366
+ return '[]'
367
+ else
368
+ s = StringIO.new
369
+ s.puts '['
370
+ walk.each do |args|
371
+ args.map! do |arg|
372
+ if arg.is_a? C::Node
373
+ argstr = arg.class.name << ' (' << arg.object_id.to_s <<
374
+ "): " << arg.to_s
375
+ else
376
+ argstr = arg.inspect
377
+ end
378
+ if argstr.length > 50
379
+ argstr[48..-1] = '...'
380
+ end
381
+ argstr
382
+ end
383
+ s.puts " [#{args.join(', ')}]"
384
+ end
385
+ s.puts ']'
386
+ return s.string
387
+ end
388
+ end
389
+
390
+ # ------------------------------------------------------------------
391
+ # depth_first, reverse_depth_first
392
+ # ------------------------------------------------------------------
393
+
394
+ def check_depth_firsts(node, exp)
395
+ # depth_first
396
+ out = yields(:depth_first, node, node)
397
+ assert_equal_yields exp, out
398
+
399
+ # reverse_depth_first
400
+ exp = exp.reverse.map! do |ev, node|
401
+ if ev == :ascending
402
+ [:descending, node]
403
+ else
404
+ [:ascending, node]
405
+ end
406
+ end
407
+ out = yields(:reverse_depth_first, node, node)
408
+ assert_equal_yields exp, out
409
+ end
410
+
411
+ def test_depth_first
412
+ # empty node
413
+ d = C::Int.new
414
+ d.longness = 1
415
+ check_depth_firsts(d,
416
+ [[:descending, d], [:ascending, d]])
417
+
418
+ # one-storey -- populate both the list child and nonlist child
419
+ d = C::Declaration.new(C::Int.new)
420
+ d.declarators << C::Declarator.new
421
+ d.declarators[0].name = 'one'
422
+ d.declarators << C::Declarator.new
423
+ d.declarators[1].name = 'two'
424
+ check_depth_firsts(d,
425
+ [
426
+ [:descending, d],
427
+ [:descending, d.type], [:ascending, d.type],
428
+ [:descending, d.declarators],
429
+ [:descending, d.declarators[0]], [:ascending, d.declarators[0]],
430
+ [:descending, d.declarators[1]], [:ascending, d.declarators[1]],
431
+ [:ascending, d.declarators],
432
+ [:ascending, d]
433
+ ])
434
+
435
+ # multi-layer
436
+ d.declarators[0].indirect_type = C::Function.new
437
+ d.declarators[0].indirect_type.params = Chain[]
438
+ d.declarators[0].indirect_type.params << C::Parameter.new(C::Int.new, 'i')
439
+ d.declarators[0].indirect_type.params << C::Parameter.new(C::Float.new, 'f')
440
+ check_depth_firsts(d,
441
+ [
442
+ [:descending, d],
443
+ [:descending, d.type], [:ascending, d.type],
444
+ [:descending, d.declarators],
445
+ [:descending, d.declarators[0]],
446
+ [:descending, d.declarators[0].indirect_type],
447
+ [:descending, d.declarators[0].indirect_type.params],
448
+ [:descending, d.declarators[0].indirect_type.params[0]],
449
+ [:descending, d.declarators[0].indirect_type.params[0].type], [:ascending, d.declarators[0].indirect_type.params[0].type],
450
+ [:ascending, d.declarators[0].indirect_type.params[0]],
451
+ [:descending, d.declarators[0].indirect_type.params[1]],
452
+ [:descending, d.declarators[0].indirect_type.params[1].type], [:ascending, d.declarators[0].indirect_type.params[1].type],
453
+ [:ascending, d.declarators[0].indirect_type.params[1]],
454
+ [:ascending, d.declarators[0].indirect_type.params],
455
+ [:ascending, d.declarators[0].indirect_type],
456
+ [:ascending, d.declarators[0]],
457
+ [:descending, d.declarators[1]], [:ascending, d.declarators[1]],
458
+ [:ascending, d.declarators],
459
+ [:ascending, d]
460
+ ])
461
+ end
462
+
463
+ def check_depth_first_prunes(pruned_nodes, node, exp)
464
+ # depth_first
465
+ out = yields(:depth_first, node, node) do |ev, node|
466
+ if ev.equal? :descending
467
+ if pruned_nodes.any?{|n| n.equal? node}
468
+ throw :prune
469
+ end
470
+ end
471
+ end
472
+ assert_equal_yields exp, out
473
+ #
474
+ ret = catch :prune do
475
+ node.depth_first do |ev, node|
476
+ throw :prune, :x if ev.equal? :ascending
477
+ end
478
+ :oops
479
+ end
480
+ assert_same(:x, ret)
481
+
482
+ # reverse_depth_first
483
+ exp = exp.reverse.map! do |ev, node|
484
+ if ev.equal? :ascending
485
+ [:descending, node]
486
+ else
487
+ [:ascending, node]
488
+ end
489
+ end
490
+ out = yields(:reverse_depth_first, node, node) do |ev, node|
491
+ if ev.equal? :descending
492
+ if pruned_nodes.any?{|n| n.equal? node}
493
+ throw :prune
494
+ end
495
+ end
496
+ end
497
+ assert_equal_yields exp, out
498
+ #
499
+ ret = catch :prune do
500
+ node.reverse_depth_first do |ev, node|
501
+ throw :prune, :x if ev.equal? :ascending
502
+ end
503
+ :oops
504
+ end
505
+ assert_same(:x, ret)
506
+ end
507
+
508
+ def test_depth_first_prune
509
+ # empty node
510
+ d = C::Int.new
511
+ d.longness = 1
512
+ check_depth_first_prunes([d], d,
513
+ [[:descending, d], [:ascending, d]])
514
+
515
+ # one-storey -- populate both the list child and nonlist child
516
+ d = C::Declaration.new(C::Int.new)
517
+ d.declarators << C::Declarator.new
518
+ d.declarators[0].name = 'one'
519
+ d.declarators << C::Declarator.new
520
+ d.declarators[1].name = 'two'
521
+ check_depth_first_prunes([d.declarators], d,
522
+ [
523
+ [:descending, d],
524
+ [:descending, d.type], [:ascending, d.type],
525
+ [:descending, d.declarators], [:ascending, d.declarators],
526
+ [:ascending, d]
527
+ ])
528
+
529
+ # multi-layer
530
+ d.type = C::Struct.new('S')
531
+ d.type.members = Chain[]
532
+ d.type.members << C::Declaration.new(C::Int.new)
533
+ d.type.members[0].declarators << C::Declarator.new(nil, 'x')
534
+ d.declarators[0].indirect_type = C::Function.new
535
+ d.declarators[0].indirect_type.params = Chain[]
536
+ d.declarators[0].indirect_type.params << C::Parameter.new(C::Int.new, 'i')
537
+ d.declarators[0].indirect_type.params << C::Parameter.new(C::Float.new, 'f')
538
+ check_depth_first_prunes([d.type.members, d.declarators[0]], d,
539
+ [
540
+ [:descending, d],
541
+ [:descending, d.type],
542
+ [:descending, d.type.members], [:ascending, d.type.members],
543
+ [:ascending, d.type],
544
+ [:descending, d.declarators],
545
+ [:descending, d.declarators[0]], [:ascending, d.declarators[0]],
546
+ [:descending, d.declarators[1]], [:ascending, d.declarators[1]],
547
+ [:ascending, d.declarators],
548
+ [:ascending, d]
549
+ ])
550
+ end
551
+
552
+ # ------------------------------------------------------------------
553
+ # each, reverse_each
554
+ # ------------------------------------------------------------------
555
+
556
+ def iter_str(iter)
557
+ iter.is_a? ::Array or
558
+ raise "iter_str: expected ::Array"
559
+ if iter.empty?
560
+ return '[]'
561
+ else
562
+ s = StringIO.new
563
+ s.puts '['
564
+ iter.each do |node|
565
+ nodestr = node.class.name << '(' << node.object_id.to_s << "): " << node.to_s
566
+ if nodestr.length > 70
567
+ nodestr[68..-1] = '...'
568
+ end
569
+ s.puts " #{nodestr}"
570
+ end
571
+ s.puts ']'
572
+ return s.string
573
+ end
574
+ end
575
+ def check_each(node, exp)
576
+ exp.map!{|n| [n]}
577
+
578
+ out = yields(:each, node, node)
579
+ assert_equal_yields exp, out
580
+
581
+ out = yields(:reverse_each, node, node)
582
+ exp.reverse!
583
+ assert_equal_yields exp, out
584
+ end
585
+ def test_each
586
+ # empty
587
+ parent = X.new
588
+ check_each(parent, [])
589
+
590
+ # one child
591
+ x1 = X.new
592
+ parent = X.new(x1)
593
+ check_each(parent, [x1])
594
+
595
+ # two children
596
+ x1, x2 = 2.of{X.new}
597
+ parent = Y.new(x1, x2)
598
+ check_each(parent, [x1, x2])
599
+
600
+ # three with some nil and some fields
601
+ x1, x2, x3, x4, x5 = 5.of{X.new}
602
+ parent = Z.new(x1, x2, nil, x4, x5)
603
+ check_each(parent, [x1, x5])
604
+ end
605
+
606
+ # ------------------------------------------------------------------
607
+ # preorder, reverse_preorder, postorder, reverse_postorder
608
+ # ------------------------------------------------------------------
609
+
610
+ def check_preorder(node, exp)
611
+ exp.map!{|n| [n]}
612
+
613
+ out = yields(:preorder, node, node)
614
+ assert_equal_yields exp, out
615
+
616
+ out = yields(:reverse_postorder, node, node)
617
+ exp.reverse!
618
+ assert_equal_yields exp, out
619
+ end
620
+ def check_postorder(node, exp)
621
+ exp.map!{|n| [n]}
622
+
623
+ out = yields(:postorder, node, node)
624
+ assert_equal_yields exp, out
625
+
626
+ out = yields(:reverse_preorder, node, node)
627
+ exp.reverse!
628
+ assert_equal_yields exp, out
629
+ end
630
+ def test_preorder
631
+ # empty node
632
+ d = C::Int.new
633
+ d.longness = 1
634
+ check_preorder(d, [d])
635
+
636
+ # one-storey -- populate both the list child and nonlist child
637
+ d = C::Declaration.new(C::Int.new)
638
+ d.declarators << C::Declarator.new
639
+ d.declarators[0].name = 'one'
640
+ d.declarators << C::Declarator.new
641
+ d.declarators[1].name = 'two'
642
+ check_preorder(d,
643
+ [
644
+ d,
645
+ d.type,
646
+ d.declarators,
647
+ d.declarators[0],
648
+ d.declarators[1]
649
+ ])
650
+
651
+ # multi-layer
652
+ d.declarators[0].indirect_type = C::Function.new
653
+ d.declarators[0].indirect_type.params = Chain[]
654
+ d.declarators[0].indirect_type.params << C::Parameter.new(C::Int.new, 'i')
655
+ d.declarators[0].indirect_type.params << C::Parameter.new(C::Float.new, 'f')
656
+ check_preorder(d,
657
+ [
658
+ d,
659
+ d.type,
660
+ d.declarators,
661
+ d.declarators[0],
662
+ d.declarators[0].indirect_type,
663
+ d.declarators[0].indirect_type.params,
664
+ d.declarators[0].indirect_type.params[0],
665
+ d.declarators[0].indirect_type.params[0].type,
666
+ d.declarators[0].indirect_type.params[1],
667
+ d.declarators[0].indirect_type.params[1].type,
668
+ d.declarators[1]
669
+ ])
670
+ end
671
+ def test_postorder
672
+ # empty node
673
+ d = C::Int.new
674
+ d.longness = 1
675
+ check_preorder(d, [d])
676
+
677
+ # one-storey -- populate both the list child and nonlist child
678
+ d = C::Declaration.new(C::Int.new)
679
+ d.declarators << C::Declarator.new
680
+ d.declarators[0].name = 'one'
681
+ d.declarators << C::Declarator.new
682
+ d.declarators[1].name = 'two'
683
+ check_postorder(d,
684
+ [
685
+ d.type,
686
+ d.declarators[0],
687
+ d.declarators[1],
688
+ d.declarators,
689
+ d
690
+ ])
691
+
692
+ # multi-layer
693
+ d.declarators[0].indirect_type = C::Function.new
694
+ d.declarators[0].indirect_type.params = Chain[]
695
+ d.declarators[0].indirect_type.params << C::Parameter.new(C::Int.new, 'i')
696
+ d.declarators[0].indirect_type.params << C::Parameter.new(C::Float.new, 'f')
697
+ check_postorder(d,
698
+ [
699
+ d.type,
700
+ d.declarators[0].indirect_type.params[0].type,
701
+ d.declarators[0].indirect_type.params[0],
702
+ d.declarators[0].indirect_type.params[1].type,
703
+ d.declarators[0].indirect_type.params[1],
704
+ d.declarators[0].indirect_type.params,
705
+ d.declarators[0].indirect_type,
706
+ d.declarators[0],
707
+ d.declarators[1],
708
+ d.declarators,
709
+ d
710
+ ])
711
+ end
712
+ def check_preorder_prune(method, pruned_nodes, root, exp)
713
+ exp.map!{|n| [n]}
714
+
715
+ out = yields(method, root, root) do |node|
716
+ if pruned_nodes.any?{|n| n.equal? node}
717
+ throw :prune
718
+ end
719
+ end
720
+ assert_equal_yields exp, out
721
+ end
722
+
723
+ def test_preorder_prune
724
+ # empty node
725
+ d = C::Int.new
726
+ d.longness = 1
727
+ check_preorder_prune(:preorder, [d], d, [d])
728
+ check_preorder_prune(:reverse_preorder, [d], d, [d])
729
+
730
+ # one-storey -- populate both the list child and nonlist child
731
+ d = C::Declaration.new(C::Int.new)
732
+ d.declarators << C::Declarator.new
733
+ d.declarators[0].name = 'one'
734
+ d.declarators << C::Declarator.new
735
+ d.declarators[1].name = 'two'
736
+ check_preorder_prune(:preorder, [d.declarators], d,
737
+ [
738
+ d,
739
+ d.type,
740
+ d.declarators,
741
+ ])
742
+ check_preorder_prune(:reverse_preorder, [d.declarators], d,
743
+ [
744
+ d,
745
+ d.declarators,
746
+ d.type,
747
+ ])
748
+
749
+ # multi-layer
750
+ d.type = C::Struct.new('S')
751
+ d.type.members = Chain[]
752
+ d.type.members << C::Declaration.new(C::Int.new)
753
+ d.type.members[0].declarators << C::Declarator.new(nil, 'x')
754
+ d.declarators[0].indirect_type = C::Function.new
755
+ d.declarators[0].indirect_type.params = Chain[]
756
+ d.declarators[0].indirect_type.params << C::Parameter.new(C::Int.new, 'i')
757
+ d.declarators[0].indirect_type.params << C::Parameter.new(C::Float.new, 'f')
758
+ check_preorder_prune(:preorder, [d.type.members, d.declarators[0]], d,
759
+ [
760
+ d,
761
+ d.type,
762
+ d.type.members,
763
+ d.declarators,
764
+ d.declarators[0],
765
+ d.declarators[1]
766
+ ])
767
+ check_preorder_prune(:reverse_preorder, [d.type.members, d.declarators[0]], d,
768
+ [
769
+ d,
770
+ d.declarators,
771
+ d.declarators[1],
772
+ d.declarators[0],
773
+ d.type,
774
+ d.type.members
775
+ ])
776
+ end
777
+
778
+ # ------------------------------------------------------------------
779
+ # next, prev, list_next, list_prev
780
+ # ------------------------------------------------------------------
781
+
782
+ def test_next_prev
783
+ # list parent
784
+ i1 = C::Int.new
785
+ i2 = C::Int.new
786
+ list = Chain[i1, i2]
787
+ assert_same(i2, i1.next)
788
+ assert_nil(i2.next)
789
+ assert_same(i1, i2.prev)
790
+ assert_nil(i1.prev)
791
+
792
+ # node parent
793
+ i1 = C::IntLiteral.new(1)
794
+ i2 = C::IntLiteral.new(2)
795
+ a = C::Add.new(i1, i2)
796
+ assert_same(i2, i1.next)
797
+ assert_nil(i2.next)
798
+ assert_same(i1, i2.prev)
799
+ assert_nil(i1.prev)
800
+
801
+ # no parent
802
+ i = C::Int.new
803
+ assert_raise(C::Node::NoParent){i.next}
804
+ assert_raise(C::Node::NoParent){i.prev}
805
+ end
806
+
807
+ def test_list_next_prev
808
+ # list parent
809
+ i1 = C::Int.new
810
+ i2 = C::Int.new
811
+ list = Chain[i1, i2]
812
+ assert_same(i2, i1.list_next)
813
+ assert_nil(i2.list_next)
814
+ assert_same(i1, i2.list_prev)
815
+ assert_nil(i1.list_prev)
816
+
817
+ # node parent
818
+ i1 = C::IntLiteral.new(1)
819
+ i2 = C::IntLiteral.new(2)
820
+ a = C::Add.new(i1, i2)
821
+ assert_raise(C::Node::BadParent){i1.list_next}
822
+ assert_raise(C::Node::BadParent){i2.list_next}
823
+ assert_raise(C::Node::BadParent){i1.list_prev}
824
+ assert_raise(C::Node::BadParent){i2.list_prev}
825
+
826
+ # no parent
827
+ i = C::Int.new
828
+ assert_raise(C::Node::NoParent){i.list_next}
829
+ assert_raise(C::Node::NoParent){i.list_prev}
830
+ end
831
+ end
832
+
833
+ class NodeTreeTest < Test::Unit::TestCase
834
+ def setup
835
+ # @c = "(int){[1] = 10,
836
+ # .x = 20,
837
+ # [2] .y = 30
838
+ # }
839
+ @c = C::CompoundLiteral.new
840
+ c.type = C::Int.new
841
+ c.member_inits << C::MemberInit.new
842
+ c.member_inits[0].member = C::NodeChain.new
843
+ c.member_inits[0].member << C::IntLiteral.new(1)
844
+ c.member_inits[0].init = C::IntLiteral.new(10)
845
+ c.member_inits << C::MemberInit.new
846
+ c.member_inits[1].member = C::NodeChain.new
847
+ c.member_inits[1].member << C::Member.new('x')
848
+ c.member_inits[1].init = C::IntLiteral.new(20)
849
+ c.member_inits << C::MemberInit.new
850
+ c.member_inits[2].member = C::NodeChain.new
851
+ c.member_inits[2].member << C::IntLiteral.new(2)
852
+ c.member_inits[2].member << C::Member.new('y')
853
+ c.member_inits[2].init = C::IntLiteral.new(30)
854
+ end
855
+ attr_reader :c
856
+
857
+ def test_empty
858
+ ast = C::TranslationUnit.new
859
+ assert_tree(ast)
860
+ end
861
+ def test_basic
862
+ assert_tree(c)
863
+ end
864
+
865
+ def test_assign_field
866
+ c.type.unsigned = true
867
+ assert_tree(c)
868
+ assert_same(true, c.type.unsigned?)
869
+ c.type.unsigned = false
870
+ assert_tree(c)
871
+ assert_same(false, c.type.unsigned?)
872
+ end
873
+ def test_assign_child
874
+ c.type = nil
875
+ assert_tree(c)
876
+ assert_nil(c.type)
877
+ f = C::Float.new
878
+ c.type = f
879
+ assert_tree(c)
880
+ assert_same(f, c.type)
881
+ end
882
+ def test_assign_list
883
+ old_list = c.member_inits[2].member
884
+ new_list = C::NodeChain[C::IntLiteral.new(4), C::Member.new('a')]
885
+ c.member_inits[2].member = new_list
886
+ assert_tree(c)
887
+ assert_tree(old_list)
888
+ assert_same(new_list, c.member_inits[2].member)
889
+ end
890
+ def test_assign_attached
891
+ f = C::Float.new
892
+ c2 = C::CompoundLiteral.new
893
+ c2.type = f
894
+
895
+ c.type = f
896
+ assert_same(f, c2.type)
897
+ assert_copy(f, c.type)
898
+ assert_tree(c)
899
+ assert_tree(c2)
900
+ end
901
+
902
+ def test_detach_node
903
+ d = c.type.detach
904
+ assert_tree(c)
905
+ assert_tree(d)
906
+ end
907
+
908
+ def test_detach_list_element
909
+ member_one = c.member_inits[1]
910
+ member_two = c.member_inits[2]
911
+ d = c.member_inits[0].detach
912
+ assert_tree(c)
913
+ assert_tree(d)
914
+ assert_same_list([member_one, member_two], c.member_inits)
915
+ end
916
+
917
+ def test_detach_list
918
+ d = c.member_inits.detach
919
+ assert_tree(c)
920
+ assert_tree(d)
921
+ end
922
+
923
+ def test_node_replace_with
924
+ i = C::Int.new
925
+ t = c.type
926
+ assert_same(c.type, c.type.replace_with(i))
927
+ assert_tree(c)
928
+ assert_tree(t)
929
+ assert_same(i, c.type)
930
+
931
+ assert_same(c.type, c.type.replace_with(nil))
932
+ assert_tree(c)
933
+ assert_nil(c.type)
934
+ end
935
+ def test_node_replace_with_none
936
+ t = c.type
937
+ assert_same(c.type, c.type.replace_with)
938
+ assert_tree(c)
939
+ assert_tree(t)
940
+ assert_nil(c.type)
941
+ end
942
+ def test_node_replace_with_many
943
+ mi = c.member_inits[0]
944
+ mis = [c.member_inits[0], c.member_inits[1], c.member_inits[2]]
945
+
946
+ mi1 = C::MemberInit.new
947
+ mi1.init = C::IntLiteral.new(1)
948
+ mi2 = C::MemberInit.new
949
+ mi2.init = C::IntLiteral.new(2)
950
+
951
+ assert_same(mi, mi.replace_with(mi1, mi2))
952
+ assert_tree(c)
953
+ assert_tree(mi)
954
+ assert_same_list([mi1, mi2, mis[1], mis[2]], c.member_inits)
955
+
956
+ assert_raise(C::Node::NoParent){mi.replace_with(nil)}
957
+ i1 = C::Int.new
958
+ i2 = C::Int.new
959
+ assert_raise(ArgumentError){c.type.replace_with(i1, i2)}
960
+ end
961
+
962
+ def test_node_swap_with
963
+ # swap with itself -- attached
964
+ x = X.new
965
+ parent = X.new(x)
966
+ assert_same(x, x.swap_with(x))
967
+ assert_same(parent, x.parent)
968
+ assert_same(x, parent.a)
969
+
970
+ # swap with itself -- detached
971
+ x = X.new
972
+ assert_same(x, x.swap_with(x))
973
+ assert_nil(x.parent)
974
+
975
+ # both attached
976
+ x = X.new
977
+ y = X.new
978
+ xp = X.new(x)
979
+ yp = X.new(y)
980
+ assert_same(x, x.swap_with(y))
981
+ assert_same(xp, y.parent)
982
+ assert_same(x, yp.a)
983
+ assert_same(yp, x.parent)
984
+ assert_same(y, xp.a)
985
+
986
+ # only receiver attached
987
+ x = X.new
988
+ y = X.new
989
+ xp = X.new(x)
990
+ assert_same(x, x.swap_with(y))
991
+ assert_nil(x.parent)
992
+ assert_same(xp, y.parent)
993
+ assert_same(y, xp.a)
994
+
995
+ # only arg attached
996
+ x = X.new
997
+ y = X.new
998
+ yp = X.new(y)
999
+ assert_same(x, x.swap_with(y))
1000
+ assert_same(yp, x.parent)
1001
+ assert_same(x, yp.a)
1002
+ assert_nil(y.parent)
1003
+
1004
+ # neither attached
1005
+ x = X.new
1006
+ y = X.new
1007
+ assert_same(x, x.swap_with(y))
1008
+ assert_nil(x.parent)
1009
+ assert_nil(y.parent)
1010
+ end
1011
+
1012
+ # ------------------------------------------------------------------
1013
+ # insert_next, insert_prev
1014
+ # ------------------------------------------------------------------
1015
+
1016
+ def test_node_insert_next_detached
1017
+ x1, x2 = 2.of{X.new}
1018
+ assert_raise(C::Node::NoParent){x1.insert_next}
1019
+ assert_nil(x1.parent)
1020
+ assert_raise(C::Node::NoParent){x1.insert_next(x2)}
1021
+ assert_nil(x1.parent)
1022
+ assert_nil(x2.parent)
1023
+ end
1024
+ def test_node_insert_next_nonlist_parent
1025
+ parent = X.new
1026
+ x1, x2 = 2.of{X.new}
1027
+ parent.a = x1
1028
+ assert_raise(C::Node::BadParent){x1.insert_next}
1029
+ assert_same(parent, x1.parent)
1030
+ assert_raise(C::Node::BadParent){x1.insert_next(x2)}
1031
+ assert_same(parent, x1.parent)
1032
+ assert_nil(x2.parent)
1033
+ end
1034
+ def test_node_insert_next_none
1035
+ x1 = X.new
1036
+ parent = Chain[x1]
1037
+ assert_same(x1, x1.insert_next)
1038
+ assert_same_list([x1], parent)
1039
+ end
1040
+ def test_node_insert_next_many
1041
+ x1, x2, x3, x4 = 4.of{X.new}
1042
+ parent = Chain[x1]
1043
+ assert_same(x1, x1.insert_next(x2, x3, x4))
1044
+ assert_same_list([x1, x2, x3, x4], parent)
1045
+ end
1046
+
1047
+ def test_node_insert_prev_detached
1048
+ a1, a2 = 2.of{X.new}
1049
+ assert_raise(C::Node::NoParent){a1.insert_prev}
1050
+ assert_nil(a1.parent)
1051
+ assert_raise(C::Node::NoParent){a1.insert_prev(a2)}
1052
+ assert_nil(a1.parent)
1053
+ assert_nil(a2.parent)
1054
+ end
1055
+ def test_node_insert_prev_nonlist_parent
1056
+ parent = X.new
1057
+ x1, x2 = 2.of{X.new}
1058
+ parent.a = x1
1059
+ assert_raise(C::Node::BadParent){x1.insert_prev}
1060
+ assert_same(parent, x1.parent)
1061
+ assert_raise(C::Node::BadParent){x1.insert_prev(x2)}
1062
+ assert_same(parent, x1.parent)
1063
+ assert_nil(x2.parent)
1064
+ end
1065
+ def test_node_insert_prev_none
1066
+ x1 = X.new
1067
+ parent = Chain[x1]
1068
+ assert_same(x1, x1.insert_prev)
1069
+ assert_same_list([x1], parent)
1070
+ end
1071
+ def test_node_insert_prev_many
1072
+ x1, x2, x3, x4 = 4.of{X.new}
1073
+ parent = Chain[x1]
1074
+ assert_same(x1, x1.insert_prev(x2, x3, x4))
1075
+ assert_same_list([x2, x3, x4, x1], parent)
1076
+ end
1077
+
1078
+ # ------------------------------------------------------------------
1079
+ # node_after, node_before
1080
+ # ------------------------------------------------------------------
1081
+
1082
+ def test_node_after_before
1083
+ # node not a child
1084
+ x1, x2 = 2.of{X.new}
1085
+ parent = X.new(x1)
1086
+ assert_raise(ArgumentError){parent.node_after(x2)}
1087
+ assert_raise(ArgumentError){parent.node_before(x2)}
1088
+
1089
+ x1, x2 = 2.of{X.new}
1090
+ parent = Z.new(nil, x1, nil, x2, nil)
1091
+ assert_raise(ArgumentError){parent.node_after(x1)}
1092
+ assert_raise(ArgumentError){parent.node_after(x2)}
1093
+ assert_raise(ArgumentError){parent.node_before(x1)}
1094
+ assert_raise(ArgumentError){parent.node_before(x2)}
1095
+
1096
+ # one child
1097
+ x = X.new
1098
+ parent = X.new(x)
1099
+ assert_nil(parent.node_after(x))
1100
+ assert_nil(parent.node_before(x))
1101
+
1102
+ # two children
1103
+ x1 = X.new
1104
+ x2 = X.new
1105
+ parent = Y.new(x1, x2)
1106
+ assert_same(x2, parent.node_after(x1))
1107
+ assert_nil(parent.node_after(x2))
1108
+ assert_same(x1, parent.node_before(x2))
1109
+ assert_nil(parent.node_before(x1))
1110
+
1111
+ # skip over stuff in the middle
1112
+ x1, x2, x3, x4, x5 = 5.of{X.new}
1113
+ parent = Z.new(x1, x2, nil, x4, x5)
1114
+ assert_same(x5, parent.node_after(x1))
1115
+ assert_nil(parent.node_after(x5))
1116
+ assert_same(x1, parent.node_before(x5))
1117
+ assert_nil(parent.node_before(x1))
1118
+
1119
+ # skip over stuff at the end
1120
+ x1, x2, x3, x4, x5 = 5.of{X.new}
1121
+ parent = Z.new(nil, x2, x3, x4, nil)
1122
+ assert_nil(parent.node_after(x3))
1123
+ assert_nil(parent.node_before(x3))
1124
+ end
1125
+
1126
+ def test_remove_node
1127
+ # node not a child
1128
+ x1, x2, x3 = 3.of{X.new}
1129
+ parent = Z.new(x1, x2)
1130
+ assert_raise(ArgumentError){parent.remove_node(x2)}
1131
+ assert_raise(ArgumentError){parent.remove_node(x3)}
1132
+
1133
+ # one child
1134
+ x = X.new
1135
+ parent = X.new(x)
1136
+ assert_same(parent, parent.remove_node(x))
1137
+ assert_tree(parent)
1138
+ assert_tree(x)
1139
+
1140
+ # two children
1141
+ x1, x2 = 2.of{X.new}
1142
+ parent = Y.new(x1, x2)
1143
+ assert_same(parent, parent.remove_node(x2))
1144
+ assert_tree(parent)
1145
+ assert_tree(x2)
1146
+ assert_same(x1, parent.a)
1147
+ assert_nil(parent.b)
1148
+ end
1149
+
1150
+ def test_replace_node
1151
+ # node not a child
1152
+ x1, x2, x3, x4 = 3.of{X.new}
1153
+ parent = Z.new(x1, x2)
1154
+ assert_raise(ArgumentError){parent.replace_node(x2, x4)}
1155
+ assert_raise(ArgumentError){parent.replace_node(x3, x4)}
1156
+
1157
+ # no newnode
1158
+ x = X.new
1159
+ parent = X.new(x)
1160
+ assert_same(parent, parent.replace_node(x))
1161
+ assert_tree(parent)
1162
+ assert_tree(x)
1163
+ assert_nil(parent.a)
1164
+
1165
+ # >1 newnode
1166
+ x1, x2, x3 = 3.of{X.new}
1167
+ parent = X.new(x1)
1168
+ assert_raise(ArgumentError){parent.replace_node(x1, x2, x3)}
1169
+
1170
+ # one child
1171
+ x1, x2 = 2.of{X.new}
1172
+ parent = X.new(x1)
1173
+ assert_same(parent, parent.replace_node(x1, x2))
1174
+ assert_tree(parent)
1175
+ assert_tree(x1)
1176
+ assert_same(x2, parent.a)
1177
+ #
1178
+ assert_same(parent, parent.replace_node(x2, nil))
1179
+ assert_tree(parent)
1180
+ assert_tree(x2)
1181
+ assert_nil(parent.a)
1182
+
1183
+ # two children
1184
+ x1, x2, x3 = 3.of{X.new}
1185
+ parent = Y.new(x1, x2)
1186
+ assert_same(parent, parent.replace_node(x2, x3))
1187
+ assert_tree(parent)
1188
+ assert_tree(x2)
1189
+ assert_same(x3, parent.b)
1190
+ #
1191
+ assert_same(parent, parent.replace_node(x3, nil))
1192
+ assert_tree(parent)
1193
+ assert_tree(x3)
1194
+ assert_nil(parent.b)
1195
+ end
1196
+ end