build(aio): improve the API Pipe pages (#22702)
This change adds: * an impure badge for Pipes that are marked as `pure: false` * a pipe specific overview that shows the syntax for using a pipe in a template. * an "input value" section describing the type of the value that the pipe expects. * a "pipe params" section describing any additional params that a pipe expects. PR Close #22702
This commit is contained in:
parent
cd2ebd22fd
commit
d509bd6849
|
@ -48,6 +48,10 @@ label.raised, .api-header label {
|
|||
|
||||
&.api-status-label {
|
||||
background-color: $mediumgray;
|
||||
|
||||
&.impure-pipe {
|
||||
background-color: $brightred;
|
||||
}
|
||||
}
|
||||
|
||||
&.api-type-label {
|
||||
|
|
|
@ -51,6 +51,12 @@ describe('Api pages', function() {
|
|||
expect(page.getSection('instance-properties').isPresent()).toBe(false);
|
||||
});
|
||||
|
||||
it('should show "impure" badge if pipe is not pure', () => {
|
||||
const page = new ApiPage('api/common/AsyncPipe');
|
||||
const impureBadge = page.getBadge('impure-pipe');
|
||||
expect(impureBadge.isPresent()).toBe(true);
|
||||
});
|
||||
|
||||
it('should show links to github', () => {
|
||||
const page = new ApiPage('api/core/EventEmitter');
|
||||
/* tslint:disable:max-line-length */
|
||||
|
|
|
@ -35,4 +35,8 @@ export class ApiPage extends SitePage {
|
|||
getSection(cls) {
|
||||
return element(by.css(`section.${cls}`));
|
||||
}
|
||||
|
||||
getBadge(cls) {
|
||||
return element(by.css('.api-status-label.' + cls));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
|
|||
.processor(require('./processors/addNotYetDocumentedProperty'))
|
||||
.processor(require('./processors/mergeDecoratorDocs'))
|
||||
.processor(require('./processors/extractDecoratedClasses'))
|
||||
.processor(require('./processors/extractPipeParams'))
|
||||
.processor(require('./processors/matchUpDirectiveDecorators'))
|
||||
.processor(require('./processors/addMetadataAliases'))
|
||||
.processor(require('./processors/computeApiBreadCrumbs'))
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
module.exports = function extractPipeParams(createDocMessage) {
|
||||
return {
|
||||
$runAfter: ['extractDecoratedClassesProcessor'],
|
||||
$runBefore: ['docs-processed'],
|
||||
$process(docs) {
|
||||
docs.forEach(doc => {
|
||||
if (doc.docType === 'pipe') {
|
||||
const transformFn = doc.members && doc.members.find(member => member.name === 'transform');
|
||||
if (!transformFn) {
|
||||
throw new Error(createDocMessage('Missing `transform` method - pipes must implement PipeTransform interface', doc));
|
||||
}
|
||||
doc.pipeName = doc.pipeOptions.name.replace(/^["']|["']$/g, '');
|
||||
doc.valueParam = transformFn.parameterDocs[0];
|
||||
doc.pipeParams = transformFn.parameterDocs.slice(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
|
@ -0,0 +1,61 @@
|
|||
const testPackage = require('../../helpers/test-package');
|
||||
const Dgeni = require('dgeni');
|
||||
|
||||
describe('extractPipeParams processor', () => {
|
||||
let processor;
|
||||
beforeEach(() => {
|
||||
const dgeni = new Dgeni([testPackage('angular-api-package')]);
|
||||
const injector = dgeni.configureInjector();
|
||||
processor = injector.get('extractPipeParams');
|
||||
});
|
||||
|
||||
it('should be available on the injector', () => {
|
||||
expect(processor.$process).toBeDefined();
|
||||
});
|
||||
|
||||
it('should run before the correct processor', () => {
|
||||
expect(processor.$runBefore).toEqual(['docs-processed']);
|
||||
});
|
||||
|
||||
it('should run after the correct processor', () => {
|
||||
expect(processor.$runAfter).toEqual(['extractDecoratedClassesProcessor']);
|
||||
});
|
||||
|
||||
it('should throw an error if the pipe document does not contain a `transform` method', () => {
|
||||
expect(() => processor.$process([{ docType: 'pipe' }])).toThrowError('Missing `transform` method - pipes must implement PipeTransform interface - doc (pipe) ');
|
||||
expect(() => processor.$process([{ docType: 'pipe', members: [] }])).toThrowError('Missing `transform` method - pipes must implement PipeTransform interface - doc (pipe) ');
|
||||
expect(() => processor.$process([{ docType: 'pipe', members: [ { name: 'notTransform' }] }])).toThrowError('Missing `transform` method - pipes must implement PipeTransform interface - doc (pipe) ');
|
||||
});
|
||||
|
||||
it('should extract the pipe name', () => {
|
||||
const docs = [ { docType: 'pipe', pipeOptions: { name: 'testPipe' }, members: [ { name: 'transform', parameterDocs: [] }] } ];
|
||||
processor.$process(docs);
|
||||
expect(docs[0].pipeName).toEqual('testPipe');
|
||||
});
|
||||
|
||||
it('should extract the value parameter', () => {
|
||||
const valueParam = {};
|
||||
const pipeParam1 = {};
|
||||
const pipeParam2 = {};
|
||||
const docs = [ { docType: 'pipe', pipeOptions: { name: 'testPipe' }, members: [
|
||||
{ name: 'transform', parameterDocs: [valueParam, pipeParam1, pipeParam2] }
|
||||
] } ];
|
||||
processor.$process(docs);
|
||||
expect(docs[0].valueParam).toBe(valueParam);
|
||||
});
|
||||
|
||||
it('should extract the pipe parameters', () => {
|
||||
const valueParam = {};
|
||||
const pipeParam1 = {};
|
||||
const pipeParam2 = {};
|
||||
const docs = [ { docType: 'pipe', pipeOptions: { name: 'testPipe' }, members: [
|
||||
{ name: 'transform', parameterDocs: [valueParam, pipeParam1, pipeParam2] }
|
||||
] } ];
|
||||
processor.$process(docs);
|
||||
expect(docs[0].pipeParams.length).toEqual(2);
|
||||
expect(docs[0].pipeParams[0]).toBe(pipeParam1);
|
||||
expect(docs[0].pipeParams[1]).toBe(pipeParam2);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
{% if doc.deprecated !== undefined %}<label class="api-status-label deprecated">deprecated</label>{% endif %}
|
||||
{% if doc.experimental !== undefined %}<label class="api-status-label experimental">experimental</label>{% endif %}
|
||||
{% if doc.stable !== undefined %}<label class="api-status-label stable">stable</label>{% endif %}
|
||||
{% if doc.pipeOptions.pure === 'false' %}<label class="api-status-label impure-pipe">impure</label>{% endif %}
|
||||
</header>
|
||||
<aio-toc class="embedded"></aio-toc>
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
{% import "lib/memberHelpers.html" as memberHelpers -%}
|
||||
{% import "lib/paramList.html" as params -%}
|
||||
|
||||
<section class="{$ doc.docType $}-overview">
|
||||
<code-example hideCopy="true" class="no-box api-heading">{{ {$ doc.valueParam.name $}_expression | <span class="kwd nocode">{$ doc.pipeName $}</span>
|
||||
{%- for param in doc.pipeParams %}
|
||||
{%- if param.isOptional or param.defaultValue !== undefined %} [{% endif %} : {$ param.name $}
|
||||
{%- endfor %}
|
||||
{%- for param in doc.pipeParams %}
|
||||
{%- if param.isOptional or param.defaultValue !== undefined %} ]{% endif %}
|
||||
{%- endfor %} }}</code-example>
|
||||
|
||||
{% if doc.valueParam.type %}
|
||||
<h2>Input Value</h2>
|
||||
{$ params.renderParameters([doc.valueParam], 'pipe-parameters', 'pipe-parameter', true) $}
|
||||
{% endif %}
|
||||
{% if doc.pipeParams.length %}
|
||||
<h2>Parameters</h2>
|
||||
{$ params.renderParameters(doc.pipeParams, 'pipe-parameters', 'pipe-parameter', true) $}
|
||||
{% endif %}
|
||||
</section>
|
|
@ -11,19 +11,20 @@
|
|||
{%- if returnType %}: {$ returnType | escape $}{% endif -%}
|
||||
{%- endmacro -%}
|
||||
|
||||
{%- macro renderParameters(parameters, containerClass, parameterClass) -%}
|
||||
{%- macro renderParameters(parameters, containerClass, parameterClass, showType) -%}
|
||||
{%- if parameters.length -%}
|
||||
<table class="is-full-width list-table parameters-table {$ containerClass $}">
|
||||
<tbody>
|
||||
{% for parameter in parameters %}
|
||||
<tr class="{$ parameterClass $}">
|
||||
<td class="param-name"><a id="{$ parameter.anchor $}"></a>{$ parameter.name $}</td>
|
||||
{% if showType %}<td class="param-type"><code>{$ parameter.type $}</code></td>{% endif %}
|
||||
<td class="param-description">
|
||||
{% marked %}
|
||||
{% if parameter.isOptional or parameter.defaultValue !== undefined %}Optional. Default is `{$ parameter.defaultValue === undefined and 'undefined' or parameter.defaultValue $}`.{% endif %}
|
||||
|
||||
{% if parameter.description | trim %}{$ parameter.description $}
|
||||
{% elseif parameter.type %}<code>{$ parameter.type $}</code>
|
||||
{% elseif not showType and parameter.type %}<p>Type: <code>{$ parameter.type $}</code>.</p>
|
||||
{% endif %}
|
||||
{% endmarked %}
|
||||
</td>
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
{% extends 'export-base.template.html' -%}
|
||||
|
||||
{% block overview %}
|
||||
{% include "includes/pipe-overview.html" %}
|
||||
{% endblock %}
|
||||
{% block details %}
|
||||
{% include "includes/description.html" %}
|
||||
{% endblock %}
|
||||
|
|
Loading…
Reference in New Issue