mirror of
https://github.com/jsdoc/jsdoc.git
synced 2025-12-08 19:46:11 +00:00
turn Doclet#merge into doclet.combine
This commit is contained in:
parent
77bd47f58a
commit
4aa3ee8f96
@ -468,18 +468,7 @@ Doclet.prototype.setMeta = function(meta) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Extend a destination object with properties from the source object, ignoring properties that
|
||||
* should be excluded.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} source - The source object.
|
||||
* @param {Object} destination - The destination object.
|
||||
* @param {Array.<string>} exclude - The names of properties to exclude from copying.
|
||||
*/
|
||||
function extend(source, destination, exclude) {
|
||||
var properties = _.difference(Object.getOwnPropertyNames(source), exclude);
|
||||
|
||||
function dooper(source, target, properties) {
|
||||
properties.forEach(function(property) {
|
||||
switch (typeof source[property]) {
|
||||
case 'function':
|
||||
@ -487,57 +476,86 @@ function extend(source, destination, exclude) {
|
||||
break;
|
||||
|
||||
case 'object':
|
||||
destination[property] = jsdoc.util.doop(source[property]);
|
||||
target[property] = jsdoc.util.doop(source[property]);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
destination[property] = source[property];
|
||||
target[property] = source[property];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend a destination doclet with the specified properties from the source doclet, provided that
|
||||
* the properties from the source doclet appear to be a better fit.
|
||||
* Combine two doclets into a target doclet, using properties from the secondary doclet only when
|
||||
* those properties do not exist on the primary doclet, and ignoring properties that should be
|
||||
* excluded.
|
||||
*
|
||||
* @private
|
||||
* @param {module:jsdoc/doclet.Doclet} source - The source doclet.
|
||||
* @param {module:jsdoc/doclet.Doclet} destination - The destination doclet.
|
||||
* @param {module:jsdoc/doclet.Doclet} primary - The primary doclet.
|
||||
* @param {module:jsdoc/doclet.Doclet} secondary - The secondary doclet.
|
||||
* @param {module:jsdoc/doclet.Doclet} target - The doclet to which properties will be copied.
|
||||
* @param {Array.<string>} exclude - The names of properties to exclude from copying.
|
||||
*/
|
||||
function combine(primary, secondary, target, exclude) {
|
||||
var primaryProperties = _.difference(Object.getOwnPropertyNames(primary), exclude);
|
||||
var secondaryProperties = _.difference(Object.getOwnPropertyNames(secondary),
|
||||
exclude.concat(primaryProperties));
|
||||
|
||||
dooper(primary, target, primaryProperties);
|
||||
dooper(secondary, target, secondaryProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine specified properties from two doclets into a target doclet, using the properties of the
|
||||
* primary doclet unless the properties of the secondary doclet appear to be a better fit.
|
||||
*
|
||||
* @private
|
||||
* @param {module:jsdoc/doclet.Doclet} primary - The primary doclet.
|
||||
* @param {module:jsdoc/doclet.Doclet} secondary - The secondary doclet.
|
||||
* @param {module:jsdoc/doclet.Doclet} target - The doclet to which properties will be copied.
|
||||
* @param {Array.<string>} include - The names of properties to copy.
|
||||
*/
|
||||
function maybeExtend(source, destination, include) {
|
||||
function combineWithLogic(primary, secondary, target, include) {
|
||||
include.forEach(function(property) {
|
||||
var shouldExtend = false;
|
||||
var shouldUsePrimary = false;
|
||||
|
||||
if ({}.hasOwnProperty.call(source, property)) {
|
||||
// use the source property if the destination property is missing or empty
|
||||
if (!destination[property] || !destination[property].length) {
|
||||
shouldExtend = true;
|
||||
if ({}.hasOwnProperty.call(primary, property)) {
|
||||
// use the primary property if the secondary property is missing or empty
|
||||
if (!secondary[property] || !secondary[property].length) {
|
||||
shouldUsePrimary = true;
|
||||
}
|
||||
// use the source property if it's not empty
|
||||
else if (source[property].length) {
|
||||
shouldExtend = true;
|
||||
else if (primary[property].length) {
|
||||
shouldUsePrimary = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldExtend) {
|
||||
destination[property] = jsdoc.util.doop(source[property]);
|
||||
if (shouldUsePrimary) {
|
||||
target[property] = jsdoc.util.doop(primary[property]);
|
||||
}
|
||||
else {
|
||||
target[property] = jsdoc.util.doop(secondary[property]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge another doclet into this doclet.
|
||||
* Combine two doclets into a new doclet.
|
||||
*
|
||||
* @param {module:jsdoc/doclet.Doclet} doclet - The doclet to merge into this one.
|
||||
* @param {module:jsdoc/doclet.Doclet} primary - The doclet whose properties will be used.
|
||||
* @param {module:jsdoc/doclet.Doclet} secondary - The doclet to use as a fallback for properties
|
||||
* that the primary doclet does not have.
|
||||
*/
|
||||
Doclet.prototype.merge = function(doclet) {
|
||||
exports.combine = function(primary, secondary) {
|
||||
var specialCase = [
|
||||
'params',
|
||||
'properties'
|
||||
];
|
||||
var target = new Doclet('');
|
||||
|
||||
extend(doclet, this, specialCase);
|
||||
maybeExtend(doclet, this, specialCase);
|
||||
combine(primary, secondary, target, specialCase);
|
||||
combineWithLogic(primary, secondary, target, specialCase);
|
||||
|
||||
return target;
|
||||
};
|
||||
|
||||
@ -3,7 +3,10 @@
|
||||
describe('jsdoc/doclet', function() {
|
||||
// TODO: more tests
|
||||
var _ = require('underscore');
|
||||
var Doclet = require('jsdoc/doclet').Doclet;
|
||||
var jsdoc = {
|
||||
doclet: require('jsdoc/doclet')
|
||||
};
|
||||
var Doclet = jsdoc.doclet.Doclet;
|
||||
|
||||
var docSet = jasmine.getDocSetFromFile('test/fixtures/doclet.js');
|
||||
var test1 = docSet.getByLongname('test1')[0];
|
||||
@ -47,25 +50,23 @@ describe('jsdoc/doclet', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('merge', function() {
|
||||
it('should override most properties of the original doclet', function() {
|
||||
var originalDoclet = new Doclet('/** Hello!\n@version 1.0.0 */');
|
||||
var newDoclet = new Doclet('/** New and improved!\n@version 2.0.0 */');
|
||||
describe('combine', function() {
|
||||
it('should override most properties of the secondary doclet', function() {
|
||||
var primaryDoclet = new Doclet('/** New and improved!\n@version 2.0.0 */');
|
||||
var secondaryDoclet = new Doclet('/** Hello!\n@version 1.0.0 */');
|
||||
var newDoclet = jsdoc.doclet.combine(primaryDoclet, secondaryDoclet);
|
||||
|
||||
originalDoclet.merge(newDoclet);
|
||||
|
||||
Object.getOwnPropertyNames(originalDoclet).forEach(function(property) {
|
||||
expect(originalDoclet[property]).toEqual(newDoclet[property]);
|
||||
Object.getOwnPropertyNames(newDoclet).forEach(function(property) {
|
||||
expect(newDoclet[property]).toEqual(primaryDoclet[property]);
|
||||
});
|
||||
});
|
||||
|
||||
it('should add properties that are missing from the original doclet', function() {
|
||||
var originalDoclet = new Doclet('/** Hello! */');
|
||||
var newDoclet = new Doclet('/** Hello!\n@version 2.0.0 */');
|
||||
it('should add properties that are missing from the secondary doclet', function() {
|
||||
var primaryDoclet = new Doclet('/** Hello!\n@version 2.0.0 */');
|
||||
var secondaryDoclet = new Doclet('/** Hello! */');
|
||||
var newDoclet = jsdoc.doclet.combine(primaryDoclet, secondaryDoclet);
|
||||
|
||||
originalDoclet.merge(newDoclet);
|
||||
|
||||
expect(originalDoclet.version).toBe('2.0.0');
|
||||
expect(newDoclet.version).toBe('2.0.0');
|
||||
});
|
||||
|
||||
describe('params and properties', function() {
|
||||
@ -74,65 +75,45 @@ describe('jsdoc/doclet', function() {
|
||||
'properties'
|
||||
];
|
||||
|
||||
it('should use the new doclet\'s params and properties if the original doclet had none',
|
||||
function() {
|
||||
var originalDoclet = new Doclet('/** Hello! */');
|
||||
var newComment = [
|
||||
'/**',
|
||||
' * @param {string} foo - The foo.',
|
||||
' * @property {number} bar - The bar.',
|
||||
' */'
|
||||
].join('\n');
|
||||
var newDoclet = new Doclet(newComment);
|
||||
it('should use the secondary doclet\'s params and properties if the primary doclet ' +
|
||||
'had none', function() {
|
||||
var primaryDoclet = new Doclet('/** Hello! */');
|
||||
var secondaryComment = [
|
||||
'/**',
|
||||
' * @param {string} foo - The foo.',
|
||||
' * @property {number} bar - The bar.',
|
||||
' */'
|
||||
].join('\n');
|
||||
var secondaryDoclet = new Doclet(secondaryComment);
|
||||
var newDoclet = jsdoc.doclet.combine(primaryDoclet, secondaryDoclet);
|
||||
|
||||
originalDoclet.merge(newDoclet);
|
||||
|
||||
properties.forEach(function(property) {
|
||||
expect(originalDoclet[property]).toEqual(newDoclet[property]);
|
||||
});
|
||||
properties.forEach(function(property) {
|
||||
expect(newDoclet[property]).toEqual(secondaryDoclet[property]);
|
||||
});
|
||||
});
|
||||
|
||||
it('should use the new doclet\'s params and properties if the new doclet has some',
|
||||
function() {
|
||||
var originalComment = [
|
||||
'/**',
|
||||
' * @param {string} foo - The foo.',
|
||||
' * @property {number} bar - The bar.',
|
||||
' */'
|
||||
].join('\n');
|
||||
var originalDoclet = new Doclet(originalComment);
|
||||
var newComment = [
|
||||
'/**',
|
||||
' * @param {number} baz - The baz.',
|
||||
' * @property {string} qux - The qux.',
|
||||
' */'
|
||||
].join('\n');
|
||||
var newDoclet = new Doclet(newComment);
|
||||
it('should use the primary doclet\'s params and properties if the primary doclet has ' +
|
||||
'some', function() {
|
||||
var primaryComment = [
|
||||
'/**',
|
||||
' * @param {number} baz - The baz.',
|
||||
' * @property {string} qux - The qux.',
|
||||
' */'
|
||||
].join('\n');
|
||||
var primaryDoclet = new Doclet(primaryComment);
|
||||
var secondaryComment = [
|
||||
'/**',
|
||||
' * @param {string} foo - The foo.',
|
||||
' * @property {number} bar - The bar.',
|
||||
' */'
|
||||
].join('\n');
|
||||
var secondaryDoclet = new Doclet(secondaryComment);
|
||||
var newDoclet = jsdoc.doclet.combine(primaryDoclet, secondaryDoclet);
|
||||
|
||||
originalDoclet.merge(newDoclet);
|
||||
|
||||
properties.forEach(function(property) {
|
||||
expect(originalDoclet[property]).toEqual(newDoclet[property]);
|
||||
});
|
||||
});
|
||||
|
||||
it('should use the old doclet\'s params and properties if the new doclet has none',
|
||||
function() {
|
||||
var originalComment = [
|
||||
'/**',
|
||||
' * @param {string} foo - The foo.',
|
||||
' * @property {number} bar - The bar.',
|
||||
' */'
|
||||
].join('\n');
|
||||
var originalDoclet = new Doclet(originalComment);
|
||||
var newDoclet = new Doclet('/** Hello! */');
|
||||
|
||||
originalDoclet.merge(newDoclet);
|
||||
|
||||
properties.forEach(function(property) {
|
||||
expect(originalDoclet[property]).not.toEqual(newDoclet[property]);
|
||||
});
|
||||
properties.forEach(function(property) {
|
||||
expect(newDoclet[property]).toEqual(primaryDoclet[property]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user