File: arbitrary_reader_test.go

package info (click to toggle)
golang-github-leodido-ragel-machinery 0.0~git20181214.299bdde-1.1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, sid, trixie
  • size: 116 kB
  • sloc: makefile: 26
file content (132 lines) | stat: -rw-r--r-- 2,935 bytes parent folder | download | duplicates (2)
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
package parser

import (
	"fmt"
	"github.com/google/go-cmp/cmp"
	"io"
	"strings"
	"testing"
)

type result struct {
	data        string // the current data at each iteration
	num         int    // the number of bytes read
	forwardErr  error
	backwardErr error
	sought      int // the number of bytes sought in case of backwards seek
}

func TestArbitraryReader(t *testing.T) {
	for _, test := range []struct {
		input  string
		backto byte
		update bool
		res    []result
	}{
		{
			input: "ciao",
			res: []result{
				{"ciao", 4, io.ErrUnexpectedEOF, nil, 0},
			},
		},
		{
			input: "ciao\nmondo",
			res: []result{
				{"ciao\n", 5, nil, nil, 0},
				{"ciao\nmondo", 5, io.ErrUnexpectedEOF, nil, 0},
			},
		},
		{
			input: "ciao\nmondo\n",
			res: []result{
				{"ciao\n", 5, nil, nil, 0},
				{"ciao\nmondo\n", 6, nil, nil, 0},
				{"ciao\nmondo\n", 0, io.EOF, nil, 0},
			},
		},
		// Updating the window
		{
			input:  "ciao\nmondo",
			update: true,
			res: []result{
				{"ciao\n", 5, nil, nil, 0},
				{"mondo", 5, io.ErrUnexpectedEOF, nil, 0},
			},
		},
		{
			input:  "ciao\nmondo\n",
			update: true,
			res: []result{
				{"ciao\n", 5, nil, nil, 0},
				{"mondo\n", 6, nil, nil, 0},
				{"", 0, io.EOF, nil, 0},
			},
		},
		{
			input:  "abcabc\ncbacba\n",
			backto: 'b',  // and then seek backwards until this
			update: true, // so to start again from the character after its (backto) first occurrence
			res: []result{
				{"abcabc\n", 7, nil, nil, 3},
				{"c\ncbacba\n", 7, nil, nil, 3}, // 9 - 2 (already read)
				{"a\n", 0, io.EOF, nil, 0},
			},
		},
		{
			input:  "ciao\nciao\n",
			backto: '\n',
			res: []result{
				{"ciao\n", 5, nil, nil, 1},
				{"ciao\nciao\n", 5, nil, nil, 1},
			},
		},
		{
			input:  "ciao\nciao",
			backto: '\n',
			res: []result{
				{"ciao\n", 5, nil, nil, 1},
				{"ciao\nciao", 4, io.ErrUnexpectedEOF, nil, 0}, // not going backwards since we avoid loop checking for error
			},
		},
	} {
		r := ArbitraryReader(strings.NewReader(test.input), '\n')

		for _, o := range test.res {
			res, err := r.Read()
			// Check error reading forward
			errorCheck(t, o.forwardErr, err)

			if test.backto > 0 && err == nil {
				nb, err := r.Seek(test.backto, true)
				// Check error reading backwards
				errorCheck(t, o.backwardErr, err)

				// Check number of sought bytes
				check(t, o.sought, nb)
			}

			// Check number of read bytes
			check(t, o.num, len(res))

			// Check the current data window
			check(t, o.data, string(r.data))

			if test.update {
				// Updating the start and end position of the window for next run
				r.p = r.pe
			}
		}
	}
}

func check(t *testing.T, x, y interface{}) {
	if diff := cmp.Diff(x, y); diff != "" {
		t.Errorf("(-want +got)\n%s", diff)
	}
}

func errorCheck(t *testing.T, x, y error) {
	if x != nil && y != nil && x.Error() != y.Error() {
		t.Errorf("(-want +got)\n%s", fmt.Sprintf("-: %#v\n+: %#v", x.Error(), y.Error()))
	}
}