Skip to content

Commit

Permalink
Merge pull request #132 from qonto/test-app-typescript-conversion
Browse files Browse the repository at this point in the history
refactor: migrate test app package to TypeScript
  • Loading branch information
michelegera committed Nov 27, 2023
2 parents ceb299a + 7647e76 commit 4a6f862
Show file tree
Hide file tree
Showing 20 changed files with 235 additions and 96 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,11 @@ jobs:
pnpm-version: 8.5.1
node-version: 18.x
args: "--frozen-lockfile"
- name: Update TS version
- name: Update TS version on addon package
run: pnpm add -D ${{ matrix.typescript-scenario }}
working-directory: ember-prismic-dom
- name: Update TS version on test-app package
run: pnpm add -D ${{ matrix.typescript-scenario }}
working-directory: test-app
- name: Type checking
run: pnpm lint:types
File renamed without changes.
1 change: 1 addition & 0 deletions test-app/app/components/group-list-item.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<ul>{{yield}} elephant</ul>
12 changes: 12 additions & 0 deletions test-app/app/components/group-list-item.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import templateOnlyComponent from '@ember/component/template-only';

export interface GroupListItemSignature {
Element: HTMLUListElement;
Blocks: {
default: [];
};
}

const GroupListItem = templateOnlyComponent<GroupListItemSignature>();

export default GroupListItem;
1 change: 1 addition & 0 deletions test-app/app/components/hyperlink.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<a href={{@node.node.data.url}}>{{yield}}</a>
17 changes: 17 additions & 0 deletions test-app/app/components/hyperlink.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import templateOnlyComponent from '@ember/component/template-only';

export interface HyperlinkSignature {
Element: HTMLAnchorElement;
// The `node` argument should be a TreeNode, but that type is not exported
// from the package.
// https://github.com/prismicio/prismic-richtext/blob/495456d843ef79153ab9de87cc76b1cc940f6aec/src/types.ts#L136
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Args: { node: any };
Blocks: {
default: [];
};
}

const Hyperlink = templateOnlyComponent<HyperlinkSignature>();

export default Hyperlink;
1 change: 1 addition & 0 deletions test-app/app/components/list-item.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<li>{{yield}} banana</li>
12 changes: 12 additions & 0 deletions test-app/app/components/list-item.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import templateOnlyComponent from '@ember/component/template-only';

export interface ListItemSignature {
Element: HTMLUListElement;
Blocks: {
default: [];
};
}

const ListItem = templateOnlyComponent<ListItemSignature>();

export default ListItem;
1 change: 1 addition & 0 deletions test-app/app/components/super-custom.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<mark>{{yield}}</mark>
12 changes: 12 additions & 0 deletions test-app/app/components/super-custom.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import templateOnlyComponent from '@ember/component/template-only';

interface SuperCustomSignature {
Element: HTMLElement;
Blocks: {
default: [];
};
}

const SuperCustom = templateOnlyComponent<SuperCustomSignature>();

export default SuperCustom;
File renamed without changes.
10 changes: 10 additions & 0 deletions test-app/config/ember-try.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
const getChannelURL = require('ember-source-channel-url');
const { embroiderSafe, embroiderOptimized } = require('@embroider/test-setup');

// Needed for ember-source < 4.8, when preview types were first shipped
const emberTypesPackages = {
'@types/ember__application': '^4.0.10',
'@types/ember__component': '^4.0.21',
'@types/ember__routing': '^4.0.19',
};

module.exports = async function () {
return {
usePnpm: true,
Expand All @@ -12,6 +19,7 @@ module.exports = async function () {
npm: {
devDependencies: {
'ember-source': '~3.28.0',
...emberTypesPackages,
},
},
},
Expand All @@ -20,6 +28,7 @@ module.exports = async function () {
npm: {
devDependencies: {
'ember-source': '~4.4.0',
...emberTypesPackages,
},
},
},
Expand Down Expand Up @@ -75,6 +84,7 @@ module.exports = async function () {
npm: {
devDependencies: {
'ember-source': '~3.28.0',
...emberTypesPackages,
},
ember: {
edition: 'classic',
Expand Down
4 changes: 3 additions & 1 deletion test-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@
"lint:hbs:fix": "ember-template-lint . --fix",
"lint:js": "eslint . --cache",
"lint:js:fix": "eslint . --fix",
"lint:types": "glint",
"start": "ember serve",
"test": "concurrently \"pnpm:lint\" \"pnpm:test:*\" --names \"lint,test:\"",
"test:ember": "ember test"
"test:ember": "ember test",
"try:ember": "ember try:one"
},
"devDependencies": {
"@babel/eslint-parser": "^7.23.3",
Expand Down
14 changes: 0 additions & 14 deletions test-app/tests/helpers/clean-html.js

This file was deleted.

18 changes: 18 additions & 0 deletions test-app/tests/helpers/clean-html.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export default function cleanHtml({
element,
}: {
element: HTMLElement;
}): string {
const elementHelperIds = / id="[a-zA-Z0-9]*"/g;
const emberViewClass = / class="ember-view"/g;
const extraWhiteSpace = /\s{2,}/g;
const spaceBetweenTags = />(\s+)</g;
const spaceAroundContent = />(\s+)([^<]+)(\s+)</g;

return element.innerHTML
.replace(elementHelperIds, '')
.replace(emberViewClass, '')
.replace(extraWhiteSpace, ' ')
.replace(spaceBetweenTags, '><')
.replace(spaceAroundContent, '>$2<');
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@ import {
setupApplicationTest as upstreamSetupApplicationTest,
setupRenderingTest as upstreamSetupRenderingTest,
setupTest as upstreamSetupTest,
type SetupTestOptions,
} from 'ember-qunit';

// This file exists to provide wrappers around ember-qunit's / ember-mocha's
// test setup functions. This way, you can easily extend the setup that is
// needed per test type.

function setupApplicationTest(hooks, options) {
function setupApplicationTest(
hooks: NestedHooks,
options: SetupTestOptions,
): void {
upstreamSetupApplicationTest(hooks, options);

// Additional setup for application tests can be done here.
Expand All @@ -27,13 +31,16 @@ function setupApplicationTest(hooks, options) {
// setupMirage(hooks); // ember-cli-mirage
}

function setupRenderingTest(hooks, options) {
function setupRenderingTest(
hooks: NestedHooks,
options: SetupTestOptions,
): void {
upstreamSetupRenderingTest(hooks, options);

// Additional setup for rendering tests can be done here.
}

function setupTest(hooks, options) {
function setupTest(hooks: NestedHooks, options: SetupTestOptions): void {
upstreamSetupTest(hooks, options);

// Additional setup for unit tests can be done here.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,44 @@
import { render } from '@ember/test-helpers';
import { setupRenderingTest } from 'ember-qunit';
import { module, test } from 'qunit';
import { setComponentTemplate } from '@ember/component';
import Component from '@glimmer/component';

import type { TestContext as TestContextBase } from '@ember/test-helpers';
import type { PrismicDomArgs } from 'ember-prismic-dom/components/prismic/dom';
import { hbs } from 'ember-cli-htmlbars';

import cleanHtml from '../../../helpers/clean-html';
import GroupListItem, {
type GroupListItemSignature,
} from 'test-app/components/group-list-item';
import Hyperlink, {
type HyperlinkSignature,
} from 'test-app/components/hyperlink';
import ListItem, {
type ListItemSignature,
} from 'test-app/components/list-item';
import SuperCustom from 'test-app/components/super-custom';

import cleanHtml from 'test-app/tests/helpers/clean-html';
import type { TemplateOnlyComponent } from '@ember/component/template-only';

interface TestContext extends TestContextBase {
element: HTMLElement;
nodes: PrismicDomArgs['nodes'];
groupListItem: TemplateOnlyComponent<GroupListItemSignature>;
hyperlink: TemplateOnlyComponent<HyperlinkSignature>;
listItem: TemplateOnlyComponent<ListItemSignature> | undefined;
}

module('Integration | Component | prismic/dom', function (hooks) {
setupRenderingTest(hooks);

module('single elements', function () {
test('renders string', async function (assert) {
await render(hbs`<Prismic::Dom @nodes='some text' />`);
test('renders string', async function (this: TestContext, assert) {
await render<TestContext>(hbs`<Prismic::Dom @nodes='some text' />`);
assert.strictEqual(cleanHtml(this), '<div>some text</div>');
});
});

module('custom elements', function () {
test('hyperlink', async function (assert) {
class Hyperlink extends Component {}
setComponentTemplate(
hbs`<a href={{@node.node.data.url}}>{{yield}}</a>`,
Hyperlink,
);

this.hyperlink = Hyperlink;

test('hyperlink', async function (this: TestContext, assert) {
this.nodes = [
{
type: 'paragraph',
Expand All @@ -43,19 +54,20 @@ module('Integration | Component | prismic/dom', function (hooks) {
},
];

await render(
this.hyperlink = Hyperlink;

await render<TestContext>(
hbs`<Prismic::Dom @nodes={{this.nodes}} @hyperlink={{this.hyperlink}} />`,
);

assert.strictEqual(
cleanHtml(this),
'<div><p>A <a href="https://example.org">link</a> to somewhere</p></div>',
);
});

test('handle passing a custom component as a string', async function (assert) {
class SuperCustom extends Component {}
setComponentTemplate(hbs`<mark>{{yield}}</mark>`, SuperCustom);

test('handle passing a custom component as a string', async function (this: TestContext, assert) {
this.owner.register('component:super-custom', SuperCustom);
this.nodes = [
{
type: 'paragraph',
Expand All @@ -64,15 +76,14 @@ module('Integration | Component | prismic/dom', function (hooks) {
{
start: 2,
end: 7,
type: 'super-custom',
type: 'strong',
},
],
},
];
this.owner.register('component:super-custom', SuperCustom);

await render(
hbs`<Prismic::Dom @nodes={{this.nodes}} @super-custom="super-custom" />`,
await render<TestContext>(
hbs`<Prismic::Dom @nodes={{this.nodes}} @strong="super-custom" />`,
);

assert.strictEqual(
Expand All @@ -81,22 +92,16 @@ module('Integration | Component | prismic/dom', function (hooks) {
);
});

test('list', async function (assert) {
class GroupListItem extends Component {}
class ListItem extends Component {}

setComponentTemplate(hbs`<ul>{{~yield~}} elephant</ul>`, GroupListItem);
setComponentTemplate(hbs`<li>{{~yield}} banana</li>`, ListItem);

test('list', async function (this: TestContext, assert) {
this.nodes = [
{ type: 'list-item', text: 'one', spans: [] },
{ type: 'list-item', text: 'two', spans: [] },
];

this.groupListItem = GroupListItem;
this.listItem = '';
this.listItem = undefined;

await render(
await render<TestContext>(
hbs`<Prismic::Dom @nodes={{this.nodes}} @group-list-item={{this.groupListItem}} @list-item={{this.listItem}}/>`,
);

Expand All @@ -115,21 +120,21 @@ module('Integration | Component | prismic/dom', function (hooks) {
});

module('complex combinations', function () {
test('list', async function (assert) {
test('list', async function (this: TestContext, assert) {
this.nodes = [
{ type: 'o-list-item', text: 'one', spans: [] },
{ type: 'o-list-item', text: 'two', spans: [] },
];

await render(hbs`<Prismic::Dom @nodes={{this.nodes}} />`);
await render<TestContext>(hbs`<Prismic::Dom @nodes={{this.nodes}} />`);

assert.strictEqual(
cleanHtml(this),
'<div><ol><li>one</li><li>two</li></ol></div>',
);
});

test('it renders text with overlapping spans', async function (assert) {
test('it renders text with overlapping spans', async function (this: TestContext, assert) {
this.nodes = [
{
type: 'paragraph',
Expand All @@ -141,15 +146,15 @@ module('Integration | Component | prismic/dom', function (hooks) {
},
];

await render(hbs`<Prismic::Dom @nodes={{this.nodes}} />`);
await render<TestContext>(hbs`<Prismic::Dom @nodes={{this.nodes}} />`);

assert.strictEqual(
cleanHtml(this),
'<div><p>This is some text with <strong>overla<em>pp</em></strong><em>ings</em> spans and here</p></div>',
);
});

test('it renders links with overlapping styles', async function (assert) {
test('it renders links with overlapping styles', async function (this: TestContext, assert) {
this.nodes = [
{
type: 'paragraph',
Expand All @@ -167,7 +172,7 @@ module('Integration | Component | prismic/dom', function (hooks) {
},
];

await render(hbs`<Prismic::Dom @nodes={{this.nodes}} />`);
await render<TestContext>(hbs`<Prismic::Dom @nodes={{this.nodes}} />`);

assert.strictEqual(
cleanHtml(this),
Expand Down

0 comments on commit 4a6f862

Please sign in to comment.