testable

package
v0.7.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 10, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package testable provides interfaces for mocking external dependencies such as exec.Command and exec.LookPath in tests.

Package testable provides interfaces for abstracting OS-level operations, enabling mock injection in tests without modifying production behavior.

Package testable provides interfaces for mocking external dependencies such as go-git operations. Production code uses the Real* implementations; tests can inject mock implementations to avoid hitting real git repos.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CommandExecutor

type CommandExecutor interface {
	// LookPath searches for an executable named file in the directories
	// named by the PATH environment variable.
	LookPath(file string) (string, error)

	// CommandContext returns an *exec.Cmd configured to run name with the
	// given arguments. The provided context is used for cancellation.
	CommandContext(ctx context.Context, name string, args ...string) *exec.Cmd
}

CommandExecutor abstracts exec.LookPath and exec.CommandContext so that callers (e.g., gitcli) can be tested without a real git binary.

func DefaultExecutor

func DefaultExecutor() CommandExecutor

DefaultExecutor returns a production CommandExecutor backed by the os/exec package.

type FileSystem

type FileSystem interface {
	// Abs returns an absolute representation of path.
	Abs(path string) (string, error)

	// EvalSymlinks returns the path name after the evaluation of any symbolic links.
	EvalSymlinks(path string) (string, error)

	// Stat returns a FileInfo describing the named file.
	Stat(name string) (os.FileInfo, error)

	// Create creates or truncates the named file.
	Create(name string) (*os.File, error)

	// WriteFile writes data to the named file, creating it if necessary.
	WriteFile(name string, data []byte, perm os.FileMode) error

	// ReadFile reads the named file and returns the contents.
	ReadFile(name string) ([]byte, error)

	// MkdirAll creates a directory named path, along with any necessary parents.
	MkdirAll(path string, perm os.FileMode) error

	// WalkDir walks the file tree rooted at root, calling fn for each file or
	// directory in the tree, including root.
	WalkDir(root string, fn fs.WalkDirFunc) error

	// Open opens the named file for reading.
	Open(name string) (*os.File, error)
}

FileSystem abstracts file system operations to enable mock injection in tests. The production implementation (OsFileSystem) delegates to the standard library.

var DefaultFS FileSystem = OsFileSystem{}

DefaultFS is the production FileSystem used as the default throughout the application. All packages should use this as their default when no custom FileSystem is injected.

type GitOpener

type GitOpener interface {
	PlainOpen(path string) (GitRepository, error)
}

GitOpener abstracts opening a git repository. Production code uses RealGitOpener; tests inject a mock to avoid filesystem dependencies.

var DefaultGitOpener GitOpener = RealGitOpener{}

DefaultGitOpener is the production GitOpener used as default.

type GitRepository

type GitRepository interface {
	Head() (*plumbing.Reference, error)
	Log(opts *git.LogOptions) (object.CommitIter, error)
	Remotes() ([]*git.Remote, error)
	References() (storer.ReferenceIter, error)
	CommitObject(h plumbing.Hash) (*object.Commit, error)
	TagObject(h plumbing.Hash) (*object.Tag, error)
	Tags() (storer.ReferenceIter, error)
}

GitRepository abstracts the subset of *git.Repository methods used by stringer. This keeps the interface minimal and easy to mock.

type MockCommandExecutor

type MockCommandExecutor struct {
	// LookPathErr, when non-nil, is returned by LookPath for any file.
	LookPathErr error

	// LookPathResult is returned as the path when LookPathErr is nil.
	LookPathResult string

	// CommandOutputs maps a command key (e.g., "git blame --porcelain") to the
	// stdout that the resulting exec.Cmd should produce. The key is built from
	// the command name and all arguments joined by spaces.
	CommandOutputs map[string]string

	// CommandErrors maps a command key to an error message. When set, the
	// resulting exec.Cmd will fail with that message written to stderr.
	CommandErrors map[string]string

	// DefaultOutput is returned when no key matches in CommandOutputs.
	DefaultOutput string

	// DefaultError, when non-empty, makes every unmatched command fail.
	DefaultError string

	// Calls records the command keys that were invoked, for assertion purposes.
	Calls []string
}

MockCommandExecutor is a test double for CommandExecutor. It can simulate git not found, command failures, and predetermined outputs.

func (*MockCommandExecutor) CommandContext

func (m *MockCommandExecutor) CommandContext(ctx context.Context, name string, args ...string) *exec.Cmd

CommandContext returns an *exec.Cmd that, when executed, produces the pre-configured output or error. It uses "echo" / "false" shell commands to simulate the behaviour without running the real binary.

func (*MockCommandExecutor) LookPath

func (m *MockCommandExecutor) LookPath(_ string) (string, error)

LookPath returns the configured result or error.

type MockFileSystem

type MockFileSystem struct {
	AbsFn          func(path string) (string, error)
	EvalSymlinksFn func(path string) (string, error)
	StatFn         func(name string) (os.FileInfo, error)
	CreateFn       func(name string) (*os.File, error)
	WriteFileFn    func(name string, data []byte, perm os.FileMode) error
	ReadFileFn     func(name string) ([]byte, error)
	MkdirAllFn     func(path string, perm os.FileMode) error
	WalkDirFn      func(root string, fn fs.WalkDirFunc) error
	OpenFn         func(name string) (*os.File, error)
}

MockFileSystem is a test double for FileSystem. Each method has a corresponding function field. When the field is non-nil, the mock calls it; otherwise, it falls through to OsFileSystem (real OS behavior).

This design lets tests override only the methods they care about while keeping realistic behavior for everything else.

func (*MockFileSystem) Abs

func (m *MockFileSystem) Abs(path string) (string, error)

Abs calls AbsFn if set, otherwise delegates to OsFileSystem.

func (*MockFileSystem) Create

func (m *MockFileSystem) Create(name string) (*os.File, error)

Create calls CreateFn if set, otherwise delegates to OsFileSystem.

func (m *MockFileSystem) EvalSymlinks(path string) (string, error)

EvalSymlinks calls EvalSymlinksFn if set, otherwise delegates to OsFileSystem.

func (*MockFileSystem) MkdirAll

func (m *MockFileSystem) MkdirAll(path string, perm os.FileMode) error

MkdirAll calls MkdirAllFn if set, otherwise delegates to OsFileSystem.

func (*MockFileSystem) Open

func (m *MockFileSystem) Open(name string) (*os.File, error)

Open calls OpenFn if set, otherwise delegates to OsFileSystem.

func (*MockFileSystem) ReadFile

func (m *MockFileSystem) ReadFile(name string) ([]byte, error)

ReadFile calls ReadFileFn if set, otherwise delegates to OsFileSystem.

func (*MockFileSystem) Stat

func (m *MockFileSystem) Stat(name string) (os.FileInfo, error)

Stat calls StatFn if set, otherwise delegates to OsFileSystem.

func (*MockFileSystem) WalkDir

func (m *MockFileSystem) WalkDir(root string, fn fs.WalkDirFunc) error

WalkDir calls WalkDirFn if set, otherwise delegates to OsFileSystem.

func (*MockFileSystem) WriteFile

func (m *MockFileSystem) WriteFile(name string, data []byte, perm os.FileMode) error

WriteFile calls WriteFileFn if set, otherwise delegates to OsFileSystem.

type MockGitOpener

type MockGitOpener struct {
	// Repo is the repository returned by PlainOpen when OpenFunc is nil.
	Repo GitRepository

	// OpenErr is the error returned by PlainOpen when OpenFunc is nil.
	OpenErr error

	// OpenFunc, if set, is called instead of using Repo/OpenErr.
	OpenFunc func(path string) (GitRepository, error)

	// OpenCalls records the paths passed to PlainOpen.
	OpenCalls []string
}

MockGitOpener is a test double for GitOpener. Set OpenFunc to control PlainOpen behavior. If nil, PlainOpen returns the Repo field (or ErrRepositoryNotExists if Repo is nil).

func (*MockGitOpener) PlainOpen

func (m *MockGitOpener) PlainOpen(path string) (GitRepository, error)

PlainOpen records the call and delegates to OpenFunc or returns Repo/OpenErr.

type MockGitRepository

type MockGitRepository struct {
	// HeadRef is returned by Head().
	HeadRef *plumbing.Reference
	// HeadErr is the error returned by Head().
	HeadErr error

	// LogIter is returned by Log().
	LogIter object.CommitIter
	// LogErr is the error returned by Log().
	LogErr error
	// LogCalls records LogOptions passed to Log().
	LogCalls []*git.LogOptions

	// RemotesList is returned by Remotes().
	RemotesList []*git.Remote
	// RemotesErr is the error returned by Remotes().
	RemotesErr error

	// ReferencesIter is returned by References().
	ReferencesIter storer.ReferenceIter
	// ReferencesErr is the error returned by References().
	ReferencesErr error

	// CommitObjects maps hashes to commits for CommitObject().
	CommitObjects map[plumbing.Hash]*object.Commit
	// CommitObjectErr is the default error returned by CommitObject() when
	// the hash is not found in CommitObjects.
	CommitObjectErr error

	// TagObjects maps hashes to tags for TagObject().
	TagObjects map[plumbing.Hash]*object.Tag
	// TagObjectErr is the default error returned by TagObject() when
	// the hash is not found in TagObjects.
	TagObjectErr error

	// TagsIter is returned by Tags().
	TagsIter storer.ReferenceIter
	// TagsErr is the error returned by Tags().
	TagsErr error
}

MockGitRepository is a test double for GitRepository. Each method has a corresponding field for the return value and error.

func (*MockGitRepository) CommitObject

func (m *MockGitRepository) CommitObject(h plumbing.Hash) (*object.Commit, error)

CommitObject looks up the hash in CommitObjects, falling back to CommitObjectErr.

func (*MockGitRepository) Head

func (m *MockGitRepository) Head() (*plumbing.Reference, error)

Head returns HeadRef and HeadErr.

func (*MockGitRepository) Log

Log records the call and returns LogIter and LogErr.

func (*MockGitRepository) References

func (m *MockGitRepository) References() (storer.ReferenceIter, error)

References returns ReferencesIter and ReferencesErr.

func (*MockGitRepository) Remotes

func (m *MockGitRepository) Remotes() ([]*git.Remote, error)

Remotes returns RemotesList and RemotesErr.

func (*MockGitRepository) TagObject

func (m *MockGitRepository) TagObject(h plumbing.Hash) (*object.Tag, error)

TagObject looks up the hash in TagObjects, falling back to TagObjectErr.

func (*MockGitRepository) Tags

Tags returns TagsIter and TagsErr.

type OsFileSystem

type OsFileSystem struct{}

OsFileSystem is the production implementation of FileSystem that delegates to the standard library os and filepath packages.

func (OsFileSystem) Abs

func (OsFileSystem) Abs(path string) (string, error)

Abs wraps filepath.Abs.

func (OsFileSystem) Create

func (OsFileSystem) Create(name string) (*os.File, error)

Create wraps os.Create.

func (OsFileSystem) EvalSymlinks(path string) (string, error)

EvalSymlinks wraps filepath.EvalSymlinks.

func (OsFileSystem) MkdirAll

func (OsFileSystem) MkdirAll(path string, perm os.FileMode) error

MkdirAll wraps os.MkdirAll.

func (OsFileSystem) Open

func (OsFileSystem) Open(name string) (*os.File, error)

Open wraps os.Open.

func (OsFileSystem) ReadFile

func (OsFileSystem) ReadFile(name string) ([]byte, error)

ReadFile wraps os.ReadFile.

func (OsFileSystem) Stat

func (OsFileSystem) Stat(name string) (os.FileInfo, error)

Stat wraps os.Stat.

func (OsFileSystem) WalkDir

func (OsFileSystem) WalkDir(root string, fn fs.WalkDirFunc) error

WalkDir wraps filepath.WalkDir.

func (OsFileSystem) WriteFile

func (OsFileSystem) WriteFile(name string, data []byte, perm os.FileMode) error

WriteFile wraps os.WriteFile.

type RealCommandExecutor

type RealCommandExecutor struct{}

RealCommandExecutor is the production implementation that delegates to the os/exec package.

func (*RealCommandExecutor) CommandContext

func (r *RealCommandExecutor) CommandContext(ctx context.Context, name string, args ...string) *exec.Cmd

CommandContext wraps exec.CommandContext.

func (*RealCommandExecutor) LookPath

func (r *RealCommandExecutor) LookPath(file string) (string, error)

LookPath wraps exec.LookPath.

type RealGitOpener

type RealGitOpener struct{}

RealGitOpener is the production implementation of GitOpener. It delegates to git.PlainOpen.

func (RealGitOpener) PlainOpen

func (RealGitOpener) PlainOpen(path string) (GitRepository, error)

PlainOpen opens a git repository at path and returns a GitRepository.

type RealGitRepository

type RealGitRepository struct {
	// contains filtered or unexported fields
}

RealGitRepository wraps *git.Repository to satisfy GitRepository.

func (*RealGitRepository) CommitObject

func (r *RealGitRepository) CommitObject(h plumbing.Hash) (*object.Commit, error)

CommitObject returns the commit with the given hash.

func (*RealGitRepository) Head

func (r *RealGitRepository) Head() (*plumbing.Reference, error)

Head returns the reference where HEAD is pointing to.

func (*RealGitRepository) Log

Log returns the commit history from the current HEAD following the given options.

func (*RealGitRepository) References

func (r *RealGitRepository) References() (storer.ReferenceIter, error)

References returns an unsorted ReferenceIter for all references.

func (*RealGitRepository) Remotes

func (r *RealGitRepository) Remotes() ([]*git.Remote, error)

Remotes returns a list of remotes in a repository.

func (*RealGitRepository) TagObject

func (r *RealGitRepository) TagObject(h plumbing.Hash) (*object.Tag, error)

TagObject returns the tag with the given hash.

func (*RealGitRepository) Tags

Tags returns all tag References in a repository.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL