-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathSnapshot.java
More file actions
131 lines (106 loc) · 3.53 KB
/
Snapshot.java
File metadata and controls
131 lines (106 loc) · 3.53 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
package io.github.jsonSnapshot;
import com.jayway.jsonpath.DocumentContext;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.spi.json.JacksonJsonProvider;
import org.assertj.core.util.diff.DiffUtils;
import org.assertj.core.util.diff.Patch;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import static io.github.jsonSnapshot.SnapshotMatcher.defaultJsonFunction;
public class Snapshot {
private SnapshotFile snapshotFile;
private Class clazz;
private Method method;
private Function<Object, String> jsonFunction;
private final List<String> pathsToIgnore = new ArrayList<>();
private Object[] current;
Snapshot(
SnapshotFile snapshotFile,
Class clazz,
Method method,
Function<Object, String> jsonFunction,
Object... current) {
this.current = current;
this.snapshotFile = snapshotFile;
this.clazz = clazz;
this.method = method;
this.jsonFunction = jsonFunction;
}
public void toMatchSnapshot() {
Set<String> rawSnapshots = snapshotFile.getRawSnapshots();
String rawSnapshot = getRawSnapshot(rawSnapshots);
String currentObject = takeSnapshot();
// Match Snapshot
if (rawSnapshot != null) {
if (!rawSnapshot.trim().equals(currentObject.trim())) {
throw generateDiffError(rawSnapshot, currentObject);
}
}
// Create New Snapshot
else {
snapshotFile.push(currentObject);
}
}
private SnapshotMatchException generateDiffError(String rawSnapshot, String currentObject) {
// compute the patch: this is the diffutils part
Patch<String> patch =
DiffUtils.diff(
Arrays.asList(rawSnapshot.trim().split("\n")),
Arrays.asList(currentObject.trim().split("\n")));
String error =
"Error on: \n"
+ currentObject.trim()
+ "\n\n"
+ patch
.getDeltas()
.stream()
.map(delta -> delta.toString() + "\n")
.reduce(String::concat)
.get();
return new SnapshotMatchException(error);
}
private String getRawSnapshot(Collection<String> rawSnapshots) {
for (String rawSnapshot : rawSnapshots) {
if (rawSnapshot.contains(getSnapshotName())) {
return rawSnapshot;
}
}
return null;
}
private Object ignorePaths(Object input) {
DocumentContext context = JsonPath.using(new JacksonJsonProvider()).parse(defaultJsonFunction().apply(input));
this.pathsToIgnore.forEach(path -> context.delete(path));
String root = "$";
return context.read(root);
}
private Object[] getCurrentWithoutIgnoredPaths() {
if (pathsToIgnore.isEmpty() || current == null) {
return current;
}
return Arrays.asList(current).stream()
.map(this::ignorePaths)
.collect(Collectors.toList())
.toArray();
}
private String takeSnapshot() {
return getSnapshotName() + jsonFunction.apply(getCurrentWithoutIgnoredPaths());
}
public String getSnapshotName() {
return clazz.getName() + "." + method.getName() + "=";
}
/**
* Ignore fields when comparing object and snapshot.
*
* @param jsonPathsToIgnore A list of paths to ignore in <a href="https://github.com/json-path/JsonPath">JsonPath</a> syntax.
*/
public Snapshot ignoring(String... jsonPathsToIgnore) {
this.pathsToIgnore.addAll(Arrays.asList(jsonPathsToIgnore));
return this;
}
}