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  }