mirror of
https://github.com/jsdoc/jsdoc.git
synced 2025-12-08 19:46:11 +00:00
refactor(jsdoc): eliminate global tag dictionary
And remove final dependency on `jsdoc/env` outside `jsdoc.js`. In some cases, `jsdoc/util/templateHelper` functions now take a `dependencies` argument even when it looks like they could get the dependencies from a `doclet` parameter. That's because non-enumerable properties don't survive when the doclets are added to TaffyDB; as a result, the dependencies are no longer attached to each doclet by the time the template runs. This limitation should go away when we stop using TaffyDB.
This commit is contained in:
parent
004ce7392c
commit
44b0862b8d
@ -1,6 +1,7 @@
|
||||
/* eslint-disable indent, no-process-exit */
|
||||
const _ = require('lodash');
|
||||
const { config, Dependencies } = require('@jsdoc/core');
|
||||
const { Dictionary } = require('jsdoc/tag/dictionary');
|
||||
const Engine = require('@jsdoc/cli');
|
||||
const { EventBus, log } = require('@jsdoc/util');
|
||||
const { Filter } = require('jsdoc/src/filter');
|
||||
@ -87,6 +88,9 @@ module.exports = (() => {
|
||||
// Now that we're done loading and merging things, register dependencies.
|
||||
dependencies.registerValue('config', env.conf);
|
||||
dependencies.registerValue('options', env.opts);
|
||||
dependencies.registerSingletonFactory('tags', () =>
|
||||
Dictionary.fromConfig(dependencies.get('env'))
|
||||
);
|
||||
|
||||
return cli;
|
||||
};
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
* @module jsdoc/doclet
|
||||
*/
|
||||
const _ = require('lodash');
|
||||
let dictionary = require('jsdoc/tag/dictionary');
|
||||
const { isFunction } = require('@jsdoc/parse').astNode;
|
||||
const {
|
||||
applyNamespace,
|
||||
@ -17,7 +16,6 @@ const {
|
||||
SCOPE_TO_PUNC,
|
||||
toParts,
|
||||
} = require('@jsdoc/core').name;
|
||||
const helper = require('jsdoc/util/templateHelper');
|
||||
const path = require('path');
|
||||
const { Syntax } = require('@jsdoc/parse');
|
||||
const tag = require('jsdoc/tag');
|
||||
@ -266,20 +264,6 @@ function resolve(doclet) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the existing tag dictionary with a new tag dictionary.
|
||||
*
|
||||
* Used for testing only.
|
||||
*
|
||||
* @private
|
||||
* @param {module:jsdoc/tag/dictionary.Dictionary} dict - The new tag dictionary.
|
||||
*/
|
||||
exports._replaceDictionary = function _replaceDictionary(dict) {
|
||||
dictionary = dict;
|
||||
tag._replaceDictionary(dict);
|
||||
helper._replaceDictionary(dict);
|
||||
};
|
||||
|
||||
function removeGlobal(longname) {
|
||||
const globalRegexp = new RegExp(`^${LONGNAMES.GLOBAL}\\.?`);
|
||||
|
||||
@ -447,6 +431,7 @@ class Doclet {
|
||||
* @param {string} [text] - The text of the tag being added.
|
||||
*/
|
||||
addTag(title, text) {
|
||||
const dictionary = this.dependencies.get('tags');
|
||||
const tagDef = dictionary.lookUp(title);
|
||||
const newTag = new Tag(title, text, this.meta, this.dependencies);
|
||||
|
||||
@ -481,6 +466,8 @@ class Doclet {
|
||||
* @param {string} longname - The longname for the doclet.
|
||||
*/
|
||||
setLongname(longname) {
|
||||
const dictionary = this.dependencies.get('tags');
|
||||
|
||||
/**
|
||||
* The fully resolved symbol name.
|
||||
* @type {string}
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
* Utility functions to support the JSDoc plugin framework.
|
||||
* @module jsdoc/plugins
|
||||
*/
|
||||
const dictionary = require('jsdoc/tag/dictionary');
|
||||
|
||||
function addHandlers(handlers, parser, deps) {
|
||||
Object.keys(handlers).forEach((eventName) => {
|
||||
@ -11,6 +10,7 @@ function addHandlers(handlers, parser, deps) {
|
||||
}
|
||||
|
||||
exports.installPlugins = (plugins, parser, deps) => {
|
||||
let dictionary;
|
||||
let plugin;
|
||||
|
||||
for (let pluginModule of plugins) {
|
||||
@ -24,6 +24,7 @@ exports.installPlugins = (plugins, parser, deps) => {
|
||||
|
||||
// ...define tags
|
||||
if (plugin.defineTags) {
|
||||
dictionary = deps.get('tags');
|
||||
plugin.defineTags(dictionary, deps);
|
||||
}
|
||||
|
||||
|
||||
@ -6,7 +6,6 @@ const _ = require('lodash');
|
||||
const { log } = require('@jsdoc/util');
|
||||
const path = require('path');
|
||||
const tag = {
|
||||
dictionary: require('jsdoc/tag/dictionary'),
|
||||
validator: require('jsdoc/tag/validator'),
|
||||
type: require('@jsdoc/tag').type,
|
||||
};
|
||||
@ -119,19 +118,6 @@ function processTagText(tagInstance, tagDef, meta, dependencies) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the existing tag dictionary with a new tag dictionary.
|
||||
*
|
||||
* Used for testing only. Do not call this method directly. Instead, call
|
||||
* {@link module:jsdoc/doclet._replaceDictionary}, which also updates this module's tag dictionary.
|
||||
*
|
||||
* @private
|
||||
* @param {module:jsdoc/tag/dictionary.Dictionary} dict - The new tag dictionary.
|
||||
*/
|
||||
exports._replaceDictionary = function _replaceDictionary(dict) {
|
||||
tag.dictionary = dict;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a single doclet tag.
|
||||
*/
|
||||
@ -145,6 +131,7 @@ class Tag {
|
||||
* @param {object} dependencies
|
||||
*/
|
||||
constructor(tagTitle, tagBody, meta, dependencies) {
|
||||
const dictionary = dependencies.get('tags');
|
||||
let tagDef;
|
||||
let trimOpts;
|
||||
|
||||
@ -154,9 +141,9 @@ class Tag {
|
||||
this.originalTitle = trim(tagTitle);
|
||||
|
||||
/** The title of the tag (for example, `title` in `@title text`). */
|
||||
this.title = tag.dictionary.normalize(this.originalTitle);
|
||||
this.title = dictionary.normalize(this.originalTitle);
|
||||
|
||||
tagDef = tag.dictionary.lookUp(this.title);
|
||||
tagDef = dictionary.lookUp(this.title);
|
||||
trimOpts = {
|
||||
keepsWhitespace: tagDef.keepsWhitespace,
|
||||
removesIndent: tagDef.removesIndent,
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
/** @module jsdoc/tag/dictionary */
|
||||
const definitions = require('jsdoc/tag/dictionary/definitions');
|
||||
const jsdocEnv = require('jsdoc/env');
|
||||
const { log } = require('@jsdoc/util');
|
||||
|
||||
const hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
@ -10,8 +9,6 @@ const DEFINITIONS = {
|
||||
jsdoc: 'jsdocTags',
|
||||
};
|
||||
|
||||
let dictionary;
|
||||
|
||||
/** @private */
|
||||
class TagDefinition {
|
||||
constructor(dict, title, etc) {
|
||||
@ -173,11 +170,5 @@ class Dictionary {
|
||||
}
|
||||
}
|
||||
|
||||
// initialize the default dictionary
|
||||
dictionary = Dictionary.fromConfig(jsdocEnv);
|
||||
|
||||
// make the constructor available for unit-testing purposes
|
||||
dictionary.Dictionary = Dictionary;
|
||||
|
||||
/** @type {module:jsdoc/tag/dictionary.Dictionary} */
|
||||
module.exports = dictionary;
|
||||
exports.Dictionary = Dictionary;
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
* @module jsdoc/util/templateHelper
|
||||
*/
|
||||
const catharsis = require('catharsis');
|
||||
let dictionary = require('jsdoc/tag/dictionary');
|
||||
const { inline } = require('@jsdoc/tag');
|
||||
const { log } = require('@jsdoc/util');
|
||||
const { longnamesToTree, SCOPE, SCOPE_TO_PUNC, toParts } = require('@jsdoc/core').name;
|
||||
@ -42,7 +41,7 @@ const registerId = (exports.registerId = (longname, fragment) => {
|
||||
linkMap.longnameToId[longname] = fragment;
|
||||
});
|
||||
|
||||
function getNamespace(kind) {
|
||||
function getNamespace(kind, dictionary) {
|
||||
if (dictionary.isNamespace(kind)) {
|
||||
return `${kind}:`;
|
||||
}
|
||||
@ -50,8 +49,10 @@ function getNamespace(kind) {
|
||||
return '';
|
||||
}
|
||||
|
||||
function formatNameForLink(doclet) {
|
||||
let newName = getNamespace(doclet.kind) + (doclet.name || '') + (doclet.variation || '');
|
||||
function formatNameForLink(doclet, dependencies) {
|
||||
const dictionary = dependencies.get('tags');
|
||||
let newName =
|
||||
getNamespace(doclet.kind, dictionary) + (doclet.name || '') + (doclet.variation || '');
|
||||
const scopePunc = SCOPE_TO_PUNC[doclet.scope] || '';
|
||||
|
||||
// Only prepend the scope punctuation if it's not the same character that marks the start of a
|
||||
@ -100,9 +101,11 @@ function makeUniqueFilename(filename, str) {
|
||||
*
|
||||
* @function
|
||||
* @param {string} str The string to convert.
|
||||
* @param {Object} dependencies The JSDoc dependency container.
|
||||
* @return {string} The filename to use for the string.
|
||||
*/
|
||||
const getUniqueFilename = (exports.getUniqueFilename = (str) => {
|
||||
const getUniqueFilename = (exports.getUniqueFilename = (str, dependencies) => {
|
||||
const dictionary = dependencies.get('tags');
|
||||
const namespaces = dictionary.getNamespaces().join('|');
|
||||
let basename = (str || '')
|
||||
// use - instead of : in namespace prefixes
|
||||
@ -131,13 +134,13 @@ const getUniqueFilename = (exports.getUniqueFilename = (str) => {
|
||||
* register the filename.
|
||||
* @private
|
||||
*/
|
||||
function getFilename(longname) {
|
||||
function getFilename(longname, dependencies) {
|
||||
let fileUrl;
|
||||
|
||||
if (hasOwnProp.call(longnameToUrl, longname)) {
|
||||
fileUrl = longnameToUrl[longname];
|
||||
} else {
|
||||
fileUrl = getUniqueFilename(longname);
|
||||
fileUrl = getUniqueFilename(longname, dependencies);
|
||||
registerLink(longname, fileUrl);
|
||||
}
|
||||
|
||||
@ -852,9 +855,10 @@ exports.prune = (data, dependencies) => {
|
||||
* represents a method), the URL will consist of a filename and a fragment ID.
|
||||
*
|
||||
* @param {module:jsdoc/doclet.Doclet} doclet - The doclet that will be used to create the URL.
|
||||
* @param {Object} dependencies - The JSDoc dependency container.
|
||||
* @return {string} The URL to the generated documentation for the doclet.
|
||||
*/
|
||||
exports.createLink = (doclet) => {
|
||||
exports.createLink = (doclet, dependencies) => {
|
||||
let fakeContainer;
|
||||
let filename;
|
||||
let fileUrl;
|
||||
@ -875,21 +879,21 @@ exports.createLink = (doclet) => {
|
||||
|
||||
// the doclet gets its own HTML file
|
||||
if (containers.includes(doclet.kind) || isModuleExports(doclet)) {
|
||||
filename = getFilename(longname);
|
||||
filename = getFilename(longname, dependencies);
|
||||
}
|
||||
// mistagged version of a doclet that gets its own HTML file
|
||||
else if (!containers.includes(doclet.kind) && fakeContainer) {
|
||||
filename = getFilename(doclet.memberof || longname);
|
||||
filename = getFilename(doclet.memberof || longname, dependencies);
|
||||
if (doclet.name !== doclet.longname) {
|
||||
fragment = formatNameForLink(doclet);
|
||||
fragment = formatNameForLink(doclet, dependencies);
|
||||
fragment = getId(longname, fragment);
|
||||
}
|
||||
}
|
||||
// the doclet is within another HTML file
|
||||
else {
|
||||
filename = getFilename(doclet.memberof || exports.globalName);
|
||||
filename = getFilename(doclet.memberof || exports.globalName, dependencies);
|
||||
if (doclet.name !== doclet.longname || doclet.scope === SCOPE.NAMES.GLOBAL) {
|
||||
fragment = formatNameForLink(doclet);
|
||||
fragment = formatNameForLink(doclet, dependencies);
|
||||
fragment = getId(longname, fragment);
|
||||
}
|
||||
}
|
||||
@ -912,16 +916,3 @@ exports.createLink = (doclet) => {
|
||||
* @return {Object} A tree with information about each longname.
|
||||
*/
|
||||
exports.longnamesToTree = longnamesToTree;
|
||||
|
||||
/**
|
||||
* Replace the existing tag dictionary with a new tag dictionary.
|
||||
*
|
||||
* Used for testing only. Do not call this method directly. Instead, call
|
||||
* {@link module:jsdoc/doclet._replaceDictionary}, which also updates this module's tag dictionary.
|
||||
*
|
||||
* @private
|
||||
* @param {module:jsdoc/tag/dictionary.Dictionary} dict - The new tag dictionary.
|
||||
*/
|
||||
exports._replaceDictionary = function _replaceDictionary(dict) {
|
||||
dictionary = dict;
|
||||
};
|
||||
|
||||
@ -39,14 +39,14 @@ function getAncestorLinks(doclet) {
|
||||
return helper.getAncestorLinks(data, doclet);
|
||||
}
|
||||
|
||||
function hashToLink(doclet, hash) {
|
||||
function hashToLink(doclet, hash, dependencies) {
|
||||
let url;
|
||||
|
||||
if (!/^(#.+)/.test(hash)) {
|
||||
return hash;
|
||||
}
|
||||
|
||||
url = helper.createLink(doclet);
|
||||
url = helper.createLink(doclet, dependencies);
|
||||
url = url.replace(/(#.+|$)/, hash);
|
||||
|
||||
return `<a href="${url}">${hash}</a>`;
|
||||
@ -254,7 +254,7 @@ function generateSourceFiles(sourceFiles, encoding, outdir, dependencies) {
|
||||
Object.keys(sourceFiles).forEach((file) => {
|
||||
let source;
|
||||
// links are keyed to the shortened path in each doclet's `meta.shortpath` property
|
||||
const sourceOutfile = helper.getUniqueFilename(sourceFiles[file].shortened);
|
||||
const sourceOutfile = helper.getUniqueFilename(sourceFiles[file].shortened, dependencies);
|
||||
|
||||
helper.registerLink(sourceFiles[file].shortened, sourceOutfile);
|
||||
|
||||
@ -452,10 +452,10 @@ exports.publish = (taffyData, dependencies) => {
|
||||
|
||||
// claim some special filenames in advance, so the All-Powerful Overseer of Filename Uniqueness
|
||||
// doesn't try to hand them out later
|
||||
indexUrl = helper.getUniqueFilename('index');
|
||||
indexUrl = helper.getUniqueFilename('index', dependencies);
|
||||
// don't call registerLink() on this one! 'index' is also a valid longname
|
||||
|
||||
globalUrl = helper.getUniqueFilename('global');
|
||||
globalUrl = helper.getUniqueFilename('global', dependencies);
|
||||
helper.registerLink('global', globalUrl);
|
||||
|
||||
// set up templating
|
||||
@ -490,7 +490,7 @@ exports.publish = (taffyData, dependencies) => {
|
||||
}
|
||||
if (doclet.see) {
|
||||
doclet.see.forEach((seeItem, i) => {
|
||||
doclet.see[i] = hashToLink(doclet, seeItem);
|
||||
doclet.see[i] = hashToLink(doclet, seeItem, dependencies);
|
||||
});
|
||||
}
|
||||
|
||||
@ -595,7 +595,7 @@ exports.publish = (taffyData, dependencies) => {
|
||||
}
|
||||
data().each((doclet) => {
|
||||
let docletPath;
|
||||
const url = helper.createLink(doclet);
|
||||
const url = helper.createLink(doclet, dependencies);
|
||||
|
||||
helper.registerLink(doclet.longname, url);
|
||||
|
||||
|
||||
@ -1,14 +1,12 @@
|
||||
const { _replaceDictionary } = require('jsdoc/doclet');
|
||||
const { augmentAll } = require('jsdoc/augment');
|
||||
const { createParser } = require('jsdoc/src/parser');
|
||||
const { Dictionary } = require('jsdoc/tag/dictionary');
|
||||
const { EventBus } = require('@jsdoc/util');
|
||||
const fs = require('fs');
|
||||
const handlers = require('jsdoc/src/handlers');
|
||||
const path = require('path');
|
||||
|
||||
const bus = new EventBus('jsdoc');
|
||||
let originalDictionaries;
|
||||
const originalDictionaries = ['jsdoc', 'closure'];
|
||||
const parseResults = [];
|
||||
|
||||
const helpers = {
|
||||
@ -63,26 +61,20 @@ const helpers = {
|
||||
},
|
||||
getParseResults: () => parseResults,
|
||||
replaceTagDictionary: (dictionaryNames) => {
|
||||
let dict;
|
||||
const env = jsdoc.deps.get('env');
|
||||
const config = jsdoc.deps.get('config');
|
||||
|
||||
if (!Array.isArray(dictionaryNames)) {
|
||||
dictionaryNames = [dictionaryNames];
|
||||
}
|
||||
|
||||
originalDictionaries = env.conf.tags.dictionaries.slice();
|
||||
env.conf.tags.dictionaries = dictionaryNames;
|
||||
|
||||
dict = Dictionary.fromConfig(env);
|
||||
dict.Dictionary = Dictionary;
|
||||
_replaceDictionary(dict);
|
||||
|
||||
env.conf.tags.dictionaries = originalDictionaries;
|
||||
config.tags.dictionaries = dictionaryNames;
|
||||
jsdoc.deps.reset('tags');
|
||||
},
|
||||
restoreTagDictionary: () => {
|
||||
const env = jsdoc.deps.get('env');
|
||||
const config = jsdoc.deps.get('config');
|
||||
|
||||
_replaceDictionary(Dictionary.fromConfig(env));
|
||||
config.tags.dictionaries = originalDictionaries.slice();
|
||||
jsdoc.deps.reset('tags');
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ const hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
const options = jsdoc.deps.get('options');
|
||||
|
||||
describe('jsdoc/tag', () => {
|
||||
const jsdocDictionary = require('jsdoc/tag/dictionary');
|
||||
const jsdocDictionary = jsdoc.deps.get('tags');
|
||||
const jsdocTag = require('jsdoc/tag');
|
||||
const parseType = require('@jsdoc/tag').type.parse;
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
describe('jsdoc/tag/dictionary', () => {
|
||||
const dictionary = require('jsdoc/tag/dictionary');
|
||||
const Dictionary = dictionary.Dictionary;
|
||||
const { Dictionary } = require('jsdoc/tag/dictionary');
|
||||
|
||||
const env = jsdoc.deps.get('env');
|
||||
let testDictionary;
|
||||
@ -17,56 +16,12 @@ describe('jsdoc/tag/dictionary', () => {
|
||||
TAG_DEF = testDictionary.defineTag(TAG_TITLE, tagOptions).synonym(TAG_SYNONYM);
|
||||
});
|
||||
|
||||
it('is an instance of dictionary.Dictionary', () => {
|
||||
expect(dictionary instanceof dictionary.Dictionary).toBe(true);
|
||||
});
|
||||
|
||||
it('has a defineSynonym method', () => {
|
||||
expect(dictionary.defineSynonym).toBeFunction();
|
||||
});
|
||||
|
||||
it('has a defineTag method', () => {
|
||||
expect(dictionary.defineTag).toBeFunction();
|
||||
});
|
||||
|
||||
it('has a defineTags method', () => {
|
||||
expect(dictionary.defineTags).toBeFunction();
|
||||
});
|
||||
|
||||
it('has a fromConfig static method', () => {
|
||||
expect(dictionary.Dictionary.fromConfig).toBeFunction();
|
||||
});
|
||||
|
||||
it('has a lookup method', () => {
|
||||
expect(dictionary.lookup).toBeFunction();
|
||||
});
|
||||
|
||||
it('has a lookUp method', () => {
|
||||
expect(dictionary.lookUp).toBeFunction();
|
||||
});
|
||||
|
||||
it('has an isNamespace method', () => {
|
||||
expect(dictionary.isNamespace).toBeFunction();
|
||||
});
|
||||
|
||||
it('has a normalise method', () => {
|
||||
expect(dictionary.normalise).toBeFunction();
|
||||
});
|
||||
|
||||
it('has a normalize method', () => {
|
||||
expect(dictionary.normalize).toBeFunction();
|
||||
});
|
||||
|
||||
it('has a Dictionary constructor', () => {
|
||||
expect(dictionary.Dictionary).toBeFunction();
|
||||
});
|
||||
|
||||
describe('defineSynonym', () => {
|
||||
it('adds a synonym for the specified tag', () => {
|
||||
dictionary.defineTag('foo', {});
|
||||
dictionary.defineSynonym('foo', 'bar');
|
||||
testDictionary.defineTag('foo', {});
|
||||
testDictionary.defineSynonym('foo', 'bar');
|
||||
|
||||
expect(dictionary.normalize('bar')).toBe('foo');
|
||||
expect(testDictionary.normalize('bar')).toBe('foo');
|
||||
});
|
||||
});
|
||||
|
||||
@ -274,14 +229,4 @@ describe('jsdoc/tag/dictionary', () => {
|
||||
expect(testDictionary.normalize(TAG_SYNONYM)).toBe(TAG_DEF.title);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Dictionary', () => {
|
||||
it('is a constructor', () => {
|
||||
function newDictionary() {
|
||||
return new dictionary.Dictionary();
|
||||
}
|
||||
|
||||
expect(newDictionary).not.toThrow();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -15,7 +15,7 @@ describe('jsdoc/tag/validator', () => {
|
||||
});
|
||||
|
||||
describe('validate', () => {
|
||||
const dictionary = require('jsdoc/tag/dictionary');
|
||||
const dictionary = jsdoc.deps.get('tags');
|
||||
|
||||
const allowUnknown = Boolean(config.tags.allowUnknownTags);
|
||||
const badTag = { dependencies: jsdoc.deps, title: 'lkjasdlkjfb' };
|
||||
|
||||
@ -3,7 +3,8 @@ const hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
|
||||
describe('jsdoc/util/templateHelper', () => {
|
||||
const _ = require('lodash');
|
||||
const dictionary = require('jsdoc/tag/dictionary');
|
||||
const { Dependencies } = require('@jsdoc/core');
|
||||
const { Dictionary } = require('jsdoc/tag/dictionary');
|
||||
const doclet = require('jsdoc/doclet');
|
||||
const helper = require('jsdoc/util/templateHelper');
|
||||
const { taffy } = require('taffydb');
|
||||
@ -139,31 +140,31 @@ describe('jsdoc/util/templateHelper', () => {
|
||||
// TODO: needs more tests for unusual values and things that get special treatment (such as
|
||||
// inner members)
|
||||
it('should convert a simple string into the string plus the default extension', () => {
|
||||
const filename = helper.getUniqueFilename('BackusNaur');
|
||||
const filename = helper.getUniqueFilename('BackusNaur', jsdoc.deps);
|
||||
|
||||
expect(filename).toBe('BackusNaur.html');
|
||||
});
|
||||
|
||||
it('should replace slashes with underscores', () => {
|
||||
const filename = helper.getUniqueFilename('tick/tock');
|
||||
const filename = helper.getUniqueFilename('tick/tock', jsdoc.deps);
|
||||
|
||||
expect(filename).toBe('tick_tock.html');
|
||||
});
|
||||
|
||||
it('should replace other problematic characters with underscores', () => {
|
||||
const filename = helper.getUniqueFilename('a very strange \\/?*:|\'"<> filename');
|
||||
const filename = helper.getUniqueFilename('a very strange \\/?*:|\'"<> filename', jsdoc.deps);
|
||||
|
||||
expect(filename).toBe('a very strange __________ filename.html');
|
||||
});
|
||||
|
||||
it('should not allow a filename to start with an underscore', () => {
|
||||
expect(helper.getUniqueFilename('')).toBe('-_.html');
|
||||
expect(helper.getUniqueFilename('', jsdoc.deps)).toBe('-_.html');
|
||||
});
|
||||
|
||||
it('should not return the same filename twice', () => {
|
||||
const name = 'polymorphic';
|
||||
const filename1 = helper.getUniqueFilename(name);
|
||||
const filename2 = helper.getUniqueFilename(name);
|
||||
const filename1 = helper.getUniqueFilename(name, jsdoc.deps);
|
||||
const filename2 = helper.getUniqueFilename(name, jsdoc.deps);
|
||||
|
||||
expect(filename1).not.toBe(filename2);
|
||||
});
|
||||
@ -171,23 +172,26 @@ describe('jsdoc/util/templateHelper', () => {
|
||||
it('should not consider the same name with different letter case to be unique', () => {
|
||||
const camel = 'myJavaScriptIdentifier';
|
||||
const pascal = 'MyJavaScriptIdentifier';
|
||||
const filename1 = helper.getUniqueFilename(camel);
|
||||
const filename2 = helper.getUniqueFilename(pascal);
|
||||
const filename1 = helper.getUniqueFilename(camel, jsdoc.deps);
|
||||
const filename2 = helper.getUniqueFilename(pascal, jsdoc.deps);
|
||||
|
||||
expect(filename1.toLowerCase()).not.toBe(filename2.toLowerCase());
|
||||
});
|
||||
|
||||
it('should remove variations from the longname before generating the filename', () => {
|
||||
const filename = helper.getUniqueFilename('MyClass(foo, bar)');
|
||||
const filename = helper.getUniqueFilename('MyClass(foo, bar)', jsdoc.deps);
|
||||
|
||||
expect(filename).toBe('MyClass.html');
|
||||
});
|
||||
|
||||
it('should generate the correct filename for built-in namespaces', () => {
|
||||
const filenameEvent = helper.getUniqueFilename('event:userDidSomething');
|
||||
const filenameExternal = helper.getUniqueFilename('external:NotInThisPackage');
|
||||
const filenameModule = helper.getUniqueFilename('module:some/sort/of/module');
|
||||
const filenamePackage = helper.getUniqueFilename('package:node-solve-all-your-problems');
|
||||
const filenameEvent = helper.getUniqueFilename('event:userDidSomething', jsdoc.deps);
|
||||
const filenameExternal = helper.getUniqueFilename('external:NotInThisPackage', jsdoc.deps);
|
||||
const filenameModule = helper.getUniqueFilename('module:some/sort/of/module', jsdoc.deps);
|
||||
const filenamePackage = helper.getUniqueFilename(
|
||||
'package:node-solve-all-your-problems',
|
||||
jsdoc.deps
|
||||
);
|
||||
|
||||
expect(filenameEvent).toBe('event-userDidSomething.html');
|
||||
expect(filenameExternal).toBe('external-NotInThisPackage.html');
|
||||
@ -196,15 +200,16 @@ describe('jsdoc/util/templateHelper', () => {
|
||||
});
|
||||
|
||||
it('should generate the correct filename for user-specified namespaces', () => {
|
||||
const deps = new Dependencies();
|
||||
const dict = new Dictionary();
|
||||
let filename;
|
||||
const dict = new dictionary.Dictionary();
|
||||
|
||||
dict.defineTag('anaphylaxis', {
|
||||
isNamespace: true,
|
||||
});
|
||||
doclet._replaceDictionary(dict);
|
||||
deps.registerSingletonFactory('tags', () => dict);
|
||||
|
||||
filename = helper.getUniqueFilename('anaphylaxis:peanut');
|
||||
filename = helper.getUniqueFilename('anaphylaxis:peanut', deps);
|
||||
|
||||
expect(filename).toBe('anaphylaxis-peanut.html');
|
||||
});
|
||||
@ -1556,6 +1561,7 @@ describe('jsdoc/util/templateHelper', () => {
|
||||
describe('createLink', () => {
|
||||
it('should create a url for a simple global.', () => {
|
||||
const mockDoclet = {
|
||||
dependencies: jsdoc.deps,
|
||||
kind: 'function',
|
||||
longname: 'foo',
|
||||
name: 'foo',
|
||||
@ -1568,6 +1574,7 @@ describe('jsdoc/util/templateHelper', () => {
|
||||
|
||||
it('should create a url for a namespace.', () => {
|
||||
const mockDoclet = {
|
||||
dependencies: jsdoc.deps,
|
||||
kind: 'namespace',
|
||||
longname: 'foo',
|
||||
name: 'foo',
|
||||
@ -1579,6 +1586,7 @@ describe('jsdoc/util/templateHelper', () => {
|
||||
|
||||
it('should create a url for a member of a namespace.', () => {
|
||||
const mockDoclet = {
|
||||
dependencies: jsdoc.deps,
|
||||
kind: 'function',
|
||||
longname: 'ns.foo',
|
||||
name: 'foo',
|
||||
@ -1590,6 +1598,7 @@ describe('jsdoc/util/templateHelper', () => {
|
||||
});
|
||||
|
||||
const nestedNamespaceDoclet = {
|
||||
dependencies: jsdoc.deps,
|
||||
kind: 'function',
|
||||
longname: 'ns1.ns2.foo',
|
||||
name: 'foo',
|
||||
@ -1611,6 +1620,7 @@ describe('jsdoc/util/templateHelper', () => {
|
||||
|
||||
it('should create a url for a name with invalid characters.', () => {
|
||||
const mockDoclet = {
|
||||
dependencies: jsdoc.deps,
|
||||
kind: 'function',
|
||||
longname: 'ns1."!"."*foo"',
|
||||
name: '"*foo"',
|
||||
@ -1623,6 +1633,7 @@ describe('jsdoc/util/templateHelper', () => {
|
||||
|
||||
it('should create a url for a function that is the only symbol exported by a module.', () => {
|
||||
const mockDoclet = {
|
||||
dependencies: jsdoc.deps,
|
||||
kind: 'function',
|
||||
longname: 'module:bar',
|
||||
name: 'module:bar',
|
||||
@ -1634,11 +1645,13 @@ describe('jsdoc/util/templateHelper', () => {
|
||||
|
||||
it('should create a url for a doclet with the wrong kind (caused by incorrect JSDoc tags', () => {
|
||||
const moduleDoclet = {
|
||||
dependencies: jsdoc.deps,
|
||||
kind: 'module',
|
||||
longname: 'module:baz',
|
||||
name: 'module:baz',
|
||||
};
|
||||
const badDoclet = {
|
||||
dependencies: jsdoc.deps,
|
||||
kind: 'member',
|
||||
longname: 'module:baz',
|
||||
name: 'module:baz',
|
||||
@ -1652,11 +1665,13 @@ describe('jsdoc/util/templateHelper', () => {
|
||||
|
||||
it('should create a url for a function that is a member of a doclet with the wrong kind', () => {
|
||||
const badModuleDoclet = {
|
||||
dependencies: jsdoc.deps,
|
||||
kind: 'member',
|
||||
longname: 'module:qux',
|
||||
name: 'module:qux',
|
||||
};
|
||||
const memberDoclet = {
|
||||
dependencies: jsdoc.deps,
|
||||
kind: 'function',
|
||||
name: 'frozzle',
|
||||
memberof: 'module:qux',
|
||||
@ -1672,6 +1687,7 @@ describe('jsdoc/util/templateHelper', () => {
|
||||
|
||||
it('should include the scope punctuation in the fragment ID for static members', () => {
|
||||
const functionDoclet = {
|
||||
dependencies: jsdoc.deps,
|
||||
kind: 'function',
|
||||
longname: 'Milk.pasteurize',
|
||||
name: 'pasteurize',
|
||||
@ -1685,6 +1701,7 @@ describe('jsdoc/util/templateHelper', () => {
|
||||
|
||||
it('should include the scope punctuation in the fragment ID for inner members', () => {
|
||||
const functionDoclet = {
|
||||
dependencies: jsdoc.deps,
|
||||
kind: 'function',
|
||||
longname: 'Milk~removeSticksAndLeaves',
|
||||
name: 'removeSticksAndLeaves',
|
||||
@ -1698,6 +1715,7 @@ describe('jsdoc/util/templateHelper', () => {
|
||||
|
||||
it('should omit the scope punctuation from the fragment ID for instance members', () => {
|
||||
const propertyDoclet = {
|
||||
dependencies: jsdoc.deps,
|
||||
kind: 'member',
|
||||
longname: 'Milk#calcium',
|
||||
name: 'calcium',
|
||||
@ -1711,6 +1729,7 @@ describe('jsdoc/util/templateHelper', () => {
|
||||
|
||||
it('should include the variation, if present, in the fragment ID', () => {
|
||||
const variationDoclet = {
|
||||
dependencies: jsdoc.deps,
|
||||
kind: 'function',
|
||||
longname: 'Milk#fat(percent)',
|
||||
name: 'fat',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user