Skip to content

Commit

Permalink
docs: show examples for modules (#2406)
Browse files Browse the repository at this point in the history
Co-authored-by: ST-DDT <ST-DDT@gmx.de>
  • Loading branch information
matthewmayer and ST-DDT authored Sep 19, 2023
1 parent d264100 commit 8e4172b
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 15 deletions.
8 changes: 8 additions & 0 deletions scripts/apidoc/apiDocsWriter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,23 @@ editLink: false
* @param moduleName The name of the module to write the docs for.
* @param lowerModuleName The lowercase name of the module.
* @param comment The module comments.
* @param examples The example code.
* @param deprecated The deprecation message.
* @param methods The methods of the module.
*/
export async function writeApiDocsModule(
moduleName: string,
lowerModuleName: string,
comment: string,
examples: string | undefined,
deprecated: string | undefined,
methods: Method[]
): Promise<ModuleSummary> {
await writeApiDocsModulePage(
moduleName,
lowerModuleName,
comment,
examples,
deprecated,
methods
);
Expand Down Expand Up @@ -83,12 +86,15 @@ export async function writeApiDocsModule(
* @param moduleName The name of the module to write the docs for.
* @param lowerModuleName The lowercase name of the module.
* @param comment The module comments.
* @param examples The example code.
* @param deprecated The deprecation message.
* @param methods The methods of the module.
*/
async function writeApiDocsModulePage(
moduleName: string,
lowerModuleName: string,
comment: string,
examples: string | undefined,
deprecated: string | undefined,
methods: Method[]
): Promise<void> {
Expand Down Expand Up @@ -118,6 +124,8 @@ async function writeApiDocsModulePage(
${comment}
${examples == null ? '' : `<div class="examples">${examples}</div>`}
:::
${methods
Expand Down
3 changes: 2 additions & 1 deletion scripts/apidoc/fakerClass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ async function processClass(

console.log(`Processing ${name} class`);

const { comment, deprecated } = analyzeModule(fakerClass);
const { comment, deprecated, examples } = analyzeModule(fakerClass);
const methods: Method[] = [];

console.debug(`- constructor`);
Expand All @@ -43,6 +43,7 @@ async function processClass(
name,
moduleFieldName,
comment,
examples,
deprecated,
methods
);
Expand Down
9 changes: 8 additions & 1 deletion scripts/apidoc/fakerUtilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,12 @@ async function processUtilities(
)
);

return writeApiDocsModule('Utilities', 'utils', comment, undefined, methods);
return writeApiDocsModule(
'Utilities',
'utils',
comment,
undefined,
undefined,
methods
);
}
10 changes: 10 additions & 0 deletions scripts/apidoc/markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ function comparableSanitizedHtml(html: string): string {
.replace(/&#39;/g, "'");
}

/**
* Converts a Typescript code block to an HTML string and sanitizes it.
* @param code The code to convert.
* @returns The converted HTML string.
*/
export function codeToHtml(code: string): string {
const delimiter = '```';
return mdToHtml(`${delimiter}ts\n${code}\n${delimiter}`);
}

/**
* Converts Markdown to an HTML string and sanitizes it.
* @param md The markdown to convert.
Expand Down
10 changes: 9 additions & 1 deletion scripts/apidoc/moduleMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import type {
} from 'typedoc';
import type { Method } from '../../docs/.vitepress/components/api-docs/method';
import { writeApiDocsModule } from './apiDocsWriter';
import { codeToHtml } from './markdown';
import { analyzeSignature } from './signature';
import {
extractDeprecated,
extractDescription,
extractJoinedRawExamples,
extractModuleFieldName,
extractModuleName,
selectApiMethodSignatures,
Expand Down Expand Up @@ -41,7 +43,7 @@ async function processModule(
const moduleName = extractModuleName(module);
console.log(`Processing Module ${moduleName}`);
const moduleFieldName = extractModuleFieldName(module);
const { comment, deprecated } = analyzeModule(module);
const { comment, deprecated, examples } = analyzeModule(module);
const methods = await processModuleMethods(
module,
`faker.${moduleFieldName}.`
Expand All @@ -51,6 +53,7 @@ async function processModule(
moduleName,
moduleFieldName,
comment,
examples,
deprecated,
methods
);
Expand All @@ -65,10 +68,15 @@ async function processModule(
export function analyzeModule(module: DeclarationReflection): {
comment: string;
deprecated: string | undefined;
examples: string | undefined;
} {
const examplesRaw = extractJoinedRawExamples(module);
const examples = examplesRaw ? codeToHtml(examplesRaw) : undefined;

return {
comment: adjustUrls(extractDescription(module)),
deprecated: extractDeprecated(module),
examples,
};
}

Expand Down
14 changes: 6 additions & 8 deletions scripts/apidoc/signature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ import type {
MethodParameter,
} from '../../docs/.vitepress/components/api-docs/method';
import { formatTypescript } from './format';
import { mdToHtml } from './markdown';
import { codeToHtml, mdToHtml } from './markdown';
import {
extractDeprecated,
extractDescription,
extractJoinedRawExamples,
extractRawDefault,
extractRawExamples,
extractSeeAlsos,
extractSince,
extractSourcePath,
Expand All @@ -28,8 +28,6 @@ import {
toBlock,
} from './typedoc';

const code = '```';

export async function analyzeSignature(
signature: SignatureReflection,
accessor: string,
Expand Down Expand Up @@ -74,9 +72,9 @@ export async function analyzeSignature(

let examples = `${accessor}${methodName}${signatureTypeParametersString}(${signatureParametersString}): ${signature.type?.toString()}\n`;

const exampleTags = extractRawExamples(signature);
if (exampleTags.length > 0) {
examples += `${exampleTags.join('\n').trim()}\n`;
const exampleTags = extractJoinedRawExamples(signature);
if (exampleTags) {
examples += exampleTags;
}

const seeAlsos = extractSeeAlsos(signature).map((seeAlso) =>
Expand All @@ -97,7 +95,7 @@ export async function analyzeSignature(
sourcePath: extractSourcePath(signature),
throws,
returns: await typeToText(signature.type),
examples: mdToHtml(`${code}ts\n${examples}${code}`),
examples: codeToHtml(examples),
deprecated,
seeAlsos,
};
Expand Down
14 changes: 13 additions & 1 deletion scripts/apidoc/typedoc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,10 +244,22 @@ export function extractRawDefault(reflection?: CommentHolder): string {
*
* @param reflection The reflection to extract the examples from.
*/
export function extractRawExamples(reflection?: CommentHolder): string[] {
function extractRawExamples(reflection?: CommentHolder): string[] {
return extractRawCode('@example', reflection);
}

/**
* Extracts the examples from the jsdocs without the surrounding md code block, then joins them with newlines and trims.
*
* @param reflection The reflection to extract the examples from.
*/
export function extractJoinedRawExamples(
reflection?: CommentHolder
): string | undefined {
const examples = extractRawExamples(reflection);
return examples.length === 0 ? undefined : examples.join('\n').trim();
}

/**
* Extracts all the `@see` references from the jsdocs separately.
*
Expand Down
12 changes: 12 additions & 0 deletions test/scripts/apidoc/__snapshots__/module.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`module > analyzeModule() > ModuleExampleTest 1`] = `
{
"comment": "This is a description for a module with a code example",
"deprecated": undefined,
"examples": "<div class=\\"language-ts\\"><button title=\\"Copy Code\\" class=\\"copy\\"></button><span class=\\"lang\\">ts</span><pre v-pre class=\\"shiki material-theme-palenight\\"><code><span class=\\"line\\"><span style=\\"color:#89DDFF\\">new</span><span style=\\"color:#BABED8\\"> </span><span style=\\"color:#82AAFF\\">ModuleExampleTest</span><span style=\\"color:#BABED8\\">()</span></span></code></pre>
</div>",
}
`;

exports[`module > analyzeModule() > ModuleFakerJsLinkTest 1`] = `
{
"comment": "Description with a link to our [website](/)
and [api docs](/api/).",
"deprecated": undefined,
"examples": undefined,
}
`;

Expand All @@ -13,11 +23,13 @@ exports[`module > analyzeModule() > ModuleNextFakerJsLinkTest 1`] = `
"comment": "Description with a link to our [website](/)
and [api docs](/api/).",
"deprecated": undefined,
"examples": undefined,
}
`;

exports[`module > analyzeModule() > expected and actual modules are equal 1`] = `
[
"ModuleExampleTest",
"ModuleFakerJsLinkTest",
"ModuleNextFakerJsLinkTest",
]
Expand Down
8 changes: 8 additions & 0 deletions test/scripts/apidoc/module.example.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,11 @@ export class ModuleFakerJsLinkTest {}
* and [api docs](https://next.fakerjs.dev/api/).
*/
export class ModuleNextFakerJsLinkTest {}

/**
* This is a description for a module with a code example
*
* @example
* new ModuleExampleTest()
*/
export class ModuleExampleTest {}
6 changes: 3 additions & 3 deletions test/scripts/apidoc/verify-jsdoc-tags.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { analyzeSignature } from '../../../scripts/apidoc/signature';
import {
extractDeprecated,
extractDescription,
extractJoinedRawExamples,
extractModuleFieldName,
extractRawExamples,
extractSeeAlsos,
extractSince,
extractTagContent,
Expand Down Expand Up @@ -110,7 +110,7 @@ describe('verify JSDoc tags', () => {
// Write temp files to disk

// Extract examples and make them runnable
const examples = extractRawExamples(signature).join('').trim();
const examples = extractJoinedRawExamples(signature);

// Save examples to a file to run them later in the specific tests
const dir = resolveDirToModule(moduleName);
Expand All @@ -135,7 +135,7 @@ describe('verify JSDoc tags', () => {

it('verify @example tag', async () => {
// Extract the examples
const examples = extractRawExamples(signature).join('').trim();
const examples = extractJoinedRawExamples(signature);

expect(
examples,
Expand Down

0 comments on commit 8e4172b

Please sign in to comment.