Skip to content

Commit 4dad1fc

Browse files
committed
Complete testing for tree
1 parent decab68 commit 4dad1fc

File tree

3 files changed

+74
-107
lines changed

3 files changed

+74
-107
lines changed

src/backend/__tests__/masterTree.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import componentActionsRecord from '../models/masterState';
44
import createTree from '../controllers/createTree/createTree';
55
import Tree from '../models/tree';
66
import React, { useState } from 'react';
7-
import { serializeState, scrubUnserializableMembers } from '../models/tree';
7+
import { serializeState } from '../models/tree';
88
import {
99
allowedComponentTypes,
1010
nextJSDefaultComponent,

src/backend/__tests__/tree.test.ts

Lines changed: 63 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,125 +1,102 @@
11
import Tree from '../models/tree';
2-
import { serializeState, scrubUnserializableMembers } from '../models/tree';
3-
4-
xdescribe('Serialize state unit test', () => {
5-
const dummyState = {
6-
counter: 1,
7-
playerOne: 'X',
8-
board: [
9-
['', 'O', 'X'],
10-
['', 'O', 'X'],
11-
['O', 'X', ''],
12-
],
13-
};
14-
15-
const circularState: { [key: string]: any } = {};
16-
circularState.circ = circularState;
17-
18-
const serializedState = serializeState(dummyState);
19-
const serializedCircularState = serializeState(circularState);
2+
import { serializeState } from '../models/tree';
203

4+
describe('Serialize state unit test', () => {
215
it('should create a deep copy of state', () => {
6+
const dummyState = {
7+
counter: 1,
8+
playerOne: 'X',
9+
board: [
10+
['', 'O', 'X'],
11+
['', 'O', 'X'],
12+
['O', 'X', ''],
13+
],
14+
};
15+
const serializedState = serializeState(dummyState);
2216
expect(dummyState).toEqual(serializedState);
2317
expect(dummyState).not.toBe(serializedState);
2418
});
2519

2620
it('should detect circular state', () => {
21+
const circularState: { [key: string]: any } = {};
22+
circularState.circ = circularState;
23+
const serializedCircularState = serializeState(circularState);
2724
expect(serializedCircularState).toEqual('circularState');
2825
});
2926
});
3027

31-
xdescribe('Scrub unserialized members unit test', () => {
32-
const dummyState = {
33-
counter: 1,
34-
playerOne: 'X',
35-
board: [
36-
['', 'O', 'X'],
37-
['', 'O', 'X'],
38-
['O', 'X', ''],
39-
],
40-
increment: function () {
41-
this.counter++;
42-
},
43-
};
44-
const newTree = new Tree(dummyState);
45-
const scrubbedTree = scrubUnserializableMembers(newTree);
46-
// make sure return type is tree
47-
it('should be instance of tree', () => {
48-
expect(newTree).toBeInstanceOf(Tree);
49-
});
50-
// make sure function is scrubbed
51-
});
52-
53-
xdescribe('Tree unit test', () => {
54-
const newTree = new Tree({});
55-
describe('Constructor', () => {
28+
describe('Tree unit test', () => {
29+
30+
describe('Constructing a default tree', () => {
31+
const newTree: Tree = new Tree({});
5632
it('should be able to create a newTree', () => {
33+
expect(newTree).toBeInstanceOf(Tree);
5734
expect(newTree.state).toEqual({});
5835
});
5936

60-
it('should have 7 properties', () => {
37+
it('should have 6 properties', () => {
6138
expect(newTree).toHaveProperty('state');
6239
expect(newTree).toHaveProperty('name');
6340
expect(newTree).toHaveProperty('componentData');
6441
expect(newTree).toHaveProperty('children');
65-
expect(newTree).toHaveProperty('parent');
6642
expect(newTree).toHaveProperty('isExpanded');
6743
expect(newTree).toHaveProperty('rtid');
6844
});
6945

70-
it('has name default value as stateless', () => {
46+
it('should have default name, componentData, isExpanded and rtid', () => {
7147
expect(newTree.name).toBe('nameless');
72-
});
73-
});
74-
75-
xdescribe('Adding children', () => {
76-
const returnChild: Tree = newTree.addChild('stateful', 'child', {}, null);
77-
78-
it("should have the child be in the children's array property", () => {
79-
// check if returnChild is in the children array property of tree that invoked addChild
80-
expect(newTree.children).toContain(returnChild);
48+
expect(newTree.componentData).toEqual({});
49+
expect(newTree.isExpanded).toBe(true);
50+
expect(newTree.rtid).toBe(null);
8151
});
8252

83-
it("should have the object that invoked it be it's parent", () => {
84-
// checking parent to be the tree that invoked addChild
85-
expect(returnChild.parent).toEqual(newTree);
53+
it('should have no children', () => {
54+
expect(newTree.children).toHaveLength(0);
8655
});
56+
});
8757

88-
it('parent now contains an array of children and each children is a valid tree', () => {
89-
expect(newTree.children[0]).toHaveProperty('state');
90-
expect(newTree.children[0]).toHaveProperty('name');
91-
expect(newTree.children[0]).toHaveProperty('componentData');
58+
describe('Constructing a tree root', () => {
59+
const root: Tree = new Tree('root', 'root');
60+
it("should have name as 'root' and state as 'root'", () => {
61+
expect(root).toBeInstanceOf(Tree);
62+
expect(root.state).toBe('root');
63+
expect(root.name).toBe('root');
64+
expect(root.componentData).toEqual({});
65+
expect(root.isExpanded).toBe(true);
66+
expect(root.rtid).toBe(null);
67+
expect(root.children).toHaveLength(0);
9268
});
9369
});
9470

95-
xdescribe('Adding sibling', () => {
96-
const newTreeCopy = new Tree({});
97-
const returnChild = newTreeCopy.addChild('stateful', 'child', {}, null);
98-
const returnSibling = returnChild.addSibling('stateful', 'child', {}, null);
99-
100-
it('the tree now has 2 children', () => {
101-
expect(newTreeCopy.children.length).toBe(2);
71+
describe('Adding children', () => {
72+
const newTree: Tree = new Tree('root', 'root');
73+
const child: Tree = newTree.addChild('stateful', 'child', {}, null);
74+
75+
it('should return a new tree child', () => {
76+
expect(child).toBeInstanceOf(Tree);
77+
expect(child).toBeInstanceOf(Tree);
78+
expect(child.state).toBe('stateful');
79+
expect(child.name).toBe('child');
80+
expect(child.componentData).toEqual({});
81+
expect(child.isExpanded).toBe(true);
82+
expect(child.rtid).toBe(null);
83+
expect(child.children).toHaveLength(0);
10284
});
10385

104-
it('both of the children has the parent as this tree', () => {
105-
expect(returnChild.parent).toEqual(newTreeCopy);
106-
expect(returnSibling.parent).toEqual(newTreeCopy);
86+
it("should have the child be in the children's array property", () => {
87+
expect(newTree.children).toHaveLength(1);
88+
expect(newTree.children).toContain(child);
89+
expect(newTree.children[0]).toBe(child);
10790
});
108-
});
109-
110-
// TO DO- add serializing state tests
111-
xdescribe('Serializing state unit test', () => {});
112-
// review this test
113-
// returnSibling not used?
114-
// Check Test
11591

116-
xdescribe('Copy & clean tree', () => {
117-
const newTreeLastCopy = new Tree({});
118-
const returnChild = newTreeLastCopy.addChild('stateful', 'child', {}, null);
119-
returnChild.addSibling('stateful', 'child', {}, null);
120-
const copy = newTreeLastCopy.cleanTreeCopy();
121-
it('its copy has 2 children', () => {
122-
expect(copy.children.length).toEqual(2);
92+
it('should have unique name', () => {
93+
const nextChild1: Tree = child.addChild('stateful', 'child', {}, null);
94+
const nextChild2: Tree = child.addChild('stateful', 'child', {}, null);
95+
expect(child.children).toHaveLength(2);
96+
expect(child.children[0]).toBe(nextChild1);
97+
expect(child.children[1]).toBe(nextChild2);
98+
expect(nextChild1.name).toBe('child1');
99+
expect(nextChild2.name).toBe('child2');
123100
});
124101
});
125102
});

src/backend/models/tree.ts

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,14 @@
1-
/* eslint-disable no-plusplus */
2-
/* eslint-disable max-len */
3-
/* eslint-disable @typescript-eslint/ban-types */
4-
/* eslint-disable no-multiple-empty-lines */
5-
/* eslint-disable max-classes-per-file */
6-
/* eslint-disable no-console */
7-
/* eslint-disable no-param-reassign */
81
import { Route } from './routes';
92
import { ComponentData } from '../types/backendTypes';
103

114
// ComponentNames is used to store a mapping between a component's unique identifier and its name. This mapping is used to reconstruct the component instances during deserialization.
125
let componentNames = {};
136

14-
// Functions dont serialize properly so we need to scrub for that
15-
export function scrubUnserializableMembers(tree: Tree): Tree {
16-
Object.entries(tree.state).forEach((keyValuePair) => {
17-
if (typeof keyValuePair[1] === 'function') tree.state[keyValuePair[0]] = 'function';
18-
});
19-
return tree;
20-
}
21-
227
// Making a deep clone of state becuase we want to make a copy
238
/**
249
* @function serializeState - In the context of React, state is often used to store data that determines the behavior and appearance of a component. By serializing the state, we can preserve the component's data across page refreshes, server-side rendering, and other transitions. Additionally, by serializing the state and passing it to a child component, we can create a deep clone of the state, which allows the child component to manipulate the state without affecting the original component. This is useful in situations where we want to keep the state of the parent component immutable, but still allow child components to modify a copy of the state.
2510
* @param state - Object that contains the current state of the application or system that needs to be serialized.
26-
* @returns
11+
* @returns - Depclone of the passed in state. If there is any circulate state, return 'circularState'
2712
*/
2813
export function serializeState(state) {
2914
try {
@@ -53,7 +38,7 @@ class Tree {
5338

5439
name: string;
5540

56-
componentData: ComponentData;
41+
componentData: ComponentData | {};
5742

5843
children: Tree[];
5944

@@ -74,11 +59,11 @@ class Tree {
7459
constructor(
7560
state: string | {},
7661
name = 'nameless',
77-
componentData: {} = {},
62+
componentData: ComponentData | {} = {},
7863
rtid: string | null = null,
7964
) {
8065
this.children = [];
81-
this.componentData = JSON.parse(JSON.stringify(componentData));
66+
this.componentData = componentData;
8267
this.state = state === 'root' ? 'root' : serializeState(state);
8368
this.name = name;
8469
this.rtid = rtid;
@@ -118,7 +103,12 @@ class Tree {
118103
* @param rtid - ??
119104
* @returns - return new tree instance that is child
120105
*/
121-
addChild(state: string | {}, name: string, componentData: {}, rtid: any): Tree {
106+
addChild(
107+
state: Tree['state'],
108+
name: Tree['name'],
109+
componentData: Tree['componentData'],
110+
rtid: Tree['rtid'],
111+
): Tree {
122112
// Get unique name by invoking checkForDuplicates method
123113
const uniqueName = this.checkForDuplicates(name);
124114
// Instantiates new child Tree with state, uniqueName, componentData and rtid

0 commit comments

Comments
 (0)