Unverified Commit 251e82d2 authored by Chris Bracken's avatar Chris Bracken Committed by GitHub

Migrate devfs tests to Dart 2 (#21285)

DevFS.update only runs in Dart 2 mode when the generator parameter is
supplied. In Dart 2 mode, both mainPath and pathToReload are required
parameters; this patch marks them as such.

generator is required for running in Dart 2. All call sites other than tests already explicitly set this value.

Note the statements on line 510 and line 516 for why mainPath and pathToReload are required.
parent 9d0084ff
...@@ -6,6 +6,7 @@ import 'dart:async'; ...@@ -6,6 +6,7 @@ import 'dart:async';
import 'dart:convert' show base64, utf8; import 'dart:convert' show base64, utf8;
import 'package:json_rpc_2/json_rpc_2.dart' as rpc; import 'package:json_rpc_2/json_rpc_2.dart' as rpc;
import 'package:meta/meta.dart';
import 'asset.dart'; import 'asset.dart';
import 'base/context.dart'; import 'base/context.dart';
...@@ -401,18 +402,18 @@ class DevFS { ...@@ -401,18 +402,18 @@ class DevFS {
/// ///
/// Returns the number of bytes synced. /// Returns the number of bytes synced.
Future<int> update({ Future<int> update({
String mainPath, @required String mainPath,
String target, String target,
AssetBundle bundle, AssetBundle bundle,
DateTime firstBuildTime, DateTime firstBuildTime,
bool bundleFirstUpload = false, bool bundleFirstUpload = false,
bool bundleDirty = false, bool bundleDirty = false,
Set<String> fileFilter, Set<String> fileFilter,
ResidentCompiler generator, @required ResidentCompiler generator,
String dillOutputPath, String dillOutputPath,
bool fullRestart = false, bool fullRestart = false,
String projectRootPath, String projectRootPath,
String pathToReload, @required String pathToReload,
}) async { }) async {
// Mark all entries as possibly deleted. // Mark all entries as possibly deleted.
for (DevFSContent content in _entries.values) { for (DevFSContent content in _entries.values) {
......
...@@ -66,6 +66,7 @@ void main() { ...@@ -66,6 +66,7 @@ void main() {
group('devfs local', () { group('devfs local', () {
final MockDevFSOperations devFSOperations = new MockDevFSOperations(); final MockDevFSOperations devFSOperations = new MockDevFSOperations();
final MockResidentCompiler residentCompiler = new MockResidentCompiler();
setUpAll(() { setUpAll(() {
tempDir = _newTempDir(fs); tempDir = _newTempDir(fs);
...@@ -88,22 +89,17 @@ void main() { ...@@ -88,22 +89,17 @@ void main() {
devFSOperations.expectMessages(<String>['create test']); devFSOperations.expectMessages(<String>['create test']);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
final int bytes = await devFS.update(); final int bytes = await devFS.update(
mainPath: 'lib/foo.txt',
generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill',
);
devFSOperations.expectMessages(<String>[ devFSOperations.expectMessages(<String>[
'writeFile test .packages', 'writeFile test lib/foo.txt.dill',
'writeFile test lib/foo.txt',
'writeFile test packages/somepkg/somefile.txt',
]); ]);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
final List<String> packageSpecOnDevice = LineSplitter.split(utf8.decode( expect(bytes, 22);
await devFSOperations.devicePathToContent[fs.path.toUri('.packages')].contentsAsBytes()
)).toList();
expect(packageSpecOnDevice,
unorderedEquals(<String>['my_project:lib/', 'somepkg:packages/somepkg/'])
);
expect(bytes, 48);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
}); });
...@@ -112,48 +108,57 @@ void main() { ...@@ -112,48 +108,57 @@ void main() {
final File file = fs.file(fs.path.join(basePath, filePath2)); final File file = fs.file(fs.path.join(basePath, filePath2));
await file.parent.create(recursive: true); await file.parent.create(recursive: true);
file.writeAsBytesSync(<int>[1, 2, 3, 4, 5, 6, 7]); file.writeAsBytesSync(<int>[1, 2, 3, 4, 5, 6, 7]);
final int bytes = await devFS.update(); final int bytes = await devFS.update(
mainPath: 'lib/foo.txt',
generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill',
);
devFSOperations.expectMessages(<String>[ devFSOperations.expectMessages(<String>[
'writeFile test foo/bar.txt', 'writeFile test lib/foo.txt.dill',
]); ]);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
expect(bytes, 7); expect(bytes, 22);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
}); });
testUsingContext('add new file to local file system and preserve unusual file name casing', () async { testUsingContext('modify existing file on local file system', () async {
final String filePathWithUnusualCasing = fs.path.join('FooBar', 'TEST.txt'); int bytes = await devFS.update(
final File file = fs.file(fs.path.join(basePath, filePathWithUnusualCasing)); mainPath: 'lib/foo.txt',
await file.parent.create(recursive: true); generator: residentCompiler,
file.writeAsBytesSync(<int>[1, 2, 3, 4, 5, 6, 7]); pathToReload: 'lib/foo.txt.dill',
final int bytes = await devFS.update(); );
devFSOperations.expectMessages(<String>[ devFSOperations.expectMessages(<String>[
'writeFile test FooBar/TEST.txt', 'writeFile test lib/foo.txt.dill',
]); ]);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
expect(bytes, 7); expect(bytes, 22);
}, overrides: <Type, Generator>{
FileSystem: () => fs,
});
testUsingContext('modify existing file on local file system', () async {
await devFS.update();
final File file = fs.file(fs.path.join(basePath, filePath)); final File file = fs.file(fs.path.join(basePath, filePath));
// Set the last modified time to 5 seconds in the past. // Set the last modified time to 5 seconds in the past.
updateFileModificationTime(file.path, new DateTime.now(), -5); updateFileModificationTime(file.path, new DateTime.now(), -5);
int bytes = await devFS.update(); bytes = await devFS.update(
devFSOperations.expectMessages(<String>[]); mainPath: 'lib/foo.txt',
generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill',
);
devFSOperations.expectMessages(<String>[
'writeFile test lib/foo.txt.dill',
]);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
expect(bytes, 0); expect(bytes, 22);
await file.writeAsBytes(<int>[1, 2, 3, 4, 5, 6]); await file.writeAsBytes(<int>[1, 2, 3, 4, 5, 6]);
bytes = await devFS.update(); bytes = await devFS.update(
mainPath: 'lib/foo.txt',
generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill',
);
devFSOperations.expectMessages(<String>[ devFSOperations.expectMessages(<String>[
'writeFile test lib/foo.txt', 'writeFile test lib/foo.txt.dill',
]); ]);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
expect(bytes, 6); expect(bytes, 22);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
}); });
...@@ -161,25 +166,33 @@ void main() { ...@@ -161,25 +166,33 @@ void main() {
testUsingContext('delete a file from the local file system', () async { testUsingContext('delete a file from the local file system', () async {
final File file = fs.file(fs.path.join(basePath, filePath)); final File file = fs.file(fs.path.join(basePath, filePath));
await file.delete(); await file.delete();
final int bytes = await devFS.update(); final int bytes = await devFS.update(
mainPath: 'lib/foo.txt',
generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill',
);
devFSOperations.expectMessages(<String>[ devFSOperations.expectMessages(<String>[
'deleteFile test lib/foo.txt', 'deleteFile test lib/foo.txt',
'writeFile test lib/foo.txt.dill',
]); ]);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
expect(bytes, 0); expect(bytes, 22);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
}); });
testUsingContext('add new package', () async { testUsingContext('add new package', () async {
await _createPackage(fs, 'newpkg', 'anotherfile.txt'); await _createPackage(fs, 'newpkg', 'anotherfile.txt');
final int bytes = await devFS.update(); final int bytes = await devFS.update(
mainPath: 'lib/foo.txt',
generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill',
);
devFSOperations.expectMessages(<String>[ devFSOperations.expectMessages(<String>[
'writeFile test .packages', 'writeFile test lib/foo.txt.dill',
'writeFile test packages/newpkg/anotherfile.txt',
]); ]);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
expect(bytes, 69); expect(bytes, 22);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
}); });
...@@ -200,85 +213,122 @@ void main() { ...@@ -200,85 +213,122 @@ void main() {
.map<String>((File file) => canonicalizePath(file.path)) .map<String>((File file) => canonicalizePath(file.path))
.toList()); .toList());
} }
final int bytes = await devFS.update(fileFilter: fileFilter); final int bytes = await devFS.update(
mainPath: 'lib/foo.txt',
fileFilter: fileFilter,
generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill',
);
devFSOperations.expectMessages(<String>[ devFSOperations.expectMessages(<String>[
'writeFile test .packages', 'writeFile test lib/foo.txt.dill',
'writeFile test packages/doubleslashpkg/somefile.txt',
]); ]);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
expect(bytes, 109); expect(bytes, 22);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
}); });
testUsingContext('add an asset bundle', () async { testUsingContext('add an asset bundle', () async {
assetBundle.entries['a.txt'] = new DevFSStringContent('abc'); assetBundle.entries['a.txt'] = new DevFSStringContent('abc');
final int bytes = await devFS.update(bundle: assetBundle, bundleDirty: true); final int bytes = await devFS.update(
mainPath: 'lib/foo.txt',
bundle: assetBundle,
bundleDirty: true,
generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill',
);
devFSOperations.expectMessages(<String>[ devFSOperations.expectMessages(<String>[
'writeFile test ${_inAssetBuildDirectory(fs, 'a.txt')}', 'writeFile test ${_inAssetBuildDirectory(fs, 'a.txt')}',
'writeFile test lib/foo.txt.dill',
]); ]);
expect(devFS.assetPathsToEvict, unorderedMatches(<String>['a.txt'])); expect(devFS.assetPathsToEvict, unorderedMatches(<String>['a.txt']));
devFS.assetPathsToEvict.clear(); devFS.assetPathsToEvict.clear();
expect(bytes, 3); expect(bytes, 25);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
}); });
testUsingContext('add a file to the asset bundle - bundleDirty', () async { testUsingContext('add a file to the asset bundle - bundleDirty', () async {
assetBundle.entries['b.txt'] = new DevFSStringContent('abcd'); assetBundle.entries['b.txt'] = new DevFSStringContent('abcd');
final int bytes = await devFS.update(bundle: assetBundle, bundleDirty: true); final int bytes = await devFS.update(
mainPath: 'lib/foo.txt',
bundle: assetBundle,
bundleDirty: true,
generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill',
);
// Expect entire asset bundle written because bundleDirty is true // Expect entire asset bundle written because bundleDirty is true
devFSOperations.expectMessages(<String>[ devFSOperations.expectMessages(<String>[
'writeFile test ${_inAssetBuildDirectory(fs, 'a.txt')}', 'writeFile test ${_inAssetBuildDirectory(fs, 'a.txt')}',
'writeFile test ${_inAssetBuildDirectory(fs, 'b.txt')}', 'writeFile test ${_inAssetBuildDirectory(fs, 'b.txt')}',
'writeFile test lib/foo.txt.dill',
]); ]);
expect(devFS.assetPathsToEvict, unorderedMatches(<String>[ expect(devFS.assetPathsToEvict, unorderedMatches(<String>[
'a.txt', 'b.txt'])); 'a.txt', 'b.txt']));
devFS.assetPathsToEvict.clear(); devFS.assetPathsToEvict.clear();
expect(bytes, 7); expect(bytes, 29);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
}); });
testUsingContext('add a file to the asset bundle', () async { testUsingContext('add a file to the asset bundle', () async {
assetBundle.entries['c.txt'] = new DevFSStringContent('12'); assetBundle.entries['c.txt'] = new DevFSStringContent('12');
final int bytes = await devFS.update(bundle: assetBundle); final int bytes = await devFS.update(
mainPath: 'lib/foo.txt',
bundle: assetBundle,
generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill',
);
devFSOperations.expectMessages(<String>[ devFSOperations.expectMessages(<String>[
'writeFile test ${_inAssetBuildDirectory(fs, 'c.txt')}', 'writeFile test ${_inAssetBuildDirectory(fs, 'c.txt')}',
'writeFile test lib/foo.txt.dill',
]); ]);
expect(devFS.assetPathsToEvict, unorderedMatches(<String>[ expect(devFS.assetPathsToEvict, unorderedMatches(<String>[
'c.txt'])); 'c.txt']));
devFS.assetPathsToEvict.clear(); devFS.assetPathsToEvict.clear();
expect(bytes, 2); expect(bytes, 24);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
}); });
testUsingContext('delete a file from the asset bundle', () async { testUsingContext('delete a file from the asset bundle', () async {
assetBundle.entries.remove('c.txt'); assetBundle.entries.remove('c.txt');
final int bytes = await devFS.update(bundle: assetBundle); final int bytes = await devFS.update(
mainPath: 'lib/foo.txt',
bundle: assetBundle,
generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill',
);
devFSOperations.expectMessages(<String>[ devFSOperations.expectMessages(<String>[
'deleteFile test ${_inAssetBuildDirectory(fs, 'c.txt')}', 'deleteFile test ${_inAssetBuildDirectory(fs, 'c.txt')}',
'writeFile test lib/foo.txt.dill',
]); ]);
expect(devFS.assetPathsToEvict, unorderedMatches(<String>['c.txt'])); expect(devFS.assetPathsToEvict, unorderedMatches(<String>['c.txt']));
devFS.assetPathsToEvict.clear(); devFS.assetPathsToEvict.clear();
expect(bytes, 0); expect(bytes, 22);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
}); });
testUsingContext('delete all files from the asset bundle', () async { testUsingContext('delete all files from the asset bundle', () async {
assetBundle.entries.clear(); assetBundle.entries.clear();
final int bytes = await devFS.update(bundle: assetBundle, bundleDirty: true); final int bytes = await devFS.update(
mainPath: 'lib/foo.txt',
bundle: assetBundle,
bundleDirty: true,
generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill',
);
devFSOperations.expectMessages(<String>[ devFSOperations.expectMessages(<String>[
'deleteFile test ${_inAssetBuildDirectory(fs, 'a.txt')}', 'deleteFile test ${_inAssetBuildDirectory(fs, 'a.txt')}',
'deleteFile test ${_inAssetBuildDirectory(fs, 'b.txt')}', 'deleteFile test ${_inAssetBuildDirectory(fs, 'b.txt')}',
'writeFile test lib/foo.txt.dill',
]); ]);
expect(devFS.assetPathsToEvict, unorderedMatches(<String>[ expect(devFS.assetPathsToEvict, unorderedMatches(<String>[
'a.txt', 'b.txt' 'a.txt', 'b.txt'
])); ]));
devFS.assetPathsToEvict.clear(); devFS.assetPathsToEvict.clear();
expect(bytes, 0); expect(bytes, 22);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
}); });
...@@ -294,6 +344,7 @@ void main() { ...@@ -294,6 +344,7 @@ void main() {
group('devfs remote', () { group('devfs remote', () {
MockVMService vmService; MockVMService vmService;
final MockResidentCompiler residentCompiler = new MockResidentCompiler();
setUpAll(() async { setUpAll(() async {
tempDir = _newTempDir(fs); tempDir = _newTempDir(fs);
...@@ -320,14 +371,16 @@ void main() { ...@@ -320,14 +371,16 @@ void main() {
vmService.expectMessages(<String>['create test']); vmService.expectMessages(<String>['create test']);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
final int bytes = await devFS.update(); final int bytes = await devFS.update(
mainPath: 'lib/foo.txt',
generator: residentCompiler,
pathToReload: 'lib/foo.txt.dill',
);
vmService.expectMessages(<String>[ vmService.expectMessages(<String>[
'writeFile test .packages', 'writeFile test lib/foo.txt.dill',
'writeFile test lib/foo.txt',
'writeFile test packages/somepkg/somefile.txt',
]); ]);
expect(devFS.assetPathsToEvict, isEmpty); expect(devFS.assetPathsToEvict, isEmpty);
expect(bytes, 48); expect(bytes, 22);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fs, FileSystem: () => fs,
}); });
......
...@@ -12,6 +12,7 @@ import 'package:flutter_tools/src/application_package.dart'; ...@@ -12,6 +12,7 @@ import 'package:flutter_tools/src/application_package.dart';
import 'package:flutter_tools/src/base/file_system.dart' hide IOSink; import 'package:flutter_tools/src/base/file_system.dart' hide IOSink;
import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/base/io.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/devfs.dart'; import 'package:flutter_tools/src/devfs.dart';
import 'package:flutter_tools/src/device.dart'; import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/ios/devices.dart'; import 'package:flutter_tools/src/ios/devices.dart';
...@@ -431,3 +432,35 @@ class MockDevFSOperations extends BasicMock implements DevFSOperations { ...@@ -431,3 +432,35 @@ class MockDevFSOperations extends BasicMock implements DevFSOperations {
devicePathToContent.remove(deviceUri); devicePathToContent.remove(deviceUri);
} }
} }
class MockResidentCompiler extends BasicMock implements ResidentCompiler {
@override
void accept() {}
@override
void reject() {}
@override
void reset() {}
@override
Future<dynamic> shutdown() async {}
@override
Future<CompilerOutput> compileExpression(
String expression,
List<String> definitions,
List<String> typeDefinitions,
String libraryUri,
String klass,
bool isStatic
) async {
return null;
}
@override
Future<CompilerOutput> recompile(String mainPath, List<String> invalidatedFiles, {String outputPath, String packagesFilePath}) async {
fs.file(outputPath).createSync(recursive: true);
fs.file(outputPath).writeAsStringSync('compiled_kernel_output');
return new CompilerOutput(outputPath, 0);
}
}
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