tree 测试

This commit is contained in:
xing 2023-03-16 12:28:53 +08:00
parent decea28316
commit aaa1f3c937
2 changed files with 412 additions and 0 deletions

View File

@ -14,6 +14,20 @@ func (n *Node[T, K]) GetChildren() []T {
}) })
} }
func (n *Node[T, K]) Posterity() (r []T) {
n.posterity(&r)
return r
}
func (n *Node[T, K]) posterity(a *[]T) {
for _, n2 := range *n.Children {
*a = append(*a, n2.Data)
if len(*n2.Children) > 0 {
n2.posterity(a)
}
}
}
func (n *Node[T, K]) ChildrenByOrder(fn func(T, T) bool) []T { func (n *Node[T, K]) ChildrenByOrder(fn func(T, T) bool) []T {
a := slice.Map(*n.Children, func(t Node[T, K]) T { a := slice.Map(*n.Children, func(t Node[T, K]) T {
return t.Data return t.Data

398
helper/tree/tree_test.go Normal file
View File

@ -0,0 +1,398 @@
package tree
import (
"fmt"
"github.com/fthvgb1/wp-go/helper/slice"
"reflect"
"testing"
)
type xx struct {
id int
pid int
}
var ss []xx
func init() {
ss = []xx{
{1, 0},
{2, 0},
{3, 0},
{4, 1},
{5, 1},
{6, 2},
{7, 3},
{8, 4},
{9, 5},
{10, 2},
}
}
func ffn(x xx) (child, parent int) {
return x.id, x.pid
}
func TestAncestor(t *testing.T) {
type args[K comparable, T any] struct {
root map[K]*Node[T, K]
top K
child *Node[T, K]
}
type testCase[K comparable, T any] struct {
name string
args args[K, T]
want *Node[T, K]
}
r := Roots(ss, 0, ffn)
tests := []testCase[int, xx]{
{
name: "t1",
args: args[int, xx]{
root: r,
top: 0,
child: &Node[xx, int]{
Data: xx{9, 5},
Parent: 5,
},
},
want: &Node[xx, int]{
Data: xx{
id: 1,
pid: 0,
},
Children: &[]Node[xx, int]{
{
Data: xx{4, 1},
Children: &[]Node[xx, int]{
{
Data: xx{8, 4},
Parent: 4,
},
},
},
{
Data: xx{5, 1},
Children: &[]Node[xx, int]{
{
Data: xx{9, 5},
Parent: 5,
},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := Ancestor(tt.args.root, tt.args.top, tt.args.child); !reflect.DeepEqual(*got, *tt.want) {
t.Errorf("Ancestor() = %v, want %v", got, tt.want)
}
})
}
}
func TestNode_ChildrenByOrder(t *testing.T) {
type args[T any] struct {
fn func(T, T) bool
}
type testCase[T any, K comparable] struct {
name string
n Node[T, K]
args args[T]
want []T
}
tests := []testCase[xx, int]{
{
name: "t1",
n: *root(ss, 0, ffn)[2],
args: args[xx]{
fn: func(x xx, x2 xx) bool {
return x.id < x2.id
},
},
want: []xx{{6, 2}, {10, 2}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.n.ChildrenByOrder(tt.args.fn); !reflect.DeepEqual(got, tt.want) {
t.Errorf("ChildrenByOrder() = %v, want %v", got, tt.want)
}
})
}
}
func TestNode_GetChildren(t *testing.T) {
type testCase[T any, K comparable] struct {
name string
n Node[T, K]
want []T
}
tests := []testCase[xx, int]{
{
name: "t1",
n: *root(ss, 0, ffn)[2],
want: []xx{{6, 2}, {10, 2}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.n.GetChildren(); !reflect.DeepEqual(got, tt.want) {
t.Errorf("GetChildren() = %v, want %v", got, tt.want)
}
})
}
}
func TestNode_Loop(t *testing.T) {
type args[T any] struct {
fn func(T, int)
}
type testCase[T any, K comparable] struct {
name string
n Node[T, K]
args args[T]
}
tests := []testCase[xx, int]{
{
name: "t1",
n: *Root(ss, 0, ffn),
args: args[xx]{
fn: func(x xx, i int) {
fmt.Println(x, i)
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.n.Loop(tt.args.fn)
})
}
}
func TestNode_OrderByLoop(t *testing.T) {
type args[T any] struct {
fn func(T, int)
orderBy func(T, T) bool
}
type testCase[T any, K comparable] struct {
name string
n Node[T, K]
args args[T]
}
tests := []testCase[xx, int]{
{
name: "",
n: *Root(ss, 0, ffn),
args: args[xx]{
fn: func(x xx, i int) {
fmt.Println(x)
},
orderBy: func(x xx, x2 xx) bool {
return x.id > x2.id
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.n.OrderByLoop(tt.args.fn, tt.args.orderBy)
})
}
}
func TestNode_Posterity(t *testing.T) {
type testCase[T any, K comparable] struct {
name string
n Node[T, K]
wantR []T
}
tests := []testCase[xx, int]{
{
name: "t1",
n: *Root(ss, 0, ffn),
wantR: ss,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotR := tt.n.Posterity()
fn := func(i, j xx) bool {
if i.id < j.id {
return true
}
if i.pid < j.pid {
return true
}
return false
}
slice.Sort(gotR, fn)
slice.Sort(tt.wantR, fn)
if !reflect.DeepEqual(gotR, tt.wantR) {
t.Errorf("Posterity() = %v, want %v", gotR, tt.wantR)
}
})
}
}
func TestNode_loop(t *testing.T) {
type args[T any] struct {
fn func(T, int)
deep int
}
type testCase[T any, K comparable] struct {
name string
n Node[T, K]
args args[T]
}
tests := []testCase[xx, int]{
{
name: "t1",
n: *Root(ss, 0, ffn),
args: args[xx]{fn: func(x xx, i int) {
fmt.Println(x)
}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.n.loop(tt.args.fn, tt.args.deep)
})
}
}
func TestNode_orderByLoop(t *testing.T) {
type args[T any] struct {
fn func(T, int)
orderBy func(T, T) bool
deep int
}
type testCase[T any, K comparable] struct {
name string
n Node[T, K]
args args[T]
}
tests := []testCase[xx, int]{
{
name: "t1",
n: *Root(ss, 0, ffn),
args: args[xx]{fn: func(x xx, i int) {
fmt.Println(x)
}, orderBy: func(x xx, x2 xx) bool {
return x.id > x2.id
}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.n.orderByLoop(tt.args.fn, tt.args.orderBy, tt.args.deep)
})
}
}
func TestNode_posterity(t *testing.T) {
type args[T any] struct {
a *[]T
}
type testCase[T any, K comparable] struct {
name string
n Node[T, K]
args args[T]
}
tests := []testCase[xx, int]{
{
name: "t1",
n: *Root(ss, 0, ffn),
args: args[xx]{a: new([]xx)},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.n.posterity(tt.args.a)
})
}
}
func TestRoot(t *testing.T) {
type args[T any, K comparable] struct {
a []T
top K
fn func(T) (child, parent K)
}
type testCase[T any, K comparable] struct {
name string
args args[T, K]
want *Node[T, K]
}
tests := []testCase[xx, int]{
{
name: "t1",
args: args[xx, int]{
a: ss,
top: 0,
fn: ffn,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := Root(tt.args.a, tt.args.top, tt.args.fn); !reflect.DeepEqual(got, tt.want) {
t.Errorf("Root() = %v, want %v", got, tt.want)
}
})
}
}
func TestRoots(t *testing.T) {
type args[T any, K comparable] struct {
a []T
top K
fn func(T) (child, parent K)
}
type testCase[T any, K comparable] struct {
name string
args args[T, K]
want map[K]*Node[T, K]
}
tests := []testCase[xx, int]{
{
name: "t1",
args: args[xx, int]{ss, 0, ffn},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := Roots(tt.args.a, tt.args.top, tt.args.fn); !reflect.DeepEqual(got, tt.want) {
t.Errorf("Roots() = %v, want %v", got, tt.want)
}
})
}
}
func Test_root(t *testing.T) {
type args[T any, K comparable] struct {
a []T
top K
fn func(T) (child, parent K)
}
type testCase[T any, K comparable] struct {
name string
args args[T, K]
want map[K]*Node[T, K]
}
tests := []testCase[xx, int]{
{
name: "t1",
args: args[xx, int]{ss, 0, ffn},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := root(tt.args.a, tt.args.top, tt.args.fn); !reflect.DeepEqual(got, tt.want) {
t.Errorf("root() = %v, want %v", got, tt.want)
}
})
}
}