<|start_filename|>assert/cmd/gty-migrate-from-testify/call.go<|end_filename|>
package main

import (
	"bytes"
	"fmt"
	"go/ast"
	"go/format"
	"go/token"
)

// call wraps an testify assert ast.CallExpr and exposes properties of the
// expression to facilitate migrating the expression to a gotest.tools/assert
type call struct {
	fileset *token.FileSet
	expr    *ast.CallExpr
	xIdent  *ast.Ident
	selExpr *ast.SelectorExpr
	assert  string
}

func (c call) String() string {
	buf := new(bytes.Buffer)
	// nolint: errcheck
	format.Node(buf, token.NewFileSet(), c.expr)
	return buf.String()
}

func (c call) StringWithFileInfo() string {
	if c.fileset.File(c.expr.Pos()) == nil {
		return fmt.Sprintf("%s at unknown file", c)
	}
	return fmt.Sprintf("%s at %s:%d", c,
		relativePath(c.fileset.File(c.expr.Pos()).Name()),
		c.fileset.Position(c.expr.Pos()).Line)
}

// testingT returns the first argument of the call, which is assumed to be a
// *ast.Ident of *testing.T or a compatible interface.
func (c call) testingT() ast.Expr {
	if len(c.expr.Args) == 0 {
		return nil
	}
	return c.expr.Args[0]
}

// extraArgs returns the arguments of the expression starting from index
func (c call) extraArgs(index int) []ast.Expr {
	if len(c.expr.Args) <= index {
		return nil
	}
	return c.expr.Args[index:]
}

// args returns a range of arguments from the expression
func (c call) args(from, to int) []ast.Expr {
	return c.expr.Args[from:to]
}

// arg returns a single argument from the expression
func (c call) arg(index int) ast.Expr {
	return c.expr.Args[index]
}

// newCallFromCallExpr returns a new call build from a ast.CallExpr. Returns false
// if the call expression does not have the expected ast nodes.
func newCallFromCallExpr(callExpr *ast.CallExpr, migration migration) (call, bool) {
	c := call{}
	selector, ok := callExpr.Fun.(*ast.SelectorExpr)
	if !ok {
		return c, false
	}
	ident, ok := selector.X.(*ast.Ident)
	if !ok {
		return c, false
	}

	return call{
		fileset: migration.fileset,
		xIdent:  ident,
		selExpr: selector,
		expr:    callExpr,
	}, true
}

// newTestifyCallFromNode returns a call that wraps a valid testify assertion.
// Returns false if the call expression is not a testify assertion.
func newTestifyCallFromNode(callExpr *ast.CallExpr, migration migration) (call, bool) {
	tcall, ok := newCallFromCallExpr(callExpr, migration)
	if !ok {
		return tcall, false
	}

	testifyNewAssignStmt := testifyAssertionsAssignment(tcall, migration)
	switch {
	case testifyNewAssignStmt != nil:
		return updateCallForTestifyNew(tcall, testifyNewAssignStmt, migration)
	case isTestifyPkgCall(tcall, migration):
		tcall.assert = migration.importNames.funcNameFromTestifyName(tcall.xIdent.Name)
		return tcall, true
	}
	return tcall, false
}

// isTestifyPkgCall returns true if the call is a testify package-level assertion
// (as apposed to an assertion method on the Assertions type)
//
// TODO: check if the xIdent.Obj.Decl is an import declaration instead of
// assuming that a name matching the import name is always an import. Some code
// may shadow import names, which could lead to incorrect results.
func isTestifyPkgCall(tcall call, migration migration) bool {
	return migration.importNames.matchesTestify(tcall.xIdent)
}

// testifyAssertionsAssignment returns an ast.AssignStmt if the call is a testify
// call from an Assertions object returned from assert.New(t) (not a package level
// assert). Otherwise returns nil.
func testifyAssertionsAssignment(tcall call, migration migration) *ast.AssignStmt {
	if tcall.xIdent.Obj == nil {
		return nil
	}

	assignStmt, ok := tcall.xIdent.Obj.Decl.(*ast.AssignStmt)
	if !ok {
		return nil
	}

	if isAssignmentFromAssertNew(assignStmt, migration) {
		return assignStmt
	}
	return nil
}

func updateCallForTestifyNew(
	tcall call,
	testifyNewAssignStmt *ast.AssignStmt,
	migration migration,
) (call, bool) {
	testifyNewCallExpr := callExprFromAssignment(testifyNewAssignStmt)
	if testifyNewCallExpr == nil {
		return tcall, false
	}
	testifyNewCall, ok := newCallFromCallExpr(testifyNewCallExpr, migration)
	if !ok {
		return tcall, false
	}

	tcall.assert = migration.importNames.funcNameFromTestifyName(testifyNewCall.xIdent.Name)
	tcall.expr = addMissingTestingTArgToCallExpr(tcall.expr, testifyNewCall.testingT())
	return tcall, true
}

// addMissingTestingTArgToCallExpr adds a testingT arg as the first arg of the
// ast.CallExpr and returns a copy of the ast.CallExpr
func addMissingTestingTArgToCallExpr(callExpr *ast.CallExpr, testingT ast.Expr) *ast.CallExpr {
	return &ast.CallExpr{
		Fun:  callExpr.Fun,
		Args: append([]ast.Expr{removePos(testingT)}, callExpr.Args...),
	}
}

func removePos(node ast.Expr) ast.Expr {
	switch typed := node.(type) {
	case *ast.Ident:
		return &ast.Ident{Name: typed.Name}
	}
	return node
}

// TODO: use pkgInfo and walkForType instead?
func isAssignmentFromAssertNew(assign *ast.AssignStmt, migration migration) bool {
	callExpr := callExprFromAssignment(assign)
	if callExpr == nil {
		return false
	}
	tcall, ok := newCallFromCallExpr(callExpr, migration)
	if !ok {
		return false
	}
	if !migration.importNames.matchesTestify(tcall.xIdent) {
		return false
	}

	if len(tcall.expr.Args) != 1 {
		return false
	}
	return tcall.selExpr.Sel.Name == "New"
}

func callExprFromAssignment(assign *ast.AssignStmt) *ast.CallExpr {
	if len(assign.Rhs) != 1 {
		return nil
	}

	callExpr, ok := assign.Rhs[0].(*ast.CallExpr)
	if !ok {
		return nil
	}
	return callExpr
}


<|start_filename|>assert/example_test.go<|end_filename|>
package assert_test

import (
	"fmt"
	"regexp"
	"testing"

	"gotest.tools/v3/assert"
	"gotest.tools/v3/assert/cmp"
)

var t = &testing.T{}

func ExampleAssert_customComparison() {
	regexPattern := func(value string, pattern string) cmp.Comparison {
		return func() cmp.Result {
			re := regexp.MustCompile(pattern)
			if re.MatchString(value) {
				return cmp.ResultSuccess
			}
			return cmp.ResultFailure(
				fmt.Sprintf("%q did not match pattern %q", value, pattern))
		}
	}
	assert.Assert(t, regexPattern("12345.34", `\d+.\d\d`))
}


<|start_filename|>assert/cmd/gty-migrate-from-testify/walktype.go<|end_filename|>
package main

import (
	"go/ast"
	"go/types"

	"golang.org/x/tools/go/loader"
)

// walkForType walks the AST tree and returns the type of the expression
func walkForType(pkgInfo *loader.PackageInfo, node ast.Node) types.Type {
	var result types.Type

	visit := func(node ast.Node) bool {
		if expr, ok := node.(ast.Expr); ok {
			if typeAndValue, ok := pkgInfo.Types[expr]; ok {
				result = typeAndValue.Type
				return false
			}
		}
		return true
	}
	ast.Inspect(node, visit)
	return result
}

func isUnknownType(typ types.Type) bool {
	if typ == nil {
		return true
	}
	basic, ok := typ.(*types.Basic)
	return ok && basic.Kind() == types.Invalid
}


<|start_filename|>skip/skip_test.go<|end_filename|>
package skip

import (
	"bytes"
	"fmt"
	"testing"

	"gotest.tools/v3/assert"
	"gotest.tools/v3/assert/cmp"
)

type fakeSkipT struct {
	reason string
	logs   []string
}

func (f *fakeSkipT) Skip(args ...interface{}) {
	buf := new(bytes.Buffer)
	for _, arg := range args {
		buf.WriteString(fmt.Sprintf("%s", arg))
	}
	f.reason = buf.String()
}

func (f *fakeSkipT) Log(args ...interface{}) {
	f.logs = append(f.logs, fmt.Sprintf("%s", args[0]))
}

func (f *fakeSkipT) Helper() {}

func version(v string) string {
	return v
}

func TestIfCondition(t *testing.T) {
	skipT := &fakeSkipT{}
	apiVersion := "v1.4"
	If(skipT, apiVersion < version("v1.6"))

	assert.Equal(t, `apiVersion < version("v1.6")`, skipT.reason)
	assert.Assert(t, cmp.Len(skipT.logs, 0))
}

func TestIfConditionWithMessage(t *testing.T) {
	skipT := &fakeSkipT{}
	apiVersion := "v1.4"
	If(skipT, apiVersion < "v1.6", "see notes")

	assert.Equal(t, `apiVersion < "v1.6": see notes`, skipT.reason)
	assert.Assert(t, cmp.Len(skipT.logs, 0))
}

func TestIfConditionMultiline(t *testing.T) {
	skipT := &fakeSkipT{}
	apiVersion := "v1.4"
	If(
		skipT,
		apiVersion < "v1.6")

	assert.Equal(t, `apiVersion < "v1.6"`, skipT.reason)
	assert.Assert(t, cmp.Len(skipT.logs, 0))
}

func TestIfConditionMultilineWithMessage(t *testing.T) {
	skipT := &fakeSkipT{}
	apiVersion := "v1.4"
	If(
		skipT,
		apiVersion < "v1.6",
		"see notes")

	assert.Equal(t, `apiVersion < "v1.6": see notes`, skipT.reason)
	assert.Assert(t, cmp.Len(skipT.logs, 0))
}

func TestIfConditionNoSkip(t *testing.T) {
	skipT := &fakeSkipT{}
	If(skipT, false)

	assert.Equal(t, "", skipT.reason)
	assert.Assert(t, cmp.Len(skipT.logs, 0))
}

func SkipBecauseISaidSo() bool {
	return true
}

func TestIf(t *testing.T) {
	skipT := &fakeSkipT{}
	If(skipT, SkipBecauseISaidSo)

	assert.Equal(t, "SkipBecauseISaidSo", skipT.reason)
}

func TestIfWithMessage(t *testing.T) {
	skipT := &fakeSkipT{}
	If(skipT, SkipBecauseISaidSo, "see notes")

	assert.Equal(t, "SkipBecauseISaidSo: see notes", skipT.reason)
}

func TestIf_InvalidCondition(t *testing.T) {
	skipT := &fakeSkipT{}
	assert.Assert(t, cmp.Panics(func() {
		If(skipT, "just a string")
	}))
}

func TestIfWithSkipResultFunc(t *testing.T) {
	t.Run("no extra message", func(t *testing.T) {
		skipT := &fakeSkipT{}
		If(skipT, alwaysSkipWithMessage)

		assert.Equal(t, "alwaysSkipWithMessage: skip because I said so!", skipT.reason)
	})
	t.Run("with extra message", func(t *testing.T) {
		skipT := &fakeSkipT{}
		If(skipT, alwaysSkipWithMessage, "also %v", 4)

		assert.Equal(t, "alwaysSkipWithMessage: skip because I said so!: also 4", skipT.reason)
	})
}

func alwaysSkipWithMessage() Result {
	return skipResult{}
}

type skipResult struct{}

func (s skipResult) Skip() bool {
	return true
}

func (s skipResult) Message() string {
	return "skip because I said so!"
}


<|start_filename|>poll/poll_test.go<|end_filename|>
package poll

import (
	"fmt"
	"testing"
	"time"

	"github.com/pkg/errors"
	"gotest.tools/v3/assert"
	"gotest.tools/v3/assert/cmp"
)

type fakeT struct {
	failed string
}

func (t *fakeT) Fatalf(format string, args ...interface{}) {
	t.failed = fmt.Sprintf(format, args...)
	panic("exit wait on")
}

func (t *fakeT) Log(args ...interface{}) {}

func (t *fakeT) Logf(format string, args ...interface{}) {}

func TestWaitOn(t *testing.T) {
	counter := 0
	end := 4
	check := func(t LogT) Result {
		if counter == end {
			return Success()
		}
		counter++
		return Continue("counter is at %d not yet %d", counter-1, end)
	}

	WaitOn(t, check, WithDelay(0))
	assert.Equal(t, end, counter)
}

func TestWaitOnWithTimeout(t *testing.T) {
	fakeT := &fakeT{}

	check := func(t LogT) Result {
		return Continue("not done")
	}

	assert.Assert(t, cmp.Panics(func() {
		WaitOn(fakeT, check, WithTimeout(time.Millisecond))
	}))
	assert.Equal(t, "timeout hit after 1ms: not done", fakeT.failed)
}

func TestWaitOnWithCheckTimeout(t *testing.T) {
	fakeT := &fakeT{}

	check := func(t LogT) Result {
		time.Sleep(1 * time.Second)
		return Continue("not done")
	}

	assert.Assert(t, cmp.Panics(func() { WaitOn(fakeT, check, WithTimeout(time.Millisecond)) }))
	assert.Equal(t, "timeout hit after 1ms: first check never completed", fakeT.failed)
}

func TestWaitOnWithCheckError(t *testing.T) {
	fakeT := &fakeT{}

	check := func(t LogT) Result {
		return Error(errors.New("broke"))
	}

	assert.Assert(t, cmp.Panics(func() { WaitOn(fakeT, check) }))
	assert.Equal(t, "polling check failed: broke", fakeT.failed)
}

func TestWaitOn_WithCompare(t *testing.T) {
	fakeT := &fakeT{}

	check := func(t LogT) Result {
		return Compare(cmp.Equal(3, 4))
	}

	assert.Assert(t, cmp.Panics(func() {
		WaitOn(fakeT, check, WithDelay(0), WithTimeout(10*time.Millisecond))
	}))
	assert.Assert(t, cmp.Contains(fakeT.failed, "assertion failed: 3 (int) != 4 (int)"))
}


<|start_filename|>icmd/example_test.go<|end_filename|>
package icmd_test

import (
	"testing"

	"gotest.tools/v3/icmd"
)

var t = &testing.T{}

func ExampleRunCommand() {
	result := icmd.RunCommand("bash", "-c", "echo all good")
	result.Assert(t, icmd.Success)
}

func ExampleRunCmd() {
	result := icmd.RunCmd(icmd.Command("cat", "/does/not/exist"))
	result.Assert(t, icmd.Expected{
		ExitCode: 1,
		Err:      "cat: /does/not/exist: No such file or directory",
	})
}


<|start_filename|>skip/example_test.go<|end_filename|>
package skip_test

import (
	"testing"

	"gotest.tools/v3/skip"
)

var apiVersion = ""

type env struct{}

func (e env) hasFeature(_ string) bool { return false }

var testEnv = env{}

func MissingFeature() bool { return false }

var t = &testing.T{}

func ExampleIf() {
	//   --- SKIP: TestName (0.00s)
	//           skip.go:19: MissingFeature
	skip.If(t, MissingFeature)

	//   --- SKIP: TestName (0.00s)
	//           skip.go:19: MissingFeature: coming soon
	skip.If(t, MissingFeature, "coming soon")
}

func ExampleIf_withExpression() {
	//   --- SKIP: TestName (0.00s)
	//           skip.go:19: apiVersion < version("v1.24")
	skip.If(t, apiVersion < version("v1.24"))

	//   --- SKIP: TestName (0.00s)
	//           skip.go:19: !textenv.hasFeature("build"): coming soon
	skip.If(t, !testEnv.hasFeature("build"), "coming soon")
}

func version(v string) string {
	return v
}


<|start_filename|>icmd/internal/stub/main.go<|end_filename|>
package main

import (
	"flag"
	"fmt"
	"os"
	"time"
)

func main() {
	sleep := flag.Duration("sleep", 0, "Sleep")
	warn := flag.Bool("warn", false, "Warn")
	fail := flag.Int("fail", 0, "Fail with code")
	flag.Parse()

	if *sleep != 0 {
		time.Sleep(*sleep)
	}

	fmt.Println("this is stdout")
	if *warn {
		fmt.Fprintln(os.Stderr, "this is stderr")
	}

	os.Exit(*fail)
}


<|start_filename|>Dockerfile<|end_filename|>

ARG     GOLANG_VERSION
FROM    golang:${GOLANG_VERSION:-1.12-alpine} as golang
RUN     apk add -U curl git bash
WORKDIR /go/src/gotest.tools
ENV     CGO_ENABLED=0 \
        PS1="# " \
        GO111MODULE=on

FROM    golang as tools
RUN     go get github.com/dnephin/filewatcher@v0.3.2

ARG     DEP_TAG=v0.4.1
RUN     export GO111MODULE=off; \
        go get -d github.com/golang/dep/cmd/dep && \
        cd /go/src/github.com/golang/dep && \
        git checkout -q "$DEP_TAG" && \
        go build -o /usr/bin/dep ./cmd/dep

RUN     go get gotest.tools/gotestsum@v0.3.3
RUN     wget -O- -q https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s && \
            mv bin/golangci-lint /go/bin


FROM    golang as dev
COPY    --from=tools /go/bin/filewatcher /usr/bin/filewatcher
COPY    --from=tools /usr/bin/dep /usr/bin/dep
COPY    --from=tools /go/bin/gotestsum /usr/bin/gotestsum
COPY    --from=tools /go/bin/golangci-lint /usr/bin/golangci-lint


FROM    dev as dev-with-source
COPY    . .


<|start_filename|>golden/example_test.go<|end_filename|>
package golden_test

import (
	"testing"

	"gotest.tools/v3/assert"
	"gotest.tools/v3/golden"
)

var t = &testing.T{}

func ExampleAssert() {
	golden.Assert(t, "foo", "foo-content.golden")
}

func ExampleString() {
	assert.Assert(t, golden.String("foo", "foo-content.golden"))
}

func ExampleAssertBytes() {
	golden.AssertBytes(t, []byte("foo"), "foo-content.golden")
}


<|start_filename|>env/example_test.go<|end_filename|>
package env

import "testing"

var t = &testing.T{}

// Patch an environment variable and defer to return to the previous state
func ExamplePatch() {
	defer Patch(t, "PATH", "/custom/path")()
}

// Patch all environment variables
func ExamplePatchAll() {
	defer PatchAll(t, map[string]string{
		"ONE": "FOO",
		"TWO": "BAR",
	})()
}


<|start_filename|>env/env_test.go<|end_filename|>
package env

import (
	"os"
	"runtime"
	"sort"
	"testing"

	"gotest.tools/v3/assert"
	"gotest.tools/v3/fs"
	"gotest.tools/v3/internal/source"
	"gotest.tools/v3/skip"
)

func TestPatchFromUnset(t *testing.T) {
	key, value := "FOO_IS_UNSET", "VALUE"
	revert := Patch(t, key, value)

	assert.Assert(t, value == os.Getenv(key))
	revert()
	_, isSet := os.LookupEnv(key)
	assert.Assert(t, !isSet)
}

func TestPatch(t *testing.T) {
	skip.If(t, os.Getenv("PATH") == "")
	oldVal := os.Getenv("PATH")

	key, value := "PATH", "NEWVALUE"
	revert := Patch(t, key, value)

	assert.Assert(t, value == os.Getenv(key))
	revert()
	assert.Assert(t, oldVal == os.Getenv(key))
}

func TestPatch_IntegrationWithCleanup(t *testing.T) {
	skip.If(t, source.GoVersionLessThan(1, 14))

	key := "totally_unique_env_var_key"
	t.Run("cleanup in subtest", func(t *testing.T) {
		Patch(t, key, "the-new-value")
		assert.Equal(t, os.Getenv(key), "the-new-value")
	})

	t.Run("env var is unset", func(t *testing.T) {
		v, ok := os.LookupEnv(key)
		assert.Assert(t, !ok, "expected env var to be unset, got %v", v)
	})
}

func TestPatchAll(t *testing.T) {
	oldEnv := os.Environ()
	newEnv := map[string]string{
		"FIRST": "STARS",
		"THEN":  "MOON",
	}

	revert := PatchAll(t, newEnv)

	actual := os.Environ()
	sort.Strings(actual)
	assert.DeepEqual(t, []string{"FIRST=STARS", "THEN=MOON"}, actual)

	revert()
	assert.DeepEqual(t, sorted(oldEnv), sorted(os.Environ()))
}

func TestPatchAllWindows(t *testing.T) {
	skip.If(t, runtime.GOOS != "windows")
	oldEnv := os.Environ()
	newEnv := map[string]string{
		"FIRST":  "STARS",
		"THEN":   "MOON",
		"=FINAL": "SUN",
		"=BAR":   "",
	}

	revert := PatchAll(t, newEnv)

	actual := os.Environ()
	sort.Strings(actual)
	assert.DeepEqual(t, []string{"=BAR=", "=FINAL=SUN", "FIRST=STARS", "THEN=MOON"}, actual)

	revert()
	assert.DeepEqual(t, sorted(oldEnv), sorted(os.Environ()))
}

func sorted(source []string) []string {
	sort.Strings(source)
	return source
}

func TestPatchAll_IntegrationWithCleanup(t *testing.T) {
	skip.If(t, source.GoVersionLessThan(1, 14))

	key := "totally_unique_env_var_key"
	t.Run("cleanup in subtest", func(t *testing.T) {
		PatchAll(t, map[string]string{key: "the-new-value"})
		assert.Equal(t, os.Getenv(key), "the-new-value")
	})

	t.Run("env var is unset", func(t *testing.T) {
		v, ok := os.LookupEnv(key)
		assert.Assert(t, !ok, "expected env var to be unset, got %v", v)
	})
}

func TestToMap(t *testing.T) {
	source := []string{
		"key=value",
		"novaluekey",
		"=foo=bar",
		"z=singlecharkey",
		"b",
		"",
	}
	actual := ToMap(source)
	expected := map[string]string{
		"key":        "value",
		"novaluekey": "",
		"=foo":       "bar",
		"z":          "singlecharkey",
		"b":          "",
		"":           "",
	}
	assert.DeepEqual(t, expected, actual)
}

func TestChangeWorkingDir(t *testing.T) {
	tmpDir := fs.NewDir(t, t.Name())
	defer tmpDir.Remove()

	origWorkDir := pwd(t)

	reset := ChangeWorkingDir(t, tmpDir.Path())
	t.Run("changed to dir", func(t *testing.T) {
		assert.Equal(t, pwd(t), tmpDir.Path())
	})

	t.Run("reset dir", func(t *testing.T) {
		reset()
		assert.Equal(t, pwd(t), origWorkDir)
	})
}

func TestChangeWorkingDir_IntegrationWithCleanup(t *testing.T) {
	skip.If(t, source.GoVersionLessThan(1, 14))

	tmpDir := fs.NewDir(t, t.Name())
	defer tmpDir.Remove()

	origWorkDir := pwd(t)

	t.Run("cleanup in subtest", func(t *testing.T) {
		ChangeWorkingDir(t, tmpDir.Path())
		assert.Equal(t, pwd(t), tmpDir.Path())
	})

	t.Run("working dir is reset", func(t *testing.T) {
		assert.Equal(t, pwd(t), origWorkDir)
	})
}

func pwd(t *testing.T) string {
	t.Helper()
	dir, err := os.Getwd()
	assert.NilError(t, err)
	return dir
}


<|start_filename|>internal/format/diff_test.go<|end_filename|>
package format_test

import (
	"testing"

	"gotest.tools/v3/assert"
	"gotest.tools/v3/golden"
	"gotest.tools/v3/internal/format"
)

func TestUnifiedDiff(t *testing.T) {
	var testcases = []struct {
		name     string
		a        string
		b        string
		expected string
		from     string
		to       string
	}{
		{
			name: "empty diff",
			a:    "a\nb\nc",
			b:    "a\nb\nc",
			from: "from",
			to:   "to",
		},
		{
			name:     "one diff with header",
			a:        "a\nxyz\nc",
			b:        "a\nb\nc",
			from:     "from",
			to:       "to",
			expected: "one-diff-with-header.golden",
		},
		{
			name:     "many diffs",
			a:        "a123\nxyz\nc\nbaba\nz\nt\nj2j2\nok\nok\ndone\n",
			b:        "a123\nxyz\nc\nabab\nz\nt\nj2j2\nok\nok\n",
			expected: "many-diff.golden",
		},
		{
			name:     "no trailing newline",
			a:        "a123\nxyz\nc\nbaba\nz\nt\nj2j2\nok\nok\ndone\n",
			b:        "a123\nxyz\nc\nabab\nz\nt\nj2j2\nok\nok",
			expected: "many-diff-no-trailing-newline.golden",
		},
		{
			name:     "whitespace diff",
			a:        "  something\n      something\n    \v\r\n",
			b:        "  something\n\tsomething\n  \n",
			expected: "whitespace-diff.golden",
		},
	}

	for _, testcase := range testcases {
		t.Run(testcase.name, func(t *testing.T) {
			diff := format.UnifiedDiff(format.DiffConfig{
				A:    testcase.a,
				B:    testcase.b,
				From: testcase.from,
				To:   testcase.to,
			})

			if testcase.expected != "" {
				assert.Assert(t, golden.String(diff, testcase.expected))
				return
			}
			assert.Equal(t, diff, "")
		})
	}
}


<|start_filename|>poll/check_test.go<|end_filename|>
package poll

import (
	"fmt"
	"os"
	"testing"

	"gotest.tools/v3/assert"
)

func TestWaitOnFile(t *testing.T) {
	fakeFilePath := "./fakefile"

	check := FileExists(fakeFilePath)

	t.Run("file does not exist", func(t *testing.T) {
		r := check(t)
		assert.Assert(t, !r.Done())
		assert.Equal(t, r.Message(), fmt.Sprintf("file %s does not exist", fakeFilePath))
	})

	os.Create(fakeFilePath)
	defer os.Remove(fakeFilePath)

	t.Run("file exists", func(t *testing.T) {
		assert.Assert(t, check(t).Done())
	})
}

func TestWaitOnSocketWithTimeout(t *testing.T) {
	t.Run("connection to unavailable address", func(t *testing.T) {
		check := Connection("tcp", "foo.bar:55555")
		r := check(t)
		assert.Assert(t, !r.Done())
		assert.Equal(t, r.Message(), "socket tcp://foo.bar:55555 not available")
	})

	t.Run("connection to ", func(t *testing.T) {
		check := Connection("tcp", "google.com:80")
		assert.Assert(t, check(t).Done())
	})
}


<|start_filename|>x/doc.go<|end_filename|>
/*Package x is a namespace for experimental packages. Packages under x have looser
compatibility requirements. Packages in this namespace may contain backwards
incompatible changes within the same major version.
*/
package x // import "gotest.tools/v3/x"


<|start_filename|>assert/cmd/gty-migrate-from-testify/main.go<|end_filename|>
package main

import (
	"bytes"
	"fmt"
	"go/ast"
	"go/build"
	"go/format"
	"go/parser"
	"go/token"
	"io/ioutil"
	"log"
	"os"
	"path"
	"path/filepath"
	"strings"

	"github.com/pkg/errors"
	"github.com/spf13/pflag"
	"golang.org/x/tools/go/loader"
	"golang.org/x/tools/imports"
)

type options struct {
	pkgs             []string
	dryRun           bool
	debug            bool
	cmpImportName    string
	showLoaderErrors bool
	useAllFiles      bool
}

func main() {
	name := os.Args[0]
	flags, opts := setupFlags(name)
	handleExitError(name, flags.Parse(os.Args[1:]))
	setupLogging(opts)
	opts.pkgs = flags.Args()
	handleExitError(name, run(*opts))
}

func setupLogging(opts *options) {
	log.SetFlags(0)
	enableDebug = opts.debug
}

var enableDebug = false

func debugf(msg string, args ...interface{}) {
	if enableDebug {
		log.Printf("DEBUG: "+msg, args...)
	}
}

func setupFlags(name string) (*pflag.FlagSet, *options) {
	opts := options{}
	flags := pflag.NewFlagSet(name, pflag.ContinueOnError)
	flags.BoolVar(&opts.dryRun, "dry-run", false,
		"don't write changes to file")
	flags.BoolVar(&opts.debug, "debug", false, "enable debug logging")
	flags.StringVar(&opts.cmpImportName, "cmp-pkg-import-alias", "is",
		"import alias to use for the assert/cmp package")
	flags.BoolVar(&opts.showLoaderErrors, "print-loader-errors", false,
		"print errors from loading source")
	flags.BoolVar(&opts.useAllFiles, "ignore-build-tags", false,
		"migrate all files ignoring build tags")
	flags.Usage = func() {
		fmt.Fprintf(os.Stderr, `Usage: %s [OPTIONS] PACKAGE [PACKAGE...]

Migrate calls from testify/{assert|require} to gotest.tools/assert.

%s`, name, flags.FlagUsages())
	}
	return flags, &opts
}

func handleExitError(name string, err error) {
	switch {
	case err == nil:
		return
	case err == pflag.ErrHelp:
		os.Exit(0)
	default:
		log.Println(name + ": Error: " + err.Error())
		os.Exit(3)
	}
}

func run(opts options) error {
	program, err := loadProgram(opts)
	if err != nil {
		return errors.Wrapf(err, "failed to load program")
	}

	pkgs := program.InitialPackages()
	debugf("package count: %d", len(pkgs))

	fileset := program.Fset
	for _, pkg := range pkgs {
		for _, astFile := range pkg.Files {
			absFilename := fileset.File(astFile.Pos()).Name()
			filename := relativePath(absFilename)
			importNames := newImportNames(astFile.Imports, opts)
			if !importNames.hasTestifyImports() {
				debugf("skipping file %s, no imports", filename)
				continue
			}

			debugf("migrating %s with imports: %#v", filename, importNames)
			m := migration{
				file:        astFile,
				fileset:     fileset,
				importNames: importNames,
				pkgInfo:     pkg,
			}
			migrateFile(m)
			if opts.dryRun {
				continue
			}

			raw, err := formatFile(m)
			if err != nil {
				return errors.Wrapf(err, "failed to format %s", filename)
			}

			if err := ioutil.WriteFile(absFilename, raw, 0); err != nil {
				return errors.Wrapf(err, "failed to write file %s", filename)
			}
		}
	}

	return nil
}

func loadProgram(opts options) (*loader.Program, error) {
	fakeImporter, err := newFakeImporter()
	if err != nil {
		return nil, err
	}
	defer fakeImporter.Close()

	conf := loader.Config{
		Fset:        token.NewFileSet(),
		ParserMode:  parser.ParseComments,
		Build:       buildContext(opts),
		AllowErrors: true,
		FindPackage: fakeImporter.Import,
	}
	for _, pkg := range opts.pkgs {
		conf.ImportWithTests(pkg)
	}
	if !opts.showLoaderErrors {
		conf.TypeChecker.Error = func(e error) {}
	}
	program, err := conf.Load()
	if opts.showLoaderErrors {
		for p, pkg := range program.AllPackages {
			if len(pkg.Errors) > 0 {
				fmt.Printf("Package %s loaded with some errors:\n", p.Name())
				for _, err := range pkg.Errors {
					fmt.Println("    ", err.Error())
				}
			}
		}
	}
	return program, err
}

func buildContext(opts options) *build.Context {
	c := build.Default
	c.UseAllFiles = opts.useAllFiles
	if val, ok := os.LookupEnv("GOPATH"); ok {
		c.GOPATH = val
	}
	return &c
}

func relativePath(p string) string {
	cwd, err := os.Getwd()
	if err != nil {
		return p
	}
	rel, err := filepath.Rel(cwd, p)
	if err != nil {
		return p
	}
	return rel
}

type importNames struct {
	testifyAssert  string
	testifyRequire string
	assert         string
	cmp            string
}

func (p importNames) hasTestifyImports() bool {
	return p.testifyAssert != "" || p.testifyRequire != ""
}

func (p importNames) matchesTestify(ident *ast.Ident) bool {
	return ident.Name == p.testifyAssert || ident.Name == p.testifyRequire
}

func (p importNames) funcNameFromTestifyName(name string) string {
	switch name {
	case p.testifyAssert:
		return funcNameCheck
	case p.testifyRequire:
		return funcNameAssert
	default:
		panic("unexpected testify import name " + name)
	}
}

func newImportNames(imports []*ast.ImportSpec, opt options) importNames {
	importNames := importNames{
		assert: path.Base(pkgAssert),
		cmp:    path.Base(pkgCmp),
	}
	for _, spec := range imports {
		switch strings.Trim(spec.Path.Value, `"`) {
		case pkgTestifyAssert, pkgGopkgTestifyAssert:
			importNames.testifyAssert = identOrDefault(spec.Name, "assert")
		case pkgTestifyRequire, pkgGopkgTestifyRequire:
			importNames.testifyRequire = identOrDefault(spec.Name, "require")
		default:
			if importedAs(spec, path.Base(pkgAssert)) {
				importNames.assert = "gtyassert"
			}
		}
	}

	if opt.cmpImportName != "" {
		importNames.cmp = opt.cmpImportName
	}
	return importNames
}

func importedAs(spec *ast.ImportSpec, pkg string) bool {
	if path.Base(strings.Trim(spec.Path.Value, `"`)) == pkg {
		return true
	}
	return spec.Name != nil && spec.Name.Name == pkg
}

func identOrDefault(ident *ast.Ident, def string) string {
	if ident != nil {
		return ident.Name
	}
	return def
}

func formatFile(migration migration) ([]byte, error) {
	buf := new(bytes.Buffer)
	err := format.Node(buf, migration.fileset, migration.file)
	if err != nil {
		return nil, err
	}
	filename := migration.fileset.File(migration.file.Pos()).Name()
	return imports.Process(filename, buf.Bytes(), nil)
}


<|start_filename|>x/subtest/context_test.go<|end_filename|>
package subtest

import (
	"context"
	"testing"

	"gotest.tools/v3/assert"
)

func TestTestcase_Run_CallsCleanup(t *testing.T) {
	calls := []int{}
	var ctx context.Context
	Run(t, "test-run-cleanup", func(t TestContext) {
		cleanup := func(n int) func() {
			return func() {
				calls = append(calls, n)
			}
		}
		ctx = t.Ctx()
		t.AddCleanup(cleanup(2))
		t.AddCleanup(cleanup(1))
		t.AddCleanup(cleanup(0))
	})
	assert.DeepEqual(t, calls, []int{0, 1, 2})
	assert.Equal(t, ctx.Err(), context.Canceled)
}

func TestTestcase_Run_Parallel(t *testing.T) {
	Run(t, "test-parallel", func(t TestContext) {
		t.Parallel()
	})
}


<|start_filename|>assert/opt/opt.go<|end_filename|>
/*Package opt provides common go-cmp.Options for use with assert.DeepEqual.
 */
package opt // import "gotest.tools/v3/assert/opt"

import (
	"fmt"
	"reflect"
	"strings"
	"time"

	gocmp "github.com/google/go-cmp/cmp"
)

// DurationWithThreshold returns a gocmp.Comparer for comparing time.Duration. The
// Comparer returns true if the difference between the two Duration values is
// within the threshold and neither value is zero.
func DurationWithThreshold(threshold time.Duration) gocmp.Option {
	return gocmp.Comparer(cmpDuration(threshold))
}

func cmpDuration(threshold time.Duration) func(x, y time.Duration) bool {
	return func(x, y time.Duration) bool {
		if x == 0 || y == 0 {
			return false
		}
		delta := x - y
		return delta <= threshold && delta >= -threshold
	}
}

// TimeWithThreshold returns a gocmp.Comparer for comparing time.Time. The
// Comparer returns true if the difference between the two Time values is
// within the threshold and neither value is zero.
func TimeWithThreshold(threshold time.Duration) gocmp.Option {
	return gocmp.Comparer(cmpTime(threshold))
}

func cmpTime(threshold time.Duration) func(x, y time.Time) bool {
	return func(x, y time.Time) bool {
		if x.IsZero() || y.IsZero() {
			return false
		}
		delta := x.Sub(y)
		return delta <= threshold && delta >= -threshold
	}
}

// PathString is a gocmp.FilterPath filter that returns true when path.String()
// matches any of the specs.
//
// The path spec is a dot separated string where each segment is a field name.
// Slices, Arrays, and Maps are always matched against every element in the
// sequence. gocmp.Indirect, gocmp.Transform, and gocmp.TypeAssertion are always
// ignored.
//
// Note: this path filter is not type safe. Incorrect paths will be silently
// ignored. Consider using a type safe path filter for more complex paths.
func PathString(specs ...string) func(path gocmp.Path) bool {
	return func(path gocmp.Path) bool {
		for _, spec := range specs {
			if path.String() == spec {
				return true
			}
		}
		return false
	}
}

// PathDebug is a gocmp.FilerPath filter that always returns false. It prints
// each path it receives. It can be used to debug path matching problems.
func PathDebug(path gocmp.Path) bool {
	fmt.Printf("PATH string=%s gostring=%s\n", path, path.GoString())
	for _, step := range path {
		fmt.Printf("  STEP %s\ttype=%s\t%s\n",
			formatStepType(step), step.Type(), stepTypeFields(step))
	}
	return false
}

func formatStepType(step gocmp.PathStep) string {
	return strings.Title(strings.TrimPrefix(reflect.TypeOf(step).String(), "*cmp."))
}

func stepTypeFields(step gocmp.PathStep) string {
	switch typed := step.(type) {
	case gocmp.StructField:
		return fmt.Sprintf("name=%s", typed.Name())
	case gocmp.MapIndex:
		return fmt.Sprintf("key=%s", typed.Key().Interface())
	case gocmp.Transform:
		return fmt.Sprintf("name=%s", typed.Name())
	case gocmp.SliceIndex:
		return fmt.Sprintf("name=%d", typed.Key())
	}
	return ""
}

// PathField is a gocmp.FilerPath filter that matches a struct field by name.
// PathField will match every instance of the field in a recursive or nested
// structure.
func PathField(structType interface{}, field string) func(gocmp.Path) bool {
	typ := reflect.TypeOf(structType)
	if typ.Kind() != reflect.Struct {
		panic(fmt.Sprintf("type %s is not a struct", typ))
	}
	if _, ok := typ.FieldByName(field); !ok {
		panic(fmt.Sprintf("type %s does not have field %s", typ, field))
	}

	return func(path gocmp.Path) bool {
		return path.Index(-2).Type() == typ && isStructField(path.Index(-1), field)
	}
}

func isStructField(step gocmp.PathStep, name string) bool {
	field, ok := step.(gocmp.StructField)
	return ok && field.Name() == name
}


<|start_filename|>assert/cmd/gty-migrate-from-testify/doc.go<|end_filename|>
/*

Command gty-migrate-from-testify migrates packages from
testify/assert and testify/require to gotest.tools/assert.

	$ go get gotest.tools/assert/cmd/gty-migrate-from-testify

Usage:

	gty-migrate-from-testify [OPTIONS] PACKAGE [PACKAGE...]

See --help for full usage.


To run on all packages (including external test packages) use:

	go list \
		-f '{{.ImportPath}} {{if .XTestGoFiles}}{{"\n"}}{{.ImportPath}}_test{{end}}' \
		./... | xargs gty-migrate-from-testify

*/
package main
