@@ -11,13 +11,16 @@ import 'package:analysis_server/src/analysis_server.dart';
1111import 'package:analyzer/file_system/file_system.dart' ;
1212import 'package:analyzer/src/test_utilities/package_config_file_builder.dart' ;
1313import 'package:analyzer/src/util/file_paths.dart' as file_paths;
14+ import 'package:analyzer/src/utilities/extensions/file_system.dart' ;
1415import 'package:analyzer_plugin/protocol/protocol_common.dart' ;
1516import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
17+ import 'package:collection/collection.dart' ;
1618import 'package:test/test.dart' ;
1719import 'package:test_reflective_loader/test_reflective_loader.dart' ;
1820
1921import 'analysis_server_base.dart' ;
2022import 'mocks.dart' ;
23+ import 'utils/tree_string_sink.dart' ;
2124
2225void main () {
2326 defineReflectiveSuite (() {
@@ -42,9 +45,9 @@ class AnalysisDomainBlazeTest extends _AnalysisDomainTest {
4245 }
4346
4447 Future <void > test_fileSystem_changeFile_buildFile_legacy () async {
45- // This BUILD file disables null safety .
48+ // Make it a Blaze package .
4649 newBlazeBuildFile (myPackageRootPath, r'''
47- dart_package(null_safety = False)
50+ # foo
4851''' );
4952
5053 newFile (myPackageTestFilePath, '''
@@ -54,37 +57,54 @@ void f(int? a) {}
5457 await setRoots (included: [myPackageRootPath], excluded: []);
5558 await server.onAnalysisComplete;
5659
57- // Cannot use `int?` without null safety.
58- assertHasErrors (myPackageTestFilePath);
60+ // No errors after initial analysis.
61+ assertNotificationsText (r'''
62+ AnalysisErrors
63+ file: /home/dart/my/lib/test.dart
64+ errors: empty
65+ ''' );
5966
60- // Stop disabling null safety.
61- newBlazeBuildFile (myPackageRootPath, '' );
67+ // Change BUILD file, nothing interesting.
68+ newBlazeBuildFile (myPackageRootPath, r'''
69+ # bar
70+ ''' );
6271
6372 await pumpEventQueue (times: 5000 );
6473 await server.onAnalysisComplete;
6574
66- // We have null safety enabled, so no errors.
67- assertNoErrors (myPackageTestFilePath);
75+ // BUILD file change caused rebuilding analysis contexts.
76+ assertNotificationsText (r'''
77+ AnalysisFlush
78+ /home/dart/my/lib/test.dart
79+ AnalysisErrors
80+ file: /home/dart/my/lib/test.dart
81+ errors: empty
82+ ''' );
6883 }
6984}
7085
7186@reflectiveTest
7287class AnalysisDomainPubTest extends _AnalysisDomainTest {
7388 Future <void > test_fileSystem_addFile_analysisOptions () async {
7489 deleteTestPackageAnalysisOptionsFile ();
75- var a_path = '$testPackageLibPath /a.dart' ;
76- var b_path = '$testPackageLibPath /b.dart' ;
7790
78- _createFilesWithErrors ([a_path, b_path]);
91+ _createFilesWithErrors ([
92+ '$testPackageLibPath /a.dart' ,
93+ '$testPackageLibPath /b.dart' ,
94+ ]);
7995
8096 await setRoots (included: [workspaceRootPath], excluded: []);
8197 await server.onAnalysisComplete;
8298
8399 // Both a.dart and b.dart are analyzed.
84- _assertAnalyzedFiles (
85- hasErrors: [a_path, b_path],
86- notAnalyzed: [],
87- );
100+ assertNotificationsText (r'''
101+ AnalysisErrors
102+ file: /home/test/lib/a.dart
103+ errors: notEmpty
104+ AnalysisErrors
105+ file: /home/test/lib/b.dart
106+ errors: notEmpty
107+ ''' );
88108
89109 // Write the options file that excludes b.dart
90110 newAnalysisOptionsYamlFile (testPackageRootPath, r'''
@@ -93,15 +113,21 @@ analyzer:
93113 - lib/b.dart
94114''' );
95115
96- await pumpEventQueue ();
116+ await pumpEventQueue (times : 5000 );
97117 await server.onAnalysisComplete;
98118
99- // Errors for all files were flushed, and only a.dart is reported again.
100- _assertFlushedResults ([a_path, b_path]);
101- _assertAnalyzedFiles (
102- hasErrors: [a_path],
103- notAnalyzed: [b_path],
104- );
119+ // Errors for all files were flushed, b.dart is not reported.
120+ assertNotificationsText (r'''
121+ AnalysisFlush
122+ /home/test/lib/a.dart
123+ /home/test/lib/b.dart
124+ AnalysisErrors
125+ file: /home/test/analysis_options.yaml
126+ errors: empty
127+ AnalysisErrors
128+ file: /home/test/lib/a.dart
129+ errors: notEmpty
130+ ''' );
105131 }
106132
107133 Future <void > test_fileSystem_addFile_analysisOptions_analysis () async {
@@ -1681,6 +1707,8 @@ class _AnalysisDomainTest extends PubPackageAnalysisServerTest {
16811707 /// The files for which `analysis.flushResults` was received.
16821708 final List <String > flushResults = [];
16831709
1710+ final List <(String , Object )> notifications = [];
1711+
16841712 void assertHasErrors (String path) {
16851713 path = convertPath (path);
16861714 expect (filesErrors[path], isNotEmpty, reason: path);
@@ -1696,6 +1724,30 @@ class _AnalysisDomainTest extends PubPackageAnalysisServerTest {
16961724 expect (filesErrors[path], isNull, reason: path);
16971725 }
16981726
1727+ void assertNotificationsText (
1728+ String expected, {
1729+ void Function (_NotificationPrinterConfiguration )? configure,
1730+ }) {
1731+ final configuration = _NotificationPrinterConfiguration ();
1732+ configure? .call (configuration);
1733+
1734+ final buffer = StringBuffer ();
1735+ final sink = TreeStringSink (sink: buffer, indent: '' );
1736+ _NotificationPrinter (
1737+ configuration: configuration,
1738+ resourceProvider: resourceProvider,
1739+ sink: sink,
1740+ ).writeNotifications (notifications);
1741+ notifications.clear ();
1742+
1743+ final actual = buffer.toString ();
1744+ if (actual != expected) {
1745+ print ('-------- Actual --------' );
1746+ print ('$actual ------------------------' );
1747+ }
1748+ expect (actual, expected);
1749+ }
1750+
16991751 void forgetReceivedErrors () {
17001752 filesErrors.clear ();
17011753 }
@@ -1704,11 +1756,13 @@ class _AnalysisDomainTest extends PubPackageAnalysisServerTest {
17041756 void processNotification (Notification notification) {
17051757 if (notification.event == ANALYSIS_NOTIFICATION_FLUSH_RESULTS ) {
17061758 var decoded = AnalysisFlushResultsParams .fromNotification (notification);
1759+ notifications.add ((notification.event, decoded));
17071760 flushResults.addAll (decoded.files);
17081761 decoded.files.forEach (filesErrors.remove);
17091762 }
17101763 if (notification.event == ANALYSIS_NOTIFICATION_ERRORS ) {
17111764 var decoded = AnalysisErrorsParams .fromNotification (notification);
1765+ notifications.add ((notification.event, decoded));
17121766 analysisErrorsNotifications.add (decoded);
17131767 filesErrors[decoded.file] = decoded.errors;
17141768 }
@@ -1748,3 +1802,57 @@ class _AnalysisDomainTest extends PubPackageAnalysisServerTest {
17481802 }
17491803 }
17501804}
1805+
1806+ class _NotificationPrinter {
1807+ final _NotificationPrinterConfiguration configuration;
1808+ final ResourceProvider resourceProvider;
1809+ final TreeStringSink sink;
1810+
1811+ _NotificationPrinter ({
1812+ required this .configuration,
1813+ required this .resourceProvider,
1814+ required this .sink,
1815+ });
1816+
1817+ void writeNotifications (List <(String , Object )> notifications) {
1818+ for (final entry in notifications) {
1819+ _writeNotification (entry.$1, entry.$2);
1820+ }
1821+ }
1822+
1823+ void _writelnFile (String path, {String ? name}) {
1824+ sink.writeIndentedLine (() {
1825+ if (name != null ) {
1826+ sink.write ('$name : ' );
1827+ }
1828+ final file = resourceProvider.getFile (path);
1829+ sink.write (file.posixPath);
1830+ });
1831+ }
1832+
1833+ void _writeNotification (String event, Object notification) {
1834+ switch (notification) {
1835+ case AnalysisFlushResultsParams ():
1836+ final files = notification.files.sorted ();
1837+ sink.writeElements ('AnalysisFlush' , files, _writelnFile);
1838+ case AnalysisErrorsParams ():
1839+ sink.writelnWithIndent ('AnalysisErrors' );
1840+ sink.withIndent (() {
1841+ _writelnFile (name: 'file' , notification.file);
1842+ if (configuration.withAnalysisErrorDetails) {
1843+ throw UnimplementedError ();
1844+ } else if (notification.errors.isNotEmpty) {
1845+ sink.writelnWithIndent ('errors: notEmpty' );
1846+ } else {
1847+ sink.writelnWithIndent ('errors: empty' );
1848+ }
1849+ });
1850+ default :
1851+ throw UnimplementedError ('${notification .runtimeType }' );
1852+ }
1853+ }
1854+ }
1855+
1856+ class _NotificationPrinterConfiguration {
1857+ bool withAnalysisErrorDetails = false ;
1858+ }
0 commit comments