[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
This commit is contained in:
parent
687121d6da
commit
ddb01a0c81
@ -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 @@
|
|||||||
analyzer:
|
analyzer:
|
||||||
exclude:
|
exclude:
|
||||||
- lib/null_safe_main.dart
|
- lib/null_safe_main.dart
|
||||||
|
- lib/sound_mode.dart
|
||||||
|
24
dev/integration_tests/web/lib/sound_mode.dart
Normal file
24
dev/integration_tests/web/lib/sound_mode.dart
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// 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';
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
''';
|
''';
|
||||||
} 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() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
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() {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
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() {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
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() {
|
|||||||
|
|
||||||
|
|
||||||
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() {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
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() {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
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() {
|
|||||||
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user