Skip to content

Commit 68d37ef

Browse files
petebacondarwinvicb
authored andcommitted
build(aio): ensure the correct decorator properties are merged (angular#24289)
Previously only the `description` and `usageNotes` were being copied over from the call-member of the decorator interface. Important properties such as `shortDescription` were missed. These are now added and the code has been refactored to make it simpler and clearer to update which properties get copied as the requirements change. PR Close angular#24289
1 parent acf270d commit 68d37ef

File tree

5 files changed

+79
-13
lines changed

5 files changed

+79
-13
lines changed

aio/tools/transforms/angular-api-package/index.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,17 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
119119
addNotYetDocumentedProperty.docTypes = API_DOC_TYPES;
120120
})
121121

122+
.config(function(mergeDecoratorDocs) {
123+
mergeDecoratorDocs.propertiesToMerge = [
124+
'shortDescription',
125+
'description',
126+
'security',
127+
'deprecated',
128+
'see',
129+
'usageNotes',
130+
];
131+
})
132+
122133
.config(function(checkContentRules, EXPORT_DOC_TYPES) {
123134
// Min length rules
124135
const createMinLengthRule = require('./content-rules/minLength');

aio/tools/transforms/angular-api-package/processors/mergeDecoratorDocs.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
const {mergeProperties} = require('../../helpers/utils');
2+
13
/**
24
* Decorators in the Angular code base are made up from three code items:
35
*
@@ -47,6 +49,7 @@ module.exports = function mergeDecoratorDocs(log) {
4749
return {
4850
$runAfter: ['processing-docs'],
4951
$runBefore: ['docs-processed'],
52+
propertiesToMerge: [],
5053
makeDecoratorCalls: [
5154
{type: '', description: 'toplevel', functionName: 'makeDecorator'},
5255
{type: 'Prop', description: 'property', functionName: 'makePropDecorator'},
@@ -55,6 +58,7 @@ module.exports = function mergeDecoratorDocs(log) {
5558
$process: function(docs) {
5659

5760
var makeDecoratorCalls = this.makeDecoratorCalls;
61+
var propertiesToMerge = this.propertiesToMerge;
5862
var docsToMerge = Object.create(null);
5963

6064
docs.forEach(function(doc) {
@@ -88,9 +92,9 @@ module.exports = function mergeDecoratorDocs(log) {
8892
log.debug(
8993
'mergeDecoratorDocs: merging', doc.name, 'into', decoratorDoc.name,
9094
callMember.description.substring(0, 50));
95+
9196
// Merge the documentation found in this call signature into the original decorator
92-
decoratorDoc.description = callMember.description;
93-
decoratorDoc.usageNotes = callMember.usageNotes;
97+
mergeProperties(decoratorDoc, callMember, propertiesToMerge);
9498

9599
// remove doc from its module doc's exports
96100
doc.moduleDoc.exports =

aio/tools/transforms/angular-api-package/processors/mergeDecoratorDocs.spec.js

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,33 +9,37 @@ describe('mergeDecoratorDocs processor', () => {
99
const injector = dgeni.configureInjector();
1010
processor = injector.get('mergeDecoratorDocs');
1111

12+
// Note that we do not include usageNotes in the tests.
13+
processor.propertiesToMerge = ['description', 'shortDescription'];
14+
1215
moduleDoc = {};
1316

1417
decoratorDoc = {
1518
name: 'Component',
1619
docType: 'const',
17-
description: 'A description of the metadata for the Component decorator',
20+
shortDescription: 'decorator - short description',
21+
description: 'decorator - description',
1822
symbol: {
1923
valueDeclaration: { initializer: { expression: { text: 'makeDecorator' }, arguments: [{ text: 'X' }] } }
2024
},
2125
members: [
22-
{ name: 'templateUrl', description: 'A description of the templateUrl property' }
26+
{ name: 'templateUrl', description: 'templateUrl - description' }
2327
],
2428
moduleDoc
2529
};
2630

2731
metadataDoc = {
2832
name: 'ComponentDecorator',
2933
docType: 'interface',
30-
description: 'A description of the interface for the call signature for the Component decorator',
34+
description: 'call interface - description',
3135
members: [
3236
{
3337
isCallMember: true,
34-
description: 'The actual description of the call signature',
35-
usageNotes: 'Use it like this...'
38+
description: 'call interface - call member - description',
39+
usageNotes: 'call interface - call member - usageNotes',
3640
},
3741
{
38-
description: 'Some other member'
42+
description: 'call interface - non call member - description'
3943
}
4044
],
4145
moduleDoc
@@ -65,10 +69,13 @@ describe('mergeDecoratorDocs processor', () => {
6569
expect(decoratorDoc.decoratorType).toEqual('X');
6670
});
6771

68-
it('should copy across properties from the call signature doc', () => {
72+
it('should copy across specified properties from the call signature doc', () => {
6973
processor.$process([decoratorDoc, metadataDoc, otherDoc]);
70-
expect(decoratorDoc.description).toEqual('The actual description of the call signature');
71-
expect(decoratorDoc.usageNotes).toEqual('Use it like this...');
74+
expect(decoratorDoc.description).toEqual('call interface - call member - description');
75+
// Since usageNotes is not in `propertiesToMerge` it will not get copied over in these tests.
76+
expect(decoratorDoc.usageNotes).toBeUndefined();
77+
// Since `shortDescription` does not exist on the call-member this will not get overridden.
78+
expect(decoratorDoc.shortDescription).toEqual('decorator - short description');
7279
});
7380

7481
it('should remove the metadataDoc from the module exports', () => {

aio/tools/transforms/helpers/utils.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,5 +96,19 @@ module.exports = {
9696
attrMap[key] === false ? '' :
9797
attrMap[key] === true ? ` ${key}` :
9898
` ${key}="${attrMap[key].replace(/"/g, '"')}"`).join('');
99-
}
99+
},
100+
101+
/**
102+
* Merge the specified properties from the source to the target document
103+
* @param {Document} target The document to receive the properties from the source
104+
* @param {Document} source The document from which to get the properties to merge
105+
* @param {string[]} properties A collection of the names of the properties to merge
106+
*/
107+
mergeProperties(target, source, properties) {
108+
properties.forEach(property => {
109+
if (source.hasOwnProperty(property)) {
110+
target[property] = source[property];
111+
}
112+
});
113+
},
100114
};

aio/tools/transforms/helpers/utils.spec.js

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const { mapObject, parseAttributes, renderAttributes } = require('./utils');
1+
const { mergeProperties, mapObject, parseAttributes, renderAttributes } = require('./utils');
22

33
describe('utils', () => {
44
describe('mapObject', () => {
@@ -96,4 +96,34 @@ describe('utils', () => {
9696
expect(renderAttributes({ })).toEqual('');
9797
});
9898
});
99+
100+
describe('mergeProperties', () => {
101+
it('should write specified properties from the source to the target', () => {
102+
const source = { a: 1, b: 2, c: 3 };
103+
const target = { };
104+
mergeProperties(target, source, ['a', 'b']);
105+
expect(target).toEqual({ a: 1, b: 2 });
106+
});
107+
108+
it('should not overwrite target properties that are not specified', () => {
109+
const source = { a: 1, b: 2, c: 3 };
110+
const target = { b: 10 };
111+
mergeProperties(target, source, ['a']);
112+
expect(target).toEqual({ a: 1, b: 10 });
113+
});
114+
115+
it('should not overwrite target properties that are specified but do not exist in the source', () => {
116+
const source = { a: 1 };
117+
const target = { b: 10 };
118+
mergeProperties(target, source, ['a', 'b']);
119+
expect(target).toEqual({ a: 1, b: 10 });
120+
});
121+
122+
it('should overwrite target properties even if they are `undefined` in the source', () => {
123+
const source = { a: undefined };
124+
const target = { a: 10 };
125+
mergeProperties(target, source, ['a']);
126+
expect(target).toEqual({ a: undefined });
127+
});
128+
});
99129
});

0 commit comments

Comments
 (0)