1
2
3
4
5 package gzip
6
7 import (
8 "bufio"
9 "bytes"
10 "io"
11 "reflect"
12 "testing"
13 "time"
14 )
15
16
17 func TestEmpty(t *testing.T) {
18 buf := new(bytes.Buffer)
19
20 if err := NewWriter(buf).Close(); err != nil {
21 t.Fatalf("Writer.Close: %v", err)
22 }
23
24 r, err := NewReader(buf)
25 if err != nil {
26 t.Fatalf("NewReader: %v", err)
27 }
28 if want := (Header{OS: 255}); !reflect.DeepEqual(r.Header, want) {
29 t.Errorf("Header mismatch:\ngot %#v\nwant %#v", r.Header, want)
30 }
31 b, err := io.ReadAll(r)
32 if err != nil {
33 t.Fatalf("ReadAll: %v", err)
34 }
35 if len(b) != 0 {
36 t.Fatalf("got %d bytes, want 0", len(b))
37 }
38 if err := r.Close(); err != nil {
39 t.Fatalf("Reader.Close: %v", err)
40 }
41 }
42
43
44
45 func TestRoundTrip(t *testing.T) {
46 buf := new(bytes.Buffer)
47
48 w := NewWriter(buf)
49 w.Comment = "comment"
50 w.Extra = []byte("extra")
51 w.ModTime = time.Unix(1e8, 0)
52 w.Name = "name"
53 if _, err := w.Write([]byte("payload")); err != nil {
54 t.Fatalf("Write: %v", err)
55 }
56 if err := w.Close(); err != nil {
57 t.Fatalf("Writer.Close: %v", err)
58 }
59
60 r, err := NewReader(buf)
61 if err != nil {
62 t.Fatalf("NewReader: %v", err)
63 }
64 b, err := io.ReadAll(r)
65 if err != nil {
66 t.Fatalf("ReadAll: %v", err)
67 }
68 if string(b) != "payload" {
69 t.Fatalf("payload is %q, want %q", string(b), "payload")
70 }
71 if r.Comment != "comment" {
72 t.Fatalf("comment is %q, want %q", r.Comment, "comment")
73 }
74 if string(r.Extra) != "extra" {
75 t.Fatalf("extra is %q, want %q", r.Extra, "extra")
76 }
77 if r.ModTime.Unix() != 1e8 {
78 t.Fatalf("mtime is %d, want %d", r.ModTime.Unix(), uint32(1e8))
79 }
80 if r.Name != "name" {
81 t.Fatalf("name is %q, want %q", r.Name, "name")
82 }
83 if err := r.Close(); err != nil {
84 t.Fatalf("Reader.Close: %v", err)
85 }
86 }
87
88
89 func TestLatin1(t *testing.T) {
90 latin1 := []byte{0xc4, 'u', 0xdf, 'e', 'r', 'u', 'n', 'g', 0}
91 utf8 := "Äußerung"
92 z := Reader{r: bufio.NewReader(bytes.NewReader(latin1))}
93 s, err := z.readString()
94 if err != nil {
95 t.Fatalf("readString: %v", err)
96 }
97 if s != utf8 {
98 t.Fatalf("read latin-1: got %q, want %q", s, utf8)
99 }
100
101 buf := bytes.NewBuffer(make([]byte, 0, len(latin1)))
102 c := Writer{w: buf}
103 if err = c.writeString(utf8); err != nil {
104 t.Fatalf("writeString: %v", err)
105 }
106 s = buf.String()
107 if s != string(latin1) {
108 t.Fatalf("write utf-8: got %q, want %q", s, string(latin1))
109 }
110 }
111
112
113
114 func TestLatin1RoundTrip(t *testing.T) {
115 testCases := []struct {
116 name string
117 ok bool
118 }{
119 {"", true},
120 {"ASCII is OK", true},
121 {"unless it contains a NUL\x00", false},
122 {"no matter where \x00 occurs", false},
123 {"\x00\x00\x00", false},
124 {"Látin-1 also passes (U+00E1)", true},
125 {"but LĀtin Extended-A (U+0100) does not", false},
126 {"neither does 日本語", false},
127 {"invalid UTF-8 also \xffails", false},
128 {"\x00 as does Látin-1 with NUL", false},
129 }
130 for _, tc := range testCases {
131 buf := new(bytes.Buffer)
132
133 w := NewWriter(buf)
134 w.Name = tc.name
135 err := w.Close()
136 if (err == nil) != tc.ok {
137 t.Errorf("Writer.Close: name = %q, err = %v", tc.name, err)
138 continue
139 }
140 if !tc.ok {
141 continue
142 }
143
144 r, err := NewReader(buf)
145 if err != nil {
146 t.Errorf("NewReader: %v", err)
147 continue
148 }
149 _, err = io.ReadAll(r)
150 if err != nil {
151 t.Errorf("ReadAll: %v", err)
152 continue
153 }
154 if r.Name != tc.name {
155 t.Errorf("name is %q, want %q", r.Name, tc.name)
156 continue
157 }
158 if err := r.Close(); err != nil {
159 t.Errorf("Reader.Close: %v", err)
160 continue
161 }
162 }
163 }
164
165 func TestWriterFlush(t *testing.T) {
166 buf := new(bytes.Buffer)
167
168 w := NewWriter(buf)
169 w.Comment = "comment"
170 w.Extra = []byte("extra")
171 w.ModTime = time.Unix(1e8, 0)
172 w.Name = "name"
173
174 n0 := buf.Len()
175 if n0 != 0 {
176 t.Fatalf("buffer size = %d before writes; want 0", n0)
177 }
178
179 if err := w.Flush(); err != nil {
180 t.Fatal(err)
181 }
182
183 n1 := buf.Len()
184 if n1 == 0 {
185 t.Fatal("no data after first flush")
186 }
187
188 w.Write([]byte("x"))
189
190 n2 := buf.Len()
191 if n1 != n2 {
192 t.Fatalf("after writing a single byte, size changed from %d to %d; want no change", n1, n2)
193 }
194
195 if err := w.Flush(); err != nil {
196 t.Fatal(err)
197 }
198
199 n3 := buf.Len()
200 if n2 == n3 {
201 t.Fatal("Flush didn't flush any data")
202 }
203
204 if err := w.Close(); err != nil {
205 t.Fatal(err)
206 }
207
208 }
209
210
211 func TestConcat(t *testing.T) {
212 var buf bytes.Buffer
213 w := NewWriter(&buf)
214 w.Write([]byte("hello "))
215 w.Close()
216 w = NewWriter(&buf)
217 w.Write([]byte("world\n"))
218 w.Close()
219
220 r, err := NewReader(&buf)
221 if err != nil {
222 t.Fatal(err)
223 }
224 data, err := io.ReadAll(r)
225 if string(data) != "hello world\n" || err != nil {
226 t.Fatalf("ReadAll = %q, %v, want %q, nil", data, err, "hello world")
227 }
228 }
229
230 func TestWriterReset(t *testing.T) {
231 buf := new(bytes.Buffer)
232 buf2 := new(bytes.Buffer)
233 z := NewWriter(buf)
234 msg := []byte("hello world")
235 z.Write(msg)
236 z.Close()
237 z.Reset(buf2)
238 z.Write(msg)
239 z.Close()
240 if buf.String() != buf2.String() {
241 t.Errorf("buf2 %q != original buf of %q", buf2.String(), buf.String())
242 }
243 }
244
245 type limitedWriter struct {
246 N int
247 }
248
249 func (l *limitedWriter) Write(p []byte) (n int, err error) {
250 if n := l.N; n < len(p) {
251 l.N = 0
252 return n, io.ErrShortWrite
253 }
254 l.N -= len(p)
255 return len(p), nil
256 }
257
258
259 func TestLimitedWrite(t *testing.T) {
260 msg := []byte("a")
261
262 for lim := 2; lim < 20; lim++ {
263 z := NewWriter(&limitedWriter{lim})
264 if n, _ := z.Write(msg); n > len(msg) {
265 t.Errorf("Write() = %d, want %d or less", n, len(msg))
266 }
267
268 z.Reset(&limitedWriter{lim})
269 z.Header = Header{
270 Comment: "comment",
271 Extra: []byte("extra"),
272 ModTime: time.Now(),
273 Name: "name",
274 OS: 1,
275 }
276 if n, _ := z.Write(msg); n > len(msg) {
277 t.Errorf("Write() = %d, want %d or less", n, len(msg))
278 }
279 }
280 }
281
View as plain text