feat(dart/transform): Add DirectiveMetadataExtractor transform step

Add a step that reads `DirectiveMetadata` object off annotated classes
into `.ng_meta.dart` files. These will be used by the `TemplateCompiler`
step as inputs to the Angular 2 render compiler.

Update one test to avoid unsupported functionality, format others.
This commit is contained in:
Tim Blasi
2015-05-01 13:57:44 -07:00
parent 8e1d53b5e9
commit 0520ca68b4
27 changed files with 214 additions and 78 deletions

View File

@ -0,0 +1,73 @@
library angular2.test.transform.directive_metadata_extractor.all_tests;
import 'dart:async';
import 'package:angular2/src/render/api.dart';
import 'package:angular2/src/transform/common/directive_metadata_reader.dart';
import 'package:angular2/src/transform/common/logging.dart';
import 'package:angular2/src/transform/common/parser.dart';
import 'package:barback/barback.dart';
import 'package:dart_style/dart_style.dart';
import 'package:guinness/guinness.dart';
import '../common/read_file.dart';
var formatter = new DartFormatter();
void allTests() {
var reader = new TestAssetReader();
var parser = new Parser(reader);
beforeEach(() => setLogger(new PrintLogger()));
Future<DirectiveMetadata> readMetadata(inputPath) async {
var ngDeps = await parser.parse(new AssetId('a', inputPath));
return readDirectiveMetadata(ngDeps.registeredTypes.first);
}
it('should parse selectors', () async {
var metadata = await readMetadata(
'directive_metadata_extractor/directive_metadata_files/selector.ng_deps.dart');
expect(metadata.selector).toEqual('hello-app');
});
it('should parse compile children values', () async {
var metadata = await readMetadata('directive_metadata_extractor/'
'directive_metadata_files/compile_children.ng_deps.dart');
expect(metadata.compileChildren).toBeTrue();
metadata = await readMetadata(
'directive_metadata_extractor/directive_metadata_files/selector.ng_deps.dart');
expect(metadata.compileChildren).toBeFalse();
});
it('should parse properties.', () async {
var metadata = await readMetadata('directive_metadata_extractor/'
'directive_metadata_files/properties.ng_deps.dart');
expect(metadata.properties).toBeNotNull();
expect(metadata.properties.length).toBe(2);
expect(metadata.properties).toContain('key1');
expect(metadata.properties['key1']).toEqual('val1');
expect(metadata.properties).toContain('key2');
expect(metadata.properties['key2']).toEqual('val2');
});
it('should parse host listeners.', () async {
var metadata = await readMetadata('directive_metadata_extractor/'
'directive_metadata_files/host_listeners.ng_deps.dart');
expect(metadata.hostListeners).toBeNotNull();
expect(metadata.hostListeners.length).toBe(2);
expect(metadata.hostListeners).toContain('change');
expect(metadata.hostListeners['change']).toEqual('onChange(\$event)');
expect(metadata.hostListeners).toContain('keyDown');
expect(metadata.hostListeners['keyDown']).toEqual('onKeyDown(\$event)');
});
it('should fail when a class is annotated with multiple Directives.',
() async {
var ngDeps = await parser.parse(new AssetId('a',
'directive_metadata_extractor/'
'directive_metadata_files/too_many_directives.ng_deps.dart'));
expect(() => readDirectiveMetadata(ngDeps.registeredTypes.first))
.toThrowWith(anInstanceOf: PrintLoggerError);
});
}

View File

@ -0,0 +1,16 @@
library foo.ng_deps.dart;
import 'foo.dart';
import 'package:angular2/src/core/annotations/annotations.dart';
var _visited = false;
void initReflector(reflector) {
if (_visited) return;
_visited = true;
reflector
..registerType(DependencyComponent, {
'factory': () => new DependencyComponent(),
'parameters': const [],
'annotations': const [const Component(selector: '[salad]')]
});
}

View File

@ -0,0 +1 @@
// {selector: '[salad]', type: 1}

View File

@ -0,0 +1,16 @@
library foo.ng_deps.dart;
import 'foo.dart';
import 'package:angular2/src/core/annotations/annotations.dart';
var _visited = false;
void initReflector(reflector) {
if (_visited) return;
_visited = true;
reflector
..registerType(DependencyComponent, {
'factory': () => new DependencyComponent(),
'parameters': const [],
'annotations': const [const Component(selector: '[salad]')]
});
}

View File

@ -1,7 +1,6 @@
library angular2.test.transform.integration;
import 'package:angular2/src/dom/html_adapter.dart';
import 'package:angular2/src/transform/common/names.dart';
import 'package:angular2/transformer.dart';
import 'package:code_transformers/tests.dart';
import 'package:dart_style/dart_style.dart';
@ -62,8 +61,7 @@ void allTests() {
'simple_annotation_files/expected/index.ng_deps.dart'
}),
new IntegrationTestConfig(
'should generate proper code for a Component using a selector defined '
'in another file.',
'should generate proper code for a Component with multiple deps.',
inputs: {
'a|web/index.dart': 'two_deps_files/index.dart',
'a|web/foo.dart': 'two_deps_files/foo.dart',

View File

@ -2,7 +2,8 @@ library bar.ng_deps.dart;
import 'bar.dart';
import 'package:angular2/src/core/annotations_impl/annotations.dart';
import 'package:angular2/src/core/annotations_impl/annotations.ng_deps.dart' as i0;
import 'package:angular2/src/core/annotations_impl/annotations.ng_deps.dart'
as i0;
import 'foo.dart';
import 'foo.ng_deps.dart' as i1;

View File

@ -2,7 +2,8 @@ library bar.ng_deps.dart;
import 'bar.dart';
import 'package:angular2/src/core/annotations_impl/annotations.dart';
import 'package:angular2/src/core/annotations_impl/annotations.ng_deps.dart' as i0;
import 'package:angular2/src/core/annotations_impl/annotations.ng_deps.dart'
as i0;
var _visited = false;
void initReflector(reflector) {

View File

@ -2,7 +2,8 @@ library bar.ng_deps.dart;
import 'bar.dart';
import 'package:angular2/src/core/annotations_impl/annotations.dart';
import 'package:angular2/src/core/annotations_impl/annotations.ng_deps.dart' as i0;
import 'package:angular2/src/core/annotations_impl/annotations.ng_deps.dart'
as i0;
var _visited = false;
void initReflector(reflector) {

View File

@ -2,7 +2,8 @@ library bar.ng_deps.dart;
import 'bar.dart';
import 'package:angular2/src/core/annotations_impl/annotations.dart';
import 'package:angular2/src/core/annotations_impl/annotations.ng_deps.dart' as i0;
import 'package:angular2/src/core/annotations_impl/annotations.ng_deps.dart'
as i0;
import 'package:angular2/src/core/annotations_impl/view.dart';
import 'package:angular2/src/core/annotations_impl/view.ng_deps.dart' as i1;

View File

@ -3,7 +3,7 @@ library bar;
import 'package:angular2/src/core/annotations_impl/annotations.dart';
import 'foo.dart' as prefix;
@Component(selector: prefix.preDefinedSelector)
@Component(selector: 'soup')
class MyComponent {
final prefix.MyContext c;
final String generatedValue;

View File

@ -2,7 +2,8 @@ library bar.ng_deps.dart;
import 'bar.dart';
import 'package:angular2/src/core/annotations_impl/annotations.dart';
import 'package:angular2/src/core/annotations_impl/annotations.ng_deps.dart' as i0;
import 'package:angular2/src/core/annotations_impl/annotations.ng_deps.dart'
as i0;
import 'foo.dart' as prefix;
import 'foo.ng_deps.dart' as i1;
@ -15,8 +16,7 @@ void initReflector(reflector) {
'factory':
(prefix.MyContext c, String inValue) => new MyComponent(c, inValue),
'parameters': const [const [prefix.MyContext], const [String]],
'annotations':
const [const Component(selector: prefix.preDefinedSelector)]
'annotations': const [const Component(selector: 'soup')]
});
i0.initReflector(reflector);
i1.initReflector(reflector);

View File

@ -1,7 +1,5 @@
library foo;
const preDefinedSelector = 'soup';
class MyContext {
final String selector;
const MyContext(this.selector);

View File

@ -1,4 +1,4 @@
library angular2.test.transform.debug_reflection_remover_files;
library angular2.test.transform.reflection_remover.debug_mirrors_files.expected;
// This file is intentionally formatted as a string to avoid having the
// automatic transformer prettify it.

View File

@ -1,4 +1,4 @@
library angular2.test.transform.reflection_remover_files;
library angular2.test.transform.reflection_remover.reflection_remover_files;
// This file is intentionally formatted as a string to avoid having the
// automatic transformer prettify it.

View File

@ -1,4 +1,4 @@
library angular2.test.transform.debug_reflection_remover_files;
library angular2.test.transform.reflection_remover.verbose_files.expected;
// This file is intentionally formatted as a string to avoid having the
// automatic transformer prettify it.

View File

@ -1,13 +1,9 @@
library angular2.test.transform.template_compiler.all_tests;
import 'dart:async';
import 'package:barback/barback.dart';
import 'package:angular2/src/dom/html_adapter.dart';
import 'package:angular2/src/render/api.dart';
import 'package:angular2/src/transform/common/asset_reader.dart';
import 'package:angular2/src/transform/common/logging.dart';
import 'package:angular2/src/transform/common/parser.dart';
import 'package:angular2/src/transform/template_compiler/directive_metadata_reader.dart';
import 'package:angular2/src/transform/template_compiler/generator.dart';
import 'package:dart_style/dart_style.dart';
import 'package:guinness/guinness.dart';
@ -19,7 +15,6 @@ var formatter = new DartFormatter();
void allTests() {
Html5LibDomAdapter.makeCurrent();
AssetReader reader = new TestAssetReader();
var parser = new Parser(reader);
beforeEach(() => setLogger(new PrintLogger()));
@ -63,59 +58,6 @@ void allTests() {
var output = await processTemplates(reader, new AssetId('a', inputPath));
_formatThenExpectEquals(output, expected);
});
describe('DirectiveMetadataReader', () {
Future<DirectiveMetadata> readMetadata(inputPath) async {
var ngDeps = await parser.parse(new AssetId('a', inputPath));
return readDirectiveMetadata(ngDeps.registeredTypes.first);
}
it('should parse selectors', () async {
var metadata = await readMetadata(
'template_compiler/directive_metadata_files/selector.ng_deps.dart');
expect(metadata.selector).toEqual('hello-app');
});
it('should parse compile children values', () async {
var metadata = await readMetadata('template_compiler/'
'directive_metadata_files/compile_children.ng_deps.dart');
expect(metadata.compileChildren).toBeTrue();
metadata = await readMetadata(
'template_compiler/directive_metadata_files/selector.ng_deps.dart');
expect(metadata.compileChildren).toBeFalse();
});
it('should parse properties.', () async {
var metadata = await readMetadata('template_compiler/'
'directive_metadata_files/properties.ng_deps.dart');
expect(metadata.properties).toBeNotNull();
expect(metadata.properties.length).toBe(2);
expect(metadata.properties).toContain('key1');
expect(metadata.properties['key1']).toEqual('val1');
expect(metadata.properties).toContain('key2');
expect(metadata.properties['key2']).toEqual('val2');
});
it('should parse host listeners.', () async {
var metadata = await readMetadata('template_compiler/'
'directive_metadata_files/host_listeners.ng_deps.dart');
expect(metadata.hostListeners).toBeNotNull();
expect(metadata.hostListeners.length).toBe(2);
expect(metadata.hostListeners).toContain('change');
expect(metadata.hostListeners['change']).toEqual('onChange(\$event)');
expect(metadata.hostListeners).toContain('keyDown');
expect(metadata.hostListeners['keyDown']).toEqual('onKeyDown(\$event)');
});
it('should fail when a class is annotated with multiple Directives.',
() async {
var ngDeps = await parser.parse(new AssetId('a', 'template_compiler/'
'directive_metadata_files/too_many_directives.ng_deps.dart'));
expect(() => readDirectiveMetadata(ngDeps.registeredTypes.first))
.toThrowWith(anInstanceOf: PrintLoggerError);
});
});
}
void _formatThenExpectEquals(String actual, String expected) {

View File

@ -6,6 +6,7 @@ import 'package:unittest/vm_config.dart';
import 'bind_generator/all_tests.dart' as bindGenerator;
import 'directive_linker/all_tests.dart' as directiveLinker;
import 'directive_metadata_extractor/all_tests.dart' as directiveMeta;
import 'directive_processor/all_tests.dart' as directiveProcessor;
import 'integration/all_tests.dart' as integration;
import 'reflection_remover/all_tests.dart' as reflectionRemover;
@ -15,6 +16,7 @@ main() {
useVMConfiguration();
describe('Bind Generator', bindGenerator.allTests);
describe('Directive Linker', directiveLinker.allTests);
describe('Directive Metadata Extractor', directiveMeta.allTests);
describe('Directive Processor', directiveProcessor.allTests);
describe('Reflection Remover', reflectionRemover.allTests);
describe('Template Compiler', templateCompiler.allTests);