Files
gitlocal/internal/config/config_test.go
Daniel Tomlinson b5f1495680 Adds initial gitlocal CLI and core functionality
Introduces the `gitlocal` command-line tool for managing nested Git repositories.

Includes the following main commands:
- `convert`: Renames `.git` to `.gitlocal`, allowing a parent repository to ignore the converted child repository. Supports recursive scanning and dry-run options. Tracks converted repositories in a global configuration.
- `revert`: Restores `.gitlocal` to `.git`. Includes an option to revert all tracked repositories.
- `status`: Displays a list of all repositories currently tracked by `gitlocal`, showing their path, conversion time, and original remote/branch.

Establishes internal modules for Git operations, configuration management, and recursive repository scanning.
Adds a comprehensive test suite covering core command logic and utility functions.
Initializes Go module and basic project `.gitignore`.
2026-04-11 14:48:01 +01:00

261 lines
5.6 KiB
Go

package config
import (
"os"
"path/filepath"
"testing"
"time"
)
func TestLoadConfigNotExists(t *testing.T) {
// Override config path to use temp file
originalHome := os.Getenv("HOME")
tempDir := t.TempDir()
os.Setenv("HOME", tempDir)
defer os.Setenv("HOME", originalHome)
cfg, err := Load()
if err != nil {
t.Fatalf("expected no error when config doesn't exist, got: %v", err)
}
if cfg.Version != ConfigVersion {
t.Errorf("expected version %s, got %s", ConfigVersion, cfg.Version)
}
if len(cfg.Repos) != 0 {
t.Errorf("expected empty repos, got %d repos", len(cfg.Repos))
}
}
func TestLoadConfigExists(t *testing.T) {
originalHome := os.Getenv("HOME")
tempDir := t.TempDir()
os.Setenv("HOME", tempDir)
defer os.Setenv("HOME", originalHome)
// Create a config file
configPath := filepath.Join(tempDir, ConfigFile)
configContent := `version: "1"
repos:
- path: /test/path/1
converted_at: 2026-04-07T14:30:00Z
original_remote: git@github.com:user/repo1.git
original_branch: main
- path: /test/path/2
converted_at: 2026-04-07T15:00:00Z
original_remote: git@github.com:user/repo2.git
original_branch: develop
`
if err := os.WriteFile(configPath, []byte(configContent), 0644); err != nil {
t.Fatalf("failed to write test config: %v", err)
}
cfg, err := Load()
if err != nil {
t.Fatalf("failed to load config: %v", err)
}
if cfg.Version != "1" {
t.Errorf("expected version 1, got %s", cfg.Version)
}
if len(cfg.Repos) != 2 {
t.Fatalf("expected 2 repos, got %d", len(cfg.Repos))
}
if cfg.Repos[0].Path != "/test/path/1" {
t.Errorf("expected path /test/path/1, got %s", cfg.Repos[0].Path)
}
if cfg.Repos[0].OriginalRemote != "git@github.com:user/repo1.git" {
t.Errorf("expected remote git@github.com:user/repo1.git, got %s", cfg.Repos[0].OriginalRemote)
}
}
func TestSaveConfig(t *testing.T) {
originalHome := os.Getenv("HOME")
tempDir := t.TempDir()
os.Setenv("HOME", tempDir)
defer os.Setenv("HOME", originalHome)
cfg := &Config{
Version: ConfigVersion,
Repos: []Repo{
{
Path: "/test/repo",
ConvertedAt: time.Now(),
OriginalRemote: "git@github.com:test/repo.git",
OriginalBranch: "main",
},
},
}
if err := cfg.Save(); err != nil {
t.Fatalf("failed to save config: %v", err)
}
configPath := filepath.Join(tempDir, ConfigFile)
if _, err := os.Stat(configPath); os.IsNotExist(err) {
t.Fatalf("config file was not created")
}
// Load it back to verify
loadedCfg, err := Load()
if err != nil {
t.Fatalf("failed to load saved config: %v", err)
}
if len(loadedCfg.Repos) != 1 {
t.Fatalf("expected 1 repo, got %d", len(loadedCfg.Repos))
}
if loadedCfg.Repos[0].Path != "/test/repo" {
t.Errorf("expected path /test/repo, got %s", loadedCfg.Repos[0].Path)
}
}
func TestAddRepo(t *testing.T) {
cfg := &Config{
Version: ConfigVersion,
Repos: []Repo{},
}
repo1 := Repo{
Path: "/test/repo1",
ConvertedAt: time.Now(),
OriginalRemote: "git@github.com:test/repo1.git",
OriginalBranch: "main",
}
cfg.AddRepo(repo1)
if len(cfg.Repos) != 1 {
t.Fatalf("expected 1 repo, got %d", len(cfg.Repos))
}
if cfg.Repos[0].Path != "/test/repo1" {
t.Errorf("expected path /test/repo1, got %s", cfg.Repos[0].Path)
}
}
func TestAddRepoReplaceExisting(t *testing.T) {
now := time.Now()
later := now.Add(1 * time.Hour)
cfg := &Config{
Version: ConfigVersion,
Repos: []Repo{
{
Path: "/test/repo",
ConvertedAt: now,
OriginalRemote: "git@github.com:test/old.git",
OriginalBranch: "main",
},
},
}
// Add same path again with different data
repo := Repo{
Path: "/test/repo",
ConvertedAt: later,
OriginalRemote: "git@github.com:test/new.git",
OriginalBranch: "develop",
}
cfg.AddRepo(repo)
if len(cfg.Repos) != 1 {
t.Fatalf("expected 1 repo (replaced), got %d", len(cfg.Repos))
}
if cfg.Repos[0].OriginalRemote != "git@github.com:test/new.git" {
t.Errorf("expected new remote, got %s", cfg.Repos[0].OriginalRemote)
}
if cfg.Repos[0].OriginalBranch != "develop" {
t.Errorf("expected branch develop, got %s", cfg.Repos[0].OriginalBranch)
}
if !cfg.Repos[0].ConvertedAt.Equal(later) {
t.Errorf("expected later timestamp")
}
}
func TestRemoveRepo(t *testing.T) {
cfg := &Config{
Version: ConfigVersion,
Repos: []Repo{
{Path: "/test/repo1"},
{Path: "/test/repo2"},
{Path: "/test/repo3"},
},
}
cfg.RemoveRepo("/test/repo2")
if len(cfg.Repos) != 2 {
t.Fatalf("expected 2 repos, got %d", len(cfg.Repos))
}
for _, repo := range cfg.Repos {
if repo.Path == "/test/repo2" {
t.Errorf("repo2 should have been removed")
}
}
}
func TestRemoveRepoNotFound(t *testing.T) {
cfg := &Config{
Version: ConfigVersion,
Repos: []Repo{
{Path: "/test/repo1"},
},
}
cfg.RemoveRepo("/test/nonexistent")
if len(cfg.Repos) != 1 {
t.Fatalf("expected 1 repo, got %d", len(cfg.Repos))
}
}
func TestFindRepo(t *testing.T) {
cfg := &Config{
Version: ConfigVersion,
Repos: []Repo{
{
Path: "/test/repo1",
OriginalRemote: "git@github.com:test/repo1.git",
},
{
Path: "/test/repo2",
OriginalRemote: "git@github.com:test/repo2.git",
},
},
}
repo := cfg.FindRepo("/test/repo1")
if repo == nil {
t.Fatalf("expected to find repo1")
}
if repo.OriginalRemote != "git@github.com:test/repo1.git" {
t.Errorf("expected repo1 remote, got %s", repo.OriginalRemote)
}
}
func TestFindRepoNotFound(t *testing.T) {
cfg := &Config{
Version: ConfigVersion,
Repos: []Repo{
{Path: "/test/repo1"},
},
}
repo := cfg.FindRepo("/test/nonexistent")
if repo != nil {
t.Errorf("expected nil for nonexistent repo, got %v", repo)
}
}