forked from microsoft/vscode-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathreactHelpers.ts
More file actions
134 lines (112 loc) · 4.79 KB
/
Copy pathreactHelpers.ts
File metadata and controls
134 lines (112 loc) · 4.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
'use strict';
import { ComponentClass, configure, ReactWrapper } from 'enzyme';
import * as Adapter from 'enzyme-adapter-react-16';
import { JSDOM } from 'jsdom';
import * as React from 'react';
export function setUpDomEnvironment() {
// tslint:disable-next-line:no-http-string
const dom = new JSDOM('<!doctype html><html><body><div id="root"></div></body></html>', { pretendToBeVisual: true, url: 'http://localhost'});
const { window } = dom;
// tslint:disable-next-line:no-string-literal
global['window'] = window;
// tslint:disable-next-line:no-string-literal
global['document'] = window.document;
// tslint:disable-next-line:no-string-literal
global['navigator'] = {
userAgent: 'node.js',
platform: 'node'
};
// tslint:disable-next-line:no-string-literal
global['self'] = window;
copyProps(window, global);
// Special case. Transform needs createRange
// tslint:disable-next-line:no-string-literal
global['document'].createRange = () => ({
createContextualFragment: str => JSDOM.fragment(str)
});
// For Jupyter server to load correctly. It expects the window object to not be defined
// tslint:disable-next-line:no-eval
const fetchMod = eval('require')('node-fetch');
// tslint:disable-next-line:no-string-literal
global['fetch'] = fetchMod;
// tslint:disable-next-line:no-string-literal
global['Request'] = fetchMod.Request;
// tslint:disable-next-line:no-string-literal
global['Headers'] = fetchMod.Headers;
// tslint:disable-next-line:no-string-literal no-eval
global['WebSocket'] = eval('require')('ws');
// For the loc test to work, we have to have a global getter for loc strings
// tslint:disable-next-line:no-string-literal no-eval
global['getLocStrings'] = () => {
return { 'DataScience.unknownMimeType' : 'Unknown mime type from helper' };
};
configure({ adapter: new Adapter() });
}
function copyProps(src, target) {
const props = Object.getOwnPropertyNames(src)
.filter(prop => typeof target[prop] === undefined);
props.forEach((p : string) => {
target[p] = src[p];
});
}
function waitForComponentDidUpdate<P, S, C>(component: React.Component<P, S, C>) : Promise<void> {
return new Promise((resolve, reject) => {
if (component) {
let originalUpdateFunc = component.componentDidUpdate;
if (originalUpdateFunc) {
originalUpdateFunc = originalUpdateFunc.bind(component);
}
// tslint:disable-next-line:no-any
component.componentDidUpdate = (prevProps: Readonly<P>, prevState: Readonly<S>, snapshot?: any) => {
// When the component updates, call the original function and resolve our promise
if (originalUpdateFunc) {
originalUpdateFunc(prevProps, prevState, snapshot);
}
// Reset our update function
component.componentDidUpdate = originalUpdateFunc;
// Finish the promise
resolve();
};
} else {
reject('Cannot find the component for waitForComponentDidUpdate');
}
});
}
function waitForRender<P, S, C>(component: React.Component<P, S, C>) : Promise<void> {
return new Promise((resolve, reject) => {
if (component) {
let originalRenderFunc = component.render;
if (originalRenderFunc) {
originalRenderFunc = originalRenderFunc.bind(component);
}
component.render = () => {
let result : React.ReactNode = null;
// When the render occurs, call the original function and resolve our promise
if (originalRenderFunc) {
result = originalRenderFunc();
}
// Reset our render function
component.render = originalRenderFunc;
resolve();
return result;
};
} else {
reject('Cannot find the component for waitForRender');
}
});
}
export async function waitForUpdate<P, S, C>(wrapper: ReactWrapper<P, S, C>, mainClass: ComponentClass<P>) : Promise<void> {
const mainObj = wrapper.find(mainClass).instance();
if (mainObj) {
// Hook the render first.
const renderPromise = waitForRender(mainObj);
// First wait for the update
await waitForComponentDidUpdate(mainObj);
// Force a render
wrapper.update();
// Wait for the render
await renderPromise;
}
}