mirror of
https://github.com/tailscale/tailscale.git
synced 2025-09-21 13:41:46 +02:00
util/eventbus: add an EqualTo helper for testing (#17178)
For a common case of events being simple struct types with some exported fields, add a helper to check (reflectively) for equal values using cmp.Diff so that a failed comparison gives a useful diff in the test output. More complex uses will still want to provide their own comparisons; this (intentionally) does not export diff options or other hooks from the cmp package. Updates #15160 Change-Id: I86bee1771cad7debd9e3491aa6713afe6fd577a6 Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
This commit is contained in:
parent
8a4b1eb6a3
commit
6992f958fc
@ -10,6 +10,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
"tailscale.com/util/eventbus"
|
"tailscale.com/util/eventbus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -249,3 +250,16 @@ func Inject[T any](inj *Injector, event T) {
|
|||||||
}
|
}
|
||||||
pub.(*eventbus.Publisher[T]).Publish(event)
|
pub.(*eventbus.Publisher[T]).Publish(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EqualTo returns an event-matching function for use with [Expect] and
|
||||||
|
// [ExpectExactly] that matches on an event of the given type that is equal to
|
||||||
|
// want by comparison with [cmp.Diff]. The expectation fails with an error
|
||||||
|
// message including the diff, if present.
|
||||||
|
func EqualTo[T any](want T) func(T) error {
|
||||||
|
return func(got T) error {
|
||||||
|
if diff := cmp.Diff(got, want); diff != "" {
|
||||||
|
return fmt.Errorf("wrong result (-got, +want):\n%s", diff)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -5,6 +5,7 @@ package eventbustest_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -29,19 +30,17 @@ func TestExpectFilter(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
events []int
|
events []int
|
||||||
expectFunc any
|
expectFunc any
|
||||||
wantErr bool
|
wantErr string // if non-empty, an error is expected containing this text
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "single event",
|
name: "single event",
|
||||||
events: []int{42},
|
events: []int{42},
|
||||||
expectFunc: eventbustest.Type[EventFoo](),
|
expectFunc: eventbustest.Type[EventFoo](),
|
||||||
wantErr: false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "multiple events, single expectation",
|
name: "multiple events, single expectation",
|
||||||
events: []int{42, 1, 2, 3, 4, 5},
|
events: []int{42, 1, 2, 3, 4, 5},
|
||||||
expectFunc: eventbustest.Type[EventFoo](),
|
expectFunc: eventbustest.Type[EventFoo](),
|
||||||
wantErr: false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "filter on event with function",
|
name: "filter on event with function",
|
||||||
@ -52,7 +51,6 @@ func TestExpectFilter(t *testing.T) {
|
|||||||
}
|
}
|
||||||
return false, nil
|
return false, nil
|
||||||
},
|
},
|
||||||
wantErr: false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "filter-with-nil-error",
|
name: "filter-with-nil-error",
|
||||||
@ -73,7 +71,7 @@ func TestExpectFilter(t *testing.T) {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
wantErr: true,
|
wantErr: "value > 10",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "first event has to be func",
|
name: "first event has to be func",
|
||||||
@ -84,7 +82,18 @@ func TestExpectFilter(t *testing.T) {
|
|||||||
}
|
}
|
||||||
return false, nil
|
return false, nil
|
||||||
},
|
},
|
||||||
wantErr: true,
|
wantErr: "expected 42, got 24",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "equal-values",
|
||||||
|
events: []int{23},
|
||||||
|
expectFunc: eventbustest.EqualTo(EventFoo{Value: 23}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "unequal-values",
|
||||||
|
events: []int{37},
|
||||||
|
expectFunc: eventbustest.EqualTo(EventFoo{Value: 23}),
|
||||||
|
wantErr: "wrong result (-got, +want)",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "no events",
|
name: "no events",
|
||||||
@ -92,7 +101,7 @@ func TestExpectFilter(t *testing.T) {
|
|||||||
expectFunc: func(event EventFoo) (bool, error) {
|
expectFunc: func(event EventFoo) (bool, error) {
|
||||||
return true, nil
|
return true, nil
|
||||||
},
|
},
|
||||||
wantErr: true,
|
wantErr: "timed out waiting",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,8 +122,16 @@ func TestExpectFilter(t *testing.T) {
|
|||||||
updater.Publish(EventFoo{i})
|
updater.Publish(EventFoo{i})
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := eventbustest.Expect(tw, tt.expectFunc); (err != nil) != tt.wantErr {
|
if err := eventbustest.Expect(tw, tt.expectFunc); err != nil {
|
||||||
t.Errorf("ExpectFilter[EventFoo]: error = %v, wantErr %v", err, tt.wantErr)
|
if tt.wantErr == "" {
|
||||||
|
t.Errorf("Expect[EventFoo]: unexpected error: %v", err)
|
||||||
|
} else if !strings.Contains(err.Error(), tt.wantErr) {
|
||||||
|
t.Errorf("Expect[EventFoo]: err = %v, want %q", err, tt.wantErr)
|
||||||
|
} else {
|
||||||
|
t.Logf("Got expected error: %v (OK)", err)
|
||||||
|
}
|
||||||
|
} else if tt.wantErr != "" {
|
||||||
|
t.Errorf("Expect[EventFoo]: unexpectedly succeeded, want error %q", tt.wantErr)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user