Skip to content

Commit be6aa7c

Browse files
committed
Complete testing for rendering mixture of functional & class components
1 parent baf0689 commit be6aa7c

File tree

10 files changed

+361
-196
lines changed

10 files changed

+361
-196
lines changed

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
"www",
1010
"./src/backend/__tests__/ignore"
1111
],
12+
"coveragePathIgnorePatterns": [
13+
"/src/backend/__tests__/ignore/"
14+
],
1215
"transformIgnorePatterns": [
1316
"/node_modules/(?!d3|d3-array|internmap|delaunator|robust-predicates)"
1417
],
@@ -99,7 +102,6 @@
99102
],
100103
"license": "ISC",
101104
"devDependencies": {
102-
"@babel/core": "^7.12.7",
103105
"@babel/plugin-proposal-class-properties": "^7.10.4",
104106
"@babel/plugin-proposal-decorators": "^7.10.5",
105107
"@babel/preset-env": "^7.12.7",

src/backend/__tests__/ignore/IncrementFunc.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useState } from 'react';
2-
function Increment() {
2+
function IncrementFunc() {
33
const [count, setCount] = useState(0);
44
return (
55
<div>
@@ -10,4 +10,4 @@ function Increment() {
1010
);
1111
}
1212

13-
export default Increment;
13+
export default IncrementFunc;

src/backend/__tests__/ignore/linkFiber-testcases.ts

Lines changed: 96 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import Tree from '../../models/tree';
22
import routes from '../../models/routes';
3-
import { ComponentData, Fiber } from '../../types/backendTypes';
3+
import { ComponentData, Fiber, FiberRoot } from '../../types/backendTypes';
44
import { FunctionComponent, ClassComponent, HostRoot } from '../../types/backendTypes';
55
import IncrementFunc from './IncrementFunc';
66
import IncrementClass from './IncrementClass';
7+
import { transformSync } from '@babel/core';
78

9+
// ----------------------------TEST CASES FOR ROOT------------------------------
810
export const root: Fiber = {
911
tag: HostRoot,
1012
elementType: null,
@@ -22,14 +24,15 @@ export const root: Fiber = {
2224
export const rootPayload = new Tree('root', 'root');
2325
rootPayload.route = routes.addRoute('http://localhost/');
2426

27+
// ----------------------TEST CASE FOR FUNCTIONAL COMPONENT---------------------
2528
export const functionalComponent: Fiber = {
2629
tag: FunctionComponent,
2730
elementType: IncrementFunc,
2831
sibling: null,
2932
stateNode: null,
3033
child: null,
3134
memoizedState: {
32-
memoizeState: 0,
35+
memoizedState: 0,
3336
queue: {
3437
dispatch: function (newState) {
3538
this.memoizedState = newState;
@@ -44,6 +47,25 @@ export const functionalComponent: Fiber = {
4447
_debugHookTypes: ['useState'],
4548
};
4649

50+
const functionalComponentData: ComponentData = {
51+
actualDuration: 1,
52+
actualStartTime: 2,
53+
selfBaseDuration: 3,
54+
treeBaseDuration: 4,
55+
context: {},
56+
hooksIndex: [0],
57+
hooksState: { count: 0 },
58+
index: null,
59+
props: {},
60+
state: null,
61+
};
62+
63+
export const functionalPayload: Tree = new Tree('root', 'root');
64+
functionalPayload.route = rootPayload.route;
65+
functionalPayload.addChild({ count: 0 }, 'IncrementFunc', functionalComponentData, null);
66+
67+
// -----------------------TEST CASE FOR CLASS COMPONENT-------------------------
68+
4769
export const classComponent: Fiber = {
4870
tag: ClassComponent,
4971
elementType: IncrementClass,
@@ -66,11 +88,7 @@ export const classComponent: Fiber = {
6688
_debugHookTypes: null,
6789
};
6890

69-
export const classPayload = new Tree('root', 'root');
70-
classPayload.route = rootPayload.route;
71-
72-
// Append increment child to root
73-
const componentData: ComponentData = {
91+
const classComponentData: ComponentData = {
7492
actualDuration: 1,
7593
actualStartTime: 2,
7694
selfBaseDuration: 3,
@@ -82,13 +100,82 @@ const componentData: ComponentData = {
82100
props: {},
83101
state: { count: 0 },
84102
};
85-
classPayload.addChild({ count: 0 }, 'IncrementClass', componentData, null);
103+
104+
export const classPayload = new Tree('root', 'root');
105+
classPayload.route = rootPayload.route;
106+
107+
classPayload.addChild({ count: 0 }, 'IncrementClass', classComponentData, null);
86108

87109
export const updateClassPayload = new Tree('root', 'root');
88110
updateClassPayload.route = rootPayload.route;
89111
updateClassPayload.addChild(
90112
{ count: 2 },
91113
'IncrementClass',
92-
{ ...componentData, state: { count: 2 } },
114+
{ ...classComponentData, state: { count: 2 } },
93115
null,
94116
);
117+
118+
// -----------------------TEST CASE FOR MIX OF COMPONENTS-----------------------
119+
export const mixComponents: Fiber = deepCopy(root);
120+
mixComponents.child = deepCopy(functionalComponent);
121+
mixComponents.sibling = deepCopy(classComponent);
122+
mixComponents.child!.child = deepCopy(functionalComponent);
123+
mixComponents.child!.child!.sibling = deepCopy(classComponent);
124+
// console.dir(mixComponents, { depth: null });
125+
126+
export const mixPayload = new Tree('root', 'root');
127+
mixPayload.route = rootPayload.route;
128+
129+
// Outer Func Comp
130+
let funcPayloadMix = new Tree({ count: 0 }, 'IncrementFunc', functionalComponentData, null);
131+
funcPayloadMix.componentData = {
132+
...funcPayloadMix.componentData,
133+
hooksState: { count: 0 },
134+
hooksIndex: [0],
135+
};
136+
mixPayload.children.push(deepCopy(funcPayloadMix));
137+
138+
// Outer Class Comp
139+
let classPayloadMix = new Tree({ count: 0 }, 'IncrementClass', classComponentData, null);
140+
classPayloadMix.componentData = {
141+
...classPayloadMix.componentData,
142+
state: { count: 0 },
143+
index: 3,
144+
};
145+
mixPayload.children.push(deepCopy(classPayloadMix));
146+
147+
// Inner Func Comp
148+
funcPayloadMix = new Tree({ count: 0 }, 'IncrementFunc', functionalComponentData, null);
149+
funcPayloadMix.componentData = {
150+
...funcPayloadMix.componentData,
151+
hooksState: { count: 0 },
152+
hooksIndex: [1],
153+
};
154+
funcPayloadMix.name = 'IncrementFunc1';
155+
mixPayload.children[0].children.push(deepCopy(funcPayloadMix));
156+
157+
// Inner Class Comp
158+
classPayloadMix = new Tree({ count: 0 }, 'IncrementClass', classComponentData, null);
159+
classPayloadMix.componentData = {
160+
...classPayloadMix.componentData,
161+
state: { count: 0 },
162+
index: 2,
163+
};
164+
mixPayload.children[0].children.push(deepCopy(classPayloadMix));
165+
166+
// console.dir(mixPayload, { depth: null });
167+
168+
function deepCopy(obj) {
169+
if (obj === null || typeof obj !== 'object') {
170+
return obj;
171+
}
172+
const copy = Array.isArray(obj) ? [] : {};
173+
Object.keys(obj).forEach((key) => {
174+
if (typeof obj[key] === 'function') {
175+
copy[key] = obj[key];
176+
} else {
177+
copy[key] = deepCopy(obj[key]);
178+
}
179+
});
180+
return copy;
181+
}

src/backend/__tests__/linkFiber.test.ts

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@ import linkFiberInitialization from '../routers/linkFiber';
22
import timeJumpInitialization from '../controllers/timeJump';
33
import componentActionsRecord from '../models/masterState';
44
import {
5-
classComponent,
65
root,
76
rootPayload,
7+
classComponent,
88
classPayload,
99
updateClassPayload,
10+
functionalComponent,
11+
functionalPayload,
12+
mixComponents,
13+
mixPayload,
1014
} from './ignore/linkFiber-testcases';
1115
import { Snapshot, Status, FiberRoot } from '../types/backendTypes';
1216
import Tree from '../models/tree';
@@ -34,9 +38,6 @@ describe('linkFiber', () => {
3438
dom = new JSDOM(indexHTML, { url: 'http://localhost' });
3539
global.window = dom.window as unknown as Window & typeof globalThis;
3640
global.document = dom.window._document;
37-
38-
// Initialize Fiber Root:
39-
fiberRoot = { current: root };
4041
});
4142

4243
afterAll(() => {
@@ -53,6 +54,8 @@ describe('linkFiber', () => {
5354
jumping: false,
5455
paused: false,
5556
};
57+
// Initialize Fiber Root:
58+
fiberRoot = { current: root };
5659

5760
// Initialize linkFiber
5861
linkFiber = linkFiberInitialization(snapshot, mode);
@@ -190,7 +193,7 @@ describe('linkFiber', () => {
190193
expect(orginalOnCommitFiberRoot).not.toEqual(monkeyPatchOnCommitFiberRoot);
191194
});
192195

193-
it('should send a snapshot when new fiberRoot is committed', async () => {
196+
it('should send a snapshot when new fiberRoot is committed for a class component', async () => {
194197
// When first initialize linkFiber, should send snapShot of rootPayload
195198
await new Promise(linkFiberDelayed);
196199
expect(mockPostMessage).toHaveBeenCalledWith(
@@ -200,7 +203,7 @@ describe('linkFiber', () => {
200203
},
201204
'*',
202205
);
203-
206+
mockPostMessage.mockClear();
204207
// After modified fiberRoot to classComponent, onCommitFiberRoot should send snapSot of classPayload
205208
fiberRoot = { current: classComponent };
206209
await new Promise(onCommitFiberRootDelayed);
@@ -212,6 +215,54 @@ describe('linkFiber', () => {
212215
'*',
213216
);
214217
});
218+
219+
it('should send a snapshot when new fiberRoot is committed for a functional component', async () => {
220+
// When first initialize linkFiber, should send snapShot of rootPayload
221+
await new Promise(linkFiberDelayed);
222+
expect(mockPostMessage).toHaveBeenCalledWith(
223+
{
224+
action: 'recordSnap',
225+
payload: rootPayload,
226+
},
227+
'*',
228+
);
229+
mockPostMessage.mockClear();
230+
231+
// After modified fiberRoot to functionalComponent, onCommitFiberRoot should send snapSot of functionalPayload
232+
fiberRoot = { current: functionalComponent };
233+
await new Promise(onCommitFiberRootDelayed);
234+
expect(mockPostMessage).toHaveBeenCalledWith(
235+
{
236+
action: 'recordSnap',
237+
payload: functionalPayload,
238+
},
239+
'*',
240+
);
241+
});
242+
243+
it('should send a snapshot when new fiberRoot is commited for mixture of components', async () => {
244+
// When first initialize linkFiber, should send snapShot of rootPayload
245+
await new Promise(linkFiberDelayed);
246+
expect(mockPostMessage).toHaveBeenCalledWith(
247+
{
248+
action: 'recordSnap',
249+
payload: rootPayload,
250+
},
251+
'*',
252+
);
253+
mockPostMessage.mockClear();
254+
255+
// After modified fiberRoot to mixComponents, onCommitFiberRoot should send snapSot of mixPayload
256+
fiberRoot = { current: mixComponents };
257+
await new Promise(onCommitFiberRootDelayed);
258+
expect(mockPostMessage).toHaveBeenCalledWith(
259+
{
260+
action: 'recordSnap',
261+
payload: mixPayload,
262+
},
263+
'*',
264+
);
265+
});
215266
});
216267

217268
describe('mode unit tests', () => {

src/backend/__tests__/masterState.test.ts

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,6 @@
11
import componentActionRecord from '../models/masterState';
22

33
describe('Master State unit tests', () => {
4-
// describe('ComponentAction and ComponentActionRecord type tests', () => {
5-
// it('ComponentAction should be an object with string keys and array values', () => {
6-
// const componentAction: ComponentAction = {
7-
// 'http://test.com': ['action1', 'action2'],
8-
// };
9-
// expect(componentAction).toEqual(expect.any(Object));
10-
// expect(Object.keys(componentAction)).toEqual(expect.arrayContaining(['http://test.com']));
11-
// expect(Array.isArray(componentAction['http://test.com'])).toBe(true);
12-
// });
13-
14-
// it('ComponentActionRecord should be an array of ComponentAction', () => {
15-
// const componentActionRecord: ComponentActionRecord = [
16-
// { 'http://test.com': ['action1', 'action2'] },
17-
// { 'http://test.com/2': ['action3', 'action4'] },
18-
// ];
19-
// expect(componentActionRecord).toEqual(expect.any(Array));
20-
// expect(componentActionRecord.length).toBe(2);
21-
// expect(componentActionRecord[0]).toEqual(
22-
// expect.objectContaining({ 'http://test.com': expect.any(Array) }),
23-
// );
24-
// expect(componentActionRecord[1]).toEqual(
25-
// expect.objectContaining({ 'http://test.com/2': expect.any(Array) }),
26-
// );
27-
// });
28-
29-
// it('ComponentAction should be an object with string keys and array values', () => {
30-
// const componentAction: ComponentAction = {
31-
// 'http://test.com': ['action1', 'action2'],
32-
// };
33-
// expect(componentAction).toEqual(expect.any(Object));
34-
// expect(Object.keys(componentAction)).toEqual(expect.arrayContaining(['http://test.com']));
35-
// expect(Array.isArray(componentAction['http://test.com'])).toBe(true);
36-
// });
37-
38-
// it('ComponentActionRecord should be an array of ComponentActions', () => {
39-
// const componentActionRecord: ComponentActionRecord = [
40-
// { 'http://test.com': ['action1', 'action2'] },
41-
// { 'http://test.com/2': ['action3', 'action4'] },
42-
// ];
43-
// expect(componentActionRecord).toEqual(expect.any(Array));
44-
// expect(componentActionRecord.length).toBe(2);
45-
// expect(componentActionRecord[0]).toEqual(
46-
// expect.objectContaining({ 'http://test.com': expect.any(Array) }),
47-
// );
48-
// expect(componentActionRecord[1]).toEqual(
49-
// expect.objectContaining({ 'http://test.com/2': expect.any(Array) }),
50-
// );
51-
// });
52-
// });
53-
544
describe('componentActionRecord unit tests', () => {
555
const component1 = { state: 'dummy state', props: {} };
566
const component2 = { state: 'dummy state2', props: {} };

0 commit comments

Comments
 (0)