@applicaster/zapp-react-native-utils
Version:
Applicaster Zapp React Native utilities package
229 lines (181 loc) • 6.27 kB
text/typescript
import {
mapAndSplit,
mapPromises,
reducePromises,
removeItemFromList,
shiftArray,
} from "../index";
const array = ["foo", "bar", "baz", 42];
const offset = 1;
const negativeOffset = -1;
describe("shiftArray", () => {
it("can be used as a curried function", () => {
expect(shiftArray(offset, array)).toEqual(shiftArray(offset)(array));
});
it("doesn't change the array if the offset is null", () => {
expect(shiftArray(0, array)).toEqual(array);
});
it("shifts the n first items from the head to the tail of the array with a positive offset", () => {
expect(shiftArray(offset, array)).toMatchSnapshot();
expect(shiftArray(2 * offset, array)).toMatchSnapshot();
});
it("shifts the n last items from the tail to the head of the array with a negative offset", () => {
expect(shiftArray(negativeOffset, array)).toMatchSnapshot();
expect(shiftArray(2 * negativeOffset, array)).toMatchSnapshot();
});
});
describe("removeItemFromList", () => {
it("removes an item from a list", () => {
const arrayOfPrimitives = [1, 2, 3, 4];
expect(removeItemFromList(1, arrayOfPrimitives)).toEqual([2, 3, 4]);
const arrayOfObjects = [
{ prop: "value1" },
{ prop: "value2" },
{ prop: "value3" },
];
expect(removeItemFromList({ prop: "value2" }, arrayOfObjects)).toEqual([
{ prop: "value1" },
{ prop: "value3" },
]);
});
it("leaves the list as is if the item is not found", () => {
const arrayOfObjects = [
{ prop: "value1" },
{ prop: "value2" },
{ prop: "value3" },
];
expect(removeItemFromList({ prop: "value4" }, arrayOfObjects)).toEqual(
arrayOfObjects
);
});
});
describe("mapPromises", () => {
const promiseFn = jest.fn((num) => Promise.resolve(num + 1));
beforeEach(() => {
promiseFn.mockClear();
});
it("is a curried function, and returns an array of resolved values", async () => {
const promiseMapper = mapPromises(promiseFn);
const values = [1, 2, 3];
expect(typeof promiseMapper).toBe("function");
await expect(promiseMapper(values)).resolves.toEqual([2, 3, 4]);
});
it("calls all the promises immediately", () => {
const values = [1, 2, 3];
mapPromises(promiseFn, values);
expect(promiseFn).toHaveBeenCalledTimes(values.length);
values.forEach((value) => {
expect(promiseFn).toHaveBeenNthCalledWith(value, value, value - 1);
});
});
describe("removeItemFromList", () => {
it("removes an item from a list", () => {
const arrayOfPrimitives = [1, 2, 3, 4];
expect(removeItemFromList(1, arrayOfPrimitives)).toEqual([2, 3, 4]);
const arrayOfObjects = [
{ prop: "value1" },
{ prop: "value2" },
{ prop: "value3" },
];
expect(removeItemFromList({ prop: "value2" }, arrayOfObjects)).toEqual([
{ prop: "value1" },
{ prop: "value3" },
]);
});
it("leaves the list as is if the item is not found", () => {
const arrayOfObjects = [
{ prop: "value1" },
{ prop: "value2" },
{ prop: "value3" },
];
expect(removeItemFromList({ prop: "value4" }, arrayOfObjects)).toEqual(
arrayOfObjects
);
});
});
describe("mapPromises", () => {
const promiseFn = jest.fn((num) => Promise.resolve(num + 1));
beforeEach(() => {
promiseFn.mockClear();
});
it("is a curried function, and returns an array of resolved values", async () => {
const promiseMapper = mapPromises(promiseFn);
const values = [1, 2, 3];
expect(typeof promiseMapper).toBe("function");
await expect(promiseMapper(values)).resolves.toEqual([2, 3, 4]);
});
it("calls all the promises immediately", () => {
const values = [1, 2, 3];
mapPromises(promiseFn, values);
expect(promiseFn).toHaveBeenCalledTimes(values.length);
values.forEach((value) => {
expect(promiseFn).toHaveBeenNthCalledWith(value, value, value - 1);
});
expect.assertions(values.length + 1);
});
});
describe("reduce promises", () => {
const promiseFn = jest.fn((current, previous, index, cb) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(previous + current);
cb?.(index);
}, 1);
});
});
beforeEach(() => {
promiseFn.mockClear();
});
it("is a curried function; and returns the reduced promise values", async () => {
const promiseReducer = reducePromises(promiseFn);
const initialValue = 0;
const values = [1, 2, 3];
const sumOfValues = initialValue + values.reduce((a, b) => a + b, 0);
expect(typeof promiseReducer).toBe("function");
await expect(promiseReducer(initialValue, values)).resolves.toEqual(
sumOfValues
);
});
it("calls promises one after the other", (done) => {
const values = [1, 2, 3];
const previousValues = [0, 1, 3];
reducePromises(
(current, previous, index) =>
promiseFn(current, previous, index, (index) => {
expect(promiseFn).toHaveBeenCalledTimes(index + 1);
expect(promiseFn).toHaveBeenNthCalledWith(
index + 1,
values[index],
previousValues[index],
index,
expect.any(Function)
);
if (index === 2) done();
}),
0,
values
);
expect.assertions(values.length * 2);
});
});
describe("mapAndSplit", () => {
it("maps over a list of values and split it in chunks", () => {
const values = new Array(20).fill(0).map((_, i) => i);
const alphabet = Array.from(Array(26)).map((_, i) =>
String.fromCharCode(i + 65)
);
const getLetterForInt = (num) => alphabet[num];
const chunkSize = 5;
const result = mapAndSplit<number, string>(
getLetterForInt,
chunkSize
)(values);
expect(result.length).toBe(values.length / chunkSize);
result.forEach((chunk, chunkIndex) => {
chunk.forEach((value, index) => {
expect(value).toBe(alphabet[chunkIndex * chunkSize + index]);
});
});
});
});
});