Skip to content

Commit 63d350b

Browse files
committed
Test custom walker integration
Cover selecting a custom walker from treefmt.toml, passing configured walker options, and forwarding requested path filters to the walker command. Use sandbox-compatible bash commands, exact lowercase walker names, and the long-form --clear-cache option in CLI coverage.
1 parent c09bf93 commit 63d350b

2 files changed

Lines changed: 205 additions & 0 deletions

File tree

cmd/root_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1814,6 +1814,65 @@ func TestJujutsu(t *testing.T) {
18141814
)
18151815
}
18161816

1817+
func TestCustomWalker(t *testing.T) {
1818+
tempDir := test.TempExamples(t)
1819+
configPath := filepath.Join(tempDir, "/treefmt.toml")
1820+
1821+
test.ChangeWorkDir(t, tempDir)
1822+
1823+
cfg := &config.Config{
1824+
Walk: "mywalker",
1825+
WalkerConfigs: map[string]*config.Walker{
1826+
"mywalker": {
1827+
Command: "bash",
1828+
Options: []string{
1829+
"-c",
1830+
`if [ "$#" -eq 0 ]; then set -- go haskell; fi
1831+
for path in "$@"; do
1832+
case "$path" in
1833+
go) printf '%s\n' go/main.go go/go.mod ;;
1834+
haskell) printf '%s\n' haskell/Foo.hs ;;
1835+
*) printf '%s\n' "$path" ;;
1836+
esac
1837+
done`,
1838+
"custom-walker",
1839+
},
1840+
},
1841+
},
1842+
FormatterConfigs: map[string]*config.Formatter{
1843+
"echo": {
1844+
Command: "echo", // will not generate any underlying changes in the file
1845+
Includes: []string{"*"},
1846+
},
1847+
},
1848+
}
1849+
1850+
test.WriteConfig(t, configPath, cfg)
1851+
1852+
treefmt(t,
1853+
withConfig(configPath, cfg),
1854+
withNoError(t),
1855+
withStats(t, map[stats.Type]int{
1856+
stats.Traversed: 3,
1857+
stats.Matched: 3,
1858+
stats.Formatted: 3,
1859+
stats.Changed: 0,
1860+
}),
1861+
)
1862+
1863+
treefmt(t,
1864+
withArgs("--clear-cache", "go"),
1865+
withConfig(configPath, cfg),
1866+
withNoError(t),
1867+
withStats(t, map[stats.Type]int{
1868+
stats.Traversed: 2,
1869+
stats.Matched: 2,
1870+
stats.Formatted: 2,
1871+
stats.Changed: 0,
1872+
}),
1873+
)
1874+
}
1875+
18171876
func TestTreeRootCmd(t *testing.T) {
18181877
as := require.New(t)
18191878

walk/custom_test.go

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
package walk_test
2+
3+
import (
4+
"context"
5+
"io"
6+
"os"
7+
"path/filepath"
8+
"testing"
9+
"time"
10+
11+
"github.com/numtide/treefmt/v2/stats"
12+
"github.com/numtide/treefmt/v2/test"
13+
"github.com/numtide/treefmt/v2/walk"
14+
"github.com/stretchr/testify/require"
15+
)
16+
17+
func TestCustomReader(t *testing.T) {
18+
as := require.New(t)
19+
20+
tempDir := test.TempExamples(t)
21+
22+
as.NoError(os.Symlink(filepath.Join(tempDir, "go", "main.go"), filepath.Join(tempDir, "link-to-main")))
23+
24+
statz := stats.New()
25+
reader, err := walk.NewCustomReader(tempDir, nil, &statz, walk.CustomConfig{
26+
Name: "mywalker",
27+
Command: "bash",
28+
Options: []string{
29+
"-c",
30+
`for path in "$@"; do printf '%s\n' "$path"; done`,
31+
"walker",
32+
"go/main.go",
33+
"go/go.mod",
34+
"go",
35+
"missing.txt",
36+
"link-to-main",
37+
},
38+
})
39+
as.NoError(err)
40+
41+
files := make([]*walk.File, 8)
42+
ctx, cancel := context.WithTimeout(t.Context(), time.Second)
43+
n, err := reader.Read(ctx, files)
44+
45+
cancel()
46+
47+
as.Equal(2, n)
48+
as.ErrorIs(err, io.EOF)
49+
as.Equal("go/main.go", files[0].RelPath)
50+
as.Equal("go/go.mod", files[1].RelPath)
51+
as.Equal(2, statz.Value(stats.Traversed))
52+
as.NoError(reader.Close())
53+
}
54+
55+
func TestCustomReaderSubpath(t *testing.T) {
56+
as := require.New(t)
57+
58+
tempDir := test.TempExamples(t)
59+
60+
statz := stats.New()
61+
reader, err := walk.NewCustomReader(tempDir, []string{"go"}, &statz, walk.CustomConfig{
62+
Name: "mywalker",
63+
Command: "bash",
64+
Options: []string{
65+
"-c",
66+
"printf '%s\n' go/main.go haskell/Foo.hs go/go.mod",
67+
},
68+
})
69+
as.NoError(err)
70+
71+
files := make([]*walk.File, 8)
72+
ctx, cancel := context.WithTimeout(t.Context(), time.Second)
73+
n, err := reader.Read(ctx, files)
74+
75+
cancel()
76+
77+
as.Equal(2, n)
78+
as.ErrorIs(err, io.EOF)
79+
as.Equal("go/main.go", files[0].RelPath)
80+
as.Equal("go/go.mod", files[1].RelPath)
81+
as.Equal(2, statz.Value(stats.Traversed))
82+
as.NoError(reader.Close())
83+
}
84+
85+
func TestCustomReaderPassesPathFilters(t *testing.T) {
86+
as := require.New(t)
87+
88+
tempDir := test.TempExamples(t)
89+
90+
statz := stats.New()
91+
reader, err := walk.NewCustomReader(tempDir, []string{"go"}, &statz, walk.CustomConfig{
92+
Name: "mywalker",
93+
Command: "bash",
94+
Options: []string{
95+
"-c",
96+
`for path in "$@"; do printf '%s\n' "$path/main.go" "$path/go.mod"; done`,
97+
"walker",
98+
},
99+
})
100+
as.NoError(err)
101+
102+
files := make([]*walk.File, 8)
103+
ctx, cancel := context.WithTimeout(t.Context(), time.Second)
104+
n, err := reader.Read(ctx, files)
105+
106+
cancel()
107+
108+
as.Equal(2, n)
109+
as.ErrorIs(err, io.EOF)
110+
as.Equal("go/main.go", files[0].RelPath)
111+
as.Equal("go/go.mod", files[1].RelPath)
112+
as.Equal(2, statz.Value(stats.Traversed))
113+
as.NoError(reader.Close())
114+
}
115+
116+
func TestCustomReaderCommandFailure(t *testing.T) {
117+
as := require.New(t)
118+
119+
tempDir := test.TempExamples(t)
120+
121+
statz := stats.New()
122+
reader, err := walk.NewCustomReader(tempDir, nil, &statz, walk.CustomConfig{
123+
Name: "mywalker",
124+
Command: "bash",
125+
Options: []string{
126+
"-c",
127+
"printf '%s\n' go/main.go; exit 7",
128+
},
129+
})
130+
as.NoError(err)
131+
132+
files := make([]*walk.File, 8)
133+
ctx, cancel := context.WithTimeout(t.Context(), time.Second)
134+
n, err := reader.Read(ctx, files)
135+
136+
cancel()
137+
138+
as.Equal(1, n)
139+
as.ErrorIs(err, io.EOF)
140+
as.Equal("go/main.go", files[0].RelPath)
141+
142+
err = reader.Close()
143+
as.Error(err)
144+
as.ErrorContains(err, "failed to wait for custom walker mywalker command to complete")
145+
as.ErrorContains(err, "exit status 7")
146+
}

0 commit comments

Comments
 (0)