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