casty 0.3.1

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,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