Skip to content

Commit 98fbbbd

Browse files
committed
Finalized Undo, Redo, and Root Component unit tests.
> > Co-authored-by: slhoehn <[email protected]>
1 parent 8c12033 commit 98fbbbd

File tree

4 files changed

+86
-63
lines changed

4 files changed

+86
-63
lines changed

__tests__/componentReducer.test.ts

Lines changed: 56 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,27 @@ describe('Testing componentReducer functionality', () => {
2626
});
2727
});
2828

29+
// TEST 'ADD COMPONENT' with new root
30+
describe('ADD COMPONENT reducer', () => {
31+
it('should add new reuseable component to state as the new root', () => {
32+
const action: Action = {
33+
type: 'ADD COMPONENT',
34+
payload: {
35+
componentName: 'TestRootChange',
36+
id: 3,
37+
root: true,
38+
},
39+
};
40+
state = reducer(state, action);
41+
42+
// expect state.components array to have length 3
43+
const length = state.components.length;
44+
expect(length).toEqual(3);
45+
// expect new root to match id of component id of TestRootChange
46+
expect(state.rootComponents[state.rootComponents.length - 1]).toEqual(action.payload.id);
47+
});
48+
});
49+
2950
// TEST 'ADD CHILD'
3051
describe('ADD CHILD reducer', () => {
3152
it('should add child component and separator to top-level component', () => {
@@ -159,43 +180,61 @@ describe('Testing componentReducer functionality', () => {
159180
expect(state.projectType).toEqual(action.payload.projectType);
160181
});
161182
});
183+
162184

163185
// TEST 'UNDO'
164186
describe('UNDO reducer', () => {
165-
// problem: past array up to this point is empty because snapshot function is responsible for populating it- not invoked in testing
166-
// undo is not deleting the children because it relies on Canvas.tsx's function Canvas and snapShotFunc inside it
167-
it('should remove the last 2 elements in the children array', () => {
187+
it('should remove the last element from the past array and push it to the future array', () => {
168188
const focusIndex = state.canvasFocus.componentId - 1;
169-
const actionHTML: Action = {
189+
state.components[focusIndex].past = [];
190+
191+
// snapShotFunc taken from src/components/main/canvas.tsx to test undo functionality
192+
const snapShotFuncCopy = () => {
193+
const deepCopiedState = JSON.parse(JSON.stringify(state));
194+
// pushes the last user action on the canvas into the past array of Component
195+
state.components[focusIndex].past.push(deepCopiedState.components[focusIndex].children);
196+
}
197+
198+
const actionHTML2: Action = {
170199
type: 'ADD CHILD',
171200
payload: {
172201
type: 'HTML Element',
173-
typeId: 9,
202+
typeId: 4,
174203
childId: null,
175204
}
176205
}
177-
console.log('focusIndex before UNDO', focusIndex);
178-
console.log('before add child', state.components[focusIndex]);
179-
state = reducer(state, actionHTML);
180-
console.log('after add kid', state.components[focusIndex]);
206+
state = reducer(state, actionHTML2);
207+
snapShotFuncCopy();
208+
181209
const actionUndo: Action = {
182210
type: 'UNDO',
183211
payload: {},
184212
};
185-
186213
state = reducer(state, actionUndo);
187-
console.log('focusIndex after UNDO', focusIndex);
188214

189-
const undoParent = state.components.find(comp => comp.id === state.canvasFocus.componentId);
190-
191-
expect(undoParent.children.length).toEqual(0);
192-
193-
console.log('after undo', state.components[focusIndex]);
215+
expect(state.components[focusIndex].past.length).toEqual(0);
216+
expect(state.components[focusIndex].future.length).toEqual(1);
217+
})
218+
});
194219

195-
//expect(state.components[focusIndex].children.length).toEqual(0);
220+
221+
// TEST 'REDO'
222+
describe('REDO reducer', () => {
223+
it('should remove the last element from the future array and push it to the past array', () => {
224+
const focusIndex = state.canvasFocus.componentId - 1;
225+
226+
const actionRedo: Action = {
227+
type: 'REDO',
228+
payload: {},
229+
};
230+
state = reducer(state, actionRedo);
231+
232+
expect(state.components[focusIndex].future.length).toEqual(0);
233+
expect(state.components[focusIndex].past.length).toEqual(1);
196234
})
197235
});
198236

237+
199238
// TEST 'RESET STATE'
200239
describe('RESET STATE reducer', () => {
201240
it('should reset project to initial state', () => {
@@ -212,19 +251,5 @@ describe('Testing componentReducer functionality', () => {
212251
expect(state.components[0].children.length).toEqual(0);
213252
});
214253
});
215-
216254
});
217255

218-
// state.components[focusIndex].past.push({
219-
// type: "HTML Element", typeId: 1000, name: "separator", childId: 1001, style: { border: "none" }, children: []
220-
// },
221-
// {
222-
// type: "HTML Element", typeId: 4, name: "button", childId: 2, style: { border: "none" }, children: []
223-
// });
224-
// state.components[focusIndex].children.push({
225-
// type: "HTML Element", typeId: 1000, name: "separator", childId: 1001, style: { border: "none" }, children: []
226-
// },
227-
// {
228-
// type: "HTML Element", typeId: 4, name: "button", childId: 2, style: { border: "none" }, children: []
229-
// }
230-
// );

app/src/components/main/Canvas.tsx

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,31 +10,30 @@ import renderChildren from '../../helperFunctions/renderChildren';
1010

1111
function Canvas() {
1212
const [state, dispatch] = useContext(StateContext);
13-
console.log('state', state);
1413
// find the current component to render on the canvas
1514
const currentComponent: Component = state.components.find(
1615
(elem: Component) => elem.id === state.canvasFocus.componentId
1716
);
18-
19-
// changes focus of the canvas to a new component / child
20-
const changeFocus = (componentId?: number, childId?: number | null, e?: string) => {
21-
dispatch({ type: 'CHANGE FOCUS', payload: { componentId, childId, e, /*state*/ } });
22-
};
23-
// onClickHandler is responsible for changing the focused component and child component
24-
function onClickHandler(event) {
25-
event.stopPropagation();
26-
// note: a null value for the child id means that we are focusing on the top-level component rather than any child
27-
changeFocus(state.canvasFocus.componentId, null);
28-
};
29-
30-
// stores a snapshot of state into the past array for UNDO
31-
const snapShotFunc = () => {
32-
// make a deep clone of state
33-
const deepCopiedState = JSON.parse(JSON.stringify(state));
34-
const focusIndex = state.canvasFocus.componentId - 1;
35-
//pushes the last user action on the canvas into the past array of Component
36-
state.components[focusIndex].past.push(deepCopiedState.components[focusIndex].children);
37-
};
17+
18+
// changes focus of the canvas to a new component / child
19+
const changeFocus = (componentId?: number, childId?: number | null, e?: string) => {
20+
dispatch({ type: 'CHANGE FOCUS', payload: { componentId, childId, e, /*state*/ } });
21+
};
22+
// onClickHandler is responsible for changing the focused component and child component
23+
function onClickHandler(event) {
24+
event.stopPropagation();
25+
// note: a null value for the child id means that we are focusing on the top-level component rather than any child
26+
changeFocus(state.canvasFocus.componentId, null);
27+
};
28+
29+
// stores a snapshot of state into the past array for UNDO
30+
const snapShotFunc = () => {
31+
// make a deep clone of state
32+
const deepCopiedState = JSON.parse(JSON.stringify(state));
33+
const focusIndex = state.canvasFocus.componentId - 1;
34+
//pushes the last user action on the canvas into the past array of Component
35+
state.components[focusIndex].past.push(deepCopiedState.components[focusIndex].children);
36+
};
3837

3938
// This hook will allow the user to drag items from the left panel on to the canvas
4039
const [{ isOver }, drop] = useDrop({
@@ -96,6 +95,6 @@ function Canvas() {
9695
</div>
9796
);
9897
}
99-
// export { snapStateArr };
98+
10099
export default Canvas;
101100

app/src/reducers/componentReducer.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -621,14 +621,14 @@ const reducer = (state: State, action: Action) => {
621621
}
622622
case 'UNDO': {
623623
const focusIndex = state.canvasFocus.componentId - 1;
624-
//if the past array is empty, return state
624+
// if the past array is empty, return state
625625
if(state.components[focusIndex].past.length === 0) return {...state};
626-
//the children array of the focused component will equal the last element of the past array
627-
state.components[focusIndex].children = state.components[focusIndex].past[state.components[focusIndex].past.length - 1]
628-
//the last element of the past array gets pushed into the future
629-
//the last element of the past array gets popped out
630-
state.components[focusIndex].future.push(state.components[focusIndex].past.pop())
631-
626+
// the children array of the focused component will equal the last element of the past array
627+
state.components[focusIndex].children = state.components[focusIndex].past[state.components[focusIndex].past.length - 1];
628+
// the last element of the past array gets popped off
629+
const poppedEl = state.components[focusIndex].past.pop();
630+
// the last element of the past array gets popped off and pushed into the future array
631+
state.components[focusIndex].future.push(poppedEl);
632632

633633
//generate code for the Code Preview
634634
state.components.forEach((el, i) => {
@@ -651,10 +651,9 @@ const reducer = (state: State, action: Action) => {
651651
//the children array of the focused component will equal the last element of the future array
652652
state.components[focusIndex].children = state.components[focusIndex].future[state.components[focusIndex].future.length - 1]
653653
//the last element of the future array gets pushed into the past
654-
//the last element of the future array gets popped out
654+
//the last element of the future array gets popped out
655655
state.components[focusIndex].past.push(state.components[focusIndex].future.pop())
656656

657-
658657
// generate code for the Code Preview
659658
state.components.forEach((el, i) => {
660659
el.code = generateCode(

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@
207207
"sass-loader": "^7.0.3",
208208
"style-loader": "^0.20.3",
209209
"supertest": "^4.0.2",
210-
"ts-jest": "^25.3.0",
210+
"ts-jest": "^25.5.1",
211211
"ts-node": "^8.10.2",
212212
"typescript": "^3.9.6",
213213
"url-loader": "^4.1.0",

0 commit comments

Comments
 (0)