-
-
Notifications
You must be signed in to change notification settings - Fork 320
Testing TS decorators #1963
Answered
by
muratcorlu
muratcorlu
asked this question in
Q&A
Testing TS decorators
#1963
-
I wrote an @event decorator for my Lit components. I want to write test for the decorator. Decorator works in browser (testing with storybook) but while testing, I can not get the reference of the class inside decorator function. Here is my web test runner config:
import { fromRollup } from "@web/dev-server-rollup" import { esbuildPlugin } from "@web/dev-server-esbuild" import rollupLitCss from "rollup-plugin-lit-css" const litCss = fromRollup(rollupLitCss) export default /** @type {import("@web/test-runner").TestRunnerConfig} */ ({ files: "src/**/*.test.ts", nodeResolve: true, coverageConfig: { include: ["src/**/*.ts"], threshold: { branches: 100, statements: 100, functions: 100, lines: 100, }, }, mimeTypes: { "src/**/*.css": "js", }, plugins: [ litCss({ include: ["src/**/*.css"], }), esbuildPlugin({ ts: true, target: "esnext" }), ], });
And event.ts file:
export interface EventOptions { bubbles?: boolean; cancelable?: boolean; } export class EventDispatcher<T> { constructor(private target: HTMLElement, private eventName: string) {} dispatch(value: T, options?: EventOptions) { this.target.dispatchEvent( new CustomEvent<T>(this.eventName, { detail: value, ...options }) ); } } export function event(customName?: string) { // eslint-disable-next-line @typescript-eslint/no-explicit-any return (protoOrDescriptor: any, name: string): any => { const eventName = customName || name || protoOrDescriptor.key; const descriptor = { get(this: HTMLElement) { return new EventDispatcher(this, eventName); }, enumerable: true, configurable: true, }; // if there is no name then this is a TypeScript runtime else its the current native TC39 proposal return name !== undefined ? Object.defineProperty(protoOrDescriptor, name, descriptor) : { kind: 'property', placement: 'prototype', key: protoOrDescriptor.key, descriptor, }; }; }
And this is the test file:
import { expect, fixture, html, defineCE, waitUntil } from '@open-wc/testing'; import { LitElement } from 'lit'; import { event, EventDispatcher } from './event'; class TestComp extends LitElement { @event('gr-test') test: EventDispatcher<string>; someMethod() { this.test.dispatch('test event'); } render() { return html`<button @click=${this.someMethod}></button>`; } } describe('event decorator helpers', () => { describe('@event decorator', () => { it('should decorate component event', async done => { const tag = defineCE(TestComp); const el = await fixture<TestComp>(`<${tag}></${tag}>`); await waitUntil( () => el.shadowRoot?.querySelector('button'), 'Element did not render children' ); el.addEventListener('test', event => { expect(event).equals('test event'); done(); }); el.shadowRoot?.querySelector('button')?.click(); }); }); });
I'm getting error:
TypeError: Cannot read properties of undefined (reading 'dispatch')
at HTMLElement.someMethod (src/utilities/event.test.ts:9:14)
at I.handleEvent (node_modules/lit-html/src/lit-html.ts:2048:28)
at o.<anonymous> (src/utilities/event.test.ts:33:46)
❌ event decorator helpers > @event decorator > should decorate component event
Error: Uncaught TypeError: Cannot read properties of undefined (reading 'dispatch') (http://localhost:8000/src/utilities/event.test.ts?wtr-session-id=7MPJUmlMt81TjpOrr64Il:18)
at o.<anonymous> (src/utilities/event.test.ts:33:46)
I feel something special happens in TS in test environment but couldn't figure out. Any suggestions?
Beta Was this translation helpful? Give feedback.
All reactions
Answered by
muratcorlu
May 20, 2022
I think this is related with #1921. Returning back to v0.2.16 solved my issue.
Replies: 1 comment
-
I think this is related with #1921. Returning back to v0.2.16 solved my issue.
Beta Was this translation helpful? Give feedback.
All reactions
0 replies
Answer selected by
muratcorlu
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment