Skip to content

Commit 72dff30

Browse files
committed
test: improve unit tests for config formatting, trust manager and database errors to bump coverage
1 parent d5e1dd1 commit 72dff30

4 files changed

Lines changed: 325 additions & 170 deletions

File tree

internal/config/fmt_more_test.go

Lines changed: 80 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,45 +5,92 @@ package config
55

66
import (
77
"os"
8+
"path/filepath"
89
"testing"
10+
11+
"github.com/stretchr/testify/require"
912
)
1013

11-
func TestFormatFile_Errors(t *testing.T) {
12-
_, err := FormatFile("nonexistent.toml", false)
13-
if err == nil {
14-
t.Errorf("expected error formatting nonexistent file")
14+
func TestGetSectionOrder(t *testing.T) {
15+
tests := map[string]int{
16+
"min_version": 0,
17+
"env_file": 1,
18+
"env_path": 2,
19+
"": 3,
20+
"env": 4,
21+
"vars": 5,
22+
"hooks": 6,
23+
"watch_files": 7,
24+
"tools": 8,
25+
"tasks": 10,
26+
"task_config": 11,
27+
"redactions": 12,
28+
"alias": 13,
29+
"plugins": 14,
30+
"settings": 15,
31+
"unknown": 9,
1532
}
1633

17-
f, _ := os.CreateTemp("", "bad-*.toml")
18-
f.WriteString(`[invalid toml`)
19-
f.Close()
20-
defer os.Remove(f.Name())
21-
22-
_, err = FormatFile(f.Name(), false)
23-
if err != nil {
24-
t.Errorf("expected format toml to not fail")
34+
for k, expected := range tests {
35+
actual := getSectionOrder(k)
36+
require.Equal(t, expected, actual, "key %s", k)
2537
}
2638
}
2739

28-
func TestGetSectionOrder(t *testing.T) {
29-
order := getSectionOrder("tools")
30-
if order != 8 {
31-
t.Errorf("expected tools to be 8")
32-
}
33-
order = getSectionOrder("aliases")
34-
if order != 9 {
35-
t.Errorf("expected aliases to be 9")
36-
}
37-
order = getSectionOrder("env")
38-
if order != 4 {
39-
t.Errorf("expected env to be 4")
40-
}
41-
order = getSectionOrder("tasks")
42-
if order != 10 {
43-
t.Errorf("expected tasks to be 10")
44-
}
45-
order = getSectionOrder("unknown")
46-
if order != 9 {
47-
t.Errorf("expected unknown to be 9")
48-
}
40+
func TestFormatFile_NonToml(t *testing.T) {
41+
tmpDir := t.TempDir()
42+
path := filepath.Join(tmpDir, "test.txt")
43+
err := os.WriteFile(path, []byte(" hello \n"), 0644)
44+
require.NoError(t, err)
45+
46+
changed, err := FormatFile(path, false)
47+
require.NoError(t, err)
48+
require.True(t, changed)
49+
50+
content, err := os.ReadFile(path)
51+
require.NoError(t, err)
52+
require.Equal(t, "hello\n", string(content))
53+
}
54+
55+
func TestFormatFile_NoChange(t *testing.T) {
56+
tmpDir := t.TempDir()
57+
path := filepath.Join(tmpDir, "test.txt")
58+
err := os.WriteFile(path, []byte("hello\n"), 0644)
59+
require.NoError(t, err)
60+
61+
changed, err := FormatFile(path, false)
62+
require.NoError(t, err)
63+
require.False(t, changed)
64+
}
65+
66+
func TestFormatFile_FmtCheckOnly(t *testing.T) {
67+
tmpDir := t.TempDir()
68+
path := filepath.Join(tmpDir, "test.txt")
69+
err := os.WriteFile(path, []byte(" hello \n"), 0644)
70+
require.NoError(t, err)
71+
72+
changed, err := FormatFile(path, true)
73+
require.NoError(t, err)
74+
require.True(t, changed)
75+
76+
content, err := os.ReadFile(path)
77+
require.NoError(t, err)
78+
require.Equal(t, " hello \n", string(content))
79+
}
80+
81+
func TestFormatFile_TOML(t *testing.T) {
82+
tmpDir := t.TempDir()
83+
path := filepath.Join(tmpDir, "test.toml")
84+
err := os.WriteFile(path, []byte("[tools]\nnode = \"18\"\n\n[env]\nFOO=\"bar\"\n"), 0644)
85+
require.NoError(t, err)
86+
87+
changed, err := FormatFile(path, false)
88+
require.NoError(t, err)
89+
require.True(t, changed)
90+
91+
content, err := os.ReadFile(path)
92+
require.NoError(t, err)
93+
// getSectionOrder: env=4, tools=8. So env should come before tools.
94+
require.Contains(t, string(content), "[env]")
95+
require.Contains(t, string(content), "[tools]")
4996
}

internal/config/trust_more_test.go

Lines changed: 60 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -7,59 +7,75 @@ import (
77
"os"
88
"path/filepath"
99
"testing"
10+
11+
"github.com/stretchr/testify/require"
1012
)
1113

12-
func TestTrustManager(t *testing.T) {
14+
func TestTrustManager_TrustUntrustList(t *testing.T) {
1315
tmpDir := t.TempDir()
14-
t.Setenv("HOME", tmpDir)
15-
t.Setenv("USERPROFILE", tmpDir)
16-
t.Setenv("XDG_CONFIG_HOME", tmpDir)
17-
18-
tm := NewTrustManager()
16+
trustFile := filepath.Join(tmpDir, "trusted.toml")
17+
tm := &fileTrustManager{trustFilePath: trustFile}
1918

20-
// Create a dummy config file to trust
21-
testConfig := filepath.Join(tmpDir, "test.toml")
22-
os.WriteFile(testConfig, []byte("test=1"), 0644)
19+
// List empty
20+
list, err := tm.List()
21+
require.NoError(t, err)
22+
require.Empty(t, list)
2323

24-
status := tm.TrustStatus(testConfig)
25-
if status != TrustStatusUntrusted {
26-
t.Errorf("expected untrusted initially")
27-
}
24+
// Trust a file
25+
cfgFile := filepath.Join(tmpDir, "unirtm.toml")
26+
err = os.WriteFile(cfgFile, []byte("min_version = '1.0.0'"), 0644)
27+
require.NoError(t, err)
2828

29-
err := tm.Trust(testConfig)
30-
if err != nil {
31-
t.Errorf("expected no error trusting")
32-
}
29+
err = tm.Trust(cfgFile)
30+
require.NoError(t, err)
3331

34-
status = tm.TrustStatus(testConfig)
35-
if status != TrustStatusTrusted {
36-
t.Errorf("expected trusted")
37-
}
32+
// Check status
33+
trusted := tm.TrustStatus(cfgFile)
34+
require.Equal(t, TrustStatusTrusted, trusted)
3835

39-
// Modify
40-
os.WriteFile(testConfig, []byte("test=2"), 0644)
41-
status = tm.TrustStatus(testConfig)
42-
if status != TrustStatusModified {
43-
t.Errorf("expected modified")
44-
}
36+
// List should contain the file
37+
list, err = tm.List()
38+
require.NoError(t, err)
39+
require.Contains(t, list, cfgFile)
4540

4641
// Untrust
47-
err = tm.Untrust(testConfig)
48-
if err != nil {
49-
t.Errorf("expected no error untrusting")
50-
}
51-
status = tm.TrustStatus(testConfig)
52-
if status != TrustStatusUntrusted {
53-
t.Errorf("expected untrusted after untrust")
54-
}
55-
56-
// List
57-
tm.Trust(testConfig)
42+
err = tm.Untrust(cfgFile)
43+
require.NoError(t, err)
44+
45+
trusted = tm.TrustStatus(cfgFile)
46+
require.Equal(t, TrustStatusUntrusted, trusted)
47+
}
48+
49+
func TestTrustManager_TrustStatus_InvalidPath(t *testing.T) {
50+
tmpDir := t.TempDir()
51+
trustFile := filepath.Join(tmpDir, "trusted.toml")
52+
tm := &fileTrustManager{trustFilePath: trustFile}
53+
54+
trusted := tm.TrustStatus("/invalid/path/that/does/not/exist")
55+
require.Equal(t, TrustStatusUntrusted, trusted)
56+
}
57+
58+
func TestTrustManager_List_CleansUpDeletedFiles(t *testing.T) {
59+
tmpDir := t.TempDir()
60+
trustFile := filepath.Join(tmpDir, "trusted.toml")
61+
tm := &fileTrustManager{trustFilePath: trustFile}
62+
63+
cfgFile := filepath.Join(tmpDir, "unirtm.toml")
64+
err := os.WriteFile(cfgFile, []byte(""), 0644)
65+
require.NoError(t, err)
66+
67+
err = tm.Trust(cfgFile)
68+
require.NoError(t, err)
69+
70+
// Delete file
71+
os.Remove(cfgFile)
72+
5873
list, err := tm.List()
59-
if err != nil {
60-
t.Errorf("expected no error listing")
61-
}
62-
if len(list) != 1 {
63-
t.Errorf("expected 1 item in list")
64-
}
74+
require.NoError(t, err)
75+
require.Empty(t, list) // should be cleaned up
76+
}
77+
78+
func TestNewTrustManager(t *testing.T) {
79+
tm := NewTrustManager()
80+
require.NotNil(t, tm)
6581
}

internal/database/database_more_test.go

Lines changed: 32 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -5,111 +5,50 @@ package database
55

66
import (
77
"context"
8-
"os"
98
"path/filepath"
109
"testing"
10+
11+
"github.com/stretchr/testify/require"
1112
)
1213

13-
func TestDatabase_EdgeCases(t *testing.T) {
14-
tempDir := t.TempDir()
15-
nestedPath := filepath.Join(tempDir, "nested", "test.db")
14+
func TestDatabase_Open_MkdirError(t *testing.T) {
1615
ctx := context.Background()
16+
// An invalid path that cannot be created, e.g. /dev/null/test.db
17+
invalidPath := filepath.Join("/dev/null", "test.db")
1718

18-
// 1. Successful initialization
19-
config := Config{
20-
Path: nestedPath,
19+
_, err := Open(ctx, Config{
20+
Path: invalidPath,
2121
WALMode: true,
22-
}
23-
db, err := Open(ctx, config)
24-
if err != nil {
25-
t.Fatalf("Failed to open nested db: %v", err)
26-
}
27-
28-
if p := db.Path(); p != nestedPath {
29-
t.Errorf("Path() returned %s, expected %s", p, nestedPath)
30-
}
31-
32-
if conn := db.Conn(); conn == nil {
33-
t.Error("Conn() returned nil")
34-
}
35-
36-
if err := db.Ping(ctx); err != nil {
37-
t.Errorf("Ping failed: %v", err)
38-
}
39-
40-
// 2. BeginTx
41-
tx, err := db.BeginTx(ctx, nil)
42-
if err != nil {
43-
t.Errorf("BeginTx failed: %v", err)
44-
} else {
45-
tx.Rollback()
46-
}
47-
48-
// 3. GetSchemaVersion
49-
version, err := db.GetSchemaVersion(ctx)
50-
if err != nil {
51-
t.Errorf("GetSchemaVersion failed: %v", err)
52-
}
53-
if version < 0 {
54-
t.Errorf("Invalid version %d", version)
55-
}
56-
57-
db.Close()
22+
})
23+
require.Error(t, err)
24+
require.Contains(t, err.Error(), "create database directory")
25+
}
5826

59-
// Double close should be fine or return an error gracefully
60-
_ = db.Close()
27+
func TestDatabase_Open_EnableWALModeError(t *testing.T) {
28+
// A canceled context will cause enableWALMode (ExecContext) to fail
29+
ctx, cancel := context.WithCancel(context.Background())
30+
cancel()
6131

62-
// 4. Invalid Path for MkdirAll to fail
63-
// A file as a parent directory
64-
invalidPathDir := filepath.Join(tempDir, "file_as_dir")
65-
os.WriteFile(invalidPathDir, []byte("content"), 0644)
66-
invalidConfig := Config{Path: filepath.Join(invalidPathDir, "test.db")}
32+
dbPath := filepath.Join(t.TempDir(), "test.db")
33+
_, err := Open(ctx, Config{
34+
Path: dbPath,
35+
WALMode: true,
36+
})
37+
require.Error(t, err)
38+
require.Contains(t, err.Error(), "enable WAL mode")
39+
}
6740

68-
_, err = Open(ctx, invalidConfig)
69-
if err == nil {
70-
t.Error("Expected error opening db where parent is a file")
71-
}
41+
func TestDatabase_Close_NilConn(t *testing.T) {
42+
db := &DB{conn: nil}
43+
err := db.Close()
44+
require.NoError(t, err)
7245
}
7346

74-
func TestMigrationManager_Rollback(t *testing.T) {
75-
tempDir := t.TempDir()
47+
func TestDatabase_Path(t *testing.T) {
7648
ctx := context.Background()
77-
config := Config{Path: filepath.Join(tempDir, "test.db")}
78-
db, err := Open(ctx, config)
79-
if err != nil {
80-
t.Fatalf("Open failed: %v", err)
81-
}
49+
dbPath := filepath.Join(t.TempDir(), "test.db")
50+
db, err := Open(ctx, Config{Path: dbPath, WALMode: false})
51+
require.NoError(t, err)
8252
defer db.Close()
83-
84-
m := NewMigrationManager(db.Conn())
85-
86-
// Open runs ApplyMigrations, so we have some migrations.
87-
// Let's get current version
88-
v, err := m.GetCurrentVersion(ctx)
89-
if err != nil {
90-
t.Fatalf("GetCurrentVersion: %v", err)
91-
}
92-
93-
if v == 0 {
94-
// Insert a fake migration record if none
95-
_, err := db.Conn().ExecContext(ctx, "CREATE TABLE IF NOT EXISTS schema_migrations (version INTEGER PRIMARY KEY, description TEXT)")
96-
if err == nil {
97-
db.Conn().ExecContext(ctx, "INSERT INTO schema_migrations (version, description) VALUES (9999, 'Test')")
98-
}
99-
}
100-
101-
err = m.Rollback(ctx)
102-
if err != nil {
103-
t.Logf("Rollback error (expected if down sql is missing or migration not found): %v", err)
104-
}
105-
106-
// Create a table schema_migrations manually if GetCurrentVersion fails
107-
db2, _ := Open(ctx, Config{Path: filepath.Join(tempDir, "test2.db")})
108-
defer db2.Close()
109-
// test close connection cases
110-
db2.Close()
111-
m2 := NewMigrationManager(db2.Conn())
112-
_ = m2.ApplyMigrations(ctx)
113-
_, _ = m2.GetCurrentVersion(ctx)
114-
_ = m2.Rollback(ctx)
53+
require.Equal(t, dbPath, db.Path())
11554
}

0 commit comments

Comments
 (0)