Skip to content

Commit 907aaa5

Browse files
matchers: reduce results lists creation (#1568)
1 parent 99de0f1 commit 907aaa5

12 files changed

Lines changed: 319 additions & 172 deletions

File tree

webtau-core/src/main/java/org/testingisdocumenting/webtau/expectation/TokenizedReportUtils.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import org.testingisdocumenting.webtau.cfg.WebTauConfig;
2020
import org.testingisdocumenting.webtau.data.ValuePath;
21+
import org.testingisdocumenting.webtau.expectation.equality.ValuePathLazyMessageList;
2122
import org.testingisdocumenting.webtau.expectation.equality.ValuePathMessage;
2223
import org.testingisdocumenting.webtau.reporter.TokenizedMessage;
2324

@@ -31,8 +32,8 @@ public class TokenizedReportUtils {
3132
private TokenizedReportUtils() {
3233
}
3334

34-
public static TokenizedMessage generateReportPart(ValuePath topLevelActualPath, TokenizedMessage label, List<List<ValuePathMessage>> messagesGroups) {
35-
if (messagesGroups.stream().allMatch(List::isEmpty)) {
35+
public static TokenizedMessage generateReportPart(ValuePath topLevelActualPath, TokenizedMessage label, List<ValuePathLazyMessageList> messagesGroups) {
36+
if (messagesGroups.stream().allMatch(l -> l == null || l.isEmpty())) {
3637
return tokenizedMessage();
3738
}
3839

@@ -63,21 +64,21 @@ public static TokenizedMessage combineReportParts(TokenizedMessage... parts) {
6364
}
6465

6566
public static TokenizedMessage generateReportPartWithoutLabel(ValuePath topLevelActualPath,
66-
Stream<List<ValuePathMessage>> messagesGroupsStream) {
67+
Stream<ValuePathLazyMessageList> messagesGroupsStream) {
6768
return generateReportPartWithoutLabel(topLevelActualPath, messagesGroupsStream, WebTauConfig.getCfg().getMatchersReportEntriesLimit());
6869
}
6970

7071
public static TokenizedMessage generateReportPartWithoutLabel(ValuePath topLevelActualPath,
71-
Stream<List<ValuePathMessage>> messagesGroupsStream,
72+
Stream<ValuePathLazyMessageList> messagesGroupsStream,
7273
int maxNumberOfEntries) {
73-
List<List<ValuePathMessage>> messagesGroups = messagesGroupsStream.filter(group -> !group.isEmpty()).toList();
74+
List<ValuePathLazyMessageList> messagesGroups = messagesGroupsStream.filter(group -> group != null && !group.isEmpty()).toList();
7475
if (messagesGroups.isEmpty()) {
7576
return tokenizedMessage();
7677
}
7778

7879
TokenizedMessage result = tokenizedMessage();
7980
int groupIdx = 0;
80-
for (List<ValuePathMessage> group : messagesGroups) {
81+
for (ValuePathLazyMessageList group : messagesGroups) {
8182
TokenizedReportUtils.appendToReport(result, topLevelActualPath, group, maxNumberOfEntries);
8283

8384
boolean isLastGroup = groupIdx == messagesGroups.size() - 1;
@@ -93,7 +94,7 @@ public static TokenizedMessage generateReportPartWithoutLabel(ValuePath topLevel
9394

9495
private static void appendToReport(TokenizedMessage report,
9596
ValuePath topLevelActualPath,
96-
List<ValuePathMessage> messages,
97+
ValuePathLazyMessageList messages,
9798
int maxNumberOfEntries) {
9899
boolean needToLimit = messages.size() > maxNumberOfEntries;
99100
int messageIdx = 0;

webtau-core/src/main/java/org/testingisdocumenting/webtau/expectation/contain/ContainAnalyzer.java

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.testingisdocumenting.webtau.expectation.contain.handlers.IterableAndTableContainHandler;
2424
import org.testingisdocumenting.webtau.expectation.contain.handlers.IterableAndSingleValueContainHandler;
2525
import org.testingisdocumenting.webtau.expectation.contain.handlers.NullContainHandler;
26+
import org.testingisdocumenting.webtau.expectation.equality.ValuePathLazyMessageList;
2627
import org.testingisdocumenting.webtau.expectation.equality.ValuePathMessage;
2728
import org.testingisdocumenting.webtau.reporter.TokenizedMessage;
2829
import org.testingisdocumenting.webtau.utils.ServiceLoaderUtils;
@@ -39,9 +40,9 @@
3940
public class ContainAnalyzer {
4041
private static final List<ContainHandler> handlers = discoverHandlers();
4142

42-
private final List<ValuePathMessage> matchMessages;
43-
private final List<ValuePathMessage> mismatchMessages;
44-
private final List<ValuePathMessage> missingMessages;
43+
private final ValuePathLazyMessageList matchMessages;
44+
private final ValuePathLazyMessageList mismatchMessages;
45+
private final ValuePathLazyMessageList missingMessages;
4546

4647
private final Set<ValuePath> extraMismatchPaths;
4748

@@ -82,7 +83,7 @@ public void reportMismatch(ContainHandler reporter, ValuePathMessage valuePathMe
8283
mismatchMessages.add(valuePathMessage);
8384
}
8485

85-
public void reportMismatches(ContainHandler reporter, List<ValuePathMessage> valuePathMessages) {
86+
public void reportMismatches(ContainHandler reporter, ValuePathLazyMessageList valuePathMessages) {
8687
mismatchMessages.addAll(valuePathMessages);
8788
}
8889

@@ -98,7 +99,7 @@ public void reportMissing(ContainHandler reporter, ValuePathMessage valuePathMes
9899
missingMessages.add(valuePathMessage);
99100
}
100101

101-
public void reportMissing(ContainHandler reporter, List<ValuePathMessage> valuePathMessages) {
102+
public void reportMissing(ContainHandler reporter, ValuePathLazyMessageList valuePathMessages) {
102103
missingMessages.addAll(valuePathMessages);
103104
}
104105

@@ -111,13 +112,13 @@ public void reportMatch(ContainHandler reporter, ValuePath actualPath, Supplier<
111112
}
112113

113114
public Set<ValuePath> generateMatchPaths() {
114-
return extractActualPaths(matchMessages);
115+
return matchMessages.extractPaths();
115116
}
116117

117118
public Set<ValuePath> generateMismatchPaths() {
118119
HashSet<ValuePath> result = new HashSet<>(extraMismatchPaths);
119-
result.addAll(extractActualPaths(mismatchMessages));
120-
result.addAll(extractActualPaths(missingMessages));
120+
result.addAll(mismatchMessages.extractPaths());
121+
result.addAll(missingMessages.extractPaths());
121122

122123
return result;
123124
}
@@ -184,9 +185,9 @@ public void resetReportData() {
184185
}
185186

186187
private ContainAnalyzer() {
187-
this.matchMessages = new ArrayList<>();
188-
this.mismatchMessages = new ArrayList<>();
189-
this.missingMessages = new ArrayList<>();
188+
this.matchMessages = new ValuePathLazyMessageList();
189+
this.mismatchMessages = new ValuePathLazyMessageList();
190+
this.missingMessages = new ValuePathLazyMessageList();
190191
this.mismatchedExpectedValues = new ArrayList<>();
191192
this.extraMismatchPaths = new HashSet<>();
192193
}
@@ -208,13 +209,6 @@ private boolean contains(ValuePath actualPath, Object actual, Object expected, b
208209
return after == before;
209210
}
210211

211-
private Set<ValuePath> extractActualPaths(List<ValuePathMessage> notEqualMessages) {
212-
return notEqualMessages
213-
.stream()
214-
.map(ValuePathMessage::actualPath)
215-
.collect(Collectors.toSet());
216-
}
217-
218212
private void updateTopLevelActualPath(ValuePath actualPath) {
219213
if (topLevelActualPath == null) {
220214
topLevelActualPath = actualPath;

webtau-core/src/main/java/org/testingisdocumenting/webtau/expectation/contain/ContainExactlyMatcher.java

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.testingisdocumenting.webtau.expectation.ValueMatcher;
2626
import org.testingisdocumenting.webtau.expectation.equality.CompareToComparator;
2727
import org.testingisdocumenting.webtau.expectation.equality.CompareToResult;
28+
import org.testingisdocumenting.webtau.expectation.equality.ValuePathLazyMessageList;
2829
import org.testingisdocumenting.webtau.expectation.equality.ValuePathMessage;
2930
import org.testingisdocumenting.webtau.reporter.TokenizedMessage;
3031

@@ -40,10 +41,10 @@ public class ContainExactlyMatcher implements ValueMatcher, ExpectedValuesAware,
4041
private List<ValuePathWithValue<Object>> actualCopy;
4142
private List<ValuePathWithValue<Object>> expectedCopy;
4243

43-
private final Map<ValuePath, List<List<ValuePathMessage>>> notEqualMessagesByExpectedPath = new HashMap<>();
44-
private final List<ValuePathMessage> notEqualCandidateMessages = new ArrayList<>();
45-
private final List<ValuePathMessage> missingMessages = new ArrayList<>();
46-
private final List<ValuePathMessage> extraMessages = new ArrayList<>();
44+
private final Map<ValuePath, List<ValuePathLazyMessageList>> notEqualMessagesByExpectedPath = new HashMap<>();
45+
private final ValuePathLazyMessageList notEqualCandidateMessages = new ValuePathLazyMessageList();
46+
private final ValuePathLazyMessageList missingMessages = new ValuePathLazyMessageList();
47+
private final ValuePathLazyMessageList extraMessages = new ValuePathLazyMessageList();
4748

4849
private CompareToComparator comparator;
4950

@@ -191,11 +192,11 @@ private boolean matches(CompareToComparator comparator, ValuePath actualPath, Ob
191192
return actualCopy.isEmpty() && expectedCopy.isEmpty();
192193
}
193194

194-
private List<ValuePathMessage> extractPotentialNotEqualMessages() {
195+
private ValuePathLazyMessageList extractPotentialNotEqualMessages() {
195196
List<ValuePath> actualPaths = actualCopy.stream().map(ValuePathWithValue::getPath).toList();
196-
List<ValuePathMessage> notEqualCandidateMessages = new ArrayList<>();
197+
ValuePathLazyMessageList notEqualCandidateMessages = new ValuePathLazyMessageList();
197198
for (ValuePathWithValue<Object> expectedWithPath : expectedCopy) {
198-
List<List<ValuePathMessage>> notEqualMessageBatches = notEqualMessagesByExpectedPath.get(expectedWithPath.getPath());
199+
List<ValuePathLazyMessageList> notEqualMessageBatches = notEqualMessagesByExpectedPath.get(expectedWithPath.getPath());
199200
if (notEqualMessageBatches == null) {
200201
continue;
201202
}
@@ -207,7 +208,7 @@ private List<ValuePathMessage> extractPotentialNotEqualMessages() {
207208
return false;
208209
}
209210

210-
ValuePathMessage firstMessage = batch.get(0);
211+
ValuePathMessage firstMessage = batch.first();
211212
return actualPaths.stream().anyMatch(path -> firstMessage.actualPath().startsWith(path));
212213
})
213214
.toList();
@@ -217,10 +218,10 @@ private List<ValuePathMessage> extractPotentialNotEqualMessages() {
217218
// it will be a potential mismatch detail to display,
218219
//
219220
int minNumberOMismatches = notEqualMessageBatches.stream()
220-
.map(List::size)
221+
.map(ValuePathLazyMessageList::size)
221222
.min(Integer::compareTo).orElse(0);
222223

223-
List<List<ValuePathMessage>> messagesWithMinFailures = notEqualMessageBatches.stream()
224+
List<ValuePathLazyMessageList> messagesWithMinFailures = notEqualMessageBatches.stream()
224225
.filter(v -> v.size() == minNumberOMismatches).toList();
225226

226227
if (notEqualMessageBatches.size() != messagesWithMinFailures.size()) {

webtau-core/src/main/java/org/testingisdocumenting/webtau/expectation/contain/handlers/CombinedMismatchAndMissing.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,22 @@
1717
package org.testingisdocumenting.webtau.expectation.contain.handlers;
1818

1919
import org.testingisdocumenting.webtau.data.ValuePath;
20+
import org.testingisdocumenting.webtau.expectation.equality.ValuePathLazyMessageList;
2021
import org.testingisdocumenting.webtau.expectation.equality.ValuePathMessage;
2122

2223
import java.util.List;
2324
import java.util.stream.Stream;
2425

25-
public record CombinedMismatchAndMissing(List<ValuePathMessage> mismatchMessages, List<ValuePathMessage> missingMessage) {
26+
public record CombinedMismatchAndMissing(ValuePathLazyMessageList mismatchMessages, ValuePathLazyMessageList missingMessages) {
2627
int size() {
27-
return mismatchMessages.size() + missingMessage.size();
28+
int mismatchMessagesSize = mismatchMessages == null ? 0 : mismatchMessages.size();
29+
int missingMessagesSize = missingMessages == null ? 0 : missingMessages.size();
30+
return mismatchMessagesSize + missingMessagesSize;
2831
}
2932

3033
List<ValuePath> extractPaths() {
3134
return Stream.concat(
32-
mismatchMessages.stream().map(ValuePathMessage::actualPath),
33-
missingMessage.stream().map(ValuePathMessage::actualPath)).toList();
35+
mismatchMessages == null ? Stream.empty() : mismatchMessages.stream().map(ValuePathMessage::actualPath),
36+
missingMessages == null ? Stream.empty() : missingMessages.stream().map(ValuePathMessage::actualPath)).toList();
3437
}
3538
}

webtau-core/src/main/java/org/testingisdocumenting/webtau/expectation/contain/handlers/IterableAndSingleValueContainHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public void analyzeContain(ContainAnalyzer containAnalyzer, ValuePath actualPath
5353
suspects.forEach(list -> containAnalyzer.registerExtraMismatchPaths(list.extractPaths()));
5454
suspects.forEach(list -> {
5555
containAnalyzer.reportMismatches(this, list.mismatchMessages());
56-
containAnalyzer.reportMissing(this, list.missingMessage());
56+
containAnalyzer.reportMissing(this, list.missingMessages());
5757
});
5858
}
5959

webtau-core/src/main/java/org/testingisdocumenting/webtau/expectation/contain/handlers/IterableContainAnalyzer.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ public List<IndexedValue> findContainingIndexedValues() {
4949
Object actualValue = iterator.next();
5050
ValuePath indexedPath = actualPath.index(idx);
5151

52-
// shit is happening here for large numbers
5352
CompareToResult compareToResult = comparator.compareUsingEqualOnly(indexedPath, actualValue, expected);
5453
boolean isEqual = compareToResult.isEqual();
5554
if (isEqual) {

webtau-core/src/main/java/org/testingisdocumenting/webtau/expectation/contain/handlers/MapContainHandler.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,13 @@ private void analyzeMapAndMapSingleExpectedEntry(ContainAnalyzer containAnalyzer
7676

7777
containAnalyzer.registerConvertedActualByPath(comparator.getConvertedActualByPath());
7878
if (!actualValueEqual) {
79-
comparator.getMissingMessages().forEach(m -> containAnalyzer.reportMissing(this, m));
80-
comparator.getNotEqualMessages().forEach(m -> containAnalyzer.reportMismatch(this, m));
79+
if (comparator.getMissingMessages() != null) {
80+
comparator.getMissingMessages().forEach(m -> containAnalyzer.reportMissing(this, m));
81+
}
82+
83+
if (comparator.getNotEqualMessages() != null) {
84+
comparator.getNotEqualMessages().forEach(m -> containAnalyzer.reportMismatch(this, m));
85+
}
8186
} else {
8287
containAnalyzer.reportMatch(this, propertyPath, comparator::generateEqualMatchReport);
8388
}

0 commit comments

Comments
 (0)