bupkis 0.0.2 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +138 -82
- package/package.json +18 -16
- package/src/bootstrap.ts +1 -1
- package/src/expect.ts +1 -1
- package/src/types.ts +16 -10
- package/src/use.ts +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.1.0](https://github.com/boneskull/bupkis/compare/bupkis-v0.0.2...bupkis-v0.1.0) (2025-09-08)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **use:** use() returns an object with a use() in it ([fb383d6](https://github.com/boneskull/bupkis/commit/fb383d6fb2f541085d2300664fe73b25c6249e42))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **package:** add description and homepage ([2ff82ea](https://github.com/boneskull/bupkis/commit/2ff82ea715280098f59612ba32da808308aced0e))
|
|
14
|
+
|
|
3
15
|
## [0.0.2](https://github.com/boneskull/bupkis/compare/bupkis-v0.0.1...bupkis-v0.0.2) (2025-09-07)
|
|
4
16
|
|
|
5
17
|
|
package/README.md
CHANGED
|
@@ -1,34 +1,51 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="
|
|
3
|
-
<h1 align="center"><
|
|
2
|
+
<img src="./assets/bupkis-logo-512.png" width="512px" align="center" alt="BUPKIS logo"/>
|
|
3
|
+
<h1 align="center"><span class="twentieth-century-caps">⁓ BUPKIS ⁓<span></h1>
|
|
4
4
|
<p align="center">
|
|
5
|
-
|
|
5
|
+
Uncommonly extensible assertions for the beautiful people
|
|
6
6
|
<br/>
|
|
7
|
-
by <a href="https://github.com/boneskull">@boneskull</a>
|
|
7
|
+
<small>by <a href="https://github.com/boneskull">@boneskull</a></small>
|
|
8
8
|
</p>
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
|
+
## Quick Links
|
|
12
|
+
|
|
13
|
+
- [BUPKIS' Homepage][docs] (<https://bupkis.zip>)
|
|
14
|
+
- [Assertion Reference][assertion-reference]
|
|
15
|
+
- [Guide: Basic Usage][basic-usage]
|
|
16
|
+
- [Guide: How to Create a Custom Assertion][create-a-custom-assertion]
|
|
17
|
+
|
|
11
18
|
## Motivation
|
|
12
19
|
|
|
20
|
+
> "_Another_ assertion library? You cannot be serious. My test framework has its own assertions!"
|
|
21
|
+
>
|
|
22
|
+
> ‒sickos, probably
|
|
23
|
+
|
|
13
24
|
Look, I'm ~~old~~ ~~wizened~~ ~~experienced~~ knowledegable and I've written a lot of tests. I've used a lot of assertion libraries. There are ones I prefer and ones I don't.
|
|
14
25
|
|
|
15
|
-
But none of them do quite what
|
|
26
|
+
But none of them do quite what _BUPKIS_ does. I want an assertion library that prioritizes:
|
|
16
27
|
|
|
17
28
|
- Type safety
|
|
18
|
-
-
|
|
19
|
-
-
|
|
29
|
+
- Uncompromisable extensibility
|
|
30
|
+
- A small API surface
|
|
20
31
|
|
|
21
|
-
|
|
32
|
+
I can think of several that tick two-thirds of those boxes! But _I demand the total package_ (And You Should Too).
|
|
22
33
|
|
|
23
|
-
>
|
|
34
|
+
> ⚠️ **Caution!**
|
|
35
|
+
>
|
|
36
|
+
> Assertion libraries tend come in two flavors: chainable or stiff & traditional. But because these styles are likely _familiar_ to you, you may hate _BUPKIS_.
|
|
37
|
+
>
|
|
38
|
+
> I _want_ you to like it, yes. But if you don't, I'm content with just making my point and asking the following favor of the reader:
|
|
24
39
|
>
|
|
25
|
-
>
|
|
40
|
+
> **Do not confuse _familiarity_ with _usability_.**
|
|
26
41
|
|
|
27
|
-
|
|
42
|
+
The following is a brief overview of the design choices We made to serve these goals.
|
|
28
43
|
|
|
29
|
-
### Natural
|
|
44
|
+
### Natural Language Assertions
|
|
30
45
|
|
|
31
|
-
In
|
|
46
|
+
In _BUPKIS_, "natural language" is the means to the end of "a small API surface".
|
|
47
|
+
|
|
48
|
+
When you're using _BUPKIS_, you **don't** write this:
|
|
32
49
|
|
|
33
50
|
```js
|
|
34
51
|
expect(actual).toEqual(expected);
|
|
@@ -50,7 +67,7 @@ expect(actual, 'is equal to', expected);
|
|
|
50
67
|
expect(actual, 'to strictly equal', expected);
|
|
51
68
|
```
|
|
52
69
|
|
|
53
|
-
If
|
|
70
|
+
If another assertion library wants you to write:
|
|
54
71
|
|
|
55
72
|
```js
|
|
56
73
|
expect(actual).to.be.a('string');
|
|
@@ -60,111 +77,150 @@ Then _BUPKIS_ wants you to write:
|
|
|
60
77
|
|
|
61
78
|
```js
|
|
62
79
|
expect(actual, 'to be a string');
|
|
63
|
-
// it is tolerant of poor/ironic grammar
|
|
80
|
+
// it is tolerant of poor/ironic grammar, sometimes
|
|
64
81
|
expect(actual, 'to be an string');
|
|
65
82
|
```
|
|
66
83
|
|
|
67
|
-
Can't remember the
|
|
84
|
+
Can't remember the phrase? Did you forget a word or make a typo? Maybe you also forgot **_BUPKIS_ is type-safe?!** You'll get a nice squiggly for your trouble.
|
|
68
85
|
|
|
69
|
-
|
|
86
|
+
This isn't black magic. It ain't no _cauldron_. We're not just _throwing rat tails and `string`s into a function and stirring that shit up._
|
|
70
87
|
|
|
71
|
-
|
|
88
|
+
> "Preposterous! Codswallop!"
|
|
89
|
+
>
|
|
90
|
+
> ‒the reader and/or more sickos
|
|
72
91
|
|
|
73
|
-
|
|
74
|
-
expect(actual, 'to be', expected);
|
|
75
|
-
// did they not teach grammar in nerd school??
|
|
76
|
-
expect(actual, 'not is', expected);
|
|
77
|
-
|
|
78
|
-
expect(
|
|
79
|
-
() => throw new TypeError('aww, shucks'),
|
|
80
|
-
'to throw a',
|
|
81
|
-
TypeError,
|
|
82
|
-
'not satisfying',
|
|
83
|
-
/gol durn/,
|
|
84
|
-
);
|
|
85
|
-
```
|
|
92
|
+
You may wonder how this could this be anything _but_ loosey-goosey _senselessness_. On the contrary—we have _conventions_!
|
|
86
93
|
|
|
87
|
-
|
|
94
|
+
#### Conventions of `expect()`
|
|
88
95
|
|
|
89
|
-
|
|
96
|
+
To formalize the conventions at a high level:
|
|
90
97
|
|
|
91
|
-
|
|
98
|
+
- The first parameter to a _BUPKIS_ assertion is always the _subject_ ([def.](https://bupkis.zip/documents/Reference.Glossary_of_Terms#subject)).
|
|
92
99
|
|
|
93
|
-
|
|
100
|
+
- The "string" part of a _BUPKIS_ assertion is known as a _phrase_. Every expectation will contain _at minimum_ one (1) phrase. As you can see from the above "to be a string" example, phrases often have aliases.
|
|
94
101
|
|
|
95
|
-
|
|
102
|
+
- Assertions may have multiple phrases or parameters, but the simplest assertions always look like this:
|
|
96
103
|
|
|
97
|
-
|
|
104
|
+
```ts
|
|
105
|
+
expect(subject, 'phrase');
|
|
106
|
+
```
|
|
98
107
|
|
|
99
|
-
|
|
108
|
+
...and more complex assertions look like this:
|
|
100
109
|
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
```
|
|
110
|
+
```ts
|
|
111
|
+
expect(subject, 'phrase', [parameter?, phrase?, parameter?, ...]);
|
|
112
|
+
```
|
|
104
113
|
|
|
105
|
-
|
|
114
|
+
- One more convention worth mentioning is _negation_.
|
|
115
|
+
|
|
116
|
+
You can _negate_ just about any phrase by prepending it with `not` and a space. For example:
|
|
117
|
+
|
|
118
|
+
```js
|
|
119
|
+
expect(actual, 'to be', expected);
|
|
120
|
+
expect(actual, 'not to be', expected);
|
|
121
|
+
|
|
122
|
+
expect(
|
|
123
|
+
() => throw new TypeError('aww, shucks'),
|
|
124
|
+
'not to throw a',
|
|
125
|
+
TypeError,
|
|
126
|
+
'satisfying',
|
|
127
|
+
/gol durn/,
|
|
128
|
+
);
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Handy!
|
|
132
|
+
|
|
133
|
+
### Custom Assertions Built With Zod
|
|
134
|
+
|
|
135
|
+
[Zod][] is a popular object validation library which does some heavy lifting for _BUPKIS_—most of the built-in assertions are implemented using Zod schemas. And so _BUPKIS_ extends this capability to you.
|
|
106
136
|
|
|
107
|
-
|
|
137
|
+
An example will be illuminating. What follows is a ~~stupid~~ ~~quick~~ _stupid_ example of a creating and "registering" a basic assertion _which can be invoked using two different phrases_:
|
|
108
138
|
|
|
109
139
|
```ts
|
|
110
|
-
import {
|
|
111
|
-
|
|
112
|
-
// Basic type assertions
|
|
113
|
-
expect('hello', 'to be a string');
|
|
114
|
-
expect(42, 'to be a number');
|
|
115
|
-
expect(true, 'to be a boolean');
|
|
116
|
-
|
|
117
|
-
// Value comparisons
|
|
118
|
-
expect(10, 'to equal', 10);
|
|
119
|
-
expect('hello world', 'to contain', 'world');
|
|
120
|
-
expect([1, 2, 3], 'to have length', 3);
|
|
121
|
-
|
|
122
|
-
// Negation
|
|
123
|
-
expect(42, 'not to be a string');
|
|
124
|
-
expect('hello', 'not to equal', 'goodbye');
|
|
125
|
-
|
|
126
|
-
// Object assertions
|
|
127
|
-
const user = { name: 'Alice', age: 30 };
|
|
128
|
-
expect(user, 'to be an object');
|
|
129
|
-
expect(user, 'to have property', 'name');
|
|
130
|
-
expect(user, 'to satisfy', { name: 'Alice' });
|
|
131
|
-
```
|
|
140
|
+
import { z, use, createAssertion } from 'bupkis';
|
|
132
141
|
|
|
133
|
-
|
|
142
|
+
const stringAssertion = createAssertion(
|
|
143
|
+
z.string(),
|
|
144
|
+
[['to be based', 'to be bussin']],
|
|
145
|
+
z.string(),
|
|
146
|
+
);
|
|
134
147
|
|
|
135
|
-
|
|
148
|
+
const { expect } = use([stringAssertion]);
|
|
136
149
|
|
|
137
|
-
|
|
150
|
+
expect('chat', 'to be based');
|
|
151
|
+
expect('fam', 'to be bussin');
|
|
138
152
|
|
|
139
|
-
|
|
140
|
-
|
|
153
|
+
// did you know? includes all builtin assertions!
|
|
154
|
+
expect('skiball lavatory', 'to be a string');
|
|
155
|
+
```
|
|
141
156
|
|
|
142
|
-
>
|
|
157
|
+
> 📒 Registration?
|
|
143
158
|
>
|
|
144
|
-
>
|
|
159
|
+
> "Registration" of an assertion (though there is no stateful "registry" anywhere) is as straightforward as passing an array of `Assertion` instances (created via `createAssertion()`/`createAsyncAssertion()`) to the `use()` function.
|
|
160
|
+
>
|
|
161
|
+
> `use()`, as exported from `bupkis`, returns a new `expect()`/`expectAsync()` pair that includes your custom assertions alongside all the built-in ones. The new `expect()`/`expectAsync()` functions are fully type-safe and aware of your custom assertions. They _also_ have a `.use()` method, which allows you to compose sets of assertions from disjoint sources.
|
|
162
|
+
|
|
163
|
+
**Zod makes it extremely easy to create most custom assertions**. But despite its power, it can't do _everything_ we need an assertion to do; for those situations, there's also a [function-based API][custom-assertion-function] for use with [parametric][] and behavioral (e.g., involving function execution) assertions.
|
|
164
|
+
|
|
165
|
+
👉 For an assiduous guide on creating assertions, read [Guide: How to Create a Custom Assertion][create-a-custom-assertion].
|
|
166
|
+
|
|
167
|
+
### Excruciating Type Safety
|
|
168
|
+
|
|
169
|
+
We have tried to make _BUPKIS_ is as type-safe as possible. To be clear, _that is pretty damn possible_. This means:
|
|
170
|
+
|
|
171
|
+
- Every built-in assertion is fully type-safe and is declared as an overload for `expect()` or `expectAsync()`.
|
|
172
|
+
- Every _custom_ assertion is _also_ fully type-safe and is declared as an overload for `expect()` or `expectAsync()` (as returned from `use()`)
|
|
173
|
+
- If an assertion demands the _subject_ be of a certain type, the TS compiler will squawk if you try to use an incompatible subject type. For example, `<Map> to have size <number>` will only accept a `Map` as the subject, and this will be obvious in your editor.
|
|
174
|
+
|
|
175
|
+
> _Note_: `expect()` is not and cannot be a type guard; see the ["Caveats" Reference doc](http://bupkis.zip/documents/Reference.Caveats#expect-is-not-a-type-guard) for more information.
|
|
176
|
+
|
|
177
|
+
## Prerequisites
|
|
145
178
|
|
|
146
|
-
|
|
179
|
+
**Node.js**: ^20.19.0, ^22.12.0, >=23
|
|
147
180
|
|
|
148
|
-
|
|
181
|
+
_BUPKIS_ has a peer dependency on [Zod][] v4+, but will install it as an optional dependency if you are not already using it.
|
|
149
182
|
|
|
150
|
-
|
|
183
|
+
_BUPKIS_ ships as a dual CJS/ESM package.
|
|
151
184
|
|
|
152
|
-
|
|
185
|
+
> Disclaimer: _BUPKIS_ has been designed to run on Node.js in a development environment. Anyone attempting to deploy _BUPKIS_ to some server somewhere will get what is coming to them.
|
|
186
|
+
|
|
187
|
+
## Installation
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
npm install bupkis -D
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Usage
|
|
194
|
+
|
|
195
|
+
👉 See the [Basic Usage Guide](https://bupkis.zip/documents/guides.basic_usage) for a quick introduction.
|
|
196
|
+
|
|
197
|
+
📖 Visit [https://bupkis.zip](https://bupkis.zip) for comprehensive guides and reference.
|
|
198
|
+
|
|
199
|
+
## Acknowledgements
|
|
153
200
|
|
|
154
201
|
- [Unexpected][] is the main inspiration for _BUPKIS_. However, creating types for this library is exceedingly difficult (and was in fact the first thing I tried). Despite that drawback, I find it more usable than any other assertion library I've tried.
|
|
155
|
-
- [Zod][] is a popular object validation library which
|
|
156
|
-
- [fast-check][]:
|
|
202
|
+
- [Zod][] is a popular object validation library upon which _BUPKIS_ builds many of its own assertions.
|
|
203
|
+
- [fast-check][]: Thanks to Nicholas Dubien for this library. There is **no better library** for an assertion library to use to test itself! Well, besides itself, I mean. How about _in addition to_ itself? Yes. Thank you!
|
|
204
|
+
- [tshy][] from Isaac Schlueter. Thanks for making dual ESM/CJS packages easy and not too fancy.
|
|
205
|
+
- [TypeDoc][] it really documents the hell out of TypeScript projects.
|
|
206
|
+
- [@cjihrig](https://github.com/cjihrig) and other Node.js contributors for the thoughtfulness put into [`node:test`](https://nodejs.org/api/test.html) that make it my current test-runner-of-choice.
|
|
157
207
|
|
|
158
|
-
##
|
|
208
|
+
## Why is it called _BUPKIS_?
|
|
159
209
|
|
|
160
|
-
|
|
161
|
-
>
|
|
162
|
-
> ‒boneskull, 2025
|
|
210
|
+
TODO: think of good reason and fill in later
|
|
163
211
|
|
|
164
212
|
## License
|
|
165
213
|
|
|
166
214
|
Copyright © 2025 Christopher Hiller. Licensed under [BlueOak-1.0.0](https://blueoakcouncil.org/license/1.0.0).
|
|
167
215
|
|
|
168
216
|
[zod]: https://zod.dev
|
|
217
|
+
[docs]: https://bupkis.zip
|
|
218
|
+
[basic-usage]: https://bupkis.zip/documents/guides.basic_usage
|
|
169
219
|
[unexpected]: https://unexpected.js.org
|
|
170
220
|
[fast-check]: https://fast-check.dev
|
|
221
|
+
[parametric]: https://bupkis.zip/documents/Reference.Glossary_of_Terms#parametric-assertion
|
|
222
|
+
[custom-assertion-function]: https://bupkis.zip/documents/guides.how_to_create_a_custom_assertion#using-a-function
|
|
223
|
+
[create-a-custom-assertion]: https://bupkis.zip/documents/Guides.How_to_Create_a_Custom_Assertion
|
|
224
|
+
[assertion-reference]: https://bupkis.zip/documents/reference.assertions
|
|
225
|
+
[tshy]: https://github.com/isaacs/tshy
|
|
226
|
+
[typedoc]: https://typedoc.org
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bupkis",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "",
|
|
5
|
+
"description": "Uncommonly extensible assertions for the beautiful people",
|
|
6
6
|
"repository": {
|
|
7
7
|
"url": "git+https://github.com/boneskull/bupkis.git"
|
|
8
8
|
},
|
|
9
|
+
"homepage": "https://bupkis.zip",
|
|
9
10
|
"author": {
|
|
10
11
|
"name": "Christopher Hiller",
|
|
11
12
|
"email": "boneskull@boneskull.com"
|
|
@@ -60,9 +61,11 @@
|
|
|
60
61
|
"build:docs:watch": "npm run --silent build:docs -- --watch",
|
|
61
62
|
"dev": "tshy --watch",
|
|
62
63
|
"dev:docs": "run-p build:docs:watch serve",
|
|
63
|
-
"lint": "eslint
|
|
64
|
+
"lint": "run-p lint:eslint lint:types lint:knip",
|
|
64
65
|
"lint:commit": "commitlint",
|
|
65
|
-
"lint:
|
|
66
|
+
"lint:eslint": "eslint .",
|
|
67
|
+
"lint:fix": "run-s \"lint:eslint -- --fix\"",
|
|
68
|
+
"lint:knip": "knip",
|
|
66
69
|
"lint:staged": "lint-staged",
|
|
67
70
|
"lint:types": "tsc -b .config/tsconfig.eslint.json",
|
|
68
71
|
"lint:types:dev": "npm run --silent lint:types -- --watch",
|
|
@@ -86,19 +89,19 @@
|
|
|
86
89
|
"devDependencies": {
|
|
87
90
|
"@commitlint/cli": "19.8.1",
|
|
88
91
|
"@commitlint/config-conventional": "19.8.1",
|
|
89
|
-
"@eslint/js": "9.
|
|
90
|
-
"@stylistic/eslint-plugin": "5.
|
|
91
|
-
"@types/node": "22.
|
|
92
|
+
"@eslint/js": "9.34.0",
|
|
93
|
+
"@stylistic/eslint-plugin": "5.3.1",
|
|
94
|
+
"@types/node": "22.18.1",
|
|
92
95
|
"@types/slug": "5.0.9",
|
|
93
96
|
"@types/wallabyjs": "0.0.15",
|
|
94
|
-
"eslint": "9.
|
|
97
|
+
"eslint": "9.34.0",
|
|
95
98
|
"eslint-plugin-jsonc": "2.20.1",
|
|
96
99
|
"eslint-plugin-perfectionist": "4.15.0",
|
|
97
100
|
"expect-type": "1.2.2",
|
|
98
|
-
"fast-check": "4.
|
|
101
|
+
"fast-check": "4.3.0",
|
|
99
102
|
"husky": "9.1.7",
|
|
100
|
-
"knip": "5.
|
|
101
|
-
"lint-staged": "16.1.
|
|
103
|
+
"knip": "5.63.1",
|
|
104
|
+
"lint-staged": "16.1.6",
|
|
102
105
|
"npm-run-all2": "8.0.4",
|
|
103
106
|
"prettier": "3.6.2",
|
|
104
107
|
"prettier-plugin-jsdoc": "1.3.3",
|
|
@@ -109,11 +112,10 @@
|
|
|
109
112
|
"tsx": "4.20.5",
|
|
110
113
|
"type-fest": "4.41.0",
|
|
111
114
|
"typedoc": "0.28.12",
|
|
112
|
-
"typedoc-github-theme": "0.3.1",
|
|
113
115
|
"typedoc-plugin-mdn-links": "5.0.9",
|
|
114
116
|
"typedoc-plugin-zod": "1.4.2",
|
|
115
117
|
"typescript": "5.9.2",
|
|
116
|
-
"typescript-eslint": "8.
|
|
118
|
+
"typescript-eslint": "8.42.0"
|
|
117
119
|
},
|
|
118
120
|
"publishConfig": {
|
|
119
121
|
"access": "public",
|
|
@@ -121,13 +123,13 @@
|
|
|
121
123
|
},
|
|
122
124
|
"knip": {
|
|
123
125
|
"ignoreDependencies": [
|
|
124
|
-
"@types/wallabyjs"
|
|
125
|
-
"serve"
|
|
126
|
+
"@types/wallabyjs"
|
|
126
127
|
],
|
|
127
128
|
"ignore": [
|
|
128
129
|
".wallaby.js",
|
|
129
130
|
"**/*.cts",
|
|
130
|
-
"**/*.d.ts"
|
|
131
|
+
"**/*.d.ts",
|
|
132
|
+
"assets/**/*"
|
|
131
133
|
],
|
|
132
134
|
"tags": [
|
|
133
135
|
"-knipignore"
|
package/src/bootstrap.ts
CHANGED
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
* @returns Object containing `expect` and `expectAsync` functions
|
|
25
25
|
* @internal
|
|
26
26
|
*/
|
|
27
|
-
|
|
27
|
+
const bootstrap = (): {
|
|
28
28
|
expect: Expect<typeof SyncAssertions>;
|
|
29
29
|
expectAsync: ExpectAsync<typeof AsyncAssertions>;
|
|
30
30
|
} => {
|
package/src/expect.ts
CHANGED
|
@@ -225,7 +225,7 @@ const execute = <
|
|
|
225
225
|
* @param stackStartFn - Function for stack trace management
|
|
226
226
|
* @param isNegated - Whether the assertion should be negated
|
|
227
227
|
*/
|
|
228
|
-
|
|
228
|
+
const executeAsync = async <
|
|
229
229
|
T extends AssertionAsync<Parts, AssertionImplAsync<Parts>, Slots>,
|
|
230
230
|
Parts extends AssertionParts,
|
|
231
231
|
Slots extends AssertionSlots<Parts>,
|
package/src/types.ts
CHANGED
|
@@ -147,13 +147,19 @@ export type MutableOrReadonly<T> = T extends readonly (infer U)[]
|
|
|
147
147
|
*/
|
|
148
148
|
export type Negation<T extends string> = `not ${T}`;
|
|
149
149
|
|
|
150
|
-
export
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
150
|
+
export interface UseFn<
|
|
151
|
+
T extends AnySyncAssertions,
|
|
152
|
+
U extends AnyAsyncAssertions,
|
|
153
|
+
> {
|
|
154
|
+
<
|
|
155
|
+
V extends readonly AnyAssertion[],
|
|
156
|
+
W extends FilterSyncAssertions<V>,
|
|
157
|
+
X extends FilterAsyncAssertions<V>,
|
|
158
|
+
>(
|
|
159
|
+
assertions: V,
|
|
160
|
+
): {
|
|
161
|
+
expect: Expect<Concat<T, W>, Concat<U, X>>;
|
|
162
|
+
expectAsync: ExpectAsync<Concat<U, X>, Concat<T, W>>;
|
|
163
|
+
use: UseFn<Concat<T, W>, Concat<U, X>>;
|
|
164
|
+
};
|
|
165
|
+
}
|