This commit is contained in:
parent
07fe017b62
commit
912873baa7
24
.ci.yaml
24
.ci.yaml
@ -2630,6 +2630,30 @@ targets:
|
|||||||
- bin/**
|
- bin/**
|
||||||
- .ci.yaml
|
- .ci.yaml
|
||||||
|
|
||||||
|
- name: Mac entrypoint_dart_registrant
|
||||||
|
recipe: devicelab/devicelab_drone
|
||||||
|
bringup: true
|
||||||
|
timeout: 60
|
||||||
|
properties:
|
||||||
|
caches: >-
|
||||||
|
[
|
||||||
|
{"name":"gradle","path":"gradle"}
|
||||||
|
]
|
||||||
|
dependencies: >-
|
||||||
|
[
|
||||||
|
{"dependency": "xcode"},
|
||||||
|
{"dependency": "gems"}
|
||||||
|
]
|
||||||
|
tags: >
|
||||||
|
["devicelab","hostonly"]
|
||||||
|
task_name: entrypoint_dart_registrant
|
||||||
|
scheduler: luci
|
||||||
|
runIf:
|
||||||
|
- dev/**
|
||||||
|
- packages/flutter_tools/**
|
||||||
|
- bin/**
|
||||||
|
- .ci.yaml
|
||||||
|
|
||||||
- name: Mac framework_tests_libraries
|
- name: Mac framework_tests_libraries
|
||||||
recipe: flutter/flutter_drone
|
recipe: flutter/flutter_drone
|
||||||
timeout: 60
|
timeout: 60
|
||||||
|
@ -203,6 +203,7 @@
|
|||||||
/dev/devicelab/bin/tasks/module_test_ios.dart @jmagman @flutter/tool
|
/dev/devicelab/bin/tasks/module_test_ios.dart @jmagman @flutter/tool
|
||||||
/dev/devicelab/bin/tasks/plugin_lint_mac.dart @stuartmorgan @flutter/plugin
|
/dev/devicelab/bin/tasks/plugin_lint_mac.dart @stuartmorgan @flutter/plugin
|
||||||
/dev/devicelab/bin/tasks/run_release_test_macos.dart @cbracken @flutter/tool
|
/dev/devicelab/bin/tasks/run_release_test_macos.dart @cbracken @flutter/tool
|
||||||
|
/dev/devicelab/bin/tasks/entrypoint_dart_registrant.dart @aaclarke @flutter/plugin
|
||||||
/dev/devicelab/bin/tasks/windows_home_scroll_perf__timeline_summary.dart @jonahwilliams @flutter/engine
|
/dev/devicelab/bin/tasks/windows_home_scroll_perf__timeline_summary.dart @jonahwilliams @flutter/engine
|
||||||
|
|
||||||
## Host only framework tests
|
## Host only framework tests
|
||||||
|
12
dev/devicelab/bin/tasks/entrypoint_dart_registrant.dart
Normal file
12
dev/devicelab/bin/tasks/entrypoint_dart_registrant.dart
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// 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:flutter_devicelab/framework/devices.dart';
|
||||||
|
import 'package:flutter_devicelab/framework/framework.dart';
|
||||||
|
import 'package:flutter_devicelab/tasks/entrypoint_dart_registrant.dart';
|
||||||
|
|
||||||
|
Future<void> main() async {
|
||||||
|
deviceOperatingSystem = DeviceOperatingSystem.android;
|
||||||
|
await task(entrypointDartRegistrant());
|
||||||
|
}
|
106
dev/devicelab/lib/tasks/entrypoint_dart_registrant.dart
Normal file
106
dev/devicelab/lib/tasks/entrypoint_dart_registrant.dart
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
// 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 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io' show Process, ProcessSignal, Directory, File;
|
||||||
|
|
||||||
|
import '../framework/devices.dart';
|
||||||
|
import '../framework/framework.dart';
|
||||||
|
import '../framework/task_result.dart';
|
||||||
|
import '../framework/utils.dart';
|
||||||
|
|
||||||
|
const String _messagePrefix = 'entrypoint:';
|
||||||
|
const String _entrypointName = 'entrypoint';
|
||||||
|
|
||||||
|
const String _dartCode = '''
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
@pragma('vm:entry-point')
|
||||||
|
void main() {
|
||||||
|
print('$_messagePrefix main');
|
||||||
|
runApp(const ColoredBox(color: Color(0xffcc0000)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@pragma('vm:entry-point')
|
||||||
|
void $_entrypointName() {
|
||||||
|
print('$_messagePrefix $_entrypointName');
|
||||||
|
runApp(const ColoredBox(color: Color(0xff00cc00)));
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
const String _kotlinCode = '''
|
||||||
|
package com.example.entrypoint_dart_registrant
|
||||||
|
|
||||||
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
|
|
||||||
|
class MainActivity: FlutterActivity() {
|
||||||
|
override fun getDartEntrypointFunctionName(): String {
|
||||||
|
return "$_entrypointName"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
Future<TaskResult> _runWithTempDir(Directory tempDir) async {
|
||||||
|
const String testDirName = 'entrypoint_dart_registrant';
|
||||||
|
final String testPath = '${tempDir.path}/$testDirName';
|
||||||
|
await inDirectory(tempDir, () async {
|
||||||
|
await flutter('create', options: <String>[
|
||||||
|
'--platforms',
|
||||||
|
'android',
|
||||||
|
testDirName,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
final String mainPath = '${tempDir.path}/$testDirName/lib/main.dart';
|
||||||
|
print(mainPath);
|
||||||
|
File(mainPath).writeAsStringSync(_dartCode);
|
||||||
|
final String activityPath =
|
||||||
|
'${tempDir.path}/$testDirName/android/app/src/main/kotlin/com/example/entrypoint_dart_registrant/MainActivity.kt';
|
||||||
|
File(activityPath).writeAsStringSync(_kotlinCode);
|
||||||
|
final Device device = await devices.workingDevice;
|
||||||
|
await device.unlock();
|
||||||
|
final String entrypoint = await inDirectory(testPath, () async {
|
||||||
|
// The problem only manifested when the dart plugin registrant was used
|
||||||
|
// (which path_provider has).
|
||||||
|
await flutter('pub', options: <String>['add', 'path_provider:2.0.9']);
|
||||||
|
// The problem only manifested on release builds, so we test release.
|
||||||
|
final Process process =
|
||||||
|
await startFlutter('run', options: <String>['--release']);
|
||||||
|
final Completer<String> completer = Completer<String>();
|
||||||
|
final StreamSubscription<String> stdoutSub = process.stdout
|
||||||
|
.transform<String>(const Utf8Decoder())
|
||||||
|
.transform<String>(const LineSplitter())
|
||||||
|
.listen((String line) async {
|
||||||
|
print(line);
|
||||||
|
if (line.contains(_messagePrefix)) {
|
||||||
|
completer.complete(line);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
final String entrypoint = await completer.future;
|
||||||
|
await stdoutSub.cancel();
|
||||||
|
process.stdin.write('q');
|
||||||
|
await process.stdin.flush();
|
||||||
|
process.kill(ProcessSignal.sigint);
|
||||||
|
return entrypoint;
|
||||||
|
});
|
||||||
|
if (entrypoint.contains('$_messagePrefix $_entrypointName')) {
|
||||||
|
return TaskResult.success(null);
|
||||||
|
} else {
|
||||||
|
return TaskResult.failure('expected entrypoint:"$_entrypointName" but found:"$entrypoint"');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Asserts that the custom entrypoint works in the presence of the dart plugin
|
||||||
|
/// registrant.
|
||||||
|
TaskFunction entrypointDartRegistrant() {
|
||||||
|
return () async {
|
||||||
|
final Directory tempDir =
|
||||||
|
Directory.systemTemp.createTempSync('entrypoint_dart_registrant.');
|
||||||
|
try {
|
||||||
|
return await _runWithTempDir(tempDir);
|
||||||
|
} finally {
|
||||||
|
rmTree(tempDir);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
10
packages/flutter/lib/src/dart_plugin_registrant.dart
Normal file
10
packages/flutter/lib/src/dart_plugin_registrant.dart
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
/// The location of the Dart Plugin Registrant. This is used by the engine to
|
||||||
|
/// execute the Dart Plugin Registrant when the Isolate is started or
|
||||||
|
/// DartPluginRegistrant.ensureInitialized() is called from a background
|
||||||
|
/// Isolate.
|
||||||
|
@pragma('vm:entry-point')
|
||||||
|
const String dartPluginRegistrantLibrary = String.fromEnvironment('flutter.dart_plugin_registrant');
|
@ -12,7 +12,7 @@ import '../../flutter_plugins.dart';
|
|||||||
import '../../project.dart';
|
import '../../project.dart';
|
||||||
import '../build_system.dart';
|
import '../build_system.dart';
|
||||||
|
|
||||||
/// Generates a new `./dart_tool/flutter_build/generated_main.dart`
|
/// Generates a new `./dart_tool/flutter_build/dart_plugin_registrant.dart`
|
||||||
/// based on the current dependency map in `pubspec.lock`.
|
/// based on the current dependency map in `pubspec.lock`.
|
||||||
class DartPluginRegistrantTarget extends Target {
|
class DartPluginRegistrantTarget extends Target {
|
||||||
/// Construct a [DartPluginRegistrantTarget].
|
/// Construct a [DartPluginRegistrantTarget].
|
||||||
@ -86,7 +86,7 @@ class DartPluginRegistrantTarget extends Target {
|
|||||||
@override
|
@override
|
||||||
List<Source> get outputs => <Source>[
|
List<Source> get outputs => <Source>[
|
||||||
const Source.pattern(
|
const Source.pattern(
|
||||||
'{PROJECT_DIR}/.dart_tool/flutter_build/generated_main.dart',
|
'{PROJECT_DIR}/.dart_tool/flutter_build/dart_plugin_registrant.dart',
|
||||||
optional: true,
|
optional: true,
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
@ -261,14 +261,12 @@ class KernelCompiler {
|
|||||||
if (outputFilePath != null && !_fileSystem.isFileSync(outputFilePath)) {
|
if (outputFilePath != null && !_fileSystem.isFileSync(outputFilePath)) {
|
||||||
_fileSystem.file(outputFilePath).createSync(recursive: true);
|
_fileSystem.file(outputFilePath).createSync(recursive: true);
|
||||||
}
|
}
|
||||||
if (buildDir != null && checkDartPluginRegistry) {
|
|
||||||
// Check if there's a Dart plugin registrant.
|
// Check if there's a Dart plugin registrant.
|
||||||
// This is contained in the file `generated_main.dart` under `.dart_tools/flutter_build/`.
|
// This is contained in the file `dart_plugin_registrant.dart` under `.dart_tools/flutter_build/`.
|
||||||
final File newMainDart = buildDir.parent.childFile('generated_main.dart');
|
final File? dartPluginRegistrant = checkDartPluginRegistry
|
||||||
if (newMainDart.existsSync()) {
|
? buildDir?.parent.childFile('dart_plugin_registrant.dart')
|
||||||
mainUri = newMainDart.path;
|
: null;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<String> command = <String>[
|
final List<String> command = <String>[
|
||||||
engineDartPath,
|
engineDartPath,
|
||||||
@ -316,6 +314,13 @@ class KernelCompiler {
|
|||||||
'--platform',
|
'--platform',
|
||||||
platformDill,
|
platformDill,
|
||||||
],
|
],
|
||||||
|
if (dartPluginRegistrant != null && dartPluginRegistrant.existsSync()) ...<String>[
|
||||||
|
'--source',
|
||||||
|
dartPluginRegistrant.path,
|
||||||
|
'--source',
|
||||||
|
'package:flutter/src/dart_plugin_registrant.dart',
|
||||||
|
'-Dflutter.dart_plugin_registrant=${dartPluginRegistrant.uri}',
|
||||||
|
],
|
||||||
...?extraFrontEndOptions,
|
...?extraFrontEndOptions,
|
||||||
mainUri,
|
mainUri,
|
||||||
];
|
];
|
||||||
@ -359,6 +364,7 @@ class _RecompileRequest extends _CompilationRequest {
|
|||||||
this.outputPath,
|
this.outputPath,
|
||||||
this.packageConfig,
|
this.packageConfig,
|
||||||
this.suppressErrors,
|
this.suppressErrors,
|
||||||
|
{this.additionalSource}
|
||||||
) : super(completer);
|
) : super(completer);
|
||||||
|
|
||||||
Uri mainUri;
|
Uri mainUri;
|
||||||
@ -366,6 +372,7 @@ class _RecompileRequest extends _CompilationRequest {
|
|||||||
String outputPath;
|
String outputPath;
|
||||||
PackageConfig packageConfig;
|
PackageConfig packageConfig;
|
||||||
bool suppressErrors;
|
bool suppressErrors;
|
||||||
|
final String? additionalSource;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<CompilerOutput?> _run(DefaultResidentCompiler compiler) async =>
|
Future<CompilerOutput?> _run(DefaultResidentCompiler compiler) async =>
|
||||||
@ -631,24 +638,31 @@ class DefaultResidentCompiler implements ResidentCompiler {
|
|||||||
if (!_controller.hasListener) {
|
if (!_controller.hasListener) {
|
||||||
_controller.stream.listen(_handleCompilationRequest);
|
_controller.stream.listen(_handleCompilationRequest);
|
||||||
}
|
}
|
||||||
// `generated_main.dart` contains the Dart plugin registry.
|
String? additionalSource;
|
||||||
|
// `dart_plugin_registrant.dart` contains the Dart plugin registry.
|
||||||
if (checkDartPluginRegistry && projectRootPath != null && fs != null) {
|
if (checkDartPluginRegistry && projectRootPath != null && fs != null) {
|
||||||
final File generatedMainDart = fs.file(
|
final File dartPluginRegistrantDart = fs.file(
|
||||||
fs.path.join(
|
fs.path.join(
|
||||||
projectRootPath,
|
projectRootPath,
|
||||||
'.dart_tool',
|
'.dart_tool',
|
||||||
'flutter_build',
|
'flutter_build',
|
||||||
'generated_main.dart',
|
'dart_plugin_registrant.dart',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
if (generatedMainDart != null && generatedMainDart.existsSync()) {
|
if (dartPluginRegistrantDart != null && dartPluginRegistrantDart.existsSync()) {
|
||||||
mainUri = generatedMainDart.uri;
|
additionalSource = dartPluginRegistrantDart.path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final Completer<CompilerOutput?> completer = Completer<CompilerOutput?>();
|
final Completer<CompilerOutput?> completer = Completer<CompilerOutput?>();
|
||||||
_controller.add(
|
_controller.add(_RecompileRequest(
|
||||||
_RecompileRequest(completer, mainUri, invalidatedFiles, outputPath, packageConfig, suppressErrors)
|
completer,
|
||||||
);
|
mainUri,
|
||||||
|
invalidatedFiles,
|
||||||
|
outputPath,
|
||||||
|
packageConfig,
|
||||||
|
suppressErrors,
|
||||||
|
additionalSource: additionalSource,
|
||||||
|
));
|
||||||
return completer.future;
|
return completer.future;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -662,7 +676,7 @@ class DefaultResidentCompiler implements ResidentCompiler {
|
|||||||
|
|
||||||
final Process? server = _server;
|
final Process? server = _server;
|
||||||
if (server == null) {
|
if (server == null) {
|
||||||
return _compile(mainUri, request.outputPath);
|
return _compile(mainUri, request.outputPath, additionalSource: request.additionalSource);
|
||||||
}
|
}
|
||||||
final String inputKey = Uuid().generateV4();
|
final String inputKey = Uuid().generateV4();
|
||||||
|
|
||||||
@ -708,6 +722,7 @@ class DefaultResidentCompiler implements ResidentCompiler {
|
|||||||
Future<CompilerOutput?> _compile(
|
Future<CompilerOutput?> _compile(
|
||||||
String scriptUri,
|
String scriptUri,
|
||||||
String? outputPath,
|
String? outputPath,
|
||||||
|
{String? additionalSource}
|
||||||
) async {
|
) async {
|
||||||
final String frontendServer = _artifacts.getArtifactPath(
|
final String frontendServer = _artifacts.getArtifactPath(
|
||||||
Artifact.frontendServerSnapshotForEngineDartSdk
|
Artifact.frontendServerSnapshotForEngineDartSdk
|
||||||
@ -760,6 +775,13 @@ class DefaultResidentCompiler implements ResidentCompiler {
|
|||||||
initializeFromDill!,
|
initializeFromDill!,
|
||||||
],
|
],
|
||||||
if (assumeInitializeFromDillUpToDate) '--assume-initialize-from-dill-up-to-date',
|
if (assumeInitializeFromDillUpToDate) '--assume-initialize-from-dill-up-to-date',
|
||||||
|
if (additionalSource != null) ...<String>[
|
||||||
|
'--source',
|
||||||
|
additionalSource,
|
||||||
|
'--source',
|
||||||
|
'package:flutter/src/dart_plugin_registrant.dart',
|
||||||
|
'-Dflutter.dart_plugin_registrant=${Uri.file(additionalSource)}',
|
||||||
|
],
|
||||||
if (platformDill != null) ...<String>[
|
if (platformDill != null) ...<String>[
|
||||||
'--platform',
|
'--platform',
|
||||||
platformDill!,
|
platformDill!,
|
||||||
|
@ -707,10 +707,6 @@ const String _dartPluginRegistryForNonWebTemplate = '''
|
|||||||
|
|
||||||
// @dart = {{dartLanguageVersion}}
|
// @dart = {{dartLanguageVersion}}
|
||||||
|
|
||||||
// When `{{mainEntrypoint}}` defines `main`, that definition is shadowed by the definition below.
|
|
||||||
export '{{mainEntrypoint}}';
|
|
||||||
|
|
||||||
import '{{mainEntrypoint}}' as entrypoint;
|
|
||||||
import 'dart:io'; // flutter_ignore: dart_io_import.
|
import 'dart:io'; // flutter_ignore: dart_io_import.
|
||||||
{{#android}}
|
{{#android}}
|
||||||
import 'package:{{pluginName}}/{{pluginName}}.dart';
|
import 'package:{{pluginName}}/{{pluginName}}.dart';
|
||||||
@ -755,18 +751,6 @@ $_dartPluginRegisterWith
|
|||||||
{{/windows}}
|
{{/windows}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef _UnaryFunction = dynamic Function(List<String> args);
|
|
||||||
typedef _NullaryFunction = dynamic Function();
|
|
||||||
|
|
||||||
void main(List<String> args) {
|
|
||||||
if (entrypoint.main is _UnaryFunction) {
|
|
||||||
(entrypoint.main as _UnaryFunction)(args);
|
|
||||||
} else {
|
|
||||||
(entrypoint.main as _NullaryFunction)();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
''';
|
''';
|
||||||
|
|
||||||
|
@ -236,7 +236,7 @@ class FlutterProject {
|
|||||||
/// The generated Dart plugin registrant for non-web platforms.
|
/// The generated Dart plugin registrant for non-web platforms.
|
||||||
File get dartPluginRegistrant => dartTool
|
File get dartPluginRegistrant => dartTool
|
||||||
.childDirectory('flutter_build')
|
.childDirectory('flutter_build')
|
||||||
.childFile('generated_main.dart');
|
.childFile('dart_plugin_registrant.dart');
|
||||||
|
|
||||||
/// The example sub-project of this project.
|
/// The example sub-project of this project.
|
||||||
FlutterProject get example => FlutterProject(
|
FlutterProject get example => FlutterProject(
|
||||||
|
@ -159,7 +159,7 @@ void main() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext("doesn't generate generated_main.dart if there aren't Dart plugins", () async {
|
testUsingContext("doesn't generate dart_plugin_registrant.dart if there aren't Dart plugins", () async {
|
||||||
final Directory projectDir = fileSystem.directory('project')..createSync();
|
final Directory projectDir = fileSystem.directory('project')..createSync();
|
||||||
final Environment environment = Environment.test(
|
final Environment environment = Environment.test(
|
||||||
fileSystem.currentDirectory,
|
fileSystem.currentDirectory,
|
||||||
@ -189,11 +189,11 @@ void main() {
|
|||||||
final File generatedMain = projectDir
|
final File generatedMain = projectDir
|
||||||
.childDirectory('.dart_tool')
|
.childDirectory('.dart_tool')
|
||||||
.childDirectory('flutter_build')
|
.childDirectory('flutter_build')
|
||||||
.childFile('generated_main.dart');
|
.childFile('dart_plugin_registrant.dart');
|
||||||
expect(generatedMain.existsSync(), isFalse);
|
expect(generatedMain.existsSync(), isFalse);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('regenerates generated_main.dart', () async {
|
testUsingContext('regenerates dart_plugin_registrant.dart', () async {
|
||||||
final Directory projectDir = fileSystem.directory('project')..createSync();
|
final Directory projectDir = fileSystem.directory('project')..createSync();
|
||||||
final Environment environment = Environment.test(
|
final Environment environment = Environment.test(
|
||||||
fileSystem.currentDirectory,
|
fileSystem.currentDirectory,
|
||||||
@ -231,7 +231,7 @@ void main() {
|
|||||||
final File generatedMain = projectDir
|
final File generatedMain = projectDir
|
||||||
.childDirectory('.dart_tool')
|
.childDirectory('.dart_tool')
|
||||||
.childDirectory('flutter_build')
|
.childDirectory('flutter_build')
|
||||||
.childFile('generated_main.dart');
|
.childFile('dart_plugin_registrant.dart');
|
||||||
final String mainContent = generatedMain.readAsStringSync();
|
final String mainContent = generatedMain.readAsStringSync();
|
||||||
expect(
|
expect(
|
||||||
mainContent,
|
mainContent,
|
||||||
@ -243,10 +243,6 @@ void main() {
|
|||||||
'\n'
|
'\n'
|
||||||
'// @dart = 2.12\n'
|
'// @dart = 2.12\n'
|
||||||
'\n'
|
'\n'
|
||||||
'// When `package:path_provider_example/main.dart` defines `main`, that definition is shadowed by the definition below.\n'
|
|
||||||
"export 'package:path_provider_example/main.dart';\n"
|
|
||||||
'\n'
|
|
||||||
"import 'package:path_provider_example/main.dart' as entrypoint;\n"
|
|
||||||
"import 'dart:io'; // flutter_ignore: dart_io_import.\n"
|
"import 'dart:io'; // flutter_ignore: dart_io_import.\n"
|
||||||
"import 'package:path_provider_linux/path_provider_linux.dart';\n"
|
"import 'package:path_provider_linux/path_provider_linux.dart';\n"
|
||||||
'\n'
|
'\n'
|
||||||
@ -272,24 +268,12 @@ void main() {
|
|||||||
' } else if (Platform.isWindows) {\n'
|
' } else if (Platform.isWindows) {\n'
|
||||||
' }\n'
|
' }\n'
|
||||||
' }\n'
|
' }\n'
|
||||||
'\n'
|
|
||||||
'}\n'
|
|
||||||
'\n'
|
|
||||||
'typedef _UnaryFunction = dynamic Function(List<String> args);\n'
|
|
||||||
'typedef _NullaryFunction = dynamic Function();\n'
|
|
||||||
'\n'
|
|
||||||
'void main(List<String> args) {\n'
|
|
||||||
' if (entrypoint.main is _UnaryFunction) {\n'
|
|
||||||
' (entrypoint.main as _UnaryFunction)(args);\n'
|
|
||||||
' } else {\n'
|
|
||||||
' (entrypoint.main as _NullaryFunction)();\n'
|
|
||||||
' }\n'
|
|
||||||
'}\n'
|
'}\n'
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('removes generated_main.dart if plugins are removed from pubspec.yaml', () async {
|
testUsingContext('removes dart_plugin_registrant.dart if plugins are removed from pubspec.yaml', () async {
|
||||||
final Directory projectDir = fileSystem.directory('project')..createSync();
|
final Directory projectDir = fileSystem.directory('project')..createSync();
|
||||||
final Environment environment = Environment.test(
|
final Environment environment = Environment.test(
|
||||||
fileSystem.currentDirectory,
|
fileSystem.currentDirectory,
|
||||||
@ -321,7 +305,7 @@ void main() {
|
|||||||
final File generatedMain = projectDir
|
final File generatedMain = projectDir
|
||||||
.childDirectory('.dart_tool')
|
.childDirectory('.dart_tool')
|
||||||
.childDirectory('flutter_build')
|
.childDirectory('flutter_build')
|
||||||
.childFile('generated_main.dart');
|
.childFile('dart_plugin_registrant.dart');
|
||||||
|
|
||||||
final FlutterProject testProject = FlutterProject.fromDirectoryTest(projectDir);
|
final FlutterProject testProject = FlutterProject.fromDirectoryTest(projectDir);
|
||||||
await DartPluginRegistrantTarget.test(testProject).build(environment);
|
await DartPluginRegistrantTarget.test(testProject).build(environment);
|
||||||
@ -372,7 +356,7 @@ void main() {
|
|||||||
final File generatedMain = projectDir
|
final File generatedMain = projectDir
|
||||||
.childDirectory('.dart_tool')
|
.childDirectory('.dart_tool')
|
||||||
.childDirectory('flutter_build')
|
.childDirectory('flutter_build')
|
||||||
.childFile('generated_main.dart');
|
.childFile('dart_plugin_registrant.dart');
|
||||||
|
|
||||||
final String mainContent = generatedMain.readAsStringSync();
|
final String mainContent = generatedMain.readAsStringSync();
|
||||||
expect(
|
expect(
|
||||||
@ -385,10 +369,6 @@ void main() {
|
|||||||
'\n'
|
'\n'
|
||||||
'// @dart = 2.12\n'
|
'// @dart = 2.12\n'
|
||||||
'\n'
|
'\n'
|
||||||
'// When `file:///root/external.dart` defines `main`, that definition is shadowed by the definition below.\n'
|
|
||||||
"export 'file:///root/external.dart';\n"
|
|
||||||
'\n'
|
|
||||||
"import 'file:///root/external.dart' as entrypoint;\n"
|
|
||||||
"import 'dart:io'; // flutter_ignore: dart_io_import.\n"
|
"import 'dart:io'; // flutter_ignore: dart_io_import.\n"
|
||||||
"import 'package:path_provider_linux/path_provider_linux.dart';\n"
|
"import 'package:path_provider_linux/path_provider_linux.dart';\n"
|
||||||
'\n'
|
'\n'
|
||||||
@ -414,18 +394,6 @@ void main() {
|
|||||||
' } else if (Platform.isWindows) {\n'
|
' } else if (Platform.isWindows) {\n'
|
||||||
' }\n'
|
' }\n'
|
||||||
' }\n'
|
' }\n'
|
||||||
'\n'
|
|
||||||
'}\n'
|
|
||||||
'\n'
|
|
||||||
'typedef _UnaryFunction = dynamic Function(List<String> args);\n'
|
|
||||||
'typedef _NullaryFunction = dynamic Function();\n'
|
|
||||||
'\n'
|
|
||||||
'void main(List<String> args) {\n'
|
|
||||||
' if (entrypoint.main is _UnaryFunction) {\n'
|
|
||||||
' (entrypoint.main as _UnaryFunction)(args);\n'
|
|
||||||
' } else {\n'
|
|
||||||
' (entrypoint.main as _NullaryFunction)();\n'
|
|
||||||
' }\n'
|
|
||||||
'}\n'
|
'}\n'
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -395,7 +395,12 @@ void main() {
|
|||||||
'--no-link-platform',
|
'--no-link-platform',
|
||||||
'--packages',
|
'--packages',
|
||||||
'.packages',
|
'.packages',
|
||||||
'.dart_tools/flutter_build/generated_main.dart',
|
'--source',
|
||||||
|
'.dart_tools/flutter_build/dart_plugin_registrant.dart',
|
||||||
|
'--source',
|
||||||
|
'package:flutter/src/dart_plugin_registrant.dart',
|
||||||
|
'-Dflutter.dart_plugin_registrant=.dart_tools/flutter_build/dart_plugin_registrant.dart',
|
||||||
|
'scheme:///main.dart',
|
||||||
], completer: completer),
|
], completer: completer),
|
||||||
]),
|
]),
|
||||||
stdoutHandler: stdoutHandler,
|
stdoutHandler: stdoutHandler,
|
||||||
@ -405,7 +410,7 @@ void main() {
|
|||||||
.childDirectory('flutter_build')
|
.childDirectory('flutter_build')
|
||||||
.childDirectory('test');
|
.childDirectory('test');
|
||||||
|
|
||||||
buildDir.parent.childFile('generated_main.dart').createSync(recursive: true);
|
buildDir.parent.childFile('dart_plugin_registrant.dart').createSync(recursive: true);
|
||||||
|
|
||||||
final Future<CompilerOutput?> output = kernelCompiler.compile(sdkRoot: '/path/to/sdkroot',
|
final Future<CompilerOutput?> output = kernelCompiler.compile(sdkRoot: '/path/to/sdkroot',
|
||||||
mainPath: '/foo/bar/fizz/main.dart',
|
mainPath: '/foo/bar/fizz/main.dart',
|
||||||
|
@ -35,7 +35,7 @@ void main() {
|
|||||||
..directory = directory
|
..directory = directory
|
||||||
..flutterPluginsFile = directory.childFile('.flutter-plugins')
|
..flutterPluginsFile = directory.childFile('.flutter-plugins')
|
||||||
..flutterPluginsDependenciesFile = directory.childFile('.flutter-plugins-dependencies')
|
..flutterPluginsDependenciesFile = directory.childFile('.flutter-plugins-dependencies')
|
||||||
..dartPluginRegistrant = directory.childFile('generated_main.dart');
|
..dartPluginRegistrant = directory.childFile('dart_plugin_registrant.dart');
|
||||||
flutterProject.directory.childFile('.packages').createSync(recursive: true);
|
flutterProject.directory.childFile('.packages').createSync(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -701,10 +701,6 @@ void main() {
|
|||||||
'\n'
|
'\n'
|
||||||
'// @dart = 2.8\n'
|
'// @dart = 2.8\n'
|
||||||
'\n'
|
'\n'
|
||||||
'// When `package:app/main.dart` defines `main`, that definition is shadowed by the definition below.\n'
|
|
||||||
"export 'package:app/main.dart';\n"
|
|
||||||
'\n'
|
|
||||||
"import 'package:app/main.dart' as entrypoint;\n"
|
|
||||||
"import 'dart:io'; // flutter_ignore: dart_io_import.\n"
|
"import 'dart:io'; // flutter_ignore: dart_io_import.\n"
|
||||||
"import 'package:url_launcher_android/url_launcher_android.dart';\n"
|
"import 'package:url_launcher_android/url_launcher_android.dart';\n"
|
||||||
"import 'package:url_launcher_ios/url_launcher_ios.dart';\n"
|
"import 'package:url_launcher_ios/url_launcher_ios.dart';\n"
|
||||||
@ -785,216 +781,7 @@ void main() {
|
|||||||
'\n'
|
'\n'
|
||||||
' }\n'
|
' }\n'
|
||||||
' }\n'
|
' }\n'
|
||||||
'\n'
|
|
||||||
'}\n'
|
'}\n'
|
||||||
'\n'
|
|
||||||
'typedef _UnaryFunction = dynamic Function(List<String> args);\n'
|
|
||||||
'typedef _NullaryFunction = dynamic Function();\n'
|
|
||||||
'\n'
|
|
||||||
'void main(List<String> args) {\n'
|
|
||||||
' if (entrypoint.main is _UnaryFunction) {\n'
|
|
||||||
' (entrypoint.main as _UnaryFunction)(args);\n'
|
|
||||||
' } else {\n'
|
|
||||||
' (entrypoint.main as _NullaryFunction)();\n'
|
|
||||||
' }\n'
|
|
||||||
'}\n',
|
|
||||||
);
|
|
||||||
}, overrides: <Type, Generator>{
|
|
||||||
FileSystem: () => fs,
|
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
|
||||||
});
|
|
||||||
|
|
||||||
testUsingContext('Rewires entrypoints', () async {
|
|
||||||
flutterProject.isModule = true;
|
|
||||||
|
|
||||||
createFakeDartPlugins(
|
|
||||||
flutterProject,
|
|
||||||
flutterManifest,
|
|
||||||
fs,
|
|
||||||
<String, String>{
|
|
||||||
'url_launcher_android': '''
|
|
||||||
flutter:
|
|
||||||
plugin:
|
|
||||||
implements: url_launcher
|
|
||||||
platforms:
|
|
||||||
android:
|
|
||||||
dartPluginClass: AndroidPlugin
|
|
||||||
''',
|
|
||||||
'url_launcher_ios': '''
|
|
||||||
flutter:
|
|
||||||
plugin:
|
|
||||||
implements: url_launcher
|
|
||||||
platforms:
|
|
||||||
ios:
|
|
||||||
dartPluginClass: IosPlugin
|
|
||||||
''',
|
|
||||||
'url_launcher_macos': '''
|
|
||||||
flutter:
|
|
||||||
plugin:
|
|
||||||
implements: url_launcher
|
|
||||||
platforms:
|
|
||||||
macos:
|
|
||||||
dartPluginClass: MacOSPlugin
|
|
||||||
''',
|
|
||||||
'url_launcher_linux': '''
|
|
||||||
flutter:
|
|
||||||
plugin:
|
|
||||||
implements: url_launcher
|
|
||||||
platforms:
|
|
||||||
linux:
|
|
||||||
dartPluginClass: LinuxPlugin
|
|
||||||
''',
|
|
||||||
'url_launcher_windows': '''
|
|
||||||
flutter:
|
|
||||||
plugin:
|
|
||||||
implements: url_launcher
|
|
||||||
platforms:
|
|
||||||
windows:
|
|
||||||
dartPluginClass: WindowsPlugin
|
|
||||||
''',
|
|
||||||
'awesome_macos': '''
|
|
||||||
flutter:
|
|
||||||
plugin:
|
|
||||||
implements: awesome
|
|
||||||
platforms:
|
|
||||||
macos:
|
|
||||||
dartPluginClass: AwesomeMacOS
|
|
||||||
'''
|
|
||||||
});
|
|
||||||
|
|
||||||
final Directory libDir = flutterProject.directory.childDirectory('lib');
|
|
||||||
libDir.createSync(recursive: true);
|
|
||||||
|
|
||||||
final File mainFile = libDir.childFile('main.dart');
|
|
||||||
mainFile.writeAsStringSync('''
|
|
||||||
// @dart = 2.8
|
|
||||||
void main() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@pragma('vm:entry-point')
|
|
||||||
void dream() => run(interactive: false);
|
|
||||||
|
|
||||||
@pragma('vm:entry-point', foobar)
|
|
||||||
void dreamWithFlags() => run(interactive: false);
|
|
||||||
''');
|
|
||||||
final PackageConfig packageConfig = await loadPackageConfigWithLogging(
|
|
||||||
flutterProject.directory.childDirectory('.dart_tool').childFile('package_config.json'),
|
|
||||||
logger: globals.logger,
|
|
||||||
throwOnError: false,
|
|
||||||
);
|
|
||||||
await generateMainDartWithPluginRegistrant(
|
|
||||||
flutterProject,
|
|
||||||
packageConfig,
|
|
||||||
'package:app/main.dart',
|
|
||||||
mainFile,
|
|
||||||
throwOnPluginPubspecError: true,
|
|
||||||
);
|
|
||||||
expect(flutterProject.dartPluginRegistrant.readAsStringSync(),
|
|
||||||
'//\n'
|
|
||||||
'// Generated file. Do not edit.\n'
|
|
||||||
'// This file is generated from template in file `flutter_tools/lib/src/flutter_plugins.dart`.\n'
|
|
||||||
'//\n'
|
|
||||||
'\n'
|
|
||||||
'// @dart = 2.8\n'
|
|
||||||
'\n'
|
|
||||||
'// When `package:app/main.dart` defines `main`, that definition is shadowed by the definition below.\n'
|
|
||||||
"export 'package:app/main.dart';\n"
|
|
||||||
'\n'
|
|
||||||
"import 'package:app/main.dart' as entrypoint;\n"
|
|
||||||
"import 'dart:io'; // flutter_ignore: dart_io_import.\n"
|
|
||||||
"import 'package:url_launcher_android/url_launcher_android.dart';\n"
|
|
||||||
"import 'package:url_launcher_ios/url_launcher_ios.dart';\n"
|
|
||||||
"import 'package:url_launcher_linux/url_launcher_linux.dart';\n"
|
|
||||||
"import 'package:awesome_macos/awesome_macos.dart';\n"
|
|
||||||
"import 'package:url_launcher_macos/url_launcher_macos.dart';\n"
|
|
||||||
"import 'package:url_launcher_windows/url_launcher_windows.dart';\n"
|
|
||||||
'\n'
|
|
||||||
"@pragma('vm:entry-point')\n"
|
|
||||||
'class _PluginRegistrant {\n'
|
|
||||||
'\n'
|
|
||||||
" @pragma('vm:entry-point')\n"
|
|
||||||
' static void register() {\n'
|
|
||||||
' if (Platform.isAndroid) {\n'
|
|
||||||
' try {\n'
|
|
||||||
' AndroidPlugin.registerWith();\n'
|
|
||||||
' } catch (err) {\n'
|
|
||||||
' print(\n'
|
|
||||||
" '`url_launcher_android` threw an error: \$err. '\n"
|
|
||||||
" 'The app may not function as expected until you remove this plugin from pubspec.yaml'\n"
|
|
||||||
' );\n'
|
|
||||||
' rethrow;\n'
|
|
||||||
' }\n'
|
|
||||||
'\n'
|
|
||||||
' } else if (Platform.isIOS) {\n'
|
|
||||||
' try {\n'
|
|
||||||
' IosPlugin.registerWith();\n'
|
|
||||||
' } catch (err) {\n'
|
|
||||||
' print(\n'
|
|
||||||
" '`url_launcher_ios` threw an error: \$err. '\n"
|
|
||||||
" 'The app may not function as expected until you remove this plugin from pubspec.yaml'\n"
|
|
||||||
' );\n'
|
|
||||||
' rethrow;\n'
|
|
||||||
' }\n'
|
|
||||||
'\n'
|
|
||||||
' } else if (Platform.isLinux) {\n'
|
|
||||||
' try {\n'
|
|
||||||
' LinuxPlugin.registerWith();\n'
|
|
||||||
' } catch (err) {\n'
|
|
||||||
' print(\n'
|
|
||||||
" '`url_launcher_linux` threw an error: \$err. '\n"
|
|
||||||
" 'The app may not function as expected until you remove this plugin from pubspec.yaml'\n"
|
|
||||||
' );\n'
|
|
||||||
' rethrow;\n'
|
|
||||||
' }\n'
|
|
||||||
'\n'
|
|
||||||
' } else if (Platform.isMacOS) {\n'
|
|
||||||
' try {\n'
|
|
||||||
' AwesomeMacOS.registerWith();\n'
|
|
||||||
' } catch (err) {\n'
|
|
||||||
' print(\n'
|
|
||||||
" '`awesome_macos` threw an error: \$err. '\n"
|
|
||||||
" 'The app may not function as expected until you remove this plugin from pubspec.yaml'\n"
|
|
||||||
' );\n'
|
|
||||||
' rethrow;\n'
|
|
||||||
' }\n'
|
|
||||||
'\n'
|
|
||||||
' try {\n'
|
|
||||||
' MacOSPlugin.registerWith();\n'
|
|
||||||
' } catch (err) {\n'
|
|
||||||
' print(\n'
|
|
||||||
" '`url_launcher_macos` threw an error: \$err. '\n"
|
|
||||||
" 'The app may not function as expected until you remove this plugin from pubspec.yaml'\n"
|
|
||||||
' );\n'
|
|
||||||
' rethrow;\n'
|
|
||||||
' }\n'
|
|
||||||
'\n'
|
|
||||||
' } else if (Platform.isWindows) {\n'
|
|
||||||
' try {\n'
|
|
||||||
' WindowsPlugin.registerWith();\n'
|
|
||||||
' } catch (err) {\n'
|
|
||||||
' print(\n'
|
|
||||||
" '`url_launcher_windows` threw an error: \$err. '\n"
|
|
||||||
" 'The app may not function as expected until you remove this plugin from pubspec.yaml'\n"
|
|
||||||
' );\n'
|
|
||||||
' rethrow;\n'
|
|
||||||
' }\n'
|
|
||||||
'\n'
|
|
||||||
' }\n'
|
|
||||||
' }\n'
|
|
||||||
'\n'
|
|
||||||
'}\n'
|
|
||||||
'\n'
|
|
||||||
'typedef _UnaryFunction = dynamic Function(List<String> args);\n'
|
|
||||||
'typedef _NullaryFunction = dynamic Function();\n'
|
|
||||||
'\n'
|
|
||||||
'void main(List<String> args) {\n'
|
|
||||||
' if (entrypoint.main is _UnaryFunction) {\n'
|
|
||||||
' (entrypoint.main as _UnaryFunction)(args);\n'
|
|
||||||
' } else {\n'
|
|
||||||
' (entrypoint.main as _NullaryFunction)();\n'
|
|
||||||
' }\n'
|
|
||||||
'}\n'
|
|
||||||
,
|
|
||||||
);
|
);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FileSystem: () => fs,
|
FileSystem: () => fs,
|
||||||
|
@ -1189,8 +1189,8 @@ void main() {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
''');
|
''');
|
||||||
// Start from an empty generated_main.dart file.
|
// Start from an empty dart_plugin_registrant.dart file.
|
||||||
globals.fs.directory('.dart_tool').childDirectory('flutter_build').childFile('generated_main.dart').createSync(recursive: true);
|
globals.fs.directory('.dart_tool').childDirectory('flutter_build').childFile('dart_plugin_registrant.dart').createSync(recursive: true);
|
||||||
|
|
||||||
await residentRunner.runSourceGenerators();
|
await residentRunner.runSourceGenerators();
|
||||||
|
|
||||||
@ -1267,9 +1267,9 @@ flutter:
|
|||||||
|
|
||||||
final File generatedMain = globals.fs.directory('.dart_tool')
|
final File generatedMain = globals.fs.directory('.dart_tool')
|
||||||
.childDirectory('flutter_build')
|
.childDirectory('flutter_build')
|
||||||
.childFile('generated_main.dart');
|
.childFile('dart_plugin_registrant.dart');
|
||||||
|
|
||||||
expect(generatedMain.readAsStringSync(), contains('custom_main.dart'));
|
expect(generatedMain.existsSync(), isTrue);
|
||||||
expect(testLogger.errorText, isEmpty);
|
expect(testLogger.errorText, isEmpty);
|
||||||
expect(testLogger.statusText, isEmpty);
|
expect(testLogger.statusText, isEmpty);
|
||||||
}));
|
}));
|
||||||
|
@ -936,7 +936,7 @@ void main() {
|
|||||||
|
|
||||||
// While this file should be ignored on web, generating it here will cause a
|
// While this file should be ignored on web, generating it here will cause a
|
||||||
// perf regression in hot restart.
|
// perf regression in hot restart.
|
||||||
testUsingContext('Does not generate generated_main.dart', () async {
|
testUsingContext('Does not generate dart_plugin_registrant.dart', () async {
|
||||||
// Create necessary files for [DartPluginRegistrantTarget]
|
// Create necessary files for [DartPluginRegistrantTarget]
|
||||||
final File packageConfig = globals.fs.directory('.dart_tool')
|
final File packageConfig = globals.fs.directory('.dart_tool')
|
||||||
.childFile('package_config.json');
|
.childFile('package_config.json');
|
||||||
@ -954,10 +954,10 @@ void main() {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
''');
|
''');
|
||||||
// Start with a generated_main.dart file.
|
// Start with a dart_plugin_registrant.dart file.
|
||||||
globals.fs.directory('.dart_tool')
|
globals.fs.directory('.dart_tool')
|
||||||
.childDirectory('flutter_build')
|
.childDirectory('flutter_build')
|
||||||
.childFile('generated_main.dart')
|
.childFile('dart_plugin_registrant.dart')
|
||||||
.createSync(recursive: true);
|
.createSync(recursive: true);
|
||||||
|
|
||||||
final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory);
|
final FlutterProject project = FlutterProject.fromDirectoryTest(fileSystem.currentDirectory);
|
||||||
@ -965,7 +965,7 @@ void main() {
|
|||||||
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
|
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
|
||||||
await residentWebRunner.runSourceGenerators();
|
await residentWebRunner.runSourceGenerators();
|
||||||
|
|
||||||
// generated_main.dart should be untouched, indicating that its
|
// dart_plugin_registrant.dart should be untouched, indicating that its
|
||||||
// generation didn't run. If it had run, the file would have been removed as
|
// generation didn't run. If it had run, the file would have been removed as
|
||||||
// there are no plugins in the project.
|
// there are no plugins in the project.
|
||||||
expect(project.dartPluginRegistrant.existsSync(), true);
|
expect(project.dartPluginRegistrant.existsSync(), true);
|
||||||
|
@ -115,7 +115,7 @@ void main() {
|
|||||||
Logger: () => BufferLogger.test(),
|
Logger: () => BufferLogger.test(),
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('TestCompiler updates generated_main.dart', () async {
|
testUsingContext('TestCompiler updates dart_plugin_registrant.dart', () async {
|
||||||
final Directory fakeDartPlugin = fileSystem.directory('a_plugin');
|
final Directory fakeDartPlugin = fileSystem.directory('a_plugin');
|
||||||
fileSystem.file('pubspec.yaml').writeAsStringSync('''
|
fileSystem.file('pubspec.yaml').writeAsStringSync('''
|
||||||
name: foo
|
name: foo
|
||||||
@ -152,12 +152,12 @@ environment:
|
|||||||
final File generatedMain = fileSystem
|
final File generatedMain = fileSystem
|
||||||
.directory('.dart_tool')
|
.directory('.dart_tool')
|
||||||
.childDirectory('flutter_build')
|
.childDirectory('flutter_build')
|
||||||
.childFile('generated_main.dart');
|
.childFile('dart_plugin_registrant.dart');
|
||||||
|
|
||||||
expect(generatedMain, exists);
|
expect(generatedMain, exists);
|
||||||
expect(
|
expect(
|
||||||
generatedMain.readAsLinesSync(),
|
generatedMain.readAsStringSync(),
|
||||||
contains("import 'test/foo.dart' as entrypoint;")
|
contains('APlugin.registerWith();')
|
||||||
);
|
);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user