Skip to content
This repository has been archived by the owner on Feb 19, 2023. It is now read-only.

Commit

Permalink
feat(#104): added test cases for faces and labels redux subtree
Browse files Browse the repository at this point in the history
  • Loading branch information
Andreas Gasser committed Apr 4, 2019
1 parent a78ff6a commit 71980b1
Show file tree
Hide file tree
Showing 12 changed files with 652 additions and 5 deletions.
4 changes: 2 additions & 2 deletions src/images/detail/Container.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { getImage } from '../../redux/images';
import { imagesByIdSelector, getImageRequestSelector } from '../../redux/images/selectors';


import { labelsByImageId, labelsByIdSelector } from '../../redux/labels/selectors';
import { labelsByImageIdSelector, labelsByIdSelector } from '../../redux/labels/selectors';
import { facesByImageId, facesByIdSelector } from '../../redux/faces/selectors';

import DetailView from './DetailView';
Expand Down Expand Up @@ -36,7 +36,7 @@ const select = (state, props) => {

return {
image,
labels: labelsByImageId(state, id),
labels: labelsByImageIdSelector(state, id),
faces: facesByImageId(state, id),
selectedFace: params.face
? facesByIdSelector(state)[params.face] || null
Expand Down
211 changes: 211 additions & 0 deletions src/redux/faces/__data__/faces.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
export default {
"faces": {
"items": [{
"id": "7efa73a7-6fe0-404b-a85e-e34abb20b572",
"age": {
"low": 20,
"high": 38,
"__typename": "FaceAge"
},
"position": {
"height": 0.16048859059810638,
"width": 0.06429165601730347,
"left": 0.7339414358139038,
"top": 0.25065237283706665,
"__typename": "BoundingBox"
},
"emotions": [{
"name": "ANGRY",
"confidence": 9.131677627563477,
"__typename": "Attribute"
}, {
"name": "SURPRISED",
"confidence": 8.68793773651123,
"__typename": "Attribute"
}, {
"name": "CALM",
"confidence": 53.679351806640625,
"__typename": "Attribute"
}, {
"name": "DISGUSTED",
"confidence": 14.890134811401367,
"__typename": "Attribute"
}, {
"name": "SAD",
"confidence": 10.600337028503418,
"__typename": "Attribute"
}, {
"name": "HAPPY",
"confidence": 0.4520353376865387,
"__typename": "Attribute"
}, {
"name": "CONFUSED",
"confidence": 0,
"__typename": "Attribute"
}],
"attributes": [{
"name": "gender",
"confidence": 61.0933837890625,
"value": "Male",
"__typename": "Attribute"
}, {
"name": "brightness",
"confidence": 100,
"value": "83.16773986816406",
"__typename": "Attribute"
}, {
"name": "sharpness",
"confidence": 100,
"value": "92.22801208496094",
"__typename": "Attribute"
}],
"__typename": "Face"
}, {
"id": "68858073-9f89-4b6d-9526-400fdf82ed49",
"age": {
"low": 26,
"high": 43,
"__typename": "FaceAge"
},
"position": {
"height": 0.15534932911396027,
"width": 0.06539079546928406,
"left": 0.1794459968805313,
"top": 0.2902233898639679,
"__typename": "BoundingBox"
},
"emotions": [{
"name": "SAD",
"confidence": 2.8847672939300537,
"__typename": "Attribute"
}, {
"name": "HAPPY",
"confidence": 0.10791733115911484,
"__typename": "Attribute"
}, {
"name": "DISGUSTED",
"confidence": 12.038032531738281,
"__typename": "Attribute"
}, {
"name": "CALM",
"confidence": 62.864418029785156,
"__typename": "Attribute"
}, {
"name": "ANGRY",
"confidence": 11.946447372436523,
"__typename": "Attribute"
}, {
"name": "CONFUSED",
"confidence": 0,
"__typename": "Attribute"
}, {
"name": "SURPRISED",
"confidence": 8.280786514282227,
"__typename": "Attribute"
}],
"attributes": [{
"name": "gender",
"confidence": 76.8848876953125,
"value": "Male",
"__typename": "Attribute"
}, {
"name": "brightness",
"confidence": 100,
"value": "78.37348937988281",
"__typename": "Attribute"
}, {
"name": "sharpness",
"confidence": 100,
"value": "94.08262634277344",
"__typename": "Attribute"
}],
"__typename": "Face"
}, {
"id": "e686fda1-b83c-46b5-8086-81902f558e81",
"age": {
"low": 26,
"high": 43,
"__typename": "FaceAge"
},
"position": {
"height": 0.12948490679264069,
"width": 0.0694088414311409,
"left": 0.4533727467060089,
"top": 0.33818867802619934,
"__typename": "BoundingBox"
},
"emotions": [{
"name": "ANGRY",
"confidence": 0.025381267070770264,
"__typename": "Attribute"
}, {
"name": "SAD",
"confidence": 0.005187096539884806,
"__typename": "Attribute"
}, {
"name": "DISGUSTED",
"confidence": 0.025570334866642952,
"__typename": "Attribute"
}, {
"name": "HAPPY",
"confidence": 99.68476867675781,
"__typename": "Attribute"
}, {
"name": "SURPRISED",
"confidence": 0.21237444877624512,
"__typename": "Attribute"
}, {
"name": "CALM",
"confidence": 0.027801742777228355,
"__typename": "Attribute"
}, {
"name": "CONFUSED",
"confidence": 0,
"__typename": "Attribute"
}],
"attributes": [{
"name": "eyeglasses",
"confidence": 99.98456573486328,
"value": "true",
"__typename": "Attribute"
}, {
"name": "eyesOpen",
"confidence": 100,
"value": "true",
"__typename": "Attribute"
}, {
"name": "gender",
"confidence": 99.29379272460938,
"value": "Female",
"__typename": "Attribute"
}, {
"name": "mouthOpen",
"confidence": 98.84275817871094,
"value": "true",
"__typename": "Attribute"
}, {
"name": "smile",
"confidence": 99.58173370361328,
"value": "true",
"__typename": "Attribute"
}, {
"name": "sunglasses",
"confidence": 99.93656158447266,
"value": "true",
"__typename": "Attribute"
}, {
"name": "brightness",
"confidence": 100,
"value": "60.014461517333984",
"__typename": "Attribute"
}, {
"name": "sharpness",
"confidence": 100,
"value": "83.14741516113281",
"__typename": "Attribute"
}],
"__typename": "Face"
}],
"__typename": "FacePayload",
},
};
71 changes: 71 additions & 0 deletions src/redux/faces/__tests__/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/* global it testUtils */
import reducer, * as reduxFaces from '../index';

import data from '../__data__/faces';

const { __testables__ } = reduxFaces;

const mockData = {
imageId: '2a2bdf23-e73f-4a2a-913e-da29926a195c',
};

describe('faces simple action test suite', () => {
it('should handle facesAddFaces', () => {
const { faces } = data;
const { imageId } = mockData;

// generate output
const ids = [];
const byId = {};
faces.items.forEach((face) => {
const { id } = face;

ids.push(id);
byId[id] = face;
});

// test function
expect(reduxFaces.facesAddFaces(imageId, faces.items))
.toEqual({
type: __testables__.FACES_ADD_FACES,
payload: {
imageId,
ids,
byId,
},
});
});
});

describe('faces reducer test suite', () => {
it('should return initial state', () => {
expect(reducer(undefined, testUtils.dummyTestAction()))
.toEqual({
byId: {},
idsByImageId: {},
});
});

it('should handle FACES_ADD_FACES', () => {
const { faces } = data;
const { imageId } = mockData;

// generate output
const ids = [];
const byId = {};
faces.items.forEach((face) => {
const { id } = face;

ids.push(id);
byId[id] = face;
});

expect(reducer(undefined, reduxFaces.facesAddFaces(imageId, faces.items)))
.toEqual({
byId,
idsByImageId: {
[imageId]: ids,
},
});
});
});
61 changes: 61 additions & 0 deletions src/redux/faces/__tests__/selector.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/* global testUtils */
import * as selectors from '../selectors';

import data from '../__data__/faces';
const { faces } = data;

const imageId = '2a2bdf23-e73f-4a2a-913e-da29926a195c';

const initialState = {
faces: {
byId: faces.items.reduce((prev, cur) => ({
...prev,
[cur.id]: cur,
}), {}),
idsByImageId: {
[imageId]: faces.items.map(item => item.id),
},
imageId,
},
};

describe('faces selector test suite', () => {
it('should return facesState state', () => {
expect(selectors.facesStateSelector(initialState))
.toEqual(initialState.faces);
});

it('should return facesIdsByImageId value', () => {
expect(selectors.facesIdsByImageIdSelector(initialState))
.toEqual(initialState.faces.idsByImageId);
});

it('should return facesById value', () => {
expect(selectors.facesByIdSelector(initialState))
.toEqual(initialState.faces.byId);
});

it('should return facesByImageId value', () => {
const idsByImageId = selectors.facesIdsByImageIdSelector(initialState);
const byId = selectors.facesByIdSelector(initialState);

const ids = idsByImageId[imageId];

const faces = ids.map(id => byId[id])
.filter(face => face !== undefined);

// const labels;
expect(selectors.facesByImageId(initialState, imageId))
.toEqual(faces);
});

it('should return empty array for facesByImageId without imageId', () => {
expect(selectors.facesByImageId(initialState, undefined))
.toEqual([]);
});

it('should return empty array for facesByImageId with wrong imageId', () => {
expect(selectors.facesByImageId(initialState, 'invalid'))
.toEqual([]);
});
});
4 changes: 4 additions & 0 deletions src/redux/faces/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ const persistConfig = {
stateReconciler: autoMergeLevel2,
};

export const __testables__ = {
FACES_ADD_FACES,
};

export default persistReducer(
persistConfig,
combineReducers({
Expand Down
2 changes: 1 addition & 1 deletion src/redux/faces/selectors.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createSelector } from 'reselect';

const facesStateSelector = state => state.faces;
export const facesStateSelector = state => state.faces;

export const facesIdsByImageIdSelector = createSelector(
facesStateSelector,
Expand Down
3 changes: 3 additions & 0 deletions src/redux/images/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,9 @@ export const getImage = hocAsyncAction(

const { faces, labels, ...image } = getImage;
const { id } = image;

console.log(faces);
console.log(labels);

dispatch(imagesAddImage(image));
dispatch(labelsAddLabels(id, labels.items));
Expand Down
Loading

0 comments on commit 71980b1

Please sign in to comment.