Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 42 additions & 11 deletions internal/acp/acp_extra_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package acp

import (
"bufio"
"bytes"
"context"
"encoding/json"
"errors"
"io"
"strings"
"sync"
"testing"
"time"

Expand Down Expand Up @@ -374,28 +376,57 @@ func TestACP_FullSessionLifecycle(t *testing.T) {
}

func TestACP_MultipleSessions(t *testing.T) {
lines := []string{
`{"jsonrpc":"2.0","id":1,"method":"initialize"}`,
`{"jsonrpc":"2.0","id":2,"method":"session/new"}`,
`{"jsonrpc":"2.0","id":3,"method":"session/new"}`,
`{"jsonrpc":"2.0","id":4,"method":"session/prompt","params":{"sessionId":"sess_1","prompt":[{"type":"text","text":"hello"}]}}`,
`{"jsonrpc":"2.0","id":5,"method":"session/prompt","params":{"sessionId":"sess_2","prompt":[{"type":"text","text":"world"}]}}`,
// Create a single server for both sessions
srv := NewServer(testFactory)
var buf bytes.Buffer
srv.w = &buf

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

in := strings.NewReader(`{"jsonrpc":"2.0","id":1,"method":"initialize"}
{"jsonrpc":"2.0","id":2,"method":"session/new"}
{"jsonrpc":"2.0","id":3,"method":"session/new"}
`)
pr, pw := io.Pipe()

var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
_ = srv.Serve(ctx, in, pw)
_ = pw.Close()
}()

var msgs []rpcMessage
scanner := bufio.NewScanner(pr)
scanner.Buffer(make([]byte, 0, 1024*1024), 1024*1024)
for scanner.Scan() {
line := scanner.Bytes()
if len(line) == 0 {
continue
}
var m rpcMessage
if err := json.Unmarshal(line, &m); err == nil {
msgs = append(msgs, m)
}
}
msgs := runServer(t, testFactory, lines)
wg.Wait()

sessionCount := 0
sessionIDs := make(map[string]bool)
for _, m := range msgs {
if hasID(m, 2) || hasID(m, 3) {
var r struct {
SessionID string `json:"sessionId"`
}
if err := json.Unmarshal(m.Result, &r); err == nil && r.SessionID != "" {
sessionCount++
sessionIDs[r.SessionID] = true
}
}
}
if sessionCount != 2 {
t.Errorf("expected 2 sessions created, got %d", sessionCount)

if len(sessionIDs) != 2 {
t.Errorf("expected 2 unique session IDs, got %d", len(sessionIDs))
}
}

Expand Down
10 changes: 5 additions & 5 deletions internal/crash/crash_extra_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,11 @@ func TestWriteReport_CreatesDirectory(t *testing.T) {

func TestFormatReport_FullFields(t *testing.T) {
r := CrashReport{
Timestamp: mustParseTime(t, "2024-01-15T10:30:00Z"),
Version: "1.2.3",
PanicValue: "runtime error: nil pointer",
Signal: "SIGSEGV",
Stack: "goroutine 1 [running]:\nmain.main()",
Timestamp: mustParseTime(t, "2024-01-15T10:30:00Z"),
Version: "1.2.3",
PanicValue: "runtime error: nil pointer",
Signal: "SIGSEGV",
Stack: "goroutine 1 [running]:\nmain.main()",
}

result := formatReport(r)
Expand Down
38 changes: 19 additions & 19 deletions internal/lint/lint_extra_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func TestEslintLinter_NoTool(t *testing.T) {

dir := t.TempDir()
file := filepath.Join(dir, "test.js")
if err := os.WriteFile(file, []byte("const x = 1;"), 0644); err != nil {
if err := os.WriteFile(file, []byte("const x = 1;"), 0o644); err != nil {
t.Fatal(err)
}

Expand All @@ -48,7 +48,7 @@ func TestRuffLinter_NoTool(t *testing.T) {

dir := t.TempDir()
file := filepath.Join(dir, "test.py")
if err := os.WriteFile(file, []byte("x = 1\n"), 0644); err != nil {
if err := os.WriteFile(file, []byte("x = 1\n"), 0o644); err != nil {
t.Fatal(err)
}

Expand All @@ -75,7 +75,7 @@ func TestGoLinter_NoTool(t *testing.T) {

dir := t.TempDir()
file := filepath.Join(dir, "test.go")
if err := os.WriteFile(file, []byte("package main\n"), 0644); err != nil {
if err := os.WriteFile(file, []byte("package main\n"), 0o644); err != nil {
t.Fatal(err)
}

Expand All @@ -90,7 +90,7 @@ func TestGoLinter_NoTool(t *testing.T) {
func TestCustomLinter_Success(t *testing.T) {
dir := t.TempDir()
file := filepath.Join(dir, "x.go")
if err := os.WriteFile(file, []byte("package x\n"), 0644); err != nil {
if err := os.WriteFile(file, []byte("package x\n"), 0o644); err != nil {
t.Fatal(err)
}

Expand All @@ -108,7 +108,7 @@ func TestCustomLinter_Success(t *testing.T) {
func TestCustomLinter_EmptyOutput(t *testing.T) {
dir := t.TempDir()
file := filepath.Join(dir, "x.go")
if err := os.WriteFile(file, []byte("package x\n"), 0644); err != nil {
if err := os.WriteFile(file, []byte("package x\n"), 0o644); err != nil {
t.Fatal(err)
}

Expand All @@ -127,7 +127,7 @@ func TestCustomLinter_EmptyOutput(t *testing.T) {
func TestRunLint_WithTimeout(t *testing.T) {
dir := t.TempDir()
file := filepath.Join(dir, "x.go")
if err := os.WriteFile(file, []byte("package x\n"), 0644); err != nil {
if err := os.WriteFile(file, []byte("package x\n"), 0o644); err != nil {
t.Fatal(err)
}

Expand Down Expand Up @@ -166,7 +166,7 @@ func TestLanguageForFile(t *testing.T) {
func TestRunLint_LanguageSet(t *testing.T) {
dir := t.TempDir()
file := filepath.Join(dir, "x.py")
if err := os.WriteFile(file, []byte("x = 1\n"), 0644); err != nil {
if err := os.WriteFile(file, []byte("x = 1\n"), 0o644); err != nil {
t.Fatal(err)
}

Expand Down Expand Up @@ -195,7 +195,7 @@ func TestEslintLinter_WithMockNpx(t *testing.T) {
// Create a mock npx that exits 0 with no output
mockDir := t.TempDir()
mockNpx := filepath.Join(mockDir, "npx")
if err := os.WriteFile(mockNpx, []byte("#!/bin/sh\nexit 0\n"), 0755); err != nil {
if err := os.WriteFile(mockNpx, []byte("#!/bin/sh\nexit 0\n"), 0o755); err != nil {
t.Fatal(err)
}

Expand All @@ -206,7 +206,7 @@ func TestEslintLinter_WithMockNpx(t *testing.T) {
linter := eslintLinter{}
dir := t.TempDir()
file := filepath.Join(dir, "test.js")
if err := os.WriteFile(file, []byte("const x = 1;"), 0644); err != nil {
if err := os.WriteFile(file, []byte("const x = 1;"), 0o644); err != nil {
t.Fatal(err)
}

Expand All @@ -220,7 +220,7 @@ func TestEslintLinter_WithMockNpx(t *testing.T) {
func TestEslintLinter_WithMockNpx_Failure(t *testing.T) {
mockDir := t.TempDir()
mockNpx := filepath.Join(mockDir, "npx")
if err := os.WriteFile(mockNpx, []byte("#!/bin/sh\necho 'error: semicolon missing'\nexit 1\n"), 0755); err != nil {
if err := os.WriteFile(mockNpx, []byte("#!/bin/sh\necho 'error: semicolon missing'\nexit 1\n"), 0o755); err != nil {
t.Fatal(err)
}

Expand All @@ -231,7 +231,7 @@ func TestEslintLinter_WithMockNpx_Failure(t *testing.T) {
linter := eslintLinter{}
dir := t.TempDir()
file := filepath.Join(dir, "test.js")
if err := os.WriteFile(file, []byte("const x = 1"), 0644); err != nil {
if err := os.WriteFile(file, []byte("const x = 1"), 0o644); err != nil {
t.Fatal(err)
}

Expand All @@ -249,7 +249,7 @@ func TestEslintLinter_WithMockNpx_EmptyOutput(t *testing.T) {
mockDir := t.TempDir()
mockNpx := filepath.Join(mockDir, "npx")
// npx --no-install miss: exits non-zero with no output
if err := os.WriteFile(mockNpx, []byte("#!/bin/sh\nexit 1\n"), 0755); err != nil {
if err := os.WriteFile(mockNpx, []byte("#!/bin/sh\nexit 1\n"), 0o755); err != nil {
t.Fatal(err)
}

Expand All @@ -260,7 +260,7 @@ func TestEslintLinter_WithMockNpx_EmptyOutput(t *testing.T) {
linter := eslintLinter{}
dir := t.TempDir()
file := filepath.Join(dir, "test.js")
if err := os.WriteFile(file, []byte("const x = 1;"), 0644); err != nil {
if err := os.WriteFile(file, []byte("const x = 1;"), 0o644); err != nil {
t.Fatal(err)
}

Expand All @@ -275,7 +275,7 @@ func TestEslintLinter_WithMockNpx_EmptyOutput(t *testing.T) {
func TestEslintLinter_WithMockEslint(t *testing.T) {
mockDir := t.TempDir()
mockEslint := filepath.Join(mockDir, "eslint")
if err := os.WriteFile(mockEslint, []byte("#!/bin/sh\nexit 0\n"), 0755); err != nil {
if err := os.WriteFile(mockEslint, []byte("#!/bin/sh\nexit 0\n"), 0o755); err != nil {
t.Fatal(err)
}

Expand All @@ -286,7 +286,7 @@ func TestEslintLinter_WithMockEslint(t *testing.T) {
linter := eslintLinter{}
dir := t.TempDir()
file := filepath.Join(dir, "test.js")
if err := os.WriteFile(file, []byte("const x = 1;"), 0644); err != nil {
if err := os.WriteFile(file, []byte("const x = 1;"), 0o644); err != nil {
t.Fatal(err)
}

Expand All @@ -300,7 +300,7 @@ func TestEslintLinter_WithMockEslint(t *testing.T) {
func TestRuffLinter_WithMockRuff(t *testing.T) {
mockDir := t.TempDir()
mockRuff := filepath.Join(mockDir, "ruff")
if err := os.WriteFile(mockRuff, []byte("#!/bin/sh\nexit 0\n"), 0755); err != nil {
if err := os.WriteFile(mockRuff, []byte("#!/bin/sh\nexit 0\n"), 0o755); err != nil {
t.Fatal(err)
}

Expand All @@ -311,7 +311,7 @@ func TestRuffLinter_WithMockRuff(t *testing.T) {
linter := ruffLinter{}
dir := t.TempDir()
file := filepath.Join(dir, "test.py")
if err := os.WriteFile(file, []byte("x = 1\n"), 0644); err != nil {
if err := os.WriteFile(file, []byte("x = 1\n"), 0o644); err != nil {
t.Fatal(err)
}

Expand All @@ -325,7 +325,7 @@ func TestRuffLinter_WithMockRuff(t *testing.T) {
func TestRuffLinter_WithMockRuff_Failure(t *testing.T) {
mockDir := t.TempDir()
mockRuff := filepath.Join(mockDir, "ruff")
if err := os.WriteFile(mockRuff, []byte("#!/bin/sh\necho 'E501 line too long'\nexit 1\n"), 0755); err != nil {
if err := os.WriteFile(mockRuff, []byte("#!/bin/sh\necho 'E501 line too long'\nexit 1\n"), 0o755); err != nil {
t.Fatal(err)
}

Expand All @@ -336,7 +336,7 @@ func TestRuffLinter_WithMockRuff_Failure(t *testing.T) {
linter := ruffLinter{}
dir := t.TempDir()
file := filepath.Join(dir, "test.py")
if err := os.WriteFile(file, []byte("x = 1\n"), 0644); err != nil {
if err := os.WriteFile(file, []byte("x = 1\n"), 0o644); err != nil {
t.Fatal(err)
}

Expand Down
8 changes: 4 additions & 4 deletions internal/lsp/lsp_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,14 @@ func TestLoadConfig_Extra(t *testing.T) {
// Create a temp directory with a custom config
dir := t.TempDir()
agentsDir := filepath.Join(dir, ".agents")
if err := os.MkdirAll(agentsDir, 0755); err != nil {
if err := os.MkdirAll(agentsDir, 0o755); err != nil {
t.Fatalf("failed to create .agents dir: %v", err)
}

// Write a custom config
customConfig := `{"lsp": {"custom-lang": {"command": "custom-lsp", "extensions": [".custom"]}}}`
configPath := filepath.Join(agentsDir, "lsp.json")
if err := os.WriteFile(configPath, []byte(customConfig), 0644); err != nil {
if err := os.WriteFile(configPath, []byte(customConfig), 0o644); err != nil {
t.Fatalf("failed to write config: %v", err)
}

Expand Down Expand Up @@ -144,13 +144,13 @@ func TestLoadConfig_InvalidJSON_Extra(t *testing.T) {

dir := t.TempDir()
agentsDir := filepath.Join(dir, ".agents")
if err := os.MkdirAll(agentsDir, 0755); err != nil {
if err := os.MkdirAll(agentsDir, 0o755); err != nil {
t.Fatalf("failed to create .agents dir: %v", err)
}

// Write invalid JSON
configPath := filepath.Join(agentsDir, "lsp.json")
if err := os.WriteFile(configPath, []byte("{invalid json}"), 0644); err != nil {
if err := os.WriteFile(configPath, []byte("{invalid json}"), 0o644); err != nil {
t.Fatalf("failed to write config: %v", err)
}

Expand Down
4 changes: 2 additions & 2 deletions internal/sandbox/config_extra_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ func TestResolveMode_Aliases(t *testing.T) {
func TestResolveMode_Extends(t *testing.T) {
cfg := TOMLConfig{
Profiles: map[string]ProfileConfig{
"base": {Mode: "strict"},
"child": {Extends: "base"},
"base": {Mode: "strict"},
"child": {Extends: "base"},
},
}
mode := resolveMode(cfg, "child")
Expand Down
Loading
Loading