test: introduce afero-based mock filesystem for hermetic tests

This commit is contained in:
2026-05-23 13:12:15 +01:00
parent 2334ed7922
commit 7bd70bfaeb
10 changed files with 379 additions and 47 deletions
+29
View File
@@ -0,0 +1,29 @@
// Package fsx provides a small filesystem abstraction so file-touching code
// can be tested against an in-memory filesystem.
package fsx
import (
"os"
"github.com/spf13/afero"
)
// FS is the harness-sync filesystem interface — alias for afero.Fs so the
// dependency stays in one place.
type FS = afero.Fs
// OS returns the production OS-backed filesystem.
func OS() FS { return afero.NewOsFs() }
// Mem returns an empty in-memory filesystem for tests.
func Mem() FS { return afero.NewMemMapFs() }
// WriteFile writes data to path on fs.
func WriteFile(fs FS, path string, data []byte, perm os.FileMode) error {
return afero.WriteFile(fs, path, data, perm)
}
// ReadFile reads the named file from fs and returns its contents.
func ReadFile(fs FS, path string) ([]byte, error) {
return afero.ReadFile(fs, path)
}
+34
View File
@@ -0,0 +1,34 @@
package fsx_test
import (
"testing"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/lukaszraczylo/harness-sync/internal/fsx"
)
func TestOSReturnsAferoOsFs(t *testing.T) {
fs := fsx.OS()
require.NotNil(t, fs)
_, ok := fs.(*afero.OsFs)
assert.True(t, ok, "OS() should return *afero.OsFs")
}
func TestMemReturnsAferoMemFs(t *testing.T) {
fs := fsx.Mem()
require.NotNil(t, fs)
_, ok := fs.(*afero.MemMapFs)
assert.True(t, ok, "Mem() should return *afero.MemMapFs")
}
func TestWriteReadRoundtrip(t *testing.T) {
fs := fsx.Mem()
data := []byte("hello world")
require.NoError(t, fsx.WriteFile(fs, "/test.txt", data, 0o644))
got, err := fsx.ReadFile(fs, "/test.txt")
require.NoError(t, err)
assert.Equal(t, data, got)
}