golang.org/x/tools/gopls@v0.15.3/internal/util/persistent/set_test.go (about) 1 // Copyright 2023 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. 4 5 package persistent_test 6 7 import ( 8 "fmt" 9 "strings" 10 "testing" 11 12 "golang.org/x/tools/gopls/internal/util/constraints" 13 "golang.org/x/tools/gopls/internal/util/persistent" 14 ) 15 16 func TestSet(t *testing.T) { 17 const ( 18 add = iota 19 remove 20 ) 21 type op struct { 22 op int 23 v int 24 } 25 26 tests := []struct { 27 label string 28 ops []op 29 want []int 30 }{ 31 {"empty", nil, nil}, 32 {"singleton", []op{{add, 1}}, []int{1}}, 33 {"add and remove", []op{ 34 {add, 1}, 35 {remove, 1}, 36 }, nil}, 37 {"interleaved and remove", []op{ 38 {add, 1}, 39 {add, 2}, 40 {remove, 1}, 41 {add, 3}, 42 }, []int{2, 3}}, 43 } 44 45 for _, test := range tests { 46 t.Run(test.label, func(t *testing.T) { 47 var s persistent.Set[int] 48 for _, op := range test.ops { 49 switch op.op { 50 case add: 51 s.Add(op.v) 52 case remove: 53 s.Remove(op.v) 54 } 55 } 56 57 if d := diff(&s, test.want); d != "" { 58 t.Errorf("unexpected diff:\n%s", d) 59 } 60 }) 61 } 62 } 63 64 func TestSet_Clone(t *testing.T) { 65 s1 := new(persistent.Set[int]) 66 s1.Add(1) 67 s1.Add(2) 68 s2 := s1.Clone() 69 s1.Add(3) 70 s2.Add(4) 71 if d := diff(s1, []int{1, 2, 3}); d != "" { 72 t.Errorf("s1: unexpected diff:\n%s", d) 73 } 74 if d := diff(s2, []int{1, 2, 4}); d != "" { 75 t.Errorf("s2: unexpected diff:\n%s", d) 76 } 77 } 78 79 func TestSet_AddAll(t *testing.T) { 80 s1 := new(persistent.Set[int]) 81 s1.Add(1) 82 s1.Add(2) 83 s2 := new(persistent.Set[int]) 84 s2.Add(2) 85 s2.Add(3) 86 s2.Add(4) 87 s3 := new(persistent.Set[int]) 88 89 s := new(persistent.Set[int]) 90 s.AddAll(s1) 91 s.AddAll(s2) 92 s.AddAll(s3) 93 94 if d := diff(s1, []int{1, 2}); d != "" { 95 t.Errorf("s1: unexpected diff:\n%s", d) 96 } 97 if d := diff(s2, []int{2, 3, 4}); d != "" { 98 t.Errorf("s2: unexpected diff:\n%s", d) 99 } 100 if d := diff(s3, nil); d != "" { 101 t.Errorf("s3: unexpected diff:\n%s", d) 102 } 103 if d := diff(s, []int{1, 2, 3, 4}); d != "" { 104 t.Errorf("s: unexpected diff:\n%s", d) 105 } 106 } 107 108 func diff[K constraints.Ordered](got *persistent.Set[K], want []K) string { 109 wantSet := make(map[K]struct{}) 110 for _, w := range want { 111 wantSet[w] = struct{}{} 112 } 113 var diff []string 114 got.Range(func(key K) { 115 if _, ok := wantSet[key]; !ok { 116 diff = append(diff, fmt.Sprintf("+%v", key)) 117 } 118 }) 119 for key := range wantSet { 120 if !got.Contains(key) { 121 diff = append(diff, fmt.Sprintf("-%v", key)) 122 } 123 } 124 if len(diff) > 0 { 125 d := new(strings.Builder) 126 for _, l := range diff { 127 fmt.Fprintln(d, l) 128 } 129 return d.String() 130 } 131 return "" 132 }