@klondikemarlen/expect-http-response 1.0.0 → 1.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/README.md +46 -6
- package/index.d.mts +15 -0
- package/index.mjs +26 -6
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,44 @@
|
|
|
1
1
|
# @klondikemarlen/expect-http-response
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Readable HTTP response failures for Jest and Vitest: focused status errors and contextual body diffs, without unrelated transport internals. One `expect` describes the status and complete body. This dependency-free ESM matcher is registered explicitly with your existing test runner.
|
|
4
|
+
|
|
5
|
+
## Why This Matcher Exists
|
|
6
|
+
|
|
7
|
+
The goal is readable failures, not satisfying an assertion-count quota. Separate status and body assertions are a useful baseline:
|
|
8
|
+
|
|
9
|
+
```js
|
|
10
|
+
expect(response.status).toEqual(200)
|
|
11
|
+
expect(response.body).toEqual(expectedBody)
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Those assertions keep an incorrect status obvious and give the body its own native diff. A stock matcher can express the combined contract too:
|
|
15
|
+
|
|
16
|
+
```js
|
|
17
|
+
expect(response).toEqual(expect.objectContaining({ status: 200, body: expectedBody }))
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
However, a failure against the whole Supertest response can include unrelated headers, request metadata, and raw response text. `toMatchObject` is not an equivalent complete-body replacement: its partial matching can accept unexpected body fields.
|
|
21
|
+
|
|
22
|
+
`toHaveHttpResponse` keeps the focused diagnostics of the two-expect approach while naming one HTTP response contract:
|
|
23
|
+
|
|
24
|
+
```js
|
|
25
|
+
expect(response).toHaveHttpResponse(200, expectedBody)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
- A status-only failure reports the differing statuses without printing the matching body.
|
|
29
|
+
- A body failure uses the active runner's contextual diff, exposing changed nested values rather than dumping both collections or hiding them as `[Object]`.
|
|
30
|
+
- If both differ, both failures are reported; separate assertions normally stop at the first failed status assertion.
|
|
31
|
+
- Failed negation explains that status and body both matched without printing the matching payload twice.
|
|
32
|
+
|
|
33
|
+
For example, a changed field among 100 response records remains visible in the diff (excerpt):
|
|
34
|
+
|
|
35
|
+
```diff
|
|
36
|
+
"id": 50,
|
|
37
|
+
- "name": "Expected record 50",
|
|
38
|
+
+ "name": "Record 50",
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
This changes the diagnostic boundary, not the equality policy. Complete-body comparison, deliberate asymmetric matches, and the runner's custom equality testers retain their existing meaning.
|
|
4
42
|
|
|
5
43
|
## Installation
|
|
6
44
|
|
|
@@ -74,6 +112,8 @@ export default defineConfig({
|
|
|
74
112
|
|
|
75
113
|
Import the matcher from the package root and extend the active runner's `expect` instance explicitly. The matcher relies on the runner's equality function and custom matcher context; it does not bundle or select a runner.
|
|
76
114
|
|
|
115
|
+
Focused failures use the runner's `utils.printDiffOrStringify`, which Jest and Vitest supply through `expect.extend`. Other compatible runners need a Jest- or Vitest-compatible version of that utility for contextual diffs; without it, only basic expected/received rendering is available.
|
|
116
|
+
|
|
77
117
|
## TypeScript
|
|
78
118
|
|
|
79
119
|
The package root resolves to `index.d.mts`. Add a declaration augmentation for each runner you actually install. For Jest's `expect` package:
|
|
@@ -174,17 +214,17 @@ npm test
|
|
|
174
214
|
npm pack --dry-run
|
|
175
215
|
git switch main
|
|
176
216
|
git pull --ff-only origin main
|
|
177
|
-
git tag v1.0.
|
|
178
|
-
git push origin v1.0.
|
|
179
|
-
gh release create v1.0.
|
|
217
|
+
git tag v1.0.1
|
|
218
|
+
git push origin v1.0.1
|
|
219
|
+
gh release create v1.0.1 --title v1.0.1 --generate-notes
|
|
180
220
|
npm publish --access public
|
|
181
|
-
npm view @klondikemarlen/expect-http-response@1.0.
|
|
221
|
+
npm view @klondikemarlen/expect-http-response@1.0.1 version
|
|
182
222
|
```
|
|
183
223
|
|
|
184
224
|
In a separate consumer project, install the registry artifact:
|
|
185
225
|
|
|
186
226
|
```sh
|
|
187
|
-
npm install --save-dev @klondikemarlen/expect-http-response@1.0.
|
|
227
|
+
npm install --save-dev @klondikemarlen/expect-http-response@1.0.1
|
|
188
228
|
```
|
|
189
229
|
|
|
190
230
|
After publishing, use the actual registry installation in a fresh consumer project and run its matcher and TypeScript registration checks. Do not claim npm availability until the publish and registry install have been observed.
|
package/index.d.mts
CHANGED
|
@@ -12,7 +12,22 @@ interface HttpResponseLike {
|
|
|
12
12
|
readonly body?: unknown
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
type JestBodyFormatter = (
|
|
16
|
+
expected: unknown,
|
|
17
|
+
received: unknown,
|
|
18
|
+
expectedLabel: string,
|
|
19
|
+
receivedLabel: string,
|
|
20
|
+
expand: boolean
|
|
21
|
+
) => string
|
|
22
|
+
|
|
23
|
+
type VitestBodyFormatter = (
|
|
24
|
+
received: unknown,
|
|
25
|
+
expected: unknown,
|
|
26
|
+
options?: { expand?: boolean }
|
|
27
|
+
) => string | undefined
|
|
28
|
+
|
|
15
29
|
interface MatcherUtils {
|
|
30
|
+
printDiffOrStringify?: JestBodyFormatter | VitestBodyFormatter
|
|
16
31
|
matcherHint?: (
|
|
17
32
|
matcherName: string,
|
|
18
33
|
received?: string,
|
package/index.mjs
CHANGED
|
@@ -58,10 +58,8 @@ function formatMessage(context, result) {
|
|
|
58
58
|
hint,
|
|
59
59
|
"",
|
|
60
60
|
"Expected the response not to match this HTTP contract:",
|
|
61
|
-
`
|
|
62
|
-
|
|
63
|
-
`Expected body: ${printValue(context, "printExpected", result.expectedBody)}`,
|
|
64
|
-
`Received body: ${printValue(context, "printReceived", result.receivedBody)}`,
|
|
61
|
+
`Matched status: ${printValue(context, "printReceived", result.receivedStatus)}`,
|
|
62
|
+
"The status and body both matched.",
|
|
65
63
|
].join("\n")
|
|
66
64
|
}
|
|
67
65
|
|
|
@@ -77,14 +75,36 @@ function formatMessage(context, result) {
|
|
|
77
75
|
lines.push(
|
|
78
76
|
"",
|
|
79
77
|
"Body mismatch:",
|
|
80
|
-
|
|
81
|
-
`Received body: ${printValue(context, "printReceived", result.receivedBody)}`
|
|
78
|
+
formatBodyDifference(context, result.expectedBody, result.receivedBody)
|
|
82
79
|
)
|
|
83
80
|
}
|
|
84
81
|
|
|
85
82
|
return lines.join("\n")
|
|
86
83
|
}
|
|
87
84
|
|
|
85
|
+
function formatBodyDifference(context, expectedBody, receivedBody) {
|
|
86
|
+
const formatter = context.utils?.printDiffOrStringify
|
|
87
|
+
let difference
|
|
88
|
+
|
|
89
|
+
if (typeof formatter === "function") {
|
|
90
|
+
// Jest uses five positional arguments; Vitest uses three or four, with reversed values.
|
|
91
|
+
if (formatter.length >= 5) {
|
|
92
|
+
difference = formatter(expectedBody, receivedBody, "Expected body", "Received body", false)
|
|
93
|
+
} else {
|
|
94
|
+
difference = formatter(receivedBody, expectedBody, { expand: false })
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (typeof difference === "string") {
|
|
99
|
+
return difference
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return [
|
|
103
|
+
`Expected body: ${printValue(context, "printExpected", expectedBody)}`,
|
|
104
|
+
`Received body: ${printValue(context, "printReceived", receivedBody)}`,
|
|
105
|
+
].join("\n")
|
|
106
|
+
}
|
|
107
|
+
|
|
88
108
|
function matcherHint(context) {
|
|
89
109
|
if (typeof context.utils?.matcherHint === "function") {
|
|
90
110
|
return context.utils.matcherHint(
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@klondikemarlen/expect-http-response",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Focused HTTP response failure diagnostics for Jest and Vitest",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"exports": {
|