forked from wader/fq
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhexpairwriter_test.go
More file actions
214 lines (202 loc) · 7.29 KB
/
hexpairwriter_test.go
File metadata and controls
214 lines (202 loc) · 7.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
package hexpairwriter_test
import (
"bytes"
"log"
"testing"
"fmt"
"github.com/wader/fq/internal/hexpairwriter"
)
func TestWrite(t *testing.T) {
b := &bytes.Buffer{}
h := hexpairwriter.New(b, 4, 0, hexpairwriter.Pair)
_, _ = h.Write([]byte(""))
_, _ = h.Write([]byte("ab"))
_, _ = h.Write([]byte("c"))
_, _ = h.Write([]byte("d"))
log.Printf("b.Bytes(): '%s'\n", b.Bytes())
}
func TestPairFunction(t *testing.T) {
// Test that the Pair function returns a two-character hexadecimal string.
tests := []struct {
input byte
expected string
}{
{0, "00"},
{1, "01"},
{15, "0f"},
{255, "ff"},
}
for _, tc := range tests {
result := hexpairwriter.Pair(tc.input)
if result != tc.expected {
t.Errorf("Pair(%d) = %q; want %q", tc.input, result, tc.expected)
}
}
}
func TestWriteCompleteLine(t *testing.T) {
// Test writing exactly a complete line (width=4) in one call.
buf := &bytes.Buffer{}
w := hexpairwriter.New(buf, 4, 0, hexpairwriter.Pair)
// Write 4 bytes.
_, err := w.Write([]byte{0, 1, 2, 3})
if err != nil {
t.Fatalf("Write failed: %v", err)
}
// Expected output: for each byte a hex pair and a space (except for no trailing space on the last pair).
expected := "00 01 02 03"
if got := buf.String(); got != expected {
t.Errorf("got %q; expected %q", got, expected)
}
}
func TestWriteSplitAcrossCalls(t *testing.T) {
// Test that writing data in two successive Write calls produces a continuous output.
buf := &bytes.Buffer{}
w := hexpairwriter.New(buf, 4, 0, hexpairwriter.Pair)
// First call: write 2 bytes.
_, err := w.Write([]byte{0, 1})
if err != nil {
t.Fatalf("First Write failed: %v", err)
}
// Second call: write the next 2 bytes.
_, err = w.Write([]byte{2, 3})
if err != nil {
t.Fatalf("Second Write failed: %v", err)
}
// For the first call, the writer writes "00 01"
// For the second call, since there is an existing non-empty line state, a prefix will be inserted.
// Expected overall output: "00 01" followed directly by " 02 03" (note the leading space).
expected := "00 01 02 03"
if got := buf.String(); got != expected {
t.Errorf("got %q; expected %q", got, expected)
}
}
func TestWriteCustomFn(t *testing.T) {
// Test that a custom formatting function is correctly applied.
customFn := func(b byte) string {
// Instead of hex, return the corresponding letter starting from 'A'
return "[" + string('A'+(b%26)) + "]"
}
buf := &bytes.Buffer{}
w := hexpairwriter.New(buf, 4, 0, customFn)
// Write 4 bytes.
_, err := w.Write([]byte{0, 1, 2, 3})
if err != nil {
t.Fatalf("Write failed: %v", err)
}
// Expected: "[A] [B] [C] [D]" (with no trailing space after the last pair).
expected := "[A] [B] [C] [D]"
if got := buf.String(); got != expected {
t.Errorf("got %q; expected %q", got, expected)
}
}
func TestWriteWithStartLineOffset(t *testing.T) {
// Test that providing a startLineOffset writes filler content (spaces or newline) before writing data.
buf := &bytes.Buffer{}
// With startLineOffset=2 and width=4, the writer should first output filler for two offsets.
w := hexpairwriter.New(buf, 4, 2, hexpairwriter.Pair)
// Write 3 bytes.
_, err := w.Write([]byte{0, 1, 2})
if err != nil {
t.Fatalf("Write failed: %v", err)
}
// Simulate filler: for offset=0 and 1 an output of " " each is produced.
filler := " " + " "
// Then for byte 0 (at offset 2): "00 " is appended.
// For byte 1 (at offset 3, width-1), the trailing space is replaced by a newline and flushes: "01\n"
// For byte 2 (at new line offset 0): "02" is written (last byte, no trailing space).
expected := filler + "00 01\n02"
if got := buf.String(); got != expected {
t.Errorf("got %q; expected %q", got, expected)
}
}
// TestWriteMultiLine tests writing data that spans multiple complete lines in a single Write call.
func TestWriteMultiLine(t *testing.T) {
buf := &bytes.Buffer{}
w := hexpairwriter.New(buf, 4, 0, hexpairwriter.Pair)
// Write 8 bytes to produce 2 lines:
// The first 4 bytes form a complete line which flushes with a newline.
// The next 4 bytes start a new line without a trailing newline.
data := []byte{0, 1, 2, 3, 4, 5, 6, 7}
n, err := w.Write(data)
if err != nil {
t.Fatalf("Write returned error: %v", err)
}
if n != len(data) {
t.Errorf("Write returned %d; expected %d", n, len(data))
}
expected := "00 01 02 03\n04 05 06 07"
if got := buf.String(); got != expected {
t.Errorf("got %q; expected %q", got, expected)
}
}
// errorWriter is a test helper that simulates a failing underlying io.Writer.
type errorWriter struct {
fail bool
}
func (ew *errorWriter) Write(p []byte) (int, error) {
if ew.fail {
return 0, fmt.Errorf("simulated write error")
}
return len(p), nil
}
// TestWriteError verifies that errors from the underlying writer are properly propagated.
func TestWriteError(t *testing.T) {
ew := &errorWriter{fail: true}
w := hexpairwriter.New(ew, 4, 0, hexpairwriter.Pair)
_, err := w.Write([]byte{0})
if err == nil {
t.Fatal("Expected error from underlying writer, but got nil")
}
}
func TestEmptyWriteWithFiller(t *testing.T) {
// Test that writing an empty slice still writes the required filler when startLineOffset > current offset.
buf := &bytes.Buffer{}
// Using width=4 and startLineOffset=3 means the writer will first output filler for offsets 0, 1, and 2.
// For offsets where (offset % width != width-1), filler " " (3 spaces) is used.
// Hence, the expected output is 9 spaces.
w := hexpairwriter.New(buf, 4, 3, hexpairwriter.Pair)
n, err := w.Write([]byte{})
if err != nil {
t.Fatalf("Write failed: %v", err)
}
if n != 0 {
t.Errorf("Write returned %d; expected 0", n)
}
expected := " " // 9 spaces
if got := buf.String(); got != expected {
t.Errorf("got %q; expected %q", got, expected)
}
}
func TestEmptyWriteAfterData(t *testing.T) {
// Test that writing an empty slice after writing data does not produce additional output or alter state.
buf := &bytes.Buffer{}
w := hexpairwriter.New(buf, 4, 0, hexpairwriter.Pair)
// Write 2 bytes (an incomplete line).
_, err := w.Write([]byte{0, 1})
if err != nil {
t.Fatalf("First Write failed: %v", err)
}
// Capture the output after the first write.
out1 := buf.String()
if out1 == "" {
t.Errorf("Expected some output after first write, got empty string")
}
// Write an empty slice – this should not change the output or state.
n, err := w.Write([]byte{})
if err != nil {
t.Fatalf("Empty Write failed: %v", err)
}
if n != 0 {
t.Errorf("Empty Write returned %d; expected 0", n)
}
// Now complete the line by writing 2 more bytes.
_, err = w.Write([]byte{2, 3})
if err != nil {
t.Fatalf("Second Write failed: %v", err)
}
// The overall expected output should be a single complete line: "00 01 02 03"
expected := "00 01 02 03"
if got := buf.String(); got != expected {
t.Errorf("got %q; expected %q", got, expected)
}
}