Date: Fri, 26 Nov 2021 20:01:05 +0100
Subject: [PATCH 6/9] docs: add selector with attribute example (#264)
Closes #263
---
.../src/app/examples/02-input-output.spec.ts | 4 ++--
.../src/app/examples/11-ng-content.spec.ts | 6 ++----
apps/example-app/src/app/examples/11-ng-content.ts | 1 +
.../17-component-with-attribute-selector.spec.ts | 14 ++++++++++++++
.../17-component-with-attribute-selector.ts | 11 +++++++++++
5 files changed, 30 insertions(+), 6 deletions(-)
create mode 100644 apps/example-app/src/app/examples/17-component-with-attribute-selector.spec.ts
create mode 100644 apps/example-app/src/app/examples/17-component-with-attribute-selector.ts
diff --git a/apps/example-app/src/app/examples/02-input-output.spec.ts b/apps/example-app/src/app/examples/02-input-output.spec.ts
index 663d63e0..f1bd4a1c 100644
--- a/apps/example-app/src/app/examples/02-input-output.spec.ts
+++ b/apps/example-app/src/app/examples/02-input-output.spec.ts
@@ -33,8 +33,8 @@ test('is possible to set input and listen for output', async () => {
test('is possible to set input and listen for output with the template syntax', async () => {
const sendSpy = jest.fn();
- await render(InputOutputComponent, {
- template: '',
+ await render('', {
+ declarations: [InputOutputComponent],
componentProperties: {
sendValue: sendSpy,
},
diff --git a/apps/example-app/src/app/examples/11-ng-content.spec.ts b/apps/example-app/src/app/examples/11-ng-content.spec.ts
index 14a1630c..2dedd809 100644
--- a/apps/example-app/src/app/examples/11-ng-content.spec.ts
+++ b/apps/example-app/src/app/examples/11-ng-content.spec.ts
@@ -1,4 +1,3 @@
-import { TestBed } from '@angular/core/testing';
import { render, screen } from '@testing-library/angular';
import { CellComponent } from './11-ng-content';
@@ -6,9 +5,8 @@ import { CellComponent } from './11-ng-content';
test('it is possible to test ng-content without selector', async () => {
const projection = 'it should be showed into a p element!';
- TestBed.overrideComponent(CellComponent, { set: { selector: 'cell' } });
- await render(CellComponent, {
- template: `${projection} | `,
+ await render(`${projection}`, {
+ declarations: [CellComponent]
});
expect(screen.getByText(projection)).toBeInTheDocument();
diff --git a/apps/example-app/src/app/examples/11-ng-content.ts b/apps/example-app/src/app/examples/11-ng-content.ts
index 302563f1..47845919 100644
--- a/apps/example-app/src/app/examples/11-ng-content.ts
+++ b/apps/example-app/src/app/examples/11-ng-content.ts
@@ -1,6 +1,7 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
@Component({
+ selector: 'app-fixture',
template: `
diff --git a/apps/example-app/src/app/examples/17-component-with-attribute-selector.spec.ts b/apps/example-app/src/app/examples/17-component-with-attribute-selector.spec.ts
new file mode 100644
index 00000000..cd6334d1
--- /dev/null
+++ b/apps/example-app/src/app/examples/17-component-with-attribute-selector.spec.ts
@@ -0,0 +1,14 @@
+import { render, screen } from '@testing-library/angular';
+import {ComponentWithAttributeSelectorComponent} from './17-component-with-attribute-selector';
+
+// Note: At this stage it is not possible to use the render(ComponentWithAttributeSelectorComponent, {...}) syntax
+// for components with attribute selectors!
+test('is possible to set input of component with attribute selector through template', async () => {
+ await render(``, {
+ declarations: [ComponentWithAttributeSelectorComponent]
+ });
+
+ const valueControl = screen.getByTestId('value');
+
+ expect(valueControl).toHaveTextContent('42');
+});
diff --git a/apps/example-app/src/app/examples/17-component-with-attribute-selector.ts b/apps/example-app/src/app/examples/17-component-with-attribute-selector.ts
new file mode 100644
index 00000000..2d0b904b
--- /dev/null
+++ b/apps/example-app/src/app/examples/17-component-with-attribute-selector.ts
@@ -0,0 +1,11 @@
+import { Component, Input } from '@angular/core';
+
+@Component({
+ selector: 'app-fixture-component-with-attribute-selector[value]',
+ template: `
+ {{ value }}
+ `,
+})
+export class ComponentWithAttributeSelectorComponent {
+ @Input() value!: number;
+}
From 30768855c09bfc95d3df55ae12fa7254b690c0c1 Mon Sep 17 00:00:00 2001
From: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com>
Date: Fri, 26 Nov 2021 21:52:28 +0100
Subject: [PATCH 7/9] feat: remove RenderDirectiveOptions (#265)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
BREAKING CHANGE:
The template property is removed from the render options.
Instead, you can pass it as the first argument of `render.
BEFORE:
```ts
await render(InputOutputComponent, {
// 👇 this is deprecated
template: '',
componentProperties: {
sendValue: sendSpy,
},
});
```
AFTER:
```ts
// 👇 Move the template in the first argument
await render('', {
// 👇 Add the component to declarations
declarations: [InputOutputComponent],
componentProperties: {
sendValue: sendSpy,
},
});
```
---
.../src/app/examples/11-ng-content.spec.ts | 2 +-
projects/testing-library/src/lib/models.ts | 37 -------------------
.../src/lib/testing-library.ts | 33 ++++-------------
.../tests/render-template.spec.ts | 9 -----
4 files changed, 8 insertions(+), 73 deletions(-)
diff --git a/apps/example-app/src/app/examples/11-ng-content.spec.ts b/apps/example-app/src/app/examples/11-ng-content.spec.ts
index 2dedd809..f061e862 100644
--- a/apps/example-app/src/app/examples/11-ng-content.spec.ts
+++ b/apps/example-app/src/app/examples/11-ng-content.spec.ts
@@ -4,7 +4,7 @@ import { CellComponent } from './11-ng-content';
test('it is possible to test ng-content without selector', async () => {
const projection = 'it should be showed into a p element!';
-
+
await render(`${projection}`, {
declarations: [CellComponent]
});
diff --git a/projects/testing-library/src/lib/models.ts b/projects/testing-library/src/lib/models.ts
index bda39543..7f5a02a7 100644
--- a/projects/testing-library/src/lib/models.ts
+++ b/projects/testing-library/src/lib/models.ts
@@ -256,43 +256,6 @@ export interface RenderComponentOptions
- extends RenderComponentOptions {
- /**
- * @description
- * The template to render the directive.
- * This template will override the template from the WrapperComponent.
- *
- * @example
- * const component = await render(SpoilerDirective, {
- * template: ``
- * })
- *
- * @deprecated Use `render(template, { declarations: [SomeDirective] })` instead.
- */
- template: string;
- /**
- * @description
- * An Angular component to wrap the component in.
- * The template will be overridden with the `template` option.
- *
- * @default
- * `WrapperComponent`, an empty component that strips the `ng-version` attribute
- *
- * @example
- * const component = await render(SpoilerDirective, {
- * template: ``
- * wrapper: CustomWrapperComponent
- * })
- */
- wrapper?: Type;
- componentProperties?: Partial;
-}
-
// eslint-disable-next-line @typescript-eslint/ban-types
export interface RenderTemplateOptions
extends RenderComponentOptions {
diff --git a/projects/testing-library/src/lib/testing-library.ts b/projects/testing-library/src/lib/testing-library.ts
index bfbe7f93..6d66e933 100644
--- a/projects/testing-library/src/lib/testing-library.ts
+++ b/projects/testing-library/src/lib/testing-library.ts
@@ -26,7 +26,7 @@ import {
getQueriesForElement,
queries as dtlQueries,
} from '@testing-library/dom';
-import { RenderComponentOptions, RenderDirectiveOptions, RenderTemplateOptions, RenderResult } from './models';
+import { RenderComponentOptions, RenderTemplateOptions, RenderResult } from './models';
import { getConfig } from './config';
const mountedFixtures = new Set>();
@@ -36,13 +36,6 @@ export async function render(
component: Type,
renderOptions?: RenderComponentOptions,
): Promise>;
-/**
- * @deprecated Use `render(template, { declarations: [DirectiveType] })` instead.
- */
-export async function render(
- component: Type,
- renderOptions?: RenderDirectiveOptions,
-): Promise>;
export async function render(
template: string,
renderOptions?: RenderTemplateOptions,
@@ -50,10 +43,7 @@ export async function render(
export async function render(
sut: Type | string,
- renderOptions:
- | RenderComponentOptions
- | RenderDirectiveOptions
- | RenderTemplateOptions = {},
+ renderOptions: RenderComponentOptions | RenderTemplateOptions = {},
): Promise> {
const { dom: domConfig, ...globalConfig } = getConfig();
const {
@@ -86,7 +76,6 @@ export async function render(
declarations: addAutoDeclarations(sut, {
declarations,
excludeComponentDeclaration,
- template,
wrapper,
}),
imports: addAutoImports({
@@ -106,7 +95,7 @@ export async function render(
TestBed.overrideProvider(provide, provider);
});
- const componentContainer = createComponentFixture(sut, { template, wrapper });
+ const componentContainer = createComponentFixture(sut, { wrapper });
let fixture: ComponentFixture;
let detectChanges: () => void;
@@ -227,22 +216,18 @@ async function createComponent(component: Type): Promise(
sut: Type | string,
- { template, wrapper }: Pick, 'template' | 'wrapper'>,
+ { wrapper }: Pick, 'wrapper'>,
): Type {
if (typeof sut === 'string') {
TestBed.overrideTemplate(wrapper, sut);
return wrapper;
}
- if (template) {
- TestBed.overrideTemplate(wrapper, template);
- return wrapper;
- }
return sut;
}
function setComponentProperties(
fixture: ComponentFixture,
- { componentProperties = {} }: Pick, 'componentProperties'>,
+ { componentProperties = {} }: Pick, 'componentProperties'>,
) {
for (const key of Object.keys(componentProperties)) {
const descriptor: PropertyDescriptor = Object.getOwnPropertyDescriptor(
@@ -293,19 +278,15 @@ function addAutoDeclarations(
{
declarations,
excludeComponentDeclaration,
- template,
wrapper,
- }: Pick, 'declarations' | 'excludeComponentDeclaration' | 'template' | 'wrapper'>,
+ }: Pick, 'declarations' | 'excludeComponentDeclaration' | 'wrapper'>,
) {
if (typeof sut === 'string') {
return [...declarations, wrapper];
}
- const wrappers = () => (template ? [wrapper] : []);
-
const components = () => (excludeComponentDeclaration ? [] : [sut]);
-
- return [...declarations, ...wrappers(), ...components()];
+ return [...declarations, ...components()];
}
function addAutoImports({ imports, routes }: Pick, 'imports' | 'routes'>) {
diff --git a/projects/testing-library/tests/render-template.spec.ts b/projects/testing-library/tests/render-template.spec.ts
index 60c2a074..9dd20d01 100644
--- a/projects/testing-library/tests/render-template.spec.ts
+++ b/projects/testing-library/tests/render-template.spec.ts
@@ -62,15 +62,6 @@ test('the component renders', async () => {
expect(screen.getByText('Hello Angular!')).toBeInTheDocument();
});
-test('the directive renders (compatibility with the deprecated signature)', async () => {
- const view = await render(OnOffDirective, {
- template: '',
- });
-
- // eslint-disable-next-line testing-library/no-container
- expect(view.container.querySelector('[onoff]')).toBeInTheDocument();
-});
-
test('uses the default props', async () => {
await render('', {
declarations: [OnOffDirective],
From 82e037eee65bbb38c42b5290baf277e588c6e761 Mon Sep 17 00:00:00 2001
From: timdeschryver <28659384+timdeschryver@users.noreply.github.com>
Date: Sat, 27 Nov 2021 09:13:14 +0100
Subject: [PATCH 8/9] fix: query params with same keys are added to the
collection
BREAKING CHANGE:
Query params on a router link with the same key are no longer overwriting the last value.
Instead they are added to an array.
---
projects/testing-library/src/lib/testing-library.ts | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/projects/testing-library/src/lib/testing-library.ts b/projects/testing-library/src/lib/testing-library.ts
index 6d66e933..12d14fde 100644
--- a/projects/testing-library/src/lib/testing-library.ts
+++ b/projects/testing-library/src/lib/testing-library.ts
@@ -130,8 +130,14 @@ export async function render(
const queryParams = params
? params.split('&').reduce((qp, q) => {
const [key, value] = q.split('=');
- // TODO(Breaking): group same keys qp[key] ? [...qp[key], value] : value
- qp[key] = value;
+ const currentValue = qp[key];
+ if (typeof currentValue === 'undefined') {
+ qp[key] = value;
+ } else if (Array.isArray(currentValue)) {
+ qp[key] = [...currentValue, value];
+ } else {
+ qp[key] = [currentValue, value];
+ }
return qp;
}, {})
: undefined;
From 6ea2e7f923a321c690d2e5193c935e0f0ad8ec9e Mon Sep 17 00:00:00 2001
From: timdeschryver <28659384+timdeschryver@users.noreply.github.com>
Date: Sat, 27 Nov 2021 09:14:50 +0100
Subject: [PATCH 9/9] fix: wrapper component selector is appended with `atl-`
BEFORE:
Wrapper component had `wrapper-component` as selector
```ts
@Component({ selector: 'wrapper-component', template: '' })
class WrapperComponent {}
```
AFTER:
Wrapper component has `atl-wrapper-component` as selector
```ts
@Component({ selector: 'atl-wrapper-component', template: '' })
class WrapperComponent {}
```
---
projects/testing-library/src/lib/testing-library.ts | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/projects/testing-library/src/lib/testing-library.ts b/projects/testing-library/src/lib/testing-library.ts
index 12d14fde..1a517aa2 100644
--- a/projects/testing-library/src/lib/testing-library.ts
+++ b/projects/testing-library/src/lib/testing-library.ts
@@ -388,9 +388,7 @@ if (typeof process === 'undefined' || !process.env?.ATL_SKIP_AUTO_CLEANUP) {
}
}
-// TODO: rename to `atl-wrapper-component`
-// eslint-disable-next-line @angular-eslint/component-selector
-@Component({ selector: 'wrapper-component', template: '' })
+@Component({ selector: 'atl-wrapper-component', template: '' })
class WrapperComponent {}
/**