<commit_before>// Load modules

var Boom = require('boom');
var Catbox = require('catbox');
var Hoek = require('hoek');
var Joi = require('joi');
var Statehood = require('statehood');
var Schema = require('./schema');
var Auth = require('./auth');
var Payload = require('./payload');
var Validation = require('./validation');
var Handler = require('./handler');

// Declare internals

var internals = {};

exports = module.exports = internals.Route = function (options, server, env) {

    // Apply plugin environment (before schema validation)

    if (env &&
        (env.route.vhost || env.route.prefix)) {

        options = Hoek.cloneWithShallow(options, ['config']);
        options.path = (env.route.prefix ? env.route.prefix + (options.path !== '/' ? options.path : '') : options.path);
        options.vhost = env.route.vhost || options.vhost;
    }

    // Setup and validate route configuration

    Hoek.assert(options.handler || (options.config && options.config.handler), 'Missing or undefined handler:', options.path);
    Hoek.assert(!!options.handler ^ !!(options.config && options.config.handler), 'Handler must only appear once:', options.path);            // XOR
    Hoek.assert(options.path === '/' || options.path[options.path.length - 1] !== '/' || !server.settings.router.stripTrailingSlash, 'Path cannot end with a trailing slash when server configured to strip:', options.path);

    this.settings = Hoek.cloneWithShallow(options.config, ['bind', 'plugins', 'app']) || {};
    this.settings.handler = this.settings.handler || options.handler;

    Schema.assert('route', options, options.path);
    Schema.assert('routeConfig', this.settings, options.path);

    this.server = server;
    this.path = options.path;
    this.method = options.method.toLowerCase();
    this._env = env || {};                                          // Plugin-specific environment

    this.settings.method = this.method;                             // Expose method in settings
    this.settings.path = this.settings.path;                        // Expose path in settings
    this.settings.vhost = options.vhost;                            // Expose vhost in settings
    this.settings.plugins = this.settings.plugins || {};            // Route-specific plugins settings, namespaced using plugin name
    this.settings.app = this.settings.app || {};                    // Route-specific application settings

    // Path parsing

    this._analysis = this.server._router.analyze(this.path);
    this.params = this._analysis.params;
    this.fingerprint = this._analysis.fingerprint;

    // Validation

    this.settings.validate = this.settings.validate || {};
    var validation = this.settings.validate;
    ['headers', 'params', 'query', 'payload'].forEach(function (type) {

        // null, undefined, true - anything allowed
        // false - nothing allowed
        // {...} - ... allowed

        var rule = validation[type];
        validation[type] = (rule === false ? Joi.object({})
                                           : typeof rule === 'function' ? rule
                                                                        : !rule || rule === true ? null                     // false tested earlier
                                                                                : Joi.compile(rule));
    });

    if (this.settings.response) {
        var rule = this.settings.response.schema;
        if (rule === true ||
            this.settings.response.sample === 0) {

            this.settings.response = null;
        }
        else {
            this.settings.response.schema = (rule === false ? Joi.object({})
                                                            : typeof rule === 'function' ? rule
                                                                                : Joi.compile(rule));
        }
    }

    // Payload parsing

    if (this.method !== 'get' &&
        this.method !== 'head') {

        this.settings.payload = this.settings.payload || {};
        var isProxy = (typeof this.settings.handler === 'object' && !!this.settings.handler.proxy);
        this.settings.payload.output = this.settings.payload.output || (isProxy ? 'stream' : 'data');
        this.settings.payload.parse = this.settings.payload.parse !== undefined ? this.settings.payload.parse : !isProxy;
        this.settings.payload.maxBytes = this.settings.payload.maxBytes || this.server.settings.payload.maxBytes;
        this.settings.payload.uploads = this.settings.payload.uploads || this.server.settings.payload.uploads;
        this.settings.payload.failAction = this.settings.payload.failAction || 'error';
        if (this.settings.payload.allow) {
            this.settings.payload.allow = [].concat(this.settings.payload.allow);
        }
    }
    else {
        Hoek.assert(!this.settings.payload, 'Cannot set payload settings on HEAD or GET request:', options.path);
        Hoek.assert(!this.settings.validate.payload, 'Cannot validate HEAD or GET requests:', options.path);
    }

    Hoek.assert(!this.settings.validate.payload || this.settings.payload.parse, 'Route payload must be set to \'parse\' when payload validation enabled:', options.path);
    Hoek.assert(!this.settings.jsonp || typeof this.settings.jsonp === 'string', 'Bad route JSONP parameter name:', options.path);

    // Authentication configuration

    this.settings.auth = this.server.auth._setupRoute(this.settings.auth, options.path);

    // Cache

    Hoek.assert(!this.settings.cache || this.method === 'get', 'Only GET routes can use a cache:', options.path);
    this._cache = this.settings.cache ? new Catbox.Policy({ expiresIn: this.settings.cache.expiresIn, expiresAt: this.settings.cache.expiresAt }) : null;

    // Handler

    this.settings.handler = Handler.configure(this.settings.handler, this);
    this._prerequisites = Handler.prerequisites(this.settings.pre, server);

    // Route lifecycle

    this._cycle = this.lifecycle();
};

internals.Route.prototype.lifecycle = function () {

    var cycle = [];

    // 'onRequest'

    if (this.server.settings.state.cookies.parse) {
        cycle.push(internals.state);
    }

    cycle.push('onPreAuth');

    var authenticate = (this.settings.auth !== false);                          // Anything other than 'false' can still require authentication
    if (authenticate) {
        cycle.push(Auth.authenticate);
    }

    if (this.method !== 'get' &&
        this.method !== 'head') {

        cycle.push(Payload.read);
        if (authenticate) {
            cycle.push(Auth.payload);
        }
    }

    cycle.push('onPostAuth');

    if (this.settings.validate.headers) {
        cycle.push(Validation.headers);
    }

    if (this.settings.validate.params) {
        cycle.push(Validation.params);
    }

    if (this.settings.jsonp) {
        cycle.push(internals.parseJSONP);
    }

    if (this.settings.validate.query) {
        cycle.push(Validation.query);
    }

    if (this.settings.validate.payload) {
        cycle.push(Validation.payload);
    }

    cycle.push('onPreHandler');
    cycle.push(Handler.execute);                                     // Must not call next() with an Error
    cycle.push('onPostHandler');                                     // An error from here on will override any result set in handler()

    if (this.settings.response) {
        cycle.push(Validation.response);
    }

    // 'onPreResponse'

    return cycle;
};

internals.state = function (request, next) {

    request.state = {};

    var req = request.raw.req;
    var cookies = req.headers.cookie;
    if (!cookies) {
        return next();
    }

    var definitions = request.server._stateDefinitions;
    var settings = request.server.settings.state;

    Statehood.parse(cookies, definitions, function (err, state, invalids) {

        request.state = state;

        var names = Object.keys(invalids);
        for (var i = 0, il = names.length; i < il; ++i) {
            var name = names[i];
            var definition = definitions.cookies[name];

            if (definition &&
                definition.clearInvalid !== undefined ? definition.clearInvalid : settings.cookies.clearInvalid) {

                request._clearState(name);
            }

            // failAction: 'error', 'log', 'ignore'

            var failAction = (definition && definition.failAction !== undefined ? definition.failAction
                                                                                : settings.cookies.failAction);
            if (failAction !== 'ignore') {
                request.log(['hapi', 'state', 'error'], invalids[name]);
            }
        }

        return next(err);
    });
};

internals.parseJSONP = function (request, next) {

    var jsonp = request.query[request.route.jsonp];
    if (jsonp) {
        if (/^[\w\$\[\]\.]+$/.test(jsonp) === false) {
            return next(Boom.badRequest('Invalid JSONP parameter value'));
        }

        request.jsonp = jsonp;
        delete request.query[request.route.jsonp];
    }

    return next();
};
<commit_msg>Fix path typo<commit_after>// Load modules

var Boom = require('boom');
var Catbox = require('catbox');
var Hoek = require('hoek');
var Joi = require('joi');
var Statehood = require('statehood');
var Schema = require('./schema');
var Auth = require('./auth');
var Payload = require('./payload');
var Validation = require('./validation');
var Handler = require('./handler');

// Declare internals

var internals = {};

exports = module.exports = internals.Route = function (options, server, env) {

    // Apply plugin environment (before schema validation)

    if (env &&
        (env.route.vhost || env.route.prefix)) {

        options = Hoek.cloneWithShallow(options, ['config']);
        options.path = (env.route.prefix ? env.route.prefix + (options.path !== '/' ? options.path : '') : options.path);
        options.vhost = env.route.vhost || options.vhost;
    }

    // Setup and validate route configuration

    Hoek.assert(options.handler || (options.config && options.config.handler), 'Missing or undefined handler:', options.path);
    Hoek.assert(!!options.handler ^ !!(options.config && options.config.handler), 'Handler must only appear once:', options.path);            // XOR
    Hoek.assert(options.path === '/' || options.path[options.path.length - 1] !== '/' || !server.settings.router.stripTrailingSlash, 'Path cannot end with a trailing slash when server configured to strip:', options.path);

    this.settings = Hoek.cloneWithShallow(options.config, ['bind', 'plugins', 'app']) || {};
    this.settings.handler = this.settings.handler || options.handler;

    Schema.assert('route', options, options.path);
    Schema.assert('routeConfig', this.settings, options.path);

    this.server = server;
    this.path = options.path;
    this.method = options.method.toLowerCase();
    this._env = env || {};                                          // Plugin-specific environment

    this.settings.method = this.method;                             // Expose method in settings
    this.settings.path = this.path;                                 // Expose path in settings
    this.settings.vhost = options.vhost;                            // Expose vhost in settings
    this.settings.plugins = this.settings.plugins || {};            // Route-specific plugins settings, namespaced using plugin name
    this.settings.app = this.settings.app || {};                    // Route-specific application settings

    // Path parsing

    this._analysis = this.server._router.analyze(this.path);
    this.params = this._analysis.params;
    this.fingerprint = this._analysis.fingerprint;

    // Validation

    this.settings.validate = this.settings.validate || {};
    var validation = this.settings.validate;
    ['headers', 'params', 'query', 'payload'].forEach(function (type) {

        // null, undefined, true - anything allowed
        // false - nothing allowed
        // {...} - ... allowed

        var rule = validation[type];
        validation[type] = (rule === false ? Joi.object({})
                                           : typeof rule === 'function' ? rule
                                                                        : !rule || rule === true ? null                     // false tested earlier
                                                                                : Joi.compile(rule));
    });

    if (this.settings.response) {
        var rule = this.settings.response.schema;
        if (rule === true ||
            this.settings.response.sample === 0) {

            this.settings.response = null;
        }
        else {
            this.settings.response.schema = (rule === false ? Joi.object({})
                                                            : typeof rule === 'function' ? rule
                                                                                : Joi.compile(rule));
        }
    }

    // Payload parsing

    if (this.method !== 'get' &&
        this.method !== 'head') {

        this.settings.payload = this.settings.payload || {};
        var isProxy = (typeof this.settings.handler === 'object' && !!this.settings.handler.proxy);
        this.settings.payload.output = this.settings.payload.output || (isProxy ? 'stream' : 'data');
        this.settings.payload.parse = this.settings.payload.parse !== undefined ? this.settings.payload.parse : !isProxy;
        this.settings.payload.maxBytes = this.settings.payload.maxBytes || this.server.settings.payload.maxBytes;
        this.settings.payload.uploads = this.settings.payload.uploads || this.server.settings.payload.uploads;
        this.settings.payload.failAction = this.settings.payload.failAction || 'error';
        if (this.settings.payload.allow) {
            this.settings.payload.allow = [].concat(this.settings.payload.allow);
        }
    }
    else {
        Hoek.assert(!this.settings.payload, 'Cannot set payload settings on HEAD or GET request:', options.path);
        Hoek.assert(!this.settings.validate.payload, 'Cannot validate HEAD or GET requests:', options.path);
    }

    Hoek.assert(!this.settings.validate.payload || this.settings.payload.parse, 'Route payload must be set to \'parse\' when payload validation enabled:', options.path);
    Hoek.assert(!this.settings.jsonp || typeof this.settings.jsonp === 'string', 'Bad route JSONP parameter name:', options.path);

    // Authentication configuration

    this.settings.auth = this.server.auth._setupRoute(this.settings.auth, options.path);

    // Cache

    Hoek.assert(!this.settings.cache || this.method === 'get', 'Only GET routes can use a cache:', options.path);
    this._cache = this.settings.cache ? new Catbox.Policy({ expiresIn: this.settings.cache.expiresIn, expiresAt: this.settings.cache.expiresAt }) : null;

    // Handler

    this.settings.handler = Handler.configure(this.settings.handler, this);
    this._prerequisites = Handler.prerequisites(this.settings.pre, server);

    // Route lifecycle

    this._cycle = this.lifecycle();
};

internals.Route.prototype.lifecycle = function () {

    var cycle = [];

    // 'onRequest'

    if (this.server.settings.state.cookies.parse) {
        cycle.push(internals.state);
    }

    cycle.push('onPreAuth');

    var authenticate = (this.settings.auth !== false);                          // Anything other than 'false' can still require authentication
    if (authenticate) {
        cycle.push(Auth.authenticate);
    }

    if (this.method !== 'get' &&
        this.method !== 'head') {

        cycle.push(Payload.read);
        if (authenticate) {
            cycle.push(Auth.payload);
        }
    }

    cycle.push('onPostAuth');

    if (this.settings.validate.headers) {
        cycle.push(Validation.headers);
    }

    if (this.settings.validate.params) {
        cycle.push(Validation.params);
    }

    if (this.settings.jsonp) {
        cycle.push(internals.parseJSONP);
    }

    if (this.settings.validate.query) {
        cycle.push(Validation.query);
    }

    if (this.settings.validate.payload) {
        cycle.push(Validation.payload);
    }

    cycle.push('onPreHandler');
    cycle.push(Handler.execute);                                     // Must not call next() with an Error
    cycle.push('onPostHandler');                                     // An error from here on will override any result set in handler()

    if (this.settings.response) {
        cycle.push(Validation.response);
    }

    // 'onPreResponse'

    return cycle;
};

internals.state = function (request, next) {

    request.state = {};

    var req = request.raw.req;
    var cookies = req.headers.cookie;
    if (!cookies) {
        return next();
    }

    var definitions = request.server._stateDefinitions;
    var settings = request.server.settings.state;

    Statehood.parse(cookies, definitions, function (err, state, invalids) {

        request.state = state;

        var names = Object.keys(invalids);
        for (var i = 0, il = names.length; i < il; ++i) {
            var name = names[i];
            var definition = definitions.cookies[name];

            if (definition &&
                definition.clearInvalid !== undefined ? definition.clearInvalid : settings.cookies.clearInvalid) {

                request._clearState(name);
            }

            // failAction: 'error', 'log', 'ignore'

            var failAction = (definition && definition.failAction !== undefined ? definition.failAction
                                                                                : settings.cookies.failAction);
            if (failAction !== 'ignore') {
                request.log(['hapi', 'state', 'error'], invalids[name]);
            }
        }

        return next(err);
    });
};

internals.parseJSONP = function (request, next) {

    var jsonp = request.query[request.route.jsonp];
    if (jsonp) {
        if (/^[\w\$\[\]\.]+$/.test(jsonp) === false) {
            return next(Boom.badRequest('Invalid JSONP parameter value'));
        }

        request.jsonp = jsonp;
        delete request.query[request.route.jsonp];
    }

    return next();
};
<|endoftext|>


<commit_before>// Import AVA
import test from 'ava'

// Imports
import ChainAgent from '../../src/chain/etherscan.js'

/**
 * Create a new Etherscan chain agent.
 */
test('create', t => {
  t.notThrows(() => {
    new ChainAgent()
  })
})
<commit_msg>Remove extraneous .js from chain/etherscan test file<commit_after>// Import AVA
import test from 'ava'

// Imports
import ChainAgent from '../../src/chain/etherscan'

/**
 * Create a new Etherscan chain agent.
 */
test('create', t => {
  t.notThrows(() => {
    new ChainAgent()
  })
})
<|endoftext|>


<commit_before>
var rules = module.exports = {}
  , _ = require('underscore')

function uncapitalize(str) {
  return str.charAt(0).toLowerCase() + str.slice(1)
}

function undash(str) {
  return str.replace(/-$/, "")
}

function firstClassWhere(el, cb, context) {
  var classes = (el.attr("class") || "").split(/\s+/)
  return _(classes).find(function(className) {
    if(!className || !className.match(/^.*-$/)) return
    return cb.call(this, className)
  }, context)
}

rules.viewClass = function(className) {
  var match = className.match(/(\S+View)-(?:\s|$)/)
  return (match) ? match[1] : false
}

rules.conditionalClass = function(className) {
  var match = className.match(/(?:^|\s)(?:isnt|isNot|hasNo|is|has)(\S+)-(?:$|\s)/)
  return (match) ? uncapitalize(match[1]) : false
}

rules.conditionals = function(el) {
  var conditionals = {}
  el.attr("class").replace(/(?:(?:isnt|isNot|hasNo|is|has)(\S+)-)+/g, function(cond, variableName) {
    rules.negationClass(cond)
    conditionals[uncapitalize(variableName)] = rules.negationClass(cond)
  })
  return conditionals
}

rules.negationClass = function(className) {
  return !!className.match(/(?:^|\s)(?:isnt|isNot|hasNo)(\S+)-(?:$|\s)/)
}

rules.polymorphicKeyClass = function(className) {
  var match = (className || "").match(/(\S+)Polymorphic-(?:\s|$)/)
  return (match) ? match[1] : false
}

rules.polymorphicValueClass = function(className) {
  var match = (className || "").match(/when(\S+)-(?:\s|$)/)
  return (match) ? uncapitalize(match[1]) : false
}

rules.polymorphicKey = function(el) {
  return el.attr("data-case") || this.polymorphicKeyClass(el.attr("class"))
}

rules.polymorphicValue = function(el) {
  return el.attr("data-when") || this.polymorphicValueClass(el.attr("class")) || "default"
}

rules.iteration = function(el) {
  if(!(el.is("[data-each]"))) {
    return false
  } else {
    return true
  }
}

rules.view = function(el) {
  return el.attr("data-view") || this.viewClass(el.attr("class"))
}

rules.conditional = function(el) {
  return this.conditionalClass(el.attr("class"))
}

rules.negation = function(el) {
  return this.negationClass(el.attr("class"))
}

rules.variable = function(el) {
  if(el.children().length && el.prop("tagName").toLowerCase() !== "select") return
  var variableName = firstClassWhere(el, function(className) {
    return !this.viewClass(className) &&
           !this.conditionalClass(className)
  }, this)
  if (this.polymorphicKeyClass(variableName) || this.polymorphicValueClass(variableName)) {
    return false
  }
  return (variableName) ? undash(variableName) : false
}

rules.model = function(el) {
  if(el[0].tagName.toLowerCase() === "select" ||
    this.iteration(el) ||
    !el.children().length) {
    return
  }

  var modelName = firstClassWhere(el, function(className) {
    return !this.viewClass(className) &&
           !this.conditionalClass(className)
  }, this)
  return (modelName) ? undash(modelName) : false
}
<commit_msg>simply return the result of el.is, the conditional if, else, is unnecessary here<commit_after>
var rules = module.exports = {}
  , _ = require('underscore')

function uncapitalize(str) {
  return str.charAt(0).toLowerCase() + str.slice(1)
}

function undash(str) {
  return str.replace(/-$/, "")
}

function firstClassWhere(el, cb, context) {
  var classes = (el.attr("class") || "").split(/\s+/)
  return _(classes).find(function(className) {
    if(!className || !className.match(/^.*-$/)) return
    return cb.call(this, className)
  }, context)
}

rules.viewClass = function(className) {
  var match = className.match(/(\S+View)-(?:\s|$)/)
  return (match) ? match[1] : false
}

rules.conditionalClass = function(className) {
  var match = className.match(/(?:^|\s)(?:isnt|isNot|hasNo|is|has)(\S+)-(?:$|\s)/)
  return (match) ? uncapitalize(match[1]) : false
}

rules.conditionals = function(el) {
  var conditionals = {}
  el.attr("class").replace(/(?:(?:isnt|isNot|hasNo|is|has)(\S+)-)+/g, function(cond, variableName) {
    rules.negationClass(cond)
    conditionals[uncapitalize(variableName)] = rules.negationClass(cond)
  })
  return conditionals
}

rules.negationClass = function(className) {
  return !!className.match(/(?:^|\s)(?:isnt|isNot|hasNo)(\S+)-(?:$|\s)/)
}

rules.polymorphicKeyClass = function(className) {
  var match = (className || "").match(/(\S+)Polymorphic-(?:\s|$)/)
  return (match) ? match[1] : false
}

rules.polymorphicValueClass = function(className) {
  var match = (className || "").match(/when(\S+)-(?:\s|$)/)
  return (match) ? uncapitalize(match[1]) : false
}

rules.polymorphicKey = function(el) {
  return el.attr("data-case") || this.polymorphicKeyClass(el.attr("class"))
}

rules.polymorphicValue = function(el) {
  return el.attr("data-when") || this.polymorphicValueClass(el.attr("class")) || "default"
}

rules.iteration = function(el) {
  return (el.is("[data-each]"))
}

rules.view = function(el) {
  return el.attr("data-view") || this.viewClass(el.attr("class"))
}

rules.conditional = function(el) {
  return this.conditionalClass(el.attr("class"))
}

rules.negation = function(el) {
  return this.negationClass(el.attr("class"))
}

rules.variable = function(el) {
  if(el.children().length && el.prop("tagName").toLowerCase() !== "select") return
  var variableName = firstClassWhere(el, function(className) {
    return !this.viewClass(className) &&
           !this.conditionalClass(className)
  }, this)
  if (this.polymorphicKeyClass(variableName) || this.polymorphicValueClass(variableName)) {
    return false
  }
  return (variableName) ? undash(variableName) : false
}

rules.model = function(el) {
  if(el[0].tagName.toLowerCase() === "select" ||
    this.iteration(el) ||
    !el.children().length) {
    return
  }

  var modelName = firstClassWhere(el, function(className) {
    return !this.viewClass(className) &&
           !this.conditionalClass(className)
  }, this)
  return (modelName) ? undash(modelName) : false
}
<|endoftext|>


<commit_before>exports.and = function(a,b, cbA, cbB) {
   var ret = Math.min(a, b);
   if (ret == a) {
       cbA();
   } else {
       cbB();
   }
   return ret;
}

exports.or = function(a, b, cbA, cbB) {
   var ret = Math.max(a,b);
   if (ret == a) {
        cbA();
   } else {
        cbB();
   }
   return ret;
}

exports.not = function(a) {
    return 1.0 - a;
}

<commit_msg>- the result of the rules result is passed to the cb<commit_after>exports.and = function(a,b, cbA, cbB) {
   var ret = Math.min(a, b);
   if (ret == a) {
       cbA(ret);
   } else {
       cbB(ret);
   }
   return ret;
}

exports.or = function(a, b, cbA, cbB) {
   var ret = Math.max(a,b);
   if (ret == a) {
        cbA(ret);
   } else {
        cbB(ret);
   }
   return ret;
}

exports.not = function(a) {
    return 1.0 - a;
}

<|endoftext|>


<commit_before>describe('uiCodemirror', function() {
  'use strict';

  // declare these up here to be global to all tests
  var scope, $compile, $timeout, uiConfig;
  var codemirrorDefaults = window.CodeMirror.defaults;

  beforeEach(function() {
    module('ui.codemirror');

    inject(function(_$rootScope_, _$compile_, _$timeout_, uiCodemirrorConfig) {
      scope = _$rootScope_.$new();
      $compile = _$compile_;
      $timeout = _$timeout_;
      uiConfig = uiCodemirrorConfig;
    });

  });

  afterEach(function() {
    uiConfig = {};
  });

  it('should not throw an error when window.CodeMirror is defined', function() {
    function compile() {
      $compile('

')(scope);
    }

    var _CodeMirror = window.CodeMirror;
    delete window.CodeMirror;
    expect(window.CodeMirror).toBeUndefined();
    expect(compile)
      .toThrow(new Error('ui-codemirror need CodeMirror to work... (o rly?)'));
    window.CodeMirror = _CodeMirror;
  });

  describe('destruction', function() {

    var parentElement;

    beforeEach(function() {
      parentElement = angular.element('

');
      angular.element(document.body).prepend(parentElement);
    });

    afterEach(function() {
      parentElement.remove();
    });

    function shouldDestroyTest(elementType, template) {
      it('should destroy the directive of ' + elementType, function() {
        var element = angular.element(template);
        parentElement.append(element);

        $compile(element)(scope);
        scope.$digest();

        expect(parentElement.children().length).toBe(1);
        element.remove();
        scope.$digest();
        expect(parentElement.children().length).toBe(0);
      });
    }

    shouldDestroyTest('an element', '<ui-codemirror></ui-codemirror>');
    shouldDestroyTest('an attribute', '

');

  });

  it('should not throw an error when window.CodeMirror is defined an attribute', function() {
    function compile() {
      $compile('

')(scope);
    }

    expect(window.CodeMirror).toBeDefined();
    expect(compile).not.toThrow();
  });

  it('should not throw an error when window.CodeMirror is defined an element', function() {
    function compile() {
      $compile('<ui-codemirror></ui-codemirror>')(scope);
    }

    expect(window.CodeMirror).toBeDefined();
    expect(compile).not.toThrow();
  });

  it('should watch all uiCodemirror attribute', function() {
    spyOn(scope, '$watch');
    scope.cmOption = {};
    $compile('

')(scope);
    expect(scope.$watch.calls.count()).toEqual(3); // The uiCodemirror+ the ngModel + the uiRefresh
    expect(scope.$watch).toHaveBeenCalledWith('cmOption', jasmine.any(Function), true); // uiCodemirror
    expect(scope.$watch).toHaveBeenCalledWith(jasmine.any(Function)); // ngModel
    expect(scope.$watch).toHaveBeenCalledWith('sdf', jasmine.any(Function)); // uiRefresh
  });

  describe('CodeMirror instance', function() {

    var codemirror = null, spies = angular.noop;

    beforeEach(function() {
      var _constructor = window.CodeMirror;
      window.CodeMirror = jasmine.createSpy('window.CodeMirror')
        .and.callFake(function() {
          codemirror = _constructor.apply(this, arguments);
          spies(codemirror);
          return codemirror;
        });

      window.CodeMirror.defaults = codemirrorDefaults;
    });

    it('should call the CodeMirror constructor with a function', function() {
      $compile('

')(scope);

      expect(window.CodeMirror.calls.count()).toEqual(1);
      expect(window.CodeMirror)
        .toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Object));

      expect(codemirror).toBeDefined();
    });

    it('should work as an element', function() {
      $compile('<ui-codemirror></ui-codemirror>')(scope);

      expect(window.CodeMirror.calls.count()).toEqual(1);
      expect(window.CodeMirror)
        .toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Object));

      expect(codemirror).toBeDefined();
    });

    it('should have a child element with a div.CodeMirror', function() {
      // Explicit a parent node to support the directive.
      var element = $compile('

')(scope).children();

      expect(element).toBeDefined();
      expect(element.prop('tagName')).toBe('DIV');
      expect(element.prop('classList').length).toEqual(2);
      expect(element.prop('classList')[0]).toEqual('CodeMirror');
      expect(element.prop('classList')[1]).toEqual('cm-s-default');
    });

    describe('options', function() {

      spies = function(codemirror) {
        codemirror._setOption = codemirror._setOption || codemirror.setOption;
        codemirror.setOption = jasmine.createSpy('codemirror.setOption')
          .and.callFake(function() {
            codemirror._setOption.apply(this, arguments);
          });
      };

      it('should not be called', function() {
        $compile('

')(scope);
        expect(window.CodeMirror)
          .toHaveBeenCalledWith(jasmine.any(Function), { value: '' });
        expect(codemirror.setOption).not.toHaveBeenCalled();
      });

      it('should include the passed options (attribute directive)', function() {
        $compile('

')(scope);

        expect(window.CodeMirror)
          .toHaveBeenCalledWith(jasmine.any(Function), {
            value: '',
            oof: 'baar'
          });
        expect(codemirror.setOption).not.toHaveBeenCalled();
      });

      it('should include the passed options (element directive)', function() {
        $compile('<ui-codemirror ui-codemirror-opts="{oof: \'baar\'}"></ui-codemirror>')(scope);

        expect(window.CodeMirror)
          .toHaveBeenCalledWith(jasmine.any(Function), {
            value: '',
            oof: 'baar'
          });
        expect(codemirror.setOption).not.toHaveBeenCalled();
      });

      it('should include the default options', function() {
        uiConfig.codemirror = { bar: 'baz' };
        $compile('

')(scope);

        expect(window.CodeMirror).toHaveBeenCalledWith(jasmine.any(Function), {
          value: '',
          bar: 'baz'
        });
        expect(codemirror.setOption).not.toHaveBeenCalled();
      });

      it('should extent the default options', function() {
        uiConfig.codemirror = { bar: 'baz' };
        $compile('

')(scope);

        expect(window.CodeMirror).toHaveBeenCalledWith(jasmine.any(Function), {
          value: '',
          oof: 'baar',
          bar: 'baz'
        });
        expect(codemirror.setOption).not.toHaveBeenCalled();
      });

      it('should impact codemirror', function() {
        uiConfig.codemirror = {};
        $compile('

')(scope);

        expect(window.CodeMirror).toHaveBeenCalledWith(jasmine.any(Function), {
          value: '',
          theme: 'baar'
        });
        expect(codemirror.setOption).not.toHaveBeenCalled();

        expect(codemirror.getOption('theme')).toEqual('baar');
      });
    });

    it('should not trigger watch ui-refresh', function() {
      spyOn(scope, '$watch');
      $compile('

')(scope);
      expect(scope.$watch).not.toHaveBeenCalled();
    });

    it('should trigger the CodeMirror.refresh() method', function() {
      $compile('

')(scope);

      spyOn(codemirror, 'refresh');
      scope.$apply('bar = null');

      scope.$apply('bar = false');
      expect(scope.bar).toBeFalsy();
      $timeout.flush();
      expect(codemirror.refresh).toHaveBeenCalled();
      scope.$apply('bar = true');
      expect(scope.bar).toBeTruthy();
      $timeout.flush();
      expect(codemirror.refresh).toHaveBeenCalled();
      scope.$apply('bar = 0');
      expect(scope.bar).toBeFalsy();
      $timeout.flush();
      expect(codemirror.refresh).toHaveBeenCalled();
      scope.$apply('bar = 1');
      expect(scope.bar).toBeTruthy();
      $timeout.flush();
      expect(codemirror.refresh).toHaveBeenCalled();

      expect(codemirror.refresh.calls.count()).toEqual(4);
    });

    it('when the IDE changes should update the model', function() {
      var element = $compile('

')(scope);

      expect(element).toBeDefined();
      expect(element.attr('class')).toEqual(
        'ng-pristine ng-untouched ng-valid ng-scope'
      );

      var value = 'baz';
      codemirror.setValue(value);
      expect(scope.foo).toBe(value);

      expect(element.attr('class')).toEqual(
        'ng-untouched ng-valid ng-scope ng-dirty ng-valid-parse'
      );

    });

    it('when the model changes should update the IDE', function() {
      var element = $compile('

')(scope);

      expect(element).toBeDefined();
      expect(element.attr('class')).toEqual(
        'ng-pristine ng-untouched ng-valid ng-scope'
      );

      scope.$apply('foo = "bar"');
      expect(codemirror.getValue()).toBe(scope.foo);

      expect(element.attr('class')).toEqual(
        'ng-pristine ng-untouched ng-valid ng-scope'
      );
    });

    it('when the IDE changes should use ngChange', function() {
      scope.change = angular.noop;
      spyOn(scope, 'change').and.callFake(function() { expect(scope.foo).toBe('baz'); });

      $compile('

')(scope);

      // change shouldn't be called initialy
      expect(scope.change).not.toHaveBeenCalled();

      // change shouldn't be called when the value change is coming from the model.
      scope.$apply('foo = "bar"');
      expect(scope.change).not.toHaveBeenCalled();

      // change should be called when user changes the input.
      codemirror.setValue('baz');
      expect(scope.change.calls.count()).toBe(1);
      expect(scope.change).toHaveBeenCalledWith();
    });

    it('should runs the onLoad callback', function() {
      scope.codemirrorLoaded = jasmine.createSpy('scope.codemirrorLoaded');

      $compile('

')(scope);

      expect(scope.codemirrorLoaded).toHaveBeenCalled();
      expect(scope.codemirrorLoaded).toHaveBeenCalledWith(codemirror);
    });

    it('responds to the $broadcast event "CodeMirror"', function() {
      var broadcast = {};
      broadcast.callback = jasmine.createSpy('broadcast.callback');

      $compile('

')(scope);
      scope.$broadcast('CodeMirror', broadcast.callback);

      expect(broadcast.callback).toHaveBeenCalled();
      expect(broadcast.callback).toHaveBeenCalledWith(codemirror);
    });

    it('should watch the options (attribute directive)', function() {

      scope.cmOption = { readOnly: true };
      $compile('

')(scope);
      scope.$digest();

      expect(codemirror.getOption('readOnly')).toBeTruthy();

      scope.cmOption.readOnly = false;
      scope.$digest();
      expect(codemirror.getOption('readOnly')).toBeFalsy();
    });

    it('should watch the options (element directive)', function() {

      scope.cmOption = { readOnly: true };
      $compile('<ui-codemirror ui-codemirror-opts="cmOption">
')(scope);
      scope.$digest();

      expect(codemirror.getOption('readOnly')).toBeTruthy();

      scope.cmOption.readOnly = false;
      scope.$digest();
      expect(codemirror.getOption('readOnly')).toBeFalsy();
    });

    it('should watch the options (object property)', function() {

      scope.cm = {};
      scope.cm.option = { readOnly: true };
      $compile('

')(scope);
      scope.$digest();

      expect(codemirror.getOption('readOnly')).toBeTruthy();

      scope.cm.option.readOnly = false;
      scope.$digest();
      expect(codemirror.getOption('readOnly')).toBeFalsy();
    });

  });

  it('when the model is an object or an array should throw an error', function() {
    function compileWithObject() {
      $compile('

')(scope);
      scope.foo = {};
      scope.$apply();
    }

    function compileWithArray() {
      $compile('

')(scope);
      scope.foo = [];
      scope.$apply();
    }

    expect(compileWithObject).toThrow();
    expect(compileWithArray).toThrow();
  });

});
<commit_msg>test: use ngmodelcontroller instead of relying on class names<commit_after>describe('uiCodemirror', function() {
  'use strict';

  // declare these up here to be global to all tests
  var scope, $compile, $timeout, uiConfig;
  var codemirrorDefaults = window.CodeMirror.defaults;

  beforeEach(function() {
    module('ui.codemirror');

    inject(function(_$rootScope_, _$compile_, _$timeout_, uiCodemirrorConfig) {
      scope = _$rootScope_.$new();
      $compile = _$compile_;
      $timeout = _$timeout_;
      uiConfig = uiCodemirrorConfig;
    });

  });

  afterEach(function() {
    uiConfig = {};
  });

  it('should not throw an error when window.CodeMirror is defined', function() {
    function compile() {
      $compile('

')(scope);
    }

    var _CodeMirror = window.CodeMirror;
    delete window.CodeMirror;
    expect(window.CodeMirror).toBeUndefined();
    expect(compile)
      .toThrow(new Error('ui-codemirror need CodeMirror to work... (o rly?)'));
    window.CodeMirror = _CodeMirror;
  });

  describe('destruction', function() {

    var parentElement;

    beforeEach(function() {
      parentElement = angular.element('

');
      angular.element(document.body).prepend(parentElement);
    });

    afterEach(function() {
      parentElement.remove();
    });

    function shouldDestroyTest(elementType, template) {
      it('should destroy the directive of ' + elementType, function() {
        var element = angular.element(template);
        parentElement.append(element);

        $compile(element)(scope);
        scope.$digest();

        expect(parentElement.children().length).toBe(1);
        element.remove();
        scope.$digest();
        expect(parentElement.children().length).toBe(0);
      });
    }

    shouldDestroyTest('an element', '<ui-codemirror></ui-codemirror>');
    shouldDestroyTest('an attribute', '

');

  });

  it('should not throw an error when window.CodeMirror is defined an attribute', function() {
    function compile() {
      $compile('

')(scope);
    }

    expect(window.CodeMirror).toBeDefined();
    expect(compile).not.toThrow();
  });

  it('should not throw an error when window.CodeMirror is defined an element', function() {
    function compile() {
      $compile('<ui-codemirror></ui-codemirror>')(scope);
    }

    expect(window.CodeMirror).toBeDefined();
    expect(compile).not.toThrow();
  });

  it('should watch all uiCodemirror attribute', function() {
    spyOn(scope, '$watch');
    scope.cmOption = {};
    $compile('

')(scope);
    expect(scope.$watch.calls.count()).toEqual(3); // The uiCodemirror+ the ngModel + the uiRefresh
    expect(scope.$watch).toHaveBeenCalledWith('cmOption', jasmine.any(Function), true); // uiCodemirror
    expect(scope.$watch).toHaveBeenCalledWith(jasmine.any(Function)); // ngModel
    expect(scope.$watch).toHaveBeenCalledWith('sdf', jasmine.any(Function)); // uiRefresh
  });

  describe('CodeMirror instance', function() {

    var codemirror = null, spies = angular.noop;

    beforeEach(function() {
      var _constructor = window.CodeMirror;
      window.CodeMirror = jasmine.createSpy('window.CodeMirror')
        .and.callFake(function() {
          codemirror = _constructor.apply(this, arguments);
          spies(codemirror);
          return codemirror;
        });

      window.CodeMirror.defaults = codemirrorDefaults;
    });

    it('should call the CodeMirror constructor with a function', function() {
      $compile('

')(scope);

      expect(window.CodeMirror.calls.count()).toEqual(1);
      expect(window.CodeMirror)
        .toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Object));

      expect(codemirror).toBeDefined();
    });

    it('should work as an element', function() {
      $compile('<ui-codemirror></ui-codemirror>')(scope);

      expect(window.CodeMirror.calls.count()).toEqual(1);
      expect(window.CodeMirror)
        .toHaveBeenCalledWith(jasmine.any(Function), jasmine.any(Object));

      expect(codemirror).toBeDefined();
    });

    it('should have a child element with a div.CodeMirror', function() {
      // Explicit a parent node to support the directive.
      var element = $compile('

')(scope).children();

      expect(element).toBeDefined();
      expect(element.prop('tagName')).toBe('DIV');
      expect(element.prop('classList').length).toEqual(2);
      expect(element.prop('classList')[0]).toEqual('CodeMirror');
      expect(element.prop('classList')[1]).toEqual('cm-s-default');
    });

    describe('options', function() {

      spies = function(codemirror) {
        codemirror._setOption = codemirror._setOption || codemirror.setOption;
        codemirror.setOption = jasmine.createSpy('codemirror.setOption')
          .and.callFake(function() {
            codemirror._setOption.apply(this, arguments);
          });
      };

      it('should not be called', function() {
        $compile('

')(scope);
        expect(window.CodeMirror)
          .toHaveBeenCalledWith(jasmine.any(Function), { value: '' });
        expect(codemirror.setOption).not.toHaveBeenCalled();
      });

      it('should include the passed options (attribute directive)', function() {
        $compile('

')(scope);

        expect(window.CodeMirror)
          .toHaveBeenCalledWith(jasmine.any(Function), {
            value: '',
            oof: 'baar'
          });
        expect(codemirror.setOption).not.toHaveBeenCalled();
      });

      it('should include the passed options (element directive)', function() {
        $compile('<ui-codemirror ui-codemirror-opts="{oof: \'baar\'}"></ui-codemirror>')(scope);

        expect(window.CodeMirror)
          .toHaveBeenCalledWith(jasmine.any(Function), {
            value: '',
            oof: 'baar'
          });
        expect(codemirror.setOption).not.toHaveBeenCalled();
      });

      it('should include the default options', function() {
        uiConfig.codemirror = { bar: 'baz' };
        $compile('

')(scope);

        expect(window.CodeMirror).toHaveBeenCalledWith(jasmine.any(Function), {
          value: '',
          bar: 'baz'
        });
        expect(codemirror.setOption).not.toHaveBeenCalled();
      });

      it('should extent the default options', function() {
        uiConfig.codemirror = { bar: 'baz' };
        $compile('

')(scope);

        expect(window.CodeMirror).toHaveBeenCalledWith(jasmine.any(Function), {
          value: '',
          oof: 'baar',
          bar: 'baz'
        });
        expect(codemirror.setOption).not.toHaveBeenCalled();
      });

      it('should impact codemirror', function() {
        uiConfig.codemirror = {};
        $compile('

')(scope);

        expect(window.CodeMirror).toHaveBeenCalledWith(jasmine.any(Function), {
          value: '',
          theme: 'baar'
        });
        expect(codemirror.setOption).not.toHaveBeenCalled();

        expect(codemirror.getOption('theme')).toEqual('baar');
      });
    });

    it('should not trigger watch ui-refresh', function() {
      spyOn(scope, '$watch');
      $compile('

')(scope);
      expect(scope.$watch).not.toHaveBeenCalled();
    });

    it('should trigger the CodeMirror.refresh() method', function() {
      $compile('

')(scope);

      spyOn(codemirror, 'refresh');
      scope.$apply('bar = null');

      scope.$apply('bar = false');
      expect(scope.bar).toBeFalsy();
      $timeout.flush();
      expect(codemirror.refresh).toHaveBeenCalled();
      scope.$apply('bar = true');
      expect(scope.bar).toBeTruthy();
      $timeout.flush();
      expect(codemirror.refresh).toHaveBeenCalled();
      scope.$apply('bar = 0');
      expect(scope.bar).toBeFalsy();
      $timeout.flush();
      expect(codemirror.refresh).toHaveBeenCalled();
      scope.$apply('bar = 1');
      expect(scope.bar).toBeTruthy();
      $timeout.flush();
      expect(codemirror.refresh).toHaveBeenCalled();

      expect(codemirror.refresh.calls.count()).toEqual(4);
    });

    it('when the IDE changes should update the model', function() {
      var element = $compile('

')(scope);
      var ctrl = element.controller('ngModel');

      expect(ctrl.$pristine).toBe(true);
      expect(ctrl.$valid).toBe(true);

      var value = 'baz';
      codemirror.setValue(value);
      scope.$apply();
      expect(scope.foo).toBe(value);

      expect(ctrl.$valid).toBe(true);
      expect(ctrl.$dirty).toBe(true);

    });

    it('when the model changes should update the IDE', function() {
      var element = $compile('

')(scope);
      var ctrl = element.controller('ngModel');

      expect(ctrl.$pristine).toBe(true);
      expect(ctrl.$valid).toBe(true);

      scope.$apply('foo = "bar"');
      expect(codemirror.getValue()).toBe(scope.foo);

      expect(ctrl.$pristine).toBe(true);
      expect(ctrl.$valid).toBe(true);
    });

    it('when the IDE changes should use ngChange', function() {
      scope.change = angular.noop;
      spyOn(scope, 'change').and.callFake(function() { expect(scope.foo).toBe('baz'); });

      $compile('

')(scope);

      // change shouldn't be called initialy
      expect(scope.change).not.toHaveBeenCalled();

      // change shouldn't be called when the value change is coming from the model.
      scope.$apply('foo = "bar"');
      expect(scope.change).not.toHaveBeenCalled();

      // change should be called when user changes the input.
      codemirror.setValue('baz');
      expect(scope.change.calls.count()).toBe(1);
      expect(scope.change).toHaveBeenCalledWith();
    });

    it('should runs the onLoad callback', function() {
      scope.codemirrorLoaded = jasmine.createSpy('scope.codemirrorLoaded');

      $compile('

')(scope);

      expect(scope.codemirrorLoaded).toHaveBeenCalled();
      expect(scope.codemirrorLoaded).toHaveBeenCalledWith(codemirror);
    });

    it('responds to the $broadcast event "CodeMirror"', function() {
      var broadcast = {};
      broadcast.callback = jasmine.createSpy('broadcast.callback');

      $compile('

')(scope);
      scope.$broadcast('CodeMirror', broadcast.callback);

      expect(broadcast.callback).toHaveBeenCalled();
      expect(broadcast.callback).toHaveBeenCalledWith(codemirror);
    });

    it('should watch the options (attribute directive)', function() {

      scope.cmOption = { readOnly: true };
      $compile('

')(scope);
      scope.$digest();

      expect(codemirror.getOption('readOnly')).toBeTruthy();

      scope.cmOption.readOnly = false;
      scope.$digest();
      expect(codemirror.getOption('readOnly')).toBeFalsy();
    });

    it('should watch the options (element directive)', function() {

      scope.cmOption = { readOnly: true };
      $compile('<ui-codemirror ui-codemirror-opts="cmOption">
')(scope);
      scope.$digest();

      expect(codemirror.getOption('readOnly')).toBeTruthy();

      scope.cmOption.readOnly = false;
      scope.$digest();
      expect(codemirror.getOption('readOnly')).toBeFalsy();
    });

    it('should watch the options (object property)', function() {

      scope.cm = {};
      scope.cm.option = { readOnly: true };
      $compile('

')(scope);
      scope.$digest();

      expect(codemirror.getOption('readOnly')).toBeTruthy();

      scope.cm.option.readOnly = false;
      scope.$digest();
      expect(codemirror.getOption('readOnly')).toBeFalsy();
    });

  });

  it('when the model is an object or an array should throw an error', function() {
    function compileWithObject() {
      $compile('

')(scope);
      scope.foo = {};
      scope.$apply();
    }

    function compileWithArray() {
      $compile('

')(scope);
      scope.foo = [];
      scope.$apply();
    }

    expect(compileWithObject).toThrow();
    expect(compileWithArray).toThrow();
  });

});
<|endoftext|>


<commit_before>import * as WHS from '../src/index';
import {Mesh} from 'three';

const meshes = [
  'Box',
  'Cylinder',
  'Dodecahedron',
  'Extrude',
  'Icosahedron',
  'Lathe',
  'Group',
  'Octahedron',
  'Parametric',
  'Plane',
  'Polyhedron',
  'Ring',
  'Shape',
  'Sphere',
  'Tetrahedron',
  // 'Text',
  'Torus',
  'Torusknot',
  'Tube'
];

const lights = [
  'AmbientLight',
  'AreaLight',
  'DirectionalLight',
  'HemisphereLight',
  'PointLight',
  'SpotLight'
];

const cameras = [
  'PerspectiveCamera',
  'CubeCamera',
  'OrthographicCamera'
];

const app = new WHS.App([
  new WHS.app.ElementModule(),
  new WHS.app.SceneModule(),
  new WHS.app.CameraModule()
]);

app.start();

[meshes, lights, cameras].forEach(category => {
  category.forEach(component => {
    test(component, () => {
      const element = new WHS[component]();

      app.add(element);
      expect(app.children).toContain(element);
    });
  });
});

test('Group', () => {
  const sphere = new WHS.Sphere();
  const box = new WHS.Box();

  const group = new WHS.Group(sphere, box, new Mesh());
  group.addTo(app);
});

describe('Line', () => {
  test('throws if no curve', () => {
    expect(() => {
      new WHS.Line();
    }).toThrow();
  });
  test('has points passed in', () => {
    // TODO assert, I suspect this component is broken
  });
});

describe('Model', () => {
  test('can construct', () => {
    const model = new WHS.Model();
  });
});
<commit_msg>Add rudimentary test for Text #169<commit_after>import * as WHS from '../src/index';
import {Mesh} from 'three';

const meshes = [
  'Box',
  'Cylinder',
  'Dodecahedron',
  'Extrude',
  'Icosahedron',
  'Lathe',
  'Group',
  'Octahedron',
  'Parametric',
  'Plane',
  'Polyhedron',
  'Ring',
  'Shape',
  'Sphere',
  'Tetrahedron',
  // 'Text',
  'Torus',
  'Torusknot',
  'Tube'
];

const lights = [
  'AmbientLight',
  'AreaLight',
  'DirectionalLight',
  'HemisphereLight',
  'PointLight',
  'SpotLight'
];

const cameras = [
  'PerspectiveCamera',
  'CubeCamera',
  'OrthographicCamera'
];

const app = new WHS.App([
  new WHS.app.ElementModule(),
  new WHS.app.SceneModule(),
  new WHS.app.CameraModule()
]);

app.start();

[meshes, lights, cameras].forEach(category => {
  category.forEach(component => {
    test(component, () => {
      const element = new WHS[component]();

      app.add(element);
      expect(app.children).toContain(element);
    });
  });
});

test('Group', () => {
  const sphere = new WHS.Sphere();
  const box = new WHS.Box();

  const group = new WHS.Group(sphere, box, new Mesh());
  group.addTo(app);
});

describe('Line', () => {
  test('throws if no curve', () => {
    expect(() => {
      new WHS.Line();
    }).toThrow();
  });
  test('has points passed in', () => {
    // TODO assert, I suspect this component is broken
  });
});

describe('Model', () => {
  test('can construct', () => {
    const model = new WHS.Model();
  });
});

describe('Text', () => {
  test('can construct', () => {
    const text = new WHS.Text();
  });
});
<|endoftext|>


<commit_before>
/*global require, exports */
var grunt = require('grunt');

/*
  ======== A Handy Little Nodeunit Reference ========
  https://github.com/caolan/nodeunit

  Test methods:
    test.expect(numAssertions)
    test.done()
  Test assertions:
    test.ok(value, [message])
    test.equal(actual, expected, [message])
    test.notEqual(actual, expected, [message])
    test.deepEqual(actual, expected, [message])
    test.notDeepEqual(actual, expected, [message])
    test.strictEqual(actual, expected, [message])
    test.notStrictEqual(actual, expected, [message])
    test.throws(block, [error], [message])
    test.doesNotThrow(block, [error], [message])
    test.ifError(value)
*/

exports.cordovacli = {
    setUp: function (done) {
        'use strict';
        // setup here if necessary
        done();
    },
    cordova_test: function (test) {
        'use strict';
        test.expect(1);

        var actual = grunt.file.exists("myHybridAppFolder/.cordova/config.json"),
            expected = true;
        test.equal(actual, expected, 'should create a cordova project with a .cordova/config.json');
        test.done();
    }
};
<commit_msg>Updating unit test to new folder structure<commit_after>/*global require, exports */
var grunt = require('grunt');

/*
 ======== A Handy Little Nodeunit Reference ========
 https://github.com/caolan/nodeunit

 Test methods:
 test.expect(numAssertions)
 test.done()
 Test assertions:
 test.ok(value, [message])
 test.equal(actual, expected, [message])
 test.notEqual(actual, expected, [message])
 test.deepEqual(actual, expected, [message])
 test.notDeepEqual(actual, expected, [message])
 test.strictEqual(actual, expected, [message])
 test.notStrictEqual(actual, expected, [message])
 test.throws(block, [error], [message])
 test.doesNotThrow(block, [error], [message])
 test.ifError(value)
 */

exports.cordovacli = {
    setUp: function (done) {
        'use strict';
        // setup here if necessary
        done();
    },
    cordova_test: function (test) {
        'use strict';
        test.expect(5);

        var expected = true;
        var actual;

        actual = grunt.file.isDir("myHybridAppFolder");
        test.equal(actual, expected, 'should create a cordova project root folder');

        actual = grunt.file.isDir("myHybridAppFolder/merges");
        test.equal(actual, expected, 'should create a cordova project folder structure');

        actual = grunt.file.isDir("myHybridAppFolder/platforms");
        test.equal(actual, expected, 'should create a cordova project folder structure');

        actual = grunt.file.isDir("myHybridAppFolder/plugins");
        test.equal(actual, expected, 'should create a cordova project folder structure');

        actual = grunt.file.isDir("myHybridAppFolder/www");
        test.equal(actual, expected, 'should create a cordova project folder structure');

        test.done();
    }
};
<|endoftext|>


<commit_before>//Get the netid of the user and renders the Login/Logout butto accordingly.
$.get("/shows", function(response){
	netid = response["netid"];
		console.log(netid)
	var text = " Logout ("+netid+") "
	if(netid == null){
		text = " Login "
	}
	$("#logoutLink").html(text);

	$("#logout").click(function(){
	$.post('logout');
	});
})<commit_msg>Remove console.log in faq.js<commit_after>//Get the netid of the user and renders the Login/Logout butto accordingly.
$.get("/shows", function(response){
	netid = response["netid"];
	var text = " Logout ("+netid+") "
	if(netid == null){
		text = " Login "
	}
	$("#logoutLink").html(text);

	$("#logout").click(function(){
	$.post('logout');
	});
})<|endoftext|>


<commit_before>SoapStone.Map = function () {
  this.outsideDrops = [];
	this.clickableDrops = [];
  $('#set-center').on('click',function(e){
    SoapStone.app.mapView.centerMap();
  });
};

SoapStone.Map.prototype.addClickableDrop = function (dropData) {
  var drop = new SoapStone.Drop(dropData);
  if (drop.lat && drop.lon) {
    drop.marker = new google.maps.Marker({
      position: new google.maps.LatLng(drop.lat, drop.lon),
      icon: {
        path: google.maps.SymbolPath.BACKWARD_CLOSED_ARROW,//'M -2,0 0,-2 2,0 0,2 z',//
        scale: 6,
        strokeColor: "hsl("+drop.user.hue+",80%,50%)",
        strokeWeight: 1
      }
    });
    drop.marker.setMap(SoapStone.app.mapView.map);
    SoapStone.app.map.clickableDrops.unshift(drop);//bad???? why was 'this' the window and not a map?
  }
};

SoapStone.Map.prototype.addOutsideDrop = function (dropData) {
  var drop = new SoapStone.Drop(dropData);
  if (drop.lat && drop.lon) {
  drop.marker = new google.maps.Marker({
    position: new google.maps.LatLng(drop.lat, drop.lon),
    icon: {
      path: google.maps.SymbolPath.BACKWARD_OPEN_ARROW,
      scale: 4,
      strokeColor: "hsl("+drop.user.hue+",30%,50%)",
      strokeWeight: 3
    }
  });
  drop.marker.setMap(SoapStone.app.mapView.map);
  SoapStone.app.map.outsideDrops.unshift(drop);
  }
};

SoapStone.Map.prototype.clearMarkers = function(){
  this.clickableDrops.forEach(function(drop){
    drop.marker.setMap(null);
  });
  this.outsideDrops.forEach(function(drop){
    drop.marker.setMap(null);
  });
  this.clickableDrops = [];
  this.outsideDrops = [];
};

SoapStone.Map.prototype.refreshDrops = function (filter) {
  var self = this;
  var myUrl = '/drops';
  if (filter){
    myUrl+=filter;
  }
  var myPosition = SoapStone.app.mapView.trackingLocation;
  return $.ajax({
    url: myUrl,
    method : "get",
    data: { lat: myPosition.lat(), lon: myPosition.lng() },
    dataType: 'json'
  })
  .then(function(response) {
    var clickableArray = response[0];
    var outsideArray = response[1];
    clickableArray.updateDropsArray(self.addClickableDrop, self.clickableDrops, self.outsideDrops, 50)
    outsideArray.updateDropsArray(self.addOutsideDrop, self.outsideDrops, self.clickableDrops, 100)
  });
};

SoapStone.Map.prototype.loadDrops = function (filter) {
  this.clearMarkers();
	var self = this;
  var myData = { lat: myPosition.lat(), lon: myPosition.lng() }
	var myUrl = '/drops';//drops/filter
  if (filter){
    if (typeof filter !== "number"){
      myUrl+=filter;
    }else{
      myData.user_id = filter;
    }
  }
  var myPosition = SoapStone.app.mapView.trackingLocation;
	return $.ajax({
    url: myUrl,
    method : "get",
    data: myData,
    dataType: 'json'
  })
	.then(function(response) {
    var clickableArray = response[0];
    var outsideArray = response[1];
    clickableArray.forEach(function(drop) {
      self.addClickableDrop(drop);
    });
    outsideArray.forEach(function(drop) {
			self.addOutsideDrop(drop);
		});
	});
};

SoapStone.MapView = function () {
  this.filter = null;
};

SoapStone.MapView.prototype.getLocation = function() {
return new Promise(function(resolve, reject) {
      if ("geolocation" in navigator) {
        navigator.geolocation.getCurrentPosition(function(position) {
          var coords = {};
          coords.latitude = position.coords.latitude;
          coords.longitude = position.coords.longitude;
          resolve(coords);
        });
      } else {
          reject(); //Geolocation not available
      }
  });
};

SoapStone.MapView.prototype.init = function () {
  var self = this;
  var mapStyles = [{featureType: "all",
      elementType: "labels.icon",
      stylers: [
        { visibility: "off" }
      ]
    },
    {
    "featureType": "landscape",
    "stylers": [
      {
        "hue": "#FF0300"
      },
      {
        "saturation": -100
      },
      {
        "lightness": 156
      },
      {
        "gamma": 1
      }
    ]
  },
  {
    "featureType": "road.highway",
    "stylers": [
      {
        "hue": "#FF2500"
      },
      {
        "saturation": -100
      },
      {
        "lightness": 138.60000000000002
      },
      {
        "gamma": 1
      }
    ]
  },
  {
    "featureType": "road.arterial",
    "stylers": [
      {
        "hue": "#7F00FF"
      },
      {
        "saturation": -71.42857142857149
      },
      {
        "lightness": 45.709803921568636
      },
      {
        "gamma": 1
      }
    ]
  },
  {
    "featureType": "road.local",
    "stylers": [
      {
        "hue": "#7F00FF"
      },
      {
        "saturation": -71.42857142857149
      },
      {
        "lightness": 46.50980392156862
      },
      {
        "gamma": 1
      }
    ]
  },
  {
    "featureType": "water",
    "stylers": [
      {
        "hue": "#0078FF"
      },
      {
        "saturation": 0
      },
      {
        "lightness": 47
      },
      {
        "gamma": 1
      }
    ]
  },
  {
    "featureType": "poi",
    "stylers": [
      {
        "hue": "#FF1B00"
      },
      {
        "saturation": -95.8
      },
      {
        "lightness": 143.8
      },
      {
        "gamma": 1
      }
    ]}];//folded text for the style press command option ']' to unfold or '[' to refold
  return new Promise(function (resolve, reject) {
      if ("geolocation" in navigator) {
        navigator.geolocation.getCurrentPosition(function(position) {
          self.trackingLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
          self.mapProp = {
            center: self.trackingLocation, //find center of collection
            zoom:17,
            zoomControlOptions: {
              position: google.maps.ControlPosition.TOP_RIGHT
            },
            streetViewControl: false,
            styles: mapStyles,
            mapTypeId:google.maps.MapTypeId.ROADMAP
         };
         self.map = new google.maps.Map(document.getElementById("googleMap"),self.mapProp);
         self.currentPositionMarker = new google.maps.Marker({
            map: self.map,
            icon: "https://robohash.org/jake.bmp?size=40x40",
            position: self.trackingLocation,
            animation: google.maps.Animation.DROP,
            title: "you are here"
          });
          self.circle = new google.maps.Circle({
            strokeColor: '#0000FF',
            strokeOpacity: 0.25,
            strokeWeight: 2,
            fillColor: '#00FFFF',
            fillOpacity: 0.25,
            map: self.map,
            center: self.trackingLocation,
            radius: 330 * 0.3048 //feet to meters
          });
          resolve(self);
        });
      } else {
        reject(); //Geolocation not available
      }
  });
};

SoapStone.MapView.prototype.showDrops = function (clickable, outside) {
	var self = this;
  clickable.forEach(function(drop){
    if (drop.hasEventListener == null){
      drop.marker.addListener('click', function() {
        SoapStone.app.showDrop(drop.id);
      });
      drop.hasEventListener = true;
    }
    if(drop.marker.map == null){
      drop.marker.setMap(self.map);
    };
  });
  outside.forEach(function(drop){
    if (drop.hasEventListener){
      drop.marker.removeListener('click', function() {//remove??
        SoapStone.app.showDrop(drop.id);
      });
      drop.hasEventListener = null;
    }
    if(drop.marker.map == null){
      drop.marker.setMap(self.map);
    };
  });
};

SoapStone.MapView.prototype.centerMap = function(){
  var self = this;
  self.map.panTo(self.trackingLocation);
};

SoapStone.MapView.prototype.watchCurrentPosition = function() {
  var self = this;
  var positionTimer = navigator.geolocation.watchPosition(function (position) {
    console.log("in the watchCurrentPosition function");
    console.log("lat: ",self.trackingLocation.lat());
    console.log("lng: ",self.trackingLocation.lng());
    self.trackingLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
    setMarkerPosition(self.currentPositionMarker,position);
    setCirclePosition(self.circle, position);
    self.controller.refreshDrops(self.filter);
  });
};

function setMarkerPosition(marker, position) {
  marker.setPosition(new google.maps.LatLng(
    position.coords.latitude,
    position.coords.longitude)
  );
}

function setCirclePosition(circle, position) {
  circle.setCenter(new google.maps.LatLng(
    position.coords.latitude,
    position.coords.longitude)
  );
}

<commit_msg>updated map js<commit_after>SoapStone.Map = function () {
  this.outsideDrops = [];
	this.clickableDrops = [];
  $('#set-center').on('click',function(e){
    SoapStone.app.mapView.centerMap();
  });
};

SoapStone.Map.prototype.addClickableDrop = function (dropData) {
  var drop = new SoapStone.Drop(dropData);
  if (drop.lat && drop.lon) {
    drop.marker = new google.maps.Marker({
      position: new google.maps.LatLng(drop.lat, drop.lon),
      icon: {
        path: google.maps.SymbolPath.BACKWARD_CLOSED_ARROW,//'M -2,0 0,-2 2,0 0,2 z',//
        scale: 6,
        strokeColor: "hsl("+drop.user.hue+",80%,50%)",
        strokeWeight: 1
      }
    });
    drop.marker.setMap(SoapStone.app.mapView.map);
    SoapStone.app.map.clickableDrops.unshift(drop);//bad???? why was 'this' the window and not a map?
  }
};

SoapStone.Map.prototype.addOutsideDrop = function (dropData) {
  var drop = new SoapStone.Drop(dropData);
  if (drop.lat && drop.lon) {
  drop.marker = new google.maps.Marker({
    position: new google.maps.LatLng(drop.lat, drop.lon),
    icon: {
      path: google.maps.SymbolPath.BACKWARD_OPEN_ARROW,
      scale: 4,
      strokeColor: "hsl("+drop.user.hue+",30%,50%)",
      strokeWeight: 3
    }
  });
  drop.marker.setMap(SoapStone.app.mapView.map);
  SoapStone.app.map.outsideDrops.unshift(drop);
  }
};

SoapStone.Map.prototype.clearMarkers = function(){
  this.clickableDrops.forEach(function(drop){
    drop.marker.setMap(null);
  });
  this.outsideDrops.forEach(function(drop){
    drop.marker.setMap(null);
  });
  this.clickableDrops = [];
  this.outsideDrops = [];
};

SoapStone.Map.prototype.refreshDrops = function (filter) {
  var self = this;
  var myUrl = '/drops';
  var myPosition = SoapStone.app.mapView.trackingLocation;
  var myData = { lat: myPosition.lat(), lon: myPosition.lng() }
  if (filter){
    if (typeof filter !== "number"){
      myUrl+=filter;
    }else{
      myData.user_id = filter;
    }
  }
  return $.ajax({
    url: myUrl,
    method : "get",
    data: myData,
    dataType: 'json'
  })
  .then(function(response) {
    var clickableArray = response[0];
    var outsideArray = response[1];
    clickableArray.updateDropsArray(self.addClickableDrop, self.clickableDrops, self.outsideDrops, 50)
    outsideArray.updateDropsArray(self.addOutsideDrop, self.outsideDrops, self.clickableDrops, 100)
  });
};

SoapStone.Map.prototype.loadDrops = function (filter) {
  this.clearMarkers();
	var self = this;
  var myPosition = SoapStone.app.mapView.trackingLocation;
  var myData = { lat: myPosition.lat(), lon: myPosition.lng() }
  var myUrl = '/drops';//drops/filter
  if (filter){
    if (typeof filter !== "number"){
      myUrl+=filter;
    }else{
      myData.user_id = filter;
    }
  }
	return $.ajax({
    url: myUrl,
    method : "get",
    data: myData,
    dataType: 'json'
  })
	.then(function(response) {

    var clickableArray = response[0];
    var outsideArray = response[1];
    clickableArray.forEach(function(drop) {
      self.addClickableDrop(drop);
    });
    outsideArray.forEach(function(drop) {
			self.addOutsideDrop(drop);
		});
	});
};

SoapStone.MapView = function () {
  this.filter = null;
};

SoapStone.MapView.prototype.getLocation = function() {
return new Promise(function(resolve, reject) {
      if ("geolocation" in navigator) {
        navigator.geolocation.getCurrentPosition(function(position) {
          var coords = {};
          coords.latitude = position.coords.latitude;
          coords.longitude = position.coords.longitude;
          resolve(coords);
        });
      } else {
          reject(); //Geolocation not available
      }
  });
};

SoapStone.MapView.prototype.init = function () {
  var self = this;
  var mapStyles = [{featureType: "all",
      elementType: "labels.icon",
      stylers: [
        { visibility: "off" }
      ]
    },
    {
    "featureType": "landscape",
    "stylers": [
      {
        "hue": "#FF0300"
      },
      {
        "saturation": -100
      },
      {
        "lightness": 156
      },
      {
        "gamma": 1
      }
    ]
  },
  {
    "featureType": "road.highway",
    "stylers": [
      {
        "hue": "#FF2500"
      },
      {
        "saturation": -100
      },
      {
        "lightness": 138.60000000000002
      },
      {
        "gamma": 1
      }
    ]
  },
  {
    "featureType": "road.arterial",
    "stylers": [
      {
        "hue": "#7F00FF"
      },
      {
        "saturation": -71.42857142857149
      },
      {
        "lightness": 45.709803921568636
      },
      {
        "gamma": 1
      }
    ]
  },
  {
    "featureType": "road.local",
    "stylers": [
      {
        "hue": "#7F00FF"
      },
      {
        "saturation": -71.42857142857149
      },
      {
        "lightness": 46.50980392156862
      },
      {
        "gamma": 1
      }
    ]
  },
  {
    "featureType": "water",
    "stylers": [
      {
        "hue": "#0078FF"
      },
      {
        "saturation": 0
      },
      {
        "lightness": 47
      },
      {
        "gamma": 1
      }
    ]
  },
  {
    "featureType": "poi",
    "stylers": [
      {
        "hue": "#FF1B00"
      },
      {
        "saturation": -95.8
      },
      {
        "lightness": 143.8
      },
      {
        "gamma": 1
      }
    ]}];//folded text for the style press command option ']' to unfold or '[' to refold
  return new Promise(function (resolve, reject) {
      if ("geolocation" in navigator) {
        navigator.geolocation.getCurrentPosition(function(position) {
          self.trackingLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
          self.mapProp = {
            center: self.trackingLocation, //find center of collection
            zoom:17,
            zoomControlOptions: {
              position: google.maps.ControlPosition.TOP_RIGHT
            },
            streetViewControl: false,
            styles: mapStyles,
            mapTypeId:google.maps.MapTypeId.ROADMAP
         };
         self.map = new google.maps.Map(document.getElementById("googleMap"),self.mapProp);
         self.currentPositionMarker = new google.maps.Marker({
            map: self.map,
            icon: "https://robohash.org/jake.bmp?size=40x40",
            position: self.trackingLocation,
            animation: google.maps.Animation.DROP,
            title: "you are here"
          });
          self.circle = new google.maps.Circle({
            strokeColor: '#0000FF',
            strokeOpacity: 0.25,
            strokeWeight: 2,
            fillColor: '#00FFFF',
            fillOpacity: 0.25,
            map: self.map,
            center: self.trackingLocation,
            radius: 330 * 0.3048 //feet to meters
          });
          resolve(self);
        });
      } else {
        reject(); //Geolocation not available
      }
  });
};

SoapStone.MapView.prototype.showDrops = function (clickable, outside) {
	var self = this;
  clickable.forEach(function(drop){
    if (drop.hasEventListener == null){
      drop.marker.addListener('click', function() {
        SoapStone.app.showDrop(drop.id);
      });
      drop.hasEventListener = true;
    }
    if(drop.marker.map == null){
      drop.marker.setMap(self.map);
    };
  });
  outside.forEach(function(drop){
    if (drop.hasEventListener){
      drop.marker.removeListener('click', function() {//remove??
        SoapStone.app.showDrop(drop.id);
      });
      drop.hasEventListener = null;
    }
    if(drop.marker.map == null){
      drop.marker.setMap(self.map);
    };
  });
};

SoapStone.MapView.prototype.centerMap = function(){
  var self = this;
  self.map.panTo(self.trackingLocation);
};

SoapStone.MapView.prototype.watchCurrentPosition = function() {
  var self = this;
  var positionTimer = navigator.geolocation.watchPosition(function (position) {
    console.log("in the watchCurrentPosition function");
    console.log("lat: ",self.trackingLocation.lat());
    console.log("lng: ",self.trackingLocation.lng());
    self.trackingLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
    setMarkerPosition(self.currentPositionMarker,position);
    setCirclePosition(self.circle, position);
    self.controller.refreshDrops(self.filter);
  });
};

function setMarkerPosition(marker, position) {
  marker.setPosition(new google.maps.LatLng(
    position.coords.latitude,
    position.coords.longitude)
  );
}

function setCirclePosition(circle, position) {
  circle.setCenter(new google.maps.LatLng(
    position.coords.latitude,
    position.coords.longitude)
  );
}

<|endoftext|>


<commit_before><commit_msg>Fix the keyboard listener in set nick to make sure it doesn't stick if you change state.<commit_after><|endoftext|>


<commit_before>let childProcess = require('child_process');
let Log = require('./Log');
let argv = require('yargs').argv;
let PackageManager = require('./PackageManager');

/**
 * @typedef {object} DependencyObject
 * @property {string} package
 * @property {(obj: any) => boolean} [check]
 */

/**
 * @typedef {string|DependencyObject} Dependency
 */

class Dependencies {
    static _queue = {
        /** @type {Dependency[]} */
        items: [],

        /** @type {boolean} */
        requiresReload: false
    };

    /**
     * Create a new Dependencies instance.
     *
     * @param {Dependency[]} dependencies
     */
    constructor(dependencies) {
        this.dependencies = dependencies
            .filter(dep => dep)
            .map(dep => this.normalize(dep));
    }

    /**
     * Create a new Dependencies instance.
     *
     * @param {Dependency|Dependency[]} dependencies
     */
    static queue(dependencies, requiresReload = false) {
        Dependencies._queue.items = Dependencies._queue.items.concat(dependencies);

        Dependencies._queue.requiresReload =
            Dependencies._queue.requiresReload || requiresReload;
    }

    /**
     * Create a new Dependencies instance.
     */
    static installQueued() {
        new Dependencies(Dependencies._queue.items).install(
            Dependencies._queue.requiresReload
        );
    }

    /**
     * Install all dependencies that aren't available.
     *
     * @param {Boolean} abortOnComplete
     */
    install(abortOnComplete = false) {
        let dependencies = this.dependencies.filter(dep => !dep.check());

        if (!dependencies.length) {
            return;
        }

        this.execute(this.buildInstallCommand(dependencies), abortOnComplete);
    }

    /**
     * Execute the provided console command.
     *
     * @param {string}  command
     * @param {Boolean} abortOnComplete
     */
    execute(command, abortOnComplete) {
        Log.feedback(
            'Additional dependencies must be installed. This will only take a moment.'
        );

        Log.feedback(`Running: ${command}`);

        childProcess.execSync(command);

        this.respond(abortOnComplete);
    }

    /**
     * Build the dependency install command.
     *
     * @param {DependencyObject[]}  dependencies
     */
    buildInstallCommand(dependencies) {
        dependencies = dependencies.map(dep => dep.package).join(' ');

        switch (PackageManager.detect()) {
            case 'npm':
                return `npm install ${dependencies} --save-dev --legacy-peer-deps`;

            case 'yarn':
                return `yarn add ${dependencies} --dev`;
        }
    }

    /**
     * Complete the install process.
     *
     * @param {Boolean} abortOnComplete
     */
    respond(abortOnComplete) {
        if (abortOnComplete) {
            Log.feedback(
                typeof abortOnComplete === 'string'
                    ? abortOnComplete
                    : 'Finished. Please run Mix again.'
            );

            if (process.env.NODE_ENV !== 'test') {
                process.exit();
            }
        }
    }

    /**
     * @param {Dependency} dep
     * @returns {DependencyObject}
     */
    normalize(dep) {
        if (typeof dep === 'string') {
            dep = { package: dep };
        }

        const name = dep.package.replace(/(?!^@)@.+$/, '');

        function isInstalled() {
            try {
                require.resolve(name);

                return true;
            } catch (e) {
                return false;
            }
        }

        function isValid() {
            return dep.check ? dep.check(require(name)) : true;
        }

        return {
            ...dep,
            check: () => isInstalled() && isValid()
        };
    }
}

module.exports = Dependencies;
<commit_msg>Set correct exit status when "Please run Mix again." happens (#2811)<commit_after>let childProcess = require('child_process');
let Log = require('./Log');
let argv = require('yargs').argv;
let PackageManager = require('./PackageManager');

/**
 * @typedef {object} DependencyObject
 * @property {string} package
 * @property {(obj: any) => boolean} [check]
 */

/**
 * @typedef {string|DependencyObject} Dependency
 */

class Dependencies {
    static _queue = {
        /** @type {Dependency[]} */
        items: [],

        /** @type {boolean} */
        requiresReload: false
    };

    /**
     * Create a new Dependencies instance.
     *
     * @param {Dependency[]} dependencies
     */
    constructor(dependencies) {
        this.dependencies = dependencies
            .filter(dep => dep)
            .map(dep => this.normalize(dep));
    }

    /**
     * Create a new Dependencies instance.
     *
     * @param {Dependency|Dependency[]} dependencies
     */
    static queue(dependencies, requiresReload = false) {
        Dependencies._queue.items = Dependencies._queue.items.concat(dependencies);

        Dependencies._queue.requiresReload =
            Dependencies._queue.requiresReload || requiresReload;
    }

    /**
     * Create a new Dependencies instance.
     */
    static installQueued() {
        new Dependencies(Dependencies._queue.items).install(
            Dependencies._queue.requiresReload
        );
    }

    /**
     * Install all dependencies that aren't available.
     *
     * @param {Boolean} abortOnComplete
     */
    install(abortOnComplete = false) {
        let dependencies = this.dependencies.filter(dep => !dep.check());

        if (!dependencies.length) {
            return;
        }

        this.execute(this.buildInstallCommand(dependencies), abortOnComplete);
    }

    /**
     * Execute the provided console command.
     *
     * @param {string}  command
     * @param {Boolean} abortOnComplete
     */
    execute(command, abortOnComplete) {
        Log.feedback(
            'Additional dependencies must be installed. This will only take a moment.'
        );

        Log.feedback(`Running: ${command}`);

        childProcess.execSync(command);

        this.respond(abortOnComplete);
    }

    /**
     * Build the dependency install command.
     *
     * @param {DependencyObject[]}  dependencies
     */
    buildInstallCommand(dependencies) {
        dependencies = dependencies.map(dep => dep.package).join(' ');

        switch (PackageManager.detect()) {
            case 'npm':
                return `npm install ${dependencies} --save-dev --legacy-peer-deps`;

            case 'yarn':
                return `yarn add ${dependencies} --dev`;
        }
    }

    /**
     * Complete the install process.
     *
     * @param {Boolean} abortOnComplete
     */
    respond(abortOnComplete) {
        if (abortOnComplete) {
            Log.feedback(
                typeof abortOnComplete === 'string'
                    ? abortOnComplete
                    : 'Finished. Please run Mix again.'
            );

            if (process.env.NODE_ENV !== 'test') {
                process.exit(1);
            }
        }
    }

    /**
     * @param {Dependency} dep
     * @returns {DependencyObject}
     */
    normalize(dep) {
        if (typeof dep === 'string') {
            dep = { package: dep };
        }

        const name = dep.package.replace(/(?!^@)@.+$/, '');

        function isInstalled() {
            try {
                require.resolve(name);

                return true;
            } catch (e) {
                return false;
            }
        }

        function isValid() {
            return dep.check ? dep.check(require(name)) : true;
        }

        return {
            ...dep,
            check: () => isInstalled() && isValid()
        };
    }
}

module.exports = Dependencies;
<|endoftext|>


<commit_before>'use strict';

(function (factory) {
  /*global define*/
  var global = this;
  if (typeof define === 'function' && define.amd) {
    define([], function () {
      return factory(global);
    });
  } else if (typeof exports !== 'undefined') {
    module.exports = factory(global);
  } else {
    global.confug = factory(global);
  }

}(function (global) {
  var confug;

  var _allowedTypes = [ typeof '', typeof true, typeof 1 ] // TODO: (maybe) support function if it returns one of these types
    , _reStageAbbreviation = /^[a-z][\w\d]+$/
    , _defaultStages = [
          { name: 'development', abbrev: 'dev' }
        , { name: 'testing', abbrev: 'test' }
        , { name: 'staging', abbrev: 'stage' }
        , { name: 'production', abbrev: 'prod' }
      ]
    , _globalEnv = {}
    , _configCache = []
    , _defaultOptions = {
          singleton: true
        , fallbackGlobal: true
        , nestedEnv: true
        , stages: null
        , consts: null
        , initial: null
        , env: null
        , overwrites: null
      };

  // import global env, if exists
  if (typeof global !== 'undefined') {
    if (typeof global.process === 'object' && typeof global.process.env === 'object') {
      _globalEnv = global.process.env;
    }
    else if (typeof global.env === 'object') { // browser env specified
      _globalEnv = global.env;
    }
    else { // global.process existence just a coinkydink (doesn't contain env property)
      _globalEnv = global;
    }
  }

  confug = function(env, passedOptions) {
    var opts = {}
      , config
      , iter;

    // no env specified.  exists in global? env is non-Stage object though (options)
    if (typeof passedOptions === 'undefined' && typeof env === 'object' && !(env instanceof Stage)) {
      passedOptions = env;
      env = null;
    }

    // init opts with defaults
    for (iter in _defaultOptions) {
      opts[iter] = _defaultOptions[iter];
    }

    // import options
    if (typeof passedOptions === 'object') {
      for (iter in passedOptions) {
        if (false === _defaultOptions.hasOwnProperty(iter)) {
          throw new Error('Confug Error - Invalid confug option "' + iter + '"');
        }

        opts[iter] = passedOptions[iter];
      }
    }

    // if Config STAGE constants aren't init (via initStages), init them with the defaults
    if (null === Config.STAGE) {
      initStages(opts.stages || _defaultStages);
    }

    // grab env from environment global
    env = env;
    if (true === opts.fallbackGlobal) {
      env = env || _globalEnv.NODE_ENV || _globalEnv.CLIENT_ENV || _globalEnv.ENV;
    }

    // expand non-Stage env
    if (!(env instanceof Stage)) {
      env = Config.STAGE[env] || Config.STAGE.production;
    }

    // limit to one config per environment
    if (true === opts.singleton && _configCache.length > 0) {
      for (var i=0; i < _configCache.length; i++) {
        var cached = _configCache[i];
        if (cached.env === env) {
          if (typeof passedOptions !== 'undefined') {
            // FIXME: (maybe) should this be silently ignored?
            throw new Error('Confug Error - Cannot pass options when a config has already been created');
          }

          return cached;
        }
      }
    }

    config = new Config(env, opts);

    if (true === opts.singleton) {
      _configCache.push(config);
    }

    return config;
  };

  var initStages = confug.initStages = function(stageNames) {
    if (null !== Config.STAGE) {
      throw new Error('Confug Error - Stages have already been initlaized');
    }
    if (typeof stageNames !== 'object' || typeof stageNames.length === 'undefined') {
      throw new Error('Confug Error - Invalid stage names.  Expecting array of stages.');
    }

    var stages = {}
      , stageShorthand = function(stage) {
          return function() {
            return this.env === stage;
          };
        };

    for (var i=0; i < stageNames.length; i++) {
      var stageName = stageNames[i]
        , stage;

      if (typeof stageName === 'object') {
        stage = new Stage(stageName.name || stageName[0], stageName.abbrev || stageName[1]);
      }
      else {
        stage = new Stage(stageName);
      }

      stages[stage.name] = stage;

      if (typeof Config.prototype[stage.abbrev] !== 'undefined') {
        throw new Error('Confug Error - Invalid stage abbreviation "' + stage.abbrev + '": Collision');
      }
      else if (!_reStageAbbreviation.test(stage.abbrev)) {
        throw new Error('Confug Error - Invalid stage abbreviation "' + stage.abbrev + '": Bad characters');
      }

      Config.prototype[stage.abbrev] = stageShorthand(stage);
    }

    Config.STAGE = stages;
  };

  confug.util = {
    env: function(key, def) {
      if (def instanceof Error && typeof _globalEnv[key] === 'undefined') {
        throw def;
      }
      return _globalEnv[key] || def;
    }
  };

  // so we can be strict with our stage comparisons
  var Stage = confug.Stage = function(name, abbrev) {
    this.name = name;
    this.abbrev = abbrev || name;
  };

  Stage.prototype.toString = function() {
    return this.name;
  };

  var Config = confug.Config = function(env, opts) {
    if (typeof env !== 'object' && typeof env !== 'undefined') {
      env = Config.STAGE[env];
    }
    if (typeof env === 'undefined') {
      throw new Error('Confug Error - Environment required');
    }

    opts = opts || {};
    if (typeof opts !== 'object') {
      throw new Error('Confug Error - Invalid options');
    }

    this.env = env;

    this._values = {};
    this._consts = opts.consts || {};

    // init values with constants
    this._extend(this._consts, true);

    // inheritence order
    this._extend(opts.initial); // apply env-independent defaults
    if (null !== opts.env && typeof opts.env === 'object') {
      // apply defaults for env
      if (true === opts.nestedEnv) { // need to determine correct env config data (server, usually)
        this._extend(opts.env[this.env.name] || opts.env[this.env.abbrev]);
      }
      else { // env data is the current environment (client, usually)
        this._extend(opts.env);
      }
    }
    this._extend(opts.overwrites); // apply user passed options
  };

  Config.prototype._validType = function(val) {
    return false !== _allowedTypes.indexOf(typeof val);
  };

  Config.prototype._extend = function(addl, bForce) {
    if (null === addl || typeof addl !== 'object') {
      // FIXME: (maybe) should this not be silently ignored?
      // throw new Error('Confug Error - Invalid config template');
      return;
    }

    for (var k in addl) {
      if (!this._validType(addl[k])) {
        throw new Error('Confug Error - Type "' + typeof addl[k] + '" not supported in config');
      }

      // don't overwrite constants
      if (true === bForce || typeof this._consts[k] === 'undefined') {
        this._values[k] = addl[k];
      }
    }

    return addl;
  };

  // lookup matches start of key, example 'db:' will match all db keys
  //  can also be regexp
  // bDontStrip determines whether to strip out the matching part of the lookup.
  //  ex lookup=db:, result would be object like 'host' less the db: namespace
  Config.prototype.get = function(lookup, bDontStrip) {
    if (typeof lookup === 'undefined') {
      return this._values;
    }
    if (typeof lookup === 'string' && typeof this._values[lookup] !== 'undefined') {
      return this._values[lookup];
    }

    var ret = {}
      , matchingKeys = 0
      , regex = lookup instanceof RegExp
      , lookuplen;

    // no partial namespace lookups for non-regex
    if (false === regex && lookup[lookup.length - 1] !== ':') {
      lookup += ':';
    }

    lookuplen = lookup.length;

    for (var key in this._values) {
      var nkey = key;
      if (regex) {
        if (true === lookup.test(key)) {
          if (!bDontStrip) {
            nkey = key.replace(lookup, '');
          }
          ret[nkey] = this._values[key];
          matchingKeys++;
        }
      }
      else if (0 === key.indexOf(lookup)) {
        if (!bDontStrip) {
          nkey = key.substr(lookuplen);
        }
        ret[nkey] = this._values[key];
        matchingKeys++;
      }
    }

    if (0 === matchingKeys) {
      return; // not found, return undefined
    }
    else {
      return ret; // return all matching
    }
  };

  // support?
  // Config.prototype.set = function(key, val) {
  //   if (typeof key === 'object' && typeof val === 'undefined') {
  //     return this.extend(key); // obj lit passed
  //   }

  //   return this._values[key] = val;
  // };

  Config.prototype.is = function(envs) {
    if (typeof envs === 'string') {
      return this.env.name === envs;
    }
    else if (envs instanceof Stage) {
      return this.env.name === envs.name;
    }
    else if (typeof envs === 'object' && typeof envs.length !== 'undefined') {
      for (var i=0; i < envs.length; i++) {
        if (this.is(envs[i])) {
          return true;
        }
      }

      return false;
    }

    throw new Error('Confug Error - Invalid lookup environments specified');
  };

  Config.STAGE = null; // populated by factory or confug.initStages

  return confug;
}));
<commit_msg>jshint, remove jscs<commit_after>'use strict';

(function (global, factory) {
  /*global define*/
  if (typeof define === 'function' && define.amd) {
    define([], function () {
      return factory(global);
    });
  } else if (typeof exports !== 'undefined') {
    module.exports = factory(global);
  } else {
    global.confug = factory(global);
  }

}(this, function (global) {
  var confug;

  var _allowedTypes = [ typeof '', typeof true, typeof 1 ] // TODO: (maybe) support function if it returns one of these types
    , _reStageAbbreviation = /^[a-z][\w\d]+$/
    , _defaultStages = [
          { name: 'development', abbrev: 'dev' }
        , { name: 'testing', abbrev: 'test' }
        , { name: 'staging', abbrev: 'stage' }
        , { name: 'production', abbrev: 'prod' }
      ]
    , _globalEnv = {}
    , _configCache = []
    , _defaultOptions = {
          singleton: true
        , fallbackGlobal: true
        , nestedEnv: true
        , stages: null
        , consts: null
        , initial: null
        , env: null
        , overwrites: null
      };

  // import global env, if exists
  if (typeof global !== 'undefined') {
    if (typeof global.process === 'object' && typeof global.process.env === 'object') {
      _globalEnv = global.process.env;
    }
    else if (typeof global.env === 'object') { // browser env specified
      _globalEnv = global.env;
    }
    else { // global.process existence just a coinkydink (doesn't contain env property)
      _globalEnv = global;
    }
  }

  confug = function(env, passedOptions) {
    var opts = {}
      , config
      , iter;

    // no env specified.  exists in global? env is non-Stage object though (options)
    if (typeof passedOptions === 'undefined' && typeof env === 'object' && !(env instanceof Stage)) {
      passedOptions = env;
      env = null;
    }

    // init opts with defaults
    for (iter in _defaultOptions) {
      opts[iter] = _defaultOptions[iter];
    }

    // import options
    if (typeof passedOptions === 'object') {
      for (iter in passedOptions) {
        if (false === _defaultOptions.hasOwnProperty(iter)) {
          throw new Error('Confug Error - Invalid confug option "' + iter + '"');
        }

        opts[iter] = passedOptions[iter];
      }
    }

    // if Config STAGE constants aren't init (via initStages), init them with the defaults
    if (null === Config.STAGE) {
      initStages(opts.stages || _defaultStages);
    }

    // grab env from environment global
    env = env;
    if (true === opts.fallbackGlobal) {
      env = env || _globalEnv.NODE_ENV || _globalEnv.CLIENT_ENV || _globalEnv.ENV;
    }

    // expand non-Stage env
    if (!(env instanceof Stage)) {
      env = Config.STAGE[env] || Config.STAGE.production;
    }

    // limit to one config per environment
    if (true === opts.singleton && _configCache.length > 0) {
      for (var i=0; i < _configCache.length; i++) {
        var cached = _configCache[i];
        if (cached.env === env) {
          if (typeof passedOptions !== 'undefined') {
            // FIXME: (maybe) should this be silently ignored?
            throw new Error('Confug Error - Cannot pass options when a config has already been created');
          }

          return cached;
        }
      }
    }

    config = new Config(env, opts);

    if (true === opts.singleton) {
      _configCache.push(config);
    }

    return config;
  };

  var initStages = confug.initStages = function(stageNames) {
    if (null !== Config.STAGE) {
      throw new Error('Confug Error - Stages have already been initlaized');
    }
    if (typeof stageNames !== 'object' || typeof stageNames.length === 'undefined') {
      throw new Error('Confug Error - Invalid stage names.  Expecting array of stages.');
    }

    var stages = {}
      , stageShorthand = function(stage) {
          return function() {
            return this.env === stage;
          };
        };

    for (var i=0; i < stageNames.length; i++) {
      var stageName = stageNames[i]
        , stage;

      if (typeof stageName === 'object') {
        stage = new Stage(stageName.name || stageName[0], stageName.abbrev || stageName[1]);
      }
      else {
        stage = new Stage(stageName);
      }

      stages[stage.name] = stage;

      if (typeof Config.prototype[stage.abbrev] !== 'undefined') {
        throw new Error('Confug Error - Invalid stage abbreviation "' + stage.abbrev + '": Collision');
      }
      else if (!_reStageAbbreviation.test(stage.abbrev)) {
        throw new Error('Confug Error - Invalid stage abbreviation "' + stage.abbrev + '": Bad characters');
      }

      Config.prototype[stage.abbrev] = stageShorthand(stage);
    }

    Config.STAGE = stages;
  };

  confug.util = {
    env: function(key, def) {
      if (def instanceof Error && typeof _globalEnv[key] === 'undefined') {
        throw def;
      }
      return _globalEnv[key] || def;
    }
  };

  // so we can be strict with our stage comparisons
  var Stage = confug.Stage = function(name, abbrev) {
    this.name = name;
    this.abbrev = abbrev || name;
  };

  Stage.prototype.toString = function() {
    return this.name;
  };

  var Config = confug.Config = function(env, opts) {
    if (typeof env !== 'object' && typeof env !== 'undefined') {
      env = Config.STAGE[env];
    }
    if (typeof env === 'undefined') {
      throw new Error('Confug Error - Environment required');
    }

    opts = opts || {};
    if (typeof opts !== 'object') {
      throw new Error('Confug Error - Invalid options');
    }

    this.env = env;

    this._values = {};
    this._consts = opts.consts || {};

    // init values with constants
    this._extend(this._consts, true);

    // inheritence order
    this._extend(opts.initial); // apply env-independent defaults
    if (null !== opts.env && typeof opts.env === 'object') {
      // apply defaults for env
      if (true === opts.nestedEnv) { // need to determine correct env config data (server, usually)
        this._extend(opts.env[this.env.name] || opts.env[this.env.abbrev]);
      }
      else { // env data is the current environment (client, usually)
        this._extend(opts.env);
      }
    }
    this._extend(opts.overwrites); // apply user passed options
  };

  Config.prototype._validType = function(val) {
    return false !== _allowedTypes.indexOf(typeof val);
  };

  Config.prototype._extend = function(addl, bForce) {
    if (null === addl || typeof addl !== 'object') {
      // FIXME: (maybe) should this not be silently ignored?
      // throw new Error('Confug Error - Invalid config template');
      return;
    }

    for (var k in addl) {
      if (!this._validType(addl[k])) {
        throw new Error('Confug Error - Type "' + typeof addl[k] + '" not supported in config');
      }

      // don't overwrite constants
      if (true === bForce || typeof this._consts[k] === 'undefined') {
        this._values[k] = addl[k];
      }
    }

    return addl;
  };

  // lookup matches start of key, example 'db:' will match all db keys
  //  can also be regexp
  // bDontStrip determines whether to strip out the matching part of the lookup.
  //  ex lookup=db:, result would be object like 'host' less the db: namespace
  Config.prototype.get = function(lookup, bDontStrip) {
    if (typeof lookup === 'undefined') {
      return this._values;
    }
    if (typeof lookup === 'string' && typeof this._values[lookup] !== 'undefined') {
      return this._values[lookup];
    }

    var ret = {}
      , matchingKeys = 0
      , regex = lookup instanceof RegExp
      , lookuplen;

    // no partial namespace lookups for non-regex
    if (false === regex && lookup[lookup.length - 1] !== ':') {
      lookup += ':';
    }

    lookuplen = lookup.length;

    for (var key in this._values) {
      var nkey = key;
      if (regex) {
        if (true === lookup.test(key)) {
          if (!bDontStrip) {
            nkey = key.replace(lookup, '');
          }
          ret[nkey] = this._values[key];
          matchingKeys++;
        }
      }
      else if (0 === key.indexOf(lookup)) {
        if (!bDontStrip) {
          nkey = key.substr(lookuplen);
        }
        ret[nkey] = this._values[key];
        matchingKeys++;
      }
    }

    if (0 === matchingKeys) {
      return; // not found, return undefined
    }
    else {
      return ret; // return all matching
    }
  };

  // support?
  // Config.prototype.set = function(key, val) {
  //   if (typeof key === 'object' && typeof val === 'undefined') {
  //     return this.extend(key); // obj lit passed
  //   }

  //   return this._values[key] = val;
  // };

  Config.prototype.is = function(envs) {
    if (typeof envs === 'string') {
      return this.env.name === envs;
    }
    else if (envs instanceof Stage) {
      return this.env.name === envs.name;
    }
    else if (typeof envs === 'object' && typeof envs.length !== 'undefined') {
      for (var i=0; i < envs.length; i++) {
        if (this.is(envs[i])) {
          return true;
        }
      }

      return false;
    }

    throw new Error('Confug Error - Invalid lookup environments specified');
  };

  Config.STAGE = null; // populated by factory or confug.initStages

  return confug;
}));
<|endoftext|>


<commit_before><commit_msg>fix csv.readFile<commit_after><|endoftext|>


<commit_before><commit_msg>Better attribute representation in Quick XPath<commit_after><|endoftext|>