github.com/v2fly/tools@v0.100.0/internal/lsp/debounce_test.go (about)

     1  // Copyright 2020 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package lsp
     6  
     7  import (
     8  	"sync"
     9  	"testing"
    10  	"time"
    11  )
    12  
    13  func TestDebouncer(t *testing.T) {
    14  	t.Parallel()
    15  	type event struct {
    16  		key       string
    17  		order     uint64
    18  		fired     bool
    19  		wantFired bool
    20  	}
    21  	tests := []struct {
    22  		label  string
    23  		events []*event
    24  	}{
    25  		{
    26  			label: "overridden",
    27  			events: []*event{
    28  				{key: "a", order: 1, wantFired: false},
    29  				{key: "a", order: 2, wantFired: true},
    30  			},
    31  		},
    32  		{
    33  			label: "distinct labels",
    34  			events: []*event{
    35  				{key: "a", order: 1, wantFired: true},
    36  				{key: "b", order: 2, wantFired: true},
    37  			},
    38  		},
    39  		{
    40  			label: "reverse order",
    41  			events: []*event{
    42  				{key: "a", order: 2, wantFired: true},
    43  				{key: "a", order: 1, wantFired: false},
    44  			},
    45  		},
    46  		{
    47  			label: "multiple overrides",
    48  			events: []*event{
    49  				{key: "a", order: 1, wantFired: false},
    50  				{key: "a", order: 2, wantFired: false},
    51  				{key: "a", order: 3, wantFired: false},
    52  				{key: "a", order: 4, wantFired: false},
    53  				{key: "a", order: 5, wantFired: true},
    54  			},
    55  		},
    56  	}
    57  	for _, test := range tests {
    58  		test := test
    59  		t.Run(test.label, func(t *testing.T) {
    60  			t.Parallel()
    61  			d := newDebouncer()
    62  			var wg sync.WaitGroup
    63  			for i, e := range test.events {
    64  				wg.Add(1)
    65  				go func(e *event) {
    66  					d.debounce(e.key, e.order, 500*time.Millisecond, func() {
    67  						e.fired = true
    68  					})
    69  					wg.Done()
    70  				}(e)
    71  				// For a bit more fidelity, sleep to try to make things actually
    72  				// execute in order. This doesn't have to be perfect, but could be done
    73  				// properly using fake timers.
    74  				if i < len(test.events)-1 {
    75  					time.Sleep(10 * time.Millisecond)
    76  				}
    77  			}
    78  			wg.Wait()
    79  			for _, event := range test.events {
    80  				if event.fired != event.wantFired {
    81  					t.Errorf("(key: %q, order: %d): fired = %t, want %t",
    82  						event.key, event.order, event.fired, event.wantFired)
    83  				}
    84  			}
    85  		})
    86  	}
    87  }