whatcanGOwrong

This commit is contained in:
2024-09-19 21:38:24 -04:00
commit d0ae4d841d
17908 changed files with 4096831 additions and 0 deletions
@@ -0,0 +1 @@
A file to try to load.
@@ -0,0 +1,5 @@
// File is versions/go.mod after expansion with TestDir()
module golang.org/fake/versions
go 1.21
@@ -0,0 +1,3 @@
// The file will be go1.21 from the go.mod.
package versions // want "mod.go@go1.21"
@@ -0,0 +1,3 @@
//go:build go1.22
package versions // want "post.go@go1.22"
@@ -0,0 +1,3 @@
//go:build go1.20
package versions // want "pre.go@go1.20"
@@ -0,0 +1 @@
package sub // want "sub.go@go1.21"
@@ -0,0 +1,151 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package testfiles provides utilities for writing Go tests with files
// in testdata.
package testfiles
import (
"io"
"io/fs"
"os"
"path/filepath"
"strings"
"testing"
"golang.org/x/tools/txtar"
)
// CopyDirToTmp copies dir to a temporary test directory using
// CopyTestFiles and returns the path to the test directory.
func CopyDirToTmp(t testing.TB, srcdir string) string {
dst := t.TempDir()
if err := CopyFS(dst, os.DirFS(srcdir)); err != nil {
t.Fatal(err)
}
return dst
}
// CopyFS copies the files and directories in src to a
// destination directory dst. Paths to files and directories
// ending in a ".test" extension have the ".test" extension
// removed. This allows tests to hide files whose names have
// special meaning, such as "go.mod" files or "testdata" directories
// from the go command, or ill-formed Go source files from gofmt.
//
// For example if we copy the directory testdata:
//
// testdata/
// go.mod.test
// a/a.go
// b/b.go
//
// The resulting files will be:
//
// dst/
// go.mod
// a/a.go
// b/b.go
func CopyFS(dstdir string, src fs.FS) error {
if err := copyFS(dstdir, src); err != nil {
return err
}
// Collect ".test" paths in lexical order.
var rename []string
err := fs.WalkDir(os.DirFS(dstdir), ".", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if strings.HasSuffix(path, ".test") {
rename = append(rename, path)
}
return nil
})
if err != nil {
return err
}
// Rename the .test paths in reverse lexical order, e.g.
// in d.test/a.test renames a.test to d.test/a then d.test to d.
for i := len(rename) - 1; i >= 0; i-- {
oldpath := filepath.Join(dstdir, rename[i])
newpath := strings.TrimSuffix(oldpath, ".test")
if err != os.Rename(oldpath, newpath) {
return err
}
}
return nil
}
// Copy the files in src to dst.
// Use os.CopyFS when 1.23 can be used in x/tools.
func copyFS(dstdir string, src fs.FS) error {
return fs.WalkDir(src, ".", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
newpath := filepath.Join(dstdir, path)
if d.IsDir() {
return os.MkdirAll(newpath, 0777)
}
r, err := src.Open(path)
if err != nil {
return err
}
defer r.Close()
w, err := os.Create(newpath)
if err != nil {
return err
}
defer w.Close()
_, err = io.Copy(w, r)
return err
})
}
// ExtractTxtar writes each archive file to the corresponding location beneath dir.
//
// TODO(adonovan): move this to txtar package, we need it all the time (#61386).
func ExtractTxtar(dstdir string, ar *txtar.Archive) error {
for _, file := range ar.Files {
name := filepath.Join(dstdir, file.Name)
if err := os.MkdirAll(filepath.Dir(name), 0777); err != nil {
return err
}
if err := os.WriteFile(name, file.Data, 0666); err != nil {
return err
}
}
return nil
}
// ExtractTxtarFileToTmp read a txtar archive on a given path,
// extracts it to a temporary directory, and returns the
// temporary directory.
func ExtractTxtarFileToTmp(t testing.TB, archiveFile string) string {
ar, err := txtar.ParseFile(archiveFile)
if err != nil {
t.Fatal(err)
}
dir := t.TempDir()
err = ExtractTxtar(dir, ar)
if err != nil {
t.Fatal(err)
}
return dir
}
// ExtractTxtarToTmp extracts the given archive to a temp directory, and
// returns that temporary directory.
func ExtractTxtarToTmp(t testing.TB, ar *txtar.Archive) string {
dir := t.TempDir()
err := ExtractTxtar(dir, ar)
if err != nil {
t.Fatal(err)
}
return dir
}
@@ -0,0 +1,55 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package testfiles_test
import (
"os"
"path/filepath"
"testing"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/analysistest"
"golang.org/x/tools/internal/testenv"
"golang.org/x/tools/internal/testfiles"
"golang.org/x/tools/internal/versions"
)
func TestTestDir(t *testing.T) {
t.Skip("Disabled for golang.org/cl/603895. Fix and re-enable.")
testenv.NeedsGo1Point(t, 22)
// TODO(taking): Expose a helper for this pattern?
// dir must contain a go.mod file to be picked up by Run().
// So this pattern or Join(TestDir(t, TestData()), "versions") are
// probably what everyone will want.
dir := testfiles.CopyDirToTmp(t, filepath.Join(analysistest.TestData(), "versions"))
filever := &analysis.Analyzer{
Name: "filever",
Doc: "reports file go versions",
Run: func(pass *analysis.Pass) (any, error) {
for _, file := range pass.Files {
ver := versions.FileVersion(pass.TypesInfo, file)
name := filepath.Base(pass.Fset.Position(file.Package).Filename)
pass.Reportf(file.Package, "%s@%s", name, ver)
}
return nil, nil
},
}
analysistest.Run(t, dir, filever, "golang.org/fake/versions", "golang.org/fake/versions/sub")
}
func TestCopyTestFilesErrors(t *testing.T) {
tmp := t.TempDir() // a real tmp dir
for _, dir := range []string{
filepath.Join(analysistest.TestData(), "not_there"), // dir does not exist
filepath.Join(analysistest.TestData(), "somefile.txt"), // not a dir
} {
err := testfiles.CopyFS(tmp, os.DirFS(dir))
if err == nil {
t.Error("Expected an error from CopyTestFiles")
}
}
}