Chromium Code Reviews| Index: pkg/front_end/test/kernel_generator_test.dart |
| diff --git a/pkg/front_end/test/kernel_generator_test.dart b/pkg/front_end/test/kernel_generator_test.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..831dbaf63c5988368269709197a62acb67955afe |
| --- /dev/null |
| +++ b/pkg/front_end/test/kernel_generator_test.dart |
| @@ -0,0 +1,210 @@ |
| +// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +import 'package:front_end/front_end.dart'; |
| +import 'package:front_end/src/fasta/kernel/utils.dart'; |
| +import 'package:front_end/src/testing/compiler_common.dart'; |
| +import 'package:kernel/ast.dart'; |
| + |
| +import 'package:test/test.dart'; |
| + |
| +main() { |
| + group('kernelForProgram', () { |
| + test('compiler fails if it cannot find sdk sources', () async { |
| + var errors = []; |
| + var options = new CompilerOptions() |
| + ..dartLibraries = invalidCoreLibs |
| + ..sdkSummary = null |
| + ..compileSdk = true // To prevent FE from loading an sdk-summary. |
| + ..onError = (e) => errors.add(e); |
| + |
| + var program = |
| + await compileScript('main() => print("hi");', options: options); |
|
ahe
2017/07/11 09:34:26
Make this source snippet a shared constant and tes
Siggi Cherem (dart-lang)
2017/07/11 23:16:31
will do
|
| + expect(program, isNull); |
| + expect(errors, isNotEmpty); |
| + }); |
| + |
| + test('compiler fails if it cannot find sdk summary', () async { |
| + var errors = []; |
| + var options = new CompilerOptions() |
| + ..sdkSummary = Uri.parse('file:///not_existing_summary_file') |
|
ahe
2017/07/11 09:34:26
Use custom URI.
Siggi Cherem (dart-lang)
2017/07/11 23:16:31
Ack (I replied in more detail on the other file)
|
| + ..onError = (e) => errors.add(e); |
| + |
| + var program = |
| + await compileScript('main() => print("hi");', options: options); |
| + expect(program, isNull); |
| + expect(errors, isNotEmpty); |
| + }); |
| + |
| + test('by default program is compiled using summaries', () async { |
| + var options = new CompilerOptions() |
| + // Note: we define [dartLibraries] with broken URIs to ensure we do not |
| + // attempt to lookup for sources of the sdk directly. |
| + ..dartLibraries = invalidCoreLibs; |
| + var program = |
| + await compileScript('main() => print("hi");', options: options); |
| + var core = program.libraries.firstWhere(isDartCoreLibrary); |
| + var printMember = core.members.firstWhere((m) => m.name.name == 'print'); |
| + |
| + // Note: summaries created by the SDK today contain empty statements as |
| + // method bodies. |
| + expect(printMember.function.body is EmptyStatement, isTrue); |
| + }); |
| + |
| + test('compiler requires a main method', () async { |
| + var errors = []; |
| + var options = new CompilerOptions()..onError = (e) => errors.add(e); |
| + await compileScript('a() => print("hi");', options: options); |
| + expect('${errors.first}', contains("No 'main' method found")); |
| + }); |
| + |
| + test('default error handler throws', () async { |
| + var exceptionThrown = false; |
| + try { |
| + await compileScript('a() => print("hi");'); |
| + } catch (e) { |
| + exceptionThrown = true; |
| + expect('$e', contains("No 'main' method found")); |
| + } |
| + expect(exceptionThrown, isTrue); |
| + }); |
| + |
| + test('generated program contains source-info', () async { |
| + var program = await compileScript('a() => print("hi"); main() {}', |
| + fileName: 'a.dart'); |
| + // Kernel always store an empty '' key in the map, so there is always at |
| + // least one. Having more means that source-info is added. |
| + expect(program.uriToSource.keys.length, greaterThan(1)); |
| + expect(program.uriToSource['file:///a/b/c/a.dart'], isNotNull); |
|
ahe
2017/07/11 09:34:26
Use custom URI.
Siggi Cherem (dart-lang)
2017/07/11 23:16:31
Acknowledged.
|
| + }); |
| + |
| + test('code from summary dependencies are marked external', () async { |
| + var program = await compileScript('a() => print("hi"); main() {}', |
|
ahe
2017/07/11 09:34:26
Add TODO about requiring main here?
Siggi Cherem (dart-lang)
2017/07/11 23:16:31
I am not sure I follow - you want to not require i
|
| + fileName: 'a.dart'); |
| + for (var lib in program.libraries) { |
| + if (lib.importUri.scheme == 'dart') { |
| + expect(lib.isExternal, isTrue); |
| + } |
| + } |
| + |
| + // Pretend that the compiled code is a summary |
| + var bytes = serializeProgram(program); |
| + program = await compileScript( |
| + { |
| + 'b.dart': 'import "a.dart" as m; b() => m.a(); main() {}', |
| + 'summary.dill': bytes |
| + }, |
| + fileName: 'b.dart', |
| + inputSummaries: ['summary.dill']); |
| + |
| + var aLib = program.libraries |
| + .firstWhere((lib) => lib.importUri.path == '/a/b/c/a.dart'); |
|
ahe
2017/07/11 09:34:26
Custom URI.
Siggi Cherem (dart-lang)
2017/07/11 23:16:31
Acknowledged.
|
| + expect(aLib.isExternal, isTrue); |
| + }); |
| + |
| + test('code from linked dependencies are not marked external', () async { |
| + var program = await compileScript('a() => print("hi"); main() {}', |
|
ahe
2017/07/11 09:34:26
TODO about main?
Siggi Cherem (dart-lang)
2017/07/11 23:16:32
Acknowledged.
|
| + fileName: 'a.dart'); |
| + for (var lib in program.libraries) { |
| + if (lib.importUri.scheme == 'dart') { |
| + expect(lib.isExternal, isTrue); |
| + } |
| + } |
| + |
| + var bytes = serializeProgram(program); |
| + program = await compileScript( |
| + { |
| + 'b.dart': 'import "a.dart" as m; b() => m.a(); main() {}', |
| + 'link.dill': bytes |
| + }, |
| + fileName: 'b.dart', |
| + linkedDependencies: ['link.dill']); |
| + |
| + var aLib = program.libraries |
| + .firstWhere((lib) => lib.importUri.path == '/a/b/c/a.dart'); |
|
ahe
2017/07/11 09:34:26
Custom URI.
Siggi Cherem (dart-lang)
2017/07/11 23:16:31
Acknowledged.
|
| + expect(aLib.isExternal, isFalse); |
| + }); |
| + |
| + // TODO(sigmund): add tests discovering libraries.json |
| + }); |
| + |
| + group('kernelForBuildUnit', () { |
| + test('compiler does not require a main method', () async { |
| + var errors = []; |
| + var options = new CompilerOptions()..onError = (e) => errors.add(e); |
| + await compileUnit(['a.dart'], {'a.dart': 'a() => print("hi");'}, |
| + options: options); |
| + expect(errors, isEmpty); |
| + }); |
| + |
| + test('compiler by default is hermetic', () async { |
| + var errors = []; |
| + var options = new CompilerOptions()..onError = (e) => errors.add(e); |
| + var sources = { |
| + 'a.dart': 'import "b.dart"; a() => print("hi");', |
| + 'b.dart': '' |
| + }; |
| + await compileUnit(['a.dart'], sources, options: options); |
| + expect(errors.first.toString(), contains('Invalid access')); |
| + errors.clear(); |
| + |
| + await compileUnit(['a.dart', 'b.dart'], sources, options: options); |
| + expect(errors, isEmpty); |
| + }); |
| + |
| + test('chaseDependencies=true removes hermetic restriction', () async { |
| + var errors = []; |
| + var options = new CompilerOptions() |
| + ..chaseDependencies = true |
| + ..onError = (e) => errors.add(e); |
| + await compileUnit([ |
| + 'a.dart' |
| + ], { |
| + 'a.dart': 'import "b.dart"; a() => print("hi");', |
| + 'b.dart': '' |
| + }, options: options); |
| + expect(errors, isEmpty); |
| + }); |
| + |
| + test('dependencies can be loaded in any order', () async { |
| + var sources = <String, dynamic>{ |
| + 'a.dart': 'a() => print("hi");', |
| + 'b.dart': 'import "a.dart"; b() => a();', |
| + 'c.dart': 'import "b.dart"; c() => b();', |
| + 'd.dart': 'import "c.dart"; d() => c();', |
| + }; |
| + |
| + var unitA = await compileUnit(['a.dart'], sources); |
| + // Pretend that the compiled code is a summary |
| + sources['a.dill'] = serializeProgram(unitA); |
| + |
| + var unitBC = await compileUnit(['b.dart', 'c.dart'], sources, |
| + inputSummaries: ['a.dill']); |
| + |
| + // Pretend that the compiled code is a summary |
| + sources['bc.dill'] = serializeProgram(unitBC); |
| + |
| + void checkDCallsC(Program program) { |
| + var dLib = findLibrary(program, 'd.dart'); |
| + var cLib = findLibrary(program, 'c.dart'); |
| + var dMethod = dLib.procedures.first; |
| + var dBody = dMethod.function.body; |
| + var dCall = (dBody as ReturnStatement).expression; |
| + var callTarget = |
| + (dCall as StaticInvocation).targetReference.asProcedure; |
| + expect(callTarget, same(cLib.procedures.first)); |
| + } |
| + |
| + var unitD1 = await compileUnit(['d.dart'], sources, |
| + inputSummaries: ['a.dill', 'bc.dill']); |
| + checkDCallsC(unitD1); |
| + |
| + var unitD2 = await compileUnit(['d.dart'], sources, |
| + inputSummaries: ['bc.dill', 'a.dill']); |
| + checkDCallsC(unitD2); |
| + }); |
| + |
| + // TODO(sigmund): add tests with trimming dependencies |
| + }); |
| +} |