-
-
Notifications
You must be signed in to change notification settings - Fork 21
/
fuzz-utils.go
109 lines (92 loc) · 2.76 KB
/
fuzz-utils.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
package testza
import (
"fmt"
"math/rand"
"testing"
"github.com/MarvinJWendt/testza/internal"
)
// FuzzUtilMergeSets merges multiple test sets into one.
// All test sets must have the same type.
//
// Example:
//
// mergedSet := testza.FuzzUtilMergeSets(testza.FuzzIntGenerateRandomNegative(3, 0), testza.FuzzIntGenerateRandomPositive(2, 0))
func FuzzUtilMergeSets[setType any](sets ...[]setType) (merged []setType) {
for _, set := range sets {
merged = append(merged, set...)
}
return merged
}
// FuzzUtilRunTests runs a test for every value in a test set.
// You can use the value as input parameter for your functions, to sanity test against many different cases.
// This ensures that your functions have a correct error handling and enables you to test against hundreds of cases easily.
//
// Example:
//
// testza.FuzzUtilRunTests(t, testza.FuzzStringEmailAddresses(), func(t *testing.T, index int, emailAddress string) {
// // Test logic
// // err := YourFunction(emailAddress)
// // testza.AssertNoError(t, err)
// // ...
// })
func FuzzUtilRunTests[setType any](t testRunner, testSet []setType, testFunc func(t *testing.T, index int, f setType)) {
if test, ok := t.(helper); ok {
test.Helper()
}
test := internal.GetTest(t)
if test == nil {
t.Error(internal.ErrCanNotRunIfNotBuiltinTesting)
return
}
for i, v := range testSet {
test.Run(fmt.Sprint(v), func(t *testing.T) {
t.Helper()
testFunc(t, i, v)
})
}
}
// FuzzUtilModifySet returns a modified version of a test set.
//
// Example:
//
// modifiedSet := testza.FuzzUtilModifySet(testza.FuzzIntFull(), func(i int, value int) int {
// return i * 2 // double every value in the test set
// })
func FuzzUtilModifySet[setType any](inputSet []setType, modifier func(index int, value setType) setType) (floats []setType) {
for i, input := range inputSet {
floats = append(floats, modifier(i, input))
}
return
}
// FuzzUtilLimitSet returns a random sample of a test set with a maximal size.
//
// Example:
//
// limitedSet := testza.FuzzUtilLimitSet(testza.FuzzStringFull(), 10)
func FuzzUtilLimitSet[setType any](testSet []setType, max int) []setType {
if len(testSet) <= max {
return testSet
}
if max <= 0 {
return []setType{}
}
rand.Shuffle(len(testSet), func(i, j int) { testSet[i], testSet[j] = testSet[j], testSet[i] })
return testSet[:max]
}
// FuzzUtilDistinctSet returns a set with removed duplicates.
//
// Example:
//
// uniqueSet := testza.FuzzUtilDistinctSet([]string{"A", "C", "A", "B", "A", "B", "C"})
// // uniqueSet => []string{"A", "C", "B"}
func FuzzUtilDistinctSet[setType comparable](testSet []setType) []setType {
seen := map[setType]bool{}
var result []setType
for _, v := range testSet {
if !seen[v] {
seen[v] = true
result = append(result, v)
}
}
return result
}