mirror of
https://github.com/syntrex-lab/gomcp.git
synced 2026-04-24 20:06:21 +02:00
151 lines
3.8 KiB
Go
151 lines
3.8 KiB
Go
// Copyright 2026 Syntrex Lab. All rights reserved.
|
|
// Use of this source code is governed by an Apache-2.0 license
|
|
// that can be found in the LICENSE file.
|
|
|
|
package causal
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestNodeType_IsValid(t *testing.T) {
|
|
assert.True(t, NodeDecision.IsValid())
|
|
assert.True(t, NodeReason.IsValid())
|
|
assert.True(t, NodeConsequence.IsValid())
|
|
assert.True(t, NodeConstraint.IsValid())
|
|
assert.True(t, NodeAlternative.IsValid())
|
|
assert.False(t, NodeType("invalid").IsValid())
|
|
}
|
|
|
|
func TestEdgeType_IsValid(t *testing.T) {
|
|
assert.True(t, EdgeJustifies.IsValid())
|
|
assert.True(t, EdgeCauses.IsValid())
|
|
assert.True(t, EdgeConstrains.IsValid())
|
|
assert.False(t, EdgeType("invalid").IsValid())
|
|
}
|
|
|
|
func TestNewNode(t *testing.T) {
|
|
n := NewNode(NodeDecision, "Use SQLite for storage")
|
|
|
|
assert.NotEmpty(t, n.ID)
|
|
assert.Equal(t, NodeDecision, n.Type)
|
|
assert.Equal(t, "Use SQLite for storage", n.Content)
|
|
assert.False(t, n.CreatedAt.IsZero())
|
|
}
|
|
|
|
func TestNewNode_UniqueIDs(t *testing.T) {
|
|
n1 := NewNode(NodeDecision, "a")
|
|
n2 := NewNode(NodeDecision, "b")
|
|
assert.NotEqual(t, n1.ID, n2.ID)
|
|
}
|
|
|
|
func TestNode_Validate(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
node *Node
|
|
wantErr bool
|
|
}{
|
|
{"valid", NewNode(NodeDecision, "content"), false},
|
|
{"empty ID", &Node{ID: "", Type: NodeDecision, Content: "x"}, true},
|
|
{"empty content", &Node{ID: "x", Type: NodeDecision, Content: ""}, true},
|
|
{"invalid type", &Node{ID: "x", Type: "bad", Content: "x"}, true},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
err := tt.node.Validate()
|
|
if tt.wantErr {
|
|
assert.Error(t, err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestNewEdge(t *testing.T) {
|
|
e := NewEdge("from1", "to1", EdgeJustifies)
|
|
|
|
assert.NotEmpty(t, e.ID)
|
|
assert.Equal(t, "from1", e.FromID)
|
|
assert.Equal(t, "to1", e.ToID)
|
|
assert.Equal(t, EdgeJustifies, e.Type)
|
|
}
|
|
|
|
func TestEdge_Validate(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
edge *Edge
|
|
wantErr bool
|
|
}{
|
|
{"valid", NewEdge("a", "b", EdgeCauses), false},
|
|
{"empty from", &Edge{ID: "x", FromID: "", ToID: "b", Type: EdgeCauses}, true},
|
|
{"empty to", &Edge{ID: "x", FromID: "a", ToID: "", Type: EdgeCauses}, true},
|
|
{"invalid type", &Edge{ID: "x", FromID: "a", ToID: "b", Type: "bad"}, true},
|
|
{"self-loop", &Edge{ID: "x", FromID: "a", ToID: "a", Type: EdgeCauses}, true},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
err := tt.edge.Validate()
|
|
if tt.wantErr {
|
|
assert.Error(t, err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestChain_Empty(t *testing.T) {
|
|
c := &Chain{}
|
|
assert.Nil(t, c.Decision)
|
|
assert.Empty(t, c.Reasons)
|
|
assert.Equal(t, 0, c.TotalNodes)
|
|
}
|
|
|
|
func TestChain_WithData(t *testing.T) {
|
|
decision := NewNode(NodeDecision, "Use Go")
|
|
reason := NewNode(NodeReason, "Performance")
|
|
consequence := NewNode(NodeConsequence, "Single binary")
|
|
|
|
chain := &Chain{
|
|
Decision: decision,
|
|
Reasons: []*Node{reason},
|
|
Consequences: []*Node{consequence},
|
|
TotalNodes: 3,
|
|
}
|
|
|
|
require.NotNil(t, chain.Decision)
|
|
assert.Equal(t, "Use Go", chain.Decision.Content)
|
|
assert.Len(t, chain.Reasons, 1)
|
|
assert.Len(t, chain.Consequences, 1)
|
|
assert.Equal(t, 3, chain.TotalNodes)
|
|
}
|
|
|
|
func TestChain_ToMermaid(t *testing.T) {
|
|
decision := NewNode(NodeDecision, "Use Go")
|
|
decision.ID = "d1"
|
|
reason := NewNode(NodeReason, "Performance")
|
|
reason.ID = "r1"
|
|
|
|
chain := &Chain{
|
|
Decision: decision,
|
|
Reasons: []*Node{reason},
|
|
TotalNodes: 2,
|
|
}
|
|
|
|
mermaid := chain.ToMermaid()
|
|
assert.Contains(t, mermaid, "graph TD")
|
|
assert.Contains(t, mermaid, "Use Go")
|
|
assert.Contains(t, mermaid, "Performance")
|
|
}
|
|
|
|
func TestCausalStats_Zero(t *testing.T) {
|
|
stats := &CausalStats{
|
|
ByType: make(map[NodeType]int),
|
|
}
|
|
assert.Equal(t, 0, stats.TotalNodes)
|
|
assert.Equal(t, 0, stats.TotalEdges)
|
|
}
|