230 lines
5.8 KiB
Go
230 lines
5.8 KiB
Go
package integration
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/versenilvis/iris/internal/config"
|
|
)
|
|
|
|
func TestLoadAtuinEntriesPreservesContext(t *testing.T) {
|
|
dbPath := filepath.Join(t.TempDir(), "history.db")
|
|
db, err := sql.Open("sqlite", dbPath)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
_, err = db.Exec(`CREATE TABLE history (
|
|
command TEXT NOT NULL,
|
|
cwd TEXT NOT NULL,
|
|
timestamp INTEGER NOT NULL,
|
|
exit INTEGER NOT NULL,
|
|
session TEXT NOT NULL,
|
|
hostname TEXT NOT NULL,
|
|
deleted_at INTEGER
|
|
)`)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
rows := []struct {
|
|
command, cwd, session, hostname string
|
|
timestamp, exit, deletedAt int
|
|
}{
|
|
{"old command", "/repo", "s1", "host", 10, 0, 0},
|
|
{"new\ncommand", "/repo/pkg", "s2", "host", 30, 1, 0},
|
|
{"deleted command", "/repo", "s3", "host", 40, 0, 99},
|
|
}
|
|
for _, row := range rows {
|
|
var deletedAt any
|
|
if row.deletedAt != 0 {
|
|
deletedAt = row.deletedAt
|
|
}
|
|
_, err = db.Exec(
|
|
"INSERT INTO history VALUES (?, ?, ?, ?, ?, ?, ?)",
|
|
row.command, row.cwd, row.timestamp, row.exit, row.session, row.hostname, deletedAt,
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
if err := db.Close(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
originalConfig := config.Get()
|
|
cfg := config.DefaultConfig()
|
|
cfg.Core.AtuinDBPath = dbPath
|
|
config.Init(cfg)
|
|
t.Cleanup(func() { config.Init(originalConfig) })
|
|
|
|
entries, err := loadAtuinEntries()
|
|
if err != nil {
|
|
t.Fatalf("load Atuin entries: %v", err)
|
|
}
|
|
if len(entries) != 2 {
|
|
t.Fatalf("expected two active entries, got %d", len(entries))
|
|
}
|
|
if entries[0].Command != "new command" || entries[0].CWD != "/repo/pkg" || entries[0].Exit != 1 {
|
|
t.Fatalf("unexpected newest entry: %#v", entries[0])
|
|
}
|
|
if entries[1].Command != "old command" || entries[1].Session != "s1" {
|
|
t.Fatalf("unexpected oldest entry: %#v", entries[1])
|
|
}
|
|
}
|
|
|
|
func TestApplyAtuinScope(t *testing.T) {
|
|
repo := t.TempDir()
|
|
cwd := filepath.Join(repo, "internal", "pkg")
|
|
if err := os.MkdirAll(filepath.Join(repo, ".git"), 0755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.MkdirAll(cwd, 0755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
originalConfig := config.Get()
|
|
originalEntries := atuinEntries
|
|
t.Cleanup(func() {
|
|
config.Init(originalConfig)
|
|
atuinEntries = originalEntries
|
|
})
|
|
|
|
cfg := config.DefaultConfig()
|
|
cfg.Core.Atuin = 1
|
|
config.Init(cfg)
|
|
atuinEntries = []atuinEntry{
|
|
{Command: "git status", CWD: cwd, Timestamp: 50},
|
|
{Command: "git pull", CWD: repo, Timestamp: 40},
|
|
{Command: "git status", CWD: cwd, Timestamp: 30},
|
|
{Command: "git push", CWD: filepath.Join(t.TempDir(), "other"), Timestamp: 20},
|
|
{Command: "git unknown", CWD: "unknown", Timestamp: 10},
|
|
}
|
|
global := []HistResult{
|
|
{Cmd: "git push", Source: "atuin"},
|
|
{Cmd: "git pull", Source: "atuin"},
|
|
{Cmd: "git status", Source: "atuin"},
|
|
}
|
|
|
|
tests := []struct {
|
|
scope string
|
|
want []string
|
|
}{
|
|
{"global", []string{"git push", "git pull", "git status"}},
|
|
{"directory", []string{"git status"}},
|
|
{"workspace", []string{"git status", "git pull"}},
|
|
{"hybrid", []string{"git status", "git pull", "git push"}},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.scope, func(t *testing.T) {
|
|
cfg.History.Scope = tt.scope
|
|
got := resultCommands(applyAtuinScope(global, "g", map[string]string{"g": "git"}, cwd))
|
|
if !reflect.DeepEqual(got, tt.want) {
|
|
t.Fatalf("scope %s: got %v, want %v", tt.scope, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
|
|
cfg.History.Scope = "hybrid"
|
|
if got := resultCommands(applyAtuinScope(global, "", nil, cwd)); !reflect.DeepEqual(got, resultCommands(global)) {
|
|
t.Fatalf("empty query must stay global: got %v", got)
|
|
}
|
|
}
|
|
|
|
func TestWorkspaceScopeOutsideGitUsesDirectory(t *testing.T) {
|
|
cwd := t.TempDir()
|
|
originalConfig := config.Get()
|
|
originalEntries := atuinEntries
|
|
t.Cleanup(func() {
|
|
config.Init(originalConfig)
|
|
atuinEntries = originalEntries
|
|
})
|
|
|
|
cfg := config.DefaultConfig()
|
|
cfg.Core.Atuin = 1
|
|
cfg.History.Scope = "workspace"
|
|
config.Init(cfg)
|
|
atuinEntries = []atuinEntry{
|
|
{Command: "make local", CWD: cwd},
|
|
{Command: "make elsewhere", CWD: t.TempDir()},
|
|
}
|
|
|
|
got := resultCommands(applyAtuinScope(nil, "make", nil, cwd))
|
|
if !reflect.DeepEqual(got, []string{"make local"}) {
|
|
t.Fatalf("got %v, want directory-only result", got)
|
|
}
|
|
}
|
|
|
|
func BenchmarkContextualAtuinCommands(b *testing.B) {
|
|
repo := b.TempDir()
|
|
cwd := filepath.Join(repo, "internal", "pkg")
|
|
if err := os.MkdirAll(filepath.Join(repo, ".git"), 0755); err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
if err := os.MkdirAll(cwd, 0755); err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
entries := make([]atuinEntry, 10000)
|
|
for i := range entries {
|
|
entryCWD := repo
|
|
if i%3 == 0 {
|
|
entryCWD = cwd
|
|
}
|
|
entries[i] = atuinEntry{Command: fmt.Sprintf("command %d", i), CWD: entryCWD}
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for range b.N {
|
|
contextualAtuinCommands(entries, cwd)
|
|
}
|
|
}
|
|
|
|
func BenchmarkApplyAtuinScope(b *testing.B) {
|
|
repo := b.TempDir()
|
|
cwd := filepath.Join(repo, "internal", "pkg")
|
|
if err := os.MkdirAll(filepath.Join(repo, ".git"), 0755); err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
if err := os.MkdirAll(cwd, 0755); err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
|
|
originalConfig := config.Get()
|
|
originalEntries := atuinEntries
|
|
b.Cleanup(func() {
|
|
config.Init(originalConfig)
|
|
atuinEntries = originalEntries
|
|
})
|
|
cfg := config.DefaultConfig()
|
|
cfg.Core.Atuin = 1
|
|
cfg.History.Scope = "hybrid"
|
|
config.Init(cfg)
|
|
|
|
atuinEntries = make([]atuinEntry, 10000)
|
|
global := make([]HistResult, 10000)
|
|
for i := range atuinEntries {
|
|
entryCWD := repo
|
|
if i%3 == 0 {
|
|
entryCWD = cwd
|
|
}
|
|
command := fmt.Sprintf("command %d", i)
|
|
atuinEntries[i] = atuinEntry{Command: command, CWD: entryCWD}
|
|
global[i] = HistResult{Cmd: command, Source: "atuin"}
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for range b.N {
|
|
applyAtuinScope(global, "command 999", nil, cwd)
|
|
}
|
|
}
|
|
|
|
func resultCommands(results []HistResult) []string {
|
|
commands := make([]string, len(results))
|
|
for i, result := range results {
|
|
commands[i] = result.Cmd
|
|
}
|
|
return commands
|
|
}
|