-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtest_util_test.go
128 lines (102 loc) · 3.51 KB
/
test_util_test.go
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
package ranges
import (
"reflect"
"testing"
)
func assertEqual[T any](t *testing.T, v1, v2 T) {
if !reflect.DeepEqual(v1, v2) {
t.Helper()
t.Fatalf("%+v != %+v", v1, v2)
}
}
func assertPanic(t *testing.T, expectedValue any, cb func()) {
defer func() {
if val := recover(); val == nil {
t.Helper()
t.Fatalf("Code did not panic!")
} else if !reflect.DeepEqual(val, expectedValue) {
t.Helper()
t.Fatalf("Panic result: %+v != %+v", val, expectedValue)
}
}()
cb()
}
func assertEmpty[T any](t *testing.T, r InputRange[T]) {
t.Helper()
if !r.Empty() {
t.Fatal("The range was not empty")
}
}
func assertNotEmpty[T any](t *testing.T, r InputRange[T]) {
t.Helper()
if r.Empty() {
t.Fatal("The range was empty")
}
}
func assertHasFront[T any](t *testing.T, r InputRange[T], value T) {
t.Helper()
if r.Empty() {
t.Fatalf("Range was empty, did not start with %v", value)
} else {
front := r.Front()
if !reflect.DeepEqual(front, value) {
t.Fatalf("Range started with %v not %v", front, value)
}
}
}
func assertHasBack[T any](t *testing.T, r BidirectionalRange[T], value T) {
t.Helper()
if r.Empty() {
t.Fatalf("Range was empty, did not end with %v", value)
} else {
back := r.Back()
if !reflect.DeepEqual(back, value) {
t.Fatalf("Range ended with %v not %v", back, value)
}
}
}
func assertHasSaveableFront[T any](t *testing.T, r ForwardRange[T], value T) {
t.Helper()
assertHasFront[T](t, r, value)
rSave := r.Save()
r.PopFront()
assertHasFront[T](t, rSave, value)
}
func assertHasSaveableBack[T any](t *testing.T, r BidirectionalRange[T], value T) {
t.Helper()
assertHasBack(t, r, value)
rSave := r.SaveB()
r.PopBack()
assertHasBack(t, rSave, value)
}
// lengthOnlyRange panics on all calls accept a Length() check.
// This can be used in tests to ensure we run length check optimizations.
type lengthOnlyRange[T any] struct {
length int
}
func (r *lengthOnlyRange[T]) Len() int { return r.length }
func (r *lengthOnlyRange[T]) Front() T { panic("Front() not implemented") }
func (r *lengthOnlyRange[T]) PopFront() { panic("PopFront() not implemented") }
func (r *lengthOnlyRange[T]) Empty() bool { panic("Empty() not implemented") }
func (r *lengthOnlyRange[T]) Back() T { panic("Back() not implemented") }
func (r *lengthOnlyRange[T]) PopBack() { panic("PopBack() not implemented") }
func (r *lengthOnlyRange[T]) Get(index int) T { panic("Get() not implemented") }
func (r *lengthOnlyRange[T]) Save() ForwardRange[T] { panic("Save() not implemented") }
func (r *lengthOnlyRange[T]) SaveB() BidirectionalRange[T] { panic("SaveB() not implemented") }
func (r *lengthOnlyRange[T]) SaveR() RandomAccessRange[T] { panic("SaveB() not implemented") }
// lengthOnly returns a RandomAccessRange that only implements Len()
// This can be used in tests to ensure we run length check optimizations.
func lengthOnly[T any](length int) RandomAccessRange[T] {
return &lengthOnlyRange[T]{length}
}
// badLengthRangeImpl implements badLengthRange
type badLengthRangeImpl[T any] struct {
RandomAccessRange[T]
badLength int
}
func (r *badLengthRangeImpl[T]) Len() int { return r.badLength }
// badLengthRange returns a RandomAccess range where the length can set improperly.
// this can be used to test how algorithms behave with flawed input.
func badLengthRange[T any](r RandomAccessRange[T], badLength int) RandomAccessRange[T] {
return &badLengthRangeImpl[T]{r, badLength}
}