Skip to content

Commit

Permalink
test: add messaging leak detection
Browse files Browse the repository at this point in the history
  • Loading branch information
tmkx committed Jan 28, 2024
1 parent f566758 commit cd59d8d
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 12 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"engines": {
"node": ">=18"
},
"packageManager": "pnpm@8.14.1",
"packageManager": "pnpm@8.15.0",
"scripts": {
"lint:type": "turbo lint:type",
"build": "turbo build",
Expand Down
44 changes: 36 additions & 8 deletions packages/messaging/src/core/__tests__/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { setTimeout as sleep } from 'node:timers/promises';
import { expect, it, vi } from 'vitest';
import { createMessaging, fromMessagePort } from '../index';
import { Messaging, createMessaging, fromMessagePort } from '../index';

function expectMessagingIsNotLeaked(messaging: Messaging) {
// @ts-expect-error
expect(messaging.ongoingRequestResolvers).toHaveLength(0);
// @ts-expect-error
expect(messaging.ongoingStreamObservers).toHaveLength(0);
}

it.concurrent('should on/off listener', async () => {
const { port1, port2 } = new MessageChannel();
Expand All @@ -15,12 +22,14 @@ it.concurrent('should on/off listener', async () => {
receiver.dispose();
await (port2.postMessage('hello'), sleep(10));
expect(listenerFn).toBeCalledTimes(1);

expectMessagingIsNotLeaked(receiver);
});

it.concurrent('should support request', async () => {
const { port1, port2 } = new MessageChannel();

const _receiver = createMessaging(fromMessagePort(port1), {
const receiver = createMessaging(fromMessagePort(port1), {
async onRequest(message) {
switch (message.name) {
case 'hello':
Expand All @@ -34,12 +43,15 @@ it.concurrent('should support request', async () => {

await expect(sender.request({ name: 'hello', user: 'Tmk' })).resolves.toEqual('Hello, Tmk');
await expect(sender.request({ name: 'greet', user: 'Tmk' })).rejects.toThrow('Unknown method');

expectMessagingIsNotLeaked(receiver);
expectMessagingIsNotLeaked(sender);
});

it.concurrent('should support stream', async () => {
const { port1, port2 } = new MessageChannel();

const _receiver = createMessaging(fromMessagePort(port1), {
const receiver = createMessaging(fromMessagePort(port1), {
async onStream(message, subscriber) {
switch (message.name) {
case 'hello': {
Expand Down Expand Up @@ -82,13 +94,16 @@ it.concurrent('should support stream', async () => {
);
})
).rejects.toThrow('Unknown method');

expectMessagingIsNotLeaked(receiver);
expectMessagingIsNotLeaked(sender);
});

it.concurrent('should support abort stream', async () => {
const { port1, port2 } = new MessageChannel();

const cleanupFn = vi.fn();
const _receiver = createMessaging(fromMessagePort(port1), {
const receiver = createMessaging(fromMessagePort(port1), {
async onStream(message, subscriber) {
switch (message.name) {
case 'hello': {
Expand Down Expand Up @@ -127,13 +142,16 @@ it.concurrent('should support abort stream', async () => {
await sleep(10);
expect(cleanupFn).toBeCalled();
expect(completeFn).not.toBeCalled();

expectMessagingIsNotLeaked(receiver);
expectMessagingIsNotLeaked(sender);
});

it.concurrent('should support relay request', async () => {
const { port1, port2 } = new MessageChannel();
const { port1: port3, port2: port4 } = new MessageChannel();

const _destination = createMessaging(fromMessagePort(port1), {
const destination = createMessaging(fromMessagePort(port1), {
async onRequest(message) {
switch (message.name) {
case 'hello':
Expand All @@ -144,7 +162,7 @@ it.concurrent('should support relay request', async () => {
},
});
const relay1 = createMessaging(fromMessagePort(port2));
const _relay2 = createMessaging(fromMessagePort(port3), {
const relay2 = createMessaging(fromMessagePort(port3), {
onRequest() {
return this.relay(relay1);
},
Expand All @@ -153,13 +171,18 @@ it.concurrent('should support relay request', async () => {

await expect(sender.request({ name: 'hello', user: 'Tmk' })).resolves.toEqual('Hello, Tmk');
await expect(sender.request({ name: 'greet', user: 'Tmk' })).rejects.toThrow('Unknown method');

expectMessagingIsNotLeaked(destination);
expectMessagingIsNotLeaked(relay1);
expectMessagingIsNotLeaked(relay2);
expectMessagingIsNotLeaked(sender);
});

it.concurrent('should support relay stream', async () => {
const { port1, port2 } = new MessageChannel();
const { port1: port3, port2: port4 } = new MessageChannel();

const _destination = createMessaging(fromMessagePort(port1), {
const destination = createMessaging(fromMessagePort(port1), {
async onStream(message, subscriber) {
switch (message.name) {
case 'hello': {
Expand All @@ -174,7 +197,7 @@ it.concurrent('should support relay stream', async () => {
},
});
const relay1 = createMessaging(fromMessagePort(port2));
const _relay2 = createMessaging(fromMessagePort(port3), {
const relay2 = createMessaging(fromMessagePort(port3), {
onStream() {
return this.relay(relay1);
},
Expand Down Expand Up @@ -208,4 +231,9 @@ it.concurrent('should support relay stream', async () => {
);
})
).rejects.toThrow('Unknown method');

expectMessagingIsNotLeaked(destination);
expectMessagingIsNotLeaked(relay1);
expectMessagingIsNotLeaked(relay2);
expectMessagingIsNotLeaked(sender);
});
11 changes: 10 additions & 1 deletion packages/messaging/src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ export function createMessaging(port: Port, options?: CreateMessagingOptions): M
onDispose?.();
}

return {
const messaging: Messaging = {
name: port.name,
request<T>(data: unknown) {
const resolvers = withResolvers<T>();
Expand All @@ -189,6 +189,15 @@ export function createMessaging(port: Port, options?: CreateMessagingOptions): M
},
dispose,
};

if (process.env.NODE_ENV === 'test') {
Object.assign(messaging, {
ongoingRequestResolvers,
ongoingStreamObservers,
});
}

return messaging;
}

export function fromMessagePort(port: MessagePort): Port {
Expand Down
4 changes: 2 additions & 2 deletions packages/messaging/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"compilerOptions": {
"target": "ES2015",
"target": "ES2020",
"lib": ["DOM", "ESNext"],
"allowJs": true,
"module": "commonjs",
"module": "ES2020",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
Expand Down

0 comments on commit cd59d8d

Please sign in to comment.