Skip to content

Commit d55394e

Browse files
committed
complete state display, working on rtid display
1 parent 89e90cb commit d55394e

File tree

6 files changed

+251
-45
lines changed

6 files changed

+251
-45
lines changed

src/backend/__tests__/ignore/IncrementFunc.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,15 @@ function IncrementFunc() {
1111
}
1212

1313
export default IncrementFunc;
14+
15+
export function IncrementFuncMultiStates() {
16+
const [count, setCount] = useState(0);
17+
const [count1, setCount1] = useState(1);
18+
return (
19+
<div>
20+
<button className='increment' onClick={() => setCount(count + 1)}>
21+
You clicked me {count + count1} times
22+
</button>
23+
</div>
24+
);
25+
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ export const classComponent: Fiber = {
8989
treeBaseDuration: 4,
9090
_debugHookTypes: null,
9191
};
92+
classComponent.stateNode.setState = classComponent.stateNode.setState.bind(
93+
classComponent.stateNode,
94+
);
9295

9396
const classComponentData: ComponentData = {
9497
actualDuration: 1,

src/backend/__tests__/masterTree.test.tsx

Lines changed: 209 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
ComponentData,
1010
WorkTag,
1111
} from '../types/backendTypes';
12+
import { IncrementFuncMultiStates } from './ignore/IncrementFunc';
1213
import Tree from '../models/tree';
1314
import {
1415
root,
@@ -26,6 +27,7 @@ import {
2627
exclude,
2728
} from '../models/filterConditions';
2829
import deepCopy from './ignore/deepCopy';
30+
import { Children } from 'react';
2931

3032
describe('master tree tests', () => {
3133
let treeRoot: Tree;
@@ -43,8 +45,11 @@ describe('master tree tests', () => {
4345
state: null,
4446
};
4547
let mockFiberTree: Tree;
48+
/** `mockChildNode` is a CLASS COMPONENT*/
4649
let mockChildNode: Fiber;
4750
let mockChildTree: Tree;
51+
52+
/** `mockSibilingNode` is a FUNCTIONAL COMPONENT*/
4853
let mockSiblingNode: Fiber;
4954
let mockSiblingTree: Tree;
5055

@@ -136,20 +141,12 @@ describe('master tree tests', () => {
136141
});
137142
});
138143
describe('Display component props information', () => {
139-
const memoizedProps: {
140-
propVal: number;
141-
propFunc: Function;
142-
propObj: { [key: string]: any };
143-
} = {
144+
const memoizedProps = {
144145
propVal: 0,
145146
propFunc: jest.fn,
146147
propObj: { dummy: 'dummy' },
147148
};
148-
const props: {
149-
propVal: number;
150-
propFunc: 'function';
151-
propObj: string;
152-
} = {
149+
const props = {
153150
propVal: 0,
154151
propFunc: 'function',
155152
propObj: JSON.stringify({ dummy: 'dummy' }),
@@ -226,40 +223,218 @@ describe('master tree tests', () => {
226223
expect(tree).toEqual(treeRoot);
227224
});
228225

229-
xit('should display props information of multiple components', () => {
230-
// Trim the root to get position of mockFiber for append child and sibiling
231-
const mockFiberTreeTrimRoot = mockFiberTree.children[0];
232-
233-
// Add child(class) component with props:
234-
mockChildNode.memoizedProps = { ...memoizedProps, name: 'child' };
235-
(mockChildTree.componentData as ComponentData).props = { ...props, name: 'child' };
236-
(mockChildTree.componentData as ComponentData).index = 0;
237-
mockFiberTreeTrimRoot.children.push(mockChildTree);
226+
it('should display props information of multiple components', () => {
227+
// Construct Fiber Node (root => FiberNode => child1 => child2 & sibling1)
228+
mockChildNode.memoizedProps = memoizedProps;
229+
const child1 = deepCopy(mockChildNode);
230+
child1.memoizedProps.name = 'child1';
231+
const child2 = deepCopy(mockChildNode);
232+
child2.memoizedProps.name = 'child2';
233+
mockSiblingNode.memoizedProps = memoizedProps;
234+
const sibling1 = deepCopy(mockSiblingNode);
235+
sibling1.memoizedProps.name = 'sibling1';
236+
mockFiberNode.child = child1;
237+
child1.child = child2;
238+
child2.sibling = sibling1;
239+
const tree = createTree(mockFiberNode);
238240

239-
// Add sibiling(functional) component with props:
240-
mockSiblingNode.memoizedProps = { ...memoizedProps, name: 'sibling' };
241-
(mockSiblingTree.componentData as ComponentData).props = { ...props, name: 'sibling' };
242-
(mockSiblingTree.componentData as ComponentData).hooksIndex = [1];
243-
mockFiberTreeTrimRoot.children.push(mockSiblingTree);
241+
// Construct result tree (root => FiberTree => childTree1 => childTree2 & siblingTree1)
242+
(mockChildTree.componentData as ComponentData).props = props;
243+
const childTree1 = deepCopy(mockChildTree);
244+
childTree1.name = 'IncrementClass';
245+
(childTree1.componentData as ComponentData).props.name = 'child1';
246+
(childTree1.componentData as ComponentData).index = 0;
247+
const childTree2 = deepCopy(mockChildTree);
248+
childTree2.name = 'IncrementClass1';
249+
(childTree2.componentData as ComponentData).props.name = 'child2';
250+
(childTree2.componentData as ComponentData).index = 1;
251+
(mockSiblingTree.componentData as ComponentData).props = props;
252+
const siblingTree1 = deepCopy(mockSiblingTree);
253+
siblingTree1.name = 'IncrementFunc';
254+
(siblingTree1.componentData as ComponentData).hooksIndex = [2];
255+
(siblingTree1.componentData as ComponentData).props.name = 'sibling1';
244256

245-
// Modify mockFiberNode to have 2 children: mockChildNode & mockSibilngNode
246-
mockFiberNode.child = mockChildNode;
247-
mockFiberNode.child.sibling = mockSiblingNode;
257+
mockFiberTree.children[0].children = [childTree1];
258+
childTree1.children.push(childTree2, siblingTree1);
248259

249-
const tree = createTree(mockFiberNode);
260+
// Compare the two trees:
250261
expect(tree).toEqual(mockFiberTree);
251262
});
252263
});
253264
describe('Display component states information', () => {
265+
const stateNode = {
266+
state: {
267+
propVal: 0,
268+
propObj: { dummy: 'dummy' },
269+
},
270+
setState: function (cb: Function) {
271+
this.state = cb();
272+
}.bind(this),
273+
};
274+
const classState = stateNode.state;
275+
276+
const memoizedState = {
277+
memoizedState: { dummy: 'dummy' },
278+
next: null,
279+
queue: {
280+
dispatch: function (newState) {
281+
this.memoizedState = newState;
282+
}.bind(this),
283+
},
284+
};
285+
const memoizedState2 = {
286+
memoizedState: { dummy2: 'dummy2' },
287+
next: null,
288+
queue: {
289+
dispatch: function (newState) {
290+
this.memoizedState = newState;
291+
}.bind(this),
292+
},
293+
};
294+
// Note: the key count is the variable state name within the incrementFunction that is assigned to mockSiblingTree
295+
const functionalState = { count: memoizedState.memoizedState };
296+
const functionalState2 = { count1: memoizedState2.memoizedState };
297+
it('should display stateless if functional state empty', () => {
298+
// Construct Fiber Node (root => childNode)
299+
mockChildNode.stateNode = null;
300+
const tree = createTree(mockChildNode);
301+
302+
// Construct Result Tree (root => childTree)
303+
mockChildTree.state = 'stateless';
304+
(mockChildTree.componentData as ComponentData).state = null;
305+
(mockChildTree.componentData as ComponentData).index = null;
306+
treeRoot.children.push(mockChildTree);
307+
308+
// Compare the two trees:
309+
expect(tree).toEqual(treeRoot);
310+
});
311+
312+
it('should display class state information', () => {
313+
// Construct Fiber Node (root => childNode)
314+
mockChildNode.stateNode = stateNode;
315+
const tree = createTree(mockChildNode);
316+
317+
// Construct Result Tree (root => childTree)
318+
mockChildTree.state = classState;
319+
(mockChildTree.componentData as ComponentData).state = classState;
320+
treeRoot.children.push(mockChildTree);
321+
322+
// Compare the two trees:
323+
expect(tree).toEqual(treeRoot);
324+
});
325+
326+
it('should keep track of class state index', () => {
327+
// Construct Fiber Node (root => FiberNode => child1 => child 2 & 3)
328+
mockChildNode.stateNode = stateNode;
329+
const child1 = deepCopy(mockChildNode);
330+
const child2 = deepCopy(mockChildNode);
331+
const child3 = deepCopy(mockChildNode);
332+
mockFiberNode.child = child1;
333+
child1.child = child2;
334+
child2.sibling = child3;
335+
const tree = createTree(mockFiberNode);
336+
337+
// Construct result tree (root => FiberTree => childTree1 => childTree2 & childTree3)
338+
(mockChildTree.componentData as ComponentData).state = classState;
339+
mockChildTree.state = classState;
340+
const childTree1 = deepCopy(mockChildTree);
341+
childTree1.name = 'IncrementClass';
342+
(childTree1.componentData as ComponentData).index = 0;
343+
const childTree2 = deepCopy(mockChildTree);
344+
childTree2.name = 'IncrementClass1';
345+
(childTree2.componentData as ComponentData).index = 1;
346+
const childTree3 = deepCopy(mockChildTree);
347+
childTree3.name = 'IncrementClass2';
348+
(childTree3.componentData as ComponentData).index = 2;
349+
mockFiberTree.children[0].children = [childTree1];
350+
childTree1.children.push(childTree2, childTree3);
351+
352+
// Compare the two trees:
353+
expect(tree).toEqual(mockFiberTree);
354+
});
355+
356+
it('should display stateless if functional state empty', () => {
357+
// Construct Fiber Node (root => siblingNode)
358+
mockSiblingNode.memoizedState = null;
359+
const tree = createTree(mockSiblingNode);
360+
// Construct Result Tree (root => siblingTree)
361+
362+
mockSiblingTree.state = 'stateless';
363+
(mockSiblingTree.componentData as ComponentData).hooksState = null;
364+
(mockSiblingTree.componentData as ComponentData).hooksIndex = null;
365+
treeRoot.children.push(mockSiblingTree);
366+
367+
// Compare the two trees:
368+
expect(tree).toEqual(treeRoot);
369+
});
370+
254371
it('should display functional state information', () => {
255-
mockChildNode.stateNode = {
256-
257-
}
372+
// Construct Fiber Node (root => siblingNode)
373+
mockSiblingNode.memoizedState = memoizedState;
374+
const tree = createTree(mockSiblingNode);
375+
376+
// Construct Result Tree (root => siblingTree)
377+
378+
mockSiblingTree.state = functionalState;
379+
(mockSiblingTree.componentData as ComponentData).hooksState = functionalState;
380+
treeRoot.children.push(mockSiblingTree);
381+
382+
// Compare the two trees:
383+
expect(tree).toEqual(treeRoot);
384+
});
385+
386+
it('should keep track of functional state index', () => {
387+
// Construct Fiber Node (root => FiberNode => sibling1 => sibling 2 & 3)
388+
// sibling 3 will have 2 states
389+
mockSiblingNode.memoizedState = memoizedState;
390+
const sibling1 = deepCopy(mockSiblingNode);
391+
const sibling2 = deepCopy(mockSiblingNode);
392+
const sibling3 = deepCopy(mockSiblingNode);
393+
sibling3.memoizedState.next = memoizedState2;
394+
sibling3.elementType = IncrementFuncMultiStates;
395+
mockFiberNode.child = sibling1;
396+
sibling1.child = sibling2;
397+
sibling2.sibling = sibling3;
398+
const tree = createTree(mockFiberNode);
399+
400+
// Construct result tree (root => FiberTree => siblingTree1 => siblingTree2 & siblingTree3)
401+
// sibling 3 will have 2 states
402+
mockSiblingTree.state = functionalState;
403+
(mockSiblingTree.componentData as ComponentData).hooksState = functionalState;
404+
const siblingTree1 = deepCopy(mockSiblingTree);
405+
siblingTree1.name = 'IncrementFunc';
406+
(siblingTree1.componentData as ComponentData).hooksIndex = [0];
407+
const siblingTree2 = deepCopy(mockSiblingTree);
408+
siblingTree2.name = 'IncrementFunc1';
409+
(siblingTree2.componentData as ComponentData).hooksIndex = [1];
410+
const siblingTree3 = deepCopy(mockSiblingTree);
411+
siblingTree3.name = 'IncrementFuncMultiStates';
412+
siblingTree3.state = { ...functionalState, ...functionalState2 };
413+
Object.assign((siblingTree3.componentData as ComponentData).hooksState!, functionalState2);
414+
(siblingTree3.componentData as ComponentData).hooksIndex = [2, 3];
415+
mockFiberTree.children[0].children = [siblingTree1];
416+
siblingTree1.children.push(siblingTree2, siblingTree3);
417+
418+
// Compare the two trees:
419+
expect(tree).toEqual(mockFiberTree);
258420
});
259-
xit('should display class state information', () => {});
260421
});
261-
xdescribe('Replace fromLinkFiber class value', () => {
262-
it('NEED UNDERSTANDING OF WHY FROMLINKFIBER IS NEEDED TO MAKE TESTING', () => {});
422+
423+
describe('Replace fromLinkFiber class value', () => {
424+
xit('NEED UNDERSTANDING THE PURPOSE OF FROMLINKFIBER FOR FRONTEND, testing below is just to ensure functionality is working', () => {});
425+
describe('should update linkFiber information as applicable', () => {
426+
it('should add LinkFiber if there is no classlist', () => {
427+
// Construct Fiber Node (root => childNode)
428+
mockChildNode.stateNode.setAttribute = jest.fn;
429+
mockChildNode.stateNode.classList = [];
430+
const tree = createTree(mockChildNode);
431+
432+
// Construct Result Tree (root => childTree)
433+
treeRoot.children.push(mockChildTree);
434+
// Compare the two trees:
435+
expect(tree).toEqual(treeRoot);
436+
});
437+
});
263438
});
264439
});
265440

src/backend/controllers/createTree/createTree.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -234,11 +234,12 @@ export default function createTree(currentFiberNode: Fiber): Tree {
234234
// TODO: Refactor this, this is currently being used for Tree & Diff tabs
235235
newState = componentData.hooksState;
236236
} catch (err) {
237-
console.log({
238-
Message: 'Error in createTree during obtaining state from functionalComponent',
239-
componentName,
240-
err,
241-
});
237+
// COMMENT OUT TO AVOID PRINTTING ON THE CONSOLE OF USER - KEEP IT FOR DEBUGGING PURPOSE
238+
// console.log({
239+
// Message: 'Error in createTree during obtaining state from functionalComponent',
240+
// componentName,
241+
// err,
242+
// });
242243
}
243244
}
244245
}

src/backend/controllers/createTree/statePropExtractors.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,16 @@ export function filterAndFormatData(
4545
reactimeData[key] = reactDevData[key];
4646
}
4747
} catch (err) {
48-
console.log('EROOR: linkFiber', { reactDevData, key });
49-
// throw Error(`Error caught at converDataToString: ${err}`);
48+
// COMMENT OUT TO AVOID PRINTTING ON THE CONSOLE OF USER - KEEP IT FOR DEBUGGING PURPOSE
49+
// console.log({
50+
// Message: 'Error in createTree during obtaining props information',
51+
// potentialRootCause: 'circular component/failed during JSON stringify',
52+
// reactDevData,
53+
// key,
54+
// err,
55+
// });
56+
// we will skip any props that cause an error
57+
continue;
5058
}
5159
}
5260
return reactimeData;
@@ -170,12 +178,19 @@ export function getHooksNames(elementType: string): { hookName: string; varName:
170178
declarations[0]?.init?.arguments[0]?.callee?.expressions; //work for jest test
171179
let reactHook: string;
172180
reactHook = expression[1].property?.name;
173-
174181
if (reactHook === 'useState') {
175182
// Obtain the variable being set:
176-
let varName: string = declarations[1]?.id?.name;
183+
let varName: string =
184+
declarations[1]?.id?.name || // work react application
185+
(Array.isArray(declarations[0]?.id?.elements)
186+
? declarations[0]?.id?.elements[0]?.name
187+
: undefined); //work for nextJS application
177188
// Obtain the setState method:
178-
let hookName: string = declarations[2]?.id?.name;
189+
let hookName: string =
190+
declarations[2]?.id?.name || // work react application
191+
(Array.isArray(declarations[0]?.id?.elements)
192+
? declarations[0]?.id?.elements[0]?.name
193+
: undefined); //work for nextJS
179194
// Push reactHook & varName to statements array
180195
statements.push({ hookName, varName });
181196
}

src/backend/types/backendTypes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export interface ComponentData {
6464
treeBaseDuration?: number;
6565
props: { [key: string]: any };
6666
context: {};
67-
state: {} | null;
67+
state: { [key: string]: any } | null;
6868
hooksState: {} | null;
6969
hooksIndex: number[] | null;
7070
index: number | null;

0 commit comments

Comments
 (0)