1
2
3
4
5 package zlib
6
7 import (
8 "bytes"
9 "fmt"
10 "io"
11 "os"
12 "testing"
13 )
14
15 var filenames = []string{
16 "../testdata/gettysburg.txt",
17 "../testdata/e.txt",
18 "../testdata/pi.txt",
19 }
20
21 var data = []string{
22 "test a reasonable sized string that can be compressed",
23 }
24
25
26
27 func testFileLevelDict(t *testing.T, fn string, level int, d string) {
28
29 golden, err := os.Open(fn)
30 if err != nil {
31 t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err)
32 return
33 }
34 defer golden.Close()
35 b0, err0 := io.ReadAll(golden)
36 if err0 != nil {
37 t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err0)
38 return
39 }
40 testLevelDict(t, fn, b0, level, d)
41 }
42
43 func testLevelDict(t *testing.T, fn string, b0 []byte, level int, d string) {
44
45 var dict []byte
46 if d != "" {
47 dict = []byte(d)
48 }
49
50
51 piper, pipew := io.Pipe()
52 defer piper.Close()
53 go func() {
54 defer pipew.Close()
55 zlibw, err := NewWriterLevelDict(pipew, level, dict)
56 if err != nil {
57 t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err)
58 return
59 }
60 defer zlibw.Close()
61 _, err = zlibw.Write(b0)
62 if err != nil {
63 t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err)
64 return
65 }
66 }()
67 zlibr, err := NewReaderDict(piper, dict)
68 if err != nil {
69 t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err)
70 return
71 }
72 defer zlibr.Close()
73
74
75 b1, err1 := io.ReadAll(zlibr)
76 if err1 != nil {
77 t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err1)
78 return
79 }
80 if len(b0) != len(b1) {
81 t.Errorf("%s (level=%d, dict=%q): length mismatch %d versus %d", fn, level, d, len(b0), len(b1))
82 return
83 }
84 for i := 0; i < len(b0); i++ {
85 if b0[i] != b1[i] {
86 t.Errorf("%s (level=%d, dict=%q): mismatch at %d, 0x%02x versus 0x%02x\n", fn, level, d, i, b0[i], b1[i])
87 return
88 }
89 }
90 }
91
92 func testFileLevelDictReset(t *testing.T, fn string, level int, dict []byte) {
93 var b0 []byte
94 var err error
95 if fn != "" {
96 b0, err = os.ReadFile(fn)
97 if err != nil {
98 t.Errorf("%s (level=%d): %v", fn, level, err)
99 return
100 }
101 }
102
103
104 buf := new(bytes.Buffer)
105 var zlibw *Writer
106 if dict == nil {
107 zlibw, err = NewWriterLevel(buf, level)
108 } else {
109 zlibw, err = NewWriterLevelDict(buf, level, dict)
110 }
111 if err == nil {
112 _, err = zlibw.Write(b0)
113 }
114 if err == nil {
115 err = zlibw.Close()
116 }
117 if err != nil {
118 t.Errorf("%s (level=%d): %v", fn, level, err)
119 return
120 }
121 out := buf.String()
122
123
124 buf2 := new(bytes.Buffer)
125 zlibw.Reset(buf2)
126 _, err = zlibw.Write(b0)
127 if err == nil {
128 err = zlibw.Close()
129 }
130 if err != nil {
131 t.Errorf("%s (level=%d): %v", fn, level, err)
132 return
133 }
134 out2 := buf2.String()
135
136 if out2 != out {
137 t.Errorf("%s (level=%d): different output after reset (got %d bytes, expected %d",
138 fn, level, len(out2), len(out))
139 }
140 }
141
142 func TestWriter(t *testing.T) {
143 for i, s := range data {
144 b := []byte(s)
145 tag := fmt.Sprintf("#%d", i)
146 testLevelDict(t, tag, b, DefaultCompression, "")
147 testLevelDict(t, tag, b, NoCompression, "")
148 testLevelDict(t, tag, b, HuffmanOnly, "")
149 for level := BestSpeed; level <= BestCompression; level++ {
150 testLevelDict(t, tag, b, level, "")
151 }
152 }
153 }
154
155 func TestWriterBig(t *testing.T) {
156 for _, fn := range filenames {
157 testFileLevelDict(t, fn, DefaultCompression, "")
158 testFileLevelDict(t, fn, NoCompression, "")
159 testFileLevelDict(t, fn, HuffmanOnly, "")
160 for level := BestSpeed; level <= BestCompression; level++ {
161 testFileLevelDict(t, fn, level, "")
162 }
163 }
164 }
165
166 func TestWriterDict(t *testing.T) {
167 const dictionary = "0123456789."
168 for _, fn := range filenames {
169 testFileLevelDict(t, fn, DefaultCompression, dictionary)
170 testFileLevelDict(t, fn, NoCompression, dictionary)
171 testFileLevelDict(t, fn, HuffmanOnly, dictionary)
172 for level := BestSpeed; level <= BestCompression; level++ {
173 testFileLevelDict(t, fn, level, dictionary)
174 }
175 }
176 }
177
178 func TestWriterReset(t *testing.T) {
179 const dictionary = "0123456789."
180 for _, fn := range filenames {
181 testFileLevelDictReset(t, fn, NoCompression, nil)
182 testFileLevelDictReset(t, fn, DefaultCompression, nil)
183 testFileLevelDictReset(t, fn, HuffmanOnly, nil)
184 testFileLevelDictReset(t, fn, NoCompression, []byte(dictionary))
185 testFileLevelDictReset(t, fn, DefaultCompression, []byte(dictionary))
186 testFileLevelDictReset(t, fn, HuffmanOnly, []byte(dictionary))
187 if testing.Short() {
188 break
189 }
190 for level := BestSpeed; level <= BestCompression; level++ {
191 testFileLevelDictReset(t, fn, level, nil)
192 }
193 }
194 }
195
196 func TestWriterDictIsUsed(t *testing.T) {
197 var input = []byte("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.")
198 var buf bytes.Buffer
199 compressor, err := NewWriterLevelDict(&buf, BestCompression, input)
200 if err != nil {
201 t.Errorf("error in NewWriterLevelDict: %s", err)
202 return
203 }
204 compressor.Write(input)
205 compressor.Close()
206 const expectedMaxSize = 25
207 output := buf.Bytes()
208 if len(output) > expectedMaxSize {
209 t.Errorf("result too large (got %d, want <= %d bytes). Is the dictionary being used?", len(output), expectedMaxSize)
210 }
211 }
212
View as plain text