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

[flutter_tools] fix root directory tests (#60060)

* fix test compiler test
* fix project test
* fix flutter_platform_test
* fix cocoapods test
parent 1c1326ad
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // 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/base/io.dart';
import 'package:flutter_tools/src/base/platform.dart'; import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/build_info.dart';
...@@ -15,6 +17,13 @@ import '../src/common.dart'; ...@@ -15,6 +17,13 @@ import '../src/common.dart';
import '../src/context.dart'; import '../src/context.dart';
void main() { void main() {
FileSystem fileSystem;
setUp(() {
fileSystem = MemoryFileSystem.test();
fileSystem.file('.packages').writeAsStringSync('\n');
});
group('FlutterPlatform', () { group('FlutterPlatform', () {
testUsingContext('ensureConfiguration throws an error if an ' testUsingContext('ensureConfiguration throws an error if an '
'explicitObservatoryPort is specified and more than one test file', () async { 'explicitObservatoryPort is specified and more than one test file', () async {
...@@ -27,6 +36,9 @@ void main() { ...@@ -27,6 +36,9 @@ void main() {
flutterPlatform.loadChannel('test1.dart', MockSuitePlatform()); flutterPlatform.loadChannel('test1.dart', MockSuitePlatform());
expect(() => flutterPlatform.loadChannel('test2.dart', MockSuitePlatform()), throwsToolExit()); expect(() => flutterPlatform.loadChannel('test2.dart', MockSuitePlatform()), throwsToolExit());
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
}); });
testUsingContext('ensureConfiguration throws an error if a precompiled ' testUsingContext('ensureConfiguration throws an error if a precompiled '
...@@ -40,6 +52,9 @@ void main() { ...@@ -40,6 +52,9 @@ void main() {
flutterPlatform.loadChannel('test1.dart', MockSuitePlatform()); flutterPlatform.loadChannel('test1.dart', MockSuitePlatform());
expect(() => flutterPlatform.loadChannel('test2.dart', MockSuitePlatform()), throwsToolExit()); expect(() => flutterPlatform.loadChannel('test2.dart', MockSuitePlatform()), throwsToolExit());
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
}); });
group('The FLUTTER_TEST environment variable is passed to the test process', () { group('The FLUTTER_TEST environment variable is passed to the test process', () {
...@@ -49,6 +64,7 @@ void main() { ...@@ -49,6 +64,7 @@ void main() {
final Map<Type, Generator> contextOverrides = <Type, Generator>{ final Map<Type, Generator> contextOverrides = <Type, Generator>{
Platform: () => mockPlatform, Platform: () => mockPlatform,
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
FileSystem: () => fileSystem,
}; };
setUp(() { setUp(() {
......
...@@ -25,7 +25,7 @@ import '../../src/context.dart'; ...@@ -25,7 +25,7 @@ import '../../src/context.dart';
typedef InvokeProcess = Future<ProcessResult> Function(); typedef InvokeProcess = Future<ProcessResult> Function();
void main() { void main() {
FileSystem fs; FileSystem fileSystem;
ProcessManager mockProcessManager; ProcessManager mockProcessManager;
MockXcodeProjectInterpreter mockXcodeProjectInterpreter; MockXcodeProjectInterpreter mockXcodeProjectInterpreter;
FlutterProject projectUnderTest; FlutterProject projectUnderTest;
...@@ -42,7 +42,7 @@ void main() { ...@@ -42,7 +42,7 @@ void main() {
} }
void podsIsInHomeDir() { void podsIsInHomeDir() {
fs.directory(fs.path.join( fileSystem.directory(fileSystem.path.join(
globals.fsUtils.homeDirPath, globals.fsUtils.homeDirPath,
'.cocoapods', '.cocoapods',
'repos', 'repos',
...@@ -51,26 +51,26 @@ void main() { ...@@ -51,26 +51,26 @@ void main() {
} }
String podsIsInCustomDir({String cocoapodsReposDir}) { String podsIsInCustomDir({String cocoapodsReposDir}) {
cocoapodsReposDir ??= fs.path.join( cocoapodsReposDir ??= fileSystem.path.join(
globals.fsUtils.homeDirPath, globals.fsUtils.homeDirPath,
'cache', 'cache',
'cocoapods', 'cocoapods',
'repos', 'repos',
); );
fs.directory(fs.path.join(cocoapodsReposDir, 'master')).createSync(recursive: true); fileSystem.directory(fileSystem.path.join(cocoapodsReposDir, 'master')).createSync(recursive: true);
return cocoapodsReposDir; return cocoapodsReposDir;
} }
setUp(() async { setUp(() async {
Cache.flutterRoot = 'flutter'; Cache.flutterRoot = 'flutter';
fs = MemoryFileSystem(); fileSystem = MemoryFileSystem.test();
mockProcessManager = MockProcessManager(); mockProcessManager = MockProcessManager();
logger = BufferLogger.test(); logger = BufferLogger.test();
mockXcodeProjectInterpreter = MockXcodeProjectInterpreter(); mockXcodeProjectInterpreter = MockXcodeProjectInterpreter();
projectUnderTest = FlutterProject.fromDirectory(fs.directory('project')); projectUnderTest = FlutterProject.fromDirectory(fileSystem.directory('project'));
projectUnderTest.ios.xcodeProject.createSync(recursive: true); projectUnderTest.ios.xcodeProject.createSync(recursive: true);
cocoaPodsUnderTest = CocoaPods( cocoaPodsUnderTest = CocoaPods(
fileSystem: fs, fileSystem: fileSystem,
processManager: mockProcessManager, processManager: mockProcessManager,
logger: logger, logger: logger,
platform: FakePlatform(), platform: FakePlatform(),
...@@ -78,17 +78,17 @@ void main() { ...@@ -78,17 +78,17 @@ void main() {
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
); );
pretendPodVersionIs('1.8.0'); pretendPodVersionIs('1.8.0');
fs.file(fs.path.join( fileSystem.file(fileSystem.path.join(
Cache.flutterRoot, 'packages', 'flutter_tools', 'templates', 'cocoapods', 'Podfile-ios-objc', Cache.flutterRoot, 'packages', 'flutter_tools', 'templates', 'cocoapods', 'Podfile-ios-objc',
)) ))
..createSync(recursive: true) ..createSync(recursive: true)
..writeAsStringSync('Objective-C iOS podfile template'); ..writeAsStringSync('Objective-C iOS podfile template');
fs.file(fs.path.join( fileSystem.file(fileSystem.path.join(
Cache.flutterRoot, 'packages', 'flutter_tools', 'templates', 'cocoapods', 'Podfile-ios-swift', Cache.flutterRoot, 'packages', 'flutter_tools', 'templates', 'cocoapods', 'Podfile-ios-swift',
)) ))
..createSync(recursive: true) ..createSync(recursive: true)
..writeAsStringSync('Swift iOS podfile template'); ..writeAsStringSync('Swift iOS podfile template');
fs.file(fs.path.join( fileSystem.file(fileSystem.path.join(
Cache.flutterRoot, 'packages', 'flutter_tools', 'templates', 'cocoapods', 'Podfile-macos', Cache.flutterRoot, 'packages', 'flutter_tools', 'templates', 'cocoapods', 'Podfile-macos',
)) ))
..createSync(recursive: true) ..createSync(recursive: true)
...@@ -108,6 +108,7 @@ void main() { ...@@ -108,6 +108,7 @@ void main() {
workingDirectory: 'project/macos', workingDirectory: 'project/macos',
environment: <String, String>{'FLUTTER_FRAMEWORK_DIR': 'engine/path', 'COCOAPODS_DISABLE_STATS': 'true', 'LANG': 'en_US.UTF-8'}, environment: <String, String>{'FLUTTER_FRAMEWORK_DIR': 'engine/path', 'COCOAPODS_DISABLE_STATS': 'true', 'LANG': 'en_US.UTF-8'},
)).thenAnswer((_) async => exitsHappy()); )).thenAnswer((_) async => exitsHappy());
fileSystem.file('.packages').writeAsStringSync('\n');
}); });
void pretendPodIsNotInstalled() { void pretendPodIsNotInstalled() {
...@@ -226,7 +227,7 @@ void main() { ...@@ -226,7 +227,7 @@ void main() {
expect(projectUnderTest.ios.podfile.readAsStringSync(), 'Swift iOS podfile template'); expect(projectUnderTest.ios.podfile.readAsStringSync(), 'Swift iOS podfile template');
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter, XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
}); });
...@@ -246,7 +247,7 @@ void main() { ...@@ -246,7 +247,7 @@ void main() {
expect(projectUnderTest.ios.podfile.readAsStringSync(), 'Existing Podfile'); expect(projectUnderTest.ios.podfile.readAsStringSync(), 'Existing Podfile');
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
}); });
...@@ -258,7 +259,7 @@ void main() { ...@@ -258,7 +259,7 @@ void main() {
expect(projectUnderTest.ios.podfile.existsSync(), false); expect(projectUnderTest.ios.podfile.existsSync(), false);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter, XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
}); });
...@@ -284,7 +285,7 @@ void main() { ...@@ -284,7 +285,7 @@ void main() {
'#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"\n')); '#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"\n'));
expect(releaseContents, contains('Existing release config')); expect(releaseContents, contains('Existing release config'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
}); });
}); });
...@@ -313,7 +314,7 @@ void main() { ...@@ -313,7 +314,7 @@ void main() {
'#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"\n')); '#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"\n'));
expect(releaseContents, contains('Existing release config')); expect(releaseContents, contains('Existing release config'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
}); });
}); });
...@@ -358,7 +359,7 @@ void main() { ...@@ -358,7 +359,7 @@ void main() {
testWithoutContext('prints warning, if Podfile creates the Flutter engine symlink', () async { testWithoutContext('prints warning, if Podfile creates the Flutter engine symlink', () async {
pretendPodIsInstalled(); pretendPodIsInstalled();
fs.file(fs.path.join('project', 'ios', 'Podfile')) fileSystem.file(fileSystem.path.join('project', 'ios', 'Podfile'))
..createSync() ..createSync()
..writeAsStringSync('Existing Podfile'); ..writeAsStringSync('Existing Podfile');
...@@ -376,7 +377,7 @@ void main() { ...@@ -376,7 +377,7 @@ void main() {
testWithoutContext('prints warning, if Podfile parses .flutter-plugins', () async { testWithoutContext('prints warning, if Podfile parses .flutter-plugins', () async {
pretendPodIsInstalled(); pretendPodIsInstalled();
fs.file(fs.path.join('project', 'ios', 'Podfile')) fileSystem.file(fileSystem.path.join('project', 'ios', 'Podfile'))
..createSync() ..createSync()
..writeAsStringSync('plugin_pods = parse_KV_file(\'../.flutter-plugins\')'); ..writeAsStringSync('plugin_pods = parse_KV_file(\'../.flutter-plugins\')');
...@@ -407,7 +408,7 @@ void main() { ...@@ -407,7 +408,7 @@ void main() {
testWithoutContext('throws, if specs repo is outdated.', () async { testWithoutContext('throws, if specs repo is outdated.', () async {
pretendPodIsInstalled(); pretendPodIsInstalled();
fs.file(fs.path.join('project', 'ios', 'Podfile')) fileSystem.file(fileSystem.path.join('project', 'ios', 'Podfile'))
..createSync() ..createSync()
..writeAsStringSync('Existing Podfile'); ..writeAsStringSync('Existing Podfile');
...@@ -660,7 +661,7 @@ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by ...@@ -660,7 +661,7 @@ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by
testWithoutContext('succeeds, if specs repo is in CP_REPOS_DIR.', () async { testWithoutContext('succeeds, if specs repo is in CP_REPOS_DIR.', () async {
pretendPodIsInstalled(); pretendPodIsInstalled();
fs.file(fs.path.join('project', 'ios', 'Podfile')) fileSystem.file(fileSystem.path.join('project', 'ios', 'Podfile'))
..createSync() ..createSync()
..writeAsStringSync('Existing Podfile'); ..writeAsStringSync('Existing Podfile');
when(mockProcessManager.run( when(mockProcessManager.run(
......
...@@ -776,6 +776,7 @@ void testInMemory(String description, Future<void> testMethod()) { ...@@ -776,6 +776,7 @@ void testInMemory(String description, Future<void> testMethod()) {
final FileSystem testFileSystem = MemoryFileSystem( final FileSystem testFileSystem = MemoryFileSystem(
style: globals.platform.isWindows ? FileSystemStyle.windows : FileSystemStyle.posix, style: globals.platform.isWindows ? FileSystemStyle.windows : FileSystemStyle.posix,
); );
testFileSystem.file('.packages').writeAsStringSync('\n');
// Transfer needed parts of the Flutter installation folder // Transfer needed parts of the Flutter installation folder
// to the in-memory file system used during testing. // to the in-memory file system used during testing.
transfer(Cache().getArtifactDirectory('gradle_wrapper'), testFileSystem); transfer(Cache().getArtifactDirectory('gradle_wrapper'), testFileSystem);
......
...@@ -2,11 +2,14 @@ ...@@ -2,11 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:file/memory.dart';
import 'package:file_testing/file_testing.dart'; import 'package:file_testing/file_testing.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart'; import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/compile.dart'; import 'package:flutter_tools/src/compile.dart';
import 'package:flutter_tools/src/globals.dart' as globals; import 'package:flutter_tools/src/dart/package_map.dart';
import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/test/test_compiler.dart'; import 'package:flutter_tools/src/test/test_compiler.dart';
import 'package:mockito/mockito.dart'; import 'package:mockito/mockito.dart';
...@@ -21,85 +24,117 @@ final Platform linuxPlatform = FakePlatform( ...@@ -21,85 +24,117 @@ final Platform linuxPlatform = FakePlatform(
); );
void main() { void main() {
group(TestCompiler, () { MockResidentCompiler residentCompiler;
Testbed testbed; FileSystem fileSystem;
FakeTestCompiler testCompiler;
MockResidentCompiler residentCompiler; setUp(() {
fileSystem = MemoryFileSystem.test();
setUp(() { fileSystem.file('pubspec.yaml').createSync();
testbed = Testbed( fileSystem.file('.packages').writeAsStringSync('flutter_test:flutter_test/');
overrides: <Type, Generator>{ fileSystem.file('test/foo.dart').createSync(recursive: true);
Platform: () => linuxPlatform, fileSystem.file(globalPackagesPath)
}, ..createSync()
setup: () async { ..writeAsStringSync('flutter_test:flutter_test/');
globals.fs.file('pubspec.yaml').createSync(); residentCompiler = MockResidentCompiler();
globals.fs.file('.packages').writeAsStringSync('flutter_test:flutter_test/'); });
globals.fs.file('test/foo.dart').createSync(recursive: true);
residentCompiler = MockResidentCompiler(); testUsingContext('TestCompiler reports a dill file when compile is successful', () async {
testCompiler = FakeTestCompiler( final FakeTestCompiler testCompiler = FakeTestCompiler(
BuildMode.debug, BuildMode.debug,
false, false,
FlutterProject.current(), FlutterProject.current(),
residentCompiler, residentCompiler,
); );
}, when(residentCompiler.recompile(
); any,
<Uri>[Uri.parse('test/foo.dart')],
outputPath: testCompiler.outputDill.path,
packageConfig: anyNamed('packageConfig'),
)).thenAnswer((Invocation invocation) async {
fileSystem.file('abc.dill').createSync();
return const CompilerOutput('abc.dill', 0, <Uri>[]);
});
expect(await testCompiler.compile(Uri.parse('test/foo.dart')), 'test/foo.dart.dill');
expect(fileSystem.file('test/foo.dart.dill'), exists);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
Platform: () => linuxPlatform,
ProcessManager: () => FakeProcessManager.any(),
Logger: () => BufferLogger.test(),
});
testUsingContext('TestCompiler reports null when a compile fails', () async {
final FakeTestCompiler testCompiler = FakeTestCompiler(
BuildMode.debug,
false,
FlutterProject.current(),
residentCompiler,
);
when(residentCompiler.recompile(
any,
<Uri>[Uri.parse('test/foo.dart')],
outputPath: testCompiler.outputDill.path,
packageConfig: anyNamed('packageConfig'),
)).thenAnswer((Invocation invocation) async {
fileSystem.file('abc.dill').createSync();
return const CompilerOutput('abc.dill', 1, <Uri>[]);
}); });
test('Reports a dill file when compile is successful', () => testbed.run(() async { expect(await testCompiler.compile(Uri.parse('test/foo.dart')), null);
when(residentCompiler.recompile( expect(fileSystem.file('test/foo.dart.dill'), isNot(exists));
any, verify(residentCompiler.shutdown()).called(1);
<Uri>[Uri.parse('test/foo.dart')], }, overrides: <Type, Generator>{
outputPath: testCompiler.outputDill.path, FileSystem: () => fileSystem,
packageConfig: anyNamed('packageConfig'), Platform: () => linuxPlatform,
)).thenAnswer((Invocation invocation) async { ProcessManager: () => FakeProcessManager.any(),
globals.fs.file('abc.dill').createSync(); Logger: () => BufferLogger.test(),
return const CompilerOutput('abc.dill', 0, <Uri>[]); });
});
testUsingContext('TestCompiler disposing test compiler shuts down backing compiler', () async {
expect(await testCompiler.compile(Uri.parse('test/foo.dart')), 'test/foo.dart.dill'); final FakeTestCompiler testCompiler = FakeTestCompiler(
expect(globals.fs.file('test/foo.dart.dill'), exists); BuildMode.debug,
})); false,
FlutterProject.current(),
test('Reports null when a compile fails', () => testbed.run(() async { residentCompiler,
when(residentCompiler.recompile( );
any, testCompiler.compiler = residentCompiler;
<Uri>[Uri.parse('test/foo.dart')],
outputPath: testCompiler.outputDill.path, expect(testCompiler.compilerController.isClosed, false);
packageConfig: anyNamed('packageConfig'),
)).thenAnswer((Invocation invocation) async { await testCompiler.dispose();
globals.fs.file('abc.dill').createSync();
return const CompilerOutput('abc.dill', 1, <Uri>[]); expect(testCompiler.compilerController.isClosed, true);
}); verify(residentCompiler.shutdown()).called(1);
}, overrides: <Type, Generator>{
expect(await testCompiler.compile(Uri.parse('test/foo.dart')), null); FileSystem: () => fileSystem,
expect(globals.fs.file('test/foo.dart.dill'), isNot(exists)); Platform: () => linuxPlatform,
verify(residentCompiler.shutdown()).called(1); ProcessManager: () => FakeProcessManager.any(),
})); Logger: () => BufferLogger.test(),
});
test('Disposing test compiler shuts down backing compiler', () => testbed.run(() async {
testCompiler.compiler = residentCompiler; testUsingContext('TestCompiler reports an error when there is no dependency on flutter_test', () async {
final FakeTestCompiler testCompiler = FakeTestCompiler(
expect(testCompiler.compilerController.isClosed, false); BuildMode.debug,
false,
await testCompiler.dispose(); FlutterProject.current(),
residentCompiler,
expect(testCompiler.compilerController.isClosed, true); );
verify(residentCompiler.shutdown()).called(1); fileSystem.file('.packages').writeAsStringSync('\n');
}));
expect(await testCompiler.compile(Uri.parse('test/foo.dart')), null);
test('Reports an error when there is no dependency on flutter_test', () => testbed.run(() async { expect(testLogger.errorText, contains('Error: cannot run without a dependency on "package:flutter_test"'));
globals.fs.file('.packages').writeAsStringSync('\n'); verifyNever(residentCompiler.recompile(
any,
expect(await testCompiler.compile(Uri.parse('test/foo.dart')), null); <Uri>[Uri.parse('test/foo.dart')],
expect(testLogger.errorText, contains('Error: cannot run without a dependency on "package:flutter_test"')); outputPath: testCompiler.outputDill.path,
verifyNever(residentCompiler.recompile( packageConfig: anyNamed('packageConfig'),
any, ));
<Uri>[Uri.parse('test/foo.dart')], }, overrides: <Type, Generator>{
outputPath: testCompiler.outputDill.path, FileSystem: () => fileSystem,
packageConfig: anyNamed('packageConfig'), Platform: () => linuxPlatform,
)); ProcessManager: () => FakeProcessManager.any(),
})); Logger: () => BufferLogger.test(),
}); });
} }
......
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