1// Copyright 2023 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
5package zstd
6
7import (
8	"bytes"
9	"fmt"
10	"testing"
11)
12
13func makeSequence(start, n int) (seq []byte) {
14	for i := 0; i < n; i++ {
15		seq = append(seq, byte(start+i))
16	}
17	return
18}
19
20func TestWindow(t *testing.T) {
21	for size := 0; size <= 3; size++ {
22		for i := 0; i <= 2*size; i++ {
23			a := makeSequence('a', i)
24			for j := 0; j <= 2*size; j++ {
25				b := makeSequence('a'+i, j)
26				for k := 0; k <= 2*size; k++ {
27					c := makeSequence('a'+i+j, k)
28
29					t.Run(fmt.Sprintf("%d-%d-%d-%d", size, i, j, k), func(t *testing.T) {
30						testWindow(t, size, a, b, c)
31					})
32				}
33			}
34		}
35	}
36}
37
38// testWindow tests window by saving three sequences of bytes to it.
39// Third sequence tests read offset that can become non-zero only after second save.
40func testWindow(t *testing.T, size int, a, b, c []byte) {
41	var w window
42	w.reset(size)
43
44	w.save(a)
45	w.save(b)
46	w.save(c)
47
48	var tail []byte
49	tail = append(tail, a...)
50	tail = append(tail, b...)
51	tail = append(tail, c...)
52
53	if len(tail) > size {
54		tail = tail[len(tail)-size:]
55	}
56
57	if w.len() != uint32(len(tail)) {
58		t.Errorf("wrong data length: got: %d, want: %d", w.len(), len(tail))
59	}
60
61	var from, to uint32
62	for from = 0; from <= uint32(len(tail)); from++ {
63		for to = from; to <= uint32(len(tail)); to++ {
64			got := w.appendTo(nil, from, to)
65			want := tail[from:to]
66
67			if !bytes.Equal(got, want) {
68				t.Errorf("wrong data at [%d:%d]: got %q, want %q", from, to, got, want)
69			}
70		}
71	}
72}
73