Skip to content

Commit

Permalink
Merge pull request #288 from microsoft/octogonz/load-from-object
Browse files Browse the repository at this point in the history
Add TSDocConfigFile.loadFromObject()
  • Loading branch information
octogonz authored Apr 16, 2021
2 parents bab6753 + 9eb890e commit 60b9cab
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@microsoft/tsdoc-config",
"comment": "Add a new API TSDocConfigFile.loadFromObject()",
"type": "minor"
}
],
"packageName": "@microsoft/tsdoc-config",
"email": "[email protected]"
}
42 changes: 34 additions & 8 deletions tsdoc-config/src/TSDocConfigFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ export class TSDocConfigFile {
}

/**
* The full path of the file that was attempted to load.
* The full path of the file that was attempted to load, or an empty string if the configuration was
* loaded from a source that is not a file.
*/
public get filePath(): string {
return this._filePath;
Expand Down Expand Up @@ -276,13 +277,9 @@ export class TSDocConfigFile {
this._hasErrors = true;
}

private _loadJsonFile(): void {
const configJsonContent: string = fs.readFileSync(this._filePath).toString();
this._fileMTime = fs.statSync(this._filePath).mtimeMs;
private _loadJsonObject(configJson: IConfigJson): void {
this._fileNotFound = false;

const configJson: IConfigJson = jju.parse(configJsonContent, { mode: 'cjson' });

if (configJson.$schema !== TSDocConfigFile.CURRENT_SCHEMA_URL) {
this._reportError({
messageId: TSDocMessageId.ConfigFileUnsupportedSchema,
Expand Down Expand Up @@ -381,7 +378,12 @@ export class TSDocConfigFile {
}
alreadyVisitedPaths.add(hashKey);

this._loadJsonFile();
const configJsonContent: string = fs.readFileSync(this._filePath).toString();
this._fileMTime = fs.statSync(this._filePath).mtimeMs;

const configJson: IConfigJson = jju.parse(configJsonContent, { mode: 'cjson' });

this._loadJsonObject(configJson);

const configFileFolder: string = path.dirname(this.filePath);

Expand Down Expand Up @@ -462,6 +464,24 @@ export class TSDocConfigFile {
return configFile;
}

/**
* Loads the object state from a JSON-serializable object as produced by {@link TSDocConfigFile.saveToObject}.
*
* @remarks
* The serialized object has the same structure as `tsdoc.json`; however the `"extends"` field is not allowed.
*/
public static loadFromObject(jsonObject: unknown): TSDocConfigFile {
const configFile: TSDocConfigFile = new TSDocConfigFile();

configFile._loadJsonObject(jsonObject as IConfigJson);

if (configFile.extendsPaths.length > 0) {
throw new Error('The "extends" field cannot be used with TSDocConfigFile.loadFromObject()');
}

return configFile;
}

/**
* Initializes a TSDocConfigFile object using the state from the provided `TSDocConfiguration` object.
*/
Expand Down Expand Up @@ -563,7 +583,13 @@ export class TSDocConfigFile {
return 'No errors.';
}

let result: string = `Errors encountered for ${this.filePath}:\n`;
let result: string;

if (this.filePath) {
result = `Errors encountered for ${this.filePath}:\n`;
} else {
result = `Errors encountered when loading TSDoc configuration:\n`;
}

for (const message of this.log.messages) {
result += ` ${message.text}\n`;
Expand Down
77 changes: 76 additions & 1 deletion tsdoc-config/src/__tests__/TSDocConfigFile.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TSDocConfiguration } from '@microsoft/tsdoc';
import { TSDocConfiguration, TSDocTagDefinition, TSDocTagSyntaxKind } from '@microsoft/tsdoc';
import * as path from 'path';

import { TSDocConfigFile } from '../TSDocConfigFile';
Expand Down Expand Up @@ -207,6 +207,8 @@ test('Load p4', () => {

test('Re-serialize p3', () => {
const configFile: TSDocConfigFile = TSDocConfigFile.loadForFolder(path.join(__dirname, 'assets/p3'));
expect(configFile.hasErrors).toBe(false);

// This is the data from p3/tsdoc.json, ignoring its "extends" field.
expect(configFile.saveToObject()).toMatchInlineSnapshot(`
Object {
Expand All @@ -229,6 +231,8 @@ test('Re-serialize p3 without defaults', () => {
parserConfiguration.clear(true);

const defaultsConfigFile: TSDocConfigFile = TSDocConfigFile.loadFromParser(parserConfiguration);
expect(defaultsConfigFile.hasErrors).toBe(false);

// This is the default configuration created by the TSDocConfigFile constructor.
expect(defaultsConfigFile.saveToObject()).toMatchInlineSnapshot(`
Object {
Expand All @@ -238,6 +242,7 @@ test('Re-serialize p3 without defaults', () => {
`);

const configFile: TSDocConfigFile = TSDocConfigFile.loadForFolder(path.join(__dirname, 'assets/p3'));
expect(configFile.hasErrors).toBe(false);
configFile.noStandardTags = true;
configFile.configureParser(parserConfiguration);

Expand Down Expand Up @@ -275,6 +280,8 @@ test('Re-serialize p3 with defaults', () => {
const parserConfiguration: TSDocConfiguration = new TSDocConfiguration();

const defaultsConfigFile: TSDocConfigFile = TSDocConfigFile.loadFromParser(parserConfiguration);
expect(defaultsConfigFile.hasErrors).toBe(false);

// This is the default configuration created by the TSDocConfigFile constructor.
expect(defaultsConfigFile.saveToObject()).toMatchInlineSnapshot(`
Object {
Expand Down Expand Up @@ -392,6 +399,7 @@ test('Re-serialize p3 with defaults', () => {
`);

const configFile: TSDocConfigFile = TSDocConfigFile.loadForFolder(path.join(__dirname, 'assets/p3'));
expect(configFile.hasErrors).toBe(false);
configFile.configureParser(parserConfiguration);

const mergedConfigFile: TSDocConfigFile = TSDocConfigFile.loadFromParser(parserConfiguration);
Expand Down Expand Up @@ -532,6 +540,7 @@ test('Re-serialize p3 with defaults', () => {

test('Test noStandardTags for p5', () => {
const configFile: TSDocConfigFile = TSDocConfigFile.loadForFolder(path.join(__dirname, 'assets/p5'));
expect(configFile.hasErrors).toBe(false);

const configuration: TSDocConfiguration = new TSDocConfiguration();
configFile.configureParser(configuration);
Expand All @@ -542,10 +551,76 @@ test('Test noStandardTags for p5', () => {

test('Test noStandardTags for p6', () => {
const configFile: TSDocConfigFile = TSDocConfigFile.loadForFolder(path.join(__dirname, 'assets/p6'));
expect(configFile.hasErrors).toBe(false);

const configuration: TSDocConfiguration = new TSDocConfiguration();
configFile.configureParser(configuration);

// noStandardTags=false because tsdoc.json overrides tsdoc-base1.json
expect(configuration.tagDefinitions.length).toBeGreaterThan(0);
});

test('Test loadFromObject()', () => {
const configuration: TSDocConfiguration = new TSDocConfiguration();
configuration.clear(true);

configuration.addTagDefinitions([
new TSDocTagDefinition({ syntaxKind: TSDocTagSyntaxKind.ModifierTag, tagName: '@tag1' }),
new TSDocTagDefinition({ syntaxKind: TSDocTagSyntaxKind.BlockTag, tagName: '@tag2', allowMultiple: true }),
new TSDocTagDefinition({ syntaxKind: TSDocTagSyntaxKind.InlineTag, tagName: '@tag3', allowMultiple: true }),
]);

configuration.setSupportForTag(configuration.tagDefinitions[0], true);

const configFile: TSDocConfigFile = TSDocConfigFile.loadFromParser(configuration);
expect(configFile.hasErrors).toBe(false);
const jsonObject: unknown = configFile.saveToObject();

const configFile2: TSDocConfigFile = TSDocConfigFile.loadFromObject(jsonObject);
expect(configFile2.hasErrors).toBe(false);
const jsonObject2: unknown = configFile2.saveToObject();

expect(jsonObject2).toMatchInlineSnapshot(`
Object {
"$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json",
"noStandardTags": true,
"supportForTags": Object {
"@tag1": true,
},
"tagDefinitions": Array [
Object {
"syntaxKind": "modifier",
"tagName": "@tag1",
},
Object {
"allowMultiple": true,
"syntaxKind": "block",
"tagName": "@tag2",
},
Object {
"allowMultiple": true,
"syntaxKind": "inline",
"tagName": "@tag3",
},
],
}
`);

expect(jsonObject2).toStrictEqual(jsonObject);
});

test('Test loadFromObject() with extends', () => {
const configuration: TSDocConfiguration = new TSDocConfiguration();
configuration.clear(true);

const configFile: TSDocConfigFile = TSDocConfigFile.loadFromParser(configuration);
expect(configFile.hasErrors).toBe(false);
const jsonObject: unknown = configFile.saveToObject();

// eslint-disable-next-line
(jsonObject as any)['extends'] = ['./some-file.json'];

expect(() => {
TSDocConfigFile.loadFromObject(jsonObject);
}).toThrowError('The "extends" field cannot be used with TSDocConfigFile.loadFromObject()');
});

0 comments on commit 60b9cab

Please sign in to comment.