fix(directive): throw if output the same event more than once

Close: #4798
This commit is contained in:
eric 2015-11-04 17:08:51 +08:00 committed by Rado Kirov
parent c8e909f8c9
commit 8c37b7e8f2
2 changed files with 33 additions and 5 deletions

View File

@ -2,6 +2,7 @@ import {resolveForwardRef, Injectable} from 'angular2/src/core/di';
import {Type, isPresent, isBlank, stringify} from 'angular2/src/facade/lang'; import {Type, isPresent, isBlank, stringify} from 'angular2/src/facade/lang';
import {BaseException} from 'angular2/src/facade/exceptions'; import {BaseException} from 'angular2/src/facade/exceptions';
import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection'; import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
import { import {
DirectiveMetadata, DirectiveMetadata,
ComponentMetadata, ComponentMetadata,
@ -38,7 +39,7 @@ export class DirectiveResolver {
var metadata = typeMetadata.find(_isDirectiveMetadata); var metadata = typeMetadata.find(_isDirectiveMetadata);
if (isPresent(metadata)) { if (isPresent(metadata)) {
var propertyMetadata = reflector.propMetadata(type); var propertyMetadata = reflector.propMetadata(type);
return this._mergeWithPropertyMetadata(metadata, propertyMetadata); return this._mergeWithPropertyMetadata(metadata, propertyMetadata, type);
} }
} }
@ -46,7 +47,8 @@ export class DirectiveResolver {
} }
private _mergeWithPropertyMetadata(dm: DirectiveMetadata, private _mergeWithPropertyMetadata(dm: DirectiveMetadata,
propertyMetadata: {[key: string]: any[]}): DirectiveMetadata { propertyMetadata: {[key: string]: any[]},
directiveType: Type): DirectiveMetadata {
var inputs = []; var inputs = [];
var outputs = []; var outputs = [];
var host: {[key: string]: string} = {}; var host: {[key: string]: string} = {};
@ -100,13 +102,27 @@ export class DirectiveResolver {
} }
}); });
}); });
return this._merge(dm, inputs, outputs, host, queries); return this._merge(dm, inputs, outputs, host, queries, directiveType);
} }
private _merge(dm: DirectiveMetadata, inputs: string[], outputs: string[], private _merge(dm: DirectiveMetadata, inputs: string[], outputs: string[],
host: {[key: string]: string}, queries: {[key: string]: any}): DirectiveMetadata { host: {[key: string]: string}, queries: {[key: string]: any},
directiveType: Type): DirectiveMetadata {
var mergedInputs = isPresent(dm.inputs) ? ListWrapper.concat(dm.inputs, inputs) : inputs; var mergedInputs = isPresent(dm.inputs) ? ListWrapper.concat(dm.inputs, inputs) : inputs;
var mergedOutputs = isPresent(dm.outputs) ? ListWrapper.concat(dm.outputs, outputs) : outputs;
var mergedOutputs;
if (isPresent(dm.outputs)) {
dm.outputs.forEach((propName: string) => {
if (ListWrapper.contains(outputs, propName)) {
throw new BaseException(
`Output event '${propName}' defined multiple times in '${stringify(directiveType)}'`);
}
});
mergedOutputs = ListWrapper.concat(dm.outputs, outputs);
} else {
mergedOutputs = outputs;
}
var mergedHost = isPresent(dm.host) ? StringMapWrapper.merge(dm.host, host) : host; var mergedHost = isPresent(dm.host) ? StringMapWrapper.merge(dm.host, host) : host;
var mergedQueries = var mergedQueries =
isPresent(dm.queries) ? StringMapWrapper.merge(dm.queries, queries) : queries; isPresent(dm.queries) ? StringMapWrapper.merge(dm.queries, queries) : queries;

View File

@ -39,6 +39,12 @@ class SomeDirectiveWithOutputs {
c; c;
} }
@Directive({selector: 'someDirective', outputs: ['a']})
class SomeDirectiveWithDuplicateOutputs {
@Output() a;
}
@Directive({selector: 'someDirective', properties: ['a']}) @Directive({selector: 'someDirective', properties: ['a']})
class SomeDirectiveWithProperties { class SomeDirectiveWithProperties {
} }
@ -153,6 +159,12 @@ export function main() {
var directiveMetadata = resolver.resolve(SomeDirectiveWithGetterOutputs); var directiveMetadata = resolver.resolve(SomeDirectiveWithGetterOutputs);
expect(directiveMetadata.outputs).toEqual(['a: renamed']); expect(directiveMetadata.outputs).toEqual(['a: renamed']);
}); });
it('should throw if duplicate outputs', () => {
expect(() => { resolver.resolve(SomeDirectiveWithDuplicateOutputs); })
.toThrowError(
`Output event 'a' defined multiple times in 'SomeDirectiveWithDuplicateOutputs'`);
});
}); });
describe('host', () => { describe('host', () => {