Skip to content

Commit 6663384

Browse files
committed
fix: support @this tag
#251
1 parent 0260abf commit 6663384

File tree

4 files changed

+144
-0
lines changed

4 files changed

+144
-0
lines changed

src/roles.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import {
3838
SEE,
3939
SINCE,
4040
TEMPLATE,
41+
THIS,
4142
THROWS,
4243
TODO,
4344
TYPE,
@@ -94,6 +95,7 @@ const TAGS_NAMELESS = [
9495
REMARKS,
9596
RETURNS,
9697
SINCE,
98+
THIS,
9799
THROWS,
98100
TODO,
99101
YIELDS,
@@ -148,6 +150,7 @@ const TAGS_TYPE_NEEDED = [
148150
PARAM,
149151
PROPERTY,
150152
RETURNS,
153+
THIS,
151154
THROWS,
152155
TYPE,
153156
SATISFIES,
@@ -160,6 +163,7 @@ const TAGS_VERTICALLY_ALIGN_ABLE = [
160163
PARAM,
161164
PROPERTY,
162165
RETURNS,
166+
THIS,
163167
THROWS,
164168
TYPE,
165169
SATISFIES,
@@ -174,6 +178,7 @@ const TAGS_GROUP_CONDITION = [
174178
PROPERTY,
175179
PARAM,
176180
RETURNS,
181+
THIS,
177182
YIELDS,
178183
THROWS,
179184
];
@@ -219,6 +224,7 @@ const TAGS_ORDER = {
219224
[SATISFIES]: 37,
220225
[PROPERTY]: 38,
221226
[CALLBACK]: 39,
227+
[THIS]: 39.5,
222228
[PARAM]: 40,
223229
[YIELDS]: 41,
224230
[RETURNS]: 42,

src/tags.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ const RETURNS = "returns";
3939
const SEE = "see";
4040
const SINCE = "since";
4141
const TEMPLATE = "template";
42+
const THIS = "this";
4243
const THROWS = "throws";
4344
const TODO = "todo";
4445
const TYPE = "type";
@@ -98,6 +99,7 @@ export {
9899
SEE,
99100
SINCE,
100101
TEMPLATE,
102+
THIS,
101103
THROWS,
102104
TODO,
103105
TYPE,

tests/__snapshots__/exampleTag.test.ts.snap

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,84 @@ exports[`example unParseAble 1`] = `
113113
"
114114
`;
115115

116+
exports[`example with @this tag preserves indentation 1`] = `
117+
"/**
118+
* @example
119+
* import { createServer } from "node:http";
120+
* import extendedResponse from "extended-response";
121+
*
122+
* async function* messages() {
123+
* for (let i = 1; i <= 5; i++) {
124+
* yield \`Message \${i}\\r\\n\`;
125+
* await new Promise((resolve) => setTimeout(resolve, 1000));
126+
* }
127+
* }
128+
*
129+
* const server = createServer(async (req, res) => {
130+
* if (
131+
* req.method === "GET" &&
132+
* new URL(req.url || "").pathname === "/stream5"
133+
* ) {
134+
* await extendedResponse.call(res, {
135+
* messages,
136+
* });
137+
* }
138+
* });
139+
*
140+
* server.listen(port, () => {
141+
* console.log(\`Server running on http://localhost:\${port}\`);
142+
* });
143+
*
144+
* @this {ServerResponse} A Node.js HTTP
145+
* {@link https://nodejs.org/api/http.html#class-httpserverresponse|ServerResponse}
146+
* instance.
147+
* @param {object} params Extended Response Parameters
148+
* @param {AsyncIterable<message>} params.messages Async messages to be sent
149+
* response stream will be closed
150+
* @returns {Promise<void>}
151+
*/
152+
"
153+
`;
154+
155+
exports[`example with @this tag preserves indentation 2`] = `
156+
"/**
157+
* @example
158+
* import { createServer } from "node:http";
159+
* import extendedResponse from "extended-response";
160+
*
161+
* async function* messages() {
162+
* for (let i = 1; i <= 5; i++) {
163+
* yield \`Message \${i}\\r\\n\`;
164+
* await new Promise((resolve) => setTimeout(resolve, 1000));
165+
* }
166+
* }
167+
*
168+
* const server = createServer(async (req, res) => {
169+
* if (
170+
* req.method === "GET" &&
171+
* new URL(req.url || "").pathname === "/stream5"
172+
* ) {
173+
* await extendedResponse.call(res, {
174+
* messages,
175+
* });
176+
* }
177+
* });
178+
*
179+
* server.listen(port, () => {
180+
* console.log(\`Server running on http://localhost:\${port}\`);
181+
* });
182+
*
183+
* @this {ServerResponse} A Node.js HTTP
184+
* {@link https://nodejs.org/api/http.html#class-httpserverresponse|ServerResponse}
185+
* instance.
186+
* @param {object} params Extended Response Parameters
187+
* @param {AsyncIterable<message>} params.messages Async messages to be sent
188+
* response stream will be closed
189+
* @returns {Promise<void>}
190+
*/
191+
"
192+
`;
193+
116194
exports[`examples Json 1`] = `
117195
"/**
118196
* @example

tests/exampleTag.test.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,3 +176,61 @@ test("example unParseAble", async () => {
176176
expect(result2).toEqual(result);
177177
expect(await subject(result)).not.toEqual(result);
178178
});
179+
180+
test("example with @this tag preserves indentation", async () => {
181+
const code = `/**
182+
* @example
183+
* import { createServer } from "node:http";
184+
* import extendedResponse from "extended-response";
185+
*
186+
* async function* messages() {
187+
* for (let i = 1; i <= 5; i++) {
188+
* yield \`Message \${i}\\r\\n\`;
189+
* await new Promise((resolve) => setTimeout(resolve, 1000));
190+
* }
191+
* }
192+
*
193+
* const server = createServer(async (req, res) => {
194+
* if (
195+
* req.method === "GET" &&
196+
* new URL(req.url || "").pathname === "/stream5"
197+
* ) {
198+
* await extendedResponse.call(res, {
199+
* messages,
200+
* });
201+
* }
202+
* });
203+
*
204+
* server.listen(port, () => {
205+
* console.log(\`Server running on http://localhost:\${port}\`);
206+
* });
207+
*
208+
* @param {object} params Extended Response Parameters
209+
* @param {AsyncIterable<message>} params.messages Async messages to be sent
210+
* response stream will be closed
211+
* @returns {Promise<void>}
212+
*
213+
* @this {ServerResponse}
214+
* A Node.js HTTP
215+
* {@link https://nodejs.org/api/http.html#class-httpserverresponse|ServerResponse}
216+
* instance.
217+
*/`;
218+
219+
const result = await subject(code, {
220+
jsdocTagsOrder: '{"this":39.9}' as any,
221+
jsdocKeepUnParseAbleExampleIndent: true,
222+
});
223+
224+
expect(result).toMatchSnapshot();
225+
226+
// Format again to ensure it's stable
227+
const result2 = await subject(result, {
228+
jsdocTagsOrder: '{"this":39.9}' as any,
229+
jsdocKeepUnParseAbleExampleIndent: true,
230+
});
231+
232+
// The example should preserve its indentation
233+
expect(result2).toMatchSnapshot();
234+
expect(result2).toContain(" import { createServer }");
235+
expect(result2).toContain(" for (let i = 1; i <= 5; i++)");
236+
});

0 commit comments

Comments
 (0)