Skip to content

Commit

Permalink
FEAT: VERSION 2.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
santi100a committed Jul 29, 2023
1 parent 6ff427b commit 2dbfaaf
Show file tree
Hide file tree
Showing 85 changed files with 7,742 additions and 5,075 deletions.
4 changes: 3 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
"plugin:@typescript-eslint/recommended",
"plugin:jest/recommended"
],
"overrides": [
],
Expand All @@ -19,5 +20,6 @@
"@typescript-eslint"
],
"rules": {
"@typescript-eslint/no-var-requires": "off"
}
}
26 changes: 8 additions & 18 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ on:

jobs:
test:
outputs:
IS_RELEASE_COMMIT: ${{ steps.commit.outputs.IS_RELEASE_COMMIT }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
Expand All @@ -35,40 +37,28 @@ jobs:
- name: Install dependencies
run: yarn
run: npm ci

- name: Validate Markdown links
run: yarn check-links
run: npm run check-links

- name: Validate package.json
run: yarn validate-package-json
run: npm run validate-package-json

- name: Run ESLint
if: env.IS_RELEASE_COMMIT == '1'
run: |
if [ "$IS_RELEASE_COMMIT" -eq "1" ]; then
yarn lint
else
exit 0
fi
npm run lint
- name: Build source code
if: env.IS_RELEASE_COMMIT == '1'
run: |
if [ "$IS_RELEASE_COMMIT" -eq "1" ]; then
yarn build
else
exit 0
fi
npm run build
- name: Run test suites
if: env.IS_RELEASE_COMMIT == '1'
run: |
if [ "$IS_RELEASE_COMMIT" -eq "1" ]; then
yarn test
else
exit 0
fi
npm run test
release:
if: needs.test.outputs.IS_RELEASE_COMMIT == '1'
permissions:
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,9 @@

- Added `assertInstanceOf`, `assertMaxExclusive` and `assertMinExclusive`.
- Modified `randomFromArray` to make sure TypeScript enforces there's at least one element in the input array.

## Version 2.0.0 (MAJOR VERSION; BREAKING CHANGES!)

- **DELETED `assertType`.**
- **Replaced `assertOneOf`'s `shallow` parameter with `comparator` to remove reliance on `@santi100/equal-lib`.**
- Modified module system to use `export =` for all individual module files, whilst keeping compatibility.
219 changes: 112 additions & 107 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
[gh stars badge]: https://img.shields.io/github/stars/santi100a/assertion-lib.svg
[bundlephobia badge]: https://img.shields.io/bundlephobia/min/@santi100/assertion-lib
[discord badge]: https://img.shields.io/badge/Join%20us%20on%20Discord-7289DA?logo=discord&logoColor=white

[actions]: https://github.com/santi100a/assertion-lib/actions
[npm homepage]: https://npmjs.org/package/@santi100/assertion-lib
[repo]: https://github.com/santi100a/assertion-lib
Expand All @@ -23,6 +22,10 @@
- 🚀 Lightweight and fast^
- 👴 ES3-compliant\*
- 💻 Portable between the browser and Node.js
- 📘 Comes with built-in TypeScript definitions
- 📑 Split into a lot of modules (under `cjs/`) so you get to choose what you want
- 🎨 Includes a wide array of assertion functions
- 💪 Very customizable (you get to choose comparison logic, name displayed on error, et cetera)

\*_Hasn't been tested in an actual ES3 environment. Feel free to open an issue or pull request if you find any non-ES3 thing. See "Contribute" for instructions on how to do so._

Expand All @@ -46,185 +49,187 @@ Make sure you follow the [contribution Code of Conduct](https://github.com/santi

### API

- `function assert(condition: boolean, { expected, actual, operator }?: AssertOptionalParams): void;`
**⚠ WARNING:** `assertType`'s documentation is no longer available here, as such function has been removed
from this library since version 2.0.0.

- `function assert(condition: boolean, params?: AssertOptionalParams): void;`

Asserts that `condition` is truthy. Throws an `AssertionError` otherwise.
| Parameter | Type | Description |
|-------------------------|------------------------------|-------------------------------------------|

| Parameter | Type | Description |
| ----------------------- | ---------------------------- | ----------------------------------------- |
| `condition` | `boolean` | The condition to assert. |
| `assertParams` | `AssertOptionalParams<E, A>` | `AssertionError` options. |
| `assertParams.expected` | `E` | Expected value for the assertion. |
| `assertParams.actual` | `A` | Received value for the assertion. |
| `assertParams.operator` | `string` | Optional operator used for the assertion. |

- ~~`function assertType(val: unknown, expectedType: Type): void;`~~ (deprecated as per 1.0.8)
Asserts that the type of `val` is `expectedType`. Throws an `AssertionError` otherwise.
| Parameter | Type | Description |
|-------------------------|------------------------------|-------------------------------------------|
| `val` | `unknown` | An expression whose type is to be asserted. |
| `expectedType` | `Type` | The type to assert. |

**DEPRECATED: Use `assertTypeOf` instead.**

- `function assertTypeOf(arg: any, expectedType: Type, name: string): void;` (since 1.0.6, `name` is optional since 1.0.8)

Asserts that the type of `arg` is `expectedType`. Throws a `TypeError` otherwise.
| Parameter | Type | Description |
| Parameter | Type | Description |
|-------------------------|------------------------------|-------------------------------------------|
| `arg` | `any` | An expression whose type is to be asserted. |
| `expectedType` | `Type` | The expected type. |
| `name` | `string` | An optional expression name to be put in the `TypeError`'s message. Defaults to "arg". |
| `arg` | `any` | An expression whose type is to be asserted. |
| `expectedType` | `Type` | The expected type. |
| `name` | `string` | An optional expression name to be put in the `TypeError`'s message. Defaults to "arg". |

- `function assertOneOf<T = unknown>(arg: any, name: string, choices: any[]): void;` (since 1.0.6, type param bound to `choices` added in 1.0.8)

Asserts `arg` is one of `choices`, using `comparator` to compare `arg` against each choice.
Throws a `TypeError` otherwise.

- `function assertOneOf(arg: any, name: string, choices: any[]): void;` (since 1.0.6, type param bound to `choices` added in 1.0.8)
Asserts `arg` is one of `choices`. Throws a `TypeError` otherwise.
**WARNING:**
**Since v2, the `shallow` argument is no longer valid -- it has been replaced with `comparator`.**

| Parameter | Type | Description |
|--------------------------|------------------------------|-------------------------------------------|
| `arg` | `any` | The value that's expected to be included within `choices`. |
| `name` | `string` | An expression name to be put in the `TypeError`'s message. |
| `choices` | `any[]` | An array containing the posible values `arg` should have in order for an error not to be thrown. |
| `shallow?` (since 1.0.8) | `boolean` or `undefined` | Whether or not to use shallow equality (default deep equality is powered by [`@santi100/equal-lib`](https://github.com/santi100a/equal-lib) 😉).
This is done so you can use this library without the need to install `@santi100/equal-lib`, whilst also
adding flexibility to use custom comparison logic or the deep equality library of your choice.

| Parameter | Type | Description |
| --------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| `arg` | `any` | The value that's expected to be included within `choices`. |
| `name` | `string` | An expression name to be put in the `TypeError`'s message. |
| `choices` | `T[]` | An array containing the posible values `arg` should have in order for an error not to be thrown. |
| `comparator?` (since 2.0.0) | `(a: unknown, b: T) => boolean` or `undefined` | A custom comparator to add, for instance, deep equality! |

- `function assertInteger(arg: number, name: string): void;` (since 1.0.6)
Asserts `arg` is an integer. Throws a `TypeError` otherwise.

Asserts `arg` is an integer. Throws a `TypeError` otherwise.

- `function assertMin(arg: any, name: string, min: any): void;` (since 1.0.6)

Asserts `arg` is bigger or equal than `min`. Throws a `TypeError` otherwise.

- `function assertMax(arg: any, name: string, max: any): void;` (since 1.0.6)

Asserts `arg` is smaller or equal than `max`. Throws a `TypeError` otherwise.

- `function assertRange(arg: any, name: string, min: any, max: any): void;` (since 1.0.6)
Asserts `arg` is between `min + 1` and `max + 1` (inclusive). Throws a `TypeError`
(`RangeError` since 1.0.7) otherwise.

Asserts `arg` is **NEITHER** smaller than `min` **NOR** bigger than `max`.
Throws a `TypeError` (`RangeError` since 1.0.7) otherwise.

- `function assertArray(arg: any, name?: string): void;` (since 1.0.7)

Asserts `arg` is an Array. Throws a `TypeError` otherwise.

## Usage example

```typescript
import assertType = require('@santi100/assertion-lib/cjs/type'); // TypeScript for individual functions
import {
assert,
assertType,
assertTypeOf,
assertOneOf,
assertInteger,
assertMin,
assertMax,
AssertionError,
Type
assert,
assertTypeOf,
assertOneOf,
assertInteger,
assertMin,
assertMax,
AssertionError,
Type
} from '@santi100/assertion-lib'; // ESM
const {
assert,
assertType,
assertTypeOf,
assertOneOf,
assertInteger,
assertMin,
assertMax,
AssertionError
assert,
assertTypeOf,
assertOneOf,
assertInteger,
assertMin,
assertMax,
AssertionError
} = require('@santi100/assertion-lib'); // CJS

function sum(a: number, b: number) {
assertType(a, 'number');
assertType(b, 'number');
assertType(a, 'number');
assertType(b, 'number');

return a + b;
return a + b;
}

function divide(a: number, b: number) {
assertType(a, 'number');
assertType(b, 'number');
assert(b !== 0, { expected: 'non-zero number', actual: b, operator: '!==' });
assertType(a, 'number');
assertType(b, 'number');
assert(b !== 0, { expected: 'non-zero number', actual: b, operator: '!==' });

return a / b;
return a / b;
}

function getGreeting(name: string, language: string) {
assertType(name, 'string');
assertOneOf(language, 'language', ['en', 'es']);
assertType(name, 'string');
assertOneOf(language, 'language', ['en', 'es']);

const greetings = {
en: 'Hello',
es: 'Hola'
};
const greetings = {
en: 'Hello',
es: 'Hola'
};

return `${greetings[language]}, ${name}!`;
return `${greetings[language]}, ${name}!`;
}

function getFactorial(n: number) {
assertType(n, 'number');
assertInteger(n, 'n');
assertMin(n, 'n', 0);
assertType(n, 'number');
assertInteger(n, 'n');
assertMin(n, 'n', 0);

let result = 1;
for (let i = 2; i <= n; i++) {
result *= i;
}
let result = 1;
for (let i = 2; i <= n; i++) {
result *= i;
}

return result;
return result;
}

try {
// Example of a failed assertion:
assert(1 === 2);
// Example of a failed assertion:
assert(1 === 2);
} catch (error) {
if (error instanceof AssertionError) {
console.log('Expected:', error.expected); // 2
console.log('Actual:', error.actual); // 1
console.log('Operator:', error.operator); // '==='
}
if (error instanceof AssertionError) {
console.log('Expected:', error.expected); // 2
console.log('Actual:', error.actual); // 1
console.log('Operator:', error.operator); // '==='
}
}

try {
// Example of a type assertion:
assertType('hello', 'number');
} catch (error) {
if (error instanceof AssertionError) {
console.log(error.message); // 'Assertion failed! Expected number. Got string when using operator typeof.'
}
}

try {
// Example of an assertion with custom error parameters:
divide(10, 0);
// Example of an assertion with custom error parameters:
divide(10, 0);
} catch (error) {
if (error instanceof AssertionError) {
console.log(error.message); // 'Assertion failed! Expected non-zero number. Got 0 when using operator !==.'
}
if (error instanceof AssertionError) {
console.log(error.message); // 'Assertion failed! Expected non-zero number. Got 0 when using operator !==.'
}
}

try {
// Example of an assertion with one of:
getGreeting('John', 'fr');
// Example of an assertion with one of:
getGreeting('John', 'fr');
} catch (error) {
if (error instanceof TypeError) {
console.log(error.message); // '"language" must be one of "en, es". Got "fr" of type "string".'
}
if (error instanceof TypeError) {
console.log(error.message); // '"language" must be one of "en, es". Got "fr" of type "string".'
}
}

try {
// Example of an integer assertion:
getFactorial(3.5);
// Example of an integer assertion:
getFactorial(3.5);
} catch (error) {
if (error instanceof TypeError) {
console.log(error.message); // '"n" must be an integer. Got "3.5" of type "number".'
}
if (error instanceof TypeError) {
console.log(error.message); // '"n" must be an integer. Got "3.5" of type "number".'
}
}

try {
// Example of a minimum assertion:
getFactorial(-1);
// Example of a minimum assertion:
getFactorial(-1);
} catch (error) {
if (error instanceof TypeError) {
console.log(error.message); // '"n" must be bigger than 0. Got "-1" of type "number".'
}
if (error instanceof TypeError) {
console.log(error.message); // '"n" must be bigger than 0. Got "-1" of type "number".'
}
}

try {
// Example of a maximum assertion:
assertMax(10, 'n', 5);
// Example of a maximum assertion:
assertMax(10, 'n', 5);
} catch (error) {
if (error instanceof TypeError) {
console.log(error.message); // '"n" must be smaller than 5. Got "10" of type "number".'
}
if (error instanceof TypeError) {
console.log(error.message); // '"n" must be smaller than 5. Got "10" of type "number".'
}
}
```
Loading

0 comments on commit 2dbfaaf

Please sign in to comment.