claude-web-chat/pty_session_test.go
djuka 3122c5cba9
Some checks failed
Tests / unit-tests (push) Failing after 22s
Pojednostavljen chat na jedan terminal, dodata notifikacija kad Claude završi
Uklonjen multi-tab sistem — sada jedna PTY sesija po stranici.
Dodat idle detection: status "Završeno", flash animacija, browser
notifikacija i treptanje naslova kad je tab u pozadini.
CSS premešten iz inline stilova u style.css.
Dodat /api/projects endpoint i testovi za PTY sesije.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 07:20:55 +00:00

137 lines
3.1 KiB
Go

package main
import (
"testing"
)
func TestRingBuffer(t *testing.T) {
t.Run("write and read", func(t *testing.T) {
rb := NewRingBuffer(10)
rb.Write([]byte("hello"))
got := rb.Bytes()
if string(got) != "hello" {
t.Errorf("got %q, want %q", got, "hello")
}
})
t.Run("wrap around", func(t *testing.T) {
rb := NewRingBuffer(5)
rb.Write([]byte("abcdefgh")) // wraps around
got := rb.Bytes()
if string(got) != "defgh" {
t.Errorf("got %q, want %q", got, "defgh")
}
})
t.Run("exact size", func(t *testing.T) {
rb := NewRingBuffer(5)
rb.Write([]byte("abcde"))
got := rb.Bytes()
if string(got) != "abcde" {
t.Errorf("got %q, want %q", got, "abcde")
}
})
t.Run("empty", func(t *testing.T) {
rb := NewRingBuffer(10)
got := rb.Bytes()
if len(got) != 0 {
t.Errorf("expected empty, got %q", got)
}
})
t.Run("multiple writes", func(t *testing.T) {
rb := NewRingBuffer(8)
rb.Write([]byte("abc"))
rb.Write([]byte("def"))
got := rb.Bytes()
if string(got) != "abcdef" {
t.Errorf("got %q, want %q", got, "abcdef")
}
})
t.Run("overflow multiple writes", func(t *testing.T) {
rb := NewRingBuffer(5)
rb.Write([]byte("abc"))
rb.Write([]byte("defgh")) // total 8, buffer 5
got := rb.Bytes()
if string(got) != "defgh" {
t.Errorf("got %q, want %q", got, "defgh")
}
})
}
func TestPTYSessionManager(t *testing.T) {
t.Run("new manager has no sessions", func(t *testing.T) {
m := &PTYSessionManager{
sessions: make(map[string]*PTYSession),
stopCh: make(chan struct{}),
}
if len(m.sessions) != 0 {
t.Error("expected empty sessions")
}
})
t.Run("different session keys create separate sessions", func(t *testing.T) {
m := &PTYSessionManager{
sessions: make(map[string]*PTYSession),
stopCh: make(chan struct{}),
}
// Use /tmp as a safe projectDir for testing
sess1, isNew1, err := m.GetOrCreate("arv:1", "/tmp")
if err != nil {
t.Fatalf("GetOrCreate arv:1: %v", err)
}
if !isNew1 {
t.Error("expected arv:1 to be new")
}
defer sess1.Close()
sess2, isNew2, err := m.GetOrCreate("arv:2", "/tmp")
if err != nil {
t.Fatalf("GetOrCreate arv:2: %v", err)
}
if !isNew2 {
t.Error("expected arv:2 to be new")
}
defer sess2.Close()
if sess1 == sess2 {
t.Error("expected different session objects for different keys")
}
if len(m.sessions) != 2 {
t.Errorf("expected 2 sessions, got %d", len(m.sessions))
}
})
t.Run("same session key returns existing session", func(t *testing.T) {
m := &PTYSessionManager{
sessions: make(map[string]*PTYSession),
stopCh: make(chan struct{}),
}
sess1, isNew1, err := m.GetOrCreate("arv:1", "/tmp")
if err != nil {
t.Fatalf("GetOrCreate: %v", err)
}
if !isNew1 {
t.Error("expected first call to be new")
}
defer sess1.Close()
sess2, isNew2, err := m.GetOrCreate("arv:1", "/tmp")
if err != nil {
t.Fatalf("GetOrCreate second: %v", err)
}
if isNew2 {
t.Error("expected second call to reuse existing session")
}
if sess1 != sess2 {
t.Error("expected same session object for same key")
}
})
}