build(aio): output `{@example}` tags as `<code-example>` elements (#15382)

This commit is contained in:
Pete Bacon Darwin 2017-03-22 20:24:40 +00:00 committed by Igor Minar
parent c58499786c
commit 8b4edcc7ad
6 changed files with 118 additions and 39 deletions

View File

@ -31,7 +31,12 @@ describe('site App', function() {
expect(page.getDocViewerText()).toMatch(/Tutorial: Tour of Heroes/i); expect(page.getDocViewerText()).toMatch(/Tutorial: Tour of Heroes/i);
}); });
it('should convert a doc with a code-example'); it('should render `{@example}` dgeni tags as `<code-example>` elements with HTML escaped content', () => {
page.navigateTo('guide/component-styles');
const codeExample = element.all(by.css('code-example')).first();
expect(page.getInnerHtml(codeExample))
.toContain('@Component({\n selector: \'hero-app\',\n template: `\n &lt;h1&gt;Tour of Heroes&lt;/h1&gt;');
});
describe('api-docs', () => { describe('api-docs', () => {
it('should show a link to github', () => { it('should show a link to github', () => {

View File

@ -28,6 +28,12 @@ export class SitePage {
return this.docViewer.getText(); return this.docViewer.getText();
} }
getInnerHtml(element) {
// `getInnerHtml` was removed from webDriver and this is the workaround.
// See https://github.com/angular/protractor/blob/master/CHANGELOG.md#breaking-changes
return browser.executeScript('return arguments[0].innerHTML;', element);
}
/** /**
* Replace the ambient Google Analytics tracker with homebrew spy * Replace the ambient Google Analytics tracker with homebrew spy
* don't send commands to GA during e2e testing! * don't send commands to GA during e2e testing!

View File

@ -28,40 +28,48 @@ module.exports = function exampleInlineTagDef(
var unnamedArgs = tagArgs._; var unnamedArgs = tagArgs._;
var relativePath = unnamedArgs[0]; var relativePath = unnamedArgs[0];
var regionName = tagArgs.region || (unnamedArgs.length > 1 ? unnamedArgs[1] : ''); var regionName = tagArgs.region || (unnamedArgs.length > 1 ? unnamedArgs[1] : '');
var title = tagArgs.title || (unnamedArgs.length > 2 ? unnamedArgs[2] : null); if (regionName === '\'\'') regionName = '';
var title = tagArgs.title || (unnamedArgs.length > 2 ? unnamedArgs.slice(2).join(' ') : null);
var linenums = tagArgs.linenums;
var stylePattern = tagArgs.stylePattern; // TODO: not yet implemented here var stylePattern = tagArgs.stylePattern; // TODO: not yet implemented here
// Find the example in the folders const sourceCode = getExampleRegion();
var exampleFile;
// Try an "annotated" version first
EXAMPLES_FOLDERS.some(
EXAMPLES_FOLDER => { return exampleFile = exampleMap[EXAMPLES_FOLDER][relativePath + '.annotated']; });
// If no annotated version is available then try the actual file const attributes = [];
if (!exampleFile) { if (title) attributes.push(` title="${title}"`);
EXAMPLES_FOLDERS.some( if (linenums !== undefined) attributes.push(` linenums="${linenums}"`);
EXAMPLES_FOLDER => { return exampleFile = exampleMap[EXAMPLES_FOLDER][relativePath]; });
return '<code-example' + attributes.join('') + '>\n' + sourceCode + '\n</code-example>';
function getExampleRegion() {
// Find the example in the folders
var exampleFile;
// Try an "annotated" version first
EXAMPLES_FOLDERS.some(EXAMPLES_FOLDER => { return exampleFile = exampleMap[EXAMPLES_FOLDER][relativePath + '.annotated']; });
// If no annotated version is available then try the actual file
if (!exampleFile) {
EXAMPLES_FOLDERS.some(EXAMPLES_FOLDER => { return exampleFile = exampleMap[EXAMPLES_FOLDER][relativePath]; });
}
// If still no file then we error
if (!exampleFile) {
log.error(createDocMessage('Missing example file... relativePath: "' + relativePath + '".', doc));
log.error('Example files can be found in: ' + EXAMPLES_FOLDERS.join(', '));
return '';
}
var sourceCodeDoc = exampleFile.regions[regionName];
if (!sourceCodeDoc) {
log.error(createDocMessage('Missing example region... relativePath: "' + relativePath + '", region: "' + regionName + '".', doc));
log.error('Regions available are:', Object.keys[exampleFile.regions]);
return '';
}
return sourceCodeDoc.renderedContent;
} }
// If still no file then we error
if (!exampleFile) {
log.error(
createDocMessage('Missing example file... relativePath: "' + relativePath + '".', doc));
log.error('Example files can be found in: ' + EXAMPLES_FOLDERS.join(', '));
return '';
}
var sourceCode = exampleFile.regions[regionName];
if (!sourceCode) {
log.error(createDocMessage(
'Missing example region... relativePath: "' + relativePath + '", region: "' +
regionName + '".',
doc));
log.error('Regions available are:', Object.keys[exampleFile.regions]);
return '';
}
return sourceCode.renderedContent;
} }
}; };
}; };

View File

@ -0,0 +1,63 @@
var testPackage = require('../../helpers/test-package');
var Dgeni = require('dgeni');
describe('example inline-tag-def', function() {
let injector, tag, collectExamples, exampleMap;
beforeEach(() => {
const dgeni = new Dgeni([testPackage('examples-package', true)]);
injector = dgeni.configureInjector();
tag = injector.get('exampleInlineTagDef');
collectExamples = injector.get('collectExamples');
exampleMap = injector.get('exampleMap');
});
it('should be available as a service', () => {
expect(tag).toBeDefined();
expect(tag.name).toEqual('example');
});
describe('handler', () => {
let handler;
beforeEach(() => {
handler = tag.handler;
collectExamples.exampleFolders = ['examples'];
exampleMap['examples'] = {
'test/url': { regions: {
'': { renderedContent: 'whole file' },
'region-1': { renderedContent: 'region 1 contents' }
} }
};
});
it('should return a <code-example> tag', () => {
expect(handler({}, 'example', 'some/uri')).toEqual('<code-example>\n\n</code-example>');
});
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>');
});
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>');
});
it('should add a title if specified', () => {
expect(handler({}, 'example', 'test/url region-1 \'Some Title\'')).toEqual('<code-example title="Some Title">\nregion 1 contents\n</code-example>');
expect(handler({}, 'example', 'test/url region-1 Some Title')).toEqual('<code-example title="Some Title">\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 Title')).toEqual('<code-example title="Some Title">\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>');
});
});
});

View File

@ -39,7 +39,10 @@ module.exports = function parseArgString() {
} else { } else {
if (arg.substr(arg.length - 1) === '=') { if (arg.substr(arg.length - 1) === '=') {
key = arg.substr(0, arg.length - 1); key = arg.substr(0, arg.length - 1);
// remove leading '-' if it exists. // remove leading '-' (or '--') if it exists.
if (key.substr(0, 1) == '-') {
key = key.substr(1);
}
if (key.substr(0, 1) == '-') { if (key.substr(0, 1) == '-') {
key = key.substr(1); key = key.substr(1);
} }

View File

@ -1,7 +1 @@
<div class="code-example"> {$ doc.contents | escape $}
{% marked %}
```
{$ doc.contents $}
```
{% endmarked %}
</div>