mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
337 lines
11 KiB
Dart
337 lines
11 KiB
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.
|
|
|
|
import 'dart:async';
|
|
|
|
import 'package:dds/dds.dart';
|
|
import 'package:file/memory.dart';
|
|
import 'package:flutter_tools/src/base/file_system.dart';
|
|
import 'package:flutter_tools/src/base/io.dart';
|
|
import 'package:flutter_tools/src/base/logger.dart';
|
|
import 'package:flutter_tools/src/base/platform.dart';
|
|
import 'package:flutter_tools/src/build_info.dart';
|
|
import 'package:flutter_tools/src/device.dart';
|
|
import 'package:flutter_tools/src/test/flutter_tester_device.dart';
|
|
import 'package:flutter_tools/src/test/font_config_manager.dart';
|
|
import 'package:flutter_tools/src/vmservice.dart';
|
|
import 'package:stream_channel/stream_channel.dart';
|
|
import 'package:test/fake.dart';
|
|
|
|
import '../src/context.dart';
|
|
import '../src/fake_process_manager.dart';
|
|
import '../src/fake_vm_services.dart';
|
|
|
|
void main() {
|
|
late FakePlatform platform;
|
|
late FileSystem fileSystem;
|
|
late FakeProcessManager processManager;
|
|
late FlutterTesterTestDevice device;
|
|
|
|
setUp(() {
|
|
fileSystem = MemoryFileSystem.test();
|
|
// Not Windows.
|
|
platform = FakePlatform(
|
|
environment: <String, String>{},
|
|
);
|
|
processManager = FakeProcessManager.any();
|
|
});
|
|
|
|
FlutterTesterTestDevice createDevice({
|
|
List<String> dartEntrypointArgs = const <String>[],
|
|
bool enableVmService = false,
|
|
bool enableImpeller = false,
|
|
}) =>
|
|
TestFlutterTesterDevice(
|
|
platform: platform,
|
|
fileSystem: fileSystem,
|
|
processManager: processManager,
|
|
enableVmService: enableVmService,
|
|
dartEntrypointArgs: dartEntrypointArgs,
|
|
uriConverter: (String input) => '$input/converted',
|
|
enableImpeller: enableImpeller,
|
|
);
|
|
|
|
testUsingContext('Missing dir error caught for FontConfigManger.dispose', () async {
|
|
final FontConfigManager fontConfigManager = FontConfigManager();
|
|
|
|
final Directory fontsDirectory = fileSystem.file(fontConfigManager.fontConfigFile).parent;
|
|
fontsDirectory.deleteSync(recursive: true);
|
|
|
|
await fontConfigManager.dispose();
|
|
}, overrides: <Type, Generator>{
|
|
FileSystem: () => fileSystem,
|
|
ProcessManager: () => processManager,
|
|
});
|
|
|
|
testUsingContext('Flutter tester passes through impeller config and environment variables.', () async {
|
|
processManager = FakeProcessManager.list(<FakeCommand>[]);
|
|
device = createDevice(enableImpeller: true);
|
|
processManager.addCommand(FakeCommand(command: const <String>[
|
|
'/',
|
|
'--disable-vm-service',
|
|
'--ipv6',
|
|
'--enable-checked-mode',
|
|
'--verify-entry-points',
|
|
'--enable-impeller',
|
|
'--enable-dart-profiling',
|
|
'--non-interactive',
|
|
'--use-test-fonts',
|
|
'--disable-asset-fonts',
|
|
'--packages=.dart_tool/package_config.json',
|
|
'example.dill',
|
|
], environment: <String, String>{
|
|
'FLUTTER_TEST': 'true',
|
|
'FONTCONFIG_FILE': device.fontConfigManager.fontConfigFile.path,
|
|
'SERVER_PORT': '0',
|
|
'APP_NAME': '',
|
|
'FLUTTER_TEST_IMPELLER': 'true',
|
|
}));
|
|
|
|
await device.start('example.dill');
|
|
|
|
expect(processManager, hasNoRemainingExpectations);
|
|
}, overrides: <Type, Generator>{
|
|
FileSystem: () => fileSystem,
|
|
ProcessManager: () => processManager,
|
|
});
|
|
|
|
group('The FLUTTER_TEST environment variable is passed to the test process', () {
|
|
setUp(() {
|
|
processManager = FakeProcessManager.list(<FakeCommand>[]);
|
|
device = createDevice();
|
|
|
|
fileSystem
|
|
.file('.dart_tool/package_config.json')
|
|
..createSync(recursive: true)
|
|
..writeAsStringSync('{"configVersion":2,"packages":[]}');
|
|
});
|
|
|
|
FakeCommand flutterTestCommand(String expectedFlutterTestValue) {
|
|
return FakeCommand(command: const <String>[
|
|
'/',
|
|
'--disable-vm-service',
|
|
'--ipv6',
|
|
'--enable-checked-mode',
|
|
'--verify-entry-points',
|
|
'--enable-software-rendering',
|
|
'--skia-deterministic-rendering',
|
|
'--enable-dart-profiling',
|
|
'--non-interactive',
|
|
'--use-test-fonts',
|
|
'--disable-asset-fonts',
|
|
'--packages=.dart_tool/package_config.json',
|
|
'example.dill',
|
|
], environment: <String, String>{
|
|
'FLUTTER_TEST': expectedFlutterTestValue,
|
|
'FONTCONFIG_FILE': device.fontConfigManager.fontConfigFile.path,
|
|
'SERVER_PORT': '0',
|
|
'APP_NAME': '',
|
|
});
|
|
}
|
|
|
|
testUsingContext('as true when not originally set', () async {
|
|
processManager.addCommand(flutterTestCommand('true'));
|
|
|
|
await device.start('example.dill');
|
|
expect(processManager, hasNoRemainingExpectations);
|
|
});
|
|
|
|
testUsingContext('as true when set to true', () async {
|
|
platform.environment = <String, String>{'FLUTTER_TEST': 'true'};
|
|
processManager.addCommand(flutterTestCommand('true'));
|
|
|
|
await device.start('example.dill');
|
|
expect(processManager, hasNoRemainingExpectations);
|
|
});
|
|
|
|
testUsingContext('as false when set to false', () async {
|
|
platform.environment = <String, String>{'FLUTTER_TEST': 'false'};
|
|
processManager.addCommand(flutterTestCommand('false'));
|
|
|
|
await device.start('example.dill');
|
|
expect(processManager, hasNoRemainingExpectations);
|
|
});
|
|
|
|
testUsingContext('unchanged when set', () async {
|
|
platform.environment = <String, String>{'FLUTTER_TEST': 'neither true nor false'};
|
|
processManager.addCommand(flutterTestCommand('neither true nor false'));
|
|
|
|
await device.start('example.dill');
|
|
expect(processManager, hasNoRemainingExpectations);
|
|
});
|
|
});
|
|
|
|
group('Dart Entrypoint Args', () {
|
|
setUp(() {
|
|
processManager = FakeProcessManager.list(<FakeCommand>[
|
|
const FakeCommand(
|
|
command: <String>[
|
|
'/',
|
|
'--disable-vm-service',
|
|
'--ipv6',
|
|
'--enable-checked-mode',
|
|
'--verify-entry-points',
|
|
'--enable-software-rendering',
|
|
'--skia-deterministic-rendering',
|
|
'--enable-dart-profiling',
|
|
'--non-interactive',
|
|
'--use-test-fonts',
|
|
'--disable-asset-fonts',
|
|
'--packages=.dart_tool/package_config.json',
|
|
'--foo',
|
|
'--bar',
|
|
'example.dill',
|
|
],
|
|
stdout: 'success',
|
|
stderr: 'failure',
|
|
),
|
|
]);
|
|
device = createDevice(dartEntrypointArgs: <String>['--foo', '--bar']);
|
|
});
|
|
|
|
testUsingContext('Can pass additional arguments to tester binary', () async {
|
|
await device.start('example.dill');
|
|
|
|
expect(processManager, hasNoRemainingExpectations);
|
|
});
|
|
});
|
|
|
|
group('DDS', () {
|
|
setUp(() {
|
|
processManager = FakeProcessManager.list(<FakeCommand>[
|
|
const FakeCommand(
|
|
command: <String>[
|
|
'/',
|
|
'--vm-service-port=0',
|
|
'--ipv6',
|
|
'--enable-checked-mode',
|
|
'--verify-entry-points',
|
|
'--enable-software-rendering',
|
|
'--skia-deterministic-rendering',
|
|
'--enable-dart-profiling',
|
|
'--non-interactive',
|
|
'--use-test-fonts',
|
|
'--disable-asset-fonts',
|
|
'--packages=.dart_tool/package_config.json',
|
|
'example.dill',
|
|
],
|
|
stdout: 'The Dart VM service is listening on http://localhost:1234',
|
|
stderr: 'failure',
|
|
),
|
|
]);
|
|
device = createDevice(enableVmService: true);
|
|
});
|
|
|
|
testUsingContext('skips setting VM Service port and uses the input port for DDS instead', () async {
|
|
await device.start('example.dill');
|
|
await device.vmServiceUri;
|
|
|
|
final Uri uri = await (device as TestFlutterTesterDevice).ddsServiceUriFuture();
|
|
expect(uri.port, 1234);
|
|
});
|
|
|
|
testUsingContext('sets up UriConverter from context', () async {
|
|
await device.start('example.dill');
|
|
await device.vmServiceUri;
|
|
|
|
final FakeDartDevelopmentService dds = (device as TestFlutterTesterDevice).dds
|
|
as FakeDartDevelopmentService;
|
|
final String? result = dds
|
|
.uriConverter
|
|
?.call('test');
|
|
expect(result, 'test/converted');
|
|
});
|
|
});
|
|
}
|
|
|
|
/// A Flutter Tester device.
|
|
///
|
|
/// Uses a mock HttpServer. We don't want to bind random ports in our CI hosts.
|
|
class TestFlutterTesterDevice extends FlutterTesterTestDevice {
|
|
TestFlutterTesterDevice({
|
|
required super.platform,
|
|
required super.fileSystem,
|
|
required super.processManager,
|
|
required super.enableVmService,
|
|
required List<String> dartEntrypointArgs,
|
|
required UriConverter uriConverter,
|
|
required bool enableImpeller,
|
|
}) : super(
|
|
id: 999,
|
|
shellPath: '/',
|
|
logger: BufferLogger.test(),
|
|
debuggingOptions: DebuggingOptions.enabled(
|
|
const BuildInfo(
|
|
BuildMode.debug,
|
|
'',
|
|
treeShakeIcons: false,
|
|
),
|
|
hostVmServicePort: 1234,
|
|
dartEntrypointArgs: dartEntrypointArgs,
|
|
enableImpeller: enableImpeller ? ImpellerStatus.enabled : ImpellerStatus.platformDefault,
|
|
),
|
|
machine: false,
|
|
host: InternetAddress.loopbackIPv6,
|
|
testAssetDirectory: null,
|
|
flutterProject: null,
|
|
icudtlPath: null,
|
|
compileExpression: null,
|
|
fontConfigManager: FontConfigManager(),
|
|
uriConverter: uriConverter,
|
|
);
|
|
late DartDevelopmentService dds;
|
|
|
|
final Completer<Uri> _ddsServiceUriCompleter = Completer<Uri>();
|
|
|
|
Future<Uri> ddsServiceUriFuture() => _ddsServiceUriCompleter.future;
|
|
|
|
@override
|
|
Future<DartDevelopmentService> startDds(
|
|
Uri uri, {
|
|
UriConverter? uriConverter,
|
|
}) async {
|
|
_ddsServiceUriCompleter.complete(uri);
|
|
dds = FakeDartDevelopmentService(
|
|
Uri.parse('http://localhost:${debuggingOptions.hostVmServicePort}'),
|
|
Uri.parse('http://localhost:8080'),
|
|
uriConverter: uriConverter,
|
|
);
|
|
return dds;
|
|
}
|
|
|
|
@override
|
|
Future<FlutterVmService> connectToVmServiceImpl(
|
|
Uri httpUri, {
|
|
CompileExpression? compileExpression,
|
|
required Logger logger,
|
|
}) async {
|
|
return FakeVmServiceHost(requests: <VmServiceExpectation>[
|
|
const FakeVmServiceRequest(method: '_serveObservatory'),
|
|
]).vmService;
|
|
}
|
|
|
|
@override
|
|
Future<HttpServer> bind(InternetAddress? host, int port) async => FakeHttpServer();
|
|
|
|
@override
|
|
Future<StreamChannel<String>> get remoteChannel async => StreamChannelController<String>().foreign;
|
|
}
|
|
|
|
class FakeDartDevelopmentService extends Fake implements DartDevelopmentService {
|
|
FakeDartDevelopmentService(this.uri, this.original, {this.uriConverter});
|
|
|
|
final Uri original;
|
|
final UriConverter? uriConverter;
|
|
|
|
@override
|
|
final Uri uri;
|
|
|
|
@override
|
|
Uri get remoteVmServiceUri => original;
|
|
}
|
|
class FakeHttpServer extends Fake implements HttpServer {
|
|
@override
|
|
int get port => 0;
|
|
}
|