Skip to content

Commit 01e0aeb

Browse files
authored
feat(core)!: Rename package to assertive-ts/core (#105)
BREAKING CHANGE: Deprecates the @stackbuilders/assertive-ts package in favor of assertive-ts/core so we can group plugins under the assertive-ts namespace
1 parent 76936a2 commit 01e0aeb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+315
-486
lines changed

README.md

+24-148
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,21 @@
44
[![CI](https://github.com/stackbuilders/assertive-ts/actions/workflows/ci.yml/badge.svg)](https://github.com/stackbuilders/assertive-ts/actions/workflows/ci.yml)
55
[![Release](https://github.com/stackbuilders/assertive-ts/actions/workflows/release.yml/badge.svg)](https://github.com/stackbuilders/assertive-ts/actions/workflows/release.yml)
66
[![Pages](https://github.com/stackbuilders/assertive-ts/actions/workflows/pages.yml/badge.svg)](https://github.com/stackbuilders/assertive-ts/actions/workflows/pages.yml)
7-
[![NPM version](https://img.shields.io/npm/v/@stackbuilders/assertive-ts?logo=npm)](https://www.npmjs.com/package/@stackbuilders/assertive-ts)
8-
[![NPM bundle size](https://img.shields.io/bundlephobia/min/@stackbuilders/assertive-ts)](https://www.npmjs.com/package/@stackbuilders/assertive-ts)
9-
[![NPM downloads](https://img.shields.io/npm/dm/@stackbuilders/assertive-ts)](https://www.npmjs.com/package/@stackbuilders/assertive-ts)
10-
[![NPM license](https://img.shields.io/npm/l/@stackbuilders/assertive-ts)](./LICENSE)
11-
[![GitHub Release Date](https://img.shields.io/github/release-date/stackbuilders/assertive-ts)](https://github.com/stackbuilders/assertive-ts/releases)
7+
[![NPM Core version](https://img.shields.io/npm/v/@assertive-ts/core?logo=npm&label=core)](https://www.npmjs.com/package/@assertive-ts/core)
8+
[![NPM license](https://img.shields.io/npm/l/@assertive-ts/core)](https://github.com/stackbuilders/assertive-ts/blob/main/LICENSE)
129
[![Known Vulnerabilities](https://snyk.io/test/github/stackbuilders/assertive-ts/badge.svg)](https://snyk.io/test/github/stackbuilders/assertive-ts)
1310

14-
# AssertiveTS
11+
# Assertive.ts
1512

1613
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/).
1714

18-
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.
15+
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.
16+
17+
**🚨 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.
1918

2019
## Type-safe library
2120

22-
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.
21+
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.
2322

2423
### Features
2524

@@ -29,39 +28,35 @@ A distinctive feature of AssertiveTS with other assertion libraries is that it l
2928
- Works with any test runner and framework such as [Jest](/docs/jest-tutorial.md), [Mocha](/docs/mocha-tutorial.md), or Ava
3029
- Well tested: more than 300 tests!
3130

32-
## Install
33-
34-
```sh
35-
npm install --save-dev @stackbuilders/assertive-ts
36-
```
31+
## Packages
3732

38-
Or:
33+
For convenience, this library is split into packages grouped within the same namespace:
3934

40-
```sh
41-
yarn add --dev @stackbuilders/assertive-ts
42-
```
35+
- **[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.
4336

4437
## Usage
4538

46-
Import the library in your test script:
39+
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`.
4740

4841
```ts
49-
import { expect } from "@stackbuilders/assertive-ts"
50-
```
42+
import { expect } from "@assertive-ts/core"
5143

52-
Use the `expect` function along with a "matcher" function on the value you want to assert:
44+
describe("sum", () => {
45+
it("returns the sum of two numbers", () => {
46+
const result = sum(3, 2);
5347

54-
```ts
55-
expect(sum(1, 2)).toBeEqual(3);
48+
expect(result).toBeEqual(5);
49+
});
50+
});
5651
```
5752

58-
To assert the opposite, just add `.not` before a matcher:
53+
To assert the opposite, you can simply use the `.not` modifier before the matcher:
5954

6055
```ts
6156
expect(sum(1, 2)).not.toBeNull();
6257
```
6358

64-
With `assertive-ts` you can use **fluent assertions**, which means you can chain multiple matcher functions to the same value under test:
59+
This library provides **fluent assertions**, which means you can chain multiple matcher functions to the same value under test:
6560

6661
```ts
6762
expect("assertive-ts is awesome!")
@@ -86,133 +81,14 @@ expect(14).toEndWith("4");
8681
^ ? type error: `toEndWith` does not exist in `NumberAssertion`
8782
```
8883

89-
For a list of all matchers and extended documentation, please refer to the [API documentation](https://stackbuilders.github.io/assertive-ts/docs/build/).
90-
91-
### Type Factory 🏭
92-
93-
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:
94-
95-
```ts
96-
import { expect, TypeFactories } from "@stackbuilders/assertive-ts";
97-
98-
expect(value)
99-
.asType(TypeFactories.String)
100-
.toBeEmpty();
101-
102-
expect(list)
103-
.asType(TypeFactories.array(TypeFactories.Number))
104-
.toHaveSameMembers([1, 2, 3, 4, 5]);
105-
```
106-
107-
If the built-in type factories are not enough to assert your specific type, you can always create your own factory. A `TypeFactory<S, A>` is nothing more than an object with 3 properties:
108-
109-
- `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<S>`).
110-
- `predicate(value: unknown): value is S` - A predicate function that checks if the value is of the expected type.
111-
- `typeName: string` - The name of the checked type. Used to make the assertion error message clearer.
112-
113-
So, using a custom `TypeFactory` can look like the following:
114-
115-
```ts
116-
interface Point3D {
117-
x: number;
118-
y: number;
119-
z: number;
120-
}
121-
122-
expect(maybePoint).asType({
123-
Factory: ObjectAssertion<Point3D>,
124-
predicate: (value): value is Point3D => {
125-
return typeof value === "object"
126-
&& value !== null
127-
&& "x" in value
128-
&& "y" in value
129-
&& "z" in value
130-
&& Object.values(value).every(v => typeof v === "number");
131-
},
132-
typeName: "Point3D"
133-
});
134-
```
135-
136-
### Handling TypeScript Unions
137-
138-
[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:
139-
140-
```ts
141-
const foo: number | string = 5;
142-
143-
expect(foo)
144-
.asType(TypeFactories.Number)
145-
.toBePositive();
146-
```
147-
148-
### Help! The value can also be `null` or `undefined`
149-
150-
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:
151-
152-
```ts
153-
const bar: string | null | undefined = " ";
154-
155-
expect(bar)
156-
.asType(TypeFactories.String)
157-
.toBeBlank();
158-
```
84+
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/).
15985

16086
## Test Runner Integration
16187

162-
- [Jest Integration](docs/jest-tutorial.md)
163-
- [Mocha Integration](docs/mocha-tutorial.md)
164-
165-
## API Reference
166-
167-
You can find the full API reference [here](https://stackbuilders.github.io/assertive-ts/docs/build/)
168-
169-
## Extension mechanism ⚙️
170-
171-
This feature allows you to extend the `expect(..)` function to return additional `Assertion<T>` instances depending on the value under test. This opens the door to add additional assertion matchers for more specific cases. An `Assertion<T>` can be added in the form of a `Plugin`:
172-
```ts
173-
interface Plugin<T, A extends Assertion<T>> {
174-
Assertion: new(actual: T) => A;
175-
insertAt: "top" | "bottom";
176-
predicate: (actual: unknown) => actual is T;
177-
}
178-
```
179-
180-
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.
181-
182-
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.
183-
```ts
184-
// test/setup.ts
185-
import { usePlugin } from "@stackbuilders/assertive-ts";
186-
187-
import { FilePlugin, HTMLElementPlugin } from "./plugins"; // your custom (or 3rd-party) plugins
188-
189-
usePlugin(FilePlugin);
190-
usePlugin(HTMLElementPlugin);
191-
// ...
192-
```
193-
194-
### What about the types?
195-
196-
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:
197-
```ts
198-
import { FileAssertion } from "./FileAssertion";
199-
import { HTMLElementAssertion } from "./HTMLElementAssertion";
200-
201-
declare module "@stackbuilders/assertive-ts" {
202-
203-
export interface Expect {
204-
(actual: File): FileAssertion;
205-
(actual: HTMLElement): HTMLElementAssertion;
206-
// ...
207-
}
208-
}
209-
```
210-
211-
> **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.
212-
213-
### How to...
88+
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:
21489

215-
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.
90+
- [Jest Integration](https://github.com/stackbuilders/assertive-ts/blob/main/docs/jest-tutorial.md)
91+
- [Mocha Integration](https://github.com/stackbuilders/assertive-ts/blob/main/docs/mocha-tutorial.md)
21692

21793
## Contributors ✨
21894

_config.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ defaults:
44
- scope:
55
path: ""
66
values:
7-
title: AssertiveTS
7+
title: Assertive.ts
88
subtitle: A type-safe fluent assertion library

docs/jest-tutorial.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Let's set up a project with Jest and assertive-ts to write our first assertion.
55
First, let's install the dependencies:
66

77
```
8-
npm install --save-dev typescript ts-jest jest @types/jest @stackbuilders/assertive-ts
8+
npm install --save-dev typescript ts-jest jest @types/jest @assertive-ts/core
99
```
1010

1111
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 => {
3131
}
3232
```
3333

34-
Now let's write a test for that function. Make sure to import `expect` from the `@stackbuilders/assertive-ts` module:
34+
Now let's write a test for that function. Make sure to import `expect` from the `@assertive-ts/core` module:
3535

3636
*tests/mathUtils.test.ts*
3737
```typescript
38-
import { expect } from "@stackbuilders/assertive-ts";
38+
import { expect } from "@assertive-ts/core";
3939
import { sum } from "../src/mathUtils";
4040

4141
describe("sum", () => {
@@ -55,12 +55,12 @@ You might want to use the `expect` function from Jest along with assertive-ts as
5555

5656
```typescript
5757
import { expect } from "@jest/globals";
58-
import { assert } from "@stackbuilders/assertive-ts";
58+
import { assert } from "@assertive-ts/core";
5959
```
6060

6161
- Or use an explicit import to rename the `expect` function from Jest to something like `jestExpect`:
6262

6363
```typescript
6464
import { expect as jestExpect } from "@jest/globals";
65-
import { expect } from "@stackbuilders/assertive-ts";
65+
import { expect } from "@assertive-ts/core";
6666
```

docs/mocha-tutorial.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Let's set up a project with Mocha and assertive-ts.
44

55
First, let's install the dependencies:
66
```
7-
npm install --save-dev typescript mocha @types/mocha ts-node @stackbuilders/assertive-ts
7+
npm install --save-dev typescript mocha @types/mocha ts-node @assertive-ts/core
88
```
99

1010
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 => {
4040
}
4141
```
4242

43-
Now let's write a test for that function. Make sure to import `expect` from the `@stackbuilders/assertive-ts` module.
43+
Now let's write a test for that function. Make sure to import `expect` from the `@assertive-ts/core` module.
4444

4545
*tests/mathUtils.test.ts*
4646
```typescript
47-
import { expect } from "@stackbuilders/assertive-ts";
47+
import { expect } from "@assertive-ts/core";
4848
import { sum } from "../src/mathUtils";
4949

5050
describe("sum", () => {

examples/jest/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Jest example
22

3-
Example project using AssertiveTS with Jest's test runner.
3+
Example project using Assertive.ts with Jest's test runner.
44

5-
This example showcases the use of AssertiveTS' `expect` and its `assert` alias,
5+
This example showcases the use of Assertive.ts' `expect` and its `assert` alias,
66
as well as the use of Jest's own `expect` function imported with a different
77
name.
88

examples/jest/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
"test": "jest"
77
},
88
"devDependencies": {
9+
"@assertive-ts/core": "workspace:^",
910
"@examples/symbol-plugin": "workspace:^",
10-
"@stackbuilders/assertive-ts": "workspace:^",
1111
"@types/jest": "^29.5.3",
1212
"@types/node": "^20.4.8",
1313
"jest": "^29.6.2",

examples/jest/test/mathUtils.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import { assert, expect } from "@assertive-ts/core";
12
import { expect as jestExpect } from "@jest/globals";
2-
import { assert, expect } from "@stackbuilders/assertive-ts";
33

44
import { sum } from "../src/mathUtils";
55

examples/jest/test/plugins.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { expect } from "@stackbuilders/assertive-ts";
1+
import { expect } from "@assertive-ts/core";
22

33
describe("plugins", () => {
44
it("can use the symbol plugin", () => {

examples/jest/test/setup.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import { usePlugin } from "@assertive-ts/core";
12
import { SymbolPlugin } from "@examples/symbol-plugin";
2-
import { usePlugin } from "@stackbuilders/assertive-ts";
33

44
beforeAll(() => {
55
usePlugin(SymbolPlugin);

examples/mocha/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Mocha example
22

3-
Example project using AssertiveTS with Mocha's test runner.
3+
Example project using Assertive.ts with Mocha's test runner.
44

5-
This example showcases the use of AssertiveTS' `expect` and its `assert` alias
5+
This example showcases the use of Assertive.ts' `expect` and its `assert` alias
66
with Mocha as the test runner.
77

88
## How to setup

examples/mocha/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
"test": "mocha"
77
},
88
"devDependencies": {
9+
"@assertive-ts/core": "workspace:^",
910
"@examples/symbol-plugin": "workspace:^",
10-
"@stackbuilders/assertive-ts": "workspace:^",
1111
"@types/mocha": "^10.0.1",
1212
"@types/node": "^20.4.8",
1313
"mocha": "^10.2.0",

examples/mocha/test/hooks.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import { usePlugin } from "@assertive-ts/core";
12
import { SymbolPlugin } from "@examples/symbol-plugin";
2-
import { usePlugin } from "@stackbuilders/assertive-ts";
33
import { RootHookObject } from "mocha";
44

55
export function mochaHooks(): RootHookObject {

examples/mocha/test/mathUtils.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { assert, expect } from "@stackbuilders/assertive-ts";
1+
import { assert, expect } from "@assertive-ts/core";
22

33
import { sum } from "../src/mathUtils";
44

examples/mocha/test/plugins.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { expect } from "@stackbuilders/assertive-ts";
1+
import { expect } from "@assertive-ts/core";
22

33
describe("plugins", () => {
44
it("can use the symbol plugin", () => {

examples/symbolPlugin/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
"compile": "tsc"
99
},
1010
"devDependencies": {
11-
"@stackbuilders/assertive-ts": "workspace:^",
11+
"@assertive-ts/core": "workspace:^",
1212
"typescript": "^5.1.6"
1313
},
1414
"peerDependencies": {
15-
"@stackbuilders/assertive-ts": "*"
15+
"@assertive-ts/core": "*"
1616
}
1717
}

examples/symbolPlugin/src/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { Plugin } from "@stackbuilders/assertive-ts";
1+
import { Plugin } from "@assertive-ts/core";
22

33
import { SymbolAssertion } from "./lib/SymbolAssertion";
44

5-
declare module "@stackbuilders/assertive-ts" {
5+
declare module "@assertive-ts/core" {
66

77
export interface Expect {
88
// eslint-disable-next-line @typescript-eslint/prefer-function-type

examples/symbolPlugin/src/lib/SymbolAssertion.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Assertion, AssertionError } from "@stackbuilders/assertive-ts";
1+
import { Assertion, AssertionError } from "@assertive-ts/core";
22

33
export class SymbolAssertion extends Assertion<symbol> {
44

0 commit comments

Comments
 (0)