From 29fc8bff4bc948dea278ba03349df0ae702490df Mon Sep 17 00:00:00 2001 From: Ronak Parmar Date: Tue, 18 Aug 2026 11:15:04 +0530 Subject: [PATCH] test: make "missing path" assertions hermetic Fifteen tool test suites hardcoded absolute paths such as "/nonexistent/file.txt" to assert not-found behaviour. That assumes the path is absent from whatever machine runs the tests -- guaranteed on no platform, and actively wrong on Windows, where "/nonexistent/file.txt" resolves to C:\nonexistent\file.txt, an ordinary and creatable location. When such a path does exist the assertion silently inverts. On a machine with a stray C:\nonexistent\path, TestDu_NonExistent walked a real directory tree, collected zero errors, and failed -- while du itself was behaving correctly. The other fourteen sites carry the same latent fault. Add internal/testutil.MissingPath, which anchors the path to t.TempDir(): a directory the test framework creates empty and removes on cleanup, so the leaf name is reliably absent everywhere. Use it at all fifteen sites. Co-authored-by: u84u Co-Authored-By: Claude Opus 5 --- internal/testutil/paths.go | 21 +++++++++++++++++++++ tools/awk/awk_test.go | 4 +++- tools/cat/cat_test.go | 4 +++- tools/checksums/checksums_test.go | 3 ++- tools/diff/diff_test.go | 4 +++- tools/du/du_test.go | 4 +++- tools/file/file_test.go | 4 +++- tools/find/find_test.go | 4 +++- tools/head/head_test.go | 4 +++- tools/ls/ls_test.go | 4 +++- tools/realpath/realpath_test.go | 4 +++- tools/sed/sed_test.go | 4 +++- tools/stat/stat_test.go | 4 +++- tools/tail/tail_test.go | 4 +++- tools/tar/tar_test.go | 4 +++- tools/wc/wc_test.go | 4 +++- 16 files changed, 65 insertions(+), 15 deletions(-) create mode 100644 internal/testutil/paths.go diff --git a/internal/testutil/paths.go b/internal/testutil/paths.go new file mode 100644 index 0000000..a27445f --- /dev/null +++ b/internal/testutil/paths.go @@ -0,0 +1,21 @@ +// Package testutil provides small helpers shared by aict's tool test suites. +package testutil + +import ( + "path/filepath" + "testing" +) + +// MissingPath returns an absolute path, ending in name, that is guaranteed not +// to exist for the duration of the test. +// +// Tests must not hardcode paths such as "/nonexistent/file.txt". On Windows +// that resolves to an ordinary, creatable location (C:\nonexistent\file.txt) +// which may genuinely exist on a developer's machine — silently inverting the +// assertion, so a "missing path" test starts exercising a real file instead. +// Anchoring to t.TempDir() gives a directory the test framework created empty +// and removes on cleanup, so name is reliably absent on every platform. +func MissingPath(t *testing.T, name string) string { + t.Helper() + return filepath.Join(t.TempDir(), name) +} diff --git a/tools/awk/awk_test.go b/tools/awk/awk_test.go index d90315d..679303c 100644 --- a/tools/awk/awk_test.go +++ b/tools/awk/awk_test.go @@ -6,6 +6,8 @@ import ( "os" "path/filepath" "testing" + + "github.com/synseqack/aict/internal/testutil" ) func createFile(t *testing.T, dir, name, content string) string { @@ -131,7 +133,7 @@ func TestAwk_NR(t *testing.T) { } func TestAwk_MissingFile(t *testing.T) { - result := runAwk(t, []string{"{print $1}", "/nonexistent/file.txt"}) + result := runAwk(t, []string{"{print $1}", testutil.MissingPath(t, "file.txt")}) if len(result.Errors) == 0 { t.Error("expected error for non-existent file") } diff --git a/tools/cat/cat_test.go b/tools/cat/cat_test.go index 9625162..705c588 100644 --- a/tools/cat/cat_test.go +++ b/tools/cat/cat_test.go @@ -6,6 +6,8 @@ import ( "os" "path/filepath" "testing" + + "github.com/synseqack/aict/internal/testutil" ) func createFile(t *testing.T, dir, name, content string) string { @@ -109,7 +111,7 @@ func TestCat_Directory(t *testing.T) { } func TestCat_Missing(t *testing.T) { - result, err := catFile("/nonexistent/missing.txt", Config{}) + result, err := catFile(testutil.MissingPath(t, "missing.txt"), Config{}) if err != nil { t.Fatal(err) } diff --git a/tools/checksums/checksums_test.go b/tools/checksums/checksums_test.go index e8dc459..2c40864 100644 --- a/tools/checksums/checksums_test.go +++ b/tools/checksums/checksums_test.go @@ -14,6 +14,7 @@ import ( "testing" pathutil "github.com/synseqack/aict/internal/path" + "github.com/synseqack/aict/internal/testutil" ) func runChecksums(args []string) (string, error) { @@ -80,7 +81,7 @@ func TestChecksums_NonExistent(t *testing.T) { os.Setenv("AICT_XML", "1") defer os.Unsetenv("AICT_XML") - output, err := runChecksums([]string{"/nonexistent/file.txt"}) + output, err := runChecksums([]string{testutil.MissingPath(t, "file.txt")}) if err != nil { t.Fatal(err) } diff --git a/tools/diff/diff_test.go b/tools/diff/diff_test.go index b70a6d6..c1129ae 100644 --- a/tools/diff/diff_test.go +++ b/tools/diff/diff_test.go @@ -6,6 +6,8 @@ import ( "os" "path/filepath" "testing" + + "github.com/synseqack/aict/internal/testutil" ) func createFile(t *testing.T, dir, name, content string) string { @@ -127,7 +129,7 @@ func TestDiff_MissingFile(t *testing.T) { dir := t.TempDir() existing := createFile(t, dir, "a.txt", "hello\n") - result := runDiff(t, []string{existing, "/nonexistent/missing.txt"}) + result := runDiff(t, []string{existing, testutil.MissingPath(t, "missing.txt")}) if len(result.Errors) == 0 { t.Error("expected error for missing file") } diff --git a/tools/du/du_test.go b/tools/du/du_test.go index 98d985e..d4c3d44 100644 --- a/tools/du/du_test.go +++ b/tools/du/du_test.go @@ -6,6 +6,8 @@ import ( "os" "path/filepath" "testing" + + "github.com/synseqack/aict/internal/testutil" ) func runDu(args []string) (string, error) { @@ -156,7 +158,7 @@ func TestDu_NonExistent(t *testing.T) { r, w, _ := os.Pipe() os.Stdout = w - err := Run([]string{"/nonexistent/path"}) + err := Run([]string{testutil.MissingPath(t, "path")}) w.Close() os.Stdout = oldStdout diff --git a/tools/file/file_test.go b/tools/file/file_test.go index a0af2e6..ebbe0aa 100644 --- a/tools/file/file_test.go +++ b/tools/file/file_test.go @@ -7,6 +7,8 @@ import ( "path/filepath" "runtime" "testing" + + "github.com/synseqack/aict/internal/testutil" ) func runFile(args []string) (string, error) { @@ -156,7 +158,7 @@ func TestFile_Executable(t *testing.T) { } func TestFile_NonExistent(t *testing.T) { - result, err := runFileWithOutput("/nonexistent/path/file.txt", Config{XML: true}) + result, err := runFileWithOutput(testutil.MissingPath(t, "file.txt"), Config{XML: true}) if err != nil { t.Fatal(err) } diff --git a/tools/find/find_test.go b/tools/find/find_test.go index a55e67f..bfe9ec5 100644 --- a/tools/find/find_test.go +++ b/tools/find/find_test.go @@ -6,6 +6,8 @@ import ( "os" "path/filepath" "testing" + + "github.com/synseqack/aict/internal/testutil" ) func createFile(t *testing.T, dir, name, content string) string { @@ -147,7 +149,7 @@ func TestFind_Invert(t *testing.T) { } func TestFind_Missing(t *testing.T) { - result := runFind(t, []string{"/nonexistent/directory"}) + result := runFind(t, []string{testutil.MissingPath(t, "directory")}) if len(result.Errors) == 0 { t.Error("expected error for non-existent root") } diff --git a/tools/head/head_test.go b/tools/head/head_test.go index 6f49406..a0d801e 100644 --- a/tools/head/head_test.go +++ b/tools/head/head_test.go @@ -6,6 +6,8 @@ import ( "os" "path/filepath" "testing" + + "github.com/synseqack/aict/internal/testutil" ) func runHead(args []string) (string, error) { @@ -124,7 +126,7 @@ func TestHead_EmptyFile(t *testing.T) { } func TestHead_NonExistent(t *testing.T) { - result, err := runHeadWithOutput("/nonexistent/file.txt", Config{XML: true}) + result, err := runHeadWithOutput(testutil.MissingPath(t, "file.txt"), Config{XML: true}) if err != nil { t.Fatal(err) } diff --git a/tools/ls/ls_test.go b/tools/ls/ls_test.go index 44eb984..4d8b666 100644 --- a/tools/ls/ls_test.go +++ b/tools/ls/ls_test.go @@ -9,6 +9,8 @@ import ( "strings" "testing" "time" + + "github.com/synseqack/aict/internal/testutil" ) func runLS(args []string) (string, error) { @@ -171,7 +173,7 @@ func TestLS_Symlinks(t *testing.T) { } func TestLS_Error_NonExistent(t *testing.T) { - result, err := runLSWithOutput([]string{"/nonexistent/path/that/does/not/exist"}, Config{XML: true}) + result, err := runLSWithOutput([]string{testutil.MissingPath(t, "does-not-exist")}, Config{XML: true}) if err != nil { t.Fatal(err) } diff --git a/tools/realpath/realpath_test.go b/tools/realpath/realpath_test.go index 88565f2..089e6d6 100644 --- a/tools/realpath/realpath_test.go +++ b/tools/realpath/realpath_test.go @@ -6,6 +6,8 @@ import ( "os" "path/filepath" "testing" + + "github.com/synseqack/aict/internal/testutil" ) func runRealpath(args []string) (string, error) { @@ -64,7 +66,7 @@ func TestRealpath_Directory(t *testing.T) { } func TestRealpath_NonExistent(t *testing.T) { - result, err := runRealpathWithOutput("/nonexistent/path/file.txt") + result, err := runRealpathWithOutput(testutil.MissingPath(t, "file.txt")) if err != nil { t.Fatal(err) } diff --git a/tools/sed/sed_test.go b/tools/sed/sed_test.go index ed4b573..1d72dcb 100644 --- a/tools/sed/sed_test.go +++ b/tools/sed/sed_test.go @@ -6,6 +6,8 @@ import ( "os" "path/filepath" "testing" + + "github.com/synseqack/aict/internal/testutil" ) func createFile(t *testing.T, dir, name, content string) string { @@ -167,7 +169,7 @@ func TestSed_RegexAddress(t *testing.T) { } func TestSed_MissingFile(t *testing.T) { - result := runSed(t, []string{"-e", "s/a/b/", "/nonexistent/file.txt"}) + result := runSed(t, []string{"-e", "s/a/b/", testutil.MissingPath(t, "file.txt")}) if len(result.Errors) == 0 { t.Error("expected error for non-existent file") } diff --git a/tools/stat/stat_test.go b/tools/stat/stat_test.go index f111b7d..6184fc2 100644 --- a/tools/stat/stat_test.go +++ b/tools/stat/stat_test.go @@ -6,6 +6,8 @@ import ( "os" "path/filepath" "testing" + + "github.com/synseqack/aict/internal/testutil" ) func createFile(t *testing.T, dir, name, content string) string { @@ -98,7 +100,7 @@ func TestStat_FollowSymlink(t *testing.T) { } func TestStat_Missing(t *testing.T) { - result, err := statPath("/nonexistent/missing.txt", Config{}) + result, err := statPath(testutil.MissingPath(t, "missing.txt"), Config{}) if err != nil { t.Fatal(err) } diff --git a/tools/tail/tail_test.go b/tools/tail/tail_test.go index d107e3d..b163431 100644 --- a/tools/tail/tail_test.go +++ b/tools/tail/tail_test.go @@ -6,6 +6,8 @@ import ( "os" "path/filepath" "testing" + + "github.com/synseqack/aict/internal/testutil" ) func runTail(args []string) (string, error) { @@ -118,7 +120,7 @@ func TestTail_EmptyFile(t *testing.T) { } func TestTail_NonExistent(t *testing.T) { - result, err := runTailWithOutput("/nonexistent/file.txt", Config{XML: true}) + result, err := runTailWithOutput(testutil.MissingPath(t, "file.txt"), Config{XML: true}) if err != nil { t.Fatal(err) } diff --git a/tools/tar/tar_test.go b/tools/tar/tar_test.go index 91e25a4..f275753 100644 --- a/tools/tar/tar_test.go +++ b/tools/tar/tar_test.go @@ -8,6 +8,8 @@ import ( "os" "path/filepath" "testing" + + "github.com/synseqack/aict/internal/testutil" ) func createTar(t *testing.T, dir, name string, files map[string]string) string { @@ -122,7 +124,7 @@ func TestTar_FileTypes(t *testing.T) { } func TestTar_NonExistent(t *testing.T) { - result := runTar(t, []string{"/nonexistent/archive.tar"}) + result := runTar(t, []string{testutil.MissingPath(t, "archive.tar")}) if len(result.Errors) == 0 { t.Error("expected error for non-existent archive") } diff --git a/tools/wc/wc_test.go b/tools/wc/wc_test.go index fa1ee46..74648d6 100644 --- a/tools/wc/wc_test.go +++ b/tools/wc/wc_test.go @@ -6,6 +6,8 @@ import ( "os" "path/filepath" "testing" + + "github.com/synseqack/aict/internal/testutil" ) func createFile(t *testing.T, dir, name, content string) string { @@ -141,7 +143,7 @@ func TestWC_Directory(t *testing.T) { } func TestWC_Missing(t *testing.T) { - result, err := runWC([]string{"/nonexistent/file.txt"}, Config{Lines: true, Words: true, Bytes: true}) + result, err := runWC([]string{testutil.MissingPath(t, "file.txt")}, Config{Lines: true, Words: true, Bytes: true}) if err != nil { t.Fatal(err) }