From 8267ce6fff71442417bc8dc5bc7aeaf8252646b2 Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Wed, 10 Jun 2026 10:57:43 -0700 Subject: [PATCH] CQ. Use more inline expected diagnostics. Change-Id: I83743fee43718133df71dd33093056543dc83094 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/510482 Reviewed-by: Johnni Winther Commit-Queue: Konstantin Shcheglov --- .../test/src/dart/micro/file_resolution.dart | 32 ++++++- .../dart/micro/simple_file_resolver_test.dart | 89 +++++++++++-------- .../const_eval_throws_exception_test.dart | 63 +++++++------ 3 files changed, 117 insertions(+), 67 deletions(-) diff --git a/pkg/analyzer/test/src/dart/micro/file_resolution.dart b/pkg/analyzer/test/src/dart/micro/file_resolution.dart index 49ae7b1d1c6..165be86a9e6 100644 --- a/pkg/analyzer/test/src/dart/micro/file_resolution.dart +++ b/pkg/analyzer/test/src/dart/micro/file_resolution.dart @@ -5,6 +5,7 @@ import 'dart:convert'; import 'package:analyzer/dart/analysis/results.dart'; +import 'package:analyzer/diagnostic/diagnostic.dart'; import 'package:analyzer/file_system/file_system.dart'; import 'package:analyzer/src/dart/analysis/byte_store.dart'; import 'package:analyzer/src/dart/analysis/file_state.dart'; @@ -19,6 +20,7 @@ import 'package:analyzer/src/util/file_paths.dart' as file_paths; import 'package:analyzer/src/util/performance/operation_performance.dart'; import 'package:analyzer/src/workspace/blaze.dart'; import 'package:analyzer_testing/resource_provider_mixin.dart'; +import 'package:analyzer_testing/src/expected_diagnostics.dart'; import 'package:analyzer_utilities/testing/tree_string_sink.dart'; import 'package:crypto/crypto.dart'; import 'package:linter/src/rules.dart'; @@ -67,6 +69,24 @@ class FileResolutionTest with ResourceProviderMixin, ResolutionTest { newFile(testFile.path, content); } + void addTestFileWithDiagnosticExpectations(String code) { + var cleanCode = removeDiagnosticExpectations(code); + addTestFile(cleanCode); + } + + void assertDiagnosticsInCode(String code, List diagnostics) { + var cleanCode = removeDiagnosticExpectations(code); + var actual = updateExpectedDiagnostics( + content: cleanCode, + actualDiagnostics: diagnostics, + ); + if (actual != code) { + NodeTextExpectationsCollector.add(actual); + printPrettyDiff(code, actual); + fail('See the difference above.'); + } + } + void assertStateString(String expected) { var buffer = StringBuffer(); printer.AnalyzerStatePrinter( @@ -88,6 +108,11 @@ class FileResolutionTest with ResourceProviderMixin, ResolutionTest { } } + Future assertTestErrorsWithDiagnostics(String code) async { + var result = await fileResolver.getErrors2(path: testFile.path); + assertDiagnosticsInCode(code, result.diagnostics); + } + /// Create a new [FileResolver] into [fileResolver]. /// /// We do this the first time, and to test reusing results from [byteStore]. @@ -110,8 +135,11 @@ class FileResolutionTest with ResourceProviderMixin, ResolutionTest { ); } - Future getTestErrors() { - return fileResolver.getErrors2(path: testFile.path); + Future getErrorsWithDiagnostics(File file, String code) async { + modifyFile2(file, removeDiagnosticExpectations(code)); + var result = await fileResolver.getErrors2(path: file.path); + assertDiagnosticsInCode(code, result.diagnostics); + return result; } @override diff --git a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart index 4ccf229c3c4..de2153f4758 100644 --- a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart +++ b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart @@ -8,7 +8,6 @@ import 'package:analyzer/source/line_info.dart'; import 'package:analyzer/src/dart/analysis/file_state.dart'; import 'package:analyzer/src/dart/micro/resolve_file.dart'; import 'package:analyzer/src/dart/micro/utils.dart'; -import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag; import 'package:test/test.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; @@ -1362,41 +1361,35 @@ void f(int? a) { } test_getErrors() async { - addTestFile(r''' + var result = await getErrorsWithDiagnostics(testFile, r''' var a = b; +// ^ +// [diag.undefinedIdentifier] Undefined name 'b'. var foo = 0; '''); - var result = await getTestErrors(); expect(result.path, convertPath('/workspace/dart/test/lib/test.dart')); expect(result.uri.toString(), 'package:dart.test/test.dart'); - assertErrorsInList(result.diagnostics, [ - error(diag.undefinedIdentifier, 8, 1), - ]); expect(result.lineInfo.lineStarts, [0, 11, 24]); } test_getErrors_docImports() async { newFile('$testPackageLibPath/a.dart', ''); - var b = newFile('$testPackageLibPath/b.dart', r''' + var b = getFile('$testPackageLibPath/b.dart'); + await getErrorsWithDiagnostics(b, r''' /// @docImport 'a.dart'; library; '''); - - var errorsResult = await fileResolver.getErrors2(path: b.path); - assertErrorsInList(errorsResult.diagnostics, []); } test_getErrors_library() async { - var a = newFile('$testPackageLibPath/a.dart', r''' + var a = getFile('$testPackageLibPath/a.dart'); + await getErrorsWithDiagnostics(a, r''' var a = 42 +// ^^ +// [diag.expectedToken] Expected to find ';'. '''); - - var errorsResult = await fileResolver.getErrors2(path: a.path); - assertErrorsInList(errorsResult.diagnostics, [ - error(diag.expectedToken, 8, 2), - ]); } test_getErrors_part_hasLibrary() async { @@ -1404,35 +1397,45 @@ var a = 42 part 'b.dart'; '''); - var b = newFile('$testPackageLibPath/b.dart', r''' + var b = getFile('$testPackageLibPath/b.dart'); + await getErrorsWithDiagnostics(b, r''' part of 'a.dart'; var a = 42 +// ^^ +// [diag.expectedToken] Expected to find ';'. '''); - - var errorsResult = await fileResolver.getErrors2(path: b.path); - assertErrorsInList(errorsResult.diagnostics, [ - error(diag.expectedToken, 26, 2), - ]); } test_getErrors_reuse() async { - addTestFile('var a = b;'); + var unresolvedB = r''' +var a = b; +// ^ +// [diag.undefinedIdentifier] Undefined name 'b'. +'''; + + var unresolvedC = r''' +var a = c; +// ^ +// [diag.undefinedIdentifier] Undefined name 'c'. +'''; + + addTestFileWithDiagnosticExpectations(unresolvedB); // No resolved files yet. _assertResolvedFiles([]); // No cached, will resolve once. - expect((await getTestErrors()).diagnostics, hasLength(1)); + await assertTestErrorsWithDiagnostics(unresolvedB); _assertResolvedFiles([testFile]); // Has cached, will be not resolved again. - expect((await getTestErrors()).diagnostics, hasLength(1)); + await assertTestErrorsWithDiagnostics(unresolvedB); _assertResolvedFiles([]); // Change the file, will be resolved again. - addTestFile('var a = c;'); + addTestFileWithDiagnosticExpectations(unresolvedC); fileResolver.changeFiles([testFile.path]); - expect((await getTestErrors()).diagnostics, hasLength(1)); + await assertTestErrorsWithDiagnostics(unresolvedC); _assertResolvedFiles([testFile]); } @@ -1441,20 +1444,31 @@ var a = 42 var a = 0; '''); - addTestFile(r''' + var testCodeWhenAIsInt = r''' import 'a.dart'; var b = a.foo; -'''); +// ^^^ +// [diag.undefinedGetter] The getter 'foo' isn't defined for the type 'int'. +'''; + + var testCodeWhenAIsDouble = r''' +import 'a.dart'; +var b = a.foo; +// ^^^ +// [diag.undefinedGetter] The getter 'foo' isn't defined for the type 'double'. +'''; + + addTestFileWithDiagnosticExpectations(testCodeWhenAIsInt); // No resolved files yet. _assertResolvedFiles([]); // No cached, will resolve once. - expect((await getTestErrors()).diagnostics, hasLength(1)); + await assertTestErrorsWithDiagnostics(testCodeWhenAIsInt); _assertResolvedFiles([testFile]); // Has cached, will be not resolved again. - expect((await getTestErrors()).diagnostics, hasLength(1)); + await assertTestErrorsWithDiagnostics(testCodeWhenAIsInt); _assertResolvedFiles([]); // Change the dependency. @@ -1464,7 +1478,7 @@ var b = a.foo; var a = 4.2; '''); fileResolver.changeFiles([a.path]); - expect((await getTestErrors()).diagnostics, hasLength(1)); + await assertTestErrorsWithDiagnostics(testCodeWhenAIsDouble); _assertResolvedFiles([testFile]); } @@ -1789,12 +1803,15 @@ byteStore 1: [k00, k02, k03, k04, k05, k06, k07] '''); - var result = await getTestErrors(); + var result = await fileResolver.getErrors2(path: testFile.path); expect(result.path, testFile.path); expect(result.uri.toString(), 'package:dart.test/test.dart'); - assertErrorsInList(result.diagnostics, [ - error(diag.undefinedIdentifier, 8, 1), - ]); + assertDiagnosticsInCode(r''' +var a = b; +// ^ +// [diag.undefinedIdentifier] Undefined name 'b'. +var foo = 0; +''', result.diagnostics); expect(result.lineInfo.lineStarts, [0, 11, 24]); // We created the library element for the test file, using the reader. diff --git a/pkg/analyzer/test/src/diagnostics/const_eval_throws_exception_test.dart b/pkg/analyzer/test/src/diagnostics/const_eval_throws_exception_test.dart index 2f8b33e4c6d..fd1a4c4f780 100644 --- a/pkg/analyzer/test/src/diagnostics/const_eval_throws_exception_test.dart +++ b/pkg/analyzer/test/src/diagnostics/const_eval_throws_exception_test.dart @@ -2,9 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag; -import 'package:analyzer_testing/analysis_rule/analysis_rule.dart'; -import 'package:test/test.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; import '../dart/resolution/context_collection_resolution.dart'; @@ -224,7 +221,19 @@ const C = 5 + D; test_CastError_intToDouble_constructor_importAnalyzedAfter() async { // See dartbug.com/35993 - var other = newFile('$testPackageLibPath/other.dart', ''' + var other = getFile('$testPackageLibPath/other.dart'); + + await resolveFilesWithDiagnostics({ + testFile: r''' +import 'other.dart'; + +void main() { + const foo = Foo(1); + const bar = Bar.some(); + print("$foo, $bar"); +} +''', + other: r''' class Foo { final double value; @@ -237,23 +246,17 @@ class Bar { const Bar(this.value); const Bar.some() : this(const Foo(1)); -}'''); - await resolveTestCodeWithDiagnostics(r''' -import 'other.dart'; - -void main() { - const foo = Foo(1); - const bar = Bar.some(); - print("$foo, $bar"); } -'''); - var otherFileResult = await resolveFile(other); - expect(otherFileResult.diagnostics, isEmpty); +''', + }); } test_CastError_intToDouble_constructor_importAnalyzedBefore() async { // See dartbug.com/35993 - var other = newFile('$testPackageLibPath/other.dart', ''' + var other = getFile('$testPackageLibPath/other.dart'); + + await resolveFilesWithDiagnostics({ + other: r''' class Foo { final double value; @@ -266,8 +269,9 @@ class Bar { const Bar(this.value); const Bar.some() : this(const Foo(1)); -}'''); - await resolveTestCodeWithDiagnostics(r''' +} +''', + testFile: r''' import 'other.dart'; void main() { @@ -275,20 +279,24 @@ void main() { const bar = Bar.some(); print("$foo, $bar"); } -'''); - var otherFileResult = await resolveFile(other); - expect(otherFileResult.diagnostics, isEmpty); +''', + }); } test_default_constructor_arg_empty_map_import() async { - var other = newFile('$testPackageLibPath/other.dart', ''' + var other = getFile('$testPackageLibPath/other.dart'); + + await resolveFilesWithDiagnostics({ + other: r''' class C { final Map m; const C({this.m = const {}}) : assert(m != null); +// ^^^^^^^ +// [diag.unnecessaryNullComparisonNeverNullTrue] The operand can't be 'null', so the condition is always 'true'. } -'''); - await resolveTestCodeWithDiagnostics(r''' +''', + testFile: r''' import 'other.dart'; main() { @@ -296,11 +304,8 @@ main() { // ^ // [diag.unusedLocalVariable] The value of the local variable 'c' isn't used. } -'''); - var otherFileResult = await resolveFile(other); - assertErrorsInList(otherFileResult.diagnostics, [ - error(diag.unnecessaryNullComparisonNeverNullTrue, 97, 7), - ]); +''', + }); } test_enum_constructor_initializer_asExpression() async {