chore(core): type checking for unit tests (#28529)

Issue number: N/A

---------

<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->

<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->

## What is the current behavior?
<!-- Please describe the current behavior that you are modifying. -->

Type checking inside of the Stencil unit tests have been disabled for a
long time. This has resulted in a difficult developer experience and
numerous issues (both types and implementation) within our unit tests.

## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->

- Type checking is now enabled for all Stencil unit tests
- Tests have been updated to resolve type errors and implementation
errors
- Many `as any` casts were introduced, as many legacy tests test invalid
configurations of functions that require it (for example passing
`undefined` to an argument that cannot be `undefined`).

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->


## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->

To test this PR you can checkout the branch locally. Install
dependencies in the `/core` directory to make sure you are on at least
`@stencil/core@4.7.2`.

Opening either a `.spec.ts` or `.spec.tsx` file, validate that your IDE
detects types and can provide auto completions for jest global types.

If you desire, you can provide an invalid type and try building the
project - you will observe the build will fail due to the invalid type.
This commit is contained in:
Sean Perkins
2023-11-17 11:47:34 -05:00
committed by GitHub
parent 1a135ebd76
commit 4f1b4cdc29
48 changed files with 2117 additions and 438 deletions

View File

@ -15,8 +15,8 @@ describe('modal: a11y', () => {
`,
});
const modal = page.body.querySelector('ion-modal');
const modalWrapper = modal.shadowRoot.querySelector('.modal-wrapper');
const modal = page.body.querySelector('ion-modal')!;
const modalWrapper = modal.shadowRoot!.querySelector('.modal-wrapper')!;
await expect(modalWrapper.getAttribute('role')).toBe('alertdialog');
});

View File

@ -7,10 +7,10 @@ describe('modal: htmlAttributes inheritance', () => {
it('should correctly inherit attributes on host', async () => {
const page = await newSpecPage({
components: [Modal],
template: () => <ion-modal htmlAttributes={{ 'data-testid': 'basic-modal' }}></ion-modal>,
template: () => <ion-modal htmlAttributes={{ 'data-testid': 'basic-modal' }} overlayIndex={1}></ion-modal>,
});
const modal = page.body.querySelector('ion-modal');
const modal = page.body.querySelector('ion-modal')!;
await expect(modal.getAttribute('data-testid')).toBe('basic-modal');
});

View File

@ -1,19 +1,18 @@
import { h } from '@stencil/core';
import { h, setMode } from '@stencil/core';
import { newSpecPage } from '@stencil/core/testing';
import { setMode } from '@stencil/core';
import { Modal } from '../../modal';
import { Content } from '../../../content/content';
import { Modal } from '../../modal';
describe('modal: canDismiss', () => {
describe('modal: regular modal', () => {
it('should dismiss when canDismiss is true', async () => {
const page = await newSpecPage({
components: [Modal],
template: () => <ion-modal animated={false} canDismiss={true}></ion-modal>,
template: () => <ion-modal overlayIndex={1} animated={false} canDismiss={true}></ion-modal>,
});
const modal = page.body.querySelector('ion-modal');
const modal = page.body.querySelector('ion-modal')!;
await modal.present();
await page.waitForChanges();
@ -26,10 +25,10 @@ describe('modal: canDismiss', () => {
it('should not dismiss when canDismiss is false', async () => {
const page = await newSpecPage({
components: [Modal],
template: () => <ion-modal animated={false} canDismiss={false}></ion-modal>,
template: () => <ion-modal overlayIndex={1} animated={false} canDismiss={false}></ion-modal>,
});
const modal = page.body.querySelector('ion-modal');
const modal = page.body.querySelector('ion-modal')!;
await modal.present();
await page.waitForChanges();
@ -44,6 +43,7 @@ describe('modal: canDismiss', () => {
components: [Modal],
template: () => (
<ion-modal
overlayIndex={1}
animated={false}
canDismiss={() => {
return new Promise((resolve) => {
@ -54,7 +54,7 @@ describe('modal: canDismiss', () => {
),
});
const modal = page.body.querySelector('ion-modal');
const modal = page.body.querySelector('ion-modal')!;
await modal.present();
await page.waitForChanges();
@ -69,6 +69,7 @@ describe('modal: canDismiss', () => {
components: [Modal],
template: () => (
<ion-modal
overlayIndex={1}
animated={false}
canDismiss={() => {
return new Promise((resolve) => {
@ -79,7 +80,7 @@ describe('modal: canDismiss', () => {
),
});
const modal = page.body.querySelector('ion-modal');
const modal = page.body.querySelector('ion-modal')!;
await modal.present();
await page.waitForChanges();
@ -94,19 +95,24 @@ describe('modal: canDismiss', () => {
/**
* Card modal is only available on iOS
*/
setMode((elm) => 'ios');
setMode(() => 'ios');
});
it('should dismiss when canDismiss is true', async () => {
const page = await newSpecPage({
components: [Content, Modal],
template: () => (
<ion-modal presentingElement={document.createElement('div')} animated={false} canDismiss={true}>
<ion-modal
overlayIndex={1}
presentingElement={document.createElement('div')}
animated={false}
canDismiss={true}
>
<ion-content>Test Content</ion-content>
</ion-modal>
),
});
const modal = page.body.querySelector('ion-modal');
const modal = page.body.querySelector('ion-modal')!;
await modal.present();
await page.waitForChanges();
@ -120,13 +126,18 @@ describe('modal: canDismiss', () => {
const page = await newSpecPage({
components: [Content, Modal],
template: () => (
<ion-modal presentingElement={document.createElement('div')} animated={false} canDismiss={false}>
<ion-modal
overlayIndex={1}
presentingElement={document.createElement('div')}
animated={false}
canDismiss={false}
>
<ion-content>Test Content</ion-content>
</ion-modal>
),
});
const modal = page.body.querySelector('ion-modal');
const modal = page.body.querySelector('ion-modal')!;
await modal.present();
await page.waitForChanges();
@ -141,6 +152,7 @@ describe('modal: canDismiss', () => {
components: [Content, Modal],
template: () => (
<ion-modal
overlayIndex={1}
presentingElement={document.createElement('div')}
animated={false}
canDismiss={() => {
@ -154,7 +166,7 @@ describe('modal: canDismiss', () => {
),
});
const modal = page.body.querySelector('ion-modal');
const modal = page.body.querySelector('ion-modal')!;
await modal.present();
await page.waitForChanges();
@ -169,6 +181,7 @@ describe('modal: canDismiss', () => {
components: [Content, Modal],
template: () => (
<ion-modal
overlayIndex={1}
presentingElement={document.createElement('div')}
animated={false}
canDismiss={() => {
@ -182,7 +195,7 @@ describe('modal: canDismiss', () => {
),
});
const modal = page.body.querySelector('ion-modal');
const modal = page.body.querySelector('ion-modal')!;
await modal.present();
await page.waitForChanges();
@ -197,11 +210,17 @@ describe('modal: canDismiss', () => {
const page = await newSpecPage({
components: [Modal],
template: () => (
<ion-modal breakpoints={[0, 1]} initialBreakpoint={1} animated={false} canDismiss={true}></ion-modal>
<ion-modal
overlayIndex={1}
breakpoints={[0, 1]}
initialBreakpoint={1}
animated={false}
canDismiss={true}
></ion-modal>
),
});
const modal = page.body.querySelector('ion-modal');
const modal = page.body.querySelector('ion-modal')!;
await modal.present();
await page.waitForChanges();
@ -215,11 +234,17 @@ describe('modal: canDismiss', () => {
const page = await newSpecPage({
components: [Modal],
template: () => (
<ion-modal breakpoints={[0, 1]} initialBreakpoint={1} animated={false} canDismiss={false}></ion-modal>
<ion-modal
overlayIndex={1}
breakpoints={[0, 1]}
initialBreakpoint={1}
animated={false}
canDismiss={false}
></ion-modal>
),
});
const modal = page.body.querySelector('ion-modal');
const modal = page.body.querySelector('ion-modal')!;
await modal.present();
await page.waitForChanges();
@ -234,6 +259,7 @@ describe('modal: canDismiss', () => {
components: [Modal],
template: () => (
<ion-modal
overlayIndex={1}
breakpoints={[0, 1]}
initialBreakpoint={1}
animated={false}
@ -246,7 +272,7 @@ describe('modal: canDismiss', () => {
),
});
const modal = page.body.querySelector('ion-modal');
const modal = page.body.querySelector('ion-modal')!;
await modal.present();
await page.waitForChanges();
@ -261,6 +287,7 @@ describe('modal: canDismiss', () => {
components: [Modal],
template: () => (
<ion-modal
overlayIndex={1}
breakpoints={[0, 1]}
initialBreakpoint={1}
animated={false}
@ -273,7 +300,7 @@ describe('modal: canDismiss', () => {
),
});
const modal = page.body.querySelector('ion-modal');
const modal = page.body.querySelector('ion-modal')!;
await modal.present();
await page.waitForChanges();
@ -288,15 +315,15 @@ describe('modal: canDismiss', () => {
const canDismiss = jest.fn();
const page = await newSpecPage({
components: [Modal],
template: () => <ion-modal animated={false} canDismiss={canDismiss}></ion-modal>,
template: () => <ion-modal overlayIndex={1} animated={false} canDismiss={canDismiss}></ion-modal>,
});
const modal = page.body.querySelector('ion-modal');
const modal = page.body.querySelector('ion-modal')!;
await modal.present();
await page.waitForChanges();
const returnValue = await modal.dismiss('my data', 'my role');
await modal.dismiss('my data', 'my role');
expect(canDismiss).toHaveBeenCalledWith('my data', 'my role');
});