All checks were successful
Tests / unit-tests (push) Successful in 8s
- Uklonjen --include-partial-messages (izazivao duple assistant evente) - content_block_start preskače tool_use blokove (prazni divovi) - Shift+Tab prebacuje između Code i Plan moda - Plan mod šalje instrukciju da Claude samo planira bez izmena - CSS za mode bar i plan poruke (plava boja, ⊞ prefix) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
172 lines
4.5 KiB
Go
172 lines
4.5 KiB
Go
package main
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestFragmentUserMessage(t *testing.T) {
|
|
f := FragmentUserMessage("Hello <world>", false)
|
|
if !strings.Contains(f, "message-user") {
|
|
t.Error("missing message-user class")
|
|
}
|
|
if !strings.Contains(f, "Hello <world>") {
|
|
t.Error("should escape HTML")
|
|
}
|
|
if !strings.Contains(f, `hx-swap-oob="beforeend"`) {
|
|
t.Error("missing OOB swap")
|
|
}
|
|
if strings.Contains(f, "message-user-plan") {
|
|
t.Error("should not have plan class in code mode")
|
|
}
|
|
|
|
// Plan mode
|
|
fp := FragmentUserMessage("analyze this", true)
|
|
if !strings.Contains(fp, "message-user-plan") {
|
|
t.Error("missing plan class in plan mode")
|
|
}
|
|
}
|
|
|
|
func TestFragmentAssistantStart(t *testing.T) {
|
|
f := FragmentAssistantStart("msg-1")
|
|
if !strings.Contains(f, `id="msg-1"`) {
|
|
t.Error("missing message ID")
|
|
}
|
|
if !strings.Contains(f, "message-assistant") {
|
|
t.Error("missing message-assistant class")
|
|
}
|
|
}
|
|
|
|
func TestFragmentAssistantChunk(t *testing.T) {
|
|
f := FragmentAssistantChunk("msg-1", "chunk<text>")
|
|
if !strings.Contains(f, `id="msg-1"`) {
|
|
t.Error("missing message ID")
|
|
}
|
|
if !strings.Contains(f, "chunk<text>") {
|
|
t.Error("should escape HTML")
|
|
}
|
|
}
|
|
|
|
func TestFragmentAssistantComplete(t *testing.T) {
|
|
f := FragmentAssistantComplete("msg-1", "<p>Hello</p>")
|
|
if !strings.Contains(f, `id="msg-1"`) {
|
|
t.Error("missing message ID")
|
|
}
|
|
if !strings.Contains(f, "<p>Hello</p>") {
|
|
t.Error("should include raw HTML content")
|
|
}
|
|
}
|
|
|
|
func TestFragmentToolCall(t *testing.T) {
|
|
f := FragmentToolCall("Read", `{"file_path":"/tmp/test.go"}`)
|
|
if !strings.Contains(f, "message-tool") {
|
|
t.Error("missing message-tool class")
|
|
}
|
|
if !strings.Contains(f, "Read") {
|
|
t.Error("missing tool name")
|
|
}
|
|
if !strings.Contains(f, "/tmp/test.go") {
|
|
t.Error("should show file path, not raw JSON")
|
|
}
|
|
if strings.Contains(f, "file_path") {
|
|
t.Error("should not show JSON key name for Read")
|
|
}
|
|
}
|
|
|
|
func TestFragmentToolCallBash(t *testing.T) {
|
|
f := FragmentToolCall("Bash", `{"command":"git status"}`)
|
|
if !strings.Contains(f, "<code>") {
|
|
t.Error("Bash command should be in code tag")
|
|
}
|
|
if !strings.Contains(f, "git status") {
|
|
t.Error("should show command")
|
|
}
|
|
}
|
|
|
|
func TestFragmentToolCallGrep(t *testing.T) {
|
|
f := FragmentToolCall("Grep", `{"pattern":"TODO","path":"/root/projects"}`)
|
|
if !strings.Contains(f, "TODO") {
|
|
t.Error("should show pattern")
|
|
}
|
|
if !strings.Contains(f, "/root/projects") {
|
|
t.Error("should show path")
|
|
}
|
|
}
|
|
|
|
func TestFragmentToolCallEdit(t *testing.T) {
|
|
f := FragmentToolCall("Edit", `{"file_path":"/tmp/main.go","old_string":"foo","new_string":"bar"}`)
|
|
if !strings.Contains(f, "/tmp/main.go") {
|
|
t.Error("should show file path")
|
|
}
|
|
}
|
|
|
|
func TestFragmentToolCallFallback(t *testing.T) {
|
|
f := FragmentToolCall("UnknownTool", `{"key1":"value1","key2":"value2"}`)
|
|
if !strings.Contains(f, "key1") || !strings.Contains(f, "value1") {
|
|
t.Error("fallback should show key=value pairs")
|
|
}
|
|
}
|
|
|
|
func TestFragmentToolCallNonJSON(t *testing.T) {
|
|
f := FragmentToolCall("Something", "plain text input")
|
|
if !strings.Contains(f, "plain text input") {
|
|
t.Error("should show plain text for non-JSON")
|
|
}
|
|
}
|
|
|
|
func TestFragmentToolCallTruncation(t *testing.T) {
|
|
longInput := strings.Repeat("x", 300)
|
|
f := FragmentToolCall("Something", longInput)
|
|
if !strings.Contains(f, "...") {
|
|
t.Error("should truncate long input")
|
|
}
|
|
}
|
|
|
|
func TestFragmentSystemMessage(t *testing.T) {
|
|
f := FragmentSystemMessage("Connected")
|
|
if !strings.Contains(f, "message-system") {
|
|
t.Error("missing message-system class")
|
|
}
|
|
if !strings.Contains(f, "Connected") {
|
|
t.Error("missing text")
|
|
}
|
|
}
|
|
|
|
func TestFragmentTypingIndicator(t *testing.T) {
|
|
show := FragmentTypingIndicator(true)
|
|
if !strings.Contains(show, "typing-indicator") {
|
|
t.Error("missing typing indicator")
|
|
}
|
|
|
|
hide := FragmentTypingIndicator(false)
|
|
if !strings.Contains(hide, `id="typing-indicator"`) {
|
|
t.Error("missing ID")
|
|
}
|
|
}
|
|
|
|
func TestFragmentStatus(t *testing.T) {
|
|
connected := FragmentStatus(true)
|
|
if !strings.Contains(connected, "connected") {
|
|
t.Error("missing connected class")
|
|
}
|
|
|
|
disconnected := FragmentStatus(false)
|
|
if strings.Contains(disconnected, `class="status connected"`) {
|
|
t.Error("should not have connected class when disconnected")
|
|
}
|
|
}
|
|
|
|
func TestFragmentClearInput(t *testing.T) {
|
|
f := FragmentClearInput()
|
|
if !strings.Contains(f, `id="message-input"`) {
|
|
t.Error("missing input ID")
|
|
}
|
|
}
|
|
|
|
func TestFragmentCombine(t *testing.T) {
|
|
combined := FragmentCombine("a", "b", "c")
|
|
if combined != "a\nb\nc" {
|
|
t.Errorf("got %q", combined)
|
|
}
|
|
}
|