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

[flutter_tools] more test fixes (#60144)

Fixes additional bugs uncovered by tester, style fixes to prevent suggested imports.
parent 850ea6d2
......@@ -837,7 +837,8 @@ class ReleaseAssetServer {
} else {
for (final Uri uri in _searchPaths) {
final Uri potential = uri.resolve(request.url.path);
if (potential == null || !globals.fs.isFileSync(potential.toFilePath())) {
if (potential == null || !globals.fs.isFileSync(
potential.toFilePath(windows: globals.platform.isWindows))) {
continue;
}
fileUri = potential;
......
......@@ -186,7 +186,9 @@ class TestCompiler {
// The idea is to keep the cache file up-to-date and include as
// much as possible in an effort to re-use as many packages as
// possible.
globals.fsUtils.ensureDirectoryExists(testFilePath);
if (!testCache.parent.existsSync()) {
testCache.parent.createSync(recursive: true);
}
await outputFile.copy(testFilePath);
}
request.result.complete(kernelReadyToRun.path);
......
......@@ -4,6 +4,7 @@
import 'dart:async';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/terminal.dart';
......@@ -74,6 +75,7 @@ void main() {
ProcessManager: () => mockProcessManager,
OutputPreferences: () => OutputPreferences(showColor: false),
Platform: kNoColorTerminalPlatform,
Artifacts: () => Artifacts.test(),
});
testUsingContext('passes correct AOT config to kernel compiler in aot/profile mode', () async {
......@@ -108,6 +110,7 @@ void main() {
ProcessManager: () => mockProcessManager,
OutputPreferences: () => OutputPreferences(showColor: false),
Platform: kNoColorTerminalPlatform,
Artifacts: () => Artifacts.test(),
});
......@@ -143,6 +146,7 @@ void main() {
ProcessManager: () => mockProcessManager,
OutputPreferences: () => OutputPreferences(showColor: false),
Platform: kNoColorTerminalPlatform,
Artifacts: () => Artifacts.test(),
});
testUsingContext('batch compile single dart failed compilation', () async {
......@@ -169,6 +173,7 @@ void main() {
ProcessManager: () => mockProcessManager,
OutputPreferences: () => OutputPreferences(showColor: false),
Platform: kNoColorTerminalPlatform,
Artifacts: () => Artifacts.test(),
});
testUsingContext('batch compile single dart abnormal compiler termination', () async {
......@@ -197,6 +202,7 @@ void main() {
ProcessManager: () => mockProcessManager,
OutputPreferences: () => OutputPreferences(showColor: false),
Platform: kNoColorTerminalPlatform,
Artifacts: () => Artifacts.test(),
});
testUsingContext('passes dartDefines to the kernel compiler', () async {
......@@ -220,6 +226,7 @@ void main() {
ProcessManager: () => mockProcessManager,
OutputPreferences: () => OutputPreferences(showColor: false),
Platform: kNoColorTerminalPlatform,
Artifacts: () => Artifacts.test(),
});
}
......
......@@ -30,14 +30,14 @@ void main() {
group('Project', () {
group('construction', () {
testInMemory('fails on null directory', () async {
_testInMemory('fails on null directory', () async {
expect(
() => FlutterProject.fromDirectory(null),
throwsAssertionError,
);
});
testInMemory('fails on invalid pubspec.yaml', () async {
_testInMemory('fails on invalid pubspec.yaml', () async {
final Directory directory = globals.fs.directory('myproject');
directory.childFile('pubspec.yaml')
..createSync(recursive: true)
......@@ -49,7 +49,7 @@ void main() {
);
});
testInMemory('fails on pubspec.yaml parse failure', () async {
_testInMemory('fails on pubspec.yaml parse failure', () async {
final Directory directory = globals.fs.directory('myproject');
directory.childFile('pubspec.yaml')
..createSync(recursive: true)
......@@ -61,7 +61,7 @@ void main() {
);
});
testInMemory('fails on invalid example/pubspec.yaml', () async {
_testInMemory('fails on invalid example/pubspec.yaml', () async {
final Directory directory = globals.fs.directory('myproject');
directory.childDirectory('example').childFile('pubspec.yaml')
..createSync(recursive: true)
......@@ -73,7 +73,7 @@ void main() {
);
});
testInMemory('treats missing pubspec.yaml as empty', () async {
_testInMemory('treats missing pubspec.yaml as empty', () async {
final Directory directory = globals.fs.directory('myproject')
..createSync(recursive: true);
expect((FlutterProject.fromDirectory(directory)).manifest.isEmpty,
......@@ -81,7 +81,7 @@ void main() {
);
});
testInMemory('reads valid pubspec.yaml', () async {
_testInMemory('reads valid pubspec.yaml', () async {
final Directory directory = globals.fs.directory('myproject');
directory.childFile('pubspec.yaml')
..createSync(recursive: true)
......@@ -92,7 +92,7 @@ void main() {
);
});
testInMemory('sets up location', () async {
_testInMemory('sets up location', () async {
final Directory directory = globals.fs.directory('myproject');
expect(
FlutterProject.fromDirectory(directory).directory.absolute.path,
......@@ -110,19 +110,19 @@ void main() {
});
group('editable Android host app', () {
testInMemory('fails on non-module', () async {
_testInMemory('fails on non-module', () async {
final FlutterProject project = await someProject();
await expectLater(
project.android.makeHostAppEditable(),
throwsAssertionError,
);
});
testInMemory('exits on already editable module', () async {
_testInMemory('exits on already editable module', () async {
final FlutterProject project = await aModuleProject();
await project.android.makeHostAppEditable();
return expectToolExitLater(project.android.makeHostAppEditable(), contains('already editable'));
});
testInMemory('creates android/app folder in place of .android/app', () async {
_testInMemory('creates android/app folder in place of .android/app', () async {
final FlutterProject project = await aModuleProject();
await project.android.makeHostAppEditable();
expectNotExists(project.directory.childDirectory('.android').childDirectory('app'));
......@@ -137,7 +137,7 @@ void main() {
contains("include ':app'"),
);
});
testInMemory('retains .android/Flutter folder and references it', () async {
_testInMemory('retains .android/Flutter folder and references it', () async {
final FlutterProject project = await aModuleProject();
await project.android.makeHostAppEditable();
expectExists(project.directory.childDirectory('.android').childDirectory('Flutter'));
......@@ -146,7 +146,7 @@ void main() {
contains("new File(settingsDir.parentFile, '.android/include_flutter.groovy')"),
);
});
testInMemory('can be redone after deletion', () async {
_testInMemory('can be redone after deletion', () async {
final FlutterProject project = await aModuleProject();
await project.android.makeHostAppEditable();
project.directory.childDirectory('android').deleteSync(recursive: true);
......@@ -156,7 +156,7 @@ void main() {
});
group('ensure ready for platform-specific tooling', () {
testInMemory('does nothing, if project is not created', () async {
_testInMemory('does nothing, if project is not created', () async {
final FlutterProject project = FlutterProject(
globals.fs.directory('not_created'),
FlutterManifest.empty(logger: logger),
......@@ -165,7 +165,7 @@ void main() {
await project.ensureReadyForPlatformSpecificTooling();
expectNotExists(project.directory);
});
testInMemory('does nothing in plugin or package root project', () async {
_testInMemory('does nothing in plugin or package root project', () async {
final FlutterProject project = await aPluginProject();
await project.ensureReadyForPlatformSpecificTooling();
expectNotExists(project.ios.hostAppRoot.childDirectory('Runner').childFile('GeneratedPluginRegistrant.h'));
......@@ -173,22 +173,22 @@ void main() {
expectNotExists(project.ios.hostAppRoot.childDirectory('Flutter').childFile('Generated.xcconfig'));
expectNotExists(project.android.hostAppGradleRoot.childFile('local.properties'));
});
testInMemory('injects plugins for iOS', () async {
_testInMemory('injects plugins for iOS', () async {
final FlutterProject project = await someProject();
await project.ensureReadyForPlatformSpecificTooling();
expectExists(project.ios.hostAppRoot.childDirectory('Runner').childFile('GeneratedPluginRegistrant.h'));
});
testInMemory('generates Xcode configuration for iOS', () async {
_testInMemory('generates Xcode configuration for iOS', () async {
final FlutterProject project = await someProject();
await project.ensureReadyForPlatformSpecificTooling();
expectExists(project.ios.hostAppRoot.childDirectory('Flutter').childFile('Generated.xcconfig'));
});
testInMemory('injects plugins for Android', () async {
_testInMemory('injects plugins for Android', () async {
final FlutterProject project = await someProject();
await project.ensureReadyForPlatformSpecificTooling();
expectExists(androidPluginRegistrant(project.android.hostAppGradleRoot.childDirectory('app')));
});
testInMemory('updates local properties for Android', () async {
_testInMemory('updates local properties for Android', () async {
final FlutterProject project = await someProject();
await project.ensureReadyForPlatformSpecificTooling();
expectExists(project.android.hostAppGradleRoot.childFile('local.properties'));
......@@ -265,14 +265,14 @@ EndGlobal''');
fileSystem: globals.fs,
),
});
testInMemory('creates Android library in module', () async {
_testInMemory('creates Android library in module', () async {
final FlutterProject project = await aModuleProject();
await project.ensureReadyForPlatformSpecificTooling();
expectExists(project.android.hostAppGradleRoot.childFile('settings.gradle'));
expectExists(project.android.hostAppGradleRoot.childFile('local.properties'));
expectExists(androidPluginRegistrant(project.android.hostAppGradleRoot.childDirectory('Flutter')));
});
testInMemory('creates iOS pod in module', () async {
_testInMemory('creates iOS pod in module', () async {
final FlutterProject project = await aModuleProject();
await project.ensureReadyForPlatformSpecificTooling();
final Directory flutter = project.ios.hostAppRoot.childDirectory('Flutter');
......@@ -289,7 +289,7 @@ EndGlobal''');
});
group('module status', () {
testInMemory('is known for module', () async {
_testInMemory('is known for module', () async {
final FlutterProject project = await aModuleProject();
expect(project.isModule, isTrue);
expect(project.android.isModule, isTrue);
......@@ -297,7 +297,7 @@ EndGlobal''');
expect(project.android.hostAppGradleRoot.basename, '.android');
expect(project.ios.hostAppRoot.basename, '.ios');
});
testInMemory('is known for non-module', () async {
_testInMemory('is known for non-module', () async {
final FlutterProject project = await someProject();
expect(project.isModule, isFalse);
expect(project.android.isModule, isFalse);
......@@ -308,15 +308,15 @@ EndGlobal''');
});
group('example', () {
testInMemory('exists for plugin in legacy format', () async {
_testInMemory('exists for plugin in legacy format', () async {
final FlutterProject project = await aPluginProject();
expect(project.hasExampleApp, isTrue);
});
testInMemory('exists for plugin in multi-platform format', () async {
_testInMemory('exists for plugin in multi-platform format', () async {
final FlutterProject project = await aPluginProject(legacy: false);
expect(project.hasExampleApp, isTrue);
});
testInMemory('does not exist for non-plugin', () async {
_testInMemory('does not exist for non-plugin', () async {
final FlutterProject project = await someProject();
expect(project.hasExampleApp, isFalse);
});
......@@ -335,7 +335,7 @@ EndGlobal''');
);
});
testInMemory('default host app language', () async {
_testInMemory('default host app language', () async {
final FlutterProject project = await someProject();
expect(project.android.isKotlin, isFalse);
});
......@@ -500,23 +500,23 @@ apply plugin: 'kotlin-android'
});
group('organization names set', () {
testInMemory('is empty, if project not created', () async {
_testInMemory('is empty, if project not created', () async {
final FlutterProject project = await someProject();
expect(await project.organizationNames, isEmpty);
});
testInMemory('is empty, if no platform folders exist', () async {
_testInMemory('is empty, if no platform folders exist', () async {
final FlutterProject project = await someProject();
project.directory.createSync();
expect(await project.organizationNames, isEmpty);
});
testInMemory('is populated from iOS bundle identifier', () async {
_testInMemory('is populated from iOS bundle identifier', () async {
final FlutterProject project = await someProject();
addIosProjectFile(project.directory, projectFileContent: () {
return projectFileWithBundleId('io.flutter.someProject', qualifier: "'");
});
expect(await project.organizationNames, <String>['io.flutter']);
});
testInMemory('is populated from Android application ID', () async {
_testInMemory('is populated from Android application ID', () async {
final FlutterProject project = await someProject();
addAndroidGradleFile(project.directory,
gradleFileContent: () {
......@@ -524,14 +524,14 @@ apply plugin: 'kotlin-android'
});
expect(await project.organizationNames, <String>['io.flutter']);
});
testInMemory('is populated from iOS bundle identifier in plugin example', () async {
_testInMemory('is populated from iOS bundle identifier in plugin example', () async {
final FlutterProject project = await someProject();
addIosProjectFile(project.example.directory, projectFileContent: () {
return projectFileWithBundleId('io.flutter.someProject', qualifier: "'");
});
expect(await project.organizationNames, <String>['io.flutter']);
});
testInMemory('is populated from Android application ID in plugin example', () async {
_testInMemory('is populated from Android application ID in plugin example', () async {
final FlutterProject project = await someProject();
addAndroidGradleFile(project.example.directory,
gradleFileContent: () {
......@@ -539,12 +539,12 @@ apply plugin: 'kotlin-android'
});
expect(await project.organizationNames, <String>['io.flutter']);
});
testInMemory('is populated from Android group in plugin', () async {
_testInMemory('is populated from Android group in plugin', () async {
final FlutterProject project = await someProject();
addAndroidWithGroup(project.directory, 'io.flutter.someproject');
expect(await project.organizationNames, <String>['io.flutter']);
});
testInMemory('is singleton, if sources agree', () async {
_testInMemory('is singleton, if sources agree', () async {
final FlutterProject project = await someProject();
addIosProjectFile(project.directory, projectFileContent: () {
return projectFileWithBundleId('io.flutter.someProject');
......@@ -555,7 +555,7 @@ apply plugin: 'kotlin-android'
});
expect(await project.organizationNames, <String>['io.flutter']);
});
testInMemory('is non-singleton, if sources disagree', () async {
_testInMemory('is non-singleton, if sources disagree', () async {
final FlutterProject project = await someProject();
addIosProjectFile(project.directory, projectFileContent: () {
return projectFileWithBundleId('io.flutter.someProject');
......@@ -771,7 +771,7 @@ flutter:
/// Executes the [testMethod] in a context where the file system
/// is in memory.
@isTest
void testInMemory(String description, Future<void> testMethod()) {
void _testInMemory(String description, Future<void> testMethod()) {
Cache.flutterRoot = getFlutterRoot();
final FileSystem testFileSystem = MemoryFileSystem(
style: globals.platform.isWindows ? FileSystemStyle.windows : FileSystemStyle.posix,
......
......@@ -61,7 +61,7 @@ void main() {
testWithoutContext('can launch chrome and connect to the devtools', () async {
expect(
() async => await testLaunchChrome(
() async => await _testLaunchChrome(
'/.tmp_rand0/flutter_tools_chrome_device.rand0',
processManager,
chromeLauncher,
......@@ -71,14 +71,14 @@ void main() {
});
testWithoutContext('cannot have two concurrent instances of chrome', () async {
await testLaunchChrome(
await _testLaunchChrome(
'/.tmp_rand0/flutter_tools_chrome_device.rand0',
processManager,
chromeLauncher,
);
expect(
() async => await testLaunchChrome(
() async => await _testLaunchChrome(
'/.tmp_rand0/flutter_tools_chrome_device.rand1',
processManager,
chromeLauncher,
......@@ -88,7 +88,7 @@ void main() {
});
testWithoutContext('can launch new chrome after stopping a previous chrome', () async {
final Chromium chrome = await testLaunchChrome(
final Chromium chrome = await _testLaunchChrome(
'/.tmp_rand0/flutter_tools_chrome_device.rand0',
processManager,
chromeLauncher,
......@@ -96,7 +96,7 @@ void main() {
await chrome.close();
expect(
() async => await testLaunchChrome(
() async => await _testLaunchChrome(
'/.tmp_rand0/flutter_tools_chrome_device.rand1',
processManager,
chromeLauncher,
......@@ -221,7 +221,7 @@ void main() {
class MockOperatingSystemUtils extends Mock implements OperatingSystemUtils {}
Future<Chromium> testLaunchChrome(String userDataDir, FakeProcessManager processManager, ChromiumLauncher chromeLauncher) {
Future<Chromium> _testLaunchChrome(String userDataDir, FakeProcessManager processManager, ChromiumLauncher chromeLauncher) {
processManager.addCommand(FakeCommand(
command: <String>[
'example_chrome',
......
......@@ -2,13 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
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/globals.dart' as globals;
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/build_runner/devfs_web.dart';
import 'package:shelf/shelf.dart';
import '../../src/common.dart';
import '../../src/testbed.dart';
import '../../src/context.dart';
const List<int> kTransparentImage = <int>[
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49,
......@@ -18,30 +20,34 @@ const List<int> kTransparentImage = <int>[
0x0A, 0x2D, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE,
];
final Platform platform = FakePlatform(
operatingSystem: 'linux',
environment: <String, String>{
'HOME': '/'
},
);
void main() {
Testbed testbed;
FileSystem fileSystem;
setUp(() {
testbed = Testbed(
setup: () {
globals.fs.file(globals.fs.path.join('lib', 'main.dart'))
.createSync(recursive: true);
globals.fs.file(globals.fs.path.join('web', 'index.html'))
..createSync(recursive: true)
..writeAsStringSync('hello');
globals.fs.file(globals.fs.path.join('build', 'flutter_assets', 'foo.png'))
..createSync(recursive: true)
..writeAsBytesSync(kTransparentImage);
globals.fs.file(globals.fs.path.join('build', 'flutter_assets', 'bar'))
..createSync(recursive: true)
..writeAsBytesSync(<int>[1, 2, 3]);
}
);
fileSystem = MemoryFileSystem.test();
fileSystem.file('lib/main.dart')
.createSync(recursive: true);
fileSystem.file('web/index.html')
..createSync(recursive: true)
..writeAsStringSync('hello');
fileSystem.file('build/flutter_assets/foo.png')
..createSync(recursive: true)
..writeAsBytesSync(kTransparentImage);
fileSystem.file('build/flutter_assets/bar')
..createSync(recursive: true)
..writeAsBytesSync(<int>[1, 2, 3]);
});
test('release asset server serves correct mime type and content length for png', () => testbed.run(() async {
testUsingContext('release asset server serves correct mime type and content length for png', () async {
final ReleaseAssetServer assetServer = ReleaseAssetServer(Uri.base);
globals.fs.file(globals.fs.path.join('build', 'web', 'assets', 'foo.png'))
fileSystem.file('build/web/assets/foo.png')
..createSync(recursive: true)
..writeAsBytesSync(kTransparentImage);
final Response response = await assetServer
......@@ -51,11 +57,15 @@ void main() {
'Content-Type': 'image/png',
'content-length': '64',
});
}));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
Platform: () => platform,
ProcessManager: () => FakeProcessManager.any(),
});
test('release asset server serves correct mime type and content length for JavaScript', () => testbed.run(() async {
testUsingContext('release asset server serves correct mime type and content length for JavaScript', () async {
final ReleaseAssetServer assetServer = ReleaseAssetServer(Uri.base);
globals.fs.file(globals.fs.path.join('build', 'web', 'assets', 'foo.js'))
fileSystem.file('build/web/assets/foo.js')
..createSync(recursive: true)
..writeAsStringSync('function main() {}');
final Response response = await assetServer
......@@ -65,11 +75,15 @@ void main() {
'Content-Type': 'application/javascript',
'content-length': '18',
});
}));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
Platform: () => platform,
ProcessManager: () => FakeProcessManager.any(),
});
test('release asset server serves correct mime type and content length for html', () => testbed.run(() async {
testUsingContext('release asset server serves correct mime type and content length for html', () async {
final ReleaseAssetServer assetServer = ReleaseAssetServer(Uri.base);
globals.fs.file(globals.fs.path.join('build', 'web', 'assets', 'foo.html'))
fileSystem.file('build/web/assets/foo.html')
..createSync(recursive: true)
..writeAsStringSync('<!doctype html><html></html>');
final Response response = await assetServer
......@@ -79,27 +93,39 @@ void main() {
'Content-Type': 'text/html',
'content-length': '28',
});
}));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
Platform: () => platform,
ProcessManager: () => FakeProcessManager.any(),
});
test('release asset server serves content from flutter root', () => testbed.run(() async {
testUsingContext('release asset server serves content from flutter root', () async {
final ReleaseAssetServer assetServer = ReleaseAssetServer(Uri.base);
globals.fs.file(globals.fs.path.join('flutter', 'bar.dart'))
fileSystem.file('flutter/bar.dart')
..createSync(recursive: true)
..writeAsStringSync('void main() { }');
final Response response = await assetServer
.handle(Request('GET', Uri.parse('http://localhost:8080/flutter/bar.dart')));
expect(response.statusCode, HttpStatus.ok);
}));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
Platform: () => platform,
ProcessManager: () => FakeProcessManager.any(),
});
test('release asset server serves content from project directory', () => testbed.run(() async {
testUsingContext('release asset server serves content from project directory', () async {
final ReleaseAssetServer assetServer = ReleaseAssetServer(Uri.base);
globals.fs.file(globals.fs.path.join('bar.dart'))
fileSystem.file('bar.dart')
..createSync(recursive: true)
..writeAsStringSync('void main() { }');
final Response response = await assetServer
.handle(Request('GET', Uri.parse('http://localhost:8080/bar.dart')));
expect(response.statusCode, HttpStatus.ok);
}));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
Platform: () => platform,
ProcessManager: () => FakeProcessManager.any(),
});
}
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