1// Copyright 2014-2017 Ulrich Kunitz. 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 lzma
6
7import (
8	"bytes"
9	"io"
10	"testing"
11)
12
13func TestBuffer_Write(t *testing.T) {
14	buf := newBuffer(10)
15	b := []byte("1234567890")
16	for i := range b {
17		n, err := buf.Write(b[i : i+1])
18		if err != nil {
19			t.Fatalf("buf.Write(b[%d:%d]) error %s", i, i+1, err)
20		}
21		if n != 1 {
22			t.Fatalf("buf.Write(b[%d:%d]) returned %d; want %d",
23				i, i+1, n, 1)
24		}
25	}
26	const c = 8
27	n, err := buf.Discard(c)
28	if err != nil {
29		t.Fatalf("Discard error %s", err)
30	}
31	if n != c {
32		t.Fatalf("Discard returned %d; want %d", n, c)
33	}
34	n, err = buf.Write(b)
35	if err == nil {
36		t.Fatalf("Write length exceed returned no error; n %d", n)
37	}
38	if n != c {
39		t.Fatalf("Write length exceeding returned %d; want %d", n, c)
40	}
41	n, err = buf.Discard(4)
42	if err != nil {
43		t.Fatalf("Discard error %s", err)
44	}
45	if n != 4 {
46		t.Fatalf("Discard returned %d; want %d", n, 4)
47	}
48	n, err = buf.Write(b[:3])
49	if err != nil {
50		t.Fatalf("buf.Write(b[:3]) error %s; n %d", err, n)
51	}
52	if n != 3 {
53		t.Fatalf("buf.Write(b[:3]) returned %d; want %d", n, 3)
54	}
55}
56
57func TestBuffer_Buffered_Available(t *testing.T) {
58	buf := newBuffer(19)
59	b := []byte("0123456789")
60	var err error
61	if _, err = buf.Write(b); err != nil {
62		t.Fatalf("buf.Write(b) error %s", err)
63	}
64	if n := buf.Buffered(); n != 10 {
65		t.Fatalf("buf.Buffered() returns %d; want %d", n, 10)
66	}
67	if _, err = buf.Discard(8); err != nil {
68		t.Fatalf("buf.Discard(8) error %s", err)
69	}
70	if _, err = buf.Write(b[:7]); err != nil {
71		t.Fatalf("buf.Write(b[:7]) error %s", err)
72	}
73	if n := buf.Buffered(); n != 9 {
74		t.Fatalf("buf.Buffered() returns %d; want %d", n, 9)
75	}
76}
77
78func TestBuffer_Read(t *testing.T) {
79	buf := newBuffer(10)
80	b := []byte("0123456789")
81	var err error
82	if _, err = buf.Write(b); err != nil {
83		t.Fatalf("buf.Write(b) error %s", err)
84	}
85	p := make([]byte, 8)
86	n, err := buf.Read(p)
87	if err != nil {
88		t.Fatalf("buf.Read(p) error %s", err)
89	}
90	if n != len(p) {
91		t.Fatalf("buf.Read(p) returned %d; want %d", n, len(p))
92	}
93	if !bytes.Equal(p, b[:8]) {
94		t.Fatalf("buf.Read(p) put %s into p; want %s", p, b[:8])
95	}
96	if _, err = buf.Write(b[:7]); err != nil {
97		t.Fatalf("buf.Write(b[:7]) error %s", err)
98	}
99	q := make([]byte, 7)
100	n, err = buf.Read(q)
101	if err != nil {
102		t.Fatalf("buf.Read(q) error %s", err)
103	}
104	if n != len(q) {
105		t.Fatalf("buf.Read(q) returns %d; want %d", n, len(q))
106	}
107	c := []byte("8901234")
108	if !bytes.Equal(q, c) {
109		t.Fatalf("buf.Read(q) put %s into q; want %s", q, c)
110	}
111	if _, err := buf.Write(b[7:]); err != nil {
112		t.Fatalf("buf.Write(b[7:]) error %s", err)
113	}
114	if _, err := buf.Write(b[:2]); err != nil {
115		t.Fatalf("buf.Write(b[:2]) error %s", err)
116	}
117	t.Logf("buf.rear %d buf.front %d", buf.rear, buf.front)
118	r := make([]byte, 2)
119	n, err = buf.Read(r)
120	if err != nil {
121		t.Fatalf("buf.Read(r) error %s", err)
122	}
123	if n != len(r) {
124		t.Fatalf("buf.Read(r) returns %d; want %d", n, len(r))
125	}
126	d := []byte("56")
127	if !bytes.Equal(r, d) {
128		t.Fatalf("buf.Read(r) put %s into r; want %s", r, d)
129	}
130}
131
132func TestBuffer_Discard(t *testing.T) {
133	buf := newBuffer(10)
134	b := []byte("0123456789")
135	var err error
136	if _, err = buf.Write(b); err != nil {
137		t.Fatalf("buf.Write(b) error %s", err)
138	}
139	n, err := buf.Discard(11)
140	if err == nil {
141		t.Fatalf("buf.Discard(11) didn't return error")
142	}
143	if n != 10 {
144		t.Fatalf("buf.Discard(11) returned %d; want %d", n, 10)
145	}
146	if _, err := buf.Write(b); err != nil {
147		t.Fatalf("buf.Write(b) #2 error %s", err)
148	}
149	n, err = buf.Discard(10)
150	if err != nil {
151		t.Fatalf("buf.Discard(10) error %s", err)
152	}
153	if n != 10 {
154		t.Fatalf("buf.Discard(11) returned %d; want %d", n, 10)
155	}
156	if _, err := buf.Write(b[:4]); err != nil {
157		t.Fatalf("buf.Write(b[:4]) error %s", err)
158	}
159	n, err = buf.Discard(1)
160	if err != nil {
161		t.Fatalf("buf.Discard(1) error %s", err)
162	}
163	if n != 1 {
164		t.Fatalf("buf.Discard(1) returned %d; want %d", n, 1)
165	}
166}
167
168func TestBuffer_Discard_error(t *testing.T) {
169	buf := newBuffer(10)
170	n, err := buf.Discard(-1)
171	if err == nil {
172		t.Fatal("buf.Discard(-1) didn't return an error")
173	}
174	if n != 0 {
175		t.Fatalf("buf.Discard(-1) returned %d; want %d", n, 0)
176	}
177}
178
179func TestPrefixLen(t *testing.T) {
180	tests := []struct {
181		a, b []byte
182		k    int
183	}{
184		{[]byte("abcde"), []byte("abc"), 3},
185		{[]byte("abc"), []byte("uvw"), 0},
186		{[]byte(""), []byte("uvw"), 0},
187		{[]byte("abcde"), []byte("abcuvw"), 3},
188	}
189	for _, c := range tests {
190		k := prefixLen(c.a, c.b)
191		if k != c.k {
192			t.Errorf("prefixLen(%q,%q) returned %d; want %d",
193				c.a, c.b, k, c.k)
194		}
195		k = prefixLen(c.b, c.a)
196		if k != c.k {
197			t.Errorf("prefixLen(%q,%q) returned %d; want %d",
198				c.b, c.a, k, c.k)
199		}
200	}
201}
202
203func TestMatchLen(t *testing.T) {
204	buf := newBuffer(13)
205	const s = "abcaba"
206	_, err := io.WriteString(buf, s)
207	if err != nil {
208		t.Fatalf("WriteString error %s", err)
209	}
210	_, err = io.WriteString(buf, s)
211	if err != nil {
212		t.Fatalf("WriteString error %s", err)
213	}
214	if _, err = buf.Discard(12); err != nil {
215		t.Fatalf("buf.Discard(6) error %s", err)
216	}
217	_, err = io.WriteString(buf, s)
218	if err != nil {
219		t.Fatalf("WriteString error %s", err)
220	}
221	tests := []struct{ d, n int }{{1, 1}, {3, 2}, {6, 6}, {5, 0}, {2, 0}}
222	for _, c := range tests {
223		n := buf.matchLen(c.d, []byte(s))
224		if n != c.n {
225			t.Errorf(
226				"MatchLen(%d,[]byte(%q)) returned %d; want %d",
227				c.d, s, n, c.n)
228		}
229	}
230}
231