1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
8 // - test use of explicit hasher across two maps.
9 // - test hashcodes are consistent with equals for a range of types
10 // (e.g. all types generated by type-checking some body of real code).
16 "golang.org/x/tools/go/types/typeutil"
20 tStr = types.Typ[types.String] // string
21 tPStr1 = types.NewPointer(tStr) // *string
22 tPStr2 = types.NewPointer(tStr) // *string, again
23 tInt = types.Typ[types.Int] // int
24 tChanInt1 = types.NewChan(types.RecvOnly, tInt) // <-chan int
25 tChanInt2 = types.NewChan(types.RecvOnly, tInt) // <-chan int, again
28 func checkEqualButNotIdentical(t *testing.T, x, y types.Type, comment string) {
29 if !types.Identical(x, y) {
30 t.Errorf("%s: not equal: %s, %s", comment, x, y)
33 t.Errorf("%s: identical: %v, %v", comment, x, y)
37 func TestAxioms(t *testing.T) {
38 checkEqualButNotIdentical(t, tPStr1, tPStr2, "tPstr{1,2}")
39 checkEqualButNotIdentical(t, tChanInt1, tChanInt2, "tChanInt{1,2}")
42 func TestMap(t *testing.T) {
43 var tmap *typeutil.Map
45 // All methods but Set are safe on on (*T)(nil).
52 tmap = new(typeutil.Map)
54 // Length of empty map.
55 if l := tmap.Len(); l != 0 {
56 t.Errorf("Len() on empty Map: got %d, want 0", l)
59 if v := tmap.At(tPStr1); v != nil {
60 t.Errorf("At() on empty Map: got %v, want nil", v)
62 // Deletion of missing key.
63 if tmap.Delete(tPStr1) {
64 t.Errorf("Delete() on empty Map: got true, want false")
67 if prev := tmap.Set(tPStr1, "*string"); prev != nil {
68 t.Errorf("Set() on empty Map returned non-nil previous value %s", prev)
71 // Now: {*string: "*string"}
73 // Length of non-empty map.
74 if l := tmap.Len(); l != 1 {
75 t.Errorf("Len(): got %d, want 1", l)
77 // At via insertion key.
78 if v := tmap.At(tPStr1); v != "*string" {
79 t.Errorf("At(): got %q, want \"*string\"", v)
82 if v := tmap.At(tPStr2); v != "*string" {
83 t.Errorf("At(): got %q, want \"*string\"", v)
85 // Iteration over sole entry.
86 tmap.Iterate(func(key types.Type, value interface{}) {
88 t.Errorf("Iterate: key: got %s, want %s", key, tPStr1)
90 if want := "*string"; value != want {
91 t.Errorf("Iterate: value: got %s, want %s", value, want)
95 // Setion with key equal to present one.
96 if prev := tmap.Set(tPStr2, "*string again"); prev != "*string" {
97 t.Errorf("Set() previous value: got %s, want \"*string\"", prev)
100 // Setion of another association.
101 if prev := tmap.Set(tChanInt1, "<-chan int"); prev != nil {
102 t.Errorf("Set() previous value: got %s, want nil", prev)
105 // Now: {*string: "*string again", <-chan int: "<-chan int"}
107 want1 := "{*string: \"*string again\", <-chan int: \"<-chan int\"}"
108 want2 := "{<-chan int: \"<-chan int\", *string: \"*string again\"}"
109 if s := tmap.String(); s != want1 && s != want2 {
110 t.Errorf("String(): got %s, want %s", s, want1)
113 want1 = "{*string, <-chan int}"
114 want2 = "{<-chan int, *string}"
115 if s := tmap.KeysString(); s != want1 && s != want2 {
116 t.Errorf("KeysString(): got %s, want %s", s, want1)
121 switch k := tmap.Keys(); {
122 case I(k[0], tChanInt1) && I(k[1], tPStr1): // ok
123 case I(k[1], tChanInt1) && I(k[0], tPStr1): // ok
125 t.Errorf("Keys(): got %v, want %s", k, want2)
128 if l := tmap.Len(); l != 2 {
129 t.Errorf("Len(): got %d, want 1", l)
131 // At via original key.
132 if v := tmap.At(tPStr1); v != "*string again" {
133 t.Errorf("At(): got %q, want \"*string again\"", v)
136 tmap.Iterate(func(key types.Type, value interface{}) {
138 case I(key, tChanInt1):
145 t.Errorf("Iterate: hamming: got %d, want %d", hamming, 6)
148 if v := tmap.At(tChanInt2); v != "<-chan int" {
149 t.Errorf("At(): got %q, want \"<-chan int\"", v)
151 // Deletion with key equal to present one.
152 if !tmap.Delete(tChanInt2) {
153 t.Errorf("Delete() of existing key: got false, want true")
156 // Now: {*string: "*string again"}
158 if l := tmap.Len(); l != 1 {
159 t.Errorf("Len(): got %d, want 1", l)
162 if !tmap.Delete(tPStr2) {
163 t.Errorf("Delete() of existing key: got false, want true")
168 if l := tmap.Len(); l != 0 {
169 t.Errorf("Len(): got %d, want %d", l, 0)
171 if s := tmap.String(); s != "{}" {
172 t.Errorf("Len(): got %q, want %q", s, "")