Skip to content

Commit 701e15c

Browse files
authored
feat(2.1.0): match, keyword configs, discrimination improvements (#1314)
1 parent 2b86e83 commit 701e15c

File tree

133 files changed

+5517
-2051
lines changed

Some content is hidden

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

133 files changed

+5517
-2051
lines changed

.npmrc

Lines changed: 0 additions & 1 deletion
This file was deleted.

ark/attest/CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
# @ark/attest
22

3+
NOTE: This changelog is incomplete, but will include notable attest-specific changes (many updates consist almost entirely of bumped `arktype` versions for assertions).
4+
5+
## 0.42.0
6+
7+
### Bail early for obviously incorrect `equals` comparisons
8+
9+
This is the short-term solution to #1287, where some comparisons with Node's `deepStrictEqual` and object with recursive properties like Type resulted in OOM crashes.
10+
11+
We will eventually add new string-diffing logic, but for now we just make some shallow comparisons between constructors and types to avoid common problematic comparisons, e.g. between Type instances:
12+
13+
```ts
14+
// previously resulted in OOM exception, now shallowly fails with simple error
15+
attest(type.string).equals(type.boolean)
16+
```
17+
318
## 0.11.0
419

520
- Fix a bug causing certain serialized types with backticks and template literals to be incorrectly formatted on inline snapshot

ark/attest/__tests__/assertions.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { attest } from "@ark/attest"
2+
import { type } from "arktype"
23
import * as assert from "node:assert/strict"
34

45
const o = { ark: "type" }
@@ -163,4 +164,20 @@ describe("type assertions", () => {
163164
"specific"
164165
)
165166
})
167+
168+
it("does not boom on Type comparison", () => {
169+
// @ts-expect-error
170+
attest(() => attest(type.string).equals(type.number)).throws
171+
.snap(`AssertionError [ERR_ASSERTION]: Assertion including at least one function or object was not between reference eqaul items
172+
Expected: number
173+
Actual: string`)
174+
})
175+
176+
it("doesn't boom on ArkErrors vs plain object", () => {
177+
attest(() => attest(type({ a: "string" })({ a: 5 })).equals({ a: "five" }))
178+
.throws
179+
.snap(`AssertionError [ERR_ASSERTION]: Objects did not have the same constructor:
180+
Expected: {"a":"five"}
181+
Actual: ArkErrors`)
182+
})
166183
})

ark/attest/__tests__/instantiations.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { it } from "mocha"
44

55
contextualize(() => {
66
it("inline", () => {
7-
attest.instantiations([7574, "instantiations"])
7+
attest.instantiations([23731, "instantiations"])
88
return type({
99
kind: "'admin'",
1010
"powers?": "string[]"

ark/attest/assert/assertions.ts

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -80,21 +80,47 @@ export const versionableAssertion =
8080
const unversionedAssertEquals: AssertFn = (expected, actual, ctx) => {
8181
if (expected === actual) return
8282

83-
if (typeof expected === "object" && typeof actual === "object") {
84-
try {
85-
assert.deepStrictEqual(actual, expected)
86-
} catch (e: any) {
87-
e.stack = ctx.assertionStack
88-
throw e
89-
}
90-
} else {
83+
try {
84+
if (
85+
typeof expected === "object" &&
86+
expected !== null &&
87+
typeof actual === "object" &&
88+
actual !== null
89+
) {
90+
if (expected.constructor === actual.constructor)
91+
assert.deepStrictEqual(actual, expected)
92+
else {
93+
const serializedExpected = printable(expected)
94+
const serializedActual = printable(actual)
95+
throw new assert.AssertionError({
96+
message: `Objects did not have the same constructor:
97+
Expected: ${serializedExpected}
98+
Actual: ${serializedActual}`,
99+
expected: serializedExpected,
100+
actual: serializedActual
101+
})
102+
}
103+
} else if (
104+
typeof expected === "object" ||
105+
typeof expected === "function" ||
106+
typeof actual === "function" ||
107+
typeof actual === "function"
108+
) {
109+
const serializedExpected = printable(expected)
110+
const serializedActual = printable(actual)
111+
throw new assert.AssertionError({
112+
message: `Assertion including at least one function or object was not between reference eqaul items
113+
Expected: ${serializedExpected}
114+
Actual: ${serializedActual}`,
115+
expected: serializedExpected,
116+
actual: serializedActual
117+
})
118+
// guaranteed to be two primitives at this point
119+
} else assert.equal(actual, expected)
120+
} catch (e: any) {
91121
// some nonsense to get a good stack trace
92-
try {
93-
assert.strictEqual(actual, expected)
94-
} catch (e: any) {
95-
e.stack = ctx.assertionStack
96-
throw e
97-
}
122+
e.stack = ctx.assertionStack
123+
throw e
98124
}
99125
}
100126

ark/attest/bench/baseline.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export const queueBaselineUpdateIfNeeded = (
3939
baselinePath: ctx.qualifiedPath
4040
})
4141

42-
if (ctx.lastSnapFunctionName === "types") writeSnapshotUpdatesOnExit()
42+
if (ctx.benchCallPosition) writeSnapshotUpdatesOnExit()
4343
}
4444

4545
/** Pretty print comparison and set the process.exitCode to 1 if delta threshold is exceeded */
@@ -66,7 +66,14 @@ export const compareToBaseline = (
6666
const handlePositiveDelta = (formattedDelta: string, ctx: BenchContext) => {
6767
const message = `'${ctx.qualifiedName}' exceeded baseline by ${formattedDelta} (threshold is ${ctx.cfg.benchPercentThreshold}%).`
6868
console.error(`📈 ${message}`)
69-
if (ctx.cfg.benchErrorOnThresholdExceeded) {
69+
const benchErrorConfig = ctx.cfg.benchErrorOnThresholdExceeded
70+
const isTypeBench = ctx.lastSnapFunctionName === "instantiations"
71+
const shouldError =
72+
benchErrorConfig === true ||
73+
(isTypeBench ?
74+
benchErrorConfig === "types"
75+
: benchErrorConfig === "runtime")
76+
if (shouldError) {
7077
const errorSummary = `❌ ${message}`
7178
if (ctx.lastSnapFunctionName === "instantiations")
7279
throwAssertionError({ stack: ctx.assertionStack, message: errorSummary })

ark/attest/config.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import {
1616

1717
export type TsVersionAliases = autocomplete<"*"> | string[]
1818

19+
export type BenchErrorConfig = "runtime" | "types" | boolean
20+
1921
type BaseAttestConfig = {
2022
tsconfig: string | null | undefined
2123
compilerOptions: ts.CompilerOptions
@@ -38,7 +40,7 @@ type BaseAttestConfig = {
3840
skipInlineInstantiations: boolean
3941
attestAliases: string[]
4042
benchPercentThreshold: number
41-
benchErrorOnThresholdExceeded: boolean
43+
benchErrorOnThresholdExceeded: BenchErrorConfig
4244
filter: string | undefined
4345
testDeclarationAliases: string[]
4446
formatCmd: string

ark/attest/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ark/attest",
3-
"version": "0.41.2",
3+
"version": "0.41.3",
44
"license": "MIT",
55
"author": {
66
"name": "David Blass",

ark/dark/arkdark.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
}
5353
},
5454
{
55-
"name": "this, primitives, built-in types, quotes",
55+
"name": "this, primitives, builtin types, quotes",
5656
"scope": [
5757
"variable.language",
5858
"constant",

ark/dark/arkdarkItalic.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
}
6363
},
6464
{
65-
"name": "this, primitives, built-in types, quotes",
65+
"name": "this, primitives, builtin types, quotes",
6666
"scope": [
6767
"variable.language",
6868
"constant",

0 commit comments

Comments
 (0)