From e6d27a353ec9c82e60b31c8d833768141beb4dab Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Sat, 28 Dec 2024 04:25:06 +0100 Subject: docs(api): add refresh button to examples (#3301) * docs(api): add refresh button to examples * chore: improve button behavior slightly * chore: improve output format * chore: ignore examples without recordable results * temp * chore: use svg button * chore: use json5 format for test * chore: simplify result formatting * test: add formatting tests * test: add e2e refresh test * test: use static test values * chore: fix regex * chore: simplify refresh placeholder * Update cypress/e2e/example-refresh.cy.ts * fix: handle property after function call * Apply suggestions from code review Co-authored-by: Shinigami * Apply suggestions from code review Co-authored-by: Shinigami * Apply suggestions from code review Co-authored-by: Shinigami * chore: format * chore: add comment --------- Co-authored-by: Shinigami --- test/docs/__snapshots__/format.spec.ts.snap | 19 ++++ test/docs/format.spec.ts | 69 +++++++++++++ .../apidocs/__snapshots__/page.spec.ts.snap | 97 ++++++++++++++++++ test/scripts/apidocs/page.spec.ts | 114 +++++++++++++++++++++ 4 files changed, 299 insertions(+) create mode 100644 test/docs/__snapshots__/format.spec.ts.snap create mode 100644 test/docs/format.spec.ts create mode 100644 test/scripts/apidocs/__snapshots__/page.spec.ts.snap create mode 100644 test/scripts/apidocs/page.spec.ts (limited to 'test') diff --git a/test/docs/__snapshots__/format.spec.ts.snap b/test/docs/__snapshots__/format.spec.ts.snap new file mode 100644 index 00000000..36679523 --- /dev/null +++ b/test/docs/__snapshots__/format.spec.ts.snap @@ -0,0 +1,19 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`formatResult > should format Date 1`] = `"'2025-01-01T00:00:00.000Z'"`; + +exports[`formatResult > should format array 1`] = `"[ 1, '2' ]"`; + +exports[`formatResult > should format bigint 1`] = `"135464154865415n"`; + +exports[`formatResult > should format number 1`] = `"123"`; + +exports[`formatResult > should format object 1`] = `"{ 'a': 1, 'b': '2' }"`; + +exports[`formatResult > should format string 1`] = `"'a simple string'"`; + +exports[`formatResult > should format string with new lines 1`] = `"'string\\nwith\\nnew\\nlines'"`; + +exports[`formatResult > should format string with special characters 1`] = `"'string with "special" characters'"`; + +exports[`formatResult > should format undefined 1`] = `"undefined"`; diff --git a/test/docs/format.spec.ts b/test/docs/format.spec.ts new file mode 100644 index 00000000..bc4a0d66 --- /dev/null +++ b/test/docs/format.spec.ts @@ -0,0 +1,69 @@ +import { describe, expect, it } from 'vitest'; +import { formatResult } from '../../docs/.vitepress/components/api-docs/format'; + +describe('formatResult', () => { + it('should format undefined', () => { + const value = undefined; + const actual = formatResult(value); + + expect(actual).toBeTypeOf('string'); + expect(actual).toBe('undefined'); + expect(actual).toMatchSnapshot(); + }); + + it('should format bigint', () => { + const actual = formatResult(135464154865415n); + + expect(actual).toBeTypeOf('string'); + expect(actual).toMatchSnapshot(); + }); + + it('should format object', () => { + const actual = formatResult({ a: 1, b: '2' }); + + expect(actual).toBeTypeOf('string'); + expect(actual).toMatchSnapshot(); + }); + + it('should format array', () => { + const actual = formatResult([1, '2']); + + expect(actual).toBeTypeOf('string'); + expect(actual).toMatchSnapshot(); + }); + + it('should format string', () => { + const actual = formatResult('a simple string'); + + expect(actual).toBeTypeOf('string'); + expect(actual).toMatchSnapshot(); + }); + + it('should format string with special characters', () => { + const actual = formatResult('string with "special" characters'); + + expect(actual).toBeTypeOf('string'); + expect(actual).toMatchSnapshot(); + }); + + it('should format string with new lines', () => { + const actual = formatResult('string\nwith\nnew\nlines'); + + expect(actual).toBeTypeOf('string'); + expect(actual).toMatchSnapshot(); + }); + + it('should format number', () => { + const actual = formatResult(123); + + expect(actual).toBeTypeOf('string'); + expect(actual).toMatchSnapshot(); + }); + + it('should format Date', () => { + const actual = formatResult(new Date(Date.UTC(2025, 0, 1))); + + expect(actual).toBeTypeOf('string'); + expect(actual).toMatchSnapshot(); + }); +}); diff --git a/test/scripts/apidocs/__snapshots__/page.spec.ts.snap b/test/scripts/apidocs/__snapshots__/page.spec.ts.snap new file mode 100644 index 00000000..4824c101 --- /dev/null +++ b/test/scripts/apidocs/__snapshots__/page.spec.ts.snap @@ -0,0 +1,97 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`toRefreshFunction > should handle multiline calls 1`] = ` +"async (): Promise => { + await enableFaker(); + faker.seed(); + faker.setDefaultRefDate(); + const result: unknown[] = []; + + try { + result.push( + faker.number.int({ + min: 1, + max: 10, + }) + ); + } catch (error: unknown) { + result.push(error instanceof Error ? error.name : 'Error'); + } + + return result; +}" +`; + +exports[`toRefreshFunction > should handle multiple calls 1`] = ` +"async (): Promise => { + await enableFaker(); + faker.seed(); + faker.setDefaultRefDate(); + const result: unknown[] = []; + + try { + result.push(faker.number.int()); + } catch (error: unknown) { + result.push(error instanceof Error ? error.name : 'Error'); + } + + try { + result.push(faker.number.int()); + } catch (error: unknown) { + result.push(error instanceof Error ? error.name : 'Error'); + } + + return result; +}" +`; + +exports[`toRefreshFunction > should handle properties after calls 1`] = ` +"async (): Promise => { + await enableFaker(); + faker.seed(); + faker.setDefaultRefDate(); + const result: unknown[] = []; + + try { + result.push(faker.airline.airport().name); + } catch (error: unknown) { + result.push(error instanceof Error ? error.name : 'Error'); + } + + return result; +}" +`; + +exports[`toRefreshFunction > should handle single line calls with semicolon 1`] = ` +"async (): Promise => { + await enableFaker(); + faker.seed(); + faker.setDefaultRefDate(); + const result: unknown[] = []; + + try { + result.push(faker.number.int()); + } catch (error: unknown) { + result.push(error instanceof Error ? error.name : 'Error'); + } + + return result; +}" +`; + +exports[`toRefreshFunction > should handle single line calls without semicolon 1`] = ` +"async (): Promise => { + await enableFaker(); + faker.seed(); + faker.setDefaultRefDate(); + const result: unknown[] = []; + + try { + result.push(faker.number.int()); + } catch (error: unknown) { + result.push(error instanceof Error ? error.name : 'Error'); + } + + return result; +}" +`; diff --git a/test/scripts/apidocs/page.spec.ts b/test/scripts/apidocs/page.spec.ts new file mode 100644 index 00000000..00fd4da2 --- /dev/null +++ b/test/scripts/apidocs/page.spec.ts @@ -0,0 +1,114 @@ +import { describe, expect, it } from 'vitest'; +import { toRefreshFunction } from '../../../scripts/apidocs/output/page'; +import type { RawApiDocsMethod } from '../../../scripts/apidocs/processing/method'; +import type { RawApiDocsSignature } from '../../../scripts/apidocs/processing/signature'; + +function newTestMethod( + signature: Partial +): RawApiDocsMethod { + return { + name: 'test', + signatures: [ + { + deprecated: 'deprecated', + description: 'description', + since: 'since', + parameters: [], + returns: { + type: 'simple', + text: 'returns', + }, + throws: [], + signature: 'signature', + examples: [], + seeAlsos: [], + ...signature, + }, + ], + source: { + filePath: 'test/page.spec.ts', + line: 1, + column: 1, + }, + }; +} + +describe('toRefreshFunction', () => { + it("should return 'undefined' when there are no faker calls", async () => { + // given + const method = newTestMethod({ + examples: ['const a = 1;'], + }); + + // when + const result = await toRefreshFunction(method); + + // then + expect(result).toBe('undefined'); + }); + + it('should handle single line calls with semicolon', async () => { + // given + const method = newTestMethod({ + examples: ['faker.number.int(); // 834135'], + }); + + // when + const result = await toRefreshFunction(method); + + // then + expect(result).toMatchSnapshot(); + }); + + it('should handle single line calls without semicolon', async () => { + // given + const method = newTestMethod({ + examples: ['faker.number.int() // 834135'], + }); + + // when + const result = await toRefreshFunction(method); + + // then + expect(result).toMatchSnapshot(); + }); + + it('should handle multiple calls', async () => { + // given + const method = newTestMethod({ + examples: ['faker.number.int()', 'faker.number.int()'], + }); + + // when + const result = await toRefreshFunction(method); + + // then + expect(result).toMatchSnapshot(); + }); + + it('should handle multiline calls', async () => { + // given + const method = newTestMethod({ + examples: 'faker.number.int({\n min: 1,\n max: 10\n})'.split('\n'), + }); + + // when + const result = await toRefreshFunction(method); + + // then + expect(result).toMatchSnapshot(); + }); + + it('should handle properties after calls', async () => { + // given + const method = newTestMethod({ + examples: ['faker.airline.airport().name'], + }); + + // when + const result = await toRefreshFunction(method); + + // then + expect(result).toMatchSnapshot(); + }); +}); -- cgit v1.2.3