Skip to content

Commit

Permalink
#454@trivial: Continues on making Window a VM context.
Browse files Browse the repository at this point in the history
  • Loading branch information
capricorn86 committed Apr 21, 2022
1 parent 0a670ad commit 546c10a
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 158 deletions.
9 changes: 4 additions & 5 deletions packages/happy-dom/package.json
Expand Up @@ -27,11 +27,10 @@
"watch": "tsc -w --preserveWatchOutput",
"lint": "eslint --ignore-path .gitignore --max-warnings 0 .",
"lint:fix": "eslint --ignore-path .gitignore --max-warnings 0 --fix .",
"test": "jest",
"test:coverage": "jest --collectCoverage",
"test:watch": "jest --watch",
"test:update-snapshot": "jest --updateSnapshot",
"test:debug": "node --inspect-brk ./node_modules/.bin/jest --runInBand"
"test": "jest --setupFilesAfterEnv ./test/setup.js",
"test:coverage": "jest --setupFilesAfterEnv ./test/setup.js --collectCoverage",
"test:watch": "jest --setupFilesAfterEnv ./test/setup.js --watch",
"test:debug": "node --inspect-brk ./node_modules/.bin/jest --setupFilesAfterEnv ./test/setup.js --runInBand"
},
"jest": {
"transform": {
Expand Down
68 changes: 5 additions & 63 deletions packages/happy-dom/src/window/Window.ts
@@ -1,5 +1,6 @@
import GlobalWindow from './GlobalWindow';
import VM from 'vm';
import GlobalProperties from './GlobalProperties';

/**
* Browser window without a VM in the global scope.
Expand All @@ -8,75 +9,16 @@ import VM from 'vm';
* https://developer.mozilla.org/en-US/docs/Web/API/Window.
*/
export default class Window extends GlobalWindow {
// Node.js Globals
public ArrayBuffer;
public Boolean;
public Buffer;
public DataView;
public Date;
public Error;
public EvalError;
public Float32Array;
public Float64Array;
public GLOBAL;
public Infinity;
public Int16Array;
public Int32Array;
public Int8Array;
public Intl;
public JSON;
public Map;
public Math;
public NaN;
public Number;
public Promise;
public RangeError;
public ReferenceError;
public RegExp;
public Reflect;
public Set;
public Symbol;
public SyntaxError;
public String;
public TypeError;
public URIError;
public Uint16Array;
public Uint32Array;
public Uint8Array;
public Uint8ClampedArray;
public WeakMap;
public WeakSet;
public clearImmediate;
public decodeURI;
public decodeURIComponent;
public encodeURI;
public encodeURIComponent;
public escape;
public global;
public isFinite;
public isNaN;
public parseFloat;
public parseInt;
public process;
public root;
public setImmediate;
public queueMicrotask;
public undefined;
public unescape;
public gc;
public v8debug;
public AbortController;
public AbortSignal;
public Array;
public Object;
public Function;

/**
* Constructor.
*/
constructor() {
super();

for (const property of GlobalProperties) {
delete this[property];
}

if (!VM.isContext(this)) {
VM.createContext(this);
}
Expand Down
26 changes: 6 additions & 20 deletions packages/happy-dom/test/fetch/ResourceFetchHandler.test.ts
Expand Up @@ -4,30 +4,16 @@ import IDocument from '../../src/nodes/document/IDocument';
import ResourceFetchHandler from '../../src/fetch/ResourceFetchHandler';
import IResponse from '../../src/fetch/IResponse';

let syncRequestStatusCode;
let syncRequestBody;
let syncRequestOptions;

jest.mock('sync-request', () => (method: string, url: string) => {
syncRequestOptions = {
method,
url
};
return {
getBody: () => syncRequestBody,
isError: () => syncRequestStatusCode !== 200,
statusCode: syncRequestStatusCode
};
});
const MOCKED_SYNC_REQUEST = global['mockedModules']['sync-request'];

describe('ResourceFetchHandler', () => {
let window: IWindow;
let document: IDocument;

beforeEach(() => {
syncRequestOptions = null;
syncRequestStatusCode = 200;
syncRequestBody = 'test';
MOCKED_SYNC_REQUEST.options = null;
MOCKED_SYNC_REQUEST.statusCode = 200;
MOCKED_SYNC_REQUEST.body = 'test';
window = new Window();
document = window.document;
});
Expand Down Expand Up @@ -61,7 +47,7 @@ describe('ResourceFetchHandler', () => {

const test = ResourceFetchHandler.fetchSync(document, 'path/to/script/');

expect(syncRequestOptions).toEqual({
expect(MOCKED_SYNC_REQUEST.options).toEqual({
method: 'GET',
url: 'https://localhost:8080/base/path/to/script/'
});
Expand All @@ -71,7 +57,7 @@ describe('ResourceFetchHandler', () => {
it('Handles error when resource is fetched synchrounously.', () => {
window.location.href = 'https://localhost:8080/base/';

syncRequestStatusCode = 404;
MOCKED_SYNC_REQUEST.statusCode = 404;

expect(() => {
ResourceFetchHandler.fetchSync(document, 'path/to/script/');
Expand Down
75 changes: 75 additions & 0 deletions packages/happy-dom/test/setup.js
@@ -0,0 +1,75 @@
global.mockedModules = {
'sync-request': {
statusCode: null,
body: null,
options: null
},
'node-fetch': {
url: null,
init: null,
error: null,
response: {
arrayBuffer: Symbol('arrayBuffer'),
blob: Symbol('blob'),
buffer: Symbol('buffer'),
json: Symbol('json'),
text: Symbol('text'),
textConverted: Symbol('textConverted')
}
}
};

jest.mock('sync-request', () => (method, url) => {
global.mockedModules['sync-request'].options = {
method,
url
};
return {
getBody: () => global.mockedModules['sync-request'].body,
isError: () => global.mockedModules['sync-request'].statusCode !== 200,
statusCode: global.mockedModules['sync-request'].statusCode
};
});

/* eslint-disable jsdoc/require-jsdoc */
class NodeFetchResponse {
arrayBuffer() {
return Promise.resolve(global.mockedModules['node-fetch'].response.arrayBuffer);
}
blob() {
return Promise.resolve(global.mockedModules['node-fetch'].response.blob);
}
buffer() {
return Promise.resolve(global.mockedModules['node-fetch'].response.buffer);
}
json() {
return Promise.resolve(global.mockedModules['node-fetch'].response.json);
}
text() {
return Promise.resolve(global.mockedModules['node-fetch'].response.text);
}
textConverted() {
return Promise.resolve(global.mockedModules['node-fetch'].response.textConverted);
}
}

class NodeFetchRequest extends NodeFetchResponse {}
class NodeFetchHeaders {}

jest.mock('node-fetch', () => {
return Object.assign(
(url, options) => {
global.mockedModules['node-fetch'].url = url;
global.mockedModules['node-fetch'].init = options;
if (global.mockedModules['node-fetch'].error) {
return Promise.reject(global.mockedModules['node-fetch'].error);
}
return Promise.resolve(new NodeFetchResponse());
},
{
Response: NodeFetchResponse,
Request: NodeFetchRequest,
Headers: NodeFetchHeaders
}
);
});
83 changes: 14 additions & 69 deletions packages/happy-dom/test/window/GlobalWindow.test.ts
Expand Up @@ -4,78 +4,23 @@ import IHTMLLinkElement from '../../src/nodes/html-link-element/IHTMLLinkElement
import IHTMLElement from '../../src/nodes/html-element/IHTMLElement';
import ResourceFetchHandler from '../../src/fetch/ResourceFetchHandler';
import IHTMLScriptElement from '../../src/nodes/html-script-element/IHTMLScriptElement';
import IRequestInit from '../../src/fetch/IRequestInit';
import GlobalWindow from '../../src/window/GlobalWindow';
import IWindow from '../../src/window/IWindow';
import Navigator from '../../src/navigator/Navigator';
import Headers from '../../src/fetch/Headers';
import Response from '../../src/fetch/Response';
import Request from '../../src/fetch/Request';

const MOCKED_RESPONSES = {
arrayBuffer: Symbol('arrayBuffer'),
blob: Symbol('blob'),
buffer: Symbol('buffer'),
json: Symbol('json'),
text: Symbol('text'),
textConverted: Symbol('textConverted')
};

/* eslint-disable jsdoc/require-jsdoc */
class NodeFetchResponse {
public arrayBuffer(): Promise<symbol> {
return Promise.resolve(MOCKED_RESPONSES.arrayBuffer);
}
public blob(): Promise<symbol> {
return Promise.resolve(MOCKED_RESPONSES.blob);
}
public buffer(): Promise<symbol> {
return Promise.resolve(MOCKED_RESPONSES.buffer);
}
public json(): Promise<symbol> {
return Promise.resolve(MOCKED_RESPONSES.json);
}
public text(): Promise<symbol> {
return Promise.resolve(MOCKED_RESPONSES.text);
}
public textConverted(): Promise<symbol> {
return Promise.resolve(MOCKED_RESPONSES.textConverted);
}
}

class NodeFetchRequest extends NodeFetchResponse {}
class NodeFetchHeaders {}

let fetchedUrl: string;
let fetchedInit: IRequestInit;
let fetchError: Error;

jest.mock('node-fetch', () => {
return Object.assign(
(url: string, options: IRequestInit) => {
fetchedUrl = url;
fetchedInit = options;
if (fetchError) {
return Promise.reject(fetchError);
}
return Promise.resolve(new NodeFetchResponse());
},
{
Response: NodeFetchResponse,
Request: NodeFetchRequest,
Headers: NodeFetchHeaders
}
);
});
const MOCKED_NODE_FETCH = global['mockedModules']['node-fetch'];

describe('GlobalWindow', () => {
let window: IWindow;
let document: IDocument;

beforeEach(() => {
fetchedUrl = null;
fetchedInit = null;
fetchError = null;
MOCKED_NODE_FETCH.url = null;
MOCKED_NODE_FETCH.init = null;
MOCKED_NODE_FETCH.error = null;
window = new GlobalWindow();
document = window.document;
});
Expand Down Expand Up @@ -136,7 +81,7 @@ describe('GlobalWindow', () => {
it(`Handles the "${method}" method with the async task manager.`, async () => {
const response = new window.Response();
const result = await response[method]();
expect(result).toBe(MOCKED_RESPONSES[method]);
expect(result).toBe(MOCKED_NODE_FETCH.response[method]);
});
}
});
Expand All @@ -151,7 +96,7 @@ describe('GlobalWindow', () => {
it(`Handles the "${method}" method with the async task manager.`, async () => {
const request = new window.Request('test');
const result = await request[method]();
expect(result).toBe(MOCKED_RESPONSES[method]);
expect(result).toBe(MOCKED_NODE_FETCH.response[method]);
});
}
});
Expand Down Expand Up @@ -296,9 +241,9 @@ describe('GlobalWindow', () => {
const response = await window.fetch(expectedUrl, expectedOptions);
const result = await response[method]();

expect(fetchedUrl).toBe(expectedUrl);
expect(fetchedInit).toBe(expectedOptions);
expect(result).toEqual(MOCKED_RESPONSES[method]);
expect(MOCKED_NODE_FETCH.url).toBe(expectedUrl);
expect(MOCKED_NODE_FETCH.init).toBe(expectedOptions);
expect(result).toEqual(MOCKED_NODE_FETCH.response[method]);
});
}

Expand All @@ -311,18 +256,18 @@ describe('GlobalWindow', () => {
const response = await window.fetch(expectedPath, expectedOptions);
const textResponse = await response.text();

expect(fetchedUrl).toBe('https://localhost:8080' + expectedPath);
expect(fetchedInit).toBe(expectedOptions);
expect(textResponse).toEqual(MOCKED_RESPONSES.text);
expect(MOCKED_NODE_FETCH.url).toBe('https://localhost:8080' + expectedPath);
expect(MOCKED_NODE_FETCH.init).toBe(expectedOptions);
expect(textResponse).toEqual(MOCKED_NODE_FETCH.response.text);
});

it('Handles error JSON request.', async () => {
fetchError = new Error('error');
MOCKED_NODE_FETCH.error = new Error('error');

try {
await window.fetch('/url/', {});
} catch (error) {
expect(error).toBe(fetchError);
expect(error).toBe(MOCKED_NODE_FETCH.error);
}
});
});
Expand Down
1 change: 0 additions & 1 deletion packages/jest-environment/package.json
Expand Up @@ -31,7 +31,6 @@
"lint:fix": "eslint --ignore-path .gitignore --max-warnings 0 --fix .",
"test": "jest",
"test:watch": "jest --runInBand --watch",
"test:update-snapshot": "jest --runInBand --updateSnapshot",
"test:debug": "node --inspect-brk ./node_modules/.bin/jest --runInBand"
},
"jest": {
Expand Down

0 comments on commit 546c10a

Please sign in to comment.