Files
bzzz/pkg/protocol/uri_test.go
anthonyrawlins b207f32d9e Implement UCXL Protocol Foundation (Phase 1)
- Add complete UCXL address parser with BNF grammar validation
- Implement temporal navigation system with bounds checking
- Create UCXI HTTP server with REST-like operations
- Add comprehensive test suite with 87 passing tests
- Integrate with existing BZZZ architecture (opt-in via config)
- Support semantic addressing with wildcards and version control

Core Features:
- UCXL address format: ucxl://agent:role@project:task/temporal/path
- Temporal segments: *^, ~~N, ^^N, *~, *~N with navigation logic
- UCXI endpoints: GET/PUT/POST/DELETE/ANNOUNCE operations
- Production-ready with error handling and graceful shutdown

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-08 07:38:04 +10:00

509 lines
11 KiB
Go

package protocol
import (
"testing"
)
func TestParseBzzzURI(t *testing.T) {
tests := []struct {
name string
uri string
expectError bool
expected *BzzzURI
}{
{
name: "valid basic URI",
uri: "bzzz://claude:frontend@chorus:implement/src/main.go",
expected: &BzzzURI{
Agent: "claude",
Role: "frontend",
Project: "chorus",
Task: "implement",
Path: "/src/main.go",
Raw: "bzzz://claude:frontend@chorus:implement/src/main.go",
},
},
{
name: "URI with wildcards",
uri: "bzzz://any:*@*:test",
expected: &BzzzURI{
Agent: "any",
Role: "*",
Project: "*",
Task: "test",
Raw: "bzzz://any:*@*:test",
},
},
{
name: "URI with query and fragment",
uri: "bzzz://claude:backend@bzzz:debug/api/handler.go?type=error#line123",
expected: &BzzzURI{
Agent: "claude",
Role: "backend",
Project: "bzzz",
Task: "debug",
Path: "/api/handler.go",
Query: "type=error",
Fragment: "line123",
Raw: "bzzz://claude:backend@bzzz:debug/api/handler.go?type=error#line123",
},
},
{
name: "URI without path",
uri: "bzzz://any:architect@project:review",
expected: &BzzzURI{
Agent: "any",
Role: "architect",
Project: "project",
Task: "review",
Raw: "bzzz://any:architect@project:review",
},
},
{
name: "invalid scheme",
uri: "http://claude:frontend@chorus:implement",
expectError: true,
},
{
name: "missing role",
uri: "bzzz://claude@chorus:implement",
expectError: true,
},
{
name: "missing task",
uri: "bzzz://claude:frontend@chorus",
expectError: true,
},
{
name: "empty URI",
uri: "",
expectError: true,
},
{
name: "invalid format",
uri: "bzzz://invalid",
expectError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := ParseBzzzURI(tt.uri)
if tt.expectError {
if err == nil {
t.Errorf("expected error but got none")
}
return
}
if err != nil {
t.Errorf("unexpected error: %v", err)
return
}
if result == nil {
t.Errorf("result is nil")
return
}
// Compare components
if result.Agent != tt.expected.Agent {
t.Errorf("Agent: expected %s, got %s", tt.expected.Agent, result.Agent)
}
if result.Role != tt.expected.Role {
t.Errorf("Role: expected %s, got %s", tt.expected.Role, result.Role)
}
if result.Project != tt.expected.Project {
t.Errorf("Project: expected %s, got %s", tt.expected.Project, result.Project)
}
if result.Task != tt.expected.Task {
t.Errorf("Task: expected %s, got %s", tt.expected.Task, result.Task)
}
if result.Path != tt.expected.Path {
t.Errorf("Path: expected %s, got %s", tt.expected.Path, result.Path)
}
if result.Query != tt.expected.Query {
t.Errorf("Query: expected %s, got %s", tt.expected.Query, result.Query)
}
if result.Fragment != tt.expected.Fragment {
t.Errorf("Fragment: expected %s, got %s", tt.expected.Fragment, result.Fragment)
}
})
}
}
func TestBzzzURIValidation(t *testing.T) {
tests := []struct {
name string
uri *BzzzURI
expectError bool
}{
{
name: "valid URI",
uri: &BzzzURI{
Agent: "claude",
Role: "frontend",
Project: "chorus",
Task: "implement",
Path: "/src/main.go",
},
expectError: false,
},
{
name: "empty agent",
uri: &BzzzURI{
Agent: "",
Role: "frontend",
Project: "chorus",
Task: "implement",
},
expectError: true,
},
{
name: "invalid agent format",
uri: &BzzzURI{
Agent: "invalid@agent",
Role: "frontend",
Project: "chorus",
Task: "implement",
},
expectError: true,
},
{
name: "wildcard components",
uri: &BzzzURI{
Agent: "*",
Role: "any",
Project: "*",
Task: "*",
},
expectError: false,
},
{
name: "invalid path",
uri: &BzzzURI{
Agent: "claude",
Role: "frontend",
Project: "chorus",
Task: "implement",
Path: "invalid-path", // Should start with /
},
expectError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.uri.Validate()
if tt.expectError && err == nil {
t.Errorf("expected error but got none")
}
if !tt.expectError && err != nil {
t.Errorf("unexpected error: %v", err)
}
})
}
}
func TestBzzzURINormalize(t *testing.T) {
uri := &BzzzURI{
Agent: "Claude",
Role: "Frontend",
Project: "CHORUS",
Task: "Implement",
Path: "src/main.go", // Missing leading slash
}
uri.Normalize()
expected := &BzzzURI{
Agent: "claude",
Role: "frontend",
Project: "chorus",
Task: "implement",
Path: "/src/main.go",
}
if uri.Agent != expected.Agent {
t.Errorf("Agent: expected %s, got %s", expected.Agent, uri.Agent)
}
if uri.Role != expected.Role {
t.Errorf("Role: expected %s, got %s", expected.Role, uri.Role)
}
if uri.Project != expected.Project {
t.Errorf("Project: expected %s, got %s", expected.Project, uri.Project)
}
if uri.Task != expected.Task {
t.Errorf("Task: expected %s, got %s", expected.Task, uri.Task)
}
if uri.Path != expected.Path {
t.Errorf("Path: expected %s, got %s", expected.Path, uri.Path)
}
}
func TestBzzzURIMatches(t *testing.T) {
tests := []struct {
name string
uri1 *BzzzURI
uri2 *BzzzURI
expected bool
}{
{
name: "exact match",
uri1: &BzzzURI{Agent: "claude", Role: "frontend", Project: "chorus", Task: "implement"},
uri2: &BzzzURI{Agent: "claude", Role: "frontend", Project: "chorus", Task: "implement"},
expected: true,
},
{
name: "wildcard agent match",
uri1: &BzzzURI{Agent: "*", Role: "frontend", Project: "chorus", Task: "implement"},
uri2: &BzzzURI{Agent: "claude", Role: "frontend", Project: "chorus", Task: "implement"},
expected: true,
},
{
name: "any role match",
uri1: &BzzzURI{Agent: "claude", Role: "any", Project: "chorus", Task: "implement"},
uri2: &BzzzURI{Agent: "claude", Role: "frontend", Project: "chorus", Task: "implement"},
expected: true,
},
{
name: "no match",
uri1: &BzzzURI{Agent: "claude", Role: "backend", Project: "chorus", Task: "implement"},
uri2: &BzzzURI{Agent: "claude", Role: "frontend", Project: "chorus", Task: "implement"},
expected: false,
},
{
name: "nil comparison",
uri1: &BzzzURI{Agent: "claude", Role: "frontend", Project: "chorus", Task: "implement"},
uri2: nil,
expected: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := tt.uri1.Matches(tt.uri2)
if result != tt.expected {
t.Errorf("expected %v, got %v", tt.expected, result)
}
})
}
}
func TestBzzzURIString(t *testing.T) {
tests := []struct {
name string
uri *BzzzURI
expected string
}{
{
name: "basic URI",
uri: &BzzzURI{
Agent: "claude",
Role: "frontend",
Project: "chorus",
Task: "implement",
Path: "/src/main.go",
},
expected: "bzzz://claude:frontend@chorus:implement/src/main.go",
},
{
name: "URI with query and fragment",
uri: &BzzzURI{
Agent: "claude",
Role: "backend",
Project: "bzzz",
Task: "debug",
Path: "/api/handler.go",
Query: "type=error",
Fragment: "line123",
},
expected: "bzzz://claude:backend@bzzz:debug/api/handler.go?type=error#line123",
},
{
name: "URI without path",
uri: &BzzzURI{
Agent: "any",
Role: "architect",
Project: "project",
Task: "review",
},
expected: "bzzz://any:architect@project:review",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := tt.uri.String()
if result != tt.expected {
t.Errorf("expected %s, got %s", tt.expected, result)
}
})
}
}
func TestGetSelectorPriority(t *testing.T) {
tests := []struct {
name string
uri *BzzzURI
expected int
}{
{
name: "all specific",
uri: &BzzzURI{
Agent: "claude",
Role: "frontend",
Project: "chorus",
Task: "implement",
Path: "/src/main.go",
},
expected: 8 + 4 + 2 + 1 + 1, // All components + path
},
{
name: "some wildcards",
uri: &BzzzURI{
Agent: "*",
Role: "frontend",
Project: "*",
Task: "implement",
},
expected: 4 + 1, // Role + Task
},
{
name: "all wildcards",
uri: &BzzzURI{
Agent: "*",
Role: "any",
Project: "*",
Task: "*",
},
expected: 0,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := tt.uri.GetSelectorPriority()
if result != tt.expected {
t.Errorf("expected %d, got %d", tt.expected, result)
}
})
}
}
func TestParseAddress(t *testing.T) {
tests := []struct {
name string
addr string
expectError bool
expected *BzzzURI
}{
{
name: "valid address",
addr: "claude:frontend@chorus:implement",
expected: &BzzzURI{
Agent: "claude",
Role: "frontend",
Project: "chorus",
Task: "implement",
},
},
{
name: "invalid address",
addr: "invalid-format",
expectError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := ParseAddress(tt.addr)
if tt.expectError {
if err == nil {
t.Errorf("expected error but got none")
}
return
}
if err != nil {
t.Errorf("unexpected error: %v", err)
return
}
if result.Agent != tt.expected.Agent {
t.Errorf("Agent: expected %s, got %s", tt.expected.Agent, result.Agent)
}
if result.Role != tt.expected.Role {
t.Errorf("Role: expected %s, got %s", tt.expected.Role, result.Role)
}
if result.Project != tt.expected.Project {
t.Errorf("Project: expected %s, got %s", tt.expected.Project, result.Project)
}
if result.Task != tt.expected.Task {
t.Errorf("Task: expected %s, got %s", tt.expected.Task, result.Task)
}
})
}
}
func TestIsWildcard(t *testing.T) {
tests := []struct {
component string
expected bool
}{
{"*", true},
{"any", true},
{"claude", false},
{"frontend", false},
{"", false},
}
for _, tt := range tests {
t.Run(tt.component, func(t *testing.T) {
result := IsWildcard(tt.component)
if result != tt.expected {
t.Errorf("expected %v, got %v", tt.expected, result)
}
})
}
}
func TestValidateBzzzURIString(t *testing.T) {
tests := []struct {
name string
uri string
expectError bool
}{
{
name: "valid URI",
uri: "bzzz://claude:frontend@chorus:implement/src/main.go",
expectError: false,
},
{
name: "invalid scheme",
uri: "http://claude:frontend@chorus:implement",
expectError: true,
},
{
name: "empty URI",
uri: "",
expectError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := ValidateBzzzURIString(tt.uri)
if tt.expectError && err == nil {
t.Errorf("expected error but got none")
}
if !tt.expectError && err != nil {
t.Errorf("unexpected error: %v", err)
}
})
}
}