fix(doclint): support lists in comments (#1492)

Adds logging comments to the doclint tests, and adds a new one with a bulleted list in a comment. Lists can only be used in comments where extra properties would be unexpected.
This commit is contained in:
Joel Einbinder 2020-03-23 14:50:32 -07:00 committed by GitHub
parent 63906454a7
commit 1a25a4efcf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 70 additions and 8 deletions

View File

@ -30,9 +30,8 @@ class MDOutline {
const writer = new commonmark.HtmlRenderer(); const writer = new commonmark.HtmlRenderer();
const html = writer.render(parsed); const html = writer.render(parsed);
page.on('console', msg => { const logConsole = msg => console.log(msg.text());
console.log(msg.text()); page.on('console', logConsole);
});
// Extract headings. // Extract headings.
await page.setContent(html); await page.setContent(html);
const {classes, errors} = await page.evaluate(() => { const {classes, errors} = await page.evaluate(() => {
@ -56,9 +55,11 @@ class MDOutline {
const name = str.substring(0, str.indexOf('<')).replace(/\`/g, '').trim(); const name = str.substring(0, str.indexOf('<')).replace(/\`/g, '').trim();
const type = findType(str); const type = findType(str);
const properties = []; const properties = [];
const comment = str.substring(str.indexOf('<') + type.length + 2).trim(); let comment = str.substring(str.indexOf('<') + type.length + 2).trim();
const hasNonEnumProperties = type.split('|').some(part => { const hasNonEnumProperties = type.split('|').some(part => {
return part !== 'string' && part !== 'number' && part !== 'Array<string>' && !(part[0] === '"' && part[part.length - 1] === '"'); const basicTypes = new Set(['string', 'number', 'boolean']);
const arrayTypes = new Set([...basicTypes].map(type => `Array<${type}>`));
return !basicTypes.has(part) && !arrayTypes.has(part) && !(part.startsWith('"') && part.endsWith('"'));
}); });
if (hasNonEnumProperties) { if (hasNonEnumProperties) {
for (const childElement of element.querySelectorAll(':scope > ul > li')) { for (const childElement of element.querySelectorAll(':scope > ul > li')) {
@ -77,6 +78,8 @@ class MDOutline {
property.required = true; property.required = true;
properties.push(property); properties.push(property);
} }
} else if (ul) {
comment += '\n' + parseComment(ul).split('\n').map(l => ` - ${l}`).join('\n');
} }
return { return {
name, name,
@ -214,6 +217,7 @@ class MDOutline {
return fragment; return fragment;
} }
}); });
page.off('console', logConsole);
return new MDOutline(classes, errors); return new MDOutline(classes, errors);
} }

View File

@ -0,0 +1,15 @@
### class: Foo
#### foo.method(arg1, arg2)
- `arg1` <[string]> A single line argument comment
- `arg2` <[string]> A multiline argument comment:
- it could be this
- or it could be that
- returns: <[Promise]<[ElementHandle]>>
The method does something.
[string]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type "String"
[Promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise "Promise"
[ElementHandle]: # "ElementHandle"
[ElementHandle]: # "Frame"

View File

@ -0,0 +1,35 @@
{
"classes": [
{
"name": "Foo",
"members": [
{
"name": "method",
"type": {
"name": "Promise<ElementHandle>"
},
"kind": "method",
"comment": "The method does something.",
"args": [
{
"name": "arg1",
"type": {
"name": "string"
},
"kind": "property",
"comment": "A single line argument comment"
},
{
"name": "arg2",
"type": {
"name": "string"
},
"kind": "property",
"comment": "A multiline argument comment:\n - it could be this\n - or it could be that"
}
]
}
]
}
]
}

View File

@ -2,13 +2,15 @@
"classes": [ "classes": [
{ {
"name": "Foo", "name": "Foo",
"comment": "This is a class.",
"members": [ "members": [
{ {
"name": "frame", "name": "frame",
"type": { "type": {
"name": "[Frame]" "name": "[Frame]"
}, },
"kind": "event" "kind": "event",
"comment": "This event is dispatched."
}, },
{ {
"name": "$", "name": "$",
@ -16,13 +18,15 @@
"name": "Promise<ElementHandle>" "name": "Promise<ElementHandle>"
}, },
"kind": "method", "kind": "method",
"comment": "The method runs document.querySelector.",
"args": [ "args": [
{ {
"name": "selector", "name": "selector",
"type": { "type": {
"name": "string" "name": "string"
}, },
"kind": "property" "kind": "property",
"comment": "A selector to query page for"
} }
] ]
}, },
@ -31,7 +35,8 @@
"type": { "type": {
"name": "string" "name": "string"
}, },
"kind": "property" "kind": "property",
"comment": "Contains the URL of the request."
} }
] ]
} }

View File

@ -55,6 +55,7 @@ describe('checkPublicAPI', function() {
it('js-builder-common', testJSBuilder); it('js-builder-common', testJSBuilder);
it('js-builder-inheritance', testJSBuilder); it('js-builder-inheritance', testJSBuilder);
it('md-builder-common', testMDBuilder); it('md-builder-common', testMDBuilder);
it('md-builder-comments', testMDBuilder);
}); });
runner.run(); runner.run();
@ -101,6 +102,7 @@ function serialize(doc) {
const result = { const result = {
classes: doc.classesArray.map(cls => ({ classes: doc.classesArray.map(cls => ({
name: cls.name, name: cls.name,
comment: cls.comment || undefined,
members: cls.membersArray.map(serializeMember) members: cls.membersArray.map(serializeMember)
})) }))
}; };
@ -114,6 +116,7 @@ function serializeMember(member) {
name: member.name, name: member.name,
type: serializeType(member.type), type: serializeType(member.type),
kind: member.kind, kind: member.kind,
comment: member.comment || undefined,
args: member.argsArray.length ? member.argsArray.map(serializeMember) : undefined args: member.argsArray.length ? member.argsArray.map(serializeMember) : undefined
} }
} }