Skip to content

Commit

Permalink
fix(core): host directives incorrectly validating aliased bindings (#…
Browse files Browse the repository at this point in the history
…50364)

Fixes that the host directives feature was incorrectly throwing the conflicting alias error when an aliased binding was being exposed under the same alias.

Fixes #48951.

PR Close #50364
  • Loading branch information
crisbeto authored and thePunderWoman committed May 19, 2023
1 parent b89fae1 commit 199ff4f
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 1 deletion.
53 changes: 53 additions & 0 deletions packages/compiler-cli/test/ngtsc/host_directives_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,59 @@ runInEachFileSystem(() => {

expect(messages).toEqual([]);
});

it('should not produce a diagnostic when exposing an aliased binding', () => {
env.write('test.ts', `
import {Directive, EventEmitter} from '@angular/core';
@Directive({
outputs: ['opened: triggerOpened'],
selector: '[trigger]',
standalone: true,
})
export class Trigger {
opened = new EventEmitter();
}
@Directive({
standalone: true,
selector: '[host]',
hostDirectives: [{directive: Trigger, outputs: ['triggerOpened']}]
})
export class Host {}
`);

const diags = env.driveDiagnostics();
expect(diags.length).toBe(0);
});

it('should not produce a diagnostic when exposing an inherited aliased binding', () => {
env.write('test.ts', `
import {Directive, EventEmitter} from '@angular/core';
@Directive({standalone: true})
export abstract class Base {
opened = new EventEmitter();
}
@Directive({
outputs: ['opened: triggerOpened'],
selector: '[trigger]',
standalone: true,
})
export class Trigger extends Base {}
@Directive({
standalone: true,
selector: '[host]',
hostDirectives: [{directive: Trigger, outputs: ['triggerOpened: hostOpened']}]
})
export class Host {}
`);

const diags = env.driveDiagnostics();
expect(diags.length).toBe(0);
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ function validateMappings(

const remappedPublicName = hostDirectiveBindings[publicName];

if (bindings.hasOwnProperty(remappedPublicName) &&
if (bindings.hasOwnProperty(remappedPublicName) && remappedPublicName !== publicName &&
bindings[remappedPublicName] !== publicName) {
throw new RuntimeError(
RuntimeErrorCode.HOST_DIRECTIVE_CONFLICTING_ALIAS,
Expand Down
60 changes: 60 additions & 0 deletions packages/core/test/acceptance/host_directives_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3219,5 +3219,65 @@ describe('host directives', () => {
fixture.detectChanges();
}).not.toThrow();
});

it('should not throw when exposing an aliased binding', () => {
@Directive({
outputs: ['opened: triggerOpened'],
selector: '[trigger]',
standalone: true,
})
class Trigger {
opened = new EventEmitter();
}

@Directive({
standalone: true,
selector: '[host]',
hostDirectives: [{directive: Trigger, outputs: ['triggerOpened']}]
})
class Host {
}

@Component({template: '<div host></div>', standalone: true, imports: [Host]})
class App {
}

expect(() => {
const fixture = TestBed.createComponent(App);
fixture.detectChanges();
}).not.toThrow();
});

it('should not throw when exposing an inherited aliased binding', () => {
@Directive({standalone: true})
abstract class Base {
opened = new EventEmitter();
}

@Directive({
outputs: ['opened: triggerOpened'],
selector: '[trigger]',
standalone: true,
})
class Trigger extends Base {
}

@Directive({
standalone: true,
selector: '[host]',
hostDirectives: [{directive: Trigger, outputs: ['triggerOpened: hostOpened']}]
})
class Host {
}

@Component({template: '<div host></div>', standalone: true, imports: [Host]})
class App {
}

expect(() => {
const fixture = TestBed.createComponent(App);
fixture.detectChanges();
}).not.toThrow();
});
});
});

0 comments on commit 199ff4f

Please sign in to comment.