<commit_before>'use strict';

var _ = require('underscore'),
    inspect = require('util').inspect,
    parseString = require('xml2js').parseString,
    fs = require('fs');

/**
 * Run multiple behat feature files in parallel.
 *
 * Example usage:
 *
 * var behat = new BehatTask({
 *     files: ['feature1.feature', 'feature2.feature'],
 *     log: console.log,
 *     bin: 'behat',
 *     flags: '--tags @wip',
 *     executor: new ParallelExec(5),
 *     numRetries: 0
 * })
 *
 * @param {Object} options
 */
function BehatTask (options) {
    var tasks = {},
        failedTasks = {},
        startTime;

    /**
     * Create a behat command for each file and run it using the executor
     */
    function run() {
        startTime = +new Date();

        _.each(options.files, addTask);
        options.log.subhead('Running ' + options.maxProcesses + ' at a time.');

        options.executor.on('startedTask', taskStarted);
        options.executor.on('finishedTask', taskFinished);
        options.executor.on('finished', finish);
        options.executor.start();
    }

    /**
     * Send an individual feature file to be run
     *
     * @param {String} file
     */
    function addTask (file) {
        if (fs.lstatSync(file).isFile() && file.indexOf('.feature') > -1) {
            var configOpt = options.config ? '-c ' + options.config : '',
                filePath = options.baseDir ? options.baseDir + file : file,
                junitOut = options.junit ? '-f junit --out ' + options.junit.output_folder : '',
                cmd = [options.bin, configOpt, filePath, options.flags, junitOut].join(' ');

            // Consistent spaces and trimming space off end
            cmd = cmd.replace(/\s+/g, ' ').trim();
            tasks[cmd] = file;
            options.executor.addTask(cmd);
        }
    }

    /**
     * Tell the user we've started a new task
     *
     * @param  {string} task
     */
    function taskStarted (task) {
        options.log.writeln('Started: ' + task);
    }

    /**
     * Process the result of the task
     *
     * @param {string} task
     * @param {Object} err
     * @param {string} stdout
     * @param {string} stderr
     */
    function taskFinished (task, err, stdout, stderr) {
        var file = tasks[task];

        // Capture junit output
        if (options.junit) {
            var file_path = file.split('/');
            var feature = file_path[file_path.length - 1].replace('.feature', '');
            file_path.splice(-1, 1);
            for (var i = 0; i < file_path.length; i++) {
                if (file_path[i] == 'features') {
                    file_path.splice(0, i + 1);
                }
            }
            var testfile = fs.readFileSync(options.junit.output_folder + feature + '.xml', 'utf8');
            if (testfile) {
                parseString(testfile, function (err, result) {

                    if (err) {
                        options.log.error('Failed: to read JUnit XML file');
                        taskPendingOrFailed(task);
                    }
                    else if ((result.testsuites.testsuite["0"].$.errors && result.testsuites.testsuite["0"].$.errors >= 1) || (result.testsuites.testsuite["0"].$.failures && result.testsuites.testsuite["0"].$.failures >= 1)) {
                        for (var i = 0; i < result.testsuites.testsuite.length; i++) {
                            if (result.testsuites.testsuite[i].$.failures) {
                                options.log.error('Error: ' + file + ' - ' + result.testsuites.testsuite[i].$.failures + ' total errors');
                                } else {
                                options.log.error('Error: ' + file);
                                }
                                // Capture normal message or runtime error as a fallback
                                taskPendingOrFailed(task);
                            }
                        }
                    else {
                        options.log.ok('Completed: ' + file + ' - ' + result.testsuites.$.name);

                    }
                });
            } else {
                options.log.error('Failed: to read JUnit XML file');
            }

        } else {
            var output = stdout ? stdout.split('\n') : [];

            if (options.debug) {
                if (err) options.log.writeln('\nerr: \n' + inspect(err));
                if (stderr) options.log.writeln('\nstderr: \n' + stderr);
                if (stdout) options.log.writeln('\nstdout: \n' + stdout);
            }

            if (err && (err.code === 13 || err.killed)) {
                options.log.writeln('Timeout: ' + file + ' - adding to the back of the queue.');
                options.executor.addTask(task);
            }
            else if (err && err.code === 1) {
                options.log.error('Failed: ' + file + ' - ' + output[output.length - 4] + ' in ' + output[output.length - 2]);
                taskPendingOrFailed(task);
            }
            else if (err) {
                options.log.error('Error: ' + file + ' - ' + err + stdout);
            }
            else {
                options.log.ok('Completed: ' + file + ' - ' + output[output.length - 4] + ' in ' + output[output.length - 2]);

                if (output[output.length - 4].indexOf('pending') > -1) {
                    taskPendingOrFailed(task);
                }
            }
        }
    }

    /**
     * Add the given task to the fail list and retry if options.numRetries is specified
     *
     * @param  {string} task
     */
    function taskPendingOrFailed (task) {
        failedTasks[task] = _.has(failedTasks, task) ? failedTasks[task] + 1 : 0;

        if (failedTasks[task] < options.numRetries) {
            options.log.writeln('Retrying: ' + tasks[task] + ' ' + (failedTasks[task] + 1) + ' of ' + options.numRetries + ' time(s)');
            options.executor.addTask(task);
        }
        else {
            options.fail.warn('Scenario failed');
        }
    }

    /**
     * Output the final run time and emit the finished event
     */
    function finish () {
        var totalTime = Math.floor((new Date() - startTime) / 1000);

        options.log.writeln('\nFinished in ' + Math.floor(totalTime / 60) + 'm' + totalTime % 60 + 's');
        options.done();
    }

    this.run = run;
}

module.exports = BehatTask;
<commit_msg>Fix to bad naming for junit output<commit_after>'use strict';

var _ = require('underscore'),
    inspect = require('util').inspect,
    parseString = require('xml2js').parseString,
    fs = require('fs');

/**
 * Run multiple behat feature files in parallel.
 *
 * Example usage:
 *
 * var behat = new BehatTask({
 *     files: ['feature1.feature', 'feature2.feature'],
 *     log: console.log,
 *     bin: 'behat',
 *     flags: '--tags @wip',
 *     executor: new ParallelExec(5),
 *     numRetries: 0
 * })
 *
 * @param {Object} options
 */
function BehatTask (options) {
    var tasks = {},
        failedTasks = {},
        startTime;

    /**
     * Create a behat command for each file and run it using the executor
     */
    function run() {
        startTime = +new Date();

        _.each(options.files, addTask);
        options.log.subhead('Running ' + options.maxProcesses + ' at a time.');

        options.executor.on('startedTask', taskStarted);
        options.executor.on('finishedTask', taskFinished);
        options.executor.on('finished', finish);
        options.executor.start();
    }

    /**
     * Send an individual feature file to be run
     *
     * @param {String} file
     */
    function addTask (file) {
        if (fs.lstatSync(file).isFile() && file.indexOf('.feature') > -1) {
            var configOpt = options.config ? '-c ' + options.config : '',
                filePath = options.baseDir ? options.baseDir + file : file,
                junitOut = options.junit ? '-f junit --out ' + options.junit.output_folder : '',
                cmd = [options.bin, configOpt, filePath, options.flags, junitOut].join(' ');

            // Consistent spaces and trimming space off end
            cmd = cmd.replace(/\s+/g, ' ').trim();
            tasks[cmd] = file;
            options.executor.addTask(cmd);
        }
    }

    /**
     * Tell the user we've started a new task
     *
     * @param  {string} task
     */
    function taskStarted (task) {
        options.log.writeln('Started: ' + task);
    }

    /**
     * Process the result of the task
     *
     * @param {string} task
     * @param {Object} err
     * @param {string} stdout
     * @param {string} stderr
     */
    function taskFinished (task, err, stdout, stderr) {
        var file = tasks[task];

        // Capture junit output
        if (options.junit) {
            var file_path = file.split('/');
            var feature = file_path[file_path.length - 1].replace('.feature', '');
            file_path.splice(-1, 1);
            for (var i = 0; i < file_path.length; i++) {
                if (file_path[i] == 'features') {
                    file_path.splice(0, i + 1);
                }
            }
            var testfile = fs.readFileSync(options.junit.output_folder + feature.toLowerCase() + '.xml', 'utf8');
            if (testfile) {
                parseString(testfile, function (err, result) {

                    if (err) {
                        options.log.error('Failed: to read JUnit XML file');
                        taskPendingOrFailed(task);
                    }
                    else if ((result.testsuites.testsuite["0"].$.errors && result.testsuites.testsuite["0"].$.errors >= 1) || (result.testsuites.testsuite["0"].$.failures && result.testsuites.testsuite["0"].$.failures >= 1)) {
                        for (var i = 0; i < result.testsuites.testsuite.length; i++) {
                            if (result.testsuites.testsuite[i].$.failures) {
                                options.log.error('Error: ' + file + ' - ' + result.testsuites.testsuite[i].$.failures + ' total errors');
                                } else {
                                options.log.error('Error: ' + file);
                                }
                                // Capture normal message or runtime error as a fallback
                                taskPendingOrFailed(task);
                            }
                        }
                    else {
                        options.log.ok('Completed: ' + file + ' - ' + result.testsuites.$.name);

                    }
                });
            } else {
                options.log.error('Failed: to read JUnit XML file');
            }

        } else {
            var output = stdout ? stdout.split('\n') : [];

            if (options.debug) {
                if (err) options.log.writeln('\nerr: \n' + inspect(err));
                if (stderr) options.log.writeln('\nstderr: \n' + stderr);
                if (stdout) options.log.writeln('\nstdout: \n' + stdout);
            }

            if (err && (err.code === 13 || err.killed)) {
                options.log.writeln('Timeout: ' + file + ' - adding to the back of the queue.');
                options.executor.addTask(task);
            }
            else if (err && err.code === 1) {
                options.log.error('Failed: ' + file + ' - ' + output[output.length - 4] + ' in ' + output[output.length - 2]);
                taskPendingOrFailed(task);
            }
            else if (err) {
                options.log.error('Error: ' + file + ' - ' + err + stdout);
            }
            else {
                options.log.ok('Completed: ' + file + ' - ' + output[output.length - 4] + ' in ' + output[output.length - 2]);

                if (output[output.length - 4].indexOf('pending') > -1) {
                    taskPendingOrFailed(task);
                }
            }
        }
    }

    /**
     * Add the given task to the fail list and retry if options.numRetries is specified
     *
     * @param  {string} task
     */
    function taskPendingOrFailed (task) {
        failedTasks[task] = _.has(failedTasks, task) ? failedTasks[task] + 1 : 0;

        if (failedTasks[task] < options.numRetries) {
            options.log.writeln('Retrying: ' + tasks[task] + ' ' + (failedTasks[task] + 1) + ' of ' + options.numRetries + ' time(s)');
            options.executor.addTask(task);
        }
        else {
            options.fail.warn('Scenario failed');
        }
    }

    /**
     * Output the final run time and emit the finished event
     */
    function finish () {
        var totalTime = Math.floor((new Date() - startTime) / 1000);

        options.log.writeln('\nFinished in ' + Math.floor(totalTime / 60) + 'm' + totalTime % 60 + 's');
        options.done();
    }

    this.run = run;
}

module.exports = BehatTask;
<|endoftext|>


<commit_before>import createElement from 'virtual-dom/create-element';
import VNode from 'virtual-dom/vnode/vnode';
import VText from 'virtual-dom/vnode/vtext';
const convertHTML = require('html-to-vdom')({
    VNode: VNode,
    VText: VText
});
import $ from 'jquery';
import _ from 'lodash';
import * as jsdiff from 'diff';

//TODO CHECK meta-date changes. Title changes -> result in new revisions
const CKEditor_vars = ['span', 'var', 'em', 'strong', 'u'];

const toHTML = (string) => (
  createElement(convertHTML(string))
);

const deepSearch = (obj, key) => {
    if (_.has(obj, key)) // or just (key in obj)
        return [obj];
    // elegant:
    // return _.flatten(_.map(obj, function(v) {
    //     return typeof v == "object" ? fn(v, key) : [];
    // }), true);

    // or efficient:
    let res = [];
    _.forEach(obj, (v) => {
        if (typeof v == 'object' && (v = deepSearch(v, key)).length)
            res.push.apply(res, v);
    });
    return res;
};

// Fn resposible for comparing 2 root IDs
const compareWrapperIds = (initSrc, finalSrc) => {
    const finalRoot = toHTML(finalSrc);
    const initRoot = toHTML(initSrc);

    return ($(finalRoot)[0].id === $(initRoot)[0].id) ? true : false;
};

const getParentId = (finalSrc, id) => {
    if(id !== undefined){
        const finalRoot = toHTML(finalSrc);
        const parent = $(finalRoot).find(`#${id}`).parent();

        return parent[0].id;
    } else {
        return null;
    }
};

const getClosestDiv = (finalSrc, id) => {
    const finalRoot = toHTML(finalSrc);
    const parent = $(finalRoot).find(`#${id}`).closest('div');

    return parent[0].id;
};

const handleTEXT = (oldText, newText, source) => {

    const oldStr = oldText.text,
        newStr = newText.text;
    let root = toHTML(source);

    let color = '',
        container = null,
        diff = jsdiff.diffWords(oldStr, newStr),
        temp = document.createElement('div');

    diff.forEach((part) => {
        // green for additions, red for deletions
        color = part.added ? 'ins' : part.removed ? 'del' : '';
        container = document.createElement('span');
        container.className = color;
        container.appendChild(document.createTextNode(part.value));
        temp.appendChild(container);
    });

    const markedText = temp.innerHTML;

    $(root).find(`*:contains(${oldStr})`)
            .filter(function() { return $(this).text() === oldStr; })
            .html(markedText);

    source = root.outerHTML;

    return source;
};

const handleINSERT = (el, source, finalsource) => {
    const elem = createElement(el.patch);
    const _id = el.patch.key;
    const tag = el.patch.tagName;
    let root = toHTML(source);

    if(_.includes(CKEditor_vars, tag)) {
        let parent = getClosestDiv(finalsource, _id);
        $(root).find(`#${parent}`).addClass('modified');
    } else {
        let targetElement = $(elem);
        targetElement.addClass('added');

        let parent = getParentId(finalsource, _id);
        $(root).prop('id') === parent ?
          $(root).append(elem) : $(root).find(`#${parent}`).append(elem);
    }

    source = root.outerHTML;

    return source;
};

const handleREMOVE = (el, source, finalsource) => {
    const _id = el.vNode.key;
    const tag = el.vNode.tagName;
    let root = toHTML(source);

    if(_.includes(CKEditor_vars, tag)) {
        let parent = getClosestDiv(finalsource, _id);
        $(root).find(`#${parent}`).addClass('modified');
    } else {
        if(_id){
            let targetElement = $(root).find(`#${_id}`);
            targetElement.addClass('deleted');
        }
    }

    source = root.outerHTML;

    return source;
};

const handlePROPS = (node, patch, source, finalsource, vnode) => {
    const _id = node.key;
    const tag = node.tagName;
    let root = toHTML(source);

    let styles = patch.style;
    if(styles) Object.keys(styles).forEach((key) => styles[key] === undefined ? delete styles[key] : '');
    let attrs = patch.attributes;
    if(attrs) Object.keys(attrs).forEach((key) => attrs[key] === undefined ? delete attrs[key] : '');

    let change = (_.isEmpty(styles)) ? attrs : styles;
    let key = Object.keys(change)[0];
    let vals = Object.values(change)[0];

    if (key && vals) {
        if (_id) {
            //[Problem] if node tags are changed. span -> h2
            // let targetElement = $(root).find(`${tag}[_id='${_id}']`);
            let targetElement;
            if(!vnode){
                targetElement = $(root).find(`#${_id}`);
            } else {
                let parent = getParentId(finalsource, _id);
                targetElement = $(root).find(`#${parent}`);
            }
            targetElement.addClass('modified');
            targetElement.css(`${key}`, `${vals}`);
        }
    }
    /*else if (patch === 'attributes') {
        node.properties[`${change}`][`${key}`] = vals;
        //$(root).find(`${tag}.${vals}`).addClass('modified');
    }*/
    source = root.outerHTML;

    return source;
};

const preprocessSrc = (source, mode) => {

    source = source
                .replace(/ /g, '')
                .replace(/(?:\r\n|\r|\n)/g, '')
                .replace(//g, '');

    if (mode) {
        //canvas slide
        const vTreeObject = convertHTML(source);
        let root;

        vTreeObject.length > 1 ? root = createElement(vTreeObject[0]) : root = createElement(vTreeObject);

        $(root).find('br').remove();
        $(root).find('.drawing-container').remove();
        $(root).find('p:empty').remove();
        $(root).find('span:empty').remove();
        $(root).find('div:empty').remove();
        // CKEditor related
        $(root).find('.cke_image_resizer, .cke_widget_drag_handler_container').remove();

        source = root.outerHTML;

    } else {
        //created slide

        //wrap in a root node
        source = `<div class='root'>${source}</div>`;
    }

    return source;
};

const setKeys = (source) => {
    //apply keys for proper change detection
    source = convertHTML({
        getVNodeKey: function(attributes) {
            return attributes.id;
        }
    }, source);

    return source;
};

/**
* @params:
@ PatchObject:list of diff changes
@ string:initSrc - apply changes on top of this source string
@ string:mode: uploaded/created
*/
const detectnPatch = (list, initSrc, mode, finalSrc) => {
    let elem;

    list.map((el) => {
        let nodeType;
        let patchType;
        switch (el.type) {
            case 0:
                break;
            case 1:
                const textArray = deepSearch(el, 'text');
                initSrc = handleTEXT(textArray[0], textArray[1], initSrc);
                break;
            case 2:
                nodeType = el.vNode.constructor.name;
                patchType = el.patch.constructor.name;
                if(nodeType === 'VirtualText')
                    initSrc = handleTEXT(el.vNode, el.patch.children[0], initSrc);
                if(nodeType === 'VirtualNode' || patchType === 'VirtualNode')
                    initSrc = handlePROPS(el.patch, el.patch.properties, initSrc, finalSrc, true);
                break;
            case 3:
                elem = createElement(el.vNode);
                break;
            case 4:
                initSrc = handlePROPS(el.vNode, el.patch, initSrc);
                break;
            case 5:
                elem = createElement(el.patch);
                break;
            case 6:
                initSrc = handleINSERT(el, initSrc, finalSrc);
                break;
            case 7:
                nodeType = el.vNode.constructor.name;
                if(nodeType === 'VirtualNode') initSrc = handleREMOVE(el, initSrc, finalSrc);
                break;
            default:
        }
    });

    return initSrc;
};

module.exports = {
    preprocess: preprocessSrc,
    construct: detectnPatch,
    setKeys: setKeys,
    compareWrapperIds: compareWrapperIds
};
<commit_msg>SWAQ-529 fix missing spaces<commit_after>import createElement from 'virtual-dom/create-element';
import VNode from 'virtual-dom/vnode/vnode';
import VText from 'virtual-dom/vnode/vtext';
const convertHTML = require('html-to-vdom')({
    VNode: VNode,
    VText: VText
});
import $ from 'jquery';
import _ from 'lodash';
import * as jsdiff from 'diff';

//TODO CHECK meta-date changes. Title changes -> result in new revisions
const CKEditor_vars = ['span', 'var', 'em', 'strong', 'u'];

const toHTML = (string) => (
  createElement(convertHTML(string))
);

const deepSearch = (obj, key) => {
    if (_.has(obj, key)) // or just (key in obj)
        return [obj];
    // elegant:
    // return _.flatten(_.map(obj, function(v) {
    //     return typeof v == "object" ? fn(v, key) : [];
    // }), true);

    // or efficient:
    let res = [];
    _.forEach(obj, (v) => {
        if (typeof v == 'object' && (v = deepSearch(v, key)).length)
            res.push.apply(res, v);
    });
    return res;
};

// Fn resposible for comparing 2 root IDs
const compareWrapperIds = (initSrc, finalSrc) => {
    const finalRoot = toHTML(finalSrc);
    const initRoot = toHTML(initSrc);

    return ($(finalRoot)[0].id === $(initRoot)[0].id) ? true : false;
};

const getParentId = (finalSrc, id) => {
    if(id !== undefined){
        const finalRoot = toHTML(finalSrc);
        const parent = $(finalRoot).find(`#${id}`).parent();

        return parent[0].id;
    } else {
        return null;
    }
};

const getClosestDiv = (finalSrc, id) => {
    const finalRoot = toHTML(finalSrc);
    const parent = $(finalRoot).find(`#${id}`).closest('div');

    return parent[0].id;
};

const handleTEXT = (oldText, newText, source) => {

    const oldStr = oldText.text,
        newStr = newText.text;
    let root = toHTML(source);

    let color = '',
        container = null,
        diff = jsdiff.diffWords(oldStr, newStr),
        temp = document.createElement('div');

    diff.forEach((part) => {
        // green for additions, red for deletions
        color = part.added ? 'ins' : part.removed ? 'del' : '';
        container = document.createElement('span');
        container.className = color;
        container.appendChild(document.createTextNode(part.value));
        temp.appendChild(container);
    });

    const markedText = temp.innerHTML;

    $(root).find(`*:contains(${oldStr})`)
            .filter(function() { return $(this).text() === oldStr; })
            .html(markedText);

    source = root.outerHTML;

    return source;
};

const handleINSERT = (el, source, finalsource) => {
    const elem = createElement(el.patch);
    const _id = el.patch.key;
    const tag = el.patch.tagName;
    let root = toHTML(source);

    if(_.includes(CKEditor_vars, tag)) {
        let parent = getClosestDiv(finalsource, _id);
        $(root).find(`#${parent}`).addClass('modified');
    } else {
        let targetElement = $(elem);
        targetElement.addClass('added');

        let parent = getParentId(finalsource, _id);
        $(root).prop('id') === parent ?
          $(root).append(elem) : $(root).find(`#${parent}`).append(elem);
    }

    source = root.outerHTML;

    return source;
};

const handleREMOVE = (el, source, finalsource) => {
    const _id = el.vNode.key;
    const tag = el.vNode.tagName;
    let root = toHTML(source);

    if(_.includes(CKEditor_vars, tag)) {
        let parent = getClosestDiv(finalsource, _id);
        $(root).find(`#${parent}`).addClass('modified');
    } else {
        if(_id){
            let targetElement = $(root).find(`#${_id}`);
            targetElement.addClass('deleted');
        }
    }

    source = root.outerHTML;

    return source;
};

const handlePROPS = (node, patch, source, finalsource, vnode) => {
    const _id = node.key;
    const tag = node.tagName;
    let root = toHTML(source);

    let styles = patch.style;
    if(styles) Object.keys(styles).forEach((key) => styles[key] === undefined ? delete styles[key] : '');
    let attrs = patch.attributes;
    if(attrs) Object.keys(attrs).forEach((key) => attrs[key] === undefined ? delete attrs[key] : '');

    let change = (_.isEmpty(styles)) ? attrs : styles;
    let key = Object.keys(change)[0];
    let vals = Object.values(change)[0];

    if (key && vals) {
        if (_id) {
            //[Problem] if node tags are changed. span -> h2
            // let targetElement = $(root).find(`${tag}[_id='${_id}']`);
            let targetElement;
            if(!vnode){
                targetElement = $(root).find(`#${_id}`);
            } else {
                let parent = getParentId(finalsource, _id);
                targetElement = $(root).find(`#${parent}`);
            }
            targetElement.addClass('modified');
            targetElement.css(`${key}`, `${vals}`);
        }
    }
    /*else if (patch === 'attributes') {
        node.properties[`${change}`][`${key}`] = vals;
        //$(root).find(`${tag}.${vals}`).addClass('modified');
    }*/
    source = root.outerHTML;

    return source;
};

const preprocessSrc = (source, mode) => {

    source = source
                .replace(/(?:\r\n|\r|\n)/g, '')
                .replace(//g, '');

    if (mode) {
        //canvas slide
        const vTreeObject = convertHTML(source);
        let root;

        vTreeObject.length > 1 ? root = createElement(vTreeObject[0]) : root = createElement(vTreeObject);

        // $(root).find('br').remove();
        $(root).find('.drawing-container').remove();
        $(root).find('p:empty').remove();
        $(root).find('span:empty').remove();
        $(root).find('div:empty').remove();
        // CKEditor related
        $(root).find('.cke_image_resizer, .cke_widget_drag_handler_container').remove();

        source = root.outerHTML;

    } else {
        //created slide

        //wrap in a root node
        source = `<div class='root'>${source}</div>`;
    }

    return source;
};

const setKeys = (source) => {
    //apply keys for proper change detection
    source = convertHTML({
        getVNodeKey: function(attributes) {
            return attributes.id;
        }
    }, source);

    return source;
};

/**
* @params:
@ PatchObject:list of diff changes
@ string:initSrc - apply changes on top of this source string
@ string:mode: uploaded/created
*/
const detectnPatch = (list, initSrc, mode, finalSrc) => {
    let elem;

    list.map((el) => {
        let nodeType;
        let patchType;
        switch (el.type) {
            case 0:
                break;
            case 1:
                const textArray = deepSearch(el, 'text');
                initSrc = handleTEXT(textArray[0], textArray[1], initSrc);
                break;
            case 2:
                nodeType = el.vNode.constructor.name;
                patchType = el.patch.constructor.name;
                if(nodeType === 'VirtualText')
                    initSrc = handleTEXT(el.vNode, el.patch.children[0], initSrc);
                if(nodeType === 'VirtualNode' || patchType === 'VirtualNode')
                    initSrc = handlePROPS(el.patch, el.patch.properties, initSrc, finalSrc, true);
                break;
            case 3:
                elem = createElement(el.vNode);
                break;
            case 4:
                initSrc = handlePROPS(el.vNode, el.patch, initSrc);
                break;
            case 5:
                elem = createElement(el.patch);
                break;
            case 6:
                initSrc = handleINSERT(el, initSrc, finalSrc);
                break;
            case 7:
                nodeType = el.vNode.constructor.name;
                if(nodeType === 'VirtualNode') initSrc = handleREMOVE(el, initSrc, finalSrc);
                break;
            default:
        }
    });

    return initSrc;
};

module.exports = {
    preprocess: preprocessSrc,
    construct: detectnPatch,
    setKeys: setKeys,
    compareWrapperIds: compareWrapperIds
};
<|endoftext|>


<commit_before>var http   = require('http');
var send   = require('send');
var port   = process.env.PORT || 8080;
var __root = __dirname + '/../..';

http.createServer(function(req, res) {
  if (req.url === '/') {
    res.writeHead(301, {'Location': '/test/browser/index.html'});
    res.end();
    return;
  }

  send(req, req.url)
    .root(__root)
    .pipe(res);
}).listen(port);

console.log('Test demo running at http://localhost:' + port + '/');
<commit_msg>Browser Test: fix call to send()-library (.root() is deprecated)<commit_after>var http   = require('http');
var send   = require('send');
var port   = process.env.PORT || 8080;
var __root = __dirname + '/../..';

http.createServer(function(req, res) {
  if (req.url === '/') {
    res.writeHead(301, {'Location': '/test/browser/index.html'});
    res.end();
    return;
  }

  send(req, req.url, {
      root: __root
    })
    .pipe(res);
}).listen(port);

console.log('Test demo running at http://localhost:' + port + '/');
<|endoftext|>


<commit_before>#!/usr/bin/env node

var express = require('express');
var http = require('http')
var path = require('path');
var util = require('util');

var config = require('./config');
var lights = require('./lights');

/*
var app = express();

app.configure(function(){
	app.set('port', process.env.PORT || 3000);
	app.set('views', __dirname + '/views');
	app.set('view engine', 'jade');
	app.use(express.favicon());
	app.use(express.logger('dev'));
	app.use(express.bodyParser());
	app.use(express.methodOverride());
	app.use(express.cookieParser('123456789987654321'));
	app.use(express.session());
	app.use(app.router);
	app.use(require('stylus').middleware(__dirname + '/public'));
	app.use(express.static(path.join(__dirname, 'public')));
});

app.configure('development', function(){
	app.use(express.errorHandler());
});

http.createServer(app).listen(app.get('port'), function(){
	console.log("Express server listening on port " + app.get('port'));
});

app.get('/', function(req, res){
	res.render('index', { title: 'Hello World' });
});
*/

function flagGrabbed(player, flagid){
	var lightid = config.player2lightid[player];
	var flag = config.flags[flagid];

	if(!lightid) return console.log('unknown player: ' + player);
	if(!flag) return console.log('unknown flag: ' + flagid);

	var sat = flag.sat;
	if(!sat)
		sat = 255; // most saturated

	console.log("Setting flag '" + flag.name + "' for player " + player + " to hue = " + flag.hue + ", sat = " + sat);
	lights.setLight(lightid, flag.hue, sat);
}

// lights.startlooping();
// lights.startlooping();

flagGrabbed('sam', 'SH');

// DEBUG: Flags test flag through commandline interface:
// process.stdin.resume();
// process.stdin.setEncoding('utf8');
// var util = require('util');
// console.log("geef flag (A, CL, G, GM, L, OO, F, R, SH, SW, SR, SB, T, V, WG) en druk ENTER:");
// process.stdin.on('data', function (flagid) {
// 	if (flagid === 'quit\n')
// 		return process.exit();
// 	flagGrabbed('sam', flagid.replace(/\n/, ''));
// });

// // DEBUG: test colors via commandline interface:
// process.stdin.resume();
// process.stdin.setEncoding('utf8');
// var util = require('util');
// console.log("geef hue en druk ENTER:");
// process.stdin.on('data', function (hueString) {
// 	if (hueString === 'quit\n')
// 		return process.exit();
// 	var hue  = hueString.replace(/\n/, '');
// 	hue = parseInt(hue);
// 	if(isNaN(hue)) return console.log("not a number");

// 	lights.setLight(1, hue);
// });

<commit_msg>added express.js code<commit_after>#!/usr/bin/env node

var express = require('express');
var http = require('http')
var path = require('path');
var util = require('util');

var config = require('./config');
var lights = require('./lights');

var app = express();

app.configure(function(){
	app.set('port', process.env.PORT || 3000);
	app.set('views', __dirname + '/views');
	app.set('view engine', 'jade');
	app.use(express.favicon());
	app.use(express.logger('dev'));
	app.use(express.bodyParser());
	app.use(express.methodOverride());
	app.use(express.cookieParser('123456789987654321'));
	app.use(express.session());
	app.use(app.router);
	app.use(require('stylus').middleware(__dirname + '/public'));
	app.use(express.static(path.join(__dirname, 'public')));
});

app.configure('development', function(){
	app.use(express.errorHandler());
});

http.createServer(app).listen(app.get('port'), function(){
	console.log("Express server listening on port " + app.get('port'));
});

app.get('/', function(req, res){
	res.render('index', { title: 'Hello World' });
});

function flagGrabbed(player, flagid){
	var lightid = config.player2lightid[player];
	var flag = config.flags[flagid];

	if(!lightid) return console.log('unknown player: ' + player);
	if(!flag) return console.log('unknown flag: ' + flagid);

	var sat = flag.sat;
	if(!sat)
		sat = 255; // most saturated

	console.log("Setting flag '" + flag.name + "' for player " + player + " to hue = " + flag.hue + ", sat = " + sat);
	lights.setLight(lightid, flag.hue, sat);
}

// lights.startlooping();
// lights.startlooping();

flagGrabbed('sam', 'SH');

// DEBUG: Flags test flag through commandline interface:
// process.stdin.resume();
// process.stdin.setEncoding('utf8');
// var util = require('util');
// console.log("geef flag (A, CL, G, GM, L, OO, F, R, SH, SW, SR, SB, T, V, WG) en druk ENTER:");
// process.stdin.on('data', function (flagid) {
// 	if (flagid === 'quit\n')
// 		return process.exit();
// 	flagGrabbed('sam', flagid.replace(/\n/, ''));
// });

// // DEBUG: test colors via commandline interface:
// process.stdin.resume();
// process.stdin.setEncoding('utf8');
// var util = require('util');
// console.log("geef hue en druk ENTER:");
// process.stdin.on('data', function (hueString) {
// 	if (hueString === 'quit\n')
// 		return process.exit();
// 	var hue  = hueString.replace(/\n/, '');
// 	hue = parseInt(hue);
// 	if(isNaN(hue)) return console.log("not a number");

// 	lights.setLight(1, hue);
// });

<|endoftext|>


<commit_before>var map = require('../src/collection/map')
var expect = require('expect.js')

function d(value, enumerable) {
  return { value: value
         , enumerable: enumerable === false? false : true
         , configurable: true
         , writable: true }
}

function count() {
  return function _() {
    return _.num = (_.num || 0) + 1 }}

describe('{} collection.map', function() {
  var foo = {a:1}
  var data, keys, values

  function check_call(value, key) {
    var i = keys.indexOf(key)
    expect(i).to.not.be(-1)
    expect(values[i]).to.be(value)
    keys.splice(i, 1)
    values.splice(i, 1)
    return [key, value] }

  beforeEach(function() {
    keys   = ['b', 'd']
    values = [2, 4]
    data   = Object.create(foo, {
      b: d(2),
      c: d(3, false),
      d: d(4) })})

  describe('λ each', function() {
    it('Should apply iterator to every own enumerable property', function() {
      var c = count()
      map.each(data, c)
      expect(c.num).to.be(2) })

    it('Should pass (value, key, map) to the iterator', function() {
      map.each(data, function(v,k,m) {
        expect(m).to.be(data)
        expect(keys).to.contain(k)
        expect(values).to.contain(v) })})
  })

  describe('λ at', function() {
    it('Should retrieve the value for the given key', function() {
      expect(map.at(null, 'foo')).to.be(undefined)
      expect(map.at(data, 'a')).to.be(1)
      expect(map.at(data, 'b')).to.be(2)
      expect(map.at(data, 'c')).to.be(3) })
  })

  describe('λ put', function() {
    it('Should assign a value to the given key', function() {
      expect(map.put(null, 'a', 1)).to.be(null)
      map.put(data, 'b', 3)
      map.put(data, 'e', 4)
      expect(data.b).to.be(3)
      expect(data.e).to.be(4) })
  })

  describe('λ remove', function() {
    it('Should delete the given key from the map', function() {
      expect(map.remove(null, 'a')).to.be(null)
      map.remove(data, 'b')
      expect(map.hasOwnProperty('b')).to.not.be.ok() })
  })

  describe('λ replace', function() {
    it('Should replace all values that match by the given replacement', function() {
      expect(map.replace({a:1,b:2,c:1,d:[1]},1,0)).to.eql({a:0,b:2,c:0,d:[1]})
    })
  })

  describe('λ clear', function() {
    it('Should remove all enumerable keys from the map', function(){
      expect(map.clear(null)).to.be(null)
      map.clear(data)
      expect(data.a).to.be(1)
      expect(data.hasOwnProperty('b')).to.not.be.ok()
      expect(data.hasOwnProperty('c')).to.be.ok()
      expect(data.hasOwnProperty('d')).to.not.be.ok() })
  })

  describe('λ size', function() {
    it('Should return the number of enumerable keys in the map', function() {
      expect(map.size(null)).to.be(0)
      expect(map.size(data)).to.be(2) })
  })

  describe('λ empty_p', function() {
    it('Should check if there\'s any enumerable key in the map', function() {
      expect(map.empty_p(null)).to.be.ok()
      expect(map.empty_p({})).to.be.ok()
      expect(map.empty_p(data)).to.not.be.ok()
      delete data.b
      delete data.d
      expect(map.empty_p(data)).to.be.ok() })
  })

  describe('λ has_key_p', function() {
    it('Should check if the map has the key', function() {
      expect(map.has_key_p(null, 'a')).to.not.be.ok()
      expect(map.has_key_p(data, 'b')).to.be.ok()
      expect(map.has_key_p(data, 'a')).to.not.be.ok()
      expect(map.has_key_p(data, 'c')).to.be.ok() })
  })

  describe('λ keys', function() {
    it('Should return all enumerable keys in the map', function() {
      expect(map.keys(null).length).to.be(0)
      expect(map.keys(data)).to.eql(keys) })
  })

  describe('λ values', function() {
    it('Should return all enumerable values in the map', function() {
      expect(map.values(null).length).to.be(0)
      expect(map.values(data)).to.eql(values) })
  })

  describe('λ items', function() {
    it('Should return all enumerable key/value pairs in the map', function() {
      expect(map.items(null).length).to.be(0)
      expect(map.items(data)).to.eql([['b',2],['d',4]]) })
  })

  describe('λ reduce', function() {
    it('Should apply the function to all key/value pairs in the map', function() {
      map.reduce(data, 0, function(acc, value, key) {
        check_call(value, key) })

      expect(keys).to.eql([])
      expect(values).to.eql([]) })

    it('Should return the accumulated value', function() {
      expect(map.reduce(data, 0, function(acc, value) {
        return acc + value })).to.be(6) })

    it('Should use the first key/value pair as initial value if one isnt given', function() {
      map.reduce(data, function(acc, value) {
        expect(values).to.contain(acc) })})
  })

  describe('λ every', function() {
    it('Should check if all key/value pairs pass the predicate', function() {
      expect(map.every(data, check_call)).to.be.ok()
      expect(keys).to.eql([])
      expect(values).to.eql([]) })

    it('Should short-circuit', function() {
      var x = true
      var c = 0
      expect(map.every(data, function(acc, value) {
        c++
        return x = !x })).to.not.be.ok()
      expect(c).to.be(1) })
  })

  describe('λ some', function() {
    it('Should check if any key/value pairs pass the predicate', function() {
      expect(map.some(data, function(v,k){ check_call(v, k) })).to.not.be.ok()
      expect(keys).to.eql([])
      expect(values).to.eql([]) })

    it('Should short-circuit', function() {
      expect(map.some(data, check_call)).to.be.ok()
      expect(keys.length).to.be(1) })
  })

  describe('λ filter', function() {
    it('Should keep only key/value pairs that pass the predicate', function() {
      var m = map.filter(data, function(v, k) { return k == 'b' })
      expect(m).to.eql({'b': 2}) })

    it('Should return a new map', function() {
      expect(map.filter(data, check_call)).to.not.be(data) })

    it('Should keep only own/enumerable properties', function() {
      var m = map.filter(data, function(v, k) { return k == 'c' })
      expect(m).to.eql({}) })
  })

  describe('λ map', function() {
    it('Should transform all enumerable key/value pairs', function() {
      var m = map.map(data, function(v, k) { return v * 2 })
      expect(m.b).to.be(4)
      expect(m.d).to.be(8) })

    it('Should return a new map', function() {
      var m = expect(map.map(data, check_call)).to.not.be(data) })

    it('Should keep only own/enumerable properties', function() {
      var m = map.map(data, function(v, k){ return k == 'c'? v * 2 : v })
      expect(m.c).to.be(undefined) })
  })

})

<commit_msg>Improves the description for `some/every' specifications.<commit_after>var map = require('../src/collection/map')
var expect = require('expect.js')

function d(value, enumerable) {
  return { value: value
         , enumerable: enumerable === false? false : true
         , configurable: true
         , writable: true }
}

function count() {
  return function _() {
    return _.num = (_.num || 0) + 1 }}

describe('{} collection.map', function() {
  var foo = {a:1}
  var data, keys, values

  function check_call(value, key) {
    var i = keys.indexOf(key)
    expect(i).to.not.be(-1)
    expect(values[i]).to.be(value)
    keys.splice(i, 1)
    values.splice(i, 1)
    return [key, value] }

  beforeEach(function() {
    keys   = ['b', 'd']
    values = [2, 4]
    data   = Object.create(foo, {
      b: d(2),
      c: d(3, false),
      d: d(4) })})

  describe('λ each', function() {
    it('Should apply iterator to every own enumerable property', function() {
      var c = count()
      map.each(data, c)
      expect(c.num).to.be(2) })

    it('Should pass (value, key, map) to the iterator', function() {
      map.each(data, function(v,k,m) {
        expect(m).to.be(data)
        expect(keys).to.contain(k)
        expect(values).to.contain(v) })})
  })

  describe('λ at', function() {
    it('Should retrieve the value for the given key', function() {
      expect(map.at(null, 'foo')).to.be(undefined)
      expect(map.at(data, 'a')).to.be(1)
      expect(map.at(data, 'b')).to.be(2)
      expect(map.at(data, 'c')).to.be(3) })
  })

  describe('λ put', function() {
    it('Should assign a value to the given key', function() {
      expect(map.put(null, 'a', 1)).to.be(null)
      map.put(data, 'b', 3)
      map.put(data, 'e', 4)
      expect(data.b).to.be(3)
      expect(data.e).to.be(4) })
  })

  describe('λ remove', function() {
    it('Should delete the given key from the map', function() {
      expect(map.remove(null, 'a')).to.be(null)
      map.remove(data, 'b')
      expect(map.hasOwnProperty('b')).to.not.be.ok() })
  })

  describe('λ replace', function() {
    it('Should replace all values that match by the given replacement', function() {
      expect(map.replace({a:1,b:2,c:1,d:[1]},1,0)).to.eql({a:0,b:2,c:0,d:[1]})
    })
  })

  describe('λ clear', function() {
    it('Should remove all enumerable keys from the map', function(){
      expect(map.clear(null)).to.be(null)
      map.clear(data)
      expect(data.a).to.be(1)
      expect(data.hasOwnProperty('b')).to.not.be.ok()
      expect(data.hasOwnProperty('c')).to.be.ok()
      expect(data.hasOwnProperty('d')).to.not.be.ok() })
  })

  describe('λ size', function() {
    it('Should return the number of enumerable keys in the map', function() {
      expect(map.size(null)).to.be(0)
      expect(map.size(data)).to.be(2) })
  })

  describe('λ empty_p', function() {
    it('Should check if there\'s any enumerable key in the map', function() {
      expect(map.empty_p(null)).to.be.ok()
      expect(map.empty_p({})).to.be.ok()
      expect(map.empty_p(data)).to.not.be.ok()
      delete data.b
      delete data.d
      expect(map.empty_p(data)).to.be.ok() })
  })

  describe('λ has_key_p', function() {
    it('Should check if the map has the key', function() {
      expect(map.has_key_p(null, 'a')).to.not.be.ok()
      expect(map.has_key_p(data, 'b')).to.be.ok()
      expect(map.has_key_p(data, 'a')).to.not.be.ok()
      expect(map.has_key_p(data, 'c')).to.be.ok() })
  })

  describe('λ keys', function() {
    it('Should return all enumerable keys in the map', function() {
      expect(map.keys(null).length).to.be(0)
      expect(map.keys(data)).to.eql(keys) })
  })

  describe('λ values', function() {
    it('Should return all enumerable values in the map', function() {
      expect(map.values(null).length).to.be(0)
      expect(map.values(data)).to.eql(values) })
  })

  describe('λ items', function() {
    it('Should return all enumerable key/value pairs in the map', function() {
      expect(map.items(null).length).to.be(0)
      expect(map.items(data)).to.eql([['b',2],['d',4]]) })
  })

  describe('λ reduce', function() {
    it('Should apply the function to all key/value pairs in the map', function() {
      map.reduce(data, 0, function(acc, value, key) {
        check_call(value, key) })

      expect(keys).to.eql([])
      expect(values).to.eql([]) })

    it('Should return the accumulated value', function() {
      expect(map.reduce(data, 0, function(acc, value) {
        return acc + value })).to.be(6) })

    it('Should use the first key/value pair as initial value if one isnt given', function() {
      map.reduce(data, function(acc, value) {
        expect(values).to.contain(acc) })})
  })

  describe('λ every', function() {
    it('Should check if all key/value pairs pass the predicate', function() {
      expect(map.every(data, check_call)).to.be.ok()
      expect(keys).to.eql([])
      expect(values).to.eql([]) })

    it('Should short-circuit as soon as the predicate fails', function() {
      var x = true
      var c = 0
      expect(map.every(data, function(acc, value) {
        c++
        return x = !x })).to.not.be.ok()
      expect(c).to.be(1) })
  })

  describe('λ some', function() {
    it('Should check if any key/value pairs pass the predicate', function() {
      expect(map.some(data, function(v,k){ check_call(v, k) })).to.not.be.ok()
      expect(keys).to.eql([])
      expect(values).to.eql([]) })

    it('Should short-circuit as soon as the predicate passes', function() {
      expect(map.some(data, check_call)).to.be.ok()
      expect(keys.length).to.be(1) })
  })

  describe('λ filter', function() {
    it('Should keep only key/value pairs that pass the predicate', function() {
      var m = map.filter(data, function(v, k) { return k == 'b' })
      expect(m).to.eql({'b': 2}) })

    it('Should return a new map', function() {
      expect(map.filter(data, check_call)).to.not.be(data) })

    it('Should keep only own/enumerable properties', function() {
      var m = map.filter(data, function(v, k) { return k == 'c' })
      expect(m).to.eql({}) })
  })

  describe('λ map', function() {
    it('Should transform all enumerable key/value pairs', function() {
      var m = map.map(data, function(v, k) { return v * 2 })
      expect(m.b).to.be(4)
      expect(m.d).to.be(8) })

    it('Should return a new map', function() {
      var m = expect(map.map(data, check_call)).to.not.be(data) })

    it('Should keep only own/enumerable properties', function() {
      var m = map.map(data, function(v, k){ return k == 'c'? v * 2 : v })
      expect(m.c).to.be(undefined) })
  })

})
<|endoftext|>


<commit_before>'use strict';

const fs = require('fs');
const Console = require('console');
const request = require('request');
const path = require('path');
let cloudwatchlogs;
let AWS;

const fileOutput = function(loc, outputs) {
    try {
        fs.appendFileSync(loc, outputs);
    } catch (e) {
        throw new Error('Could not access file, your script may not have permission to the file', e);
    }
};

const elasticOutput = function(endpoint, outputs) {
    const config = {
        uri: endpoint + '/logback',
        method: 'POST',
        body: outputs
    };

    request(config);
};

const cloudWatchOutput = function(logGroupName, logStreamName, outputs) {

    cloudwatchlogs.describeLogStreams({
        logGroupName: logGroupName,
        logStreamNamePrefix: logStreamName
    }, function(err, data) {
        cloudwatchlogs.putLogEvents({
                logGroupName: logGroupName,
                logStreamName: logStreamName,
                sequenceToken: data.nextToken,
                logEvents: [{
                    timestamp: new Date().getTime(),
                    message: outputs
                }]
            },
            function(err, data) {
                if (err) {
                    throw err;
                }
            }
        );
    });

};

const rights = function(requestedLevel, logLevel) {
    if (requestedLevel === 0) {
        return true;
    } else if (requestedLevel === 1) {
        if (logLevel >= 1) {
            return true;
        }
    } else if (requestedLevel === 2) {
        if (logLevel >= 2) {
            return true;
        }
    } else if (requestedLevel === 3) {
        if (logLevel >= 3) {
            return true;
        }
    }
    return false;
};

module.exports = class Logback {
    constructor(app, loc, output) {

        if (app !== undefined && app !== '' && app !== null) {
            this.application = app;
        } else {
            this.application = '';
        }

        if (output !== undefined && output !== '' && output !== null) {
            this.output = output;
        } else {
            this.output = 'json';
        }

        if (loc !== undefined && loc !== '' && loc !== null) {
            //check the quality of the object
            this.loc = loc;
            if (typeof loc === 'object') {
                if (loc.file !== undefined) {
                    if (loc.file.location === undefined || loc.file.level === undefined) {
                        throw new Error('File Location (string) and Level (int) must be defined');
                    }
                }
                if (loc.elastic !== undefined) {
                    if (loc.elastic.endpoint === undefined || loc.elastic.level === undefined) {
                        throw new Error('Elastic endpoint (string) and Level (int) must be defined');
                    }
                }
                if (loc.cloudwatch !== undefined) {
                    if (loc.cloudwatch.level === undefined || loc.cloudwatch.logGroupName === undefined || loc.cloudwatch.logStreamName === undefined || loc.cloudwatch.region === undefined) {
                        throw new Error('Cloudwatch region (string), logGroupName (string), logStreamName (string) and Level (int) must be defined');
                    } else {

                        this.logGroupName = loc.cloudwatch.logGroupName;
                        this.logStreamName = loc.cloudwatch.logStreamName;

                        AWS = require('aws-sdk');
                        AWS.config.update({
                            region: loc.cloudwatch.region,
                            apiVersions: {
                                cloudwatchlogs: '2014-03-28'
                            }
                        });

                        if (loc.cloudwatch.accessKeyId !== undefined) { AWS.config.update({ accessKeyId: loc.cloudwatch.accessKeyId }); }
                        if (loc.cloudwatch.secretAccessKey !== undefined) { AWS.config.update({ secretAccessKey: loc.cloudwatch.secretAccessKey }); }

                        cloudwatchlogs = new AWS.CloudWatchLogs();
                    }
                }
            }
        } else {
            //nothing specified, output to file in root
            this.loc = path.dirname(require.main.filename) + '/output.' + this.output;
        }

    }

    a(message, type, file) {
        let log = {
            date: null,
            type: null,
            message: null,
            file: null
        }; //object
        let outputs = ''; //string

        if (type !== undefined && typeof type === 'number') {
            switch (type) {
                case 1:
                    { log.type = 'info'; break; }
                case 2:
                    { log.type = 'warning'; break; }
                case 3:
                    { log.type = 'error'; break; }
                default:
                    { log.type = type; }
            }
        } else {
            log.type = (type) ? type : 'info';
            type = 1;
        }

        if (message !== undefined) {
            log.message = message;
        } else {
            log.message = '';
        }

        log.date = new Date();

        log.file = (file) ? file : '';

        if (this.application !== undefined) {
            log.app = this.application;
        }

        //what is the output of this log
        if (this.output === 'json') {
            //convert the object to string
            outputs = JSON.stringify(log);
        } else {
            //loop through the log object
            for (let cell in log) {
                //create csv
                outputs += log[cell] + ',';
            }
            //remove the last commor of the line
            outputs = outputs.substring(0, outputs.length - 1);
        }
        //add ending new line
        outputs += '\n';
        //append line to log file

        if (typeof this.loc === 'string') {
            //yes, set the output ot a file
            fileOutput(this.loc, outputs);

        } else if (typeof this.loc === 'object') {
            //advanced output
            //check file system
            if (this.loc.file !== undefined) {
                if (rights(this.loc.file.level, type) === true) {
                    fileOutput(this.loc.file.location, outputs);
                }
            }
            if (this.loc.elastic !== undefined) {
                if (rights(this.loc.elastic.level, type) === true) {
                    elasticOutput(this.loc.elastic.endpoint, outputs);
                }
            }
            if (this.loc.cloudwatch !== undefined) {
                if (rights(this.loc.cloudwatch.level, type) === true) {
                    cloudWatchOutput(this.logGroupName, this.logStreamName, outputs);
                }
            }
            if (this.loc.stdout !== undefined) {
                if (rights(this.loc.stdout.level, type) === true) {
                    process.stdout.write(outputs + '\n');
                }
            }
        }
    }

    l() {
        for (var i = 0; i < arguments.length; i++) {
            Console.log(arguments[i]);
        }
    }

    w() {
        for (var i = 0; i < arguments.length; i++) {
            Console.warn(arguments[i]);
        }
    }

    i() {
        for (var x = 0; x < arguments.length; x++) {
            Console.info(arguments[x]);
        }
    }

    d(obj, opts) {
        Console.dir(obj, opts);
    }
};<commit_msg>swapped cloud watch for sqs<commit_after>'use strict';

const fs = require('fs');
const Console = require('console');
const request = require('request');
const path = require('path');
let sqs;
let AWS;

const fileOutput = function(loc, outputs) {
    try {
        fs.appendFileSync(loc, outputs);
    } catch (e) {
        throw new Error('Could not access file, your script may not have permission to the file', e);
    }
};

const elasticOutput = function(endpoint, outputs) {
    const config = {
        uri: endpoint + '/logback',
        method: 'POST',
        body: outputs
    };

    request(config);
};

const sqsOutput = function(QueueUrl, outputs) {

    sqs.sendMessage({
            QueueUrl: QueueUrl,
            MessageBody: outputs
        },
        function(err, data) {
            if (err) {
                throw err;
            }
        }
    );
};

const rights = function(requestedLevel, logLevel) {
    if (requestedLevel === 0) {
        return true;
    } else if (requestedLevel === 1) {
        if (logLevel >= 1) {
            return true;
        }
    } else if (requestedLevel === 2) {
        if (logLevel >= 2) {
            return true;
        }
    } else if (requestedLevel === 3) {
        if (logLevel >= 3) {
            return true;
        }
    }
    return false;
};

module.exports = class Logback {
    constructor(app, loc, output) {

        if (app !== undefined && app !== '' && app !== null) {
            this.application = app;
        } else {
            this.application = '';
        }

        if (output !== undefined && output !== '' && output !== null) {
            this.output = output;
        } else {
            this.output = 'json';
        }

        if (loc !== undefined && loc !== '' && loc !== null) {
            //check the quality of the object
            this.loc = loc;
            if (typeof loc === 'object') {
                if (loc.file !== undefined) {
                    if (loc.file.location === undefined || loc.file.level === undefined) {
                        throw new Error('File Location (string) and Level (int) must be defined');
                    }
                }
                if (loc.elastic !== undefined) {
                    if (loc.elastic.endpoint === undefined || loc.elastic.level === undefined) {
                        throw new Error('Elastic endpoint (string) and Level (int) must be defined');
                    }
                }
                if (loc.sqs !== undefined) {
                    if (loc.sqs.level === undefined || loc.sqs.queueUrl === undefined || loc.sqs.region === undefined) {
                        throw new Error('SQS region (string), logGroupName (string), logStreamName (string) and Level (int) must be defined');
                    } else {

                        this.QueueUrl = loc.sqs.queueUrl;

                        AWS = require('aws-sdk');
                        AWS.config.update({
                            region: loc.sqs.region
                        });

                        if (loc.sqs.accessKeyId !== undefined) { AWS.config.update({ accessKeyId: loc.sqs.accessKeyId }); }
                        if (loc.sqs.secretAccessKey !== undefined) { AWS.config.update({ secretAccessKey: loc.sqs.secretAccessKey }); }

                        sqs = new AWS.SQS();
                    }
                }
            }
        } else {
            //nothing specified, output to file in root
            this.loc = path.dirname(require.main.filename) + '/output.' + this.output;
        }

    }

    a(message, type, file) {
        let log = {
            date: null,
            type: null,
            message: null,
            file: null
        }; //object
        let outputs = ''; //string

        if (type !== undefined && typeof type === 'number') {
            switch (type) {
                case 1:
                    { log.type = 'info'; break; }
                case 2:
                    { log.type = 'warning'; break; }
                case 3:
                    { log.type = 'error'; break; }
                default:
                    { log.type = type; }
            }
        } else {
            log.type = (type) ? type : 'info';
            type = 1;
        }

        if (message !== undefined) {
            log.message = message;
        } else {
            log.message = '';
        }

        log.date = new Date();

        log.file = (file) ? file : '';

        if (this.application !== undefined) {
            log.app = this.application;
        }

        //what is the output of this log
        if (this.output === 'json') {
            //convert the object to string
            outputs = JSON.stringify(log);
        } else {
            //loop through the log object
            for (let cell in log) {
                //create csv
                outputs += log[cell] + ',';
            }
            //remove the last commor of the line
            outputs = outputs.substring(0, outputs.length - 1);
        }
        //add ending new line
        outputs += '\n';
        //append line to log file

        if (typeof this.loc === 'string') {
            //yes, set the output ot a file
            fileOutput(this.loc, outputs);

        } else if (typeof this.loc === 'object') {
            //advanced output
            //check file system
            if (this.loc.file !== undefined) {
                if (rights(this.loc.file.level, type) === true) {
                    fileOutput(this.loc.file.location, outputs);
                }
            }
            if (this.loc.elastic !== undefined) {
                if (rights(this.loc.elastic.level, type) === true) {
                    elasticOutput(this.loc.elastic.endpoint, outputs);
                }
            }
            if (this.loc.sqs !== undefined) {
                if (rights(this.loc.sqs.level, type) === true) {
                    sqsOutput(this.QueueUrl, outputs);
                }
            }
            if (this.loc.stdout !== undefined) {
                if (rights(this.loc.stdout.level, type) === true) {
                    process.stdout.write(outputs + '\n');
                }
            }
        }
    }

    l() {
        for (var i = 0; i < arguments.length; i++) {
            Console.log(arguments[i]);
        }
    }

    w() {
        for (var i = 0; i < arguments.length; i++) {
            Console.warn(arguments[i]);
        }
    }

    i() {
        for (var x = 0; x < arguments.length; x++) {
            Console.info(arguments[x]);
        }
    }

    d(obj, opts) {
        Console.dir(obj, opts);
    }
};<|endoftext|>


<commit_before>"use strict";

var fs = require('fs');
var path = require('path');

var execFile = require('child_process').execFile;
var async = require('async');
var tempfile = require('tempfile');

function Optimizer(param) {
  this.options = param.options || {};
  this.src = param.src;
  this.tmp = tempfile(path.extname(this.src));
  this.dest = param.dest || this.src;
  this.extension = path.extname(this.src);
  this.optimizers = this.getOptimizers(this.extension);

  // copy src file to tmp
  fs.writeFileSync(this.tmp, fs.readFileSync(this.src));
}

Optimizer.prototype.optipng = function () {
  var args = [];
  args.push('-i 1');
  args.push('-strip all');
  args.push('-fix');
  args.push('-o7');
  args.push('-force');
  args.push(this.tmp);

  return {
    name: 'optipng',
    path: require('optipng-bin').path,
    args: args
  };
};

Optimizer.prototype.pngquant = function () {
  var args = [];
  args.push('--ext=.png');
  args.push('--speed=1');
  args.push('--force');
  args.push('256');
  args.push(this.tmp);

  return {
    name: 'pngquant',
    path: require('pngquant-bin').path,
    args: args
  };
};

Optimizer.prototype.advpng = function () {
  var args = [];
  args.push('--recompress');
  args.push('--shrink-extra');
  args.push(this.tmp);

  return {
    name: 'advpng',
    path: require('advpng-bin').path,
    args: args
  };
};

Optimizer.prototype.pngcrush = function () {
  var args = [];
  args.push('-rem alla');
  args.push('-rem text');
  args.push('-brute');
  args.push('-reduce');
  args.push(this.tmp);

  return {
    name: 'pngcrush',
    path: require('pngcrush-bin').path,
    args: args
  };
};

Optimizer.prototype.pngout = function () {
  var args = [];
  args.push('-s0');
  args.push('-k0');
  args.push('-f0');
  args.push(this.tmp);
  args.push(this.tmp);

  return {
    name: 'pngout',
    path: require('pngout-bin').path,
    args: args
  };
};

Optimizer.prototype.zopflipng = function () {
  var args = [];
  args.push('-m');
  args.push('--iterations=500');
  args.push('--splitting=3');
  args.push('--filters=01234mepb');
  args.push('--lossy_8bit');
  args.push('--lossy_transparent');
  args.push(this.tmp);

  return {
    name: 'zopflipng',
    path: require('zopflipng-bin').path,
    args: args
  };
};

Optimizer.prototype.gifsicle = function () {
  var args = [];
  //args.push('--careful');
  //args.push('--interlace');
  args.push('--optimize');
  args.push('--output');
  args.push(this.tmp);
  args.push(this.tmp);

  return {
    name: 'gifsicle',
    path: require('gifsicle').path,
    args: args
  };
};

Optimizer.prototype.jpegtran = function () {
  var args = [];
  args.push('-optimize');
  args.push('-progressive');
  args.push('-outfile ' + this.tmp);
  args.push(this.tmp);

  return {
    name: 'jpegtran',
    path: require('jpegtran-bin').path,
    args: args
  };
};

Optimizer.prototype.jpegRecompress = function () {
  var args = [];
  args.push('--progressive');
  args.push('--strip');
  args.push('--quality medium');
  args.push('--min 40');
  args.push('--max 80');
  args.push(this.tmp);
  args.push(this.tmp);

  return {
    name: 'jpeg-recompress',
    path: require('jpeg-recompress-bin').path,
    args: args
  };
};

Optimizer.prototype.jpegoptim = function () {
  var args = [];
  args.push('--override');
  args.push('--strip-all');
  args.push('--strip-iptc');
  args.push('--strip-icc');
  args.push('--all-progressive');
  args.push(this.tmp);

  return {
    name: 'jpegoptim',
    path: require('jpegoptim-bin').path,
    args: args
  };
};

Optimizer.prototype.mozjpeg = function () {
  var args = [];
  args.push('-optimize');
  args.push('-progressive');
  //args.push('-outfile ' + this.tmp);
  args.push(this.tmp);

  return {
    name: 'mozjpeg',
    path: require('mozjpeg').path,
    args: args
  };
};

Optimizer.prototype.svgo = function () {
  var args = [];
  args.push(this.tmp);
  args.push(this.tmp);

  return {
    name: 'svgo',
    path: './node_modules/svgo/bin/svgo',
    args: args
  };
};

Optimizer.prototype.getOptimizers = function (extension) {
  var optimizers = [];
  extension = extension.toLowerCase();
  switch (extension) {
    case '.png':
      if (this.options.optipng) {
        optimizers.push(this.optipng());
      }
      if (this.options.pngquant) {
        optimizers.push(this.pngquant());
      }
      if (this.options.zopflipng) {
        optimizers.push(this.zopflipng());
      }
      if (this.options.pngcrush) {
        optimizers.push(this.pngcrush());
      }
      if (this.options.advpng) {
        optimizers.push(this.advpng());
      }
      //if (this.options.pngout) {
      //  optimizers.push(this.pngout());
      //}
      break;
    case '.jpg':
      //if (this.options.jpegtran) {
      //  optimizers.push(this.jpegtran());
      //}
      if (this.options.jpegRecompress) {
        optimizers.push(this.jpegRecompress());
      }
      if (this.options.jpegoptim) {
        optimizers.push(this.jpegoptim());
      }
      if (this.options.mozjpeg) {
        optimizers.push(this.mozjpeg());
      }
      break;
    case '.gif':
      if (this.options.gifsicle) {
        optimizers.push(this.gifsicle());
      }
      break;
    case '.svg':
      if (this.options.svgo) {
        optimizers.push(this.svgo());
      }
      break;
  }
  return optimizers;
};

// @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round
function _round10 (value, exp) {
  // If the exp is undefined or zero...
  if (typeof exp === 'undefined' || +exp === 0) {
    return Math.round(value);
  }
  value = +value;
  exp = +exp;
  // If the value is not a number or the exp is not an integer...
  if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
    return NaN;
  }
  // Shift
  value = value.toString().split('e');
  value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));
  // Shift back
  value = value.toString().split('e');
  return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
}

Optimizer.prototype.optimize = function (callback) {

  var src = this.src;
  var tmp = this.tmp;
  var dest = this.dest;

  var fns = this.optimizers.map(function (optimizer) {
    return function (callback) {
      execFile(optimizer.path, optimizer.args, function () {
        callback(null, optimizer.name);
      });
    };
  });

  async.series(fns, function (error, result) {

    var isOptimized = null;
    var originalSize = fs.statSync(src).size;
    var optimizedSize = fs.statSync(tmp).size;
    var diffSize = originalSize - optimizedSize;

    if (diffSize > 0) {
      // optimized size is smaller
      isOptimized = true;
      fs.writeFileSync(dest, fs.readFileSync(tmp));
      fs.unlinkSync(tmp);
    } else {
      // original size is smaller
      isOptimized = false;
      fs.writeFileSync(dest, fs.readFileSync(src));
      fs.unlinkSync(tmp);
    }

    callback(error, {
      isOptimized: isOptimized,
      originalSize: originalSize,
      optimizedSize: optimizedSize,
      diffSize: diffSize,
      diffPercent: _round10(100 * (diffSize / originalSize), -1)
    });
  });
};

module.exports = Optimizer;
<commit_msg>pngquant quality 80-1000<commit_after>"use strict";

var fs = require('fs');
var path = require('path');

var execFile = require('child_process').execFile;
var async = require('async');
var tempfile = require('tempfile');

function Optimizer(param) {
  this.options = param.options || {};
  this.src = param.src;
  this.tmp = tempfile(path.extname(this.src));
  this.dest = param.dest || this.src;
  this.extension = path.extname(this.src);
  this.optimizers = this.getOptimizers(this.extension);

  // copy src file to tmp
  fs.writeFileSync(this.tmp, fs.readFileSync(this.src));
}

Optimizer.prototype.optipng = function () {
  var args = [];
  args.push('-i 1');
  args.push('-strip all');
  args.push('-fix');
  args.push('-o7');
  args.push('-force');
  args.push(this.tmp);

  return {
    name: 'optipng',
    path: require('optipng-bin').path,
    args: args
  };
};

Optimizer.prototype.pngquant = function () {
  var args = [];
  args.push('--ext=.png');
  args.push('--speed=1');
  args.push('--force');
  args.push('--quality=80-100');
  args.push('256');
  args.push(this.tmp);

  return {
    name: 'pngquant',
    path: require('pngquant-bin').path,
    args: args
  };
};

Optimizer.prototype.advpng = function () {
  var args = [];
  args.push('--recompress');
  args.push('--shrink-extra');
  args.push(this.tmp);

  return {
    name: 'advpng',
    path: require('advpng-bin').path,
    args: args
  };
};

Optimizer.prototype.pngcrush = function () {
  var args = [];
  args.push('-rem alla');
  args.push('-rem text');
  args.push('-brute');
  args.push('-reduce');
  args.push(this.tmp);

  return {
    name: 'pngcrush',
    path: require('pngcrush-bin').path,
    args: args
  };
};

Optimizer.prototype.pngout = function () {
  var args = [];
  args.push('-s0');
  args.push('-k0');
  args.push('-f0');
  args.push(this.tmp);
  args.push(this.tmp);

  return {
    name: 'pngout',
    path: require('pngout-bin').path,
    args: args
  };
};

Optimizer.prototype.zopflipng = function () {
  var args = [];
  args.push('-m');
  args.push('--iterations=500');
  args.push('--splitting=3');
  args.push('--filters=01234mepb');
  args.push('--lossy_8bit');
  args.push('--lossy_transparent');
  args.push(this.tmp);

  return {
    name: 'zopflipng',
    path: require('zopflipng-bin').path,
    args: args
  };
};

Optimizer.prototype.gifsicle = function () {
  var args = [];
  //args.push('--careful');
  //args.push('--interlace');
  args.push('--optimize');
  args.push('--output');
  args.push(this.tmp);
  args.push(this.tmp);

  return {
    name: 'gifsicle',
    path: require('gifsicle').path,
    args: args
  };
};

Optimizer.prototype.jpegtran = function () {
  var args = [];
  args.push('-optimize');
  args.push('-progressive');
  args.push('-outfile ' + this.tmp);
  args.push(this.tmp);

  return {
    name: 'jpegtran',
    path: require('jpegtran-bin').path,
    args: args
  };
};

Optimizer.prototype.jpegRecompress = function () {
  var args = [];
  args.push('--progressive');
  args.push('--strip');
  args.push('--quality medium');
  args.push('--min 40');
  args.push('--max 80');
  args.push(this.tmp);
  args.push(this.tmp);

  return {
    name: 'jpeg-recompress',
    path: require('jpeg-recompress-bin').path,
    args: args
  };
};

Optimizer.prototype.jpegoptim = function () {
  var args = [];
  args.push('--override');
  args.push('--strip-all');
  args.push('--strip-iptc');
  args.push('--strip-icc');
  args.push('--all-progressive');
  args.push(this.tmp);

  return {
    name: 'jpegoptim',
    path: require('jpegoptim-bin').path,
    args: args
  };
};

Optimizer.prototype.mozjpeg = function () {
  var args = [];
  args.push('-optimize');
  args.push('-progressive');
  //args.push('-outfile ' + this.tmp);
  args.push(this.tmp);

  return {
    name: 'mozjpeg',
    path: require('mozjpeg').path,
    args: args
  };
};

Optimizer.prototype.svgo = function () {
  var args = [];
  args.push(this.tmp);
  args.push(this.tmp);

  return {
    name: 'svgo',
    path: './node_modules/svgo/bin/svgo',
    args: args
  };
};

Optimizer.prototype.getOptimizers = function (extension) {
  var optimizers = [];
  extension = extension.toLowerCase();
  switch (extension) {
    case '.png':
      if (this.options.optipng) {
        optimizers.push(this.optipng());
      }
      if (this.options.pngquant) {
        optimizers.push(this.pngquant());
      }
      if (this.options.zopflipng) {
        optimizers.push(this.zopflipng());
      }
      if (this.options.pngcrush) {
        optimizers.push(this.pngcrush());
      }
      if (this.options.advpng) {
        optimizers.push(this.advpng());
      }
      //if (this.options.pngout) {
      //  optimizers.push(this.pngout());
      //}
      break;
    case '.jpg':
      //if (this.options.jpegtran) {
      //  optimizers.push(this.jpegtran());
      //}
      if (this.options.jpegRecompress) {
        optimizers.push(this.jpegRecompress());
      }
      if (this.options.jpegoptim) {
        optimizers.push(this.jpegoptim());
      }
      if (this.options.mozjpeg) {
        optimizers.push(this.mozjpeg());
      }
      break;
    case '.gif':
      if (this.options.gifsicle) {
        optimizers.push(this.gifsicle());
      }
      break;
    case '.svg':
      if (this.options.svgo) {
        optimizers.push(this.svgo());
      }
      break;
  }
  return optimizers;
};

// @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round
function _round10 (value, exp) {
  // If the exp is undefined or zero...
  if (typeof exp === 'undefined' || +exp === 0) {
    return Math.round(value);
  }
  value = +value;
  exp = +exp;
  // If the value is not a number or the exp is not an integer...
  if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
    return NaN;
  }
  // Shift
  value = value.toString().split('e');
  value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));
  // Shift back
  value = value.toString().split('e');
  return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
}

Optimizer.prototype.optimize = function (callback) {

  var src = this.src;
  var tmp = this.tmp;
  var dest = this.dest;

  var fns = this.optimizers.map(function (optimizer) {
    return function (callback) {
      execFile(optimizer.path, optimizer.args, function () {
        callback(null, optimizer.name);
      });
    };
  });

  async.series(fns, function (error, result) {

    var isOptimized = null;
    var originalSize = fs.statSync(src).size;
    var optimizedSize = fs.statSync(tmp).size;
    var diffSize = originalSize - optimizedSize;

    if (diffSize > 0) {
      // optimized size is smaller
      isOptimized = true;
      fs.writeFileSync(dest, fs.readFileSync(tmp));
      fs.unlinkSync(tmp);
    } else {
      // original size is smaller
      isOptimized = false;
      fs.writeFileSync(dest, fs.readFileSync(src));
      fs.unlinkSync(tmp);
    }

    callback(error, {
      isOptimized: isOptimized,
      originalSize: originalSize,
      optimizedSize: optimizedSize,
      diffSize: diffSize,
      diffPercent: _round10(100 * (diffSize / originalSize), -1)
    });
  });
};

module.exports = Optimizer;
<|endoftext|>


<commit_before>var _         = require('underscore'),
    Clearwing = require('../lib/clearwing.js'),
    should    = require('should');

var client,
    string = 'network.foo channel.#bar bah baz',
    array  = [ { network: 'foo' }, { channel: '#bar' }, 'bah', 'baz' ];

describe('Clearwing', function() {
	describe('.stringifyPropName', function() {
		it('should parse an array that matches string', function() {
			Clearwing.stringifyPropName(array).should.equal(string);
		});
	});

	describe('.parsePropName', function() {
		it('should parse a string that matches array', function() {
			Clearwing.parsePropName(string).should.eql(array);
		});
	});

	before(function() {
		client = new Clearwing();
	});

	describe('#get and #set', function() {
		it('should return undefined for undefined properties', function() {
			should.strictEqual(undefined, client.get('foo'));
			should.notStrictEqual(null, client.get('foo'));
		});

		it('should let you set and retrieve values', function() {
			client.set('foo', 'bar');
			client.get('foo').should.equal('bar');
		});
	});

	describe('#on', function() {
		it('sets Clearwing#_events[event]', function() {
			var fn = function() {};
			client.on('foo', fn);
			client._events['foo'].should.eql([ fn ]);
		});
	});

	describe('#emit', function() {
		it('should work', function(done) {
			client._events['test'] = [ function() { done(); } ];
			client.emit('test', 'foo');
		});

		it('should thrown an error if fewer than two arguments are supplied', function() {
			_.bind(client.emit, client, 'foo').should.throw('#emit() expects at least two arguments');
		});
	});
});
<commit_msg>Fix tests<commit_after>var _         = require('underscore'),
    Clearwing = require('../lib/clearwing.js'),
    should    = require('should');

var client,
    string = 'network.foo channel.#bar bah baz',
    array  = [ { network: 'foo' }, { channel: '#bar' }, 'bah', 'baz' ];

describe('Clearwing', function() {
	describe('.stringifyPropName', function() {
		it('should parse an array that matches string', function() {
			Clearwing.stringifyPropName(array).should.equal(string);
		});
	});

	describe('.parsePropName', function() {
		it('should parse a string that matches array', function() {
			Clearwing.parsePropName(string).should.eql(array);
		});
	});

	before(function() {
		client = new Clearwing();
	});

	describe('#get and #set', function() {
		it('should return undefined for undefined properties', function() {
			should.strictEqual(undefined, client.get('foo'));
			should.notStrictEqual(null, client.get('foo'));
		});

		it('should let you set and retrieve values', function() {
			client.set('foo', 'bar');
			client.get('foo').should.equal('bar');
		});
	});

	describe('#on', function() {
		it('sets Clearwing#_events[event]', function() {
			var fn = function() {};
			client.on('foo', fn);
			client._events['foo'].should.eql([ fn ]);
		});
	});

	describe('#emit', function() {
		it('should work', function(done) {
			client._events['test'] = [ function() { done(); } ];
			client.emit('test', {});
		});

		it('should thrown an error if fewer than two arguments are supplied', function() {
			_.bind(client.emit, client, 'foo').should.throw('#emit() expects at least two arguments');
		});
	});
});
<|endoftext|>