85b362e8cd
- add the standalone HrynCo.Common solution and projects - include the shared common library source and tests - add package metadata and a repo gitignore
152 lines
3.6 KiB
C#
152 lines
3.6 KiB
C#
namespace HrynCo.Common.Tests;
|
|
|
|
using HrynCo.Common.Tree;
|
|
using FluentAssertions;
|
|
using Xunit;
|
|
|
|
public sealed class FakeNode : ITreeNode<Guid>
|
|
{
|
|
public required Guid Id { get; init; }
|
|
public Guid? ParentId { get; init; }
|
|
}
|
|
|
|
public sealed class FakeNamedNode : ITreeNode<Guid>, INameNode
|
|
{
|
|
public required string Name { get; init; }
|
|
public required Guid Id { get; init; }
|
|
public Guid? ParentId { get; init; }
|
|
}
|
|
|
|
public sealed class TreeUtilsTests
|
|
{
|
|
[Fact]
|
|
public void CollectDescendants_ShouldReturnSelfAndAllChildren()
|
|
{
|
|
// Arrange
|
|
var root = Guid.NewGuid();
|
|
var child1 = Guid.NewGuid();
|
|
var child2 = Guid.NewGuid();
|
|
var nodes = new List<FakeNode>
|
|
{
|
|
new()
|
|
{
|
|
Id = root,
|
|
ParentId = null
|
|
},
|
|
new()
|
|
{
|
|
Id = child1,
|
|
ParentId = root
|
|
},
|
|
new()
|
|
{
|
|
Id = child2,
|
|
ParentId = child1
|
|
}
|
|
};
|
|
|
|
// Act
|
|
var result = TreeUtils.CollectDescendants(root, nodes, Guid.Empty);
|
|
|
|
// Assert
|
|
result.Should().BeEquivalentTo(new[]
|
|
{
|
|
root, child1, child2
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public void BuildBreadcrumb_ShouldReturnPathFromRootToNode()
|
|
{
|
|
// Arrange
|
|
var root = Guid.NewGuid();
|
|
var child = Guid.NewGuid();
|
|
var grandchild = Guid.NewGuid();
|
|
|
|
var map = new Dictionary<Guid, FakeNamedNode>
|
|
{
|
|
[root] = new()
|
|
{
|
|
Id = root,
|
|
ParentId = null,
|
|
Name = "Root"
|
|
},
|
|
[child] = new()
|
|
{
|
|
Id = child,
|
|
ParentId = root,
|
|
Name = "Child"
|
|
},
|
|
[grandchild] = new()
|
|
{
|
|
Id = grandchild,
|
|
ParentId = child,
|
|
Name = "Grandchild"
|
|
}
|
|
};
|
|
|
|
// Act
|
|
var result = TreeUtils.BuildBreadcrumb(grandchild, map);
|
|
|
|
// Assert
|
|
result.Should().BeEquivalentTo(new[]
|
|
{
|
|
new BreadcrumbNode<Guid>(root, "Root"), new BreadcrumbNode<Guid>(child, "Child"),
|
|
new BreadcrumbNode<Guid>(grandchild, "Grandchild")
|
|
}, options => options.WithStrictOrdering());
|
|
}
|
|
|
|
[Fact]
|
|
public void CollectDescendants_ShouldReturnOnlyRootWhenThereAreNoChildren()
|
|
{
|
|
// Arrange
|
|
var root = Guid.NewGuid();
|
|
|
|
// Act
|
|
var result = TreeUtils.CollectDescendants(root, Array.Empty<FakeNode>(), Guid.Empty);
|
|
|
|
// Assert
|
|
result.Should().BeEquivalentTo(new[] { root });
|
|
}
|
|
|
|
[Fact]
|
|
public void CollectDescendants_ShouldHandleCyclesWithoutRepeatingNodes()
|
|
{
|
|
// Arrange
|
|
var root = Guid.NewGuid();
|
|
var child = Guid.NewGuid();
|
|
var nodes = new List<FakeNode>
|
|
{
|
|
new()
|
|
{
|
|
Id = root,
|
|
ParentId = child
|
|
},
|
|
new()
|
|
{
|
|
Id = child,
|
|
ParentId = root
|
|
}
|
|
};
|
|
|
|
// Act
|
|
var result = TreeUtils.CollectDescendants(root, nodes, Guid.Empty);
|
|
|
|
// Assert
|
|
result.Should().BeEquivalentTo(new[] { root, child });
|
|
}
|
|
|
|
[Fact]
|
|
public void BuildBreadcrumb_ShouldReturnEmptyListWhenNodeIsMissing()
|
|
{
|
|
// Arrange
|
|
var map = new Dictionary<Guid, FakeNamedNode>();
|
|
|
|
// Act
|
|
var result = TreeUtils.BuildBreadcrumb(Guid.NewGuid(), map);
|
|
|
|
// Assert
|
|
result.Should().BeEmpty();
|
|
}
|
|
}
|