Skip to content

Commit f59e2af

Browse files
authored
chore: Update new test-utils documenter (#83)
1 parent 3913223 commit f59e2af

File tree

8 files changed

+133
-58
lines changed

8 files changed

+133
-58
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,26 @@
11
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33
export class TestUtilWrapper {
4+
/**
5+
* Generic return value
6+
*/
47
findAll(): Array<HTMLElement> {
58
return [];
69
}
710

11+
/**
12+
* Generic arguments
13+
*/
814
setAll(all: Array<HTMLElement>) {}
15+
16+
/**
17+
* Method overload example
18+
*/
19+
keydown(keyCode: number): void;
20+
keydown(keyboardEventProps: KeyboardEventInit): void;
21+
keydown(args: KeyboardEventInit | number) {}
22+
}
23+
24+
export default function createWrapper() {
25+
return new TestUtilWrapper();
926
}

src/test-utils-new/extractor.ts

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ function getDefaultValue(declaration: ts.Declaration) {
2525
return declaration.initializer.getText();
2626
}
2727

28-
export default function extractDocumentation(sourceFile: ts.SourceFile, checker: ts.TypeChecker): Array<TestUtilsDoc> {
28+
export default function extractDocumentation(
29+
sourceFile: ts.SourceFile,
30+
checker: ts.TypeChecker,
31+
extraExports: Array<string>
32+
): Array<TestUtilsDoc> {
2933
const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
3034
if (!moduleSymbol) {
3135
throw new Error(`Unable to resolve module: ${sourceFile.fileName}`);
@@ -35,14 +39,21 @@ export default function extractDocumentation(sourceFile: ts.SourceFile, checker:
3539
const definitions: Array<TestUtilsDoc> = [];
3640

3741
for (const symbol of exportSymbols) {
42+
const className = symbol.getName();
43+
if (extraExports.includes(className)) {
44+
continue;
45+
}
3846
if (!(symbol.flags & ts.SymbolFlags.Class)) {
3947
throw new Error(`Exported symbol is not a class, got ${checker.symbolToString(symbol)}`);
4048
}
41-
const className = symbol.getName();
49+
4250
const classType = checker.getTypeAtLocation(extractDeclaration(symbol));
4351
const classDefinition: TestUtilsDoc = { name: className, methods: [] };
4452
for (const property of classType.getProperties()) {
45-
const declaration = extractDeclaration(property);
53+
const declaration = property.valueDeclaration;
54+
if (!declaration) {
55+
throw new Error(`Unexpected member on ${className}${property.getName()}`);
56+
}
4657
const modifiers = (ts.canHaveModifiers(declaration) && ts.getModifiers(declaration)) || [];
4758
if (
4859
modifiers.find(
@@ -52,26 +63,25 @@ export default function extractDocumentation(sourceFile: ts.SourceFile, checker:
5263
continue;
5364
}
5465
const type = checker.getTypeAtLocation(declaration);
55-
if (type.getCallSignatures().length !== 1) {
56-
throw new Error(`Unexpected member on ${className}${property.getName()}: ${stringifyType(type, checker)}`);
66+
for (const signature of type.getCallSignatures()) {
67+
// report each function signature as a separate method
68+
classDefinition.methods.push({
69+
name: property.getName(),
70+
description: getDescription(property.getDocumentationComment(checker), declaration).text,
71+
returnType: { name: stringifyType(signature.getReturnType(), checker) },
72+
parameters: signature.parameters.map(parameter => {
73+
const paramType = checker.getTypeAtLocation(extractDeclaration(parameter));
74+
return {
75+
name: parameter.name,
76+
typeName: stringifyType(paramType, checker),
77+
description: getDescription(parameter.getDocumentationComment(checker), declaration).text,
78+
flags: { isOptional: isOptional(paramType) },
79+
defaultValue: getDefaultValue(extractDeclaration(parameter)),
80+
};
81+
}),
82+
inheritedFrom: getInheritedFrom(declaration, className),
83+
});
5784
}
58-
const returnType = type.getCallSignatures()[0].getReturnType();
59-
classDefinition.methods.push({
60-
name: property.getName(),
61-
description: getDescription(property.getDocumentationComment(checker), declaration).text,
62-
inheritedFrom: getInheritedFrom(declaration, className),
63-
parameters: type.getCallSignatures()[0].parameters.map(parameter => {
64-
const paramType = checker.getTypeAtLocation(extractDeclaration(parameter));
65-
return {
66-
name: parameter.name,
67-
typeName: stringifyType(paramType, checker),
68-
description: getDescription(parameter.getDocumentationComment(checker), declaration).text,
69-
flags: { isOptional: isOptional(paramType) },
70-
defaultValue: getDefaultValue(extractDeclaration(parameter)),
71-
};
72-
}),
73-
returnType: { name: stringifyType(returnType, checker) },
74-
});
7585
}
7686
classDefinition.methods.sort((a, b) => a.name.localeCompare(b.name));
7787

src/test-utils-new/index.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,15 @@ import { bootstrapTypescriptProject } from '../bootstrap/typescript';
66
import extractDocumentation from './extractor';
77
import { TestUtilsDoc } from '../test-utils/interfaces';
88

9+
export interface TestUtilsVariantOptions {
10+
root: string;
11+
extraExports?: Array<string>;
12+
}
13+
914
export interface TestUtilsDocumenterOptions {
1015
tsconfigPath: string;
11-
domUtilsRoot: string;
12-
selectorsUtilsRoot: string;
16+
domUtils: TestUtilsVariantOptions;
17+
selectorsUtils: TestUtilsVariantOptions;
1318
}
1419

1520
interface TestUtilsDefinitions {
@@ -18,8 +23,8 @@ interface TestUtilsDefinitions {
1823
}
1924

2025
export function documentTestUtilsNew(options: TestUtilsDocumenterOptions): TestUtilsDefinitions {
21-
const domUtilsRoot = pathe.resolve(options.domUtilsRoot);
22-
const selectorsUtilsRoot = pathe.resolve(options.selectorsUtilsRoot);
26+
const domUtilsRoot = pathe.resolve(options.domUtils.root);
27+
const selectorsUtilsRoot = pathe.resolve(options.selectorsUtils.root);
2328
const program = bootstrapTypescriptProject(options.tsconfigPath);
2429
const checker = program.getTypeChecker();
2530

@@ -33,8 +38,8 @@ export function documentTestUtilsNew(options: TestUtilsDocumenterOptions): TestU
3338
throw new Error(`File '${selectorsUtilsFile}' not found`);
3439
}
3540
return {
36-
domDefinitions: extractDocumentation(domUtilsFile, checker),
37-
selectorsDefinitions: extractDocumentation(selectorsUtilsFile, checker),
41+
domDefinitions: extractDocumentation(domUtilsFile, checker, options.domUtils.extraExports ?? []),
42+
selectorsDefinitions: extractDocumentation(selectorsUtilsFile, checker, options.selectorsUtils.extraExports ?? []),
3843
};
3944
}
4045

test/test-utils/__snapshots__/doc-generation.test.ts.snap

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,70 @@ exports[`Generate documentation > For simple cases 1`] = `
1717
exports[`Generate documentation > deal with more complex types 1`] = `
1818
[
1919
{
20-
"defaultValue": undefined,
21-
"description": undefined,
22-
"flags": {
23-
"isOptional": false,
20+
"description": "Generic return value",
21+
"inheritedFrom": undefined,
22+
"name": "findAll",
23+
"parameters": [],
24+
"returnType": {
25+
"name": "Array<HTMLElement>",
26+
},
27+
},
28+
{
29+
"description": "Method overload example",
30+
"inheritedFrom": undefined,
31+
"name": "keydown",
32+
"parameters": [
33+
{
34+
"defaultValue": undefined,
35+
"description": undefined,
36+
"flags": {
37+
"isOptional": false,
38+
},
39+
"name": "keyCode",
40+
"typeName": "number",
41+
},
42+
],
43+
"returnType": {
44+
"name": "void",
45+
},
46+
},
47+
{
48+
"description": "Method overload example",
49+
"inheritedFrom": undefined,
50+
"name": "keydown",
51+
"parameters": [
52+
{
53+
"defaultValue": undefined,
54+
"description": undefined,
55+
"flags": {
56+
"isOptional": false,
57+
},
58+
"name": "keyboardEventProps",
59+
"typeName": "KeyboardEventInit",
60+
},
61+
],
62+
"returnType": {
63+
"name": "void",
64+
},
65+
},
66+
{
67+
"description": "Generic arguments",
68+
"inheritedFrom": undefined,
69+
"name": "setAll",
70+
"parameters": [
71+
{
72+
"defaultValue": undefined,
73+
"description": undefined,
74+
"flags": {
75+
"isOptional": false,
76+
},
77+
"name": "all",
78+
"typeName": "Array<HTMLElement>",
79+
},
80+
],
81+
"returnType": {
82+
"name": "void",
2483
},
25-
"name": "all",
26-
"typeName": "Array<HTMLElement>",
2784
},
2885
]
2986
`;

test/test-utils/doc-generation.test.ts

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,29 +49,16 @@ describe('Generate documentation', () => {
4949
});
5050

5151
test('deal with more complex types', () => {
52-
const results = buildTestUtilsProject('advanced-types');
52+
const results = buildTestUtilsProject('advanced-types', { extraExports: ['default'] });
5353

5454
expect(results.length).toBe(1);
5555
const classDoc = results[0];
5656

5757
expect(classDoc.name).toBe('TestUtilWrapper');
5858

5959
const methods = classDoc.methods;
60-
expect(methods.length).toBe(2);
61-
62-
const findAllMethod = methods.find(method => method.name === 'findAll');
63-
expect(findAllMethod).toBeDefined();
64-
expect(findAllMethod?.returnType).toEqual({ name: 'Array<HTMLElement>' });
65-
expect(findAllMethod?.parameters).toEqual([]);
66-
expect(findAllMethod?.description).toBeUndefined();
67-
expect(findAllMethod?.inheritedFrom).toBeUndefined();
68-
69-
const setAllMethod = methods.find(method => method.name === 'setAll');
70-
expect(setAllMethod).toBeDefined();
71-
expect(setAllMethod?.returnType).toEqual({ name: 'void' });
72-
expect(setAllMethod?.parameters).toMatchSnapshot();
73-
expect(setAllMethod?.description).toBeUndefined();
74-
expect(setAllMethod?.inheritedFrom).toBeUndefined();
60+
expect(methods.length).toBe(4);
61+
expect(methods).toMatchSnapshot();
7562
});
7663

7764
test('and deal with inheritance', () => {

test/test-utils/test-helpers.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
3-
import { documentTestUtilsNew, TestUtilsDocumenterOptions } from '../../src/test-utils-new';
3+
import { documentTestUtilsNew, TestUtilsVariantOptions } from '../../src/test-utils-new';
44
import { TestUtilsDoc } from '../../src/test-utils/interfaces';
55

66
export function buildTestUtilsProject(
77
name: string,
8-
configOverrides?: Partial<TestUtilsDocumenterOptions>
8+
configOverrides?: Partial<TestUtilsVariantOptions>
99
): TestUtilsDoc[] {
1010
return documentTestUtilsNew({
1111
tsconfigPath: require.resolve(`../../fixtures/test-utils/${name}/tsconfig.json`),
12-
domUtilsRoot: `fixtures/test-utils/${name}/index.ts`,
13-
selectorsUtilsRoot: `fixtures/test-utils/${name}/index.ts`,
14-
...configOverrides,
12+
domUtils: { root: `fixtures/test-utils/${name}/index.ts`, ...configOverrides },
13+
selectorsUtils: { root: `fixtures/test-utils/${name}/index.ts`, ...configOverrides },
1514
}).domDefinitions;
1615
}

test/test-utils/usage.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ describe('documentTestUtils throws error for ', () => {
1919
test('having no input files because of a non-matching glob', () => {
2020
expect(() =>
2121
buildTestUtilsProject('simple', {
22-
domUtilsRoot: 'fixtures/does-not-exist/index.ts',
22+
root: 'fixtures/does-not-exist/index.ts',
2323
})
2424
).toThrow(/File '.*fixtures\/does-not-exist\/index.ts' not found/);
2525
});

test/test-utils/writer.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ test('should write documentation files into the outDir', async () => {
1414

1515
writeTestUtilsDocumentation({
1616
tsconfigPath: pathe.resolve('fixtures/test-utils/simple/tsconfig.json'),
17-
domUtilsRoot: 'fixtures/test-utils/simple/index.ts',
18-
selectorsUtilsRoot: 'fixtures/test-utils/simple/index.ts',
17+
domUtils: { root: 'fixtures/test-utils/simple/index.ts' },
18+
selectorsUtils: { root: 'fixtures/test-utils/simple/index.ts' },
1919
outDir,
2020
});
2121

0 commit comments

Comments
 (0)