Source file
src/compress/lzw/writer_test.go
1
2
3
4
5 package lzw
6
7 import (
8 "bytes"
9 "fmt"
10 "internal/testenv"
11 "io"
12 "math"
13 "os"
14 "runtime"
15 "testing"
16 )
17
18 var filenames = []string{
19 "../testdata/gettysburg.txt",
20 "../testdata/e.txt",
21 "../testdata/pi.txt",
22 }
23
24
25
26 func testFile(t *testing.T, fn string, order Order, litWidth int) {
27
28 golden, err := os.Open(fn)
29 if err != nil {
30 t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err)
31 return
32 }
33 defer golden.Close()
34
35
36 raw, err := os.Open(fn)
37 if err != nil {
38 t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err)
39 return
40 }
41
42 piper, pipew := io.Pipe()
43 defer piper.Close()
44 go func() {
45 defer raw.Close()
46 defer pipew.Close()
47 lzww := NewWriter(pipew, order, litWidth)
48 defer lzww.Close()
49 var b [4096]byte
50 for {
51 n, err0 := raw.Read(b[:])
52 if err0 != nil && err0 != io.EOF {
53 t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err0)
54 return
55 }
56 _, err1 := lzww.Write(b[:n])
57 if err1 != nil {
58 t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err1)
59 return
60 }
61 if err0 == io.EOF {
62 break
63 }
64 }
65 }()
66 lzwr := NewReader(piper, order, litWidth)
67 defer lzwr.Close()
68
69
70 b0, err0 := io.ReadAll(golden)
71 b1, err1 := io.ReadAll(lzwr)
72 if err0 != nil {
73 t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err0)
74 return
75 }
76 if err1 != nil {
77 t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err1)
78 return
79 }
80 if len(b1) != len(b0) {
81 t.Errorf("%s (order=%d litWidth=%d): length mismatch %d != %d", fn, order, litWidth, len(b1), len(b0))
82 return
83 }
84 for i := 0; i < len(b0); i++ {
85 if b1[i] != b0[i] {
86 t.Errorf("%s (order=%d litWidth=%d): mismatch at %d, 0x%02x != 0x%02x\n", fn, order, litWidth, i, b1[i], b0[i])
87 return
88 }
89 }
90 }
91
92 func TestWriter(t *testing.T) {
93 for _, filename := range filenames {
94 for _, order := range [...]Order{LSB, MSB} {
95
96 for litWidth := 6; litWidth <= 8; litWidth++ {
97 if filename == "../testdata/gettysburg.txt" && litWidth == 6 {
98 continue
99 }
100 testFile(t, filename, order, litWidth)
101 }
102 }
103 if testing.Short() && testenv.Builder() == "" {
104 break
105 }
106 }
107 }
108
109 func TestWriterReset(t *testing.T) {
110 for _, order := range [...]Order{LSB, MSB} {
111 t.Run(fmt.Sprintf("Order %d", order), func(t *testing.T) {
112 for litWidth := 6; litWidth <= 8; litWidth++ {
113 t.Run(fmt.Sprintf("LitWidth %d", litWidth), func(t *testing.T) {
114 var data []byte
115 if litWidth == 6 {
116 data = []byte{1, 2, 3}
117 } else {
118 data = []byte(`lorem ipsum dolor sit amet`)
119 }
120 var buf bytes.Buffer
121 w := NewWriter(&buf, order, litWidth)
122 if _, err := w.Write(data); err != nil {
123 t.Errorf("write: %v: %v", string(data), err)
124 }
125
126 if err := w.Close(); err != nil {
127 t.Errorf("close: %v", err)
128 }
129
130 b1 := buf.Bytes()
131 buf.Reset()
132
133 w.(*Writer).Reset(&buf, order, litWidth)
134
135 if _, err := w.Write(data); err != nil {
136 t.Errorf("write: %v: %v", string(data), err)
137 }
138
139 if err := w.Close(); err != nil {
140 t.Errorf("close: %v", err)
141 }
142 b2 := buf.Bytes()
143
144 if !bytes.Equal(b1, b2) {
145 t.Errorf("bytes written were not same")
146 }
147 })
148 }
149 })
150 }
151 }
152
153 func TestWriterReturnValues(t *testing.T) {
154 w := NewWriter(io.Discard, LSB, 8)
155 n, err := w.Write([]byte("asdf"))
156 if n != 4 || err != nil {
157 t.Errorf("got %d, %v, want 4, nil", n, err)
158 }
159 }
160
161 func TestSmallLitWidth(t *testing.T) {
162 w := NewWriter(io.Discard, LSB, 2)
163 if _, err := w.Write([]byte{0x03}); err != nil {
164 t.Fatalf("write a byte < 1<<2: %v", err)
165 }
166 if _, err := w.Write([]byte{0x04}); err == nil {
167 t.Fatal("write a byte >= 1<<2: got nil error, want non-nil")
168 }
169 }
170
171 func TestStartsWithClearCode(t *testing.T) {
172
173
174
175
176
177
178
179 for _, empty := range []bool{false, true} {
180 var buf bytes.Buffer
181 w := NewWriter(&buf, LSB, 7)
182 if !empty {
183 w.Write([]byte("Hi"))
184 }
185 w.Close()
186 got := buf.String()
187
188 want := "\x80\x81"
189 if !empty {
190 want = "\x80Hi\x81"
191 }
192
193 if got != want {
194 t.Errorf("empty=%t: got %q, want %q", empty, got, want)
195 }
196 }
197 }
198
199 func BenchmarkEncoder(b *testing.B) {
200 buf, err := os.ReadFile("../testdata/e.txt")
201 if err != nil {
202 b.Fatal(err)
203 }
204 if len(buf) == 0 {
205 b.Fatalf("test file has no data")
206 }
207
208 for e := 4; e <= 6; e++ {
209 n := int(math.Pow10(e))
210 buf0 := buf
211 buf1 := make([]byte, n)
212 for i := 0; i < n; i += len(buf0) {
213 if len(buf0) > n-i {
214 buf0 = buf0[:n-i]
215 }
216 copy(buf1[i:], buf0)
217 }
218 buf0 = nil
219 runtime.GC()
220 b.Run(fmt.Sprint("1e", e), func(b *testing.B) {
221 b.SetBytes(int64(n))
222 for i := 0; i < b.N; i++ {
223 w := NewWriter(io.Discard, LSB, 8)
224 w.Write(buf1)
225 w.Close()
226 }
227 })
228 b.Run(fmt.Sprint("1e-Reuse", e), func(b *testing.B) {
229 b.SetBytes(int64(n))
230 w := NewWriter(io.Discard, LSB, 8)
231 for i := 0; i < b.N; i++ {
232 w.Write(buf1)
233 w.Close()
234 w.(*Writer).Reset(io.Discard, LSB, 8)
235 }
236 })
237 }
238 }
239
View as plain text