Skip to content

Commit 0ca1b0c

Browse files
authored
Merge pull request #10 from elenaconn/UndoRedoTests
Jest Tests for Undo/Redo/Root Component
2 parents a3b29f9 + d8208ae commit 0ca1b0c

File tree

8 files changed

+117
-100
lines changed

8 files changed

+117
-100
lines changed

__tests__/componentReducer.test.ts

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import reducer from '../app/src/reducers/componentReducer';
2-
import { State, Action } from '../app/src/interfaces/InterfacesNew';
2+
import { State, Action } from '../app/src/interfaces/Interfaces';
33

44
import initialState from '../app/src/context/initialState';
5+
import { iterate } from 'localforage';
56

67
describe('Testing componentReducer functionality', () => {
78
let state: State = initialState;
@@ -25,6 +26,27 @@ describe('Testing componentReducer functionality', () => {
2526
});
2627
});
2728

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 (rootComponents is an array of component ID numbers)
46+
expect(state.rootComponents[state.rootComponents.length - 1]).toEqual(action.payload.id);
47+
});
48+
});
49+
2850
// TEST 'ADD CHILD'
2951
describe('ADD CHILD reducer', () => {
3052
it('should add child component and separator to top-level component', () => {
@@ -158,6 +180,62 @@ describe('Testing componentReducer functionality', () => {
158180
expect(state.projectType).toEqual(action.payload.projectType);
159181
});
160182
});
183+
184+
185+
// TEST 'UNDO'
186+
describe('UNDO reducer', () => {
187+
it('should remove the last element from the past array and push it to the future array', () => {
188+
const focusIndex = state.canvasFocus.componentId - 1;
189+
state.components[focusIndex].past = [];
190+
191+
// snapShotFunc taken from src/components/main/canvas.tsx to test undo functionality
192+
// snapShotFunc takes a snapshot of state to be used in UNDO/REDO functionality
193+
const snapShotFuncCopy = () => {
194+
const deepCopiedState = JSON.parse(JSON.stringify(state));
195+
// pushes the last user action on the canvas into the past array of Component
196+
state.components[focusIndex].past.push(deepCopiedState.components[focusIndex].children);
197+
}
198+
199+
const actionHTML2: Action = {
200+
type: 'ADD CHILD',
201+
payload: {
202+
type: 'HTML Element',
203+
typeId: 4,
204+
childId: null,
205+
}
206+
}
207+
state = reducer(state, actionHTML2);
208+
// invoking snapShotFunc is necessary to push actions into the past array, referenced in the UNDO functionality to define children
209+
snapShotFuncCopy();
210+
211+
const actionUndo: Action = {
212+
type: 'UNDO',
213+
payload: {},
214+
};
215+
state = reducer(state, actionUndo);
216+
217+
expect(state.components[focusIndex].past.length).toEqual(0);
218+
expect(state.components[focusIndex].future.length).toEqual(1);
219+
})
220+
});
221+
222+
223+
// TEST 'REDO'
224+
describe('REDO reducer', () => {
225+
it('should remove the last element from the future array and push it to the past array', () => {
226+
const focusIndex = state.canvasFocus.componentId - 1;
227+
228+
const actionRedo: Action = {
229+
type: 'REDO',
230+
payload: {},
231+
};
232+
state = reducer(state, actionRedo);
233+
234+
expect(state.components[focusIndex].future.length).toEqual(0);
235+
expect(state.components[focusIndex].past.length).toEqual(1);
236+
})
237+
});
238+
161239

162240
// TEST 'RESET STATE'
163241
describe('RESET STATE reducer', () => {
@@ -176,3 +254,4 @@ describe('Testing componentReducer functionality', () => {
176254
});
177255
});
178256
});
257+

app/src/Dashboard/FormsContainer.tsx

Lines changed: 0 additions & 38 deletions
This file was deleted.

app/src/components/login/SignIn.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ const SignIn: React.FC<LoginInt & RouteComponentProps> = props => {
7575
window.api.setCookie();
7676
window.api.getCookie(cookie => {
7777
// if a cookie exists, set localstorage item with cookie data, clear interval, go back to '/' route to load app
78-
console.log(cookie);
7978
if (cookie[0]) {
8079
window.localStorage.setItem('ssid', cookie[0].value);
8180
clearInterval(githubCookie);

app/src/components/main/Canvas.tsx

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,31 +14,25 @@ function Canvas() {
1414
const currentComponent: Component = state.components.find(
1515
(elem: Component) => elem.id === state.canvasFocus.componentId
1616
);
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-
37-
/** OLD CODE */
38-
// state.past.push(deepCopiedState.components[focusIndex].children);
39-
// state.past.push(deepCopiedState.components[state.canvasFocus.componentId].children);
40-
// state.arrowMovements.push(deepCopiedState.canvasFocus)
41-
// console.log('state in snapshotFunc', state)
17+
18+
// changes focus of the canvas to a new component / child
19+
const changeFocus = (componentId?: number, childId?: number | null) => {
20+
dispatch({ type: 'CHANGE FOCUS', payload: { componentId, childId } });
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);
4236
};
4337

4438
// This hook will allow the user to drag items from the left panel on to the canvas
@@ -101,6 +95,5 @@ function Canvas() {
10195
</div>
10296
);
10397
}
104-
// export { snapStateArr };
105-
export default Canvas;
10698

99+
export default Canvas;

app/src/components/main/DirectChildHTML.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ function DirectChildHTML({
4848
function onClickHandler(event) {
4949
event.stopPropagation();
5050
changeFocus(state.canvasFocus.componentId, childId);
51-
console.log('state in directChild', state)
5251
}
5352

5453
// combine all styles so that higher priority style specifications overrule lower priority style specifications

app/src/reducers/componentReducer.ts

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -215,10 +215,11 @@ const reducer = (state: State, action: Action) => {
215215
};
216216
components.push(newComponent);
217217

218+
// functionality if the new component will become the root component
218219
const rootComponents = [...state.rootComponents];
219220
if (action.payload.root) rootComponents.push(newComponent.id);
220221

221-
// update the focus to the new component
222+
// updates the focus to the new component, which redirects to the new blank canvas of said new component
222223
const canvasFocus = {
223224
...state.canvasFocus,
224225
componentId: newComponent.id,
@@ -344,7 +345,7 @@ const reducer = (state: State, action: Action) => {
344345
case 'CHANGE POSITION': {
345346
const { currentChildId, newParentChildId } = action.payload;
346347

347-
// if the currentChild Id is the same as the newParentId (i.e. a component is trying to drop itself into itself), don't update sate
348+
// if the currentChild Id is the same as the newParentId (i.e. a component is trying to drop itself into itself), don't update state
348349
if (currentChildId === newParentChildId) return state;
349350

350351
// find the current component in focus
@@ -618,24 +619,17 @@ const reducer = (state: State, action: Action) => {
618619
HTMLTypes
619620
};
620621
}
622+
621623
case 'UNDO': {
622624
const focusIndex = state.canvasFocus.componentId - 1;
623-
//if the past array is empty, return state
625+
// if the past array is empty, return state
624626
if(state.components[focusIndex].past.length === 0) return {...state};
625-
//the children array of the focused component will equal the last element of the past array
626-
state.components[focusIndex].children = state.components[focusIndex].past[state.components[focusIndex].past.length - 1]
627-
//the last element of the past array gets pushed into the future
628-
//the last element of the past array gets popped out
629-
state.components[focusIndex].future.push(state.components[focusIndex].past.pop())
630-
631-
632-
/**OLD CODE */
633-
// //if past is empty, return state
634-
// if (state.past.length === 0) return {...state};
635-
// //the children array of state.components[0] will equal the last element of the past array
636-
// state.components[focusIndex].children = state.past[state.past.length-1];
637-
// //the last element of past array gets pushed into future;
638-
// state.future.push(state.past.pop());
627+
// the children array of the focused component will equal the last element of the past array
628+
state.components[focusIndex].children = state.components[focusIndex].past[state.components[focusIndex].past.length - 1];
629+
// the last element of the past array gets popped off
630+
const poppedEl = state.components[focusIndex].past.pop();
631+
// the last element of the past array gets popped off and pushed into the future array
632+
state.components[focusIndex].future.push(poppedEl);
639633

640634
//generate code for the Code Preview
641635
state.components.forEach((el, i) => {
@@ -651,26 +645,18 @@ const reducer = (state: State, action: Action) => {
651645
...state
652646
};
653647
}
648+
654649
case 'REDO': {
655650
const focusIndex = state.canvasFocus.componentId - 1;
656651
//if future array is empty, return state
657652
if(state.components[focusIndex].future.length === 0) return {...state};
658653
//the children array of the focused component will equal the last element of the future array
659654
state.components[focusIndex].children = state.components[focusIndex].future[state.components[focusIndex].future.length - 1]
660655
//the last element of the future array gets pushed into the past
661-
//the last element of the future array gets popped out
656+
//the last element of the future array gets popped out
662657
state.components[focusIndex].past.push(state.components[focusIndex].future.pop())
663658

664-
665-
666-
//nothing left to redo
667-
// if(state.future.length === 0) return {...state};
668-
// //the children array of state.components[0] will equal the last element of the future array
669-
// state.components[focusIndex].children = state.future[state.future.length - 1];
670-
// //the last element of the future array gets pushed into the past array and the last element of the future array gets popped off
671-
// state.past.push(state.future.pop());
672-
673-
// //generate code for the Code Preview
659+
// generate code for the Code Preview
674660
state.components.forEach((el, i) => {
675661
el.code = generateCode(
676662
state.components,

app/src/utils/createApplication.util.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,7 @@ export const createPackage = (path, appName) => {
136136
"express": "^4.17.1",
137137
"react": "^16.13.1",
138138
"react-dom": "^16.13.1",
139-
"webpack": "^4.29.6",
140-
"react-native": "^0.62.1"
139+
"webpack": "^4.29.6"
141140
},
142141
"devDependencies": {
143142
"@babel/core": "^7.4.3",

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@
175175
"@types/chai": "^4.2.11",
176176
"@types/enzyme": "^3.10.5",
177177
"@types/enzyme-adapter-react-16": "^1.0.6",
178-
"@types/jest": "^25.1.5",
178+
"@types/jest": "^25.2.3",
179179
"apollo": "^2.32.5",
180180
"babel-eslint": "^8.2.6",
181181
"babel-jest": "^25.2.4",
@@ -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)