From f5fe7f6606bb82cdf649a518fbc77f9018ce71d8 Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Thu, 9 Nov 2023 10:31:28 +0100 Subject: [PATCH] Fix teardown and tests --- .../coverage.json | 8 +- .../common/BaseSnapExecutor.test.browser.ts | 2 + .../src/common/endowments/network.test.ts | 15 +- .../src/common/endowments/network.ts | 208 ++++++++++-------- 4 files changed, 127 insertions(+), 106 deletions(-) diff --git a/packages/snaps-execution-environments/coverage.json b/packages/snaps-execution-environments/coverage.json index 0c15b35af3..75198cf4c3 100644 --- a/packages/snaps-execution-environments/coverage.json +++ b/packages/snaps-execution-environments/coverage.json @@ -1,6 +1,6 @@ { - "branches": 80.71, - "functions": 92.02, - "lines": 91.66, - "statements": 91.36 + "branches": 80.28, + "functions": 90.41, + "lines": 91.06, + "statements": 90.65 } diff --git a/packages/snaps-execution-environments/src/common/BaseSnapExecutor.test.browser.ts b/packages/snaps-execution-environments/src/common/BaseSnapExecutor.test.browser.ts index dbf2dc34b7..27a38020b0 100644 --- a/packages/snaps-execution-environments/src/common/BaseSnapExecutor.test.browser.ts +++ b/packages/snaps-execution-environments/src/common/BaseSnapExecutor.test.browser.ts @@ -1685,6 +1685,7 @@ describe('BaseSnapExecutor', () => { expect(await executor.readCommand()).toStrictEqual({ jsonrpc: '2.0', method: 'OutboundResponse', + params: { source: 'ethereum.request' }, }); expect(await executor.readCommand()).toStrictEqual({ @@ -1796,6 +1797,7 @@ describe('BaseSnapExecutor', () => { expect(await executor.readCommand()).toStrictEqual({ jsonrpc: '2.0', method: 'OutboundResponse', + params: { source: 'ethereum.request' }, }); expect(await executor.readCommand()).toStrictEqual({ diff --git a/packages/snaps-execution-environments/src/common/endowments/network.test.ts b/packages/snaps-execution-environments/src/common/endowments/network.test.ts index c9859dbcc1..a5763cc2ae 100644 --- a/packages/snaps-execution-environments/src/common/endowments/network.test.ts +++ b/packages/snaps-execution-environments/src/common/endowments/network.test.ts @@ -53,13 +53,7 @@ describe('Network endowments', () => { }); it('can use AbortController normally', async () => { - let resolve: ((result: string) => void) | null = null; - fetchMock.mockOnce( - async () => - new Promise((_resolve) => { - resolve = _resolve; - }), - ); + fetchMock.mockOnce(async () => 'FAIL'); const { fetch } = network.factory(factoryOptions); @@ -67,7 +61,6 @@ describe('Network endowments', () => { const fetchPromise = fetch('foo.com', { signal: controller.signal }); controller.abort(); - (resolve as any)('FAIL'); await expect(fetchPromise).rejects.toThrow('The operation was aborted'); }); @@ -86,10 +79,7 @@ describe('Network endowments', () => { it.todo('reason from AbortController.abort() is passed down'); it('should not expose then or catch after teardown has been called', async () => { - let fetchResolve: ((result: string) => void) | null = null; - fetchMock.mockOnce( - async () => new Promise((resolve) => (fetchResolve = resolve)), - ); + fetchMock.mockOnce(async () => 'Resolved'); const { fetch, teardownFunction } = network.factory(factoryOptions); const ErrorProxy = jest @@ -107,7 +97,6 @@ describe('Network endowments', () => { .catch((error) => console.log(error)); const teardownPromise = teardownFunction(); - (fetchResolve as any)('Resolved'); await teardownPromise; await new Promise((resolve) => setTimeout(() => resolve('Resolved'), 0)); diff --git a/packages/snaps-execution-environments/src/common/endowments/network.ts b/packages/snaps-execution-environments/src/common/endowments/network.ts index 2971b8e148..7dccdf47f5 100644 --- a/packages/snaps-execution-environments/src/common/endowments/network.ts +++ b/packages/snaps-execution-environments/src/common/endowments/network.ts @@ -65,33 +65,45 @@ class ResponseWrapper implements Response { } async text() { - await this.#onStart(); - try { - return await withTeardown(this.#ogResponse.text(), this as any); - } finally { - await this.#onFinish(); - } + return await withTeardown( + (async () => { + await this.#onStart(); + try { + return await this.#ogResponse.text(); + } finally { + await this.#onFinish(); + } + })(), + this.#teardownRef, + ); } async arrayBuffer(): Promise { - await this.#onStart(); - try { - return await withTeardown( - this.#ogResponse.arrayBuffer(), - this as any, - ); - } finally { - await this.#onFinish(); - } + return await withTeardown( + (async () => { + await this.#onStart(); + try { + return await this.#ogResponse.arrayBuffer(); + } finally { + await this.#onFinish(); + } + })(), + this.#teardownRef, + ); } async blob(): Promise { - await this.#onStart(); - try { - return await withTeardown(this.#ogResponse.blob(), this as any); - } finally { - await this.#onFinish(); - } + return await withTeardown( + (async () => { + await this.#onStart(); + try { + return await this.#ogResponse.blob(); + } finally { + await this.#onFinish(); + } + })(), + this.#teardownRef, + ); } clone(): Response { @@ -105,24 +117,31 @@ class ResponseWrapper implements Response { } async formData(): Promise { - await this.#onStart(); - try { - return await withTeardown( - this.#ogResponse.formData(), - this as any, - ); - } finally { - await this.#onFinish(); - } + return await withTeardown( + (async () => { + await this.#onStart(); + try { + return await this.#ogResponse.formData(); + } finally { + await this.#onFinish(); + } + })(), + this.#teardownRef, + ); } async json(): Promise { - await this.#onStart(); - try { - return await withTeardown(this.#ogResponse.json(), this as any); - } finally { - await this.#onFinish(); - } + return await withTeardown( + (async () => { + await this.#onStart(); + try { + return await this.#ogResponse.json(); + } finally { + await this.#onFinish(); + } + })(), + this.#teardownRef, + ); } } @@ -195,60 +214,71 @@ const createNetwork = ({ notify }: EndowmentFactoryOptions = {}) => { let res: Response; let openFetchConnection: { cancel: () => Promise } | undefined; - try { - await notify({ method: 'OutboundRequest', params: { source: 'fetch' } }); - const fetchPromise = fetch(input, { - ...init, - signal: abortController.signal, - }); - - openFetchConnection = { - cancel: async () => { - abortController.abort(); - try { - await fetchPromise; - } catch { - /* do nothing */ + return await withTeardown( + (async () => { + try { + await notify({ + method: 'OutboundRequest', + params: { source: 'fetch' }, + }); + const fetchPromise = fetch(input, { + ...init, + signal: abortController.signal, + }); + + openFetchConnection = { + cancel: async () => { + abortController.abort(); + try { + await fetchPromise; + } catch { + /* do nothing */ + } + }, + }; + openConnections.add(openFetchConnection); + + res = new ResponseWrapper( + await fetchPromise, + teardownRef, + onStart, + onFinish, + ); + } finally { + if (openFetchConnection !== undefined) { + openConnections.delete(openFetchConnection); } - }, - }; - openConnections.add(openFetchConnection); - - res = new ResponseWrapper( - await withTeardown(fetchPromise, teardownRef), - teardownRef, - onStart, - onFinish, - ); - } finally { - if (openFetchConnection !== undefined) { - openConnections.delete(openFetchConnection); - } - await notify({ method: 'OutboundResponse', params: { source: 'fetch' } }); - } - - if (res.body !== null) { - const body = new WeakRef(res.body); - - const openBodyConnection = { - cancel: - /* istanbul ignore next: see it.todo('can be torn down during body read') test */ - async () => { - try { - await body.deref()?.cancel(); - } catch { - /* do nothing */ - } - }, - }; - openConnections.add(openBodyConnection); - cleanup.register( - res.body, - /* istanbul ignore next: can't test garbage collection without modifying node parameters */ - () => openConnections.delete(openBodyConnection), - ); - } - return harden(res); + await notify({ + method: 'OutboundResponse', + params: { source: 'fetch' }, + }); + } + + if (res.body !== null) { + const body = new WeakRef(res.body); + + const openBodyConnection = { + cancel: + /* istanbul ignore next: see it.todo('can be torn down during body read') test */ + async () => { + try { + await body.deref()?.cancel(); + } catch { + /* do nothing */ + } + }, + }; + openConnections.add(openBodyConnection); + cleanup.register( + res.body, + /* istanbul ignore next: can't test garbage collection without modifying node parameters */ + () => openConnections.delete(openBodyConnection), + ); + } + return harden(res); + })(), + teardownRef, + ); }; const teardownFunction = async () => {