Index: pkg/analysis_server/bin/fuzz.dart |
diff --git a/pkg/analysis_server/bin/fuzz.dart b/pkg/analysis_server/bin/fuzz.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..8fc71d997bf51a221d91ea65c09d511fc48c29ec |
--- /dev/null |
+++ b/pkg/analysis_server/bin/fuzz.dart |
@@ -0,0 +1,166 @@ |
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
+// 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 'dart:async'; |
+import 'dart:io'; |
+ |
+import 'package:args/args.dart'; |
+import 'package:matcher/matcher.dart'; |
+import 'package:path/path.dart' as path; |
+ |
+import 'fuzz/server_manager.dart'; |
+ |
+/** |
+ * Start analysis server as a separate process and use the stdio to communicate |
+ * with the server. |
+ */ |
+void main(List<String> args) { |
+ new _FuzzTest().run(args); |
+} |
+ |
+/** |
+ * Instances of [_FuzzTest] launch and test an analysis server. |
+ * You must specify the location of the Dart SDK and the directory |
+ * containing sources to be analyzed. |
+ */ |
+class _FuzzTest { |
+ |
+ //TODO (danrubel) extract common behavior for use in multiple test scenarios |
+ //TODO (danrubel) cleanup test to use async/await for better readability |
+ // VM flag --enable_async |
+ |
+ static const String DART_SDK_OPTION = 'dart-sdk'; |
+ static const String HELP_OPTION = 'help'; |
+ |
+ File serverSnapshot; |
+ Directory appDir; |
+ |
+ /// Parse the arguments and initialize the receiver |
+ /// Return `true` if proper arguments were provided |
+ bool parseArgs(List<String> args) { |
+ ArgParser parser = new ArgParser(); |
+ |
+ void error(String errMsg) { |
+ stderr.writeln(errMsg); |
+ print(''); |
+ _printUsage(parser); |
+ exitCode = 11; |
+ } |
+ |
+ parser.addOption(DART_SDK_OPTION, help: '[sdkPath] path to Dart SDK'); |
+ parser.addFlag( |
+ HELP_OPTION, |
+ help: 'print this help message without starting analysis', |
+ defaultsTo: false, |
+ negatable: false); |
+ |
+ ArgResults results; |
+ try { |
+ results = parser.parse(args); |
+ } on FormatException catch (e) { |
+ error(e.message); |
+ return false; |
+ } |
+ if (results[HELP_OPTION]) { |
+ _printUsage(parser); |
+ return false; |
+ } |
+ String sdkPath = results[DART_SDK_OPTION]; |
+ if (sdkPath is! String) { |
+ error('Missing path to Dart SDK'); |
+ return false; |
+ } |
+ Directory sdkDir = new Directory(sdkPath); |
+ if (!sdkDir.existsSync()) { |
+ error('Specified Dart SDK does not exist: $sdkPath'); |
+ return false; |
+ } |
+ if (results.rest.length == 0) { |
+ error('Expected directory to analyze'); |
+ return false; |
+ } |
+ appDir = new Directory(results.rest[0]); |
+ if (!appDir.existsSync()) { |
+ error('Specified application directory does not exist: $appDir'); |
+ return false; |
+ } |
+ if (results.rest.length > 1) { |
+ error('Unexpected arguments after $appDir'); |
+ return false; |
+ } |
+ serverSnapshot = new File( |
+ path.join(sdkDir.path, 'bin', 'snapshots', 'analysis_server.dart.snapshot')); |
+ if (!serverSnapshot.existsSync()) { |
+ error('Analysis Server snapshot not found: $serverSnapshot'); |
+ return false; |
+ } |
+ return true; |
+ } |
+ |
+ /// Main entry point for launching, testing, and shutting down the server |
+ void run(List<String> args) { |
+ if (!parseArgs(args)) return; |
+ ServerManager.start(serverSnapshot.path).then((ServerManager manager) { |
+ runZoned(() { |
+ test(manager).then(manager.stop).then((_) { |
+ expect(manager.errorOccurred, isFalse); |
+ print('Test completed successfully'); |
+ }); |
+ }, onError: (error, stack) { |
+ stderr.writeln(error); |
+ print(stack); |
+ exitCode = 12; |
+ manager.stop(); |
+ }); |
+ }); |
+ } |
+ |
+ /// Use manager to exercise the analysis server |
+ Future test(ServerManager manager) { |
+ |
+ // perform initial analysis |
+ return manager.analyze(appDir).then((AnalysisResults analysisResults) { |
+ print( |
+ 'Found ${analysisResults.errorCount} errors,' |
+ ' ${analysisResults.warningCount} warnings,' |
+ ' and ${analysisResults.hintCount} hints in ${analysisResults.elapsed}'); |
+ |
+ // edit a method body |
+ return manager.openFileNamed( |
+ 'domain_completion.dart').then((Editor editor) { |
+ return editor.moveAfter('Response processRequest(Request request) {'); |
+ }).then((Editor editor) { |
+ return editor.replace(0, '\nOb'); |
+ }).then((Editor editor) { |
+ |
+ // request code completion and assert results |
+ return editor.getSuggestions().then((List<CompletionResults> list) { |
+ expect(list, isNotNull); |
+ expect(list.length, equals(0)); |
+ list.forEach((CompletionResults results) { |
+ print('${results.elapsed} received ${results.suggestionCount} suggestions'); |
+ }); |
+ return editor; |
+ }); |
+ |
+ }).then((Editor editor) { |
+ print('tests complete'); |
+ }); |
+ }); |
+ } |
+ |
+ void _printAnalysisSummary(AnalysisResults results) { |
+ print( |
+ 'Found ${results.errorCount} errors, ${results.warningCount} warnings,' |
+ ' and ${results.hintCount} hints in $results.elapsed'); |
+ } |
+ |
+ /// Print information about how to use the server. |
+ void _printUsage(ArgParser parser) { |
+ print('Usage: analyzer [flags] <application_directory>'); |
+ print(''); |
+ print('Supported flags are:'); |
+ print(parser.getUsage()); |
+ } |
+} |