Skip to content

Commit f6b14dd

Browse files
authored
Merge pull request microsoft#1043 from Microsoft/pgonzal/ae-test-mode
[api-extractor] Eliminate spurious diffs in test projects
2 parents 3ffd7b4 + 81de96a commit f6b14dd

File tree

36 files changed

+132
-44
lines changed

36 files changed

+132
-44
lines changed

apps/api-extractor/.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@
8989
"request": "launch",
9090
"name": "scratch",
9191
"program": "${workspaceFolder}/lib/start.js",
92-
"cwd": "D:\\GitRepos\\wbt\\core-build\\gulp-core-build",
92+
"cwd": "(your project path)",
9393
"args": [
9494
"--debug",
9595
"run",

apps/api-extractor/src/api/Extractor.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,8 @@ export class Extractor {
406406
this._monitoredLogger.logVerbose('Writing: ' + apiJsonFilename);
407407
apiPackage.saveToJsonFile(apiJsonFilename, {
408408
newlineConversion: NewlineKind.CrLf,
409-
ensureFolderExists: true
409+
ensureFolderExists: true,
410+
testMode: this.actualConfig.testMode
410411
});
411412
}
412413

apps/api-extractor/src/api/IExtractorConfig.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,4 +309,12 @@ export interface IExtractorConfig {
309309
* This option only applies when compiler.config.configType is set to "tsconfig"
310310
*/
311311
skipLibCheck?: boolean;
312+
313+
/**
314+
* Set to true when invoking API Extractor's test harness.
315+
* @remarks
316+
* When `testMode` is true, the `toolVersion` field in the .api.json file is assigned an empty string
317+
* to prevent spurious diffs in output files tracked for tests.
318+
*/
319+
testMode?: boolean;
312320
}

apps/api-extractor/src/api/items/ApiDeclaredItem.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export class ApiDeclaredItem extends ApiDocumentedItem {
4646
public constructor(options: IApiDeclaredItemOptions) {
4747
super(options);
4848

49-
this._excerptTokens = options.excerptTokens;
49+
this._excerptTokens = options.excerptTokens.map(x => new ExcerptToken(x.kind, x.text));
5050
this._excerpt = new Excerpt(this.excerptTokens, { startIndex: 0, endIndex: this.excerptTokens.length });
5151
}
5252

@@ -98,7 +98,6 @@ export class ApiDeclaredItem extends ApiDocumentedItem {
9898
/** @override */
9999
public serializeInto(jsonObject: Partial<IApiDeclaredItemJson>): void {
100100
super.serializeInto(jsonObject);
101-
102101
jsonObject.excerptTokens = this.excerptTokens.map(x => ({ kind: x.kind, text: x.text }));
103102
}
104103

apps/api-extractor/src/api/mixins/Excerpt.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
22
// See LICENSE in the project root for license information.
33

4+
import { Text } from '@microsoft/node-core-library';
5+
46
/** @public */
57
export const enum ExcerptTokenKind {
68
Content = 'Content',
@@ -23,12 +25,24 @@ export interface IExcerptToken {
2325

2426
/** @public */
2527
export class ExcerptToken {
26-
public readonly kind: ExcerptTokenKind;
27-
public readonly text: string;
28+
private readonly _kind: ExcerptTokenKind;
29+
private readonly _text: string;
2830

2931
public constructor(kind: ExcerptTokenKind, text: string) {
30-
this.kind = kind;
31-
this.text = text;
32+
this._kind = kind;
33+
34+
// Standardize the newlines across operating systems. Even though this may deviate from the actual
35+
// input source file that was parsed, it's useful because the newline gets serialized inside
36+
// a string literal in .api.json, which cannot be automatically normalized by Git.
37+
this._text = Text.convertToLf(text);
38+
}
39+
40+
public get kind(): ExcerptTokenKind {
41+
return this._kind;
42+
}
43+
44+
public get text(): string {
45+
return this._text;
3246
}
3347
}
3448

apps/api-extractor/src/api/model/ApiPackage.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,15 @@ export interface IApiPackageJson extends IApiItemJson {
5252
metadata: IApiPackageMetadataJson;
5353
}
5454

55+
/**
56+
* Options for {@link ApiPackage.saveToJsonFile}.
57+
* @public
58+
*/
59+
export interface IApiPackageSaveOptions extends IJsonFileSaveOptions {
60+
/** {@inheritDoc IExtractorConfig.testMode} */
61+
testMode?: boolean;
62+
}
63+
5564
/**
5665
* Represents an NPM package containing API declarations.
5766
*
@@ -98,11 +107,17 @@ export class ApiPackage extends ApiItemContainerMixin(ApiNameMixin(ApiDocumented
98107
return this.findMembersByName(importPath) as ReadonlyArray<ApiEntryPoint>;
99108
}
100109

101-
public saveToJsonFile(apiJsonFilename: string, options?: IJsonFileSaveOptions): void {
110+
public saveToJsonFile(apiJsonFilename: string, options?: IApiPackageSaveOptions): void {
111+
if (!options) {
112+
options = {};
113+
}
114+
102115
const jsonObject: IApiPackageJson = {
103116
metadata: {
104117
toolPackage: Extractor.packageName,
105-
toolVersion: Extractor.version,
118+
// In test mode, we don't write the real version, since that would cause spurious diffs whenever
119+
// the verison is bumped. Instead we write a placeholder string.
120+
toolVersion: options.testMode ? '[test mode]' : Extractor.version,
106121
schemaVersion: ApiJsonSchemaVersion.V_1000
107122
}
108123
} as IApiPackageJson;

apps/api-extractor/src/generators/ExcerptBuilder.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
// See LICENSE in the project root for license information.
33

44
import * as ts from 'typescript';
5+
56
import {
6-
ExcerptToken,
77
ExcerptTokenKind,
88
IExcerptToken,
99
IExcerptTokenRange
@@ -152,7 +152,7 @@ export class ExcerptBuilder {
152152
}
153153

154154
if (excerptTokenKind !== ExcerptTokenKind.Content) {
155-
excerptTokens.push(new ExcerptToken(excerptTokenKind, text));
155+
excerptTokens.push({ kind: excerptTokenKind, text: text});
156156
state.disableMergingForNextToken = false;
157157

158158
} else {
@@ -166,7 +166,7 @@ export class ExcerptBuilder {
166166
}
167167
}
168168

169-
excerptTokens.push(new ExcerptToken(excerptTokenKind, text));
169+
excerptTokens.push({ kind: excerptTokenKind, text: text});
170170
state.disableMergingForNextToken = false;
171171
}
172172
}

apps/api-extractor/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ export {
139139
} from './api/model/ApiNamespace';
140140
export {
141141
IApiPackageOptions,
142-
ApiPackage
142+
ApiPackage,
143+
IApiPackageSaveOptions
143144
} from './api/model/ApiPackage';
144145
export {
145146
IParameterOptions,

apps/api-extractor/src/schemas/api-extractor-defaults.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,9 @@
3535
"publishFolderForPublic": "./dist/public",
3636

3737
"mainDtsRollupPath": ""
38-
}
38+
},
39+
40+
"skipLibCheck": false,
41+
42+
"testMode": false
3943
}

apps/api-extractor/src/schemas/api-extractor.schema.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,10 @@
169169
"skipLibCheck": {
170170
"description": "This option causes the typechecker to be invoked with the --skipLibCheck option. This option is not recommended and may cause API Extractor to produce incomplete or incorrect declarations, but it may be required when dependencies contain declarations that are incompatible with the TypeScript engine that API Extractor uses for its analysis. If this option is used, it is strongly recommended that broken dependencies be fixed or upgraded.",
171171
"type": "boolean"
172+
},
173+
"testMode": {
174+
"description": "Set to true invoking API Extractor's test harness. When \"testMode\" is true, the \"toolVersion\" field in the .api.json file is assigned an empty string to prevent spurious diffs in output files tracked for tests.",
175+
"type": "boolean"
172176
}
173177
},
174178
"required": [ "compiler", "project" ],

0 commit comments

Comments
 (0)