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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
* @module jsdoc/src/scanner * @module jsdoc/src/scanner
*/ */
const { EventEmitter } = require('events'); const { EventEmitter } = require('events');
const logger = require('jsdoc/util/logger'); const { log } = require('@jsdoc/util');
const { lsSync } = require('@jsdoc/util').fs; const { lsSync } = require('@jsdoc/util').fs;
const path = require('path'); const path = require('path');
const { statSync } = require('fs'); const { statSync } = require('fs');
@ -35,7 +35,7 @@ class Scanner extends EventEmitter {
currentFile = statSync(filepath); currentFile = statSync(filepath);
} }
catch (e) { 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; return;
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -3,7 +3,7 @@
*/ */
const env = require('jsdoc/env'); const env = require('jsdoc/env');
const fs = require('fs'); const fs = require('fs');
const logger = require('jsdoc/util/logger'); const { log } = require('@jsdoc/util');
const { lsSync } = require('@jsdoc/util').fs; const { lsSync } = require('@jsdoc/util').fs;
const path = require('path'); const path = require('path');
const stripBom = require('strip-bom'); const stripBom = require('strip-bom');
@ -62,7 +62,10 @@ function addTutorialConf(name, meta) {
} }
// check if the tutorial has already been defined... // check if the tutorial has already been defined...
if (hasOwnProp.call(conf, name)) { 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 { } else {
conf[name] = meta; conf[name] = meta;
} }
@ -81,7 +84,10 @@ function addTutorialConf(name, meta) {
*/ */
exports.addTutorial = current => { exports.addTutorial = current => {
if (exports.root.getByName(current.name)) { 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 { } else {
// by default, the root tutorial is the parent // by default, the root tutorial is the parent
current.setParent(exports.root); current.setParent(exports.root);
@ -175,7 +181,7 @@ exports.resolve = () => {
const childTutorial = exports.root.getByName(child); const childTutorial = exports.root.getByName(child);
if (!childTutorial) { if (!childTutorial) {
logger.error('Missing child tutorial: %s', child); log.error(`Missing child tutorial: ${child}`);
} }
else { else {
childTutorial.setParent(current); 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 * @module jsdoc/util/markdown
*/ */
const env = require('jsdoc/env'); const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger'); const { log } = require('@jsdoc/util');
const MarkdownIt = require('markdown-it'); const MarkdownIt = require('markdown-it');
const marked = require('marked'); const marked = require('marked');
const mda = require('markdown-it-anchor'); const mda = require('markdown-it-anchor');
@ -143,11 +143,11 @@ function getHighlighter(conf) {
try { try {
highlighter = require(conf.highlight).highlight; highlighter = require(conf.highlight).highlight;
} catch (e) { } catch (e) {
logger.error(e); log.error(e);
} }
if (typeof highlighter !== 'function') { 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.'); 'method to `exports.highlight`. Using the default syntax highlighter.');
highlighter = highlight; highlighter = highlight;
} }
@ -249,8 +249,9 @@ function getParseFunction(parserName, conf) {
return parserFunction; return parserFunction;
default: default:
logger.error(`Unrecognized Markdown parser "${parserName}". Markdown support is ` + log.error(
'disabled.'); `Unrecognized Markdown parser "${parserName}". Markdown support is disabled.`
);
return undefined; return undefined;
} }

View File

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

View File

@ -1,7 +1,7 @@
/** /**
* @module plugins/sourcetag * @module plugins/sourcetag
*/ */
const logger = require('jsdoc/util/logger'); const { log } = require('@jsdoc/util');
exports.handlers = { exports.handlers = {
/** /**
@ -35,7 +35,10 @@ exports.handlers = {
value = JSON.parse(tag.value); value = JSON.parse(tag.value);
} }
catch (ex) { 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; return;
} }

View File

@ -4,10 +4,12 @@ const { createParser } = require('jsdoc/src/parser');
const { defineTags } = require('jsdoc/tag/dictionary/definitions'); const { defineTags } = require('jsdoc/tag/dictionary/definitions');
const dictionary = require('jsdoc/tag/dictionary'); const dictionary = require('jsdoc/tag/dictionary');
const env = require('jsdoc/env'); const env = require('jsdoc/env');
const { EventBus } = require('@jsdoc/util');
const fs = require('fs'); const fs = require('fs');
const handlers = require('jsdoc/src/handlers'); const handlers = require('jsdoc/src/handlers');
const path = require('path'); const path = require('path');
const bus = new EventBus('jsdoc');
const originalDictionary = dictionary; const originalDictionary = dictionary;
const parseResults = []; const parseResults = [];
@ -19,6 +21,19 @@ const helpers = global.jsdoc = {
}); });
}, },
createParser, 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) => { getDocSetFromFile: (filename, parser, shouldValidate, augment) => {
let doclets; 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" ' + 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.', () => { '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 allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
const errors = [];
function errorListener(err) { function getDocSet() {
errors.push(err); env.conf.tags.allowUnknownTags = false;
jsdoc.getDocSetFromFile('test/fixtures/also2.js');
env.conf.tags.allowUnknownTags = allowUnknownTags;
} }
logger.addListener('logger:error', errorListener); expect(jsdoc.didLog(getDocSet, 'error')).toBeFalse();
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;
}); });
}); });

View File

@ -1,10 +1,9 @@
const logger = require('jsdoc/util/logger');
describe('empty JSDoc comments', () => { describe('empty JSDoc comments', () => {
it('should not report an error when a JSDoc comment contains only whitespace', () => { it('should not report an error when a JSDoc comment contains only whitespace', () => {
spyOn(logger, 'error'); function getDocSet() {
jsdoc.getDocSetFromFile('test/fixtures/emptycomments.js'); 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', () => { describe('JSX support', () => {
it('should parse JSX files without errors', () => { it('should parse JSX files without errors', () => {
const logger = require('jsdoc/util/logger');
function parseJsx() { function parseJsx() {
return jsdoc.getDocSetFromFile('test/fixtures/jsx.js'); return jsdoc.getDocSetFromFile('test/fixtures/jsx.js');
} }
spyOn(logger, 'error');
expect(parseJsx).not.toThrow(); 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', () => { describe('jsdoc/package', () => {
let emptyPackage; let emptyPackage;
const jsdocPackage = require('jsdoc/package'); const jsdocPackage = require('jsdoc/package');
const logger = require('jsdoc/util/logger');
const Package = jsdocPackage.Package; const Package = jsdocPackage.Package;
function checkPackageProperty(name, value) { function checkPackageProperty(name, value) {
@ -61,10 +60,8 @@ describe('jsdoc/package', () => {
return new Package('abcdefg'); return new Package('abcdefg');
} }
spyOn(logger, 'error');
expect(newPackage).not.toThrow(); expect(newPackage).not.toThrow();
expect(logger.error).toHaveBeenCalled(); expect(jsdoc.didLog(newPackage, 'error')).toBeTrue();
}); });
describe('author', () => { describe('author', () => {

View File

@ -23,19 +23,13 @@ describe('jsdoc/src/astbuilder', () => {
describe('build', () => { describe('build', () => {
// TODO: more tests // 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', () => { it('should log (not throw) an error when a file cannot be parsed', () => {
function parse() { function parse() {
builder.build('qwerty!!!!!', 'bad.js'); builder.build('qwerty!!!!!', 'bad.js');
} }
expect(parse).not.toThrow(); 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 { dirname } = require('jsdoc/env');
const fs = require('fs'); const fs = require('fs');
const jsdocParser = require('jsdoc/src/parser'); const jsdocParser = require('jsdoc/src/parser');
const logger = require('jsdoc/util/logger');
const path = require('path'); const path = require('path');
it('should exist', () => { it('should exist', () => {
@ -32,10 +31,11 @@ describe('jsdoc/src/parser', () => {
}); });
it('should log a fatal error on bad input', () => { it('should log a fatal error on bad input', () => {
spyOn(logger, 'fatal'); function createParser() {
jsdocParser.createParser('not-a-real-parser-ever'); 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 env = require('jsdoc/env');
const jsdocDictionary = require('jsdoc/tag/dictionary'); const jsdocDictionary = require('jsdoc/tag/dictionary');
const jsdocTag = require('jsdoc/tag'); const jsdocTag = require('jsdoc/tag');
const logger = require('jsdoc/util/logger');
const parseType = require('jsdoc/tag/type').parse; const parseType = require('jsdoc/tag/type').parse;
it('should exist', () => { it('should exist', () => {
@ -115,14 +114,14 @@ describe('jsdoc/tag', () => {
let wsOnly; let wsOnly;
let wsTrailing; 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 ' } });
}
wsOnly = new jsdocTag.Tag('name', ' ', { code: { name: ' ' } }); expect(jsdoc.didLog(newTags, 'error')).toBeFalse();
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(wsOnly.text).toBe('" "'); expect(wsOnly.text).toBe('" "');
expect(wsLeading.text).toBe('" foo"'); expect(wsLeading.text).toBe('" foo"');
expect(wsTrailing.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. // further tests for this sort of thing are in jsdoc/tag/validator.js tests.
describe('tag validating', () => { describe('tag validating', () => {
beforeEach(() => {
spyOn(logger, 'error');
});
it('logs an error for tags with bad type expressions', () => { it('logs an error for tags with bad type expressions', () => {
/* eslint-disable no-unused-vars */ function newTag() {
const tag = new jsdocTag.Tag('param', '{!*!*!*!} foo'); return new jsdocTag.Tag('param', '{!*!*!*!} foo');
/* eslint-enable no-unused-vars */ }
expect(logger.error).toHaveBeenCalled(); expect(jsdoc.didLog(newTag, 'error')).toBeTrue();
}); });
it('validates tags with no text', () => { it('validates tags with no text', () => {
/* eslint-disable no-unused-vars */ function newTag() {
const tag = new jsdocTag.Tag('copyright'); return new jsdocTag.Tag('copyright');
/* eslint-enable no-unused-vars */ }
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 env = require('jsdoc/env');
const definitions = require('jsdoc/tag/dictionary/definitions'); const definitions = require('jsdoc/tag/dictionary/definitions');
const Dictionary = require('jsdoc/tag/dictionary').Dictionary; const Dictionary = require('jsdoc/tag/dictionary').Dictionary;
const logger = require('jsdoc/util/logger');
it('should exist', () => { it('should exist', () => {
expect(definitions).toBeObject(); expect(definitions).toBeObject();
@ -48,19 +47,21 @@ describe('jsdoc/tag/dictionary/definitions', () => {
}); });
it('should log an error if `env.conf.tags.dictionaries` is undefined', () => { it('should log an error if `env.conf.tags.dictionaries` is undefined', () => {
env.conf.tags.dictionaries = undefined; function defineTags() {
spyOn(logger, 'error'); env.conf.tags.dictionaries = undefined;
definitions.defineTags(tagDict); definitions.defineTags(tagDict);
}
expect(logger.error).toHaveBeenCalled(); expect(jsdoc.didLog(defineTags, 'error')).toBeTrue();
}); });
it('should log an error if an unknown dictionary is requested', () => { it('should log an error if an unknown dictionary is requested', () => {
env.conf.tags.dictionaries = ['jsmarmoset']; function defineTags() {
spyOn(logger, 'error'); env.conf.tags.dictionaries = ['jsmarmoset'];
definitions.defineTags(tagDict); definitions.defineTags(tagDict);
}
expect(logger.error).toHaveBeenCalled(); expect(jsdoc.didLog(defineTags, 'error')).toBeTrue();
}); });
it('should add both JSDoc and Closure tags by default', () => { it('should add both JSDoc and Closure tags by default', () => {

View File

@ -1,7 +1,7 @@
describe('jsdoc/tag/validator', () => { describe('jsdoc/tag/validator', () => {
const _ = require('lodash'); const _ = require('lodash');
const env = require('jsdoc/env'); const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger'); const { EventBus } = require('@jsdoc/util');
const tag = require('jsdoc/tag'); const tag = require('jsdoc/tag');
const validator = require('jsdoc/tag/validator'); const validator = require('jsdoc/tag/validator');
@ -19,7 +19,6 @@ describe('jsdoc/tag/validator', () => {
const allowUnknown = Boolean(env.conf.tags.allowUnknownTags); const allowUnknown = Boolean(env.conf.tags.allowUnknownTags);
const badTag = { title: 'lkjasdlkjfb' }; const badTag = { title: 'lkjasdlkjfb' };
const badTag2 = new tag.Tag('type', '{string} I am a string!'); const badTag2 = new tag.Tag('type', '{string} I am a string!');
let errorSpy;
const meta = { const meta = {
filename: 'asdf.js', filename: 'asdf.js',
lineno: 1, lineno: 1,
@ -32,80 +31,95 @@ describe('jsdoc/tag/validator', () => {
validator.validate(theTag, dictionary.lookUp(theTag.title), meta); validator.validate(theTag, dictionary.lookUp(theTag.title), meta);
} }
beforeEach(() => {
errorSpy = spyOn(logger, 'error');
spyOn(logger, 'warn');
});
afterEach(() => { afterEach(() => {
env.conf.tags.allowUnknownTags = allowUnknown; env.conf.tags.allowUnknownTags = allowUnknown;
}); });
it('logs an error if the tag is not in the dictionary and conf.tags.allowUnknownTags is false', () => { it('logs an error if the tag is not in the dictionary and conf.tags.allowUnknownTags is false', () => {
env.conf.tags.allowUnknownTags = false; function validate() {
validateTag(badTag); 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', () => { it('logs an error if the tag is not in the dictionary and conf.tags.allowUnknownTags is does not include it', () => {
env.conf.tags.allowUnknownTags = []; function validate() {
validateTag(badTag); 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', () => { it('does not log an error if the tag is not in the dictionary and conf.tags.allowUnknownTags is true', () => {
env.conf.tags.allowUnknownTags = true; function validate() {
validateTag(badTag); 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', () => { it('does not log an error if the tag is not in the dictionary and conf.tags.allowUnknownTags includes it', () => {
env.conf.tags.allowUnknownTags = [badTag.title]; function validate() {
validateTag(badTag); 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', () => { it('does not log an error for valid tags', () => {
validateTag(goodTag); function validate() {
validateTag(goodTag2); 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', () => { it('logs an error if the tag has no text but mustHaveValue is true', () => {
const missingName = _.cloneDeep(goodTag); function validate() {
const missingName = _.cloneDeep(goodTag);
missingName.text = null; missingName.text = null;
validateTag(missingName); 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', () => { it('logs a warning if the tag has text but mustNotHaveValue is true', () => {
const missingText = _.cloneDeep(goodTag2); function validate() {
const missingText = _.cloneDeep(goodTag2);
missingText.mustNotHaveValue = true; missingText.mustNotHaveValue = true;
missingText.text = missingText.text || 'asdf'; missingText.text = missingText.text || 'asdf';
validateTag(missingText); 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', () => { it('logs a warning if the tag has a description but mustNotHaveDescription is true', () => {
validateTag(badTag2); function validate() {
validateTag(badTag2);
}
expect(logger.warn).toHaveBeenCalled(); expect(jsdoc.didLog(validate, 'warn')).toBeTrue();
}); });
it('logs meta.comment when present', () => { 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; env.conf.tags.allowUnknownTags = false;
validateTag(badTag); 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', () => { describe('jsdoc/tutorial/resolver', () => {
const env = require('jsdoc/env'); const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const resolver = require('jsdoc/tutorial/resolver'); const resolver = require('jsdoc/tutorial/resolver');
const tutorial = require('jsdoc/tutorial'); const tutorial = require('jsdoc/tutorial');
@ -160,8 +159,6 @@ describe('jsdoc/tutorial/resolver', () => {
// |- test4 // |- test4
describe('resolve', () => { describe('resolve', () => {
beforeEach(() => { beforeEach(() => {
spyOn(logger, 'error');
spyOn(logger, 'warn');
loadTutorials(); loadTutorials();
resolver.resolve(); resolver.resolve();
}); });
@ -211,27 +208,32 @@ describe('jsdoc/tutorial/resolver', () => {
}); });
it('logs an error for missing tutorials', () => { it('logs an error for missing tutorials', () => {
resolver.load(`${env.dirname}/test/fixtures/tutorials/incomplete`); function load() {
resolver.resolve(); 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)', () => { it('logs a warning for duplicate-named tutorials (e.g. test.md, test.html)', () => {
const tute = new tutorial.Tutorial('myTutorial', '', tutorial.TYPES.HTML); function load() {
const tute = new tutorial.Tutorial('myTutorial', '', tutorial.TYPES.HTML);
resolver.addTutorial(tute); resolver.addTutorial(tute);
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', () => { it('allows tutorials to be defined in one .json file and redefined in another', () => {
resolver.load(`${env.dirname}/test/fixtures/tutorials/duplicateDefined`); function load() {
resolver.resolve(); resolver.load(`${env.dirname}/test/fixtures/tutorials/duplicateDefined`);
resolver.resolve();
}
expect(logger.error).not.toHaveBeenCalled(); expect(jsdoc.didLog(load, 'warn')).toBeTrue();
expect(logger.warn).toHaveBeenCalled();
// we don't check to see which one wins; it depends on the order in which the JS engine // we don't check to see which one wins; it depends on the order in which the JS engine
// iterates over object keys // iterates over object keys
expect(resolver.root.getByName('asdf')).toBeObject(); 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', () => { describe('jsdoc/util/markdown', () => {
const env = require('jsdoc/env'); const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const markdown = require('jsdoc/util/markdown'); const markdown = require('jsdoc/util/markdown');
const path = require('path'); const path = require('path');
@ -69,11 +68,12 @@ describe('jsdoc/util/markdown', () => {
}); });
it('should log an error if an unrecognized Markdown parser is requested', () => { it('should log an error if an unrecognized Markdown parser is requested', () => {
setMarkdownConf({parser: 'not-a-real-markdown-parser'}); function getParser() {
spyOn(logger, 'error'); setMarkdownConf({parser: 'not-a-real-markdown-parser'});
markdown.getParser(); markdown.getParser();
}
expect(logger.error).toHaveBeenCalled(); expect(jsdoc.didLog(getParser, 'error')).toBeTrue();
}); });
it('should not apply formatting to inline tags', () => { 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', () => { it('should log an error if the `highlight` module cannot be found', () => {
spyOn(logger, 'error'); function getParser() {
setMarkdownConf({
highlight: 'foo/bar/baz'
});
markdown.getParser();
}
setMarkdownConf({ expect(jsdoc.didLog(getParser, 'error')).toBeTrue();
highlight: 'foo/bar/baz'
});
markdown.getParser();
expect(logger.error).toHaveBeenCalled();
}); });
it('should log an error if the `highlight` module does not assign a method to ' + it('should log an error if the `highlight` module does not assign a method to ' +
'`exports.highlight`', () => { '`exports.highlight`', () => {
spyOn(logger, 'error'); function getParser() {
setMarkdownConf({
highlight: path.join(env.dirname, 'test/fixtures/markdown/badhighlighter')
});
markdown.getParser();
}
setMarkdownConf({ expect(jsdoc.didLog(getParser, 'error')).toBeTrue();
highlight: path.join(env.dirname, 'test/fixtures/markdown/badhighlighter')
});
markdown.getParser();
expect(logger.error).toHaveBeenCalled();
}); });
}); });
}); });

View File

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

View File

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

View File

@ -1,12 +1,10 @@
describe('@dict tag', () => { describe('@dict tag', () => {
const env = require('jsdoc/env'); const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags); const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => { beforeEach(() => {
env.conf.tags.allowUnknownTags = false; env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
}); });
afterEach(() => { afterEach(() => {
@ -20,9 +18,11 @@ describe('@dict tag', () => {
}); });
it('should not recognize the @dict tag', () => { it('should not recognize the @dict tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/dicttag.js'); 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', () => { it('should recognize the @dict tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/dicttag.js'); 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', () => { describe('@export tag', () => {
const env = require('jsdoc/env'); const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags); const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => { beforeEach(() => {
env.conf.tags.allowUnknownTags = false; env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
}); });
afterEach(() => { afterEach(() => {
@ -20,9 +18,11 @@ describe('@export tag', () => {
}); });
it('should not recognize the @export tag', () => { it('should not recognize the @export tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/exporttag.js'); 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', () => { it('should recognize the @export tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/exporttag.js'); 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', () => { describe('@externs tag', () => {
const env = require('jsdoc/env'); const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags); const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => { beforeEach(() => {
env.conf.tags.allowUnknownTags = false; env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
}); });
afterEach(() => { afterEach(() => {
@ -20,9 +18,11 @@ describe('@externs tag', () => {
}); });
it('should not recognize the @externs tag', () => { it('should not recognize the @externs tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/externstag.js'); 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', () => { it('should recognize the @externs tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/externstag.js'); 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', () => { 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.', () => { 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); expect(foo.ignore).toBe(true);
}); });
it('When a symbol has an @ignore tag with a value a warning is logged', () => { 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', () => { describe('@implicitCast tag', () => {
const env = require('jsdoc/env'); const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags); const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => { beforeEach(() => {
env.conf.tags.allowUnknownTags = false; env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
}); });
afterEach(() => { afterEach(() => {
@ -20,9 +18,11 @@ describe('@implicitCast tag', () => {
}); });
it('should not recognize the @implicitCast tag', () => { it('should not recognize the @implicitCast tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/implicitcasttag.js'); 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', () => { it('should recognize the @implicitCast tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/implicitcasttag.js'); 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', () => { describe('@interface tag', () => {
const logger = require('jsdoc/util/logger');
const docSet = jsdoc.getDocSetFromFile('test/fixtures/interface-implements.js'); const docSet = jsdoc.getDocSetFromFile('test/fixtures/interface-implements.js');
const testerInterface = docSet.getByLongname('ITester')[0]; const testerInterface = docSet.getByLongname('ITester')[0];
const testerImplementation = docSet.getByLongname('MyTester')[0]; const testerImplementation = docSet.getByLongname('MyTester')[0];
@ -14,10 +12,6 @@ describe('@interface tag', () => {
}); });
describe('virtual doclets', () => { describe('virtual doclets', () => {
beforeEach(() => {
spyOn(logger, 'warn');
});
afterEach(() => { afterEach(() => {
jsdoc.restoreTagDictionary(); jsdoc.restoreTagDictionary();
}); });
@ -26,12 +20,17 @@ describe('@interface tag', () => {
let docSet2; let docSet2;
let virtualInterface; let virtualInterface;
jsdoc.replaceTagDictionary('jsdoc'); 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]; virtualInterface = docSet2.getByLongname('VirtualInterface')[0];
expect(logger.warn).not.toHaveBeenCalled();
expect(virtualInterface).toBeObject(); expect(virtualInterface).toBeObject();
expect(virtualInterface.longname).toBe('VirtualInterface'); expect(virtualInterface.longname).toBe('VirtualInterface');
}); });
@ -40,12 +39,17 @@ describe('@interface tag', () => {
let docSet2; let docSet2;
let virtualInterface; let virtualInterface;
jsdoc.replaceTagDictionary('closure'); 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]; virtualInterface = docSet2.getByLongname('VirtualInterface')[0];
expect(logger.warn).toHaveBeenCalled();
expect(virtualInterface).toBeUndefined(); expect(virtualInterface).toBeUndefined();
}); });
}); });

View File

@ -1,12 +1,10 @@
describe('@noalias tag', () => { describe('@noalias tag', () => {
const env = require('jsdoc/env'); const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags); const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => { beforeEach(() => {
env.conf.tags.allowUnknownTags = false; env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
}); });
afterEach(() => { afterEach(() => {
@ -20,9 +18,11 @@ describe('@noalias tag', () => {
}); });
it('should not recognize the @noalias tag', () => { it('should not recognize the @noalias tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/noaliastag.js'); 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', () => { it('should recognize the @noalias tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/noaliastag.js'); 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', () => { describe('@nocollapse tag', () => {
const env = require('jsdoc/env'); const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags); const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => { beforeEach(() => {
env.conf.tags.allowUnknownTags = false; env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
}); });
afterEach(() => { afterEach(() => {
@ -20,9 +18,11 @@ describe('@nocollapse tag', () => {
}); });
it('should not recognize the @nocollapse tag', () => { it('should not recognize the @nocollapse tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/nocollapsetag.js'); 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', () => { it('should recognize the @nocollapse tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/nocollapsetag.js'); 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', () => { describe('@nocompile tag', () => {
const env = require('jsdoc/env'); const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags); const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => { beforeEach(() => {
env.conf.tags.allowUnknownTags = false; env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
}); });
afterEach(() => { afterEach(() => {
@ -20,9 +18,11 @@ describe('@nocompile tag', () => {
}); });
it('should not recognize the @nocompile tag', () => { it('should not recognize the @nocompile tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/nocompiletag.js'); 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', () => { it('should recognize the @nocompile tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/nocompiletag.js'); 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', () => { describe('@override tag', () => {
const env = require('jsdoc/env'); const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags); const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
@ -10,7 +9,6 @@ describe('@override tag', () => {
beforeEach(() => { beforeEach(() => {
env.conf.tags.allowUnknownTags = false; env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
}); });
afterEach(() => { afterEach(() => {
@ -24,9 +22,11 @@ describe('@override tag', () => {
}); });
it('should not recognize the @override tag', () => { it('should not recognize the @override tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/overridetag.js'); 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', () => { describe('@package tag', () => {
const docSet = jsdoc.getDocSetFromFile('test/fixtures/packagetag.js'); const docSet = jsdoc.getDocSetFromFile('test/fixtures/packagetag.js');
const foo = docSet.getByLongname('foo')[0]; 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.', () => { it('When JSDoc tags are enabled, the @package tag does not accept a value.', () => {
jsdoc.replaceTagDictionary('jsdoc'); function getDocSet() {
spyOn(logger, 'warn'); jsdoc.replaceTagDictionary('jsdoc');
jsdoc.getDocSetFromFile('test/fixtures/packagetag2.js');
}
jsdoc.getDocSetFromFile('test/fixtures/packagetag2.js'); expect(jsdoc.didLog(getDocSet, 'warn')).toBeTrue();
expect(logger.warn).toHaveBeenCalled();
}); });
}); });
@ -30,18 +28,25 @@ describe('@package tag', () => {
}); });
it('When Closure Compiler tags are enabled, the @package tag accepts a type expression.', 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 connectionPorts;
let privateDocs; let privateDocs;
jsdoc.replaceTagDictionary('closure'); jsdoc.replaceTagDictionary('closure');
spyOn(logger, 'warn');
privateDocs = jsdoc.getDocSetFromFile('test/fixtures/packagetag2.js'); privateDocs = jsdoc.getDocSetFromFile('test/fixtures/packagetag2.js');
connectionPorts = privateDocs.getByLongname('connectionPorts')[0]; connectionPorts = privateDocs.getByLongname('connectionPorts')[0];
expect(logger.warn).not.toHaveBeenCalled();
expect(connectionPorts).toBeObject(); expect(connectionPorts).toBeObject();
expect(connectionPorts.access).toBe('package'); expect(connectionPorts.access).toBe('package');

View File

@ -1,12 +1,10 @@
describe('@polymerBehavior tag', () => { describe('@polymerBehavior tag', () => {
const env = require('jsdoc/env'); const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags); const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => { beforeEach(() => {
env.conf.tags.allowUnknownTags = false; env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
}); });
afterEach(() => { afterEach(() => {
@ -20,9 +18,11 @@ describe('@polymerBehavior tag', () => {
}); });
it('should not recognize the @polymerBehavior tag', () => { it('should not recognize the @polymerBehavior tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/polymerbehaviortag.js'); 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', () => { it('should recognize the @polymerBehavior tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/polymerbehaviortag.js'); 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', () => { describe('@polymer tag', () => {
const env = require('jsdoc/env'); const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags); const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => { beforeEach(() => {
env.conf.tags.allowUnknownTags = false; env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
}); });
afterEach(() => { afterEach(() => {
@ -20,9 +18,11 @@ describe('@polymer tag', () => {
}); });
it('should not recognize the @polymer tag', () => { it('should not recognize the @polymer tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/polymertag.js'); 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', () => { it('should recognize the @polymer tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/polymertag.js'); 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', () => { describe('@preserve tag', () => {
const env = require('jsdoc/env'); const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags); const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => { beforeEach(() => {
env.conf.tags.allowUnknownTags = false; env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
}); });
afterEach(() => { afterEach(() => {
@ -20,9 +18,11 @@ describe('@preserve tag', () => {
}); });
it('should not recognize the @preserve tag', () => { it('should not recognize the @preserve tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/preservetag.js'); 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', () => { describe('@private tag', () => {
const docSet = jsdoc.getDocSetFromFile('test/fixtures/privatetag.js'); const docSet = jsdoc.getDocSetFromFile('test/fixtures/privatetag.js');
const foo = docSet.getByLongname('Foo')[0]; 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.', () => { it('When JSDoc tags are enabled, the @private tag does not accept a value.', () => {
jsdoc.replaceTagDictionary('jsdoc'); function getDocSet() {
spyOn(logger, 'warn'); jsdoc.replaceTagDictionary('jsdoc');
jsdoc.getDocSetFromFile('test/fixtures/privatetag2.js');
}
jsdoc.getDocSetFromFile('test/fixtures/privatetag2.js'); expect(jsdoc.didLog(getDocSet, 'warn')).toBeTrue();
expect(logger.warn).toHaveBeenCalled();
}); });
}); });
describe('Closure Compiler tags', () => { describe('Closure Compiler tags', () => {
beforeEach(() => {
jsdoc.replaceTagDictionary('closure');
});
afterEach(() => { afterEach(() => {
jsdoc.restoreTagDictionary(); jsdoc.restoreTagDictionary();
}); });
it('When Closure Compiler tags are enabled, the @private tag accepts a type expression.', 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 connectionPorts;
let privateDocs; let privateDocs;
jsdoc.replaceTagDictionary('closure');
spyOn(logger, 'warn');
privateDocs = jsdoc.getDocSetFromFile('test/fixtures/privatetag2.js'); privateDocs = jsdoc.getDocSetFromFile('test/fixtures/privatetag2.js');
connectionPorts = privateDocs.getByLongname('connectionPorts')[0]; connectionPorts = privateDocs.getByLongname('connectionPorts')[0];
expect(logger.warn).not.toHaveBeenCalled();
expect(connectionPorts).toBeObject(); expect(connectionPorts).toBeObject();
expect(connectionPorts.access).toBe('private'); expect(connectionPorts.access).toBe('private');

View File

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

View File

@ -1,12 +1,10 @@
describe('@struct tag', () => { describe('@struct tag', () => {
const env = require('jsdoc/env'); const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags); const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => { beforeEach(() => {
env.conf.tags.allowUnknownTags = false; env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
}); });
afterEach(() => { afterEach(() => {
@ -20,9 +18,11 @@ describe('@struct tag', () => {
}); });
it('should not recognize the @struct tag', () => { it('should not recognize the @struct tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/structtag.js'); 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', () => { it('should recognize the @struct tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/structtag.js'); 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', () => { describe('@suppress tag', () => {
const env = require('jsdoc/env'); const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags); const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => { beforeEach(() => {
env.conf.tags.allowUnknownTags = false; env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
}); });
afterEach(() => { afterEach(() => {
@ -20,9 +18,11 @@ describe('@suppress tag', () => {
}); });
it('should not recognize the @suppress tag', () => { it('should not recognize the @suppress tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/suppresstag.js'); 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', () => { it('should recognize the @suppress tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/suppresstag.js'); 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', () => { describe('@template tag', () => {
const env = require('jsdoc/env'); const env = require('jsdoc/env');
const logger = require('jsdoc/util/logger');
const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags); const allowUnknownTags = Boolean(env.conf.tags.allowUnknownTags);
beforeEach(() => { beforeEach(() => {
env.conf.tags.allowUnknownTags = false; env.conf.tags.allowUnknownTags = false;
spyOn(logger, 'error');
}); });
afterEach(() => { afterEach(() => {
@ -20,9 +18,11 @@ describe('@template tag', () => {
}); });
it('should not recognize the @template tag', () => { it('should not recognize the @template tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/templatetag.js'); 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', () => { it('should recognize the @template tag', () => {
jsdoc.getDocSetFromFile('test/fixtures/templatetag.js'); 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', () => { describe('@type tag', () => {
const docSet = jsdoc.getDocSetFromFile('test/fixtures/typetag.js'); 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.', () => { it('When JSDoc tags are enabled, the @type tag does not accept a description.', () => {
jsdoc.replaceTagDictionary('jsdoc'); function getDocSet() {
spyOn(logger, 'warn'); jsdoc.replaceTagDictionary('jsdoc');
jsdoc.getDocSetFromFile('test/fixtures/typetag2.js');
}
jsdoc.getDocSetFromFile('test/fixtures/typetag2.js'); expect(jsdoc.didLog(getDocSet, 'warn')).toBeTrue();
expect(logger.warn).toHaveBeenCalled();
}); });
}); });
@ -44,17 +42,23 @@ describe('@type tag', () => {
}); });
it('When Closure tags are enabled, the @type tag accepts a description.', () => { 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 stringOrNumber;
let typeDocs; let typeDocs;
jsdoc.replaceTagDictionary('closure'); jsdoc.replaceTagDictionary('closure');
spyOn(logger, 'warn');
typeDocs = jsdoc.getDocSetFromFile('test/fixtures/typetag2.js'); typeDocs = jsdoc.getDocSetFromFile('test/fixtures/typetag2.js');
stringOrNumber = typeDocs.getByLongname('stringOrNumber')[0]; stringOrNumber = typeDocs.getByLongname('stringOrNumber')[0];
expect(logger.warn).not.toHaveBeenCalled();
expect(stringOrNumber).toBeObject(); expect(stringOrNumber).toBeObject();
expect(stringOrNumber.description).toBe('A string or a number.'); expect(stringOrNumber.description).toBe('A string or a number.');
}); });

View File

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