diff --git a/README.md b/README.md index efb76cca..69d6ac9e 100644 --- a/README.md +++ b/README.md @@ -4,22 +4,21 @@ [![CI](https://github.com/stackbuilders/assertive-ts/actions/workflows/ci.yml/badge.svg)](https://github.com/stackbuilders/assertive-ts/actions/workflows/ci.yml) [![Release](https://github.com/stackbuilders/assertive-ts/actions/workflows/release.yml/badge.svg)](https://github.com/stackbuilders/assertive-ts/actions/workflows/release.yml) [![Pages](https://github.com/stackbuilders/assertive-ts/actions/workflows/pages.yml/badge.svg)](https://github.com/stackbuilders/assertive-ts/actions/workflows/pages.yml) -[![NPM version](https://img.shields.io/npm/v/@stackbuilders/assertive-ts?logo=npm)](https://www.npmjs.com/package/@stackbuilders/assertive-ts) -[![NPM bundle size](https://img.shields.io/bundlephobia/min/@stackbuilders/assertive-ts)](https://www.npmjs.com/package/@stackbuilders/assertive-ts) -[![NPM downloads](https://img.shields.io/npm/dm/@stackbuilders/assertive-ts)](https://www.npmjs.com/package/@stackbuilders/assertive-ts) -[![NPM license](https://img.shields.io/npm/l/@stackbuilders/assertive-ts)](./LICENSE) -[![GitHub Release Date](https://img.shields.io/github/release-date/stackbuilders/assertive-ts)](https://github.com/stackbuilders/assertive-ts/releases) +[![NPM Core version](https://img.shields.io/npm/v/@assertive-ts/core?logo=npm&label=core)](https://www.npmjs.com/package/@assertive-ts/core) +[![NPM license](https://img.shields.io/npm/l/@assertive-ts/core)](https://github.com/stackbuilders/assertive-ts/blob/main/LICENSE) [![Known Vulnerabilities](https://snyk.io/test/github/stackbuilders/assertive-ts/badge.svg)](https://snyk.io/test/github/stackbuilders/assertive-ts) -# AssertiveTS +# Assertive.ts A type-safe fluent assertion library written in TypeScript and inspired by [Jest](https://jestjs.io/docs/expect) assertions and the popular [AssertJ](https://assertj.github.io/doc/). -This library is designed to work in the browser and in Node.js. It ships with a rich set of expressive and flexible matchers that allows chaining multiple assertions. AssertiveTS is framework agnostic and should be used with a test framework such as [Jest](/docs/jest-tutorial.md), [Mocha](/docs/mocha-tutorial.md), or Ava. +This library is designed to work in the browser and in Node.js. It ships with a rich set of expressive and flexible matchers that allows chaining multiple assertions. Assertive.ts is framework agnostic and should be used with a test framework such as [Jest](/docs/jest-tutorial.md), [Mocha](/docs/mocha-tutorial.md), or Ava. + +**🚨 BREAKING CHANGES:** Since v2, the `@stackbuilders/assertive-ts` package has been renamed to `@assertive-ts/core` so we can group other packages, such as plugins, into the same namespace. Check the [packages](#packages) section for more info. ## Type-safe library -A distinctive feature of AssertiveTS with other assertion libraries is that it leverages the TypeScript compiler to avoid type coercions and mismatches. It also infers the static type of the value you want to assert and provides you with intelligent matcher completion and signature help so that you can write code more quickly and correctly. +A distinctive feature of Assertive.ts with other assertion libraries is that it leverages the TypeScript compiler to avoid type coercions and mismatches. It also infers the static type of the value you want to assert and provides you with intelligent matcher completion and signature help so that you can write code more quickly and correctly. ### Features @@ -29,39 +28,35 @@ A distinctive feature of AssertiveTS with other assertion libraries is that it l - Works with any test runner and framework such as [Jest](/docs/jest-tutorial.md), [Mocha](/docs/mocha-tutorial.md), or Ava - Well tested: more than 300 tests! -## Install - -```sh -npm install --save-dev @stackbuilders/assertive-ts -``` +## Packages -Or: +For convenience, this library is split into packages grouped within the same namespace: -```sh -yarn add --dev @stackbuilders/assertive-ts -``` +- **[assertive-ts/core](https://github.com/stackbuilders/assertive-ts/blob/main/packages/core/README.md):** Core functionalities, assertions applicable for any kind of application. This package is required for the [extension mechanism](https://github.com/stackbuilders/assertive-ts/blob/main/packages/core/README.md#extension-mechanism-⚙️) (plugins). Also, this is package replaces the deprecated `stackbuilders/assertive-ts` package. ## Usage -Import the library in your test script: +Using you favorite test runner, you just need to import the `expect` and test away! If you don't really agree with `expect` as the name of the assertion function, we provide a couple aliases, such as `assert` and `assertThat`. ```ts -import { expect } from "@stackbuilders/assertive-ts" -``` +import { expect } from "@assertive-ts/core" -Use the `expect` function along with a "matcher" function on the value you want to assert: +describe("sum", () => { + it("returns the sum of two numbers", () => { + const result = sum(3, 2); -```ts -expect(sum(1, 2)).toBeEqual(3); + expect(result).toBeEqual(5); + }); +}); ``` -To assert the opposite, just add `.not` before a matcher: +To assert the opposite, you can simply use the `.not` modifier before the matcher: ```ts expect(sum(1, 2)).not.toBeNull(); ``` -With `assertive-ts` you can use **fluent assertions**, which means you can chain multiple matcher functions to the same value under test: +This library provides **fluent assertions**, which means you can chain multiple matcher functions to the same value under test: ```ts expect("assertive-ts is awesome!") @@ -86,133 +81,14 @@ expect(14).toEndWith("4"); ^ ? type error: `toEndWith` does not exist in `NumberAssertion` ``` -For a list of all matchers and extended documentation, please refer to the [API documentation](https://stackbuilders.github.io/assertive-ts/docs/build/). - -### Type Factory 🏭 - -A great feature of AssertiveTS is the type safety across the API. But, what should you do if you want to check the value under test is of some specific type during runtime? The answer is simple, AssertiveTS provides a `.asType(TypeFactory)` method, where the [TypeFactory](https://stackbuilders.github.io/assertive-ts/docs/build/interfaces/TypeFactory.html) parameter lets you check for the specific type and narrow the assertion instance to a more specific one. To make things simpler, AssertiveTS provides [TypeFactories](https://stackbuilders.github.io/assertive-ts/docs/build/interfaces/StaticTypeFactories.html) for the basic types: - -```ts -import { expect, TypeFactories } from "@stackbuilders/assertive-ts"; - -expect(value) - .asType(TypeFactories.String) - .toBeEmpty(); - -expect(list) - .asType(TypeFactories.array(TypeFactories.Number)) - .toHaveSameMembers([1, 2, 3, 4, 5]); -``` - -If the built-in type factories are not enough to assert your specific type, you can always create your own factory. A `TypeFactory` is nothing more than an object with 3 properties: - -- `Factory: new(actual: S) => A` - The specific assertion constructor to return if the predicate is true. Where `S` is the actual value type, and `A` is the type of the assertion to return (`A` should extend from `Assertion`). -- `predicate(value: unknown): value is S` - A predicate function that checks if the value is of the expected type. -- `typeName: string` - The name of the checked type. Used to make the assertion error message clearer. - -So, using a custom `TypeFactory` can look like the following: - -```ts -interface Point3D { - x: number; - y: number; - z: number; -} - -expect(maybePoint).asType({ - Factory: ObjectAssertion, - predicate: (value): value is Point3D => { - return typeof value === "object" - && value !== null - && "x" in value - && "y" in value - && "z" in value - && Object.values(value).every(v => typeof v === "number"); - }, - typeName: "Point3D" -}); -``` - -### Handling TypeScript Unions - -[Union types](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types) are a TypeScript concept that is only applicable at type level. During runtime, the value can only be one of the types. For instance, if we say `const foo: number | string = ...`, at runtime `foo` will be either a `number` or a `string`. If you want to use a more specific assertion on a union type, you can use `.asType(..)` to first assert the expected type, and then move forward with more assertions: - -```ts -const foo: number | string = 5; - -expect(foo) - .asType(TypeFactories.Number) - .toBePositive(); -``` - -### Help! The value can also be `null` or `undefined` - -When a value can be also `null` or `undefined`, we're going over the same concept as [Union types](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types). So if you want to make more specific assertions over a value that can be `null | undefined`, just use `.asType(..)` first: - -```ts -const bar: string | null | undefined = " "; - -expect(bar) - .asType(TypeFactories.String) - .toBeBlank(); -``` +For a list of all [Core](https://github.com/stackbuilders/assertive-ts/blob/main/packages/core/README.md) matchers and extended documentation, you can refer to the [Core API documentation](https://stackbuilders.github.io/assertive-ts/docs/core/build/). ## Test Runner Integration -- [Jest Integration](docs/jest-tutorial.md) -- [Mocha Integration](docs/mocha-tutorial.md) - -## API Reference - -You can find the full API reference [here](https://stackbuilders.github.io/assertive-ts/docs/build/) - -## Extension mechanism ⚙️ - -This feature allows you to extend the `expect(..)` function to return additional `Assertion` instances depending on the value under test. This opens the door to add additional assertion matchers for more specific cases. An `Assertion` can be added in the form of a `Plugin`: -```ts -interface Plugin> { - Assertion: new(actual: T) => A; - insertAt: "top" | "bottom"; - predicate: (actual: unknown) => actual is T; -} -``` - -Where `Assertion` is the class you want to add, `insertAt` determines if the logic is inserted before or after all the primitives, and `predicate` is the logical code used to determine if value matches the `Assertion` type. - -Once you have a plugin object, you can add it to assertive-ts with the `usePlugin(..)` helper function. Calls to this function should go on the setup file of your test runner or in a `beforeAll()` hook, so the extension is applied to all your tests. -```ts -// test/setup.ts -import { usePlugin } from "@stackbuilders/assertive-ts"; - -import { FilePlugin, HTMLElementPlugin } from "./plugins"; // your custom (or 3rd-party) plugins - -usePlugin(FilePlugin); -usePlugin(HTMLElementPlugin); -// ... -``` - -### What about the types? - -Each new plugin should add an additional overload to the `expect(..)` function to maintain type safety. To do that, you can extend the `Expect` interface to add the additional overloads. For example: -```ts -import { FileAssertion } from "./FileAssertion"; -import { HTMLElementAssertion } from "./HTMLElementAssertion"; - -declare module "@stackbuilders/assertive-ts" { - - export interface Expect { - (actual: File): FileAssertion; - (actual: HTMLElement): HTMLElementAssertion; - // ... - } -} -``` - -> **Note:** 3rd-party libraries should do this on their types entry point (index.d.ts), this way the interface is automatically extended when their plugin is passed to the `usePlugin(..)` function. - -### How to... +Assertive.ts works on any JavaScript test runner, both on Node.js and browser environments. Below you can find some example of how to use it on some of the most common test runners: -If you're looking to write a plugin, you can find a simple example [here](./examples/symbolPlugin/). The example plugin is used in the [Jest](./examples/jest/test/plugins.test.ts) and [Mocha](./examples/mocha/test/plugins.test.ts) examples too, so you can also take a look at them to see how to apply and use plugins. +- [Jest Integration](https://github.com/stackbuilders/assertive-ts/blob/main/docs/jest-tutorial.md) +- [Mocha Integration](https://github.com/stackbuilders/assertive-ts/blob/main/docs/mocha-tutorial.md) ## Contributors ✨ diff --git a/_config.yml b/_config.yml index 175aeed6..004cc622 100644 --- a/_config.yml +++ b/_config.yml @@ -4,5 +4,5 @@ defaults: - scope: path: "" values: - title: AssertiveTS + title: Assertive.ts subtitle: A type-safe fluent assertion library diff --git a/docs/jest-tutorial.md b/docs/jest-tutorial.md index 21583852..d5ae269a 100644 --- a/docs/jest-tutorial.md +++ b/docs/jest-tutorial.md @@ -5,7 +5,7 @@ Let's set up a project with Jest and assertive-ts to write our first assertion. First, let's install the dependencies: ``` -npm install --save-dev typescript ts-jest jest @types/jest @stackbuilders/assertive-ts +npm install --save-dev typescript ts-jest jest @types/jest @assertive-ts/core ``` This library is meant to be used with TypeScript, so to have better results we encourage you to use TypeScript in your project. @@ -31,11 +31,11 @@ export const sum = (a: number, b: number): number => { } ``` -Now let's write a test for that function. Make sure to import `expect` from the `@stackbuilders/assertive-ts` module: +Now let's write a test for that function. Make sure to import `expect` from the `@assertive-ts/core` module: *tests/mathUtils.test.ts* ```typescript -import { expect } from "@stackbuilders/assertive-ts"; +import { expect } from "@assertive-ts/core"; import { sum } from "../src/mathUtils"; describe("sum", () => { @@ -55,12 +55,12 @@ You might want to use the `expect` function from Jest along with assertive-ts as ```typescript import { expect } from "@jest/globals"; - import { assert } from "@stackbuilders/assertive-ts"; + import { assert } from "@assertive-ts/core"; ``` - Or use an explicit import to rename the `expect` function from Jest to something like `jestExpect`: ```typescript import { expect as jestExpect } from "@jest/globals"; - import { expect } from "@stackbuilders/assertive-ts"; + import { expect } from "@assertive-ts/core"; ``` diff --git a/docs/mocha-tutorial.md b/docs/mocha-tutorial.md index c020b12e..5a3407a9 100644 --- a/docs/mocha-tutorial.md +++ b/docs/mocha-tutorial.md @@ -4,7 +4,7 @@ Let's set up a project with Mocha and assertive-ts. First, let's install the dependencies: ``` -npm install --save-dev typescript mocha @types/mocha ts-node @stackbuilders/assertive-ts +npm install --save-dev typescript mocha @types/mocha ts-node @assertive-ts/core ``` This library is meant to be used with TypeScript, so to have better results we encourage you to use TypeScript in your project. @@ -40,11 +40,11 @@ export const sum = (a: number, b: number): number => { } ``` -Now let's write a test for that function. Make sure to import `expect` from the `@stackbuilders/assertive-ts` module. +Now let's write a test for that function. Make sure to import `expect` from the `@assertive-ts/core` module. *tests/mathUtils.test.ts* ```typescript -import { expect } from "@stackbuilders/assertive-ts"; +import { expect } from "@assertive-ts/core"; import { sum } from "../src/mathUtils"; describe("sum", () => { diff --git a/examples/jest/README.md b/examples/jest/README.md index 3c97257d..e1036a83 100644 --- a/examples/jest/README.md +++ b/examples/jest/README.md @@ -1,8 +1,8 @@ # Jest example -Example project using AssertiveTS with Jest's test runner. +Example project using Assertive.ts with Jest's test runner. -This example showcases the use of AssertiveTS' `expect` and its `assert` alias, +This example showcases the use of Assertive.ts' `expect` and its `assert` alias, as well as the use of Jest's own `expect` function imported with a different name. diff --git a/examples/jest/package.json b/examples/jest/package.json index 23cd644d..e5d2a2fd 100644 --- a/examples/jest/package.json +++ b/examples/jest/package.json @@ -6,8 +6,8 @@ "test": "jest" }, "devDependencies": { + "@assertive-ts/core": "workspace:^", "@examples/symbol-plugin": "workspace:^", - "@stackbuilders/assertive-ts": "workspace:^", "@types/jest": "^29.5.3", "@types/node": "^20.4.8", "jest": "^29.6.2", diff --git a/examples/jest/test/mathUtils.test.ts b/examples/jest/test/mathUtils.test.ts index 80522416..d1b17673 100644 --- a/examples/jest/test/mathUtils.test.ts +++ b/examples/jest/test/mathUtils.test.ts @@ -1,5 +1,5 @@ +import { assert, expect } from "@assertive-ts/core"; import { expect as jestExpect } from "@jest/globals"; -import { assert, expect } from "@stackbuilders/assertive-ts"; import { sum } from "../src/mathUtils"; diff --git a/examples/jest/test/plugins.test.ts b/examples/jest/test/plugins.test.ts index 0756d984..39b86423 100644 --- a/examples/jest/test/plugins.test.ts +++ b/examples/jest/test/plugins.test.ts @@ -1,4 +1,4 @@ -import { expect } from "@stackbuilders/assertive-ts"; +import { expect } from "@assertive-ts/core"; describe("plugins", () => { it("can use the symbol plugin", () => { diff --git a/examples/jest/test/setup.ts b/examples/jest/test/setup.ts index 76c7d77d..d98317be 100644 --- a/examples/jest/test/setup.ts +++ b/examples/jest/test/setup.ts @@ -1,5 +1,5 @@ +import { usePlugin } from "@assertive-ts/core"; import { SymbolPlugin } from "@examples/symbol-plugin"; -import { usePlugin } from "@stackbuilders/assertive-ts"; beforeAll(() => { usePlugin(SymbolPlugin); diff --git a/examples/mocha/README.md b/examples/mocha/README.md index 93c98859..9e20a7ba 100644 --- a/examples/mocha/README.md +++ b/examples/mocha/README.md @@ -1,8 +1,8 @@ # Mocha example -Example project using AssertiveTS with Mocha's test runner. +Example project using Assertive.ts with Mocha's test runner. -This example showcases the use of AssertiveTS' `expect` and its `assert` alias +This example showcases the use of Assertive.ts' `expect` and its `assert` alias with Mocha as the test runner. ## How to setup diff --git a/examples/mocha/package.json b/examples/mocha/package.json index ee83b47a..3946a3bd 100644 --- a/examples/mocha/package.json +++ b/examples/mocha/package.json @@ -6,8 +6,8 @@ "test": "mocha" }, "devDependencies": { + "@assertive-ts/core": "workspace:^", "@examples/symbol-plugin": "workspace:^", - "@stackbuilders/assertive-ts": "workspace:^", "@types/mocha": "^10.0.1", "@types/node": "^20.4.8", "mocha": "^10.2.0", diff --git a/examples/mocha/test/hooks.ts b/examples/mocha/test/hooks.ts index 848b5fa6..9f7d68dd 100644 --- a/examples/mocha/test/hooks.ts +++ b/examples/mocha/test/hooks.ts @@ -1,5 +1,5 @@ +import { usePlugin } from "@assertive-ts/core"; import { SymbolPlugin } from "@examples/symbol-plugin"; -import { usePlugin } from "@stackbuilders/assertive-ts"; import { RootHookObject } from "mocha"; export function mochaHooks(): RootHookObject { diff --git a/examples/mocha/test/mathUtils.test.ts b/examples/mocha/test/mathUtils.test.ts index 85cc7949..5215b30d 100644 --- a/examples/mocha/test/mathUtils.test.ts +++ b/examples/mocha/test/mathUtils.test.ts @@ -1,4 +1,4 @@ -import { assert, expect } from "@stackbuilders/assertive-ts"; +import { assert, expect } from "@assertive-ts/core"; import { sum } from "../src/mathUtils"; diff --git a/examples/mocha/test/plugins.test.ts b/examples/mocha/test/plugins.test.ts index 0756d984..39b86423 100644 --- a/examples/mocha/test/plugins.test.ts +++ b/examples/mocha/test/plugins.test.ts @@ -1,4 +1,4 @@ -import { expect } from "@stackbuilders/assertive-ts"; +import { expect } from "@assertive-ts/core"; describe("plugins", () => { it("can use the symbol plugin", () => { diff --git a/examples/symbolPlugin/package.json b/examples/symbolPlugin/package.json index 44387bbb..39574676 100644 --- a/examples/symbolPlugin/package.json +++ b/examples/symbolPlugin/package.json @@ -8,10 +8,10 @@ "compile": "tsc" }, "devDependencies": { - "@stackbuilders/assertive-ts": "workspace:^", + "@assertive-ts/core": "workspace:^", "typescript": "^5.1.6" }, "peerDependencies": { - "@stackbuilders/assertive-ts": "*" + "@assertive-ts/core": "*" } } diff --git a/examples/symbolPlugin/src/index.ts b/examples/symbolPlugin/src/index.ts index 9560a08e..c59a9b31 100644 --- a/examples/symbolPlugin/src/index.ts +++ b/examples/symbolPlugin/src/index.ts @@ -1,8 +1,8 @@ -import { Plugin } from "@stackbuilders/assertive-ts"; +import { Plugin } from "@assertive-ts/core"; import { SymbolAssertion } from "./lib/SymbolAssertion"; -declare module "@stackbuilders/assertive-ts" { +declare module "@assertive-ts/core" { export interface Expect { // eslint-disable-next-line @typescript-eslint/prefer-function-type diff --git a/examples/symbolPlugin/src/lib/SymbolAssertion.ts b/examples/symbolPlugin/src/lib/SymbolAssertion.ts index 6cd9f2ae..d2044ea3 100644 --- a/examples/symbolPlugin/src/lib/SymbolAssertion.ts +++ b/examples/symbolPlugin/src/lib/SymbolAssertion.ts @@ -1,4 +1,4 @@ -import { Assertion, AssertionError } from "@stackbuilders/assertive-ts"; +import { Assertion, AssertionError } from "@assertive-ts/core"; export class SymbolAssertion extends Assertion { diff --git a/examples/symbolPlugin/tsconfig.tsbuildinfo b/examples/symbolPlugin/tsconfig.tsbuildinfo deleted file mode 100644 index aa02bf68..00000000 --- a/examples/symbolPlugin/tsconfig.tsbuildinfo +++ /dev/null @@ -1 +0,0 @@ -{"program":{"fileNames":["../../node_modules/typescript/lib/lib.es6.d.ts","../../node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/typescript/lib/lib.dom.d.ts","../../node_modules/typescript/lib/lib.dom.iterable.d.ts","../../node_modules/typescript/lib/lib.webworker.importscripts.d.ts","../../node_modules/typescript/lib/lib.scripthost.d.ts","../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/typescript/lib/lib.esnext.intl.d.ts","../../node_modules/tslib/tslib.d.ts","../../node_modules/@types/node/assert.d.ts","../../node_modules/@types/node/assert/strict.d.ts","../../node_modules/@types/node/globals.d.ts","../../node_modules/@types/node/async_hooks.d.ts","../../node_modules/@types/node/buffer.d.ts","../../node_modules/@types/node/child_process.d.ts","../../node_modules/@types/node/cluster.d.ts","../../node_modules/@types/node/console.d.ts","../../node_modules/@types/node/constants.d.ts","../../node_modules/@types/node/crypto.d.ts","../../node_modules/@types/node/dgram.d.ts","../../node_modules/@types/node/diagnostics_channel.d.ts","../../node_modules/@types/node/dns.d.ts","../../node_modules/@types/node/dns/promises.d.ts","../../node_modules/@types/node/domain.d.ts","../../node_modules/@types/node/events.d.ts","../../node_modules/@types/node/fs.d.ts","../../node_modules/@types/node/fs/promises.d.ts","../../node_modules/@types/node/http.d.ts","../../node_modules/@types/node/http2.d.ts","../../node_modules/@types/node/https.d.ts","../../node_modules/@types/node/inspector.d.ts","../../node_modules/@types/node/module.d.ts","../../node_modules/@types/node/net.d.ts","../../node_modules/@types/node/os.d.ts","../../node_modules/@types/node/path.d.ts","../../node_modules/@types/node/perf_hooks.d.ts","../../node_modules/@types/node/process.d.ts","../../node_modules/@types/node/punycode.d.ts","../../node_modules/@types/node/querystring.d.ts","../../node_modules/@types/node/readline.d.ts","../../node_modules/@types/node/readline/promises.d.ts","../../node_modules/@types/node/repl.d.ts","../../node_modules/@types/node/stream.d.ts","../../node_modules/@types/node/stream/promises.d.ts","../../node_modules/@types/node/stream/consumers.d.ts","../../node_modules/@types/node/stream/web.d.ts","../../node_modules/@types/node/string_decoder.d.ts","../../node_modules/@types/node/test.d.ts","../../node_modules/@types/node/timers.d.ts","../../node_modules/@types/node/timers/promises.d.ts","../../node_modules/@types/node/tls.d.ts","../../node_modules/@types/node/trace_events.d.ts","../../node_modules/@types/node/tty.d.ts","../../node_modules/@types/node/url.d.ts","../../node_modules/@types/node/util.d.ts","../../node_modules/@types/node/v8.d.ts","../../node_modules/@types/node/vm.d.ts","../../node_modules/@types/node/wasi.d.ts","../../node_modules/@types/node/worker_threads.d.ts","../../node_modules/@types/node/zlib.d.ts","../../node_modules/@types/node/globals.global.d.ts","../../node_modules/@types/node/index.d.ts","../../package/dist/lib/arrayassertion.d.ts","../../package/dist/lib/booleanassertion.d.ts","../../package/dist/lib/dateassertion.types.d.ts","../../package/dist/lib/dateassertion.d.ts","../../package/dist/lib/errorassertion.d.ts","../../package/dist/lib/functionassertion.d.ts","../../package/dist/lib/numberassertion.d.ts","../../package/dist/lib/objectassertion.d.ts","../../package/dist/lib/stringassertion.d.ts","../../package/dist/lib/helpers/typefactories.d.ts","../../package/dist/lib/assertion.d.ts","../../package/dist/lib/config/config.d.ts","../../package/dist/lib/promiseassertion.d.ts","../../package/dist/lib/expect.d.ts","../../package/dist/index.d.ts","./src/lib/symbolassertion.ts","./src/index.ts","../../node_modules/@babel/types/lib/index.d.ts","../../node_modules/@types/babel__generator/index.d.ts","../../node_modules/@babel/parser/typings/babel-parser.d.ts","../../node_modules/@types/babel__template/index.d.ts","../../node_modules/@types/babel__traverse/index.d.ts","../../node_modules/@types/babel__core/index.d.ts","../../node_modules/@types/graceful-fs/index.d.ts","../../node_modules/@types/istanbul-lib-coverage/index.d.ts","../../node_modules/@types/istanbul-lib-report/index.d.ts","../../node_modules/@types/istanbul-reports/index.d.ts","../../node_modules/@jest/expect-utils/build/index.d.ts","../../node_modules/chalk/index.d.ts","../../node_modules/@sinclair/typebox/typebox.d.ts","../../node_modules/@jest/schemas/build/index.d.ts","../../node_modules/pretty-format/build/index.d.ts","../../node_modules/jest-diff/build/index.d.ts","../../node_modules/jest-matcher-utils/build/index.d.ts","../../node_modules/expect/build/index.d.ts","../../node_modules/@types/jest/index.d.ts","../../node_modules/@types/minimist/index.d.ts","../../node_modules/@types/mocha/index.d.ts","../../node_modules/@types/normalize-package-data/index.d.ts","../../node_modules/@types/parse-json/index.d.ts","../../node_modules/@types/prettier/index.d.ts","../../node_modules/@types/retry/index.d.ts","../../node_modules/@types/sinonjs__fake-timers/index.d.ts","../../node_modules/@types/sinon/index.d.ts","../../node_modules/@types/stack-utils/index.d.ts","../../node_modules/@types/yargs-parser/index.d.ts","../../node_modules/@types/yargs/index.d.ts"],"fileInfos":["721cec59c3fef87aaf480047d821fb758b3ec9482c4129a54631e6e25e432a31",{"version":"f20c05dbfe50a208301d2a1da37b9931bce0466eb5a1f4fe240971b4ecc82b67","affectsGlobalScope":true},"dc47c4fa66b9b9890cf076304de2a9c5201e94b740cffdf09f87296d877d71f6","7a387c58583dfca701b6c85e0adaf43fb17d590fb16d5b2dc0a2fbd89f35c467","8a12173c586e95f4433e0c6dc446bc88346be73ffe9ca6eec7aa63c8f3dca7f9","5f4e733ced4e129482ae2186aae29fde948ab7182844c3a5a51dd346182c7b06","e6b724280c694a9f588847f754198fb96c43d805f065c3a5b28bbc9594541c84","1fc5ab7a764205c68fa10d381b08417795fc73111d6dd16b5b1ed36badb743d9",{"version":"9b087de7268e4efc5f215347a62656663933d63c0b1d7b624913240367b999ea","affectsGlobalScope":true},{"version":"3260e3386d9535b804205bdddb5618a9a27735bd22927f48ad54363abcd23d45","affectsGlobalScope":true},{"version":"7fac8cb5fc820bc2a59ae11ef1c5b38d3832c6d0dfaec5acdb5569137d09a481","affectsGlobalScope":true},{"version":"097a57355ded99c68e6df1b738990448e0bf170e606707df5a7c0481ff2427cd","affectsGlobalScope":true},{"version":"adb996790133eb33b33aadb9c09f15c2c575e71fb57a62de8bf74dbf59ec7dfb","affectsGlobalScope":true},{"version":"8cc8c5a3bac513368b0157f3d8b31cfdcfe78b56d3724f30f80ed9715e404af8","affectsGlobalScope":true},{"version":"cdccba9a388c2ee3fd6ad4018c640a471a6c060e96f1232062223063b0a5ac6a","affectsGlobalScope":true},{"version":"c5c05907c02476e4bde6b7e76a79ffcd948aedd14b6a8f56e4674221b0417398","affectsGlobalScope":true},{"version":"0d5f52b3174bee6edb81260ebcd792692c32c81fd55499d69531496f3f2b25e7","affectsGlobalScope":true},{"version":"55f400eec64d17e888e278f4def2f254b41b89515d3b88ad75d5e05f019daddd","affectsGlobalScope":true},{"version":"181f1784c6c10b751631b24ce60c7f78b20665db4550b335be179217bacc0d5f","affectsGlobalScope":true},{"version":"3013574108c36fd3aaca79764002b3717da09725a36a6fc02eac386593110f93","affectsGlobalScope":true},{"version":"75ec0bdd727d887f1b79ed6619412ea72ba3c81d92d0787ccb64bab18d261f14","affectsGlobalScope":true},{"version":"3be5a1453daa63e031d266bf342f3943603873d890ab8b9ada95e22389389006","affectsGlobalScope":true},{"version":"17bb1fc99591b00515502d264fa55dc8370c45c5298f4a5c2083557dccba5a2a","affectsGlobalScope":true},{"version":"7ce9f0bde3307ca1f944119f6365f2d776d281a393b576a18a2f2893a2d75c98","affectsGlobalScope":true},{"version":"6a6b173e739a6a99629a8594bfb294cc7329bfb7b227f12e1f7c11bc163b8577","affectsGlobalScope":true},{"version":"81cac4cbc92c0c839c70f8ffb94eb61e2d32dc1c3cf6d95844ca099463cf37ea","affectsGlobalScope":true},{"version":"b0124885ef82641903d232172577f2ceb5d3e60aed4da1153bab4221e1f6dd4e","affectsGlobalScope":true},{"version":"0eb85d6c590b0d577919a79e0084fa1744c1beba6fd0d4e951432fa1ede5510a","affectsGlobalScope":true},{"version":"da233fc1c8a377ba9e0bed690a73c290d843c2c3d23a7bd7ec5cd3d7d73ba1e0","affectsGlobalScope":true},{"version":"d154ea5bb7f7f9001ed9153e876b2d5b8f5c2bb9ec02b3ae0d239ec769f1f2ae","affectsGlobalScope":true},{"version":"bb2d3fb05a1d2ffbca947cc7cbc95d23e1d053d6595391bd325deb265a18d36c","affectsGlobalScope":true},{"version":"c80df75850fea5caa2afe43b9949338ce4e2de086f91713e9af1a06f973872b8","affectsGlobalScope":true},{"version":"9d57b2b5d15838ed094aa9ff1299eecef40b190722eb619bac4616657a05f951","affectsGlobalScope":true},{"version":"6c51b5dd26a2c31dbf37f00cfc32b2aa6a92e19c995aefb5b97a3a64f1ac99de","affectsGlobalScope":true},{"version":"6e7997ef61de3132e4d4b2250e75343f487903ddf5370e7ce33cf1b9db9a63ed","affectsGlobalScope":true},{"version":"2ad234885a4240522efccd77de6c7d99eecf9b4de0914adb9a35c0c22433f993","affectsGlobalScope":true},{"version":"09aa50414b80c023553090e2f53827f007a301bc34b0495bfb2c3c08ab9ad1eb","affectsGlobalScope":true},{"version":"d7f680a43f8cd12a6b6122c07c54ba40952b0c8aa140dcfcf32eb9e6cb028596","affectsGlobalScope":true},{"version":"3787b83e297de7c315d55d4a7c546ae28e5f6c0a361b7a1dcec1f1f50a54ef11","affectsGlobalScope":true},{"version":"e7e8e1d368290e9295ef18ca23f405cf40d5456fa9f20db6373a61ca45f75f40","affectsGlobalScope":true},{"version":"faf0221ae0465363c842ce6aa8a0cbda5d9296940a8e26c86e04cc4081eea21e","affectsGlobalScope":true},{"version":"06393d13ea207a1bfe08ec8d7be562549c5e2da8983f2ee074e00002629d1871","affectsGlobalScope":true},{"version":"775d9c9fd150d5de79e0450f35bc8b8f94ae64e3eb5da12725ff2a649dccc777","affectsGlobalScope":true},{"version":"b248e32ca52e8f5571390a4142558ae4f203ae2f94d5bac38a3084d529ef4e58","affectsGlobalScope":true},{"version":"52d1bb7ab7a3306fd0375c8bff560feed26ed676a5b0457fa8027b563aecb9a4","affectsGlobalScope":true},"4576b4e61049f5ffd7c9e935cf88832e089265bdb15ffc35077310042cbbbeea","9122ed7070e054b73ebab37c2373a196def2d90e7d1a9a7fcd9d46b0e51fae78","a69c09dbea52352f479d3e7ac949fde3d17b195abe90b045d619f747b38d6d1a",{"version":"77f0b5c6a193a699c9f7d7fb0578e64e562d271afa740783665d2a827104a873","affectsGlobalScope":true},"21a167fec8f933752fb8157f06d28fab6817af3ad9b0bdb1908a10762391eab9",{"version":"002d6d5f044365b3fbfba0ba9be3bb57cac09b81547c8df4b0795755d2081d90","affectsGlobalScope":true},"0c0cee62cb619aed81133b904f644515ba3064487002a7da83fd8aa07b1b4abd","5a94487653355b56018122d92392beb2e5f4a6c63ba5cef83bbe1c99775ef713",{"version":"d5135ad93b33adcce80b18f8065087934cdc1730d63db58562edcf017e1aad9b","affectsGlobalScope":true},"82408ed3e959ddc60d3e9904481b5a8dc16469928257af22a3f7d1a3bc7fd8c4","c4cfc9a6e2ebb8bc8c0e2392dfc4056993ced3b35069ebf132ac18ca7a562881","bb9c4ffa5e6290c6980b63c815cdd1625876dadb2efaf77edbe82984be93e55e","75ecef44f126e2ae018b4abbd85b6e8a2e2ba1638ebec56cc64274643ce3567b","f30bb836526d930a74593f7b0f5c1c46d10856415a8f69e5e2fc3db80371e362","14b5aa23c5d0ae1907bc696ac7b6915d88f7d85799cc0dc2dcf98fbce2c5a67c","5c439dafdc09abe4d6c260a96b822fa0ba5be7203c71a63ab1f1423cd9e838ea",{"version":"bae4ea23beb8397755b935cb84d3cdc6cdb0b1b4a329b90de9fc6c8774d71994","affectsGlobalScope":true},"cec36af22f514322f870e81d30675c78df82ae8bf4863f5fd4e4424c040c678d","df36874d9e56aff601e921c4b3971d37cf66d14f6455935ce821e6cad13b1823","3c135ff5bda0355f6b52a10ea931736ec7c5a80b7fb8772019054e0eaa0fd6b6","1abb206a4ecd13b21536b677d7d5f66e0d7316f0d44610197cfcc5776f78884a","dbe5aa5a5dd8bd1c6a8d11b1310c3f0cdabaacc78a37b394a8c7b14faeb5fb84","2c828a5405191d006115ab34e191b8474bc6c86ffdc401d1a9864b1b6e088a58",{"version":"e8b18c6385ff784228a6f369694fcf1a6b475355ba89090a88de13587a9391d5","affectsGlobalScope":true},"76527127c8b749bee5977408861ce3ee56ec19ddcea8704c628f98ca610283e6","7fc5b4377d39edbbd127cdc84805bd85da1ec2fc55412213912cd6f67b66399b","b68bd7bef90dab08b1866a9fee24f03d9fee10bcb3f587b074e96e61abf6d3f0","cb4f3f03480e1727eae46400606cecaa97f550186ff8fa909ebc00db4180531b",{"version":"b3624aed92dab6da8484280d3cb3e2f4130ec3f4ef3f8201c95144ae9e898bb6","affectsGlobalScope":true},"5153a2fd150e46ce57bb3f8db1318d33f6ad3261ed70ceeff92281c0608c74a3","d1a78a3c5708807e8de3e399f91df4797c62e44b02195eefc2209b2e713e54ee","36b03690b628eab08703d63f04eaa89c5df202e5f1edf3989f13ad389cd2c091","0effadd232a20498b11308058e334d3339cc5bf8c4c858393e38d9d4c0013dcf","25846d43937c672bab7e8195f3d881f93495df712ee901860effc109918938cc","556bf5c36deb62cffa1bf697c1789fe008ec82db0273025001db66732714e9d9","1b952304137851e45bc009785de89ada562d9376177c97e37702e39e60c2f1ff",{"version":"806ef4cac3b3d9fa4a48d849c8e084d7c72fcd7b16d76e06049a9ed742ff79c0","affectsGlobalScope":true},"44b8b584a338b190a59f4f6929d072431950c7bd92ec2694821c11bce180c8a5","23b89798789dffbd437c0c423f5d02d11f9736aea73d6abf16db4f812ff36eda","0830071706fa0e477fb5e95f0955cc1062b5948b146b7d4e03a126f12ad6085f",{"version":"970a90f76d4d219ad60819d61f5994514087ba94c985647a3474a5a3d12714ed","affectsGlobalScope":true},"664d8f2d59164f2e08c543981453893bc7e003e4dfd29651ce09db13e9457980","4c8525f256873c7ba3135338c647eaf0ca7115a1a2805ae2d0056629461186ce","3c13ef48634e7b5012fcf7e8fce7496352c2d779a7201389ca96a2a81ee4314d","5d0a25ec910fa36595f85a67ac992d7a53dd4064a1ba6aea1c9f14ab73a023f2",{"version":"bfe39beb986d2a2e512c091cbe924f1c415bc65de54de0e2f6a0dc6f84c183d9","affectsGlobalScope":true},"2d526e6f21d8cc66ac11ada32874e95ae88d870c6c9d3d9d4e03b1d1f9ad7b8e","06d7c42d256f0ce6afe1b2b6cfbc97ab391f29dadb00dd0ae8e8f23f5bc916c3","ec4bd1b200670fb567920db572d6701ed42a9641d09c4ff6869768c8f81b404c","e59a892d87e72733e2a9ca21611b9beb52977be2696c7ba4b216cbbb9a48f5aa","d2ec52f565f0570e90b659811347bd689f8c6039b11eaaccd0f243759d46da6e","8a300fa9b698845a1f9c41ecbe2c5966634582a8e2020d51abcace9b55aa959e",{"version":"ab9b9a36e5284fd8d3bf2f7d5fcbc60052f25f27e4d20954782099282c60d23e","affectsGlobalScope":true},"a12806a1bde5e9f137bb79728d87a4ceaedf04e95efc9967d3288a3c252d9a7b","e898f2546dac59d8e41ae4b07501995ab8ff7608d9da85b022520ce8f93b2795","036783319f007422be27340662f96ed20b9ff824542b933b2d79087c953a7a89","5048079550ba4ec51c5dc613bc527d86c2903c9ec5e6e24d4ffd05560e078c42","5099a8e7fb51137eeb4f0c4385fd8b3048329ed8c389ee6d417871d1a2409367","e533c0133a88f3fc30af1fb5191289369eb8f7c0b6ac239d6ce66c2a0e9cbe87","f38749b62ef00acabcf74095f1aecda70592c53ec6d8bce79d17371eefd935e4","400cc7cd188868a816e118343972ca93bbd9281157aa25bdd9f6cf8c42e17334","d38e63f68003b4ea7a0ad46b7b4f526163914534c22ffa25215896896a331017","97ef3d66a6c886c9e7d699f17a04447fdf741888332769efbab8fb85fb24c970","41c1e252bed1477a80c4480b580a9a4ff50510fefc5e817e4f28df96c551f35e","7e56363c220e4912d80353ab2522b75b172cc5edcea23564329606834c5cbc91","7ca1756c7d60b985ceacd438d688dbfe79752a3d460a8777f1b2fc834c96459b","756721fa1c965cdb5de2083b2eb8f03e754b50750a2ea8f19e8e6b39d434ab14","b2e42ed4f42903f23238e44658aede2064ab704f69eabe915821ab5e18baf88e","3dc00ed0e572e7f99bb0afc54f49867213beb369cc6e008dd0270b269147de33",{"version":"191556fe4dad5c9a97257fc1df7378fb47fabcabbf492319f6b67a7b8e16077a","signature":"6d9c2b8e5cad79b8afb8b7d869be3f204fb09326dacb2fc9ef7085f7bb6cbf0d"},{"version":"83714ed95e2a14a970898c4acdf615c7894480fc632fb5e0c5c66b0579ef5d7b","signature":"8fcb6dafe9cc8593c420fc3ebe7ef4b0a8b594c2f771334c7490ae56511d3e72"},"c561efdf5ba0b62619745d4761fe2d9756f23db972e039367d15922fed67fd2f","cc957354aa3c94c9961ebf46282cfde1e81d107fc5785a61f62c67f1dd3ac2eb","7ec238b220ea991b6643e24191b1f552a65956d5f6de4c6144e700b9985265d8","93de1c6dab503f053efe8d304cb522bb3a89feab8c98f307a674a4fae04773e9","dae3d1adc67ac3dbd1cd471889301339ec439837b5df565982345be20c8fca9a","5426e62886b7be7806312d31a00e8f7dccd6fe63ba9bbefe99ee2eab29cc48a3","3ebae8c00411116a66fca65b08228ea0cf0b72724701f9b854442100aab55aba","8b06ac3faeacb8484d84ddb44571d8f410697f98d7bfa86c0fda60373a9f5215","7eb06594824ada538b1d8b48c3925a83e7db792f47a081a62cf3e5c4e23cf0ee","f5638f7c2f12a9a1a57b5c41b3c1ea7db3876c003bab68e6a57afd6bcc169af0","763e521cf114b80e0dd0e21ca49b9f8ae62e8999555a5e7bade8ce36b33001c2","0d14fa22c41fdc7277e6f71473b20ebc07f40f00e38875142335d5b63cdfc9d2","3e6bbb0883148627ca0854a9f62d820aaf1a0f1842f5568176721fef156b8f23","427ce5854885cfc34387e09de05c1d5c1acf94c2143e1693f1d9ff54880573e7","bed2c4f96fab3348be4a34d88dcb12578c1b2475b07c6acd369e99e227718d81","e3ba509d3dce019b3190ceb2f3fc88e2610ab717122dabd91a9efaa37804040d","cda0cb09b995489b7f4c57f168cd31b83dcbaa7aad49612734fb3c9c73f6e4f2","3ad5991645bbea846d4efe615cd847e785ca30fff0205fdffb0f9a3ade3d13df",{"version":"0dd26bdaa8dfb562d2a600540fa76375f778f34e83fd84fcadc586050e3572ca","affectsGlobalScope":true},"209e814e8e71aec74f69686a9506dd7610b97ab59dcee9446266446f72a76d05",{"version":"3f6d6465811321abc30a1e5f667feed63e5b3917b3d6c8d6645daf96c75f97ba","affectsGlobalScope":true},"6fa0008bf91a4cc9c8963bace4bba0bd6865cbfa29c3e3ccc461155660fb113a","2b8264b2fefd7367e0f20e2c04eed5d3038831fe00f5efbc110ff0131aab899b","93c4fc5b5237c09bc9ed65cb8f0dc1d89034406ab40500b89701341994897142","199f9ead0daf25ae4c5632e3d1f42570af59685294a38123eef457407e13f365","f83b320cceccfc48457a818d18fc9a006ab18d0bdd727aa2c2e73dc1b4a45e98","354abbae08f72ea982b1a767a8908f1b3efe8bbe53955c64f9c0c249c8832d5d","b0d10e46cfe3f6c476b69af02eaa38e4ccc7430221ce3109ae84bb9fb8282298","70e9a18da08294f75bf23e46c7d69e67634c0765d355887b9b41f0d959e1426e","28288f5e5f8b7b895ed2abe6359c1da3e0d14a64b5aef985071285671f347c01"],"options":{"alwaysStrict":true,"declaration":true,"esModuleInterop":true,"importHelpers":true,"module":1,"noImplicitAny":true,"noImplicitOverride":true,"noImplicitReturns":true,"noImplicitThis":true,"noUncheckedIndexedAccess":true,"noUnusedLocals":true,"noUnusedParameters":true,"removeComments":false,"skipLibCheck":true,"sourceMap":true,"strict":true,"target":2},"fileIdsList":[[46,92,114,115,116],[46,92,114,116],[92,117],[92],[92,129],[92,117,118,119,120,121],[92,117,119],[63,92,99],[92,124],[92,125],[92,131,134],[47,92],[50,92],[51,56,92],[52,62,63,70,80,91,92],[52,53,62,70,92],[54,92],[55,56,63,71,92],[56,80,88,92],[57,59,62,70,92],[58,92],[59,60,92],[61,62,92],[62,92],[62,63,64,80,91,92],[62,63,64,80,83,92],[92,96],[65,70,80,91,92],[62,63,65,66,70,80,88,91,92],[65,67,80,88,91,92],[47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98],[62,68,92],[69,91,92],[59,62,70,80,92],[71,92],[72,92],[50,73,92],[74,90,92,96],[75,92],[76,92],[62,77,78,92],[77,79,92,94],[62,80,81,82,83,92],[80,82,92],[80,81,92],[83,92],[84,92],[62,86,87,92],[86,87,92],[56,70,80,88,92],[89,92],[70,90,92],[51,65,76,91,92],[56,92],[80,92,93],[92,94],[92,95],[51,56,62,64,73,80,91,92,94,96],[80,92,97],[92,142],[92,145],[92,127,133],[92,131],[92,128,132],[92,130],[48,92,109,110,111,113],[92,109,110],[47,92,99,109],[92,110],[92,102,110],[92,100,101,103,104,105,106,107,108,110,112],[92,104,109,110],[92,100,101,103,105,106,107,108,110],[114,115,116],[114,116]],"referencedMap":[[116,1],[115,2],[119,3],[117,4],[127,4],[130,5],[129,4],[122,6],[118,3],[120,7],[121,3],[123,8],[124,4],[125,9],[126,10],[135,11],[136,4],[137,4],[47,12],[48,12],[50,13],[51,14],[52,15],[53,16],[54,17],[55,18],[56,19],[57,20],[58,21],[59,22],[60,22],[61,23],[62,24],[63,25],[64,26],[49,27],[98,4],[65,28],[66,29],[67,30],[99,31],[68,32],[69,33],[70,34],[71,35],[72,36],[73,37],[74,38],[75,39],[76,40],[77,41],[78,41],[79,42],[80,43],[82,44],[81,45],[83,46],[84,47],[85,4],[86,48],[87,49],[88,50],[89,51],[90,52],[91,53],[92,54],[93,55],[94,56],[95,57],[96,58],[97,59],[138,4],[139,4],[140,4],[141,4],[143,60],[142,4],[144,4],[145,4],[146,61],[128,4],[134,62],[132,63],[133,64],[131,65],[46,4],[9,4],[10,4],[14,4],[13,4],[3,4],[15,4],[16,4],[17,4],[18,4],[19,4],[20,4],[21,4],[22,4],[4,4],[5,4],[26,4],[23,4],[24,4],[25,4],[27,4],[28,4],[29,4],[6,4],[30,4],[31,4],[32,4],[33,4],[7,4],[34,4],[35,4],[36,4],[37,4],[8,4],[38,4],[43,4],[44,4],[39,4],[40,4],[41,4],[42,4],[2,4],[1,4],[45,4],[12,4],[11,4],[114,66],[100,67],[110,68],[101,69],[111,69],[103,70],[102,4],[104,69],[113,71],[105,72],[109,73],[106,69],[107,69],[112,69],[108,69]],"exportedModulesMap":[[116,74],[115,75],[119,3],[117,4],[127,4],[130,5],[129,4],[122,6],[118,3],[120,7],[121,3],[123,8],[124,4],[125,9],[126,10],[135,11],[136,4],[137,4],[47,12],[48,12],[50,13],[51,14],[52,15],[53,16],[54,17],[55,18],[56,19],[57,20],[58,21],[59,22],[60,22],[61,23],[62,24],[63,25],[64,26],[49,27],[98,4],[65,28],[66,29],[67,30],[99,31],[68,32],[69,33],[70,34],[71,35],[72,36],[73,37],[74,38],[75,39],[76,40],[77,41],[78,41],[79,42],[80,43],[82,44],[81,45],[83,46],[84,47],[85,4],[86,48],[87,49],[88,50],[89,51],[90,52],[91,53],[92,54],[93,55],[94,56],[95,57],[96,58],[97,59],[138,4],[139,4],[140,4],[141,4],[143,60],[142,4],[144,4],[145,4],[146,61],[128,4],[134,62],[132,63],[133,64],[131,65],[46,4],[9,4],[10,4],[14,4],[13,4],[3,4],[15,4],[16,4],[17,4],[18,4],[19,4],[20,4],[21,4],[22,4],[4,4],[5,4],[26,4],[23,4],[24,4],[25,4],[27,4],[28,4],[29,4],[6,4],[30,4],[31,4],[32,4],[33,4],[7,4],[34,4],[35,4],[36,4],[37,4],[8,4],[38,4],[43,4],[44,4],[39,4],[40,4],[41,4],[42,4],[2,4],[1,4],[45,4],[12,4],[11,4],[114,66],[100,67],[110,68],[101,69],[111,69],[103,70],[102,4],[104,69],[113,71],[105,72],[109,73],[106,69],[107,69],[112,69],[108,69]],"semanticDiagnosticsPerFile":[116,115,119,117,127,130,129,122,118,120,121,123,124,125,126,135,136,137,47,48,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,49,98,65,66,67,99,68,69,70,71,72,73,74,75,76,77,78,79,80,82,81,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,138,139,140,141,143,142,144,145,146,128,134,132,133,131,46,9,10,14,13,3,15,16,17,18,19,20,21,22,4,5,26,23,24,25,27,28,29,6,30,31,32,33,7,34,35,36,37,8,38,43,44,39,40,41,42,2,1,45,12,11,114,100,110,101,111,103,102,104,113,105,109,106,107,112,108]},"version":"4.8.4"} \ No newline at end of file diff --git a/package.json b/package.json index 5044ef16..e5fe4622 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "assertive-ts-workspace", - "description": "The AssertiveTS workspace", + "name": "assertive-ts", + "description": "The Assertive.ts workspace", "repository": "git@github.com:stackbuilders/assertive-ts.git", "homepage": "https://stackbuilders.github.io/assertive-ts/", "author": "Stack Builders ", @@ -10,14 +10,14 @@ }, "packageManager": "yarn@3.6.1", "workspaces": [ - "package/", + "packages/*", "examples/*" ], "scripts": { "check": "turbo check && yarn lint", "build": "turbo run build", "compile": "turbo run compile", - "docs": "yarn workspace @stackbuilders/assertive-ts docs", + "docs": "yarn workspace @assertive-ts/core docs", "lint": "eslint .", "release": "turbo release --concurrency=1", "test": "turbo run test" diff --git a/package/README.md b/package/README.md deleted file mode 100644 index 49e30954..00000000 --- a/package/README.md +++ /dev/null @@ -1,261 +0,0 @@ - -[![All Contributors](https://img.shields.io/badge/all_contributors-10-orange.svg?style=flat-square)](#contributors-) - -[![CI](https://github.com/stackbuilders/assertive-ts/actions/workflows/ci.yml/badge.svg)](https://github.com/stackbuilders/assertive-ts/actions/workflows/ci.yml) -[![Release](https://github.com/stackbuilders/assertive-ts/actions/workflows/release.yml/badge.svg)](https://github.com/stackbuilders/assertive-ts/actions/workflows/release.yml) -[![Pages](https://github.com/stackbuilders/assertive-ts/actions/workflows/pages.yml/badge.svg)](https://github.com/stackbuilders/assertive-ts/actions/workflows/pages.yml) -[![NPM version](https://img.shields.io/npm/v/@stackbuilders/assertive-ts?logo=npm)](https://www.npmjs.com/package/@stackbuilders/assertive-ts) -[![NPM bundle size](https://img.shields.io/bundlephobia/min/@stackbuilders/assertive-ts)](https://www.npmjs.com/package/@stackbuilders/assertive-ts) -[![NPM downloads](https://img.shields.io/npm/dm/@stackbuilders/assertive-ts)](https://www.npmjs.com/package/@stackbuilders/assertive-ts) -[![NPM license](https://img.shields.io/npm/l/@stackbuilders/assertive-ts)](https://github.com/stackbuilders/assertive-ts/blob/main/LICENSE) -[![GitHub Release Date](https://img.shields.io/github/release-date/stackbuilders/assertive-ts)](https://github.com/stackbuilders/assertive-ts/releases) -[![Known Vulnerabilities](https://snyk.io/test/github/stackbuilders/assertive-ts/badge.svg)](https://snyk.io/test/github/stackbuilders/assertive-ts) - -# AssertiveTS - -A type-safe fluent assertion library written in TypeScript and inspired by [Jest](https://jestjs.io/docs/expect) assertions and the popular [AssertJ](https://assertj.github.io/doc/). - -This library is designed to work in the browser and in Node.js. It ships with a rich set of expressive and flexible matchers that allows chaining multiple assertions. AssertiveTS is framework agnostic and should be used with a test framework such as [Jest](https://github.com/stackbuilders/assertive-ts/blob/main/docs/jest-tutorial.md), [Mocha](https://github.com/stackbuilders/assertive-ts/blob/main/docs/mocha-tutorial.md), or Ava. - -## Type-safe library - -A distinctive feature of AssertiveTS with other assertion libraries is that it leverages the TypeScript compiler to avoid type coercions and mismatches. It also infers the static type of the value you want to assert and provides you with intelligent matcher completion and signature help so that you can write code more quickly and correctly. - -### Features - -- Type safety and intelligent matcher completion -- Rich set of expressive and flexible matchers -- Concise, chainable interface inspired by AssertJ -- Works with any test runner and framework such as [Jest](https://github.com/stackbuilders/assertive-ts/blob/main/docs/jest-tutorial.md), [Mocha](https://github.com/stackbuilders/assertive-ts/blob/main/docs/mocha-tutorial.md), or Ava -- Well tested: more than 300 tests! - -## Install - -```sh -npm install --save-dev @stackbuilders/assertive-ts -``` - -Or: - -```sh -yarn add --dev @stackbuilders/assertive-ts -``` - -## Usage - -Import the library in your test script: - -```ts -import { expect } from "@stackbuilders/assertive-ts" -``` - -Use the `expect` function along with a "matcher" function on the value you want to assert: - -```ts -expect(sum(1, 2)).toBeEqual(3); -``` - -To assert the opposite, just add `.not` before a matcher: - -```ts -expect(sum(1, 2)).not.toBeNull(); -``` - -With `assertive-ts` you can use **fluent assertions**, which means you can chain multiple matcher functions to the same value under test: - -```ts -expect("assertive-ts is awesome!") - .toStartWith("assertive-ts") - .not.toContain("unsafe") - .toEndWith("awesome!"); -``` - -The matcher functions depend on the type of the value on the `expect`. If you're using TypeScript, the compiler will let you know if something is not available for that assertion: - -```ts -// Boolean assertion -expect(isEven(2)).toBeTrue(); - -// String assertion -expect("foobar").toStartWith("foo"); - -// Number assertion -expect(sum(1, 2)).toBePositive(); - -expect(14).toEndWith("4"); - ^ ? type error: `toEndWith` does not exist in `NumberAssertion` -``` - -For a list of all matchers and extended documentation, please refer to the [API documentation](https://stackbuilders.github.io/assertive-ts/docs/build/). - -### Type Factory 🏭 - -A great feature of AssertiveTS is the type safety across the API. But, what should you do if you want to check the value under test is of some specific type during runtime? The answer is simple, AssertiveTS provides a `.asType(TypeFactory)` method, where the [TypeFactory](https://stackbuilders.github.io/assertive-ts/docs/build/interfaces/TypeFactory.html) parameter lets you check for the specific type and narrow the assertion instance to a more specific one. To make things simpler, AssertiveTS provides [TypeFactories](https://stackbuilders.github.io/assertive-ts/docs/build/interfaces/StaticTypeFactories.html) for the basic types: - -```ts -import { expect, TypeFactories } from "@stackbuilders/assertive-ts"; - -expect(value) - .asType(TypeFactories.String) - .toBeEmpty(); - -expect(list) - .asType(TypeFactories.array(TypeFactories.Number)) - .toHaveSameMembers([1, 2, 3, 4, 5]); -``` - -If the built-in type factories are not enough to assert your specific type, you can always create your own factory. A `TypeFactory` is nothing more than an object with 3 properties: - -- `Factory: new(actual: S) => A` - The specific assertion constructor to return if the predicate is true. Where `S` is the actual value type, and `A` is the type of the assertion to return (`A` should extend from `Assertion`). -- `predicate(value: unknown): value is S` - A predicate function that checks if the value is of the expected type. -- `typeName: string` - The name of the checked type. Used to make the assertion error message clearer. - -So, using a custom `TypeFactory` can look like the following: - -```ts -interface Point3D { - x: number; - y: number; - z: number; -} - -expect(maybePoint).asType({ - Factory: ObjectAssertion, - predicate: (value): value is Point3D => { - return typeof value === "object" - && value !== null - && "x" in value - && "y" in value - && "z" in value - && Object.values(value).every(v => typeof v === "number"); - }, - typeName: "Point3D" -}); -``` - -### Handling TypeScript Unions - -[Union types](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types) are a TypeScript concept that is only applicable at type level. During runtime, the value can only be one of the types. For instance, if we say `const foo: number | string = ...`, at runtime `foo` will be either a `number` or a `string`. If you want to use a more specific assertion on a union type, you can use `.asType(..)` to first assert the expected type, and then move forward with more assertions: - -```ts -const foo: number | string = 5; - -expect(foo) - .asType(TypeFactories.Number) - .toBePositive(); -``` - -### Help! The value can also be `null` or `undefined` - -When a value can be also `null` or `undefined`, we're going over the same concept as [Union types](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types). So if you want to make more specific assertions over a value that can be `null | undefined`, just use `.asType(..)` first: - -```ts -const bar: string | null | undefined = " "; - -expect(bar) - .asType(TypeFactories.String) - .toBeBlank(); -``` - -## Test Runner Integration - -- [Jest Integration](https://github.com/stackbuilders/assertive-ts/blob/main/docs/jest-tutorial.md) -- [Mocha Integration](https://github.com/stackbuilders/assertive-ts/blob/main/docs/mocha-tutorial.md) - -## API Reference - -You can find the full API reference [here](https://stackbuilders.github.io/assertive-ts/docs/build/) - -## Extension mechanism ⚙️ - -This feature allows you to extend the `expect(..)` function to return additional `Assertion` instances depending on the value under test. This opens the door to add additional assertion matchers for more specific cases. An `Assertion` can be added in the form of a `Plugin`: -```ts -interface Plugin> { - Assertion: new(actual: T) => A; - insertAt: "top" | "bottom"; - predicate: (actual: unknown) => actual is T; -} -``` - -Where `Assertion` is the class you want to add, `insertAt` determines if the logic is inserted before or after all the primitives, and `predicate` is the logical code used to determine if value matches the `Assertion` type. - -Once you have a plugin object, you can add it to assertive-ts with the `usePlugin(..)` helper function. Calls to this function should go on the setup file of your test runner or in a `beforeAll()` hook, so the extension is applied to all your tests. -```ts -// test/setup.ts -import { usePlugin } from "@stackbuilders/assertive-ts"; - -import { FilePlugin, HTMLElementPlugin } from "./plugins"; // your custom (or 3rd-party) plugins - -usePlugin(FilePlugin); -usePlugin(HTMLElementPlugin); -// ... -``` - -### What about the types? - -Each new plugin should add an additional overload to the `expect(..)` function to maintain type safety. To do that, you can extend the `Expect` interface to add the additional overloads. For example: -```ts -import { FileAssertion } from "./FileAssertion"; -import { HTMLElementAssertion } from "./HTMLElementAssertion"; - -declare module "@stackbuilders/assertive-ts" { - - export interface Expect { - (actual: File): FileAssertion; - (actual: HTMLElement): HTMLElementAssertion; - // ... - } -} -``` - -> **Note:** 3rd-party libraries should do this on their types entry point (index.d.ts), this way the interface is automatically extended when their plugin is passed to the `usePlugin(..)` function. - -### How to... - -If you're looking to write a plugin, you can find a simple example [here](https://github.com/stackbuilders/assertive-ts/blob/main/examples/symbolPlugin/). The example plugin is used in the [Jest](https://github.com/stackbuilders/assertive-ts/blob/main/examples/jest/test/plugins.test.ts) and [Mocha](https://github.com/stackbuilders/assertive-ts/blob/main/examples/mocha/test/plugins.test.ts) examples too, so you can also take a look at them to see how to apply and use plugins. - -## Contributors ✨ - -Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): - - - - - - - - - - - - - - - - - - - - - -
Jose Luis Leon
Jose Luis Leon

💻 🚇 🚧 📦 ⚠️
Byron Motoche
Byron Motoche

💻 ⚠️ 👀
Alejandro Vivanco
Alejandro Vivanco

💻 ⚠️ 👀
David Villamarin
David Villamarin

💻 ⚠️
Alexander Mejía
Alexander Mejía

💻 ⚠️
Christian Samaniego
Christian Samaniego

📖 💻 ⚠️ 👀
Sebastián Estrella
Sebastián Estrella

🚇
Daniel Calle
Daniel Calle

🚇
Anthony Suárez
Anthony Suárez

📖
Sebastian Avalos
Sebastian Avalos

👀
- - - - - - -This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! - -## License - -MIT, see [the LICENSE file](https://github.com/stackbuilders/assertive-ts/blob/main/LICENSE). - -## Contributing - -Do you want to contribute to this project? Please take a look at our [contributing guideline](https://github.com/stackbuilders/assertive-ts/blob/main/docs/CONTRIBUTING.md) to know how you can help us build it. - ---- -Stack Builders - -[Check out our libraries](https://github.com/stackbuilders/) | [Join our team](https://www.stackbuilders.com/join-us/) diff --git a/package/.mocharc.json b/packages/core/.mocharc.json similarity index 100% rename from package/.mocharc.json rename to packages/core/.mocharc.json diff --git a/package/.releaserc.json b/packages/core/.releaserc.json similarity index 87% rename from package/.releaserc.json rename to packages/core/.releaserc.json index 2f48dbab..5c615812 100644 --- a/package/.releaserc.json +++ b/packages/core/.releaserc.json @@ -8,5 +8,6 @@ "@semantic-release/release-notes-generator", "semantic-release-yarn", "@semantic-release/github" - ] + ], + "tagFormat": "core/v${version}" } diff --git a/package/LICENSE b/packages/core/LICENSE similarity index 100% rename from package/LICENSE rename to packages/core/LICENSE diff --git a/packages/core/README.md b/packages/core/README.md new file mode 100644 index 00000000..b499e249 --- /dev/null +++ b/packages/core/README.md @@ -0,0 +1,208 @@ +[![CI](https://github.com/stackbuilders/assertive-ts/actions/workflows/ci.yml/badge.svg)](https://github.com/stackbuilders/assertive-ts/actions/workflows/ci.yml) +[![Release](https://github.com/stackbuilders/assertive-ts/actions/workflows/release.yml/badge.svg)](https://github.com/stackbuilders/assertive-ts/actions/workflows/release.yml) +[![Pages](https://github.com/stackbuilders/assertive-ts/actions/workflows/pages.yml/badge.svg)](https://github.com/stackbuilders/assertive-ts/actions/workflows/pages.yml) +[![NPM version](https://img.shields.io/npm/v/@assertive-ts/core?logo=npm)](https://www.npmjs.com/package/@assertive-ts/core) +[![NPM bundle size](https://img.shields.io/bundlephobia/min/@assertive-ts/core)](https://www.npmjs.com/package/@assertive-ts/core) +[![NPM downloads](https://img.shields.io/npm/dm/@assertive-ts/core)](https://www.npmjs.com/package/@assertive-ts/core) +[![NPM license](https://img.shields.io/npm/l/@assertive-ts/core)](https://github.com/stackbuilders/assertive-ts/blob/main/LICENSE) +[![GitHub Release Date](https://img.shields.io/github/release-date/stackbuilders/assertive-ts)](https://github.com/stackbuilders/assertive-ts/releases) +[![Known Vulnerabilities](https://snyk.io/test/github/stackbuilders/assertive-ts/badge.svg)](https://snyk.io/test/github/stackbuilders/assertive-ts) + +# Assertive.ts Core + +The Assertive.ts Core package contains the main functionalities for the library. Namely, it provides assertions for basic types and all that's common in the JavaScript language, helpers to check and convert types, and an extension mechanism to use and create plugins that let us reach out to the whole JavaScript ecosystem. + +## Install + +```sh +npm install --save-dev @assertive-ts/core +``` + +Or: + +```sh +yarn add --dev @assertive-ts/core +``` + +## API Reference + +You can find the full API reference [here](https://stackbuilders.github.io/assertive-ts/docs/core/build/) 📚 + +## Usage + +Using you favorite test runner, you just need to import the `expect` and test away! If you don't really agree with `expect` as the name of the assertion function, we provide a couple aliases, such as `assert` and `assertThat`. + +```ts +import { expect } from "@assertive-ts/core" + +describe("sum", () => { + it("returns the sum of two numbers", () => { + const result = sum(3, 2); + + expect(result).toBeEqual(5); + }); +}); +``` + +To assert the opposite, you can simply use the `.not` modifier before the matcher: + +```ts +expect(sum(1, 2)).not.toBeNull(); +``` + +This library provides **fluent assertions**, which means you can chain multiple matcher functions to the same value under test: + +```ts +expect("assertive-ts is awesome!") + .toStartWith("assertive-ts") + .not.toContain("unsafe") + .toEndWith("awesome!"); +``` + +The matcher functions depend on the type of the value on the `expect`. If you're using TypeScript, the compiler will let you know if something is not available for that assertion: + +```ts +// Boolean assertion +expect(isEven(2)).toBeTrue(); + +// String assertion +expect("foobar").toStartWith("foo"); + +// Number assertion +expect(sum(1, 2)).toBePositive(); + +expect(14).toEndWith("4"); + ^ ? type error: `toEndWith` does not exist in `NumberAssertion` +``` + +For a list of all [Core](https://github.com/stackbuilders/assertive-ts/blob/main/packages/core/README.md) matchers and extended documentation, you can refer to the [Core API documentation](https://stackbuilders.github.io/assertive-ts/docs/core/build/). + +### Type Factory 🏭 + +A great feature of Assertive.ts is the type safety across the API. But, what should you do if you want to check the value under test is of some specific type during runtime? The answer is simple, Assertive.ts provides a `.asType(TypeFactory)` method, where the [TypeFactory](https://stackbuilders.github.io/assertive-ts/docs/core/build/interfaces/TypeFactory.html) parameter lets you check for the specific type and narrow the assertion instance to a more specific one. To make things simpler, Assertive.ts provides [TypeFactories](https://stackbuilders.github.io/assertive-ts/docs/core/build/interfaces/StaticTypeFactories.html) for the basic types: + +```ts +import { expect, TypeFactories } from "@assertive-ts/core"; + +expect(value) + .asType(TypeFactories.String) + .toBeEmpty(); + +expect(list) + .asType(TypeFactories.array(TypeFactories.Number)) + .toHaveSameMembers([1, 2, 3, 4, 5]); +``` + +If the built-in type factories are not enough to assert your specific type, you can always create your own factory. A `TypeFactory` is nothing more than an object with 3 properties: + +- `Factory: new(actual: S) => A` - The specific assertion constructor to return if the predicate is true. Where `S` is the actual value type, and `A` is the type of the assertion to return (`A` should extend from `Assertion`). +- `predicate(value: unknown): value is S` - A predicate function that checks if the value is of the expected type. +- `typeName: string` - The name of the checked type. Used to make the assertion error message clearer. + +So, using a custom `TypeFactory` can look like the following: + +```ts +interface Point3D { + x: number; + y: number; + z: number; +} + +expect(maybePoint).asType({ + Factory: ObjectAssertion, + predicate: (value): value is Point3D => { + return typeof value === "object" + && value !== null + && "x" in value + && "y" in value + && "z" in value + && Object.values(value).every(v => typeof v === "number"); + }, + typeName: "Point3D" +}); +``` + +### Handling TypeScript Unions + +[Union types](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types) are a TypeScript concept that is only applicable at type level. During runtime, the value can only be one of the types. For instance, if we say `const foo: number | string = ...`, at runtime `foo` will be either a `number` or a `string`. If you want to use a more specific assertion on a union type, you can use `.asType(..)` to first assert the expected type, and then move forward with more assertions: + +```ts +const foo: number | string = 5; + +expect(foo) + .asType(TypeFactories.Number) + .toBePositive(); +``` + +### Help! The value can also be `null` or `undefined` + +When a value can be also `null` or `undefined`, we're going over the same concept as [Union types](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types). So if you want to make more specific assertions over a value that can be `null | undefined`, just use `.asType(..)` first: + +```ts +const bar: string | null | undefined = " "; + +expect(bar) + .asType(TypeFactories.String) + .toBeBlank(); +``` + +## Extension mechanism ⚙️ + +This feature allows you to extend the `expect(..)` function to return additional `Assertion` instances depending on the value under test. This opens the door to add additional assertion matchers for more specific cases. An `Assertion` can be added in the form of a `Plugin`: +```ts +interface Plugin> { + Assertion: new(actual: T) => A; + insertAt: "top" | "bottom"; + predicate: (actual: unknown) => actual is T; +} +``` + +Where `Assertion` is the class you want to add, `insertAt` determines if the logic is inserted before or after all the primitives, and `predicate` is the logical code used to determine if value matches the `Assertion` type. + +Once you have a plugin object, you can add it to assertive-ts with the `usePlugin(..)` helper function. Calls to this function should go on the setup file of your test runner or in a `beforeAll()` hook, so the extension is applied to all your tests. +```ts +// test/setup.ts +import { usePlugin } from "@assertive-ts/core"; + +import { FilePlugin, HTMLElementPlugin } from "./plugins"; // your custom (or 3rd-party) plugins + +usePlugin(FilePlugin); +usePlugin(HTMLElementPlugin); +// ... +``` + +### What about the types? + +Each new plugin should add an additional overload to the `expect(..)` function to maintain type safety. To do that, you can extend the `Expect` interface to add the additional overloads. For example: +```ts +import { FileAssertion } from "./FileAssertion"; +import { HTMLElementAssertion } from "./HTMLElementAssertion"; + +declare module "@assertive-ts/core" { + + export interface Expect { + (actual: File): FileAssertion; + (actual: HTMLElement): HTMLElementAssertion; + // ... + } +} +``` + +> **Note:** 3rd-party libraries should do this on their types entry point (index.d.ts), this way the interface is automatically extended when their plugin is passed to the `usePlugin(..)` function. + +### How to... + +If you're looking to write a plugin, you can find a simple example [here](https://github.com/stackbuilders/assertive-ts/blob/main/examples/symbolPlugin/). The example plugin is used in the [Jest](https://github.com/stackbuilders/assertive-ts/blob/main/examples/jest/test/plugins.test.ts) and [Mocha](https://github.com/stackbuilders/assertive-ts/blob/main/examples/mocha/test/plugins.test.ts) examples too, so you can also take a look at them to see how to apply and use plugins. + +## License + +MIT, see [the LICENSE file](https://github.com/stackbuilders/assertive-ts/blob/main/LICENSE). + +## Contributing + +Do you want to contribute to this project? Please take a look at our [contributing guideline](https://github.com/stackbuilders/assertive-ts/blob/main/docs/CONTRIBUTING.md) to know how you can help us build it. + +--- +Stack Builders + +[Check out our libraries](https://github.com/stackbuilders/) | [Join our team](https://www.stackbuilders.com/join-us/) diff --git a/package/package.json b/packages/core/package.json similarity index 97% rename from package/package.json rename to packages/core/package.json index cb2358df..f623f9b2 100644 --- a/package/package.json +++ b/packages/core/package.json @@ -1,5 +1,5 @@ { - "name": "@stackbuilders/assertive-ts", + "name": "@assertive-ts/core", "version": "0.0.0", "description": "A type-safe fluent assertion library", "repository": "git@github.com:stackbuilders/assertive-ts.git", diff --git a/package/src/index.ts b/packages/core/src/index.ts similarity index 89% rename from package/src/index.ts rename to packages/core/src/index.ts index d1c9a02a..afd4e705 100644 --- a/package/src/index.ts +++ b/packages/core/src/index.ts @@ -20,7 +20,7 @@ export { }; /** - * Extends `@stackbuilders/assertive-ts` with a local or 3rd-party plugin. + * Extends `@assertive-ts/core` with a local or 3rd-party plugin. * * @param plugin the plugin to use to extend assertive-ts * @see {@link Plugin Plugin} diff --git a/package/src/lib/ArrayAssertion.ts b/packages/core/src/lib/ArrayAssertion.ts similarity index 100% rename from package/src/lib/ArrayAssertion.ts rename to packages/core/src/lib/ArrayAssertion.ts diff --git a/package/src/lib/Assertion.ts b/packages/core/src/lib/Assertion.ts similarity index 100% rename from package/src/lib/Assertion.ts rename to packages/core/src/lib/Assertion.ts diff --git a/package/src/lib/BooleanAssertion.ts b/packages/core/src/lib/BooleanAssertion.ts similarity index 100% rename from package/src/lib/BooleanAssertion.ts rename to packages/core/src/lib/BooleanAssertion.ts diff --git a/package/src/lib/DateAssertion.ts b/packages/core/src/lib/DateAssertion.ts similarity index 100% rename from package/src/lib/DateAssertion.ts rename to packages/core/src/lib/DateAssertion.ts diff --git a/package/src/lib/DateAssertion.types.ts b/packages/core/src/lib/DateAssertion.types.ts similarity index 100% rename from package/src/lib/DateAssertion.types.ts rename to packages/core/src/lib/DateAssertion.types.ts diff --git a/package/src/lib/ErrorAssertion.ts b/packages/core/src/lib/ErrorAssertion.ts similarity index 100% rename from package/src/lib/ErrorAssertion.ts rename to packages/core/src/lib/ErrorAssertion.ts diff --git a/package/src/lib/FunctionAssertion.ts b/packages/core/src/lib/FunctionAssertion.ts similarity index 100% rename from package/src/lib/FunctionAssertion.ts rename to packages/core/src/lib/FunctionAssertion.ts diff --git a/package/src/lib/NumberAssertion.helpers.ts b/packages/core/src/lib/NumberAssertion.helpers.ts similarity index 100% rename from package/src/lib/NumberAssertion.helpers.ts rename to packages/core/src/lib/NumberAssertion.helpers.ts diff --git a/package/src/lib/NumberAssertion.ts b/packages/core/src/lib/NumberAssertion.ts similarity index 100% rename from package/src/lib/NumberAssertion.ts rename to packages/core/src/lib/NumberAssertion.ts diff --git a/package/src/lib/ObjectAssertion.ts b/packages/core/src/lib/ObjectAssertion.ts similarity index 100% rename from package/src/lib/ObjectAssertion.ts rename to packages/core/src/lib/ObjectAssertion.ts diff --git a/package/src/lib/PromiseAssertion.ts b/packages/core/src/lib/PromiseAssertion.ts similarity index 100% rename from package/src/lib/PromiseAssertion.ts rename to packages/core/src/lib/PromiseAssertion.ts diff --git a/package/src/lib/StringAssertion.ts b/packages/core/src/lib/StringAssertion.ts similarity index 100% rename from package/src/lib/StringAssertion.ts rename to packages/core/src/lib/StringAssertion.ts diff --git a/package/src/lib/config/Config.ts b/packages/core/src/lib/config/Config.ts similarity index 100% rename from package/src/lib/config/Config.ts rename to packages/core/src/lib/config/Config.ts diff --git a/package/src/lib/errors/UnsupportedOperationError.ts b/packages/core/src/lib/errors/UnsupportedOperationError.ts similarity index 100% rename from package/src/lib/errors/UnsupportedOperationError.ts rename to packages/core/src/lib/errors/UnsupportedOperationError.ts diff --git a/package/src/lib/expect.ts b/packages/core/src/lib/expect.ts similarity index 100% rename from package/src/lib/expect.ts rename to packages/core/src/lib/expect.ts diff --git a/package/src/lib/helpers/TypeFactories.ts b/packages/core/src/lib/helpers/TypeFactories.ts similarity index 100% rename from package/src/lib/helpers/TypeFactories.ts rename to packages/core/src/lib/helpers/TypeFactories.ts diff --git a/package/src/lib/helpers/dates.ts b/packages/core/src/lib/helpers/dates.ts similarity index 100% rename from package/src/lib/helpers/dates.ts rename to packages/core/src/lib/helpers/dates.ts diff --git a/package/src/lib/helpers/guards.ts b/packages/core/src/lib/helpers/guards.ts similarity index 100% rename from package/src/lib/helpers/guards.ts rename to packages/core/src/lib/helpers/guards.ts diff --git a/package/src/lib/helpers/messages.ts b/packages/core/src/lib/helpers/messages.ts similarity index 100% rename from package/src/lib/helpers/messages.ts rename to packages/core/src/lib/helpers/messages.ts diff --git a/package/src/lib/helpers/types.ts b/packages/core/src/lib/helpers/types.ts similarity index 100% rename from package/src/lib/helpers/types.ts rename to packages/core/src/lib/helpers/types.ts diff --git a/package/test/hooks.ts b/packages/core/test/hooks.ts similarity index 100% rename from package/test/hooks.ts rename to packages/core/test/hooks.ts diff --git a/package/test/index.test.ts b/packages/core/test/index.test.ts similarity index 100% rename from package/test/index.test.ts rename to packages/core/test/index.test.ts diff --git a/package/test/lib/ArrayAssertion.test.ts b/packages/core/test/lib/ArrayAssertion.test.ts similarity index 100% rename from package/test/lib/ArrayAssertion.test.ts rename to packages/core/test/lib/ArrayAssertion.test.ts diff --git a/package/test/lib/Assertion.test.ts b/packages/core/test/lib/Assertion.test.ts similarity index 100% rename from package/test/lib/Assertion.test.ts rename to packages/core/test/lib/Assertion.test.ts diff --git a/package/test/lib/BooleanAssertion.test.ts b/packages/core/test/lib/BooleanAssertion.test.ts similarity index 100% rename from package/test/lib/BooleanAssertion.test.ts rename to packages/core/test/lib/BooleanAssertion.test.ts diff --git a/package/test/lib/DateAssertion.test.ts b/packages/core/test/lib/DateAssertion.test.ts similarity index 100% rename from package/test/lib/DateAssertion.test.ts rename to packages/core/test/lib/DateAssertion.test.ts diff --git a/package/test/lib/ErrorAssertion.test.ts b/packages/core/test/lib/ErrorAssertion.test.ts similarity index 100% rename from package/test/lib/ErrorAssertion.test.ts rename to packages/core/test/lib/ErrorAssertion.test.ts diff --git a/package/test/lib/FunctionAssertion.test.ts b/packages/core/test/lib/FunctionAssertion.test.ts similarity index 100% rename from package/test/lib/FunctionAssertion.test.ts rename to packages/core/test/lib/FunctionAssertion.test.ts diff --git a/package/test/lib/NumberAssertion.helpers.test.ts b/packages/core/test/lib/NumberAssertion.helpers.test.ts similarity index 100% rename from package/test/lib/NumberAssertion.helpers.test.ts rename to packages/core/test/lib/NumberAssertion.helpers.test.ts diff --git a/package/test/lib/NumberAssertion.test.ts b/packages/core/test/lib/NumberAssertion.test.ts similarity index 100% rename from package/test/lib/NumberAssertion.test.ts rename to packages/core/test/lib/NumberAssertion.test.ts diff --git a/package/test/lib/ObjectAssertion.test.ts b/packages/core/test/lib/ObjectAssertion.test.ts similarity index 100% rename from package/test/lib/ObjectAssertion.test.ts rename to packages/core/test/lib/ObjectAssertion.test.ts diff --git a/package/test/lib/PromiseAssertion.test.ts b/packages/core/test/lib/PromiseAssertion.test.ts similarity index 100% rename from package/test/lib/PromiseAssertion.test.ts rename to packages/core/test/lib/PromiseAssertion.test.ts diff --git a/package/test/lib/StringAssertion.test.ts b/packages/core/test/lib/StringAssertion.test.ts similarity index 100% rename from package/test/lib/StringAssertion.test.ts rename to packages/core/test/lib/StringAssertion.test.ts diff --git a/package/test/lib/expect.test.ts b/packages/core/test/lib/expect.test.ts similarity index 100% rename from package/test/lib/expect.test.ts rename to packages/core/test/lib/expect.test.ts diff --git a/package/test/lib/helpers/TypeFactories.test.ts b/packages/core/test/lib/helpers/TypeFactories.test.ts similarity index 100% rename from package/test/lib/helpers/TypeFactories.test.ts rename to packages/core/test/lib/helpers/TypeFactories.test.ts diff --git a/package/test/lib/helpers/dates.test.ts b/packages/core/test/lib/helpers/dates.test.ts similarity index 100% rename from package/test/lib/helpers/dates.test.ts rename to packages/core/test/lib/helpers/dates.test.ts diff --git a/package/test/lib/helpers/guards.test.ts b/packages/core/test/lib/helpers/guards.test.ts similarity index 100% rename from package/test/lib/helpers/guards.test.ts rename to packages/core/test/lib/helpers/guards.test.ts diff --git a/package/tsconfig.json b/packages/core/tsconfig.json similarity index 56% rename from package/tsconfig.json rename to packages/core/tsconfig.json index 9101173d..05bc1dc0 100644 --- a/package/tsconfig.json +++ b/packages/core/tsconfig.json @@ -1,8 +1,11 @@ { - "extends": "../tsconfig.json", + "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "./build", - "typeRoots": ["../node_modules/@types/", "./typings/"] + "typeRoots": [ + "../../node_modules/@types/", + "./typings/" + ] }, "exclude": [ "build/*", diff --git a/package/tsconfig.prod.json b/packages/core/tsconfig.prod.json similarity index 67% rename from package/tsconfig.prod.json rename to packages/core/tsconfig.prod.json index 7144ed19..3473c03e 100644 --- a/package/tsconfig.prod.json +++ b/packages/core/tsconfig.prod.json @@ -4,5 +4,8 @@ "incremental": false, "outDir": "./dist" }, - "include": ["src/**/*", "typings/**/*"] + "include": [ + "src/**/*", + "typings/**/*" + ] } diff --git a/package/typedoc.json b/packages/core/typedoc.json similarity index 84% rename from package/typedoc.json rename to packages/core/typedoc.json index 844cfed6..0dd22f5d 100644 --- a/package/typedoc.json +++ b/packages/core/typedoc.json @@ -1,7 +1,7 @@ { "$schema": "https://typedoc.org/schema.json", "cleanOutputDir": true, - "entryPoints": ["src/lib"], + "entryPoints": ["src/index.ts"], "entryPointStrategy": "expand", "gitRevision": "main", "githubPages": false, @@ -10,8 +10,8 @@ "intentionallyNotExported": ["NoThrow"], "mergeModulesMergeMode": "project", "mergeModulesRenameDefaults": true, - "name": "AssertiveTS - API Reference", - "out": "../docs/build", + "name": "Assertive.ts - Core API", + "out": "../../docs/core/build", "plugin": [ "typedoc-plugin-markdown", "typedoc-plugin-merge-modules" diff --git a/package/typings/extensions.d.ts b/packages/core/typings/extensions.d.ts similarity index 100% rename from package/typings/extensions.d.ts rename to packages/core/typings/extensions.d.ts diff --git a/yarn.lock b/yarn.lock index 6075fe69..6f07301e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22,6 +22,28 @@ __metadata: languageName: node linkType: hard +"@assertive-ts/core@workspace:^, @assertive-ts/core@workspace:packages/core": + version: 0.0.0-use.local + resolution: "@assertive-ts/core@workspace:packages/core" + dependencies: + "@cometlib/dedent": ^0.8.0-es.10 + "@types/mocha": ^10.0.1 + "@types/node": ^20.4.8 + "@types/sinon": ^10.0.16 + all-contributors-cli: ^6.26.1 + fast-deep-equal: ^3.1.3 + mocha: ^10.2.0 + semantic-release: ^21.0.7 + semantic-release-yarn: ^2.0.0 + sinon: ^15.2.0 + ts-node: ^10.9.1 + typedoc: ^0.24.8 + typedoc-plugin-markdown: ^3.15.4 + typedoc-plugin-merge-modules: ^5.0.1 + typescript: ^5.1.6 + languageName: unknown + linkType: soft + "@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.21.4, @babel/code-frame@npm:^7.22.10, @babel/code-frame@npm:^7.22.5": version: 7.22.10 resolution: "@babel/code-frame@npm:7.22.10" @@ -506,8 +528,8 @@ __metadata: version: 0.0.0-use.local resolution: "@examples/jest@workspace:examples/jest" dependencies: + "@assertive-ts/core": "workspace:^" "@examples/symbol-plugin": "workspace:^" - "@stackbuilders/assertive-ts": "workspace:^" "@types/jest": ^29.5.3 "@types/node": ^20.4.8 jest: ^29.6.2 @@ -521,8 +543,8 @@ __metadata: version: 0.0.0-use.local resolution: "@examples/mocha@workspace:examples/mocha" dependencies: + "@assertive-ts/core": "workspace:^" "@examples/symbol-plugin": "workspace:^" - "@stackbuilders/assertive-ts": "workspace:^" "@types/mocha": ^10.0.1 "@types/node": ^20.4.8 mocha: ^10.2.0 @@ -535,10 +557,10 @@ __metadata: version: 0.0.0-use.local resolution: "@examples/symbol-plugin@workspace:examples/symbolPlugin" dependencies: - "@stackbuilders/assertive-ts": "workspace:^" + "@assertive-ts/core": "workspace:^" typescript: ^5.1.6 peerDependencies: - "@stackbuilders/assertive-ts": "*" + "@assertive-ts/core": "*" languageName: unknown linkType: soft @@ -1463,28 +1485,6 @@ __metadata: languageName: node linkType: hard -"@stackbuilders/assertive-ts@workspace:^, @stackbuilders/assertive-ts@workspace:package": - version: 0.0.0-use.local - resolution: "@stackbuilders/assertive-ts@workspace:package" - dependencies: - "@cometlib/dedent": ^0.8.0-es.10 - "@types/mocha": ^10.0.1 - "@types/node": ^20.4.8 - "@types/sinon": ^10.0.16 - all-contributors-cli: ^6.26.1 - fast-deep-equal: ^3.1.3 - mocha: ^10.2.0 - semantic-release: ^21.0.7 - semantic-release-yarn: ^2.0.0 - sinon: ^15.2.0 - ts-node: ^10.9.1 - typedoc: ^0.24.8 - typedoc-plugin-markdown: ^3.15.4 - typedoc-plugin-merge-modules: ^5.0.1 - typescript: ^5.1.6 - languageName: unknown - linkType: soft - "@tootallnate/once@npm:2": version: 2.0.0 resolution: "@tootallnate/once@npm:2.0.0" @@ -1651,9 +1651,9 @@ __metadata: linkType: hard "@types/node@npm:*, @types/node@npm:^20.4.8": - version: 20.4.8 - resolution: "@types/node@npm:20.4.8" - checksum: 86a3963c0c7af3410553d1dfa4b018a20b3cb3ab4d8e8ffe27408b6338c5de0374b0bf379bc705da2205b466daa751ccfe062f453ba9bde34fdb0e5163ca6a68 + version: 20.4.9 + resolution: "@types/node@npm:20.4.9" + checksum: 504e3da96274f3865c1251830f4750bb0a8f6ef6f8648902cd3bba33370c5f219235471bfbf55cce726b25c8eacfcc8e2aad0ec3b13e27ea6708b00d4a9a46c8 languageName: node linkType: hard @@ -2318,9 +2318,9 @@ __metadata: languageName: node linkType: hard -"assertive-ts-workspace@workspace:.": +"assertive-ts@workspace:.": version: 0.0.0-use.local - resolution: "assertive-ts-workspace@workspace:." + resolution: "assertive-ts@workspace:." dependencies: "@typescript-eslint/eslint-plugin": ^6.3.0 "@typescript-eslint/parser": ^6.3.0 @@ -3369,9 +3369,9 @@ __metadata: linkType: hard "electron-to-chromium@npm:^1.4.477": - version: 1.4.487 - resolution: "electron-to-chromium@npm:1.4.487" - checksum: 244651fa6878f8ccf94ab76924b7a1c482ac714e2e6032d9e0f3268a21876991b5ca4fb75fe77274a4b19e3836bbe4522cdacb75d6f6758af61a93030051a992 + version: 1.4.488 + resolution: "electron-to-chromium@npm:1.4.488" + checksum: 431c100e01262976bcef3d15505da3817d19978b57236aeede1d42653c3bc5872b79ea9ef7f2b13b2719a2663bd1cab718342217a8daa3bbc52c3819f418e552 languageName: node linkType: hard @@ -3576,13 +3576,13 @@ __metadata: linkType: hard "eslint-import-resolver-node@npm:^0.3.7": - version: 0.3.8 - resolution: "eslint-import-resolver-node@npm:0.3.8" + version: 0.3.9 + resolution: "eslint-import-resolver-node@npm:0.3.9" dependencies: debug: ^3.2.7 is-core-module: ^2.13.0 resolve: ^1.22.4 - checksum: 5769ebec976d1145957f5d87ee05b6e880cd3fbeb001a43b7a6e6a03b303d9b253b37ca296277f228159a0bbb690638c2e4b3a573dd4d6753b8f28ff85dbe192 + checksum: 439b91271236b452d478d0522a44482e8c8540bf9df9bd744062ebb89ab45727a3acd03366a6ba2bdbcde8f9f718bab7fe8db64688aca75acf37e04eafd25e22 languageName: node linkType: hard