Skip to content

Commit e451d48

Browse files
committed
Add unit tests for x-tsdoc-tag support in node-core-library and heft-json-schema-typings-plugin.
1 parent 2c9e6cb commit e451d48

5 files changed

Lines changed: 109 additions & 26 deletions

File tree

heft-plugins/heft-json-schema-typings-plugin/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"scripts": {
1313
"build": "heft test --clean",
1414
"start": "heft build-watch",
15-
"_phase:build": "heft run --only build -- --clean"
15+
"_phase:build": "heft run --only build -- --clean",
16+
"_phase:test": "heft run --only test -- --clean"
1617
},
1718
"peerDependencies": {
1819
"@rushstack/heft": "1.1.14"

heft-plugins/heft-json-schema-typings-plugin/src/JsonSchemaTypingsGenerator.ts

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,9 @@ import { compileFromFile } from 'json-schema-to-typescript';
88

99
import { type ITypingsGeneratorBaseOptions, TypingsGenerator } from '@rushstack/typings-generator';
1010

11-
interface IJsonSchemaTypingsGeneratorBaseOptions extends ITypingsGeneratorBaseOptions {}
12-
13-
/**
14-
* Adds a TSDoc release tag (e.g. `@public`, `@beta`) to all exported declarations
15-
* in generated typings.
16-
*
17-
* `json-schema-to-typescript` does not emit release tags, so this function
18-
* post-processes the output to ensure API Extractor treats these types with the
19-
* correct release tag when they are re-exported from package entry points.
20-
*/
21-
function _addTsDocTagToExports(typingsData: string, tag: string): string {
22-
// Normalize line endings for consistent regex matching.
23-
// The TypingsGenerator base class applies NewlineKind.OsDefault when writing.
24-
const normalized: string = typingsData.replace(/\r\n/g, '\n');
25-
26-
// Pass 1: For exports preceded by an existing JSDoc comment, insert
27-
// the tag before the closing "*/".
28-
let result: string = normalized.replace(/ \*\/\n(export )/g, ` *\n * ${tag}\n */\n$1`);
11+
import { _addTsDocTagToExports } from './TsDocTagHelpers';
2912

30-
// Pass 2: For exports NOT preceded by a JSDoc comment, insert a new
31-
// JSDoc block. The negative lookbehind ensures Pass 1
32-
// results are not double-matched.
33-
result = result.replace(/(?<!\*\/\n)^(export )/gm, `/**\n * ${tag}\n */\n$1`);
34-
35-
return result;
36-
}
13+
interface IJsonSchemaTypingsGeneratorBaseOptions extends ITypingsGeneratorBaseOptions {}
3714

3815
export class JsonSchemaTypingsGenerator extends TypingsGenerator {
3916
public constructor(options: IJsonSchemaTypingsGeneratorBaseOptions) {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2+
// See LICENSE in the project root for license information.
3+
4+
/**
5+
* Adds a TSDoc release tag (e.g. `@public`, `@beta`) to all exported declarations
6+
* in generated typings.
7+
*
8+
* `json-schema-to-typescript` does not emit release tags, so this function
9+
* post-processes the output to ensure API Extractor treats these types with the
10+
* correct release tag when they are re-exported from package entry points.
11+
*/
12+
export function _addTsDocTagToExports(typingsData: string, tag: string): string {
13+
// Normalize line endings for consistent regex matching.
14+
// The TypingsGenerator base class applies NewlineKind.OsDefault when writing.
15+
const normalized: string = typingsData.replace(/\r\n/g, '\n');
16+
17+
// Pass 1: For exports preceded by an existing JSDoc comment, insert
18+
// the tag before the closing "*/".
19+
let result: string = normalized.replace(/ \*\/\n(export )/g, ` *\n * ${tag}\n */\n$1`);
20+
21+
// Pass 2: For exports NOT preceded by a JSDoc comment, insert a new
22+
// JSDoc block. The negative lookbehind ensures Pass 1
23+
// results are not double-matched.
24+
result = result.replace(/(?<!\*\/\n)^(export )/gm, `/**\n * ${tag}\n */\n$1`);
25+
26+
return result;
27+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`_addTsDocTagToExports creates a new JSDoc block for an export without a preceding comment 1`] = `
4+
"/**
5+
* @public
6+
*/
7+
export type Foo = {};"
8+
`;
9+
10+
exports[`_addTsDocTagToExports does not double-tag an export that already has a JSDoc block 1`] = `
11+
"/**
12+
* Already documented.
13+
*
14+
* @public
15+
*/
16+
export interface IConfig {
17+
name: string;
18+
}"
19+
`;
20+
21+
exports[`_addTsDocTagToExports does not modify non-export lines 1`] = `
22+
"// A leading comment
23+
const internal = 1;
24+
25+
/**
26+
* @beta
27+
*/
28+
export type Foo = {};"
29+
`;
30+
31+
exports[`_addTsDocTagToExports handles multiple exports with and without JSDoc comments 1`] = `
32+
"/**
33+
* First type.
34+
*
35+
* @beta
36+
*/
37+
export type Foo = {};
38+
39+
/**
40+
* @beta
41+
*/
42+
export type Bar = {};"
43+
`;
44+
45+
exports[`_addTsDocTagToExports injects tag into an existing JSDoc comment before an export 1`] = `
46+
"/**
47+
* A description.
48+
*
49+
* @beta
50+
*/
51+
export type Foo = {};"
52+
`;
53+
54+
exports[`_addTsDocTagToExports normalizes CRLF line endings to LF 1`] = `
55+
"/**
56+
* A description.
57+
*
58+
* @beta
59+
*/
60+
export type Foo = {};"
61+
`;

libraries/node-core-library/src/test/JsonSchema.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,23 @@ describe(JsonSchema.name, () => {
120120
});
121121
});
122122

123+
test('accepts a schema containing the x-tsdoc-tag custom keyword', () => {
124+
const schemaWithTsDocTag: JsonSchema = JsonSchema.fromLoadedObject(
125+
{
126+
title: 'Test x-tsdoc-tag',
127+
'x-tsdoc-tag': '@beta',
128+
type: 'object',
129+
properties: {
130+
name: { type: 'string' }
131+
},
132+
additionalProperties: false,
133+
required: ['name']
134+
},
135+
{ schemaVersion: 'draft-07' }
136+
);
137+
expect(() => schemaWithTsDocTag.validateObject({ name: 'hello' }, '')).not.toThrow();
138+
});
139+
123140
test('successfully applies custom formats', () => {
124141
const schemaWithCustomFormat = JsonSchema.fromLoadedObject(
125142
{

0 commit comments

Comments
 (0)