1
2
3
4
5 package types2
6
7 import (
8 "fmt"
9 "slices"
10 "testing"
11 )
12
13
14 func TestScopeObjects(t *testing.T) {
15 s := NewScope(nil, nopos, nopos, "test")
16
17
18 var gotNames []string
19 for obj := range s.Objects() {
20 gotNames = append(gotNames, obj.Name())
21 }
22 if len(gotNames) != 0 {
23 t.Errorf("empty scope: got %v, want empty", gotNames)
24 }
25
26
27 names := []string{"e", "c", "a", "b", "d"}
28 for _, name := range names {
29 v := NewVar(nopos, nil, name, Typ[Int])
30 if alt := s.Insert(v); alt != nil {
31 t.Fatalf("Insert(%s) failed", name)
32 }
33 }
34
35 wantNames := []string{"a", "b", "c", "d", "e"}
36 if !slices.Equal(s.Names(), wantNames) {
37 t.Errorf("Names() = %v, want %v", s.Names(), wantNames)
38 }
39
40
41 gotNames = nil
42 for obj := range s.Objects() {
43 gotNames = append(gotNames, obj.Name())
44 if obj != s.Lookup(obj.Name()) {
45 t.Errorf("Objects() yielded %v, want Lookup result %v", obj, s.Lookup(obj.Name()))
46 }
47 }
48 if !slices.Equal(gotNames, wantNames) {
49 t.Errorf("Objects() yielded %v, want %v", gotNames, wantNames)
50 }
51
52
53 count := 0
54 for range s.Objects() {
55 count++
56 if count == 2 {
57 break
58 }
59 }
60 if count != 2 {
61 t.Errorf("early break: iterated %d times, want 2", count)
62 }
63 }
64
65
66 func TestScopeMutationReflectsChanges(t *testing.T) {
67 s := NewScope(nil, nopos, nopos, "test")
68
69 v1 := NewVar(nopos, nil, "b", Typ[Int])
70 s.Insert(v1)
71
72
73 if want := []string{"b"}; !slices.Equal(s.Names(), want) {
74 t.Fatalf("Names() = %v, want %v", s.Names(), want)
75 }
76
77
78 v0 := NewVar(nopos, nil, "a", Typ[Int])
79 s.Insert(v0)
80
81
82 wantNames := []string{"a", "b"}
83 if !slices.Equal(s.Names(), wantNames) {
84 t.Errorf("after inserting 'a': Names() = %v, want %v", s.Names(), wantNames)
85 }
86
87
88 var gotNames []string
89 for obj := range s.Objects() {
90 gotNames = append(gotNames, obj.Name())
91 }
92 if !slices.Equal(gotNames, wantNames) {
93 t.Errorf("after inserting 'a': Objects() = %v, want %v", gotNames, wantNames)
94 }
95
96
97 v2 := NewVar(nopos, nil, "c", Typ[Int])
98 s.Insert(v2)
99
100 wantNames = []string{"a", "b", "c"}
101 if !slices.Equal(s.Names(), wantNames) {
102 t.Errorf("after inserting 'c': Names() = %v, want %v", s.Names(), wantNames)
103 }
104 gotNames = nil
105 for obj := range s.Objects() {
106 gotNames = append(gotNames, obj.Name())
107 }
108 if !slices.Equal(gotNames, wantNames) {
109 t.Errorf("after inserting 'c': Objects() = %v, want %v", gotNames, wantNames)
110 }
111
112
113 dup := NewVar(nopos, nil, "b", Typ[String])
114 if alt := s.Insert(dup); alt != v1 {
115 t.Errorf("Insert duplicate: got %v, want %v", alt, v1)
116 }
117 if !slices.Equal(s.Names(), wantNames) {
118 t.Errorf("after duplicate Insert: Names() = %v, want %v", s.Names(), wantNames)
119 }
120 }
121
122
123
124 func TestScopeNoAllocations(t *testing.T) {
125 s := NewScope(nil, nopos, nopos, "test")
126 for i := range 10 {
127 s.Insert(NewVar(nopos, nil, fmt.Sprintf("v%d", i), Typ[Int]))
128 }
129
130
131 _ = s.Names()
132
133
134 namesAllocs := testing.AllocsPerRun(100, func() { _ = s.Names() })
135 if namesAllocs > 0 {
136 t.Errorf("repeated s.Names() allocated %f times, want 0", namesAllocs)
137 }
138
139
140
141 if allocs := testing.AllocsPerRun(100, func() {
142 s.Objects()(func(Object) bool { return true })
143 }); allocs > namesAllocs+1 {
144 t.Errorf("repeated s.Objects() iteration allocated %f times, want at most %f", allocs, namesAllocs+1)
145 }
146 }
147
View as plain text