Chromium Code Reviews| Index: pkg/front_end/test/src/base/processed_options_test.dart |
| diff --git a/pkg/front_end/test/src/base/processed_options_test.dart b/pkg/front_end/test/src/base/processed_options_test.dart |
| index 349cd08e5fa072e0b6de3b9e80a5bf090ada6e09..2f34edc5f8b0ee73629714ea79499f0805b9ca5a 100644 |
| --- a/pkg/front_end/test/src/base/processed_options_test.dart |
| +++ b/pkg/front_end/test/src/base/processed_options_test.dart |
| @@ -8,8 +8,10 @@ import 'package:front_end/compiler_options.dart'; |
| import 'package:front_end/memory_file_system.dart'; |
| import 'package:front_end/src/base/processed_options.dart'; |
| import 'package:front_end/src/fasta/fasta.dart' show ByteSink; |
| +import 'package:front_end/src/fasta/fasta_codes.dart'; |
| import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter; |
| import 'package:kernel/kernel.dart' show Program, Library, CanonicalName; |
| +import 'package:package_config/packages.dart' show Packages; |
| import 'package:test/test.dart'; |
| import 'package:test_reflective_loader/test_reflective_loader.dart'; |
| @@ -22,7 +24,7 @@ main() { |
| @reflectiveTest |
| class ProcessedOptionsTest { |
| - final fileSystem = new MemoryFileSystem(Uri.parse('file:///')); |
| + MemoryFileSystem fileSystem = new MemoryFileSystem(Uri.parse('file:///')); |
| Program _mockOutline; |
| @@ -82,6 +84,13 @@ class ProcessedOptionsTest { |
| mockSummary.libraries.single.importUri); |
| } |
| + checkPackageExpansion( |
| + String packageName, String packageDir, Packages packages) { |
| + var input = Uri.parse('package:$packageName/a.dart'); |
| + var expected = Uri.parse('file:///$packageDir/a.dart'); |
|
ahe
2017/07/14 13:44:58
Is this a real file or a fake URI?
Siggi Cherem (dart-lang)
2017/07/14 19:54:07
All fake. Tracked in https://github.com/dart-lang/
|
| + expect(packages.resolve(input), expected); |
| + } |
| + |
| test_getUriTranslator_explicitPackagesFile() async { |
| // This .packages file should be ignored. |
| fileSystem |
| @@ -96,7 +105,7 @@ class ProcessedOptionsTest { |
| ..packagesFileUri = Uri.parse('file:///explicit.packages'); |
| var processed = new ProcessedOptions(raw); |
| var uriTranslator = await processed.getUriTranslator(); |
| - expect(uriTranslator.packages, {'foo': Uri.parse('file:///baz/')}); |
| + checkPackageExpansion('foo', 'baz', uriTranslator.packages); |
| } |
| test_getUriTranslator_explicitPackagesFile_withBaseLocation() async { |
| @@ -113,21 +122,152 @@ class ProcessedOptionsTest { |
| ..packagesFileUri = Uri.parse('file:///base/location/explicit.packages'); |
| var processed = new ProcessedOptions(raw); |
| var uriTranslator = await processed.getUriTranslator(); |
| - expect(uriTranslator.packages, |
| - {'foo': Uri.parse('file:///base/location/baz/')}); |
| + checkPackageExpansion('foo', 'base/location/baz', uriTranslator.packages); |
| + } |
| + |
| + test_getUriTranslator_implicitPackagesFile_ambiguous() async { |
| + // This .packages file should be ignored. |
| + fileSystem |
| + .entityForUri(Uri.parse('file:///.packages')) |
|
ahe
2017/07/14 13:44:58
Use custom URI.
I don't like seeing error message
Siggi Cherem (dart-lang)
2017/07/14 19:54:06
tracking here https://github.com/dart-lang/sdk/iss
|
| + .writeAsStringSync('foo:bar\n'); |
| + // This one should be used. |
| + fileSystem |
| + .entityForUri(Uri.parse('file:///explicit.packages')) |
| + .writeAsStringSync('foo:baz\n'); |
| + var raw = new CompilerOptions() |
| + ..fileSystem = fileSystem |
| + ..packagesFileUri = Uri.parse('file:///explicit.packages'); |
| + var processed = new ProcessedOptions(raw); |
| + var uriTranslator = await processed.getUriTranslator(); |
| + checkPackageExpansion('foo', 'baz', uriTranslator.packages); |
| + } |
| + |
| + test_getUriTranslator_implicitPackagesFile_nextToScript() async { |
| + // Fake the existence of the base directory. |
| + fileSystem |
| + .entityForUri(Uri.parse('file:///base/location/')) |
| + .writeAsStringSync(''); |
| + // Packages directory should be ignored (.packages file takes precedence). |
| + fileSystem |
| + .entityForUri(Uri.parse('file:///base/location/packages/')) |
| + .writeAsStringSync(''); |
| + // This .packages file should be ignored. |
| + fileSystem |
| + .entityForUri(Uri.parse('file:///.packages')) |
| + .writeAsStringSync('foo:bar\n'); |
| + // This one should be used. |
| + fileSystem |
| + .entityForUri(Uri.parse('file:///base/location/.packages')) |
| + .writeAsStringSync('foo:baz\n'); |
| + var raw = new CompilerOptions()..fileSystem = fileSystem; |
| + var processed = new ProcessedOptions( |
| + raw, false, [Uri.parse('file:///base/location/script.dart')]); |
| + var uriTranslator = await processed.getUriTranslator(); |
| + checkPackageExpansion('foo', 'base/location/baz', uriTranslator.packages); |
| + } |
| + |
| + test_getUriTranslator_implicitPackagesFile_searchAbove() async { |
| + // Fake the existence of the base directory. |
| + fileSystem |
| + .entityForUri(Uri.parse('file:///base/location/')) |
| + .writeAsStringSync(''); |
| + // This .packages file should be ignored. |
| + fileSystem |
| + .entityForUri(Uri.parse('file:///.packages')) |
| + .writeAsStringSync('foo:bar\n'); |
| + // This one should be used. |
| + fileSystem |
| + .entityForUri(Uri.parse('file:///base/.packages')) |
| + .writeAsStringSync('foo:baz\n'); |
| + var raw = new CompilerOptions()..fileSystem = fileSystem; |
| + var processed = new ProcessedOptions( |
| + raw, false, [Uri.parse('file:///base/location/script.dart')]); |
| + var uriTranslator = await processed.getUriTranslator(); |
| + checkPackageExpansion('foo', 'base/baz', uriTranslator.packages); |
| + } |
| + |
| + test_getUriTranslator_implicitPackagesFile_packagesDirectory() async { |
| + // Fake the existence of the base directory. |
| + fileSystem |
| + .entityForUri(Uri.parse('file:///base/location/')) |
| + .writeAsStringSync(''); |
| + fileSystem |
| + .entityForUri(Uri.parse('file:///base/location/packages/')) |
| + .writeAsStringSync(''); |
| + |
| + // Both of these .packages file should be ignored. |
| + fileSystem |
| + .entityForUri(Uri.parse('file:///.packages')) |
| + .writeAsStringSync('foo:bar\n'); |
| + fileSystem |
| + .entityForUri(Uri.parse('file:///base/.packages')) |
| + .writeAsStringSync('foo:baz\n'); |
| + var raw = new CompilerOptions()..fileSystem = fileSystem; |
| + var processed = new ProcessedOptions( |
| + raw, false, [Uri.parse('file:///base/location/script.dart')]); |
| + var uriTranslator = await processed.getUriTranslator(); |
| + checkPackageExpansion( |
| + 'foo', 'base/location/packages/foo', uriTranslator.packages); |
| + } |
| + |
| + test_getUriTranslator_implicitPackagesFile_noPackages() async { |
| + // Fake the existence of the base directory. |
| + fileSystem |
| + .entityForUri(Uri.parse('file:///base/location/')) |
| + .writeAsStringSync(''); |
| + var errors = []; |
| + // .packages file should be ignored. |
| + var raw = new CompilerOptions() |
| + ..fileSystem = fileSystem |
| + ..onError = (e) => errors.add(e); |
| + var processed = new ProcessedOptions( |
| + raw, false, [Uri.parse('file:///base/location/script.dart')]); |
| + var uriTranslator = await processed.getUriTranslator(); |
| + expect(errors, isEmpty); |
| + expect(uriTranslator.packages.asMap(), isEmpty); |
| } |
| test_getUriTranslator_noPackages() async { |
| + var errors = []; |
| // .packages file should be ignored. |
| fileSystem |
| .entityForUri(Uri.parse('file:///.packages')) |
| .writeAsStringSync('foo:bar\n'); |
| var raw = new CompilerOptions() |
| ..fileSystem = fileSystem |
| - ..packagesFileUri = new Uri(); |
| + ..packagesFileUri = new Uri() |
| + ..onError = (e) => errors.add(e); |
| var processed = new ProcessedOptions(raw); |
| var uriTranslator = await processed.getUriTranslator(); |
| - expect(uriTranslator.packages, isEmpty); |
| + expect(uriTranslator.packages.asMap(), isEmpty); |
| + expect(errors.single.message, |
| + startsWith(_stringPrefixOf(templateInvalidPackagesFile))); |
| + } |
| + |
| + test_validateOptions_noInputs() async { |
| + fileSystem |
| + .entityForUri(Uri.parse('file:///foo.dart')) |
| + .writeAsStringSync('main(){}\n'); |
| + var errors = []; |
| + var raw = new CompilerOptions() |
| + ..fileSystem = fileSystem |
| + ..onError = (e) => errors.add(e); |
| + var options = new ProcessedOptions(raw); |
| + var result = await options.validateOptions(); |
| + expect(errors.single.message, messageMissingInputs.message); |
| + expect(result, isFalse); |
| + } |
| + |
| + test_validateOptions_input_doesnt_exist() async { |
| + var errors = []; |
| + var raw = new CompilerOptions() |
| + ..fileSystem = fileSystem |
| + ..onError = (e) => errors.add(e); |
| + var options = new ProcessedOptions(raw, false, [Uri.parse('foo.dart')]); |
| + var result = await options.validateOptions(); |
| + expect(errors.single.message, |
| + startsWith(_stringPrefixOf(templateMissingInputFile))); |
| + expect(result, isFalse); |
| } |
| test_validateOptions_root_exists() async { |
| @@ -140,13 +280,16 @@ class ProcessedOptionsTest { |
| fileSystem |
| .entityForUri(sdkRoot.resolve('outline.dill')) |
| .writeAsStringSync('\n'); |
| + fileSystem |
| + .entityForUri(Uri.parse('file:///foo.dart')) |
| + .writeAsStringSync('main(){}\n'); |
| var errors = []; |
| var raw = new CompilerOptions() |
| ..sdkRoot = sdkRoot |
| ..fileSystem = fileSystem |
| ..onError = (e) => errors.add(e); |
| - var options = new ProcessedOptions(raw); |
| + var options = new ProcessedOptions(raw, false, [Uri.parse('foo.dart')]); |
| var result = await options.validateOptions(); |
| // Note: we check this first so test failures show the cause directly. |
| expect(errors, isEmpty); |
| @@ -154,42 +297,53 @@ class ProcessedOptionsTest { |
| } |
| test_validateOptions_root_doesnt_exists() async { |
| + fileSystem |
| + .entityForUri(Uri.parse('file:///foo.dart')) |
| + .writeAsStringSync('main(){}\n'); |
| var sdkRoot = Uri.parse('file:///sdk/root'); |
| var errors = []; |
| var raw = new CompilerOptions() |
| ..sdkRoot = sdkRoot |
| ..fileSystem = fileSystem |
| ..onError = (e) => errors.add(e); |
| - var options = new ProcessedOptions(raw); |
| + var options = new ProcessedOptions(raw, false, [Uri.parse('foo.dart')]); |
| expect(await options.validateOptions(), isFalse); |
| - expect(errors.first.message, contains("SDK root directory not found")); |
| + expect(errors.first.message, |
| + startsWith(_stringPrefixOf(templateMissingSdkRoot))); |
| } |
| test_validateOptions_summary_exists() async { |
| var sdkSummary = Uri.parse('file:///sdk/root/outline.dill'); |
| fileSystem.entityForUri(sdkSummary).writeAsStringSync('\n'); |
| + fileSystem |
| + .entityForUri(Uri.parse('file:///foo.dart')) |
| + .writeAsStringSync('main(){}\n'); |
| var errors = []; |
| var raw = new CompilerOptions() |
| ..sdkSummary = sdkSummary |
| ..fileSystem = fileSystem |
| ..onError = (e) => errors.add(e); |
| - var options = new ProcessedOptions(raw); |
| + var options = new ProcessedOptions(raw, false, [Uri.parse('foo.dart')]); |
| var result = await options.validateOptions(); |
| expect(errors, isEmpty); |
| expect(result, isTrue); |
| } |
| test_validateOptions_summary_doesnt_exists() async { |
| + fileSystem |
| + .entityForUri(Uri.parse('file:///foo.dart')) |
| + .writeAsStringSync('main(){}\n'); |
| var sdkSummary = Uri.parse('file:///sdk/root/outline.dill'); |
| var errors = []; |
| var raw = new CompilerOptions() |
| ..sdkSummary = sdkSummary |
| ..fileSystem = fileSystem |
| ..onError = (e) => errors.add(e); |
| - var options = new ProcessedOptions(raw); |
| + var options = new ProcessedOptions(raw, false, [Uri.parse('foo.dart')]); |
| expect(await options.validateOptions(), isFalse); |
| - expect(errors.first.message, contains("SDK summary not found")); |
| + expect(errors.single.message, |
| + startsWith(_stringPrefixOf(templateMissingSdkSummary))); |
| } |
| test_validateOptions_inferred_summary_exists() async { |
| @@ -197,13 +351,16 @@ class ProcessedOptionsTest { |
| var sdkSummary = Uri.parse('file:///sdk/root/outline.dill'); |
| fileSystem.entityForUri(sdkRoot).writeAsStringSync('\n'); |
| fileSystem.entityForUri(sdkSummary).writeAsStringSync('\n'); |
| + fileSystem |
| + .entityForUri(Uri.parse('file:///foo.dart')) |
| + .writeAsStringSync('main(){}\n'); |
| var errors = []; |
| var raw = new CompilerOptions() |
| ..sdkRoot = sdkRoot |
| ..fileSystem = fileSystem |
| ..onError = (e) => errors.add(e); |
| - var options = new ProcessedOptions(raw); |
| + var options = new ProcessedOptions(raw, false, [Uri.parse('foo.dart')]); |
| var result = await options.validateOptions(); |
| expect(errors, isEmpty); |
| expect(result, isTrue); |
| @@ -213,13 +370,31 @@ class ProcessedOptionsTest { |
| var sdkRoot = Uri.parse('file:///sdk/root/'); |
| var sdkSummary = Uri.parse('file:///sdk/root/outline.dill'); |
| fileSystem.entityForUri(sdkRoot).writeAsStringSync('\n'); |
| + fileSystem |
| + .entityForUri(Uri.parse('file:///foo.dart')) |
| + .writeAsStringSync('main(){}\n'); |
| var errors = []; |
| var raw = new CompilerOptions() |
| ..sdkSummary = sdkSummary |
| ..fileSystem = fileSystem |
| ..onError = (e) => errors.add(e); |
| - var options = new ProcessedOptions(raw); |
| + var options = new ProcessedOptions(raw, false, [Uri.parse('foo.dart')]); |
| expect(await options.validateOptions(), isFalse); |
| - expect(errors.first.message, contains("SDK summary not found")); |
| + expect(errors.single.message, |
| + startsWith(_stringPrefixOf(templateMissingSdkSummary))); |
| + } |
| + |
| + /// Returns the longest prefix of the text in a message template that doesn't |
| + /// mention a template argument. |
| + _stringPrefixOf(Template template) { |
| + var messageTemplate = template.messageTemplate; |
| + var index = messageTemplate.indexOf('#'); |
| + var prefix = messageTemplate.substring(0, index - 1); |
| + |
| + // Check that the prefix is not empty and that it contains more than one |
| + // word. |
| + expect(prefix.length > 0, isTrue); |
| + expect(prefix.contains(' '), isTrue); |
| + return prefix; |
| } |
| } |