Files
git.stella-ops.org/src/__Libraries/StellaOps.Resolver.Tests/GraphValidationTests.cs
StellaOps Bot b9f71fc7e9 sprints work
2025-12-24 21:46:08 +02:00

135 lines
4.1 KiB
C#

/**
* Graph Validation & NFC Tests
* Sprint: SPRINT_9100_0003_0002 (Graph Validation & NFC Normalization)
* Tasks: VALID-9100-021 through VALID-9100-028
*/
using Xunit;
namespace StellaOps.Resolver.Tests;
public class GraphValidationTests
{
[Fact]
public void NfcNormalization_ProducesConsistentNodeIds()
{
// VALID-9100-021: NFC normalization produces consistent NodeIds
// Using different Unicode representations of the same character
// é can be represented as:
// - U+00E9 (precomposed: LATIN SMALL LETTER E WITH ACUTE)
// - U+0065 U+0301 (decomposed: e + COMBINING ACUTE ACCENT)
var precomposed = "caf\u00E9"; // café with precomposed é
var decomposed = "cafe\u0301"; // café with decomposed é
var nodeId1 = NodeId.From("package", precomposed);
var nodeId2 = NodeId.From("package", decomposed);
// After NFC normalization, both should produce the same NodeId
Assert.Equal(nodeId1, nodeId2);
}
[Fact]
public void EdgeReferencingNonExistentNode_Detected()
{
// VALID-9100-022
var node1 = Node.Create("package", "a");
var nonExistentNodeId = NodeId.From("package", "nonexistent");
var edge = Edge.Create(node1.Id, "depends_on", nonExistentNodeId);
var graph = EvidenceGraph.Create(new[] { node1 }, new[] { edge });
var detector = new DefaultImplicitDataDetector();
var violations = detector.Detect(graph);
Assert.Contains(violations, v => v.ViolationType == "DanglingEdgeDestination");
}
[Fact]
public void DuplicateNodeIds_Detected()
{
// VALID-9100-023
var node1 = Node.Create("package", "a");
var node2 = new Node(node1.Id, "package", "a-duplicate"); // Same ID, different key
var graph = new EvidenceGraph
{
Nodes = [node1, node2],
Edges = []
};
var detector = new DefaultImplicitDataDetector();
var violations = detector.Detect(graph);
Assert.Contains(violations, v => v.ViolationType == "DuplicateNodeId");
}
[Fact]
public void DuplicateEdgeIds_Detected()
{
// VALID-9100-024
var node1 = Node.Create("package", "a");
var node2 = Node.Create("package", "b");
var edge1 = Edge.Create(node1.Id, "depends_on", node2.Id);
var edge2 = Edge.Create(node1.Id, "depends_on", node2.Id); // Same EdgeId
var graph = new EvidenceGraph
{
Nodes = [node1, node2],
Edges = [edge1, edge2]
};
var detector = new DefaultImplicitDataDetector();
var violations = detector.Detect(graph);
Assert.Contains(violations, v => v.ViolationType == "DuplicateEdgeId");
}
[Fact]
public void ValidGraph_PassesAllChecks()
{
// VALID-9100-027
var node1 = Node.Create("package", "a");
var node2 = Node.Create("package", "b");
var node3 = Node.Create("package", "c");
var edge1 = Edge.Create(node1.Id, "depends_on", node2.Id);
var edge2 = Edge.Create(node2.Id, "depends_on", node3.Id);
var graph = EvidenceGraph.Create(new[] { node1, node2, node3 }, new[] { edge1, edge2 });
var validator = new DefaultGraphValidator();
var result = validator.Validate(graph);
Assert.True(result.IsValid);
Assert.Empty(result.Errors);
}
[Fact]
public void NfcNormalization_IsIdempotent()
{
// VALID-9100-028: Property test - NFC is idempotent
var normalizer = NfcStringNormalizer.Instance;
var input = "café";
var normalized1 = normalizer.Normalize(input);
var normalized2 = normalizer.Normalize(normalized1);
var normalized3 = normalizer.Normalize(normalized2);
Assert.Equal(normalized1, normalized2);
Assert.Equal(normalized2, normalized3);
}
[Fact]
public void EmptyGraph_IsValid()
{
var graph = EvidenceGraph.Empty;
var validator = new DefaultGraphValidator();
var result = validator.Validate(graph);
Assert.True(result.IsValid);
}
}