[flutter_tools] replace most MockBuildSystem instances with TestBuildSystem (#76821)
This commit is contained in:
parent
cca26d0653
commit
666c950989
@ -144,7 +144,7 @@ List<FlutterCommand> generateCommands({
|
||||
terminal: globals.terminal,
|
||||
artifacts: globals.artifacts,
|
||||
),
|
||||
AssembleCommand(verboseHelp: verboseHelp),
|
||||
AssembleCommand(verboseHelp: verboseHelp, buildSystem: globals.buildSystem),
|
||||
AttachCommand(verboseHelp: verboseHelp),
|
||||
BuildCommand(verboseHelp: verboseHelp),
|
||||
ChannelCommand(verboseHelp: verboseHelp),
|
||||
|
@ -82,7 +82,8 @@ const bool useLegacyNames = true;
|
||||
/// Assemble provides a low level API to interact with the flutter tool build
|
||||
/// system.
|
||||
class AssembleCommand extends FlutterCommand {
|
||||
AssembleCommand({ bool verboseHelp = false }) {
|
||||
AssembleCommand({ bool verboseHelp = false, @required BuildSystem buildSystem })
|
||||
: _buildSystem = buildSystem {
|
||||
argParser.addMultiOption(
|
||||
'define',
|
||||
abbr: 'd',
|
||||
@ -124,6 +125,8 @@ class AssembleCommand extends FlutterCommand {
|
||||
);
|
||||
}
|
||||
|
||||
final BuildSystem _buildSystem;
|
||||
|
||||
@override
|
||||
String get description => 'Assemble and build Flutter resources.';
|
||||
|
||||
@ -229,7 +232,7 @@ class AssembleCommand extends FlutterCommand {
|
||||
Future<FlutterCommandResult> runCommand() async {
|
||||
final List<Target> targets = createTargets();
|
||||
final Target target = targets.length == 1 ? targets.single : CompositeTarget(targets);
|
||||
final BuildResult result = await globals.buildSystem.build(
|
||||
final BuildResult result = await _buildSystem.build(
|
||||
target,
|
||||
createEnvironment(),
|
||||
buildSystemConfig: BuildSystemConfig(
|
||||
|
@ -13,99 +13,107 @@ import 'package:flutter_tools/src/build_system/build_system.dart';
|
||||
import 'package:flutter_tools/src/cache.dart';
|
||||
import 'package:flutter_tools/src/commands/assemble.dart';
|
||||
import 'package:flutter_tools/src/convert.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||
|
||||
import '../../src/common.dart';
|
||||
import '../../src/context.dart';
|
||||
import '../../src/fakes.dart';
|
||||
import '../../src/testbed.dart';
|
||||
|
||||
void main() {
|
||||
Cache.disableLocking();
|
||||
Cache.flutterRoot = '';
|
||||
final StackTrace stackTrace = StackTrace.current;
|
||||
|
||||
final Testbed testbed = Testbed(overrides: <Type, Generator>{
|
||||
BuildSystem: () => MockBuildSystem(),
|
||||
Cache: () => FakeCache(),
|
||||
});
|
||||
|
||||
testbed.test('flutter assemble can run a build', () async {
|
||||
when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
|
||||
.thenAnswer((Invocation invocation) async {
|
||||
return BuildResult(success: true);
|
||||
});
|
||||
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand());
|
||||
testUsingContext('flutter assemble can run a build', () async {
|
||||
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand(
|
||||
buildSystem: TestBuildSystem.all(BuildResult(success: true)),
|
||||
));
|
||||
await commandRunner.run(<String>['assemble', '-o Output', 'debug_macos_bundle_flutter_assets']);
|
||||
|
||||
expect(testLogger.traceText, contains('build succeeded.'));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => FakeCache(),
|
||||
FileSystem: () => MemoryFileSystem.test(),
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
testbed.test('flutter assemble can parse defines whose values contain =', () async {
|
||||
when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
|
||||
.thenAnswer((Invocation invocation) async {
|
||||
expect((invocation.positionalArguments[1] as Environment).defines, containsPair('FooBar', 'fizz=2'));
|
||||
return BuildResult(success: true);
|
||||
});
|
||||
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand());
|
||||
testUsingContext('flutter assemble can parse defines whose values contain =', () async {
|
||||
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand(
|
||||
buildSystem: TestBuildSystem.all(BuildResult(success: true), (Target target, Environment environment) {
|
||||
expect(environment.defines, containsPair('FooBar', 'fizz=2'));
|
||||
})
|
||||
));
|
||||
await commandRunner.run(<String>['assemble', '-o Output', '-dFooBar=fizz=2', 'debug_macos_bundle_flutter_assets']);
|
||||
|
||||
expect(testLogger.traceText, contains('build succeeded.'));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => FakeCache(),
|
||||
FileSystem: () => MemoryFileSystem.test(),
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
testbed.test('flutter assemble can parse inputs', () async {
|
||||
when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
|
||||
.thenAnswer((Invocation invocation) async {
|
||||
expect((invocation.positionalArguments[1] as Environment).inputs, containsPair('Foo', 'Bar.txt'));
|
||||
return BuildResult(success: true);
|
||||
});
|
||||
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand());
|
||||
testUsingContext('flutter assemble can parse inputs', () async {
|
||||
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand(
|
||||
buildSystem: TestBuildSystem.all(BuildResult(success: true), (Target target, Environment environment) {
|
||||
expect(environment.inputs, containsPair('Foo', 'Bar.txt'));
|
||||
})
|
||||
));
|
||||
await commandRunner.run(<String>['assemble', '-o Output', '-iFoo=Bar.txt', 'debug_macos_bundle_flutter_assets']);
|
||||
|
||||
expect(testLogger.traceText, contains('build succeeded.'));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => FakeCache(),
|
||||
FileSystem: () => MemoryFileSystem.test(),
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
testbed.test('flutter assemble throws ToolExit if not provided with output', () async {
|
||||
when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
|
||||
.thenAnswer((Invocation invocation) async {
|
||||
return BuildResult(success: true);
|
||||
});
|
||||
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand());
|
||||
testUsingContext('flutter assemble throws ToolExit if not provided with output', () async {
|
||||
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand(
|
||||
buildSystem: TestBuildSystem.all(BuildResult(success: true)),
|
||||
));
|
||||
|
||||
expect(commandRunner.run(<String>['assemble', 'debug_macos_bundle_flutter_assets']),
|
||||
throwsToolExit());
|
||||
expect(commandRunner.run(<String>['assemble', 'debug_macos_bundle_flutter_assets']), throwsToolExit());
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => FakeCache(),
|
||||
FileSystem: () => MemoryFileSystem.test(),
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
testbed.test('flutter assemble throws ToolExit if called with non-existent rule', () async {
|
||||
when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
|
||||
.thenAnswer((Invocation invocation) async {
|
||||
return BuildResult(success: true);
|
||||
});
|
||||
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand());
|
||||
testUsingContext('flutter assemble throws ToolExit if called with non-existent rule', () async {
|
||||
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand(
|
||||
buildSystem: TestBuildSystem.all(BuildResult(success: true)),
|
||||
));
|
||||
|
||||
expect(commandRunner.run(<String>['assemble', '-o Output', 'undefined']),
|
||||
throwsToolExit());
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => FakeCache(),
|
||||
FileSystem: () => MemoryFileSystem.test(),
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
testbed.test('flutter assemble does not log stack traces during build failure', () async {
|
||||
final StackTrace testStackTrace = StackTrace.current;
|
||||
when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
|
||||
.thenAnswer((Invocation invocation) async {
|
||||
return BuildResult(success: false, exceptions: <String, ExceptionMeasurement>{
|
||||
'hello': ExceptionMeasurement('hello', 'bar', testStackTrace),
|
||||
});
|
||||
});
|
||||
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand());
|
||||
testUsingContext('flutter assemble does not log stack traces during build failure', () async {
|
||||
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand(
|
||||
buildSystem: TestBuildSystem.all(BuildResult(success: false, exceptions: <String, ExceptionMeasurement>{
|
||||
'hello': ExceptionMeasurement('hello', 'bar', stackTrace),
|
||||
}))
|
||||
));
|
||||
|
||||
await expectLater(commandRunner.run(<String>['assemble', '-o Output', 'debug_macos_bundle_flutter_assets']),
|
||||
throwsToolExit());
|
||||
expect(testLogger.errorText, isNot(contains('bar')));
|
||||
expect(testLogger.errorText, isNot(contains(testStackTrace.toString())));
|
||||
expect(testLogger.errorText, isNot(contains(stackTrace.toString())));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => FakeCache(),
|
||||
FileSystem: () => MemoryFileSystem.test(),
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
testbed.test('flutter assemble outputs JSON performance data to provided file', () async {
|
||||
when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
|
||||
.thenAnswer((Invocation invocation) async {
|
||||
return BuildResult(success: true, performance: <String, PerformanceMeasurement>{
|
||||
testUsingContext('flutter assemble outputs JSON performance data to provided file', () async {
|
||||
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand(
|
||||
buildSystem: TestBuildSystem.all(
|
||||
BuildResult(success: true, performance: <String, PerformanceMeasurement>{
|
||||
'hello': PerformanceMeasurement(
|
||||
target: 'hello',
|
||||
analyticsName: 'bar',
|
||||
@ -113,9 +121,9 @@ void main() {
|
||||
skipped: false,
|
||||
succeeded: true,
|
||||
),
|
||||
});
|
||||
});
|
||||
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand());
|
||||
}),
|
||||
),
|
||||
));
|
||||
|
||||
await commandRunner.run(<String>[
|
||||
'assemble',
|
||||
@ -131,34 +139,45 @@ void main() {
|
||||
containsPair('name', 'bar'),
|
||||
)),
|
||||
);
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => FakeCache(),
|
||||
FileSystem: () => MemoryFileSystem.test(),
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
testbed.test('flutter assemble does not inject engine revision with local-engine', () async {
|
||||
Environment environment;
|
||||
when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
|
||||
.thenAnswer((Invocation invocation) async {
|
||||
environment = invocation.positionalArguments[1] as Environment;
|
||||
return BuildResult(success: true);
|
||||
});
|
||||
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand());
|
||||
testUsingContext('flutter assemble does not inject engine revision with local-engine', () async {
|
||||
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand(
|
||||
buildSystem: TestBuildSystem.all(BuildResult(success: true), (Target target, Environment environment) {
|
||||
expect(environment.engineVersion, isNull);
|
||||
})
|
||||
));
|
||||
await commandRunner.run(<String>['assemble', '-o Output', 'debug_macos_bundle_flutter_assets']);
|
||||
|
||||
expect(environment.engineVersion, isNull);
|
||||
}, overrides: <Type, Generator>{
|
||||
Artifacts: () => Artifacts.test(localEngine: 'out/host_release'),
|
||||
Cache: () => FakeCache(),
|
||||
FileSystem: () => MemoryFileSystem.test(),
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
testbed.test('flutter assemble only writes input and output files when the values change', () async {
|
||||
when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
|
||||
.thenAnswer((Invocation invocation) async {
|
||||
return BuildResult(
|
||||
success: true,
|
||||
inputFiles: <File>[globals.fs.file('foo')..createSync()],
|
||||
outputFiles: <File>[globals.fs.file('bar')..createSync()],
|
||||
);
|
||||
});
|
||||
|
||||
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand());
|
||||
testUsingContext('flutter assemble only writes input and output files when the values change', () async {
|
||||
final BuildSystem buildSystem = TestBuildSystem.list(<BuildResult>[
|
||||
BuildResult(
|
||||
success: true,
|
||||
inputFiles: <File>[globals.fs.file('foo')..createSync()],
|
||||
outputFiles: <File>[globals.fs.file('bar')..createSync()],
|
||||
),
|
||||
BuildResult(
|
||||
success: true,
|
||||
inputFiles: <File>[globals.fs.file('foo')..createSync()],
|
||||
outputFiles: <File>[globals.fs.file('bar')..createSync()],
|
||||
),
|
||||
BuildResult(
|
||||
success: true,
|
||||
inputFiles: <File>[globals.fs.file('foo'), globals.fs.file('fizz')..createSync()],
|
||||
outputFiles: <File>[globals.fs.file('bar'), globals.fs.file(globals.fs.path.join('.dart_tool', 'fizz2'))..createSync(recursive: true)],
|
||||
),
|
||||
]);
|
||||
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand(buildSystem: buildSystem));
|
||||
await commandRunner.run(<String>[
|
||||
'assemble',
|
||||
'-o Output',
|
||||
@ -186,13 +205,6 @@ void main() {
|
||||
expect(inputs.lastModifiedSync(), theDistantPast);
|
||||
expect(outputs.lastModifiedSync(), theDistantPast);
|
||||
|
||||
when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
|
||||
.thenAnswer((Invocation invocation) async {
|
||||
return BuildResult(
|
||||
success: true,
|
||||
inputFiles: <File>[globals.fs.file('foo'), globals.fs.file('fizz')..createSync()],
|
||||
outputFiles: <File>[globals.fs.file('bar'), globals.fs.file(globals.fs.path.join('.dart_tool', 'fizz2'))..createSync(recursive: true)]);
|
||||
});
|
||||
await commandRunner.run(<String>[
|
||||
'assemble',
|
||||
'-o Output',
|
||||
@ -204,6 +216,10 @@ void main() {
|
||||
expect(inputs.readAsStringSync(), contains('foo'));
|
||||
expect(inputs.readAsStringSync(), contains('fizz'));
|
||||
expect(inputs.lastModifiedSync(), isNot(theDistantPast));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => FakeCache(),
|
||||
FileSystem: () => MemoryFileSystem.test(),
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
testWithoutContext('writePerformanceData outputs performance data in JSON form', () {
|
||||
@ -236,5 +252,3 @@ void main() {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
class MockBuildSystem extends Mock implements BuildSystem {}
|
||||
|
@ -16,6 +16,7 @@ import 'package:mockito/mockito.dart';
|
||||
|
||||
import '../../src/common.dart';
|
||||
import '../../src/context.dart';
|
||||
import '../../src/fakes.dart';
|
||||
|
||||
void main() {
|
||||
group('build ios-framework', () {
|
||||
@ -70,7 +71,7 @@ void main() {
|
||||
when(mockFlutterVersion.frameworkVersion).thenReturn(frameworkVersion);
|
||||
|
||||
final BuildIOSFrameworkCommand command = BuildIOSFrameworkCommand(
|
||||
buildSystem: MockBuildSystem(),
|
||||
buildSystem: TestBuildSystem.all(BuildResult(success: true)),
|
||||
platform: fakePlatform,
|
||||
flutterVersion: mockFlutterVersion,
|
||||
cache: cache,
|
||||
@ -95,7 +96,7 @@ void main() {
|
||||
when(mockGitTagVersion.commits).thenReturn(2);
|
||||
|
||||
final BuildIOSFrameworkCommand command = BuildIOSFrameworkCommand(
|
||||
buildSystem: MockBuildSystem(),
|
||||
buildSystem: TestBuildSystem.all(BuildResult(success: true)),
|
||||
platform: fakePlatform,
|
||||
flutterVersion: mockFlutterVersion,
|
||||
cache: cache,
|
||||
@ -117,7 +118,7 @@ void main() {
|
||||
when(mockGitTagVersion.commits).thenReturn(0);
|
||||
|
||||
final BuildIOSFrameworkCommand command = BuildIOSFrameworkCommand(
|
||||
buildSystem: MockBuildSystem(),
|
||||
buildSystem: TestBuildSystem.all(BuildResult(success: true)),
|
||||
platform: fakePlatform,
|
||||
flutterVersion: mockFlutterVersion,
|
||||
cache: cache,
|
||||
@ -155,7 +156,7 @@ void main() {
|
||||
|
||||
testUsingContext('created when forced', () async {
|
||||
final BuildIOSFrameworkCommand command = BuildIOSFrameworkCommand(
|
||||
buildSystem: MockBuildSystem(),
|
||||
buildSystem: TestBuildSystem.all(BuildResult(success: true)),
|
||||
platform: fakePlatform,
|
||||
flutterVersion: mockFlutterVersion,
|
||||
cache: cache,
|
||||
@ -178,7 +179,7 @@ void main() {
|
||||
|
||||
testUsingContext('contains license and version', () async {
|
||||
final BuildIOSFrameworkCommand command = BuildIOSFrameworkCommand(
|
||||
buildSystem: MockBuildSystem(),
|
||||
buildSystem: TestBuildSystem.all(BuildResult(success: true)),
|
||||
platform: fakePlatform,
|
||||
flutterVersion: mockFlutterVersion,
|
||||
cache: cache,
|
||||
@ -198,7 +199,7 @@ void main() {
|
||||
|
||||
testUsingContext('debug URL', () async {
|
||||
final BuildIOSFrameworkCommand command = BuildIOSFrameworkCommand(
|
||||
buildSystem: MockBuildSystem(),
|
||||
buildSystem: TestBuildSystem.all(BuildResult(success: true)),
|
||||
platform: fakePlatform,
|
||||
flutterVersion: mockFlutterVersion,
|
||||
cache: cache,
|
||||
@ -216,7 +217,7 @@ void main() {
|
||||
|
||||
testUsingContext('profile URL', () async {
|
||||
final BuildIOSFrameworkCommand command = BuildIOSFrameworkCommand(
|
||||
buildSystem: MockBuildSystem(),
|
||||
buildSystem: TestBuildSystem.all(BuildResult(success: true)),
|
||||
platform: fakePlatform,
|
||||
flutterVersion: mockFlutterVersion,
|
||||
cache: cache,
|
||||
@ -234,7 +235,7 @@ void main() {
|
||||
|
||||
testUsingContext('release URL', () async {
|
||||
final BuildIOSFrameworkCommand command = BuildIOSFrameworkCommand(
|
||||
buildSystem: MockBuildSystem(),
|
||||
buildSystem: TestBuildSystem.all(BuildResult(success: true)),
|
||||
platform: fakePlatform,
|
||||
flutterVersion: mockFlutterVersion,
|
||||
cache: cache,
|
||||
@ -257,4 +258,3 @@ void main() {
|
||||
|
||||
class MockFlutterVersion extends Mock implements FlutterVersion {}
|
||||
class MockGitTagVersion extends Mock implements GitTagVersion {}
|
||||
class MockBuildSystem extends Mock implements BuildSystem {}
|
||||
|
@ -16,10 +16,8 @@ import 'package:flutter_tools/src/commands/build_web.dart';
|
||||
import 'package:flutter_tools/src/runner/flutter_command.dart';
|
||||
import 'package:flutter_tools/src/dart/pub.dart';
|
||||
import 'package:flutter_tools/src/features.dart';
|
||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||
import 'package:flutter_tools/src/project.dart';
|
||||
import 'package:flutter_tools/src/web/compile.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import '../../src/common.dart';
|
||||
import '../../src/context.dart';
|
||||
@ -112,7 +110,7 @@ void main() {
|
||||
FeatureFlags: () => TestFeatureFlags(isWebEnabled: true),
|
||||
Pub: () => FakePub(),
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
BuildSystem: () => MockBuildSystem(),
|
||||
BuildSystem: () => TestBuildSystem.all(BuildResult(success: true)),
|
||||
});
|
||||
|
||||
testUsingContext('hidden if feature flag is not enabled', () async {
|
||||
@ -149,7 +147,7 @@ void main() {
|
||||
FeatureFlags: () => TestFeatureFlags(isWebEnabled: true),
|
||||
Pub: () => FakePub(),
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
BuildSystem: () => MockBuildSystem(),
|
||||
BuildSystem: () => TestBuildSystem.all(BuildResult(success: true)),
|
||||
});
|
||||
}
|
||||
|
||||
@ -201,16 +199,8 @@ class UrlLauncherPlugin {}
|
||||
''');
|
||||
fileSystem.file(fileSystem.path.join('lib', 'main.dart'))
|
||||
.writeAsStringSync('void main() { }');
|
||||
|
||||
// Process calls. We're not testing that these invocations are correct because
|
||||
// that is covered in targets/web_test.dart.
|
||||
when(globals.buildSystem.build(any, any)).thenAnswer((Invocation invocation) async {
|
||||
return BuildResult(success: true);
|
||||
});
|
||||
}
|
||||
|
||||
class MockBuildSystem extends Mock implements BuildSystem {}
|
||||
|
||||
class TestWebBuildCommand extends FlutterCommand {
|
||||
TestWebBuildCommand({ bool verboseHelp = false }) :
|
||||
webCommand = BuildWebCommand(verboseHelp: verboseHelp) {
|
||||
|
@ -21,6 +21,7 @@ import 'package:flutter_tools/src/globals.dart' as globals;
|
||||
|
||||
import '../../src/common.dart';
|
||||
import '../../src/context.dart';
|
||||
import '../../src/fakes.dart';
|
||||
import '../../src/testbed.dart';
|
||||
|
||||
void main() {
|
||||
@ -210,18 +211,6 @@ void main() {
|
||||
globals.fs.file('pubspec.yaml').createSync();
|
||||
globals.fs.file('.packages').createSync();
|
||||
final CommandRunner<void> runner = createTestCommandRunner(BuildBundleCommand());
|
||||
when(globals.buildSystem.build(any, any)).thenAnswer((Invocation invocation) async {
|
||||
final Environment environment = invocation.positionalArguments[1] as Environment;
|
||||
expect(environment.defines, <String, String>{
|
||||
kTargetFile: globals.fs.path.join('lib', 'main.dart'),
|
||||
kBuildMode: 'debug',
|
||||
kTargetPlatform: 'android-arm',
|
||||
kTrackWidgetCreation: 'true',
|
||||
kIconTreeShakerFlag: null,
|
||||
});
|
||||
|
||||
return BuildResult(success: true);
|
||||
});
|
||||
|
||||
await runner.run(<String>[
|
||||
'bundle',
|
||||
@ -231,11 +220,18 @@ void main() {
|
||||
'--track-widget-creation'
|
||||
]);
|
||||
}, overrides: <Type, Generator>{
|
||||
BuildSystem: () => MockBuildSystem(),
|
||||
BuildSystem: () => TestBuildSystem.all(BuildResult(success: true), (Target target, Environment environment) {
|
||||
expect(environment.defines, <String, String>{
|
||||
kTargetFile: globals.fs.path.join('lib', 'main.dart'),
|
||||
kBuildMode: 'debug',
|
||||
kTargetPlatform: 'android-arm',
|
||||
kTrackWidgetCreation: 'true',
|
||||
kIconTreeShakerFlag: null,
|
||||
});
|
||||
}),
|
||||
FileSystem: () => MemoryFileSystem.test(),
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
}
|
||||
|
||||
class MockBundleBuilder extends Mock implements BundleBuilder {}
|
||||
class MockBuildSystem extends Mock implements BuildSystem {}
|
||||
|
@ -4,35 +4,21 @@
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/build_info.dart';
|
||||
import 'package:flutter_tools/src/build_system/build_system.dart';
|
||||
import 'package:flutter_tools/src/bundle.dart';
|
||||
import 'package:flutter_tools/src/project.dart';
|
||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import '../src/common.dart';
|
||||
import '../src/testbed.dart';
|
||||
import '../src/context.dart';
|
||||
import '../src/fakes.dart';
|
||||
|
||||
// Tests for the temporary flutter assemble/bundle shim.
|
||||
void main() {
|
||||
Testbed testbed;
|
||||
|
||||
setUp(() {
|
||||
testbed = Testbed(overrides: <Type, Generator>{
|
||||
BuildSystem: () => MockBuildSystem(),
|
||||
});
|
||||
});
|
||||
|
||||
test('Copies assets to expected directory after building', () => testbed.run(() async {
|
||||
when(globals.buildSystem.build(any, any)).thenAnswer((Invocation invocation) async {
|
||||
final Environment environment = invocation.positionalArguments[1] as Environment;
|
||||
environment.outputDir.childFile('kernel_blob.bin').createSync(recursive: true);
|
||||
environment.outputDir.childFile('isolate_snapshot_data').createSync();
|
||||
environment.outputDir.childFile('vm_snapshot_data').createSync();
|
||||
environment.outputDir.childFile('LICENSE').createSync(recursive: true);
|
||||
return BuildResult(success: true);
|
||||
});
|
||||
testUsingContext('Copies assets to expected directory after building', () async {
|
||||
await buildWithAssemble(
|
||||
buildMode: BuildMode.debug,
|
||||
flutterProject: FlutterProject.fromDirectoryTest(globals.fs.currentDirectory),
|
||||
@ -45,16 +31,18 @@ void main() {
|
||||
expect(globals.fs.file(globals.fs.path.join('example', 'kernel_blob.bin')).existsSync(), true);
|
||||
expect(globals.fs.file(globals.fs.path.join('example', 'LICENSE')).existsSync(), true);
|
||||
expect(globals.fs.file(globals.fs.path.join('example.d')).existsSync(), false);
|
||||
}));
|
||||
|
||||
test('Handles build system failure', () => testbed.run(() {
|
||||
when(globals.buildSystem.build(any, any)).thenAnswer((Invocation _) async {
|
||||
return BuildResult(
|
||||
success: false,
|
||||
exceptions: <String, ExceptionMeasurement>{},
|
||||
);
|
||||
});
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => MemoryFileSystem.test(),
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
BuildSystem: () => TestBuildSystem.all(BuildResult(success: true), (Target target, Environment environment) {
|
||||
environment.outputDir.childFile('kernel_blob.bin').createSync(recursive: true);
|
||||
environment.outputDir.childFile('isolate_snapshot_data').createSync();
|
||||
environment.outputDir.childFile('vm_snapshot_data').createSync();
|
||||
environment.outputDir.childFile('LICENSE').createSync(recursive: true);
|
||||
}),
|
||||
});
|
||||
|
||||
testUsingContext('Handles build system failure', () {
|
||||
expect(() => buildWithAssemble(
|
||||
buildMode: BuildMode.debug,
|
||||
flutterProject: FlutterProject.fromDirectoryTest(globals.fs.currentDirectory),
|
||||
@ -64,7 +52,9 @@ void main() {
|
||||
depfilePath: 'example.d',
|
||||
treeShakeIcons: false,
|
||||
), throwsToolExit());
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => MemoryFileSystem.test(),
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
BuildSystem: () => TestBuildSystem.all(BuildResult(success: false)),
|
||||
});
|
||||
}
|
||||
|
||||
class MockBuildSystem extends Mock implements BuildSystem {}
|
||||
|
@ -11,7 +11,6 @@ import 'package:flutter_tools/src/base/io.dart';
|
||||
import 'package:flutter_tools/src/base/logger.dart';
|
||||
import 'package:flutter_tools/src/base/platform.dart';
|
||||
import 'package:flutter_tools/src/build_info.dart';
|
||||
import 'package:flutter_tools/src/build_system/build_system.dart';
|
||||
import 'package:flutter_tools/src/devfs.dart';
|
||||
import 'package:flutter_tools/src/device.dart';
|
||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||
@ -986,5 +985,3 @@ flutter:
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
class MockBuildSystem extends Mock implements BuildSystem {}
|
||||
|
@ -6,15 +6,14 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:flutter_tools/src/base/common.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/base/logger.dart';
|
||||
import 'package:flutter_tools/src/base/platform.dart';
|
||||
import 'package:flutter_tools/src/base/terminal.dart';
|
||||
import 'package:flutter_tools/src/build_info.dart';
|
||||
import 'package:flutter_tools/src/isolated/devfs_web.dart';
|
||||
import 'package:flutter_tools/src/isolated/resident_web_runner.dart';
|
||||
import 'package:flutter_tools/src/build_system/build_system.dart';
|
||||
import 'package:flutter_tools/src/dart/pub.dart';
|
||||
import 'package:flutter_tools/src/device.dart';
|
||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||
import 'package:flutter_tools/src/project.dart';
|
||||
@ -25,42 +24,22 @@ import 'package:mockito/mockito.dart';
|
||||
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';
|
||||
|
||||
import '../src/common.dart';
|
||||
import '../src/context.dart';
|
||||
import '../src/fakes.dart';
|
||||
import '../src/testbed.dart';
|
||||
|
||||
void main() {
|
||||
Testbed testbed;
|
||||
ResidentWebRunner residentWebRunner;
|
||||
MockFlutterDevice mockFlutterDevice;
|
||||
MockWebDevFS mockWebDevFS;
|
||||
MockBuildSystem mockBuildSystem;
|
||||
|
||||
setUp(() {
|
||||
mockWebDevFS = MockWebDevFS();
|
||||
mockBuildSystem = MockBuildSystem();
|
||||
final MockWebDevice mockWebDevice = MockWebDevice();
|
||||
mockFlutterDevice = MockFlutterDevice();
|
||||
when(mockFlutterDevice.device).thenReturn(mockWebDevice);
|
||||
when(mockFlutterDevice.devFS).thenReturn(mockWebDevFS);
|
||||
when(mockWebDevFS.sources).thenReturn(<Uri>[]);
|
||||
when(mockBuildSystem.build(any, any)).thenAnswer((Invocation invocation) async {
|
||||
return BuildResult(success: true);
|
||||
});
|
||||
testbed = Testbed(
|
||||
setup: () {
|
||||
final FlutterProject project = FlutterProject.fromDirectoryTest(globals.fs.currentDirectory);
|
||||
residentWebRunner = residentWebRunner = DwdsWebRunnerFactory().createWebRunner(
|
||||
mockFlutterDevice,
|
||||
flutterProject: project,
|
||||
debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
|
||||
ipv6: true,
|
||||
stayResident: true,
|
||||
urlTunneller: null,
|
||||
) as ResidentWebRunner;
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => FakePub(),
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
void _setupMocks() {
|
||||
@ -68,9 +47,18 @@ void main() {
|
||||
globals.fs.file('pubspec.yaml').createSync();
|
||||
globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
|
||||
globals.fs.file(globals.fs.path.join('web', 'index.html')).createSync(recursive: true);
|
||||
final FlutterProject project = FlutterProject.fromDirectoryTest(globals.fs.currentDirectory);
|
||||
residentWebRunner = DwdsWebRunnerFactory().createWebRunner(
|
||||
mockFlutterDevice,
|
||||
flutterProject: project,
|
||||
debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
|
||||
ipv6: true,
|
||||
stayResident: true,
|
||||
urlTunneller: null,
|
||||
) as ResidentWebRunner;
|
||||
}
|
||||
|
||||
test('Can successfully run and connect without vmservice', () => testbed.run(() async {
|
||||
testUsingContext('Can successfully run and connect without vmservice', () async {
|
||||
_setupMocks();
|
||||
final FakeStatusLogger fakeStatusLogger = globals.logger as FakeStatusLogger;
|
||||
final MockStatus mockStatus = MockStatus();
|
||||
@ -84,43 +72,37 @@ void main() {
|
||||
expect(debugConnectionInfo.wsUri, null);
|
||||
verify(mockStatus.stop()).called(1);
|
||||
}, overrides: <Type, Generator>{
|
||||
BuildSystem: () => mockBuildSystem,
|
||||
Logger: () => FakeStatusLogger(BufferLogger(
|
||||
terminal: AnsiTerminal(
|
||||
stdio: null,
|
||||
platform: const LocalPlatform(),
|
||||
),
|
||||
outputPreferences: OutputPreferences.test(),
|
||||
)),
|
||||
}));
|
||||
BuildSystem: () => TestBuildSystem.all(BuildResult(success: true)),
|
||||
Logger: () => FakeStatusLogger(BufferLogger.test()),
|
||||
FileSystem: () => MemoryFileSystem.test(),
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/flutter/flutter/issues/60613
|
||||
test('ResidentWebRunner calls appFailedToStart if initial compilation fails', () => testbed.run(() async {
|
||||
testUsingContext('ResidentWebRunner calls appFailedToStart if initial compilation fails', () async {
|
||||
_setupMocks();
|
||||
when(mockBuildSystem.build(any, any)).thenAnswer((Invocation invocation) async {
|
||||
return BuildResult(success: false);
|
||||
});
|
||||
|
||||
expect(() async => await residentWebRunner.run(), throwsToolExit());
|
||||
expect(await residentWebRunner.waitForAppToFinish(), 1);
|
||||
|
||||
}, overrides: <Type, Generator>{
|
||||
BuildSystem: () => mockBuildSystem,
|
||||
}));
|
||||
BuildSystem: () => TestBuildSystem.all(BuildResult(success: false)),
|
||||
FileSystem: () => MemoryFileSystem.test(),
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/flutter/flutter/issues/60613
|
||||
test('ResidentWebRunner calls appFailedToStart if error is thrown during startup', () => testbed.run(() async {
|
||||
testUsingContext('ResidentWebRunner calls appFailedToStart if error is thrown during startup', () async {
|
||||
_setupMocks();
|
||||
when(mockBuildSystem.build(any, any)).thenAnswer((Invocation invocation) async {
|
||||
throw Exception('foo');
|
||||
});
|
||||
|
||||
expect(() async => await residentWebRunner.run(), throwsA(isA<Exception>()));
|
||||
expect(await residentWebRunner.waitForAppToFinish(), 1);
|
||||
|
||||
}, overrides: <Type, Generator>{
|
||||
BuildSystem: () => mockBuildSystem,
|
||||
}));
|
||||
BuildSystem: () => TestBuildSystem.error(Exception('foo')),
|
||||
FileSystem: () => MemoryFileSystem.test(),
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
test('Can full restart after attaching', () => testbed.run(() async {
|
||||
testUsingContext('Can full restart after attaching', () async {
|
||||
_setupMocks();
|
||||
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
||||
unawaited(residentWebRunner.run(
|
||||
@ -131,28 +113,32 @@ void main() {
|
||||
|
||||
expect(result.code, 0);
|
||||
}, overrides: <Type, Generator>{
|
||||
BuildSystem: () => mockBuildSystem,
|
||||
}));
|
||||
BuildSystem: () => TestBuildSystem.all(BuildResult(success: true)),
|
||||
FileSystem: () => MemoryFileSystem.test(),
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
test('Fails on compilation errors in hot restart', () => testbed.run(() async {
|
||||
testUsingContext('Fails on compilation errors in hot restart', () async {
|
||||
_setupMocks();
|
||||
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
|
||||
unawaited(residentWebRunner.run(
|
||||
connectionInfoCompleter: connectionInfoCompleter,
|
||||
));
|
||||
await connectionInfoCompleter.future;
|
||||
when(mockBuildSystem.build(any, any)).thenAnswer((Invocation invocation) async {
|
||||
return BuildResult(success: false);
|
||||
});
|
||||
final OperationResult result = await residentWebRunner.restart(fullRestart: true);
|
||||
|
||||
expect(result.code, 1);
|
||||
expect(result.message, contains('Failed to recompile application.'));
|
||||
}, overrides: <Type, Generator>{
|
||||
BuildSystem: () => mockBuildSystem,
|
||||
}));
|
||||
BuildSystem: () => TestBuildSystem.list(<BuildResult>[
|
||||
BuildResult(success: true),
|
||||
BuildResult(success: false),
|
||||
]),
|
||||
FileSystem: () => MemoryFileSystem.test(),
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
test('Correctly performs a full refresh on attached chrome device.', () => testbed.run(() async {
|
||||
testUsingContext('Correctly performs a full refresh on attached chrome device.', () async {
|
||||
_setupMocks();
|
||||
final MockChromeDevice chromeDevice = MockChromeDevice();
|
||||
final MockChrome chrome = MockChrome();
|
||||
@ -184,9 +170,10 @@ void main() {
|
||||
'ignoreCache': true,
|
||||
})).called(1);
|
||||
}, overrides: <Type, Generator>{
|
||||
BuildSystem: () => mockBuildSystem,
|
||||
}));
|
||||
|
||||
BuildSystem: () => TestBuildSystem.all(BuildResult(success: true)),
|
||||
FileSystem: () => MemoryFileSystem.test(),
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
}
|
||||
|
||||
class MockWebDevFS extends Mock implements WebDevFS {}
|
||||
@ -198,5 +185,4 @@ class MockChrome extends Mock implements Chromium {}
|
||||
class MockChromeConnection extends Mock implements ChromeConnection {}
|
||||
class MockChromeTab extends Mock implements ChromeTab {}
|
||||
class MockWipConnection extends Mock implements WipConnection {}
|
||||
class MockBuildSystem extends Mock implements BuildSystem {}
|
||||
class MockChromiumLauncher extends Mock implements ChromiumLauncher {}
|
||||
|
@ -21,6 +21,7 @@ import 'package:mockito/mockito.dart';
|
||||
|
||||
import '../../src/common.dart';
|
||||
import '../../src/context.dart';
|
||||
import '../../src/fakes.dart';
|
||||
|
||||
void main() {
|
||||
MemoryFileSystem fileSystem;
|
||||
@ -80,26 +81,19 @@ void main() {
|
||||
String mainPath;
|
||||
|
||||
FakeProcessManager fakeProcessManager;
|
||||
MockBuildSystem mockBuildSystem;
|
||||
TestBuildSystem buildSystem;
|
||||
|
||||
final Map<Type, Generator> startOverrides = <Type, Generator>{
|
||||
Platform: () => FakePlatform(operatingSystem: 'linux'),
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => fakeProcessManager,
|
||||
Artifacts: () => Artifacts.test(),
|
||||
BuildSystem: () => mockBuildSystem,
|
||||
BuildSystem: () => buildSystem,
|
||||
};
|
||||
|
||||
setUp(() {
|
||||
mockBuildSystem = MockBuildSystem();
|
||||
buildSystem = TestBuildSystem.all(BuildResult(success: true));
|
||||
fakeProcessManager = FakeProcessManager.list(<FakeCommand>[]);
|
||||
|
||||
when(mockBuildSystem.build(
|
||||
any,
|
||||
any,
|
||||
)).thenAnswer((_) async {
|
||||
return BuildResult(success: true);
|
||||
});
|
||||
device = FlutterTesterDevice('flutter-tester',
|
||||
fileSystem: fileSystem,
|
||||
processManager: fakeProcessManager,
|
||||
@ -194,5 +188,4 @@ FlutterTesterDevices setUpFlutterTesterDevices() {
|
||||
);
|
||||
}
|
||||
|
||||
class MockBuildSystem extends Mock implements BuildSystem {}
|
||||
class MockFlutterVersion extends Mock implements FlutterVersion {}
|
||||
|
@ -12,6 +12,7 @@ import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/base/io.dart';
|
||||
import 'package:flutter_tools/src/base/logger.dart';
|
||||
import 'package:flutter_tools/src/base/os.dart';
|
||||
import 'package:flutter_tools/src/build_system/build_system.dart';
|
||||
import 'package:flutter_tools/src/cache.dart';
|
||||
import 'package:flutter_tools/src/convert.dart';
|
||||
import 'package:flutter_tools/src/dart/pub.dart';
|
||||
@ -443,3 +444,63 @@ class FakePub extends Fake implements Pub {
|
||||
bool checkUpToDate = false,
|
||||
}) async { }
|
||||
}
|
||||
|
||||
class TestBuildSystem implements BuildSystem {
|
||||
/// Create a [BuildSystem] instance that returns the provided results in order.
|
||||
TestBuildSystem.list(this._results, [this._onRun])
|
||||
: _exception = null,
|
||||
_singleResult = null;
|
||||
|
||||
/// Create a [BuildSystem] instance that returns the provided result for every build
|
||||
/// and buildIncremental request.
|
||||
TestBuildSystem.all(this._singleResult, [this._onRun])
|
||||
: _exception = null,
|
||||
_results = <BuildResult>[];
|
||||
|
||||
/// Create a [BuildSystem] instance that always throws the provided error for every build
|
||||
/// and buildIncremental request.
|
||||
TestBuildSystem.error(this._exception)
|
||||
: _singleResult = null,
|
||||
_results = <BuildResult>[],
|
||||
_onRun = null;
|
||||
|
||||
final List<BuildResult> _results;
|
||||
final BuildResult _singleResult;
|
||||
final dynamic _exception;
|
||||
final void Function(Target target, Environment environment) _onRun;
|
||||
int _nextResult = 0;
|
||||
|
||||
@override
|
||||
Future<BuildResult> build(Target target, Environment environment, {BuildSystemConfig buildSystemConfig = const BuildSystemConfig()}) async {
|
||||
if (_onRun != null) {
|
||||
_onRun(target, environment);
|
||||
}
|
||||
if (_exception != null) {
|
||||
throw _exception;
|
||||
}
|
||||
if (_singleResult != null) {
|
||||
return _singleResult;
|
||||
}
|
||||
if (_nextResult >= _results.length) {
|
||||
throw StateError('Unexpected buildIncremental request of ${target.name}');
|
||||
}
|
||||
return _results[_nextResult++];
|
||||
}
|
||||
|
||||
@override
|
||||
Future<BuildResult> buildIncremental(Target target, Environment environment, BuildResult previousBuild) async {
|
||||
if (_onRun != null) {
|
||||
_onRun(target, environment);
|
||||
}
|
||||
if (_exception != null) {
|
||||
throw _exception;
|
||||
}
|
||||
if (_singleResult != null) {
|
||||
return _singleResult;
|
||||
}
|
||||
if (_nextResult >= _results.length) {
|
||||
throw StateError('Unexpected buildIncremental request of ${target.name}');
|
||||
}
|
||||
return _results[_nextResult++];
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user