<commit_before>var test = require('tape');
var testSetup = require('redtape');
var temp = require('temp');
var fs   = require('fs');
var path = require('path');
var utils = require('./../lib/utils');
var DecompressZip = require('decompress-zip');
var _ = require('lodash');
var EventEmitter = require('events').EventEmitter;
var del = require('rimraf');

test('getPackageInfo invalid', function (t) {
    t.plan(1);
    utils.getPackageInfo('./test/fixtures/invalid.json').catch(function (error) {
        t.ok(error);
    });
});

test('getPackageInfo valid', function (t) {
    t.plan(2);
    var pkg = utils.getPackageInfo('./test/fixtures/nwapp/package.json').then(function (pkg) {
        t.equal(pkg.name, 'nw-demo', 'get package name');
        t.equal(pkg.version, '0.1.0', 'get package version');
    });

});

test('editPlist', function (t) {
    t.plan(1);
    temp.open('plstest', function(err, info) {
        utils.editPlist('./test/fixtures/Info.plist', info.path, utils.getPlistOptions(
            {
                name: 'TestApp',
                version: '1.3.3.7',
                copyright: '(c) by me'
            },
            {
                CFBundleDisplayName: "My cool TestApp",
                LSEnvironment: {
                    PATH: '/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin'
                }
            }
        )).then(function () {
            var actual   = fs.readFileSync(info.path).toString().replace(/\r|\n/gm, '');
            var expected = fs.readFileSync('./test/expected/Info.plist').toString().replace(/\r|\n/gm, '');
            t.equal(actual, expected, 'generate and write a valid plist file');
            t.end();
        });

    });

});

test('getFileList', function (t) {
    t.plan(5);

    utils.getFileList('./test/fixtures/nwapp/**').then(function(data) {
        t.equal(data.json, path.normalize('test/fixtures/nwapp/package.json'), 'figure out the right json');
        var expected = [{
            "src" : path.normalize("test/fixtures/nwapp/images/imagefile.img"),
            "dest": path.normalize("images/imagefile.img")
        }, {
            "src" : path.normalize("test/fixtures/nwapp/index.html"),
            "dest": path.normalize("index.html")
        }, {
            "src" : path.normalize("test/fixtures/nwapp/javascript/bower_packages/simple/package.json"),
            "dest": path.normalize("javascript/bower_packages/simple/package.json")
        }, {
            "src" : path.normalize("test/fixtures/nwapp/javascript/jsfile.js"),
            "dest": path.normalize("javascript/jsfile.js")
        }, {
            "src" : path.normalize("test/fixtures/nwapp/node_modules/package/package.json"),
            "dest": path.normalize("node_modules/package/package.json")
        }, {
            "src" : path.normalize("test/fixtures/nwapp/package.json"),
            "dest": path.normalize("package.json")
        }];
        t.deepEqual(data.files, expected);
    });

    utils.getFileList('./test/fixtures/nwapp/images/**').then(function(data) {
    }, function (error) {
        t.equal(error, 'Could not find a package.json in your src folder', 'throw an error if there is no package json');
    });

    utils.getFileList('./test/fixtures/nwapp/images/*.js').then(function(data) {
    }, function (error) {
        t.equal(error, 'No files matching');
    });

    utils.getFileList(['./test/fixtures/nwapp/**/*', '!./test/fixtures/nwapp/node_modules/**/*',  '!./test/fixtures/nwapp/javascript/**/*']).then(function(data) {
        var expected = [{
            "src" : path.normalize("test/fixtures/nwapp/images/imagefile.img"),
            "dest": path.normalize("images/imagefile.img")
        }, {
            "src" : path.normalize("test/fixtures/nwapp/index.html"),
            "dest": path.normalize("index.html")
        }, {
            "src" : path.normalize("test/fixtures/nwapp/package.json"),
            "dest": path.normalize("package.json")
        }];
        t.deepEqual(data.files, expected);
    });

});

test('should zip the app and create the app.nw file + log it', function (t) {
    t.plan(6);

    var files = [{
        "src" : path.normalize("test/fixtures/nwapp/images/imagefile.img"),
        "dest": path.normalize("images/imagefile.img")
    }, {
        "src" : path.normalize("test/fixtures/nwapp/javascript/bower_packages/simple/package.json"),
        "dest": path.normalize("javascript/bower_packages/simple/package.json")
    }, {
        "src" : path.normalize("test/fixtures/nwapp/javascript/jsfile.js"),
        "dest": path.normalize("javascript/jsfile.js")
    }, {
        "src" : path.normalize("test/fixtures/nwapp/node_modules/package/package.json"),
        "dest": path.normalize("node_modules/package/package.json")
    }, {
        "src" : path.normalize("test/fixtures/nwapp/package.json"),
        "dest": path.normalize("package.json")
    }], expected = _.pluck(files, 'dest');

    var _evt = new EventEmitter();
    _evt.on('log', function (logging) {
        t.ok(logging, 'LOG: ' + logging);
    });

    utils.generateZipFile(files, _evt).then(function(nwfile) {
        var unzipper = new DecompressZip(nwfile);
        unzipper.on('list', function (files) {
            t.deepEqual(expected, files);
        });
        unzipper.list();
    });

});

testSetup({
    afterEach: function(done){
        del('./test/temp/platform-specific-unzipped', done);
    }
})('should zip but use platform-specific manifest with overrides in package.json', function (t) {
    t.plan(3);

    var files = [{
        "src" : path.normalize("test/fixtures/nwapp/images/imagefile.img"),
        "dest": path.normalize("images/imagefile.img")
    }, {
        "src" : path.normalize("test/fixtures/nwapp/package.json"),
        "dest": path.normalize("package.json")
    }], expectedPackage = "{hello: 'world'}";

    var _evt = new EventEmitter();
    _evt.on('log', function (logging) {
        t.ok(logging, 'LOG: ' + logging);
    });

    utils.generateZipFile(files, _evt, expectedPackage).then(function(nwfile) {
        var unzipper = new DecompressZip(nwfile),
            unzipDestination = 'test/temp/platform-specific-unzipped';

        unzipper.on('extract', function (log) {
            t.equal(fs.readFileSync(path.join(unzipDestination, 'package.json')).toString(), expectedPackage);
            t.end();
        });

        unzipper.extract({
            path: unzipDestination
        });
    });

});

test('mergeFiles', function (t) {
    t.plan(2);

    var releasefile = temp.openSync();
    fs.writeFileSync(releasefile.path, 'A');

    var zipFile = temp.openSync();
    fs.writeFileSync(zipFile.path, 'B');

    utils.mergeFiles(releasefile.path, zipFile.path, '0755').then(function() {
        var contents = fs.readFileSync(releasefile.path);
        var stats    = fs.lstatSync(releasefile.path);
        t.equal(contents.toString(), 'AB', 'merge two files');
        t.equal(stats.mode.toString(8), '100755', 'fix the permission'); // DOES NOT WORK ON WINDOWS
    });

});
<commit_msg>Fixed zip-app test failing sometimes<commit_after>var test = require('tape');
var testSetup = require('redtape');
var temp = require('temp');
var fs   = require('fs');
var path = require('path');
var utils = require('./../lib/utils');
var DecompressZip = require('decompress-zip');
var _ = require('lodash');
var EventEmitter = require('events').EventEmitter;
var del = require('rimraf');

test('getPackageInfo invalid', function (t) {
    t.plan(1);
    utils.getPackageInfo('./test/fixtures/invalid.json').catch(function (error) {
        t.ok(error);
    });
});

test('getPackageInfo valid', function (t) {
    t.plan(2);
    var pkg = utils.getPackageInfo('./test/fixtures/nwapp/package.json').then(function (pkg) {
        t.equal(pkg.name, 'nw-demo', 'get package name');
        t.equal(pkg.version, '0.1.0', 'get package version');
    });

});

test('editPlist', function (t) {
    t.plan(1);
    temp.open('plstest', function(err, info) {
        utils.editPlist('./test/fixtures/Info.plist', info.path, utils.getPlistOptions(
            {
                name: 'TestApp',
                version: '1.3.3.7',
                copyright: '(c) by me'
            },
            {
                CFBundleDisplayName: "My cool TestApp",
                LSEnvironment: {
                    PATH: '/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin'
                }
            }
        )).then(function () {
            var actual   = fs.readFileSync(info.path).toString().replace(/\r|\n/gm, '');
            var expected = fs.readFileSync('./test/expected/Info.plist').toString().replace(/\r|\n/gm, '');
            t.equal(actual, expected, 'generate and write a valid plist file');
            t.end();
        });

    });

});

test('getFileList', function (t) {
    t.plan(5);

    utils.getFileList('./test/fixtures/nwapp/**').then(function(data) {
        t.equal(data.json, path.normalize('test/fixtures/nwapp/package.json'), 'figure out the right json');
        var expected = [{
            "src" : path.normalize("test/fixtures/nwapp/images/imagefile.img"),
            "dest": path.normalize("images/imagefile.img")
        }, {
            "src" : path.normalize("test/fixtures/nwapp/index.html"),
            "dest": path.normalize("index.html")
        }, {
            "src" : path.normalize("test/fixtures/nwapp/javascript/bower_packages/simple/package.json"),
            "dest": path.normalize("javascript/bower_packages/simple/package.json")
        }, {
            "src" : path.normalize("test/fixtures/nwapp/javascript/jsfile.js"),
            "dest": path.normalize("javascript/jsfile.js")
        }, {
            "src" : path.normalize("test/fixtures/nwapp/node_modules/package/package.json"),
            "dest": path.normalize("node_modules/package/package.json")
        }, {
            "src" : path.normalize("test/fixtures/nwapp/package.json"),
            "dest": path.normalize("package.json")
        }];
        t.deepEqual(data.files, expected);
    });

    utils.getFileList('./test/fixtures/nwapp/images/**').then(function(data) {
    }, function (error) {
        t.equal(error, 'Could not find a package.json in your src folder', 'throw an error if there is no package json');
    });

    utils.getFileList('./test/fixtures/nwapp/images/*.js').then(function(data) {
    }, function (error) {
        t.equal(error, 'No files matching');
    });

    utils.getFileList(['./test/fixtures/nwapp/**/*', '!./test/fixtures/nwapp/node_modules/**/*',  '!./test/fixtures/nwapp/javascript/**/*']).then(function(data) {
        var expected = [{
            "src" : path.normalize("test/fixtures/nwapp/images/imagefile.img"),
            "dest": path.normalize("images/imagefile.img")
        }, {
            "src" : path.normalize("test/fixtures/nwapp/index.html"),
            "dest": path.normalize("index.html")
        }, {
            "src" : path.normalize("test/fixtures/nwapp/package.json"),
            "dest": path.normalize("package.json")
        }];
        t.deepEqual(data.files, expected);
    });

});

test('should zip the app and create the app.nw file + log it', function (t) {
    t.plan(6);

    var files = [{
        "src" : path.normalize("test/fixtures/nwapp/images/imagefile.img"),
        "dest": path.normalize("images/imagefile.img")
    }, {
        "src" : path.normalize("test/fixtures/nwapp/javascript/bower_packages/simple/package.json"),
        "dest": path.normalize("javascript/bower_packages/simple/package.json")
    }, {
        "src" : path.normalize("test/fixtures/nwapp/javascript/jsfile.js"),
        "dest": path.normalize("javascript/jsfile.js")
    }, {
        "src" : path.normalize("test/fixtures/nwapp/node_modules/package/package.json"),
        "dest": path.normalize("node_modules/package/package.json")
    }, {
        "src" : path.normalize("test/fixtures/nwapp/package.json"),
        "dest": path.normalize("package.json")
    }], expected = _.pluck(files, 'dest').sort();

    var _evt = new EventEmitter();
    _evt.on('log', function (logging) {
        t.ok(logging, 'LOG: ' + logging);
    });

    utils.generateZipFile(files, _evt).then(function(nwfile) {
        var unzipper = new DecompressZip(nwfile);
        unzipper.on('list', function (files) {
            t.deepEqual(expected, files.sort());
        });
        unzipper.list();
    });

});

testSetup({
    afterEach: function(done){
        del('./test/temp/platform-specific-unzipped', done);
    }
})('should zip but use platform-specific manifest with overrides in package.json', function (t) {
    t.plan(3);

    var files = [{
        "src" : path.normalize("test/fixtures/nwapp/images/imagefile.img"),
        "dest": path.normalize("images/imagefile.img")
    }, {
        "src" : path.normalize("test/fixtures/nwapp/package.json"),
        "dest": path.normalize("package.json")
    }], expectedPackage = "{hello: 'world'}";

    var _evt = new EventEmitter();
    _evt.on('log', function (logging) {
        t.ok(logging, 'LOG: ' + logging);
    });

    utils.generateZipFile(files, _evt, expectedPackage).then(function(nwfile) {
        var unzipper = new DecompressZip(nwfile),
            unzipDestination = 'test/temp/platform-specific-unzipped';

        unzipper.on('extract', function (log) {
            t.equal(fs.readFileSync(path.join(unzipDestination, 'package.json')).toString(), expectedPackage);
            t.end();
        });

        unzipper.extract({
            path: unzipDestination
        });
    });

});

test('mergeFiles', function (t) {
    t.plan(2);

    var releasefile = temp.openSync();
    fs.writeFileSync(releasefile.path, 'A');

    var zipFile = temp.openSync();
    fs.writeFileSync(zipFile.path, 'B');

    utils.mergeFiles(releasefile.path, zipFile.path, '0755').then(function() {
        var contents = fs.readFileSync(releasefile.path);
        var stats    = fs.lstatSync(releasefile.path);
        t.equal(contents.toString(), 'AB', 'merge two files');
        t.equal(stats.mode.toString(8), '100755', 'fix the permission'); // DOES NOT WORK ON WINDOWS
    });

});
<|endoftext|>


<commit_before>var tls = require('tls');
var _ = require('underscore');

function SenderApns(objectCert, production) {

    this.host = 'gateway.push.apple.com';
    this.objectCert = objectCert;
    this.resultArray = [];
    this.callsuccess = null;
    this.callsuccess = null;
    this.notifications = null;
    this.reconnectTry = 0;
    this.tokens = [];
    this.tlsStream = null;

    if (!production) {
        this.host = 'gateway.sandbox.push.apple.com';
    }

}

SenderApns.prototype.sendThroughApns = function (notifications, tokens, callsuccess, callerror) {

    var self = this;
    self.notifications = notifications;
    self.tokens = tokens;
    self.callsuccess = callsuccess;
    self.callerror = callerror;
    if (!this.isInputValid()) {
        return;
    }

    //set last notification to fail
    notifications.push({expiry : 30000, payload : {}, _id : "007"});
    tokens.push("aaa111");

    self.newConnection(function (tlsStream) {
        self.tlsStream = tlsStream;
        _.each(notifications, function (notification, index) {
            tlsStream.write(makeApnsMessage(tokens[index], index, notification));
        });
    });
};

SenderApns.prototype.reSendThroughApns = function (notifications, tokens) {

    var self = this;
    self.notifications = notifications;
    self.tokens = tokens;

    self.newConnection(function (tlsStream) {
        self.tlsStream = tlsStream;
        _.each(notifications, function (notification, index) {
            tlsStream.write(makeApnsMessage(tokens[index], index, notification));
        });
    });
};

SenderApns.prototype.newConnection = function (callsuccess) {

    var self = this;
    var tlsConnectionOptions = {
        port : 2195,
        host : self.host,
        key : self.objectCert.keyData,
        cert : self.objectCert.certData
    };

    try {
        var tlsStream = tls.connect(tlsConnectionOptions, function () {
            callsuccess(tlsStream);
        });
    } catch (err) {
        self.callerror(err);
        return;
    }

    tlsStream.on("error", function () {
        self.reconnect();
    });

    tlsStream.on("data", function (data) {
        self.errorResponse(data);
    });

    //tlsStream.on("close", function () { console.log("close"); });
    //tlsStream.on("end", function () { console.log("end"); });
};

SenderApns.prototype.errorResponse = function (data) {

    var self = this;

    if (data[0] === 8) {
        var apnsError = data[1];
        var identifier = data.readUInt32BE(2);
        _.each(self.tokens, function (token, index) {
            if (index < identifier) {
                self.resultArray.push({token : token, status : 0, _id : self.notifications[index]._id});
            }
            if (index === identifier && self.tokens.length !== identifier + 1) {
                self.resultArray.push({token : token, status : apnsError,  _id : self.notifications[index]._id});
            }
        });

        if (self.tokens.length === identifier + 1) {
            self.tlsStream.destroySoon();
            self.callsuccess(self.resultArray);
            return;
        }

        var tokens = self.tokens.slice(identifier + 1);
        var notifications = self.notifications.slice(identifier + 1);
        self.reSendThroughApns(notifications, tokens);
    }
};

SenderApns.prototype.reconnect = function () {

    var self = this;
    self.reconnectTry += 1;
    setTimeout(function () {
        self.reSendThroughApns(self.notifications, self.tokens);
    }, 1000 * self.reconnectTry * self.reconnectTry);
};

SenderApns.prototype.isInputValid = function () {

    var isValid = true;
    if (typeof (this.callerror) !== 'function' || typeof (this.callsuccess) !== 'function') {
        return false;
    }
    if (!this.objectCert || !this.objectCert.certData || !this.objectCert.keyData) {
        this.callerror("Object cert is not valid!");
        return false;
    }
    if (!this.notifications || !this.tokens || this.tokens.length !== this.notifications.length) {
        this.callerror("Notifications or tokens are not valid or not the same length!");
        return false;
    }
    _.each(this.notifications, function (notification) {
        if (!notification || !notification.payload || !notification._id || isNaN(notification.expiry)) {
            isValid = false;
        }
    });
    if (!isValid) {
        this.callerror("Some notification is not valid!");
        return false;
    }
    _.each(this.tokens, function (token) {
        try {
            var tempToken =  new Buffer(token.replace(/\s/g, ""), "hex");
        } catch (error) {
            isValid = false;
            return;
        }
        if (tempToken.length !== 32) {
            isValid = false;
        }
    });
    if (!isValid) {
        this.callerror("Some token is not valid!");
        return false;
    }

    return true;
};

function makeApnsMessage(token, identifier, notification) {

    token = new Buffer(token.replace(/\s/g, ""), "hex");
    var encoding = 'utf8';
    var message = JSON.stringify(notification.payload);
    var messageLength = Buffer.byteLength(message, encoding);
    var position = 0;
    var apnsMessage = new Buffer(1 + 4 + 4 + 2 + token.length + 2 + messageLength);

    // Command
    apnsMessage[position] = 1;
    position += 1;
    // Identifier
    apnsMessage.writeUInt32BE(identifier, position);
    position += 4;
    // Expiry
    apnsMessage.writeUInt32BE(notification.expiry, position);
    position += 4;

    // Token Length
    apnsMessage.writeUInt16BE(token.length, position);
    position += 2;
    // Device Token
    token.copy(apnsMessage, position, 0);
    position += token.length;
    // Payload Length
    apnsMessage.writeUInt16BE(messageLength, position);
    position += 2;
    //Payload
    apnsMessage.write(message, position, encoding);
    return apnsMessage;
}

exports.SenderApns   = SenderApns;<commit_msg>Better verification. Reconnecting timeout made.<commit_after>var tls = require('tls');
var _ = require('underscore');

function SenderApns(objectCert, production) {

    this.host = 'gateway.push.apple.com';
    this.objectCert = objectCert;
    this.resultArray = [];
    this.callsuccess = null;
    this.callsuccess = null;
    this.notifications = null;
    this.reconnectTry = 0;
    this.tokens = [];
    this.tlsStream = null;

    if (!production) {
        this.host = 'gateway.sandbox.push.apple.com';
    }
}

SenderApns.prototype.sendThroughApns = function (notifications, tokens, callsuccess, callerror) {

    var self = this;
    self.notifications = notifications;
    self.tokens = tokens;
    self.callsuccess = callsuccess;
    self.callerror = callerror;
    if (!self.isInputValid()) {
        return;
    }

    //set last notification to fail
    notifications.push({expiry : 30000, payload : {}, _id : "007"});
    tokens.push("aaa111");

    self.newConnection(function (tlsStream) {
        self.tlsStream = tlsStream;
        _.each(notifications, function (notification, index) {
            tlsStream.write(makeApnsMessage(tokens[index], index, notification));
        });
    });
};

SenderApns.prototype.reSendThroughApns = function (notifications, tokens) {

    var self = this;
    self.notifications = notifications;
    self.tokens = tokens;

    self.newConnection(function (tlsStream) {
        self.tlsStream = tlsStream;
        _.each(notifications, function (notification, index) {
            tlsStream.write(makeApnsMessage(tokens[index], index, notification));
        });
    });
};

SenderApns.prototype.newConnection = function (callsuccess) {

    var self = this;
    var tlsConnectionOptions = {
        port : 2195,
        host : self.host,
        key : self.objectCert.keyData,
        cert : self.objectCert.certData
    };

    try {
        var tlsStream = tls.connect(tlsConnectionOptions, function () {
            callsuccess(tlsStream);
        });
    } catch (err) {
        self.callerror(err);
        return;
    }

    tlsStream.on("error", function () {
        self.reconnect();
    });

    tlsStream.on("data", function (data) {
        self.errorResponse(data);
    });;
};

SenderApns.prototype.errorResponse = function (data) {

    var self = this;

    if (data[0] === 8) {
        var apnsError = data[1];
        var identifier = data.readUInt32BE(2);
        _.each(self.tokens, function (token, index) {
            if (index < identifier) {
                self.resultArray.push({token : token, status : 0, _id : self.notifications[index]._id});
            }
            if (index === identifier && self.tokens.length !== identifier + 1) {
                self.resultArray.push({token : token, status : apnsError,  _id : self.notifications[index]._id});
            }
        });

        if (self.tokens.length === identifier + 1) {
            self.tlsStream.destroySoon();
            self.callsuccess(self.resultArray);
            return;
        }

        var tokens = self.tokens.slice(identifier + 1);
        var notifications = self.notifications.slice(identifier + 1);
        self.reSendThroughApns(notifications, tokens);
        return;
    }
    self.reSendThroughApns(notifications, tokens);
};

SenderApns.prototype.reconnect = function () {

    var self = this;
    self.reconnectTry += 1;
    if (self.reconnectTry >= 10) {
        self.callerror("Error in connecting with APNS");
        return;
    }
    setTimeout(function () {
        self.reSendThroughApns(self.notifications, self.tokens);
    }, 1000 * self.reconnectTry * self.reconnectTry);
};

SenderApns.prototype.isInputValid = function () {

    var self = this;
    if (typeof (self.callerror) !== 'function' || typeof (self.callsuccess) !== 'function') {
        return false;
    }
    if (!self.objectCert || !self.objectCert.certData || !self.objectCert.keyData) {
        self.callerror("Object cert is not valid!");
        return false;
    }
    if (!self.notifications || !self.tokens || self.tokens.length !== self.notifications.length) {
        self.callerror("Notifications or tokens are not valid or not the same length!");
        return false;
    }

    var numberNotDeleted = 0;
    _.each(_.clone(self.notifications), function (notification, index) {
        if (!notification || !notification.payload || !notification._id || isNaN(notification.expiry)) {
            manageFalseInput(self, index - numberNotDeleted, 9);
            numberNotDeleted += 1;
            return;
        }
        if (JSON.stringify(notification.payload).length > 256) {
            manageFalseInput(self, index - numberNotDeleted, 7);
            numberNotDeleted += 1;
        }
    });

    var numberTokDeleted = 0;
    _.each(_.clone(self.tokens), function (token, index) {
        try {
            var tempToken =  new Buffer(token.replace(/\s/g, ""), "hex");
        } catch (error) {
            manageFalseInput(self, index - numberTokDeleted, 8);
            numberTokDeleted += 1;
            return;
        }
        if (tempToken.length !== 32) {
            manageFalseInput(self, index - numberTokDeleted, 8);
            numberTokDeleted += 1;
        }
    });

    if (self.notifications.length === 0) {
        self.callsuccess(self.resultArray);
        return false;
    }

    return true;
};

function makeApnsMessage(token, identifier, notification) {

    token = new Buffer(token.replace(/\s/g, ""), "hex");
    var encoding = 'utf8';
    var message = JSON.stringify(notification.payload);
    var messageLength = Buffer.byteLength(message, encoding);
    var position = 0;
    var apnsMessage = new Buffer(1 + 4 + 4 + 2 + token.length + 2 + messageLength);

    // Command
    apnsMessage[position] = 1;
    position += 1;
    // Identifier
    apnsMessage.writeUInt32BE(identifier, position);
    position += 4;
    // Expiry
    apnsMessage.writeUInt32BE(notification.expiry, position);
    position += 4;

    // Token Length
    apnsMessage.writeUInt16BE(token.length, position);
    position += 2;
    // Device Token
    token.copy(apnsMessage, position, 0);
    position += token.length;
    // Payload Length
    apnsMessage.writeUInt16BE(messageLength, position);
    position += 2;
    //Payload
    apnsMessage.write(message, position, encoding);
    return apnsMessage;
}

function manageFalseInput(self, index, status) {
    self.resultArray.push({token : self.tokens[index], status : status,  _id : self.notifications[index]._id});
    self.tokens.splice(index, 1);
    self.notifications.splice(index, 1);
}

exports.SenderApns   = SenderApns;<|endoftext|>


<commit_before>(function (angular) {

    'use strict';

    var crearLugarTerritorioModule = angular.module('crearLugarTerritorioModal',['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
    crearLugarTerritorioModule.service('crearLugarTerritorio',['$uibModal', function($uibModal){
        var $ctrl = this;
        $ctrl.valorInicial = {};
        var modalOptionsDefault = {
          animation: true,
          templateUrl: 'views/services/crearLugarTemplate.html',
          controller: 'ModalInstanceCtrl',
          controllerAs: '$ctrl',
          size: 'lg',
          resolve: {
            valorInicial: function () {
              return $ctrl.valorInicial;
            }
          }
        }

        this.show = function (valorInicial, customModalOptions) {
            var modalOptions = {};
            if (!customModalOptions) modalOptions = modalOptionsDefault;
            $ctrl.valorInicial = valorInicial;
            return $uibModal.open(modalOptions).result;
        };
    }]);

    crearLugarTerritorioModule.controller('ModalInstanceCtrl', function ($uibModalInstance, valorInicial) {
        var $ctrl = this;

        $ctrl.datosLugar = {
            lugarID: -1,
            nombre: valorInicial,
            tipoLugar: '',
            categoria: '',
            coordenadas: '',
            //fechaInicial: '',
            fechaInicialFormato: '',
            //fechaFinal: '',
            feachaFinalFormato:''
        };

        $ctrl.ok = function () {
            // Insertar lugar en base de datos
            // revisar si el personaje nombre esta vacio
            if ($ctrl.datosLugar.nombre !== "") {
                var parametros = {};
                // removemos el lugarID
                for (key in $ctrl.datosLugar) {
                    if (key != lugarID) {
                        parametros[key] = $ctrl.datosLugar[key];
                    }
                }

                $http.get('http://monsalvediaz.com:5000/PIMC0.1/Insertar/Lugares',{
                    params: parametros
                }).then(function(data) {
                    console.log(data);
                    // Data contains the last insert id
                    if (Object.keys(data.data).length != 0) {
                        var lastInsertID = data.data[0]["LAST_INSERT_ID()"];
                        $ctrl.datosLugar.lugarID = lastInsertID;
                        $uibModalInstance.close($ctrl.datosLugar);
                    } else {
                        $uibModalInstance.close({});
                    }
                });
            }

        };

        $ctrl.cancel = function () {
            $uibModalInstance.dismiss('cancelar');
        };
    });

})(window.angular);<commit_msg>lugarTerritorio ene mbarcacion<commit_after>(function (angular) {

    'use strict';

    var crearLugarTerritorioModule = angular.module('crearLugarTerritorioModal',['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
    crearLugarTerritorioModule.service('crearLugarTerritorio',['$uibModal', function($uibModal){
        var $ctrl = this;
        $ctrl.valorInicial = {};
        var modalOptionsDefault = {
          animation: true,
          templateUrl: 'views/services/crearLugarTemplate.html',
          controller: 'ModalInstanceCtrl',
          controllerAs: '$ctrl',
          size: 'lg',
          resolve: {
            valorInicial: function () {
              return $ctrl.valorInicial;
            }
          }
        }

        this.show = function (valorInicial, customModalOptions) {
            var modalOptions = {};
            if (!customModalOptions) modalOptions = modalOptionsDefault;
            $ctrl.valorInicial = valorInicial;
            return $uibModal.open(modalOptions).result;
        };
    }]);

    crearLugarTerritorioModule.controller('ModalInstanceCtrl', function ($uibModalInstance, valorInicial) {
        var $ctrl = this;

        $ctrl.datosLugar = {
            lugarID: -1,
            nombre: valorInicial,
            tipoLugar: '',
            categoria: '',
            coordenadas: '',
            //fechaInicial: '',
            fechaInicialFormato: '',
            //fechaFinal: '',
            feachaFinalFormato:''
        };

        $ctrl.ok = function () {
            // Insertar lugar en base de datos
            // revisar si el personaje nombre esta vacio
            if ($ctrl.datosLugar.nombre !== "") {
                var parametros = {};
                // removemos el lugarID
                for (var key in $ctrl.datosLugar) {
                    if (key != lugarID) {
                        parametros[key] = $ctrl.datosLugar[key];
                    }
                }

                $http.get('http://monsalvediaz.com:5000/PIMC0.1/Insertar/Lugares',{
                    params: parametros
                }).then(function(data) {
                    console.log(data);
                    // Data contains the last insert id
                    if (Object.keys(data.data).length != 0) {
                        var lastInsertID = data.data[0]["LAST_INSERT_ID()"];
                        $ctrl.datosLugar.lugarID = lastInsertID;
                        $uibModalInstance.close($ctrl.datosLugar);
                    } else {
                        $uibModalInstance.close({});
                    }
                });
            }

        };

        $ctrl.cancel = function () {
            $uibModalInstance.dismiss('cancelar');
        };
    });

})(window.angular);<|endoftext|>


<commit_before>'use strict';

// The host poller handles the communication with the web server.  Messages from
// the server get converted into timer events (e.g., PREPARE_HEAT_RECEIVED or
// ABORT_HEAT_RECEIVED).  The host poller also listens for several events that
// it then reports to the web server.

const HEARTBEAT_PACE = 500;

var g_host_poller;  // See initialization at bottom of file

class HostPoller {
  // This URL is shared with role_finder.
  static url = 'action.php';

  next_message_time = 0;
  identified = false;
  confirmed = true;  // TODO

  competing = false;

  remote_start = false;

  constructor() {
    TimerEvent.register(this);
    this.sendMessage({action: 'timer-message',
                      message: 'HELLO',
                      interface: 'web',
                      build: g_version.branch + "-" + g_version.revision});
  }

  offer_remote_start(v) {
    this.remote_start = v;
  }

  async heartbeat() {
    if (Date.now() >= this.next_message_time) {
      if (!this.identified) {
        this.sendMessage({action: 'timer-message',
                          message: 'HEARTBEAT',
                          unhealthy: true});
      } else {
        this.sendMessage({action: 'timer-message',
                          message: 'HEARTBEAT',
                          confirmed: this.confirmed ? 1 : 0});
      }
    }
  }

  async onEvent(event, args) {
    switch (event) {
    case 'IDENTIFIED':
      this.identified = true;
      this.sendMessage({action: 'timer-message',
                        message: 'IDENTIFIED',
                        interface: 'web',
                        // TODO lane_count, ident, options
                        timer: args[0],  // TODO No formal name
                        human: args[0],
                        ident: args[1]});
      break;
    case 'RACE_STARTED':
      this.sendMessage({action: 'timer-message',
                        message: 'STARTED'});
      break;
    case 'RACE_FINISHED': {  // roundid, heat, results
      var msg = {action: 'timer-message',
                 message: 'FINISHED'};
      var results = args[2].lane_results;
      for (var i = 0; i < results.length; ++i) {
        if (results[i]) {
          msg['lane' + (i + 1)] = results[i].time;
          if (results[i]?.place && !Flag.ignore_place.value) {
            msg['place' + (i + 1)] = results[i].place;
          }
        }
      }
      console.log(msg);
      g_logger.internal_msg('RACE_FINISHED: ' + JSON.stringify(msg));
      this.sendMessage(msg);
      break;
    }
    case 'LOST_CONNECTION':
      this.identified = false;
      this.sendMessage({action: 'timer-message',
                        message: 'MALFUNCTION',
                        detectable: args[0] ? 1 : 0,
                        error: args[1]});
      break;
    }
  }

  sendMessage(msg) {
    msg['remote-start'] = this.remote_start ? 'YES' : 'NO';
    var now = Date.now();
    if (now > this.next_message_time + HEARTBEAT_PACE && this.next_message_time != 0) {
      // The heartbeat loop above should be sending messages regularly, but
      // apparently some browsers slow down non-frontmost windows, allowing
      // arbitrary delays in responding to timeouts.
      msg['overdue'] = now - this.next_message_time;
    }
    this.next_message_time = now + HEARTBEAT_PACE;
    g_clock_worker.postMessage(['HEARTBEAT', HEARTBEAT_PACE, 'HEARTBEAT']);
    if (msg?.message != 'HEARTBEAT') {
      console.log('sendMessage', msg);
    }
    if (this.competing) {
      console.log('Squelching message to host');
    } else {
      $.ajax(HostPoller.url,
             {type: 'POST',
              data: msg,
              success: this.decodeResponse.bind(this),
              error: function() {
                console.error('sendMessage fails');
              }
             });
    }
  }

  decodeResponse(response) {
    response = response.documentElement;
    var nodes;
    if ((nodes = response.getElementsByTagName("remote-log")).length > 0) {
      g_logger.set_remote_logging( nodes[0].getAttribute('send') == 'true' );
    }
    if (response.getElementsByTagName("abort").length > 0) {
      g_logger.host_in('ABORT HEAT');
      $("#heat-prepared").text("* Heat Aborted *");
      TimerEvent.send('ABORT_HEAT_RECEIVED', []);
    }
    if ((nodes = response.getElementsByTagName("heat-ready")).length > 0) {
      var args = [parseInt(nodes[0].getAttribute('roundid')),
                  parseInt(nodes[0].getAttribute('heat')),
                  parseInt(nodes[0].getAttribute('lane-mask')),
                  parseInt(nodes[0].getAttribute('lanes')),
                  parseInt(nodes[0].getAttribute('round')),
                  nodes[0].getAttribute('class')];
      if (g_logger.do_logging) {
        g_logger.host_in('Prepare heat ' + args.join(','));
      }
      TimerEvent.send('PREPARE_HEAT_RECEIVED', args);
    }
    if ((nodes = response.getElementsByTagName("remote-start")).length > 0) {
      g_logger.host_in('START RACE');
      TimerEvent.send('START_RACE', []);
    }
    if ((nodes = response.getElementsByTagName("assign-flag")).length > 0) {
      // attributes for each node: flag=no-gate-watcher, value=true
      for (var i = 0; i < nodes.length; ++i) {
        var name = nodes[i].getAttribute('flag');
        var v = nodes[i].getAttribute('value');
        g_logger.host_in('assign-flag ' + name + ' = ' + v);
        console.log('assign-flag flag=' + name + ', value=' + v);
        for (var j = 0; j < Flag._all_flags.length; ++j) {
          var flag = Flag._all_flags[j];
          if (flag.name != name) {
            continue;
          }
          console.log('   type=' + flag.type);
          if (flag.type == 'bool') {
            flag.value = (v == 'true');
          } else if (flag.type == 'int') {
            flag.value = parseInt(v);
          } else {
            flag.value = v;
          }
        }
      }
    }
    if ((nodes = response.getElementsByTagName("assign-port")).length > 0) {
      // TODO
    }
    if ((nodes = response.getElementsByTagName("assign-device")).length > 0) {
      // TODO
    }
    if ((nodes = response.getElementsByTagName("query")).length > 0) {
      Flag.sendFlagsMessage(this);
    }
    if ((nodes = response.getElementsByTagName("debug")).length > 0) {
      for (var i = 0; i < nodes.length; ++i) {
        console.log("<debug>");
        console.log(nodes[i].textContent);
      }
    }
    if ((nodes = response.getElementsByTagName("competing")).length > 0) {
      this.competing = true;
      show_modal("#competing-modal");
      if (g_prober) {
        g_prober.give_up = true;
      }
      g_timer_proxy && g_timer_proxy.teardown();
      g_timer_proxy = null;
      g_host_poller = null;

      for (var i = 0; i < nodes.length; ++i) {
        console.log("<competing>", nodes[i].textContent);
      }
    }
  }
}

$(function() {
  if (!g_standalone) {
    g_host_poller = new HostPoller();
  }
});
<commit_msg>Stop sending 'interface' key on 'IDENTIFIED' message.<commit_after>'use strict';

// The host poller handles the communication with the web server.  Messages from
// the server get converted into timer events (e.g., PREPARE_HEAT_RECEIVED or
// ABORT_HEAT_RECEIVED).  The host poller also listens for several events that
// it then reports to the web server.

const HEARTBEAT_PACE = 500;

var g_host_poller;  // See initialization at bottom of file

class HostPoller {
  // This URL is shared with role_finder.
  static url = 'action.php';

  next_message_time = 0;
  identified = false;
  confirmed = true;  // TODO

  competing = false;

  remote_start = false;

  constructor() {
    TimerEvent.register(this);
    this.sendMessage({action: 'timer-message',
                      message: 'HELLO',
                      interface: 'web',
                      build: g_version.branch + "-" + g_version.revision});
  }

  offer_remote_start(v) {
    this.remote_start = v;
  }

  async heartbeat() {
    if (Date.now() >= this.next_message_time) {
      if (!this.identified) {
        this.sendMessage({action: 'timer-message',
                          message: 'HEARTBEAT',
                          unhealthy: true});
      } else {
        this.sendMessage({action: 'timer-message',
                          message: 'HEARTBEAT',
                          confirmed: this.confirmed ? 1 : 0});
      }
    }
  }

  async onEvent(event, args) {
    switch (event) {
    case 'IDENTIFIED':
      this.identified = true;
      this.sendMessage({action: 'timer-message',
                        message: 'IDENTIFIED',
                        // TODO lane_count, ident, options
                        timer: args[0],  // TODO No formal name
                        human: args[0],
                        ident: args[1]});
      break;
    case 'RACE_STARTED':
      this.sendMessage({action: 'timer-message',
                        message: 'STARTED'});
      break;
    case 'RACE_FINISHED': {  // roundid, heat, results
      var msg = {action: 'timer-message',
                 message: 'FINISHED'};
      var results = args[2].lane_results;
      for (var i = 0; i < results.length; ++i) {
        if (results[i]) {
          msg['lane' + (i + 1)] = results[i].time;
          if (results[i]?.place && !Flag.ignore_place.value) {
            msg['place' + (i + 1)] = results[i].place;
          }
        }
      }
      console.log(msg);
      g_logger.internal_msg('RACE_FINISHED: ' + JSON.stringify(msg));
      this.sendMessage(msg);
      break;
    }
    case 'LOST_CONNECTION':
      this.identified = false;
      this.sendMessage({action: 'timer-message',
                        message: 'MALFUNCTION',
                        detectable: args[0] ? 1 : 0,
                        error: args[1]});
      break;
    }
  }

  sendMessage(msg) {
    msg['remote-start'] = this.remote_start ? 'YES' : 'NO';
    var now = Date.now();
    if (now > this.next_message_time + HEARTBEAT_PACE && this.next_message_time != 0) {
      // The heartbeat loop above should be sending messages regularly, but
      // apparently some browsers slow down non-frontmost windows, allowing
      // arbitrary delays in responding to timeouts.
      msg['overdue'] = now - this.next_message_time;
    }
    this.next_message_time = now + HEARTBEAT_PACE;
    g_clock_worker.postMessage(['HEARTBEAT', HEARTBEAT_PACE, 'HEARTBEAT']);
    if (msg?.message != 'HEARTBEAT') {
      console.log('sendMessage', msg);
    }
    if (this.competing) {
      console.log('Squelching message to host');
    } else {
      $.ajax(HostPoller.url,
             {type: 'POST',
              data: msg,
              success: this.decodeResponse.bind(this),
              error: function() {
                console.error('sendMessage fails');
              }
             });
    }
  }

  decodeResponse(response) {
    response = response.documentElement;
    var nodes;
    if ((nodes = response.getElementsByTagName("remote-log")).length > 0) {
      g_logger.set_remote_logging( nodes[0].getAttribute('send') == 'true' );
    }
    if (response.getElementsByTagName("abort").length > 0) {
      g_logger.host_in('ABORT HEAT');
      $("#heat-prepared").text("* Heat Aborted *");
      TimerEvent.send('ABORT_HEAT_RECEIVED', []);
    }
    if ((nodes = response.getElementsByTagName("heat-ready")).length > 0) {
      var args = [parseInt(nodes[0].getAttribute('roundid')),
                  parseInt(nodes[0].getAttribute('heat')),
                  parseInt(nodes[0].getAttribute('lane-mask')),
                  parseInt(nodes[0].getAttribute('lanes')),
                  parseInt(nodes[0].getAttribute('round')),
                  nodes[0].getAttribute('class')];
      if (g_logger.do_logging) {
        g_logger.host_in('Prepare heat ' + args.join(','));
      }
      TimerEvent.send('PREPARE_HEAT_RECEIVED', args);
    }
    if ((nodes = response.getElementsByTagName("remote-start")).length > 0) {
      g_logger.host_in('START RACE');
      TimerEvent.send('START_RACE', []);
    }
    if ((nodes = response.getElementsByTagName("assign-flag")).length > 0) {
      // attributes for each node: flag=no-gate-watcher, value=true
      for (var i = 0; i < nodes.length; ++i) {
        var name = nodes[i].getAttribute('flag');
        var v = nodes[i].getAttribute('value');
        g_logger.host_in('assign-flag ' + name + ' = ' + v);
        console.log('assign-flag flag=' + name + ', value=' + v);
        for (var j = 0; j < Flag._all_flags.length; ++j) {
          var flag = Flag._all_flags[j];
          if (flag.name != name) {
            continue;
          }
          console.log('   type=' + flag.type);
          if (flag.type == 'bool') {
            flag.value = (v == 'true');
          } else if (flag.type == 'int') {
            flag.value = parseInt(v);
          } else {
            flag.value = v;
          }
        }
      }
    }
    if ((nodes = response.getElementsByTagName("assign-port")).length > 0) {
      // TODO
    }
    if ((nodes = response.getElementsByTagName("assign-device")).length > 0) {
      // TODO
    }
    if ((nodes = response.getElementsByTagName("query")).length > 0) {
      Flag.sendFlagsMessage(this);
    }
    if ((nodes = response.getElementsByTagName("debug")).length > 0) {
      for (var i = 0; i < nodes.length; ++i) {
        console.log("<debug>");
        console.log(nodes[i].textContent);
      }
    }
    if ((nodes = response.getElementsByTagName("competing")).length > 0) {
      this.competing = true;
      show_modal("#competing-modal");
      if (g_prober) {
        g_prober.give_up = true;
      }
      g_timer_proxy && g_timer_proxy.teardown();
      g_timer_proxy = null;
      g_host_poller = null;

      for (var i = 0; i < nodes.length; ++i) {
        console.log("<competing>", nodes[i].textContent);
      }
    }
  }
}

$(function() {
  if (!g_standalone) {
    g_host_poller = new HostPoller();
  }
});
<|endoftext|>


<commit_before>var tape = require('../');
var tap = require('tap');
var concat = require('concat-stream');

function fn() {
    throw new TypeError('RegExp');
}

function getNonFunctionMessage(fn) {
    try {
        fn();
    } catch (e) {
        return e.message;
    }
}

tape('throws', function (t) {
    t.throws(fn);
    t.end();
});

tape('throws (RegExp match)', function (t) {
    t.throws(fn, /RegExp/);
    t.end();
});

tape('throws (Function match)', function (t) {
    t.throws(fn, TypeError);
    t.end();
});

tap.test('failures', function (tt) {
    tt.plan(1);

    var test = tape.createHarness();
    test.createStream().pipe(concat(function (body) {
        tt.equal(
            body.toString('utf8'),
            'TAP version 13\n'
           + '# non functions\n'
           + 'not ok 1 should throw\n'
           + '  ---\n'
           + '    operator: throws\n'
           + '    expected: |-\n'
           + '      undefined\n'
           + '    actual: |-\n'
           + "      { [TypeError: " + getNonFunctionMessage() + "] message: '" + getNonFunctionMessage() + "' }\n"
           + '  ...\n'
           + 'not ok 2 should throw\n'
           + '  ---\n'
           + '    operator: throws\n'
           + '    expected: |-\n'
           + '      undefined\n'
           + '    actual: |-\n'
           + "      { [TypeError: " + getNonFunctionMessage(null) + "] message: '" + getNonFunctionMessage(null) + "' }\n"
           + '  ...\n'
           + 'not ok 3 should throw\n'
           + '  ---\n'
           + '    operator: throws\n'
           + '    expected: |-\n'
           + '      undefined\n'
           + '    actual: |-\n'
           + "      { [TypeError: " + getNonFunctionMessage(true) + "] message: '" + getNonFunctionMessage(true) + "' }\n"
           + '  ...\n'
           + 'not ok 4 should throw\n'
           + '  ---\n'
           + '    operator: throws\n'
           + '    expected: |-\n'
           + '      undefined\n'
           + '    actual: |-\n'
           + "      { [TypeError: " + getNonFunctionMessage(false) + "] message: '" + getNonFunctionMessage(false) + "' }\n"
           + '  ...\n'
           + 'not ok 5 should throw\n'
           + '  ---\n'
           + '    operator: throws\n'
           + '    expected: |-\n'
           + '      undefined\n'
           + '    actual: |-\n'
           + "      { [TypeError: " + getNonFunctionMessage('abc') + "] message: '" + getNonFunctionMessage('abc') + "' }\n"
           + '  ...\n'
           + 'not ok 6 should throw\n'
           + '  ---\n'
           + '    operator: throws\n'
           + '    expected: |-\n'
           + '      undefined\n'
           + '    actual: |-\n'
           + "      { [TypeError: " + getNonFunctionMessage(/a/g) + "] message: '" + getNonFunctionMessage(/a/g) + "' }\n"
           + '  ...\n'
           + 'not ok 7 should throw\n'
           + '  ---\n'
           + '    operator: throws\n'
           + '    expected: |-\n'
           + '      undefined\n'
           + '    actual: |-\n'
           + "      { [TypeError: " + getNonFunctionMessage([]) + "] message: '" + getNonFunctionMessage([]) + "' }\n"
           + '  ...\n'
           + 'not ok 8 should throw\n'
           + '  ---\n'
           + '    operator: throws\n'
           + '    expected: |-\n'
           + '      undefined\n'
           + '    actual: |-\n'
           + "      { [TypeError: " + getNonFunctionMessage({}) + "] message: '" + getNonFunctionMessage({}) + "' }\n"
           + '  ...\n'
           + '# function\n'
           + 'not ok 9 should throw\n'
           + '  ---\n'
           + '    operator: throws\n'
           + '    expected: undefined\n'
           + '    actual:   undefined\n'
           + '  ...\n\n'
           + '1..9\n'
           + '# tests 9\n'
           + '# pass  0\n'
           + '# fail  9\n'
        );
    }));

    test('non functions', function (t) {
        t.plan(8);
        t.throws();
        t.throws(null);
        t.throws(true);
        t.throws(false);
        t.throws('abc');
        t.throws(/a/g);
        t.throws([]);
        t.throws({});
    });

    test('function', function (t) {
        t.plan(1);
        t.throws(function () {});
    });
});
<commit_msg>Minor test tweaks due to whitespace differences in v2 vs v4.<commit_after>var tape = require('../');
var tap = require('tap');
var concat = require('concat-stream');

function fn() {
    throw new TypeError('RegExp');
}

function getNonFunctionMessage(fn) {
    try {
        fn();
    } catch (e) {
        return e.message;
    }
}

tape('throws', function (t) {
    t.throws(fn);
    t.end();
});

tape('throws (RegExp match)', function (t) {
    t.throws(fn, /RegExp/);
    t.end();
});

tape('throws (Function match)', function (t) {
    t.throws(fn, TypeError);
    t.end();
});

tap.test('failures', function (tt) {
    tt.plan(1);

    var test = tape.createHarness();
    test.createStream().pipe(concat(function (body) {
        tt.equal(
            body.toString('utf8'),
            'TAP version 13\n'
           + '# non functions\n'
           + 'not ok 1 should throw\n'
           + '  ---\n'
           + '    operator: throws\n'
           + '    expected:\n'
           + '      undefined\n'
           + '    actual:\n'
           + "      { [TypeError: " + getNonFunctionMessage() + "] message: '" + getNonFunctionMessage() + "' }\n"
           + '  ...\n'
           + 'not ok 2 should throw\n'
           + '  ---\n'
           + '    operator: throws\n'
           + '    expected:\n'
           + '      undefined\n'
           + '    actual:\n'
           + "      { [TypeError: " + getNonFunctionMessage(null) + "] message: '" + getNonFunctionMessage(null) + "' }\n"
           + '  ...\n'
           + 'not ok 3 should throw\n'
           + '  ---\n'
           + '    operator: throws\n'
           + '    expected:\n'
           + '      undefined\n'
           + '    actual:\n'
           + "      { [TypeError: " + getNonFunctionMessage(true) + "] message: '" + getNonFunctionMessage(true) + "' }\n"
           + '  ...\n'
           + 'not ok 4 should throw\n'
           + '  ---\n'
           + '    operator: throws\n'
           + '    expected:\n'
           + '      undefined\n'
           + '    actual:\n'
           + "      { [TypeError: " + getNonFunctionMessage(false) + "] message: '" + getNonFunctionMessage(false) + "' }\n"
           + '  ...\n'
           + 'not ok 5 should throw\n'
           + '  ---\n'
           + '    operator: throws\n'
           + '    expected:\n'
           + '      undefined\n'
           + '    actual:\n'
           + "      { [TypeError: " + getNonFunctionMessage('abc') + "] message: '" + getNonFunctionMessage('abc') + "' }\n"
           + '  ...\n'
           + 'not ok 6 should throw\n'
           + '  ---\n'
           + '    operator: throws\n'
           + '    expected:\n'
           + '      undefined\n'
           + '    actual:\n'
           + "      { [TypeError: " + getNonFunctionMessage(/a/g) + "] message: '" + getNonFunctionMessage(/a/g) + "' }\n"
           + '  ...\n'
           + 'not ok 7 should throw\n'
           + '  ---\n'
           + '    operator: throws\n'
           + '    expected:\n'
           + '      undefined\n'
           + '    actual:\n'
           + "      { [TypeError: " + getNonFunctionMessage([]) + "] message: '" + getNonFunctionMessage([]) + "' }\n"
           + '  ...\n'
           + 'not ok 8 should throw\n'
           + '  ---\n'
           + '    operator: throws\n'
           + '    expected:\n'
           + '      undefined\n'
           + '    actual:\n'
           + "      { [TypeError: " + getNonFunctionMessage({}) + "] message: '" + getNonFunctionMessage({}) + "' }\n"
           + '  ...\n'
           + '# function\n'
           + 'not ok 9 should throw\n'
           + '  ---\n'
           + '    operator: throws\n'
           + '    expected: undefined\n'
           + '    actual:   undefined\n'
           + '  ...\n\n'
           + '1..9\n'
           + '# tests 9\n'
           + '# pass  0\n'
           + '# fail  9\n'
        );
    }));

    test('non functions', function (t) {
        t.plan(8);
        t.throws();
        t.throws(null);
        t.throws(true);
        t.throws(false);
        t.throws('abc');
        t.throws(/a/g);
        t.throws([]);
        t.throws({});
    });

    test('function', function (t) {
        t.plan(1);
        t.throws(function () {});
    });
});
<|endoftext|>


<commit_before>// Usage:
//   utils.matchesSelector(div, '.something');
utils.matchesSelector = (function() {
  // Suffix.
  var sfx = 'MatchesSelector';
  var tag = document.createElement('div');
  var name;
  ['matches', 'webkit' + sfx, 'moz' + sfx, 'ms' + sfx].some(function(item) {
    var valid = (item in tag);
    name = item;
    return valid;
  });
  if (!name) {
    throw new Error('Element#matches is not supported');
  }
  return function(element, selector) {
    return element[name](selector);
  };
})();

// Make AJAX request to the server.
// Usage:
//   var callback = function(error, data) {console.log('Done.', error, data);};
//   ajax({url: 'url', method: 'PATCH', data: 'data'}, callback);
utils.ajax = (function() {
  var xmlRe = /^(?:application|text)\/xml/;
  var jsonRe = /^application\/json/;

  var getData = function(accepts, xhr) {
    if (accepts == null) accepts = xhr.getResponseHeader('content-type');
    if (xmlRe.test(accepts)) {
      return xhr.responseXML;
    } else if (jsonRe.test(accepts)) {
      return JSON.parse(xhr.responseText);
    } else {
      return xhr.responseText;
    }
  };

  var isValid = function(xhr) {
    return (xhr.status >= 200 && xhr.status < 300) ||
      (xhr.status === 304) ||
      (xhr.status === 0 && window.location.protocol === 'file:')
  };

  var end = function(xhr, options, promise) {
    return function() {
      if (xhr.readyState !== 4) return;

      var status = xhr.status;
      var data = getData(options.headers && options.headers.Accept, xhr);

      // Check for validity.
      if (isValid(xhr)) {
        if (options.success) options.success(data);
        if (promise) Backbone.resolveDeferred(promise, true, [data, xhr]);
      } else {
        var error = new Error('Server responded with a status of ' + status);
        error.code = status;
        if (options.error) options.error(xhr, status, error);
        if (promise) Backbone.resolveDeferred(promise, false, [xhr]);
      }
    }
  };

  return function(options) {
    if (options == null) throw new Error('You must provide options');
    if (options.method == null) options.method = 'GET';

    var xhr = new XMLHttpRequest();
    var promise = Backbone.Deferred && Backbone.Deferred();
    if (options.credentials) options.withCredentials = true;
    xhr.addEventListener('readystatechange', end(xhr, options, promise));
    xhr.open(options.method, options.url, true);
    if (options.headers) for (var key in options.headers) {
      xhr.setRequestHeader(key, options.headers[key]);
    }
    xhr.send(options.data);
    return promise;
  };
})();
<commit_msg>Fix node env. Closes gh-39.<commit_after>// Usage:
//   utils.matchesSelector(div, '.something');
utils.matchesSelector = (function() {
  if (typeof document === 'undefined') return;
  // Suffix.
  var sfx = 'MatchesSelector';
  var tag = document.createElement('div');
  var name;
  ['matches', 'webkit' + sfx, 'moz' + sfx, 'ms' + sfx].some(function(item) {
    var valid = (item in tag);
    name = item;
    return valid;
  });
  if (!name) {
    throw new Error('Element#matches is not supported');
  }
  return function(element, selector) {
    return element[name](selector);
  };
})();

// Make AJAX request to the server.
// Usage:
//   var callback = function(error, data) {console.log('Done.', error, data);};
//   ajax({url: 'url', method: 'PATCH', data: 'data'}, callback);
utils.ajax = (function() {
  var xmlRe = /^(?:application|text)\/xml/;
  var jsonRe = /^application\/json/;

  var getData = function(accepts, xhr) {
    if (accepts == null) accepts = xhr.getResponseHeader('content-type');
    if (xmlRe.test(accepts)) {
      return xhr.responseXML;
    } else if (jsonRe.test(accepts)) {
      return JSON.parse(xhr.responseText);
    } else {
      return xhr.responseText;
    }
  };

  var isValid = function(xhr) {
    return (xhr.status >= 200 && xhr.status < 300) ||
      (xhr.status === 304) ||
      (xhr.status === 0 && window.location.protocol === 'file:')
  };

  var end = function(xhr, options, promise) {
    return function() {
      if (xhr.readyState !== 4) return;

      var status = xhr.status;
      var data = getData(options.headers && options.headers.Accept, xhr);

      // Check for validity.
      if (isValid(xhr)) {
        if (options.success) options.success(data);
        if (promise) Backbone.resolveDeferred(promise, true, [data, xhr]);
      } else {
        var error = new Error('Server responded with a status of ' + status);
        error.code = status;
        if (options.error) options.error(xhr, status, error);
        if (promise) Backbone.resolveDeferred(promise, false, [xhr]);
      }
    }
  };

  return function(options) {
    if (options == null) throw new Error('You must provide options');
    if (options.method == null) options.method = 'GET';

    var xhr = new XMLHttpRequest();
    var promise = Backbone.Deferred && Backbone.Deferred();
    if (options.credentials) options.withCredentials = true;
    xhr.addEventListener('readystatechange', end(xhr, options, promise));
    xhr.open(options.method, options.url, true);
    if (options.headers) for (var key in options.headers) {
      xhr.setRequestHeader(key, options.headers[key]);
    }
    xhr.send(options.data);
    return promise;
  };
})();
<|endoftext|>


<commit_before>"use strict";

var fs = require('fs');
var path = require('path');
var walk = require('walk');
var rek = require('rekuire');
var methods = rek('methods');
var logger = rek('logger');

module.exports = {
  findDupes: findDupes,
  logger: logger
};

var methodsList = [
  methods.separateFilesBySize
// , methods.separateFilesByHeadMD5
, methods.separateFilesByMD5
];

var resultObject = {};

function findDupes(options) {
  logger.setVerbosity(options.verbosity);
  options.targetPath = resolveDirectory(options.targetPath);
  resultObject.path = options.targetPath;
  getFiles(options, processFiles);
}

/////////////////////////////////

function resolveDirectory(dir) {
  var fullPath = path.resolve(dir || process.cwd());
  if (!(fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory())) {
    logger.error(fullPath + ' is not a directory!');
    process.exit();
  }
  return fullPath;
}

function getFiles(options, callback) {
  logger.log('Scanning files in ' + options.targetPath + ':\n');
  var files   = [];
  var walkOptions = { followLinks: false, filters: ['node_modules', '.git'] };
  var walker  = walk.walk(options.targetPath, walkOptions);

  walker.on('file', function(root, stat, next) {
    if (stat.size || options.includeEmpty) {
      stat.path = root + '/' + stat.name;
      files.push(stat);
    }
    next();
  });

  walker.on('end', function() {
    callback(files, options);
  });
}

function processFiles(files, options) {
  var sets = [files];

  resultObject.steps = [];

  methodsList.forEach(function(method) {
    logger.verbose('Running method: ' + method.name)
    var step = { method: method.name, before: getSetsStatsObj(sets) };
    sets = method(sets);
    step.after = getSetsStatsObj(sets);
    logger.verbose(JSON.stringify(step,null,3) + '\n');
    resultObject.steps.push(step);
  });
  resultObject.result = sets;
  logger.log(resultOutput(sets));
  if (options.write) fs.writeFileSync(options.targetPath + '/dupes.json', JSON.stringify(resultObject, null, 2));
}

function getSetsStatsObj(sets) {
  return { files: sets.map(function(set) { return set.length; }).reduce(sum, 0), pools: sets.length };
}

function resultOutput(sets) {
  if (sets.length == 0) return '\nThere are no suspected dupes.\n';
  var totalDuplicatesVolume = sets.map(function(set) { return (set.length - 1) * set[0].size; }).reduce(sum, 0);
  var setsByPathOnly = sets.map(function(set) { return set.map(function(file) { return file.path; })});
  var list = setsByPathOnly.map(function(set) { return set.join('\n'); }).join('\n\n');
  return 'These are the suspected dupes:\n\n' + list + '\n\n...With a total duplicate volume of ' + totalDuplicatesVolume + ' bytes';
}

function sum(a, b) {
  return a + b;
}

<commit_msg>added durations of steps and total<commit_after>"use strict";

var fs = require('fs');
var path = require('path');
var walk = require('walk');
var rek = require('rekuire');
var methods = rek('methods');
var logger = rek('logger');

module.exports = {
  findDupes: findDupes,
  logger: logger
};

var methodsList = [
  methods.separateFilesBySize
// , methods.separateFilesByHeadMD5
, methods.separateFilesByMD5
];

var resultObject = {};

function findDupes(options) {
  logger.setVerbosity(options.verbosity);
  options.targetPath = resolveDirectory(options.targetPath);
  resultObject.path = options.targetPath;
  getFiles(options, processFiles);
}

/////////////////////////////////

function resolveDirectory(dir) {
  var fullPath = path.resolve(dir || process.cwd());
  if (!(fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory())) {
    logger.error(fullPath + ' is not a directory!');
    process.exit();
  }
  return fullPath;
}

function getFiles(options, callback) {
  var start = process.hrtime();
  logger.log('\nScanning files in ' + options.targetPath);
  var files   = [];
  var walkOptions = { followLinks: false, filters: ['node_modules', '.git'] };
  var walker  = walk.walk(options.targetPath, walkOptions);

  walker.on('file', function(root, stat, next) {
    if (stat.size || options.includeEmpty) {
      stat.path = root + '/' + stat.name;
      files.push(stat);
    }
    next();
  });

  walker.on('end', function() {
    resultObject.scanDuration = hrtimeToSeconds(process.hrtime(start));
    logger.log('Scan finished in ' + resultObject.scanDuration.toFixed(3) + ' seconds.');
    callback(files, options);
  });
}

function processFiles(files, options) {
  var sets = [files];

  resultObject.steps = [];

  methodsList.forEach(function(method) {
    logger.log('Running method: ' + method.name);
    var step = { method: method.name, before: getSetsStatsObj(sets) };
    sets = method(sets);
    step.after = getSetsStatsObj(sets);
    step.duration = hrtimeToSeconds(process.hrtime(step.before.time));
    logger.log('Method finished in ' + step.duration.toFixed(3) + ' seconds.');
    logger.verbose(JSON.stringify(step,null,3) + '\n');
    resultObject.steps.push(step);
  });
  resultObject.result = sets;
  logger.log(resultOutput(sets));
  if (options.write) fs.writeFileSync(options.targetPath + '/dupes.json', JSON.stringify(resultObject, null, 2));
}

function getSetsStatsObj(sets) {
  return { files: sets.map(function(set) { return set.length; }).reduce(sum, 0), pools: sets.length, time: process.hrtime() };
}

function hrtimeToSeconds(hrTime) {
  return hrTime[0] + hrTime[1] / 1000000000;
}

function resultOutput(sets) {
  if (sets.length == 0) return '\nThere are no suspected dupes.\n';
  var totalDuplicatesVolume = sets.map(function(set) { return (set.length - 1) * set[0].size; }).reduce(sum, 0);
  var setsByPathOnly = sets.map(function(set) { return set.map(function(file) { return file.path; })});
  var list = setsByPathOnly.map(function(set) { return set.join('\n'); }).join('\n\n');
  console.log(typeof resultObject.scanDuration);
  var totalRunDuration = resultObject.scanDuration + resultObject.steps.map(function(step) { return step.duration; }).reduce(sum, 0);
  return '\nThese are the suspected dupes:\n\n' + list + '\n\nTotal duplicate volume: ' + totalDuplicatesVolume + ' bytes' + '\nTotal run duration: ' + totalRunDuration.toFixed(3) + ' seconds.';
}

function sum(a, b) {
  return a + b;
}

<|endoftext|>


<commit_before>/**
 * Framework for making Angular Unit Test's easier to write.
 */
(function() {
  'use strict';

  /**
   * @class EasyTest
   */
  function EasyTest() {}

  /**
   * @function injectify
   * @memberof EasyTest
   * @description
   *
   * Injects a number of services and returns an object that has, as its
   * properties, the injected services.
   *
   * @param {array} injectibles An array of the names of the services to inject.
   *
   * @returns {object} An object that has, as its properties, the services that
   * were injected.
   *
   * @example
   * var services = EasyTest.injectify(['MyServiceOne', 'MyServiceTwo']);
   * expect(services.MyServiceOne).to.be.an.instanceOf(MyServiceOne);
   */
  EasyTest.injectify = function injectify(injectibles) {
    var obj = [];
    injectibles.push(function() {
      for (var i = 0, l = arguments.length; i < l; i++) {
        obj[injectibles[i]] = arguments[i];
      }
    });
    inject(injectibles);
    return obj;
  };

  /**
   * @memberof EasyTest
   * @description
   *
   * Mocks a specified module that has already been registered with angular.
   * Optionally registers a number of services with the mocked module.
   *
   * @param {string} moduleName The name of the module to mock.
   * @param {array} services An array of objects representing fake services to register
   * with the module. Each object must have a name property representing the
   * name of the service and a provider property which is the body of the
   * service, i.e. an object that has the functions and properties of the service.
   *
   * @example
   * // Mock MyModule and provide the passed fake services to it.
   * EasyTest.mockModule('MyModule', [{
   *   name: 'MyFakeServiceName', =
   *   provider: {
   *     get: function() {},
   *     name: 'ServiceName'
   *   }
   * }]);
   */
  EasyTest.mockModule = function mockModule(moduleName, services) {
    services = services || [];
    angular.mock.module(moduleName, function($provide) {
      services.forEach(function (service) {
        $provide.factory(service.name, [ function () {
          return service.provider;
        }]);
      });
    });
  };

  /**
   * @memberof EasyTest
   * @description
   *
   * Mocks a series of modules. The arguments that are passed into this function
   * can be passed in a very flexible manner. String arguments will be split
   * on their spaces and mocked directly, object arguments will be expected to
   * have a `name` property and `values` property which is an array of the
   * values to be provided for the module. See the {@link EasyTest.mockModule}
   * function for more information on how that works.
   *
   * @param {string|object} arguments A series of string or object parameters.
   *
   * @example
   * // Simply mock three modules
   * EasyTest.mockModules('one two three');
   * // or
   * EasyTest.mockModules('one two', 'three');
   * // etc, can mix and match.
   *
   * @example
   * // Mock two simple modules and a third with a fake service.
   * EasyTest.mockModules('one two', { name: 'three', values: [{
   *   name: 'FakeService',
   *   provider: { get: function() {} }
   * }]});
   */
  EasyTest.mockModules = function mockModules() {
    var modules =  Array.prototype.slice.call(arguments, 0);
    modules.forEach(function(arg) {
      if (typeof arg === 'string') {
        return arg.split(' ').forEach(function(moduleName) {
          angular.mock.module(moduleName); // Go directly to angular.mock
        });
      }
      EasyTest.mockModule(arg.name, arg.values);
    });
  };

  /**
   * @memberof EasyTest
   * @description
   *
   * Injects a specific service and returns a reference to it.
   *
   * @param {string} serviceName The name of the service to inject.
   *
   * @returns {object} The service that was injected.
   *
   * @example
   * var $q = EasyTest.getService('$q');
   */
  EasyTest.getService = function getService(serviceName) {
    return EasyTest.injectify([ serviceName ])[serviceName];
  };

  /**
   * @memberof EasyTest
   * @description
   *
   * Creates a 'test context' for a particular controller. Note that currently
   * you need to mock any modules that this controller may need beforehand.
   * See the {@link EasyTest.mockModule} function.
   *
   * @param {string} controller The name of the controller to load and create a context for.
   *
   * @returns {object} An object with a $scope and controller property representing the
   * controller that has been loaded and its scope.
   *
   * @example
   * var context = EasyTest.createTextContext('MyControllerName');
   * expect(context.$scope).to.have.property('MyExpectedProperty');
   * expect(context.controller.myFunc).to.be.a('function');
   */
  EasyTest.createTestContext = function createTestContext(controller) {
    var testContext = {};
    inject(function($rootScope, $controller) {
      var $scope = $rootScope.$new();
      testContext = {
        $scope: $scope,
        controller: $controller(controller, {
          $scope: $scope
        })
      };
    });
    return testContext;
  };

  /**
  * @memberof EasyTest
  * @description
  *
  * Gets a specific controller and returns a reference to it.
  *
  * @param {string} controllerName The name of the controller to get.
  *
  * @returns {object} The controller that was retreived.
  *
  * @example
  * var myController = EasyTest.getController('myController');
  */
  EasyTest.getController = function getController(controllerName) {
    return EasyTest.createTestContext(controllerName).controller;
  };

  /**
   * @memberof EasyTest
   * @description
   *
   * Compiles a directive and returns the top level element in the compiled
   * directive's HTML. Note that currently you need to mock any modules that
   * this directive may need beforehand. See the {@link EasyTest.mockModule} function.
   *
   * @param {string} directiveHTML The HTML of the directive to be compiled.
   * @param {object} scope a dictionary of variables that will be inserted into the element's scope.
   *
   * @returns {HTMLElement} The top level HTML element of the compiled directive.
   *
   * @example
   * var element = EasyTest.compileDirective('

');
   * expect(element.length).to.equal(expectedLength);
   */
  EasyTest.compileDirective = function compileDirective(directiveHTML, scope) {
    var $el;
    inject(function($compile, $rootScope) {
      var $scope = $rootScope.$new();
      if (scope) {
        Object.keys(scope).forEach(function(k) {
          $scope[k] = scope[k];
        });
      }
      $el = angular.element(directiveHTML);
      $compile($el)($scope);
      $scope.$digest();
    });
    return $el;
  };

  /**
   * @memberof EasyTest
   * @description
   *
   * Tests an object against a JSON specification object.
   *
   * @param {object} object The object to test.
   * @param {object} spec The 'specification' to test the object against. Should
   * have the expected types as properties and the names of the properties with
   * that type as their value, separated by spaces.
   *
   * @returns {object} An error object if anything failed, nothing if it passed.
   *
   * @example
   * // Using Chai you could pass the result directly back to 'done'
   * it('test object', function(done) {
   *   var res = EasyTest.looksLike(object, {
   *     'function': 'funcOne funcTwo',
   *     'number': 'numberOne numberTwo numberThree'
   *   });
   *   done(res);
   * });
   */
  EasyTest.looksLike = function looksLike(object, spec) {
    var types = Object.getOwnPropertyNames(spec);
    for (var i = 0; i < types.length; i++) {
      var type = types[i];
      var properties = spec[type].split(' ');
      for (var y = 0; y < properties.length; y++) {
        var property = properties[y];
        if (!(property in object)) {
          return new Error('Expected object to have the property \'' +
                           property + '\'.');
        }
        if (typeof object[property] !== type) {
          return new Error('Expected property \'' + property + '\' to be of ' +
                           'type ' + type + '.');
        }
      }
    }
  };

  /**
   * @memberof EasyTest
   * @description
   *
   * Tests a controller's scope by seeing if it conforms to a JSON specficiation
   * object. See {@link EasyTest.looksLike} for more information.
   *
   * @param {string|object} context The name of the controller to create a test
   * context for or the context itself.
   * @param {array} scopeSpec The scope's spec. An object with the names of the
   * expected types as its keys and a string for its value of all the properties,
   * separated by spaces.
   *
   * @example
   * // Will load the controller and test it using the passed spec.
   * EasyTest.testScope('MyControllerName', {
   *   'function': 'funcOne funcTwo funcThree',
   *   'number': 'numberOne numberTwo',
   *   'boolean': 'hasStuff'
   * });
   */
  EasyTest.testScope = function testScope(context, scopeSpec) {
    if (typeof context === 'string') {
      context = EasyTest.createTestContext(context);
    }
    return EasyTest.looksLike(context.$scope, scopeSpec);
  };

  /**
   * @memberof EasyTest
   * @description
   *
   * Tests a controller to see if it conforms to a JSON specification object.
   * See {@link EasyTest.looksLike} for more information.
   *
   * @param {string|object} controller The name of the controller to create or a
   * reference to a controller.
   * @param {array} spec The controller's spec. An object with the names of the
   * expected types as its keys and a string for its value of all the properties,
   * separated by spaces.
   *
   * @example
   * // Will load the controller and test it using the passed spec.
   * EasyTest.testController('MyControllerName', {
   *   'function': 'funcOne funcTwo funcThree',
   *   'number': 'numberOne numberTwo',
   *   'boolean': 'hasStuff'
   * });
   */
  EasyTest.testController = function testScope(controller, spec) {
    if (typeof controller === 'string') {
      controller = EasyTest.getController(controller);
    }
    return EasyTest.looksLike(controller, spec);
  };

  /**
  * @memberof EasyTest
  * @description
  *
  * Tests a service to see if it conforms to a JSON specification object.
  * See {@link EasyTest.looksLike} for more information.
  *
  * @param {string|object} service The name of the service to create or a
  * reference to a service.
  * @param {array} spec  The service's spec. An object with the names of the
  * expected types as its keys and a string for its value of all the properties,
  * separated by spaces.
  *
  * @example
  * // Will load the service and test it using the passed spec.
  * EasyTest.testService('MyServiceName', {
  *   'function': 'funcOne funcTwo funcThree',
  *   'number': 'numberOne numberTwo',
  *   'boolean': 'hasStuff'
  * });
  */
  EasyTest.testService = function testScope(service, spec) {
    if (typeof service === 'string') {
      service = EasyTest.getService(service);
    }
    return EasyTest.looksLike(service, spec);
  };

  window.EasyTest = EasyTest;

}());
<commit_msg>Add example for compileDirective with scope<commit_after>/**
 * Framework for making Angular Unit Test's easier to write.
 */
(function() {
  'use strict';

  /**
   * @class EasyTest
   */
  function EasyTest() {}

  /**
   * @function injectify
   * @memberof EasyTest
   * @description
   *
   * Injects a number of services and returns an object that has, as its
   * properties, the injected services.
   *
   * @param {array} injectibles An array of the names of the services to inject.
   *
   * @returns {object} An object that has, as its properties, the services that
   * were injected.
   *
   * @example
   * var services = EasyTest.injectify(['MyServiceOne', 'MyServiceTwo']);
   * expect(services.MyServiceOne).to.be.an.instanceOf(MyServiceOne);
   */
  EasyTest.injectify = function injectify(injectibles) {
    var obj = [];
    injectibles.push(function() {
      for (var i = 0, l = arguments.length; i < l; i++) {
        obj[injectibles[i]] = arguments[i];
      }
    });
    inject(injectibles);
    return obj;
  };

  /**
   * @memberof EasyTest
   * @description
   *
   * Mocks a specified module that has already been registered with angular.
   * Optionally registers a number of services with the mocked module.
   *
   * @param {string} moduleName The name of the module to mock.
   * @param {array} services An array of objects representing fake services to register
   * with the module. Each object must have a name property representing the
   * name of the service and a provider property which is the body of the
   * service, i.e. an object that has the functions and properties of the service.
   *
   * @example
   * // Mock MyModule and provide the passed fake services to it.
   * EasyTest.mockModule('MyModule', [{
   *   name: 'MyFakeServiceName', =
   *   provider: {
   *     get: function() {},
   *     name: 'ServiceName'
   *   }
   * }]);
   */
  EasyTest.mockModule = function mockModule(moduleName, services) {
    services = services || [];
    angular.mock.module(moduleName, function($provide) {
      services.forEach(function (service) {
        $provide.factory(service.name, [ function () {
          return service.provider;
        }]);
      });
    });
  };

  /**
   * @memberof EasyTest
   * @description
   *
   * Mocks a series of modules. The arguments that are passed into this function
   * can be passed in a very flexible manner. String arguments will be split
   * on their spaces and mocked directly, object arguments will be expected to
   * have a `name` property and `values` property which is an array of the
   * values to be provided for the module. See the {@link EasyTest.mockModule}
   * function for more information on how that works.
   *
   * @param {string|object} arguments A series of string or object parameters.
   *
   * @example
   * // Simply mock three modules
   * EasyTest.mockModules('one two three');
   * // or
   * EasyTest.mockModules('one two', 'three');
   * // etc, can mix and match.
   *
   * @example
   * // Mock two simple modules and a third with a fake service.
   * EasyTest.mockModules('one two', { name: 'three', values: [{
   *   name: 'FakeService',
   *   provider: { get: function() {} }
   * }]});
   */
  EasyTest.mockModules = function mockModules() {
    var modules =  Array.prototype.slice.call(arguments, 0);
    modules.forEach(function(arg) {
      if (typeof arg === 'string') {
        return arg.split(' ').forEach(function(moduleName) {
          angular.mock.module(moduleName); // Go directly to angular.mock
        });
      }
      EasyTest.mockModule(arg.name, arg.values);
    });
  };

  /**
   * @memberof EasyTest
   * @description
   *
   * Injects a specific service and returns a reference to it.
   *
   * @param {string} serviceName The name of the service to inject.
   *
   * @returns {object} The service that was injected.
   *
   * @example
   * var $q = EasyTest.getService('$q');
   */
  EasyTest.getService = function getService(serviceName) {
    return EasyTest.injectify([ serviceName ])[serviceName];
  };

  /**
   * @memberof EasyTest
   * @description
   *
   * Creates a 'test context' for a particular controller. Note that currently
   * you need to mock any modules that this controller may need beforehand.
   * See the {@link EasyTest.mockModule} function.
   *
   * @param {string} controller The name of the controller to load and create a context for.
   *
   * @returns {object} An object with a $scope and controller property representing the
   * controller that has been loaded and its scope.
   *
   * @example
   * var context = EasyTest.createTextContext('MyControllerName');
   * expect(context.$scope).to.have.property('MyExpectedProperty');
   * expect(context.controller.myFunc).to.be.a('function');
   */
  EasyTest.createTestContext = function createTestContext(controller) {
    var testContext = {};
    inject(function($rootScope, $controller) {
      var $scope = $rootScope.$new();
      testContext = {
        $scope: $scope,
        controller: $controller(controller, {
          $scope: $scope
        })
      };
    });
    return testContext;
  };

  /**
  * @memberof EasyTest
  * @description
  *
  * Gets a specific controller and returns a reference to it.
  *
  * @param {string} controllerName The name of the controller to get.
  *
  * @returns {object} The controller that was retreived.
  *
  * @example
  * var myController = EasyTest.getController('myController');
  */
  EasyTest.getController = function getController(controllerName) {
    return EasyTest.createTestContext(controllerName).controller;
  };

  /**
   * @memberof EasyTest
   * @description
   *
   * Compiles a directive and returns the top level element in the compiled
   * directive's HTML. Note that currently you need to mock any modules that
   * this directive may need beforehand. See the {@link EasyTest.mockModule} function.
   *
   * @param {string} directiveHTML The HTML of the directive to be compiled.
   * @param {object} scope a dictionary of variables that will be inserted into the element's scope.
   *
   * @returns {HTMLElement} The top level HTML element of the compiled directive.
   *
   * @example
   * var element = EasyTest.compileDirective('

');
   * expect(element.length).to.equal(expectedLength);
   *
   * @example
   * var scope = { a: 1, b: 'something' };
   * var element = EasyTest.compileDirective('
{{a}} {{b}}
', scope);
   * expect(element.text()).to.equal('1 something');
   */
  EasyTest.compileDirective = function compileDirective(directiveHTML, scope) {
    var $el;
    inject(function($compile, $rootScope) {
      var $scope = $rootScope.$new();
      if (scope) {
        Object.keys(scope).forEach(function(k) {
          $scope[k] = scope[k];
        });
      }
      $el = angular.element(directiveHTML);
      $compile($el)($scope);
      $scope.$digest();
    });
    return $el;
  };

  /**
   * @memberof EasyTest
   * @description
   *
   * Tests an object against a JSON specification object.
   *
   * @param {object} object The object to test.
   * @param {object} spec The 'specification' to test the object against. Should
   * have the expected types as properties and the names of the properties with
   * that type as their value, separated by spaces.
   *
   * @returns {object} An error object if anything failed, nothing if it passed.
   *
   * @example
   * // Using Chai you could pass the result directly back to 'done'
   * it('test object', function(done) {
   *   var res = EasyTest.looksLike(object, {
   *     'function': 'funcOne funcTwo',
   *     'number': 'numberOne numberTwo numberThree'
   *   });
   *   done(res);
   * });
   */
  EasyTest.looksLike = function looksLike(object, spec) {
    var types = Object.getOwnPropertyNames(spec);
    for (var i = 0; i < types.length; i++) {
      var type = types[i];
      var properties = spec[type].split(' ');
      for (var y = 0; y < properties.length; y++) {
        var property = properties[y];
        if (!(property in object)) {
          return new Error('Expected object to have the property \'' +
                           property + '\'.');
        }
        if (typeof object[property] !== type) {
          return new Error('Expected property \'' + property + '\' to be of ' +
                           'type ' + type + '.');
        }
      }
    }
  };

  /**
   * @memberof EasyTest
   * @description
   *
   * Tests a controller's scope by seeing if it conforms to a JSON specficiation
   * object. See {@link EasyTest.looksLike} for more information.
   *
   * @param {string|object} context The name of the controller to create a test
   * context for or the context itself.
   * @param {array} scopeSpec The scope's spec. An object with the names of the
   * expected types as its keys and a string for its value of all the properties,
   * separated by spaces.
   *
   * @example
   * // Will load the controller and test it using the passed spec.
   * EasyTest.testScope('MyControllerName', {
   *   'function': 'funcOne funcTwo funcThree',
   *   'number': 'numberOne numberTwo',
   *   'boolean': 'hasStuff'
   * });
   */
  EasyTest.testScope = function testScope(context, scopeSpec) {
    if (typeof context === 'string') {
      context = EasyTest.createTestContext(context);
    }
    return EasyTest.looksLike(context.$scope, scopeSpec);
  };

  /**
   * @memberof EasyTest
   * @description
   *
   * Tests a controller to see if it conforms to a JSON specification object.
   * See {@link EasyTest.looksLike} for more information.
   *
   * @param {string|object} controller The name of the controller to create or a
   * reference to a controller.
   * @param {array} spec The controller's spec. An object with the names of the
   * expected types as its keys and a string for its value of all the properties,
   * separated by spaces.
   *
   * @example
   * // Will load the controller and test it using the passed spec.
   * EasyTest.testController('MyControllerName', {
   *   'function': 'funcOne funcTwo funcThree',
   *   'number': 'numberOne numberTwo',
   *   'boolean': 'hasStuff'
   * });
   */
  EasyTest.testController = function testScope(controller, spec) {
    if (typeof controller === 'string') {
      controller = EasyTest.getController(controller);
    }
    return EasyTest.looksLike(controller, spec);
  };

  /**
  * @memberof EasyTest
  * @description
  *
  * Tests a service to see if it conforms to a JSON specification object.
  * See {@link EasyTest.looksLike} for more information.
  *
  * @param {string|object} service The name of the service to create or a
  * reference to a service.
  * @param {array} spec  The service's spec. An object with the names of the
  * expected types as its keys and a string for its value of all the properties,
  * separated by spaces.
  *
  * @example
  * // Will load the service and test it using the passed spec.
  * EasyTest.testService('MyServiceName', {
  *   'function': 'funcOne funcTwo funcThree',
  *   'number': 'numberOne numberTwo',
  *   'boolean': 'hasStuff'
  * });
  */
  EasyTest.testService = function testScope(service, spec) {
    if (typeof service === 'string') {
      service = EasyTest.getService(service);
    }
    return EasyTest.looksLike(service, spec);
  };

  window.EasyTest = EasyTest;

}());
<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

var http = require('http')
  , debug = require('debug')('engine:core')

/**
 * Protocol revision number.
 *
 * @api public
 */

exports.protocol = 1;

/**
 * Expose Server constructor.
 *
 * @api public
 */

exports.Server = require('./server');

/**
 * Expose Server constructor.
 *
 * @api public
 */

exports.Socket = require('./socket');

/**
 * Expose Transport constructor.
 *
 * @api public
 */

exports.Transport = require('./transport');

/**
 * Expose mutable list of available trnasports.
 *
 * @api public
 */

exports.transports = require('./transports');

/**
 * Exports parser.
 *
 * @api public
 */

exports.parser = require('./parser');

/**
 * Crates an http.Server exclusively used for WS upgrades.
 *
 * @param {Number} port
 * @param {Function} callback
 * @param {Object} options
 * @return {Server} websocket.io server
 * @api public
 */

exports.listen = function (port, options, fn) {
  if ('function' == typeof options) {
    fn = options;
    options = {};
  }

  var server = http.createServer(function (req, res) {
    res.writeHead(501);
    res.end('Not Implemented');
  });

  server.listen(port, fn);

  // create engine server
  var engine = exports.attach(server, options);
  engine.httpServer = server;

  return engine;
};

/**
 * Captures upgrade requests for a http.Server.
 *
 * @param {http.Server} server
 * @param {Object} options
 * @return {Server} engine server
 * @api public
 */

exports.attach = function (server, options) {
  var engine = new exports.Server(options)
    , options = options || {}
    , path = (options.path || '/engine.io').replace(/\/$/, '')
    , resource = options.resource || 'default'

  // normalize path
  path += '/' + resource + '/';

  function check (req) {
    return path == req.url.substr(0, path.length);
  }

  // cache and clean up listeners
  var listeners = server.listeners('request')
    , oldListeners = []

  // copy the references onto a new array for node >=0.7
  for (var i = 0, l = listeners.length; i < l; i++) {
    oldListeners[i] = listeners[i];
  }

  server.removeAllListeners('request');

  server.on('close', function () {
    engine.close();
  });

  // add request handler
  server.on('request', function (req, res) {
    if (check(req)) {
      debug('intercepting request for path "%s"', path);
      engine.handleRequest(req, res);
    } else {
      for (var i = 0, l = oldListeners.length; i < l; i++) {
        oldListeners[i].call(server, req, res);
      }
    }
  });

  if(~engine.transports.indexOf('websocket')) {
    server.on('upgrade', function (req, socket, head) {
      if (check(req)) {
        engine.handleUpgrade(req, socket, head);
      } else if (false !== options.destroyUpgrade) {
        socket.end();
      }
    });
  }

  if (~engine.transports.indexOf('flashsocket')
  && false !== options.policyFile) {
    server.on('connection', function (socket) {
      engine.handleSocket(socket);
    });
  }

  return engine;
};
<commit_msg>invoking as a function causes attach, refs #104<commit_after>/**
 * Module dependencies.
 */

var http = require('http')
  , debug = require('debug')('engine:core')

/**
 * Protocol revision number.
 *
 * @api public
 */

exports.protocol = 1;

/**
 * Expose Server constructor.
 *
 * @api public
 */

exports.Server = require('./server');

/**
 * Expose Server constructor.
 *
 * @api public
 */

exports.Socket = require('./socket');

/**
 * Expose Transport constructor.
 *
 * @api public
 */

exports.Transport = require('./transport');

/**
 * Expose mutable list of available trnasports.
 *
 * @api public
 */

exports.transports = require('./transports');

/**
 * Exports parser.
 *
 * @api public
 */

exports.parser = require('./parser');

/**
 * Crates an http.Server exclusively used for WS upgrades.
 *
 * @param {Number} port
 * @param {Function} callback
 * @param {Object} options
 * @return {Server} websocket.io server
 * @api public
 */

exports.listen = function (port, options, fn) {
  if ('function' == typeof options) {
    fn = options;
    options = {};
  }

  var server = http.createServer(function (req, res) {
    res.writeHead(501);
    res.end('Not Implemented');
  });

  server.listen(port, fn);

  // create engine server
  var engine = exports.attach(server, options);
  engine.httpServer = server;

  return engine;
};

/**
 * Captures upgrade requests for a http.Server.
 *
 * @param {http.Server} server
 * @param {Object} options
 * @return {Server} engine server
 * @api public
 */

exports.attach = function (server, options) {
  var engine = new exports.Server(options)
    , options = options || {}
    , path = (options.path || '/engine.io').replace(/\/$/, '')
    , resource = options.resource || 'default'

  // normalize path
  path += '/' + resource + '/';

  function check (req) {
    return path == req.url.substr(0, path.length);
  }

  // cache and clean up listeners
  var listeners = server.listeners('request')
    , oldListeners = []

  // copy the references onto a new array for node >=0.7
  for (var i = 0, l = listeners.length; i < l; i++) {
    oldListeners[i] = listeners[i];
  }

  server.removeAllListeners('request');

  server.on('close', function () {
    engine.close();
  });

  // add request handler
  server.on('request', function (req, res) {
    if (check(req)) {
      debug('intercepting request for path "%s"', path);
      engine.handleRequest(req, res);
    } else {
      for (var i = 0, l = oldListeners.length; i < l; i++) {
        oldListeners[i].call(server, req, res);
      }
    }
  });

  if(~engine.transports.indexOf('websocket')) {
    server.on('upgrade', function (req, socket, head) {
      if (check(req)) {
        engine.handleUpgrade(req, socket, head);
      } else if (false !== options.destroyUpgrade) {
        socket.end();
      }
    });
  }

  if (~engine.transports.indexOf('flashsocket')
  && false !== options.policyFile) {
    server.on('connection', function (socket) {
      engine.handleSocket(socket);
    });
  }

  return engine;
};

/**
 * Invoking the library as a function delegates to attach
 *
 * @param {http.Server} server
 * @param {Object} options
 * @return {Server} engine server
 * @api public
 */

module.exports = function() {
  return exports.attach.apply(this, arguments);
}

module.exports.__proto__ = exports;<|endoftext|>


<commit_before>class Evaluator {
  evaluate(workflow, context) {
    const promises = [];

    const actions = this.pluginData(workflow);
    for (const action in actions) {
      if ({}.hasOwnProperty.call(actions, action)) {
        promises.push(this[action].call(context, actions[action]));
      }
    }

    return promises;
  }
}

module.exports = Evaluator;
<commit_msg>Remove unused evaluator<commit_after><|endoftext|>