Skip to content

Commit

Permalink
Update utility functions and add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
0pilatos0 committed Apr 6, 2024
1 parent b741387 commit 8dd11b1
Show file tree
Hide file tree
Showing 13 changed files with 239 additions and 2 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

TypeLegend is a versatile and typesafe utility library designed to simplify common tasks in your TypeScript projects. With TypeLegend, you can harness the power of TypeScript's strong typing system to write safer and more maintainable code.

- Total amount of typesafe utility functions: **75**
- Total amount of typesafe utility functions: **79**
- Total amount of typesafe utility classes: **9**

## Features
Expand Down
55 changes: 55 additions & 0 deletions USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ Here are some of the utility functions and classes available in this library:
- [benchmark](#benchmark)

- [ArrayUtils](#arrayutils)
- [union](#union)
- [diff](#diff)
- [sample](#sample)
- [intersect](#intersect)
- [zip](#zip)
- [shuffle](#shuffle)
- [chunk](#chunk)
- [random](#random)
Expand Down Expand Up @@ -40,6 +43,7 @@ Here are some of the utility functions and classes available in this library:
- [throttle](#throttle)
- [debounce](#debounce)
- [curry](#curry)
- [retry](#retry)
- [compose](#compose)
- [memoize](#memoize)

Expand Down Expand Up @@ -145,6 +149,32 @@ the following utility functions are available in the `BenchmarkUtils` class, the
the following utility functions are available in the `ArrayUtils` class, they can be used as a static method on the `ArrayUtils` class or as a standalone function.


### union
```typescript
/**
* Returns a new array that contains unique elements from both input arrays.
*
* @template T - The type of elements in the arrays.
* @param arr1 - The first input array.
* @param arr2 - The second input array.
* @returns A new array that contains unique elements from both input arrays.
*/
```


### diff
```typescript
/**
* Returns an array containing the elements from `arr1` that are not present in `arr2`.
*
* @template T - The type of elements in the arrays.
* @param arr1 - The first array.
* @param arr2 - The second array.
* @returns - The difference between `arr1` and `arr2`.
*/
```


### sample
```typescript
/**
Expand All @@ -169,6 +199,20 @@ the following utility functions are available in the `ArrayUtils` class, they ca
```


### zip
```typescript
/**
* Zips two arrays together, creating an array of tuples where each tuple contains
* corresponding elements from both input arrays.
*
* @template T - The type of elements in the arrays.
* @param arr1 - The first input array.
* @param arr2 - The second input array.
* @returns - An array of tuples containing corresponding elements from both input arrays.
*/
```


### shuffle
```typescript
/**
Expand Down Expand Up @@ -433,6 +477,17 @@ the following utility functions are available in the `FunctionUtils` class, they
```


### retry
```typescript
/**
* Retries a given function a specified number of times if it fails.
* @param fn - The function to be retried.
* @param retries - The number of times to retry the function.
* @returns A promise that resolves with the result of the function if it succeeds, or rejects with the last error if it fails after all retries.
*/
```


### compose
```typescript
/**
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "typelegend",
"version": "0.1.16",
"version": "0.1.17",
"module": "dist/index.mjs",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
11 changes: 11 additions & 0 deletions src/array/diff.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* Returns an array containing the elements from `arr1` that are not present in `arr2`.
*
* @template T - The type of elements in the arrays.
* @param {T[]} arr1 - The first array.
* @param {T[]} arr2 - The second array.
* @returns {T[]} - The difference between `arr1` and `arr2`.
*/
export function diff<T>(arr1: T[], arr2: T[]): T[] {
return arr1.filter((value) => !arr2.includes(value));
}
9 changes: 9 additions & 0 deletions src/array/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@

import { union } from "./union";
import { diff } from "./diff";
import { sample } from "./sample";
import { intersect } from "./intersect";
import { zip } from "./zip";
import { shuffle } from "./shuffle";
import { chunk } from "./chunk";
import { random } from "./random";
Expand All @@ -9,8 +12,11 @@ import { range } from "./range";
import { flatten } from "./flatten";

export class ArrayUtils {
static union: typeof union = union;
static diff: typeof diff = diff;
static sample: typeof sample = sample;
static intersect: typeof intersect = intersect;
static zip: typeof zip = zip;
static shuffle: typeof shuffle = shuffle;
static chunk: typeof chunk = chunk;
static random: typeof random = random;
Expand All @@ -19,8 +25,11 @@ export class ArrayUtils {
static flatten: typeof flatten = flatten;
}

export { union } from "./union";
export { diff } from "./diff";
export { sample } from "./sample";
export { intersect } from "./intersect";
export { zip } from "./zip";
export { shuffle } from "./shuffle";
export { chunk } from "./chunk";
export { random } from "./random";
Expand Down
11 changes: 11 additions & 0 deletions src/array/union.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* Returns a new array that contains unique elements from both input arrays.
*
* @template T - The type of elements in the arrays.
* @param arr1 - The first input array.
* @param arr2 - The second input array.
* @returns A new array that contains unique elements from both input arrays.
*/
export function union<T>(arr1: T[], arr2: T[]): T[] {
return [...new Set([...arr1, ...arr2])];
}
13 changes: 13 additions & 0 deletions src/array/zip.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* Zips two arrays together, creating an array of tuples where each tuple contains
* corresponding elements from both input arrays.
*
* @template T - The type of elements in the arrays.
* @param {T[]} arr1 - The first input array.
* @param {T[]} arr2 - The second input array.
* @returns {[T, T][]} - An array of tuples containing corresponding elements from both input arrays.
*/
export function zip<T>(arr1: T[], arr2: T[]): [T, T][] {
const minLength = Math.min(arr1.length, arr2.length);
return arr1.slice(0, minLength).map((value, index) => [value, arr2[index]]);
}
3 changes: 3 additions & 0 deletions src/function/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,23 @@
import { throttle } from "./throttle";
import { debounce } from "./debounce";
import { curry } from "./curry";
import { retry } from "./retry";
import { compose } from "./compose";
import { memoize } from "./memoize";

export class FunctionUtils {
static throttle: typeof throttle = throttle;
static debounce: typeof debounce = debounce;
static curry: typeof curry = curry;
static retry: typeof retry = retry;
static compose: typeof compose = compose;
static memoize: typeof memoize = memoize;
}

export { throttle } from "./throttle";
export { debounce } from "./debounce";
export { curry } from "./curry";
export { retry } from "./retry";
export { compose } from "./compose";
export { memoize } from "./memoize";

14 changes: 14 additions & 0 deletions src/function/retry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Retries a given function a specified number of times if it fails.
* @param fn - The function to be retried.
* @param retries - The number of times to retry the function.
* @returns A promise that resolves with the result of the function if it succeeds, or rejects with the last error if it fails after all retries.
*/
export function retry<T>(fn: () => Promise<T>, retries: number): Promise<T> {
return fn().catch((error) => {
if (retries > 0) {
return retry(fn, retries - 1);
}
throw error;
});
}
32 changes: 32 additions & 0 deletions test/array/diff.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { expect, describe, it } from "bun:test";
import { diff } from "../../src/array/diff";

describe("diff", () => {
it("should return the difference between two arrays", () => {
const arr1 = [1, 2, 3, 4, 5];
const arr2 = [3, 4, 5, 6, 7];
const result = diff(arr1, arr2);
expect(result).toEqual([1, 2]);
});

it("should return an empty array if both arrays are identical", () => {
const arr1 = [1, 2, 3];
const arr2 = [1, 2, 3];
const result = diff(arr1, arr2);
expect(result).toEqual([]);
});

it("should return the first array if the second array is empty", () => {
const arr1 = [1, 2, 3];
const arr2: number[] = [];
const result = diff(arr1, arr2);
expect(result).toEqual(arr1);
});

it("should return an empty array if the first array is empty", () => {
const arr1: number[] = [];
const arr2 = [1, 2, 3];
const result = diff(arr1, arr2);
expect(result).toEqual([]);
});
});
32 changes: 32 additions & 0 deletions test/array/union.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { expect, describe, it } from "bun:test";
import { union } from "../../src/array/union";

describe("union", () => {
it("should return the union of two arrays", () => {
const arr1 = [1, 2, 3, 4, 5];
const arr2 = [3, 4, 5, 6, 7];
const result = union(arr1, arr2);
expect(result).toEqual([1, 2, 3, 4, 5, 6, 7]);
});

it("should return the first array if the second array is empty", () => {
const arr1 = [1, 2, 3];
const arr2: number[] = [];
const result = union(arr1, arr2);
expect(result).toEqual(arr1);
});

it("should return the second array if the first array is empty", () => {
const arr1: number[] = [];
const arr2 = [1, 2, 3];
const result = union(arr1, arr2);
expect(result).toEqual(arr2);
});

it("should return an empty array if both arrays are empty", () => {
const arr1: number[] = [];
const arr2: number[] = [];
const result = union(arr1, arr2);
expect(result).toEqual([]);
});
});
39 changes: 39 additions & 0 deletions test/array/zip.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { expect, describe, it } from "bun:test";
import { zip } from "../../src/array/zip";

describe("zip", () => {
it("should return an array of tuples with corresponding elements from two arrays", () => {
const arr1: number[] = [1, 2, 3];
const arr2: number[] = [4, 5, 6];
const result = zip(arr1, arr2);
expect(result).toEqual([
[1, 4],
[2, 5],
[3, 6],
]);
});

it("should return an empty array if either of the input arrays is empty", () => {
const arr1: number[] = [];
const arr2: number[] = [4, 5, 6];
const result = zip(arr1, arr2);
expect(result).toEqual([]);
});

it("should return an empty array if both input arrays are empty", () => {
const arr1: number[] = [];
const arr2: number[] = [];
const result = zip(arr1, arr2);
expect(result).toEqual([]);
});

it("should truncate the longer array if the input arrays have different lengths", () => {
const arr1: number[] = [1, 2, 3];
const arr2: number[] = [4, 5];
const result = zip(arr1, arr2);
expect(result).toEqual([
[1, 4],
[2, 5],
]);
});
});
18 changes: 18 additions & 0 deletions test/function/retry.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { expect, describe, it, jest } from "bun:test";
import { retry } from "../../src/function/retry";

describe("retry", () => {
it("should resolve with the result of the function if it succeeds on the first try", async () => {
const fn = jest.fn().mockResolvedValue("success");
const result = await retry(fn, 3);
expect(result).toBe("success");
expect(fn).toHaveBeenCalledTimes(1);
});

it("should resolve with the result of the function if it succeeds after multiple retries", async () => {
const fn = jest.fn().mockRejectedValueOnce(new Error("error 1")).mockRejectedValueOnce(new Error("error 2")).mockResolvedValue("success");
const result = await retry(fn, 3);
expect(result).toBe("success");
expect(fn).toHaveBeenCalledTimes(3);
});
});

0 comments on commit 8dd11b1

Please sign in to comment.