Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Testing TS decorators #1963

Answered by muratcorlu
muratcorlu asked this question in Q&A
Discussion options

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?

You must be logged in to vote

I think this is related with #1921. Returning back to v0.2.16 solved my issue.

Replies: 1 comment

Comment options

I think this is related with #1921. Returning back to v0.2.16 solved my issue.

You must be logged in to vote
0 replies
Answer selected by muratcorlu
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet
1 participant

AltStyle によって変換されたページ (->オリジナル) /