Skip to content

Commit

Permalink
Add type tests for listeners and event streams
Browse files Browse the repository at this point in the history
And ensure they deal with events that don't have data just fine!
  • Loading branch information
airhorns committed Dec 28, 2020
1 parent a5da0bb commit 1de1f29
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 30 deletions.
15 changes: 8 additions & 7 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,11 +326,12 @@ declare class Emittery<
@returns A method to unsubscribe.
*/
onAny(
listener: <Name extends keyof EventData>(
eventName: Name,
eventData?: EventData[Name]
listener: (
eventName: keyof EventData,
eventData: EventData[keyof EventData] | undefined
) => void
): Emittery.UnsubscribeFn;

/**
Get an async iterator which buffers a tuple of an event name and data each time an event is emitted.
Expand Down Expand Up @@ -366,16 +367,16 @@ declare class Emittery<
```
*/
anyEvent(): AsyncIterableIterator<
[keyof EventData, EventData[keyof EventData]]
[keyof EventData, EventData[keyof EventData] | undefined]
>;

/**
Remove an `onAny` subscription.
*/
offAny(
listener: <Name extends keyof EventData>(
eventName: Name,
eventData?: EventData[Name]
listener: (
eventName: keyof EventData,
eventData: EventData[keyof EventData] | undefined
) => void
): void;

Expand Down
107 changes: 84 additions & 23 deletions index.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,116 @@
import {expectType, expectError} from 'tsd';
import Emittery = require('.');
import { expectType, expectError } from "tsd";
import Emittery = require(".");

// emit
{
const ee = new Emittery();
ee.emit('anEvent');
ee.emit('anEvent', 'some data');
ee.emit("anEvent");
ee.emit("anEvent", "some data");
}

// on
{
const ee = new Emittery();
ee.on('anEvent', () => undefined);
ee.on('anEvent', () => Promise.resolve());
ee.on('anEvent', data => undefined);
ee.on('anEvent', data => Promise.resolve());
ee.on(Emittery.listenerAdded, ({eventName, listener}) => {});
ee.on(Emittery.listenerRemoved, ({eventName, listener}) => {});
const off = ee.on('anEvent', () => undefined);
ee.on("anEvent", () => undefined);
ee.on("anEvent", () => Promise.resolve());
ee.on("anEvent", data => undefined);
ee.on("anEvent", data => Promise.resolve());
ee.on(Emittery.listenerAdded, ({ eventName, listener }) => {});
ee.on(Emittery.listenerRemoved, ({ eventName, listener }) => {});
const off = ee.on("anEvent", () => undefined);
off();
}

// off
{
const ee = new Emittery();
ee.off('anEvent', () => undefined);
ee.off('anEvent', () => Promise.resolve());
ee.off('anEvent', data => undefined);
ee.off('anEvent', data => Promise.resolve());
ee.off("anEvent", () => undefined);
ee.off("anEvent", () => Promise.resolve());
ee.off("anEvent", data => undefined);
ee.off("anEvent", data => Promise.resolve());
}

{
const ee = new Emittery();
expectError(ee.emit('anEvent', 'some data', 'and more'));
expectError(ee.emit("anEvent", "some data", "and more"));
}

{
const ee = new Emittery();
expectError(ee.on('anEvent', (data: any, more: any) => undefined));
expectError(ee.on("anEvent", (data: any, more: any) => undefined));
}

// Strict typing
// Strict typing for emission
{
const ee = new Emittery<{
value: string;
open: undefined;
close: undefined;
}>();
ee.emit('open');
ee.emit('close');
ee.emit('value', 'test');
expectError(ee.emit('value'));
expectError(ee.emit('open', 'test'));
ee.emit("open");
ee.emit("close");
ee.emit("value", "test");
expectError(ee.emit("value"));
expectError(ee.emit("open", "test"));
}

// Strict typing for listeners
{
const ee = new Emittery<{
value: string;
open: undefined;
close: undefined;
}>();
ee.on("open", () => {});
ee.on("open", argument => {
expectType<undefined>(argument);
});

ee.on("value", () => {});
ee.on("value", argument => {
expectType<string>(argument);
});

const listener = (value: string) => undefined;
ee.on("value", listener);
ee.off("value", listener);
ee.once("value").then(listener);

expectError(ee.on("value", (value: number) => {}));
}

// Strict typing for onAny, offAny listeners
{
const ee = new Emittery<{
value: string;
open: undefined;
close: undefined;
other: number;
}>();

ee.onAny((name, data) => {
expectType<"value" | "open" | "close" | "other">(name);
expectType<string | number | undefined>(data);
});

const listener = (name: string) => {};
ee.onAny(listener);
ee.offAny(listener);
}

// Strict typing for anyEvent iterator
{
const testAnyEvent = async () => {
const ee = new Emittery<{
value: string;
open: undefined;
close: undefined;
}>();

for await (const event of ee.anyEvent()) {
expectType<"value" | "open" | "close">(
event[0]
);
}
};
}

0 comments on commit 1de1f29

Please sign in to comment.