build(aio): fail doc-gen if a code-example is badly formatted.
This will catch the problem that was missed in https://github.com/angular/angular/pull/19845#issuecomment-338626662
This commit is contained in:
parent
5b16ce9302
commit
0355142737
|
@ -12,16 +12,43 @@ module.exports = function renderExamples(getExampleRegion) {
|
||||||
docs.forEach(doc => {
|
docs.forEach(doc => {
|
||||||
if (doc.renderedContent) {
|
if (doc.renderedContent) {
|
||||||
// We match either `code-example` or `code-pane` elements that have a path attribute
|
// We match either `code-example` or `code-pane` elements that have a path attribute
|
||||||
doc.renderedContent = doc.renderedContent.replace(/<(code-example|code-pane)([^>]*)>[^<]*<\/\1>/g, (original, element, attributes) => {
|
doc.renderedContent = doc.renderedContent.replace(
|
||||||
const attrMap = parseAttributes(attributes);
|
/<(code-example|code-pane)([^>]*)>[^<]*<\/([^>]+)>/g,
|
||||||
if (attrMap.path) {
|
(original, openingTag, attributes, closingTag) => {
|
||||||
// We found a path attribute so look up the example and rebuild the HTML
|
const attrMap = parseAttributes(attributes);
|
||||||
const exampleContent = getExampleRegion(doc, attrMap.path, attrMap.region);
|
if (attrMap.path) {
|
||||||
return `<${element}${renderAttributes(attrMap)}>\n${exampleContent}\n</${element}>`;
|
if (closingTag !== openingTag) {
|
||||||
}
|
// The markdown renderer will wrap what it thinks is a paragraph in `<p>` and `</p>` tags.
|
||||||
// No path attribute so just ignore this one
|
// If you do not leave a blank line between a paragraph of text and a `<code-example>` then
|
||||||
return original;
|
// the markdown renderer may add a paragraph marker "in-between" the opening and closing
|
||||||
});
|
// tags of the code-example. For example:
|
||||||
|
//
|
||||||
|
// ```
|
||||||
|
// Some paragraph
|
||||||
|
// <code-example path="...">
|
||||||
|
//
|
||||||
|
// </code-example>
|
||||||
|
// ```
|
||||||
|
//
|
||||||
|
// will be rendered as:
|
||||||
|
//
|
||||||
|
// ```
|
||||||
|
// <p>Some paragraph
|
||||||
|
// <code-example path="...">
|
||||||
|
// </p>
|
||||||
|
// </code-example>
|
||||||
|
// ```
|
||||||
|
throw new Error(
|
||||||
|
'Badly formed example: ' + original + ' - closing tag does not match opening tag.\n' +
|
||||||
|
' - Perhaps you forgot to put a blank line before the example?');
|
||||||
|
}
|
||||||
|
// We found a path attribute so look up the example and rebuild the HTML
|
||||||
|
const exampleContent = getExampleRegion(doc, attrMap.path, attrMap.region);
|
||||||
|
return `<${openingTag}${renderAttributes(attrMap)}>\n${exampleContent}\n</${openingTag}>`;
|
||||||
|
}
|
||||||
|
// No path attribute so just ignore this one
|
||||||
|
return original;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,10 +34,10 @@ describe('renderExamples processor', () => {
|
||||||
describe(CODE_TAG, () => {
|
describe(CODE_TAG, () => {
|
||||||
it(`should ignore a <${CODE_TAG}> tags with no path attribute`, () => {
|
it(`should ignore a <${CODE_TAG}> tags with no path attribute`, () => {
|
||||||
const docs = [
|
const docs = [
|
||||||
{ renderedContent: `Some text\n<${CODE_TAG}>Some code</${CODE_TAG}>\n<${CODE_TAG} class="anti-pattern" title="Bad Code">do not do this</${CODE_TAG}>` }
|
{ renderedContent: `Some text\n<${CODE_TAG}>Some code</${CODE_TAG}>\n<${CODE_TAG} class="anti-pattern" title="Bad Code">do <strong>not</strong> do this</${CODE_TAG}>` }
|
||||||
];
|
];
|
||||||
processor.$process(docs);
|
processor.$process(docs);
|
||||||
expect(docs[0].renderedContent).toEqual(`Some text\n<${CODE_TAG}>Some code</${CODE_TAG}>\n<${CODE_TAG} class="anti-pattern" title="Bad Code">do not do this</${CODE_TAG}>`);
|
expect(docs[0].renderedContent).toEqual(`Some text\n<${CODE_TAG}>Some code</${CODE_TAG}>\n<${CODE_TAG} class="anti-pattern" title="Bad Code">do <strong>not</strong> do this</${CODE_TAG}>`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should replace the content of the <${CODE_TAG}> tag with the whole contents from an example file if a path is provided`, () => {
|
it(`should replace the content of the <${CODE_TAG}> tag with the whole contents from an example file if a path is provided`, () => {
|
||||||
|
@ -88,6 +88,15 @@ describe('renderExamples processor', () => {
|
||||||
processor.$process(docs);
|
processor.$process(docs);
|
||||||
expect(docs[0].renderedContent).toEqual(`<${CODE_TAG} title="a "quoted" value" path="test/url">\nwhole file\n</${CODE_TAG}>`);
|
expect(docs[0].renderedContent).toEqual(`<${CODE_TAG} title="a "quoted" value" path="test/url">\nwhole file\n</${CODE_TAG}>`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should throw an exception if the code-example tag is not closed correctly', () => {
|
||||||
|
const docs = [
|
||||||
|
{ renderedContent: `<${CODE_TAG} path="test/url"></p></${CODE_TAG}>`}
|
||||||
|
];
|
||||||
|
expect(() => processor.$process(docs)).toThrowError(
|
||||||
|
'Badly formed example: <' + CODE_TAG + ' path="test/url"></p> - closing tag does not match opening tag.\n' +
|
||||||
|
' - Perhaps you forgot to put a blank line before the example?');
|
||||||
|
});
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue