Skip to content

Commit 69e9fd5

Browse files
srawlinsCommit Queue
authored andcommitted
analyzer_testing: split assertDiagnosticsIn into multiple, overridable methods
Work towards #61271 Change-Id: I3732176b84fb0ce79d2de180e8fb32d76ea4a08c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/444361 Commit-Queue: Samuel Rawlins <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
1 parent ca74ec5 commit 69e9fd5

File tree

3 files changed

+126
-78
lines changed

3 files changed

+126
-78
lines changed

pkg/analyzer_testing/api.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ package:analyzer_testing/analysis_rule/analysis_rule.dart:
55
analysisRule (getter: String)
66
assertNoPubspecDiagnostics (method: Future<void> Function(String))
77
assertPubspecDiagnostics (method: Future<void> Function(String, List<ExpectedDiagnostic>))
8+
correctionMessage (method: String Function(List<Diagnostic>))
89
lint (method: ExpectedDiagnostic Function(int, int, {Pattern? correctionContains, Pattern? messageContains, String? name}))
910
setUp (method: void Function())
11+
unexpectedMessage (method: String Function(List<Diagnostic>))
1012
package:analyzer_testing/experiments/experiments.dart:
1113
experimentsForTests (static getter: List<String>)
1214
experimentsForTests= (static setter: List<String>)
@@ -78,6 +80,8 @@ dart:core:
7880
int (referenced)
7981
package:_fe_analyzer_shared/src/base/errors.dart:
8082
DiagnosticCode (referenced)
83+
package:analyzer/diagnostic/diagnostic.dart:
84+
Diagnostic (referenced)
8185
package:analyzer/file_system/file_system.dart:
8286
File (referenced)
8387
Folder (referenced)

pkg/analyzer_testing/lib/analysis_rule/analysis_rule.dart

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
import 'dart:convert' show json;
6+
57
import 'package:analyzer/analysis_rule/pubspec.dart';
68
import 'package:analyzer/diagnostic/diagnostic.dart';
79
import 'package:analyzer/error/error.dart';
@@ -46,6 +48,28 @@ abstract class AnalysisRuleTest extends PubPackageResolutionTest {
4648
assertDiagnosticsIn(errors, expectedDiagnostics);
4749
}
4850

51+
@override
52+
String correctionMessage(List<Diagnostic> diagnostics) {
53+
var buffer = StringBuffer();
54+
diagnostics.sort((first, second) => first.offset.compareTo(second.offset));
55+
buffer.writeln();
56+
buffer.writeln('To accept the current state, expect:');
57+
for (var actual in diagnostics) {
58+
if (actual.diagnosticCode is LintCode) {
59+
buffer.write(' lint(');
60+
} else {
61+
buffer.write(' error(${actual.diagnosticCode}, ');
62+
}
63+
buffer.write('${actual.offset}, ${actual.length}');
64+
if (actual.diagnosticCode.name != analysisRule) {
65+
buffer.write(", name: '${actual.diagnosticCode.name}'");
66+
}
67+
buffer.writeln('),');
68+
}
69+
70+
return buffer.toString();
71+
}
72+
4973
/// Returns an "expected diagnostic" for [analysisRule] (or [name], if given)
5074
/// at [offset] and [length].
5175
///
@@ -79,6 +103,25 @@ abstract class AnalysisRuleTest extends PubPackageResolutionTest {
79103
);
80104
}
81105

106+
@override
107+
String unexpectedMessage(List<Diagnostic> unmatchedActual) {
108+
var buffer = StringBuffer();
109+
if (buffer.isNotEmpty) {
110+
buffer.writeln();
111+
}
112+
buffer.writeln('Found but did not expect:');
113+
for (var actual in unmatchedActual) {
114+
buffer.write(' $analysisRule.${actual.diagnosticCode.name} [');
115+
buffer.write('${actual.offset}, ${actual.length}, ${actual.message}');
116+
if (actual.correctionMessage case Pattern correctionMessage) {
117+
buffer.write(', ');
118+
buffer.write(json.encode(correctionMessage));
119+
}
120+
buffer.writeln(']');
121+
}
122+
return buffer.toString();
123+
}
124+
82125
Future<List<Diagnostic>> _analyzePubspecFile(String content) async {
83126
var path = convertPath(testPackagePubspecPath);
84127
var pubspecRules = <AbstractAnalysisRule, PubspecVisitor<Object?>>{};

pkg/analyzer_testing/lib/src/analysis_rule/pub_package_resolution.dart

Lines changed: 79 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -212,9 +212,7 @@ class PubPackageResolutionTest with MockPackagesMixin, ResourceProviderMixin {
212212
List<Diagnostic> diagnostics,
213213
List<ExpectedDiagnostic> expectedDiagnostics,
214214
) {
215-
//
216215
// Match actual diagnostics to expected diagnostics.
217-
//
218216
var unmatchedActual = diagnostics.toList();
219217
var unmatchedExpected = expectedDiagnostics.toList();
220218
var actualIndex = 0;
@@ -236,99 +234,33 @@ class PubPackageResolutionTest with MockPackagesMixin, ResourceProviderMixin {
236234
actualIndex++;
237235
}
238236
}
239-
//
240-
// Write the results.
241-
//
237+
238+
// Print the results to the terminal.
242239
var buffer = StringBuffer();
243240
if (unmatchedExpected.isNotEmpty) {
244-
buffer.writeln('Expected but did not find:');
245-
for (var expected in unmatchedExpected) {
246-
buffer.write(' ');
247-
if (expected is ExpectedError) {
248-
buffer.write(expected._code);
249-
}
250-
if (expected is ExpectedLint) {
251-
buffer.write(expected._lintName);
252-
}
253-
buffer.write(' [');
254-
buffer.write(expected._offset);
255-
buffer.write(', ');
256-
buffer.write(expected._length);
257-
if (expected._messageContains != null) {
258-
buffer.write(', messageContains: ');
259-
buffer.write(json.encode(expected._messageContains.toString()));
260-
}
261-
if (expected._correctionContains != null) {
262-
buffer.write(', correctionContains: ');
263-
buffer.write(json.encode(expected._correctionContains.toString()));
264-
}
265-
buffer.writeln(']');
266-
}
241+
buffer.write(missingExpectedMessage(unmatchedExpected));
267242
}
268243
if (unmatchedActual.isNotEmpty) {
269-
if (buffer.isNotEmpty) {
270-
buffer.writeln();
271-
}
272-
buffer.writeln('Found but did not expect:');
273-
for (var actual in unmatchedActual) {
274-
buffer.write(' ');
275-
buffer.write(actual.diagnosticCode);
276-
buffer.write(' [');
277-
buffer.write(actual.offset);
278-
buffer.write(', ');
279-
buffer.write(actual.length);
280-
buffer.write(', ');
281-
buffer.write(actual.message);
282-
if (actual.correctionMessage != null) {
283-
buffer.write(', ');
284-
buffer.write(json.encode(actual.correctionMessage));
285-
}
286-
buffer.writeln(']');
287-
}
244+
buffer.write(unexpectedMessage(unmatchedActual));
288245
}
289-
if (buffer.isNotEmpty) {
290-
diagnostics.sort(
291-
(first, second) => first.offset.compareTo(second.offset),
292-
);
293-
buffer.writeln();
294-
buffer.writeln('To accept the current state, expect:');
295-
for (var actual in diagnostics) {
296-
late String diagnosticKind;
297-
Object? description;
298-
if (actual.diagnosticCode is LintCode) {
299-
diagnosticKind = 'lint';
300-
} else {
301-
diagnosticKind = 'error';
302-
description = actual.diagnosticCode;
303-
}
304-
buffer.write(' $diagnosticKind(');
305-
if (description != null) {
306-
buffer.write(description);
307-
buffer.write(', ');
308-
}
309-
buffer.write(actual.offset);
310-
buffer.write(', ');
311-
buffer.write(actual.length);
312-
buffer.writeln('),');
313-
}
246+
if (unmatchedExpected.isNotEmpty || unmatchedActual.isNotEmpty) {
247+
buffer.write(correctionMessage(diagnostics));
314248

315249
if (dumpAstOnFailures) {
316250
buffer.writeln();
317251
buffer.writeln();
318-
try {
319-
var astSink = StringBuffer();
320252

253+
try {
321254
Spelunker(
322255
result.unit.toSource(),
323-
sink: astSink,
256+
sink: buffer,
324257
featureSet: result.unit.featureSet,
325258
).spelunk();
326-
buffer.write(astSink);
327-
buffer.writeln();
328-
// I hereby choose to catch this type.
329259
} on ArgumentError catch (_) {
330260
// Perhaps we encountered a parsing error while spelunking.
331261
}
262+
263+
buffer.writeln();
332264
}
333265

334266
fail(buffer.toString());
@@ -371,6 +303,54 @@ class PubPackageResolutionTest with MockPackagesMixin, ResourceProviderMixin {
371303
Future<void> assertNoDiagnosticsInFile(String path) async =>
372304
assertDiagnosticsInFile(path, const []);
373305

306+
/// Text to display upon failure, which indicates possible corrections.
307+
@visibleForOverriding
308+
String correctionMessage(List<Diagnostic> diagnostics) {
309+
var buffer = StringBuffer();
310+
diagnostics.sort((first, second) => first.offset.compareTo(second.offset));
311+
buffer.writeln();
312+
buffer.writeln('To accept the current state, expect:');
313+
for (var actual in diagnostics) {
314+
if (actual.diagnosticCode is LintCode) {
315+
buffer.write(' lint(');
316+
} else {
317+
buffer.write(' error(${actual.diagnosticCode}, ');
318+
}
319+
buffer.write('${actual.offset}, ${actual.length}),');
320+
}
321+
322+
return buffer.toString();
323+
}
324+
325+
/// Text to display upon failure, indicating that [unmatchedExpected]
326+
/// diagnostics were expected, but not found.
327+
@visibleForOverriding
328+
String missingExpectedMessage(List<ExpectedDiagnostic> unmatchedExpected) {
329+
var buffer = StringBuffer();
330+
buffer.writeln('Expected but did not find:');
331+
for (var expected in unmatchedExpected) {
332+
buffer.write(' ');
333+
if (expected is ExpectedError) {
334+
buffer.write(expected._code);
335+
}
336+
if (expected is ExpectedLint) {
337+
buffer.write(expected._lintName);
338+
}
339+
buffer.write(' [${expected._offset}, ');
340+
buffer.write(expected._length);
341+
if (expected._messageContains case Pattern messageContains) {
342+
buffer.write(', messageContains: ');
343+
buffer.write(json.encode(messageContains.toString()));
344+
}
345+
if (expected._correctionContains case Pattern correctionContains) {
346+
buffer.write(', correctionContains: ');
347+
buffer.write(json.encode(correctionContains.toString()));
348+
}
349+
buffer.writeln(']');
350+
}
351+
return buffer.toString();
352+
}
353+
374354
@override
375355
File newFile(String path, String content) {
376356
if (_analysisContextCollection != null && !path.endsWith('.dart')) {
@@ -414,6 +394,27 @@ class PubPackageResolutionTest with MockPackagesMixin, ResourceProviderMixin {
414394
_analysisContextCollection = null;
415395
}
416396

397+
/// Text to display upon failure, indicating that [unmatchedActual]
398+
/// diagnostics were found, but unexpected.
399+
@visibleForOverriding
400+
String unexpectedMessage(List<Diagnostic> unmatchedActual) {
401+
var buffer = StringBuffer();
402+
if (buffer.isNotEmpty) {
403+
buffer.writeln();
404+
}
405+
buffer.writeln('Found but did not expect:');
406+
for (var actual in unmatchedActual) {
407+
buffer.write(' ${actual.diagnosticCode} [');
408+
buffer.write('${actual.offset}, ${actual.length}, ${actual.message}');
409+
if (actual.correctionMessage case Pattern correctionMessage) {
410+
buffer.write(', ');
411+
buffer.write(json.encode(correctionMessage));
412+
}
413+
buffer.writeln(']');
414+
}
415+
return buffer.toString();
416+
}
417+
417418
void writePackageConfig(String path, PackageConfigFileBuilder config) {
418419
newFile(path, config.toContent(pathContext: pathContext));
419420
}

0 commit comments

Comments
 (0)