diff options
| author | Sam Anthony <sam@samanthony.xyz> | 2025-09-15 11:45:04 -0400 |
|---|---|---|
| committer | Sam Anthony <sam@samanthony.xyz> | 2025-09-15 11:45:04 -0400 |
| commit | abdfc41f64938dc77a23e35db2768e46e19f6d18 (patch) | |
| tree | 651492ebaf9fd3d90834ca2f1f5499ec1d315480 /deque_test.go | |
| parent | a26dcba10a0d02a2e74784d87d93f5f5e53c5c24 (diff) | |
| download | share-master.zip | |
Diffstat (limited to 'deque_test.go')
| -rw-r--r-- | deque_test.go | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/deque_test.go b/deque_test.go new file mode 100644 index 0000000..4f64585 --- /dev/null +++ b/deque_test.go @@ -0,0 +1,128 @@ +package share_test + +import ( + "fmt" + "slices" + "sync" + "testing" + + "github.com/sam-rba/share" +) + +func TestDequeFIFO(t *testing.T) { + dq := share.NewDeque[string]() + vals := []string{"foo", "bar", "baz", "xyz"} + testFIFO(t, dq.PutTail, dq.TakeHead, vals, dq.Close) +} + +func TestDequeReverseFIFO(t *testing.T) { + dq := share.NewDeque[string]() + vals := []string{"foo", "bar", "baz", "xyz"} + testFIFO(t, dq.PutHead, dq.TakeTail, vals, dq.Close) +} + +func testFIFO[T comparable](t *testing.T, put chan<- T, take <-chan T, vals []T, end func()) { + var wg sync.WaitGroup + wg.Add(2) + go func() { + produce(put, vals) + end() + wg.Done() + }() + go func() { + consume(t, take, vals) + wg.Done() + }() + wg.Wait() +} + +func TestDequeLIFO(t *testing.T) { + dq := share.NewDeque[string]() + vals := []string{"foo", "bar", "baz", "xyz"} + testLIFO(t, dq.PutTail, dq.TakeTail, vals, dq.Close) +} + +func TestDequeReverseLIFO(t *testing.T) { + dq := share.NewDeque[string]() + vals := []string{"foo", "bar", "baz", "xyz"} + testLIFO(t, dq.PutHead, dq.TakeHead, vals, dq.Close) +} + +func testLIFO[T comparable](t *testing.T, put chan<- T, take <-chan T, vals []T, end func()) { + var wg sync.WaitGroup + + wg.Add(1) + go func() { + produce(put, vals) + end() + wg.Done() + }() + + want := slices.Clone(vals) + slices.Reverse(want) + wg.Wait() + consume(t, take, want) +} + +func produce[T any](put chan<- T, vals []T) { + for _, v := range vals { + put <- v + } +} + +func consume[T comparable](t *testing.T, take <-chan T, want []T) { + i := 0 + for v := range take { + if i >= len(want) { + t.Fatal("received too many") + } + if v != want[i] { + t.Fatalf("Index %d: %v; want %v", i, v, want[i]) + } + i++ + } + if i < len(want) { + t.Fatalf("Only received %d; want %d", i, len(want)) + } +} + +func TestDequePutback(t *testing.T) { + dq := share.NewDeque[string]() + + dq.PutTail <- "foo" + dq.PutTail <- "bar" + dq.PutTail <- "baz" + dq.PutTail <- "xyz" + + <-dq.TakeHead // foo + <-dq.TakeHead // bar + <-dq.TakeHead // baz + + dq.PutHead <- "baz" + dq.PutHead <- "bar" + + dq.Close() + + consume(t, dq.TakeHead, []string{"bar", "baz", "xyz"}) +} + +func ExampleDeque() { + // Use as a FIFO queue + dq := share.NewDeque[string]() + + // Producer + go func() { + defer dq.Close() + for _, word := range []string{"foo", "bar", "baz"} { + dq.PutTail <- word + } + }() + + for word := range dq.TakeHead { + fmt.Println(word) + } + // Output: + // foo + // bar + // baz +} |