Unverified Commit 385728e7 authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Add tools test for buildWeb compilation (#124179)

Add tools test for buildWeb compilation
parent 6058e959
......@@ -7,6 +7,7 @@ import '../base/file_system.dart';
import '../build_info.dart';
import '../build_system/targets/web.dart';
import '../features.dart';
import '../globals.dart' as globals;
import '../html_utils.dart';
import '../project.dart';
import '../runner/flutter_command.dart'
......@@ -168,7 +169,14 @@ class BuildWebCommand extends BuildSubCommand {
final String? outputDirectoryPath = stringArg('output');
displayNullSafetyMode(buildInfo);
await buildWeb(
final WebBuilder webBuilder = WebBuilder(
logger: globals.logger,
buildSystem: globals.buildSystem,
fileSystem: globals.fs,
flutterVersion: globals.flutterVersion,
usage: globals.flutterUsage,
);
await webBuilder.buildWeb(
flutterProject,
target,
buildInfo,
......
......@@ -314,7 +314,14 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
device!.generator!.accept();
cacheInitialDillCompilation();
} else {
await buildWeb(
final WebBuilder webBuilder = WebBuilder(
logger: _logger,
buildSystem: globals.buildSystem,
fileSystem: _fileSystem,
flutterVersion: globals.flutterVersion,
usage: globals.flutterUsage,
);
await webBuilder.buildWeb(
flutterProject,
target,
debuggingOptions.buildInfo,
......@@ -387,7 +394,14 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
}
} else {
try {
await buildWeb(
final WebBuilder webBuilder = WebBuilder(
logger: _logger,
buildSystem: globals.buildSystem,
fileSystem: _fileSystem,
flutterVersion: globals.flutterVersion,
usage: globals.flutterUsage,
);
await webBuilder.buildWeb(
flutterProject,
target,
debuggingOptions.buildInfo,
......
......@@ -16,96 +16,112 @@ import '../globals.dart' as globals;
import '../platform_plugins.dart';
import '../plugins.dart';
import '../project.dart';
import '../reporting/reporting.dart';
import '../version.dart';
import 'migrations/scrub_generated_plugin_registrant.dart';
export '../build_system/targets/web.dart' show kDart2jsDefaultOptimizationLevel;
Future<void> buildWeb(
FlutterProject flutterProject,
String target,
BuildInfo buildInfo,
bool csp,
String serviceWorkerStrategy,
bool sourceMaps,
bool nativeNullAssertions,
bool isWasm, {
String dart2jsOptimization = kDart2jsDefaultOptimizationLevel,
String? baseHref,
bool dumpInfo = false,
bool noFrequencyBasedMinification = false,
String? outputDirectoryPath,
}) async {
final bool hasWebPlugins = (await findPlugins(flutterProject))
.any((Plugin p) => p.platforms.containsKey(WebPlugin.kConfigKey));
final Directory outputDirectory = outputDirectoryPath == null
? globals.fs.directory(getWebBuildDirectory(isWasm))
: globals.fs.directory(outputDirectoryPath);
outputDirectory.createSync(recursive: true);
class WebBuilder {
WebBuilder({
required Logger logger,
required BuildSystem buildSystem,
required Usage usage,
required FlutterVersion flutterVersion,
required FileSystem fileSystem,
}) : _logger = logger,
_buildSystem = buildSystem,
_flutterUsage = usage,
_flutterVersion = flutterVersion,
_fileSystem = fileSystem;
// The migrators to apply to a Web project.
final List<ProjectMigrator> migrators = <ProjectMigrator>[
ScrubGeneratedPluginRegistrant(flutterProject.web, globals.logger),
];
final Logger _logger;
final BuildSystem _buildSystem;
final Usage _flutterUsage;
final FlutterVersion _flutterVersion;
final FileSystem _fileSystem;
final ProjectMigration migration = ProjectMigration(migrators);
migration.run();
Future<void> buildWeb(
FlutterProject flutterProject,
String target,
BuildInfo buildInfo,
bool csp,
String serviceWorkerStrategy,
bool sourceMaps,
bool nativeNullAssertions,
bool isWasm, {
String dart2jsOptimization = kDart2jsDefaultOptimizationLevel,
String? baseHref,
bool dumpInfo = false,
bool noFrequencyBasedMinification = false,
String? outputDirectoryPath,
}) async {
final bool hasWebPlugins =
(await findPlugins(flutterProject)).any((Plugin p) => p.platforms.containsKey(WebPlugin.kConfigKey));
final Directory outputDirectory = outputDirectoryPath == null
? _fileSystem.directory(getWebBuildDirectory(isWasm))
: _fileSystem.directory(outputDirectoryPath);
outputDirectory.createSync(recursive: true);
final Status status = globals.logger.startProgress('Compiling $target for the Web...');
final Stopwatch sw = Stopwatch()..start();
try {
final BuildResult result = await globals.buildSystem.build(
WebServiceWorker(globals.fs, buildInfo.webRenderer, isWasm: isWasm),
Environment(
projectDir: globals.fs.currentDirectory,
outputDir: outputDirectory,
buildDir: flutterProject.directory
.childDirectory('.dart_tool')
.childDirectory('flutter_build'),
defines: <String, String>{
kTargetFile: target,
kHasWebPlugins: hasWebPlugins.toString(),
kCspMode: csp.toString(),
if (baseHref != null)
kBaseHref : baseHref,
kSourceMapsEnabled: sourceMaps.toString(),
kNativeNullAssertions: nativeNullAssertions.toString(),
kServiceWorkerStrategy: serviceWorkerStrategy,
kDart2jsOptimization: dart2jsOptimization,
kDart2jsDumpInfo: dumpInfo.toString(),
kDart2jsNoFrequencyBasedMinification: noFrequencyBasedMinification.toString(),
...buildInfo.toBuildSystemEnvironment(),
},
artifacts: globals.artifacts!,
fileSystem: globals.fs,
logger: globals.logger,
processManager: globals.processManager,
platform: globals.platform,
usage: globals.flutterUsage,
cacheDir: globals.cache.getRoot(),
engineVersion: globals.artifacts!.isLocalEngine
? null
: globals.flutterVersion.engineRevision,
flutterRootDir: globals.fs.directory(Cache.flutterRoot),
// Web uses a different Dart plugin registry.
// https://github.com/flutter/flutter/issues/80406
generateDartPluginRegistry: false,
));
if (!result.success) {
for (final ExceptionMeasurement measurement in result.exceptions.values) {
globals.printError('Target ${measurement.target} failed: ${measurement.exception}',
stackTrace: measurement.fatal
? measurement.stackTrace
: null,
);
// The migrators to apply to a Web project.
final List<ProjectMigrator> migrators = <ProjectMigrator>[
ScrubGeneratedPluginRegistrant(flutterProject.web, _logger),
];
final ProjectMigration migration = ProjectMigration(migrators);
migration.run();
final Status status = _logger.startProgress('Compiling $target for the Web...');
final Stopwatch sw = Stopwatch()..start();
try {
final BuildResult result = await _buildSystem.build(
WebServiceWorker(_fileSystem, buildInfo.webRenderer, isWasm: isWasm),
Environment(
projectDir: _fileSystem.currentDirectory,
outputDir: outputDirectory,
buildDir: flutterProject.directory.childDirectory('.dart_tool').childDirectory('flutter_build'),
defines: <String, String>{
kTargetFile: target,
kHasWebPlugins: hasWebPlugins.toString(),
kCspMode: csp.toString(),
if (baseHref != null) kBaseHref: baseHref,
kSourceMapsEnabled: sourceMaps.toString(),
kNativeNullAssertions: nativeNullAssertions.toString(),
kServiceWorkerStrategy: serviceWorkerStrategy,
kDart2jsOptimization: dart2jsOptimization,
kDart2jsDumpInfo: dumpInfo.toString(),
kDart2jsNoFrequencyBasedMinification: noFrequencyBasedMinification.toString(),
...buildInfo.toBuildSystemEnvironment(),
},
artifacts: globals.artifacts!,
fileSystem: _fileSystem,
logger: _logger,
processManager: globals.processManager,
platform: globals.platform,
usage: _flutterUsage,
cacheDir: globals.cache.getRoot(),
engineVersion: globals.artifacts!.isLocalEngine ? null : _flutterVersion.engineRevision,
flutterRootDir: _fileSystem.directory(Cache.flutterRoot),
// Web uses a different Dart plugin registry.
// https://github.com/flutter/flutter/issues/80406
generateDartPluginRegistry: false,
));
if (!result.success) {
for (final ExceptionMeasurement measurement in result.exceptions.values) {
_logger.printError(
'Target ${measurement.target} failed: ${measurement.exception}',
stackTrace: measurement.fatal ? measurement.stackTrace : null,
);
}
throwToolExit('Failed to compile application for the Web.');
}
throwToolExit('Failed to compile application for the Web.');
} on Exception catch (err) {
throwToolExit(err.toString());
} finally {
status.stop();
}
} on Exception catch (err) {
throwToolExit(err.toString());
} finally {
status.stop();
_flutterUsage.sendTiming('build', 'dart2js', Duration(milliseconds: sw.elapsedMilliseconds));
}
globals.flutterUsage.sendTiming('build', 'dart2js', Duration(milliseconds: sw.elapsedMilliseconds));
}
/// Web rendering backend mode.
......
// Copyright 2014 The Flutter 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 'package:file/memory.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/build_system/build_system.dart';
import 'package:flutter_tools/src/build_system/targets/web.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:flutter_tools/src/version.dart';
import 'package:flutter_tools/src/web/compile.dart';
import '../../src/common.dart';
import '../../src/context.dart';
import '../../src/fakes.dart';
import '../../src/test_build_system.dart';
void main() {
late MemoryFileSystem fileSystem;
late TestUsage testUsage;
late BufferLogger logger;
late FlutterVersion flutterVersion;
late FlutterProject flutterProject;
setUp(() {
fileSystem = MemoryFileSystem.test();
testUsage = TestUsage();
logger = BufferLogger.test();
flutterVersion = FakeFlutterVersion(frameworkVersion: '1.0.0', engineRevision: '9.8.7');
flutterProject = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory);
fileSystem.file('.packages').createSync();
});
testUsingContext('WebBuilder sets environment on success', () async {
final TestBuildSystem buildSystem =
TestBuildSystem.all(BuildResult(success: true), (Target target, Environment environment) {
final WebServiceWorker webServiceWorker = target as WebServiceWorker;
expect(webServiceWorker.isWasm, isTrue);
expect(webServiceWorker.webRenderer, WebRendererMode.autoDetect);
expect(environment.defines, <String, String>{
'TargetFile': 'target',
'HasWebPlugins': 'false',
'cspMode': 'true',
'SourceMaps': 'true',
'NativeNullAssertions': 'true',
'ServiceWorkerStrategy': 'serviceWorkerStrategy',
'Dart2jsOptimization': 'O4',
'Dart2jsDumpInfo': 'false',
'Dart2jsNoFrequencyBasedMinification': 'false',
'BuildMode': 'debug',
'DartObfuscation': 'false',
'TrackWidgetCreation': 'true',
'TreeShakeIcons': 'false',
});
expect(environment.engineVersion, '9.8.7');
expect(environment.generateDartPluginRegistry, isFalse);
});
final WebBuilder webBuilder = WebBuilder(
logger: logger,
buildSystem: buildSystem,
usage: testUsage,
flutterVersion: flutterVersion,
fileSystem: fileSystem,
);
await webBuilder.buildWeb(
flutterProject,
'target',
BuildInfo.debug,
true,
'serviceWorkerStrategy',
true,
true,
true,
);
expect(logger.statusText, contains('Compiling target for the Web...'));
expect(logger.errorText, isEmpty);
// Runs ScrubGeneratedPluginRegistrant migrator.
expect(logger.traceText, contains('generated_plugin_registrant.dart not found. Skipping.'));
// Sends timing event.
final TestTimingEvent timingEvent = testUsage.timings.single;
expect(timingEvent.category, 'build');
expect(timingEvent.variableName, 'dart2js');
});
testUsingContext('WebBuilder throws tool exit on failure', () async {
final TestBuildSystem buildSystem = TestBuildSystem.all(BuildResult(
success: false,
exceptions: <String, ExceptionMeasurement>{
'hello': ExceptionMeasurement(
'hello',
const FormatException('illegal character in input string'),
StackTrace.current,
),
},
));
final WebBuilder webBuilder = WebBuilder(
logger: logger,
buildSystem: buildSystem,
usage: testUsage,
flutterVersion: flutterVersion,
fileSystem: fileSystem,
);
await expectLater(
() async => webBuilder.buildWeb(
flutterProject,
'target',
BuildInfo.debug,
true,
'serviceWorkerStrategy',
true,
true,
true,
),
throwsToolExit(message: 'Failed to compile application for the Web.'));
expect(logger.errorText, contains('Target hello failed: FormatException: illegal character in input string'));
expect(testUsage.timings, isEmpty);
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment