diff --git a/aio/src/styles/2-modules/_label.scss b/aio/src/styles/2-modules/_label.scss
index 45d225fa8a..67d546e2c8 100644
--- a/aio/src/styles/2-modules/_label.scss
+++ b/aio/src/styles/2-modules/_label.scss
@@ -48,6 +48,10 @@ label.raised, .api-header label {
&.api-status-label {
background-color: $mediumgray;
+
+ &.impure-pipe {
+ background-color: $brightred;
+ }
}
&.api-type-label {
diff --git a/aio/tests/e2e/api.e2e-spec.ts b/aio/tests/e2e/api.e2e-spec.ts
index b09ab70e44..9ff6625eef 100644
--- a/aio/tests/e2e/api.e2e-spec.ts
+++ b/aio/tests/e2e/api.e2e-spec.ts
@@ -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 */
diff --git a/aio/tests/e2e/api.po.ts b/aio/tests/e2e/api.po.ts
index dcf9f0371e..b2bb4a3b15 100644
--- a/aio/tests/e2e/api.po.ts
+++ b/aio/tests/e2e/api.po.ts
@@ -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));
+ }
}
diff --git a/aio/tools/transforms/angular-api-package/index.js b/aio/tools/transforms/angular-api-package/index.js
index 5ead537ca4..1c26fec515 100644
--- a/aio/tools/transforms/angular-api-package/index.js
+++ b/aio/tools/transforms/angular-api-package/index.js
@@ -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'))
diff --git a/aio/tools/transforms/angular-api-package/processors/extractPipeParams.js b/aio/tools/transforms/angular-api-package/processors/extractPipeParams.js
new file mode 100644
index 0000000000..441377e019
--- /dev/null
+++ b/aio/tools/transforms/angular-api-package/processors/extractPipeParams.js
@@ -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);
+ }
+ });
+ }
+ };
+};
diff --git a/aio/tools/transforms/angular-api-package/processors/extractPipeParams.spec.js b/aio/tools/transforms/angular-api-package/processors/extractPipeParams.spec.js
new file mode 100644
index 0000000000..75448ba477
--- /dev/null
+++ b/aio/tools/transforms/angular-api-package/processors/extractPipeParams.spec.js
@@ -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);
+ });
+});
+
+
diff --git a/aio/tools/transforms/templates/api/base.template.html b/aio/tools/transforms/templates/api/base.template.html
index 69514248fd..7d93b9e861 100644
--- a/aio/tools/transforms/templates/api/base.template.html
+++ b/aio/tools/transforms/templates/api/base.template.html
@@ -25,6 +25,7 @@
{% if doc.deprecated !== undefined %}{% endif %}
{% if doc.experimental !== undefined %}{% endif %}
{% if doc.stable !== undefined %}{% endif %}
+ {% if doc.pipeOptions.pure === 'false' %}{% endif %}
Input Value
+ {$ params.renderParameters([doc.valueParam], 'pipe-parameters', 'pipe-parameter', true) $}
+ {% endif %}
+ {% if doc.pipeParams.length %}
+ Parameters
+ {$ params.renderParameters(doc.pipeParams, 'pipe-parameters', 'pipe-parameter', true) $}
+ {% endif %}
+