added reducers
authorAlex-Laptop <[email protected]>
Wed, 20 Mar 2019 18:44:17 +0000 (11:44 -0700)
committerAlex-Laptop <[email protected]>
Wed, 20 Mar 2019 18:44:17 +0000 (11:44 -0700)
src/classes/workout.js
src/constants.js [new file with mode: 0644]
src/reducers/combined.js [new file with mode: 0644]
src/reducers/view.js [new file with mode: 0644]
src/reducers/workouts.js [new file with mode: 0644]
test/view.reducer.tests.js [new file with mode: 0644]
test/workout.tests.js [moved from test/workouts.tests.js with 64% similarity]
test/workouts.reducer.tests.js [new file with mode: 0644]

index 1b69b575471a54ddc45c385184b8ae3023099b83..774e37a25a5df71b0a88373b9c0da7b1e831b58c 100644 (file)
@@ -1,16 +1,12 @@
+import {constants} from '../constants.js';
+const {DEFAULT_ATTRIBUTES} = constants;
+
 export default class workout {
        constructor() {
-               this.attributes = {
-                       lower:false,
-                       core:false,
-                       back:false,
-                       upper:false,
-                       cardio:false,
-                       martial:false,
-                       other:false
-               };
+               this.attributes = {...DEFAULT_ATTRIBUTES};
                this.datesDone = [];
-               this.name = "New workout";
+               this.name = "New Workout";
+               this.description = "";
        }
        add(dates) { // add new workout to 
                if(!(dates instanceof Array)) {
@@ -33,16 +29,29 @@ export default class workout {
                ];
                this.datesDone.sort();
        }
+       changeDescription(str) {
+               if(typeof str != "string") {
+                       throw new TypeError('Workout::changeDescription(str) expects parameter `str` to be a string');
+               }
+               this.description = str;
+       }
        export() {
-
+               throw new Error("Not implemented");
+       }
+       get last_done() {
+               throw new Error('Not implemented');
+       }
+       remove(date) {
+               throw new Error("Not implemented");
        }
        setName(name) {
                if(typeof name != "string") {
-                       throw new TypeErorr('Workout::setName(name) expects parameter `name` to be a string');
+                       throw new TypeError('Workout::setName(name) expects parameter `name` to be a string');
                }
+               this.name = name;
        }
        toggleAttribute(attr) {
-               if(this.attributes[attr] == void(0)) {
+               if(this.attributes[attr] === void(0)) {
                        throw new TypeError('Workout::toggleAttribute(attr) expects parameter `attr` to be a valid attribute');
                }
                this.attributes[attr] = !this.attributes[attr];
diff --git a/src/constants.js b/src/constants.js
new file mode 100644 (file)
index 0000000..08ab8e0
--- /dev/null
@@ -0,0 +1,22 @@
+const constants = {
+       ADD_WORKOUT:"ADD_WORKOUT",
+       CHANGE_ATTRIBUTE:"CHANGE_ATTRIBUTE",
+       CHANGE_VIEW:"CHANGE_VIEW",
+       CHANGE_WORKOUT_DESCRIPTION:"CHANGE_WORKOUT_DESCRIPTION",
+       CHANGE_WORKOUT_NAME:"CHANGE_WORKOUT_NAME",
+       DEFAULT_ATTRIBUTES:{
+               lower:false,
+               core:false,
+               back:false,
+               upper:false,
+               cardio:false,
+               martial:false,
+               other:false
+       },
+       DELETE_WORKOUT:"DELETE_WORKOUT",
+       NEW_WORKOUT:"NEW_WORKOUT",
+       REMOVE_WORKOUT:"REMOVE_WORKOUT",
+       SORT_VIEW:"SORT_VIEW"
+};
+Object.freeze(constants);
+export constants;
\ No newline at end of file
diff --git a/src/reducers/combined.js b/src/reducers/combined.js
new file mode 100644 (file)
index 0000000..6ba7c20
--- /dev/null
@@ -0,0 +1,9 @@
+import {combineReducers} from 'redux';
+
+import workouts from './workouts.js';
+import view from './view.js';
+
+export default combineReducers({
+       workouts,
+       view
+});
\ No newline at end of file
diff --git a/src/reducers/view.js b/src/reducers/view.js
new file mode 100644 (file)
index 0000000..af54542
--- /dev/null
@@ -0,0 +1,77 @@
+import workout from '../classes/workout.js';
+
+import {constants} from '../constants.js';
+
+const {DEFAULT_ATTRIBUTES} = constants;
+const defaultDaysAgo = {...DEFAULT_ATTRIBUTES};
+Object.keys(defaultDaysAgo).map((attr) => {
+       defaultDaysAgo[attr] = -1;
+});
+const defaultState = {
+       view:"manage",
+       daysAgo:defaultDaysAgo,
+       data:[],
+       sortKey:"last_done",
+       sortOrder:"desc"
+};
+
+export default function view(state = defaultState,action) {
+       const {CHANGE_VIEW,SORT_VIEW} = constants;
+       if((action.workouts == void(0))||(!(action.workouts instanceof Array))) {
+               return state;
+       }
+       if(!action.workouts.every((x) => x instanceof workout)) {
+               return state;
+       }
+       switch(action.type) {
+               case CHANGE_VIEW:
+                       if((action.view === void(0))||(action.view == state.view)) {
+                               return state;
+                       }
+                       switch(action.view) {
+                               case "manage":
+                                       const newStateManageView = {...state};
+                                       newStateManageView.data = [];
+                                       for(let i=0;i<action.workouts.length;i++) {
+                                               newStateManageView.data.push({
+                                                       attributes:actions.workouts[i].attributes,
+                                                       name:actions.workouts[i].name,
+                                                       last_done:actions.workouts[i].last_done,
+                                                       description:actions.workouts[i].description
+                                               });
+                                       }
+                                       return newStateManageView;
+                               case "recent":
+                                       const newStateRecentView = {...state};
+                                       newStateRecentView.data = [];
+                                       for(let i=0;i<action.workouts.length;i++) {
+                                               for(let j=0;j<action.workouts[i].datesDone;j++) {
+                                                       newStateRecentView.data.push({
+                                                               name:actions.workouts[i].name,
+                                                               date:actions.workouts[i].datesDone[j]
+                                                       });
+                                               }
+                                       }
+                                       return newStateRecentView;
+                               default:
+                                       return state;
+                       }
+               case SORT_VIEW:
+                       /*if(action.key === void(0)) {
+                               return state;
+                       }
+                       if(action.order === void(0)) {
+                               return state;
+                       }
+                       let newSortKey = [...state.sortKey];
+                       let newSortOrder = [...state.sortOrder];
+                       const sortIndex = state.sortKey.indexOf(action.key);
+                       if(sortIndex>-1) {
+                               newSortOrder[sortIndex] = (newSortOrder[sortIndex]=="asc")?"desc":"asc";
+                       } else {
+                               newSortkey*/
+                       return state;
+               default:
+                       return state;
+       }
+}
\ No newline at end of file
diff --git a/src/reducers/workouts.js b/src/reducers/workouts.js
new file mode 100644 (file)
index 0000000..60d0159
--- /dev/null
@@ -0,0 +1,86 @@
+import {constants} from '../constants.js';
+
+export default function workouts(state = {},action) {
+       const {ADD_WORKOUT,CHANGE_ATTRIBUTE,CHANGE_WORKOUT_NAME,DEFAULT_ATTRIBUTES,DELETE_WORKOUT,NEW_WORKOUT,REMOVE_WORKOUT} = constants;
+       if(typeof action != "object") {
+               return state;
+       }
+       switch(action.type) {
+               case ADD_WORKOUT:
+                       if(action.name === void(0)) {
+                               return state;
+                       }
+                       if(!(state[action.name] instanceof workout)) {
+                               return state;
+                       }
+                       const newStateAfterAdd = {...state};
+                       try {
+                               newStateAfterAdd[action.name].add(action.toAdd);
+                               return newStateAfterAdd;
+                       } catch(err) {
+                               return state;
+                       }
+               case CHANGE_ATTRIBUTE:
+                       if((action.workout === void(0))||(action.attribute === void(0))) {
+                               return state;
+                       }
+                       if(state[action.workout] === void(0)) {
+                               return state;
+                       }
+                       try {
+                               const newStateAfterChangeAttribute = {...state};
+                               newStateAfterChangeAttribute[action.workout].toggleAttribute(action.attribute);
+                               return newStateAfterChangeAttribute;
+                       } catch(err) {
+                               return state;
+                       }
+               case CHANGE_WORKOUT_NAME:
+                       if(action.workout === void(0)) {
+                               return state;
+                       }
+                       if(state[action.workout] === void(0)) {
+                               return state;
+                       }
+                       try {
+                               const newStateAfterNameChange = {...state};
+                               newStateAfterNameChange[action.workout].setName(action.name);
+                               return newStateAfterNameChange;
+                       } catch(err) {
+                               return state;
+                       }
+               case DELETE_WORKOUT:
+                       if(action.name === void(0)) {
+                               return state;
+                       }
+                       if(!(state[action.name] instanceof workout)) {
+                               return state;
+                       }
+                       try {
+                               const newStateAfterDelete = {...state};
+                               newStateAfterDelete[action.workout].remove(toDel);
+                               return newStateAfterDelete;
+                       } catch(err) {
+                               return state;
+                       }
+               case NEW_WORKOUT:
+                       if(state["New Workout"] !== void(0)) {
+                               return state;
+                       }
+                       const newStateAfterNew = {...state};
+                       const newWorkout = new workout();
+                       newStateAfterNew[newWorkout.name] = newWorkout;
+                       return newStateAfterNew;
+               case REMOVE_WORKOUT:
+                       if(action.toRemove === void(0)) {
+                               return state;
+                       }
+                       if(state[action.toRemove] === void(0)) {
+                               return state;
+                       }
+                       const newStateAfterRemove = {...state};
+                       delete(newStateAfterRemove[action.toRemove]);
+                       return newStateAfterRemove;
+               default:
+                       return state;
+       }
+}
\ No newline at end of file
diff --git a/test/view.reducer.tests.js b/test/view.reducer.tests.js
new file mode 100644 (file)
index 0000000..9749ba0
--- /dev/null
@@ -0,0 +1,38 @@
+import assert from 'assert';
+
+import view from '../src/reducers/view.js';
+
+import {constants} from '../src/constants.js';
+const {CHANGE_VIEW,SORT_VIEW} = constants;
+
+describe('view reducers',() => {
+
+       describe(CHANGE_VIEW,() => {
+
+               it('should not change the state when an invalid action is given',() => {
+                       assert.fail('Not implemented');
+               });
+
+               it('should successfully change the state to the `manage` view',() => {
+                       assert.fail('Not implemented');
+               });
+
+               it('should successfully change the state to the `recent` view',() => {
+                       assert.fail('Not implemented');
+               });
+
+       });
+
+       describe(SORT_VIEW,() => {
+
+               it('should not change the state when an invalid action is given',() => {
+                       assert.fail('Not implemented');
+               });
+
+               it('should successfully sort the view',() => {
+                       assert.fail('Not implemented');
+               });
+                       
+       });
+
+});
\ No newline at end of file
similarity index 64%
rename from test/workouts.tests.js
rename to test/workout.tests.js
index acf71a7c9c84474c11f14c35c3a8bfbdc314510f..4640e2470b813d239d6bebfa428192e231ba8f2e 100644 (file)
@@ -8,11 +8,23 @@ describe('workout object tests', () => {
                assert.fail('Not implemented');
        });
 
+       it('should successfully add dates', () => {
+               assert.fail('Not implemented');
+       });
+
+       it('should successfully change description',() => {
+               assert.fail('Not implemented');
+       });
+
        it('should successfully export', () => {
                assert.fail('Not implemented');
        });
 
-       it('should successfully add dates', () => {
+       it('should successfully output the last time the workout was completed',() => {
+               assert.fail('Not implemented');
+       });
+
+       it('should successfully remove dates', () => {
                assert.fail('Not implemented');
        });
 
diff --git a/test/workouts.reducer.tests.js b/test/workouts.reducer.tests.js
new file mode 100644 (file)
index 0000000..70940c5
--- /dev/null
@@ -0,0 +1,101 @@
+import assert from 'assert';
+
+import workouts from '../src/reducers/workouts.js';
+
+import {constants} from '../src/constants.js';
+const {ADD_WORKOUT,CHANGE_ATTRIBUTE,CHANGE_WORKOUT_NAME,DELETE_WORKOUT,NEW_WORKOUT,REMOVE_WORKOUT} = constants;
+
+describe('workouts reducer',() => {
+
+       describe(ADD_WORKOUT,() => {
+
+               it('should not change the state when invalid action is given',() => {
+                       assert.fail('Not implemented');
+               });
+
+               it('should successfully add a workout to an already existing workout',() => {
+                       assert.fail('Not implemented');
+               });
+
+       });
+
+       describe(CHANGE_ATTRIBUTE,() => {
+
+               it('should not change the state when an invalid action is given',() => {
+                       assert.fail('Not implemented');
+               });
+
+               it('should not change the state when trying to change an attribute for a nonexistent workout',() => {
+                       assert.fail('Not implemented');
+               });
+
+               it('should successfully change the attribute of an already existing workout',() => {
+                       assert.fail('Not implemented');
+               });
+
+       });
+
+       describe(CHANGE_WORKOUT_NAME,() => {
+
+               it('should not change the state when an invalid action is given',() => {
+                       assert.fail('Not implemented');
+               });
+
+               it('should not change the state when trying to change the name for a nonexistent workout',() => {
+                       assert.fail('Not implemented');
+               });
+
+               it('should successfully change the name of an already existing workout',() => {
+                       assert.fail('Not implemented');
+               });
+
+       });
+
+       describe(DELETE_WORKOUT,() => {
+
+               it('should not change the state when an invalid action is given',() => {
+                       assert.fail('Not implemented');
+               });
+
+               it('should not change the state when action.name refers to a nonexistent workout',() => {
+                       assert.fail('Not implemented');
+               });
+
+               it('should successfully delete a workout from an existent workout',() => {
+                       assert.fail('Not implemented');
+               });
+
+       });
+
+       describe(NEW_WORKOUT,() => {
+
+               it('should not change the state when an invalid action is given',() => {
+                       assert.fail('Not implemented');
+               });
+
+               it('should not change the state when "New Workout" workout already exists',() => {
+                       assert.fail('Not implemented');
+               });
+
+               it('should successfully add a new workout',() => {
+                       assert.fail('Not implemented');
+               });
+       });
+
+       describe(REMOVE_WORKOUT,() => {
+
+               it('should not change the state when an invalid action is given',() => {
+                       assert.fail('Not implemented');
+               });
+
+               it('should fail when action.toRemove refers to a nonexistent workout',() => {
+                       assert.fail('Not implemented');
+               });
+
+               it('should successfully remove a workout',() => {
+                       assert.fail('Not implemented');
+               });
+
+       });
+
+});
\ No newline at end of file