Files
server/tests/unit/tree_test.go
T
2026-01-16 15:49:34 +08:00

204 lines
4.3 KiB
Go

package unit
import (
"testing"
"github.com/stretchr/testify/suite"
)
// TreeServiceTestSuite 树形服务测试套件
type TreeServiceTestSuite struct {
suite.Suite
}
func TestTreeServiceTestSuite(t *testing.T) {
suite.Run(t, new(TreeServiceTestSuite))
}
func (s *TreeServiceTestSuite) SetupTest() {
}
func (s *TreeServiceTestSuite) TearDownTest() {
}
// TreeNode 测试用树形节点
type TreeNode struct {
ID uint
ParentID uint
Name string
Children []TreeNode
}
// buildTree 构建树形结构
func buildTree(nodes []TreeNode) []TreeNode {
if len(nodes) == 0 {
return []TreeNode{}
}
// 先创建所有节点的映射
nodeMap := make(map[uint]*TreeNode)
for i := range nodes {
nodes[i].Children = []TreeNode{}
nodeMap[nodes[i].ID] = &nodes[i]
}
// 构建父子关系
for i := range nodes {
if nodes[i].ParentID != 0 {
if parent, ok := nodeMap[nodes[i].ParentID]; ok {
parent.Children = append(parent.Children, nodes[i])
}
}
}
// 收集根节点(从 map 中获取,确保 Children 已更新)
var roots []TreeNode
for i := range nodes {
if nodes[i].ParentID == 0 {
roots = append(roots, *nodeMap[nodes[i].ID])
}
}
return roots
}
// flattenTree 展平树形结构
func flattenTree(nodes []TreeNode) []TreeNode {
var result []TreeNode
for _, node := range nodes {
result = append(result, node)
if len(node.Children) > 0 {
result = append(result, flattenTree(node.Children)...)
}
}
return result
}
// contains 检查切片是否包含元素
func contains(slice []uint, item uint) bool {
for _, v := range slice {
if v == item {
return true
}
}
return false
}
// uniqueUint 去重
func uniqueUint(slice []uint) []uint {
seen := make(map[uint]bool)
var result []uint
for _, v := range slice {
if !seen[v] {
seen[v] = true
result = append(result, v)
}
}
return result
}
// TestBuildTree_EmptyList 测试空列表
func (s *TreeServiceTestSuite) TestBuildTree_EmptyList() {
result := buildTree([]TreeNode{})
s.Empty(result)
}
// TestBuildTree_SingleRoot 测试单个根节点
func (s *TreeServiceTestSuite) TestBuildTree_SingleRoot() {
nodes := []TreeNode{
{ID: 1, ParentID: 0, Name: "Root"},
}
result := buildTree(nodes)
s.Len(result, 1)
s.Equal("Root", result[0].Name)
}
// TestBuildTree_MultipleRoots 测试多个根节点
func (s *TreeServiceTestSuite) TestBuildTree_MultipleRoots() {
nodes := []TreeNode{
{ID: 1, ParentID: 0, Name: "Root1"},
{ID: 2, ParentID: 0, Name: "Root2"},
{ID: 3, ParentID: 0, Name: "Root3"},
}
result := buildTree(nodes)
s.Len(result, 3)
}
// TestBuildTree_ParentChild 测试父子关系
func (s *TreeServiceTestSuite) TestBuildTree_ParentChild() {
nodes := []TreeNode{
{ID: 1, ParentID: 0, Name: "Root"},
{ID: 2, ParentID: 1, Name: "Child1"},
{ID: 3, ParentID: 1, Name: "Child2"},
{ID: 4, ParentID: 2, Name: "Grandchild"},
}
result := buildTree(nodes)
s.Len(result, 1, "应该只有 1 个根节点")
s.Len(result[0].Children, 2, "根节点应该有 2 个子节点")
}
// TestFlattenTree 测试树形展平
func (s *TreeServiceTestSuite) TestFlattenTree() {
tree := []TreeNode{
{
ID: 1,
Name: "Root",
Children: []TreeNode{
{ID: 2, Name: "Child1"},
{ID: 3, Name: "Child2"},
},
},
}
result := flattenTree(tree)
s.Len(result, 3)
s.Equal("Root", result[0].Name)
s.Equal("Child1", result[1].Name)
s.Equal("Child2", result[2].Name)
}
// TestContains 测试 contains 函数
func (s *TreeServiceTestSuite) TestContains() {
tests := []struct {
name string
slice []uint
item uint
want bool
}{
{"空切片", []uint{}, 1, false},
{"存在的元素", []uint{1, 2, 3}, 2, true},
{"不存在的元素", []uint{1, 2, 3}, 4, false},
{"单元素存在", []uint{5}, 5, true},
}
for _, tt := range tests {
s.Run(tt.name, func() {
s.Equal(tt.want, contains(tt.slice, tt.item))
})
}
}
// TestUniqueUint 测试去重函数
func (s *TreeServiceTestSuite) TestUniqueUint() {
tests := []struct {
name string
slice []uint
want int // 期望的长度
}{
{"空切片", []uint{}, 0},
{"无重复", []uint{1, 2, 3}, 3},
{"有重复", []uint{1, 2, 2, 3, 3, 3}, 3},
{"全部重复", []uint{5, 5, 5}, 1},
}
for _, tt := range tests {
s.Run(tt.name, func() {
got := uniqueUint(tt.slice)
s.Len(got, tt.want)
})
}
}