Skip to content

Commit

Permalink
feat(ng-dev): ComponentContext supports standalone components
Browse files Browse the repository at this point in the history
  • Loading branch information
ersimont committed Jan 21, 2023
1 parent 7b51270 commit 92eae17
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,26 @@ describe('ComponentContext', () => {
expect(ctx.inject(ANIMATION_MODULE_TYPE)).toBe('NoopAnimations');
});
});

it('supports standalone components', () => {
@Component({ template: 'hi', standalone: true })
class StandaloneComponent {}

const ctx = new ComponentContext(StandaloneComponent);
ctx.run(() => {
expect(ctx.fixture.nativeElement.textContent).toBe('hi');
});
});

it('errors with a nice message when given a non-component', () => {
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
class NotAComponent {}

expect(() => {
// eslint-disable-next-line no-new -- nothing more is needed for this test
new ComponentContext(NotAComponent);
}).toThrowError('That does not appear to be a component');
});
});

describe('.assignInputs()', () => {
Expand Down
21 changes: 13 additions & 8 deletions projects/ng-dev/src/lib/component-context/component-context.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { ApplicationInitStatus, Type } from '@angular/core';
import {
ApplicationInitStatus,
reflectComponentType,
Type,
} from '@angular/core';
import {
ComponentFixture,
TestBed,
Expand All @@ -7,6 +11,7 @@ import {
} from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { assert } from '@s-libs/js-core';
import { keys } from '@s-libs/micro-dash';
import {
AngularContext,
Expand Down Expand Up @@ -164,13 +169,13 @@ export class ComponentContext<T> extends AngularContext {
moduleMetadata: TestModuleMetadata = {},
unboundInputs: Array<keyof T> = [],
) {
const inputProperties = WrapperComponent.wrap(componentType, unboundInputs);
super(
extendMetadata(moduleMetadata, {
imports: [NoopAnimationsModule],
declarations: [WrapperComponent, componentType],
}),
);
const mirror = reflectComponentType(componentType);
assert(mirror, 'That does not appear to be a component');
const inputProperties = WrapperComponent.wrap(mirror, unboundInputs);
const imports: any[] = [NoopAnimationsModule];
const declarations: any[] = [WrapperComponent];
(mirror.isStandalone ? imports : declarations).push(componentType);
super(extendMetadata(moduleMetadata, { imports, declarations }));

this.#componentType = componentType;
this.#inputProperties = new Set(inputProperties);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,4 @@ describe('WrapperComponent', () => {
expect(ctx.getComponentInstance().doNotBind).toBe('default value');
});
});

it('errors with a nice message when given a non-component', () => {
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
class NotAComponent {}

expect(() => {
// eslint-disable-next-line no-new -- nothing more is needed for this test
new ComponentContext(NotAComponent);
}).toThrowError('That does not appear to be a component');
});
});
16 changes: 4 additions & 12 deletions projects/ng-dev/src/lib/component-context/wrapper.component.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import {
Component,
ComponentMirror,
reflectComponentType,
Type,
} from '@angular/core';
import { Component, ComponentMirror } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { assert } from '@s-libs/js-core';

// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection -- change detection is carefully orchestrated in the typescript */
@Component({ template: '' })
Expand All @@ -14,13 +8,11 @@ export class WrapperComponent<T> {
styles: Record<string, any> = {};

static wrap<T>(
componentType: Type<T>,
componentMirror: ComponentMirror<T>,
unboundInputs: Array<keyof T>,
): Array<keyof T> {
const mirror = reflectComponentType(componentType);
assert(mirror, 'That does not appear to be a component');
const selector = getSelector(mirror);
const inputs = mirror.inputs.filter(
const selector = getSelector(componentMirror);
const inputs = componentMirror.inputs.filter(
({ propName }) => !unboundInputs.includes(propName as keyof T),
);

Expand Down

0 comments on commit 92eae17

Please sign in to comment.