refactor(jsdoc): remove jsdoc/util/logger

BREAKING CHANGE: `jsdoc/util/logger` was removed. Use `@jsdoc/util.log` instead.
This commit is contained in:
Jeff Williams 2020-02-29 15:03:36 -08:00
parent 901e4884a3
commit a59fe90cdf
51 changed files with 443 additions and 815 deletions

View File

@ -3,7 +3,7 @@
const { config } = require('@jsdoc/core');
const Engine = require('@jsdoc/cli');
const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const { EventBus, log } = require('@jsdoc/util');
const stripBom = require('strip-bom');
const stripJsonComments = require('strip-json-comments');
const Promise = require('bluebird');
@ -22,10 +22,12 @@ module.exports = (() => {
tmpdir: null
};
const FATAL_ERROR_MESSAGE = 'Exiting JSDoc because an error occurred. See the previous log ' +
'messages for details.';
const bus = new EventBus('jsdoc');
const cli = {};
const engine = new Engine();
const FATAL_ERROR_MESSAGE = 'Exiting JSDoc because an error occurred. See the previous log ' +
'messages for details.';
const LOG_LEVELS = Engine.LOG_LEVELS;
// TODO: docs
cli.setVersionInfo = () => {
@ -96,24 +98,24 @@ module.exports = (() => {
}
if (env.opts.test) {
logger.setLevel(logger.LEVELS.SILENT);
engine.logLevel = LOG_LEVELS.SILENT;
} else {
if (env.opts.debug) {
logger.setLevel(logger.LEVELS.DEBUG);
engine.logLevel = LOG_LEVELS.DEBUG;
}
else if (env.opts.verbose) {
logger.setLevel(logger.LEVELS.INFO);
engine.logLevel = LOG_LEVELS.INFO;
}
if (env.opts.pedantic) {
logger.once('logger:warn', recoverableError);
logger.once('logger:error', fatalError);
bus.once('logger:warn', recoverableError);
bus.once('logger:error', fatalError);
}
else {
logger.once('logger:error', recoverableError);
bus.once('logger:error', recoverableError);
}
logger.once('logger:fatal', fatalError);
bus.once('logger:fatal', fatalError);
}
return cli;
@ -121,8 +123,8 @@ module.exports = (() => {
// TODO: docs
cli.logStart = () => {
logger.debug(engine.versionDetails);
logger.debug('Environment info: %j', {
log.debug(engine.versionDetails);
log.debug('Environment info: %j', {
env: {
conf: env.conf,
opts: env.opts
@ -141,7 +143,7 @@ module.exports = (() => {
if (delta !== undefined) {
deltaSeconds = (delta / 1000).toFixed(2);
logger.info(`Finished running in ${deltaSeconds} seconds.`);
log.info(`Finished running in ${deltaSeconds} seconds.`);
}
};
@ -222,7 +224,7 @@ module.exports = (() => {
return stripJsonComments( fs.readFileSync(filepath, 'utf8') );
}
catch (e) {
logger.error(`Unable to read the package file ${filepath}`);
log.error(`Unable to read the package file ${filepath}`);
return null;
}
@ -323,11 +325,11 @@ module.exports = (() => {
packageDocs.files = env.sourceFiles || [];
docs.push(packageDocs);
logger.debug('Adding inherited symbols, mixins, and interface implementations...');
log.debug('Adding inherited symbols, mixins, and interface implementations...');
augment.augmentAll(docs);
logger.debug('Adding borrowed doclets...');
log.debug('Adding borrowed doclets...');
borrow.resolveBorrows(docs);
logger.debug('Post-processing complete.');
log.debug('Post-processing complete.');
props.parser.fireProcessingComplete(docs);
@ -380,14 +382,14 @@ module.exports = (() => {
template = require(`${env.opts.template}/publish`);
}
catch (e) {
logger.fatal(`Unable to load template: ${e.message}` || e);
log.fatal(`Unable to load template: ${e.message}` || e);
}
// templates should include a publish.js file that exports a "publish" function
if (template.publish && typeof template.publish === 'function') {
let publishPromise;
logger.info('Generating output files...');
log.info('Generating output files...');
publishPromise = template.publish(
taffy(props.docs),
env.opts,
@ -399,7 +401,7 @@ module.exports = (() => {
else {
message = `${env.opts.template} does not export a "publish" function. ` +
'Global "publish" functions are no longer supported.';
logger.fatal(message);
log.fatal(message);
return Promise.reject(new Error(message));
}

View File

@ -1,4 +1,4 @@
const logger = require('jsdoc/util/logger');
const { log } = require('@jsdoc/util');
const stripBom = require('strip-bom');
/**
@ -82,7 +82,7 @@ class Package {
packageInfo = JSON.parse(json ? stripBom(json) : '{}');
}
catch (e) {
logger.error('Unable to parse the package file: %s', e.message);
log.error(`Unable to parse the package file: ${e.message}`);
packageInfo = {};
}

View File

@ -1,6 +1,6 @@
const babelParser = require('@babel/parser');
const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const { log } = require('@jsdoc/util');
// exported so we can use them in tests
const parserOptions = exports.parserOptions = {
@ -46,10 +46,9 @@ function parse(source, filename) {
try {
ast = babelParser.parse(source, parserOptions);
// console.log(JSON.stringify(ast, null, 2));
}
catch (e) {
logger.error(`Unable to parse ${filename}: ${e.message}`);
log.error(`Unable to parse ${filename}: ${e.message}`);
}
return ast;

View File

@ -3,7 +3,7 @@
*/
const { Doclet } = require('jsdoc/doclet');
const escape = require('escape-string-regexp');
const logger = require('jsdoc/util/logger');
const { log } = require('@jsdoc/util');
const { SCOPE } = require('@jsdoc/core').name;
const { Syntax } = require('jsdoc/src/syntax');
@ -36,7 +36,7 @@ function createDoclet(comment, e) {
catch (error) {
flatComment = comment.replace(/[\r\n]/g, '');
msg = `cannot create a doclet for the comment "${flatComment}": ${error.message}`;
logger.error(msg);
log.error(msg);
doclet = new Doclet('', e);
}

View File

@ -6,7 +6,7 @@ const astNode = require('jsdoc/src/astnode');
const { conf } = require('jsdoc/env');
const { EventEmitter } = require('events');
const fs = require('fs');
const logger = require('jsdoc/util/logger');
const { log } = require('@jsdoc/util');
const { getBasename, LONGNAMES, SCOPE, toParts } = require('@jsdoc/core').name;
const { Syntax } = require('jsdoc/src/syntax');
@ -57,7 +57,7 @@ exports.createParser = type => {
modulePath = PARSERS[type];
}
else {
logger.fatal('The parser type "%s" is not recognized.', type);
log.fatal(`The parser type "${type}" is not recognized.`);
return null;
}
@ -168,7 +168,7 @@ class Parser extends EventEmitter {
}
e.sourcefiles = sourceFiles;
logger.debug('Parsing source files: %j', sourceFiles);
log.debug('Parsing source files: %j', sourceFiles);
this.emit('parseBegin', e);
@ -186,7 +186,7 @@ class Parser extends EventEmitter {
sourceCode = fs.readFileSync(filename, encoding);
}
catch (err) {
logger.error('Unable to read and parse the source file %s: %s', filename, err);
log.error(`Unable to read and parse the source file ${filename}: ${err}`);
}
}
@ -200,7 +200,7 @@ class Parser extends EventEmitter {
sourcefiles: parsedFiles,
doclets: this._resultBuffer
});
logger.debug('Finished parsing source files.');
log.debug('Finished parsing source files.');
return this._resultBuffer;
}
@ -270,7 +270,7 @@ class Parser extends EventEmitter {
};
this.emit('fileBegin', e);
logger.info('Parsing %s ...', sourceName);
log.info(`Parsing ${sourceName} ...`);
if (!e.defaultPrevented) {
e = {

View File

@ -2,7 +2,7 @@
* @module jsdoc/src/scanner
*/
const { EventEmitter } = require('events');
const logger = require('jsdoc/util/logger');
const { log } = require('@jsdoc/util');
const { lsSync } = require('@jsdoc/util').fs;
const path = require('path');
const { statSync } = require('fs');
@ -35,7 +35,7 @@ class Scanner extends EventEmitter {
currentFile = statSync(filepath);
}
catch (e) {
logger.error('Unable to find the source file or directory %s', filepath);
log.error(`Unable to find the source file or directory ${filepath}`);
return;
}

View File

@ -4,7 +4,7 @@
* @module jsdoc/src/walker
*/
const astnode = require('jsdoc/src/astnode');
const logger = require('jsdoc/util/logger');
const { log } = require('@jsdoc/util');
const { Syntax } = require('jsdoc/src/syntax');
// TODO: docs
@ -646,8 +646,10 @@ class Walker {
};
function logUnknownNodeType({type}) {
logger.debug('Found a node with unrecognized type %s. Ignoring the node and its ' +
'descendants.', type);
log.debug(
`Found a node with unrecognized type ${type}. Ignoring the node and its ` +
'descendants.'
);
}
function cb(node, parent, cbState) {

View File

@ -3,7 +3,7 @@
* @module jsdoc/tag
*/
const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const { log } = require('@jsdoc/util');
const path = require('path');
const tag = {
dictionary: require('jsdoc/tag/dictionary'),
@ -58,7 +58,7 @@ function parseType({text, originalTitle}, {canHaveName, canHaveType}, meta) {
return tag.type.parse(text, canHaveName, canHaveType);
}
catch (e) {
logger.error(
log.error(
'Unable to parse a tag\'s type expression%s with tag title "%s" and text "%s": %s',
meta.filename ? ( ` for source file ${path.join(meta.path, meta.filename)}${meta.lineno ? (` in line ${meta.lineno}`) : ''}` ) : '',
originalTitle,

View File

@ -7,7 +7,7 @@ const { applyNamespace, SCOPE, LONGNAMES } = require('@jsdoc/core').name;
const commonPathPrefix = require('common-path-prefix');
const env = require('jsdoc/env');
const { isInlineTag } = require('jsdoc/tag/inline');
const logger = require('jsdoc/util/logger');
const { log } = require('@jsdoc/util');
const { nodeToValue } = require('jsdoc/src/astnode');
const path = require('path');
const { Syntax } = require('jsdoc/src/syntax');
@ -79,7 +79,7 @@ function setDocletScopeToTitle(doclet, {title}) {
doclet.setScope(title);
}
catch (e) {
logger.error(e.message);
log.error(e.message);
}
}
@ -1064,8 +1064,10 @@ exports.defineTags = (dictionary, tagDefinitions) => {
dictionaries = env.conf.tags.dictionaries;
if (!dictionaries) {
logger.error('The configuration setting "tags.dictionaries" is undefined. ' +
'Unable to load tag definitions.');
log.error(
'The configuration setting "tags.dictionaries" is undefined. ' +
'Unable to load tag definitions.'
);
return;
}
@ -1077,8 +1079,10 @@ exports.defineTags = (dictionary, tagDefinitions) => {
const tagDefs = exports[DEFINITIONS[dictName]];
if (!tagDefs) {
logger.error('The configuration setting "tags.dictionaries" contains ' +
'the unknown dictionary name %s. Ignoring the dictionary.', dictName);
log.error(
'The configuration setting "tags.dictionaries" contains ' +
`the unknown dictionary name ${dictName}. Ignoring the dictionary.`
);
return;
}

View File

@ -3,7 +3,7 @@
* @requires jsdoc/tag/dictionary
*/
const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const { log } = require('@jsdoc/util');
function buildMessage(tagName, {filename, lineno, comment}, desc) {
let result = `The @${tagName} tag ${desc}. File: ${filename}, line: ${lineno}`;
@ -27,7 +27,7 @@ exports.validate = ({title, text, value}, tagDef, meta) => {
if (!allowUnknownTags ||
(Array.isArray(allowUnknownTags) &&
!allowUnknownTags.includes(title))) {
logger.error( buildMessage(title, meta, 'is not a known tag') );
log.error(buildMessage(title, meta, 'is not a known tag'));
}
// stop validation, since there's nothing to validate against
@ -36,16 +36,16 @@ exports.validate = ({title, text, value}, tagDef, meta) => {
// check for errors that make the tag useless
if (!text && tagDef.mustHaveValue) {
logger.error( buildMessage(title, meta, 'requires a value') );
log.error(buildMessage(title, meta, 'requires a value'));
}
// check for minor issues that are usually harmless
else if (text && tagDef.mustNotHaveValue) {
logger.warn( buildMessage(title, meta,
log.warn(buildMessage(title, meta,
'does not permit a value; the value will be ignored'));
}
else if (value && value.description && tagDef.mustNotHaveDescription) {
logger.warn( buildMessage(title, meta,
log.warn(buildMessage(title, meta,
'does not permit a description; the description will be ignored'));
}
};

View File

@ -3,7 +3,7 @@
*/
const env = require('jsdoc/env');
const fs = require('fs');
const logger = require('jsdoc/util/logger');
const { log } = require('@jsdoc/util');
const { lsSync } = require('@jsdoc/util').fs;
const path = require('path');
const stripBom = require('strip-bom');
@ -62,7 +62,10 @@ function addTutorialConf(name, meta) {
}
// check if the tutorial has already been defined...
if (hasOwnProp.call(conf, name)) {
logger.warn(`Metadata for the tutorial ${name} is defined more than once. Only the first definition will be used.`);
log.warn(
`Metadata for the tutorial ${name} is defined more than once. ` +
'Only the first definition will be used.'
);
} else {
conf[name] = meta;
}
@ -81,7 +84,10 @@ function addTutorialConf(name, meta) {
*/
exports.addTutorial = current => {
if (exports.root.getByName(current.name)) {
logger.warn('The tutorial %s is defined more than once. Only the first definition will be used.', current.name);
log.warn(
`The tutorial ${current.name} is defined more than once. ` +
'Only the first definition will be used.'
);
} else {
// by default, the root tutorial is the parent
current.setParent(exports.root);
@ -175,7 +181,7 @@ exports.resolve = () => {
const childTutorial = exports.root.getByName(child);
if (!childTutorial) {
logger.error('Missing child tutorial: %s', child);
log.error(`Missing child tutorial: ${child}`);
}
else {
childTutorial.setParent(current);

View File

@ -1,254 +0,0 @@
/**
* Logging tools for JSDoc.
*
* Log messages are printed to the console based on the current logging level. By default, messages
* at level `{@link module:jsdoc/util/logger.LEVELS.ERROR}` or above are logged; all other messages
* are ignored.
*
* In addition, the module object emits an event whenever a logger method is called, regardless of
* the current logging level. The event's name is the string `logger:` followed by the logger's name
* (for example, `logger:error`). The event handler receives an array of arguments that were passed
* to the logger method.
*
* Each logger method accepts a `message` parameter that may contain zero or more placeholders. Each
* placeholder is replaced by the corresponding argument following the message. If the placeholder
* does not have a corresponding argument, the placeholder is not replaced.
*
* The following placeholders are supported:
*
* + `%s`: String.
* + `%d`: Number.
* + `%j`: JSON.
*
* @module jsdoc/util/logger
* @extends module:events.EventEmitter
* @example
* var logger = require('jsdoc/util/logger');
*
* var data = {
* foo: 'bar'
* };
* var name = 'baz';
*
* logger.warn('%j %s', data, name); // prints '{"foo":"bar"} baz'
* @see http://nodejs.org/api/util.html#util_util_format_format
*/
const { EventEmitter } = require('events');
const util = require('util');
/* eslint-disable no-empty-function */
class Logger extends EventEmitter {}
/* eslint-enable no-empty-function */
const logger = module.exports = new Logger();
/**
* Logging levels for the JSDoc logger. The default logging level is
* {@link module:jsdoc/util/logger.LEVELS.ERROR}.
*
* @alias module:jsdoc/util/logger.LEVELS
* @enum
* @type {number}
*/
const LEVELS = logger.LEVELS = {
/**
* Do not log any messages.
*
* @alias module:jsdoc/util/logger.LEVELS.SILENT
*/
SILENT: 0,
/**
* Log fatal errors that prevent JSDoc from running.
*
* @alias module:jsdoc/util/logger.LEVELS.FATAL
*/
FATAL: 10,
/**
* Log all errors, including errors from which JSDoc can recover.
*
* @alias module:jsdoc/util/logger.LEVELS.ERROR
*/
ERROR: 20,
/**
* Log the following messages:
*
* + Warnings
* + Errors
*
* @alias module:jsdoc/util/logger.LEVELS.WARN
*/
WARN: 30,
/**
* Log the following messages:
*
* + Informational messages
* + Warnings
* + Errors
*
* @alias module:jsdoc/util/logger.LEVELS.INFO
*/
INFO: 40,
/**
* Log the following messages:
*
* + Debugging messages
* + Informational messages
* + Warnings
* + Errors
*
* @alias module:jsdoc/util/logger.LEVELS.DEBUG
*/
DEBUG: 50,
/**
* Log all messages.
*
* @alias module:jsdoc/util/logger.LEVELS.VERBOSE
*/
VERBOSE: 1000
};
const DEFAULT_LEVEL = LEVELS.WARN;
let logLevel = DEFAULT_LEVEL;
const PREFIXES = {
DEBUG: 'DEBUG: ',
ERROR: 'ERROR: ',
FATAL: 'FATAL: ',
WARN: 'WARNING: '
};
// Add a prefix to a log message if necessary.
function addPrefix(args, prefix) {
let updatedArgs;
if (prefix && typeof args[0] === 'string') {
updatedArgs = args.slice(0);
updatedArgs[0] = prefix + updatedArgs[0];
}
return updatedArgs || args;
}
// TODO: document events
function wrapLogFunction(name, func) {
const eventName = `logger:${name}`;
const upperCaseName = name.toUpperCase();
const level = LEVELS[upperCaseName];
const prefix = PREFIXES[upperCaseName];
return function() {
let loggerArgs;
const args = Array.prototype.slice.call(arguments, 0);
if (logLevel >= level) {
loggerArgs = addPrefix(args, prefix);
func(...loggerArgs);
}
args.unshift(eventName);
logger.emit(...args);
};
}
// Print a message to STDOUT without a terminating newline.
function printToStdout(...args) {
process.stdout.write( util.format(...args) );
}
/**
* Log a message at log level {@link module:jsdoc/util/logger.LEVELS.DEBUG}.
*
* @alias module:jsdoc/util/logger.debug
* @param {string} message - The message to log.
* @param {...*=} values - The values that will replace the message's placeholders.
*/
logger.debug = wrapLogFunction('debug', console.info);
/**
* Print a string at log level {@link module:jsdoc/util/logger.LEVELS.DEBUG}. The string is not
* terminated by a newline.
*
* @alias module:jsdoc/util/logger.printDebug
* @param {string} message - The message to log.
* @param {...*=} values - The values that will replace the message's placeholders.
*/
logger.printDebug = wrapLogFunction('debug', printToStdout);
/**
* Log a message at log level {@link module:jsdoc/util/logger.LEVELS.ERROR}.
*
* @alias module:jsdoc/util/logger.error
* @param {string} message - The message to log.
* @param {...*=} values - The values that will replace the message's placeholders.
*/
logger.error = wrapLogFunction('error', console.error);
/**
* Log a message at log level {@link module:jsdoc/util/logger.LEVELS.FATAL}.
*
* @alias module:jsdoc/util/logger.fatal
* @param {string} message - The message to log.
* @param {...*=} values - The values that will replace the message's placeholders.
*/
logger.fatal = wrapLogFunction('fatal', console.error);
/**
* Log a message at log level {@link module:jsdoc/util/logger.LEVELS.INFO}.
*
* @alias module:jsdoc/util/logger.info
* @param {string} message - The message to log.
* @param {...*=} values - The values that will replace the message's placeholders.
*/
logger.info = wrapLogFunction('info', console.info);
/**
* Print a string at log level {@link module:jsdoc/util/logger.LEVELS.INFO}. The string is not
* terminated by a newline.
*
* @alias module:jsdoc/util/logger.printInfo
* @param {string} message - The message to log.
* @param {...*=} values - The values that will replace the message's placeholders.
*/
logger.printInfo = wrapLogFunction('info', printToStdout);
/**
* Log a message at log level {@link module:jsdoc/util/logger.LEVELS.VERBOSE}.
*
* @alias module:jsdoc/util/logger.verbose
* @param {string} message - The message to log.
* @param {...*=} values - The values that will replace the message's placeholders.
*/
logger.verbose = wrapLogFunction('verbose', console.info);
/**
* Print a string at log level {@link module:jsdoc/util/logger.LEVELS.VERBOSE}. The string is not
* terminated by a newline.
*
* @alias module:jsdoc/util/logger.printVerbose
* @param {string} message - The message to log.
* @param {...*=} values - The values that will replace the message's placeholders.
*/
logger.printVerbose = wrapLogFunction('verbose', printToStdout);
/**
* Log a message at log level {@link module:jsdoc/util/logger.LEVELS.WARN}.
*
* @alias module:jsdoc/util/logger.warn
* @param {string} message - The message to log.
* @param {...*=} values - The values that will replace the message's placeholders.
*/
logger.warn = wrapLogFunction('warn', console.warn);
/**
* Set the log level.
*
* @alias module:jsdoc/util/logger.setLevel
* @param {module:jsdoc/util/logger.LEVELS} level - The log level to use.
*/
logger.setLevel = function(level) {
logLevel = (level !== undefined) ? level : DEFAULT_LEVEL;
};
/**
* Get the current log level.
*
* @alias module:jsdoc/util/logger.getLevel
* @return {module:jsdoc/util/logger.LEVELS} The current log level.
*/
logger.getLevel = function() {
return logLevel;
};

View File

@ -3,7 +3,7 @@
* @module jsdoc/util/markdown
*/
const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const { log } = require('@jsdoc/util');
const MarkdownIt = require('markdown-it');
const marked = require('marked');
const mda = require('markdown-it-anchor');
@ -143,11 +143,11 @@ function getHighlighter(conf) {
try {
highlighter = require(conf.highlight).highlight;
} catch (e) {
logger.error(e);
log.error(e);
}
if (typeof highlighter !== 'function') {
logger.error(`The syntax highlighting module ${conf.highlight} does not assign a ` +
log.error(`The syntax highlighting module ${conf.highlight} does not assign a ` +
'method to `exports.highlight`. Using the default syntax highlighter.');
highlighter = highlight;
}
@ -249,8 +249,9 @@ function getParseFunction(parserName, conf) {
return parserFunction;
default:
logger.error(`Unrecognized Markdown parser "${parserName}". Markdown support is ` +
'disabled.');
log.error(
`Unrecognized Markdown parser "${parserName}". Markdown support is disabled.`
);
return undefined;
}

View File

@ -5,7 +5,7 @@ const catharsis = require('catharsis');
let dictionary = require('jsdoc/tag/dictionary');
const env = require('jsdoc/env');
const inline = require('jsdoc/tag/inline');
const logger = require('jsdoc/util/logger');
const { log } = require('@jsdoc/util');
const { longnamesToTree, SCOPE, SCOPE_TO_PUNC, toParts } = require('@jsdoc/core').name;
const hasOwnProp = Object.prototype.hasOwnProperty;
@ -252,7 +252,7 @@ function parseType(longname) {
}
catch (e) {
err = new Error(`unable to parse ${longname}: ${e.message}`);
logger.error(err);
log.error(err);
return longname;
}
@ -435,7 +435,7 @@ const tutorialToUrl = exports.tutorialToUrl = tutorial => {
// no such tutorial
if (!node) {
logger.error( new Error(`No such tutorial: ${tutorial}`) );
log.error( new Error(`No such tutorial: ${tutorial}`) );
return null;
}
@ -474,7 +474,7 @@ const toTutorial = exports.toTutorial = (tutorial, content, missingOpts) => {
if (!tutorial) {
logger.error( new Error('Missing required parameter: tutorial') );
log.error(new Error('Missing required parameter: tutorial'));
return null;
}

View File

@ -1,7 +1,7 @@
/**
* @module plugins/sourcetag
*/
const logger = require('jsdoc/util/logger');
const { log } = require('@jsdoc/util');
exports.handlers = {
/**
@ -35,7 +35,10 @@ exports.handlers = {
value = JSON.parse(tag.value);
}
catch (ex) {
logger.error('@source tag expects a valid JSON value, like { "filename": "myfile.js", "lineno": 123 }.');
log.error(
'@source tag expects a valid JSON value, like ' +
'{ "filename": "myfile.js", "lineno": 123 }.'
);
return;
}

View File

@ -4,10 +4,12 @@ const { createParser } = require('jsdoc/src/parser');
const { defineTags } = require('jsdoc/tag/dictionary/definitions');
const dictionary = require('jsdoc/tag/dictionary');
const env = require('jsdoc/env');
const { EventBus } = require('@jsdoc/util');
const fs = require('fs');
const handlers = require('jsdoc/src/handlers');
const path = require('path');
const bus = new EventBus('jsdoc');
const originalDictionary = dictionary;
const parseResults = [];
@ -19,6 +21,19 @@ const helpers = global.jsdoc = {
});
},
createParser,
didLog: (fn, level) => {
const events = [];
function listener(e) {
events.push(e);
}
bus.on(`logger:${level}`, listener);
fn();
bus.off(`logger:${level}`, listener);
return events.length !== 0;
},
getDocSetFromFile: (filename, parser, shouldValidate, augment) => {
let doclets;

View File

@ -46,22 +46,14 @@ describe('multiple doclets per symbol', () => {
it('When a file contains a JSDoc comment with an @also tag, and the "tags.allowUnknownTags" ' +
'option is set to false, the file can be parsed without errors.', () => {
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
const errors = [];
function errorListener(err) {
errors.push(err);
function getDocSet() {
env.conf.tags.allowUnknownTags = false;
jsdoc.getDocSetFromFile('test/fixtures/also2.js');
env.conf.tags.allowUnknownTags = allowUnknownTags;
}
logger.addListener('logger:error', errorListener);
env.conf.tags.allowUnknownTags = false;
jsdoc.getDocSetFromFile('test/fixtures/also2.js');
expect(errors[0]).not.toBeDefined();
logger.removeListener('logger:error', errorListener);
env.conf.tags.allowUnknownTags = allowUnknownTags;
expect(jsdoc.didLog(getDocSet, 'error')).toBeFalse();
});
});

View File

@ -1,10 +1,9 @@
const logger = require('jsdoc/util/logger');
describe('empty JSDoc comments', () => {
it('should not report an error when a JSDoc comment contains only whitespace', () => {
spyOn(logger, 'error');
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/emptycomments.js');
}
expect(logger.error).not.toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeFalse();
});
});

View File

@ -1,13 +1,10 @@
describe('JSX support', () => {
it('should parse JSX files without errors', () => {
const logger = require('jsdoc/util/logger');
function parseJsx() {
return jsdoc.getDocSetFromFile('test/fixtures/jsx.js');
}
spyOn(logger, 'error');
expect(parseJsx).not.toThrow();
expect(logger.error).not.toHaveBeenCalled();
expect(jsdoc.didLog(parseJsx, 'error')).toBeFalse();
});
});

View File

@ -3,7 +3,6 @@ const hasOwnProp = Object.prototype.hasOwnProperty;
describe('jsdoc/package', () => {
let emptyPackage;
const jsdocPackage = require('jsdoc/package');
const logger = require('jsdoc/util/logger');
const Package = jsdocPackage.Package;
function checkPackageProperty(name, value) {
@ -61,10 +60,8 @@ describe('jsdoc/package', () => {
return new Package('abcdefg');
}
spyOn(logger, 'error');
expect(newPackage).not.toThrow();
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(newPackage, 'error')).toBeTrue();
});
describe('author', () => {

View File

@ -23,19 +23,13 @@ describe('jsdoc/src/astbuilder', () => {
describe('build', () => {
// TODO: more tests
const logger = require('jsdoc/util/logger');
beforeEach(() => {
spyOn(logger, 'error');
});
it('should log (not throw) an error when a file cannot be parsed', () => {
function parse() {
builder.build('qwerty!!!!!', 'bad.js');
}
expect(parse).not.toThrow();
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(parse, 'error')).toBeTrue();
});
});
});

View File

@ -5,7 +5,6 @@ describe('jsdoc/src/parser', () => {
const { dirname } = require('jsdoc/env');
const fs = require('fs');
const jsdocParser = require('jsdoc/src/parser');
const logger = require('jsdoc/util/logger');
const path = require('path');
it('should exist', () => {
@ -32,10 +31,11 @@ describe('jsdoc/src/parser', () => {
});
it('should log a fatal error on bad input', () => {
spyOn(logger, 'fatal');
function createParser() {
jsdocParser.createParser('not-a-real-parser-ever');
}
expect(logger.fatal).toHaveBeenCalled();
expect(jsdoc.didLog(createParser, 'fatal')).toBeTrue();
});
});

View File

@ -4,7 +4,6 @@ describe('jsdoc/tag', () => {
const env = require('jsdoc/env');
const jsdocDictionary = require('jsdoc/tag/dictionary');
const jsdocTag = require('jsdoc/tag');
const logger = require('jsdoc/util/logger');
const parseType = require('jsdoc/tag/type').parse;
it('should exist', () => {
@ -115,14 +114,14 @@ describe('jsdoc/tag', () => {
let wsOnly;
let wsTrailing;
spyOn(logger, 'error');
function newTags() {
wsOnly = new jsdocTag.Tag('name', ' ', { code: { name: ' ' } });
wsLeading = new jsdocTag.Tag('name', ' foo', { code: { name: ' foo' } });
wsTrailing = new jsdocTag.Tag('name', 'foo ', { code: { name: 'foo ' } });
wsBoth = new jsdocTag.Tag('name', ' foo ', { code: { name: ' foo ' } });
}
expect(logger.error).not.toHaveBeenCalled();
expect(jsdoc.didLog(newTags, 'error')).toBeFalse();
expect(wsOnly.text).toBe('" "');
expect(wsLeading.text).toBe('" foo"');
expect(wsTrailing.text).toBe('"foo "');
@ -207,24 +206,20 @@ describe('jsdoc/tag', () => {
// further tests for this sort of thing are in jsdoc/tag/validator.js tests.
describe('tag validating', () => {
beforeEach(() => {
spyOn(logger, 'error');
});
it('logs an error for tags with bad type expressions', () => {
/* eslint-disable no-unused-vars */
const tag = new jsdocTag.Tag('param', '{!*!*!*!} foo');
/* eslint-enable no-unused-vars */
function newTag() {
return new jsdocTag.Tag('param', '{!*!*!*!} foo');
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(newTag, 'error')).toBeTrue();
});
it('validates tags with no text', () => {
/* eslint-disable no-unused-vars */
const tag = new jsdocTag.Tag('copyright');
/* eslint-enable no-unused-vars */
function newTag() {
return new jsdocTag.Tag('copyright');
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(newTag, 'error')).toBeTrue();
});
});
});

View File

@ -2,7 +2,6 @@ describe('jsdoc/tag/dictionary/definitions', () => {
const env = require('jsdoc/env');
const definitions = require('jsdoc/tag/dictionary/definitions');
const Dictionary = require('jsdoc/tag/dictionary').Dictionary;
const logger = require('jsdoc/util/logger');
it('should exist', () => {
expect(definitions).toBeObject();
@ -48,19 +47,21 @@ describe('jsdoc/tag/dictionary/definitions', () => {
});
it('should log an error if `env.conf.tags.dictionaries` is undefined', () => {
function defineTags() {
env.conf.tags.dictionaries = undefined;
spyOn(logger, 'error');
definitions.defineTags(tagDict);
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(defineTags, 'error')).toBeTrue();
});
it('should log an error if an unknown dictionary is requested', () => {
function defineTags() {
env.conf.tags.dictionaries = ['jsmarmoset'];
spyOn(logger, 'error');
definitions.defineTags(tagDict);
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(defineTags, 'error')).toBeTrue();
});
it('should add both JSDoc and Closure tags by default', () => {

View File

@ -1,7 +1,7 @@
describe('jsdoc/tag/validator', () => {
const _ = require('lodash');
const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const { EventBus } = require('@jsdoc/util');
const tag = require('jsdoc/tag');
const validator = require('jsdoc/tag/validator');
@ -19,7 +19,6 @@ describe('jsdoc/tag/validator', () => {
const allowUnknown = Boolean(env.conf.tags.allowUnknownTags);
const badTag = { title: 'lkjasdlkjfb' };
const badTag2 = new tag.Tag('type', '{string} I am a string!');
let errorSpy;
const meta = {
filename: 'asdf.js',
lineno: 1,
@ -32,80 +31,95 @@ describe('jsdoc/tag/validator', () => {
validator.validate(theTag, dictionary.lookUp(theTag.title), meta);
}
beforeEach(() => {
errorSpy = spyOn(logger, 'error');
spyOn(logger, 'warn');
});
afterEach(() => {
env.conf.tags.allowUnknownTags = allowUnknown;
});
it('logs an error if the tag is not in the dictionary and conf.tags.allowUnknownTags is false', () => {
function validate() {
env.conf.tags.allowUnknownTags = false;
validateTag(badTag);
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(validate, 'error')).toBeTrue();
});
it('logs an error if the tag is not in the dictionary and conf.tags.allowUnknownTags is does not include it', () => {
function validate() {
env.conf.tags.allowUnknownTags = [];
validateTag(badTag);
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(validate, 'error')).toBeTrue();
});
it('does not log an error if the tag is not in the dictionary and conf.tags.allowUnknownTags is true', () => {
function validate() {
env.conf.tags.allowUnknownTags = true;
validateTag(badTag);
}
expect(logger.error).not.toHaveBeenCalled();
expect(jsdoc.didLog(validate, 'error')).toBeFalse();
});
it('does not log an error if the tag is not in the dictionary and conf.tags.allowUnknownTags includes it', () => {
function validate() {
env.conf.tags.allowUnknownTags = [badTag.title];
validateTag(badTag);
}
expect(logger.error).not.toHaveBeenCalled();
expect(jsdoc.didLog(validate, 'error')).toBeFalse();
});
it('does not log an error for valid tags', () => {
function validate() {
validateTag(goodTag);
validateTag(goodTag2);
}
expect(logger.error).not.toHaveBeenCalled();
expect(jsdoc.didLog(validate, 'error')).toBeFalse();
});
it('logs an error if the tag has no text but mustHaveValue is true', () => {
function validate() {
const missingName = _.cloneDeep(goodTag);
missingName.text = null;
validateTag(missingName);
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(validate, 'error')).toBeTrue();
});
it('logs a warning if the tag has text but mustNotHaveValue is true', () => {
function validate() {
const missingText = _.cloneDeep(goodTag2);
missingText.mustNotHaveValue = true;
missingText.text = missingText.text || 'asdf';
validateTag(missingText);
}
expect(logger.warn).toHaveBeenCalled();
expect(jsdoc.didLog(validate, 'warn')).toBeTrue();
});
it('logs a warning if the tag has a description but mustNotHaveDescription is true', () => {
function validate() {
validateTag(badTag2);
}
expect(logger.warn).toHaveBeenCalled();
expect(jsdoc.didLog(validate, 'warn')).toBeTrue();
});
it('logs meta.comment when present', () => {
const bus = new EventBus('jsdoc');
const events = [];
bus.once('logger:error', e => events.push(e));
env.conf.tags.allowUnknownTags = false;
validateTag(badTag);
expect(errorSpy.calls.mostRecent().args[0]).toContain(meta.comment);
expect(events[0]).toContain(meta.comment);
});
});
});

View File

@ -1,6 +1,5 @@
describe('jsdoc/tutorial/resolver', () => {
const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const resolver = require('jsdoc/tutorial/resolver');
const tutorial = require('jsdoc/tutorial');
@ -160,8 +159,6 @@ describe('jsdoc/tutorial/resolver', () => {
// |- test4
describe('resolve', () => {
beforeEach(() => {
spyOn(logger, 'error');
spyOn(logger, 'warn');
loadTutorials();
resolver.resolve();
});
@ -211,27 +208,32 @@ describe('jsdoc/tutorial/resolver', () => {
});
it('logs an error for missing tutorials', () => {
function load() {
resolver.load(`${env.dirname}/test/fixtures/tutorials/incomplete`);
resolver.resolve();
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(load, 'error')).toBeTrue();
});
it('logs a warning for duplicate-named tutorials (e.g. test.md, test.html)', () => {
function load() {
const tute = new tutorial.Tutorial('myTutorial', '', tutorial.TYPES.HTML);
resolver.addTutorial(tute);
resolver.addTutorial(tute);
}
expect(logger.warn).toHaveBeenCalled();
expect(jsdoc.didLog(load, 'warn')).toBeTrue();
});
it('allows tutorials to be defined in one .json file and redefined in another', () => {
function load() {
resolver.load(`${env.dirname}/test/fixtures/tutorials/duplicateDefined`);
resolver.resolve();
}
expect(logger.error).not.toHaveBeenCalled();
expect(logger.warn).toHaveBeenCalled();
expect(jsdoc.didLog(load, 'warn')).toBeTrue();
// we don't check to see which one wins; it depends on the order in which the JS engine
// iterates over object keys
expect(resolver.root.getByName('asdf')).toBeObject();

View File

@ -1,188 +0,0 @@
describe('jsdoc/util/logger', () => {
const logger = require('jsdoc/util/logger');
const loggerArgs = ['foo bar %s', 'hello'];
it('should exist', () => {
expect(logger).toBeObject();
});
it('should inherit from EventEmitter', () => {
const { EventEmitter } = require('events');
expect(logger instanceof EventEmitter).toBe(true);
});
it('should export a "debug" method', () => {
expect(logger.debug).toBeFunction();
});
it('should export an "error" method', () => {
expect(logger.error).toBeFunction();
});
it('should export a "fatal" method', () => {
expect(logger.fatal).toBeFunction();
});
it('should export a "getLevel" method', () => {
expect(logger.getLevel).toBeFunction();
});
it('should export an "info" method', () => {
expect(logger.info).toBeFunction();
});
it('should export a "LEVELS" object', () => {
expect(logger.LEVELS).toBeObject();
});
it('should export a "setLevel" method', () => {
expect(logger.setLevel).toBeFunction();
});
it('should export a "verbose" method', () => {
expect(logger.verbose).toBeFunction();
});
it('should export a "warn" method', () => {
expect(logger.warn).toBeFunction();
});
// helpers for testing logger methods
function eventIsEmitted(name) {
let called = false;
logger.once(`logger:${name}`, () => {
called = true;
});
logger[name]();
expect(called).toBe(true);
}
function eventGetsArguments(name) {
let capturedArgs;
logger.once(`logger:${name}`, (...args) => {
capturedArgs = args.slice();
});
logger[name](loggerArgs[0], loggerArgs[1]);
expect(capturedArgs).toBeArrayOfSize(2);
expect(capturedArgs[0]).toBe(loggerArgs[0]);
expect(capturedArgs[1]).toBe(loggerArgs[1]);
}
describe('debug', () => {
const methodName = 'debug';
it('should cause the logger to emit the correct event', () => {
eventIsEmitted(methodName);
});
it('should pass its arguments to listeners', () => {
eventGetsArguments(methodName);
});
});
describe('error', () => {
const methodName = 'error';
it('should cause the logger to emit the correct event', () => {
eventIsEmitted(methodName);
});
it('should pass its arguments to listeners', () => {
eventGetsArguments(methodName);
});
});
describe('fatal', () => {
const methodName = 'fatal';
it('should cause the logger to emit the correct event', () => {
eventIsEmitted(methodName);
});
it('should pass its arguments to listeners', () => {
eventGetsArguments(methodName);
});
});
describe('getLevel', () => {
it('should return LEVELS.SILENT when we are running tests', () => {
expect( logger.getLevel() ).toBe(logger.LEVELS.SILENT);
});
});
describe('info', () => {
const methodName = 'info';
it('should cause the logger to emit the correct event', () => {
eventIsEmitted(methodName);
});
it('should pass its arguments to listeners', () => {
eventGetsArguments(methodName);
});
});
describe('LEVELS', () => {
const LEVELS = logger.LEVELS;
it('should include the correct properties', () => {
expect(LEVELS.VERBOSE).toBeNumber();
expect(LEVELS.DEBUG).toBeNumber();
expect(LEVELS.INFO).toBeNumber();
expect(LEVELS.WARN).toBeNumber();
expect(LEVELS.ERROR).toBeNumber();
expect(LEVELS.SILENT).toBeNumber();
});
it('should weight the logging levels correctly relative to one another', () => {
expect(LEVELS.VERBOSE).toBeGreaterThan(LEVELS.DEBUG);
expect(LEVELS.DEBUG).toBeGreaterThan(LEVELS.INFO);
expect(LEVELS.INFO).toBeGreaterThan(LEVELS.WARN);
expect(LEVELS.WARN).toBeGreaterThan(LEVELS.ERROR);
expect(LEVELS.ERROR).toBeGreaterThan(LEVELS.SILENT);
});
});
describe('setLevel', () => {
const oldLevel = logger.getLevel();
afterEach(() => {
logger.setLevel(oldLevel);
});
it('should update the log level', () => {
logger.setLevel(logger.LEVELS.VERBOSE);
expect( logger.getLevel() ).toBe(logger.LEVELS.VERBOSE);
});
});
describe('verbose', () => {
const methodName = 'verbose';
it('should cause the logger to emit the correct event', () => {
eventIsEmitted(methodName);
});
it('should pass its arguments to listeners', () => {
eventGetsArguments(methodName);
});
});
describe('warn', () => {
const methodName = 'warn';
it('should cause the logger to emit the correct event', () => {
eventIsEmitted(methodName);
});
it('should pass its arguments to listeners', () => {
eventGetsArguments(methodName);
});
});
});

View File

@ -1,6 +1,5 @@
describe('jsdoc/util/markdown', () => {
const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const markdown = require('jsdoc/util/markdown');
const path = require('path');
@ -69,11 +68,12 @@ describe('jsdoc/util/markdown', () => {
});
it('should log an error if an unrecognized Markdown parser is requested', () => {
function getParser() {
setMarkdownConf({parser: 'not-a-real-markdown-parser'});
spyOn(logger, 'error');
markdown.getParser();
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(getParser, 'error')).toBeTrue();
});
it('should not apply formatting to inline tags', () => {
@ -164,26 +164,26 @@ describe('jsdoc/util/markdown', () => {
});
it('should log an error if the `highlight` module cannot be found', () => {
spyOn(logger, 'error');
function getParser() {
setMarkdownConf({
highlight: 'foo/bar/baz'
});
markdown.getParser();
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(getParser, 'error')).toBeTrue();
});
it('should log an error if the `highlight` module does not assign a method to ' +
'`exports.highlight`', () => {
spyOn(logger, 'error');
function getParser() {
setMarkdownConf({
highlight: path.join(env.dirname, 'test/fixtures/markdown/badhighlighter')
});
markdown.getParser();
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(getParser, 'error')).toBeTrue();
});
});
});

View File

@ -8,7 +8,6 @@ describe("jsdoc/util/templateHelper", () => {
const doclet = require('jsdoc/doclet');
const env = require('jsdoc/env');
const helper = require('jsdoc/util/templateHelper');
const logger = require('jsdoc/util/logger');
const resolver = require('jsdoc/tutorial/resolver');
const { taffy } = require('taffydb');
@ -406,11 +405,11 @@ describe("jsdoc/util/templateHelper", () => {
it('does not try to parse a longname starting with <anonymous> as a type application',
() => {
spyOn(logger, 'error');
function linkto() {
helper.linkto('<anonymous>~foo');
}
expect(logger.error).not.toHaveBeenCalled();
expect(jsdoc.didLog(linkto, 'error')).toBeFalse();
});
it('does not treat a longname with a variation as a type application', () => {
@ -1281,7 +1280,6 @@ describe("jsdoc/util/templateHelper", () => {
describe("tutorialToUrl", () => {
beforeEach(() => {
spyOn(logger, 'error');
helper.setTutorials(resolver.root);
});
@ -1290,15 +1288,19 @@ describe("jsdoc/util/templateHelper", () => {
});
it('logs an error if the tutorial is missing', () => {
function toUrl() {
helper.tutorialToUrl('be-a-perfect-person-in-just-three-days');
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(toUrl, 'error')).toBeTrue();
});
it("logs an error if the tutorial's name is a reserved JS keyword and it doesn't exist", () => {
function toUrl() {
helper.tutorialToUrl('prototype');
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(toUrl, 'error')).toBeTrue();
});
it("creates links to tutorials if they exist", () => {
@ -1326,7 +1328,6 @@ describe("jsdoc/util/templateHelper", () => {
describe("toTutorial", () => {
beforeEach(() => {
spyOn(logger, 'error');
helper.setTutorials(resolver.root);
});
@ -1335,9 +1336,11 @@ describe("jsdoc/util/templateHelper", () => {
});
it('logs an error if the first param is missing', () => {
function toTutorial() {
helper.toTutorial();
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(toTutorial, 'error')).toBeTrue();
});
// missing tutorials

View File

@ -1,6 +1,4 @@
describe('@define tag', () => {
const logger = require('jsdoc/util/logger');
describe('JSDoc tags', () => {
const env = require('jsdoc/env');
@ -12,13 +10,13 @@ describe('@define tag', () => {
});
it('should not recognize the @define tag', () => {
function getDocSet() {
env.conf.tags.allowUnknownTags = false;
jsdoc.replaceTagDictionary('jsdoc');
spyOn(logger, 'error');
jsdoc.getDocSetFromFile('test/fixtures/definetag.js');
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeTrue();
});
});

View File

@ -1,12 +1,10 @@
describe('@dict tag', () => {
const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => {
env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
});
afterEach(() => {
@ -20,9 +18,11 @@ describe('@dict tag', () => {
});
it('should not recognize the @dict tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/dicttag.js');
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeTrue();
});
});
@ -32,9 +32,11 @@ describe('@dict tag', () => {
});
it('should recognize the @dict tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/dicttag.js');
}
expect(logger.error).not.toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeFalse();
});
});
});

View File

@ -1,12 +1,10 @@
describe('@export tag', () => {
const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => {
env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
});
afterEach(() => {
@ -20,9 +18,11 @@ describe('@export tag', () => {
});
it('should not recognize the @export tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/exporttag.js');
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeTrue();
});
});
@ -32,9 +32,11 @@ describe('@export tag', () => {
});
it('should recognize the @export tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/exporttag.js');
}
expect(logger.error).not.toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeFalse();
});
});
});

View File

@ -1,12 +1,10 @@
describe('@externs tag', () => {
const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => {
env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
});
afterEach(() => {
@ -20,9 +18,11 @@ describe('@externs tag', () => {
});
it('should not recognize the @externs tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/externstag.js');
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeTrue();
});
});
@ -32,9 +32,11 @@ describe('@externs tag', () => {
});
it('should recognize the @externs tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/externstag.js');
}
expect(logger.error).not.toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeFalse();
});
});
});

View File

@ -1,20 +1,16 @@
const logger = require('jsdoc/util/logger');
describe('@ignore tag', () => {
let docSet = jsdoc.getDocSetFromFile('test/fixtures/ignoretag.js');
let foo = docSet.getByLongname('foo')[0];
beforeEach(() => {
spyOn(logger, 'warn');
});
it('When a symbol has an @ignore tag, the doclet has a ignore property set to true.', () => {
const docSet = jsdoc.getDocSetFromFile('test/fixtures/ignoretag.js');
const foo = docSet.getByLongname('foo')[0];
expect(foo.ignore).toBe(true);
});
it('When a symbol has an @ignore tag with a value a warning is logged', () => {
docSet = jsdoc.getDocSetFromFile('test/fixtures/ignoretag2.js');
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/ignoretag2.js');
}
expect(logger.warn).toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'warn')).toBeTrue();
});
});

View File

@ -1,12 +1,10 @@
describe('@implicitCast tag', () => {
const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => {
env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
});
afterEach(() => {
@ -20,9 +18,11 @@ describe('@implicitCast tag', () => {
});
it('should not recognize the @implicitCast tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/implicitcasttag.js');
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeTrue();
});
});
@ -32,9 +32,11 @@ describe('@implicitCast tag', () => {
});
it('should recognize the @implicitCast tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/implicitcasttag.js');
}
expect(logger.error).not.toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeFalse();
});
});
});

View File

@ -1,6 +1,4 @@
describe('@interface tag', () => {
const logger = require('jsdoc/util/logger');
const docSet = jsdoc.getDocSetFromFile('test/fixtures/interface-implements.js');
const testerInterface = docSet.getByLongname('ITester')[0];
const testerImplementation = docSet.getByLongname('MyTester')[0];
@ -14,10 +12,6 @@ describe('@interface tag', () => {
});
describe('virtual doclets', () => {
beforeEach(() => {
spyOn(logger, 'warn');
});
afterEach(() => {
jsdoc.restoreTagDictionary();
});
@ -26,12 +20,17 @@ describe('@interface tag', () => {
let docSet2;
let virtualInterface;
function getDocSet() {
jsdoc.replaceTagDictionary('jsdoc');
docSet2 = jsdoc.getDocSetFromFile('test/fixtures/interfacetag2.js');
return jsdoc.getDocSetFromFile('test/fixtures/interfacetag2.js');
}
expect(jsdoc.didLog(getDocSet, 'warn')).toBeFalse();
docSet2 = getDocSet();
virtualInterface = docSet2.getByLongname('VirtualInterface')[0];
expect(logger.warn).not.toHaveBeenCalled();
expect(virtualInterface).toBeObject();
expect(virtualInterface.longname).toBe('VirtualInterface');
});
@ -40,12 +39,17 @@ describe('@interface tag', () => {
let docSet2;
let virtualInterface;
function getDocSet() {
jsdoc.replaceTagDictionary('closure');
docSet2 = jsdoc.getDocSetFromFile('test/fixtures/interfacetag2.js');
return jsdoc.getDocSetFromFile('test/fixtures/interfacetag2.js');
}
expect(jsdoc.didLog(getDocSet, 'warn')).toBeTrue();
docSet2 = getDocSet();
virtualInterface = docSet2.getByLongname('VirtualInterface')[0];
expect(logger.warn).toHaveBeenCalled();
expect(virtualInterface).toBeUndefined();
});
});

View File

@ -1,12 +1,10 @@
describe('@noalias tag', () => {
const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => {
env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
});
afterEach(() => {
@ -20,9 +18,11 @@ describe('@noalias tag', () => {
});
it('should not recognize the @noalias tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/noaliastag.js');
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeTrue();
});
});
@ -32,9 +32,11 @@ describe('@noalias tag', () => {
});
it('should recognize the @noalias tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/noaliastag.js');
}
expect(logger.error).not.toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeFalse();
});
});
});

View File

@ -1,12 +1,10 @@
describe('@nocollapse tag', () => {
const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => {
env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
});
afterEach(() => {
@ -20,9 +18,11 @@ describe('@nocollapse tag', () => {
});
it('should not recognize the @nocollapse tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/nocollapsetag.js');
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeTrue();
});
});
@ -32,9 +32,11 @@ describe('@nocollapse tag', () => {
});
it('should recognize the @nocollapse tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/nocollapsetag.js');
}
expect(logger.error).not.toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeFalse();
});
});
});

View File

@ -1,12 +1,10 @@
describe('@nocompile tag', () => {
const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => {
env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
});
afterEach(() => {
@ -20,9 +18,11 @@ describe('@nocompile tag', () => {
});
it('should not recognize the @nocompile tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/nocompiletag.js');
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeTrue();
});
});
@ -32,9 +32,11 @@ describe('@nocompile tag', () => {
});
it('should recognize the @nocompile tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/nocompiletag.js');
}
expect(logger.error).not.toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeFalse();
});
});
});

View File

@ -1,6 +1,5 @@
describe('@override tag', () => {
const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
@ -10,7 +9,6 @@ describe('@override tag', () => {
beforeEach(() => {
env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
});
afterEach(() => {
@ -24,9 +22,11 @@ describe('@override tag', () => {
});
it('should not recognize the @override tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/overridetag.js');
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeTrue();
});
});

View File

@ -1,5 +1,3 @@
const logger = require('jsdoc/util/logger');
describe('@package tag', () => {
const docSet = jsdoc.getDocSetFromFile('test/fixtures/packagetag.js');
const foo = docSet.getByLongname('foo')[0];
@ -15,12 +13,12 @@ describe('@package tag', () => {
});
it('When JSDoc tags are enabled, the @package tag does not accept a value.', () => {
function getDocSet() {
jsdoc.replaceTagDictionary('jsdoc');
spyOn(logger, 'warn');
jsdoc.getDocSetFromFile('test/fixtures/packagetag2.js');
}
expect(logger.warn).toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'warn')).toBeTrue();
});
});
@ -30,18 +28,25 @@ describe('@package tag', () => {
});
it('When Closure Compiler tags are enabled, the @package tag accepts a type expression.',
() => {
function getDocSet() {
jsdoc.replaceTagDictionary('closure');
jsdoc.getDocSetFromFile('test/fixtures/packagetag2.js');
}
expect(jsdoc.didLog(getDocSet, 'warn')).toBeFalse();
});
it('When Closure Compiler tags are enabled, the @package tag parses the type expression.',
() => {
let connectionPorts;
let privateDocs;
jsdoc.replaceTagDictionary('closure');
spyOn(logger, 'warn');
privateDocs = jsdoc.getDocSetFromFile('test/fixtures/packagetag2.js');
connectionPorts = privateDocs.getByLongname('connectionPorts')[0];
expect(logger.warn).not.toHaveBeenCalled();
expect(connectionPorts).toBeObject();
expect(connectionPorts.access).toBe('package');

View File

@ -1,12 +1,10 @@
describe('@polymerBehavior tag', () => {
const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => {
env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
});
afterEach(() => {
@ -20,9 +18,11 @@ describe('@polymerBehavior tag', () => {
});
it('should not recognize the @polymerBehavior tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/polymerbehaviortag.js');
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeTrue();
});
});
@ -32,9 +32,11 @@ describe('@polymerBehavior tag', () => {
});
it('should recognize the @polymerBehavior tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/polymerbehaviortag.js');
}
expect(logger.error).not.toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeFalse();
});
});
});

View File

@ -1,12 +1,10 @@
describe('@polymer tag', () => {
const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => {
env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
});
afterEach(() => {
@ -20,9 +18,11 @@ describe('@polymer tag', () => {
});
it('should not recognize the @polymer tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/polymertag.js');
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeTrue();
});
});
@ -32,9 +32,11 @@ describe('@polymer tag', () => {
});
it('should recognize the @polymer tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/polymertag.js');
}
expect(logger.error).not.toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeFalse();
});
});
});

View File

@ -1,12 +1,10 @@
describe('@preserve tag', () => {
const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => {
env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
});
afterEach(() => {
@ -20,9 +18,11 @@ describe('@preserve tag', () => {
});
it('should not recognize the @preserve tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/preservetag.js');
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeTrue();
});
});

View File

@ -1,5 +1,3 @@
const logger = require('jsdoc/util/logger');
describe('@private tag', () => {
const docSet = jsdoc.getDocSetFromFile('test/fixtures/privatetag.js');
const foo = docSet.getByLongname('Foo')[0];
@ -21,33 +19,41 @@ describe('@private tag', () => {
});
it('When JSDoc tags are enabled, the @private tag does not accept a value.', () => {
function getDocSet() {
jsdoc.replaceTagDictionary('jsdoc');
spyOn(logger, 'warn');
jsdoc.getDocSetFromFile('test/fixtures/privatetag2.js');
}
expect(logger.warn).toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'warn')).toBeTrue();
});
});
describe('Closure Compiler tags', () => {
beforeEach(() => {
jsdoc.replaceTagDictionary('closure');
});
afterEach(() => {
jsdoc.restoreTagDictionary();
});
it('When Closure Compiler tags are enabled, the @private tag accepts a type expression.',
() => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/privatetag2.js');
}
expect(jsdoc.didLog(getDocSet, 'warn')).toBeFalse();
});
it('When Closure Compiler tags are enabled, the @private tag parses the type expression.',
() => {
let connectionPorts;
let privateDocs;
jsdoc.replaceTagDictionary('closure');
spyOn(logger, 'warn');
privateDocs = jsdoc.getDocSetFromFile('test/fixtures/privatetag2.js');
connectionPorts = privateDocs.getByLongname('connectionPorts')[0];
expect(logger.warn).not.toHaveBeenCalled();
expect(connectionPorts).toBeObject();
expect(connectionPorts.access).toBe('private');

View File

@ -1,5 +1,3 @@
const logger = require('jsdoc/util/logger');
describe('@protected tag', () => {
const docSet = jsdoc.getDocSetFromFile('test/fixtures/protectedtag.js');
const uidCounter = docSet.getByLongname('module:uid~uidCounter')[0];
@ -21,12 +19,12 @@ describe('@protected tag', () => {
});
it('When JSDoc tags are enabled, the @protected tag does not accept a value.', () => {
function getDocSet() {
jsdoc.replaceTagDictionary('jsdoc');
spyOn(logger, 'warn');
jsdoc.getDocSetFromFile('test/fixtures/protectedtag2.js');
}
expect(logger.warn).toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'warn')).toBeTrue();
});
});
@ -36,18 +34,25 @@ describe('@protected tag', () => {
});
it('When Closure Compiler tags are enabled, the @private tag accepts a type expression.',
() => {
function getDocSet() {
jsdoc.replaceTagDictionary('closure');
jsdoc.getDocSetFromFile('test/fixtures/protectedtag2.js');
}
expect(jsdoc.didLog(getDocSet, 'warn')).toBeFalse();
});
it('When Closure Compiler tags are enabled, the @private tag parses the type expression.',
() => {
let counter;
let protectedDocs;
jsdoc.replaceTagDictionary('closure');
spyOn(logger, 'warn');
protectedDocs = jsdoc.getDocSetFromFile('test/fixtures/protectedtag2.js');
counter = protectedDocs.getByLongname('uidCounter')[0];
expect(logger.warn).not.toHaveBeenCalled();
expect(counter).toBeObject();
expect(counter.access).toBe('protected');

View File

@ -1,12 +1,10 @@
describe('@struct tag', () => {
const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => {
env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
});
afterEach(() => {
@ -20,9 +18,11 @@ describe('@struct tag', () => {
});
it('should not recognize the @struct tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/structtag.js');
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeTrue();
});
});
@ -32,9 +32,11 @@ describe('@struct tag', () => {
});
it('should recognize the @struct tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/structtag.js');
}
expect(logger.error).not.toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeFalse();
});
});
});

View File

@ -1,12 +1,10 @@
describe('@suppress tag', () => {
const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => {
env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
});
afterEach(() => {
@ -20,9 +18,11 @@ describe('@suppress tag', () => {
});
it('should not recognize the @suppress tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/suppresstag.js');
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeTrue();
});
});
@ -32,9 +32,11 @@ describe('@suppress tag', () => {
});
it('should recognize the @suppress tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/suppresstag.js');
}
expect(logger.error).not.toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeFalse();
});
});
});

View File

@ -1,12 +1,10 @@
describe('@template tag', () => {
const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => {
env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
});
afterEach(() => {
@ -20,9 +18,11 @@ describe('@template tag', () => {
});
it('should not recognize the @template tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/templatetag.js');
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeTrue();
});
});
@ -32,9 +32,11 @@ describe('@template tag', () => {
});
it('should recognize the @template tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/templatetag.js');
}
expect(logger.error).not.toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeFalse();
});
});
});

View File

@ -1,5 +1,3 @@
const logger = require('jsdoc/util/logger');
describe('@type tag', () => {
const docSet = jsdoc.getDocSetFromFile('test/fixtures/typetag.js');
@ -29,12 +27,12 @@ describe('@type tag', () => {
});
it('When JSDoc tags are enabled, the @type tag does not accept a description.', () => {
function getDocSet() {
jsdoc.replaceTagDictionary('jsdoc');
spyOn(logger, 'warn');
jsdoc.getDocSetFromFile('test/fixtures/typetag2.js');
}
expect(logger.warn).toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'warn')).toBeTrue();
});
});
@ -44,17 +42,23 @@ describe('@type tag', () => {
});
it('When Closure tags are enabled, the @type tag accepts a description.', () => {
function getDocSet() {
jsdoc.replaceTagDictionary('closure');
jsdoc.getDocSetFromFile('test/fixtures/typetag2.js');
}
expect(jsdoc.didLog(getDocSet, 'warn')).toBeFalse();
});
it('When Closure tags are enabled, the @type tag captures the description.', () => {
let stringOrNumber;
let typeDocs;
jsdoc.replaceTagDictionary('closure');
spyOn(logger, 'warn');
typeDocs = jsdoc.getDocSetFromFile('test/fixtures/typetag2.js');
stringOrNumber = typeDocs.getByLongname('stringOrNumber')[0];
expect(logger.warn).not.toHaveBeenCalled();
expect(stringOrNumber).toBeObject();
expect(stringOrNumber.description).toBe('A string or a number.');
});

View File

@ -1,12 +1,10 @@
describe('@unrestricted tag', () => {
const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => {
env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
});
afterEach(() => {
@ -20,9 +18,11 @@ describe('@unrestricted tag', () => {
});
it('should not recognize the @unrestricted tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/unrestrictedtag.js');
}
expect(logger.error).toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeTrue();
});
});
@ -32,9 +32,11 @@ describe('@unrestricted tag', () => {
});
it('should recognize the @unrestricted tag', () => {
function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/unrestrictedtag.js');
}
expect(logger.error).not.toHaveBeenCalled();
expect(jsdoc.didLog(getDocSet, 'error')).toBeFalse();
});
});
});