exercism/javascript/react/react.spec.js

212 lines
5.3 KiB
JavaScript
Raw Permalink Normal View History

2018-10-03 13:00:19 -04:00
import {InputCell, ComputeCell, CallbackCell} from './react';
describe('React module', () => {
test('accepts input', () => {
const inputCell = new InputCell(10);
expect(inputCell.value).toEqual(10);
});
test('allows input cell value to be set', () => {
const inputCell = new InputCell(4);
inputCell.setValue(20);
expect(inputCell.value).toEqual(20);
});
test('allows setting compute cells', () => {
const inputCell = new InputCell(1);
const fn = inputCells => inputCells[0].value + 1;
const computeCell = new ComputeCell([inputCell], fn);
expect(computeCell.value).toEqual(2);
});
test('compute cell takes inputs in correct order', () => {
const inputCells = [
new InputCell(1),
new InputCell(2)
];
const computeCell = new ComputeCell(
inputCells,
inputs => inputs[0].value + inputs[1].value * 10
);
expect(computeCell.value).toEqual(21);
});
test('compute cells update value when inputs are changed', () => {
const inputCell = new InputCell(1);
const computeCell = new ComputeCell(
[inputCell],
inputs => inputs[0].value + 1
);
inputCell.setValue(3);
expect(computeCell.value).toEqual(4);
});
test('compute cells can depend on other compute cells', () => {
const inputCell = new InputCell(1);
const timesTwo = new ComputeCell(
[inputCell],
inputs => inputs[0].value * 2
);
const timesThirty = new ComputeCell(
[inputCell],
inputs => inputs[0].value * 30
);
const sum = new ComputeCell(
[timesTwo, timesThirty],
inputs => inputs[0].value + inputs[1].value
);
expect(sum.value).toEqual(32);
inputCell.setValue(3);
expect(sum.value).toEqual(96);
});
test('compute cells fire callbacks', () => {
const inputCell = new InputCell(1);
const output = new ComputeCell(
[inputCell],
inputs => inputs[0].value + 1
);
const callback = new CallbackCell(cell => cell.value);
output.addCallback(callback);
inputCell.setValue(3);
expect(callback.values).toEqual([4]);
});
test('callbacks fire only when output values change', () => {
const inputCell = new InputCell(1);
const output = new ComputeCell(
[inputCell],
inputs => inputs[0].value < 3 ? 111 : 222
);
const callback = new CallbackCell(cell => cell.value);
output.addCallback(callback);
inputCell.setValue(2);
expect(callback.values).toEqual([]);
inputCell.setValue(4);
expect(callback.values).toEqual([222]);
});
test('callbacks can be added and removed', () => {
const inputCell = new InputCell(1);
const output = new ComputeCell(
[inputCell],
inputs => inputs[0].value + 1
);
const callback1 = new CallbackCell(cell => cell.value);
const callback2 = new CallbackCell(cell => cell.value);
output.addCallback(callback1);
output.addCallback(callback2);
inputCell.setValue(31);
output.removeCallback(callback1);
const callback3 = new CallbackCell(cell => cell.value);
output.addCallback(callback3);
inputCell.setValue(41);
expect(callback1.values).toEqual([32]);
expect(callback2.values).toEqual([32, 42]);
expect(callback3.values).toEqual([42]);
});
test('removing a callback multiple times doesn\'t interfere with other callbacks', () => {
const inputCell = new InputCell(1);
const output = new ComputeCell(
[inputCell],
inputs => inputs[0].value + 1
);
const callback1 = new CallbackCell(cell => cell.value);
const callback2 = new CallbackCell(cell => cell.value);
output.addCallback(callback1);
output.addCallback(callback2);
output.removeCallback(callback1);
output.removeCallback(callback1);
output.removeCallback(callback1);
inputCell.setValue(2);
expect(callback1.values).toEqual([]);
expect(callback2.values).toEqual([3]);
});
test('callbacks should only be called once, even if multiple dependencies change', () => {
const inputCell = new InputCell(1);
const plusOne = new ComputeCell(
[inputCell],
inputs => inputs[0].value + 1
);
const minusOne1 = new ComputeCell(
[inputCell],
inputs => inputs[0].value - 1
);
const minusOne2 = new ComputeCell(
[minusOne1],
inputs => inputs[0].value - 1
);
const output = new ComputeCell(
[plusOne, minusOne2],
inputs => inputs[0].value * inputs[1].value
);
const callback1 = new CallbackCell(cell => cell.value);
output.addCallback(callback1);
inputCell.setValue(4);
expect(callback1.values).toEqual([10]);
});
test('callbacks should not be called if dependencies change but output value doesn\'t change', () => {
const inputCell = new InputCell(1);
const plusOne = new ComputeCell(
[inputCell],
inputs => inputs[0].value + 1
);
const minusOne = new ComputeCell(
[inputCell],
inputs => inputs[0].value - 1
);
const alwaysTwo = new ComputeCell(
[plusOne, minusOne],
inputs => inputs[0].value - inputs[1].value
);
const callback = new CallbackCell(cell => cell.value);
alwaysTwo.addCallback(callback);
inputCell.setValue(2);
inputCell.setValue(3);
inputCell.setValue(4);
inputCell.setValue(5);
expect(callback.values).toEqual([]);
});
});