Skip to content

Commit

Permalink
Fix circular references (#1188)
Browse files Browse the repository at this point in the history
* Fix circular references
* Remove unnecessary test

Co-authored-by: Jason Cheatham <[email protected]>
  • Loading branch information
rhpijnacker and jason0x43 authored Nov 26, 2021
1 parent 2149dfc commit 847fbed
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 44 deletions.
5 changes: 5 additions & 0 deletions src/lib/browser/shim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,8 @@ if (typeof global.Symbol === 'undefined') {
if (typeof global.Set === 'undefined') {
global.Set = require('core-js-pure/features/set');
}

// Polyfill WeakSet if no global WeakSet is defined.
if (typeof global.WeakSet === 'undefined') {
global.WeakSet = require('core-js-pure/features/weak-set');
}
8 changes: 0 additions & 8 deletions src/lib/channels/Base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,6 @@ export default abstract class BaseChannel {
* when the message has been sent.
*/
sendMessage(name: keyof RemoteEvents, data: any) {
if (data instanceof Error) {
data = {
name: data.name,
message: data.message,
stack: data.stack
};
}

return this._sendData(name, data);
}

Expand Down
13 changes: 7 additions & 6 deletions src/lib/channels/Http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { request, Task, CancellablePromise } from '@theintern/common';

import { RemoteEvents } from '../RemoteSuite';
import BaseChannel, { ChannelOptions, Message } from './Base';
import { stringify } from '../common/util';

export default class HttpChannel extends BaseChannel {
protected _lastRequest: CancellablePromise<void>;
Expand All @@ -25,9 +26,9 @@ export default class HttpChannel extends BaseChannel {
const task = new Task(
(resolve, reject) => {
this._messageBuffer.push({
message: JSON.stringify(message),
message: stringify(message),
resolve,
reject
reject,
});

if (this._activeRequest) {
Expand Down Expand Up @@ -72,9 +73,9 @@ export default class HttpChannel extends BaseChannel {
this._activeRequest = request(this.url, {
method: 'post',
headers: { 'Content-Type': 'application/json' },
data: block.map(entry => entry.message)
data: block.map((entry) => entry.message),
})
.then(response => {
.then((response) => {
if (response.status === 200) {
return response.json<any[]>();
} else if (response.status === 204) {
Expand All @@ -88,8 +89,8 @@ export default class HttpChannel extends BaseChannel {
entry.resolve(results[index]);
});
})
.catch(error => {
block.forEach(entry => {
.catch((error) => {
block.forEach((entry) => {
entry.reject(error);
});
})
Expand Down
13 changes: 7 additions & 6 deletions src/lib/channels/WebSocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Task, CancellablePromise, global } from '@theintern/common';

import BaseChannel, { ChannelOptions, Message } from './Base';
import { parseUrl } from '../browser/util';
import { stringify } from '../common/util';

export default class WebSocketChannel extends BaseChannel {
/** Time to wait for response before rejecting a send */
Expand Down Expand Up @@ -39,11 +40,11 @@ export default class WebSocketChannel extends BaseChannel {
this._socket.addEventListener('error', reject);
});

this._socket.addEventListener('message', event => {
this._socket.addEventListener('message', (event) => {
this._handleMessage(JSON.parse(event.data));
});

this._socket.addEventListener('error', _event => {
this._socket.addEventListener('error', (_event) => {
this._handleError(new Error('WebSocket error'));
});

Expand All @@ -59,7 +60,7 @@ export default class WebSocketChannel extends BaseChannel {
const sessionId = this.sessionId;
const message: Message = { id, sessionId, name, data };

this._socket.send(JSON.stringify(message));
this._socket.send(stringify(message));

const timer = setTimeout(() => {
reject(new Error('Send timed out'));
Expand All @@ -72,7 +73,7 @@ export default class WebSocketChannel extends BaseChannel {
},
reject(error: Error) {
reject(error);
}
},
};
})
);
Expand All @@ -90,8 +91,8 @@ export default class WebSocketChannel extends BaseChannel {

// Reject any open sends
Object.keys(this._sendQueue)
.filter(id => this._sendQueue[id] != null)
.forEach(id => {
.filter((id) => this._sendQueue[id] != null)
.forEach((id) => {
this._sendQueue[id]!.reject(error);
this._sendQueue[id] = undefined;
});
Expand Down
34 changes: 22 additions & 12 deletions src/lib/common/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,7 @@ export function splitConfigPath(
* @returns A JSON string
*/
export function stringify(object: Object, indent?: string) {
return JSON.stringify(object, serializeReplacer, indent);
return JSON.stringify(object, getSerializeReplacer(), indent);
}

// ============================================================================
Expand Down Expand Up @@ -986,20 +986,30 @@ const configPathSeparator = '@';
/**
* Replacer function used in stringify
*/
function serializeReplacer(_key: string, value: any) {
if (!value) {
return value;
}
function getSerializeReplacer() {
const seen = new WeakSet();
return function (_key: string, value: any) {
if (!value) {
return value;
}

if (value instanceof RegExp) {
return value.source;
}
if (value instanceof RegExp) {
return value.source;
}

if (typeof value === 'function') {
return value.toString();
}
if (typeof value === 'function') {
return value.toString();
}

if (typeof value === 'object') {
if (seen.has(value)) {
return;
}
seen.add(value);
}

return value;
return value;
};
}

export function errorToJSON(error?: InternError): InternError | undefined {
Expand Down
13 changes: 1 addition & 12 deletions tests/unit/lib/channels/Base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,12 @@ registerSuite('lib/channels/Base', {
base.sendMessage('remoteStatus', 'foo');
assert.deepEqual(base.sent, [['remoteStatus', 'foo']]);
},

error() {
const base = new TestBase({ sessionId: 'foo', url: 'bar' });
base.sendMessage('error', new Error('bad'));
assert.lengthOf(base.sent, 1);
const message = base.sent[0];
assert.propertyVal(message[1], 'name', 'Error');
assert.property(message[1], 'message');
assert.match(message[1].message, /bad/);
assert.property(message[1], 'stack');
}
},

isChannel() {
assert.isFalse(isChannel('foo'));
assert.isFalse(isChannel({}));
assert.isFalse(isChannel({ sendMessage: true }));
assert.isTrue(isChannel({ sendMessage() {} }));
}
},
});

0 comments on commit 847fbed

Please sign in to comment.