-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathSpecimenBuilder.java
More file actions
147 lines (129 loc) · 4.8 KB
/
SpecimenBuilder.java
File metadata and controls
147 lines (129 loc) · 4.8 KB
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package com.github.nylle.javafixture;
import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class SpecimenBuilder<T> implements ISpecimenBuilder<T> {
private final List<Consumer<T>> functions = new LinkedList<>();
private final List<String> ignoredFields = new LinkedList<>();
private final Map<String, Object> customFields = new HashMap<>();
private final Map<SpecimenType<?>, Object> predefinedInstances = new HashMap<>();
private final SpecimenType<T> type;
private final Configuration configuration;
public SpecimenBuilder(final SpecimenType<T> type, final Configuration configuration) {
this.type = type;
this.configuration = configuration;
}
/**
* @return a new object based on this {@code ISpecimenBuilder<T>}
*/
@Override
public T create() {
return customize(new SpecimenFactory(new Context(configuration, predefinedInstances)).build(type).create(new CustomizationContext(ignoredFields, customFields, false), new Annotation[0]));
}
/**
* @return a new {@code Optional<T>} based on this {@code ISpecimenBuilder<T>}
* <p>
* This feature is deprecated without replacement.
*/
@Deprecated(forRemoval = true)
@Override
public Optional<T> createOptional() {
return Optional.of(create());
}
/**
* @return a {@code Stream} of objects based on this {@code ISpecimenBuilder<T>}
*/
@Override
public Stream<T> createMany() {
return createMany(configuration.getStreamSize());
}
/**
* Creates a {@code Stream} of objects based on this {@code ISpecimenBuilder<T>} with the specified size
*
* @param size the size of the {@code Stream} to be created
* @return a {@code Stream} of objects based on this {@code ISpecimenBuilder<T>}
*/
@Override
public Stream<T> createMany(final int size) {
return IntStream.range(0, size).boxed().map(x -> create());
}
/**
* Applies the specified function to the created object
*
* @param function a function to customise the created object
* @return this builder for further customisation
*/
@Override
public ISpecimenBuilder<T> with(final Consumer<T> function) {
functions.add(function);
return this;
}
/**
* Sets the field with the specified name to the specified value during object creation
*
* @param fieldName the name of the field to be set
* @param value the value to be set to the field
* @return this builder for further customisation
*/
@Override
public ISpecimenBuilder<T> with(final String fieldName, Object value) {
customFields.put(fieldName, value);
return this;
}
/**
* Sets all fields with the specified type to the specified value during object creation.
*
* @param type the type of the fields to be set
* @param value the value to be set to the fields
* @param <U> the type of the value
* @return this builder for further customisation
*/
@Override
public <U> ISpecimenBuilder<T> with(final Class<U> type, final U value) {
predefinedInstances.putIfAbsent(SpecimenType.fromClass(type), value);
return this;
}
/**
* Sets all fields with the specified type to the specified value during object creation.
*
* @param type the type of the fields to be set
* @param value the value to be set to the fields
* @param <U> the type of the value
* @return this builder for further customisation
*/
@Override
public <U> ISpecimenBuilder<T> with(final SpecimenType<U> type, final U value) {
predefinedInstances.putIfAbsent(type, value);
return this;
}
/**
* Omits the field with the specified name during object creation
* Primitives will receive their respective default-value, objects will be null
*
* @param fieldName the name of the field to be set
* @return this builder for further customisation
*/
@Override
public ISpecimenBuilder<T> without(final String fieldName) {
ignoredFields.add(fieldName);
return this;
}
@Override
public <U> ISpecimenBuilder<T> without(Class<U> fieldName) {
predefinedInstances.put(SpecimenType.fromClass(fieldName), null);
return this;
}
T construct() {
return new SpecimenFactory(new Context(configuration)).build(type).create(new CustomizationContext(List.of(), Map.of(), true), new Annotation[0]);
}
private T customize(T instance) {
functions.forEach(f -> f.accept(instance));
return instance;
}
}