ai-tests 2.0.1
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/.turbo/turbo-build.log +5 -0
- package/CHANGELOG.md +3 -0
- package/README.md +214 -0
- package/dist/assertions.d.ts +132 -0
- package/dist/assertions.d.ts.map +1 -0
- package/dist/assertions.js +384 -0
- package/dist/assertions.js.map +1 -0
- package/dist/cli.d.ts +13 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +77 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/local.d.ts +31 -0
- package/dist/local.d.ts.map +1 -0
- package/dist/local.js +63 -0
- package/dist/local.js.map +1 -0
- package/dist/runner.d.ts +68 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +215 -0
- package/dist/runner.js.map +1 -0
- package/dist/types.d.ts +62 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/worker.d.ts +55 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +92 -0
- package/dist/worker.js.map +1 -0
- package/package.json +58 -0
- package/src/assertions.ts +465 -0
- package/src/cli.ts +87 -0
- package/src/index.ts +33 -0
- package/src/local.ts +76 -0
- package/src/runner.ts +238 -0
- package/src/types.ts +68 -0
- package/src/worker.ts +112 -0
- package/test/assertions.test.ts +607 -0
- package/test/index.test.ts +51 -0
- package/test/local.test.ts +31 -0
- package/test/runner.test.ts +379 -0
- package/test/worker.test.ts +198 -0
- package/tsconfig.json +23 -0
- package/vitest.config.ts +11 -0
- package/wrangler.toml +6 -0
package/CHANGELOG.md
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# ai-tests
|
|
2
|
+
|
|
3
|
+
Test utilities via RPC. Run tests anywhere—Workers, sandboxes, or locally.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
import { expect, createRunner } from 'ai-tests'
|
|
7
|
+
|
|
8
|
+
const runner = createRunner()
|
|
9
|
+
|
|
10
|
+
runner.describe('math', () => {
|
|
11
|
+
runner.it('adds numbers', () => {
|
|
12
|
+
expect(1 + 1).to.equal(2)
|
|
13
|
+
})
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
const results = await runner.run()
|
|
17
|
+
// { total: 1, passed: 1, failed: 0 }
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pnpm add ai-tests
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Why RPC?
|
|
27
|
+
|
|
28
|
+
Traditional test frameworks assume local execution. `ai-tests` extends testing to distributed environments:
|
|
29
|
+
|
|
30
|
+
- **Cloudflare Workers** — Deploy as a Worker and call tests via RPC
|
|
31
|
+
- **ai-sandbox** — Run tests in isolated sandboxes with AI-generated code
|
|
32
|
+
- **Miniflare** — Local development with Workers RPC
|
|
33
|
+
|
|
34
|
+
## Assertions
|
|
35
|
+
|
|
36
|
+
Chai-compatible assertions with both BDD and Vitest-style APIs:
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import { expect, assert, should } from 'ai-tests'
|
|
40
|
+
|
|
41
|
+
// BDD style (expect/should)
|
|
42
|
+
expect(result).to.equal(42)
|
|
43
|
+
expect(array).to.have.length(3)
|
|
44
|
+
expect(obj).to.deep.equal({ name: 'test' })
|
|
45
|
+
expect(value).to.be.ok
|
|
46
|
+
|
|
47
|
+
// Vitest-compatible
|
|
48
|
+
expect(result).toBe(42)
|
|
49
|
+
expect(array).toHaveLength(3)
|
|
50
|
+
expect(obj).toEqual({ name: 'test' })
|
|
51
|
+
expect(value).toBeTruthy()
|
|
52
|
+
|
|
53
|
+
// TDD style (assert)
|
|
54
|
+
assert.equal(result, 42)
|
|
55
|
+
assert.lengthOf(array, 3)
|
|
56
|
+
assert.deepEqual(obj, { name: 'test' })
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Test Runner
|
|
60
|
+
|
|
61
|
+
Full test runner with suites, hooks, and result aggregation:
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { createRunner } from 'ai-tests'
|
|
65
|
+
|
|
66
|
+
const runner = createRunner()
|
|
67
|
+
|
|
68
|
+
runner.describe('user service', () => {
|
|
69
|
+
runner.beforeEach(() => {
|
|
70
|
+
// Setup before each test
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
runner.afterEach(() => {
|
|
74
|
+
// Cleanup after each test
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
runner.it('creates users', async () => {
|
|
78
|
+
const user = await createUser({ name: 'Alice' })
|
|
79
|
+
expect(user.id).to.exist
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
runner.it('validates email', () => {
|
|
83
|
+
expect(() => createUser({ email: 'invalid' })).to.throw()
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
runner.skip('pending feature', () => {
|
|
87
|
+
// This test is skipped
|
|
88
|
+
})
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
const results = await runner.run()
|
|
92
|
+
console.log(`${results.passed}/${results.total} tests passed`)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Hooks
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
runner.beforeAll(() => { /* once before all tests */ })
|
|
99
|
+
runner.beforeEach(() => { /* before each test */ })
|
|
100
|
+
runner.afterEach(() => { /* after each test */ })
|
|
101
|
+
runner.afterAll(() => { /* once after all tests */ })
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Focus and Skip
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
runner.only('focus on this', () => { /* only this runs */ })
|
|
108
|
+
runner.skip('skip this', () => { /* skipped */ })
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Worker Deployment
|
|
112
|
+
|
|
113
|
+
Deploy as a Cloudflare Worker for remote test execution:
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
// worker.ts
|
|
117
|
+
export { default } from 'ai-tests'
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
```toml
|
|
121
|
+
# wrangler.toml
|
|
122
|
+
name = "test-worker"
|
|
123
|
+
main = "worker.ts"
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Call from other workers via RPC:
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
// In ai-sandbox or another worker
|
|
130
|
+
const results = await env.TEST.run(testCode)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Assertion Chain Reference
|
|
134
|
+
|
|
135
|
+
### Flags
|
|
136
|
+
- `.not` — Negate the assertion
|
|
137
|
+
- `.deep` — Deep equality
|
|
138
|
+
- `.nested` — Nested property access
|
|
139
|
+
- `.own` — Own properties only
|
|
140
|
+
- `.ordered` — Ordered array matching
|
|
141
|
+
- `.any` / `.all` — Member quantifiers
|
|
142
|
+
|
|
143
|
+
### Value Checks
|
|
144
|
+
- `.equal(val)` / `.eq()` — Strict equality
|
|
145
|
+
- `.eql(val)` — Deep equality
|
|
146
|
+
- `.above(n)` / `.gt()` — Greater than
|
|
147
|
+
- `.below(n)` / `.lt()` — Less than
|
|
148
|
+
- `.within(min, max)` — Range check
|
|
149
|
+
- `.closeTo(n, delta)` — Approximate equality
|
|
150
|
+
|
|
151
|
+
### Type Checks
|
|
152
|
+
- `.ok` — Truthy
|
|
153
|
+
- `.true` / `.false` — Boolean
|
|
154
|
+
- `.null` / `.undefined` — Nullish
|
|
155
|
+
- `.NaN` — Not a number
|
|
156
|
+
- `.a(type)` / `.an()` — Type check
|
|
157
|
+
|
|
158
|
+
### Property Checks
|
|
159
|
+
- `.property(name)` — Has property
|
|
160
|
+
- `.lengthOf(n)` — Length check
|
|
161
|
+
- `.keys(...keys)` — Has keys
|
|
162
|
+
- `.include(val)` — Contains value
|
|
163
|
+
- `.members(arr)` — Array members
|
|
164
|
+
|
|
165
|
+
### Vitest Compatibility
|
|
166
|
+
- `.toBe()` — Strict equality
|
|
167
|
+
- `.toEqual()` — Deep equality
|
|
168
|
+
- `.toBeTruthy()` / `.toBeFalsy()`
|
|
169
|
+
- `.toBeNull()` / `.toBeUndefined()`
|
|
170
|
+
- `.toContain()` — Contains
|
|
171
|
+
- `.toHaveLength()` — Length
|
|
172
|
+
- `.toHaveProperty()` — Property
|
|
173
|
+
- `.toMatch()` — Regex/string match
|
|
174
|
+
- `.toThrow()` — Throws error
|
|
175
|
+
- `.toBeGreaterThan()` / `.toBeLessThan()`
|
|
176
|
+
- `.toBeInstanceOf()` — Instance check
|
|
177
|
+
|
|
178
|
+
## API Reference
|
|
179
|
+
|
|
180
|
+
| Export | Description |
|
|
181
|
+
|--------|-------------|
|
|
182
|
+
| `expect(value)` | BDD-style assertion |
|
|
183
|
+
| `should(value)` | Should-style assertion |
|
|
184
|
+
| `assert` | TDD-style assertions |
|
|
185
|
+
| `Assertion` | Assertion class (RpcTarget) |
|
|
186
|
+
| `createRunner()` | Create test runner |
|
|
187
|
+
| `TestRunner` | Test runner class |
|
|
188
|
+
| `TestService` | Worker entrypoint |
|
|
189
|
+
|
|
190
|
+
## Types
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
interface TestResult {
|
|
194
|
+
name: string
|
|
195
|
+
passed: boolean
|
|
196
|
+
skipped?: boolean
|
|
197
|
+
error?: string
|
|
198
|
+
duration: number
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
interface TestResults {
|
|
202
|
+
total: number
|
|
203
|
+
passed: number
|
|
204
|
+
failed: number
|
|
205
|
+
skipped: number
|
|
206
|
+
tests: TestResult[]
|
|
207
|
+
duration: number
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Related Packages
|
|
212
|
+
|
|
213
|
+
- [`ai-sandbox`](../ai-sandbox) — Sandboxed code execution with test integration
|
|
214
|
+
- [`ai-functions`](../ai-functions) — AI-powered test generation
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assertion utilities powered by Chai
|
|
3
|
+
*
|
|
4
|
+
* Exposes expect, should, and assert APIs via RPC.
|
|
5
|
+
* Uses Chai under the hood for battle-tested assertions.
|
|
6
|
+
*/
|
|
7
|
+
import { RpcTarget } from 'cloudflare:workers';
|
|
8
|
+
/**
|
|
9
|
+
* Wrapper around Chai's expect that extends RpcTarget
|
|
10
|
+
* This allows the assertion chain to work over RPC with promise pipelining
|
|
11
|
+
*/
|
|
12
|
+
export declare class Assertion extends RpcTarget {
|
|
13
|
+
private assertion;
|
|
14
|
+
constructor(value: unknown, message?: string);
|
|
15
|
+
get to(): this;
|
|
16
|
+
get be(): this;
|
|
17
|
+
get been(): this;
|
|
18
|
+
get is(): this;
|
|
19
|
+
get that(): this;
|
|
20
|
+
get which(): this;
|
|
21
|
+
get and(): this;
|
|
22
|
+
get has(): this;
|
|
23
|
+
get have(): this;
|
|
24
|
+
get with(): this;
|
|
25
|
+
get at(): this;
|
|
26
|
+
get of(): this;
|
|
27
|
+
get same(): this;
|
|
28
|
+
get but(): this;
|
|
29
|
+
get does(): this;
|
|
30
|
+
get still(): this;
|
|
31
|
+
get also(): this;
|
|
32
|
+
get not(): Assertion;
|
|
33
|
+
get deep(): Assertion;
|
|
34
|
+
get nested(): Assertion;
|
|
35
|
+
get own(): Assertion;
|
|
36
|
+
get ordered(): Assertion;
|
|
37
|
+
get any(): Assertion;
|
|
38
|
+
get all(): Assertion;
|
|
39
|
+
get length(): Assertion;
|
|
40
|
+
get ok(): this;
|
|
41
|
+
get true(): this;
|
|
42
|
+
get false(): this;
|
|
43
|
+
get null(): this;
|
|
44
|
+
get undefined(): this;
|
|
45
|
+
get NaN(): this;
|
|
46
|
+
get exist(): this;
|
|
47
|
+
get empty(): this;
|
|
48
|
+
get arguments(): this;
|
|
49
|
+
equal(value: unknown, message?: string): this;
|
|
50
|
+
equals(value: unknown, message?: string): this;
|
|
51
|
+
eq(value: unknown, message?: string): this;
|
|
52
|
+
eql(value: unknown, message?: string): this;
|
|
53
|
+
eqls(value: unknown, message?: string): this;
|
|
54
|
+
above(value: number, message?: string): this;
|
|
55
|
+
gt(value: number, message?: string): this;
|
|
56
|
+
greaterThan(value: number, message?: string): this;
|
|
57
|
+
least(value: number, message?: string): this;
|
|
58
|
+
gte(value: number, message?: string): this;
|
|
59
|
+
greaterThanOrEqual(value: number, message?: string): this;
|
|
60
|
+
below(value: number, message?: string): this;
|
|
61
|
+
lt(value: number, message?: string): this;
|
|
62
|
+
lessThan(value: number, message?: string): this;
|
|
63
|
+
most(value: number, message?: string): this;
|
|
64
|
+
lte(value: number, message?: string): this;
|
|
65
|
+
lessThanOrEqual(value: number, message?: string): this;
|
|
66
|
+
within(start: number, finish: number, message?: string): this;
|
|
67
|
+
instanceof(constructor: unknown, message?: string): this;
|
|
68
|
+
instanceOf(constructor: unknown, message?: string): this;
|
|
69
|
+
property(name: string, value?: unknown, message?: string): this;
|
|
70
|
+
ownProperty(name: string, message?: string): this;
|
|
71
|
+
haveOwnProperty(name: string, message?: string): this;
|
|
72
|
+
ownPropertyDescriptor(name: string, descriptor?: PropertyDescriptor, message?: string): this;
|
|
73
|
+
lengthOf(n: number, message?: string): this;
|
|
74
|
+
match(re: RegExp, message?: string): this;
|
|
75
|
+
matches(re: RegExp, message?: string): this;
|
|
76
|
+
string(str: string, message?: string): this;
|
|
77
|
+
keys(...keys: string[]): this;
|
|
78
|
+
key(...keys: string[]): this;
|
|
79
|
+
throw(errorLike?: unknown, errMsgMatcher?: string | RegExp, message?: string): this;
|
|
80
|
+
throws(errorLike?: unknown, errMsgMatcher?: string | RegExp, message?: string): this;
|
|
81
|
+
Throw(errorLike?: unknown, errMsgMatcher?: string | RegExp, message?: string): this;
|
|
82
|
+
respondTo(method: string, message?: string): this;
|
|
83
|
+
respondsTo(method: string, message?: string): this;
|
|
84
|
+
satisfy(matcher: (val: unknown) => boolean, message?: string): this;
|
|
85
|
+
satisfies(matcher: (val: unknown) => boolean, message?: string): this;
|
|
86
|
+
closeTo(expected: number, delta: number, message?: string): this;
|
|
87
|
+
approximately(expected: number, delta: number, message?: string): this;
|
|
88
|
+
members(set: unknown[], message?: string): this;
|
|
89
|
+
oneOf(list: unknown[], message?: string): this;
|
|
90
|
+
include(value: unknown, message?: string): this;
|
|
91
|
+
includes(value: unknown, message?: string): this;
|
|
92
|
+
contain(value: unknown, message?: string): this;
|
|
93
|
+
contains(value: unknown, message?: string): this;
|
|
94
|
+
a(type: string, message?: string): this;
|
|
95
|
+
an(type: string, message?: string): this;
|
|
96
|
+
toBe(value: unknown): this;
|
|
97
|
+
toEqual(value: unknown): this;
|
|
98
|
+
toStrictEqual(value: unknown): this;
|
|
99
|
+
toBeTruthy(): this;
|
|
100
|
+
toBeFalsy(): this;
|
|
101
|
+
toBeNull(): this;
|
|
102
|
+
toBeUndefined(): this;
|
|
103
|
+
toBeDefined(): this;
|
|
104
|
+
toBeNaN(): this;
|
|
105
|
+
toContain(value: unknown): this;
|
|
106
|
+
toHaveLength(length: number): this;
|
|
107
|
+
toHaveProperty(path: string, value?: unknown): this;
|
|
108
|
+
toMatch(pattern: RegExp | string): this;
|
|
109
|
+
toMatchObject(obj: object): this;
|
|
110
|
+
toThrow(expected?: string | RegExp | Error): this;
|
|
111
|
+
toBeGreaterThan(n: number): this;
|
|
112
|
+
toBeLessThan(n: number): this;
|
|
113
|
+
toBeGreaterThanOrEqual(n: number): this;
|
|
114
|
+
toBeLessThanOrEqual(n: number): this;
|
|
115
|
+
toBeCloseTo(n: number, digits?: number): this;
|
|
116
|
+
toBeInstanceOf(cls: unknown): this;
|
|
117
|
+
toBeTypeOf(type: string): this;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Assert API - TDD style assertions
|
|
121
|
+
*/
|
|
122
|
+
export declare const assert: Chai.AssertStatic;
|
|
123
|
+
/**
|
|
124
|
+
* Create an expect assertion
|
|
125
|
+
*/
|
|
126
|
+
export declare function expect(value: unknown, message?: string): Assertion;
|
|
127
|
+
/**
|
|
128
|
+
* Create a should-style assertion
|
|
129
|
+
* Since we can't modify Object.prototype over RPC, this takes a value
|
|
130
|
+
*/
|
|
131
|
+
export declare function should(value: unknown): Assertion;
|
|
132
|
+
//# sourceMappingURL=assertions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assertions.d.ts","sourceRoot":"","sources":["../src/assertions.ts"],"names":[],"mappings":"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"}
|