chore: add hrynco common library solution
- add the standalone HrynCo.Common solution and projects - include the shared common library source and tests - add package metadata and a repo gitignore
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user