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

     1  // Copyright 2024 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 workspace
     6  
     7  import (
     8  	"flag"
     9  	"os"
    10  	"os/exec"
    11  	"runtime"
    12  	"strings"
    13  	"testing"
    14  
    15  	. "golang.org/x/tools/gopls/internal/test/integration"
    16  	"golang.org/x/tools/internal/testenv"
    17  )
    18  
    19  var go121bin = flag.String("go121bin", "", "bin directory containing go 1.21 or later")
    20  
    21  // TODO(golang/go#65917): delete this test once we no longer support building
    22  // gopls with older Go versions.
    23  func TestCanHandlePatchVersions(t *testing.T) {
    24  	// This test verifies the fixes for golang/go#66195 and golang/go#66636 --
    25  	// that gopls does not crash when encountering a go version with a patch
    26  	// number in the go.mod file.
    27  	//
    28  	// This is tricky to test, because the regression requires that gopls is
    29  	// built with an older go version, and then the environment is upgraded to
    30  	// have a more recent go. To set up this scenario, the test requires a path
    31  	// to a bin directory containing go1.21 or later.
    32  	if *go121bin == "" {
    33  		t.Skip("-go121bin directory is not set")
    34  	}
    35  
    36  	if runtime.GOOS != "linux" && runtime.GOOS != "darwin" {
    37  		t.Skip("requires linux or darwin") // for PATH separator
    38  	}
    39  
    40  	path := os.Getenv("PATH")
    41  	t.Setenv("PATH", *go121bin+":"+path)
    42  
    43  	const files = `
    44  -- go.mod --
    45  module example.com/bar
    46  
    47  go 1.21.1
    48  
    49  -- p.go --
    50  package bar
    51  
    52  type I interface { string }
    53  `
    54  
    55  	WithOptions(
    56  		EnvVars{
    57  			"PATH": path,
    58  		},
    59  	).Run(t, files, func(t *testing.T, env *Env) {
    60  		env.OpenFile("p.go")
    61  		env.AfterChange(
    62  			NoDiagnostics(ForFile("p.go")),
    63  		)
    64  	})
    65  }
    66  
    67  func TestTypeCheckingFutureVersions(t *testing.T) {
    68  	// This test checks the regression in golang/go#66677, where go/types fails
    69  	// silently when the language version is 1.22.
    70  	//
    71  	// It does this by recreating the scenario of a toolchain upgrade to 1.22, as
    72  	// reported in the issue. For this to work, the test must be able to download
    73  	// toolchains from proxy.golang.org.
    74  	//
    75  	// This is really only a problem for Go 1.21, because with Go 1.23, the bug
    76  	// is fixed, and starting with 1.23 we're going to *require* 1.23 to build
    77  	// gopls.
    78  	//
    79  	// TODO(golang/go#65917): delete this test after Go 1.23 is released and
    80  	// gopls requires the latest Go to build.
    81  	testenv.SkipAfterGo1Point(t, 21)
    82  
    83  	if testing.Short() {
    84  		t.Skip("skipping with -short, as this test uses the network")
    85  	}
    86  
    87  	// If go 1.22.2 is already available in the module cache, reuse it rather
    88  	// than downloading it anew.
    89  	out, err := exec.Command("go", "env", "GOPATH").Output()
    90  	if err != nil {
    91  		t.Fatal(err)
    92  	}
    93  	gopath := strings.TrimSpace(string(out)) // use the ambient 1.22.2 toolchain if available
    94  
    95  	const files = `
    96  -- go.mod --
    97  module example.com/foo
    98  
    99  go 1.22.2
   100  
   101  -- main.go --
   102  package main
   103  
   104  func main() {
   105  	x := 1
   106  }
   107  `
   108  
   109  	WithOptions(
   110  		Modes(Default), // slow test, only run in one mode
   111  		EnvVars{
   112  			"GOPATH":      gopath,
   113  			"GOTOOLCHAIN": "", // not local
   114  			"GOPROXY":     "https://proxy.golang.org",
   115  			"GOSUMDB":     "sum.golang.org",
   116  		},
   117  	).Run(t, files, func(t *testing.T, env *Env) {
   118  		env.OpenFile("main.go")
   119  		env.AfterChange(
   120  			Diagnostics(
   121  				env.AtRegexp("main.go", "x"),
   122  				WithMessage("not used"),
   123  			),
   124  		)
   125  	})
   126  }