fix(animations): throw errors when duplicate component trigger names are registered
This commit is contained in:
parent
79eda30f0f
commit
5af1e891cd
|
@ -33,23 +33,33 @@ export class AnimationCompiler {
|
||||||
var compiledAnimations: CompiledAnimation[] = [];
|
var compiledAnimations: CompiledAnimation[] = [];
|
||||||
var index = 0;
|
var index = 0;
|
||||||
var groupedErrors: string[] = [];
|
var groupedErrors: string[] = [];
|
||||||
|
var triggerLookup: {[key: string]: CompiledAnimation} = {};
|
||||||
|
var componentName = component.type.name;
|
||||||
|
|
||||||
component.template.animations.forEach(entry => {
|
component.template.animations.forEach(entry => {
|
||||||
var result = parseAnimationEntry(entry);
|
var result = parseAnimationEntry(entry);
|
||||||
|
var triggerName = entry.name;
|
||||||
if (result.errors.length > 0) {
|
if (result.errors.length > 0) {
|
||||||
var errorMessage =
|
var errorMessage =
|
||||||
`Unable to parse the animation sequence for "${entry.name}" due to the following errors:`;
|
`Unable to parse the animation sequence for "${triggerName}" due to the following errors:`;
|
||||||
result.errors.forEach(
|
result.errors.forEach(
|
||||||
(error: AnimationParseError) => { errorMessage += '\n-- ' + error.msg; });
|
(error: AnimationParseError) => { errorMessage += '\n-- ' + error.msg; });
|
||||||
// todo (matsko): include the component name when throwing
|
// todo (matsko): include the component name when throwing
|
||||||
groupedErrors.push(errorMessage);
|
groupedErrors.push(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
var factoryName = `${component.type.name}_${entry.name}_${index}`;
|
if (triggerLookup[triggerName]) {
|
||||||
index++;
|
groupedErrors.push(
|
||||||
|
`The animation trigger "${triggerName}" has already been registered on "${componentName}"`);
|
||||||
|
} else {
|
||||||
|
var factoryName = `${component.type.name}_${entry.name}_${index}`;
|
||||||
|
index++;
|
||||||
|
|
||||||
var visitor = new _AnimationBuilder(entry.name, factoryName);
|
var visitor = new _AnimationBuilder(triggerName, factoryName);
|
||||||
compiledAnimations.push(visitor.build(result.ast));
|
var compileResult = visitor.build(result.ast)
|
||||||
|
compiledAnimations.push(compileResult);
|
||||||
|
triggerLookup[entry.name] = compileResult;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
_validateAnimationProperties(compiledAnimations, template).forEach(entry => {
|
_validateAnimationProperties(compiledAnimations, template).forEach(entry => {
|
||||||
|
|
|
@ -9,8 +9,9 @@
|
||||||
import {AnimationMetadata, animate, group, sequence, style, transition, trigger} from '@angular/core';
|
import {AnimationMetadata, animate, group, sequence, style, transition, trigger} from '@angular/core';
|
||||||
import {AsyncTestCompleter, beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal';
|
import {AsyncTestCompleter, beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal';
|
||||||
|
|
||||||
|
import {StringMapWrapper} from '../../../platform-browser-dynamic/src/facade/collection';
|
||||||
import {AnimationCompiler, CompiledAnimation} from '../../src/animation/animation_compiler';
|
import {AnimationCompiler, CompiledAnimation} from '../../src/animation/animation_compiler';
|
||||||
import {CompileDirectiveMetadata, CompileTemplateMetadata, CompileTypeMetadata} from '../../src/compile_metadata';
|
import {CompileAnimationEntryMetadata, CompileDirectiveMetadata, CompileTemplateMetadata, CompileTypeMetadata} from '../../src/compile_metadata';
|
||||||
import {CompileMetadataResolver} from '../../src/metadata_resolver';
|
import {CompileMetadataResolver} from '../../src/metadata_resolver';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
|
@ -25,18 +26,24 @@ export function main() {
|
||||||
return compiler.compileComponent(component, [])[0];
|
return compiler.compileComponent(component, [])[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
var compile = (seq: AnimationMetadata) => {
|
var compileTriggers = (input: any[]) => {
|
||||||
var entry = trigger('myAnimation', [transition('state1 => state2', seq)]);
|
var entries: CompileAnimationEntryMetadata[] = input.map(entry => {
|
||||||
|
var animationTriggerData = trigger(entry[0], entry[1]);
|
||||||
|
return resolver.getAnimationEntryMetadata(animationTriggerData);
|
||||||
|
});
|
||||||
|
|
||||||
var compiledAnimationEntry = resolver.getAnimationEntryMetadata(entry);
|
|
||||||
var component = CompileDirectiveMetadata.create({
|
var component = CompileDirectiveMetadata.create({
|
||||||
type: new CompileTypeMetadata({name: 'something'}),
|
type: new CompileTypeMetadata({name: 'myCmp'}),
|
||||||
template: new CompileTemplateMetadata({animations: [compiledAnimationEntry]})
|
template: new CompileTemplateMetadata({animations: entries})
|
||||||
});
|
});
|
||||||
|
|
||||||
return compileAnimations(component);
|
return compileAnimations(component);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var compileSequence = (seq: AnimationMetadata) => {
|
||||||
|
return compileTriggers([['myAnimation', [transition('state1 => state2', seq)]]]);
|
||||||
|
};
|
||||||
|
|
||||||
it('should throw an exception containing all the inner animation parser errors', () => {
|
it('should throw an exception containing all the inner animation parser errors', () => {
|
||||||
var animation = sequence([
|
var animation = sequence([
|
||||||
style({'color': 'red'}), animate(1000, style({'font-size': '100px'})),
|
style({'color': 'red'}), animate(1000, style({'font-size': '100px'})),
|
||||||
|
@ -46,7 +53,7 @@ export function main() {
|
||||||
|
|
||||||
var capturedErrorMessage: string;
|
var capturedErrorMessage: string;
|
||||||
try {
|
try {
|
||||||
compile(animation);
|
compileSequence(animation);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
capturedErrorMessage = e.message;
|
capturedErrorMessage = e.message;
|
||||||
}
|
}
|
||||||
|
@ -57,5 +64,23 @@ export function main() {
|
||||||
expect(capturedErrorMessage)
|
expect(capturedErrorMessage)
|
||||||
.toMatch(/Animation states via styles must be prefixed with a ":"/);
|
.toMatch(/Animation states via styles must be prefixed with a ":"/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should throw an error when two or more animation triggers contain the same name', () => {
|
||||||
|
var doCompile = () => {
|
||||||
|
var t1Data: any[] = [];
|
||||||
|
var t2Data: any[] = [];
|
||||||
|
compileTriggers([['myTrigger', t1Data], ['myTrigger', t2Data]]);
|
||||||
|
};
|
||||||
|
|
||||||
|
var capturedErrorMessage: string;
|
||||||
|
try {
|
||||||
|
doCompile();
|
||||||
|
} catch (e) {
|
||||||
|
capturedErrorMessage = e.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(capturedErrorMessage)
|
||||||
|
.toMatch(/The animation trigger "myTrigger" has already been registered on "myCmp"/);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue