All checks were successful
Tests / unit-tests (push) Successful in 51s
- Login sa session cookie autentifikacijom - Lista projekata iz filesystem-a - Chat sa Claude CLI preko WebSocket-a - Streaming NDJSON parsiranje iz CLI stdout-a - Sesija zivi nezavisno od browsera (reconnect replay) - Sidebar sa .md fajlovima i markdown renderovanjem - Dark tema, htmx + Go templates - 47 unit testova Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
127 lines
3.3 KiB
Go
127 lines
3.3 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
)
|
|
|
|
func TestFilterEnv(t *testing.T) {
|
|
env := []string{
|
|
"PATH=/usr/bin",
|
|
"HOME=/root",
|
|
"CLAUDECODE=1",
|
|
"OTHER=value",
|
|
}
|
|
|
|
filtered := filterEnv(env, "CLAUDECODE")
|
|
|
|
if len(filtered) != 3 {
|
|
t.Fatalf("got %d entries, want 3", len(filtered))
|
|
}
|
|
|
|
for _, e := range filtered {
|
|
if e == "CLAUDECODE=1" {
|
|
t.Error("CLAUDECODE should be filtered out")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestFilterEnvNotPresent(t *testing.T) {
|
|
env := []string{"PATH=/usr/bin", "HOME=/root"}
|
|
filtered := filterEnv(env, "CLAUDECODE")
|
|
if len(filtered) != 2 {
|
|
t.Fatalf("got %d entries, want 2", len(filtered))
|
|
}
|
|
}
|
|
|
|
func TestTruncate(t *testing.T) {
|
|
tests := []struct {
|
|
input string
|
|
n int
|
|
want string
|
|
}{
|
|
{"hello", 10, "hello"},
|
|
{"hello world", 5, "hello..."},
|
|
{"", 5, ""},
|
|
}
|
|
for _, tt := range tests {
|
|
got := truncate(tt.input, tt.n)
|
|
if got != tt.want {
|
|
t.Errorf("truncate(%q, %d) = %q, want %q", tt.input, tt.n, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestCLIEventParsing(t *testing.T) {
|
|
t.Run("assistant message", func(t *testing.T) {
|
|
raw := `{"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"Hello!"}]}}`
|
|
var event CLIEvent
|
|
if err := json.Unmarshal([]byte(raw), &event); err != nil {
|
|
t.Fatalf("unmarshal: %v", err)
|
|
}
|
|
if event.Type != "assistant" {
|
|
t.Errorf("type = %q", event.Type)
|
|
}
|
|
if event.Message == nil {
|
|
t.Fatal("message is nil")
|
|
}
|
|
if len(event.Message.Content) != 1 {
|
|
t.Fatalf("content length = %d", len(event.Message.Content))
|
|
}
|
|
if event.Message.Content[0].Text != "Hello!" {
|
|
t.Errorf("text = %q", event.Message.Content[0].Text)
|
|
}
|
|
})
|
|
|
|
t.Run("content_block_delta", func(t *testing.T) {
|
|
raw := `{"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"chunk"}}`
|
|
var event CLIEvent
|
|
if err := json.Unmarshal([]byte(raw), &event); err != nil {
|
|
t.Fatalf("unmarshal: %v", err)
|
|
}
|
|
if event.Type != "content_block_delta" {
|
|
t.Errorf("type = %q", event.Type)
|
|
}
|
|
if event.Delta == nil {
|
|
t.Fatal("delta is nil")
|
|
}
|
|
if event.Delta.Text != "chunk" {
|
|
t.Errorf("text = %q", event.Delta.Text)
|
|
}
|
|
})
|
|
|
|
t.Run("result event", func(t *testing.T) {
|
|
raw := `{"type":"result","subtype":"success","result":{"duration_ms":1234.5,"num_turns":3,"cost_usd":0.05,"session_id":"abc123"}}`
|
|
var event CLIEvent
|
|
if err := json.Unmarshal([]byte(raw), &event); err != nil {
|
|
t.Fatalf("unmarshal: %v", err)
|
|
}
|
|
if event.Type != "result" {
|
|
t.Errorf("type = %q", event.Type)
|
|
}
|
|
if event.Subtype != "success" {
|
|
t.Errorf("subtype = %q", event.Subtype)
|
|
}
|
|
if event.Result == nil {
|
|
t.Fatal("result is nil")
|
|
}
|
|
if event.Result.SessionID != "abc123" {
|
|
t.Errorf("session_id = %q", event.Result.SessionID)
|
|
}
|
|
})
|
|
|
|
t.Run("tool_use content", func(t *testing.T) {
|
|
raw := `{"type":"assistant","message":{"role":"assistant","content":[{"type":"tool_use","name":"Read","id":"tool1","input":{"file_path":"/tmp/test.go"}}]}}`
|
|
var event CLIEvent
|
|
if err := json.Unmarshal([]byte(raw), &event); err != nil {
|
|
t.Fatalf("unmarshal: %v", err)
|
|
}
|
|
if event.Message.Content[0].Type != "tool_use" {
|
|
t.Errorf("content type = %q", event.Message.Content[0].Type)
|
|
}
|
|
if event.Message.Content[0].Name != "Read" {
|
|
t.Errorf("name = %q", event.Message.Content[0].Name)
|
|
}
|
|
})
|
|
}
|