package core_test import ( "io" "os" "path/filepath" "strings" "testing" "git.hrafn.xyz/aether/gosick/internal/homesick/core" git "github.com/go-git/go-git/v5" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" ) type DestroySuite struct { suite.Suite tmpDir string homeDir string reposDir string app *core.App } func TestDestroySuite(t *testing.T) { suite.Run(t, new(DestroySuite)) } func (s *DestroySuite) SetupTest() { s.tmpDir = s.T().TempDir() s.homeDir = filepath.Join(s.tmpDir, "home") s.reposDir = filepath.Join(s.homeDir, ".homesick", "repos") require.NoError(s.T(), os.MkdirAll(s.reposDir, 0o755)) s.app = &core.App{ HomeDir: s.homeDir, ReposDir: s.reposDir, Stdin: strings.NewReader("y\n"), Stdout: io.Discard, Stderr: io.Discard, } } func (s *DestroySuite) createCastleRepo(castle string) string { castleRoot := filepath.Join(s.reposDir, castle) require.NoError(s.T(), os.MkdirAll(filepath.Join(castleRoot, "home"), 0o755)) _, err := git.PlainInit(castleRoot, false) require.NoError(s.T(), err) return castleRoot } func (s *DestroySuite) TestDestroy_RemovesCastleDirectory() { castleRoot := s.createCastleRepo("dotfiles") require.DirExists(s.T(), castleRoot) s.app.Stdin = strings.NewReader("y\n") require.NoError(s.T(), s.app.Destroy("dotfiles")) require.NoDirExists(s.T(), castleRoot) } func (s *DestroySuite) TestDestroy_MissingCastleReturnsError() { err := s.app.Destroy("missing") require.Error(s.T(), err) } func (s *DestroySuite) TestDestroy_UnlinksDotfilesBeforeRemoval() { castleRoot := s.createCastleRepo("dotfiles") tracked := filepath.Join(castleRoot, "home", ".vimrc") require.NoError(s.T(), os.WriteFile(tracked, []byte("set number\n"), 0o644)) require.NoError(s.T(), s.app.LinkCastle("dotfiles")) homePath := filepath.Join(s.homeDir, ".vimrc") info, err := os.Lstat(homePath) require.NoError(s.T(), err) require.NotZero(s.T(), info.Mode()&os.ModeSymlink) s.app.Stdin = strings.NewReader("y\n") require.NoError(s.T(), s.app.Destroy("dotfiles")) _, err = os.Lstat(homePath) require.Error(s.T(), err) require.True(s.T(), os.IsNotExist(err)) require.NoDirExists(s.T(), castleRoot) } func (s *DestroySuite) TestDestroy_RemovesSymlinkedCastleOnly() { target := filepath.Join(s.tmpDir, "local-castle") require.NoError(s.T(), os.MkdirAll(target, 0o755)) symlinkCastle := filepath.Join(s.reposDir, "dotfiles") require.NoError(s.T(), os.Symlink(target, symlinkCastle)) s.app.Stdin = strings.NewReader("y\n") require.NoError(s.T(), s.app.Destroy("dotfiles")) require.NoFileExists(s.T(), symlinkCastle) require.DirExists(s.T(), target) } func (s *DestroySuite) TestDestroy_DeclineConfirmationKeepsCastle() { castleRoot := s.createCastleRepo("dotfiles") require.DirExists(s.T(), castleRoot) s.app.Stdin = strings.NewReader("n\n") require.NoError(s.T(), s.app.Destroy("dotfiles")) require.DirExists(s.T(), castleRoot) }