flutter/packages/flutter_tools/test/general.shard/commands/analyze_once_test.dart
Siva c15cfdd6af
flutter/engine@ef99738...72341ed (#36885)
flutter/engine@72341ed03 Roll fuchsia/sdk/core/linux-amd64 from gQ3ztEQmdEh3iE6n9EO6iGRdmDSX-edmP5WyE-Ui4BEC to gTG1jp04GzBudVJqRxulXYOEQgbYTUQgnqLDYAq7z3sC (#10115)
flutter/engine@d66031f2a Roll src/third_party/dart 82f657d7cb..0c97c31b6e (7 commits) (#10114)
flutter/engine@f742514a5 Cache font family lookups that fail to obtain a font collection (#10109)
flutter/engine@7c177724c Roll fuchsia/sdk/core/mac-amd64 from A21rwGAUjpjVTX8HgpT9Iyx6J_QZBRDhu-5GAclrf00C to UCAnzi4k9pA30l_iZ2Ru51Tc3Ke6iacIdjFMgVUVdRMC (#10107)
flutter/engine@c3165da09 Roll src/third_party/skia fdf4bfe6d389..b3956dc6ba6a (1 commits) (#10101)
flutter/engine@71702b3f8 Roll fuchsia/sdk/core/linux-amd64 from gPDgr6u-BPJTgV2Nf0tlg9MTY3JwGW0cETtsQcx365AC to gQ3ztEQmdEh3iE6n9EO6iGRdmDSX-edmP5WyE-Ui4BEC (#10103)
flutter/engine@f393da22d [fuchsia] copy over the cmx file (#10087)
flutter/engine@8ebd15d26 Roll src/third_party/skia f564f1515bde..fdf4bfe6d389 (1 commits) (#10100)
flutter/engine@f529a251b Roll fuchsia/sdk/core/mac-amd64 from lvLKs8Q4CKm_XLoZCQ72RO0RHI6yvJXnA9M_M8r4-aAC to A21rwGAUjpjVTX8HgpT9Iyx6J_QZBRDhu-5GAclrf00C (#10099)
flutter/engine@d409df823 Roll src/third_party/dart 9c148623c5..82f657d7cb (25 commits)
flutter/engine@acd139ce6 Roll src/third_party/skia 1cd1ed8976c4..f564f1515bde (1 commits) (#10097)
flutter/engine@f2c9da4a0 Roll src/third_party/skia 3ae30cc2e6e0..1cd1ed8976c4 (1 commits) (#10096)
flutter/engine@d2f0b9ef1 Roll fuchsia/sdk/core/linux-amd64 from MCDItwEzechMpZAiI0QOzuiTtNUGArUa4TprH0Er-7QC to gPDgr6u-BPJTgV2Nf0tlg9MTY3JwGW0cETtsQcx365AC (#10095)
flutter/engine@0f4db494a Roll fuchsia/sdk/core/mac-amd64 from EH_61w2lpSn0UmpJkynWM6tiT0nnKk1GhTRRKK2cGMwC to lvLKs8Q4CKm_XLoZCQ72RO0RHI6yvJXnA9M_M8r4-aAC (#10094)
flutter/engine@298799991 Roll src/third_party/skia 0f9c660aa939..3ae30cc2e6e0 (1 commits) (#10093)
flutter/engine@a4d2d3648 Roll fuchsia/sdk/core/linux-amd64 from tCzkXNr7cb5OAbS5NcJ4F_g0DgVj3w8rfbT14AcaTHoC to MCDItwEzechMpZAiI0QOzuiTtNUGArUa4TprH0Er-7QC (#10090)
flutter/engine@d27a6373d Roll fuchsia/sdk/core/mac-amd64 from xNAaLqZJk8Bkz00BaHGzE8hCpiohggO7KabM3g2wdsQC to EH_61w2lpSn0UmpJkynWM6tiT0nnKk1GhTRRKK2cGMwC (#10089)
flutter/engine@20dc17282 Roll src/third_party/skia d15571af2e1b..0f9c660aa939 (1 commits) (#10088)
flutter/engine@9e7260b9d Roll fuchsia/sdk/core/linux-amd64 from kU0OwJYlceN477ejdh9RXrl7Mp-wUTNvQozlaV96xmQC to tCzkXNr7cb5OAbS5NcJ4F_g0DgVj3w8rfbT14AcaTHoC (#10086)
flutter/engine@0e621d902 [fuchsia] Use the new far package model (#10085)
flutter/engine@bdc713695 [fuchsia] Add sysroot and clang libs to package (#10082)
flutter/engine@72f747ae4 Roll fuchsia/clang/linux-amd64 from apsjZJ9ZIwlS08divc0QwxuNgIFeN4X-52mKR9d8qacC to zHiuOGMDwdWPUkV1B2fHKyRy2fGWGcUgfa2z6dyGAZQC (#10084)
flutter/engine@bfe689ee8 Roll fuchsia/clang/mac-amd64 from USm3Qt9wen4bXoFF0T9Xt8NX-pyEfte2cTYi7geLAhQC to UYD9C8IEkWVi83ef4zwO1Ump2B8cP9Nd5WECjU8l3AUC (#10083)
flutter/engine@cf5d76c17 [fuchsia] Add support for libs in packages (#10081)
flutter/engine@c4c64896a Roll src/third_party/skia 829144cc76fe..d15571af2e1b (2 commits) (#10080)
flutter/engine@25e5d597e Roll fuchsia/sdk/core/linux-amd64 from S_24mhItBb7pfUof8zsJPPSctC7xdlfjDEXEtyO25GYC to kU0OwJYlceN477ejdh9RXrl7Mp-wUTNvQozlaV96xmQC (#10079)
flutter/engine@f7e0614b8 Change ParagraphBuilder to replace the parent style's font families with the child style's font families (#10074)
flutter/engine@eb74f2ce7 One more luci fix (#10078)
flutter/engine@6e732c7f1 Change flutter runner target for LUCI (#10075)
flutter/engine@44ec59b70 Roll src/third_party/dart fedd74669a..9c148623c5 (70 commits) (#10066)
flutter/engine@abf93699f Basic structure for flutter_jit_runner far (#10073)
flutter/engine@3c76b90b2 Track clusters and return cluster boundaries in getGlyphPositionForCoordinates (emoji fix) (#10063)
flutter/engine@e8fb641f6 Enable consts from environment in DDK for flutter_web (#10069)
flutter/engine@bd3870219 [macos] Revert check on FlutterCodecs and refactor message function] (#10009)
flutter/engine@d6e1a93e2 Roll src/third_party/skia e11dfd3da4d7..829144cc76fe (4 commits) (#10072)
flutter/engine@d595af681 Roll fuchsia/sdk/core/linux-amd64 from XqtWTBni4xpYCTr7gqU7rFTuXNY1TZ_zOqBJrZM8c_kC to S_24mhItBb7pfUof8zsJPPSctC7xdlfjDEXEtyO25GYC (#10071)
2019-07-24 22:44:12 -07:00

243 lines
8.4 KiB
Dart

// Copyright 2017 The Chromium Authors. 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 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/analyze.dart';
import 'package:flutter_tools/src/commands/create.dart';
import 'package:flutter_tools/src/runner/flutter_command.dart';
import '../../src/common.dart';
import '../../src/context.dart';
/// Test case timeout for tests involving project analysis.
const Timeout allowForSlowAnalyzeTests = Timeout.factor(5.0);
final Generator _kNoColorTerminalPlatform = () => FakePlatform.fromPlatform(const LocalPlatform())..stdoutSupportsAnsi = false;
final Map<Type, Generator> noColorTerminalOverride = <Type, Generator>{
Platform: _kNoColorTerminalPlatform,
};
void main() {
final String analyzerSeparator = platform.isWindows ? '-' : '';
group('analyze once', () {
Directory tempDir;
String projectPath;
File libMain;
setUpAll(() {
Cache.disableLocking();
tempDir = fs.systemTempDirectory.createTempSync('flutter_analyze_once_test_1.').absolute;
projectPath = fs.path.join(tempDir.path, 'flutter_project');
libMain = fs.file(fs.path.join(projectPath, 'lib', 'main.dart'));
});
tearDownAll(() {
tryToDelete(tempDir);
});
// Create a project to be analyzed
testUsingContext('flutter create', () async {
await runCommand(
command: CreateCommand(),
arguments: <String>['--no-wrap', 'create', projectPath],
statusTextContains: <String>[
'All done!',
'Your application code is in ${fs.path.normalize(fs.path.join(fs.path.relative(projectPath), 'lib', 'main.dart'))}',
],
);
expect(libMain.existsSync(), isTrue);
}, timeout: allowForRemotePubInvocation);
// Analyze in the current directory - no arguments
testUsingContext('working directory', () async {
await runCommand(
command: AnalyzeCommand(workingDirectory: fs.directory(projectPath)),
arguments: <String>['analyze'],
statusTextContains: <String>['No issues found!'],
);
}, timeout: allowForSlowAnalyzeTests);
// Analyze a specific file outside the current directory
testUsingContext('passing one file throws', () async {
await runCommand(
command: AnalyzeCommand(),
arguments: <String>['analyze', libMain.path],
toolExit: true,
exitMessageContains: 'is not a directory',
);
});
// Analyze in the current directory - no arguments
testUsingContext('working directory with errors', () async {
// Break the code to produce the "The parameter 'onPressed' is required" hint
// that is upgraded to a warning in package:flutter/analysis_options_user.yaml
// to assert that we are using the default Flutter analysis options.
// Also insert a statement that should not trigger a lint here
// but will trigger a lint later on when an analysis_options.yaml is added.
String source = await libMain.readAsString();
source = source.replaceFirst(
'onPressed: _incrementCounter,',
'// onPressed: _incrementCounter,',
);
source = source.replaceFirst(
'_counter++;',
'_counter++; throw "an error message";',
);
await libMain.writeAsString(source);
// Analyze in the current directory - no arguments
await runCommand(
command: AnalyzeCommand(workingDirectory: fs.directory(projectPath)),
arguments: <String>['analyze'],
statusTextContains: <String>[
'Analyzing',
'warning $analyzerSeparator The parameter \'onPressed\' is required',
'info $analyzerSeparator The declaration \'_incrementCounter\' isn\'t',
],
exitMessageContains: '2 issues found.',
toolExit: true,
);
}, timeout: allowForSlowAnalyzeTests, overrides: noColorTerminalOverride);
// Analyze in the current directory - no arguments
testUsingContext('working directory with local options', () async {
// Insert an analysis_options.yaml file in the project
// which will trigger a lint for broken code that was inserted earlier
final File optionsFile = fs.file(fs.path.join(projectPath, 'analysis_options.yaml'));
await optionsFile.writeAsString('''
include: package:flutter/analysis_options_user.yaml
linter:
rules:
- only_throw_errors
''');
// Analyze in the current directory - no arguments
await runCommand(
command: AnalyzeCommand(workingDirectory: fs.directory(projectPath)),
arguments: <String>['analyze'],
statusTextContains: <String>[
'Analyzing',
'warning $analyzerSeparator The parameter \'onPressed\' is required',
'info $analyzerSeparator The declaration \'_incrementCounter\' isn\'t',
'info $analyzerSeparator Only throw instances of classes extending either Exception or Error',
],
exitMessageContains: '3 issues found.',
toolExit: true,
);
}, timeout: allowForSlowAnalyzeTests, overrides: noColorTerminalOverride);
testUsingContext('no duplicate issues', () async {
final Directory tempDir = fs.systemTempDirectory.createTempSync('flutter_analyze_once_test_2.').absolute;
try {
final File foo = fs.file(fs.path.join(tempDir.path, 'foo.dart'));
foo.writeAsStringSync('''
import 'bar.dart';
void foo() => bar();
''');
final File bar = fs.file(fs.path.join(tempDir.path, 'bar.dart'));
bar.writeAsStringSync('''
import 'dart:async'; // unused
void bar() {
}
''');
// Analyze in the current directory - no arguments
await runCommand(
command: AnalyzeCommand(workingDirectory: tempDir),
arguments: <String>['analyze'],
statusTextContains: <String>[
'Analyzing',
],
exitMessageContains: '1 issue found.',
toolExit: true,
);
} finally {
tryToDelete(tempDir);
}
}, overrides: noColorTerminalOverride);
testUsingContext('returns no issues when source is error-free', () async {
const String contents = '''
StringBuffer bar = StringBuffer('baz');
''';
final Directory tempDir = fs.systemTempDirectory.createTempSync('flutter_analyze_once_test_3.');
tempDir.childFile('main.dart').writeAsStringSync(contents);
try {
await runCommand(
command: AnalyzeCommand(workingDirectory: fs.directory(tempDir)),
arguments: <String>['analyze'],
statusTextContains: <String>['No issues found!'],
);
} finally {
tryToDelete(tempDir);
}
}, overrides: noColorTerminalOverride);
testUsingContext('returns no issues for todo comments', () async {
const String contents = '''
// TODO(foobar):
StringBuffer bar = StringBuffer('baz');
''';
final Directory tempDir = fs.systemTempDirectory.createTempSync('flutter_analyze_once_test_4.');
tempDir.childFile('main.dart').writeAsStringSync(contents);
try {
await runCommand(
command: AnalyzeCommand(workingDirectory: fs.directory(tempDir)),
arguments: <String>['analyze'],
statusTextContains: <String>['No issues found!'],
);
} finally {
tryToDelete(tempDir);
}
}, overrides: noColorTerminalOverride);
});
}
void assertContains(String text, List<String> patterns) {
if (patterns == null) {
expect(text, isEmpty);
} else {
for (String pattern in patterns) {
expect(text, contains(pattern));
}
}
}
Future<void> runCommand({
FlutterCommand command,
List<String> arguments,
List<String> statusTextContains,
List<String> errorTextContains,
bool toolExit = false,
String exitMessageContains,
}) async {
try {
arguments.insert(0, '--flutter-root=${Cache.flutterRoot}');
await createTestCommandRunner(command).run(arguments);
expect(toolExit, isFalse, reason: 'Expected ToolExit exception');
} on ToolExit catch (e) {
if (!toolExit) {
testLogger.clear();
rethrow;
}
if (exitMessageContains != null) {
expect(e.message, contains(exitMessageContains));
}
}
assertContains(testLogger.statusText, statusTextContains);
assertContains(testLogger.errorText, errorTextContains);
testLogger.clear();
}