Migrate `const_finder_test` to use `package:test` (#55132)
... instead of some home-grown framework.
This is the last test in the engine that uses custom command line arguments to start. As of this PR, `dart test` including full debugging in an IDE works across all Dart tooling code.
I tried to make this idiomatic as much as possible without changing the logic.
diff --git a/testing/run_tests.py b/testing/run_tests.py
index f70a72c..c8d68bd 100755
--- a/testing/run_tests.py
+++ b/testing/run_tests.py
@@ -988,14 +988,7 @@
),
(os.path.join('flutter', 'tools', 'build_bucket_golden_scraper'), []),
(os.path.join('flutter', 'tools', 'clang_tidy'), []),
- (
- os.path.join('flutter', 'tools', 'const_finder'),
- [
- os.path.join(build_dir, 'gen', 'frontend_server_aot.dart.snapshot'),
- os.path.join(build_dir, 'flutter_patched_sdk'),
- os.path.join(build_dir, 'dart-sdk', 'lib', 'libraries.json'),
- ],
- ),
+ (os.path.join('flutter', 'tools', 'const_finder'), []),
(os.path.join('flutter', 'tools', 'dir_contents_diff'), []),
(os.path.join('flutter', 'tools', 'engine_tool'), []),
(os.path.join('flutter', 'tools', 'githooks'), []),
diff --git a/tools/const_finder/pubspec.yaml b/tools/const_finder/pubspec.yaml
index 9ce8906..6d27db3 100644
--- a/tools/const_finder/pubspec.yaml
+++ b/tools/const_finder/pubspec.yaml
@@ -18,4 +18,6 @@
dev_dependencies:
collection: any
+ engine_repo_tools: any
path: any
+ test: any
diff --git a/tools/const_finder/test/const_finder_test.dart b/tools/const_finder/test/const_finder_test.dart
index 0731b17..5c5f314 100644
--- a/tools/const_finder/test/const_finder_test.dart
+++ b/tools/const_finder/test/const_finder_test.dart
@@ -2,489 +2,428 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// ignore_for_file: avoid_dynamic_calls
-
import 'dart:convert';
-import 'dart:io';
+import 'dart:io' as io;
-import 'package:collection/collection.dart';
+import 'package:engine_repo_tools/engine_repo_tools.dart';
import 'package:kernel/const_finder.dart';
import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
-void expect<T>(T value, T expected) {
- if (value != expected) {
- stderr.writeln('Expected: $expected');
- stderr.writeln('Actual: $value');
- exitCode = -1;
+void main() {
+ final engine = Engine.findWithin();
+ var buildDir = io.Platform.environment['FLUTTER_BUILD_DIRECTORY'];
+ buildDir ??= engine.latestOutput()?.path.path;
+ if (buildDir == null) {
+ fail('No build directory found. Set FLUTTER_BUILD_DIRECTORY');
}
-}
-void expectInstances(dynamic value, dynamic expected, Compiler compiler) {
- // To ensure we ignore insertion order into maps as well as lists we use
- // DeepCollectionEquality as well as sort the lists.
-
- int compareByStringValue(dynamic a, dynamic b) {
- return a['stringValue'].compareTo(b['stringValue']) as int;
- }
- value['constantInstances'].sort(compareByStringValue);
- expected['constantInstances'].sort(compareByStringValue);
-
- final Equality<Object?> equality;
- if (compiler == Compiler.dart2js) {
- equality = const Dart2JSDeepCollectionEquality();
- } else {
- equality = const DeepCollectionEquality();
- }
- if (!equality.equals(value, expected)) {
- stderr.writeln('Expected: ${jsonEncode(expected)}');
- stderr.writeln('Actual: ${jsonEncode(value)}');
- exitCode = -1;
- }
-}
-
-// This test is assuming the `dart` used to invoke the tests is compatible
-// with the version of package:kernel in //third-party/dart/pkg/kernel
-final String dart = Platform.resolvedExecutable;
-final String dartaotruntime = path.join(path.dirname(Platform.resolvedExecutable), 'dartaotruntime');
-
-void _checkRecursion(String dillPath, Compiler compiler) {
- stdout.writeln('Checking recursive calls.');
- final ConstFinder finder = ConstFinder(
- kernelFilePath: dillPath,
- classLibraryUri: 'package:const_finder_fixtures/box.dart',
- className: 'Box',
+ final fixturesPath = path.join(
+ engine.flutterDir.path,
+ 'tools',
+ 'const_finder',
+ 'test',
+ 'fixtures',
);
- // Will timeout if we did things wrong.
- jsonEncode(finder.findInstances());
-}
+ final String fixturesUrl = io.Platform.isWindows
+ ? '/$fixturesPath'.replaceAll(io.Platform.pathSeparator, '/')
+ : fixturesPath;
-void _checkConsts(String dillPath, Compiler compiler) {
- stdout.writeln('Checking for expected constants.');
- final ConstFinder finder = ConstFinder(
- kernelFilePath: dillPath,
- classLibraryUri: 'package:const_finder_fixtures/target.dart',
- className: 'Target',
+ final frontendServerSnapshot = path.join(
+ buildDir,
+ 'gen',
+ 'frontend_server_aot.dart.snapshot',
);
- final Map<String, Object?> expectation = <String, dynamic>{
- 'constantInstances': <Map<String, dynamic>>[
- <String, dynamic>{'stringValue': '100', 'intValue': 100, 'targetValue': null},
- <String, dynamic>{'stringValue': '102', 'intValue': 102, 'targetValue': null},
- <String, dynamic>{'stringValue': '101', 'intValue': 101},
- <String, dynamic>{'stringValue': '103', 'intValue': 103, 'targetValue': null},
- <String, dynamic>{'stringValue': '105', 'intValue': 105, 'targetValue': null},
- <String, dynamic>{'stringValue': '104', 'intValue': 104},
- <String, dynamic>{'stringValue': '106', 'intValue': 106, 'targetValue': null},
- <String, dynamic>{'stringValue': '108', 'intValue': 108, 'targetValue': null},
- <String, dynamic>{'stringValue': '107', 'intValue': 107},
- <String, dynamic>{'stringValue': '1', 'intValue': 1, 'targetValue': null},
- <String, dynamic>{'stringValue': '4', 'intValue': 4, 'targetValue': null},
- <String, dynamic>{'stringValue': '2', 'intValue': 2},
- <String, dynamic>{'stringValue': '6', 'intValue': 6, 'targetValue': null},
- <String, dynamic>{'stringValue': '8', 'intValue': 8, 'targetValue': null},
- <String, dynamic>{'stringValue': '10', 'intValue': 10, 'targetValue': null},
- <String, dynamic>{'stringValue': '9', 'intValue': 9},
- <String, dynamic>{'stringValue': '7', 'intValue': 7, 'targetValue': null},
- <String, dynamic>{'stringValue': '11', 'intValue': 11, 'targetValue': null},
- <String, dynamic>{'stringValue': '12', 'intValue': 12, 'targetValue': null},
- <String, dynamic>{'stringValue': 'package', 'intValue':-1, 'targetValue': null},
+ final flutterPatchedSdk = path.join(
+ buildDir,
+ 'flutter_patched_sdk',
+ );
+ final librariesDotJson = path.join(
+ flutterPatchedSdk,
+ 'lib',
+ 'libraries.json',
+ );
+ final String packageConfig = path.join(
+ fixturesPath,
+ '.dart_tool',
+ 'package_config.json',
+ );
+
+ final dart = io.Platform.resolvedExecutable;
+ final dartaotruntime = path.join(
+ path.dirname(io.Platform.resolvedExecutable),
+ 'dartaotruntime',
+ );
+
+ void compileAOTDill({
+ required String sourcePath,
+ required String dillPath,
+ }) {
+ final result = io.Process.runSync(
+ dartaotruntime,
+ [
+ frontendServerSnapshot,
+ '--sdk-root=$flutterPatchedSdk',
+ '--target=flutter',
+ '--aot',
+ '--tfa',
+ '--packages=$packageConfig',
+ '--output-dill=$dillPath',
+ sourcePath,
],
- 'nonConstantLocations': <dynamic>[],
- };
- if (compiler == Compiler.aot) {
- expectation['nonConstantLocations'] = <Object?>[];
- } else {
- final String fixturesUrl = Platform.isWindows
- ? '/$fixtures'.replaceAll(Platform.pathSeparator, '/')
- : fixtures;
+ );
+ printOnFailure(result.stdout.toString());
+ printOnFailure(result.stderr.toString());
+ if (result.exitCode != 0) {
+ fail('Failed to compile AOT dill');
+ }
+ addTearDown(() => io.File(dillPath).deleteSync());
+ }
- // Without true tree-shaking, there is a non-const reference in a
- // never-invoked function that will be present in the dill.
- expectation['nonConstantLocations'] = <Object?>[
- <String, dynamic>{
+ void compileDart2JSDill({
+ required String sourcePath,
+ required String dillPath,
+ }) {
+ final result = io.Process.runSync(
+ dart,
+ [
+ 'compile',
+ 'js',
+ '--libraries-spec=$librariesDotJson',
+ '-Ddart.vm.product=true',
+ '-o',
+ dillPath,
+ '--packages=$packageConfig',
+ '--cfe-only',
+ sourcePath,
+ ],
+ );
+ printOnFailure(result.stdout.toString());
+ printOnFailure(result.stderr.toString());
+ if (result.exitCode != 0) {
+ fail('Failed to compile Dart2JS dill');
+ }
+ addTearDown(() => io.File(dillPath).deleteSync());
+ }
+
+ test('box_frontend (aot)', () {
+ final sourcePath = path.join(fixturesPath, 'lib', 'box.dart');
+ final dillPath = path.join(fixturesPath, 'box_frontend.dill');
+ compileAOTDill(sourcePath: sourcePath, dillPath: dillPath);
+ final finder = ConstFinder(
+ kernelFilePath: dillPath,
+ classLibraryUri: 'package:const_finder_fixtures/box.dart',
+ className: 'Box',
+ );
+
+ // Will timeout if we did things wrong.
+ jsonEncode(finder.findInstances());
+ });
+
+ test('box_web (dart2js)', () {
+ final sourcePath = path.join(fixturesPath, 'lib', 'box.dart');
+ final dillPath = path.join(fixturesPath, 'box_web.dill');
+ compileDart2JSDill(sourcePath: sourcePath, dillPath: dillPath);
+ final finder = ConstFinder(
+ kernelFilePath: dillPath,
+ classLibraryUri: 'package:const_finder_fixtures/box.dart',
+ className: 'Box',
+ );
+
+ // Will timeout if we did things wrong.
+ jsonEncode(finder.findInstances());
+ });
+
+ test('consts_frontend (aot)', () {
+ final sourcePath = path.join(fixturesPath, 'lib', 'consts.dart');
+ final dillPath = path.join(fixturesPath, 'consts_frontend.dill');
+ compileAOTDill(sourcePath: sourcePath, dillPath: dillPath);
+
+ final {
+ 'constantInstances': List<Object?> constantInstances,
+ 'nonConstantLocations': List<Object?> nonConstantLocations,
+ } = ConstFinder(
+ kernelFilePath: dillPath,
+ classLibraryUri: 'package:const_finder_fixtures/target.dart',
+ className: 'Target',
+ ).findInstances();
+
+ expect(
+ constantInstances,
+ unorderedEquals([
+ {'stringValue': '100', 'intValue': 100, 'targetValue': null},
+ {'stringValue': '102', 'intValue': 102, 'targetValue': null},
+ {'stringValue': '101', 'intValue': 101},
+ {'stringValue': '103', 'intValue': 103, 'targetValue': null},
+ {'stringValue': '105', 'intValue': 105, 'targetValue': null},
+ {'stringValue': '104', 'intValue': 104},
+ {'stringValue': '106', 'intValue': 106, 'targetValue': null},
+ {'stringValue': '108', 'intValue': 108, 'targetValue': null},
+ {'stringValue': '107', 'intValue': 107},
+ {'stringValue': '1', 'intValue': 1, 'targetValue': null},
+ {'stringValue': '4', 'intValue': 4, 'targetValue': null},
+ {'stringValue': '2', 'intValue': 2},
+ {'stringValue': '6', 'intValue': 6, 'targetValue': null},
+ {'stringValue': '8', 'intValue': 8, 'targetValue': null},
+ {'stringValue': '10', 'intValue': 10, 'targetValue': null},
+ {'stringValue': '9', 'intValue': 9},
+ {'stringValue': '7', 'intValue': 7, 'targetValue': null},
+ {'stringValue': '11', 'intValue': 11, 'targetValue': null},
+ {'stringValue': '12', 'intValue': 12, 'targetValue': null},
+ {'stringValue': 'package', 'intValue': -1, 'targetValue': null},
+ ]),
+ );
+ expect(nonConstantLocations, isEmpty);
+ });
+
+ test('consts_web (dart2js)', () {
+ final sourcePath = path.join(fixturesPath, 'lib', 'consts.dart');
+ final dillPath = path.join(fixturesPath, 'consts_web.dill');
+ compileDart2JSDill(sourcePath: sourcePath, dillPath: dillPath);
+
+ final {
+ 'constantInstances': List<Object?> constantInstances,
+ 'nonConstantLocations': List<Object?> nonConstantLocations,
+ } = ConstFinder(
+ kernelFilePath: dillPath,
+ classLibraryUri: 'package:const_finder_fixtures/target.dart',
+ className: 'Target',
+ ).findInstances();
+
+ expect(
+ constantInstances,
+ unorderedEquals([
+ {'stringValue': '100', 'intValue': 100, 'targetValue': null},
+ {'stringValue': '102', 'intValue': 102, 'targetValue': null},
+ {'stringValue': '101', 'intValue': 101},
+ {'stringValue': '103', 'intValue': 103, 'targetValue': null},
+ {'stringValue': '105', 'intValue': 105, 'targetValue': null},
+ {'stringValue': '104', 'intValue': 104},
+ {'stringValue': '106', 'intValue': 106, 'targetValue': null},
+ {'stringValue': '108', 'intValue': 108, 'targetValue': null},
+ {'stringValue': '107', 'intValue': 107},
+ {'stringValue': '1', 'intValue': 1, 'targetValue': null},
+ {'stringValue': '4', 'intValue': 4, 'targetValue': null},
+ {'stringValue': '2', 'intValue': 2},
+ {'stringValue': '6', 'intValue': 6, 'targetValue': null},
+ {'stringValue': '8', 'intValue': 8, 'targetValue': null},
+ {'stringValue': '10', 'intValue': 10, 'targetValue': null},
+ {'stringValue': '9', 'intValue': 9},
+ {'stringValue': '7', 'intValue': 7, 'targetValue': null},
+ {'stringValue': '11', 'intValue': 11, 'targetValue': null},
+ {'stringValue': '12', 'intValue': 12, 'targetValue': null},
+ {'stringValue': 'package', 'intValue': -1, 'targetValue': null},
+ ]),
+ );
+
+ expect(nonConstantLocations, [
+ {
'file': 'file://$fixturesUrl/pkg/package.dart',
'line': 14,
'column': 25,
+ }
+ ]);
+ });
+
+ test('consts_and_non_frontend (aot)', () {
+ final sourcePath = path.join(fixturesPath, 'lib', 'consts_and_non.dart');
+ final dillPath = path.join(fixturesPath, 'consts_and_non_frontend.dill');
+ compileAOTDill(sourcePath: sourcePath, dillPath: dillPath);
+
+ final {
+ 'constantInstances': List<Object?> constantInstances,
+ 'nonConstantLocations': List<Object?> nonConstantLocations,
+ } = ConstFinder(
+ kernelFilePath: dillPath,
+ classLibraryUri: 'package:const_finder_fixtures/target.dart',
+ className: 'Target',
+ ).findInstances();
+
+ expect(
+ constantInstances,
+ unorderedEquals([
+ {'stringValue': '1', 'intValue': 1, 'targetValue': null},
+ {'stringValue': '4', 'intValue': 4, 'targetValue': null},
+ {'stringValue': '6', 'intValue': 6, 'targetValue': null},
+ {'stringValue': '8', 'intValue': 8, 'targetValue': null},
+ {'stringValue': '10', 'intValue': 10, 'targetValue': null},
+ {'stringValue': '9', 'intValue': 9},
+ {'stringValue': '7', 'intValue': 7, 'targetValue': null},
+ ]),
+ );
+ expect(nonConstantLocations, [
+ {
+ 'file': 'file://$fixturesUrl/lib/consts_and_non.dart',
+ 'line': 14,
+ 'column': 26,
},
- ];
- }
- expectInstances(
- finder.findInstances(),
- expectation,
- compiler,
- );
+ {
+ 'file': 'file://$fixturesUrl/lib/consts_and_non.dart',
+ 'line': 16,
+ 'column': 26,
+ },
+ {
+ 'file': 'file://$fixturesUrl/lib/consts_and_non.dart',
+ 'line': 16,
+ 'column': 41,
+ },
+ {
+ 'file': 'file://$fixturesUrl/lib/consts_and_non.dart',
+ 'line': 17,
+ 'column': 26,
+ },
+ {
+ 'file': 'file://$fixturesUrl/pkg/package.dart',
+ 'line': 14,
+ 'column': 25,
+ }
+ ]);
+ });
- final ConstFinder finder2 = ConstFinder(
- kernelFilePath: dillPath,
- classLibraryUri: 'package:const_finder_fixtures/target.dart',
- className: 'MixedInTarget',
- );
- expectInstances(
- finder2.findInstances(),
- <String, dynamic>{
- 'constantInstances': <Map<String, dynamic>>[
- <String, dynamic>{'val': '13'},
- ],
- 'nonConstantLocations': <dynamic>[],
- },
- compiler,
- );
-}
+ test('consts_and_non_web (dart2js)', () {
+ final sourcePath = path.join(fixturesPath, 'lib', 'consts_and_non.dart');
+ final dillPath = path.join(fixturesPath, 'consts_and_non_web.dill');
+ compileDart2JSDill(sourcePath: sourcePath, dillPath: dillPath);
-void _checkAnnotation(String dillPath, Compiler compiler) {
- stdout.writeln('Checking constant instances in a class annotated with instance of StaticIconProvider are ignored with $compiler');
- final ConstFinder finder = ConstFinder(
- kernelFilePath: dillPath,
- classLibraryUri: 'package:const_finder_fixtures/target.dart',
- className: 'Target',
- annotationClassName: 'StaticIconProvider',
- annotationClassLibraryUri: 'package:const_finder_fixtures/static_icon_provider.dart',
- );
- final Map<String, dynamic> instances = finder.findInstances();
- expectInstances(
- instances,
- <String, dynamic>{
- 'constantInstances': <Map<String, Object?>>[
- <String, Object?>{
+ final {
+ 'constantInstances': List<Object?> constantInstances,
+ 'nonConstantLocations': List<Object?> nonConstantLocations,
+ } = ConstFinder(
+ kernelFilePath: dillPath,
+ classLibraryUri: 'package:const_finder_fixtures/target.dart',
+ className: 'Target',
+ ).findInstances();
+
+ expect(
+ constantInstances,
+ unorderedEquals([
+ {'stringValue': '1', 'intValue': 1, 'targetValue': null},
+ {'stringValue': '4', 'intValue': 4, 'targetValue': null},
+ {'stringValue': '6', 'intValue': 6, 'targetValue': null},
+ {'stringValue': '8', 'intValue': 8, 'targetValue': null},
+ {'stringValue': '10', 'intValue': 10, 'targetValue': null},
+ {'stringValue': '9', 'intValue': 9},
+ {'stringValue': '7', 'intValue': 7, 'targetValue': null},
+ {'stringValue': 'package', 'intValue': -1, 'targetValue': null},
+ ]),
+ );
+
+ expect(nonConstantLocations, [
+ {
+ 'file': 'file://$fixturesUrl/lib/consts_and_non.dart',
+ 'line': 14,
+ 'column': 26,
+ },
+ {
+ 'file': 'file://$fixturesUrl/lib/consts_and_non.dart',
+ 'line': 16,
+ 'column': 26,
+ },
+ {
+ 'file': 'file://$fixturesUrl/lib/consts_and_non.dart',
+ 'line': 16,
+ 'column': 41,
+ },
+ {
+ 'file': 'file://$fixturesUrl/lib/consts_and_non.dart',
+ 'line': 17,
+ 'column': 26,
+ },
+ {
+ 'file': 'file://$fixturesUrl/pkg/package.dart',
+ 'line': 14,
+ 'column': 25,
+ }
+ ]);
+ });
+
+ test('static_icon_provider_frontend (aot)', () {
+ final sourcePath = path.join(
+ fixturesPath,
+ 'lib',
+ 'static_icon_provider.dart',
+ );
+ final dillPath = path.join(
+ fixturesPath,
+ 'static_icon_provider_frontend.dill',
+ );
+ compileAOTDill(sourcePath: sourcePath, dillPath: dillPath);
+ final finder = ConstFinder(
+ kernelFilePath: dillPath,
+ classLibraryUri: 'package:const_finder_fixtures/target.dart',
+ className: 'Target',
+ annotationClassName: 'StaticIconProvider',
+ annotationClassLibraryUri:
+ 'package:const_finder_fixtures/static_icon_provider.dart',
+ );
+
+ final {
+ 'constantInstances': List<Object?> constantInstances,
+ 'nonConstantLocations': List<Object?> nonConstantLocations,
+ } = finder.findInstances();
+ expect(
+ constantInstances,
+ unorderedEquals([
+ {
'stringValue': 'used1',
'intValue': 1,
'targetValue': null,
},
- <String, Object?>{
+ {
'stringValue': 'used2',
'intValue': 2,
'targetValue': null,
},
- ],
- // TODO(fujino): This should have non-constant locations from the use of
- // a tear-off, see https://github.com/flutter/flutter/issues/116797
- 'nonConstantLocations': <Object?>[],
- },
- compiler,
- );
-}
+ ]),
+ );
-void _checkNonConstsFrontend(String dillPath, Compiler compiler) {
- stdout.writeln('Checking for non-constant instances with $compiler');
- final ConstFinder finder = ConstFinder(
- kernelFilePath: dillPath,
- classLibraryUri: 'package:const_finder_fixtures/target.dart',
- className: 'Target',
- );
- final String fixturesUrl = Platform.isWindows
- ? '/$fixtures'.replaceAll(Platform.pathSeparator, '/')
- : fixtures;
+ // TODO(fujino): This should have non-constant locations from the use of
+ // a tear-off, see https://github.com/flutter/flutter/issues/116797
+ expect(nonConstantLocations, isEmpty);
+ });
- expectInstances(
- finder.findInstances(),
- <String, dynamic>{
- 'constantInstances': <dynamic>[
- <String, dynamic>{'stringValue': '1', 'intValue': 1, 'targetValue': null},
- <String, dynamic>{'stringValue': '4', 'intValue': 4, 'targetValue': null},
- <String, dynamic>{'stringValue': '6', 'intValue': 6, 'targetValue': null},
- <String, dynamic>{'stringValue': '8', 'intValue': 8, 'targetValue': null},
- <String, dynamic>{'stringValue': '10', 'intValue': 10, 'targetValue': null},
- <String, dynamic>{'stringValue': '9', 'intValue': 9},
- <String, dynamic>{'stringValue': '7', 'intValue': 7, 'targetValue': null},
- ],
- 'nonConstantLocations': <dynamic>[
- <String, dynamic>{
- 'file': 'file://$fixturesUrl/lib/consts_and_non.dart',
- 'line': 14,
- 'column': 26,
+ test('static_icon_provider_web (dart2js)', () {
+ final sourcePath = path.join(
+ fixturesPath,
+ 'lib',
+ 'static_icon_provider.dart',
+ );
+ final dillPath = path.join(
+ fixturesPath,
+ 'static_icon_provider_web.dill',
+ );
+ compileDart2JSDill(sourcePath: sourcePath, dillPath: dillPath);
+ final finder = ConstFinder(
+ kernelFilePath: dillPath,
+ classLibraryUri: 'package:const_finder_fixtures/target.dart',
+ className: 'Target',
+ annotationClassName: 'StaticIconProvider',
+ annotationClassLibraryUri:
+ 'package:const_finder_fixtures/static_icon_provider.dart',
+ );
+
+ final {
+ 'constantInstances': List<Object?> constantInstances,
+ 'nonConstantLocations': List<Object?> nonConstantLocations,
+ } = finder.findInstances();
+ expect(
+ constantInstances,
+ unorderedEquals([
+ {
+ 'stringValue': 'used1',
+ 'intValue': 1,
+ 'targetValue': null,
},
- <String, dynamic>{
- 'file': 'file://$fixturesUrl/lib/consts_and_non.dart',
- 'line': 16,
- 'column': 26,
+ {
+ 'stringValue': 'used2',
+ 'intValue': 2,
+ 'targetValue': null,
},
- <String, dynamic>{
- 'file': 'file://$fixturesUrl/lib/consts_and_non.dart',
- 'line': 16,
- 'column': 41,
- },
- <String, dynamic>{
- 'file': 'file://$fixturesUrl/lib/consts_and_non.dart',
- 'line': 17,
- 'column': 26,
- },
- <String, dynamic>{
- 'file': 'file://$fixturesUrl/pkg/package.dart',
- 'line': 14,
- 'column': 25,
- }
- ]
- },
- compiler,
- );
-}
+ ]),
+ );
-// Note, since web dills don't have tree shaking, we aren't able to eliminate
-// an additional const versus _checkNonConstFrontend.
-void _checkNonConstsWeb(String dillPath, Compiler compiler) {
- assert(compiler == Compiler.dart2js);
- stdout.writeln('Checking for non-constant instances with $compiler');
- final ConstFinder finder = ConstFinder(
- kernelFilePath: dillPath,
- classLibraryUri: 'package:const_finder_fixtures/target.dart',
- className: 'Target',
- );
-
- final String fixturesUrl = Platform.isWindows
- ? '/$fixtures'.replaceAll(Platform.pathSeparator, '/')
- : fixtures;
- expectInstances(
- finder.findInstances(),
- <String, dynamic>{
- 'constantInstances': <dynamic>[
- <String, dynamic>{'stringValue': '1', 'intValue': 1, 'targetValue': null},
- <String, dynamic>{'stringValue': '4', 'intValue': 4, 'targetValue': null},
- <String, dynamic>{'stringValue': '6', 'intValue': 6, 'targetValue': null},
- <String, dynamic>{'stringValue': '8', 'intValue': 8, 'targetValue': null},
- <String, dynamic>{'stringValue': '10', 'intValue': 10, 'targetValue': null},
- <String, dynamic>{'stringValue': '9', 'intValue': 9},
- <String, dynamic>{'stringValue': '7', 'intValue': 7, 'targetValue': null},
- <String, dynamic>{'stringValue': 'package', 'intValue': -1, 'targetValue': null},
- ],
- 'nonConstantLocations': <dynamic>[
- <String, dynamic>{
- 'file': 'file://$fixturesUrl/lib/consts_and_non.dart',
- 'line': 14,
- 'column': 26,
- },
- <String, dynamic>{
- 'file': 'file://$fixturesUrl/lib/consts_and_non.dart',
- 'line': 16,
- 'column': 26,
- },
- <String, dynamic>{
- 'file': 'file://$fixturesUrl/lib/consts_and_non.dart',
- 'line': 16,
- 'column': 41,
- },
- <String, dynamic>{
- 'file': 'file://$fixturesUrl/lib/consts_and_non.dart',
- 'line': 17,
- 'column': 26,
- },
- <String, dynamic>{
- 'file': 'file://$fixturesUrl/pkg/package.dart',
- 'line': 14,
- 'column': 25,
- }
- ],
- },
- compiler,
- );
-}
-
-void checkProcessResult(ProcessResult result) {
- if (result.exitCode != 0) {
- stdout.writeln(result.stdout);
- stderr.writeln(result.stderr);
- }
- expect(result.exitCode, 0);
-}
-
-final String basePath =
- path.canonicalize(path.join(path.dirname(Platform.script.toFilePath()), '..'));
-final String fixtures = path.join(basePath, 'test', 'fixtures');
-final String packageConfig = path.join(fixtures, '.dart_tool', 'package_config.json');
-
-Future<void> main(List<String> args) async {
- if (args.length != 3) {
- stderr.writeln('The first argument must be the path to the frontend server dill.');
- stderr.writeln('The second argument must be the path to the flutter_patched_sdk');
- stderr.writeln('The third argument must be the path to libraries.json');
- exit(-1);
- }
-
- final String frontendServer = args[0];
- final String sdkRoot = args[1];
- final String librariesSpec = args[2];
-
- final List<_Test> tests = <_Test>[
- _Test(
- name: 'box_frontend',
- dartSource: path.join(fixtures, 'lib', 'box.dart'),
- frontendServer: frontendServer,
- sdkRoot: sdkRoot,
- librariesSpec: librariesSpec,
- verify: _checkRecursion,
- compiler: Compiler.aot,
- ),
- _Test(
- name: 'box_web',
- dartSource: path.join(fixtures, 'lib', 'box.dart'),
- frontendServer: frontendServer,
- sdkRoot: sdkRoot,
- librariesSpec: librariesSpec,
- verify: _checkRecursion,
- compiler: Compiler.dart2js,
- ),
- _Test(
- name: 'consts_frontend',
- dartSource: path.join(fixtures, 'lib', 'consts.dart'),
- frontendServer: frontendServer,
- sdkRoot: sdkRoot,
- librariesSpec: librariesSpec,
- verify: _checkConsts,
- compiler: Compiler.aot,
- ),
- _Test(
- name: 'consts_web',
- dartSource: path.join(fixtures, 'lib', 'consts.dart'),
- frontendServer: frontendServer,
- sdkRoot: sdkRoot,
- librariesSpec: librariesSpec,
- verify: _checkConsts,
- compiler: Compiler.dart2js,
- ),
- _Test(
- name: 'consts_and_non_frontend',
- dartSource: path.join(fixtures, 'lib', 'consts_and_non.dart'),
- frontendServer: frontendServer,
- sdkRoot: sdkRoot,
- librariesSpec: librariesSpec,
- verify: _checkNonConstsFrontend,
- compiler: Compiler.aot,
- ),
- _Test(
- name: 'consts_and_non_web',
- dartSource: path.join(fixtures, 'lib', 'consts_and_non.dart'),
- frontendServer: frontendServer,
- sdkRoot: sdkRoot,
- librariesSpec: librariesSpec,
- verify: _checkNonConstsWeb,
- compiler: Compiler.dart2js,
- ),
- _Test(
- name: 'static_icon_provider_frontend',
- dartSource: path.join(fixtures, 'lib', 'static_icon_provider.dart'),
- frontendServer: frontendServer,
- sdkRoot: sdkRoot,
- librariesSpec: librariesSpec,
- verify: _checkAnnotation,
- compiler: Compiler.aot,
- ),
- _Test(
- name: 'static_icon_provider_web',
- dartSource: path.join(fixtures, 'lib', 'static_icon_provider.dart'),
- frontendServer: frontendServer,
- sdkRoot: sdkRoot,
- librariesSpec: librariesSpec,
- verify: _checkAnnotation,
- compiler: Compiler.dart2js,
- ),
- ];
- try {
- stdout.writeln('Generating kernel fixtures...');
-
- for (final _Test test in tests) {
- test.run();
- }
- } finally {
- try {
- for (final _Test test in tests) {
- test.dispose();
- }
- } finally {
- stdout.writeln('Tests ${exitCode == 0 ? 'succeeded' : 'failed'} - exit code: $exitCode');
- }
- }
-}
-
-enum Compiler {
- // Uses TFA tree-shaking.
- aot,
- // Does not have TFA tree-shaking.
- dart2js,
-}
-
-class _Test {
- _Test({
- required this.name,
- required this.dartSource,
- required this.sdkRoot,
- required this.verify,
- required this.frontendServer,
- required this.librariesSpec,
- required this.compiler,
- }) : dillPath = path.join(fixtures, '$name.dill');
-
- final String name;
- final String dartSource;
- final String sdkRoot;
- final String frontendServer;
- final String librariesSpec;
- final String dillPath;
- void Function(String, Compiler) verify;
- final Compiler compiler;
-
- final List<String> resourcesToDispose = <String>[];
-
- void run() {
- stdout.writeln('Compiling $dartSource to $dillPath with $compiler');
-
- if (compiler == Compiler.aot) {
- _compileAOTDill();
- } else {
- _compileWebDill();
- }
-
- stdout.writeln('Testing $dillPath');
-
- verify(dillPath, compiler);
- }
-
- void dispose() {
- for (final String resource in resourcesToDispose) {
- stdout.writeln('Deleting $resource');
- File(resource).deleteSync();
- }
- }
-
- void _compileAOTDill() {
- checkProcessResult(Process.runSync(dartaotruntime, <String>[
- frontendServer,
- '--sdk-root=$sdkRoot',
- '--target=flutter',
- '--aot',
- '--tfa',
- '--packages=$packageConfig',
- '--output-dill=$dillPath',
- dartSource,
- ]));
-
- resourcesToDispose.add(dillPath);
- }
-
- void _compileWebDill() {
- final ProcessResult result = Process.runSync(dart, <String>[
- 'compile',
- 'js',
- '--libraries-spec=$librariesSpec',
- '-Ddart.vm.product=true',
- '-o',
- dillPath,
- '--packages=$packageConfig',
- '--cfe-only',
- dartSource,
- ]);
- checkProcessResult(result);
-
- resourcesToDispose.add(dillPath);
- }
-}
-
-/// Equality that casts all [num]'s to [double] before comparing.
-class Dart2JSDeepCollectionEquality extends DeepCollectionEquality {
- const Dart2JSDeepCollectionEquality();
-
- @override
- bool equals(Object? e1, Object? e2) {
- if (e1 is num && e2 is num) {
- return e1.toDouble() == e2.toDouble();
- }
- return super.equals(e1, e2);
- }
+ // TODO(fujino): This should have non-constant locations from the use of
+ // a tear-off, see https://github.com/flutter/flutter/issues/116797
+ expect(nonConstantLocations, isEmpty);
+ });
}