Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion exercises/00 - Setup Jest/ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@

For this exercise the function to test and the test have already been written.

Your task is to setup jest. To pass you should be able to run `npm test` or `yarn test` and see a successful test output.
Your task is to setup jest. To pass you should be able to run `npm test` or `yarn test` and see a successful test output.

# Solution

1) Add `jest-cli` as devDependency
2) Update test script to simple call `jest`
5 changes: 4 additions & 1 deletion exercises/00 - Setup Jest/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
"private": true,
"version": "0.0.1",
"scripts": {
"test": "echo \"This is part of the jest setup\" && exit 1"
"test": "jest"
},
"devDependencies": {
"jest-cli": "^19.0.2"
}
}
8 changes: 8 additions & 0 deletions exercises/10 - Lookup/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ const users = [
// lookup()
const lookup = (login, property) => {
// START -- THIS IS WHERE YOUR CODE GOES
const user = users.find(u=> u.login === login);
if (!user) {
throw new Error("Could not find user");
}
if (!user.hasOwnProperty(property)) {
throw new Error("Could not find property");
}
return user[property];
// END
};

Expand Down
6 changes: 4 additions & 2 deletions exercises/11 - Pure Function/index.spec.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
// setPrice(item: Object, price: Number) => item: Object
const setPrice = (item, price) => {
// TODO: implement
return Object.assign({}, item, {
price,
});
};

// addToCart(cart: Array, item: Object) => cart: Array
const addToCart = (cart, item) => {
// TODO: implement
return cart.concat(item);
};

describe('setPrice()', () => {
Expand Down
18 changes: 16 additions & 2 deletions exercises/12 - Object Snapshot/index.spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
import { createStore, combineReducers } from 'redux';

const usersReducer = (state, action) => {
// Implement this reducer to pass the tests below
const usersReducer = (state = [], action) => {
switch (action.type) {
case 'SAVE_USER':
const { user } = action;
if (state.some(u => u.handle === user.handle)) {
return state.map(u => {
if (u.handle === user.handle) {
return Object.assign({}, u, user);
}
return u;
});
}
return [...state, user];
default:
return state;
}
};

const configureStore = (initialState = {}) => {
Expand Down
18 changes: 16 additions & 2 deletions exercises/13 - Component Testing/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
import React from 'react';
import classnames from 'classnames';

export default () => {
// Implement this component to pass the tests in ./__tests/index.spec.js
export default ({data, onClick}) => {
const handleClick = (key) => () => {
return onClick(key);
}
return (<ul>
{data.map(i => {
return (<li
key={i.key}
className={classnames({selected: i.selected})}
onClick={handleClick(i.key)}
>
{i.name}
</li>);
})}
</ul>);
};
34 changes: 30 additions & 4 deletions exercises/14 - Promise Testing/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,41 @@ export const defaultFetchHeaders = {
};

export const camelCase = input => {
// TODO: implement
return (typeof input === 'string') ? input.charAt(0).toLowerCase() + input.slice(1) : input;
};

const normalizeCasing = value => {
// TODO: implement
export const normalizeCasing = value => {
if (value === null) {
return null;
}
if (Array.isArray(value)) {
return value.map(normalizeCasing);
}
if (typeof value === 'object') {
return Object.keys(value).reduce((acc, curr) => {
return {
...acc,
[camelCase(curr)]: normalizeCasing(value[curr]),
};
}, {});
}
return value;
};

const callApi = (url = '', options = {}) => {
// TODO: implement
const apiUrl = (/https?:\/\//.test(url)) ? url : `${LOCATION_ORIGIN}${url}`;
const fetchOptions = Object.assign({}, defaultFetchHeaders, options);
return fetch(apiUrl, fetchOptions)
.then((resp) => {
if (resp.status !== 204) {
return resp.json()
.then((json) => {
const results = { json: normalizeCasing(json), resp };
return (resp.status >= 500 && resp.status < 600) ? Promise.reject(results) : results;
});
}
return { json: null, resp };
});
};

export default callApi;
16 changes: 8 additions & 8 deletions exercises/14 - Promise Testing/index.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'isomorphic-fetch';
import callApi, { defaultFetchHeaders, camelCase } from './index';
import callApi, { defaultFetchHeaders, normalizeCasing } from './index';
var mockFetch;

jest.mock('node-fetch', () => {
Expand Down Expand Up @@ -125,35 +125,35 @@ describe('callApi', () => {
});
});

describe('#camelCase', () => {
describe('#normalizeCasing', () => {
const obj = { SuperLongCSharpVariableNameThatIsInMyJSON: 1 };
const formattedObj = { superLongCSharpVariableNameThatIsInMyJSON: 1 };

it('returns the input if it is an array with no objects', () => {
expect(camelCase([1, 2, 3])).toEqual([1,2,3]);
expect(normalizeCasing([1, 2, 3])).toEqual([1,2,3]);
});

it('returns the input if it is a nested array with no objects', () => {
expect(camelCase([1, [2], 3])).toEqual([1, [2] ,3]);
expect(normalizeCasing([1, [2], 3])).toEqual([1, [2] ,3]);
});

it('camel-cases object keys when a single object is nested inside an array', () => {
expect(camelCase([obj])).toEqual([formattedObj]);
expect(normalizeCasing([obj])).toEqual([formattedObj]);
});

it('camel-cases object keys when an object and a primitive are nested in an array', () => {
expect(camelCase([obj, 1])).toEqual([formattedObj, 1]);
expect(normalizeCasing([obj, 1])).toEqual([formattedObj, 1]);
});

it('camel-cases object keys if the object contains an array', () => {
const nestedArray = Object.assign({}, obj, { Arr: [1, 2, 3] });
const expected = Object.assign({}, formattedObj, { arr: [1, 2, 3] });
expect(camelCase(nestedArray)).toEqual(expected);
expect(normalizeCasing(nestedArray)).toEqual(expected);
});

it('camel-cases object keys if the object contains an array containing an object', () => {
const nestedArray = Object.assign({}, obj, { Arr: [1, { B: 2 }, 3] });
const expected = Object.assign({}, formattedObj, { arr: [1, { b: 2 }, 3] });
expect(camelCase(nestedArray)).toEqual(expected);
expect(normalizeCasing(nestedArray)).toEqual(expected);
});
});
3 changes: 0 additions & 3 deletions exercises/14 - Promise Testing/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,5 @@
"latest",
"stage-2"
]
},
"jest": {
"testEnvironment": "node"
}
}
8 changes: 4 additions & 4 deletions exercises/15 - Expect Extensions/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,20 @@ expect.extend({
});

test('should return function', () => {
const value = undefined;
const value = ()=>({});
expect(value).toBeFunction();
});

test('should not be function', () => {
const value = undefined;
const value = null;
expect(value).not.toBeFunction();
});

test('should return property', () => {
const value = undefined;
const value = {name: 'Kyle Welch', age: 27};
expect(value).toHaveProperty('name');
});
test('should return property', () => {
const value = undefined;
const value = {name: 'Kyle Welch'};
expect(value).not.toHaveProperty('age');
});