golang.org/x/tools/gopls@v0.15.3/internal/test/integration/completion/completion18_test.go (about)

     1  // Copyright 2021 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  //go:build go1.18
     6  // +build go1.18
     7  
     8  package completion
     9  
    10  import (
    11  	"testing"
    12  
    13  	"golang.org/x/tools/gopls/internal/protocol"
    14  	. "golang.org/x/tools/gopls/internal/test/integration"
    15  )
    16  
    17  // test generic receivers
    18  func TestGenericReceiver(t *testing.T) {
    19  	const files = `
    20  -- go.mod --
    21  module mod.com
    22  
    23  go 1.18
    24  -- main.go --
    25  package main
    26  type SyncMap[K any, V comparable] struct {}
    27  func (s *SyncMap[K,V]) f() {}
    28  type XX[T any] struct {}
    29  type UU[T any] struct {}
    30  func (s SyncMap[XX,string]) g(v UU) {}
    31  `
    32  
    33  	tests := []struct {
    34  		pat  string
    35  		want []string
    36  	}{
    37  		{"s .Syn", []string{"SyncMap[K, V]"}},
    38  		{"Map.X", []string{}}, // This is probably wrong, Maybe "XX"?
    39  		{"v U", []string{"UU", "uint", "uint16", "uint32", "uint64", "uint8", "uintptr"}}, // not U[T]
    40  	}
    41  	Run(t, files, func(t *testing.T, env *Env) {
    42  		env.OpenFile("main.go")
    43  		env.Await(env.DoneWithOpen())
    44  		for _, tst := range tests {
    45  			loc := env.RegexpSearch("main.go", tst.pat)
    46  			loc.Range.Start.Character += uint32(protocol.UTF16Len([]byte(tst.pat)))
    47  			completions := env.Completion(loc)
    48  			result := compareCompletionLabels(tst.want, completions.Items)
    49  			if result != "" {
    50  				t.Errorf("%s: wanted %v", result, tst.want)
    51  				for i, g := range completions.Items {
    52  					t.Errorf("got %d %s %s", i, g.Label, g.Detail)
    53  				}
    54  			}
    55  		}
    56  	})
    57  }
    58  func TestFuzzFunc(t *testing.T) {
    59  	// use the example from the package documentation
    60  	modfile := `
    61  -- go.mod --
    62  module mod.com
    63  
    64  go 1.18
    65  `
    66  	part0 := `package foo
    67  import "testing"
    68  func FuzzNone(f *testing.F) {
    69  	f.Add(12) // better not find this f.Add
    70  }
    71  func FuzzHex(f *testing.F) {
    72  	for _, seed := range [][]byte{{}, {0}, {9}, {0xa}, {0xf}, {1, 2, 3, 4}} {
    73  		f.Ad`
    74  	part1 := `d(seed)
    75  	}
    76  	f.F`
    77  	part2 := `uzz(func(t *testing.T, in []byte) {
    78  		enc := hex.EncodeToString(in)
    79  		out, err := hex.DecodeString(enc)
    80  		if err != nil {
    81  		  f.Failed()
    82  		}
    83  		if !bytes.Equal(in, out) {
    84  		  t.Fatalf("%v: round trip: %v, %s", in, out, f.Name())
    85  		}
    86  	})
    87  }
    88  `
    89  	data := modfile + `-- a_test.go --
    90  ` + part0 + `
    91  -- b_test.go --
    92  ` + part0 + part1 + `
    93  -- c_test.go --
    94  ` + part0 + part1 + part2
    95  
    96  	tests := []struct {
    97  		file   string
    98  		pat    string
    99  		offset uint32 // UTF16 length from the beginning of pat to what the user just typed
   100  		want   []string
   101  	}{
   102  		{"a_test.go", "f.Ad", 3, []string{"Add"}},
   103  		{"c_test.go", " f.F", 4, []string{"Failed"}},
   104  		{"c_test.go", "f.N", 3, []string{"Name"}},
   105  		{"b_test.go", "f.F", 3, []string{"Fuzz(func(t *testing.T, a []byte)", "Fail", "FailNow",
   106  			"Failed", "Fatal", "Fatalf"}},
   107  	}
   108  	Run(t, data, func(t *testing.T, env *Env) {
   109  		for _, test := range tests {
   110  			env.OpenFile(test.file)
   111  			env.Await(env.DoneWithOpen())
   112  			loc := env.RegexpSearch(test.file, test.pat)
   113  			loc.Range.Start.Character += test.offset // character user just typed? will type?
   114  			completions := env.Completion(loc)
   115  			result := compareCompletionLabels(test.want, completions.Items)
   116  			if result != "" {
   117  				t.Errorf("pat %q %q", test.pat, result)
   118  				for i, it := range completions.Items {
   119  					t.Errorf("%d got %q %q", i, it.Label, it.Detail)
   120  				}
   121  			}
   122  		}
   123  	})
   124  }