< Summary - Neospec Coverage

Information
Line coverage
100%
Covered lines: 3
Uncovered lines: 0
Coverable lines: 3
Total lines: 93
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
NewFactory0%00100%

File(s)

/home/runner/work/neospec/neospec/internal/adapters/sandbox/xdg.go

#LineLine coverage
 1// Package sandbox implements ports.SandboxFactory. Each sandbox creates a
 2// temporary directory tree that mirrors the XDG base directory structure and
 3// sets the corresponding XDG_* environment variables so Neovim uses them
 4// exclusively, without touching the user's real config.
 5package sandbox
 6
 7import (
 8  "context"
 9  "errors"
 10  "fmt"
 11  "os"
 12  "path/filepath"
 13
 14  "github.com/jedi-knights/neospec/internal/ports"
 15)
 16
 17// fsOps abstracts the OS filesystem operations used by Factory.Create. Holding
 18// them in an interface lets tests inject fakes that trigger the MkdirTemp and
 19// MkdirAll error branches without manipulating real filesystem state.
 20type fsOps interface {
 21  MkdirTemp(dir, pattern string) (string, error)
 22  MkdirAll(path string, perm os.FileMode) error
 23  RemoveAll(path string) error
 24}
 25
 26// realFS is the production fsOps implementation that delegates to the os package.
 27type realFS struct{}
 28
 29func (realFS) MkdirTemp(dir, pattern string) (string, error) { return os.MkdirTemp(dir, pattern) }
 30func (realFS) MkdirAll(path string, perm os.FileMode) error  { return os.MkdirAll(path, perm) }
 31func (realFS) RemoveAll(path string) error                   { return os.RemoveAll(path) }
 32
 33// xdgSandbox is a single-use XDG environment tied to a temporary directory.
 34type xdgSandbox struct {
 35  root string
 36  fs   fsOps
 37}
 38
 39// Factory creates XDG sandboxes.
 40type Factory struct {
 41  fs fsOps
 42}
 43
 44// NewFactory creates a Factory backed by the real OS filesystem.
 445func NewFactory() *Factory {
 446  return &Factory{fs: realFS{}}
 447}
 48
 49// Create creates a new sandbox with a unique temporary root directory.
 50func (f *Factory) Create(_ context.Context) (ports.Sandbox, error) {
 51  root, err := f.fs.MkdirTemp("", "neospec-sandbox-*")
 52  if err != nil {
 53    return nil, fmt.Errorf("creating sandbox temp dir: %w", err)
 54  }
 55
 56  // Pre-create all XDG subdirectories so Neovim doesn't encounter missing dirs.
 57  for _, sub := range []string{"data", "config", "state", "cache", "runtime"} {
 58    if err := f.fs.MkdirAll(filepath.Join(root, sub), 0o700); err != nil {
 59      mkdirErr := fmt.Errorf("creating xdg subdir %s: %w", sub, err)
 60      if cerr := f.fs.RemoveAll(root); cerr != nil {
 61        return nil, errors.Join(mkdirErr, fmt.Errorf("cleaning up sandbox root: %w", cerr))
 62      }
 63      return nil, mkdirErr
 64    }
 65  }
 66
 67  return &xdgSandbox{root: root, fs: f.fs}, nil
 68}
 69
 70// Env returns the environment variables that activate this sandbox.
 71func (s *xdgSandbox) Env() []string {
 72  return []string{
 73    "XDG_DATA_HOME=" + filepath.Join(s.root, "data"),
 74    "XDG_CONFIG_HOME=" + filepath.Join(s.root, "config"),
 75    "XDG_STATE_HOME=" + filepath.Join(s.root, "state"),
 76    "XDG_CACHE_HOME=" + filepath.Join(s.root, "cache"),
 77    "XDG_RUNTIME_DIR=" + filepath.Join(s.root, "runtime"),
 78    // Prevent Neovim from reading system init files.
 79    "NVIM_APPNAME=neospec-isolated",
 80    // HOME override ensures no ~/.config/nvim fallback.
 81    "HOME=" + s.root,
 82  }
 83}
 84
 85// Dir returns the root temporary directory of the sandbox.
 86func (s *xdgSandbox) Dir() string {
 87  return s.root
 88}
 89
 90// Close removes all temporary directories created for this sandbox.
 91func (s *xdgSandbox) Close() error {
 92  return s.fs.RemoveAll(s.root)
 93}

Methods/Properties

NewFactory