mirror of
https://github.com/syntrex-lab/gomcp.git
synced 2026-04-25 04:16:22 +02:00
184 lines
5.2 KiB
Go
184 lines
5.2 KiB
Go
package session
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestNewCognitiveStateVector(t *testing.T) {
|
|
csv := NewCognitiveStateVector("test-session")
|
|
|
|
assert.Equal(t, "test-session", csv.SessionID)
|
|
assert.Equal(t, 1, csv.Version)
|
|
assert.False(t, csv.Timestamp.IsZero())
|
|
assert.Nil(t, csv.PrimaryGoal)
|
|
assert.Empty(t, csv.Hypotheses)
|
|
assert.Empty(t, csv.Decisions)
|
|
assert.Empty(t, csv.Facts)
|
|
assert.Empty(t, csv.OpenQuestions)
|
|
assert.NotNil(t, csv.ConfidenceMap)
|
|
}
|
|
|
|
func TestCognitiveStateVector_SetGoal(t *testing.T) {
|
|
csv := NewCognitiveStateVector("s1")
|
|
csv.SetGoal("Build GoMCP v2", 0.3)
|
|
|
|
require.NotNil(t, csv.PrimaryGoal)
|
|
assert.Equal(t, "Build GoMCP v2", csv.PrimaryGoal.Description)
|
|
assert.InDelta(t, 0.3, csv.PrimaryGoal.Progress, 0.001)
|
|
assert.NotEmpty(t, csv.PrimaryGoal.ID)
|
|
}
|
|
|
|
func TestCognitiveStateVector_SetGoal_ClampProgress(t *testing.T) {
|
|
csv := NewCognitiveStateVector("s1")
|
|
|
|
csv.SetGoal("over", 1.5)
|
|
assert.InDelta(t, 1.0, csv.PrimaryGoal.Progress, 0.001)
|
|
|
|
csv.SetGoal("under", -0.5)
|
|
assert.InDelta(t, 0.0, csv.PrimaryGoal.Progress, 0.001)
|
|
}
|
|
|
|
func TestCognitiveStateVector_AddHypothesis(t *testing.T) {
|
|
csv := NewCognitiveStateVector("s1")
|
|
h := csv.AddHypothesis("Caching reduces latency by 50%")
|
|
|
|
assert.NotEmpty(t, h.ID)
|
|
assert.Equal(t, "Caching reduces latency by 50%", h.Statement)
|
|
assert.Equal(t, HypothesisProposed, h.Status)
|
|
assert.Len(t, csv.Hypotheses, 1)
|
|
}
|
|
|
|
func TestCognitiveStateVector_AddDecision(t *testing.T) {
|
|
csv := NewCognitiveStateVector("s1")
|
|
d := csv.AddDecision("Use SQLite", "Embedded, no server", []string{"PostgreSQL", "Redis"})
|
|
|
|
assert.NotEmpty(t, d.ID)
|
|
assert.Equal(t, "Use SQLite", d.Description)
|
|
assert.Equal(t, "Embedded, no server", d.Rationale)
|
|
assert.Equal(t, []string{"PostgreSQL", "Redis"}, d.Alternatives)
|
|
assert.Len(t, csv.Decisions, 1)
|
|
}
|
|
|
|
func TestCognitiveStateVector_AddFact(t *testing.T) {
|
|
csv := NewCognitiveStateVector("s1")
|
|
f := csv.AddFact("Go 1.25 is required", "requirement", 0.95)
|
|
|
|
assert.NotEmpty(t, f.ID)
|
|
assert.Equal(t, "Go 1.25 is required", f.Content)
|
|
assert.Equal(t, "requirement", f.EntityType)
|
|
assert.InDelta(t, 0.95, f.Confidence, 0.001)
|
|
assert.Len(t, csv.Facts, 1)
|
|
}
|
|
|
|
func TestCognitiveStateVector_BumpVersion(t *testing.T) {
|
|
csv := NewCognitiveStateVector("s1")
|
|
assert.Equal(t, 1, csv.Version)
|
|
|
|
csv.BumpVersion()
|
|
assert.Equal(t, 2, csv.Version)
|
|
}
|
|
|
|
func TestCognitiveStateVector_ToJSON_FromJSON(t *testing.T) {
|
|
csv := NewCognitiveStateVector("s1")
|
|
csv.SetGoal("Test serialization", 0.5)
|
|
csv.AddHypothesis("JSON round-trips cleanly")
|
|
csv.AddDecision("Use encoding/json", "stdlib", nil)
|
|
csv.AddFact("fact1", "fact", 1.0)
|
|
|
|
data, err := json.Marshal(csv)
|
|
require.NoError(t, err)
|
|
require.NotEmpty(t, data)
|
|
|
|
var restored CognitiveStateVector
|
|
err = json.Unmarshal(data, &restored)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, csv.SessionID, restored.SessionID)
|
|
assert.Equal(t, csv.Version, restored.Version)
|
|
require.NotNil(t, restored.PrimaryGoal)
|
|
assert.Equal(t, csv.PrimaryGoal.Description, restored.PrimaryGoal.Description)
|
|
assert.Len(t, restored.Hypotheses, 1)
|
|
assert.Len(t, restored.Decisions, 1)
|
|
assert.Len(t, restored.Facts, 1)
|
|
}
|
|
|
|
func TestCognitiveStateVector_ToCompactString(t *testing.T) {
|
|
csv := NewCognitiveStateVector("s1")
|
|
csv.SetGoal("Build GoMCP", 0.4)
|
|
csv.AddFact("Go 1.25", "requirement", 1.0)
|
|
csv.AddDecision("Use mcp-go", "mature lib", nil)
|
|
|
|
compact := csv.ToCompactString(500)
|
|
assert.Contains(t, compact, "GOAL:")
|
|
assert.Contains(t, compact, "Build GoMCP")
|
|
assert.Contains(t, compact, "FACTS:")
|
|
assert.Contains(t, compact, "Go 1.25")
|
|
assert.Contains(t, compact, "DECISIONS:")
|
|
}
|
|
|
|
func TestCognitiveStateVector_ToCompactString_Truncation(t *testing.T) {
|
|
csv := NewCognitiveStateVector("s1")
|
|
csv.SetGoal("Goal", 0.0)
|
|
for i := 0; i < 100; i++ {
|
|
csv.AddFact("This is a moderately long fact content for testing truncation behavior", "fact", 1.0)
|
|
}
|
|
|
|
compact := csv.ToCompactString(100)
|
|
assert.LessOrEqual(t, len(compact), 100*4) // max_tokens * 4 chars
|
|
}
|
|
|
|
func TestCognitiveStateVector_Checksum(t *testing.T) {
|
|
csv := NewCognitiveStateVector("s1")
|
|
csv.AddFact("fact", "fact", 1.0)
|
|
|
|
c1 := csv.Checksum()
|
|
assert.NotEmpty(t, c1)
|
|
assert.Len(t, c1, 64) // SHA-256 hex
|
|
|
|
// Same state = same checksum
|
|
c2 := csv.Checksum()
|
|
assert.Equal(t, c1, c2)
|
|
|
|
// Different state = different checksum
|
|
csv.AddFact("another fact", "fact", 1.0)
|
|
c3 := csv.Checksum()
|
|
assert.NotEqual(t, c1, c3)
|
|
}
|
|
|
|
func TestGoal_Validate(t *testing.T) {
|
|
g := &Goal{ID: "g1", Description: "test", Progress: 0.5}
|
|
assert.NoError(t, g.Validate())
|
|
|
|
g.Description = ""
|
|
assert.Error(t, g.Validate())
|
|
|
|
g.Description = "test"
|
|
g.Progress = -0.1
|
|
assert.Error(t, g.Validate())
|
|
|
|
g.Progress = 1.1
|
|
assert.Error(t, g.Validate())
|
|
}
|
|
|
|
func TestHypothesisStatus_Valid(t *testing.T) {
|
|
assert.True(t, HypothesisProposed.IsValid())
|
|
assert.True(t, HypothesisTesting.IsValid())
|
|
assert.True(t, HypothesisConfirmed.IsValid())
|
|
assert.True(t, HypothesisRejected.IsValid())
|
|
assert.False(t, HypothesisStatus("invalid").IsValid())
|
|
}
|
|
|
|
func TestSessionInfo(t *testing.T) {
|
|
info := SessionInfo{
|
|
SessionID: "s1",
|
|
Version: 5,
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
assert.Equal(t, "s1", info.SessionID)
|
|
assert.Equal(t, 5, info.Version)
|
|
}
|