Unverified Commit ddb01a0c authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[null-safety] add integration tests for sound null safety modes, add support...

[null-safety] add integration tests for sound null safety modes, add support for sound null safety in dart2js (#67171)

Add integration tests to verify that ddc and dart2js can be built and run in sound mode. Updates dart2js compilation to insert a language version comment into the generated entrypoint if necessary.

dart-lang/sdk#42253
parent 687121d6
...@@ -765,6 +765,16 @@ Future<void> _runWebIntegrationTests() async { ...@@ -765,6 +765,16 @@ Future<void> _runWebIntegrationTests() async {
'--dart-define=test.valueB=Value', '--dart-define=test.valueB=Value',
] ]
); );
await _runWebDebugTest('lib/sound_mode.dart', additionalArguments: <String>[
'--enable-experiment',
'non-nullable',
'--sound-null-safety',
]);
await _runWebReleaseTest('lib/sound_mode.dart', additionalArguments: <String>[
'--enable-experiment',
'non-nullable',
'--sound-null-safety',
]);
} }
Future<void> _runWebStackTraceTest(String buildMode) async { Future<void> _runWebStackTraceTest(String buildMode) async {
......
...@@ -3,3 +3,4 @@ ...@@ -3,3 +3,4 @@
analyzer: analyzer:
exclude: exclude:
- lib/null_safe_main.dart - lib/null_safe_main.dart
- lib/sound_mode.dart
// 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.
// @dart=2.10
import 'dart:html' as html;
// Verify that web applications can be run in sound mode.
void main() {
const isWeak = <int?>[] is List<int>;
String output;
if (isWeak) {
output = '--- TEST FAILED ---';
} else {
output = '--- TEST SUCCEEDED ---';
}
print(output);
html.HttpRequest.request(
'/test-result',
method: 'POST',
sendData: '$output',
);
}
...@@ -12,6 +12,7 @@ import '../../artifacts.dart'; ...@@ -12,6 +12,7 @@ import '../../artifacts.dart';
import '../../base/file_system.dart'; import '../../base/file_system.dart';
import '../../base/io.dart'; import '../../base/io.dart';
import '../../build_info.dart'; import '../../build_info.dart';
import '../../dart/language_version.dart';
import '../../dart/package_map.dart'; import '../../dart/package_map.dart';
import '../../globals.dart' as globals; import '../../globals.dart' as globals;
import '../../project.dart'; import '../../project.dart';
...@@ -94,6 +95,11 @@ class WebEntrypointTarget extends Target { ...@@ -94,6 +95,11 @@ class WebEntrypointTarget extends Target {
environment.fileSystem.file(packageFile), environment.fileSystem.file(packageFile),
logger: environment.logger, logger: environment.logger,
); );
final FlutterProject flutterProject = FlutterProject.current();
final String languageVersion = determineLanguageVersion(
environment.fileSystem.file(targetFile),
packageConfig[flutterProject.manifest.appName],
) ?? '';
// Use the PackageConfig to find the correct package-scheme import path // Use the PackageConfig to find the correct package-scheme import path
// for the user application. If the application has a mix of package-scheme // for the user application. If the application has a mix of package-scheme
...@@ -117,6 +123,8 @@ class WebEntrypointTarget extends Target { ...@@ -117,6 +123,8 @@ class WebEntrypointTarget extends Target {
final String generatedImport = packageConfig.toPackageUri(generatedUri)?.toString() final String generatedImport = packageConfig.toPackageUri(generatedUri)?.toString()
?? generatedUri.toString(); ?? generatedUri.toString();
contents = ''' contents = '''
$languageVersion
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:flutter_web_plugins/flutter_web_plugins.dart'; import 'package:flutter_web_plugins/flutter_web_plugins.dart';
...@@ -134,6 +142,8 @@ Future<void> main() async { ...@@ -134,6 +142,8 @@ Future<void> main() async {
'''; ''';
} else { } else {
contents = ''' contents = '''
$languageVersion
import 'dart:ui' as ui; import 'dart:ui' as ui;
import '$mainImport' as entrypoint; import '$mainImport' as entrypoint;
......
...@@ -72,6 +72,10 @@ void main() { ...@@ -72,6 +72,10 @@ void main() {
}); });
test('WebEntrypointTarget generates an entrypoint with plugins and init platform', () => testbed.run(() async { test('WebEntrypointTarget generates an entrypoint with plugins and init platform', () => testbed.run(() async {
final File mainFile = globals.fs.file(globals.fs.path.join('foo', 'lib', 'main.dart'))
..createSync(recursive: true)
..writeAsStringSync('void main() {}');
environment.defines[kTargetFile] = mainFile.path;
environment.defines[kHasWebPlugins] = 'true'; environment.defines[kHasWebPlugins] = 'true';
environment.defines[kInitializePlatform] = 'true'; environment.defines[kInitializePlatform] = 'true';
await const WebEntrypointTarget().build(environment); await const WebEntrypointTarget().build(environment);
...@@ -144,7 +148,10 @@ void main() { ...@@ -144,7 +148,10 @@ void main() {
})); }));
test('WebEntrypointTarget generates an entrypoint for a file outside of main', () => testbed.run(() async { test('WebEntrypointTarget generates an entrypoint for a file outside of main', () => testbed.run(() async {
environment.defines[kTargetFile] = globals.fs.path.join('other', 'lib', 'main.dart'); final File mainFile = globals.fs.file(globals.fs.path.join('other', 'lib', 'main.dart'))
..createSync(recursive: true)
..writeAsStringSync('void main() {}');
environment.defines[kTargetFile] = mainFile.path;
await const WebEntrypointTarget().build(environment); await const WebEntrypointTarget().build(environment);
final String generated = environment.buildDir.childFile('main.dart').readAsStringSync(); final String generated = environment.buildDir.childFile('main.dart').readAsStringSync();
...@@ -154,7 +161,10 @@ void main() { ...@@ -154,7 +161,10 @@ void main() {
})); }));
test('WebEntrypointTarget generates a plugin registrant for a file outside of main', () => testbed.run(() async { test('WebEntrypointTarget generates a plugin registrant for a file outside of main', () => testbed.run(() async {
environment.defines[kTargetFile] = globals.fs.path.join('other', 'lib', 'main.dart'); final File mainFile = globals.fs.file(globals.fs.path.join('other', 'lib', 'main.dart'))
..createSync(recursive: true)
..writeAsStringSync('void main() {}');
environment.defines[kTargetFile] = mainFile.path;
environment.defines[kHasWebPlugins] = 'true'; environment.defines[kHasWebPlugins] = 'true';
await const WebEntrypointTarget().build(environment); await const WebEntrypointTarget().build(environment);
...@@ -167,6 +177,11 @@ void main() { ...@@ -167,6 +177,11 @@ void main() {
test('WebEntrypointTarget generates an entrypoint with plugins and init platform on windows', () => testbed.run(() async { test('WebEntrypointTarget generates an entrypoint with plugins and init platform on windows', () => testbed.run(() async {
final File mainFile = globals.fs.file(globals.fs.path.join('foo', 'lib', 'main.dart'))
..createSync(recursive: true)
..writeAsStringSync('void main() {}');
environment.defines[kTargetFile] = mainFile.path;
environment.defines[kHasWebPlugins] = 'true'; environment.defines[kHasWebPlugins] = 'true';
environment.defines[kInitializePlatform] = 'true'; environment.defines[kInitializePlatform] = 'true';
await const WebEntrypointTarget().build(environment); await const WebEntrypointTarget().build(environment);
...@@ -190,6 +205,10 @@ void main() { ...@@ -190,6 +205,10 @@ void main() {
})); }));
test('WebEntrypointTarget generates an entrypoint without plugins and init platform', () => testbed.run(() async { test('WebEntrypointTarget generates an entrypoint without plugins and init platform', () => testbed.run(() async {
final File mainFile = globals.fs.file(globals.fs.path.join('foo', 'lib', 'main.dart'))
..createSync(recursive: true)
..writeAsStringSync('void main() {}');
environment.defines[kTargetFile] = mainFile.path;
environment.defines[kHasWebPlugins] = 'false'; environment.defines[kHasWebPlugins] = 'false';
environment.defines[kInitializePlatform] = 'true'; environment.defines[kInitializePlatform] = 'true';
await const WebEntrypointTarget().build(environment); await const WebEntrypointTarget().build(environment);
...@@ -208,6 +227,10 @@ void main() { ...@@ -208,6 +227,10 @@ void main() {
})); }));
test('WebEntrypointTarget generates an entrypoint with plugins and without init platform', () => testbed.run(() async { test('WebEntrypointTarget generates an entrypoint with plugins and without init platform', () => testbed.run(() async {
final File mainFile = globals.fs.file(globals.fs.path.join('foo', 'lib', 'main.dart'))
..createSync(recursive: true)
..writeAsStringSync('void main() {}');
environment.defines[kTargetFile] = mainFile.path;
environment.defines[kHasWebPlugins] = 'true'; environment.defines[kHasWebPlugins] = 'true';
environment.defines[kInitializePlatform] = 'false'; environment.defines[kInitializePlatform] = 'false';
await const WebEntrypointTarget().build(environment); await const WebEntrypointTarget().build(environment);
...@@ -225,7 +248,39 @@ void main() { ...@@ -225,7 +248,39 @@ void main() {
expect(generated, contains('entrypoint.main();')); expect(generated, contains('entrypoint.main();'));
})); }));
test('WebEntrypointTarget generates an entrypoint with a language version', () => testbed.run(() async {
final File mainFile = globals.fs.file(globals.fs.path.join('foo', 'lib', 'main.dart'))
..createSync(recursive: true)
..writeAsStringSync('// @dart=2.8\nvoid main() {}');
environment.defines[kTargetFile] = mainFile.path;
await const WebEntrypointTarget().build(environment);
final String generated = environment.buildDir.childFile('main.dart').readAsStringSync();
// Language version
expect(generated, contains('// @dart=2.8'));
}));
test('WebEntrypointTarget generates an entrypoint with a language version from a package config', () => testbed.run(() async {
final File mainFile = globals.fs.file(globals.fs.path.join('foo', 'lib', 'main.dart'))
..createSync(recursive: true)
..writeAsStringSync('void main() {}');
globals.fs.file(globals.fs.path.join('pubspec.yaml'))
.writeAsStringSync('name: foo\n');
environment.defines[kTargetFile] = mainFile.path;
await const WebEntrypointTarget().build(environment);
final String generated = environment.buildDir.childFile('main.dart').readAsStringSync();
// Language version
expect(generated, contains('// @dart = 2.7'));
}));
test('WebEntrypointTarget generates an entrypoint without plugins and without init platform', () => testbed.run(() async { test('WebEntrypointTarget generates an entrypoint without plugins and without init platform', () => testbed.run(() async {
final File mainFile = globals.fs.file(globals.fs.path.join('foo', 'lib', 'main.dart'))
..createSync(recursive: true)
..writeAsStringSync('void main() {}');
environment.defines[kTargetFile] = mainFile.path;
environment.defines[kHasWebPlugins] = 'false'; environment.defines[kHasWebPlugins] = 'false';
environment.defines[kInitializePlatform] = 'false'; environment.defines[kInitializePlatform] = 'false';
await const WebEntrypointTarget().build(environment); await const WebEntrypointTarget().build(environment);
......
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