Skip to content

Commit 0c148a6

Browse files
committed
Implement testing.TB.Chdir, added in go 1.24
1 parent 05ed01f commit 0c148a6

6 files changed

Lines changed: 123 additions & 5 deletions

File tree

fake_coverage_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func TestTBCoverage(t *testing.T) {
3737

3838
mn := m.Name
3939
// TODO(prashant): Implement new methods added in 1.24 before release.
40-
if mn == "Chdir" || mn == "Context" {
40+
if mn == "Context" {
4141
continue
4242
}
4343
if _, ok := ftSet[mn]; !ok {

fake_tb.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package faket
33
import (
44
"fmt"
55
"os"
6+
"path/filepath"
67
"runtime"
78
"strings"
89
"sync"
@@ -415,3 +416,37 @@ func (tb *fakeTB) TempDir() string {
415416

416417
return d
417418
}
419+
420+
func (tb *fakeTB) Chdir(dir string) {
421+
oldWd, err := os.Open(".")
422+
if err != nil {
423+
// Match stdlib error.
424+
tb.Fatal(err)
425+
}
426+
if err := os.Chdir(dir); err != nil {
427+
// Match stdlib error.
428+
tb.Fatal(err)
429+
}
430+
431+
// Similar to stdlib, on POSIX, set PWD.
432+
switch runtime.GOOS {
433+
case "windows", "plan9":
434+
// Windows and Plan 9 do not use the PWD variable.
435+
default:
436+
if !filepath.IsAbs(dir) {
437+
dir, err = os.Getwd()
438+
if err != nil {
439+
tb.Fatal(err)
440+
}
441+
}
442+
tb.Setenv("PWD", dir)
443+
}
444+
445+
tb.Cleanup(func() {
446+
defer oldWd.Close() //nolint:errcheck // best-effort close to avoid leaks.
447+
if err := oldWd.Chdir(); err != nil {
448+
// Note: The stdlib implementation panics here, but we avoid panics.
449+
tb.Errorf("ChDir failed to ChDir to original directory: %v", err)
450+
}
451+
})
452+
}

integration_1_24_test.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//go:build go1.24
2+
3+
package faket_test
4+
5+
import (
6+
"os"
7+
"regexp"
8+
"strings"
9+
"testing"
10+
11+
"github.com/prashantv/faket/internal/cmptest"
12+
"github.com/prashantv/faket/internal/want"
13+
)
14+
15+
func TestCmp_Chdir(t *testing.T) {
16+
t.Run("to non-existent", func(t *testing.T) {
17+
// ChDir failures are reported by testing.go in stdlib
18+
// and similarly fake_tb.go with faket.
19+
opts := cmptest.Opts{
20+
LogReplace: func(s string) string {
21+
s = regexp.MustCompile("testing.go:[0-9]+").ReplaceAllString(s, "testing.go:Chdir")
22+
s = strings.ReplaceAll(s, "fake_tb.go:428", "testing.go:Chdir")
23+
return s
24+
},
25+
}
26+
cmptest.CompareOpts(t, opts, func(t testing.TB) {
27+
t.Chdir("./does/not/exist")
28+
t.Log("skipped (due to fatal in ChDir)")
29+
})
30+
})
31+
32+
mustGetWd := func() string {
33+
wd, err := os.Getwd()
34+
want.NoErr(t, err)
35+
return wd
36+
}
37+
38+
initialWD := mustGetWd()
39+
initialPWD := os.Getenv("PWD")
40+
41+
stripWD := func(s string) string {
42+
return strings.ReplaceAll(s, initialWD, "/path/to/faket")
43+
}
44+
45+
t.Run("success", func(t *testing.T) {
46+
cmptest.Compare(t, func(t testing.TB) {
47+
t.Chdir("./testdata")
48+
49+
wd, err := os.Getwd()
50+
want.NoErr(t, err)
51+
t.Log("wd is", stripWD(wd))
52+
t.Log("PWD is", stripWD(os.Getenv("PWD")))
53+
})
54+
})
55+
56+
postWD := mustGetWd()
57+
postPWD := os.Getenv("PWD")
58+
want.Equal(t, "Getwd", postWD, initialWD)
59+
want.Equal(t, "PWD", postPWD, initialPWD)
60+
}

internal/cmptest/cmptest.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ func Compare(t *testing.T, f func(testing.TB)) {
6363

6464
// Opts are options for comparing faket to a real test run.
6565
type Opts struct {
66-
WantPanic bool
66+
WantPanic bool
67+
LogReplace func(string) string
6768
}
6869

6970
// CompareOpts is the same as Compare, but supports options for customizing comparisons.
@@ -127,7 +128,14 @@ func CompareOpts(t *testing.T, opts Opts, f func(t testing.TB)) {
127128
}
128129
}
129130

131+
wantLogs := wantOutput.String()
132+
gotLogs := logs.String()
133+
if opts.LogReplace != nil {
134+
wantLogs = opts.LogReplace(wantLogs)
135+
gotLogs = opts.LogReplace(gotLogs)
136+
}
137+
130138
want.Equal(t, "result event", resultEvent, true)
131-
want.Equal(t, "log output", logs.String(), wantOutput.String())
139+
want.Equal(t, "log output", gotLogs, wantLogs)
132140
want.Equal(t, "panicked", res.Panicked(), opts.WantPanic)
133141
}

internal/panictests/p1/testdata/cmp_test_results.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
{"Time":"2022-06-11T00:00:00.0Z","Action":"output","Package":"github.com/prashantv/faket/internal/panictests/p1","Test":"TestCmp_Panic","Output":"\truntime/panic.go:1 +0x0000\n"}
1717
{"Time":"2022-06-11T00:00:00.0Z","Action":"output","Package":"github.com/prashantv/faket/internal/panictests/p1","Test":"TestCmp_Panic","Output":"github.com/prashantv/faket/internal/panictests/p1.TestCmp_Panic.func1({0x0000, 0x0000})\n"}
1818
{"Time":"2022-06-11T00:00:00.0Z","Action":"output","Package":"github.com/prashantv/faket/internal/panictests/p1","Test":"TestCmp_Panic","Output":"\tgithub.com/prashantv/faket/internal/panictests/p1/panic_1_test.go:15 +0x0000\n"}
19-
{"Time":"2022-06-11T00:00:00.0Z","Action":"output","Package":"github.com/prashantv/faket/internal/panictests/p1","Test":"TestCmp_Panic","Output":"github.com/prashantv/faket/internal/cmptest.CompareOpts(0x0000, {0x0000?}, 0x0000?)\n"}
20-
{"Time":"2022-06-11T00:00:00.0Z","Action":"output","Package":"github.com/prashantv/faket/internal/panictests/p1","Test":"TestCmp_Panic","Output":"\tgithub.com/prashantv/faket/internal/cmptest/cmptest.go:77 +0x0000\n"}
19+
{"Time":"2022-06-11T00:00:00.0Z","Action":"output","Package":"github.com/prashantv/faket/internal/panictests/p1","Test":"TestCmp_Panic","Output":"github.com/prashantv/faket/internal/cmptest.CompareOpts(0x0000, {0x0000?, 0x0000?}, 0x0000?)\n"}
20+
{"Time":"2022-06-11T00:00:00.0Z","Action":"output","Package":"github.com/prashantv/faket/internal/panictests/p1","Test":"TestCmp_Panic","Output":"\tgithub.com/prashantv/faket/internal/cmptest/cmptest.go:78 +0x0000\n"}
2121
{"Time":"2022-06-11T00:00:00.0Z","Action":"output","Package":"github.com/prashantv/faket/internal/panictests/p1","Test":"TestCmp_Panic","Output":"github.com/prashantv/faket/internal/panictests/p1.TestCmp_Panic(0x0000?)\n"}
2222
{"Time":"2022-06-11T00:00:00.0Z","Action":"output","Package":"github.com/prashantv/faket/internal/panictests/p1","Test":"TestCmp_Panic","Output":"\tgithub.com/prashantv/faket/internal/panictests/p1/panic_1_test.go:11 +0x0000\n"}
2323
{"Time":"2022-06-11T00:00:00.0Z","Action":"output","Package":"github.com/prashantv/faket/internal/panictests/p1","Test":"TestCmp_Panic","Output":"testing.tRunner(0x0000, 0x0000)\n"}

testdata/cmp_test_results.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,19 @@
11
{"Time":"2022-06-11T00:00:00.0Z","Action":"start","Package":"github.com/prashantv/faket"}
2+
{"Time":"2022-06-11T00:00:00.0Z","Action":"run","Package":"github.com/prashantv/faket","Test":"TestCmp_Chdir"}
3+
{"Time":"2022-06-11T00:00:00.0Z","Action":"output","Package":"github.com/prashantv/faket","Test":"TestCmp_Chdir","Output":"=== RUN TestCmp_Chdir\n"}
4+
{"Time":"2022-06-11T00:00:00.0Z","Action":"run","Package":"github.com/prashantv/faket","Test":"TestCmp_Chdir/to_non-existent"}
5+
{"Time":"2022-06-11T00:00:00.0Z","Action":"output","Package":"github.com/prashantv/faket","Test":"TestCmp_Chdir/to_non-existent","Output":"=== RUN TestCmp_Chdir/to_non-existent\n"}
6+
{"Time":"2022-06-11T00:00:00.0Z","Action":"output","Package":"github.com/prashantv/faket","Test":"TestCmp_Chdir/to_non-existent","Output":" testing.go:1358: chdir ./does/not/exist: no such file or directory\n"}
7+
{"Time":"2022-06-11T00:00:00.0Z","Action":"run","Package":"github.com/prashantv/faket","Test":"TestCmp_Chdir/success"}
8+
{"Time":"2022-06-11T00:00:00.0Z","Action":"output","Package":"github.com/prashantv/faket","Test":"TestCmp_Chdir/success","Output":"=== RUN TestCmp_Chdir/success\n"}
9+
{"Time":"2022-06-11T00:00:00.0Z","Action":"output","Package":"github.com/prashantv/faket","Test":"TestCmp_Chdir/success","Output":" integration_1_24_test.go:51: wd is /path/to/faket/testdata\n"}
10+
{"Time":"2022-06-11T00:00:00.0Z","Action":"output","Package":"github.com/prashantv/faket","Test":"TestCmp_Chdir/success","Output":" integration_1_24_test.go:52: PWD is /path/to/faket/testdata\n"}
11+
{"Time":"2022-06-11T00:00:00.0Z","Action":"output","Package":"github.com/prashantv/faket","Test":"TestCmp_Chdir","Output":"--- FAIL: TestCmp_Chdir (0.01s)\n"}
12+
{"Time":"2022-06-11T00:00:00.0Z","Action":"output","Package":"github.com/prashantv/faket","Test":"TestCmp_Chdir/to_non-existent","Output":" --- FAIL: TestCmp_Chdir/to_non-existent (0.01s)\n"}
13+
{"Time":"2022-06-11T00:00:00.0Z","Action":"fail","Package":"github.com/prashantv/faket","Test":"TestCmp_Chdir/to_non-existent","Elapsed":0}
14+
{"Time":"2022-06-11T00:00:00.0Z","Action":"output","Package":"github.com/prashantv/faket","Test":"TestCmp_Chdir/success","Output":" --- PASS: TestCmp_Chdir/success (0.01s)\n"}
15+
{"Time":"2022-06-11T00:00:00.0Z","Action":"pass","Package":"github.com/prashantv/faket","Test":"TestCmp_Chdir/success","Elapsed":0}
16+
{"Time":"2022-06-11T00:00:00.0Z","Action":"fail","Package":"github.com/prashantv/faket","Test":"TestCmp_Chdir","Elapsed":0}
217
{"Time":"2022-06-11T00:00:00.0Z","Action":"run","Package":"github.com/prashantv/faket","Test":"TestCmp_Success"}
318
{"Time":"2022-06-11T00:00:00.0Z","Action":"output","Package":"github.com/prashantv/faket","Test":"TestCmp_Success","Output":"=== RUN TestCmp_Success\n"}
419
{"Time":"2022-06-11T00:00:00.0Z","Action":"output","Package":"github.com/prashantv/faket","Test":"TestCmp_Success","Output":" integration_test.go:20: log1\n"}

0 commit comments

Comments
 (0)