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'; ...@@ -7,6 +7,7 @@ import '../base/file_system.dart';
import '../build_info.dart'; import '../build_info.dart';
import '../build_system/targets/web.dart'; import '../build_system/targets/web.dart';
import '../features.dart'; import '../features.dart';
import '../globals.dart' as globals;
import '../html_utils.dart'; import '../html_utils.dart';
import '../project.dart'; import '../project.dart';
import '../runner/flutter_command.dart' import '../runner/flutter_command.dart'
...@@ -168,7 +169,14 @@ class BuildWebCommand extends BuildSubCommand { ...@@ -168,7 +169,14 @@ class BuildWebCommand extends BuildSubCommand {
final String? outputDirectoryPath = stringArg('output'); final String? outputDirectoryPath = stringArg('output');
displayNullSafetyMode(buildInfo); 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, flutterProject,
target, target,
buildInfo, buildInfo,
......
...@@ -314,7 +314,14 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive). ...@@ -314,7 +314,14 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
device!.generator!.accept(); device!.generator!.accept();
cacheInitialDillCompilation(); cacheInitialDillCompilation();
} else { } else {
await buildWeb( final WebBuilder webBuilder = WebBuilder(
logger: _logger,
buildSystem: globals.buildSystem,
fileSystem: _fileSystem,
flutterVersion: globals.flutterVersion,
usage: globals.flutterUsage,
);
await webBuilder.buildWeb(
flutterProject, flutterProject,
target, target,
debuggingOptions.buildInfo, debuggingOptions.buildInfo,
...@@ -387,7 +394,14 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive). ...@@ -387,7 +394,14 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
} }
} else { } else {
try { try {
await buildWeb( final WebBuilder webBuilder = WebBuilder(
logger: _logger,
buildSystem: globals.buildSystem,
fileSystem: _fileSystem,
flutterVersion: globals.flutterVersion,
usage: globals.flutterUsage,
);
await webBuilder.buildWeb(
flutterProject, flutterProject,
target, target,
debuggingOptions.buildInfo, debuggingOptions.buildInfo,
......
...@@ -16,96 +16,112 @@ import '../globals.dart' as globals; ...@@ -16,96 +16,112 @@ import '../globals.dart' as globals;
import '../platform_plugins.dart'; import '../platform_plugins.dart';
import '../plugins.dart'; import '../plugins.dart';
import '../project.dart'; import '../project.dart';
import '../reporting/reporting.dart';
import '../version.dart';
import 'migrations/scrub_generated_plugin_registrant.dart'; import 'migrations/scrub_generated_plugin_registrant.dart';
export '../build_system/targets/web.dart' show kDart2jsDefaultOptimizationLevel; export '../build_system/targets/web.dart' show kDart2jsDefaultOptimizationLevel;
Future<void> buildWeb( class WebBuilder {
FlutterProject flutterProject, WebBuilder({
String target, required Logger logger,
BuildInfo buildInfo, required BuildSystem buildSystem,
bool csp, required Usage usage,
String serviceWorkerStrategy, required FlutterVersion flutterVersion,
bool sourceMaps, required FileSystem fileSystem,
bool nativeNullAssertions, }) : _logger = logger,
bool isWasm, { _buildSystem = buildSystem,
String dart2jsOptimization = kDart2jsDefaultOptimizationLevel, _flutterUsage = usage,
String? baseHref, _flutterVersion = flutterVersion,
bool dumpInfo = false, _fileSystem = fileSystem;
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);
// The migrators to apply to a Web project. final Logger _logger;
final List<ProjectMigrator> migrators = <ProjectMigrator>[ final BuildSystem _buildSystem;
ScrubGeneratedPluginRegistrant(flutterProject.web, globals.logger), final Usage _flutterUsage;
]; final FlutterVersion _flutterVersion;
final FileSystem _fileSystem;
final ProjectMigration migration = ProjectMigration(migrators); Future<void> buildWeb(
migration.run(); 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...'); // The migrators to apply to a Web project.
final Stopwatch sw = Stopwatch()..start(); final List<ProjectMigrator> migrators = <ProjectMigrator>[
try { ScrubGeneratedPluginRegistrant(flutterProject.web, _logger),
final BuildResult result = await globals.buildSystem.build( ];
WebServiceWorker(globals.fs, buildInfo.webRenderer, isWasm: isWasm),
Environment( final ProjectMigration migration = ProjectMigration(migrators);
projectDir: globals.fs.currentDirectory, migration.run();
outputDir: outputDirectory,
buildDir: flutterProject.directory final Status status = _logger.startProgress('Compiling $target for the Web...');
.childDirectory('.dart_tool') final Stopwatch sw = Stopwatch()..start();
.childDirectory('flutter_build'), try {
defines: <String, String>{ final BuildResult result = await _buildSystem.build(
kTargetFile: target, WebServiceWorker(_fileSystem, buildInfo.webRenderer, isWasm: isWasm),
kHasWebPlugins: hasWebPlugins.toString(), Environment(
kCspMode: csp.toString(), projectDir: _fileSystem.currentDirectory,
if (baseHref != null) outputDir: outputDirectory,
kBaseHref : baseHref, buildDir: flutterProject.directory.childDirectory('.dart_tool').childDirectory('flutter_build'),
kSourceMapsEnabled: sourceMaps.toString(), defines: <String, String>{
kNativeNullAssertions: nativeNullAssertions.toString(), kTargetFile: target,
kServiceWorkerStrategy: serviceWorkerStrategy, kHasWebPlugins: hasWebPlugins.toString(),
kDart2jsOptimization: dart2jsOptimization, kCspMode: csp.toString(),
kDart2jsDumpInfo: dumpInfo.toString(), if (baseHref != null) kBaseHref: baseHref,
kDart2jsNoFrequencyBasedMinification: noFrequencyBasedMinification.toString(), kSourceMapsEnabled: sourceMaps.toString(),
...buildInfo.toBuildSystemEnvironment(), kNativeNullAssertions: nativeNullAssertions.toString(),
}, kServiceWorkerStrategy: serviceWorkerStrategy,
artifacts: globals.artifacts!, kDart2jsOptimization: dart2jsOptimization,
fileSystem: globals.fs, kDart2jsDumpInfo: dumpInfo.toString(),
logger: globals.logger, kDart2jsNoFrequencyBasedMinification: noFrequencyBasedMinification.toString(),
processManager: globals.processManager, ...buildInfo.toBuildSystemEnvironment(),
platform: globals.platform, },
usage: globals.flutterUsage, artifacts: globals.artifacts!,
cacheDir: globals.cache.getRoot(), fileSystem: _fileSystem,
engineVersion: globals.artifacts!.isLocalEngine logger: _logger,
? null processManager: globals.processManager,
: globals.flutterVersion.engineRevision, platform: globals.platform,
flutterRootDir: globals.fs.directory(Cache.flutterRoot), usage: _flutterUsage,
// Web uses a different Dart plugin registry. cacheDir: globals.cache.getRoot(),
// https://github.com/flutter/flutter/issues/80406 engineVersion: globals.artifacts!.isLocalEngine ? null : _flutterVersion.engineRevision,
generateDartPluginRegistry: false, flutterRootDir: _fileSystem.directory(Cache.flutterRoot),
)); // Web uses a different Dart plugin registry.
if (!result.success) { // https://github.com/flutter/flutter/issues/80406
for (final ExceptionMeasurement measurement in result.exceptions.values) { generateDartPluginRegistry: false,
globals.printError('Target ${measurement.target} failed: ${measurement.exception}', ));
stackTrace: measurement.fatal if (!result.success) {
? measurement.stackTrace for (final ExceptionMeasurement measurement in result.exceptions.values) {
: null, _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) { _flutterUsage.sendTiming('build', 'dart2js', Duration(milliseconds: sw.elapsedMilliseconds));
throwToolExit(err.toString());
} finally {
status.stop();
} }
globals.flutterUsage.sendTiming('build', 'dart2js', Duration(milliseconds: sw.elapsedMilliseconds));
} }
/// Web rendering backend mode. /// 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