Skip to content

Commit 080bce5

Browse files
Merge pull request #15 from oslabs-beta/testing
Testing
2 parents 0356fdb + 7096df5 commit 080bce5

20 files changed

+805
-585
lines changed

demo-app/src/client/Components/Increment.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { BoardText } from '../../types';
44
import { Function } from 'lodash';
55
function Increment() {
66
const [count, setCount] = useState(0);
7-
const [value, setValue]: [BoardText, any] = useState('-');
87
return (
98
<div>
109
<button className='increment' onClick={() => setCount(count + 1)}>
Lines changed: 165 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,182 @@
1-
/* eslint-disable jest/no-disabled-tests */
2-
/* eslint-disable react/state-in-constructor */
3-
/* eslint-disable lines-between-class-members */
4-
/* eslint-disable @typescript-eslint/no-unused-vars */
5-
/* eslint-disable @typescript-eslint/no-var-requires */
6-
/* eslint-disable import/order */
7-
/* eslint-disable import/no-extraneous-dependencies */
8-
/* eslint-disable react/jsx-filename-extension */
9-
import { string } from 'prop-types';
10-
import React, { useState } from 'react';
11-
import { render } from 'react-dom';
12-
import linkFiberStart from '../routers/linkFiber';
13-
14-
const puppeteer = require('puppeteer');
15-
const SERVER = require('../puppeteerServer');
16-
17-
// Apple uses port 5000 for Air Play.
18-
const APP = 'http://localhost:5001';
19-
20-
let linkFiber;
21-
let mode;
22-
let snapShot;
23-
24-
let browser;
25-
let page;
26-
27-
interface fooState {
28-
foo: string;
29-
setFoo?: (string) => void;
30-
}
31-
function App(): JSX.Element {
32-
const [fooState, setFooState] = useState({
33-
foo: 'bar',
1+
import linkFiberInitialization from '../routers/linkFiber';
2+
import { Snapshot, Status, FiberRoot } from '../types/backendTypes';
3+
import Tree from '../models/tree';
4+
import { DevTools } from '../types/linkFiberTypes';
5+
import updateAndSendSnapShotTree from '../routers/snapShot';
6+
import throttle from '../controllers/throttle';
7+
8+
describe('linkFiber', () => {
9+
let snapShot: Snapshot;
10+
let mode: Status;
11+
let linkFiber;
12+
let fiberRoot: FiberRoot;
13+
const mockPostMessage = jest.fn();
14+
15+
beforeEach(() => {
16+
// Create snapshot and mode objects
17+
snapShot = {
18+
tree: new Tree('root', 'root'),
19+
};
20+
mode = {
21+
jumping: false,
22+
paused: false,
23+
navigating: undefined,
24+
};
25+
26+
fiberRoot = {
27+
current: {
28+
tag: 3,
29+
key: null,
30+
elementType: 'div',
31+
type: 'div',
32+
stateNode: {},
33+
child: null,
34+
sibling: null,
35+
index: 0,
36+
memoizedState: null,
37+
memoizedProps: {},
38+
dependencies: null,
39+
_debugHookTypes: [],
40+
},
41+
};
42+
43+
linkFiber = linkFiberInitialization(snapShot, mode);
44+
// Set up mock postMessage function
45+
window.postMessage = mockPostMessage;
46+
47+
// Set up mock React DevTools global hook
48+
(window as any).__REACT_DEVTOOLS_GLOBAL_HOOK__ = {
49+
renderers: new Map<1, { version: string }>([[1, { version: '16' }]]),
50+
inject: jest.fn(),
51+
supportsFiber: true,
52+
onCommitFiberRoot: jest.fn((...args) => {
53+
console.log(...args);
54+
}),
55+
onCommitFiberUnmount: jest.fn(),
56+
rendererInterfaces: {},
57+
getFiberRoots: jest.fn(() => [{ current: { tag: 3 } }]),
58+
};
59+
});
60+
61+
afterEach(() => {
62+
jest.clearAllMocks();
63+
delete window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
3464
});
35-
return <div>{fooState}</div>;
36-
}
37-
38-
xdescribe('unit test for linkFiber', () => {
39-
beforeAll(async () => {
40-
await SERVER;
41-
const args = puppeteer
42-
.defaultArgs()
43-
.filter((arg) => String(arg).toLowerCase() !== '--disable-extensions');
44-
browser = await puppeteer.launch({
45-
args: args.concat([
46-
'--no-sandbox',
47-
'--disable-setuid-sandbox',
48-
'---extensions-on-chrome-urls',
49-
'--whitelisted-extension-id=fmkadmapgofadopljbjfkapdkoienihi',
50-
'--whitelisted-extension-id=hilpbahfbckghckaiafiiinjkeagmfhn',
51-
'--load-extension=/mnt/d/Libraries/Documents/codeRepos/reactime/src/extension/build',
52-
]),
53-
devtools: true,
54-
ignoreDefaultArgs: true,
55-
});
5665

57-
const c = await puppeteer.connect({
58-
browserWSEndpoint: browser.wsEndpoint(),
59-
ignoreHTTPSErrors: false,
66+
describe('link fiber initiliaztion', () => {
67+
it('link fiber should return a function', () => {
68+
expect(typeof linkFiber).toBe('function');
6069
});
6170

62-
page = await browser.newPage();
71+
it('returned function should not throw an error', () => {
72+
expect(() => linkFiber()).not.toThrowError();
73+
});
6374
});
6475

65-
afterAll(async () => {
66-
await SERVER.close();
76+
describe('React dev tools and react app check', () => {
77+
it('should send message to front end that React DevTools is installed', () => {
78+
linkFiber();
79+
expect(mockPostMessage).toHaveBeenCalled();
80+
expect(mockPostMessage).toHaveBeenCalledWith(
81+
{
82+
action: 'devToolsInstalled',
83+
payload: 'devToolsInstalled',
84+
},
85+
'*',
86+
);
87+
});
6788

68-
await browser.close();
69-
});
89+
it('should not do anything if React Devtools is not installed', () => {
90+
delete window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
91+
expect(() => linkFiber()).not.toThrowError();
92+
expect(mockPostMessage).not.toHaveBeenCalled();
93+
});
7094

71-
beforeEach(() => {
72-
snapShot = { tree: null };
73-
mode = {
74-
jumping: false,
75-
paused: false,
76-
};
77-
linkFiber = linkFiberStart(snapShot, mode);
95+
it('should send a message to the front end if the target application is a React App', () => {
96+
linkFiber();
97+
// the third call is from the onCommitFiberRoot() function
98+
expect(mockPostMessage).toHaveBeenCalledTimes(3);
99+
expect(mockPostMessage).toHaveBeenCalledWith(
100+
{
101+
action: 'devToolsInstalled',
102+
payload: 'devToolsInstalled',
103+
},
104+
'*',
105+
);
106+
expect(mockPostMessage).toHaveBeenCalledWith(
107+
{
108+
action: 'aReactApp',
109+
payload: 'aReactApp',
110+
},
111+
'*',
112+
);
113+
});
78114

79-
page.waitForFunction(
80-
async (lf) => {
81-
const container = document.createElement('div');
82-
render(<App />, container);
83-
lf(container);
84-
},
85-
{},
86-
linkFiber,
87-
);
115+
it('should not do anything if the target application is not a React App', () => {
116+
(window as any).__REACT_DEVTOOLS_GLOBAL_HOOK__.renderers = new Map();
117+
linkFiber();
118+
expect(mockPostMessage).not.toHaveBeenCalledTimes(3);
119+
});
88120
});
89121

90-
test('type of tree should be an object', () => {
91-
expect(typeof snapShot.tree).toBe('object');
122+
describe('document visibility', () => {
123+
it('should initiate an event listener for visibility change', () => {
124+
const addEventListenerSpy = jest.spyOn(document, 'addEventListener');
125+
linkFiber();
126+
expect(addEventListenerSpy).toHaveBeenCalledWith('visibilitychange', expect.any(Function));
127+
});
92128
});
93129

94-
test.skip('linkFiber should mutate the snapshot tree property', () => {
95-
expect(snapShot.tree.state).toBe('root');
96-
expect(snapShot.tree.children).toHaveLength(1);
97-
expect(snapShot.tree.children[0].component.state.foo).toBe('bar');
130+
describe('throttledUpdateSnapshot', () => {
131+
const mockUpdateAndSendSnapShotTree = jest.fn();
132+
133+
beforeEach(() => {
134+
jest.useFakeTimers();
135+
mockUpdateAndSendSnapShotTree.mockClear();
136+
});
137+
138+
afterEach(() => {
139+
jest.runOnlyPendingTimers();
140+
jest.useRealTimers();
141+
});
142+
143+
it('throttled function should be called with the correct arguments', () => {
144+
const throttledUpdateSnapshot = throttle(mockUpdateAndSendSnapShotTree, 1000);
145+
const onCoolDown = true;
146+
const isCallQueued = true;
147+
throttledUpdateSnapshot(onCoolDown, isCallQueued);
148+
149+
expect(mockUpdateAndSendSnapShotTree).toHaveBeenCalledWith(onCoolDown, isCallQueued);
150+
});
151+
152+
it('should call updateAndSendSnapShotTree only once per 100ms', () => {
153+
const throttledUpdateSnapshot = throttle(mockUpdateAndSendSnapShotTree, 100);
154+
throttledUpdateSnapshot();
155+
expect(mockUpdateAndSendSnapShotTree).toHaveBeenCalledTimes(1);
156+
throttledUpdateSnapshot();
157+
expect(mockUpdateAndSendSnapShotTree).toHaveBeenCalledTimes(1);
158+
jest.advanceTimersByTime(100);
159+
expect(mockUpdateAndSendSnapShotTree).toHaveBeenCalledTimes(2);
160+
});
161+
162+
it('should call throttle after visibility change', () => {
163+
const throttledUpdateSnapshot = throttle(mockUpdateAndSendSnapShotTree, 100);
164+
// Simulate visibility change
165+
const visibilityChangeEvent = new Event('visibilitychange');
166+
document.dispatchEvent(visibilityChangeEvent);
167+
expect(throttle).toHaveBeenCalled();
168+
});
98169
});
99170

100-
test.skip('linkFiber should modify the setState of the stateful component', () => {
101-
expect(snapShot.tree.children[0].component.setState.linkFiberChanged).toBe(true);
171+
describe('addOneMoreStep', () => {
172+
it('should add a new step to the current path in the snapshot tree', () => {});
102173
});
103-
});
104174

105-
SERVER.close();
175+
describe('onCommitFiberRoot', () => {
176+
it('should call throttledUpdateSnapshot', () => {
177+
linkFiber();
178+
const onCommitFiberRoot = window.__REACT_DEVTOOLS_GLOBAL_HOOK__?.onCommitFiberRoot;
179+
expect(onCommitFiberRoot).toHaveBeenCalled();
180+
});
181+
});
182+
});

0 commit comments

Comments
 (0)