'use strict';
/**
* Desktop Notifications module. * @module Growl */
const os = require('os'); const path = require('path'); const {sync: which} = require('which'); const {EVENT_RUN_END} = require('./runner').constants;
/**
* @summary * Checks if Growl notification support seems likely. * * @description * Glosses over the distinction between an unsupported platform * and one that lacks prerequisite software installations. * * @public * @see {@link https://github.com/tj/node-growl/blob/master/README.md|Prerequisite Installs} * @see {@link Mocha#growl} * @see {@link Mocha#isGrowlCapable} * @return {boolean} whether Growl notification support can be expected */
exports.isCapable = () => {
if (!process.browser) { return getSupportBinaries().reduce( (acc, binary) => acc || Boolean(which(binary, {nothrow: true})), false ); } return false;
};
/**
* Implements desktop notifications as a pseudo-reporter. * * @public * @see {@link Mocha#_growl} * @param {Runner} runner - Runner instance. */
exports.notify = runner => {
runner.once(EVENT_RUN_END, () => { display(runner); });
};
/**
* Displays the notification. * * @private * @param {Runner} runner - Runner instance. */
const display = runner => {
const growl = require('growl'); const stats = runner.stats; const symbol = { cross: '\u274C', tick: '\u2705' }; let _message; let message; let title; if (stats.failures) { _message = `${stats.failures} of ${stats.tests} tests failed`; message = `${symbol.cross} ${_message}`; title = 'Failed'; } else { _message = `${stats.passes} tests passed in ${stats.duration}ms`; message = `${symbol.tick} ${_message}`; title = 'Passed'; } // Send notification const options = { image: logo(), name: 'mocha', title }; growl(message, options, onCompletion);
};
/**
* @summary * Callback for result of attempted Growl notification. * * @description * Despite its appearance, this is <strong>not</strong> an Error-first * callback -- all parameters are populated regardless of success. * * @private * @callback Growl~growlCB * @param {*} err - Error object, or <code>null</code> if successful. */
function onCompletion(err) {
if (err) { // As notifications are tangential to our purpose, just log the error. const message = err.code === 'ENOENT' ? 'prerequisite software not found' : err.message; console.error('notification error:', message); }
}
/**
* Returns Mocha logo image path. * * @private * @return {string} Pathname of Mocha logo */
const logo = () => {
return path.join(__dirname, '..', 'assets', 'mocha-logo-96.png');
};
/**
* @summary * Gets platform-specific Growl support binaries. * * @description * Somewhat brittle dependency on `growl` package implementation, but it * rarely changes. * * @private * @see {@link https://github.com/tj/node-growl/blob/master/lib/growl.js#L28-L126|setupCmd} * @return {string[]} names of Growl support binaries */
const getSupportBinaries = () => {
const binaries = { Darwin: ['terminal-notifier', 'growlnotify'], Linux: ['notify-send', 'growl'], Windows_NT: ['growlnotify.exe'] }; return binaries[os.type()] || [];
};