fix(ivy): directives without selector should not be supported (#28021)
PR Close #28021
This commit is contained in:
parent
7374dfd1fa
commit
76ed13bffe
|
@ -165,6 +165,9 @@ export function extractDirectiveMetadata(
|
|||
}
|
||||
selector = resolved;
|
||||
}
|
||||
if (!selector) {
|
||||
throw new Error(`Directive ${clazz.name !.text} has no selector, please add it!`);
|
||||
}
|
||||
|
||||
const host = extractHostBindings(directive, decoratedElements, evaluator, coreModule);
|
||||
|
||||
|
|
|
@ -640,9 +640,6 @@ describe('compiler compliance', () => {
|
|||
'spec.ts': `
|
||||
import {Component, Directive, NgModule} from '@angular/core';
|
||||
|
||||
@Directive({})
|
||||
export class EmptyOutletDirective {}
|
||||
|
||||
@Component({template: '<router-outlet></router-outlet>'})
|
||||
export class EmptyOutletComponent {}
|
||||
|
||||
|
@ -652,16 +649,6 @@ describe('compiler compliance', () => {
|
|||
}
|
||||
};
|
||||
|
||||
// EmptyOutletDirective definition should be:
|
||||
const EmptyOutletDirectiveDefinition = `
|
||||
…
|
||||
EmptyOutletDirective.ngDirectiveDef = $r3$.ɵdefineDirective({
|
||||
type: EmptyOutletDirective,
|
||||
selectors: [],
|
||||
factory: function EmptyOutletDirective_Factory(t) { return new (t || EmptyOutletDirective)(); }
|
||||
});
|
||||
`;
|
||||
|
||||
// EmptyOutletComponent definition should be:
|
||||
const EmptyOutletComponentDefinition = `
|
||||
…
|
||||
|
@ -683,13 +670,48 @@ describe('compiler compliance', () => {
|
|||
const result = compile(files, angularFiles);
|
||||
const source = result.source;
|
||||
|
||||
expectEmit(
|
||||
source, EmptyOutletDirectiveDefinition,
|
||||
'Incorrect EmptyOutletDirective.ngDirectiveDefDef');
|
||||
expectEmit(
|
||||
source, EmptyOutletComponentDefinition, 'Incorrect EmptyOutletComponent.ngComponentDef');
|
||||
});
|
||||
|
||||
it('should not support directives without selector', () => {
|
||||
const files = {
|
||||
app: {
|
||||
'spec.ts': `
|
||||
import {Component, Directive, NgModule} from '@angular/core';
|
||||
|
||||
@Directive({})
|
||||
export class EmptyOutletDirective {}
|
||||
|
||||
@NgModule({declarations: [EmptyOutletDirective]})
|
||||
export class MyModule{}
|
||||
`
|
||||
}
|
||||
};
|
||||
|
||||
expect(() => compile(files, angularFiles))
|
||||
.toThrowError('Directive EmptyOutletDirective has no selector, please add it!');
|
||||
});
|
||||
|
||||
it('should not support directives with empty selector', () => {
|
||||
const files = {
|
||||
app: {
|
||||
'spec.ts': `
|
||||
import {Component, Directive, NgModule} from '@angular/core';
|
||||
|
||||
@Directive({selector: ''})
|
||||
export class EmptyOutletDirective {}
|
||||
|
||||
@NgModule({declarations: [EmptyOutletDirective]})
|
||||
export class MyModule{}
|
||||
`
|
||||
}
|
||||
};
|
||||
|
||||
expect(() => compile(files, angularFiles))
|
||||
.toThrowError('Directive EmptyOutletDirective has no selector, please add it!');
|
||||
});
|
||||
|
||||
it('should not treat ElementRef, ViewContainerRef, or ChangeDetectorRef specially when injecting',
|
||||
() => {
|
||||
const files = {
|
||||
|
|
|
@ -164,9 +164,9 @@ export function compileDirectiveFromMetadata(
|
|||
addFeatures(definitionMap, meta);
|
||||
const expression = o.importExpr(R3.defineDirective).callFn([definitionMap.toLiteralMap()]);
|
||||
|
||||
// On the type side, remove newlines from the selector as it will need to fit into a TypeScript
|
||||
// string literal, which must be on one line.
|
||||
const selectorForType = (meta.selector || '').replace(/\n/g, '');
|
||||
if (!meta.selector) {
|
||||
throw new Error(`Directive ${meta.name} has no selector, please add it!`);
|
||||
}
|
||||
|
||||
const type = createTypeForDef(meta, R3.DirectiveDefWithMeta);
|
||||
return {expression, type, statements};
|
||||
|
|
|
@ -1423,21 +1423,19 @@ function declareTests(config?: {useJit: boolean}) {
|
|||
expect(getDOM().querySelectorAll(fixture.nativeElement, 'script').length).toEqual(0);
|
||||
});
|
||||
|
||||
fixmeIvy('FW-662: Components without selector are not supported')
|
||||
.it('should throw when using directives without selector', () => {
|
||||
@Directive({})
|
||||
class SomeDirective {
|
||||
}
|
||||
it('should throw when using directives without selector', () => {
|
||||
@Directive({})
|
||||
class SomeDirective {
|
||||
}
|
||||
|
||||
@Component({selector: 'comp', template: ''})
|
||||
class SomeComponent {
|
||||
}
|
||||
@Component({selector: 'comp', template: ''})
|
||||
class SomeComponent {
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({declarations: [MyComp, SomeDirective, SomeComponent]});
|
||||
expect(() => TestBed.createComponent(MyComp))
|
||||
.toThrowError(
|
||||
`Directive ${stringify(SomeDirective)} has no selector, please add it!`);
|
||||
});
|
||||
TestBed.configureTestingModule({declarations: [MyComp, SomeDirective, SomeComponent]});
|
||||
expect(() => TestBed.createComponent(MyComp))
|
||||
.toThrowError(`Directive ${stringify(SomeDirective)} has no selector, please add it!`);
|
||||
});
|
||||
|
||||
it('should use a default element name for components without selectors', () => {
|
||||
let noSelectorComponentFactory: ComponentFactory<SomeComponent> = undefined !;
|
||||
|
|
Loading…
Reference in New Issue