Major additions: - Community Next.js app (port 18187) for browsing claims with API docs - stemedb-chaos crate: Fault injection, chaos testing, CRDT properties - Latent ingestion system: Reddit/FDA ingesters with ADK-Go agents - Disputed claims handling: Manual review workflows and validation - Aphoria security scanner: New extractors (SQL injection, command injection, weak crypto, TLS version), policy-based ignores, UAT reports - Docker infrastructure: Dockerfile, docker-compose.yml for full stack - VulnBank demo: Intentionally vulnerable multi-language test corpus SDK & API enhancements: - Source registry handlers for tracking data provenance - Metrics endpoint - Skeptic filtering improvements Code quality: - Split 14 large files (>500 lines) into focused modules - All files now under 500-line limit per project guidelines Documentation: - Chaos testing guide, circuit breakers, observability docs - Phase 7 UAT documentation updates - Martin Kleppmann technical writer agent Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
139 lines
3.1 KiB
Go
139 lines
3.1 KiB
Go
package adk
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/orchard9/stemedb-go/steme"
|
|
)
|
|
|
|
func TestToolNames(t *testing.T) {
|
|
client := &mockClient{}
|
|
|
|
tests := []struct {
|
|
tool Tool
|
|
expectedName string
|
|
}{
|
|
{NewQueryTool(client), "episteme_query"},
|
|
{NewAssertTool(client), "episteme_assert"},
|
|
{NewConstraintCheckTool(client), "episteme_constraint_check"},
|
|
{NewTraceTool(client), "episteme_trace"},
|
|
{NewSupersedeTool(client), "episteme_supersede"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
if tt.tool.Name() != tt.expectedName {
|
|
t.Errorf("expected tool name %s, got %s", tt.expectedName, tt.tool.Name())
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAllTools(t *testing.T) {
|
|
client := &mockClient{}
|
|
tools := AllTools(client)
|
|
|
|
if len(tools) != 5 {
|
|
t.Errorf("expected 5 tools, got %d", len(tools))
|
|
}
|
|
|
|
// Verify all expected tools are present
|
|
expectedNames := map[string]bool{
|
|
"episteme_query": false,
|
|
"episteme_assert": false,
|
|
"episteme_constraint_check": false,
|
|
"episteme_trace": false,
|
|
"episteme_supersede": false,
|
|
}
|
|
|
|
for _, tool := range tools {
|
|
expectedNames[tool.Name()] = true
|
|
}
|
|
|
|
for name, found := range expectedNames {
|
|
if !found {
|
|
t.Errorf("expected to find tool %s", name)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestConfigCreation(t *testing.T) {
|
|
client := &mockClient{}
|
|
logFunc := func(format string, args ...any) {}
|
|
setState := func(key string, value any) {}
|
|
|
|
configs := AllConfigs(client, 0.8, setState, logFunc)
|
|
|
|
expectedAgents := []string{
|
|
"implementation",
|
|
"lead",
|
|
"research",
|
|
"supervisor",
|
|
"oncall",
|
|
}
|
|
|
|
for _, agentType := range expectedAgents {
|
|
config, ok := configs[agentType]
|
|
if !ok {
|
|
t.Errorf("expected config for %s", agentType)
|
|
continue
|
|
}
|
|
|
|
if config.Name == "" {
|
|
t.Errorf("config for %s has empty name", agentType)
|
|
}
|
|
|
|
if config.Description == "" {
|
|
t.Errorf("config for %s has empty description", agentType)
|
|
}
|
|
|
|
if config.Instruction == "" {
|
|
t.Errorf("config for %s has empty instruction", agentType)
|
|
}
|
|
|
|
if len(config.Tools) == 0 {
|
|
t.Errorf("config for %s has no tools", agentType)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestParseLifecycle(t *testing.T) {
|
|
tests := []struct {
|
|
input string
|
|
expected steme.LifecycleStage
|
|
}{
|
|
{"proposed", steme.LifecycleProposed},
|
|
{"under_review", steme.LifecycleUnderReview},
|
|
{"approved", steme.LifecycleApproved},
|
|
{"deprecated", steme.LifecycleDeprecated},
|
|
{"rejected", steme.LifecycleRejected},
|
|
{"invalid", steme.LifecycleProposed}, // Default
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
result := parseLifecycle(tt.input)
|
|
if result != tt.expected {
|
|
t.Errorf("parseLifecycle(%s) = %v, expected %v", tt.input, result, tt.expected)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestParseLens(t *testing.T) {
|
|
tests := []struct {
|
|
input string
|
|
expected steme.Lens
|
|
}{
|
|
{"recency", steme.LensRecency},
|
|
{"consensus", steme.LensConsensus},
|
|
{"authority", steme.LensAuthority},
|
|
{"vote_aware_consensus", steme.LensVoteAwareConsensus},
|
|
{"trust_aware_authority", steme.LensTrustAwareAuthority},
|
|
{"invalid", steme.LensConsensus}, // Default
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
result := parseLen(tt.input)
|
|
if result != tt.expected {
|
|
t.Errorf("parseLen(%s) = %v, expected %v", tt.input, result, tt.expected)
|
|
}
|
|
}
|
|
}
|