mctx: implement BreadthFirstVisit
This commit is contained in:
parent
8e2cffd65b
commit
5bd0790f6e
18
mctx/ctx.go
18
mctx/ctx.go
@ -152,6 +152,24 @@ func ChildOf(ctx Context, name string) Context {
|
||||
return childCtx
|
||||
}
|
||||
|
||||
// BreadthFirstVisit visits this Context and all of its children, and their
|
||||
// children, in a breadth-first order. If the callback returns false then the
|
||||
// function returns without visiting any more Contexts.
|
||||
//
|
||||
// The exact order of visitation is non-deterministic.
|
||||
func BreadthFirstVisit(ctx Context, callback func(Context) bool) {
|
||||
queue := []Context{ctx}
|
||||
for len(queue) > 0 {
|
||||
if !callback(queue[0]) {
|
||||
return
|
||||
}
|
||||
for _, child := range Children(queue[0]) {
|
||||
queue = append(queue, child)
|
||||
}
|
||||
queue = queue[1:]
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// code related to mutable values
|
||||
|
||||
|
@ -54,6 +54,44 @@ func TestInheritance(t *T) {
|
||||
))
|
||||
}
|
||||
|
||||
func TestBreadFirstVisit(t *T) {
|
||||
ctx := New()
|
||||
ctx1 := ChildOf(ctx, "1")
|
||||
ctx1a := ChildOf(ctx1, "a")
|
||||
ctx1b := ChildOf(ctx1, "b")
|
||||
ctx2 := ChildOf(ctx, "2")
|
||||
|
||||
{
|
||||
got := make([]Context, 0, 5)
|
||||
BreadthFirstVisit(ctx, func(ctx Context) bool {
|
||||
got = append(got, ctx)
|
||||
return true
|
||||
})
|
||||
// since children are stored in a map the exact order is non-deterministic
|
||||
massert.Fatal(t, massert.Any(
|
||||
massert.Equal([]Context{ctx, ctx1, ctx2, ctx1a, ctx1b}, got),
|
||||
massert.Equal([]Context{ctx, ctx1, ctx2, ctx1b, ctx1a}, got),
|
||||
massert.Equal([]Context{ctx, ctx2, ctx1, ctx1a, ctx1b}, got),
|
||||
massert.Equal([]Context{ctx, ctx2, ctx1, ctx1b, ctx1a}, got),
|
||||
))
|
||||
}
|
||||
|
||||
{
|
||||
got := make([]Context, 0, 3)
|
||||
BreadthFirstVisit(ctx, func(ctx Context) bool {
|
||||
if len(Path(ctx)) > 1 {
|
||||
return false
|
||||
}
|
||||
got = append(got, ctx)
|
||||
return true
|
||||
})
|
||||
massert.Fatal(t, massert.Any(
|
||||
massert.Equal([]Context{ctx, ctx1, ctx2}, got),
|
||||
massert.Equal([]Context{ctx, ctx2, ctx1}, got),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMutableValues(t *T) {
|
||||
fn := func(v interface{}) interface{} {
|
||||
if v == nil {
|
||||
|
Loading…
Reference in New Issue
Block a user