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,63 +24,80 @@ final Platform linuxPlatform = FakePlatform( ...@@ -21,63 +24,80 @@ final Platform linuxPlatform = FakePlatform(
); );
void main() { void main() {
group(TestCompiler, () {
Testbed testbed;
FakeTestCompiler testCompiler;
MockResidentCompiler residentCompiler; MockResidentCompiler residentCompiler;
FileSystem fileSystem;
setUp(() { setUp(() {
testbed = Testbed( fileSystem = MemoryFileSystem.test();
overrides: <Type, Generator>{ fileSystem.file('pubspec.yaml').createSync();
Platform: () => linuxPlatform, fileSystem.file('.packages').writeAsStringSync('flutter_test:flutter_test/');
}, fileSystem.file('test/foo.dart').createSync(recursive: true);
setup: () async { fileSystem.file(globalPackagesPath)
globals.fs.file('pubspec.yaml').createSync(); ..createSync()
globals.fs.file('.packages').writeAsStringSync('flutter_test:flutter_test/'); ..writeAsStringSync('flutter_test:flutter_test/');
globals.fs.file('test/foo.dart').createSync(recursive: true);
residentCompiler = MockResidentCompiler(); residentCompiler = MockResidentCompiler();
testCompiler = FakeTestCompiler( });
testUsingContext('TestCompiler reports a dill file when compile is successful', () async {
final FakeTestCompiler testCompiler = FakeTestCompiler(
BuildMode.debug, BuildMode.debug,
false, false,
FlutterProject.current(), FlutterProject.current(),
residentCompiler, residentCompiler,
); );
},
);
});
test('Reports a dill file when compile is successful', () => testbed.run(() async {
when(residentCompiler.recompile( when(residentCompiler.recompile(
any, any,
<Uri>[Uri.parse('test/foo.dart')], <Uri>[Uri.parse('test/foo.dart')],
outputPath: testCompiler.outputDill.path, outputPath: testCompiler.outputDill.path,
packageConfig: anyNamed('packageConfig'), packageConfig: anyNamed('packageConfig'),
)).thenAnswer((Invocation invocation) async { )).thenAnswer((Invocation invocation) async {
globals.fs.file('abc.dill').createSync(); fileSystem.file('abc.dill').createSync();
return const CompilerOutput('abc.dill', 0, <Uri>[]); return const CompilerOutput('abc.dill', 0, <Uri>[]);
}); });
expect(await testCompiler.compile(Uri.parse('test/foo.dart')), 'test/foo.dart.dill'); expect(await testCompiler.compile(Uri.parse('test/foo.dart')), 'test/foo.dart.dill');
expect(globals.fs.file('test/foo.dart.dill'), exists); expect(fileSystem.file('test/foo.dart.dill'), exists);
})); }, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
Platform: () => linuxPlatform,
ProcessManager: () => FakeProcessManager.any(),
Logger: () => BufferLogger.test(),
});
test('Reports null when a compile fails', () => testbed.run(() async { testUsingContext('TestCompiler reports null when a compile fails', () async {
final FakeTestCompiler testCompiler = FakeTestCompiler(
BuildMode.debug,
false,
FlutterProject.current(),
residentCompiler,
);
when(residentCompiler.recompile( when(residentCompiler.recompile(
any, any,
<Uri>[Uri.parse('test/foo.dart')], <Uri>[Uri.parse('test/foo.dart')],
outputPath: testCompiler.outputDill.path, outputPath: testCompiler.outputDill.path,
packageConfig: anyNamed('packageConfig'), packageConfig: anyNamed('packageConfig'),
)).thenAnswer((Invocation invocation) async { )).thenAnswer((Invocation invocation) async {
globals.fs.file('abc.dill').createSync(); fileSystem.file('abc.dill').createSync();
return const CompilerOutput('abc.dill', 1, <Uri>[]); return const CompilerOutput('abc.dill', 1, <Uri>[]);
}); });
expect(await testCompiler.compile(Uri.parse('test/foo.dart')), null); expect(await testCompiler.compile(Uri.parse('test/foo.dart')), null);
expect(globals.fs.file('test/foo.dart.dill'), isNot(exists)); expect(fileSystem.file('test/foo.dart.dill'), isNot(exists));
verify(residentCompiler.shutdown()).called(1); verify(residentCompiler.shutdown()).called(1);
})); }, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
Platform: () => linuxPlatform,
ProcessManager: () => FakeProcessManager.any(),
Logger: () => BufferLogger.test(),
});
test('Disposing test compiler shuts down backing compiler', () => testbed.run(() async { testUsingContext('TestCompiler disposing test compiler shuts down backing compiler', () async {
final FakeTestCompiler testCompiler = FakeTestCompiler(
BuildMode.debug,
false,
FlutterProject.current(),
residentCompiler,
);
testCompiler.compiler = residentCompiler; testCompiler.compiler = residentCompiler;
expect(testCompiler.compilerController.isClosed, false); expect(testCompiler.compilerController.isClosed, false);
...@@ -86,10 +106,21 @@ void main() { ...@@ -86,10 +106,21 @@ void main() {
expect(testCompiler.compilerController.isClosed, true); expect(testCompiler.compilerController.isClosed, true);
verify(residentCompiler.shutdown()).called(1); verify(residentCompiler.shutdown()).called(1);
})); }, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
Platform: () => linuxPlatform,
ProcessManager: () => FakeProcessManager.any(),
Logger: () => BufferLogger.test(),
});
test('Reports an error when there is no dependency on flutter_test', () => testbed.run(() async { testUsingContext('TestCompiler reports an error when there is no dependency on flutter_test', () async {
globals.fs.file('.packages').writeAsStringSync('\n'); final FakeTestCompiler testCompiler = FakeTestCompiler(
BuildMode.debug,
false,
FlutterProject.current(),
residentCompiler,
);
fileSystem.file('.packages').writeAsStringSync('\n');
expect(await testCompiler.compile(Uri.parse('test/foo.dart')), null); expect(await testCompiler.compile(Uri.parse('test/foo.dart')), null);
expect(testLogger.errorText, contains('Error: cannot run without a dependency on "package:flutter_test"')); expect(testLogger.errorText, contains('Error: cannot run without a dependency on "package:flutter_test"'));
...@@ -99,7 +130,11 @@ void main() { ...@@ -99,7 +130,11 @@ void main() {
outputPath: testCompiler.outputDill.path, outputPath: testCompiler.outputDill.path,
packageConfig: anyNamed('packageConfig'), packageConfig: anyNamed('packageConfig'),
)); ));
})); }, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
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