Files
Anatolii Grynchuk 85b362e8cd 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
2026-05-01 00:17:34 +03:00

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();
}
}