<commit_before>var _              = require('underscore'),
    uuid           = require('node-uuid'),
    backboneio     = require('backbone.io'),
    config         = require('config'),
    search_options = config.Search,
    collections    = config.Common.Collections,
    logger         = require("../logger")().addLogger('iobackends')
    publisher      = require('../pubsub')();
;

// Override mongoStore read method with custom
var searchWrapper = require('./searchWrapper.js');

var iobackends = module.exports = exports = function (db, backends) {
    var self = this;

    this.middleware = {
        debug: function (req, res, next) {
            logger.debug('Backend:', req.backend);
            logger.debug('Method: ', req.method);
            logger.debug('Channel:', req.channel);
            logger.debug('Options:', JSON.stringify(req.options));
            logger.debug('Model:  ', JSON.stringify(req.model));
            next();
        },

        uuid: function (req, res, next) {
            if( req.method == 'create' && req.model._id === undefined) {
                req.model._id = uuid.v1();
            }
            next();
        },

        publishJSON: function (req, res, next) {
            publisher.publishJSON([req.backend, req.method].join('.'), { model: req.model });
            next();
        }
    };

    if(_.isUndefined(backends) || _.isEmpty(backends)) {
        logger.info("Backends are missing");
    }

    this.backends = backends;

    /* process the backends object to streamline code */
    var binded = [];
    _(this.backends).each (function (backend) {
        backend.io = backboneio.createBackend();
        if (backend.use) {
            _(backend.use).each (function (usefn) {
                backend.io.use(usefn);
            });
        }

        /* adds a debugging middleware before the storage (see below) */
        backend.io.use (self.middleware.debug);

        /*
         * On the backend definition we either pass a 'mongo' hash with the
         * connection details or a middleware that stores data.
         *
         * This is so because most of the storage middlewares end up doing
         * a res.end() stopping the processing there and sometimes we want
         * things like the debugbackend to work.
         */

        if (backend.store) {
            backend.io.use(backend.store);

        } else if (backend.mongo) {
            var mongo = _.extend ({db: db, opts: {}}, backend.mongo);
            var fn = _.identity;
            binded.push (backend.mongo.collection);

            if (_.has(mongo.opts, 'search'))
                fn = searchWrapper;
            backend.io.use(
                fn(backboneio.middleware.mongoStore(mongo.db,
                                                    mongo.collection,
                                                    mongo.opts)));
        }
    });

    logger.info ('binding to mongo collections:', binded.join(', ') + '.');
};

iobackends.prototype.register_sync = function (collection, name) {
    logger.info ('binding sync on', name);
    var backend = this.get(name).io;

    function backend_emit (method, model) {
        var event = {create: 'created', read: 'updated', update: 'updated', delete: 'removed'};

        logger.warn ('emmiting', method);
        backend.emit (event[method], model);
    };

    function backend_sync (method, model, options) {
        var success = options.success || function (item) {logger.info  ('info:'  + item)};
        var error   = options.error   || function (err)  {logger.error ('error:' + err )};

        var res = {end: success, error: error};
        var req = {method: method, model: model.toJSON(), options: options};

        backend.handle (req, res, function(err, result) {
            if (err)
                logger.error ('while sync: ' + err);
            else
                backend_emit (method, result || model.toJSON());
        });
    }

    collection.osync = backend_sync;

    if (collection.delayed)
        while (p = collection.delayed.pop()) {
            backend_sync.apply(p);
        }
};

iobackends.prototype.emit = function (name, args) {
    var backend = this.backends[name];
    if (backend) {
        var _io = backend.io;
        _io.emit.apply(_io, args);
    } else {
        logger.error('iobackends.emit() no such backend:', name);
    }
};

iobackends.prototype.get_ios = function () {
    var ret = {};
    var self = this;
    _(_.keys(this.backends)).each (function (backend) {
        ret[backend + 'backend'] = self.backends[backend].io;
    });
    return ret;
};

iobackends.prototype.get = function (name) {
    return this.backends[name];
};

iobackends.prototype.get_middleware = function () {
    return this.middleware;
};
<commit_msg>iobackends: adds eventMiddleware from iocompat.<commit_after>var _              = require('underscore'),
    uuid           = require('node-uuid'),
    backboneio     = require('backbone.io'),
    config         = require('config'),
    search_options = config.Search,
    collections    = config.Common.Collections,
    logger         = require("../logger")().addLogger('iobackends')
    publisher      = require('../pubsub')();
    iocompat       = require('./iocompat');
;

// Override mongoStore read method with custom
var searchWrapper = require('./searchWrapper.js');

var iobackends = module.exports = exports = function (db, backends) {
    var self = this;

    this.middleware = {
        debug: function (req, res, next) {
            logger.debug('Backend:', req.backend);
            logger.debug('Method: ', req.method);
            logger.debug('Channel:', req.channel);
            logger.debug('Options:', JSON.stringify(req.options));
            logger.debug('Model:  ', JSON.stringify(req.model));
            next();
        },

        uuid: function (req, res, next) {
            if( req.method == 'create' && req.model._id === undefined) {
                req.model._id = uuid.v1();
            }
            next();
        },

        publishJSON: function (req, res, next) {
            publisher.publishJSON([req.backend, req.method].join('.'), { model: req.model });
            next();
        }
    };

    if(_.isUndefined(backends) || _.isEmpty(backends)) {
        logger.info("Backends are missing");
    }

    this.backends = backends;

    /* process the backends object to streamline code */
    var binded = [];
    _(this.backends).each (function (backend) {
        backend.io = backboneio.createBackend();
        if (backend.use) {
            _(backend.use).each (function (usefn) {
                backend.io.use(usefn);
            });
        }

        /* adds a debugging middleware before the storage (see below) */
        backend.io.use (self.middleware.debug);

        /*
         * adds the io compatibility layer middleware that forwards changes
         * from the browser as events so we can react and update our models.
         */
        backend.io.use (iocompat.eventMiddleware(backend));

        /*
         * On the backend definition we either pass a 'mongo' hash with the
         * connection details or a middleware that stores data.
         *
         * This is so because most of the storage middlewares end up doing
         * a res.end() stopping the processing there and sometimes we want
         * things like the debugbackend to work.
         */

        if (backend.store) {
            backend.io.use(backend.store);

        } else if (backend.mongo) {
            var mongo = _.extend ({db: db, opts: {}}, backend.mongo);
            var fn = _.identity;
            binded.push (backend.mongo.collection);

            if (_.has(mongo.opts, 'search'))
                fn = searchWrapper;
            backend.io.use(
                fn(backboneio.middleware.mongoStore(mongo.db,
                                                    mongo.collection,
                                                    mongo.opts)));
        }
    });

    logger.info ('binding to mongo collections:', binded.join(', ') + '.');
};

iobackends.prototype.register_sync = function (collection, name) {
    logger.info ('binding sync on', name);
    var backend = this.get(name).io;

    function backend_emit (method, model) {
        var event = {create: 'created', read: 'updated', update: 'updated', delete: 'removed'};

        logger.warn ('emmiting', method);
        backend.emit (event[method], model);
    };

    function backend_sync (method, model, options) {
        var success = options.success || function (item) {logger.info  ('info:'  + item)};
        var error   = options.error   || function (err)  {logger.error ('error:' + err )};

        var res = {end: success, error: error};
        var req = {method: method, model: model.toJSON(), options: options};

        backend.handle (req, res, function(err, result) {
            if (err)
                logger.error ('while sync: ' + err);
            else
                backend_emit (method, result || model.toJSON());
        });
    }

    collection.osync = backend_sync;

    if (collection.delayed)
        while (p = collection.delayed.pop()) {
            backend_sync.apply(p);
        }
};

iobackends.prototype.emit = function (name, args) {
    var backend = this.backends[name];
    if (backend) {
        var _io = backend.io;
        _io.emit.apply(_io, args);
    } else {
        logger.error('iobackends.emit() no such backend:', name);
    }
};

iobackends.prototype.get_ios = function () {
    var ret = {};
    var self = this;
    _(_.keys(this.backends)).each (function (backend) {
        ret[backend + 'backend'] = self.backends[backend].io;
    });
    return ret;
};

iobackends.prototype.get = function (name) {
    return this.backends[name];
};

iobackends.prototype.get_middleware = function () {
    return this.middleware;
};
<|endoftext|>


<commit_before>const server = 'ws://127.0.0.1:3000';
const badServer = 'ws://127.0.0.1:777';

function promise(resolver=()=>{}) {
  let resolve;
  let reject;
  const promise = new Promise((res, rej)=>resolver(resolve = res, reject = rej));
  promise.resolve = resolve;
  promise.reject = reject;
  return promise;
}

describe('JS-Nexus', function() {
  setSpecHelper(NexusSpecHelpers);
  manageWebSockets();
  catchMissedEvents();

  describe('user:', function() {
    let user;
    beforeEach(async function(){
      user = await Nexus(server);
    });

    describe('getHosts()', function() {
      it('only returns active hosts', async function() {
        const host1 = await Nexus(server).host('Pac-Man');
        const host2 = await Nexus(server).host('Donkey Kong');

        let list = await user.getHosts();
        this.expectHostToBeListed(host1, list);
        this.expectHostToBeListed(host2, list);

        await host1.close();
        list = await user.getHosts();
        this.expectHostNotToBeListed(host1, list);
        this.expectHostToBeListed(host2, list);

        await host2.close();
        list = await user.getHosts();
        this.expectHostNotToBeListed(host1, list);
        this.expectHostNotToBeListed(host2, list);
      });
    });

    when('the server is down', function() {
      it('triggers an else', async function() {
        let caught = promise();
        let user = Nexus(badServer).else(caught.resolve);
        await caught;
        expect(user.type).toBe('User');
      });

      it('triggers a .else even if they tried to .join', async function() {
        let caught = promise();

        let user = Nexus(badServer)
          .else(() => caught.resolve())
          .join('The Game');
        await caught;

        expect(user.type).toBe('Dead');
      });

      it('triggers a .else even if they tried to .host', async function() {
        let caught = promise();

        let user = Nexus(badServer)
          .else(() => caught.resolve())
          .host('The Game');
        await caught;

        expect(user.type).toBe('Dead');
      });
    });
  });

  describe('client:', function() {
    let client;
    beforeEach(async function(){
      client = await timebox(Nexus(server));
    });

    it('can connect to a host by name', async function() {
      const name = 'Frogger';
      const host = await timebox(Nexus(server).host(name));

      const onNewClient = host.onNewClient.then((id, request) => {
        expect(id).toBe(1);
        expect(request).toEqual({
          type: 'CONNECT',
          hostName: name,
        });
      });
      await Promise.all([
        client.join(name),
        onNewClient,
      ]);
    });

    it('can connect to a host by id', async function() {
      const host = await timebox(Nexus(server).host("Asteroids"));

      const onNewClient = host.onNewClient.then((id, request) => {
        expect(id).toBe(1);
        expect(request).toEqual({
          type: 'CONNECT',
          hostID: host.id,
        });
      });
      await Promise.all([
        client.join(host.id),
        onNewClient,
      ]);
    });

    when('connected to a host', function() {
      beforeEach(async function() {
        this.host = await Nexus(server).host('Space Invaders');

        client.join(this.host.id);
        await this.host.onNewClient;
        await client.joined;
      });

      it('can send messages to the host', async function() {
        const msg = "Hello there!";
        client.send(msg);

        await this.host.onMessage.then((message, id) => {
          expect(message).toBe(msg);
          expect(id).toBe(1);
        });
      });

      it('can receive messages from the host', async function() {
        const msg = "General Kenobi";
        this.host.send(msg);

        const message = await client.onMessage;
        expect(message).toBe(msg);
      });
    });

    when('attempting to connect to a non-existent host', function() {
      it('triggers a .else', async function() {
        let caught = promise();

        client
          .join({ hostID: -18237867 })
          .else(caught.resolve);

        await caught;

        expect(client.type).toBe('User');
      });

      it('can become a host itself', async function() {
        client.joinOrHost('Defender');
        await client.whenHosting;
        expect(client.type).toBe('Host');

        const user2 = Nexus(server).joinOrHost('Defender');
        await user2.whenJoined;
        expect(user2.type).toBe('Client');
      });
    });
  });

  describe('host:', function() {
    let host;

    beforeEach(async function() {
      host = await Nexus(server).host('Tron');
    });

    when('it has clients', function() {
      let client1;
      let client2;
      let client3;

      beforeEach(async function() {
        client1 = await Nexus(server).join(host.id);
        client2 = await Nexus(server).join(host.id);
        client3 = await Nexus(server).join(host.id);
      });

      it('does not let a message from one client leak to others', async function() {
        let msg1=null;
        let msg2=null;
        let msg3=null;

        client1.onMessage(m => msg1=m);
        client2.onMessage(m => msg2=m);
        client3.onMessage(m => msg3=m);

        function verifySecret(msg, id) {
          expect(msg).toEqual('secret');
          expect(id).toEqual(2);
        }

        client2.send('secret');
        await host.onMessage.then(verifySecret);

        client2.send('another secret');
        const msg = await host.onMessage;
        expect(msg).toBe('another secret');

        expect(msg1).toBe(null);
        expect(msg2).toBe(null);
        expect(msg3).toBe(null);
      });

      it('can message exactly one of them at a time', async function() {
        let msg1=null;
        let msg2=null;
        let msg3=null;

        client1.onMessage(m => msg1=m);
        client2.onMessage(m => msg2=m);
        client3.onMessage(m => msg3=m);

        host.send('one', 1);

        await client1.onMessage;
        expect(msg1).toEqual('one');
        expect(msg2).not.toExist();
        expect(msg3).not.toExist();

        host.send('two', 2);

        await client2.onMessage;
        expect(msg1).toEqual('one');
        expect(msg2).toEqual('two');
        expect(msg3).not.toExist();

        host.send('three', 3);

        await client3.onMessage;
        expect(msg1).toEqual('one');
        expect(msg2).toEqual('two');
        expect(msg3).toEqual('three');
      });

      it('can message multiple clients', async function() {
        let msg1=null;
        let msg2=null;
        let msg3=null;

        client1.onMessage(m => msg1=m);
        client2.onMessage(m => msg2=m);
        client3.onMessage(m => msg3=m);

        const msgOneTwo = 'one and two';
        const msgTwoThree = 'two and three';

        host.send(msgOneTwo, [1, 2]);
        await Promise.all([
          client1.onMessage,
          client2.onMessage,
        ]);

        expect(msg1).toBe(msgOneTwo);
        expect(msg2).toBe(msgOneTwo);
        expect(msg3).toBe(null);

        host.send(msgTwoThree, [2, 3]);
        await Promise.all([
          client2.onMessage,
          client3.onMessage,
        ]);

        expect(msg1).toBe(msgOneTwo);
        expect(msg2).toBe(msgTwoThree);
        expect(msg3).toBe(msgTwoThree);
      });

      it('can message all clients', async function() {
        const msg = 'all';

        host.send(msg);
        await Promise.all([
          client1.onMessage,
          client2.onMessage,
          client3.onMessage,
        ]).then(([msg1, msg2, msg3]) => {
          expect(msg1).toBe(msg);
          expect(msg2).toBe(msg);
          expect(msg3).toBe(msg);
        });
      });

      it('gets notified when a client disconnects', async function() {
        let id;

        client1.close();
        id = await host.onLostClient;
        expect(id).toEqual(1);

        client2.close();
        id = await host.onLostClient;
        expect(id).toEqual(2);
      });

      it('disconnects all clients when it closes (and handle clients that are already closed or closing)', async function() {
        await client1.close(); // close 1 early
        host.close();
        const onClose2 = client2.close(); // close 2 at the same time as host
        const onClose3 = client3.onClose; // listen for 3 to close

        await onClose2;
        await onClose3.then((code, reason) => {
          expect(code).toEqual(1001);
          expect(reason).toEqual('Host was closed');
        });
      });
    });
  });

  describe('unhandled awaitableEvents:', function() {
    when('we connect to the server', function() {
      it('shows a warning', async function() {
        const user = Nexus(server);
        const [event] = await this.warningSpy('whenServerConnected');
        expect(event.type).toEqual('open');
      });
    });

    when('we fail to connect to the server', function() {
      it('shows a warning', async function() {
        const user = Nexus(badServer);
        const [error] = await this.warningSpy('whenServerConnected.onError');
        expect(error.message).toEqual('Server connection failed');
      });
    })
  });
});
<commit_msg>Ensure warning when uncaught event: whenHosting<commit_after>const server = 'ws://127.0.0.1:3000';
const badServer = 'ws://127.0.0.1:777';

function promise(resolver=()=>{}) {
  let resolve;
  let reject;
  const promise = new Promise((res, rej)=>resolver(resolve = res, reject = rej));
  promise.resolve = resolve;
  promise.reject = reject;
  return promise;
}

describe('JS-Nexus', function() {
  setSpecHelper(NexusSpecHelpers);
  manageWebSockets();
  catchMissedEvents();

  describe('user:', function() {
    let user;
    beforeEach(async function(){
      user = await Nexus(server);
    });

    describe('getHosts()', function() {
      it('only returns active hosts', async function() {
        const host1 = await Nexus(server).host('Pac-Man');
        const host2 = await Nexus(server).host('Donkey Kong');

        let list = await user.getHosts();
        this.expectHostToBeListed(host1, list);
        this.expectHostToBeListed(host2, list);

        await host1.close();
        list = await user.getHosts();
        this.expectHostNotToBeListed(host1, list);
        this.expectHostToBeListed(host2, list);

        await host2.close();
        list = await user.getHosts();
        this.expectHostNotToBeListed(host1, list);
        this.expectHostNotToBeListed(host2, list);
      });
    });

    when('the server is down', function() {
      it('triggers an else', async function() {
        let caught = promise();
        let user = Nexus(badServer).else(caught.resolve);
        await caught;
        expect(user.type).toBe('User');
      });

      it('triggers a .else even if they tried to .join', async function() {
        let caught = promise();

        let user = Nexus(badServer)
          .else(() => caught.resolve())
          .join('The Game');
        await caught;

        expect(user.type).toBe('Dead');
      });

      it('triggers a .else even if they tried to .host', async function() {
        let caught = promise();

        let user = Nexus(badServer)
          .else(() => caught.resolve())
          .host('The Game');
        await caught;

        expect(user.type).toBe('Dead');
      });
    });
  });

  describe('client:', function() {
    let client;
    beforeEach(async function(){
      client = await timebox(Nexus(server));
    });

    it('can connect to a host by name', async function() {
      const name = 'Frogger';
      const host = await timebox(Nexus(server).host(name));

      const onNewClient = host.onNewClient.then((id, request) => {
        expect(id).toBe(1);
        expect(request).toEqual({
          type: 'CONNECT',
          hostName: name,
        });
      });
      await Promise.all([
        client.join(name),
        onNewClient,
      ]);
    });

    it('can connect to a host by id', async function() {
      const host = await timebox(Nexus(server).host("Asteroids"));

      const onNewClient = host.onNewClient.then((id, request) => {
        expect(id).toBe(1);
        expect(request).toEqual({
          type: 'CONNECT',
          hostID: host.id,
        });
      });
      await Promise.all([
        client.join(host.id),
        onNewClient,
      ]);
    });

    when('connected to a host', function() {
      beforeEach(async function() {
        this.host = await Nexus(server).host('Space Invaders');

        client.join(this.host.id);
        await this.host.onNewClient;
        await client.joined;
      });

      it('can send messages to the host', async function() {
        const msg = "Hello there!";
        client.send(msg);

        await this.host.onMessage.then((message, id) => {
          expect(message).toBe(msg);
          expect(id).toBe(1);
        });
      });

      it('can receive messages from the host', async function() {
        const msg = "General Kenobi";
        this.host.send(msg);

        const message = await client.onMessage;
        expect(message).toBe(msg);
      });
    });

    when('attempting to connect to a non-existent host', function() {
      it('triggers a .else', async function() {
        let caught = promise();

        client
          .join({ hostID: -18237867 })
          .else(caught.resolve);

        await caught;

        expect(client.type).toBe('User');
      });

      it('can become a host itself', async function() {
        client.joinOrHost('Defender');
        await client.whenHosting;
        expect(client.type).toBe('Host');

        const user2 = Nexus(server).joinOrHost('Defender');
        await user2.whenJoined;
        expect(user2.type).toBe('Client');
      });
    });
  });

  describe('host:', function() {
    let host;

    beforeEach(async function() {
      host = await Nexus(server).host('Tron');
    });

    when('it has clients', function() {
      let client1;
      let client2;
      let client3;

      beforeEach(async function() {
        client1 = await Nexus(server).join(host.id);
        client2 = await Nexus(server).join(host.id);
        client3 = await Nexus(server).join(host.id);
      });

      it('does not let a message from one client leak to others', async function() {
        let msg1=null;
        let msg2=null;
        let msg3=null;

        client1.onMessage(m => msg1=m);
        client2.onMessage(m => msg2=m);
        client3.onMessage(m => msg3=m);

        function verifySecret(msg, id) {
          expect(msg).toEqual('secret');
          expect(id).toEqual(2);
        }

        client2.send('secret');
        await host.onMessage.then(verifySecret);

        client2.send('another secret');
        const msg = await host.onMessage;
        expect(msg).toBe('another secret');

        expect(msg1).toBe(null);
        expect(msg2).toBe(null);
        expect(msg3).toBe(null);
      });

      it('can message exactly one of them at a time', async function() {
        let msg1=null;
        let msg2=null;
        let msg3=null;

        client1.onMessage(m => msg1=m);
        client2.onMessage(m => msg2=m);
        client3.onMessage(m => msg3=m);

        host.send('one', 1);

        await client1.onMessage;
        expect(msg1).toEqual('one');
        expect(msg2).not.toExist();
        expect(msg3).not.toExist();

        host.send('two', 2);

        await client2.onMessage;
        expect(msg1).toEqual('one');
        expect(msg2).toEqual('two');
        expect(msg3).not.toExist();

        host.send('three', 3);

        await client3.onMessage;
        expect(msg1).toEqual('one');
        expect(msg2).toEqual('two');
        expect(msg3).toEqual('three');
      });

      it('can message multiple clients', async function() {
        let msg1=null;
        let msg2=null;
        let msg3=null;

        client1.onMessage(m => msg1=m);
        client2.onMessage(m => msg2=m);
        client3.onMessage(m => msg3=m);

        const msgOneTwo = 'one and two';
        const msgTwoThree = 'two and three';

        host.send(msgOneTwo, [1, 2]);
        await Promise.all([
          client1.onMessage,
          client2.onMessage,
        ]);

        expect(msg1).toBe(msgOneTwo);
        expect(msg2).toBe(msgOneTwo);
        expect(msg3).toBe(null);

        host.send(msgTwoThree, [2, 3]);
        await Promise.all([
          client2.onMessage,
          client3.onMessage,
        ]);

        expect(msg1).toBe(msgOneTwo);
        expect(msg2).toBe(msgTwoThree);
        expect(msg3).toBe(msgTwoThree);
      });

      it('can message all clients', async function() {
        const msg = 'all';

        host.send(msg);
        await Promise.all([
          client1.onMessage,
          client2.onMessage,
          client3.onMessage,
        ]).then(([msg1, msg2, msg3]) => {
          expect(msg1).toBe(msg);
          expect(msg2).toBe(msg);
          expect(msg3).toBe(msg);
        });
      });

      it('gets notified when a client disconnects', async function() {
        let id;

        client1.close();
        id = await host.onLostClient;
        expect(id).toEqual(1);

        client2.close();
        id = await host.onLostClient;
        expect(id).toEqual(2);
      });

      it('disconnects all clients when it closes (and handle clients that are already closed or closing)', async function() {
        await client1.close(); // close 1 early
        host.close();
        const onClose2 = client2.close(); // close 2 at the same time as host
        const onClose3 = client3.onClose; // listen for 3 to close

        await onClose2;
        await onClose3.then((code, reason) => {
          expect(code).toEqual(1001);
          expect(reason).toEqual('Host was closed');
        });
      });
    });
  });

  describe('unhandled awaitableEvents:', function() {
    when('we connect to the server', function() {
      it('shows a warning', async function() {
        const user = Nexus(server);
        const [event] = await this.warningSpy('whenServerConnected');
        expect(event.type).toEqual('open');
      });
    });

    when('we fail to connect to the server', function() {
      it('shows a warning', async function() {
        const user = Nexus(badServer);
        const [error] = await this.warningSpy('whenServerConnected.onError');
        expect(error.message).toEqual('Server connection failed');
      });
    });

    when('we begin hosting', function() {
      it('shows a warning', async function() {
        const user = Nexus(server).host('Galaxian');
        const [hostType]= await this.warningSpy('whenHosting');
        expect(hostType.hostID).toExist();
      });
    });
  });
});
<|endoftext|>


<commit_before>/*global describe, it, sinon */

define([ 'js/app' ], function(app) {
  'use strict';

  describe('Main', function() {
    describe('Main init', function() {
      it('should be main equal Test', function() {
        app.should.be.a('object');
      });
    });
  });
});
<commit_msg>Fix broken tests<commit_after>/*global describe, it, sinon */

define(function() {
  'use strict';

  describe('Main', function() {
    describe('Main init', function() {
      it('should be main equal Test', function() {
        ({}).should.be.a('object');
      });
    });
  });
});
<|endoftext|>


<commit_before>// Copyright 2014, Renasar Technologies Inc.
/* jslint node: true */
'use strict';

describe('dihelper', function () {
    var di = require('di');
    describe("initialized ", function () {
        var dihelper = helper.require('/lib/di')(di);

        it('initialized ok', function () {
            should.exist(dihelper);
            dihelper.should.be.an('object');
        });

        describe('simpleWrapper', function () {
            var simpleWrapper = dihelper.simpleWrapper;

            it('exists', function () {
                should.exist(simpleWrapper);
            });
            it('is a function', function () {
                simpleWrapper.should.be.a('function');
            });

            describe('can inject an object', function () {
                it('simple object returns same', function () {
                    var fooObject = {foo: 'bar'};
                    var injector = new di.Injector([simpleWrapper(fooObject, 'foo')]);
                    var retrievedObject = injector.get('foo');
                    fooObject.should.equal(retrievedObject);
                });
                it('decorated simple object returns same', function () {
                    var fooObject = {foo: 'bar', $provide: 'foo'};
                    var injector = new di.Injector([simpleWrapper(fooObject)]);
                    var retrievedObject = injector.get('foo');
                    fooObject.should.equal(retrievedObject);
                });
                it('decorated simple object with override returns same', function () {
                    var fooObject = {foo: 'bar', $provide: 'foo'};
                    var injector = new di.Injector([simpleWrapper(fooObject, 'bar')]);
                    var retrievedObject = injector.get('bar');
                    fooObject.should.equal(retrievedObject);
                });
            });
            describe('can inject string', function () {
                it('simple string returns same', function () {
                    var fooObject = 'bar';
                    var injector = new di.Injector([simpleWrapper(fooObject, 'foo')]);
                    var retrievedObject = injector.get('foo');
                    fooObject.should.equal(retrievedObject);
                });
            });

            describe('can inject a function', function () {
                describe('just function provide', function () {
                    it('simple function returns same function', function () {
                        var fooObject = function (val) {
                            return 'before:' + val + ':after';
                        };
                        var injector = new di.Injector([simpleWrapper(fooObject, 'foo')]);
                        var getBack = injector.get('foo');
                        fooObject.should.equal(getBack);
                        var outputFoo = fooObject('test');
                        var outputBack = getBack('test');
                        outputFoo.should.eql(outputBack);
                    });
                    it('function returns same function', function () {
                        var fooObject = function (val) {
                            return 'before:' + val + ':after';
                        };
                        fooObject.testProperty = 'my test property';
                        var injector = new di.Injector([simpleWrapper(fooObject, 'foo')]);
                        var getBack = injector.get('foo');
                        fooObject.should.equal(getBack);
                        fooObject.testProperty.should.eql(getBack.testProperty);
                        var outputFoo = fooObject('test');
                        var outputBack = getBack('test');
                        outputFoo.should.eql(outputBack);
                    });
                    it('function decorated returns same', function () {
                        var fooObject = function () {
                            console.log('sample');
                        };
                        fooObject.$provide = 'foo';
                        var injector = new di.Injector([simpleWrapper(fooObject)]);
                        var getBack = injector.get('foo');
                        fooObject.should.equal(getBack);
                    });
                    it('function decorated with overide returns same', function () {
                        var fooObject = function () {
                            console.log('sample');
                        };
                        fooObject.$provide = 'foo';
                        var injector = new di.Injector([simpleWrapper(fooObject,
                            'myOverrideFooName')]);
                        var getBack = injector.get('myOverrideFooName');
                        fooObject.should.equal(getBack);
                    });
                });
                describe('wrap injectable modules', function () {
                    it('baseline', function () {
                        var returnedFunc;

                        function setupFoo(injectedData) {
                            function fooConcat(inputData) {
                                return injectedData + ':' + inputData;
                            }

                            returnedFunc = fooConcat;
                            return fooConcat;
                        }

                        di.annotate(setupFoo, new di.Provide('foo'));

                        var injector = new di.Injector([simpleWrapper(setupFoo, 'foo')]);
                        var getBack = injector.get('foo');
                        setupFoo.should.equal(getBack);
                    });
                });
                describe('override injectable modules', function () {
                    var overrideInjection = dihelper.overrideInjection;
                    it('overide provide and inject', function () {
                        var returnedFunc = (void 0);

                        function setupFoo(injectedData) {
                            function fooConcat(inputData) {
                                return injectedData + ':' + inputData;
                            }

                            returnedFunc = fooConcat;
                            return fooConcat;
                        }

                        di.annotate(setupFoo, new di.Provide('foo'));
                        di.annotate(setupFoo, new di.Inject('foobar'));

                        var injector = new di.Injector(
                            [simpleWrapper('test1', 'basicstring'),
                                overrideInjection(setupFoo, 'bar', 'basicstring')
                            ]);
                        var getBack = injector.get('bar');
                        should.exist(returnedFunc);
                        returnedFunc.should.equal(getBack);
                        var out = getBack('test2');
                        out.should.equal('test1:test2');
                    });
                    it('overide same injectable multiple times', function () {
                        var returnedFunc = (void 0);

                        function setupFoo(injectedData) {
                            function fooConcat(inputData) {
                                return injectedData + ':' + inputData;
                            }

                            returnedFunc = fooConcat;
                            return fooConcat;
                        }

                        di.annotate(setupFoo, new di.Provide('foo'));

                        var injector = new di.Injector([
                            simpleWrapper('test1', 'test1'),
                            simpleWrapper('test2', 'test2'),
                            overrideInjection(setupFoo, 'bar1', 'test1'),
                            overrideInjection(setupFoo, 'bar2', 'test2')
                        ]);
                        var getBack1 = injector.get('bar1');
                        returnedFunc.should.equal(getBack1);
                        var out1 = getBack1('test2');
                        out1.should.equal('test1:test2');

                        var getBack2 = injector.get('bar2');
                        returnedFunc.should.equal(getBack2);
                        var out2 = getBack2('test3');
                        out2.should.equal('test2:test3');
                    });

                });
            });
        });
        describe('and requireWrapper', function () {
            var asRequire = dihelper.requireWrapper;

            it('exists', function () {
                should.exist(asRequire);
                asRequire.should.be.a('function');
            });
            describe('plain library name', function () {
                it('just named library', function () {
                    var injector = new di.Injector([asRequire('lodash')]);
                    var injected = injector.get('lodash');
                    injected.VERSION.should.be.a('string');
                });
            });
            describe('plain library name change injected name', function () {
                it('just named library', function () {
                    var injector = new di.Injector([asRequire('lodash', 'fooService')]);
                    var injected = injector.get('fooService');
                    injected.VERSION.should.be.a('string');
                });
            });
        });
        describe('requireGlob', function () {
            it('exists', function () {
                should.exist(dihelper.requireGlob);
            });

            it('should require across directories', function () {
                dihelper.requireGlob(__dirname + '/files/**/*.js');
            });

            it('should require specific files without globs', function () {
                dihelper.requireGlob(__dirname + '/files/a/a.js');
            });
        });

        describe('requireGlobInjectables', function () {
            it('exists', function () {
                should.exist(dihelper.requireGlobInjectables);
            });

            it('should require across directories', function () {
                dihelper.requireGlobInjectables(__dirname + '/files/**/*.js');
            });

            it('should require specific files without globs', function () {
                dihelper.requireGlobInjectables(__dirname + '/files/a/a-injectable.js');
            });
        });
        describe('getAsChild', function () {
            var simpleWrapper = dihelper.simpleWrapper;
            it('basic return from function', function () {
                var fooObject = function (val) {
                    return 'before:' + val + ':after';
                };
                di.annotate(fooObject, new di.Inject('bar'));

                var barval = 'barval';
                var injector = new di.Injector([simpleWrapper(barval, 'bar')]);
                var outputBack = injector.getAsChild(fooObject);
                var outputFoo = fooObject(barval);
                outputFoo.should.eql(outputBack);
            });
        });
        describe('exec', function () {
            var simpleWrapper = dihelper.simpleWrapper;
            it('empty injector string val', function () {
                var fooObject = function (val) {
                    return 'before:' + val + ':after';
                };
                di.annotate(fooObject, new di.Inject('bar'));
                var barval = 'barval';
                var injector = new di.Injector([]);
                var outputBack = injector.exec(barval, fooObject);
                var outputFoo = fooObject(barval);
                outputFoo.should.eql(outputBack);
            });
            it('empty injector literal ob format', function () {
                var fooObject = function (val) {
                    return 'before:' + val + ':after';
                };
                di.annotate(fooObject, new di.Inject('bar'));
                var barval = 'barval';
                var injector = new di.Injector([]);
                var outputBack = injector.exec({literal: barval}, fooObject);
                var outputFoo = fooObject(barval);
                outputFoo.should.eql(outputBack);
            });
            it('exec with injected val with string token for injection', function () {
                var fooObject = function (val) {
                    return 'before:' + val + ':after';
                };
                di.annotate(fooObject, new di.Inject('bar'));
                var barval = 'barval';
                var injector = new di.Injector([simpleWrapper(barval, 'bar')]);
                var outputBack = injector.exec('bar', fooObject);
                var outputFoo = fooObject(barval);
                outputFoo.should.eql(outputBack);
            });
            it('exec with injected string using literal with module of same name in injector',
                function () {
                    var fooObject = function (val) {
                        return 'before:' + val + ':after';
                    };
                    di.annotate(fooObject, new di.Inject('bar'));
                    var barval = 'barval';
                    var injector = new di.Injector([simpleWrapper(barval, 'bar')]);
                    var outputBack = injector.exec({literal: 'bar'}, fooObject);
                    var outputFoo = fooObject('bar');
                    outputFoo.should.eql(outputBack);
            });
        });
        describe('childExec', function () {
            var simpleWrapper = dihelper.simpleWrapper;
            it('should take a list of arguments', function () {
                var foo = {foo: 1};
                var injector = new di.Injector();
                injector.childExec(
                    simpleWrapper(foo, 'foo'),
                    function (foo_) {
                        foo_.should.equal(foo);
                    });
            });
        });

        describe('getMatching', function () {
            var simpleWrapper = dihelper.simpleWrapper;
            var foo = {foo: 1};
            var bar = {bar: 2};
            var baz = {baz: 3};

            var injector = new di.Injector([
                simpleWrapper(foo, 'module.foo'),
                simpleWrapper(bar, 'module/bar'),
                simpleWrapper(baz, 'module::baz')
            ]);

            function verifyModules(given, expected) {
                given.should.have.length(expected.length);
                expected.forEach(function (mod) {
                    given.should.include(mod);
                });
            }

            it('should get tokens split by a dot using a wildcard character', function () {
                var modules = injector.getMatching('module.*');
                verifyModules(modules, [foo, bar, baz]);
            });

            it('should get tokens split by a slash using a wildcard character', function () {
                var modules = injector.getMatching('module/*');
                verifyModules(modules, [foo, bar, baz]);
            });

            it('should get tokens split by a double colon using a wildcard character', function () {
                var modules = injector.getMatching('module::*');
                verifyModules(modules, [foo, bar, baz]);
            });

            it('should get tokens from a child injector', function () {
                var qux = {qux: 4};
                var childInjector = injector.createChild([
                    simpleWrapper(qux, 'module.qux'),
                ]);
                var modules = childInjector.getMatching('module.*');
                verifyModules(modules, [foo, bar, baz, qux]);
            });
        });
    });
});

<commit_msg>adding in a few more tests where I could grok the code intention<commit_after>// Copyright 2014, Renasar Technologies Inc.
/* jslint node: true */
'use strict';

describe('dihelper', function () {
    var di = require('di');
    describe("initialized ", function () {
        var dihelper = helper.require('/lib/di')(di);

        it('initialized ok', function () {
            should.exist(dihelper);
            dihelper.should.be.an('object');
        });

        describe('simpleWrapper', function () {
            var simpleWrapper = dihelper.simpleWrapper;

            it('exists', function () {
                should.exist(simpleWrapper);
            });
            it('is a function', function () {
                simpleWrapper.should.be.a('function');
            });

            describe('can inject an object', function () {
                it('simple object returns same', function () {
                    var fooObject = {foo: 'bar'};
                    var injector = new di.Injector([simpleWrapper(fooObject, 'foo')]);
                    var retrievedObject = injector.get('foo');
                    fooObject.should.equal(retrievedObject);
                });
                it('decorated simple object returns same', function () {
                    var fooObject = {foo: 'bar', $provide: 'foo'};
                    var injector = new di.Injector([simpleWrapper(fooObject)]);
                    var retrievedObject = injector.get('foo');
                    fooObject.should.equal(retrievedObject);
                });
                it('decorated simple object with override returns same', function () {
                    var fooObject = {foo: 'bar', $provide: 'foo'};
                    var injector = new di.Injector([simpleWrapper(fooObject, 'bar')]);
                    var retrievedObject = injector.get('bar');
                    fooObject.should.equal(retrievedObject);
                });
            });
            describe('can inject string', function () {
                it('simple string returns same', function () {
                    var fooObject = 'bar';
                    var injector = new di.Injector([simpleWrapper(fooObject, 'foo')]);
                    var retrievedObject = injector.get('foo');
                    fooObject.should.equal(retrievedObject);
                });
            });

            describe('can inject a function', function () {
                describe('just function provide', function () {
                    it('simple function returns same function', function () {
                        var fooObject = function (val) {
                            return 'before:' + val + ':after';
                        };
                        var injector = new di.Injector([simpleWrapper(fooObject, 'foo')]);
                        var getBack = injector.get('foo');
                        fooObject.should.equal(getBack);
                        var outputFoo = fooObject('test');
                        var outputBack = getBack('test');
                        outputFoo.should.eql(outputBack);
                    });
                    it('function returns same function', function () {
                        var fooObject = function (val) {
                            return 'before:' + val + ':after';
                        };
                        fooObject.testProperty = 'my test property';
                        var injector = new di.Injector([simpleWrapper(fooObject, 'foo')]);
                        var getBack = injector.get('foo');
                        fooObject.should.equal(getBack);
                        fooObject.testProperty.should.eql(getBack.testProperty);
                        var outputFoo = fooObject('test');
                        var outputBack = getBack('test');
                        outputFoo.should.eql(outputBack);
                    });
                    it('function decorated returns same', function () {
                        var fooObject = function () {
                            console.log('sample');
                        };
                        fooObject.$provide = 'foo';
                        var injector = new di.Injector([simpleWrapper(fooObject)]);
                        var getBack = injector.get('foo');
                        fooObject.should.equal(getBack);
                    });
                    it('function decorated with overide returns same', function () {
                        var fooObject = function () {
                            console.log('sample');
                        };
                        fooObject.$provide = 'foo';
                        var injector = new di.Injector([simpleWrapper(fooObject,
                            'myOverrideFooName')]);
                        var getBack = injector.get('myOverrideFooName');
                        fooObject.should.equal(getBack);
                    });
                });
                describe('wrap injectable modules', function () {
                    it('baseline', function () {
                        var returnedFunc;

                        function setupFoo(injectedData) {
                            function fooConcat(inputData) {
                                return injectedData + ':' + inputData;
                            }

                            returnedFunc = fooConcat;
                            return fooConcat;
                        }

                        di.annotate(setupFoo, new di.Provide('foo'));

                        var injector = new di.Injector([simpleWrapper(setupFoo, 'foo')]);
                        var getBack = injector.get('foo');
                        setupFoo.should.equal(getBack);
                    });
                });
                describe('override injectable modules', function () {
                    var overrideInjection = dihelper.overrideInjection;
                    it('overide provide and inject', function () {
                        var returnedFunc = (void 0);

                        function setupFoo(injectedData) {
                            function fooConcat(inputData) {
                                return injectedData + ':' + inputData;
                            }

                            returnedFunc = fooConcat;
                            return fooConcat;
                        }

                        di.annotate(setupFoo, new di.Provide('foo'));
                        di.annotate(setupFoo, new di.Inject('foobar'));

                        var injector = new di.Injector(
                            [simpleWrapper('test1', 'basicstring'),
                                overrideInjection(setupFoo, 'bar', 'basicstring')
                            ]);
                        var getBack = injector.get('bar');
                        should.exist(returnedFunc);
                        returnedFunc.should.equal(getBack);
                        var out = getBack('test2');
                        out.should.equal('test1:test2');
                    });
                    it('overide same injectable multiple times', function () {
                        var returnedFunc = (void 0);

                        function setupFoo(injectedData) {
                            function fooConcat(inputData) {
                                return injectedData + ':' + inputData;
                            }

                            returnedFunc = fooConcat;
                            return fooConcat;
                        }

                        di.annotate(setupFoo, new di.Provide('foo'));

                        var injector = new di.Injector([
                            simpleWrapper('test1', 'test1'),
                            simpleWrapper('test2', 'test2'),
                            overrideInjection(setupFoo, 'bar1', 'test1'),
                            overrideInjection(setupFoo, 'bar2', 'test2')
                        ]);
                        var getBack1 = injector.get('bar1');
                        returnedFunc.should.equal(getBack1);
                        var out1 = getBack1('test2');
                        out1.should.equal('test1:test2');

                        var getBack2 = injector.get('bar2');
                        returnedFunc.should.equal(getBack2);
                        var out2 = getBack2('test3');
                        out2.should.equal('test2:test3');
                    });

                });
            });
        });
        describe('and requireWrapper', function () {
            var asRequire = dihelper.requireWrapper;

            it('exists', function () {
                should.exist(asRequire);
                asRequire.should.be.a('function');
            });
            describe('plain library name', function () {
                it('just named library', function () {
                    var injector = new di.Injector([asRequire('lodash')]);
                    var injected = injector.get('lodash');
                    injected.VERSION.should.be.a('string');
                });
            });
            describe('plain library name change injected name', function () {
                it('just named library', function () {
                    var injector = new di.Injector([asRequire('lodash', 'fooService')]);
                    var injected = injector.get('fooService');
                    injected.VERSION.should.be.a('string');
                });
            });
        });
        describe('requireGlob', function () {
            it('exists', function () {
                should.exist(dihelper.requireGlob);
            });

            it('should require across directories', function () {
                dihelper.requireGlob(__dirname + '/files/**/*.js');
            });

            it('should require specific files without globs', function () {
                dihelper.requireGlob(__dirname + '/files/a/a.js');
            });
        });

        describe('requireGlobInjectables', function () {
            it('exists', function () {
                should.exist(dihelper.requireGlobInjectables);
            });

            it('should require across directories', function () {
                dihelper.requireGlobInjectables(__dirname + '/files/**/*.js');
            });

            it('should require specific files without globs', function () {
                dihelper.requireGlobInjectables(__dirname + '/files/a/a-injectable.js');
            });
        });
        describe('getAsChild', function () {
            var simpleWrapper = dihelper.simpleWrapper;
            it('basic return from function', function () {
                var fooObject = function (val) {
                    return 'before:' + val + ':after';
                };
                di.annotate(fooObject, new di.Inject('bar'));

                var barval = 'barval';
                var injector = new di.Injector([simpleWrapper(barval, 'bar')]);
                var outputBack = injector.getAsChild(fooObject);
                var outputFoo = fooObject(barval);
                outputFoo.should.eql(outputBack);
            });
        });
        describe('exec', function () {
            var simpleWrapper = dihelper.simpleWrapper;
            it("should throw error if last argument isn't a function", function() {
                var fooObject = {};
                var injector = new di.Injector([]);
                expect(function() {
                    injector.exec('blah', fooObject);
                }).to.throw(Error, 'last argument must be a function');
            });
            it('empty injector string val', function () {
                var fooObject = function (val) {
                    return 'before:' + val + ':after';
                };
                di.annotate(fooObject, new di.Inject('bar'));
                var barval = 'barval';
                var injector = new di.Injector([]);
                var outputBack = injector.exec(barval, fooObject);
                var outputFoo = fooObject(barval);
                outputFoo.should.eql(outputBack);
            });
            it('empty injector literal ob format', function () {
                var fooObject = function (val) {
                    return 'before:' + val + ':after';
                };
                di.annotate(fooObject, new di.Inject('bar'));
                var barval = 'barval';
                var injector = new di.Injector([]);
                var outputBack = injector.exec({literal: barval}, fooObject);
                var outputFoo = fooObject(barval);
                outputFoo.should.eql(outputBack);
            });
            it('exec with injected val with string token for injection', function () {
                var fooObject = function (val) {
                    return 'before:' + val + ':after';
                };
                di.annotate(fooObject, new di.Inject('bar'));
                var barval = 'barval';
                var injector = new di.Injector([simpleWrapper(barval, 'bar')]);
                var outputBack = injector.exec('bar', fooObject);
                var outputFoo = fooObject(barval);
                outputFoo.should.eql(outputBack);
            });
            it('exec with injected string using literal with module of same name in injector',
                function () {
                    var fooObject = function (val) {
                        return 'before:' + val + ':after';
                    };
                    di.annotate(fooObject, new di.Inject('bar'));
                    var barval = 'barval';
                    var injector = new di.Injector([simpleWrapper(barval, 'bar')]);
                    var outputBack = injector.exec({literal: 'bar'}, fooObject);
                    var outputFoo = fooObject('bar');
                    outputFoo.should.eql(outputBack);
            });
        });
        describe('childExec', function () {
            var simpleWrapper = dihelper.simpleWrapper;
            it('should take a list of arguments', function () {
                var foo = {foo: 1};
                var injector = new di.Injector();
                injector.childExec(
                    simpleWrapper(foo, 'foo'),
                    function (foo_) {
                        foo_.should.equal(foo);
                    });
            });
            it("should throw error if last argument isn't a function", function() {
                var foo = {foo: 1};
                var injector = new di.Injector();
                expect(function() {
                    injector.childExec(
                        simpleWrapper(foo, 'foo'),
                        { notAFunction: 1 });
                }).to.throw(Error, 'last argument must be a function');
            });
        });

        describe('getMatching', function () {
            var simpleWrapper = dihelper.simpleWrapper;
            var foo = {foo: 1};
            var bar = {bar: 2};
            var baz = {baz: 3};

            var injector = new di.Injector([
                simpleWrapper(foo, 'module.foo'),
                simpleWrapper(bar, 'module/bar'),
                simpleWrapper(baz, 'module::baz')
            ]);

            function verifyModules(given, expected) {
                given.should.have.length(expected.length);
                expected.forEach(function (mod) {
                    given.should.include(mod);
                });
            }
            it('should throw an error if not a string or regex', function () {
                expect(function() {
                    injector.getMatching({});
                }).to.throw(Error, 'pattern must be a string or RegExp');
            });

            it('should get tokens split by a dot using a wildcard character', function () {
                var modules = injector.getMatching('module.*');
                verifyModules(modules, [foo, bar, baz]);
            });

            it('should get tokens split by a slash using a wildcard character', function () {
                var modules = injector.getMatching('module/*');
                verifyModules(modules, [foo, bar, baz]);
            });

            it('should get tokens split by a double colon using a wildcard character', function () {
                var modules = injector.getMatching('module::*');
                verifyModules(modules, [foo, bar, baz]);
            });

            it('should get tokens from a child injector', function () {
                var qux = {qux: 4};
                var childInjector = injector.createChild([
                    simpleWrapper(qux, 'module.qux'),
                ]);
                var modules = childInjector.getMatching('module.*');
                verifyModules(modules, [foo, bar, baz, qux]);
            });
        });
    });
    describe("provideName", function() {
        it("throws an error if token isn't a string", function() {
            var dihelper = helper.require('/lib/di')(di);
            expect(function() {
                dihelper.testFunctions.provideName({}, 123)
            }).to.throw(Error, 'Must provide string as name of module');
        });
    });
    describe("addInject", function() {
        it("should return immediately if inject doesn't exist", function() {
            var obj = {}
            var dihelper = helper.require('/lib/di')(di);
            dihelper.testFunctions.addInject(obj);
        });
    });
});

<|endoftext|>


<commit_before>/*
==================================================================================================
  Jasy - JavaScript Tooling Framework
  Copyright 2010-2011 Sebastian Werner
--------------------------------------------------------------------------------------------------
  Inspired by: http://www.phpied.com/when-is-a-stylesheet-really-loaded/
==================================================================================================
*/

(function(global, doc)
{
	var completed = {};
	var loading = {};

	/**
	 * Stylesheet (CSS) loader and manager. Tracks status of all loaded files.
	 */
	Module("jasy.io.StyleSheet",
	{
		/**
		 * Whether the given stylesheet is loaded.
		 *
		 * @param url {String} URL pointing to the stylesheet
		 * @return {Boolean} Whether the stylesheet is loaded
		 */
		isLoaded : function(url) {
			return !!completed[url];
		},

		/**
		 * Loads a stylesheet and fires a callback when the stylesheet is applied to the page.
		 *
		 * Inspired by:
		 * http://www.phpied.com/when-is-a-stylesheet-really-loaded/
		 *
		 * @param url {String} URL pointing to the stylesheet
		 * @param callback {Function} Callback that fires when stylesheet is loaded
		 * @param context {Object} Context in which the callback is being executed. Defaults to global context.
		 */
		load: function(url, callback, context)
		{
			var head = doc.getElementsByTagName('head')[0];

			context = context || global;

			if (loading[url]) {
				throw new Error("Stylesheet is already loading: " + url);
			}

			loading[url] = true;

			var load = function load()
			{
				completed[url] = true;
				delete loading[url];

				if (callback) {
					callback.call(context);
				}
			};

			// Use listener to stylesheet list and compare elements
			if (jasy.Env.isSet("engine", "webkit"))
			{
				var link = doc.createElement('link');
				var sheets = doc.styleSheets;
				var startPos = sheets.length;

				handle = setInterval(function()
				{
					for (var i = 0, l = sheets.length; i < l; i++)
					{
						if (sheets[i].ownerNode === link)
						{
							clearInterval(handle);
							load();
						}
					}
				}, 10);

				link.rel = "stylesheet";
				link.type = "text/css";
				link.href = url;

				head.appendChild(link);
			}

			// Use style import fallback for buggy GECKO
			else if (jasy.Env.isSet("engine", "gecko"))
			{
				var style = doc.createElement("style");
				style.textContent = "@import '" + url + "'";

				var handle = setInterval(function()
				{
					try
					{
						// MAGIC: only populated when file is loaded
						style.sheet.cssRules;
						clearInterval(handle);
						load();
					} catch(e) {}
				}, 10);

				head.appendChild(style);
			}

			// Load event only supported by MSIE and OPERA
			else
			{
				var link = doc.createElement("link");
				link.onload = function()
				{
					link.onload = null;
					load();
				};

				link.rel = "stylesheet";
				link.type = "text/css";
				link.href = url;

				head.appendChild(link);
			}
		}
	});
})(this, document);
<commit_msg>Added possibility to have no-cache stylesheets. Enabled by default on debug variant - otherwise false.<commit_after>/*
==================================================================================================
  Jasy - JavaScript Tooling Framework
  Copyright 2010-2011 Sebastian Werner
--------------------------------------------------------------------------------------------------
  Inspired by: http://www.phpied.com/when-is-a-stylesheet-really-loaded/
==================================================================================================
*/

(function(global, doc)
{
	var completed = {};
	var loading = {};
	var dynamicUri = "?r=" + Date.now();

	/**
	 * Stylesheet (CSS) loader and manager. Tracks status of all loaded files.
	 */
	Module("jasy.io.StyleSheet",
	{
		/**
		 * Whether the given stylesheet is loaded.
		 *
		 * @param url {String} URL pointing to the stylesheet
		 * @return {Boolean} Whether the stylesheet is loaded
		 */
		isLoaded : function(url) {
			return !!completed[url];
		},

		/**
		 * Loads a stylesheet and fires a callback when the stylesheet is applied to the page.
		 *
		 * Inspired by:
		 * http://www.phpied.com/when-is-a-stylesheet-really-loaded/
		 *
		 * @param url {String} URL pointing to the stylesheet
		 * @param callback {Function} Callback that fires when stylesheet is loaded
		 * @param context {Object} Context in which the callback is being executed. Defaults to global context.
		 * @param nocache {Boolean?false} Appends a dynamic parameter to each script to force a fresh copy
		 */
		load: function(url, callback, context, nocache)
		{
			var head = doc.getElementsByTagName('head')[0];

			if (jasy.Env.isSet("debug")) {
				nocache = true;
			}

			context = context || global;

			if (loading[url]) {
				throw new Error("Stylesheet is already loading: " + url);
			}

			loading[url] = true;

			var load = function load()
			{
				completed[url] = true;
				delete loading[url];

				if (callback) {
					callback.call(context);
				}
			};

			// Use listener to stylesheet list and compare elements
			if (jasy.Env.isSet("engine", "webkit"))
			{
				var link = doc.createElement('link');
				var sheets = doc.styleSheets;
				var startPos = sheets.length;

				handle = setInterval(function()
				{
					for (var i = 0, l = sheets.length; i < l; i++)
					{
						if (sheets[i].ownerNode === link)
						{
							clearInterval(handle);
							load();
						}
					}
				}, 10);

				link.rel = "stylesheet";
				link.type = "text/css";
				link.href = url + (nocache ? dynamicUri : "");

				head.appendChild(link);
			}

			// Use style import fallback for buggy GECKO
			else if (jasy.Env.isSet("engine", "gecko"))
			{
				var style = doc.createElement("style");
				style.textContent = "@import '" + url + (nocache ? dynamicUri : "") + "'";

				var handle = setInterval(function()
				{
					try
					{
						// MAGIC: only populated when file is loaded
						style.sheet.cssRules;
						clearInterval(handle);
						load();
					} catch(e) {}
				}, 30);

				head.appendChild(style);
			}

			// Load event only supported by MSIE and OPERA
			else
			{
				var link = doc.createElement("link");
				link.onload = function()
				{
					link.onload = null;
					load();
				};

				link.rel = "stylesheet";
				link.type = "text/css";
				link.href = url + (nocache ? dynamicUri : "");

				head.appendChild(link);
			}
		}
	});
})(this, document);
<|endoftext|>


<commit_before>'use strict';

var esj = require('escomplex-js');
var expect = require('expect.js');
var glob = require('glob');

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

var options = {
  'max_complexity': 6,
  'max_cyclomatic_density': 110,
  'max_dependencies': 10,
  'maintainability': 100
};

describe('Code complexity', function () {
  // find all source files
  var codeFiles = glob.sync('lib/**/*.js');
  // loop through them
  codeFiles.forEach(function (file) {

    describe(file, function () {
      // get the absolute path
      file = path.resolve(file);
      // read the file
      var code = fs.readFileSync(file, 'utf-8');

      // calculate the complexity
      var analysis = esj.analyse(code);

      // Halstead
      // TO-DO: analysis.aggregate.halstead

      // Complexity
      describe('functions', function () {
        var fns = analysis.functions || [];
        fns.forEach(function (fn) {
          it(fn.name, function () {
            // TO-DO: add checks on fn.halstead
            expect(fn.cyclomatic).to.be.lessThan(options.max_complexity);
            expect(fn.cyclomaticDensity).to.be.lessThan(options.max_cyclomatic_density);
          });
        });
      });

      // prevent too many dependencies
      it('dependencies', function () {
        expect(analysis.dependencies.length).to.be.lessThan(options.max_dependencies);
      });

      // keep functions maintainable
      it('maintainability', function () {
        expect(analysis.maintainability).to.be.greaterThan(options.maintainability);
      });
    });
  });
});
<commit_msg>simplify complexity specs<commit_after>'use strict';

var esj = require('escomplex-js');
var expect = require('expect.js');
var glob = require('glob');

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

var options = {
  'max_complexity': 6,
  'max_cyclomatic_density': 101,
  'max_dependencies': 6,
  'maintainability': 110
};

describe('Code complexity', function () {
  // find all source files
  var codeFiles = glob.sync('lib/**/*.js');
  // loop through them
  codeFiles.forEach(function (file) {

    it(file, function () {
      // get the absolute path
      file = path.resolve(file);
      // read the file
      var code = fs.readFileSync(file, 'utf-8');

      // calculate the complexity
      var analysis = esj.analyse(code);

      // Halstead
      // TO-DO: analysis.aggregate.halstead

      // Complexity
      var fns = analysis.functions || [];
      fns.forEach(function (fn) {
        it(fn.name, function () {
          // TO-DO: add checks on fn.halstead
          expect(fn.cyclomatic).to.be.lessThan(options.max_complexity);
          expect(fn.cyclomaticDensity).to.be.lessThan(options.max_cyclomatic_density);
        });
      });

      // prevent too many dependencies
      expect(analysis.dependencies.length).to.be.lessThan(options.max_dependencies);

      // keep functions maintainable
      expect(analysis.maintainability).to.be.greaterThan(options.maintainability);
    });
  });
});
<|endoftext|>


<commit_before><commit_msg>_c -> originalColor<commit_after><|endoftext|>


<commit_before>var request = require('superagent');<commit_msg>Adds tests for Roles<commit_after>var url = 'http://localhost:3000',
  request = require('superagent');

describe('Roles', function() {
  it('validates that the seeded roles are stored in database', function(done) {
    request
      .get(url + '/api/users/roles')
      .end(function(err, res) {
        // expected responses after seeding
        if (err) {
          return err;
        } else {
          expect(200, done);
          expect('Content-Type', 'json', done);
          expect(res.body.length).toEqual(2);
          expect(res.body[0].id).toEqual(1);
          expect(res.body[0].title).toEqual('Administrator');
          expect(res.body[1].id).toEqual(2);
          expect(res.body[1].title).toEqual('User');
          done();
        }
      });
  });

  it("validates that a new role created has a unique title", function() {
    expect(true).toBe(true);
  });

  it("validates that all documents are returned, limited by a specified number, when getAllDocuments is called", function() {
    expect(true).toBe(true);
  });

  it("validates that all documents are returned in order of their published dates, starting from the most recent when getAllDocuments is called", function() {
    expect(true).toBe(true);
  });

});
<|endoftext|>


<commit_before>exports.BattlePokedex = {
	butterfree: {
		inherit: true,
		baseStats: {hp:60,atk:45,def:50,spa:80,spd:80,spe:70},
		abilities: {0:"Compound Eyes"}
	},
	beedrill: {
		inherit: true,
		baseStats: {hp:65,atk:80,def:40,spa:45,spd:80,spe:75},
		abilities: {0:"Swarm"}
	},
	pikachu: {
		inherit: true,
		baseStats: {hp:35,atk:55,def:30,spa:50,spd:40,spe:90},
		abilities: {0:"Static"}
	},
	raichu: {
		inherit: true,
		baseStats: {hp:60,atk:90,def:55,spa:90,spd:80,spe:100},
		abilities: {0:"Static"}
	},
	clefairy: {
		inherit: true,
		types:["Normal"],
		baseStats: {hp:70,atk:45,def:48,spa:60,spd:65,spe:35},
		abilities: {0:"Cute Charm",1:"Magic Guard"}
	},
	clefable: {
		inherit: true,
		types:["Normal"],
		baseStats: {hp:95,atk:70,def:73,spa:85,spd:90,spe:60},
		abilities: {0:"Cute Charm",1:"Magic Guard"}
	},
	jigglypuff: {
		inherit: true,
		types:["Normal"],
		abilities: {0:"Cute Charm"}
	},
	wigglytuff: {
		inherit: true,
		types:["Normal"],
		baseStats: {hp:140,atk:70,def:45,spa:75,spd:50,spe:45},
		abilities: {0:"Cute Charm"}
	},
	alakazam: {
		inherit: true,
		baseStats: {hp:55,atk:50,def:45,spa:135,spd:85,spe:120},
		abilities: {0:"Synchronize",1:"Inner Focus"}
	},
	golem: {
		inherit: true,
		baseStats: {hp:80,atk:120,def:130,spa:55,spd:65,spe:45},
		abilities: {0:"Rock Head",1:"Sturdy"}
	},
	mrmime: {
		inherit: true,
		baseStats: {hp:40,atk:45,def:65,spa:100,spd:120,spe:90},
		abilities: {0:"Soundproof",1:"Filter"}
	},
	igglybuff: {
		inherit: true,
		abilities: {0:"Cute Charm"}
	},
	togepi: {
		inherit: true,
		baseStats: {hp:35,atk:20,def:65,spa:40,spd:65,spe:20},
		abilities: {0:"Hustle",1:"Serene Grace"}
	},
	togetic: {
		inherit: true,
		baseStats: {hp:55,atk:40,def:85,spa:80,spd:105,spe:40},
		abilities: {0:"Hustle",1:"Serene Grace"}
	},
	cleffa: {
		inherit: true,
		baseStats: {hp:50,atk:25,def:28,spa:45,spd:55,spe:15},
		abilities: {0:"Cute Charm",1:"Magic Guard"}
	},
	marill: {
		inherit: true,
		types:["Water"],
		baseStats: {hp:70,atk:20,def:50,spa:20,spd:50,spe:40},
		abilities: {0:"Thick Fat",1:"Huge Power"}
	},
	azumarill: {
		inherit: true,
		types:["Water"],
		baseStats: {hp:100,atk:50,def:80,spa:50,spd:80,spe:50},
		abilities: {0:"Thick Fat",1:"Huge Power"}
	},
	snubbull: {
		inherit: true,
		types:["Normal"],
		baseStats: {hp:60,atk:80,def:50,spa:40,spd:40,spe:30},
		abilities: {0:"Intimidate",1:"Run Away"}
	},
	granbull: {
		inherit: true,
		types:["Normal"],
		baseStats: {hp:90,atk:120,def:75,spa:60,spd:60,spe:45},
		abilities: {0:"Intimidate",1:"Quick Feet"}
	},
	ralts: {
		inherit: true,
		types:["Psychic"],
		baseStats: {hp:28,atk:25,def:25,spa:45,spd:35,spe:40},
		abilities: {0:"Synchronize",1:"Trace"}
	},
	kirlia: {
		inherit: true,
		types:["Psychic"],
		baseStats: {hp:38,atk:35,def:35,spa:65,spd:55,spe:50},
		abilities: {0:"Synchronize",1:"Trace"}
	},
	gardevoir: {
		inherit: true,
		types:["Psychic"],
		baseStats: {hp:68,atk:65,def:65,spa:125,spd:115,spe:80},
		abilities: {0:"Synchronize",1:"Trace"}
	},
	azurill: {
		inherit: true,
		types:["Normal"],
		baseStats: {hp:50,atk:20,def:40,spa:20,spd:40,spe:20},
		abilities: {0:"Thick Fat",1:"Huge Power"}
	},
	mawile: {
		inherit: true,
		baseStats: {hp:50,atk:85,def:85,spa:55,spd:55,spe:50},
		abilities: {0:"Hyper Cutter",1:"Intimidate"}
	},
	plusle: {
		inherit: true,
		baseStats: {hp:60,atk:50,def:40,spa:85,spd:75,spe:95},
		abilities: {0:"Plus"}
	},
	minun: {
		inherit: true,
		baseStats: {hp:60,atk:40,def:50,spa:75,spd:85,spe:95},
		abilities: {0:"Minus"}
	},
	kecleon: {
		inherit: true,
		baseStats: {hp:60,atk:90,def:70,spa:60,spd:120,spe:40},
		abilities: {0:"Color Change"}
	},
	duskull: {
		inherit: true,
		abilities: {0:"Levitate"}
	},
	dusclops: {
		inherit: true,
		abilities: {0:"Pressure"}
	},
	starly: {
		inherit: true,
		abilities: {0:"Keen Eye"}
	},
	staraptor: {
		inherit: true,
		baseStats: {hp:85,atk:120,def:70,spa:50,spd:50,spe:100},
		abilities: {0:"Intimidate"}
	},
	togekiss: {
		inherit: true,
		types:["Normal","Flying"],
		baseStats: {hp:85,atk:50,def:95,spa:120,spd:115,spe:80},
		abilities: {0:"Hustle",1:"Serene Grace"}
	},
	dusknoir: {
		inherit: true,
		baseStats: {hp:45,atk:100,def:135,spa:65,spd:135,spe:45},
		abilities: {0:"Pressure"}
	},
	rotomheat: {
		inherit: true,
		types: ["Electric", "Ghost"]
	},
	rotomwash: {
		inherit: true,
		types: ["Electric", "Ghost"]
	},
	rotomfrost: {
		inherit: true,
		types: ["Electric", "Ghost"]
	},
	rotomfan: {
		inherit: true,
		types: ["Electric", "Ghost"]
	},
	rotommow: {
		inherit: true,
		types: ["Electric", "Ghost"]
	}
};
<commit_msg>Fixing Golem's base Attack in Gen 4<commit_after>exports.BattlePokedex = {
	butterfree: {
		inherit: true,
		baseStats: {hp:60,atk:45,def:50,spa:80,spd:80,spe:70},
		abilities: {0:"Compound Eyes"}
	},
	beedrill: {
		inherit: true,
		baseStats: {hp:65,atk:80,def:40,spa:45,spd:80,spe:75},
		abilities: {0:"Swarm"}
	},
	pikachu: {
		inherit: true,
		baseStats: {hp:35,atk:55,def:30,spa:50,spd:40,spe:90},
		abilities: {0:"Static"}
	},
	raichu: {
		inherit: true,
		baseStats: {hp:60,atk:90,def:55,spa:90,spd:80,spe:100},
		abilities: {0:"Static"}
	},
	clefairy: {
		inherit: true,
		types:["Normal"],
		baseStats: {hp:70,atk:45,def:48,spa:60,spd:65,spe:35},
		abilities: {0:"Cute Charm",1:"Magic Guard"}
	},
	clefable: {
		inherit: true,
		types:["Normal"],
		baseStats: {hp:95,atk:70,def:73,spa:85,spd:90,spe:60},
		abilities: {0:"Cute Charm",1:"Magic Guard"}
	},
	jigglypuff: {
		inherit: true,
		types:["Normal"],
		abilities: {0:"Cute Charm"}
	},
	wigglytuff: {
		inherit: true,
		types:["Normal"],
		baseStats: {hp:140,atk:70,def:45,spa:75,spd:50,spe:45},
		abilities: {0:"Cute Charm"}
	},
	alakazam: {
		inherit: true,
		baseStats: {hp:55,atk:50,def:45,spa:135,spd:85,spe:120},
		abilities: {0:"Synchronize",1:"Inner Focus"}
	},
	golem: {
		inherit: true,
		abilities: {0:"Rock Head",1:"Sturdy"}
	},
	mrmime: {
		inherit: true,
		baseStats: {hp:40,atk:45,def:65,spa:100,spd:120,spe:90},
		abilities: {0:"Soundproof",1:"Filter"}
	},
	igglybuff: {
		inherit: true,
		abilities: {0:"Cute Charm"}
	},
	togepi: {
		inherit: true,
		baseStats: {hp:35,atk:20,def:65,spa:40,spd:65,spe:20},
		abilities: {0:"Hustle",1:"Serene Grace"}
	},
	togetic: {
		inherit: true,
		baseStats: {hp:55,atk:40,def:85,spa:80,spd:105,spe:40},
		abilities: {0:"Hustle",1:"Serene Grace"}
	},
	cleffa: {
		inherit: true,
		baseStats: {hp:50,atk:25,def:28,spa:45,spd:55,spe:15},
		abilities: {0:"Cute Charm",1:"Magic Guard"}
	},
	marill: {
		inherit: true,
		types:["Water"],
		baseStats: {hp:70,atk:20,def:50,spa:20,spd:50,spe:40},
		abilities: {0:"Thick Fat",1:"Huge Power"}
	},
	azumarill: {
		inherit: true,
		types:["Water"],
		baseStats: {hp:100,atk:50,def:80,spa:50,spd:80,spe:50},
		abilities: {0:"Thick Fat",1:"Huge Power"}
	},
	snubbull: {
		inherit: true,
		types:["Normal"],
		baseStats: {hp:60,atk:80,def:50,spa:40,spd:40,spe:30},
		abilities: {0:"Intimidate",1:"Run Away"}
	},
	granbull: {
		inherit: true,
		types:["Normal"],
		baseStats: {hp:90,atk:120,def:75,spa:60,spd:60,spe:45},
		abilities: {0:"Intimidate",1:"Quick Feet"}
	},
	ralts: {
		inherit: true,
		types:["Psychic"],
		baseStats: {hp:28,atk:25,def:25,spa:45,spd:35,spe:40},
		abilities: {0:"Synchronize",1:"Trace"}
	},
	kirlia: {
		inherit: true,
		types:["Psychic"],
		baseStats: {hp:38,atk:35,def:35,spa:65,spd:55,spe:50},
		abilities: {0:"Synchronize",1:"Trace"}
	},
	gardevoir: {
		inherit: true,
		types:["Psychic"],
		baseStats: {hp:68,atk:65,def:65,spa:125,spd:115,spe:80},
		abilities: {0:"Synchronize",1:"Trace"}
	},
	azurill: {
		inherit: true,
		types:["Normal"],
		baseStats: {hp:50,atk:20,def:40,spa:20,spd:40,spe:20},
		abilities: {0:"Thick Fat",1:"Huge Power"}
	},
	mawile: {
		inherit: true,
		baseStats: {hp:50,atk:85,def:85,spa:55,spd:55,spe:50},
		abilities: {0:"Hyper Cutter",1:"Intimidate"}
	},
	plusle: {
		inherit: true,
		baseStats: {hp:60,atk:50,def:40,spa:85,spd:75,spe:95},
		abilities: {0:"Plus"}
	},
	minun: {
		inherit: true,
		baseStats: {hp:60,atk:40,def:50,spa:75,spd:85,spe:95},
		abilities: {0:"Minus"}
	},
	kecleon: {
		inherit: true,
		baseStats: {hp:60,atk:90,def:70,spa:60,spd:120,spe:40},
		abilities: {0:"Color Change"}
	},
	duskull: {
		inherit: true,
		abilities: {0:"Levitate"}
	},
	dusclops: {
		inherit: true,
		abilities: {0:"Pressure"}
	},
	starly: {
		inherit: true,
		abilities: {0:"Keen Eye"}
	},
	staraptor: {
		inherit: true,
		baseStats: {hp:85,atk:120,def:70,spa:50,spd:50,spe:100},
		abilities: {0:"Intimidate"}
	},
	togekiss: {
		inherit: true,
		types:["Normal","Flying"],
		baseStats: {hp:85,atk:50,def:95,spa:120,spd:115,spe:80},
		abilities: {0:"Hustle",1:"Serene Grace"}
	},
	dusknoir: {
		inherit: true,
		baseStats: {hp:45,atk:100,def:135,spa:65,spd:135,spe:45},
		abilities: {0:"Pressure"}
	},
	rotomheat: {
		inherit: true,
		types: ["Electric", "Ghost"]
	},
	rotomwash: {
		inherit: true,
		types: ["Electric", "Ghost"]
	},
	rotomfrost: {
		inherit: true,
		types: ["Electric", "Ghost"]
	},
	rotomfan: {
		inherit: true,
		types: ["Electric", "Ghost"]
	},
	rotommow: {
		inherit: true,
		types: ["Electric", "Ghost"]
	}
};
<|endoftext|>