Skip to content

Commit

Permalink
test: update tests
Browse files Browse the repository at this point in the history
Signed-off-by: Rong Sen Ng (motss) <wes.ngrongsen@gmail.com>
  • Loading branch information
motss committed Feb 20, 2022
1 parent c201c14 commit 4f212ae
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 73 deletions.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@
"access": "public"
},
"nano-staged": {
"*.ts": ["npm run lint:build -- --fix", "git add"]
"*.ts": [
"npm run lint:build -- --fix",
"git add"
]
}
}
25 changes: 9 additions & 16 deletions src/__demo__/demo-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,6 @@ export class DemoApp extends RootElement {
.max=${'2100-12-31'}
.min=${'1970-01-01'}
.value=${'2020-02-02'}
.lazyLoad=${async () => {
const deps = [
'../date-picker/app-date-picker.js',
'../date-picker-input-surface/app-date-picker-input-surface.js',
];
await Promise.all(deps.map(n => import(n)));
console.debug('Lazy loaded');
}}
></app-date-picker-input>
<button data-id="datePickerDialog1" @click=${this.#showDialog}>Open</button>
Expand All @@ -115,10 +105,13 @@ export class DemoApp extends RootElement {
`;
}

async #showDialog(ev: MouseEvent) {
#showDialog = async (ev: MouseEvent) => {
const { dataset } = ev.currentTarget as HTMLButtonElement;

const dialog = this.query<AppDatePickerDialog>(`#${dataset.id}`);
const task = globalThis.customElements.whenDefined(appDatePickerDialogName);

await import('../date-picker-dialog/app-date-picker-dialog.js');
await task;

dialog?.show();

Expand All @@ -127,17 +120,17 @@ export class DemoApp extends RootElement {
valueAsDate: dialog?.valueAsDate,
valueAsNumber: new Date(dialog?.valueAsNumber as number),
});
}
};

#dateUpdated({
#dateUpdated = ({
detail,
currentTarget,
}: CustomEvent<CustomEventDetail['date-updated']['detail']>): void {
}: CustomEvent<CustomEventDetail['date-updated']['detail']>): void => {
const { id } = currentTarget as AppDatePicker;

console.debug({
id,
detail,
});
}
};
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import '../../date-picker/app-date-picker';
import '../../date-picker-input/app-date-picker-input';
import '../../date-picker-input-surface/app-date-picker-input-surface';
import '../../date-picker-input/app-date-picker-input';

import type { Button } from '@material/mwc-button';
import { expect, fixture, html } from '@open-wc/testing';
Expand Down
30 changes: 30 additions & 0 deletions src/__tests__/icon-button/app-icon-button.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import '../../icon-button/app-icon-button';

import { expect, fixture, html } from '@open-wc/testing';
import { sendKeys } from '@web/test-runner-commands';

import type { AppIconButton } from '../../icon-button/app-icon-button';
import { appIconButtonName } from '../../icon-button/constants';

describe(appIconButtonName, () => {
it('renders', async () => {
const el = await fixture<AppIconButton>(html`
<app-icon-button></app-icon-button>
`);

expect(await el.ripple).not.exist;

el.focus();

/**
* NOTE(motss): `.click()` and `.focus()` does not render any ripple.
* So we need to actually focus with keypress or mouse click.
*/
await sendKeys({ press: 'Enter' });

// Force layout
await el.layout();

expect(await el.ripple).exist;
});
});
17 changes: 9 additions & 8 deletions src/date-picker-dialog/date-picker-dialog.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import '@material/mwc-button';
import '@material/mwc-dialog';
import '../date-picker/app-date-picker.js';
import './app-date-picker-dialog-base.js';

import type { TemplateResult } from 'lit';
Expand All @@ -17,7 +18,7 @@ import { RootElement } from '../root-element/root-element.js';
import { baseStyling } from '../stylings.js';
import type { CustomEventDetail } from '../typings.js';
import { datePickerDialogStyling } from './stylings.js';
import type { DatePickerDialogProperties, DialogClosedEventDetail, DialogClosingEventDetail } from './typings.js';
import type { DatePickerDialogChangedProperties, DatePickerDialogProperties, DialogClosedEventDetail, DialogClosingEventDetail } from './typings.js';

export class DatePickerDialog extends DatePickerMixin(DatePickerMinMaxMixin(RootElement)) implements DatePickerDialogProperties {
public get valueAsDate(): Date {
Expand Down Expand Up @@ -50,15 +51,15 @@ export class DatePickerDialog extends DatePickerMixin(DatePickerMinMaxMixin(Root
this.#selectedDate = this.#valueAsDate = toResolvedDate();
}

override willUpdate(changedProperties: Map<string | number | symbol, unknown>): void {
protected override willUpdate(changedProperties: DatePickerDialogChangedProperties): void {
super.willUpdate(changedProperties);

if (!this._rendered && this.open) {
this._rendered = true;
}
}

override updated(changedProperties: Map<string | number | symbol, unknown>) {
protected override updated(changedProperties: DatePickerDialogChangedProperties): void {
/**
* NOTE(motss): `value` should always update `#selectedDate` and `#valueAsDate`.
*/
Expand Down Expand Up @@ -120,7 +121,7 @@ export class DatePickerDialog extends DatePickerMixin(DatePickerMinMaxMixin(Root
detail: {
valueAsDate,
},
}: CustomEvent<CustomEventDetail['date-updated']['detail']>) {
}: CustomEvent<CustomEventDetail['date-updated']['detail']>): void {
this.#selectedDate = new Date(valueAsDate);

/**
Expand All @@ -138,7 +139,7 @@ export class DatePickerDialog extends DatePickerMixin(DatePickerMinMaxMixin(Root
detail: {
valueAsDate,
},
}: CustomEvent<CustomEventDetail['first-updated']['detail']>) {
}: CustomEvent<CustomEventDetail['first-updated']['detail']>): void {
this.#selectedDate = this.#valueAsDate = valueAsDate;
}

Expand Down Expand Up @@ -196,7 +197,7 @@ export class DatePickerDialog extends DatePickerMixin(DatePickerMinMaxMixin(Root
});
}

#onClosed = async (ev: CustomEvent<DialogClosedEventDetail>) => {
#onClosed = async (ev: CustomEvent<DialogClosedEventDetail>): Promise<void> => {
const datePicker = await this._datePicker;

this.hide();
Expand Down Expand Up @@ -226,8 +227,8 @@ export class DatePickerDialog extends DatePickerMixin(DatePickerMinMaxMixin(Root
this.fire({ detail, type: 'opening' });
};

#onResetClick() {
#onResetClick = () => {
this.#isResetAction = true;
this.value = undefined;
}
};
}
7 changes: 6 additions & 1 deletion src/date-picker-dialog/typings.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import type { Dialog } from '@material/mwc-dialog';

export interface DatePickerDialogProperties extends DialogProperties {
import type { ChangedProperties, DatePickerProperties } from '../typings';

export type DatePickerDialogChangedProperties = ChangedProperties<DatePickerDialogProperties>;

export interface DatePickerDialogProperties extends DialogProperties, DatePickerProperties {
confirmLabel: string;
dismissLabel: string;
hide(): void;
resetLabel: string;
show(): void;
}
Expand Down
80 changes: 50 additions & 30 deletions src/date-picker-input/date-picker-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import { datePickerInputStyling } from './stylings.js';

export class DatePickerInput extends ElementMixin(DatePickerMixin(DatePickerMinMaxMixin(TextField))) implements DatePickerMixinProperties {
public override iconTrailing = 'clear';
public lazyLoad?:() => Promise<void>;
public override type = appDatePickerInputType;

public get valueAsDate(): Date | null {
Expand All @@ -46,13 +45,14 @@ export class DatePickerInput extends ElementMixin(DatePickerMixin(DatePickerMinM
@queryAsync('.mdc-text-field__input') protected $input!: Promise<HTMLInputElement | null>;
@queryAsync(appDatePickerInputSurfaceName) protected $inputSurface!: Promise<AppDatePickerInputSurface | null>;
@queryAsync(appDatePickerName) protected $picker!: Promise<AppDatePicker | null>;
@state() private _lazyLoaded = false;
@state() private _open = false;
@state() private _rendered = false;
@state() private _valueText = '';

#disconnect: () => void = () => undefined;
#focusElement: HTMLElement | undefined = undefined;
#isClearAction = false;
#lazyLoading = false;
#picker: AppDatePicker | undefined = undefined;
#selectedDate: Date | undefined;
#valueAsDate: Date | undefined;
Expand All @@ -64,7 +64,7 @@ export class DatePickerInput extends ElementMixin(DatePickerMixin(DatePickerMinM
datePickerInputStyling,
];

public override async disconnectedCallback(): Promise<void> {
public override disconnectedCallback(): void {
super.disconnectedCallback();

this.#disconnect();
Expand Down Expand Up @@ -107,7 +107,7 @@ export class DatePickerInput extends ElementMixin(DatePickerMixin(DatePickerMinM
}
}

public override willUpdate(changedProperties: ChangedProperties<DatePickerProperties>) {
public override willUpdate(changedProperties: ChangedProperties<DatePickerProperties>): void {
super.willUpdate(changedProperties);

if (changedProperties.has('locale')) {
Expand All @@ -126,16 +126,16 @@ export class DatePickerInput extends ElementMixin(DatePickerMixin(DatePickerMinM
}
}

public override async updated() {
if (this._open && this._rendered) {
public override async updated(): Promise<void> {
if (this._open && this._lazyLoaded) {
const picker = await this.$picker;

picker?.queryAll?.<AppIconButton>(appIconButtonName).forEach(n => n.layout());
}
}

public override render(): TemplateResult {
if (!this._rendered && this._open) this.#lazyLoad();
if (!this._lazyLoaded && this._open) this.#lazyLoad();

return html`
${super.render()}
Expand Down Expand Up @@ -280,38 +280,58 @@ export class DatePickerInput extends ElementMixin(DatePickerMixin(DatePickerMinM
});
}

async #lazyLoad() {
/**
* FIXME(motss): Unable to test the lazy loading in `wtr` due to:
* 1. Unable to dynamically import `.js` file
* 2. Unable to dedupe the same custom element caused by dynamic import with import maps
*
* Therefore, defer testing the lazy loading until there is a way to test it in `wtr`.
*/
/* c8 ignore start */
#lazyLoad = async (): Promise<void> => {
if (this._lazyLoaded || this.#lazyLoading) return;

const deps = [
appDatePickerName,
appDatePickerInputSurfaceName,
];
] as const;

if (deps.some(n => globalThis.customElements.get(n) == null)) {
const tasks = deps.map(
n => globalThis.customElements.whenDefined(n)
);

await this.lazyLoad?.();
await Promise.all(tasks);
this.#lazyLoading = true;

const tasks = deps.map(n => globalThis.customElements.whenDefined(n));
const imports = [
'../date-picker/app-date-picker.js',
'../date-picker-input-surface/app-date-picker-input-surface.js',
].map(n => import(n));

try {
await Promise.all(imports);
await Promise.all(tasks);
} catch (error) {
console.error(error);
}
}

this._rendered = true;
}
this.#lazyLoading = false;
this._lazyLoaded = true;
};
/* c8 ignore stop */

#onResetClick() {
#onResetClick = (): void => {
this.#isClearAction = true;
this.#selectedDate = this.#valueAsDate = undefined;

this.value = this._valueText = '';
}
};

#onClosed({ detail }: CustomEvent): void {
#onClosed = ({ detail }: CustomEvent): void => {
this._open = false;
this.#picker && (this.#picker.startView = 'calendar');
this.fire({ detail, type: 'closed' });
}
};

async #onDatePickerDateUpdated(ev: CustomEvent<CustomEventDetail['date-updated']['detail']>): Promise<void> {
#onDatePickerDateUpdated = async (ev: CustomEvent<CustomEventDetail['date-updated']['detail']>): Promise<void> => {
const {
isKeypress,
key,
Expand Down Expand Up @@ -339,29 +359,29 @@ export class DatePickerInput extends ElementMixin(DatePickerMixin(DatePickerMinM
} else {
this.#isClearAction = false;
}
}
};

#onDatePickerFirstUpdated({
#onDatePickerFirstUpdated = ({
currentTarget,
detail: {
focusableElements: [focusableElement],
valueAsDate,
},
}: CustomEvent<CustomEventDetail['first-updated']['detail']>): void {
}: CustomEvent<CustomEventDetail['first-updated']['detail']>): void => {
this.#focusElement = focusableElement;
this.#picker = currentTarget as AppDatePicker;
this.#selectedDate = valueAsDate;
}
};

async #onOpened({ detail }: CustomEvent): Promise<void> {
#onOpened = async ({ detail }: CustomEvent): Promise<void> => {
await this.#picker?.updateComplete;
await this.updateComplete;

this.#focusElement?.focus();
this.fire({ detail, type: 'opened' });
}
};

#updateValues(value: string): void {
#updateValues = (value: string): void => {
if (value) {
const valueDate = new Date(value);

Expand All @@ -370,5 +390,5 @@ export class DatePickerInput extends ElementMixin(DatePickerMixin(DatePickerMinM
} else {
this.#onResetClick();
}
}
};
}
Loading

0 comments on commit 4f212ae

Please sign in to comment.