summaryrefslogtreecommitdiffstats
path: root/src/internal/coverage/slicewriter/slw_test.go
blob: f4e75f40d9a29b9cbe2cd187c04a93933eb9afe0 (plain)
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
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package slicewriter

import (
	"io"
	"testing"
)

func TestSliceWriter(t *testing.T) {

	sleq := func(t *testing.T, got []byte, want []byte) {
		t.Helper()
		if len(got) != len(want) {
			t.Fatalf("bad length got %d want %d", len(got), len(want))
		}
		for i := range got {
			if got[i] != want[i] {
				t.Fatalf("bad read at %d got %d want %d", i, got[i], want[i])
			}
		}
	}

	wf := func(t *testing.T, ws *WriteSeeker, p []byte) {
		t.Helper()
		nw, werr := ws.Write(p)
		if werr != nil {
			t.Fatalf("unexpected write error: %v", werr)
		}
		if nw != len(p) {
			t.Fatalf("wrong amount written want %d got %d", len(p), nw)
		}
	}

	rf := func(t *testing.T, ws *WriteSeeker, p []byte) {
		t.Helper()
		b := make([]byte, len(p))
		nr, rerr := ws.Read(b)
		if rerr != nil {
			t.Fatalf("unexpected read error: %v", rerr)
		}
		if nr != len(p) {
			t.Fatalf("wrong amount read want %d got %d", len(p), nr)
		}
		sleq(t, b, p)
	}

	sk := func(t *testing.T, ws *WriteSeeker, offset int64, whence int) {
		t.Helper()
		_, err := ws.Seek(offset, whence)
		if err != nil {
			t.Fatalf("unexpected seek error: %v", err)
		}
	}

	wp1 := []byte{1, 2}
	ws := &WriteSeeker{}

	// write some stuff
	wf(t, ws, wp1)
	// check that BytesWritten returns what we wrote.
	sleq(t, ws.BytesWritten(), wp1)
	// offset is at end of slice, so reading should return zero bytes.
	rf(t, ws, []byte{})

	// write some more stuff
	wp2 := []byte{7, 8, 9}
	wf(t, ws, wp2)
	// check that BytesWritten returns what we expect.
	wpex := []byte{1, 2, 7, 8, 9}
	sleq(t, ws.BytesWritten(), wpex)
	rf(t, ws, []byte{})

	// seeks and reads.
	sk(t, ws, 1, io.SeekStart)
	rf(t, ws, []byte{2, 7})
	sk(t, ws, -2, io.SeekCurrent)
	rf(t, ws, []byte{2, 7})
	sk(t, ws, -4, io.SeekEnd)
	rf(t, ws, []byte{2, 7})

	// seek back and overwrite
	sk(t, ws, 1, io.SeekStart)
	wf(t, ws, []byte{9, 11})
	wpex = []byte{1, 9, 11, 8, 9}
	sleq(t, ws.BytesWritten(), wpex)

	// seeks on empty writer.
	ws2 := &WriteSeeker{}
	sk(t, ws2, 0, io.SeekStart)
	sk(t, ws2, 0, io.SeekCurrent)
	sk(t, ws2, 0, io.SeekEnd)

	// check for seek errors.
	_, err := ws.Seek(-1, io.SeekStart)
	if err == nil {
		t.Fatalf("expected error on invalid -1 seek")
	}
	_, err = ws.Seek(int64(len(ws.BytesWritten())), io.SeekStart)
	if err == nil {
		t.Fatalf("expected error on invalid %d seek", len(ws.BytesWritten()))
	}

	ws.Seek(0, io.SeekStart)
	_, err = ws.Seek(-1, io.SeekCurrent)
	if err == nil {
		t.Fatalf("expected error on invalid -1 seek")
	}
	_, err = ws.Seek(int64(len(ws.BytesWritten())), io.SeekCurrent)
	if err == nil {
		t.Fatalf("expected error on invalid %d seek", len(ws.BytesWritten()))
	}

	_, err = ws.Seek(1, io.SeekEnd)
	if err == nil {
		t.Fatalf("expected error on invalid 1 seek")
	}
	bsamt := int64(-1*len(ws.BytesWritten()) - 1)
	_, err = ws.Seek(bsamt, io.SeekEnd)
	if err == nil {
		t.Fatalf("expected error on invalid %d seek", bsamt)
	}

	// bad seek mode
	_, err = ws.Seek(-1, io.SeekStart+9)
	if err == nil {
		t.Fatalf("expected error on invalid seek mode")
	}
}