readme-assert 7.2.1 → 7.2.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "readme-assert",
3
- "version": "7.2.1",
3
+ "version": "7.2.2",
4
4
  "description": "Run code blocks in your readme as tests",
5
5
  "keywords": [
6
6
  "readme",
package/readme.md CHANGED
@@ -103,6 +103,12 @@ Assert that a promise rejects with `// rejects`:
103
103
  Promise.reject(new Error("no")) // rejects /no/
104
104
  ```
105
105
 
106
+ Or match the error name and message with `//=> rejects`:
107
+
108
+ ```javascript test
109
+ Promise.reject(new TypeError("no")) //=> rejects TypeError: no
110
+ ```
111
+
106
112
  ### TypeScript
107
113
 
108
114
  TypeScript code blocks are supported natively:
@@ -11,6 +11,7 @@ import MagicString from "magic-string";
11
11
  * console.log(x) //=> v → console.log(x); assert.deepEqual(x, v)
12
12
  * expr //=> resolves to v → assert.deepEqual(await expr, v)
13
13
  * expr // rejects /pat/ → assert.rejects(() => expr, /pat/)
14
+ * expr //=> rejects Error: msg → assert.rejects(() => expr, { message: "msg" })
14
15
  *
15
16
  * Uses oxc-parser for AST + comment extraction. Handles both JS and TS.
16
17
  *
@@ -40,6 +41,9 @@ export function commentToAssert(code, { typescript = false } = {}) {
40
41
  if (match) {
41
42
  const rest = match[2].trim();
42
43
  const resolvesMatch = rest.match(/^resolves\s+(?:to\s+)?([\s\S]*)$/);
44
+ const rejectsErrorMatch = rest.match(
45
+ /^rejects\s+((?:[A-Z]\w+)?Error)(?::\s*(.*))?$/,
46
+ );
43
47
  changed = true;
44
48
 
45
49
  const errorMatch = rest.match(/^((?:[A-Z]\w+)?Error)(?::\s*(.*))?$/);
@@ -56,6 +60,23 @@ export function commentToAssert(code, { typescript = false } = {}) {
56
60
  comment.end,
57
61
  `assert.deepEqual(await ${exprSource}, ${expected});`,
58
62
  );
63
+ } else if (rejectsErrorMatch) {
64
+ // expr //=> rejects TypeError: msg → assert.rejects(() => expr, { name, message })
65
+ const errorName = rejectsErrorMatch[1];
66
+ const errorMessage = rejectsErrorMatch[2]?.trim();
67
+ const exprSource = code.slice(
68
+ node.expression.start,
69
+ node.expression.end,
70
+ );
71
+ const props = [`name: "${errorName}"`];
72
+ if (errorMessage) {
73
+ props.push(formatMessageProp(errorMessage));
74
+ }
75
+ s.overwrite(
76
+ node.start,
77
+ comment.end,
78
+ `await assert.rejects(() => ${exprSource}, { ${props.join(", ")} });`,
79
+ );
59
80
  } else if (errorMatch) {
60
81
  // expr //=> TypeError: msg → assert.throws(() => { expr }, { name, message })
61
82
  const errorName = errorMatch[1];
@@ -66,12 +87,7 @@ export function commentToAssert(code, { typescript = false } = {}) {
66
87
  );
67
88
  const props = [`name: "${errorName}"`];
68
89
  if (errorMessage) {
69
- const reMatch = errorMessage.match(/^\/(.+)\/([gimsuy]*)$/);
70
- props.push(
71
- reMatch
72
- ? `message: /${reMatch[1]}/${reMatch[2]}`
73
- : `message: "${errorMessage}"`,
74
- );
90
+ props.push(formatMessageProp(errorMessage));
75
91
  }
76
92
  s.overwrite(
77
93
  node.start,
@@ -153,6 +169,13 @@ function findTrailingComment(comments, node, code) {
153
169
  return null;
154
170
  }
155
171
 
172
+ function formatMessageProp(msg) {
173
+ const reMatch = msg.match(/^\/(.+)\/([gimsuy]*)$/);
174
+ return reMatch
175
+ ? `message: /${reMatch[1]}/${reMatch[2]}`
176
+ : `message: "${msg}"`;
177
+ }
178
+
156
179
  function isConsoleCall(expr) {
157
180
  return (
158
181
  expr.type === "CallExpression" &&