blob: a06af3584d6cc6e25ebc6904e55bb23493f49aed [file] [log] [blame]
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package lsp
import (
"sync"
"testing"
"time"
)
func TestDebouncer(t *testing.T) {
t.Parallel()
type event struct {
key string
order uint64
fired bool
wantFired bool
}
tests := []struct {
label string
events []*event
}{
{
label: "overridden",
events: []*event{
{key: "a", order: 1, wantFired: false},
{key: "a", order: 2, wantFired: true},
},
},
{
label: "distinct labels",
events: []*event{
{key: "a", order: 1, wantFired: true},
{key: "b", order: 2, wantFired: true},
},
},
{
label: "reverse order",
events: []*event{
{key: "a", order: 2, wantFired: true},
{key: "a", order: 1, wantFired: false},
},
},
{
label: "multiple overrides",
events: []*event{
{key: "a", order: 1, wantFired: false},
{key: "a", order: 2, wantFired: false},
{key: "a", order: 3, wantFired: false},
{key: "a", order: 4, wantFired: false},
{key: "a", order: 5, wantFired: true},
},
},
}
for _, test := range tests {
test := test
t.Run(test.label, func(t *testing.T) {
t.Parallel()
d := newDebouncer()
var wg sync.WaitGroup
for i, e := range test.events {
wg.Add(1)
go func(e *event) {
d.debounce(e.key, e.order, 100*time.Millisecond, func() {
e.fired = true
})
wg.Done()
}(e)
// For a bit more fidelity, sleep to try to make things actually
// execute in order. This doesn't have to be perfect, but could be done
// properly using fake timers.
if i < len(test.events)-1 {
time.Sleep(10 * time.Millisecond)
}
}
wg.Wait()
for _, event := range test.events {
if event.fired != event.wantFired {
t.Errorf("(key: %q, order: %d): fired = %t, want %t",
event.key, event.order, event.fired, event.wantFired)
}
}
})
}
}