diff --git a/CHANGELOG.md b/CHANGELOG.md index db7d0c4..d222b57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,63 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [3.0.0-rc] - 2022-02-16 + +### [3.0.0-rc] Added + +- Add `define()`, `isValidationError()` static method to the `ValidationError` object. [b261662] [eb2d8e2] +- Add the generic type variable `Id` to the `ValidationError`. [eb2d8e2] +- Add `[Symbol.toStringTag]()` get accessor to return the object different class name. [eb2d8e2] +- Add `ValidationErrors` object that is is an extension of the `CommonErrors` object that represents multiple identification numbers under which the errors of the `ValidationError` type are prepared to throw. [43a0162] +- Add `TypeErrors` object that is an extension of the `CommonErrors` object that represents multiple identification numbers under which the errors of the `TypeError` type are prepared to throw. [ff2feeb] +- Add `TypeError` object that is an extension of the `CommonError` class and is thrown when an operation could not be performed, typically(but not exclusively) when a value is not of the expected type, with the message built from the described problem and its solution, optional an explicit identification and type, on the given or stored template. [8112c16] +- Add `RangeErrors` object that is an extension of the `CommonErrors` object that represents multiple identification numbers under which the errors of the `RangeError` type are prepared to throw. [72b8582] +- Add `RangeError` object that is an extension of the `CommonError` class and is thrown when a value is not in the set or range of allowed values with the message built from the described problem and its solution, optional explicit identification and minimum/maximum range on the given or stored template. [77e4e0a] +- Add `Errors` object that is an extension of the `CommonErrors` object that represents multiple identification numbers under which the errors of the `Error` type are prepared to throw. [a5f391c] +- Add `Error` object that is an extension of the `CommonError` class and is thrown when a runtime error occurs with a message built from a solution to the described problem but with additional identification, on the template. [789083e] +- Add `CommonErrors` object that represents the storage of errors with unique identification numbers. [a17461b] +- Add `CommonError` abstract object to throw an identified error with a solution to the described problem, additional type, and range built on the template. [9089375] + +### [3.0.0-rc] Changed + +- Change the `constructor()` of the `ValidationError` to use direct parameters instead of object. +- Change `#tpl` property to `#template` and the default value to `Problem{id}: {problem} => Fix: {fix}`. +- Change the property `name` to `name` accessor. + +### [3.0.0-rc] Removed + +- Remove `#callback` private property from the `ValidationError` to simplify the object. +- Remove `VEAllowedCallback` type and `ErrorMessage` interface to simplify the object. [00229cd] [30716b2] +- Remove `set problem()`, `set message()`, `set fix()`, `set template()` accessors of an `ValidationError` instance. [b261662] +- Remove `#guardMessage()`, `#guardTemplate()`, `defineMessage()`, static method from the `ValidationError()`. [b261662] +- Remove `updateMessage()`, `throw()`, `setTemplate()`, `setProblem()`, `setMessage()`, `setFix()` instance method from the `ValidationError()`. [b261662] + +[eb2d8e2]: https://github.com/angular-package/error/commit/eb2d8e243ff6ee5f44fd00e4d462d2b2c175702a +[b261662]: https://github.com/angular-package/error/commit/b2616625bb80790f97da9138f75305ceb3c55af2 +[30716b2]: https://github.com/angular-package/error/commit/30716b22970218bb4745d0482908e55138467833 +[00229cd]: https://github.com/angular-package/error/commit/00229cda3f116766df5d1872519184332ee0402d +[43a0162]: https://github.com/angular-package/error/commit/43a01628af2a73aa428d7d6bcb48e9c3a1c755f3 +[ff2feeb]: https://github.com/angular-package/error/commit/ff2feebe48fdb1b3f8bfe3c58cedc09c8b6402df +[8112c16]: https://github.com/angular-package/error/commit/8112c166a2a7848b166bd4a45996f6e24b42862e +[72b8582]: https://github.com/angular-package/error/commit/72b8582f848075c27bd97ae8a05bed29c287ffd9 +[77e4e0a]: https://github.com/angular-package/error/commit/77e4e0a3760150a515f3a59b5efd5c779221427e +[a5f391c]: https://github.com/angular-package/error/commit/a5f391cbdb3a9a756b0f730bdc3c63232889ce0b +[789083e]: https://github.com/angular-package/error/commit/789083e5c79d6ee0f1f098bcc5a352a8dccf939b +[a17461b]: https://github.com/angular-package/error/commit/15a40397a17461bbd735079c3544c4c44f7b3f45 +[9089375]: https://github.com/angular-package/error/commit/908937597024576ad5d47fd1f1af652c1a2cc265 + +## [2.0.2] - 2021-08-12 + +### 2.0.2 Fixed + +- [`ff06f3a`][ff06f3a] + Fixed `package.json` peer dependencies cause of `@angular-package/callback`. + +[ff06f3a]: https://github.com/angular-package/error/commit/ff06f3ae1b5c922c7605a7fb6301dd238b9e1b7a + ## [2.0.1] - 2021-08-12 -### 2.0.1 Fix +### 2.0.1 Fixed - [`c77f3cf`][c77f3cf] Fix JS documentation of `ValidationError`. @@ -24,15 +78,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### 2.0.0 Added - [`069d111`][069d111] - Added static private property `#template` of a `string` type. - Added private instance `#callback` property of [`Callback`][package-callback] instance. - Added private instance `#fix`, `#problem`, `#tpl` property. - Added pubic methods [`setFix()`][error-method-setfix], [`setMessage()`][error-method-setmessage], [`setProblem()`][error-method-setproblem], [`setTemplate()`][error-method-settemplate], [`throw()`][error-method-throw], [`updateMessage()`][error-method-updatemssage] of an instance. - Added static private methods `#guardMessage()`, `#guardTemplate()`. + Add static private property `#template` of a `string` type. + Add private instance `#callback` property of [`Callback`][package-callback] instance. + Add private instance `#fix`, `#problem`, `#tpl` property. + Add pubic methods [`setFix()`][error-method-setfix], [`setMessage()`][error-method-setmessage], [`setProblem()`][error-method-setproblem], [`setTemplate()`][error-method-settemplate], [`throw()`][error-method-throw], [`updateMessage()`][error-method-updatemssage] of an instance. + Add static private methods `#guardMessage()`, `#guardTemplate()`. - [`4040750`][4040750] - Added an optional property `template` to the [`ErrorMessage`][error-interface-errormessage] interface. + Add an optional property `template` to the [`ErrorMessage`][error-interface-errormessage] interface. - [`0d5cc92`][0d5cc92] - Added [`VEAllowedCallback`][error-type-veallowedcallback] type of allowed names for internal instance of [`Callback`][package-callback]. + Add [`VEAllowedCallback`][error-type-veallowedcallback] type of allowed names for internal instance of [`Callback`][package-callback]. [069d111]: https://github.com/angular-package/error/commit/069d111220b63c2d2cdbffa499f3588121f14e16 [4040750]: https://github.com/angular-package/error/commit/40407503893484874e588b8b5b42c6e40a5fc3ab @@ -78,7 +132,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### 1.0.3 Fixed - [`5427c65`][5427c65] - Added message builder to api. + Add message builder to api. [5427c65]: https://github.com/angular-package/error/commit/5427c6585ddebe01bc6e3733425e07b924ec0ca6 diff --git a/README.md b/README.md index 7fac344..920350d 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,47 @@ -# Packages - -Useful and simple to use packages based on the [angular.io][angulario]. - -| Package | Description | Status | -| :----------------------------------- | :----------------------------------------------------- | -----: | -| [callback][callback-github-readme] | Manages the callback [`function`][js-function]. | [![npm version][callback-npm-badge-png]][callback-npm-badge] | -| [change-detection][cd-github-readme] | Improves application performance. | [![npm version][cd-npm-badge-png]][cd-npm-badge] | -| [component-loader][cl-github-readme] | Handles dynamic loading components. | [![npm version][cl-npm-badge-png]][cl-npm-badge] | -| [core][core-github-readme] | Core features. | [![npm version][core-npm-badge-png]][core-npm-badge] | -| [error][error-github-readme] | Manages an [`Error`][js-error]. | [![npm version][error-npm-badge-png]][error-npm-badge] | -| [prism][prism-github-readme] | [`Prism`][prism-js] highlighter module. | [![npm version][prism-npm-badge-png]][prism-npm-badge] | -| [property][property-github-readme] | Handles object properties. | [![npm version][property-npm-badge-png]][property-npm-badge] | -| [reactive][reactive-github-readme] | Automatize the process of creating some rxjs features. | [![npm version][reactive-npm-badge-png]][reactive-npm-badge] | -| [testing][testing-github-readme] | Support for testing other packages. | [![npm version][testing-npm-badge-png]][testing-npm-badge] | -| [type][type-github-readme] | Common types, type guards, and type checkers. | [![npm version][type-npm-badge-png]][type-npm-badge] | -| [ui][ui-github-readme] | User interface. | *In Progress* | - -> Click on the package name to visit its [GitHub](https://github.com/) page. +# angular-package + + + +The angular-package supports the development process of [angular][angulario]-based applications in varied ways through the thoughtful, reusable, easy-to-use small pieces of code called packages. + +[**docs.angular-package.dev**](https://docs.angular-package.dev) + +
+ +## Packages + +| Package | Description | Status | +| :------------------------------------------- | :---------------------------------------------------------------- | -----: | +| [callback][callback-github-readme] | Manages the callback [`function`][js-function]. | [![npm version][callback-npm-badge-png]][callback-npm-badge] | +| [change-detection][cd-github-readme] | Improves application performance. | [![npm version][cd-npm-badge-png]][cd-npm-badge] | +| [component-loader][cl-github-readme] | Handles dynamic loading components. | [![npm version][cl-npm-badge-png]][cl-npm-badge] | +| [core][core-github-readme] | Core features. | [![npm version][core-npm-badge-png]][core-npm-badge] | +| **[error][error-github-readme]** | **Manages an [`Error`][js-error].** | [![npm version][error-npm-badge-png]][error-npm-badge] | +| [name][name-github-readme] | The name with prefix and suffix. | [![npm version][name-npm-badge-png]][name-npm-badge] | +| [preferences][preferences-github-readme] | Preferences, settings, options, configuration and setup in steps. | [![npm version][preferences-npm-badge-png]][preferences-npm-badge] | +| [prism][prism-github-readme] | [`Prism`][prism-js] highlighter module. | [![npm version][prism-npm-badge-png]][prism-npm-badge] | +| [property][property-github-readme] | Handles object properties. | [![npm version][property-npm-badge-png]][property-npm-badge] | +| [range][range-github-readme] | The range between a minimum and maximum. | [![npm version][range-npm-badge-png]][range-npm-badge] | +| [reactive][reactive-github-readme] | Automatize the process of creating some rxjs features. | [![npm version][reactive-npm-badge-png]][reactive-npm-badge] | +| [storage][storage-github-readme] | The storage of data under allowed names. | [![npm version][storage-npm-badge-png]][storage-npm-badge] | +| [tag][tag-github-readme] | Any tag with optional attributes. | [![npm version][tag-npm-badge-png]][tag-npm-badge] | +| [testing][testing-github-readme] | Support for testing other packages. | [![npm version][testing-npm-badge-png]][testing-npm-badge] | +| [text][text-github-readme] | Text on the template with replaceable tags. | [![npm version][text-npm-badge-png]][text-npm-badge] | +| [type][type-github-readme] | Common types, type guards, and type checkers. | [![npm version][type-npm-badge-png]][type-npm-badge] | +| [ui][ui-github-readme] | User interface. | *In Progress* | +| [wrapper][wrapper-github-readme] | Wrap the text with the opening and closing chars. | [![npm version][wrapper-npm-badge-png]][wrapper-npm-badge] | + +Click on the package name to visit its [GitHub](https://github.com/) page. + +
## angular-package/error Manages an [`Error`][js-error]. +[![Gitter][gitter-badge]][gitter-chat] +[![Discord][discord-badge]][discord-channel] +[![Twitter][twitter-badge]][twitter-follow] [![npm version][error-npm-badge-svg]][error-npm-badge] @@ -33,62 +53,52 @@ Manages an [`Error`][js-error]. [![GitHub sponsors][github-badge-sponsor]][github-sponsor-link] [![Support me on Patreon][patreon-badge]][patreon-link] ----- +
+ +## Documentation + +For the detailed documentation go to [**https://error.angular-package.dev**](https://error.angular-package.dev) + +
## Table of contents -* [Basic concepts](#basic-concepts) * [Skeleton](#skeleton) * [Installation](#installation) -* [Api](#api) -* [`ValidationError`](#validationerror) -* [Interface](#interface) -* [Type](#type) -* [Experimental](#experimental) * [Changelog](#changelog) * [Git](#git) * [Commit](#commit) * [Versioning](#versioning) * [License](#license) ----- -
-## Basic concepts - -Checks -> It's to check the provided value to be **the same** as **expected**. - -Type guard (constrain) -> Constrains the parameter type to **not let** input **unexpected** value in the **code editor**. +## Skeleton -Guards -> It's a **combination** of both above, **constrains** the type of the parameter in the **code editor**, and checks its provided argument. +This package was built by the [library skeleton][skeleton] which was generated with [Angular CLI](https://github.com/angular/angular-cli) version 12.2.5. -Defines -> Returns defined value from a method of an object. -> Defines new value in an object and returns a defined value. +Copy this package to the `packages/error` folder of the [library skeleton][skeleton] then run the commands below. -Gets -> Returns a value from an object. +### Code scaffolding -Sets -> Adds or updates an element with a specified key and a value to an object and returns an object. +Run `ng generate component component-name --project error` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project storage`. +> Note: Don't forget to add `--project error` or else it will be added to the default project in your `angular.json` file. -
+### Build -## Skeleton +Run `ng build error` to build the package. The build artifacts will be stored in the `dist/` directory. -This package was built by the [library skeleton][skeleton] which was generated with [Angular CLI](https://github.com/angular/angular-cli) version 12.1.1. +### Publishing -Copy this package to the `packages/error` folder of the [library skeleton][skeleton] then run the commands below. +After building your library with `ng build error`, go to the dist folder `cd dist/error` and run `npm publish`. -### Build +### Running unit tests -Run `ng build error` to build the package. The build artifacts will be stored in the `dist/` directory. +Install `@angular-package/testing` with command: -### Running unit tests +```typescript +npm i @angular-package/testing --no-save +``` Run `ng test error` to execute the unit tests via [Karma](https://karma-runner.github.io). @@ -104,1029 +114,6 @@ npm i @angular-package/error --save
-## Api - -```typescript -import { - // Class. - ValidationError, - // Interface. - ErrorMessage, -} from '@angular-package/error'; -``` - -```typescript -/* - * Experimental. - */ -import { - // Class. - MessageBuilder, - MessageBuilderTemplate, - MessageFunctionBuilder, -} from '@angular-package/error'; -``` - -
- -## `ValidationError` - -Manages an [`Error`][js-error] of validation. - -**Static properties:** - -| ValidationError. | Description | -| :-------------------------------------------- | :---------- | -| [`template: string`][error-property-template] | A template of the error message guarded by a [`string`][js-string] type with the replaceable `[problem]` and `[fix]` words. By default, it's set to `'Problem: [problem] => Fix: [fix]'`. | - -[error-property-template]: #validationerrortemplate - -**Instance properties:** - -| ValidationError.prototype. | Description | -| :------------------------------------------ | :---------- | -| [`fix: string`][error-property-fix] | A possible solution to the described [`problem`][error-property-problem] of validation that is guarded by a [`string`][js-string] type. | -| [`message: string`][error-property-message] | A validation error message guarded by a [`string`][js-string] type that can be built with the [`problem`][error-property-problem] and [`fix`][error-property-fix] of [`ValidationError`](#validationerror) on the [`template`][error-property-template] by the [`throw()`][error-method-throw] and [`setMessage()`][error-method-setmessage] method. | -| [`name: string`][error-property-name] | Error name of a [`string`][js-string] type that is being thrown. | -| [`problem: string`][error-property-problem] | Description of a validation [`problem`][error-property-problem] guarded by a [`string`][js-string] type. | - -[error-property-fix]: #validationerrorprototypefix -[error-property-message]: #validationerrorprototypemessage -[error-property-name]: #validationerrorprototypename -[error-property-problem]: #validationerrorprototypeproblem - -**Static methods:** - -| ValidationError. | Description | -| :------------------------------------------------- | :---------- | -| [`defineMessage()`](#validationerrordefinemessage) | Defines the validation error message of a [`string`][js-string] type from the provided `message` of the [`ErrorMessage`](#errormessage) interface. | - -**Constructor:** - -| Constructor | Description | -| :-------------------------------------------------- | :---------- | -| [`ValidationError()`](#validationerror-constructor) | Creates a new instance with the message. If the provided `message` is an [`object`][js-object], then its properties are assigned to the instance. | - -**Instance methods:** - -| ValidationError.prototype. | Description | -| :---------------------------------------------- | :---------- | -| [`setFix()`][error-method-setfix] | Sets the fix a possible solution to the described [`problem`][error-property-problem]. | -| [`setMessage()`][error-method-setmessage] | Sets the validation error message of a [`string`][js-string] type from the provided `message` of the [`ErrorMessage`](#errormessage) interface. | -| [`setProblem()`][error-method-setproblem] | Sets description problem of a validation. | -| [`setTemplate()`][error-method-settemplate] | Sets the template of validation error message. | -| [`throw()`][error-method-throw] | Throws an error of [`ValidationError`](#validationerror) with actual settings. | -| [`updateMessage()`][error-method-updatemessage] | Updates the message with a stored [`fix`][error-property-fix], [`problem`][error-property-problem], and [`template`][error-property-template]. | - -[error-method-setfix]: #validationerrorprototypesetfix -[error-method-setmessage]: #validationerrorprototypesetmessage -[error-method-setproblem]: #validationerrorprototypesetproblem -[error-method-settemplate]: #validationerrorprototypesettemplate -[error-method-throw]: #validationerrorprototypethrow -[error-method-updatemessage]: #validationerrorprototypeupdatemessage - -
- -### `ValidationError` static properties - ----- - -#### `ValidationError.template` - -![update] - -**`2.0.0`:** Uses static private property `#template` and guards the value with private static method `#guardTemplate()` to be [`string`][js-string] type that contains `[fix]` and `[problem]` words. - -A template of the error message guarded by [`string`][js-string] type with the replaceable `[problem]` and `[fix]` words. By default, it's set to `Problem: [problem] => Fix: [fix]`. It can be set directly or by the [`setTemplate()`][error-method-settemplate] and [`setMessage()`][error-method-setmessage] method. The value is being checked against the existence of `[problem]` and `[fix]` words. - -```typescript -static get template(): string { - return ValidationError.#template; -} -static set template(value: string) { - ValidationError.#template = ValidationError.#guardTemplate(value) - ? value - : ValidationError.#template; -} -``` - -
- -### `ValidationError` instance public properties - ----- - -#### `ValidationError.prototype.fix` - -![update] - -**`2.0.0`:** Uses static private property `#fix` and guards the value to be a [`string`][js-string] type. - -A possible solution to the described [`problem`][error-property-problem] of validation that is guarded by a [`string`][js-string] type. By default, it's an empty [`string`][js-string]. It can be set directly or by the [`setFix()`][error-method-setfix] and [`setMessage()`][error-method-setmessage] method. - -```typescript -public get fix(): string { - return this.#fix; -} -public set fix(value: string) { - this.#fix = guard.string(value) ? value : this.#fix; -} -``` - -
- -#### `ValidationError.prototype.message` - -![update] - -**`2.0.0`:** Uses inherited from [`Error`][js-error] property and guards the value to be a [`string`][js-string] type. - -A validation error message guarded by a [`string`][js-string] type that can be build from the [`problem`][error-property-problem] and [`fix`][error-property-fix] of [`ValidationError`](#validationerror) on the [`template`][error-property-template]. It can be set directly or by the [`throw()`][error-method-throw] and [`setMessage()`][error-method-setmessage] method. - -```typescript -public set message(value: string) { - super.message = guard.string(value) ? value : super.message; -} -public get message(): string { - return super.message; -} -``` - -
- -#### `ValidationError.prototype.name` - -Error name of a [`string`][js-string] type that is being thrown. By default, it's ['ValidationError'](#validationerror). - -```typescript -public name = ValidationError.name; -``` - -
- -#### `ValidationError.prototype.problem` - -![update] - -Description of a validation [`problem`][error-property-problem] guarded by a [`string`][js-string] type. By default, it's an empty [`string`][js-string]. It can be set directly or by the [`setProblem()`][error-method-setproblem] and [`setMessage()`][error-method-setmessage] method. - -```typescript -public get problem(): string { - return this.#problem; -} -public set problem(value: string) { - this.#problem = guard.string(value) ? value : this.#problem; -} -``` - -
- -### `ValidationError` static methods - ----- - -#### `ValidationError.defineMessage()` - -![update] - -**`2.0.0`:** Adds template to the provided `message` instead of separate parameter and guards it with a static `#guardMessage()` method. - -Defines the validation error message of a [`string`][js-string] type from the provided `message` of the [`ErrorMessage`](#errormessage) interface. - -```typescript -// Syntax. -public static defineMessage( - message: ErrorMessage, - callback?: ResultCallback -): string { - return ValidationError.#guardMessage(message, callback) - ? (message.template || ValidationError.template) - .replace(`[fix]`, message.fix) - .replace(`[problem]`, message.problem) - : ''; -} -``` - -**Parameters:** - -| Name: type | Description | -| :-------------------------- | :---------- | -| `message: ErrorMessage` | An [`object`][js-object] of the [`ErrorMessage`](#errormessage) interface to build a message of a [`string`][js-string] type. The value is checked against the proper [`object`][js-object] | -| `callback?: ResultCallback` | An optional callback function of [`ResultCallback`][package-callback-resultcallback] type to handle the check whether the provided message contains required `problem` and `fix` properties | - -**Returns:** - -The **return value** is a message of a [`string`][js-string] type created from the provided `message` of [`ErrorMessage`](#errormessage) interface, or it's an empty [`string`][js-string] if the provided message [`object`][js-object] isn't proper. - -**Usage:** - -```typescript -// Example usage. -import { ValidationError } from '@angular-package/error'; - -const fix = 'There is no solution to the described problem.'; -const problem = 'The problem has no solution.'; - -/* - Returns - -------- - Problem: The problem has no solution. => Fix: There is no solution - to the described problem. -*/ -const errorMessage = ValidationError.defineMessage({ fix, problem }); -``` - -```typescript -/* - Example usage: create an error message of a string type - from the provided object with a different template. -*/ -import { ValidationError } from '@angular-package/error'; - -const fix = 'There is no solution to the described problem.'; -const problem = 'The problem has no solution.'; -const template = `[problem] ... [fix]`; - -/* - Returns - -------- - The problem has no solution. ... There is no solution to the described problem. -*/ -const errorMessage = ValidationError.defineMessage({ - fix, problem, template -}); -``` - -```typescript -/* - Example usage: create an error message of a string type - from the provided object and the changed template. -*/ -import { ValidationError } from '@angular-package/error'; - -const fix = 'There is no solution to the described problem.'; -const problem = 'The problem has no solution.'; - -// Change the template by directly assign a new value. -ValidationError.template = `\nPROBLEM: [problem]\nFIX: [fix] `; - -/* - Returns - ------- - PROBLEM: The problem has no solution. - FIX: There is no solution to the described problem. -*/ -const errorMessage = ValidationError.defineMessage({ fix, problem }); -``` - -```typescript -/* - Example usage: create an error message of a string type - from the provided object and the changed template. -*/ -import { ValidationError } from '@angular-package/error'; - -const fix = 'There is no solution to the described problem.'; -const problem = 'The problem has no solution.'; - -const errorMessage = ValidationError.defineMessage( - { fix, problem }, - (result, payload) => { - // Do something with the `result` of the `message` check - // and `payload`. - return result; - } -); -``` - -
- -### `ValidationError` constructor - ----- - -#### `ValidationError()` - -![update] - -**`2.0.0`:** Adds template to the provided `message` instead of separate parameter and uses a new method [`setMessage()`][error-method-setmessage] to set message. Handle the callback for all instance methods with the callback parameter. - -Creates a new instance with the message. If the provided `message` is an [`object`][js-object], then its properties are assigned to the instance. - -```typescript -// Syntax. -constructor( - message: string | ErrorMessage = '', - callback?: (callback: Callback) => void -) { - super(); - - // Sets the callback for an instance methods. - if (is.function(callback)) { - callback(this.#callback); - } - - // Initializes the message and assigns message properties `fix`, `problem` and optionally `template` to a new instance. - this.setMessage(message); -} -``` - -**Parameters:** - -| Name: type | Description | -| :----------------------------------------------------------- | :---------- | -| `message: string \| ErrorMessage` | The message of a [`string`][js-string] type or of an [`ErrorMessage`](#errormessage) interface that is used to throw with an [`Error`][js-error]. | -| `callback?: (callback: Callback) => void` | An optional function to handle the internal instance of [`Callback`][callback-github-readme]. | - -**Returns:** - -The **return value** is an instance of [`ValidationError`](#validationerror). - -**Usage:** - -```typescript -// Example usage. -import { ValidationError } from '@angular-package/error'; - -const fix = 'There is no solution to the described problem.'; -const problem = 'The problem has no solution.'; - -const validationError = new ValidationError({ fix, problem }); -``` - -```typescript -// Example usage with callback. -import { ValidationError } from '@angular-package/error'; - -// Define a fix. -const fix = 'There is no solution to the described problem.'; - -// Define a problem. -const problem = 'The problem has no solution.'; - -// Define a template. -const template = 'PROBLEM: [problem] FIX: [fix]'; - -// Initialize an instance. -const validationError = new ValidationError( - { fix, problem, template }, - (callback) => { - callback - /* - Console: false, - { - "fix": "There is no solution to the described problem.", - "problem": "The problem has no solution.", - "template": "PROBLEM: [problem] FIX: [fix]" - } - - Console: true, - { - "fix": "There is no solution to the described problem.", - "problem": "The problem has no solution.", - "template": "PROBLEM: [problem] FIX: [fix]" - } - */ - .setResultCallback('setFix', (result, payload) => - console.log(`setFix`, result, payload); - ) - - // Console: 'setFix true There is no solution to the described problem.' - .setResultCallback('setMessage', (result, payload) => - console.log(`setMessage`, result, payload); - ) - - // Console: 'setProblem true The problem has no solution.' - .setResultCallback('setProblem', (result, payload) => - console.log(`setProblem`, result, payload); - ) - - // Console: 'setTemplate true PROBLEM: [problem] FIX: [fix]' - .setResultCallback('setTemplate', (result, payload) => - console.log(`setTemplate`, result, payload); - ); - } -); -``` - -
- -### `ValidationError` instance public methods - ----- - -#### `ValidationError.prototype.setFix()` - -![new] - -Sets the [`fix`][error-property-fix] a possible solution to the described [`problem`][error-property-problem]. - -```typescript -// Syntax. -public setFix( - fix: string, - callback: ResultCallback = this.#callback.getCallback( - 'setFix' - ) -): this { - if (guard.string(fix, callback)) { - this.#fix = fix; - } - return this; -} -``` - -**Parameters:** - -| Name: type | Description | -| :------------------------------------------- | :---------- | -| `fix: string` | A possible solution to the described problem guarded by a [`string`][js-string] type. | -| `callback?: ResultCallback` | An optional callback function of [`ResultCallback`][package-callback-resultcallback] type to handle the check whether the provided [`fix`][error-property-fix] is a [`string`][js-string]. By default, it uses an internal callback under the `'setFix'` name, which can be initially set by the optional `callback` parameter that gives access to the internal instance of [`Callback`][callback-github-readme]. | - -**Returns:** - -The **return value** is an instance of an [`ValidationError`](#validationerror). - -**Usage:** - -```typescript -// Example usage. -import { ValidationError } from '@angular-package/error'; - -// Initialize an instance. -const validationError = new ValidationError(); - -// Define a fix. -const fix = 'There is no solution to the described problem.'; - -// Returns 'There is no solution to the described problem.' -validationError.setFix(fix).fix; -``` - -```typescript -// Example usage with a callback. -import { ValidationError } from '@angular-package/error'; - -// Initialize an instance. -const validationError = new ValidationError(); - -// Define a fix. -const fix = 'There is no solution to the described problem.'; - -// Set the fix and handle the check of it with a callback. -validationError.setFix(fix, (result, payload) => { - // Returns `true`. - result; - // Returns `There is no solution to the described problem.`. - payload; - return result; -}); -``` - -
- -#### `ValidationError.prototype.setMessage()` - -![new] - -Sets the validation error message of a [`string`][js-string] type from the provided `message` of the [`ErrorMessage`](#errormessage) interface. - -```typescript -// Syntax. -public setMessage( - message: string | ErrorMessage, - callback: ResultCallback< - CallbackPayload & ErrorMessage - > = this.#callback.getCallback('setMessage') -): this { - this.message = is.string(message, callback) - ? // Sets a message of a string type from the provided message of `string`. - message - : // Sets a message of a string type from the provided message of `ErrorMessage`. - ValidationError.defineMessage(message, callback); - - // Sets `fix`, `problem` and optionally `template` from the provided `message`. - if (is.object(message)) { - this.setFix(message.fix).setProblem(message.problem); - if (is.defined(message.template)) { - this.setTemplate(message.template); - } - } - return this; -} -``` - -**Parameters:** - -| Name: type | Description | -| :------------------------------------------- | :---------- | -| `message: string \| ErrorMessage` | An object of an [`ErrorMessage`](#errormessage) interface to build the message of a [`string`][js-string] type. The value is checked against the proper `object`. | -| `callback?: ResultCallback` | An optional callback function of [`ResultCallback`][package-callback-resultcallback] type to handle the check whether the provided `message` is a [`string`][js-string] type or whether it's an object that contains required [`problem`][error-property-problem] and [`fix`][error-property-fix] properties. By default, it uses an internal callback under the `'setMessage'` name, which can be initially set by the optional `callback` parameter that gives access to the internal instance of [`Callback`][callback-github-readme]. | - -**Returns:** - -The **return value** is an instance of an [`ValidationError`](#validationerror). - -**Usage:** - -```typescript -// Example usage with a callback. -import { ValidationError } from '@angular-package/error'; - -// Initialize an instance. -const validationError = new ValidationError(); - -// Define a fix. -const fix = 'There is no solution to the described problem.'; - -// Define a problem. -const problem = 'The problem has no solution.'; - -// Define a template. -const template = 'PROBLEM: [problem], FIX: [fix]'; - -// Set the message and handle the check of it with a callback. -validationError.setMessage({ fix, problem }, (result, payload) => { - // Returns `false` then `true`. - result; - /* - Returns { - "fix": "There is no solution to the described problem.", - "problem": "The problem has no solution.", - "template": "PROBLEM: [problem] FIX: [fix]" - } - */ - payload; - return result; -}); -/* - Returns - PROBLEM: The problem has no solution. FIX: There is no solution to the described problem. -*/ -console.log(validationError.message); -``` - -
- -#### `ValidationError.prototype.setProblem()` - -![new] - -Sets description [`problem`][error-property-problem] of a validation. - -```typescript -public setProblem( - problem: string, - callback: ResultCallback = this.#callback.getCallback( - 'setProblem' - ) -): this { - this.#problem = guard.string(problem, callback) ? problem : this.#problem; - return this; -} -``` - -**Parameters:** - -| Name: type | Description | -| :------------------------------------------- | :---------- | -| `problem: string` | Description of a validation [`problem`][error-property-problem] guarded by a [`string`][js-string] type. | -| `callback?: ResultCallback` | An optional callback function of [`ResultCallback`][package-callback-resultcallback] type to handle the check whether the provided `problem` is a [`string`][js-string]. By default, it uses an internal callback under the `'setProblem'` name, which can be initially set by the optional `callback` parameter that gives access to the internal instance of [`Callback`][callback-github-readme]. | - -**Returns:** - -The **return value** is an instance of an [`ValidationError`](#validationerror). - -**Usage:** - -```typescript -// Example usage. -import { ValidationError } from '@angular-package/error'; - -// Initialize an instance. -const validationError = new ValidationError(); - -// Define a problem. -const problem = 'The problem has no solution.'; - -// Returns 'The problem has no solution.' -validationError.setProblem(problem).problem; -``` - -```typescript -// Example usage with a callback. -import { ValidationError } from '@angular-package/error'; - -// Initialize an instance. -const validationError = new ValidationError(); - -// Define a problem. -const problem = 'The problem has no solution.'; - -// Set the problem and handle the check of it with a callback. -validationError.setProblem(problem, (result, payload) => { - // Returns `true`. - result; - // Returns 'The problem has no solution.' - payload; - return result; -}); -``` - -
- -#### `ValidationError.prototype.setTemplate()` - -![new] - -Sets the [`template`][error-property-template] of validation error message. - -```typescript -public setTemplate( - template: string, - callback: ResultCallback = this.#callback.getCallback( - 'setTemplate' - ) -): this { - this.#tpl = ValidationError.#guardTemplate(template, callback) - ? template - : this.#tpl; - return this; -} -``` - -**Parameters:** - -| Name: type | Description | -| :------------------------------------------- | :---------- | -| `template: string` | A message [`template`][error-property-template] guarded by a [`string`][js-string] type with replaceable `[problem]` and `[fix]` words. | -| `callback?: ResultCallback` | An optional callback function of [`ResultCallback`][package-callback-resultcallback] type to handle the check whether the provided `template` is a [`string`][js-string] that contains `[fix]` and `[problem]` words. By default, it uses an internal callback under the `'setTemplate'` name, which can be initially set by the optional `callback` parameter that gives access to the internal instance of [`Callback`][callback-github-readme]. | - -**Returns:** - -The **return value** is an instance of an [`ValidationError`](#validationerror). - -**Usage:** - -```typescript -// Example usage. -import { ValidationError } from '@angular-package/error'; - -// Initialize an instance. -const validationError = new ValidationError(); - -// Define a template. -const template = 'PROBLEM: [problem], FIX: [fix]'; - -// Set the template. -validationError.setTemplate(template); - -// Returns 'PROBLEM: [problem], FIX: [fix]' -validationError.template; -``` - -```typescript -// Example usage with a callback. -import { ValidationError } from '@angular-package/error'; - -// Initialize an instance. -const validationError = new ValidationError(); - -// Define a template. -const template = 'PROBLEM: [problem], FIX: [fix]'; - -// Set the template and handle the check of it with a callback. -validationError.setTemplate(template, (result, payload) => { - // Returns `true`. - result; - // Returns 'PROBLEM: [problem], FIX: [fix]' - payload; - return result; -}); -``` - -
- -#### `ValidationError.prototype.throw()` - -![new] - -Throws an error of [`ValidationError`](#validationerror) with the message built from the stored [`fix`][error-property-fix], [`problem`][error-property-problem] and [`template`][error-property-template] or optionally from the provided `message`. - -```typescript -public throw(message?: string | ErrorMessage): void { - if (is.defined(message)) { - this.setMessage(message); - } else { - this.updateMessage(); - } - throw this; -} -``` - -**Parameters:** - -| Name: type | Description | -| :--------------------------------- | :---------- | -| `message?: string \| ErrorMessage` | An optional object of an [`ErrorMessage`](#errormessage) interface to build the message of a [`string`][js-string] type. The value is checked against the proper `object`. | - -**Returns:** - -The **return value** is an instance of an [`ValidationError`](#validationerror). - -**Usage:** - -```typescript -// Example usage. -import { ValidationError } from '@angular-package/error'; - -// Define a fix. -const fix = 'There is no solution to the described problem.'; - -// Define a problem. -const problem = 'The problem has no solution.'; - -// Define a template. -const template = 'PROBLEM: [problem] FIX: [fix]'; - -// Initialize an instance. -const validationError = new ValidationError({ fix, problem, template }); - -// Throw an error. -validationError.throw(); -``` - -```typescript -// Example usage. -import { ValidationError } from '@angular-package/error'; - -// Define a fix. -const fix = 'There is no solution to the described problem.'; - -// Define a problem. -const problem = 'The problem has no solution.'; - -// Define a template. -const template = 'PROBLEM: [problem] FIX: [fix]'; - -// Initialize an instance. -const validationError = new ValidationError(); - -// Throw an error with message. -validationError.throw({ fix, problem, template }); -``` - -
- -#### `ValidationError.prototype.updateMessage()` - -![new] - -Updates the message with a stored [`fix`][error-property-fix], [`problem`][error-property-problem], and [`template`][error-property-template]. - -```typescript -public updateMessage(): void { - this.message = ValidationError.defineMessage({ - fix: this.#fix, - problem: this.#problem, - template: this.#tpl, - }); -} -``` - -**Returns:** - -The **return value** is an instance of an [`ValidationError`](#validationerror). - -**Usage:** - -```typescript -// Example usage. -import { ValidationError } from '@angular-package/error'; - -// Define a fix. -const fix = 'There is no solution to the described problem.'; - -// Define a problem. -const problem = 'The problem has no solution.'; - -// Define a template. -const template = 'PROBLEM: [problem] FIX: [fix]'; - -// Initialize an instance. -const validationError = new ValidationError(); - -// Sets defined above fix, problem, and template. -validationError.setProblem(problem).setFix(fix).setTemplate(template); - -// Returns empty string. -validationError.message; - -// Update the message with actual settings. -validationError.updateMessage(); - -/* - Returns - PROBLEM: The problem has no solution. FIX: There is no solution to the described problem. -*/ -validationError.message; - -// Throw. -validationError.throw(); - -// or throw -throw validationError; -``` - -
- -### Another example usage of `ValidationError` - -```typescript -// Example usage. -import { ValidationError } from '@angular-package/error'; - -// Declare shape of the person. -interface Person { - firstName: string; - lastName: string; -} - -// Initialize an instance. -const validationErrorOfPerson = new ValidationError(); - -// Define a fix. -const fix = 'Please, provide only alphabetical characters.'; - -// Create an object. -const personError = { - firstName: validationErrorOfPerson.setMessage({ - problem: 'Provided the first name cannot include special characters.', - fix - }), - lastName: validationErrorOfPerson.setMessage({ - problem: 'Provided the last name cannot include special characters.', - fix - }) -}; - - -const addPerson = (person: Person) => { - if (person.firstName.includes('#')) { - personError.firstName.throw(); - } - if (person.firstName.includes('#')) { - personError.lastName.throw(); - } -}; - -addPerson({ - firstName: '#', - lastName: '#' -}); - -``` - -
- -## Interface - -#### `ErrorMessage` - -![update] - -**`2.0.0`:** Adds an optional `template` property. - -The shape of an [`object`][js-object] for an [`error`][js-error] message that contains a possible solution to the described problem. - -```typescript -export interface ErrorMessage { - fix: string; - problem: string; - template?: string; -} -``` - -**Properties:** - -**`fix: string`** -A possible solution to the described problem of a [`string`][js-string] type. - -**`problem: string`** -Description of validation problem of a [`string`][js-string] type. - -**`template?: string`** -![new] -An optional error message template of a [`string`][js-string] type. - -
- -## Type - -#### `VEAllowedCallback` - -Allowed callback function names available for the [`ValidationError`](#validationerror). - -```typescript -type VEAllowedCallback = 'setFix' | 'setMessage' | 'setProblem' | 'setTemplate'; -``` - -
- -## Experimental - -![experimental] - -### Message builder - -#### `MessageBuilder` - -Message builder for error message of a [`string`][js-string] type. - -```typescript -// Example usage of building a function. -import { MessageBuilder } from '@angular-package/error'; - -/** - * Initialize `MessageBuilder`. - */ -const messageFunctionBuilder = new MessageBuilder('function'); - -messageFunctionBuilder - .setFunctionName('guardString') - .setParam('value', 'string') - .setReturn('boolean'); - -// Console returns `guardString(value: string): boolean` -console.log(messageFunctionBuilder.get); -``` - -```typescript -// Example usage of building a method. -import { MessageBuilder } from '@angular-package/error'; - -/** - * Initialize `MessageBuilder`. - */ -const messageMethodBuilder = new MessageBuilder('method'); - -// Build the method of any class. -messageMethodBuilder - .setMethodName('setPerson') - .setParam('value', 'string') - .setReturn('this'); - -// Console returns `setPerson(value: string): this` -console.log(messageMethodBuilder.get); -``` - -```typescript -// Example usage of building a class. -import { MessageBuilder } from '@angular-package/error'; - -/** - * Initialize `MessageBuilder`. - */ -const messageClassBuilder = new MessageBuilder('class'); - -// Build the method of a specified class. -messageClassBuilder - .setClassName('Person.prototype.') - .setMethodName('setPerson') - .setParam('value?', 'object') - .setReturn('object'); - -// Console returns `Person.prototype.setPerson(value?: object): object` -console.log(messageClassBuilder.get); -``` - -
- -#### `MessageFunctionBuilder` - -Message function builder for error message of a [`string`][js-string] type. - -```typescript -// Example usage of building a function. -import { MessageFunctionBuilder } from '@angular-package/error'; - -/** - * Initialize `MessageFunctionBuilder`. - */ -const messageFunctionBuilder = new MessageFunctionBuilder(); - -messageFunctionBuilder - .setName('guardString') - .setParam('value', 'string') - .setReturn('boolean') - .build(); - -// Console returns `guardString(value: string): boolean` -console.log(messageFunctionBuilder.get); -``` - -
- ## Changelog The **changelog** of this package is based on [*keep a changelog*](https://keepachangelog.com/en/1.0.0/). To read it, click on the [CHANGELOG.md](https://github.com/angular-package/error/blob/main/CHANGELOG.md) link. @@ -1183,6 +170,18 @@ MIT © angular-package ([license][error-license]) [new]: https://img.shields.io/badge/-new-green [update]: https://img.shields.io/badge/-update-red + +[discord-badge]: https://img.shields.io/discord/925168966098386944 +[discord-channel]: https://discord.com/channels/925168966098386944/925168966098386948 + + +[gitter-badge]: https://badges.gitter.im/angularpackage/Lobby.svg +[gitter-chat]: https://gitter.im/angularpackage/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge + + +[twitter-badge]: https://img.shields.io/twitter/url?style=social&label=Follow%20%40angularpackage&url=https%3A%2F%2Ftwitter.com%2Fangularpackage +[twitter-follow]: https://twitter.com/angularpackage + [git-semver]: http://semver.org/ @@ -1203,6 +202,7 @@ MIT © angular-package ([license][error-license]) [error-license]: https://github.com/angular-package/error/blob/master/LICENSE [error-stars]: https://github.com/angular-package/error/stargazers + [error-github-changelog]: https://github.com/angular-package/error/blob/main/CHANGELOG.md @@ -1214,6 +214,7 @@ MIT © angular-package ([license][error-license]) [callback-github-readme]: https://github.com/angular-package/callback#readme + [package-callback-callbackpayload]: https://github.com/angular-package/callback#callbackpayload [package-callback-resultcallback]: https://github.com/angular-package/callback#resultcallback @@ -1256,6 +257,26 @@ MIT © angular-package ([license][error-license]) [error-github-readme]: https://github.com/angular-package/error#readme + + + [name-npm-badge-svg]: https://badge.fury.io/js/%40angular-package%2Fname.svg + [name-npm-badge-png]: https://badge.fury.io/js/%40angular-package%2Fname.png + [name-npm-badge]: https://badge.fury.io/js/%40angular-package%2Fname + [name-npm-readme]: https://www.npmjs.com/package/@angular-package/name#readme + + + [name-github-readme]: https://github.com/angular-package/name#readme + + + + [preferences-npm-badge-svg]: https://badge.fury.io/js/%40angular-package%2Fpreferences.svg + [preferences-npm-badge-png]: https://badge.fury.io/js/%40angular-package%2Fpreferences.png + [preferences-npm-badge]: https://badge.fury.io/js/%40angular-package%2Fpreferences + [preferences-npm-readme]: https://www.npmjs.com/package/@angular-package/preferences#readme + + + [preferences-github-readme]: https://github.com/angular-package/preferences#readme + [prism-npm-badge-svg]: https://badge.fury.io/js/%40angular-package%2Fprism.svg @@ -1276,6 +297,16 @@ MIT © angular-package ([license][error-license]) [property-github-readme]: https://github.com/angular-package/property#readme + + + [range-npm-badge-svg]: https://badge.fury.io/js/%40angular-package%2Frange.svg + [range-npm-badge-png]: https://badge.fury.io/js/%40angular-package%2Frange.png + [range-npm-badge]: https://badge.fury.io/js/%40angular-package%2Frange + [range-npm-readme]: https://www.npmjs.com/package/@angular-package/range#readme + + + [range-github-readme]: https://github.com/angular-package/range#readme + [reactive-npm-badge-svg]: https://badge.fury.io/js/%40angular-package%2Freactive.svg @@ -1286,6 +317,26 @@ MIT © angular-package ([license][error-license]) [reactive-github-readme]: https://github.com/angular-package/reactive#readme + + + [storage-npm-badge-svg]: https://badge.fury.io/js/%40angular-package%2Fstorage.svg + [storage-npm-badge-png]: https://badge.fury.io/js/%40angular-package%2Fstorage.png + [storage-npm-badge]: https://badge.fury.io/js/%40angular-package%2Fstorage + [storage-npm-readme]: https://www.npmjs.com/package/@angular-package/storage#readme + + + [storage-github-readme]: https://github.com/angular-package/storage#readme + + + + [tag-npm-badge-svg]: https://badge.fury.io/js/%40angular-package%2Ftag.svg + [tag-npm-badge-png]: https://badge.fury.io/js/%40angular-package%2Ftag.png + [tag-npm-badge]: https://badge.fury.io/js/%40angular-package%2Ftag + [tag-npm-readme]: https://www.npmjs.com/package/@angular-package/tag#readme + + + [tag-github-readme]: https://github.com/angular-package/tag#readme + [testing-npm-badge-svg]: https://badge.fury.io/js/%40angular-package%2Ftesting.svg @@ -1296,6 +347,16 @@ MIT © angular-package ([license][error-license]) [testing-github-readme]: https://github.com/angular-package/testing#readme + + + [text-npm-badge-svg]: https://badge.fury.io/js/%40angular-package%2Ftext.svg + [text-npm-badge-png]: https://badge.fury.io/js/%40angular-package%2Ftext.png + [text-npm-badge]: https://badge.fury.io/js/%40angular-package%2Ftext + [text-npm-readme]: https://www.npmjs.com/package/@angular-package/text#readme + + + [text-github-readme]: https://github.com/angular-package/text#readme + [type-npm-badge-svg]: https://badge.fury.io/js/%40angular-package%2Ftype.svg @@ -1306,9 +367,6 @@ MIT © angular-package ([license][error-license]) [type-github-readme]: https://github.com/angular-package/type#readme - [package-type-resultcallback]: https://github.com/angular-package/type#resultcallback - [package-type-key]: https://github.com/angular-package/type#key - [ui-npm-badge-svg]: https://badge.fury.io/js/%40angular-package%2Fui.svg @@ -1319,6 +377,16 @@ MIT © angular-package ([license][error-license]) [ui-github-readme]: https://github.com/angular-package/ui#readme + + + [wrapper-npm-badge-svg]: https://badge.fury.io/js/%40angular-package%2Fwrapper.svg + [wrapper-npm-badge-png]: https://badge.fury.io/js/%40angular-package%2Fwrapper.png + [wrapper-npm-badge]: https://badge.fury.io/js/%40angular-package%2Fwrapper + [wrapper-npm-readme]: https://www.npmjs.com/package/@angular-package/wrapper#readme + + + [wrapper-github-readme]: https://github.com/angular-package/wrapper#readme + [angular-component-factory-resolver]: https://angular.io/api/core/ComponentFactoryResolver [angular-view-container-ref]: https://angular.io/api/core/ViewContainerRef @@ -1346,7 +414,7 @@ MIT © angular-package ([license][error-license]) [js-error]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error [js-function]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions -[js-function-rest-parameter]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters +[js-rest-parameter]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters [js-getter]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get [js-object-getownpropertydescriptor]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor @@ -1398,6 +466,13 @@ MIT © angular-package ([license][error-license]) [prism-js]: https://prismjs.com/ +[ts-any]: https://www.typescriptlang.org/docs/handbook/basic-types.html#any +[ts-boolean]: https://www.typescriptlang.org/docs/handbook/basic-types.html#boolean [ts-classes]: https://www.typescriptlang.org/docs/handbook/2/classes.html [ts-function]: https://www.typescriptlang.org/docs/handbook/2/functions.html [ts-interface]: https://www.typescriptlang.org/docs/handbook/interfaces.html#our-first-interface +[ts-never]: https://www.typescriptlang.org/docs/handbook/basic-types.html#never +[ts-number]: https://www.typescriptlang.org/docs/handbook/basic-types.html#number +[ts-object]: https://www.typescriptlang.org/docs/handbook/basic-types.html#object +[ts-string]: https://www.typescriptlang.org/docs/handbook/basic-types.html#string +[ts-unknown]: https://www.typescriptlang.org/docs/handbook/basic-types.html#unknown diff --git a/ng-package.json b/ng-package.json index d83a37a..87acb8b 100644 --- a/ng-package.json +++ b/ng-package.json @@ -2,10 +2,6 @@ "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", "dest": "../../dist/error", "lib": { - "entryFile": "src/public-api.ts", - "umdModuleIds": { - "@angular-package/callback": "angular-package.callback", - "@angular-package/type": "angular-package.type" - } + "entryFile": "src/public-api.ts" } } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index f938e59..7bce365 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,323 +1,31 @@ { "name": "@angular-package/error", - "version": "2.0.2", - "lockfileVersion": 2, + "version": "3.0.0-rc", + "lockfileVersion": 1, "requires": true, - "packages": { - "": { - "name": "@angular-package/error", - "version": "2.0.2", - "license": "MIT", - "dependencies": { - "tslib": "^2.2.0" - }, - "devDependencies": { - "@angular-package/testing": "^1.1.0" - }, - "peerDependencies": { - "@angular-package/type": "^4.2.0" - } - }, - "node_modules/@angular-package/testing": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@angular-package/testing/-/testing-1.1.0.tgz", - "integrity": "sha512-N/c75WBG4GPcgj7NYWAKSE9IwcPSqVMOYjkZ3RU4rUZW5equkjZvQ4zWKc8S4lbxr1wPD6KxPy3T52xTsBW3Dw==", - "dev": true, - "dependencies": { - "tslib": "^2.2.0" - }, - "peerDependencies": { - "@angular-package/type": ">= 4.2.0", - "jasmine": "^3.8.0" - } - }, - "node_modules/@angular-package/type": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@angular-package/type/-/type-4.2.0.tgz", - "integrity": "sha512-Y7HT94Gia4soR2ynwK8qva0WTOplau++gInEQCwDnhXmYy/r/1J/XhW0+aVj5XIa3SLWWa70nHvI0ivBM7O1nw==", - "peer": true, - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "peer": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true, - "peer": true - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true, - "peer": true - }, - "node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, - "peer": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "peer": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "peer": true - }, - "node_modules/jasmine": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.8.0.tgz", - "integrity": "sha512-kdQ3SfcNpMbbMdgJPLyFe9IksixdnrgYaCJapP9sS0aLgdWdIZADNXEr+11Zafxm1VDfRSC5ZL4fzXT0bexzXw==", - "dev": true, - "peer": true, - "dependencies": { - "glob": "^7.1.6", - "jasmine-core": "~3.8.0" - }, - "bin": { - "jasmine": "bin/jasmine.js" - } - }, - "node_modules/jasmine-core": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.8.0.tgz", - "integrity": "sha512-zl0nZWDrmbCiKns0NcjkFGYkVTGCPUgoHypTaj+G2AzaWus7QGoXARSlYsSle2VRpSdfJmM+hzmFKzQNhF2kHg==", - "dev": true, - "peer": true - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "peer": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tslib": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", - "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true, - "peer": true - } - }, "dependencies": { "@angular-package/testing": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@angular-package/testing/-/testing-1.1.0.tgz", - "integrity": "sha512-N/c75WBG4GPcgj7NYWAKSE9IwcPSqVMOYjkZ3RU4rUZW5equkjZvQ4zWKc8S4lbxr1wPD6KxPy3T52xTsBW3Dw==", + "version": "2.0.0-rc", + "resolved": "https://registry.npmjs.org/@angular-package/testing/-/testing-2.0.0-rc.tgz", + "integrity": "sha512-DjlOD0gnLlqT8b4Qqr5FlPJWnl1NsO0823fH9B+e+rDxoJZa6Ys2cGg8716ZRBrSVWdBeuVxrjDhMJpYX5GVDw==", "dev": true, "requires": { - "tslib": "^2.2.0" + "tslib": "^2.3.0" } }, "@angular-package/type": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@angular-package/type/-/type-4.2.0.tgz", - "integrity": "sha512-Y7HT94Gia4soR2ynwK8qva0WTOplau++gInEQCwDnhXmYy/r/1J/XhW0+aVj5XIa3SLWWa70nHvI0ivBM7O1nw==", - "peer": true, - "requires": { - "tslib": "^2.1.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "peer": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "peer": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true, - "peer": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true, - "peer": true - }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, - "peer": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "version": "5.0.0-rc.0", + "resolved": "https://registry.npmjs.org/@angular-package/type/-/type-5.0.0-rc.0.tgz", + "integrity": "sha512-NR3ODKJTmmdEqCz7fn6YDO68p9DK/SNWGvCV8pUqQUSFHlbrc0RDaqqF0liIi1iJcRZhbF2UnhWIIOp/iamtsg==", "dev": true, - "peer": true, "requires": { - "once": "^1.3.0", - "wrappy": "1" + "tslib": "^2.3.0" } }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "peer": true - }, - "jasmine": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.8.0.tgz", - "integrity": "sha512-kdQ3SfcNpMbbMdgJPLyFe9IksixdnrgYaCJapP9sS0aLgdWdIZADNXEr+11Zafxm1VDfRSC5ZL4fzXT0bexzXw==", - "dev": true, - "peer": true, - "requires": { - "glob": "^7.1.6", - "jasmine-core": "~3.8.0" - } - }, - "jasmine-core": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.8.0.tgz", - "integrity": "sha512-zl0nZWDrmbCiKns0NcjkFGYkVTGCPUgoHypTaj+G2AzaWus7QGoXARSlYsSle2VRpSdfJmM+hzmFKzQNhF2kHg==", - "dev": true, - "peer": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "peer": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "peer": true, - "requires": { - "wrappy": "1" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "peer": true - }, "tslib": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true, - "peer": true } } } diff --git a/package.json b/package.json index c802d4b..d9eb854 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,15 @@ { "name": "@angular-package/error", - "version": "2.0.2", + "version": "3.0.0-rc", "description": "Manages an error.", - "author": "Angular Package (https://wvvw.dev)", - "homepage": "https://github.com/angular-package/error#readme", - "peerDependencies": { - "@angular-package/callback": "^2.0.0", - "@angular-package/type": "^4.2.0" - }, + "author": "Angular Package (https://angular-package.dev)", + "homepage": "https://error.angular-package.dev", "dependencies": { - "tslib": "^2.2.0" + "tslib": "^2.3.0" }, "devDependencies": { - "@angular-package/testing": "^1.1.0" + "@angular-package/testing": "^2.0.0-rc", + "@angular-package/type": "^5.0.0-rc.0" }, "publishConfig": { "access": "public", diff --git a/src/interface/error-message.interface.ts b/src/interface/error-message.interface.ts deleted file mode 100644 index ff935e3..0000000 --- a/src/interface/error-message.interface.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * The shape of an `object` for the error message that contains a possible solution to the described problem. - * @param fix A possible solution to the described problem of a `string` type. - * @param problem Description of validation problem of a string type. - * @param template An optional message template of a `string` type. - */ -export interface ErrorMessage { - /** - * A possible solution to the described problem of a `string` type. - */ - fix: string; - - /** - * Description of validation problem of a `string` type. - */ - problem: string; - - /** - * An optional message template of a `string` type. - */ - template?: string; -} diff --git a/src/lib/common-error.class.ts b/src/lib/common-error.class.ts new file mode 100644 index 0000000..407b2ad --- /dev/null +++ b/src/lib/common-error.class.ts @@ -0,0 +1,175 @@ +/** + * The `CommonError` abstract object to throw an identified error with a solution to the described problem, additional type, and range built + * on the template. + */ +export abstract class CommonError extends Error { + //#region public static properties. + /** + * A template of the error message of `string` type with the replaceable `{problem}`, `{fix}` and optional `{id}`, `{link}`, `{max}`, + * `{min}`, `{type}` tags. By default, it's set to `Problem{id}: {problem} => Fix: {fix}`. + */ + public static template = `Problem{id}: {problem} => Fix: {fix}`; + //#endregion public static properties. + + //#region public instance accessors. + /** + * The `get` accessor obtains a possible solution to the described problem by returning the `#fix` property of a specified object. + * @returns The return value is the fix of a `string` type. + * @angularpackage + */ + public get fix(): string { + return this.#fix; + } + + /** + * The `get` accessor gets the error identification by returning the `#id` property of a specified object. + * @returns The return value is the error identification of the generic type variable `Id` or `undefined`. + * @angularpackage + */ + public get id(): Id | undefined { + return this.#id; + } + + /** + * The `get` accessor gets the link(to read more about the thrown error) by returning the `#link` property of a specified object. + * @returns The return value is the link of a `string` type or `undefined`. + * @angularpackage + */ + public get link(): string | undefined { + return this.#link; + } + + /** + * The `get` accessor gets the error message by returning the parent `message` property of the `Error` object. + * @returns The return value is the error message of a `string` type. + * @angularpackage + */ + public get message(): string { + return super.message; + } + + /** + * The `get` accessor gets the problem by returning the `#problem` property of a specified object. + * @returns The return value is the problem of a `string` type. + * @angularpackage + */ + public get problem(): string { + return this.#problem; + } + + /** + * The `get` accessor gets the template of the error message by returning the `#template` property of a specified object. + * @returns The return value is the template of a `string` type. + * @angularpackage + */ + public get template(): string { + return this.#template; + } + //#endregion public instance accessors. + + //#region private instance properties. + /** + * A privately stored possible solution to the described problem of a `string` type. + */ + #fix: string; + + /** + * Optional privately stored unique identification of the described problem of generic type variable `Id`. + */ + #id?: Id; + + /** + * The optional privately stored link of `string` type redirects to read more about the thrown error. + */ + #link?: string; + + /** + * A privately stored problem of a `string` type. + */ + #problem: string; + + /** + * A string-type privately stored template of the error message that contains replaceable required `{fix}`, `{problem}` and optional + * `{id}`, `{max}`, `{min}`, `{type}` tags. + */ + #template: string; + //#endregion private instance properties. + + //#region protected static methods. + /** + * The static "tag" method builds from the given `values` the error message of a string type on the template. + * @param templateStringsArray - + * @param values A rest parameter of expressions in order the `problem`, `fix`, `id`, `template` and `additional`. + * @returns The return value is the error message of a `string` type created from the expressions given in the `values`. + * @angularpackage + */ + protected static defineMessage( + templateStringsArray: TemplateStringsArray, + ...values: any[] + ): string { + let problem: string, + fix: string, + id: string | undefined, + template: string, + additional: { link?: string; min?: number; max?: number; type?: string }; + [problem, fix, id, template, additional] = values; + template = (template || CommonError.template) + .replace('{problem}', problem || '') + .replace(/{id}/g, id || '') + .replace(/{link}/g, additional?.link ? additional.link : '') + .replace(/{max}/g, additional?.max ? String(additional.max) : '') + .replace(/{min}/g, additional?.min ? String(additional.min) : '') + .replace(/{type}/g, additional?.type ? additional.type : '') + .replace('{fix}', fix || ''); + return template; + } + + /** + * Checks whether the value of any type is a `this` instance of any or the given identification. + * @param value The value of any type to check against the `this` instance. + * @param id Optional identification of generic type variable `Id` to check whether the given `value` contains. + * @returns The return value is a `boolean` type indicating whether the given `value` is a `this` instance of any or the given `id`. + * @angularpackage + */ + protected static isError( + value: any, + id?: Id + ): value is CommonError { + return typeof value === 'object' && value instanceof this + ? typeof id === 'string' + ? value.id === id + : true + : false; + } + //#endregion protected static methods. + + //#region constructor. + /** + * Creates an error instance with the message built from the given problem, its solution, optional type, range, an explicit identification + * on the supplied or stored template. + * @param problem Description of the problem of a `string` type. + * @param fix A solution to the given `problem` of a `string` type. + * @param id Optional unique identification to the given `problem` of generic type variable `Id`. + * @param template A template of error message with the replaceable `{problem}`, `{fix}` and optional `{id}`, `{link}`, `{max}`, `{min}` + * and `{type}` tags. By default, the value is equal to the static property `template`. + * @param additional An optional object consists of optional `link`, `min`, `max`, and `type` properties to define the error message. + * @angularpackage + */ + constructor( + problem: string, + fix: string, + id?: Id, + template = CommonError.template, + additional?: { link?: string; max?: number; min?: number; type?: string } + ) { + super( + CommonError.defineMessage`${problem}${fix}${id}${template}${additional}` + ); + this.#fix = fix; + this.#id = id; + this.#link = additional?.link; + this.#problem = problem; + this.#template = template; + } + //#endregion constructor. +} diff --git a/src/lib/common-errors.class.ts b/src/lib/common-errors.class.ts new file mode 100644 index 0000000..60a5935 --- /dev/null +++ b/src/lib/common-errors.class.ts @@ -0,0 +1,90 @@ +/** + * The `CommonErrors` object represents the storage of errors with unique identification numbers. + */ +export abstract class CommonErrors { + /** + * Optional template of `string` type. + */ + public static template?: string; + + //#region protected instance accessors. + /** + * The `get` accessor returns the errors of `Map` type by returning the `#errors` property of a specified object. + * @returns The return value is the `Map` object of errors. + * @angularpackage + */ + protected get errors(): Map { + return this.#errors; + } + //#endregion protected instance accessors. + + //#region private instance properties. + /** + * The collection of unique allowed identification numbers of generic type variable `Id`. + */ + #id?: Set; + + /** + * The errors storage of the `Map` type where the `key` is of the generic type variable `Id`. + */ + #errors: Map = new Map(); + //#endregion private instance properties. + + //#region constructor. + /** + * Creates an instance of the errors storage with unique identification numbers. + * @param id A rest parameter of generic type variable `Id` indicates unique identification numbers under which the errors are stored in + * the object. + * @angularpackage + */ + constructor(...id: Id[]) { + Array.isArray(id) && (this.#id = new Set(id)); + } + //#endregion constructor. + + //#region instance public methods. + /** + * Deletes the error of a specified `id` from the object. + * @param id The unique identification of a generic type variable `ErrorId` to remove the error from the object. + * @returns The return value is an instance of an `ValidationError`. + * @angularpackage + */ + public delete(id: ErrorId): this { + this.#errors.delete(id); + return this; + } + + /** + * The `has()` method checks whether the error of the given `id` exists in a specified object. + * @param id The error identification number of generic type variable `ErrorId` to test for the presence of the error in the object. + * @returns The return value is a `boolean` indicating whether the error of the given `id` exists in the object. + * @angularpackage + */ + public has(id: ErrorId): boolean { + return this.#errors.has(id); + } + + /** + * Throws an error of the given `id` if the unique id was provided in the constructor. + * @param id The unique identification number of generic type variable `ErrorId` to obtain an error to throw. + * @angularpackage + */ + public throw(id: ErrorId): void { + if (this.isAllowedId(id)) { + throw this.errors.get(id); + } + } + + //#endregion instance public methods. + + //#region instance protected methods. + /** + * Checks whether the given identification number was provided in the constructor. + * @param id The error identification number of generic type variable `ErrorId` to test for its presence in the object. + * @angularpackage + */ + protected isAllowedId(id: ErrorId): boolean { + return this.#id ? this.#id.has(id) : false; + } + //#endregion instance protected methods. +} diff --git a/src/lib/error.class.ts b/src/lib/error.class.ts new file mode 100644 index 0000000..7f4b1ef --- /dev/null +++ b/src/lib/error.class.ts @@ -0,0 +1,84 @@ +import { CommonError } from './common-error.class'; +/** + * The `Error` object is an extension of the `CommonError` class and is thrown when a runtime error occurs with a message built from a + * solution to the described problem but with additional identification, on the template. + */ +export class Error extends CommonError { + //#region public instance accessors. + /** + * Error name of a `string` type, set to `Error` that is being thrown. + * @returns The return value is the error instance name of `string` type. + * @angularpackage + */ + public get name(): string { + return 'Error'; + } + + /** + * The `get` accessor, with the help of `toStringTag`, changes the default tag to `'Error'` for an instance of `Error`. It can be read + * by the `typeOf()` function of `@angular-package/type`. + * @returns The return value is the word `Error` of a `string`. + * @angularpackage + */ + public get [Symbol.toStringTag](): string { + return 'Error'; + } + //#endregion public instance accessors. + + //#region public static methods. + /** + * Defines the `Error` instance with the message built of the given required `problem`, `fix` and optional `id` on the `template`. + * @param problem Description of the problem of a `string` type. + * @param fix A solution to the given `problem` of a `string` type. + * @param id Optional unique identification to the given `problem` of generic type variable `Id`. + * @param template A template of error message with the replaceable `{problem}`, `{fix}` and optional `{id}` tags. By default, the value + * is picked from the static property `template`. + * @returns The return value is a new instance of the `Error` with the message built from the given required `problem`, `fix` and optional + * `id` on the `template`. + * @angularpackage + */ + public static define( + problem: string, + fix: string, + id?: Id, + template = Error.template + ): Error { + return new this(problem, fix, id, template); + } + + /** + * Checks whether the value of any type is an instance of `Error` of any or the given identification. + * @param value The value of any type to check against the `Error` instance. + * @param id Optional unique identification of generic type variable `Id` that the given `value` contains. + * @returns The return value is a `boolean` type indicating whether the given `value` is an instance of `Error` of any or the given `id`. + * @angularpackage + */ + public static isError( + value: any, + id?: Id + ): value is Error { + return super.isError(value, id); + } + //#endregion public static methods. + + //#region constructor. + /** + * Creates the `Error` instance with the message built from the given described `problem` and its solution, optional explicit + * identification on the given or stored `template`. + * @param problem Description of the problem of a string type. + * @param fix A solution to the given `problem` of a string type. + * @param id Optional unique identification to the given `problem` of generic type variable `Id`. + * @param template A template of error message with the replaceable `{problem}`, `{fix}` and optional `{id}`, `{max}`, `{min}` and tags. + * By default, the value is equal to the static property `template`. + * @angularpackage + */ + constructor( + problem: string, + fix: string, + id?: Id, + template = Error.template + ) { + super(problem, fix, id, template); + } + //#endregion constructor. +} diff --git a/src/lib/errors.class.ts b/src/lib/errors.class.ts new file mode 100644 index 0000000..4c92821 --- /dev/null +++ b/src/lib/errors.class.ts @@ -0,0 +1,63 @@ +import { CommonErrors } from './common-errors.class'; +import { Error } from './error.class'; +/** + * The `Errors` is an extension of the `CommonErrors` object that represents multiple identification numbers under which the errors of the + * `Error` type are prepared to throw. + */ +export class Errors extends CommonErrors { + //#region constructor. + /** + * Creates the `Errors` instance of unique identification numbers under which the `Error` objects are stored. + * @param id A rest parameter of generic type variable `Id` indicates unique identification numbers under which the errors are stored in + * the object. + * @angularpackage + */ + constructor(...id: Id[]) { + super(...id); + } + //#endregion constructor. + + //#region instance public methods. + /** + * Returns the `Error` instance of the given unique identification `id` if set, otherwise `undefined`. + * @param id The unique identification number of generic type variable `ErrorId` to pick an error from the object. + * @returns The return value is the `Error` instance of the given `id` if set, otherwise `undefined`. + * @angularpackage + */ + public get(id: ErrorId): Error | undefined { + return this.errors.get(id); + } + + /** + * Returns an `object` of set errors, where the key is a unique identification. + * @returns The return value is an `object` of set errors. + * @angularpackage + */ + public getErrors(): { [Key in Id]: Error | undefined } { + return Object.fromEntries(this.errors.entries()) as any; + } + + /** + * Sets the `Error` object with the message built from the given required `problem`, `fix`, `id` on the given or stored `template` under + * the given `id`. + * ! The error is not set, if the given `id` was not provided in the constructor. + * @param problem Description of the problem of a `string` type. + * @param fix A solution to the given `problem` of a `string` type. + * @param id The unique identification to the given `problem` of generic type variable `ErrorId`. + * @param template A template of the error message with a replaceable `{problem}`, `{fix}`, `{id}` tags. By default, the value is equal to + * the static property `Errors.template`. + * @returns The return value is an instance of `Errors`. + * @angularpackage + */ + public set( + problem: string, + fix: string, + id: ErrorId, + template = Errors.template + ): this { + this.isAllowedId(id) && + this.errors.set(id, new Error(problem, fix, id, template)); + return this; + } + //#endregion instance public methods. +} diff --git a/src/lib/index.ts b/src/lib/index.ts new file mode 100644 index 0000000..9e62f74 --- /dev/null +++ b/src/lib/index.ts @@ -0,0 +1,9 @@ +export { CommonError } from './common-error.class'; +export { Error } from './error.class'; +export { Errors } from './errors.class'; +export { RangeError } from './range-error.class'; +export { RangeErrors } from './range-errors.class'; +export { TypeError } from './type-error.class'; +export { TypeErrors } from './type-errors.class'; +export { ValidationError } from './validation-error.class'; +export { ValidationErrors } from './validation-errors.class'; diff --git a/src/lib/range-error.class.ts b/src/lib/range-error.class.ts new file mode 100644 index 0000000..afd53ff --- /dev/null +++ b/src/lib/range-error.class.ts @@ -0,0 +1,170 @@ +import { CommonError } from './common-error.class'; +/** + * The `RangeError` object is an extension of the `CommonError` class and is thrown when a value is not in the set or range of allowed + * values with the message built from the described problem and its solution, optional explicit identification and minimum/maximum range + * on the given or stored template. + */ +export class RangeError< + Id extends string, + Min extends number | undefined = undefined, + Max extends number | undefined = undefined +> extends CommonError { + /** + * A template of the error message of `string` type with the replaceable required `{problem}`, `{fix}` and optional `{id}`, `{max}`, + * `{min}` tags. By default, it's set to `Problem{id}: {problem} => Fix: {fix} between {min} and {max}`. + */ + public static template = `Problem{id}: {problem} => Fix: {fix} between {min} and {max}`; + + //#region public instance accessors. + /** + * The `get` accessor obtains the maximum range of generic type variable `Max` that causes an error to be thrown(or not thrown), if set, + * otherwise returns `undefined`. + * @returns The return value is the maximum range of generic type variable `Max` or `undefined`. + * @angularpackage + */ + public get max(): Max | undefined { + return this.#max; + } + + /** + * The `get` accessor obtains the minimum range of generic type variable `Min` that causes an error to be thrown(or not thrown), if set, + * otherwise returns `undefined`. + * @returns The return value is the minimum range of generic type variable `Min` or undefined. + * @angularpackage + */ + public get min(): Min | undefined { + return this.#min; + } + + /** + * The `get` accessor obtains error name of a `string` type, set to `RangeError` that is being thrown. + * @returns The return value is the error instance name of `string` type. + * @angularpackage + */ + public get name(): string { + return 'RangeError'; + } + + /** + * The `get` accessor obtains the minimum and maximum range in the form of an `object`. + * @returns The return value is an `object` that consists of the minimum range under the `min` property and the maximum under the + * `max` property. + * @angularpackage + */ + public get range(): { min?: Min; max?: Max } { + return { + min: this.#min, + max: this.#max, + }; + } + + /** + * The `get` accessor, with the help of `toStringTag`, changes the default tag to `'RangeError'` for an instance of + * `RangeError`. It can be read by the `typeOf()` function of `@angular-package/type`. + * @returns The return value is the word 'RangeError` of a `string`. + * @angularpackage + */ + public get [Symbol.toStringTag](): string { + return 'RangeError'; + } + //#endregion public instance accessors. + + //#region private instance properties. + /** + * Private property of the maximum range of generic type variable `Max` that causes an error to be thrown(or not thrown). + */ + #max?: Max; + + /** + * Private property of the minimum range of generic type variable `Min` that causes an error to be thrown(or not thrown). + */ + #min?: Min; + //#endregion private instance properties. + + //#region public static methods. + /** + * Defines the `RangeError` instance with the message built from the given required `problem`, `fix` and optional `id`, `max`, `min` on + * the given or stored `template`. + * @param problem Description of the problem of a `string` type. + * @param fix A solution to the given `problem` of a `string` type. + * @param id Optional unique identification to the given `problem` of generic type variable `Id`. + * @param min The optional minimum range of generic type variable `Min` that causes an error to be thrown(or not thrown). + * @param max The optional maximum range of generic type variable `Max` that causes an error to be thrown(or not thrown). + * @param template A template of error message with the replaceable `{problem}`, `{fix}` and optional `{id}`, `{max}`, `{min}` and tags. + * By default, the value is picked from the static property `RangeError.template`. + * @returns The return value is a new instance of the `RangeError` with the message built from the given required `problem`, `fix` and + * optional `id`, `min`, `max` on the given or stored `template`. + * @angularpackage + */ + public static define< + Id extends string, + Min extends number | undefined = undefined, + Max extends number | undefined = undefined + >( + problem: string, + fix: string, + id?: Id, + min?: Min, + max?: Max, + template = RangeError.template + ): RangeError { + return new this(problem, fix, id, min, max, template); + } + + /** + * Checks whether the value of any type is an instance of `RangeError` of any or the given minimum/maximum range and identification. + * @param value The value of any type to check against the `RangeError` instance. + * @param id Optional identification of generic type variable `Id` to check whether the given `value` contains. + * @param min The optional minimum range of generic type variable `Min` that causes an error to be thrown(or not thrown) to check whether + * the given `value` contains. + * @param max The optional maximum range of generic type variable `Max` that causes an error to be thrown(or not thrown) to check whether + * the given `value` contains. + * @returns The return value is a `boolean` type indicating whether the given `value` is an instance of `RangeError` of any or the given + * `min`, max` and `id` properties. + * @angularpackage + */ + public static isRangeError< + Id extends string, + Min extends number | undefined = undefined, + Max extends number | undefined = undefined + >( + value: any, + id?: Id, + min?: Min, + max?: Max + ): value is RangeError { + return ( + super.isError(value, id) && + (typeof min === 'number' ? (value as any).min === min : true) && + (typeof max === 'number' ? (value as any).max === max : true) + ); + } + //#endregion public static methods. + + //#region constructor. + /** + * Creates the `RangeError` instance that represents range error with the message built of the given described `problem` and its solution, + * optional `min`/`max` range, and an explicit identification on the given or stored error message template. + * @param problem Description of the range problem of a `string` type. + * @param fix A solution to the given range issue of a `string` type. + * @param min The optional minimum range of generic type variable `Min` that causes an error to be thrown(or not thrown). + * @param max The optional maximum range of generic type variable `Max` that causes an error to be thrown(or not thrown). + * @param id Optional unique identification to the given `problem` of generic type variable `Id`. + * @param template A template of error message with the replaceable required `{problem}`, `{fix}` and optional `{id}`, `{max}`, `{min}` + * tags. By default, the value is equal to the static property `template`. + * @angularpackage + */ + constructor( + problem: string, + fix: string, + id?: Id, + min?: Min, + max?: Max, + template = RangeError.template + ) { + super(problem, fix, id, template, { min, max }); + this.#max = max; + this.#min = min; + } + //#endregion constructor. +} diff --git a/src/lib/range-errors.class.ts b/src/lib/range-errors.class.ts new file mode 100644 index 0000000..b6e9c13 --- /dev/null +++ b/src/lib/range-errors.class.ts @@ -0,0 +1,67 @@ +import { CommonErrors } from './common-errors.class'; +import { RangeError } from './range-error.class'; +/** + * The `RangeErrors` is an extension of the `CommonErrors` object that represents multiple identification numbers under which the errors of + * the `RangeError` type are prepared to throw. + */ +export class RangeErrors extends CommonErrors { + //#region constructor. + /** + * Creates the `RangeErrors` instance of unique identification numbers under which the `RangeError` objects are stored. + * @param id A rest parameter of generic type variable `Id` indicates unique identification numbers under which the `RangeError` objects + * are stored. + * @angularpackage + */ + constructor(...id: Id[]) { + super(...id); + } + //#endregion constructor. + + //#region instance public methods. + /** + * Returns the `RangeError` instance of the given unique identification `id` if set, otherwise `undefined`. + * @param id The unique identification number of generic type variable `ErrorId` to pick an error from the object. + * @returns The return value is the `RangeError` instance of the given `id` if set, otherwise undefined. + * @angularpackage + */ + public get(id: ErrorId): RangeError | undefined { + return this.errors.get(id); + } + + /** + * Returns the object of set range errors, where the key is a unique identification. + * @returns The return value is an `object` of set range errors. + * @angularpackage + */ + public getErrors(): { [Key in Id]: RangeError | undefined } { + return Object.fromEntries(this.errors.entries()) as any; + } + + /** + * Sets the `RangeError` object with the message built from the given required `problem`, `fix`, `id` and optional `min`, `max` on the + * given or stored `template` under the given `id`. + * ! The error is not set, if the given `id` was not provided in the constructor. + * @param problem Description of the problem of a string type. + * @param fix A solution to the given `problem` of a string type. + * @param id The unique identification to the given `problem` of generic type variable `ErrorId`. + * @param min The optional minimum range of `number` type that causes an error to be thrown(or not thrown). + * @param max The optional maximum range of `number` type that causes an error to be thrown(or not thrown). + * @param template A template of error message with the replaceable `{problem}`, `{fix}`, `{id}`, and optional `{max}`, `{min}` tags. By + * default, the value is equal to the static property `RangeErrors.template`. + * @returns The return value is an instance of `RangeErrors`. + * @angularpackage + */ + public set( + problem: string, + fix: string, + id: ErrorId, + min?: number, + max?: number, + template = RangeErrors.template + ): this { + this.isAllowedId(id) && + this.errors.set(id, new RangeError(problem, fix, id, min, max, template)); + return this; + } + //#endregion instance public methods. +} diff --git a/src/lib/type-error.class.ts b/src/lib/type-error.class.ts new file mode 100644 index 0000000..d805f6c --- /dev/null +++ b/src/lib/type-error.class.ts @@ -0,0 +1,123 @@ +import { CommonError } from './common-error.class'; +/** + * The `TypeError` object is an extension of the `CommonError` class and is thrown when an operation could not be performed, + * typically(but not exclusively) when a value is not of the expected type, with the message built from the described problem and its + * solution, optional an explicit identification and type, on the given or stored template. + */ +export class TypeError< + Id extends string, + Type extends string | undefined = undefined +> extends CommonError { + /** + * A template of the error message of `string` type with the replaceable required `{fix}`,`{problem}` and optional `{id}`, `{max}`, + * `{min}`, `{type}` tags. By default, it's set to `Problem{id}: {problem} => Fix: {fix} must be of the {type}`. + */ + public static template = `Problem{id}: {problem} => Fix: {fix} must be of the {type}`; + + //#region public instance accessors. + /** + * The `get` accessor obtains error name of a `string` type, set to 'TypeError' that is being thrown. + * @returns The return value is the error instance name of `string` type. + * @angularpackage + */ + public get name(): string { + return 'TypeError'; + } + + /** + * The `get` accessor obtains the type of generic type variable `Type` that causes an error to be thrown(or not thrown) if set, otherwise + * returns `undefined`. + * @returns The return value is the type of generic type variable `Type` or `undefined`. + * @angularpackage + */ + public get type(): Type | undefined { + return this.#type; + } + + /** + * The `get` accessor, with the help of `toStringTag`, changes the default tag to `'TypeError'` for an instance of + * `TypeError`. It can be read by the `typeOf()` function of `@angular-package/type`. + * @returns The return value is the word 'TypeError` of a `string`. + * @angularpackage + */ + public get [Symbol.toStringTag](): string { + return 'TypeError'; + } + //#endregion public instance accessors. + + /** + * Private string-type property of the type that causes an error to be thrown(or not thrown). + */ + #type?: Type; + + //#region public static methods. + /** + * Defines the `TypeError` instance with the given required `problem`, `fix` and optional `id`, `type` and `template`. + * @param problem Description of the problem of a `string` type. + * @param fix A solution to the given `problem` of a `string` type. + * @param id Optional unique identification to the given `problem` of generic type variable `Id`. + * @param type The optional type of generic type variable `Type` that causes an error to be thrown(or not thrown). + * @param template A template of error message with the replaceable `{problem}`, `{fix}` and optional `{id}`, `{type}` tags. By default, + * the value is picked from the static property `TypeError.template`. + * @returns The return value is a new instance of the `TypeError` with the message built from the given required `problem`, `fix` and + * optional `id`, `type` on the given or stored `template`. + * @angularpackage + */ + public static define< + Id extends string, + Type extends string | undefined = undefined + >( + problem: string, + fix: string, + id?: Id, + type?: Type, + template = TypeError.template + ): TypeError { + return new this(problem, fix, id, type, template); + } + + /** + * Checks whether the value of any type is an instance of `TypeError` of any or the given type and identification. + * @param value The value of any type to check against the `TypeError` instance. + * @param id Optional unique identification of generic type variable `Id` to check whether the given `value` contains. + * @param type The optional type of generic type variable `Type` that causes an error to be thrown(or not thrown) to check whether the + * given `value` contains. + * @returns The return value is a `boolean` type indicating whether the given `value` is an instance of `TypeError` of any or the given + * `type` and `id` properties. + * @angularpackage + */ + public static isTypeError< + Id extends string, + Type extends string | undefined = undefined + >(value: any, id?: Id, type?: Type): value is TypeError { + return ( + super.isError(value, id) && + (typeof type === 'string' ? (value as any).type === type : true) + ); + } + //#endregion public static methods. + + //#region constructor. + /** + * Creates a `TypeError` instance that represents type error with the message built of the given described problem and its solution, + * optional type, and an explicit identification on the supplied or stored error message template. + * @param problem Description of the range problem of a `string` type. + * @param fix A solution to the given range issue of a `string` type. + * @param id Optional unique identification to the given `problem` of generic type variable `Id`. + * @param type The optional type of generic type variable `Type` that causes an error to be thrown(or not thrown). + * @param template Optional template of error message with the replaceable `{problem}`, `{fix}` and optional `{id}`, `{max}`, `{min}` and + * `{type}` tags. By default, the value is picked from the static property `TypeError.template`. + * @angularpackage + */ + constructor( + problem: string, + fix: string, + id?: Id, + type?: Type, + template = TypeError.template + ) { + super(problem, fix, id, template, { type }); + this.#type = type; + } + //#endregion constructor. +} diff --git a/src/lib/type-errors.class.ts b/src/lib/type-errors.class.ts new file mode 100644 index 0000000..ad33812 --- /dev/null +++ b/src/lib/type-errors.class.ts @@ -0,0 +1,65 @@ +import { CommonErrors } from './common-errors.class'; +import { TypeError } from './type-error.class'; +/** + * The `TypeErrors` is an extension of the `CommonErrors` object that represents multiple identification numbers under which the errors of + * the `TypeError` type are prepared to throw. + */ +export class TypeErrors extends CommonErrors { + //#region constructor. + /** + * Creates the `TypeErrors` instance of unique identification numbers under which the `TypeError` objects are stored. + * @param id A rest parameter of generic type variable `Id` indicates unique identification numbers under which the `TypeError` objects + * are stored. + * @angularpackage + */ + constructor(...id: Id[]) { + super(...id); + } + //#endregion constructor. + + //#region instance public methods. + /** + * Returns the `TypeError` instance of the given unique identification `id` if set, otherwise `undefined`. + * @param id The unique identification number of generic type variable `ErrorId` to pick an error from the object. + * @returns The return value is the `TypeError` instance of the given `id` if set, otherwise undefined. + * @angularpackage + */ + public get(id: ErrorId): TypeError | undefined { + return this.errors.get(id); + } + + /** + * The method returns the object of set type errors, where the key is a unique identification. + * @returns The return value is an `object` of set type errors. + * @angularpackage + */ + public getErrors(): { [Key in Id]: TypeError | undefined } { + return Object.fromEntries(this.errors.entries()) as any; + } + + /** + * Sets the `TypeError` object with the message built from the given required `problem`, `fix`, `id` and optional `type` on the given or + * stored `template` under the given `id`. + * ! The error is not set, if the given `id` was not provided in the constructor. + * @param problem Description of the problem of a string type. + * @param fix A solution to the given `problem` of a string type. + * @param id The unique identification to the given `problem` of generic type variable `ErrorId`. + * @param type The optional type of `string` type that causes an error to be thrown(or not thrown). + * @param template A template of error message with the replaceable `{problem}`, `{fix}`, `{id}`, and optional `{type}` tags. By default, + * the value is equal to the static property `RangeErrors.template`. + * @returns The return value is an instance of `TypeErrors`. + * @angularpackage + */ + public set( + problem: string, + fix: string, + id: ErrorId, + type?: string, + template = TypeErrors.template + ): this { + this.isAllowedId(id) && + this.errors.set(id, new TypeError(problem, fix, id, type, template)); + return this; + } + //#endregion instance public methods. +} diff --git a/src/lib/validation-error.class.ts b/src/lib/validation-error.class.ts index 192a368..8583101 100644 --- a/src/lib/validation-error.class.ts +++ b/src/lib/validation-error.class.ts @@ -1,314 +1,88 @@ -// @angular-package/type. -import { is, guard } from '@angular-package/type'; - -// @angular-package/callback. -import { - Callback, - CallbackPayload, - ResultCallback, -} from '@angular-package/callback'; - -// Interface. -import { ErrorMessage } from '../interface/error-message.interface'; - -// Type. -import { VEAllowedCallback } from '../type/allowed-callback.type'; - +import { CommonError } from './common-error.class'; /** - * Manages an `Error` of validation. + * The `ValidationError` object is an extension of the `CommonError` class and is thrown when an operation could not be performed despite + * proper type(but not exclusively) with the message built from the described problem and its solution, along with additional identification + * on the given or stored template. */ -export class ValidationError extends Error { - /* #region static private properties */ - /** - * A static, privately stored template of the error message. - */ - static #template = `Problem: [problem] => Fix: [fix]`; - /* #endregion static private properties */ - - //#region instance private properties. - /** - * An instance of `Callback` with specified allowed names of callback functions for the `ValidationError`. - */ - #callback = new Callback('setFix', 'setMessage', 'setProblem', 'setTemplate'); - - /** - * A privately stored possible solution to the described problem of a `string` type. - * By default, it's an empty `string`. - */ - #fix = ''; - - /** - * A privately stored validation problem of a `string` type. - * By default, it's an empty `string`. - */ - #problem = ''; - - /** - * A string-type privately stored template of the error message that contains replaceable `[fix]` and `[problem]` words. - */ - #tpl = ValidationError.template; - //#endregion instance private properties. - - /** - * A template of the error message guarded by a `string` type with the replaceable `[problem]` and `[fix]` words. - * By default, it's set to `Problem: [problem] => Fix: [fix]`. It can be set directly or by the `setTemplate()` and `setMessage()` method. - * The value is being checked against the existence of `[problem]` and `[fix]` words. - */ - static get template(): string { - return ValidationError.#template; - } - static set template(value: string) { - ValidationError.#template = ValidationError.#guardTemplate(value) - ? value - : ValidationError.#template; - } - - //#region instance public properties. - /** - * A possible solution to the described `problem` of validation that is guarded by a `string` type. - * By default, it's an empty `string`. It can be set directly or by the `setTemplate()` and `setMessage()` method - */ - public get fix(): string { - return this.#fix; - } - public set fix(value: string) { - this.#fix = guard.string(value) ? value : this.#fix; - } - - /** - * A validation error message guarded by a `string` type that can be built from the `problem` and `fix` of `ValidationError` on the - * `template`. It can be set directly or by the `throw()` or `setMessage()` method. - */ - public set message(value: string) { - super.message = guard.string(value) ? value : super.message; - } - public get message(): string { - return super.message; - } - - /** - * Error name of a `string` type that is being thrown. By default, it's `ValidationError`. - */ - public name = ValidationError.name; - - /** - * Description of a validation problem guarded by a `string` type. By default, it's an empty `string`. - * It can be set directly or by the `setProblem()` and `setMessage()` method. - */ - public get problem(): string { - return this.#problem; - } - public set problem(value: string) { - this.#problem = guard.string(value) ? value : this.#problem; - } - //#endregion instance public properties. - - //#region static public methods - /** - * Defines the validation error message of a `string` type from the provided `message` of the `ErrorMessage` interface. - * @param message An object of an `ErrorMessage` interface to build a message of a `string` type. The value is checked against - * the proper `object`. - * @param callback An optional callback function of `ResultCallback` type to handle the check whether the provided message contains - * required `problem` and `fix` properties. - * @returns The return value is a message of a `string` type created from the provided `message` of `ErrorMessage` interface or it's an - * empty `string` if the provided message object isn't proper. - * @angularpackage - */ - public static defineMessage( - message: ErrorMessage, - callback?: ResultCallback - ): string { - return ValidationError.#guardMessage(message, callback) - ? (message.template || ValidationError.template) - .replace(`[fix]`, message.fix) - .replace(`[problem]`, message.problem) - : ''; - } - //#endregion static public methods - - //#region private static methods. +export class ValidationError extends CommonError { + //#region public instance accessors. /** - * Guards the provided message to be of `ErrorMessage` shape. - * @param message An object of the `ErrorMessage` interface to build the message of a `string` type. The value is checked against - * the proper `object`. - * @param callback An optional callback function of `ResultCallback` type to handle the check whether the provided `message` contains - * required `problem` and `fix` properties. - * @returns The return value is a `boolean` indicating whether the provided `message` is an object of `ErrorMessage`. + * The `get` accessor obtains error name of a `string` type, set to 'ValidationError' that is being thrown. + * @returns The return value is the error instance name of `string` type. * @angularpackage */ - static #guardMessage( - message: ErrorMessage, - callback?: ResultCallback - ): message is ErrorMessage { - return guard.objectKey(message, ['fix', 'problem'], callback) - ? is.defined(message.template) - ? guard.string(message.problem) && - guard.string(message.fix) && - ValidationError.#guardTemplate(message.template, callback) - : guard.string(message.problem) && guard.string(message.fix) - : false; + public get name(): string { + return 'ValidationError'; } /** - * Guards the provided `template` to be a `string` type that includes `[fix]` and `[problem]` words. - * @param template A string-type value to guard. - * @param callback An optional callback function of `ResultCallback` type to handle the check whether the provided message contains - * @returns The return value is a `boolean` indicating whether the provided `template` is a `string` that includes `[fix]` and `[problem]` - * words. + * The `get` accessor, with the help of `toStringTag`, changes the default tag to `'ValidationError'` for an instance of + * `ValidationError`. It can be read by the `typeOf()` function of `@angular-package/type`. + * @returns The return value is the word 'ValidationError` of a `string`. * @angularpackage */ - static #guardTemplate( - template: string, - callback?: ResultCallback - ): template is string { - return guard.string(template, callback) - ? template.includes('[fix]') && template.includes('[problem]') - : false; + public get [Symbol.toStringTag](): string { + return 'ValidationError'; } - //#endregion private static methods. + //#endregion public instance accessors. + //#region public static methods. /** - * Creates a new instance with the message. If the provided `message` is an `object`, then its properties are assigned - * to the instance. - * @param message The message of a `string` type or of an `ErrorMessage` interface that is used to throw with an `Error`. - * @param callback An optional function to handle the internal instance of `Callback`. + * Defines the `ValidationError` instance with the message built of the given required `problem`, `fix`, and optional `id` on the supplied + * or stored `template`. + * @param problem Description of the problem of a `string` type. + * @param fix A solution to the given `problem` of a `string` type. + * @param id Optional unique identification to the given `problem` of generic type variable `Id`. + * @param template A template of error message with the replaceable `{problem}`, `{fix}` and optional `{id}`, `{min}`, `{max}` and tags. + * By default, the value is picked from the static property `ValidationError.template`. + * @returns The return value is a new instance of the `ValidationError` with the message built from the given required `problem`, `fix` + * and optional `id` on the given or stored `template`. * @angularpackage */ - constructor( - message: string | ErrorMessage = '', - callback?: (callback: Callback) => void - ) { - super(); - - // Sets the callback for an instance methods. - if (is.function(callback)) { - callback(this.#callback); - } - - // Initializes the message and assigns message properties `fix`, `problem` and optionally `template` to a new instance. - this.setMessage(message); - } - - //#region instance public methods. - /** - * Sets the fix a possible solution to the described problem. - * @param fix A possible solution to the described problem guarded by a `string` type. - * @param callback An optional callback function of `ResultCallback` type to handle the check whether the provided `fix` is a `string`. - * By default, it uses an internal callback under the `'setFix'` name, which can be initially set by the optional `callback` parameter - * that gives access to the internal instance of `Callback`. - * @returns The return value is an instance of an `ValidationError`. - * @angularpackage - */ - public setFix( + public static define( + problem: string, fix: string, - callback: ResultCallback = this.#callback.getCallback( - 'setFix' - ) - ): this { - if (guard.string(fix, callback)) { - this.#fix = fix; - } - return this; + id?: Id, + template = ValidationError.template + ): ValidationError { + return new this(problem, fix, id, template); } /** - * Sets the validation error message of a `string` type from the provided `message` of the `ErrorMessage` interface. - * @param message An object of an `ErrorMessage` interface to build the message of a `string` type. The value is checked against - * the proper `object`. - * @param callback An optional callback function of `ResultCallback` type to handle the check whether the provided message is a string - * type or whether it's an object that contains required `problem` and `fix` properties. - * By default, it uses an internal callback under the `'setFix'` name, which can be initially set by the optional `callback` parameter - * that gives access to the internal instance of `Callback`. - * @returns The return value is an instance of an `ValidationError`. + * Checks whether the value of any type is the `ValidationError` instance of any or the given identification. + * @param value The value of any type to check against the `ValidationError` instance. + * @param id Optional unique identification of generic type variable `Id` to check whether the given `value` contains. + * @returns The return value is a `boolean` type indicating whether the given `value` is an instance of `ValidationError` of any or the + * supplied optional id properties. * @angularpackage */ - public setMessage( - message: string | ErrorMessage, - callback: ResultCallback< - CallbackPayload & ErrorMessage - > = this.#callback.getCallback('setMessage') - ): this { - this.message = is.string(message, callback) - ? // Sets a message of a string type from the provided message of `string`. - message - : // Sets a message of a string type from the provided message of `ErrorMessage`. - ValidationError.defineMessage(message, callback); - - // Sets `fix`, `problem` and `template` from the provided `message`. - if (is.object(message)) { - this.setFix(message.fix).setProblem(message.problem); - if (is.defined(message.template)) { - this.setTemplate(message.template); - } - } - return this; + public static isValidationError( + value: any, + id?: Id + ): value is ValidationError { + return super.isError(value, id); } + //#endregion public static methods. + //#region constructor. /** - * Sets description problem of a validation. - * @param problem Description of validation problem guarded by a `string` type. - * @param callback An optional callback function of `ResultCallback` type to handle the check whether the provided `problem` is a - * `string`. By default, it uses an internal callback under the `'setProblem'` name, which can be initially set by the optional `callback` - * parameter that gives access to the internal instance of `Callback`. - * @returns The return value is an instance of an `ValidationError`. + * Creates the `ValidationError` instance that represents validation error with the message built of the given described problem, its + * solution, and optional explicit identification, on the supplied or stored error message template. + * @param problem Description of the validation problem of a `string` type. + * @param fix A solution to the given validation issue of a `string` type. + * @param id Optional unique identification to the given `problem` of generic type variable `Id`. + * @param template Optional template of error message with the replaceable `{problem}`, `{fix}` and optional `{id}`, `{max}`, `{min}` and + * tags. By default, the value is picked from the static property `template`. * @angularpackage */ - public setProblem( + constructor( problem: string, - callback: ResultCallback = this.#callback.getCallback( - 'setProblem' - ) - ): this { - this.#problem = guard.string(problem, callback) ? problem : this.#problem; - return this; - } - - /** - * Sets the template of validation error message. - * @param template A message template guarded by a `string` type with replaceable `[problem]` and `[fix]` words. - * @param callback An optional callback function of `ResultCallback` type to handle the check whether the provided `template` is a - * `string` that contains `[fix]` and `[problem]` words. By default, it uses an internal callback under the `'setTemplate'` name, which - * can be initially set by the optional `callback` parameter that gives access to the internal instance of `Callback`. - * @angularpackage - */ - public setTemplate( - template: string, - callback: ResultCallback = this.#callback.getCallback( - 'setTemplate' - ) - ): this { - this.#tpl = ValidationError.#guardTemplate(template, callback) - ? template - : this.#tpl; - return this; - } - - /** - * Throws an error of `ValidationError` with the message built from the stored `fix`, `problem` and `template` or optionally from - * the provided `message`. - * @param message An optional object of an `ErrorMessage` interface to build the message of a `string` type. - * The value is checked against the proper object. - * @angularpackage - */ - public throw(message?: string | ErrorMessage): void { - if (is.defined(message)) { - this.setMessage(message); - } else { - this.updateMessage(); - } - throw this; - } - - /** - * Updates the message with a stored `fix`, `problem`, and `template`. - * @angularpackage - */ - public updateMessage(): void { - this.message = ValidationError.defineMessage({ - fix: this.#fix, - problem: this.#problem, - template: this.#tpl, - }); + fix: string, + id?: Id, + // field?: string, + template = ValidationError.template + ) { + super(problem, fix, id, template); } - //#endregion instance public methods. + //#endregion constructor. } diff --git a/src/lib/validation-errors.class.ts b/src/lib/validation-errors.class.ts new file mode 100644 index 0000000..78c0b14 --- /dev/null +++ b/src/lib/validation-errors.class.ts @@ -0,0 +1,65 @@ +import { CommonErrors } from './common-errors.class'; +import { ValidationError } from './validation-error.class'; +/** + * The `ValidationErrors` is an extension of the `CommonErrors` object that represents multiple identification numbers under which the + * errors of the `ValidationError` type are prepared to throw. + */ +export class ValidationErrors extends CommonErrors { + //#region constructor. + /** + * Creates the `ValidationErrors` instance of unique identification numbers under which the `ValidationError` objects are stored. + * @param id A rest parameter of generic type variable `Id` indicates unique identification numbers under which the `ValidationError` + * objects are stored. + * @angularpackage + */ + constructor(...id: Id[]) { + super(...id); + } + //#endregion constructor. + + //#region instance public methods. + /** + * Returns the `ValidationError` instance of the given unique identification `id` if set, otherwise `undefined`. + * @param id The unique identification number of generic type variable `ErrorId` to pick an error from the object. + * @returns The return value is the `ValidationError` instance of the given `id` if set, otherwise undefined. + * @angularpackage + */ + public get( + id: ErrorId + ): ValidationError | undefined { + return this.errors.get(id); + } + + /** + * Returns the object of set validation errors, where the key is a unique identification. + * @returns The return value is an `object` of set validation errors. + * @angularpackage + */ + public getErrors(): { [Key in Id]: ValidationError | undefined } { + return Object.fromEntries(this.errors.entries()) as any; + } + + /** + * Sets the `ValidationError` object with the message built from the given required `problem`, `fix`, `id` on the given or stored + * `template` under the given `id`. + * ! The error is not set, if the given `id` was not provided in the constructor. + * @param problem Description of the problem of a `string` type. + * @param fix A solution to the given `problem` of a string type. + * @param id The unique identification to the given `problem` of generic type variable `ErrorId`. + * @param template A template of error message with the replaceable `{problem}`, `{fix}`, `{id}` tags. By default, the value is equal + * to the static property `ValidationErrors.template`. + * @returns The return value is an instance of `Errors`. + * @angularpackage + */ + public set( + problem: string, + fix: string, + id: ErrorId, + template = ValidationErrors.template + ): this { + this.isAllowedId(id) && + this.errors.set(id, new ValidationError(problem, fix, id, template)); + return this; + } + //#endregion instance public methods. +} diff --git a/src/message-builder/index.ts b/src/message-builder/index.ts deleted file mode 100644 index 6a9974f..0000000 --- a/src/message-builder/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { MessageBuilder } from './src/message-builder.class'; -export { MessageBuilderTemplate } from './src/message-builder-template.class'; -export { MessageFunctionBuilder } from './src/message-function-builder.class'; diff --git a/src/message-builder/interface/message-template.interface.ts b/src/message-builder/interface/message-template.interface.ts deleted file mode 100644 index a2388da..0000000 --- a/src/message-builder/interface/message-template.interface.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface MessageTemplate { - [index: string]: string; -} diff --git a/src/message-builder/interface/parameter.interface.ts b/src/message-builder/interface/parameter.interface.ts deleted file mode 100644 index 8d17d26..0000000 --- a/src/message-builder/interface/parameter.interface.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface Parameter { - name: string; - type: string; -} diff --git a/src/message-builder/src/message-builder-template.class.ts b/src/message-builder/src/message-builder-template.class.ts deleted file mode 100644 index 3ea7a3d..0000000 --- a/src/message-builder/src/message-builder-template.class.ts +++ /dev/null @@ -1,31 +0,0 @@ -// @angular-package/type -import { is } from '@angular-package/type'; -// Interface. -import { MessageTemplate } from '../interface/message-template.interface'; -/** - * MessageBuilderTemplate. - */ -export class MessageBuilderTemplate { - // argument value is [value.type] type, must be [param.type] type - - #template: MessageTemplate = { - class: `[class][method]([param.name][param.type])[return]`, - function: `[function]([param.name][param.type])[return]`, - method: `[method]([param.name][param.type])[return]` - }; - - #type!: keyof MessageTemplate; - - /** - * Gets privately stored template of the provided in the constructor type. - */ - get get(): string { - return this.#template[this.#type]; - } - - constructor(type: 'class' | 'function' | 'method') { - if (is.string(type)) { - this.#type = type; - } - } -} diff --git a/src/message-builder/src/message-builder.class.ts b/src/message-builder/src/message-builder.class.ts deleted file mode 100644 index 0facfdb..0000000 --- a/src/message-builder/src/message-builder.class.ts +++ /dev/null @@ -1,82 +0,0 @@ -// @angular-package/type -import { is, guard, ResultCallback } from '@angular-package/type'; -// Class. -import { MessageBuilderTemplate } from './message-builder-template.class'; -/** - * Message builder for error message of a string type. - * @version Experimental This `object` is an experimental version of the message builder. - */ -export class MessageBuilder { - #regExp = { - class: /\[class\]/i, - function: /\[function\]/i, - method: /\[method\]/i, - param: { - name: /\[param.name\]/i, - type: /\[param.type\]/i, - }, - return: /\[return\]/i - }; - - #template: string; - - get get(): string { - return this.#template; - } - - constructor(template: 'class' | 'function' | 'method') { - this.#template = new MessageBuilderTemplate(template).get; - } - - public setClassName(name: string, callback?: ResultCallback): this { - if (guard.string(name, callback)) { - this.replace(this.#regExp.class, name); - } - return this; - } - - public setFunctionName(name: string, callback?: ResultCallback): this { - if (guard.string(name, callback)) { - this.replace(this.#regExp.function, name); - } - return this; - } - - public setMethodName(name: string, callback?: ResultCallback): this { - if (guard.string(name, callback)) { - this.replace(this.#regExp.method, name); - } - return this; - } - - public setParam(name: string, type: string = ''): this { - if (guard.string(name)) { - const param = `${name}${type}`; - this - .replace(this.#regExp.param.name, name) - .replace(this.#regExp.param.type, type); - - if (type.length > 0) { - this.replace(type, `: ${type}`); - } - } - return this; - } - - public setReturn(returns: string, callback?: ResultCallback): this { - if (guard.string(returns, callback)) { - this.replace(this.#regExp.return, returns.length > 0 ? `: ${returns}` : returns); - } - return this; - } - - private replace(searchValue: string | RegExp, replaceValue: string): this { - if (is.defined(searchValue)) { - this.#template = this.#template.replace( - searchValue, - is.string(replaceValue) ? replaceValue : '' - ); - } - return this; - } -} diff --git a/src/message-builder/src/message-function-builder.class.ts b/src/message-builder/src/message-function-builder.class.ts deleted file mode 100644 index 2afad1a..0000000 --- a/src/message-builder/src/message-function-builder.class.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { guard, is, ResultCallback } from '@angular-package/type'; -// Class. -import { MessageBuilder } from './message-builder.class'; -// Interface. -import { Parameter } from '../interface/parameter.interface'; -/** - * Message function builder for error message of a string type. - * @version Experimental This `object` is an experimental version of the message function builder that is using `MessageBuilder`. - */ -export class MessageFunctionBuilder { - #messageBuilder: MessageBuilder; - #name = ''; - #param: Parameter = { - name: '', - type: '' - }; - #return = ''; - - /** - * Gets the build function of a `string` type. - */ - get get(): string { - return this.#messageBuilder.get; - } - - /** - * Creates an instance of `MessageFunctionBuilder`. - */ - constructor() { - this.#messageBuilder = new MessageBuilder('function'); - } - - /** - * Builds string-type function from the privately stored `name`, `param`, and `return`. - */ - public build(): this { - this - .#messageBuilder - .setFunctionName(this.#name) - .setParam(this.#param.name, this.#param.type) - .setReturn(this.#return); - return this; - } - - /** - * Sets the function name to build function of a `string` type. - * @param name Function name of a `string` type. - * @param callback An optional callback function of `ResultCallback` to handle the result of the check whether the provided `name` - * is a `string` type. - * @returns The return value is an instance of `MessageFunctionBuilder`. - */ - public setName(name: string, callback?: ResultCallback): this { - if (guard.string(name, callback)) { - this.#name = name; - } - return this; - } - - /** - * Sets param name with an optional type of `function` to build function of a `string` type. - * @param name Parameter name of a function guarded by string. - * @param type An optional parameter type of function guarded by string. - * @param callback An optional callback function of `ResultCallback` to handle the result of the check whether the provided `name` - * is a `string` type. - * @returns The return value is an instance of `MessageFunctionBuilder`. - */ - public setParam(name: string, type?: string, callback?: ResultCallback): this { - if (guard.string(name, callback)) { - this.#param.name = name; - if (is.string(type)) { - this.#param.type = type; - } - } - return this; - } - - /** - * Sets return type to build the function of a `string` type. - * @param returns A return type of `function` guarded by `string`. - * @param callback An optional callback function of `ResultCallback` to handle the result of the check whether the provided `returns` - * is a `string` type. - * @returns The return value is an instance of `MessageFunctionBuilder`. - */ - public setReturn(returns: string, callback?: ResultCallback): this { - if (guard.string(returns, callback)) { - this.#return = returns; - } - return this; - } -} diff --git a/src/message-builder/test/message-builder.spec.ts b/src/message-builder/test/message-builder.spec.ts deleted file mode 100644 index a643d7d..0000000 --- a/src/message-builder/test/message-builder.spec.ts +++ /dev/null @@ -1,68 +0,0 @@ -// External class. -import { Testing, TestingToBeMatchers } from '@angular-package/testing'; -// Class. -import { MessageBuilder } from '../src/message-builder.class'; -/** - * Initialize `Testing`. - */ -const testing = new Testing(true, true); -const toBe = new TestingToBeMatchers(); -/** - * Tests. - */ -testing.describe(MessageBuilder.name, () => { - let messageClassBuilder = new MessageBuilder('class'); - let messageFunctionBuilder = new MessageBuilder('function'); - let messageMethodBuilder = new MessageBuilder('method'); - - beforeEach(() => (messageClassBuilder = new MessageBuilder('class'))); - beforeEach(() => (messageFunctionBuilder = new MessageBuilder('function'))); - beforeEach(() => (messageMethodBuilder = new MessageBuilder('method'))); - - // Basic testing. - testing - .it(`defined`, () => - toBe - .defined(MessageBuilder) - .defined(messageClassBuilder) - .defined(messageFunctionBuilder) - .defined(messageMethodBuilder) - .instance(messageClassBuilder, MessageBuilder) - .instance(messageFunctionBuilder, MessageBuilder) - .instance(messageMethodBuilder, MessageBuilder) - ) - .toBeClass(MessageBuilder); - - testing.it(`build function`, () => { - messageFunctionBuilder - .setFunctionName('guardString') - .setParam('value', 'string') - .setReturn('boolean'); - - toBe.string(messageFunctionBuilder.get); - console.log(messageFunctionBuilder.get); - expect(messageFunctionBuilder.get).toEqual('guardString(value: string): boolean'); - }); - - testing.it(`build class`, () => { - messageClassBuilder - .setClassName('Person.prototype.') - .setMethodName('setPerson') - .setParam('value?', 'object') - .setReturn('object'); - - toBe.string(messageClassBuilder.get); - expect(messageClassBuilder.get).toEqual('Person.prototype.setPerson(value?: object): object'); - }); - - testing.it(`build method`, () => { - messageMethodBuilder - .setMethodName('setPerson') - .setParam('value', 'string') - .setReturn('this'); - - console.log(messageMethodBuilder.get); - toBe.string(messageMethodBuilder.get); - expect(messageMethodBuilder.get).toEqual('setPerson(value: string): this'); - }); -}); diff --git a/src/message-builder/test/message-function-builder.spec.ts b/src/message-builder/test/message-function-builder.spec.ts deleted file mode 100644 index 74c2222..0000000 --- a/src/message-builder/test/message-function-builder.spec.ts +++ /dev/null @@ -1,38 +0,0 @@ -// External class. -import { Testing, TestingToBeMatchers } from '@angular-package/testing'; -// Class. -import { MessageFunctionBuilder } from '../src/message-function-builder.class'; -/** - * Initialize `Testing`. - */ -const testing = new Testing(true, true); -const toBe = new TestingToBeMatchers(); -/** - * Tests. - */ -testing.describe(MessageFunctionBuilder.name, () => { - let messageFunctionBuilder = new MessageFunctionBuilder(); - - beforeEach(() => (messageFunctionBuilder = new MessageFunctionBuilder())); - - // Basic testing. - testing - .it(`defined`, () => - toBe - .defined(messageFunctionBuilder) - .defined(messageFunctionBuilder) - .instance(messageFunctionBuilder, MessageFunctionBuilder) - ) - .toBeClass(MessageFunctionBuilder); - - testing.it(`build function`, () => { - messageFunctionBuilder - .setName('guardString') - .setParam('value', 'string') - .setReturn('boolean') - .build(); - - toBe.string(messageFunctionBuilder.get); - expect(messageFunctionBuilder.get).toEqual('guardString(value: string): boolean'); - }); -}); diff --git a/src/public-api.ts b/src/public-api.ts index 83f99bb..8804519 100644 --- a/src/public-api.ts +++ b/src/public-api.ts @@ -1,17 +1,15 @@ /* * Public API Surface of error */ -// Class. -export { ValidationError } from './lib/validation-error.class'; -// Interface. -export { ErrorMessage } from './interface/error-message.interface'; - -/* - * Experimental - */ export { // Class. - MessageBuilder, - MessageFunctionBuilder, - MessageBuilderTemplate, -} from './message-builder/'; + CommonError, + Error, + Errors, + RangeError, + RangeErrors, + TypeError, + TypeErrors, + ValidationError, + ValidationErrors +} from './lib'; diff --git a/src/test.ts b/src/test.ts index 52e5516..f26f742 100644 --- a/src/test.ts +++ b/src/test.ts @@ -18,7 +18,9 @@ declare const require: { // First, initialize the Angular testing environment. getTestBed().initTestEnvironment( BrowserDynamicTestingModule, - platformBrowserDynamicTesting() + platformBrowserDynamicTesting(), { + teardown: { destroyAfterEach: false } +} ); // Then we find all the tests. const context = require.context('./', true, /\.spec\.ts$/); diff --git a/src/test/common-error.spec.ts b/src/test/common-error.spec.ts new file mode 100644 index 0000000..ec464c2 --- /dev/null +++ b/src/test/common-error.spec.ts @@ -0,0 +1,86 @@ +// External class. +import { Testing, TestingToBeMatchers } from '@angular-package/testing'; +// Class. +import { CommonError } from '../lib/common-error.class'; +/** + * Initialize `Testing`. + */ +const testing = new Testing(true, true); +const toBe = new TestingToBeMatchers(); +/** + * Tests. + */ +testing.describe('[counter] CommonError', () => { + class TestError extends CommonError { + public static isError( + value: any, + id?: Id + ): value is CommonError { + return super.isError(value, id); + } + + public static defineMessage( + templateStringsArray: TemplateStringsArray, + ...values: any[] + ): string { + return super.defineMessage(templateStringsArray, ...values); + } + } + + + const problem = 'The value must be string type.'; + const fix = 'Provide the string type instead of number.'; + const id = 'AE: 427'; + const max = 427; + const min = 9; + const link = 'http://duckduckgo.com'; + const template = `{problem} {fix} {id} {max} {min} {type}`; + const type = 'string'; + const additional = { link, max, min, type }; + let testError = new TestError(problem, fix, id, template, additional); + + beforeEach(() => testError = new TestError(problem, fix, id, template, additional)); + + testing + .describe(`Accessors`, () => { + testing + .it(`TestError.prototype.fix`, () => expect(testError.fix).toEqual(fix)) + .it(`TestError.prototype.id`, () => expect(testError.id).toEqual(id)) + .it(`TestError.prototype.link`, () => expect(testError.link).toEqual(link)) + .it(`TestError.prototype.message`, () => + expect(testError.message).toEqual( + `${problem} ${fix} ${id} ${additional.max} ${additional.min} ${additional.type}` + ) + ) + .it(`TestError.prototype.problem`, () => + expect(testError.problem).toEqual(problem) + ) + .it(`TestError.prototype.template`, () => + expect(testError.template).toEqual(template) + ); + }).describe(`Properties`, () => { + testing.it(`TestError.template`, () => expect(TestError.template).toEqual(`Problem{id}: {problem} => Fix: {fix}`)); + }).describe(`Methods`, () => { + testing + .it('TestError.defineMessage`${problem}${fix}${id}${template}${additional}`', + () => expect(TestError.defineMessage`${problem}${fix}${id}${template}${additional}`).toEqual(`${problem} ${fix} ${id} ${additional.max} ${additional.min} ${additional.type}`)) + .it('TestError.defineMessage`${problem}${fix}${id}${template}${additional}`', + () => expect(TestError.defineMessage`${problem}${fix}${id}${template}${{ min: 1 }}`).toEqual(`${problem} ${fix} ${id} ${''} ${1} ${''}`)) + .it('TestError.defineMessage`${problem}${fix}${id}${template}`', + () => expect(TestError.defineMessage`${problem}${fix}${id}${template}`).toEqual(`${problem} ${fix} ${id} `)) + .it('TestError.defineMessage`${problem}${fix}`', + () => expect(TestError.defineMessage`${problem}${fix}`).toEqual(`Problem${''}: ${problem} => Fix: ${fix}`)) + .it('TestError.defineMessage`${problem}`', + () => expect(TestError.defineMessage`${problem}`).toEqual(`Problem${''}: ${problem} => Fix: ${''}`)) + .it('TestError.defineMessage`${problem}`', + () => expect(TestError.defineMessage`${problem}`).toEqual(`Problem${''}: ${problem} => Fix: ${''}`)) + .it('TestError.defineMessage``', + () => expect(TestError.defineMessage``).toEqual(`Problem${''}: ${''} => Fix: ${''}`)) + + .it(`TestError.isError()`, () => { + expect(TestError.isError(testError)).toBeTrue(); + expect(TestError.isError(testError, id)).toBeTrue(); + expect(TestError.isError(null, id)).toBeFalse(); + }); + }); +}); diff --git a/src/test/common-errors.spec.ts b/src/test/common-errors.spec.ts new file mode 100644 index 0000000..bb5fb8e --- /dev/null +++ b/src/test/common-errors.spec.ts @@ -0,0 +1,19 @@ +import { CommonErrors } from '../lib/common-errors.class'; +import { Error } from '../lib/error.class'; + +export class TestClass extends CommonErrors { + public get errors(): Map { + return super.errors; + } + public set( + problem: string, + fix: string, + id: ErrorId + ): this { + if (super.isAllowedId(id)) { + this.errors.set(id, new Error(problem, fix, id)); + } + return this; + } +} + diff --git a/src/test/error.spec.ts b/src/test/error.spec.ts new file mode 100644 index 0000000..a32bf01 --- /dev/null +++ b/src/test/error.spec.ts @@ -0,0 +1,134 @@ +// External class. +import { Testing, TestingToBeMatchers } from '@angular-package/testing'; +import { typeOf } from '@angular-package/type'; +// Class. +import { Error } from '../lib/error.class'; +/** + * Initialize `Testing`. + */ +const testing = new Testing(true, true); +const toBe = new TestingToBeMatchers(); +/** + * Tests. + */ +testing.describe('[counter] Error', () => { + // Prepare the values. + const fix = 'Provide string type value. Read more: https://duckduckgo.com/'; + const id = '427'; + const problem = 'The value must be a string type.'; + const template = `Problem(VE{id}): {problem}\nFix: {fix}`; + let error = new Error(problem, fix, id, template); + + beforeEach(() => error = new Error(problem, fix, id, template)); + + testing + + /** + * Static properties. + */ + .describe(`Static properties`, () => { + testing + .it(`Error.template`, () => { + expect(Error.template).toEqual(`Problem{id}: {problem} => Fix: {fix}`); + Error.template = `{problem} => Fix: {fix} of {id}`; + expect(Error.template).toEqual(`{problem} => Fix: {fix} of {id}`); + Error.template = `Problem{id}: {problem} => Fix: {fix}`; + }); + }) + + /** + * Instance accessors. + */ + .describe(`Instance accessors`, () => { + testing + + /** + * Error.prototype.fix + */ + .it(`Error.prototype.fix`, () => { + expect(error.fix).toEqual(fix); + toBe.string(fix); + }) + + /** + * Error.prototype.id + */ + .it(`Error.prototype.id`, () => expect(error.id).toEqual(id)) + + /** + * Error.prototype.name + */ + .it(`Error.prototype.name`, () => expect(error.name).toEqual('Error')) + + /** + * Error.prototype.problem + */ + .it(`Error.prototype.problem`, () => expect(error.problem).toEqual(problem)) + + /** + * Error.prototype.template + */ + .it(`Error.prototype.template`, () => expect(error.template).toEqual(template)) + + /** + * [Symbol.toStringTag] + */ + .it(`[Symbol.toStringTag]`, () => { + expect(typeOf(error)).toEqual('error'); + expect(Object.prototype.toString.call(error)).toEqual('[object Error]'); + }); + }) + + /** + * Static methods. + */ + .describe(`Static methods`, () => { + testing + + /** + * Error.define() + */ + .it(`Error.define()`, () => { + const e = Error.define(problem, fix, id, template); + expect(e.message).toEqual(`Problem(VE${id}): ${problem}\nFix: ${fix}`); + expect(e.fix).toEqual(fix); + expect(e.id).toEqual(id); + expect(e.problem).toEqual(problem); + }) + + /** + * Error.isError() + */ + .it(`Error.isError()`, () => { + expect(Error.isError(error)).toBeTrue(); + expect(Error.isError(error, id)).toBeTrue(); + }); + }) + + /** + * Constructor. + */ + .describe(`constructor()`, () => { + testing + .it(`(problem, fix, id)`, () => { + const e = new Error(problem, fix, id); + expect(e.message).toEqual(`Problem${id}: ${e.problem} => Fix: ${e.fix}`); + expect(e.fix).toEqual(fix); + expect(e.id).toEqual(id); + expect(e.problem).toEqual(problem); + }) + .it(`(problem, fix, id, template)`, () => { + const e = new Error(problem, fix, id, template); + expect(e.message).toEqual(`Problem(VE${id}): ${problem}\nFix: ${fix}`); + expect(e.fix).toEqual(fix); + expect(e.id).toEqual(id); + expect(e.problem).toEqual(problem); + }) + .it(`(problem, fix)`, () => { + const e = new Error(problem, fix); + expect(e.message).toEqual(`Problem: ${e.problem} => Fix: ${e.fix}`); + expect(e.fix).toEqual(fix); + expect(e.problem).toEqual(problem); + }); + }); +}); diff --git a/src/test/errors.spec.ts b/src/test/errors.spec.ts new file mode 100644 index 0000000..e27b6f1 --- /dev/null +++ b/src/test/errors.spec.ts @@ -0,0 +1,79 @@ +import { Testing, TestingToBeMatchers } from '@angular-package/testing'; +// Class. +import { Error } from '../lib/error.class'; +import { Errors } from '../lib/errors.class'; +import { testError } from './test-error.func'; +/** + * Initialize `Testing`. + */ +const testing = new Testing(true, true); +const toBe = new TestingToBeMatchers(); +/** + * Tests. + */ +testing.describe('[counter] Errors', () => { + // Prepare the values. + const id1 = '(E:127)'; + const id2 = '(RE:227)'; + const id3 = '(TE:327)'; + const id4 = '(VE:427)'; + + const fix = 'Provide string type value. Read more: https://duckduckgo.com/'; + const problem = 'The value must be a string type.'; + const template = `Problem(VE{id}): {problem}\nFix: {fix} {type}`; + + let errors = new Errors(id1, id2, id3, id4); + + beforeEach(() => (errors = new Errors(id1, id2, id3, id4))); + + testing.describe(`[counter] Methods`, () => { + testing + + /* + Errors.prototype.delete() + */ + .it(`Errors.prototype.delete()`, () => { + toBe.instance(errors, Errors); + errors.set(problem, fix, '(E:127)'); + expect(errors.has('(E:127)')).toBeTrue(); + errors.delete('(E:127)'); + expect(errors.has('(E:127)')).toBeFalse(); + }) + + /* + Errors.prototype.has() + */ + .it(`Errors.prototype.has()`, () => { + errors.set(problem, fix, id4); + expect(errors.has(id4)).toBeTrue(); + }) + + /* + Errors.prototype.set() + */ + .it(`Errors.prototype.set()`, () => { + errors.set(problem, fix, id3, template); + expect(errors.has(id3)).toBeTrue(); + }) + + /* + Errors.prototype.throw() + */ + .it(`Errors.prototype.throw()`, () => { + try { + errors.set(problem, fix, id4, template).throw('(VE:427)'); + } catch (e) { + if (e instanceof Error) { + testError(e, { + fix, + id: id4, + name: 'Error', + message: `Problem(VE${id4}): ${problem}\nFix: ${fix} ${''}`, + problem, + template, + }); + } + } + }); + }); +}); diff --git a/src/test/range-error.spec.ts b/src/test/range-error.spec.ts new file mode 100644 index 0000000..e157303 --- /dev/null +++ b/src/test/range-error.spec.ts @@ -0,0 +1,209 @@ +// External class. +import { Testing, TestingToBeMatchers } from '@angular-package/testing'; +import { typeOf } from '@angular-package/type'; +// Class. +import { RangeError } from '../lib/range-error.class'; +/** + * Initialize `Testing`. + */ +const testing = new Testing(true, true); +const toBe = new TestingToBeMatchers(); +/** + * Tests. + */ +testing.describe('[counter] RangeError', () => { + // Prepare the values. + const fix = 'Provide string type value. Read more: https://duckduckgo.com/'; + const id = '427'; + const min = 9; + const max = 27; + const problem = 'The value'; + const template = `Problem(VE{id}): {problem} {min} and {max}.\nFix: {fix}.`; + + let rangeError = new RangeError(problem, fix, id, min, max, template); + + beforeEach(() => rangeError = new RangeError(problem, fix, id, min, max, template)); + + testing + + /** + * Static properties. + */ + .describe(`Static properties`, () => { + testing.it(`RangeError.template`, () => { + expect(RangeError.template).toEqual(`Problem{id}: {problem} => Fix: {fix} between {min} and {max}`); + RangeError.template = `{problem} => Fix: {fix} of {id}`; + expect(RangeError.template).toEqual(`{problem} => Fix: {fix} of {id}`); + RangeError.template = `Problem{id}: {problem} => Fix: {fix} between {min} and {max}`; + }); + }) + + /** + * Instance accessors. + */ + .describe(`Instance accessors`, () => { + testing + + /** + * RangeError.prototype.fix + */ + .it(`RangeError.prototype.fix`, () => expect(rangeError.fix).toEqual(fix)) + + /** + * RangeError.prototype.id + */ + .it(`RangeError.prototype.id`, () => expect(rangeError.id).toEqual(id)) + + /** + * RangeError.prototype.max + */ + .it(`RangeError.prototype.max`, () => expect(rangeError.max).toEqual(max)) + + /** + * RangeError.prototype.min + */ + .it(`RangeError.prototype.min`, () => expect(rangeError.min).toEqual(min)) + + /** + * RangeError.prototype.name + */ + .it(`RangeError.prototype.name`, () => expect(rangeError.name).toEqual('RangeError')) + + /** + * RangeError.prototype.problem + */ + .it(`RangeError.prototype.problem`, () => expect(rangeError.problem).toEqual(problem)) + + /** + * RangeError.prototype.range + */ + .it(`RangeError.prototype.range`, () => expect(rangeError.range).toEqual({ min, max })) + + /** + * RangeError.prototype.template + */ + .it(`RangeError.prototype.template`, () => expect(rangeError.template).toEqual(template)) + + /** + * [Symbol.toStringTag] + */ + .it(`[Symbol.toStringTag]`, () => { + expect(typeOf(rangeError)).toEqual('rangeerror'); + expect(Object.prototype.toString.call(rangeError)).toEqual( + '[object RangeError]' + ); + }); + }) + + /** + * Static methods. + */ + .describe(`Static methods`, () => { + testing + + /** + * RangeError.define() + */ + .it(`RangeError.define(problem, fix, id, min, max, template)`, () => { + const e = RangeError.define(problem, fix, id, min, max, template); + expect(e.message).toEqual(`Problem(VE${id}): ${problem} ${min} and ${max}.\nFix: ${fix}.`); + // Required. + expect(e.fix).toEqual(fix); + expect(e.problem).toEqual(problem); + // Optional. + expect(e.id).toEqual(id); + expect(e.max).toEqual(max); + expect(e.min).toEqual(min); + expect(e.template).toEqual(template); + }) + + /** + * RangeError.isRangeError() + */ + .it(`RangeError.isRangeError()`, () => { + expect(RangeError.isRangeError(rangeError)).toBeTrue(); + expect(RangeError.isRangeError(rangeError, id)).toBeTrue(); + expect(RangeError.isRangeError(rangeError, undefined, min)).toBeTrue(); + expect(RangeError.isRangeError(rangeError, undefined, undefined, max)).toBeTrue(); + expect(RangeError.isRangeError(rangeError, undefined, min, max)).toBeTrue(); + expect(RangeError.isRangeError(rangeError, id, min, undefined)).toBeTrue(); + expect(RangeError.isRangeError(rangeError, id, undefined, max)).toBeTrue(); + expect(RangeError.isRangeError(rangeError, id, min, max)).toBeTrue(); + }); + }) + + /** + * Constructor. + */ + .describe(`constructor()`, () => { + testing + .it(`(problem, fix)`, () => { + const e = new RangeError(problem, fix); + expect(e.message).toEqual(`Problem${''}: ${problem} => Fix: ${fix} between ${''} and ${''}`); + // Required. + expect(e.fix).toEqual(fix); + expect(e.problem).toEqual(problem); + // Optional. + expect(e.id).toBeUndefined(); + expect(e.max).toBeUndefined(); + expect(e.min).toBeUndefined(); + expect(e.template).toEqual(RangeError.template); + }) + + .it(`(problem, fix, id, min, undefined)`, () => { + const e = new RangeError(problem, fix, id, min, undefined); + expect(e.message).toEqual(`Problem${id}: ${problem} => Fix: ${fix} between ${min} and ${''}`); + // Required. + expect(e.fix).toEqual(fix); + expect(e.problem).toEqual(problem); + // Optional. + expect(e.id).toEqual(id); + expect(e.max).toBeUndefined(); + expect(e.min).toEqual(min); + expect(e.template).toEqual(RangeError.template); + }) + .it(`(problem, fix, id, undefined, max)`, () => { + const e = new RangeError(problem, fix, id, undefined, max); + expect(e.message).toEqual(`Problem${id}: ${problem} => Fix: ${fix} between ${''} and ${max}`); + // Required. + expect(e.fix).toEqual(fix); + expect(e.problem).toEqual(problem); + // Optional. + expect(e.id).toEqual(id); + expect(e.max).toEqual(max); + expect(e.min).toBeUndefined(); + expect(e.template).toEqual(RangeError.template); + }) + .it(`(problem, fix, id, min, max)`, () => { + const e = new RangeError(problem, fix, id, min, max); + expect(e.message).toEqual(`Problem${id}: ${problem} => Fix: ${fix} between ${min} and ${max}`); + // Required. + expect(e.fix).toEqual(fix); + expect(e.problem).toEqual(problem); + // Optional. + expect(e.id).toEqual(id); + expect(e.max).toEqual(max); + expect(e.min).toEqual(min); + expect(e.template).toEqual(RangeError.template); + }) + .it(`('The age', 'Try to change minimum or maximum', id, min, max, template)`, () => { + const e = new RangeError( + `The age`, + `Try to change minimum or maximum`, + id, + min, + max, + template + ); + expect(e.message).toEqual(`Problem(VE${id}): ${'The age'} ${min} and ${max}.\nFix: ${'Try to change minimum or maximum'}.`); + // Required. + expect(e.fix).toEqual(`Try to change minimum or maximum`); + expect(e.problem).toEqual(`The age`); + // Optional. + expect(e.id).toEqual(id); + expect(e.max).toEqual(max); + expect(e.min).toEqual(min); + expect(e.template).toEqual(template); + }); + }); +}); diff --git a/src/test/range-errors.spec.ts b/src/test/range-errors.spec.ts new file mode 100644 index 0000000..8f50972 --- /dev/null +++ b/src/test/range-errors.spec.ts @@ -0,0 +1,86 @@ +import { Testing, TestingToBeMatchers } from '@angular-package/testing'; +// Class. +import { RangeErrors } from '../lib/range-errors.class'; +import { RangeError } from '../lib/range-error.class'; +// Function. +import { testError } from './test-error.func'; +/** + * Initialize `Testing`. + */ +const testing = new Testing(true, true); +const toBe = new TestingToBeMatchers(); +/** + * Tests. + */ +testing.describe('[counter] RangeErrors', () => { + // Prepare the values. + const id1 = '(E:127)'; + const id2 = '(RE:227)'; + const id3 = '(TE:327)'; + const id4 = '(VE:427)'; + + const min = 9; + const max = 27; + + const fix = 'Provide string type value. Read more: https://duckduckgo.com/'; + const problem = 'The value must be a string type.'; + const template = `Problem(VE{id}): {problem}\nFix: {fix} {min} {max}`; + + let errors = new RangeErrors(id1, id2, id3, id4); + + beforeEach(() => (errors = new RangeErrors(id1, id2, id3, id4))); + + testing.describe(`[counter] Methods`, () => { + testing + + /* + RangeErrors.prototype.delete() + */ + .it(`RangeErrors.prototype.delete()`, () => { + toBe.instance(errors, RangeErrors); + errors.set(problem, fix, '(E:127)'); + expect(errors.has('(E:127)')).toBeTrue(); + errors.delete('(E:127)'); + expect(errors.has('(E:127)')).toBeFalse(); + }) + + /* + RangeErrors.prototype.has() + */ + .it(`RangeErrors.prototype.has()`, () => { + errors.set(problem, fix, id4, min, max, template); + expect(errors.has(id4)).toBeTrue(); + }) + + /* + RangeErrors.prototype.set() + */ + .it(`RangeErrors.prototype.set()`, () => { + errors.set(problem, fix, id3, min, max, template); + expect(errors.has(id3)).toBeTrue(); + }) + + /* + RangeErrors.prototype.throw() + */ + .it(`RangeErrors.prototype.throw()`, () => { + try { + errors.set(problem, fix, id4, min, max, template).throw(id4); + } catch (e) { + if (e instanceof RangeError) { + testError(e, { + fix, + id: id4, + name: 'RangeError', + message: `Problem(VE${id4}): ${problem}\nFix: ${fix} ${min} ${max}`, + min, + max, + range: {min, max}, + problem, + template, + }); + } + } + }); + }); +}); diff --git a/src/test/test-error.func.ts b/src/test/test-error.func.ts new file mode 100644 index 0000000..a5b252e --- /dev/null +++ b/src/test/test-error.func.ts @@ -0,0 +1,17 @@ + + +export const testError = (value: any, check: any) => { + + expect(value.fix).toEqual(check.fix); + expect(value.id).toEqual(check.id); + expect(value.link).toEqual(check.link); + expect(value.max).toEqual(check.max); + expect(value.min).toEqual(check.min); + expect(value.name).toEqual(check.name); + expect(value.problem).toEqual(check.problem); + expect(value.range).toEqual(check.range); + expect(value.message).toEqual(check.message); + expect(value.template).toEqual(check.template); + expect(value.type).toEqual(check.type); + +}; diff --git a/src/test/type-error.spec.ts b/src/test/type-error.spec.ts new file mode 100644 index 0000000..7b31d0c --- /dev/null +++ b/src/test/type-error.spec.ts @@ -0,0 +1,177 @@ +// External class. +import { Testing, TestingToBeMatchers } from '@angular-package/testing'; +import { typeOf } from '@angular-package/type'; +// Class. +import { TypeError } from '../lib/type-error.class'; +/** + * Initialize `Testing`. + */ +const testing = new Testing(true, true); +const toBe = new TestingToBeMatchers(); +/** + * Tests. + */ +testing.describe('[counter] TypeError', () => { + // Prepare the values. + const fix = 'Provide string type value. Read more: https://duckduckgo.com/'; + const id = '427'; + const problem = 'The value must be a string type.'; + const template = `Problem(VE{id}): {problem} {type}\nFix: {fix}`; + const type = 'Symbol'; + + let typeError = new TypeError(problem, fix, id, type, template); + + beforeEach(() => typeError = new TypeError(problem, fix, id, type, template)); + + testing + + /** + * Static properties. + */ + .describe(`Static properties`, () => { + testing + .it(`TypeError.template`, () => { + expect(TypeError.template).toEqual(`Problem{id}: {problem} => Fix: {fix} must be of the {type}`); + TypeError.template = `{problem} => Fix: {fix} of {id}`; + expect(TypeError.template).toEqual(`{problem} => Fix: {fix} of {id}`); + TypeError.template = `Problem{id}: {problem} => Fix: {fix} must be of the {type}`; + }); + }) + + /** + * Instance accessors. + */ + .describe(`Instance accessors`, () => { + testing + + /** + * TypeError.prototype.expectedType + */ + .it(`TypeError.prototype.expectedType`, () => expect(typeError.type).toEqual(type)) + + /** + * TypeError.prototype.fix + */ + .it(`TypeError.prototype.fix`, () => expect(typeError.fix).toEqual(fix)) + + /** + * TypeError.prototype.id + */ + .it(`TypeError.prototype.id`, () => expect(typeError.id).toEqual(id)) + + /** + * TypeError.prototype.name + */ + .it(`TypeError.prototype.name`, () => expect(typeError.name).toEqual('TypeError')) + + /** + * TypeError.prototype.problem + */ + .it(`TypeError.prototype.problem`, () => expect(typeError.problem).toEqual(problem)) + + /** + * TypeError.prototype.template + */ + .it(`TypeError.prototype.template`, () => expect(typeError.template).toEqual(template)) + + /** + * [Symbol.toStringTag] + */ + .it(`[Symbol.toStringTag]`, () => { + expect(typeOf(typeError)).toEqual('typeerror'); + expect(Object.prototype.toString.call(typeError)).toEqual('[object TypeError]'); + }); + }) + + /** + * Static methods. + */ + .describe(`Static methods`, () => { + testing + + /** + * TypeError.define() + */ + .it(`TypeError.define(problem, fix, id, type, template)`, () => { + const e = TypeError.define(problem, fix, id, type, template); + expect(e.message).toEqual(`Problem(VE${id}): ${problem} ${type}\nFix: ${fix}`); + // Required. + expect(e.fix).toEqual(fix); + expect(e.problem).toEqual(problem); + // Optional. + expect(e.type).toEqual(type); + expect(e.id).toEqual(id); + expect(e.template).toEqual(template); + }) + + /** + * TypeError.isTypeError() + */ + .it(`TypeError.isTypeError()`, () => { + expect(TypeError.isTypeError(typeError)).toBeTrue(); + expect(TypeError.isTypeError(typeError, id, type)).toBeTrue(); + }); + }) + + /** + * Constructor. + */ + .describe(`constructor()`, () => { + testing + .it(`(problem, fix)`, () => { + const e = new TypeError(problem, fix); + expect(e.message).toEqual(`Problem${''}: ${problem} => Fix: ${fix} must be of the ${''}`); + // Required. + expect(e.fix).toEqual(fix); + expect(e.problem).toEqual(problem); + // Optional. + expect(e.id).toBeUndefined(); + expect(e.type).toBeUndefined(); + expect(e.template).toEqual(TypeError.template); + }) + .it(`(problem, fix, undefined, type)`, () => { + const e = new TypeError(problem, fix, undefined, type); + expect(e.message).toEqual(`Problem${''}: ${problem} => Fix: ${fix} must be of the ${type}`); + // Required. + expect(e.fix).toEqual(fix); + expect(e.problem).toEqual(problem); + // Optional. + expect(e.id).toBeUndefined(); + expect(e.type).toEqual(type); + expect(e.template).toEqual(TypeError.template); + }) + .it(`(problem, fix, id)`, () => { + const e = new TypeError(problem, fix, id); + expect(e.message).toEqual(`Problem${id}: ${problem} => Fix: ${fix} must be of the ${''}`); + // Required. + expect(e.fix).toEqual(fix); + expect(e.problem).toEqual(problem); + // Optional. + expect(e.id).toEqual(id); + expect(e.type).toBeUndefined(); + expect(e.template).toEqual(TypeError.template); + }) + .it(`(problem, fix, id, type)`, () => { + const e = new TypeError(problem, fix, id, type); + expect(e.message).toEqual(`Problem${id}: ${problem} => Fix: ${fix} must be of the ${type}`); + // Required. + expect(e.fix).toEqual(fix); + expect(e.problem).toEqual(problem); + // Optional. + expect(e.id).toEqual(id); + expect(e.type).toEqual(type); + expect(e.template).toEqual(TypeError.template); + }) + .it(`(problem, fix, id, type, template)`, () => { + const e = new TypeError(problem, fix, id, type, template); + expect(e.message).toEqual(`Problem(VE${id}): ${problem} ${type}\nFix: ${fix}`); + // Required. + expect(e.fix).toEqual(fix); + expect(e.problem).toEqual(problem); + // Optional. + expect(e.id).toEqual(id); + expect(e.type).toEqual(type); + expect(e.template).toEqual(template); + }); + }); +}); diff --git a/src/test/type-errors.spec.ts b/src/test/type-errors.spec.ts new file mode 100644 index 0000000..6a6615d --- /dev/null +++ b/src/test/type-errors.spec.ts @@ -0,0 +1,114 @@ + +import { Testing, TestingToBeMatchers } from '@angular-package/testing'; +// Class. +import { TypeError } from '../lib/type-error.class'; +import { TypeErrors } from '../lib/type-errors.class'; +import { testError } from './test-error.func'; +/** + * Initialize `Testing`. + */ +const testing = new Testing(true, true); +const toBe = new TestingToBeMatchers(); +/** + * Tests. + */ +testing.describe('[counter] TypeErrors', () => { + // Prepare the values. + const id1 = '(E:127)'; + const id2 = '(RE:227)'; + const id3 = '(TE:327)'; + const id4 = '(VE:427)'; + + const fix = 'Provide string type value. Read more: https://duckduckgo.com/'; + const problem = 'The value must be a string type.'; + const type = 'number'; + const template = `Problem(VE{id}): {problem}\nFix: {fix} {type}`; + + let errors = new TypeErrors(id1, id2, id3, id4); + + beforeEach(() => errors = new TypeErrors(id1, id2, id3, id4)); + + testing + .describe(`[counter] Methods`, () => { + testing + + /* + TypeErrors.prototype.delete() + */ + .it(`TypeErrors.prototype.delete()`, () => { + toBe.instance(errors, TypeErrors); + errors.set(problem, fix, '(E:127)'); + expect(errors.has('(E:127)')).toBeTrue(); + errors.delete('(E:127)'); + expect(errors.has('(E:127)')).toBeFalse(); + }) + + /* + TypeErrors.prototype.has() + */ + .it(`TypeErrors.prototype.has()`, () => { + errors.set(problem, fix, id4, type, template); + expect(errors.has(id4)).toBeTrue(); + }) + + /* + TypeErrors.prototype.set() + */ + .it(`TypeErrors.prototype.set()`, () => { + errors.set(problem, fix, id3, type, template); + expect(errors.has(id3)).toBeTrue(); + }) + + /* + TypeErrors.prototype.throw() + */ + .it(`TypeErrors.prototype.throw()`, () => { + try { + errors.set(problem, fix, id4).throw(id4); + } catch (e) { + if (e instanceof TypeError) { + testError(e, { + fix, + id: id4, + name: 'TypeError', + message: `Problem${id4}: ${problem} => Fix: ${fix} must be of the ${''}`, + problem, + template: `Problem{id}: {problem} => Fix: {fix} must be of the {type}` + }); + } + } + + try { + errors.set(problem, fix, id4, type).throw(id4); + } catch (e) { + if (e instanceof TypeError) { + testError(e, { + fix, + id: id4, + name: 'TypeError', + message: `Problem${id4}: ${problem} => Fix: ${fix} must be of the ${type}`, + problem, + template: `Problem{id}: {problem} => Fix: {fix} must be of the {type}`, + type + }); + } + } + + try { + errors.set(problem, fix, id4, type, template).throw(id4); + } catch (e) { + if (e instanceof TypeError) { + testError(e, { + fix, + id: id4, + name: 'TypeError', + message: `Problem(VE${id4}): ${problem}\nFix: ${fix} ${type}`, + problem, + template, + type + }); + } + } + }); + }); +}); diff --git a/src/test/validation-error.spec.ts b/src/test/validation-error.spec.ts index 6edc5f9..80b4274 100644 --- a/src/test/validation-error.spec.ts +++ b/src/test/validation-error.spec.ts @@ -10,84 +10,95 @@ const toBe = new TestingToBeMatchers(); /** * Tests. */ -testing.describe('ValidationError', () => { - testing.describe('throw', () => { - const problem = 'My callback problem'; - const fix = 'Possible fix does not exist'; - try { - throw new ValidationError({ problem, fix }); - } catch (e: any) { - testing - .toBeClass(ValidationError) - .toBe('instanceof ValidationError', e instanceof ValidationError, true) - .toBeStringType( - e.problem, - undefined, - '`e.problem` must be of a `string` type' - ) - .toBeStringType(e.fix, undefined, '`e.fix` must be of a `string` type'); - } - }); +testing.describe('[counter] ValidationError', () => { + // Prepare the values. + const fix = 'Provide string type value. Read more: https://duckduckgo.com/'; + const id = '427'; + const problem = 'The value must be a string type.'; + const template = `Problem(VE{id}): {problem}\nFix: {fix}`; + const value = Symbol(123); + let validationError = new ValidationError(problem, fix, id, template); - testing.describe('instantiate', () => { - let fix: any; - let problem: any; - let validationError: any; + beforeEach(() => validationError = new ValidationError(problem, fix, id, template)); - beforeEach(() => { - fix = 'There is no solution to the described problem.'; - problem = 'The problem has no solution.'; - validationError = new ValidationError({ fix, problem }); - }); + testing - testing.it(`with the message of a \`string\` type`, () => { - const message = 'Validation error message'; - validationError = new ValidationError(message); - toBe.string(validationError.message); - expect(validationError.message).toContain(message); - }); + /** + * Accessors. + */ + .describe(`accessors`, () => { + testing - testing.it(`with the message of the \`ErrorMessage\` interface`, () => { - toBe - .string(validationError.message) - .string(validationError.problem) - .string(validationError.fix); + /** + * ValidationError.prototype.fix + */ + .it(`ValidationError.prototype.fix`, () => expect(validationError.fix).toEqual(fix)) - // to Equal. - expect(validationError.problem).toEqual(problem); - expect(validationError.fix).toEqual(fix); - expect(validationError.message).toEqual( - ValidationError.template - .replace(`[fix]`, fix) - .replace(`[problem]`, problem) - ); - // toContain. - expect(validationError.message).toContain(fix); - expect(validationError.message).toContain(problem); - }); - }); + /** + * ValidationError.prototype.id + */ + .it(`ValidationError.prototype.id`, () => expect(validationError.id).toEqual(id)) - testing.describe('static defineMessage()', () => { - let fix: any; - let problem: any; - let errorMessage: any; + /** + * ValidationError.prototype.problem + */ + .it(`ValidationError.prototype.problem`, () => expect(validationError.problem).toEqual(problem)) - beforeEach(() => { - fix = 'There is no solution to the described problem.'; - problem = 'The problem has no solution.'; - errorMessage = ValidationError.defineMessage({ fix, problem }); - }); + /** + * ValidationError.prototype.template + */ + .it(`ValidationError.prototype.template`, () => expect(validationError.template).toEqual(template)); + // .it(`[Symbol.toStringTag]`, () => {}); + }) + + /** + * Static methods. + */ + .describe(`Static methods`, () => { + testing + /** + * ValidationError.define() + */ + .it(`ValidationError.define()`, () => { + const e = ValidationError.define(problem, fix, id, template); + expect(e.message).toEqual(`Problem(VE${id}): ${problem}\nFix: ${fix}`); + expect(e.fix).toEqual(fix); + expect(e.id).toEqual(id); + expect(e.problem).toEqual(problem); + }) - testing.it(`with the message of the \`ErrorMessage\` interface`, () => { - toBe.string(errorMessage); - expect(errorMessage).toEqual( - ValidationError.template - .replace(`[fix]`, fix) - .replace(`[problem]`, problem) - ); - // toContain. - expect(errorMessage).toContain(fix); - expect(errorMessage).toContain(problem); + /** + * ValidationError.isValidationError() + */ + .it(`ValidationError.isValidationError()`, () => { + expect(validationError.id).toEqual(id); + }); + }) + + /** + * Constructor. + */ + .describe(`constructor()`, () => { + testing + .it(`(problem, fix, id)`, () => { + const e = new ValidationError(problem, fix, id); + expect(e.message).toEqual(`Problem${id}: ${e.problem} => Fix: ${e.fix}`); + expect(e.fix).toEqual(fix); + expect(e.id).toEqual(id); + expect(e.problem).toEqual(problem); + }) + .it(`(problem, fix, id, template)`, () => { + const e = new ValidationError(problem, fix, id, template); + expect(e.message).toEqual(`Problem(VE${id}): ${problem}\nFix: ${fix}`); + expect(e.fix).toEqual(fix); + expect(e.id).toEqual(id); + expect(e.problem).toEqual(problem); + }) + .it(`(problem, fix)`, () => { + const e = new ValidationError(problem, fix); + expect(e.message).toEqual(`Problem: ${e.problem} => Fix: ${e.fix}`); + expect(e.fix).toEqual(fix); + expect(e.problem).toEqual(problem); + }); }); - }); }); diff --git a/src/test/validation-errors.spec.ts b/src/test/validation-errors.spec.ts new file mode 100644 index 0000000..c6d9e46 --- /dev/null +++ b/src/test/validation-errors.spec.ts @@ -0,0 +1,78 @@ +import { Testing, TestingToBeMatchers } from '@angular-package/testing'; +// Class. +import { ValidationErrors } from '../lib/validation-errors.class'; +import { testError } from './test-error.func'; +/** + * Initialize `Testing`. + */ +const testing = new Testing(true, true); +const toBe = new TestingToBeMatchers(); +/** + * Tests. + */ +testing.describe('[counter] ValidationErrors', () => { + // Prepare the values. + const id1 = '(E:127)'; + const id2 = '(RE:227)'; + const id3 = '(TE:327)'; + const id4 = '(VE:427)'; + + const fix = 'Provide string type value. Read more: https://duckduckgo.com/'; + const problem = 'The value must be a string type.'; + const template = `Problem(VE{id}): {problem}\nFix: {fix} {type}`; + + let errors = new ValidationErrors(id1, id2, id3, id4); + + beforeEach(() => (errors = new ValidationErrors(id1, id2, id3, id4))); + + testing.describe(`[counter] Methods`, () => { + testing + + /* + ValidationErrors.prototype.delete() + */ + .it(`ValidationErrors.prototype.delete()`, () => { + toBe.instance(errors, ValidationErrors); + errors.set(problem, fix, '(E:127)'); + expect(errors.has('(E:127)')).toBeTrue(); + errors.delete('(E:127)'); + expect(errors.has('(E:127)')).toBeFalse(); + }) + + /* + ValidationErrors.prototype.has() + */ + .it(`ValidationErrors.prototype.has()`, () => { + errors.set(problem, fix, id4); + expect(errors.has(id4)).toBeTrue(); + }) + + /* + ValidationErrors.prototype.set() + */ + .it(`ValidationErrors.prototype.set()`, () => { + errors.set(problem, fix, id3, template); + expect(errors.has(id3)).toBeTrue(); + }) + + /* + ValidationErrors.prototype.throw() + */ + .it(`ValidationErrors.prototype.throw()`, () => { + try { + errors.set(problem, fix, id4, template).throw('(VE:427)'); + } catch (e) { + if (e instanceof Error) { + testError(e, { + fix, + id: id4, + name: 'ValidationError', + message: `Problem(VE${id4}): ${problem}\nFix: ${fix} ${''}`, + problem, + template, + }); + } + } + }); + }); +}); diff --git a/src/type/allowed-callback.type.ts b/src/type/allowed-callback.type.ts deleted file mode 100644 index 9e8a189..0000000 --- a/src/type/allowed-callback.type.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Allowed callback function names available for the `ValidationError`. - */ -export type VEAllowedCallback = 'setFix' | 'setMessage' | 'setProblem' | 'setTemplate'; diff --git a/tsconfig.lib.json b/tsconfig.lib.json index 1407202..3e0398f 100644 --- a/tsconfig.lib.json +++ b/tsconfig.lib.json @@ -10,7 +10,7 @@ "types": [], "lib": [ "dom", - "es2018" + "es2020" ] }, "exclude": [ diff --git a/tsconfig.spec.json b/tsconfig.spec.json index bc7fbe9..715dd0a 100644 --- a/tsconfig.spec.json +++ b/tsconfig.spec.json @@ -3,9 +3,6 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "../../out-tsc/spec", - "paths": { - "@angular/*": [ "./node_modules/@angular/*" ] - }, "types": [ "jasmine" ]