2019-11-27 23:04:02 +00:00
|
|
|
// Copyright 2014 The Flutter Authors. All rights reserved.
|
2019-07-11 23:53:17 +00:00
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
|
|
|
import 'package:args/command_runner.dart';
|
2020-04-29 20:04:59 +00:00
|
|
|
import 'package:file/memory.dart';
|
|
|
|
import 'package:file_testing/file_testing.dart';
|
2020-04-20 19:21:20 +00:00
|
|
|
import 'package:flutter_tools/src/artifacts.dart';
|
2019-07-31 23:19:22 +00:00
|
|
|
import 'package:flutter_tools/src/base/file_system.dart';
|
2019-07-11 23:53:17 +00:00
|
|
|
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';
|
2020-04-29 20:04:59 +00:00
|
|
|
import 'package:flutter_tools/src/convert.dart';
|
2019-07-11 23:53:17 +00:00
|
|
|
import 'package:mockito/mockito.dart';
|
2020-01-06 19:04:20 +00:00
|
|
|
import 'package:flutter_tools/src/globals.dart' as globals;
|
2019-07-11 23:53:17 +00:00
|
|
|
|
2019-07-13 18:51:44 +00:00
|
|
|
import '../../src/common.dart';
|
2019-11-24 05:54:43 +00:00
|
|
|
import '../../src/context.dart';
|
2019-07-13 18:51:44 +00:00
|
|
|
import '../../src/testbed.dart';
|
2019-07-11 23:53:17 +00:00
|
|
|
|
|
|
|
void main() {
|
2019-11-08 22:38:44 +00:00
|
|
|
Cache.disableLocking();
|
2020-11-05 23:21:05 +00:00
|
|
|
Cache.flutterRoot = '';
|
|
|
|
|
2019-11-12 23:35:59 +00:00
|
|
|
final Testbed testbed = Testbed(overrides: <Type, Generator>{
|
|
|
|
BuildSystem: () => MockBuildSystem(),
|
|
|
|
Cache: () => FakeCache(),
|
2019-07-25 15:50:03 +00:00
|
|
|
});
|
2019-07-11 23:53:17 +00:00
|
|
|
|
2020-04-08 16:04:32 +00:00
|
|
|
testbed.test('flutter assemble can run a build', () async {
|
2020-03-24 18:23:10 +00:00
|
|
|
when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
|
2019-09-24 19:03:37 +00:00
|
|
|
.thenAnswer((Invocation invocation) async {
|
|
|
|
return BuildResult(success: true);
|
|
|
|
});
|
2019-07-25 15:50:03 +00:00
|
|
|
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand());
|
2019-08-28 05:52:51 +00:00
|
|
|
await commandRunner.run(<String>['assemble', '-o Output', 'debug_macos_bundle_flutter_assets']);
|
2019-12-19 21:44:21 +00:00
|
|
|
|
|
|
|
expect(testLogger.traceText, contains('build succeeded.'));
|
|
|
|
});
|
|
|
|
|
2020-04-08 16:04:32 +00:00
|
|
|
testbed.test('flutter assemble can parse defines whose values contain =', () async {
|
2020-03-24 18:23:10 +00:00
|
|
|
when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
|
2019-12-19 21:44:21 +00:00
|
|
|
.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());
|
|
|
|
await commandRunner.run(<String>['assemble', '-o Output', '-dFooBar=fizz=2', 'debug_macos_bundle_flutter_assets']);
|
2019-07-11 23:53:17 +00:00
|
|
|
|
2019-11-24 05:54:43 +00:00
|
|
|
expect(testLogger.traceText, contains('build succeeded.'));
|
2019-11-12 23:35:59 +00:00
|
|
|
});
|
2019-07-31 23:19:22 +00:00
|
|
|
|
2020-04-08 16:04:32 +00:00
|
|
|
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());
|
|
|
|
await commandRunner.run(<String>['assemble', '-o Output', '-iFoo=Bar.txt', 'debug_macos_bundle_flutter_assets']);
|
|
|
|
|
|
|
|
expect(testLogger.traceText, contains('build succeeded.'));
|
|
|
|
});
|
|
|
|
|
|
|
|
testbed.test('flutter assemble throws ToolExit if not provided with output', () async {
|
2020-03-24 18:23:10 +00:00
|
|
|
when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
|
2019-09-24 19:03:37 +00:00
|
|
|
.thenAnswer((Invocation invocation) async {
|
|
|
|
return BuildResult(success: true);
|
|
|
|
});
|
2019-08-28 05:52:51 +00:00
|
|
|
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand());
|
|
|
|
|
2019-11-18 22:04:11 +00:00
|
|
|
expect(commandRunner.run(<String>['assemble', 'debug_macos_bundle_flutter_assets']),
|
2020-01-27 22:36:02 +00:00
|
|
|
throwsToolExit());
|
2019-11-12 23:35:59 +00:00
|
|
|
});
|
2019-08-28 05:52:51 +00:00
|
|
|
|
2020-04-08 16:04:32 +00:00
|
|
|
testbed.test('flutter assemble throws ToolExit if called with non-existent rule', () async {
|
2020-03-24 18:23:10 +00:00
|
|
|
when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
|
2019-09-24 19:03:37 +00:00
|
|
|
.thenAnswer((Invocation invocation) async {
|
|
|
|
return BuildResult(success: true);
|
|
|
|
});
|
2019-08-22 06:44:39 +00:00
|
|
|
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand());
|
|
|
|
|
2019-11-18 22:04:11 +00:00
|
|
|
expect(commandRunner.run(<String>['assemble', '-o Output', 'undefined']),
|
2020-01-27 22:36:02 +00:00
|
|
|
throwsToolExit());
|
2019-11-18 22:04:11 +00:00
|
|
|
});
|
|
|
|
|
2020-04-08 16:04:32 +00:00
|
|
|
testbed.test('flutter assemble does not log stack traces during build failure', () async {
|
2019-11-18 22:04:11 +00:00
|
|
|
final StackTrace testStackTrace = StackTrace.current;
|
2020-03-24 18:23:10 +00:00
|
|
|
when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
|
2019-11-18 22:04:11 +00:00
|
|
|
.thenAnswer((Invocation invocation) async {
|
|
|
|
return BuildResult(success: false, exceptions: <String, ExceptionMeasurement>{
|
|
|
|
'hello': ExceptionMeasurement('hello', 'bar', testStackTrace),
|
|
|
|
});
|
|
|
|
});
|
|
|
|
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand());
|
|
|
|
|
|
|
|
await expectLater(commandRunner.run(<String>['assemble', '-o Output', 'debug_macos_bundle_flutter_assets']),
|
2020-01-27 22:36:02 +00:00
|
|
|
throwsToolExit());
|
2020-06-03 19:00:03 +00:00
|
|
|
expect(testLogger.errorText, isNot(contains('bar')));
|
2019-11-24 05:54:43 +00:00
|
|
|
expect(testLogger.errorText, isNot(contains(testStackTrace.toString())));
|
2019-11-12 23:35:59 +00:00
|
|
|
});
|
2019-08-28 05:52:51 +00:00
|
|
|
|
2020-04-29 20:04:59 +00:00
|
|
|
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>{
|
|
|
|
'hello': PerformanceMeasurement(
|
|
|
|
target: 'hello',
|
2020-10-12 16:31:02 +00:00
|
|
|
analyticsName: 'bar',
|
2020-04-29 20:04:59 +00:00
|
|
|
elapsedMilliseconds: 123,
|
|
|
|
skipped: false,
|
|
|
|
succeeded: true,
|
|
|
|
),
|
|
|
|
});
|
|
|
|
});
|
|
|
|
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand());
|
|
|
|
|
|
|
|
await commandRunner.run(<String>[
|
|
|
|
'assemble',
|
|
|
|
'-o Output',
|
|
|
|
'--performance-measurement-file=out.json',
|
|
|
|
'debug_macos_bundle_flutter_assets',
|
|
|
|
]);
|
|
|
|
|
|
|
|
expect(globals.fs.file('out.json'), exists);
|
|
|
|
expect(
|
|
|
|
json.decode(globals.fs.file('out.json').readAsStringSync()),
|
|
|
|
containsPair('targets', contains(
|
|
|
|
containsPair('name', 'bar'),
|
|
|
|
)),
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2020-04-20 19:21:20 +00:00
|
|
|
testbed.test('flutter assemble does not inject engine revision with local-engine', () async {
|
|
|
|
Environment environment;
|
|
|
|
when(globals.artifacts.isLocalEngine).thenReturn(true);
|
|
|
|
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());
|
|
|
|
await commandRunner.run(<String>['assemble', '-o Output', 'debug_macos_bundle_flutter_assets']);
|
|
|
|
|
|
|
|
expect(environment.engineVersion, isNull);
|
|
|
|
}, overrides: <Type, Generator>{
|
|
|
|
Artifacts: () => MockLocalEngineArtifacts()
|
|
|
|
});
|
|
|
|
|
2020-04-08 16:04:32 +00:00
|
|
|
testbed.test('flutter assemble only writes input and output files when the values change', () async {
|
2020-03-24 18:23:10 +00:00
|
|
|
when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
|
2019-09-24 19:03:37 +00:00
|
|
|
.thenAnswer((Invocation invocation) async {
|
|
|
|
return BuildResult(
|
|
|
|
success: true,
|
2020-01-06 19:04:20 +00:00
|
|
|
inputFiles: <File>[globals.fs.file('foo')..createSync()],
|
|
|
|
outputFiles: <File>[globals.fs.file('bar')..createSync()],
|
2019-09-24 19:03:37 +00:00
|
|
|
);
|
|
|
|
});
|
2019-07-31 23:19:22 +00:00
|
|
|
|
|
|
|
final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand());
|
2019-11-18 22:04:11 +00:00
|
|
|
await commandRunner.run(<String>[
|
|
|
|
'assemble',
|
|
|
|
'-o Output',
|
|
|
|
'--build-outputs=outputs',
|
|
|
|
'--build-inputs=inputs',
|
|
|
|
'debug_macos_bundle_flutter_assets',
|
|
|
|
]);
|
2019-07-31 23:19:22 +00:00
|
|
|
|
2020-01-06 19:04:20 +00:00
|
|
|
final File inputs = globals.fs.file('inputs');
|
|
|
|
final File outputs = globals.fs.file('outputs');
|
2019-07-31 23:19:22 +00:00
|
|
|
expect(inputs.readAsStringSync(), contains('foo'));
|
|
|
|
expect(outputs.readAsStringSync(), contains('bar'));
|
|
|
|
|
|
|
|
final DateTime theDistantPast = DateTime(1991, 8, 23);
|
|
|
|
inputs.setLastModifiedSync(theDistantPast);
|
|
|
|
outputs.setLastModifiedSync(theDistantPast);
|
2019-11-18 22:04:11 +00:00
|
|
|
await commandRunner.run(<String>[
|
|
|
|
'assemble',
|
|
|
|
'-o Output',
|
|
|
|
'--build-outputs=outputs',
|
|
|
|
'--build-inputs=inputs',
|
|
|
|
'debug_macos_bundle_flutter_assets',
|
|
|
|
]);
|
2019-07-31 23:19:22 +00:00
|
|
|
|
|
|
|
expect(inputs.lastModifiedSync(), theDistantPast);
|
|
|
|
expect(outputs.lastModifiedSync(), theDistantPast);
|
|
|
|
|
2020-03-24 18:23:10 +00:00
|
|
|
when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
|
2019-09-24 19:03:37 +00:00
|
|
|
.thenAnswer((Invocation invocation) async {
|
|
|
|
return BuildResult(
|
|
|
|
success: true,
|
2020-01-06 19:04:20 +00:00
|
|
|
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)]);
|
2019-09-24 19:03:37 +00:00
|
|
|
});
|
2019-11-18 22:04:11 +00:00
|
|
|
await commandRunner.run(<String>[
|
|
|
|
'assemble',
|
|
|
|
'-o Output',
|
|
|
|
'--build-outputs=outputs',
|
|
|
|
'--build-inputs=inputs',
|
|
|
|
'debug_macos_bundle_flutter_assets',
|
|
|
|
]);
|
2019-07-31 23:19:22 +00:00
|
|
|
|
|
|
|
expect(inputs.readAsStringSync(), contains('foo'));
|
|
|
|
expect(inputs.readAsStringSync(), contains('fizz'));
|
|
|
|
expect(inputs.lastModifiedSync(), isNot(theDistantPast));
|
2019-11-12 23:35:59 +00:00
|
|
|
});
|
2020-04-29 20:04:59 +00:00
|
|
|
|
|
|
|
testWithoutContext('writePerformanceData outputs performance data in JSON form', () {
|
|
|
|
final List<PerformanceMeasurement> performanceMeasurement = <PerformanceMeasurement>[
|
|
|
|
PerformanceMeasurement(
|
2020-10-12 16:31:02 +00:00
|
|
|
analyticsName: 'foo',
|
2020-04-29 20:04:59 +00:00
|
|
|
target: 'hidden',
|
|
|
|
skipped: false,
|
|
|
|
succeeded: true,
|
|
|
|
elapsedMilliseconds: 123,
|
|
|
|
)
|
|
|
|
];
|
|
|
|
final FileSystem fileSystem = MemoryFileSystem.test();
|
|
|
|
final File outFile = fileSystem.currentDirectory
|
|
|
|
.childDirectory('foo')
|
|
|
|
.childFile('out.json');
|
|
|
|
|
|
|
|
writePerformanceData(performanceMeasurement, outFile);
|
|
|
|
|
|
|
|
expect(outFile, exists);
|
|
|
|
expect(json.decode(outFile.readAsStringSync()), <String, Object>{
|
|
|
|
'targets': <Object>[
|
|
|
|
<String, Object>{
|
|
|
|
'name': 'foo',
|
|
|
|
'skipped': false,
|
|
|
|
'succeeded': true,
|
|
|
|
'elapsedMilliseconds': 123,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
});
|
|
|
|
});
|
2019-07-11 23:53:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
class MockBuildSystem extends Mock implements BuildSystem {}
|
2020-04-20 19:21:20 +00:00
|
|
|
class MockLocalEngineArtifacts extends Mock implements LocalEngineArtifacts {}
|