forked from Bijnagte/spock-genesis
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Generator.groovy
112 lines (93 loc) · 3.29 KB
/
Generator.groovy
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
package spock.genesis.generators
import groovy.transform.CompileStatic
import spock.genesis.extension.ExtensionMethods
import spock.genesis.generators.values.NullGenerator
/**
* An Iterator that generates a type (usually lazily)
* @param < E > the generated type
*/
@CompileStatic
abstract class Generator<E> implements Iterable<E>, Closeable {
protected final Random random = new Random()
/**
* Wraps this generator in a generator that returns values that matches the supplied predicate
* @param predicate
* @return a FilteredGenerator
*/
FilteredGenerator<E> filter(Closure predicate) {
new FilteredGenerator<E>(this, predicate)
}
@SuppressWarnings(['UnnecessaryPublicModifier']) // needed for generic parsing issue
public <T> TransformingGenerator<E, T> map(Closure<T> transform) {
new TransformingGenerator<E, T>(this, transform)
}
TransformingGenerator<E, E> with(Closure<?> transform) {
Closure withClosure = { generatedValue ->
generatedValue.with(transform)
generatedValue
}
new TransformingGenerator<E, E>(this, withClosure)
}
LimitedGenerator<E> take(int qty) {
new LimitedGenerator<E>(this, qty)
}
SequentialMultisourceGenerator<E> then(Iterable<E>... iterables) {
Generator<E>[] all = new Generator<E>[iterables.length + 1]
all[0] = this
for (int i = 0; i < iterables.length; i++) {
all[i + 1] = ExtensionMethods.toGenerator(iterables[i])
}
new SequentialMultisourceGenerator<E>(all)
}
CyclicGenerator<E> repeat() {
new CyclicGenerator<E>(this)
}
LimitedGenerator<E> multiply(int qty) {
take(qty)
}
CyclicGenerator<E> getRepeat() {
repeat()
}
MultiSourceGenerator<E> getWithNulls() {
withNulls(100)
}
/**Wraps this generator in a {@link spock.genesis.generators.MultiSourceGenerator} that randomly returns nulls
* @param resultsPerNull the average number of results from this generator per null result
* @return {@link spock.genesis.generators.MultiSourceGenerator}
*/
@SuppressWarnings('SpaceAroundMapEntryColon')
MultiSourceGenerator<E> withNulls(int resultsPerNull) {
Map weightedGenerators = [(this): resultsPerNull, (new NullGenerator<E>()): 1]
new MultiSourceGenerator<E>(weightedGenerators)
}
MultiSourceGenerator and(Iterable iterable) {
if (MultiSourceGenerator.isAssignableFrom(this.getClass())) {
((MultiSourceGenerator) this) + iterable
} else {
new MultiSourceGenerator([this, iterable])
}
}
abstract UnmodifiableIterator<E> iterator()
/**
* If false then the generator may still terminate when iterated
* @return true if the Generator will terminate
*/
boolean isFinite() {
!iterator().hasNext()
}
List<E> getRealized() {
this.collect().asList()
}
@SuppressWarnings('EmptyMethodInAbstractClass')
void close() { }
/**
* Set the {@link Random} seed for this generator and all contained generators.
* This method mutates the generator!
* @param seed
* @return this generator
*/
Generator<E> seed(Long seed) {
random.setSeed(seed)
this
}
}