-
Notifications
You must be signed in to change notification settings - Fork 113
Move types from DefinitelyTyped to this repository #165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
d1ab9ff
6e2ce45
1a2822e
ad510b2
cc07d23
34594eb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,7 @@ | ||
| module.exports = { | ||
| parserOptions: { | ||
| parser: '@typescript-eslint/parser', | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Support for this is now built-in to the latest version of kcd-scripts (actually, eslint-config-kentcdodds, but that's what kcd-scripts uses). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's what I assumed when I checked the changelogs, but sadly enough eslint-plugin-vue requires us to use SFC are cool but come with their own headaches 😅 |
||
| }, | ||
| extends: [ | ||
| './node_modules/kcd-scripts/eslint.js', | ||
| 'plugin:vue/recommended', | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| // TypeScript Version: 4.0 | ||
|
|
||
| import Vue, {ComponentOptions} from 'vue' | ||
| import {ThisTypedMountOptions, VueClass} from '@vue/test-utils' | ||
| import {Store, StoreOptions} from 'vuex' | ||
| import Router, {RouteConfig} from 'vue-router' | ||
| // eslint-disable-next-line import/no-extraneous-dependencies | ||
| import {OptionsReceived as PrettyFormatOptions} from 'pretty-format' | ||
| import {queries, EventType, BoundFunctions} from '@testing-library/dom' | ||
|
|
||
| // NOTE: fireEvent is overridden below | ||
| export * from '@testing-library/dom' | ||
|
|
||
| export interface RenderResult extends BoundFunctions<typeof queries> { | ||
| container: HTMLElement | ||
| baseElement: HTMLElement | ||
| debug: ( | ||
| baseElement?: | ||
| | HTMLElement | ||
| | DocumentFragment | ||
| | Array<HTMLElement | DocumentFragment>, | ||
| maxLength?: number, | ||
| options?: PrettyFormatOptions, | ||
| ) => void | ||
| unmount(): void | ||
| isUnmounted(): boolean | ||
| html(): string | ||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| emitted(): {[name: string]: any[][]} | ||
| updateProps(props: object): Promise<void> | ||
| } | ||
|
|
||
| export interface RenderOptions<V extends Vue, S = {}> | ||
| // The props and store options special-cased by Vue Testing Library and NOT passed to mount(). | ||
| extends Omit<ThisTypedMountOptions<V>, 'store' | 'props'> { | ||
| props?: object | ||
| store?: StoreOptions<S> | ||
| routes?: RouteConfig[] | ||
| container?: HTMLElement | ||
| baseElement?: HTMLElement | ||
| } | ||
|
|
||
| export type ConfigurationCallback<V extends Vue> = ( | ||
| localVue: typeof Vue, | ||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| store: Store<any>, | ||
| router: Router, | ||
| ) => Partial<ThisTypedMountOptions<V>> | void | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This line productes the following warning with latest config: not entirely sure I should be worried about this? |
||
|
|
||
| export function render<V extends Vue>( | ||
| TestComponent: VueClass<V> | ComponentOptions<V>, | ||
| options?: RenderOptions<V>, | ||
| configure?: ConfigurationCallback<V>, | ||
| ): RenderResult | ||
|
|
||
| export type AsyncFireObject = { | ||
| [K in EventType]: ( | ||
| element: Document | Element | Window, | ||
| options?: {}, | ||
| ) => Promise<void> | ||
| } | ||
|
|
||
| export interface VueFireEventObject extends AsyncFireObject { | ||
| (element: Document | Element | Window, event: Event): Promise<void> | ||
| touch(element: Document | Element | Window): Promise<void> | ||
| update(element: HTMLOptionElement): Promise<void> | ||
| update( | ||
| element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement, | ||
| value: string, | ||
| ): Promise<void> | ||
| update(element: HTMLElement, value?: string): Promise<void> | ||
| } | ||
|
|
||
| export const fireEvent: VueFireEventObject | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,137 @@ | ||
| import Vue from 'vue' | ||
| import {render, fireEvent, screen, waitFor} from '@testing-library/vue' | ||
|
|
||
| declare const elem: HTMLElement | ||
|
|
||
| const SomeComponent = Vue.extend({ | ||
| name: 'SomeComponent', | ||
| props: { | ||
| foo: {type: Number, default: 0}, | ||
| bar: {type: String, default: '0'}, | ||
| }, | ||
| }) | ||
|
|
||
| export async function testRender() { | ||
| const page = render({template: '<div />'}) | ||
|
|
||
| // single queries | ||
| page.getByText('foo') | ||
| page.queryByText('foo') | ||
| await page.findByText('foo') | ||
|
|
||
| // multiple queries | ||
| page.getAllByText('bar') | ||
| page.queryAllByText('bar') | ||
| await page.findAllByText('bar') | ||
|
|
||
| // helpers | ||
| const {container, unmount, debug} = page | ||
|
|
||
| debug(container) | ||
|
|
||
| debug(elem) // $ExpectType void | ||
| debug([elem, elem], 100, {highlight: false}) // $ExpectType void | ||
|
|
||
| unmount() | ||
| } | ||
|
|
||
| export function testRenderOptions() { | ||
| const container = document.createElement('div') | ||
| const options = {container} | ||
| render({template: 'div'}, options) | ||
| } | ||
|
|
||
| export async function testFireEvent() { | ||
| const {container} = render({template: 'button'}) | ||
| await fireEvent.click(container) | ||
| } | ||
|
|
||
| export function testDebug() { | ||
| const {debug, getAllByTestId} = render({ | ||
| render(h) { | ||
| return h('div', [ | ||
| h('h1', {attrs: {'data-testId': 'testid'}}, 'hello world'), | ||
| h('h2', {attrs: {'data-testId': 'testid'}}, 'hello world'), | ||
| ]) | ||
| }, | ||
| }) | ||
|
|
||
| debug(getAllByTestId('testid')) | ||
| } | ||
|
|
||
| export async function testScreen() { | ||
| render({template: 'button'}) | ||
|
|
||
| await screen.findByRole('button') | ||
| } | ||
|
|
||
| export async function testWaitFor() { | ||
| const {container} = render({template: 'button'}) | ||
| await fireEvent.click(container) | ||
| await waitFor(() => {}) | ||
| } | ||
|
|
||
| export function testOptions() { | ||
| render(SomeComponent, { | ||
| // options for new Vue() | ||
| name: 'SomeComponent', | ||
| methods: { | ||
| glorb() { | ||
| return 42 | ||
| }, | ||
| }, | ||
| // options for vue-test-utils mount() | ||
| slots: { | ||
| quux: '<p>Baz</p>', | ||
| }, | ||
| mocks: { | ||
| isThisFake() { | ||
| return true | ||
| }, | ||
| }, | ||
| // options for Vue Testing Library render() | ||
| container: elem, | ||
| baseElement: elem, | ||
| props: { | ||
| foo: 9, | ||
| bar: 'x', | ||
| }, | ||
| store: { | ||
| state: { | ||
| foos: [4, 5], | ||
| bars: ['a', 'b'], | ||
| }, | ||
| getters: { | ||
| fooCount() { | ||
| return this.foos.length | ||
| }, | ||
| }, | ||
| }, | ||
| routes: [ | ||
| {path: '/', name: 'home', component: SomeComponent}, | ||
| { | ||
| path: '/about', | ||
| name: 'about', | ||
| component: () => Promise.resolve(SomeComponent), | ||
| }, | ||
| ], | ||
| }) | ||
| } | ||
|
|
||
| export function testConfigCallback() { | ||
| const ExamplePlugin: Vue.PluginFunction<never> = () => {} | ||
| render(SomeComponent, {}, (localVue, store, router) => { | ||
| localVue.use(ExamplePlugin) | ||
| store.replaceState({foo: 'bar'}) | ||
| router.onError(error => console.log(error.message)) | ||
| }) | ||
| } | ||
|
|
||
| /* | ||
| eslint | ||
| testing-library/prefer-explicit-assert: "off", | ||
| testing-library/no-wait-for-empty-callback: "off", | ||
| testing-library/no-debug: "off", | ||
| testing-library/prefer-screen-queries: "off", | ||
| @typescript-eslint/unbound-method: "off", | ||
| */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| // this additional tsconfig is required by dtslint | ||
| // see: https://github.com/Microsoft/dtslint#typestsconfigjson | ||
| { | ||
| "compilerOptions": { | ||
| "module": "commonjs", | ||
| "lib": ["es6", "dom"], | ||
| "noImplicitAny": true, | ||
| "noImplicitThis": true, | ||
| "strictNullChecks": true, | ||
| "strictFunctionTypes": true, | ||
| "noEmit": true, | ||
| "baseUrl": ".", | ||
| "paths": { | ||
| "@testing-library/vue": ["."] | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "extends": ["dtslint/dtslint.json"], | ||
| "rules": { | ||
| "semicolon": false, | ||
| "whitespace": false | ||
| } | ||
| } |