build(docs-infra): throw error if using `title` on code snippets (#26514)
Since #26396, the `title` property is ignored and `header` should be used instead for specifying a code snippet's header. This commit ensures that we don't accidentally set `title` have it be silently ignored. PR Close #26514
This commit is contained in:
parent
d557f1d9de
commit
0add00a743
|
@ -31,9 +31,15 @@ module.exports = function exampleInlineTagDef(parseArgString, createDocMessage,
|
|||
const sourceCode = getExampleRegion(doc, relativePath, regionName);
|
||||
|
||||
const attributes = [];
|
||||
if (relativePath) attributes.push(` path="${relativePath}"`);
|
||||
if (regionName) attributes.push(` region="${regionName}"`);
|
||||
if (header) attributes.push(` header="${header}"`);
|
||||
if (linenums !== undefined) attributes.push(` linenums="${linenums}"`);
|
||||
|
||||
// Preserve the no-longer-supported `title` attribute,
|
||||
// in order to throw an appropriate error in `renderExamples` later.
|
||||
if (tagArgs.title) attributes.push(` title="${tagArgs.title}"`);
|
||||
|
||||
return '<code-example' + attributes.join('') + '>\n' + sourceCode + '\n</code-example>';
|
||||
}
|
||||
};
|
||||
|
|
|
@ -42,27 +42,40 @@ describe('example inline-tag-def', function() {
|
|||
});
|
||||
|
||||
it('should contain the whole contents from the example file if no region is specified', () => {
|
||||
expect(handler({}, 'example', 'test/url')).toEqual('<code-example>\nwhole file\n</code-example>');
|
||||
expect(handler({}, 'example', 'test/url')).toEqual('<code-example path="test/url">\nwhole file\n</code-example>');
|
||||
});
|
||||
|
||||
it('should contain the region contents from the example file if a region is specified', () => {
|
||||
expect(handler({}, 'example', 'test/url region-1')).toEqual('<code-example>\nregion 1 contents\n</code-example>');
|
||||
expect(handler({}, 'example', 'test/url region-1')).toEqual(
|
||||
'<code-example path="test/url" region="region-1">\nregion 1 contents\n</code-example>');
|
||||
});
|
||||
|
||||
it('should add a header if specified', () => {
|
||||
expect(handler({}, 'example', 'test/url region-1 \'Some Header\'')).toEqual('<code-example header="Some Header">\nregion 1 contents\n</code-example>');
|
||||
expect(handler({}, 'example', 'test/url region-1 Some Header')).toEqual('<code-example header="Some Header">\nregion 1 contents\n</code-example>');
|
||||
expect(handler({}, 'example', 'test/url region-1 \'Some Header\'')).toEqual(
|
||||
'<code-example path="test/url" region="region-1" header="Some Header">\nregion 1 contents\n</code-example>');
|
||||
expect(handler({}, 'example', 'test/url region-1 Some Header')).toEqual(
|
||||
'<code-example path="test/url" region="region-1" header="Some Header">\nregion 1 contents\n</code-example>');
|
||||
});
|
||||
|
||||
it('should contain the whole contents from the example file if an empty ("") region is specified', () => {
|
||||
expect(handler({}, 'example', 'test/url \'\'')).toEqual('<code-example>\nwhole file\n</code-example>');
|
||||
expect(handler({}, 'example', 'test/url \'\' Some Header')).toEqual('<code-example header="Some Header">\nwhole file\n</code-example>');
|
||||
expect(handler({}, 'example', 'test/url \'\'')).toEqual(
|
||||
'<code-example path="test/url">\nwhole file\n</code-example>');
|
||||
expect(handler({}, 'example', 'test/url \'\' Some Header')).toEqual(
|
||||
'<code-example path="test/url" header="Some Header">\nwhole file\n</code-example>');
|
||||
});
|
||||
|
||||
it('should add in linenum attribute if specified', () => {
|
||||
expect(handler({}, 'example', 'test/url --linenums=\'false\'')).toEqual('<code-example linenums="false">\nwhole file\n</code-example>');
|
||||
expect(handler({}, 'example', 'test/url --linenums=\'true\'')).toEqual('<code-example linenums="true">\nwhole file\n</code-example>');
|
||||
expect(handler({}, 'example', 'test/url --linenums=\'15\'')).toEqual('<code-example linenums="15">\nwhole file\n</code-example>');
|
||||
expect(handler({}, 'example', 'test/url --linenums=\'false\'')).toEqual(
|
||||
'<code-example path="test/url" linenums="false">\nwhole file\n</code-example>');
|
||||
expect(handler({}, 'example', 'test/url --linenums=\'true\'')).toEqual(
|
||||
'<code-example path="test/url" linenums="true">\nwhole file\n</code-example>');
|
||||
expect(handler({}, 'example', 'test/url --linenums=\'15\'')).toEqual(
|
||||
'<code-example path="test/url" linenums="15">\nwhole file\n</code-example>');
|
||||
});
|
||||
|
||||
it('should preserve the title if specified', () => {
|
||||
expect(handler({}, 'example', 'test/url title="Some Title"')).toEqual(
|
||||
'<code-example path="test/url" title="Some Title">\nwhole file\n</code-example>');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -10,6 +10,8 @@ module.exports = function renderExamples(getExampleRegion, log, createDocMessage
|
|||
$runBefore: ['writing-files'],
|
||||
ignoreBrokenExamples: false,
|
||||
$process: function(docs) {
|
||||
const titleVsHeaderErrors = [];
|
||||
|
||||
docs.forEach(doc => {
|
||||
if (doc.renderedContent) {
|
||||
// We match either `code-example` or `code-pane` elements that have a path attribute
|
||||
|
@ -17,6 +19,14 @@ module.exports = function renderExamples(getExampleRegion, log, createDocMessage
|
|||
/<(code-example|code-pane)([^>]*)>[^<]*<\/([^>]+)>/g,
|
||||
(original, openingTag, attributes, closingTag) => {
|
||||
const attrMap = parseAttributes(attributes);
|
||||
|
||||
if (attrMap.hasOwnProperty('title')) {
|
||||
titleVsHeaderErrors.push(createDocMessage(
|
||||
`Using the "title" attribute for specifying a ${openingTag} header is no longer supported. ` +
|
||||
`Use the "header" attribute instead.\n<${openingTag}${attributes}>`, doc));
|
||||
return;
|
||||
}
|
||||
|
||||
if (attrMap.path) {
|
||||
try {
|
||||
if (closingTag !== openingTag) {
|
||||
|
@ -59,6 +69,11 @@ module.exports = function renderExamples(getExampleRegion, log, createDocMessage
|
|||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (titleVsHeaderErrors.length) {
|
||||
titleVsHeaderErrors.forEach(err => log.error(err));
|
||||
throw new Error('Some code snippets use the `title` attribute instead of `header`.');
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -84,10 +84,10 @@ describe('renderExamples processor', () => {
|
|||
|
||||
it('should cope with spaces and double quotes inside attribute values', () => {
|
||||
const docs = [
|
||||
{ renderedContent: `<${CODE_TAG} title='a "quoted" value' path="test/url"></${CODE_TAG}>`}
|
||||
{ renderedContent: `<${CODE_TAG} header='a "quoted" value' path="test/url"></${CODE_TAG}>`}
|
||||
];
|
||||
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} header="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', () => {
|
||||
|
@ -117,6 +117,55 @@ describe('renderExamples processor', () => {
|
|||
'Missing example file... relativePath: "missing/url". - doc\n' +
|
||||
'Example files can be found in the following relative paths: "examples" - doc');
|
||||
});
|
||||
|
||||
it('should throw an exception if any code-example tag has a `title` attribute', () => {
|
||||
const docs = [
|
||||
{
|
||||
name: 'Document A',
|
||||
renderedContent: `
|
||||
Example 1: <${CODE_TAG} path="test/url" header="This is a header "></${CODE_TAG}>
|
||||
Example 2: <${CODE_TAG} path="test/url" title="This is a title 2"></${CODE_TAG}>
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: 'Document B',
|
||||
renderedContent: `
|
||||
Example 3: <${CODE_TAG} path="test/url" title="This is a title 3"></${CODE_TAG}>
|
||||
Example 4: <${CODE_TAG} path="test/url" header="This is a header 4"></${CODE_TAG}>
|
||||
`,
|
||||
},
|
||||
];
|
||||
|
||||
expect(() => processor.$process(docs)).toThrowError(
|
||||
'Some code snippets use the `title` attribute instead of `header`.');
|
||||
|
||||
expect(log.error).toHaveBeenCalledTimes(2);
|
||||
expect(log.error).toHaveBeenCalledWith(
|
||||
`Using the "title" attribute for specifying a ${CODE_TAG} header is no longer supported. ` +
|
||||
'Use the "header" attribute instead.\n' +
|
||||
`<${CODE_TAG} path="test/url" title="This is a title 2"> - doc "Document A"`);
|
||||
expect(log.error).toHaveBeenCalledWith(
|
||||
`Using the "title" attribute for specifying a ${CODE_TAG} header is no longer supported. ` +
|
||||
'Use the "header" attribute instead.\n' +
|
||||
`<${CODE_TAG} path="test/url" title="This is a title 3"> - doc "Document B"`);
|
||||
});
|
||||
|
||||
it('should throw an exception for `title` attribute even if `ignoreBrokenExamples` is set to true', () => {
|
||||
processor.ignoreBrokenExamples = true;
|
||||
const docs = [
|
||||
{ renderedContent: `<${CODE_TAG} path="test/url" title="This is a title"></${CODE_TAG}>` },
|
||||
];
|
||||
expect(() => processor.$process(docs)).toThrowError(
|
||||
'Some code snippets use the `title` attribute instead of `header`.');
|
||||
});
|
||||
|
||||
it('should throw an exception for `title` attribute even if there is no `path` attribute', () => {
|
||||
const docs = [
|
||||
{ renderedContent: `<${CODE_TAG} title="This is a title">Hard-coded contents.</${CODE_TAG}>` },
|
||||
];
|
||||
expect(() => processor.$process(docs)).toThrowError(
|
||||
'Some code snippets use the `title` attribute instead of `header`.');
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue