Skip to content

Commit

Permalink
fix(platform-browser): improve error message for missing animation tr…
Browse files Browse the repository at this point in the history
…igger (#41356)

There are two reasons why this error can be called, but only one was covered before.

Fixes #15581

PR Close #41356
  • Loading branch information
kirjs authored and jessicajaniuk committed Sep 15, 2021
1 parent e5d08c1 commit 35725f5
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 22 deletions.
72 changes: 54 additions & 18 deletions packages/core/test/animation/animation_integration_spec.ts
Expand Up @@ -3827,29 +3827,65 @@ describe('animation tests', function() {
});
});

it('should throw when using an @prop binding without the animation module', () => {
@Component({template: `<div [@myAnimation]="true"></div>`})
class Cmp {
}

TestBed.configureTestingModule({declarations: [Cmp]});
const comp = TestBed.createComponent(Cmp);
expect(() => comp.detectChanges())
.toThrowError(
'Found the synthetic property @myAnimation. Please include either "BrowserAnimationsModule" or "NoopAnimationsModule" in your application.');
function syntheticPropError(name: string, nameKind: string) {
return `Unexpected synthetic ${nameKind} ${name} found. Please make sure that:
- Either \`BrowserAnimationsModule\` or \`NoopAnimationsModule\` are imported in your application.
- There is corresponding configuration for the animation named \`${
name}\` defined in the \`animations\` field of the \`@Component\` decorator (see https://angular.io/api/core/Component#animations).`;
}

describe('when modules are missing', () => {
it('should throw when using an @prop binding without the animation module', () => {
@Component({template: `<div [@myAnimation]="true"></div>`})
class Cmp {
}

TestBed.configureTestingModule({declarations: [Cmp]});
const comp = TestBed.createComponent(Cmp);
expect(() => comp.detectChanges())
.toThrowError(syntheticPropError('@myAnimation', 'property'));
});

it('should throw when using an @prop listener without the animation module', () => {
@Component({template: `<div (@myAnimation.start)="a = true"></div>`})
class Cmp {
a = false;
}

TestBed.configureTestingModule({declarations: [Cmp]});

expect(() => TestBed.createComponent(Cmp))
.toThrowError(syntheticPropError('@myAnimation.start', 'listener'));
});
});

it('should throw when using an @prop listener without the animation module', () => {
@Component({template: `<div (@myAnimation.start)="a = true"></div>`})
class Cmp {
a: any;
}
describe('when modules are present, but animations are missing', () => {
it('should throw when using an @prop property, BrowserAnimationModule is imported, but there is no animation rule',
() => {
@Component({template: `<div [@myAnimation]="true"></div>`})
class Cmp {
}

TestBed.configureTestingModule({declarations: [Cmp]});
TestBed.configureTestingModule(
{declarations: [Cmp], imports: [BrowserAnimationsModule]});
const comp = TestBed.createComponent(Cmp);
expect(() => comp.detectChanges())
.toThrowError(syntheticPropError('@myAnimation', 'property'));
});

expect(() => TestBed.createComponent(Cmp))
.toThrowError(
'Found the synthetic listener @myAnimation.start. Please include either "BrowserAnimationsModule" or "NoopAnimationsModule" in your application.');
it('should throw when using an @prop listener, BrowserAnimationModule is imported, but there is no animation rule',
() => {
@Component({template: `<div (@myAnimation.start)="true"></div>`})
class Cmp {
}

TestBed.configureTestingModule(
{declarations: [Cmp], imports: [BrowserAnimationsModule]});

expect(() => TestBed.createComponent(Cmp))
.toThrowError(syntheticPropError('@myAnimation.start', 'listener'));
});
});
});
});
Expand Down
6 changes: 4 additions & 2 deletions packages/platform-browser/src/dom/dom_renderer.ts
Expand Up @@ -280,8 +280,10 @@ class DefaultDomRenderer2 implements Renderer2 {
const AT_CHARCODE = (() => '@'.charCodeAt(0))();
function checkNoSyntheticProp(name: string, nameKind: string) {
if (name.charCodeAt(0) === AT_CHARCODE) {
throw new Error(`Found the synthetic ${nameKind} ${
name}. Please include either "BrowserAnimationsModule" or "NoopAnimationsModule" in your application.`);
throw new Error(`Unexpected synthetic ${nameKind} ${name} found. Please make sure that:
- Either \`BrowserAnimationsModule\` or \`NoopAnimationsModule\` are imported in your application.
- There is corresponding configuration for the animation named \`${
name}\` defined in the \`animations\` field of the \`@Component\` decorator (see https://angular.io/api/core/Component#animations).`);
}
}

Expand Down
6 changes: 4 additions & 2 deletions packages/platform-server/src/server_renderer.ts
Expand Up @@ -241,8 +241,10 @@ class DefaultServerRenderer2 implements Renderer2 {
const AT_CHARCODE = '@'.charCodeAt(0);
function checkNoSyntheticProp(name: string, nameKind: string) {
if (name.charCodeAt(0) === AT_CHARCODE) {
throw new Error(`Found the synthetic ${nameKind} ${
name}. Please include either "BrowserAnimationsModule" or "NoopAnimationsModule" in your application.`);
throw new Error(`Unexpected synthetic ${nameKind} ${name} found. Please make sure that:
- Either \`BrowserAnimationsModule\` or \`NoopAnimationsModule\` are imported in your application.
- There is corresponding configuration for the animation named \`${
name}\` defined in the \`animations\` field of the \`@Component\` decorator (see https://angular.io/api/core/Component#animations).`);
}
}

Expand Down

0 comments on commit 35725f5

Please sign in to comment.