diff --git a/test/scripts/apidoc/.gitignore b/test/scripts/apidoc/.gitignore new file mode 100644 index 00000000000..b0645e5bd67 --- /dev/null +++ b/test/scripts/apidoc/.gitignore @@ -0,0 +1 @@ +*.actuals.json diff --git a/test/scripts/apidoc/signature.example.ts b/test/scripts/apidoc/signature.example.ts new file mode 100644 index 00000000000..8f1ada32f4d --- /dev/null +++ b/test/scripts/apidoc/signature.example.ts @@ -0,0 +1,88 @@ +export class SignatureTest { + /** + * Test with no parameters. + */ + noParamMethod(): number { + return 0; + } + + /** + * Test with a required parameter. + * + * @param a The number parameter. + */ + requiredNumberParamMethod(a: number): number { + return a; + } + + /** + * Test with an optional parameter. + * + * @param b The string parameter. + */ + optionalStringParamMethod(b?: string): number { + return +b; + } + + /** + * Test with a default parameter. + * + * @param c The boolean parameter. + */ + defaultBooleanParamMethod(c: boolean = true): number { + return c ? 1 : 0; + } + + /** + * Test with multiple parameters. + * + * @param a The number parameter. + * @param b The string parameter. + * @param c The boolean parameter. + */ + multiParamMethod(a: number, b?: string, c: boolean = true): number { + return c ? a : +b; + } + + /** + * Test with a function parameters. + * + * @param fn The function parameter. + */ + functionParamMethod(fn: (a: string) => number): number { + return fn('a'); + } + + /** + * Test with a function parameters. + * + * @param options The function parameter. + * @param options.a The number parameter. + * @param options.b The string parameter. + * @param options.c The boolean parameter. + */ + optionsParamMethod(options: { a: number; b?: string; c: boolean }): number { + return options.c ? options.a : +options.b; + } + + /** + * Test with example marker. + * + * @example + * test.apidoc.methodWithExample() // 0 + */ + methodWithExample(): number { + return 0; + } + + /** + * Test with deprecated and see marker. + * + * @see test.apidoc.methodWithExample() + * + * @deprecated + */ + methodWithDeprecated(): number { + return 0; + } +} diff --git a/test/scripts/apidoc/signature.expected.json b/test/scripts/apidoc/signature.expected.json new file mode 100644 index 00000000000..d0674899053 --- /dev/null +++ b/test/scripts/apidoc/signature.expected.json @@ -0,0 +1,155 @@ +{ + "noParamMethod": { + "name": "noParamMethod", + "title": "No Param Method", + "description": "

Test with no parameters.

\n", + "parameters": [], + "returns": "number", + "examples": "
faker.noParamMethod(): number\n
\n
", + "deprecated": false, + "seeAlsos": [] + }, + "defaultBooleanParamMethod": { + "name": "defaultBooleanParamMethod", + "title": "Default Boolean Param Method", + "description": "

Test with a default parameter.

\n", + "parameters": [ + { + "name": "c", + "type": "boolean", + "default": "true", + "description": "

The boolean parameter.

\n" + } + ], + "returns": "number", + "examples": "
faker.defaultBooleanParamMethod(c: boolean = true): number\n
\n
", + "deprecated": false, + "seeAlsos": [] + }, + "functionParamMethod": { + "name": "functionParamMethod", + "title": "Function Param Method", + "description": "

Test with a function parameters.

\n", + "parameters": [ + { + "name": "fn", + "type": "Function", + "description": "

The function parameter.

\n" + } + ], + "returns": "number", + "examples": "
faker.functionParamMethod(fn: Function): number\n
\n
", + "deprecated": false, + "seeAlsos": [] + }, + "methodWithDeprecated": { + "name": "methodWithDeprecated", + "title": "Method With Deprecated", + "description": "

Test with deprecated and see marker.

\n", + "parameters": [], + "returns": "number", + "examples": "
faker.methodWithDeprecated(): number\n
\n
", + "deprecated": true, + "seeAlsos": ["test.apidoc.methodWithExample()"] + }, + "methodWithExample": { + "name": "methodWithExample", + "title": "Method With Example", + "description": "

Test with example marker.

\n", + "parameters": [], + "returns": "number", + "examples": "
faker.methodWithExample(): number\ntest.apidoc.methodWithExample() // 0\n
\n
", + "deprecated": false, + "seeAlsos": [] + }, + "multiParamMethod": { + "name": "multiParamMethod", + "title": "Multi Param Method", + "description": "

Test with multiple parameters.

\n", + "parameters": [ + { + "name": "a", + "type": "number", + "description": "

The number parameter.

\n" + }, + { + "name": "b?", + "type": "string", + "description": "

The string parameter.

\n" + }, + { + "name": "c", + "type": "boolean", + "default": "true", + "description": "

The boolean parameter.

\n" + } + ], + "returns": "number", + "examples": "
faker.multiParamMethod(a: number, b?: string, c: boolean = true): number\n
\n
", + "deprecated": false, + "seeAlsos": [] + }, + "optionalStringParamMethod": { + "name": "optionalStringParamMethod", + "title": "Optional String Param Method", + "description": "

Test with an optional parameter.

\n", + "parameters": [ + { + "name": "b?", + "type": "string", + "description": "

The string parameter.

\n" + } + ], + "returns": "number", + "examples": "
faker.optionalStringParamMethod(b?: string): number\n
\n
", + "deprecated": false, + "seeAlsos": [] + }, + "optionsParamMethod": { + "name": "optionsParamMethod", + "title": "Options Param Method", + "description": "

Test with a function parameters.

\n", + "parameters": [ + { + "name": "options", + "type": "Object", + "description": "

The function parameter.

\n" + }, + { + "name": "options.a", + "type": "number", + "description": "

The number parameter.

\n" + }, + { + "name": "options.b?", + "type": "string", + "description": "

The string parameter.

\n" + }, + { + "name": "options.c", + "type": "boolean", + "description": "

The boolean parameter.

\n" + } + ], + "returns": "number", + "examples": "
faker.optionsParamMethod(options: Object): number\n
\n
", + "deprecated": false, + "seeAlsos": [] + }, + "requiredNumberParamMethod": { + "name": "requiredNumberParamMethod", + "title": "Required Number Param Method", + "description": "

Test with a required parameter.

\n", + "parameters": [ + { + "name": "a", + "type": "number", + "description": "

The number parameter.

\n" + } + ], + "returns": "number", + "examples": "
faker.requiredNumberParamMethod(a: number): number\n
\n
", + "deprecated": false, + "seeAlsos": [] + } +} diff --git a/test/scripts/apidoc/signature.spec.ts b/test/scripts/apidoc/signature.spec.ts new file mode 100644 index 00000000000..f536a219e47 --- /dev/null +++ b/test/scripts/apidoc/signature.spec.ts @@ -0,0 +1,53 @@ +import { writeFileSync } from 'fs'; +import { resolve } from 'path'; +import * as TypeDoc from 'typedoc'; +import { afterAll, describe, expect, it } from 'vitest'; +import type { Method } from '../../../docs/.vitepress/components/api-docs/method'; +import { analyzeSignature } from '../../../scripts/apidoc/signature'; +import expected_ from './signature.expected.json'; +const expected: Record = expected_; + +function prettyJson(object): string { + return JSON.stringify(object, null, 2); +} + +describe('signature', () => { + const app = new TypeDoc.Application(); + + app.options.addReader(new TypeDoc.TSConfigReader()); + + app.bootstrap({ + entryPoints: ['test/scripts/apidoc/signature.example.ts'], + tsconfig: 'test/scripts/apidoc/tsconfig.json', + }); + + const methods: Record = app + .convert() + .getChildrenByKind(TypeDoc.ReflectionKind.Class)[0] + .getChildrenByKind(TypeDoc.ReflectionKind.Method) + .reduce((a, v) => ({ ...a, [v.name]: v }), {}); + + describe('analyzeSignature()', () => { + const actuals = {}; + + it('expected and actual methods are equal', () => { + expect(Object.keys(methods).sort()).toEqual(Object.keys(expected).sort()); + }); + + it.each(Object.keys(expected))('%s', (name) => { + const method = methods[name]; + const actual = analyzeSignature(method.signatures[0], null, method.name); + actuals[name] = actual; + + expect(prettyJson(actual)).toBe(prettyJson(expected[name])); + }); + + afterAll(() => { + // Write to file for easier comparison + writeFileSync( + resolve('test', 'scripts', 'apidoc', 'signature.actuals.json'), + prettyJson(actuals) + ); + }); + }); +}); diff --git a/test/scripts/apidoc/tsconfig.json b/test/scripts/apidoc/tsconfig.json new file mode 100644 index 00000000000..ebc4e81722b --- /dev/null +++ b/test/scripts/apidoc/tsconfig.json @@ -0,0 +1,3 @@ +{ + "include": ["signature.example.ts"] +}