<commit_before>'use strict';

var zmq         = require('zmq');
var dbc         = require('dbc');
var binaryutils = require('./binaryutils.js');

var __hasProp = Object.prototype.hasOwnProperty;

var pre_process_filters  = [];
var post_process_filters = [];

var status = {
   OK_200                     : 200,
   NO_CONTENT_204             : 204,
   BAD_REQUEST_400            : 400,
   UNAUTHORIZED_401           : 401,
   FORBIDDEN_402              : 402,
   NOT_FOUND_404              : 404,
   INTERNAL_SERVER_ERROR_500  : 500
};

var standard_headers = {
   plain : {
      "access-control-allow-origin" : '*',
      'Content-Type': 'text/plain; charset=utf-8'
   },
   json  : {
      "access-control-allow-origin" : '*',
      'Content-Type': 'application/json; charset=utf-8'
   },
   html  : {
      "access-control-allow-origin" : '*',
      'Content-Type': 'text/html; charset=utf-8'
   },
   stream: {
      "access-control-allow-origin" : '*',
      'Content-Type': 'text/event-stream; charset=utf-8',
      'Cache-Control' : 'no-cache',
      'Connection'    : 'keep-alive'
   }
};

var header_cors = {
   "access-control-allow-origin" : "*",
   "access-control-allow-methods": "GET, POST, PUT, DELETE, OPTIONS, PATCH",
   "access-control-allow-headers": "content-type, accept, authorization",
   "access-control-max-age"      : 10, // Seconds.
   "content-length"              : 0
};

var statusMessages = {
   '100': 'Continue',
   '101': 'Switching Protocols',
   '200': 'OK',
   '201': 'Created',
   '202': 'Accepted',
   '203': 'Non-Authoritative Information',
   '204': 'No Content',
   '205': 'Reset Content',
   '206': 'Partial Content',
   '300': 'Multiple Choices',
   '301': 'Moved Permanently',
   '302': 'Found',
   '303': 'See Other',
   '304': 'Not Modified',
   '305': 'Use Proxy',
   '307': 'Temporary Redirect',
   '400': 'Bad Request',
   '401': 'Unauthorized',
   '402': 'Payment Required',
   '403': 'Forbidden',
   '404': 'Not Found',
   '405': 'Method Not Allowed',
   '406': 'Not Acceptable',
   '407': 'Proxy Authentication Required',
   '408': 'Request Timeout',
   '409': 'Conflict',
   '410': 'Gone',
   '411': 'Length Required',
   '412': 'Precondition Failed',
   '413': 'Request Entity Too Large',
   '414': 'Request-URI Too Large',
   '415': 'Unsupported Media Type',
   '416': 'Request Range Not Satisfiable',
   '417': 'Expectation Failed',
   '500': 'Internal Server Error',
   '501': 'Not Implemented',
   '502': 'Bad Gateway',
   '503': 'Service Unavailable',
   '504': 'Gateway Timeout',
   '505': 'HTTP Version Not Supported'
};

var setCors = function(headers){
   header_cors = headers;
};

var addPreProcessFilter = function(fun){
   pre_process_filters.push(fun);
};

var addPostProcessFilter = function(fun){
   post_process_filters.push(fun);
};

var split = function(str, chr, limit) {
   var parts = str.split  (chr);
   var ret   = parts.slice(0, limit - 1);

   ret.push(parts.slice(limit - 1).join(chr));
   return ret;
};

var parseNetstring = function(ns) {

   var nsSplit = split(ns, ':', 2);
   var length  = parseInt  (nsSplit[0], 10);
   var payload = nsSplit[1];

   if (payload.length -1 < length){
      length = payload.length -1
   }

   if (payload[length] !== ',') {
      throw 'Netstring did not end in ","';
   }

   return [ payload.slice(0, length), payload.slice(length + 1) ];
};

var getJSON = function(str){
   try {
      return JSON.parse(str);
   } catch(e) {
      return null;
   }
};

var isValidJSON = function(str){
   if (0 === str.length){
      return true;
   }
   try {
      JSON.parse(str);
      return true;
   } catch(e) {
      return false;
   }
};

var parse = function(mongrelString) {

   var mongrelStringSplit = split(mongrelString, ' ', 4);

   var uuid       = mongrelStringSplit[0];
   var connId     = parseInt(mongrelStringSplit[1]);
   var path       = mongrelStringSplit[2];
   var payload    = mongrelStringSplit[3];

   console.log("££££££££££££££££££££")
   console.log(payload)

   var paySplit   = parseNetstring(payload);
   var headers    = getJSON       (paySplit[0]);
   var body       = parseNetstring(paySplit[1])[0];

   var valid_json = isValidJSON(body);
   var json       = getJSON(body);

   return {
      headers    : headers,
      uuid       : uuid,
      connId     : connId,
      path       : path,
      json       : json,
      valid_json : valid_json
   };
};

var dataToBuffer = function(data){

   if (Buffer.isBuffer(data)){
      return data;
   }

   var body = (Object.prototype.toString.call(data) === '[object String]') ? data : JSON.stringify(data);

   if (undefined === body){
      body = '';
   }

   return new Buffer(body, 'utf8' );
};

var buildZmqResponse = function(uuid, connId, status, headers, data) {

   var header_arr = [];
   var dataBuffer = dataToBuffer(data);

   header_arr.push('Content-Length: ' + dataBuffer.length);

   for (var header in headers) {
      if (__hasProp.call(headers, header)) {
         header_arr.push('' + header + ': ' + headers[header]);
      }
   }

   var str = ''
      + uuid
      + ' '
      + String(connId).length
      + ':'
      + connId
      + ', '
      + 'HTTP/1.1 '
      + status
      + ' '
      + statusMessages[status]
      + '\r\n'
      + header_arr.join('\r\n')
      + '\r\n\r\n';

   var strBuffer = new Buffer(str, 'utf8' );

   return Buffer.concat([strBuffer, dataBuffer]);
};

var sender = function(config) {

   dbc.hasMember(config, 'spec');
   dbc.hasMemberIn(config, 'type', ['pub', 'push']);

   var send      = zmq.socket(config.type);
   send.identity = config.id;

   process.on('exit', function(){
      if (send){
         send.close();
         process.exit();
      }
   });

   if (config.bind) {
      send.bindSync(config.spec);
   } else {
      send.connect(config.spec);
   }

   if (config.isMongrel2) {
      return {
         'send' : function (uuid, connId, status, headers, body) {

            var msg = {
               'uuid'    : uuid,
               'connId'  : connId,
               'status'  : status,
               'headers' : headers,
               'body'    : body
            };

            for (var i in post_process_filters) {
               if(post_process_filters.hasOwnProperty(i)) {
                  post_process_filters[i](msg);
               }

            }

            var message = buildZmqResponse(msg.uuid, msg.connId, msg.status, msg.headers, msg.body);
            return send.send(message);
         }
      };
   } else {
      return {
         'send' : function (message) {
            send.send(JSON.stringify(message));
         }
      };
   }
};

var readFirstLine = function(data) {

   for (var i = 0; i < data.length; i++) {
      if (10 === data.readInt8(i) && 13 === data.readInt8(i-1)) {
         return data.toString('utf8', 0, i);
      }
   }
   return data.toString('utf8');
};

var getHeadersAndMongrel2 = function(data) {

   var mongrelString      = readFirstLine(data);
   var mongrelStringSplit = split(mongrelString, ' ', 4);
   var payload            = mongrelStringSplit[3];
   var paySplit           = parseNetstring(payload);

   return [mongrelStringSplit[0], mongrelStringSplit[1], mongrelStringSplit[2], getJSON(paySplit[0])];

};

var receiver = function(config, error_config, callback) {

   dbc.hasMember           (config, 'spec');
   dbc.hasMemberIn         (config, 'type', ['sub', 'pull']);
   dbc.conditionalHasMember(config, 'subscribe', config.type === 'sub');

   var receive      = zmq.socket(config.type);
   receive.identity = config.id;

   var client = null;

   if (config.isMongrel2) {
      dbc.hasMember  (error_config, 'spec');
      dbc.assert     (error_config.isMongrel2 === true);
      client = zmq.socket('pub');
      client.connect(error_config.spec);
   }

   process.on('exit', function() {
      if (receive) {
         receive.close();
      }
      if (config.isMongrel2 && client) {
         client.close();
      }
      process.exit();
   });

   if (config.isMongrel2) {
      receive.on('message', function (envelope) {

         var headersAndMongrel2 = getHeadersAndMongrel2(envelope);
         var headers            = headersAndMongrel2[3];

         var proceed = true;

         var filterResponse = function (uuid, connId, status, headers, body) {
            proceed = false;
            var message = buildZmqResponse(uuid, connId, status, headers, body);
            return client.send(message);
         };

         var callbackWithFilter = function(zmqMsg) {

            for (var i in pre_process_filters) {
               if(pre_process_filters.hasOwnProperty(i)) {
                  pre_process_filters[i](zmqMsg, filterResponse);
                  if (false === proceed) {
                     return;
                  }
               }
            }

            callback(zmqMsg);
         };

         if( binaryutils.isBinaryUpload(headers)) {
            binaryutils.processBinaryUpload(headersAndMongrel2, client, envelope, callbackWithFilter);
         } else {
            var zmqMsg = parse(envelope.toString('utf8'));

            if(zmqMsg.headers.METHOD === 'JSON' && 'disconnect' === zmqMsg.json.type) {
               //do nothing
            } else if (zmqMsg.headers.METHOD === 'OPTIONS') {
               client.send(buildZmqResponse(zmqMsg.uuid, zmqMsg.connId, status.NO_CONTENT_204, header_cors, ''));
            } else if (!zmqMsg.valid_json) {
               client.send(buildZmqResponse(zmqMsg.uuid, zmqMsg.connId, status.BAD_REQUEST_400, standard_headers.json, {'message':'Invalid JSON'}));
            } else {
               delete zmqMsg['valid_json'];
               return callbackWithFilter(zmqMsg);
            }
         }
      });
   } else {
      receive.on('message', function (envelope) {
         var zmqMsg = envelope.toString('utf8');
         return callback(JSON.parse(zmqMsg));
      });
   }

   if (config.bind) {
      receive.bindSync(config.spec);
   } else {
      receive.connect(config.spec);
   }

   if ('sub' === config.type){
      receive.subscribe(config.subscribe);
   }
};

var setMongrel2UploadDir = function(dir) {
   binaryutils.setMongrel2UploadDir(dir);
};

module.exports.status               = status;
module.exports.getJSON              = getJSON;
module.exports.parse                = parse;
module.exports.parseNetstring       = parseNetstring;
module.exports.receiver             = receiver;
module.exports.sender               = sender;
module.exports.buildZmqResponse     = buildZmqResponse;
module.exports.setCors              = setCors;
module.exports.addPreProcessFilter  = addPreProcessFilter;
module.exports.addPostProcessFilter = addPostProcessFilter;
module.exports.setMongrel2UploadDir = setMongrel2UploadDir;
module.exports.standard_headers     = standard_headers;
<commit_msg>removed comments<commit_after>'use strict';

var zmq         = require('zmq');
var dbc         = require('dbc');
var binaryutils = require('./binaryutils.js');

var __hasProp = Object.prototype.hasOwnProperty;

var pre_process_filters  = [];
var post_process_filters = [];

var status = {
   OK_200                     : 200,
   NO_CONTENT_204             : 204,
   BAD_REQUEST_400            : 400,
   UNAUTHORIZED_401           : 401,
   FORBIDDEN_402              : 402,
   NOT_FOUND_404              : 404,
   INTERNAL_SERVER_ERROR_500  : 500
};

var standard_headers = {
   plain : {
      "access-control-allow-origin" : '*',
      'Content-Type': 'text/plain; charset=utf-8'
   },
   json  : {
      "access-control-allow-origin" : '*',
      'Content-Type': 'application/json; charset=utf-8'
   },
   html  : {
      "access-control-allow-origin" : '*',
      'Content-Type': 'text/html; charset=utf-8'
   },
   stream: {
      "access-control-allow-origin" : '*',
      'Content-Type': 'text/event-stream; charset=utf-8',
      'Cache-Control' : 'no-cache',
      'Connection'    : 'keep-alive'
   }
};

var header_cors = {
   "access-control-allow-origin" : "*",
   "access-control-allow-methods": "GET, POST, PUT, DELETE, OPTIONS, PATCH",
   "access-control-allow-headers": "content-type, accept, authorization",
   "access-control-max-age"      : 10, // Seconds.
   "content-length"              : 0
};

var statusMessages = {
   '100': 'Continue',
   '101': 'Switching Protocols',
   '200': 'OK',
   '201': 'Created',
   '202': 'Accepted',
   '203': 'Non-Authoritative Information',
   '204': 'No Content',
   '205': 'Reset Content',
   '206': 'Partial Content',
   '300': 'Multiple Choices',
   '301': 'Moved Permanently',
   '302': 'Found',
   '303': 'See Other',
   '304': 'Not Modified',
   '305': 'Use Proxy',
   '307': 'Temporary Redirect',
   '400': 'Bad Request',
   '401': 'Unauthorized',
   '402': 'Payment Required',
   '403': 'Forbidden',
   '404': 'Not Found',
   '405': 'Method Not Allowed',
   '406': 'Not Acceptable',
   '407': 'Proxy Authentication Required',
   '408': 'Request Timeout',
   '409': 'Conflict',
   '410': 'Gone',
   '411': 'Length Required',
   '412': 'Precondition Failed',
   '413': 'Request Entity Too Large',
   '414': 'Request-URI Too Large',
   '415': 'Unsupported Media Type',
   '416': 'Request Range Not Satisfiable',
   '417': 'Expectation Failed',
   '500': 'Internal Server Error',
   '501': 'Not Implemented',
   '502': 'Bad Gateway',
   '503': 'Service Unavailable',
   '504': 'Gateway Timeout',
   '505': 'HTTP Version Not Supported'
};

var setCors = function(headers){
   header_cors = headers;
};

var addPreProcessFilter = function(fun){
   pre_process_filters.push(fun);
};

var addPostProcessFilter = function(fun){
   post_process_filters.push(fun);
};

var split = function(str, chr, limit) {
   var parts = str.split  (chr);
   var ret   = parts.slice(0, limit - 1);

   ret.push(parts.slice(limit - 1).join(chr));
   return ret;
};

var parseNetstring = function(ns) {

   var nsSplit = split(ns, ':', 2);
   var length  = parseInt  (nsSplit[0], 10);
   var payload = nsSplit[1];

   if (payload.length -1 < length){
      length = payload.length -1
   }

   if (payload[length] !== ',') {
      throw 'Netstring did not end in ","';
   }

   return [ payload.slice(0, length), payload.slice(length + 1) ];
};

var getJSON = function(str){
   try {
      return JSON.parse(str);
   } catch(e) {
      return null;
   }
};

var isValidJSON = function(str){
   if (0 === str.length){
      return true;
   }
   try {
      JSON.parse(str);
      return true;
   } catch(e) {
      return false;
   }
};

var parse = function(mongrelString) {

   var mongrelStringSplit = split(mongrelString, ' ', 4);

   var uuid       = mongrelStringSplit[0];
   var connId     = parseInt(mongrelStringSplit[1]);
   var path       = mongrelStringSplit[2];
   var payload    = mongrelStringSplit[3];

   var paySplit   = parseNetstring(payload);
   var headers    = getJSON       (paySplit[0]);
   var body       = parseNetstring(paySplit[1])[0];

   var valid_json = isValidJSON(body);
   var json       = getJSON(body);

   return {
      headers    : headers,
      uuid       : uuid,
      connId     : connId,
      path       : path,
      json       : json,
      valid_json : valid_json
   };
};

var dataToBuffer = function(data){

   if (Buffer.isBuffer(data)){
      return data;
   }

   var body = (Object.prototype.toString.call(data) === '[object String]') ? data : JSON.stringify(data);

   if (undefined === body){
      body = '';
   }

   return new Buffer(body, 'utf8' );
};

var buildZmqResponse = function(uuid, connId, status, headers, data) {

   var header_arr = [];
   var dataBuffer = dataToBuffer(data);

   header_arr.push('Content-Length: ' + dataBuffer.length);

   for (var header in headers) {
      if (__hasProp.call(headers, header)) {
         header_arr.push('' + header + ': ' + headers[header]);
      }
   }

   var str = ''
      + uuid
      + ' '
      + String(connId).length
      + ':'
      + connId
      + ', '
      + 'HTTP/1.1 '
      + status
      + ' '
      + statusMessages[status]
      + '\r\n'
      + header_arr.join('\r\n')
      + '\r\n\r\n';

   var strBuffer = new Buffer(str, 'utf8' );

   return Buffer.concat([strBuffer, dataBuffer]);
};

var sender = function(config) {

   dbc.hasMember(config, 'spec');
   dbc.hasMemberIn(config, 'type', ['pub', 'push']);

   var send      = zmq.socket(config.type);
   send.identity = config.id;

   process.on('exit', function(){
      if (send){
         send.close();
         process.exit();
      }
   });

   if (config.bind) {
      send.bindSync(config.spec);
   } else {
      send.connect(config.spec);
   }

   if (config.isMongrel2) {
      return {
         'send' : function (uuid, connId, status, headers, body) {

            var msg = {
               'uuid'    : uuid,
               'connId'  : connId,
               'status'  : status,
               'headers' : headers,
               'body'    : body
            };

            for (var i in post_process_filters) {
               if(post_process_filters.hasOwnProperty(i)) {
                  post_process_filters[i](msg);
               }

            }

            var message = buildZmqResponse(msg.uuid, msg.connId, msg.status, msg.headers, msg.body);
            return send.send(message);
         }
      };
   } else {
      return {
         'send' : function (message) {
            send.send(JSON.stringify(message));
         }
      };
   }
};

var readFirstLine = function(data) {

   for (var i = 0; i < data.length; i++) {
      if (10 === data.readInt8(i) && 13 === data.readInt8(i-1)) {
         return data.toString('utf8', 0, i);
      }
   }
   return data.toString('utf8');
};

var getHeadersAndMongrel2 = function(data) {

   var mongrelString      = readFirstLine(data);
   var mongrelStringSplit = split(mongrelString, ' ', 4);
   var payload            = mongrelStringSplit[3];
   var paySplit           = parseNetstring(payload);

   return [mongrelStringSplit[0], mongrelStringSplit[1], mongrelStringSplit[2], getJSON(paySplit[0])];

};

var receiver = function(config, error_config, callback) {

   dbc.hasMember           (config, 'spec');
   dbc.hasMemberIn         (config, 'type', ['sub', 'pull']);
   dbc.conditionalHasMember(config, 'subscribe', config.type === 'sub');

   var receive      = zmq.socket(config.type);
   receive.identity = config.id;

   var client = null;

   if (config.isMongrel2) {
      dbc.hasMember  (error_config, 'spec');
      dbc.assert     (error_config.isMongrel2 === true);
      client = zmq.socket('pub');
      client.connect(error_config.spec);
   }

   process.on('exit', function() {
      if (receive) {
         receive.close();
      }
      if (config.isMongrel2 && client) {
         client.close();
      }
      process.exit();
   });

   if (config.isMongrel2) {
      receive.on('message', function (envelope) {

         var headersAndMongrel2 = getHeadersAndMongrel2(envelope);
         var headers            = headersAndMongrel2[3];

         var proceed = true;

         var filterResponse = function (uuid, connId, status, headers, body) {
            proceed = false;
            var message = buildZmqResponse(uuid, connId, status, headers, body);
            return client.send(message);
         };

         var callbackWithFilter = function(zmqMsg) {

            for (var i in pre_process_filters) {
               if(pre_process_filters.hasOwnProperty(i)) {
                  pre_process_filters[i](zmqMsg, filterResponse);
                  if (false === proceed) {
                     return;
                  }
               }
            }

            callback(zmqMsg);
         };

         if( binaryutils.isBinaryUpload(headers)) {
            binaryutils.processBinaryUpload(headersAndMongrel2, client, envelope, callbackWithFilter);
         } else {
            var zmqMsg = parse(envelope.toString('utf8'));

            if(zmqMsg.headers.METHOD === 'JSON' && 'disconnect' === zmqMsg.json.type) {
               //do nothing
            } else if (zmqMsg.headers.METHOD === 'OPTIONS') {
               client.send(buildZmqResponse(zmqMsg.uuid, zmqMsg.connId, status.NO_CONTENT_204, header_cors, ''));
            } else if (!zmqMsg.valid_json) {
               client.send(buildZmqResponse(zmqMsg.uuid, zmqMsg.connId, status.BAD_REQUEST_400, standard_headers.json, {'message':'Invalid JSON'}));
            } else {
               delete zmqMsg['valid_json'];
               return callbackWithFilter(zmqMsg);
            }
         }
      });
   } else {
      receive.on('message', function (envelope) {
         var zmqMsg = envelope.toString('utf8');
         return callback(JSON.parse(zmqMsg));
      });
   }

   if (config.bind) {
      receive.bindSync(config.spec);
   } else {
      receive.connect(config.spec);
   }

   if ('sub' === config.type){
      receive.subscribe(config.subscribe);
   }
};

var setMongrel2UploadDir = function(dir) {
   binaryutils.setMongrel2UploadDir(dir);
};

module.exports.status               = status;
module.exports.getJSON              = getJSON;
module.exports.parse                = parse;
module.exports.parseNetstring       = parseNetstring;
module.exports.receiver             = receiver;
module.exports.sender               = sender;
module.exports.buildZmqResponse     = buildZmqResponse;
module.exports.setCors              = setCors;
module.exports.addPreProcessFilter  = addPreProcessFilter;
module.exports.addPostProcessFilter = addPostProcessFilter;
module.exports.setMongrel2UploadDir = setMongrel2UploadDir;
module.exports.standard_headers     = standard_headers;
<|endoftext|>


<commit_before>/*!
 * mocha
 * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var path = require('path')
  , utils = require('./utils');

/**
 * Expose `Mocha`.
 */

exports = module.exports = Mocha;

/**
 * Expose internals.
 */

exports.utils = utils;
exports.interfaces = require('./interfaces');
exports.reporters = require('./reporters');
exports.Runnable = require('./runnable');
exports.Context = require('./context');
exports.Runner = require('./runner');
exports.Suite = require('./suite');
exports.Hook = require('./hook');
exports.Test = require('./test');

/**
 * Return image `name` path.
 *
 * @param {String} name
 * @return {String}
 * @api private
 */

function image(name) {
  return __dirname + '/../images/' + name + '.png';
}

/**
 * Setup mocha with `options`.
 *
 * Options:
 *
 *   - `ui` name "bdd", "tdd", "exports" etc
 *   - `reporter` reporter instance, defaults to `mocha.reporters.Dot`
 *   - `globals` array of accepted globals
 *   - `timeout` timeout in milliseconds
 *   - `bail` bail on the first test failure
 *   - `slow` milliseconds to wait before considering a test slow
 *   - `ignoreLeaks` ignore global leaks
 *   - `grep` string or regexp to filter tests with
 *
 * @param {Object} options
 * @api public
 */

function Mocha(options) {
  options = options || {};
  this.files = [];
  this.options = options;
  this.grep(options.grep);
  this.suite = new exports.Suite('', new exports.Context);
  this.ui(options.ui);
  this.bail(options.bail);
  this.reporter(options.reporter);
  if (null != options.timeout) this.timeout(options.timeout);
  this.useColors(options.useColors)
  if (options.slow) this.slow(options.slow);

  this.suite.on('pre-require', function (context) {
    exports.afterEach = context.afterEach || context.teardown;
    exports.after = context.after || context.suiteTeardown;
    exports.beforeEach = context.beforeEach || context.setup;
    exports.before = context.before || context.suiteSetup;
    exports.describe = context.describe || context.suite;
    exports.it = context.it || context.test;
    exports.setup = context.setup || context.beforeEach;
    exports.suiteSetup = context.suiteSetup || context.before;
    exports.suiteTeardown = context.suiteTeardown || context.after;
    exports.suite = context.suite || context.describe;
    exports.teardown = context.teardown || context.afterEach;
    exports.test = context.test || context.it;
  });
}

/**
 * Enable or disable bailing on the first failure.
 *
 * @param {Boolean} [bail]
 * @api public
 */

Mocha.prototype.bail = function(bail){
  if (0 == arguments.length) bail = true;
  this.suite.bail(bail);
  return this;
};

/**
 * Add test `file`.
 *
 * @param {String} file
 * @api public
 */

Mocha.prototype.addFile = function(file){
  this.files.push(file);
  return this;
};

/**
 * Set reporter to `reporter`, defaults to "dot".
 *
 * @param {String|Function} reporter name or constructor
 * @api public
 */

Mocha.prototype.reporter = function(reporter){
  if ('function' == typeof reporter) {
    this._reporter = reporter;
  } else {
    reporter = reporter || 'dot';
    var _reporter;
    try { _reporter = require('./reporters/' + reporter); } catch (err) {};
    if (!_reporter) try { _reporter = require(reporter); } catch (err) {};
    if (!_reporter && reporter === 'teamcity')
      console.warn('The Teamcity reporter was moved to a package named ' +
        'mocha-teamcity-reporter ' +
        '(https://npmjs.org/package/mocha-teamcity-reporter).');
    if (!_reporter) throw new Error('invalid reporter "' + reporter + '"');
    this._reporter = _reporter;
  }
  return this;
};

/**
 * Set test UI `name`, defaults to "bdd".
 *
 * @param {String} bdd
 * @api public
 */

Mocha.prototype.ui = function(name){
  name = name || 'bdd';
  this._ui = exports.interfaces[name];
  if (!this._ui) try { this._ui = require(name); } catch (err) {};
  if (!this._ui) throw new Error('invalid interface "' + name + '"');
  this._ui = this._ui(this.suite);
  return this;
};

/**
 * Load registered files.
 *
 * @api private
 */

Mocha.prototype.loadFiles = function(fn){
  var self = this;
  var suite = this.suite;
  var pending = this.files.length;
  this.files.forEach(function(file){
    file = path.resolve(file);
    suite.emit('pre-require', global, file, self);
    suite.emit('require', require(file), file, self);
    suite.emit('post-require', global, file, self);
    --pending || (fn && fn());
  });
};

/**
 * Enable growl support.
 *
 * @api private
 */

Mocha.prototype._growl = function(runner, reporter) {
  var notify = require('growl');

  runner.on('end', function(){
    var stats = reporter.stats;
    if (stats.failures) {
      var msg = stats.failures + ' of ' + runner.total + ' tests failed';
      notify(msg, { name: 'mocha', title: 'Failed', image: image('error') });
    } else {
      notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {
          name: 'mocha'
        , title: 'Passed'
        , image: image('ok')
      });
    }
  });
};

/**
 * Add regexp to grep, if `re` is a string it is escaped.
 *
 * @param {RegExp|String} re
 * @return {Mocha}
 * @api public
 */

Mocha.prototype.grep = function(re){
  this.options.grep = 'string' == typeof re
    ? new RegExp(utils.escapeRegexp(re))
    : re;
  return this;
};

/**
 * Invert `.grep()` matches.
 *
 * @return {Mocha}
 * @api public
 */

Mocha.prototype.invert = function(){
  this.options.invert = true;
  return this;
};

/**
 * Ignore global leaks.
 *
 * @param {Boolean} ignore
 * @return {Mocha}
 * @api public
 */

Mocha.prototype.ignoreLeaks = function(ignore){
  this.options.ignoreLeaks = !!ignore;
  return this;
};

/**
 * Enable global leak checking.
 *
 * @return {Mocha}
 * @api public
 */

Mocha.prototype.checkLeaks = function(){
  this.options.ignoreLeaks = false;
  return this;
};

/**
 * Enable growl support.
 *
 * @return {Mocha}
 * @api public
 */

Mocha.prototype.growl = function(){
  this.options.growl = true;
  return this;
};

/**
 * Ignore `globals` array or string.
 *
 * @param {Array|String} globals
 * @return {Mocha}
 * @api public
 */

Mocha.prototype.globals = function(globals){
  this.options.globals = (this.options.globals || []).concat(globals);
  return this;
};

/**
 * Emit color output.
 *
 * @param {Boolean} colors
 * @return {Mocha}
 * @api public
 */

Mocha.prototype.useColors = function(colors){
  this.options.useColors = arguments.length && colors != undefined
    ? colors
    : true;
  return this;
};

/**
 * Use inline diffs rather than +/-.
 *
 * @param {Boolean} inlineDiffs
 * @return {Mocha}
 * @api public
 */

Mocha.prototype.useInlineDiffs = function(inlineDiffs) {
  this.options.useInlineDiffs = arguments.length && inlineDiffs != undefined
  ? inlineDiffs
  : false;
  return this;
};

/**
 * Set the timeout in milliseconds.
 *
 * @param {Number} timeout
 * @return {Mocha}
 * @api public
 */

Mocha.prototype.timeout = function(timeout){
  this.suite.timeout(timeout);
  return this;
};

/**
 * Set slowness threshold in milliseconds.
 *
 * @param {Number} slow
 * @return {Mocha}
 * @api public
 */

Mocha.prototype.slow = function(slow){
  this.suite.slow(slow);
  return this;
};

/**
 * Makes all tests async (accepting a callback)
 *
 * @return {Mocha}
 * @api public
 */

Mocha.prototype.asyncOnly = function(){
  this.options.asyncOnly = true;
  return this;
};

/**
 * Run tests and invoke `fn()` when complete.
 *
 * @param {Function} fn
 * @return {Runner}
 * @api public
 */

Mocha.prototype.run = function(fn){
  if (this.files.length) this.loadFiles();
  var suite = this.suite;
  var options = this.options;
  options.files = this.files;
  var runner = new exports.Runner(suite);
  var reporter = new this._reporter(runner, options);
  runner.ignoreLeaks = false !== options.ignoreLeaks;
  runner.asyncOnly = options.asyncOnly;
  if (options.grep) runner.grep(options.grep, options.invert);
  if (options.globals) runner.globals(options.globals);
  if (options.growl) this._growl(runner, reporter);
  exports.reporters.Base.useColors = options.useColors;
  exports.reporters.Base.inlineDiffs = options.useInlineDiffs;
  return runner.run(fn);
};
<commit_msg>reporter: change default to `spec`<commit_after>/*!
 * mocha
 * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var path = require('path')
  , utils = require('./utils');

/**
 * Expose `Mocha`.
 */

exports = module.exports = Mocha;

/**
 * Expose internals.
 */

exports.utils = utils;
exports.interfaces = require('./interfaces');
exports.reporters = require('./reporters');
exports.Runnable = require('./runnable');
exports.Context = require('./context');
exports.Runner = require('./runner');
exports.Suite = require('./suite');
exports.Hook = require('./hook');
exports.Test = require('./test');

/**
 * Return image `name` path.
 *
 * @param {String} name
 * @return {String}
 * @api private
 */

function image(name) {
  return __dirname + '/../images/' + name + '.png';
}

/**
 * Setup mocha with `options`.
 *
 * Options:
 *
 *   - `ui` name "bdd", "tdd", "exports" etc
 *   - `reporter` reporter instance, defaults to `mocha.reporters.spec`
 *   - `globals` array of accepted globals
 *   - `timeout` timeout in milliseconds
 *   - `bail` bail on the first test failure
 *   - `slow` milliseconds to wait before considering a test slow
 *   - `ignoreLeaks` ignore global leaks
 *   - `grep` string or regexp to filter tests with
 *
 * @param {Object} options
 * @api public
 */

function Mocha(options) {
  options = options || {};
  this.files = [];
  this.options = options;
  this.grep(options.grep);
  this.suite = new exports.Suite('', new exports.Context);
  this.ui(options.ui);
  this.bail(options.bail);
  this.reporter(options.reporter);
  if (null != options.timeout) this.timeout(options.timeout);
  this.useColors(options.useColors)
  if (options.slow) this.slow(options.slow);

  this.suite.on('pre-require', function (context) {
    exports.afterEach = context.afterEach || context.teardown;
    exports.after = context.after || context.suiteTeardown;
    exports.beforeEach = context.beforeEach || context.setup;
    exports.before = context.before || context.suiteSetup;
    exports.describe = context.describe || context.suite;
    exports.it = context.it || context.test;
    exports.setup = context.setup || context.beforeEach;
    exports.suiteSetup = context.suiteSetup || context.before;
    exports.suiteTeardown = context.suiteTeardown || context.after;
    exports.suite = context.suite || context.describe;
    exports.teardown = context.teardown || context.afterEach;
    exports.test = context.test || context.it;
  });
}

/**
 * Enable or disable bailing on the first failure.
 *
 * @param {Boolean} [bail]
 * @api public
 */

Mocha.prototype.bail = function(bail){
  if (0 == arguments.length) bail = true;
  this.suite.bail(bail);
  return this;
};

/**
 * Add test `file`.
 *
 * @param {String} file
 * @api public
 */

Mocha.prototype.addFile = function(file){
  this.files.push(file);
  return this;
};

/**
 * Set reporter to `reporter`, defaults to "spec".
 *
 * @param {String|Function} reporter name or constructor
 * @api public
 */

Mocha.prototype.reporter = function(reporter){
  if ('function' == typeof reporter) {
    this._reporter = reporter;
  } else {
    reporter = reporter || 'spec';
    var _reporter;
    try { _reporter = require('./reporters/' + reporter); } catch (err) {};
    if (!_reporter) try { _reporter = require(reporter); } catch (err) {};
    if (!_reporter && reporter === 'teamcity')
      console.warn('The Teamcity reporter was moved to a package named ' +
        'mocha-teamcity-reporter ' +
        '(https://npmjs.org/package/mocha-teamcity-reporter).');
    if (!_reporter) throw new Error('invalid reporter "' + reporter + '"');
    this._reporter = _reporter;
  }
  return this;
};

/**
 * Set test UI `name`, defaults to "bdd".
 *
 * @param {String} bdd
 * @api public
 */

Mocha.prototype.ui = function(name){
  name = name || 'bdd';
  this._ui = exports.interfaces[name];
  if (!this._ui) try { this._ui = require(name); } catch (err) {};
  if (!this._ui) throw new Error('invalid interface "' + name + '"');
  this._ui = this._ui(this.suite);
  return this;
};

/**
 * Load registered files.
 *
 * @api private
 */

Mocha.prototype.loadFiles = function(fn){
  var self = this;
  var suite = this.suite;
  var pending = this.files.length;
  this.files.forEach(function(file){
    file = path.resolve(file);
    suite.emit('pre-require', global, file, self);
    suite.emit('require', require(file), file, self);
    suite.emit('post-require', global, file, self);
    --pending || (fn && fn());
  });
};

/**
 * Enable growl support.
 *
 * @api private
 */

Mocha.prototype._growl = function(runner, reporter) {
  var notify = require('growl');

  runner.on('end', function(){
    var stats = reporter.stats;
    if (stats.failures) {
      var msg = stats.failures + ' of ' + runner.total + ' tests failed';
      notify(msg, { name: 'mocha', title: 'Failed', image: image('error') });
    } else {
      notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {
          name: 'mocha'
        , title: 'Passed'
        , image: image('ok')
      });
    }
  });
};

/**
 * Add regexp to grep, if `re` is a string it is escaped.
 *
 * @param {RegExp|String} re
 * @return {Mocha}
 * @api public
 */

Mocha.prototype.grep = function(re){
  this.options.grep = 'string' == typeof re
    ? new RegExp(utils.escapeRegexp(re))
    : re;
  return this;
};

/**
 * Invert `.grep()` matches.
 *
 * @return {Mocha}
 * @api public
 */

Mocha.prototype.invert = function(){
  this.options.invert = true;
  return this;
};

/**
 * Ignore global leaks.
 *
 * @param {Boolean} ignore
 * @return {Mocha}
 * @api public
 */

Mocha.prototype.ignoreLeaks = function(ignore){
  this.options.ignoreLeaks = !!ignore;
  return this;
};

/**
 * Enable global leak checking.
 *
 * @return {Mocha}
 * @api public
 */

Mocha.prototype.checkLeaks = function(){
  this.options.ignoreLeaks = false;
  return this;
};

/**
 * Enable growl support.
 *
 * @return {Mocha}
 * @api public
 */

Mocha.prototype.growl = function(){
  this.options.growl = true;
  return this;
};

/**
 * Ignore `globals` array or string.
 *
 * @param {Array|String} globals
 * @return {Mocha}
 * @api public
 */

Mocha.prototype.globals = function(globals){
  this.options.globals = (this.options.globals || []).concat(globals);
  return this;
};

/**
 * Emit color output.
 *
 * @param {Boolean} colors
 * @return {Mocha}
 * @api public
 */

Mocha.prototype.useColors = function(colors){
  this.options.useColors = arguments.length && colors != undefined
    ? colors
    : true;
  return this;
};

/**
 * Use inline diffs rather than +/-.
 *
 * @param {Boolean} inlineDiffs
 * @return {Mocha}
 * @api public
 */

Mocha.prototype.useInlineDiffs = function(inlineDiffs) {
  this.options.useInlineDiffs = arguments.length && inlineDiffs != undefined
  ? inlineDiffs
  : false;
  return this;
};

/**
 * Set the timeout in milliseconds.
 *
 * @param {Number} timeout
 * @return {Mocha}
 * @api public
 */

Mocha.prototype.timeout = function(timeout){
  this.suite.timeout(timeout);
  return this;
};

/**
 * Set slowness threshold in milliseconds.
 *
 * @param {Number} slow
 * @return {Mocha}
 * @api public
 */

Mocha.prototype.slow = function(slow){
  this.suite.slow(slow);
  return this;
};

/**
 * Makes all tests async (accepting a callback)
 *
 * @return {Mocha}
 * @api public
 */

Mocha.prototype.asyncOnly = function(){
  this.options.asyncOnly = true;
  return this;
};

/**
 * Run tests and invoke `fn()` when complete.
 *
 * @param {Function} fn
 * @return {Runner}
 * @api public
 */

Mocha.prototype.run = function(fn){
  if (this.files.length) this.loadFiles();
  var suite = this.suite;
  var options = this.options;
  options.files = this.files;
  var runner = new exports.Runner(suite);
  var reporter = new this._reporter(runner, options);
  runner.ignoreLeaks = false !== options.ignoreLeaks;
  runner.asyncOnly = options.asyncOnly;
  if (options.grep) runner.grep(options.grep, options.invert);
  if (options.globals) runner.globals(options.globals);
  if (options.growl) this._growl(runner, reporter);
  exports.reporters.Base.useColors = options.useColors;
  exports.reporters.Base.inlineDiffs = options.useInlineDiffs;
  return runner.run(fn);
};
<|endoftext|>


<commit_before>if (typeof jsMaps.Yandex == 'undefined') {
    jsMaps.Yandex = function (mapDomDocument) {};
    jsMaps.Yandex.prototype = new jsMaps.Abstract();
}

var fn;

function GeocodeCallback(data)
{
    var geoCoder = {'results': []};

    var Use = data.response.GeoObjectCollection;

    if (Use.metaDataProperty.found == 0 || Use.featureMember.length == 0) {
        fn(geoCoder);
        return;
    }

    for (var i in Use.featureMember) {
        if (Use.featureMember.hasOwnProperty(i) == false) continue;

        var featureMember = Use.featureMember[i].GeoObject;
        var metaProp = featureMember.metaDataProperty.GeocoderMetaData;

        var types = [];

        if (metaProp.kind == 'country') {
            types.push(jsMaps.supported_Address_types.country);
        } else if (metaProp.kind == 'area') {
            types.push(jsMaps.supported_Address_types.administrative_area_level_1);
            types.push(jsMaps.supported_Address_types.political);
        } else if (metaProp.kind == 'province') {
            types.push(jsMaps.supported_Address_types.administrative_area_level_2);
            types.push(jsMaps.supported_Address_types.political);
        } else if (metaProp.kind == 'locality') {
            types.push(jsMaps.supported_Address_types.locality);
            types.push(jsMaps.supported_Address_types.political);
        } else if (metaProp.kind == 'district') {
            types.push(jsMaps.supported_Address_types.administrative_area_level_3);
            types.push(jsMaps.supported_Address_types.political);
        } else if ((metaProp.kind == 'house' || metaProp.kind == 'street') && (metaProp.precision == 'exact')) {
            types.push(jsMaps.supported_Address_types.street_address);
        } else if ((metaProp.kind == 'house' || metaProp.kind == 'street') && (metaProp.precision != 'exact')) {
            types.push(jsMaps.supported_Address_types.postal_code);
        } else if (metaProp.kind == 'hydro') {
            types.push(jsMaps.supported_Address_types.point_of_interest);
        } else if (metaProp.kind == 'vegetation') {
            types.push(jsMaps.supported_Address_types.natural_feature);
        } else if (metaProp.kind == 'airport') {
            types.push(jsMaps.supported_Address_types.airport);
        }

        var point = featureMember.Point.pos.split(' ');
        var location = new jsMaps.geo.Location(point[1],point[0]);
        var view_port = jsMaps.geo.View_port;

        var location_type = jsMaps.supported_location_types.APPROXIMATE;

        if (metaProp.precision == 'pointAddress') {
            location_type = jsMaps.supported_location_types.ROOFTOP;
        } else if (metaProp.precision == 'number' || metaProp.precision == 'near') {
            location_type = jsMaps.supported_location_types.RANGE_INTERPOLATED;
        }

        var boundedBy   = featureMember.boundedBy.Envelope;
        var upperCorner = boundedBy.upperCorner.split(' '); // topRight
        var lowerCorner = boundedBy.lowerCorner.split(' '); // bottomLeft

        view_port.getTopLeft     = {lat: upperCorner[1], lng: lowerCorner[0]};
        view_port.getBottomRight = {lat: lowerCorner[1], lng: upperCorner[0]};
        view_port.location_type  = location_type;

        var geoCoderResult = new jsMaps.AddressSearchResult(featureMember.name+', '+featureMember.description, types, (metaProp.precision != 'exact'), new jsMaps.Geometry(location, view_port));
        geoCoder['results'].push(geoCoderResult);
    }

    fn(geoCoder);
}

/**
 *
 * @param search
 * @param fun
 */
jsMaps.Yandex.prototype.addressGeoSearch = function (search, fun) {
    fn = fun;
    var script = document.createElement('script');
    script.src = 'http://geocode-maps.yandex.ru/1.x/?geocode=' + search + '&lang=en-US&format=json&callback=GeocodeCallback';

    document.getElementsByTagName('head')[0].appendChild(script);
};
<commit_msg>Fix multiple threads yandex geocode compatibility<commit_after>if (typeof jsMaps.Yandex == 'undefined') {
    jsMaps.Yandex = function (mapDomDocument) {
    };
    jsMaps.Yandex.prototype = new jsMaps.Abstract();
}

var callbackStorage = {};
function GeocodeCallbackFactory(fn) {

    var id;
    do {
        id = "callback" + (Math.random()).toString(10).substr(2);
    }while(callbackStorage.id);

    callbackStorage[id] = function (fn) {
        return function (data) {
            var geoCoder = {'results': []};

            var Use = data.response.GeoObjectCollection;

            if (Use.metaDataProperty.found == 0 || Use.featureMember.length == 0) {
                fn(geoCoder);
                return;
            }

            for (var i in Use.featureMember) {
                if (Use.featureMember.hasOwnProperty(i) == false) continue;

                var featureMember = Use.featureMember[i].GeoObject;
                var metaProp = featureMember.metaDataProperty.GeocoderMetaData;

                var types = [];

                if (metaProp.kind == 'country') {
                    types.push(jsMaps.supported_Address_types.country);
                } else if (metaProp.kind == 'area') {
                    types.push(jsMaps.supported_Address_types.administrative_area_level_1);
                    types.push(jsMaps.supported_Address_types.political);
                } else if (metaProp.kind == 'province') {
                    types.push(jsMaps.supported_Address_types.administrative_area_level_2);
                    types.push(jsMaps.supported_Address_types.political);
                } else if (metaProp.kind == 'locality') {
                    types.push(jsMaps.supported_Address_types.locality);
                    types.push(jsMaps.supported_Address_types.political);
                } else if (metaProp.kind == 'district') {
                    types.push(jsMaps.supported_Address_types.administrative_area_level_3);
                    types.push(jsMaps.supported_Address_types.political);
                } else if ((metaProp.kind == 'house' || metaProp.kind == 'street') && (metaProp.precision == 'exact')) {
                    types.push(jsMaps.supported_Address_types.street_address);
                } else if ((metaProp.kind == 'house' || metaProp.kind == 'street') && (metaProp.precision != 'exact')) {
                    types.push(jsMaps.supported_Address_types.postal_code);
                } else if (metaProp.kind == 'hydro') {
                    types.push(jsMaps.supported_Address_types.point_of_interest);
                } else if (metaProp.kind == 'vegetation') {
                    types.push(jsMaps.supported_Address_types.natural_feature);
                } else if (metaProp.kind == 'airport') {
                    types.push(jsMaps.supported_Address_types.airport);
                }

                var point = featureMember.Point.pos.split(' ');
                var location = new jsMaps.geo.Location(point[1], point[0]);
                var view_port = jsMaps.geo.View_port;

                var location_type = jsMaps.supported_location_types.APPROXIMATE;

                if (metaProp.precision == 'pointAddress') {
                    location_type = jsMaps.supported_location_types.ROOFTOP;
                } else if (metaProp.precision == 'number' || metaProp.precision == 'near') {
                    location_type = jsMaps.supported_location_types.RANGE_INTERPOLATED;
                }

                var boundedBy = featureMember.boundedBy.Envelope;
                var upperCorner = boundedBy.upperCorner.split(' '); // topRight
                var lowerCorner = boundedBy.lowerCorner.split(' '); // bottomLeft

                view_port.getTopLeft = {lat: upperCorner[1], lng: lowerCorner[0]};
                view_port.getBottomRight = {lat: lowerCorner[1], lng: upperCorner[0]};
                view_port.location_type = location_type;

                var geoCoderResult = new jsMaps.AddressSearchResult(featureMember.name + ', ' + featureMember.description, types, (metaProp.precision != 'exact'), new jsMaps.Geometry(location, view_port));
                geoCoder['results'].push(geoCoderResult);
            }
            fn(geoCoder);
            delete callbackStorage.id;
        }
    }(fn);
    return "callbackStorage." + id;
}
/**
 *
 * @param search
 * @param fun
 */
jsMaps.Yandex.prototype.addressGeoSearch = function (search, fun) {
    var script = document.createElement('script');
    script.src = 'http://geocode-maps.yandex.ru/1.x/?geocode=' + search + '&lang=en-US&format=json&callback=' + GeocodeCallbackFactory(fun);

    document.getElementsByTagName('head')[0].appendChild(script);
};
<|endoftext|>


<commit_before>"use strict";

const fs = require("fs");
const path = require("path");

const _ = require("lodash");
const Minimatch = require("minimatch").Minimatch;

const utils = require("../utils");

const IGNORE_FILE = ".flooignore";

// const HIDDEN_WHITELIST = [".floo"] + IGNORE_FILES;
const BLACKLIST = [
  ".DS_Store",
  ".git",
  ".svn",
  ".hg",
];

const DEFAULT_IGNORES = [
  "#*",
  "*.o",
  "*.pyc",
  "*~",
  "extern/",
  "node_modules/",
  "tmp",
  "vendor/",
];

const MAX_FILE_SIZE = 1024 * 1024 * 5;

// const IS_IG_IGNORED = 1;
// const IS_IG_CHECK_CHILD = 2;

function Ignore() {
  this.ignores = [];
  this.unignores = [];
  this.repo = null;
}

Ignore.prototype.init = function (directory, cb) {
  /* eslint-disable no-sync */
  this.dir_path = directory.getRealPathSync();
  const pretend_path = path.join(this.dir_path, IGNORE_FILE);
  /* eslint-enable no-sync */
  _.each(BLACKLIST, this.add_ignore_entry_.bind(this, pretend_path));
  this.create_flooignore_(this.dir_path);
  atom.project.repositoryForDirectory(directory).then((repo) => {
    this.repo = repo;
    return cb();
  }, cb);
};

Ignore.prototype.create_flooignore_ = function () {
  const flooignore = path.join(this.dir_path, IGNORE_FILE);
  try {
    /*eslint-disable no-sync */
    if (fs.existsSync(flooignore)) {
      return;
    }
    fs.writeFileSync(flooignore, DEFAULT_IGNORES.join("\n"));
    /*eslint-enable no-sync */
  } catch (e) {
    console.error(e);
  }
};

Ignore.prototype.is_unignored_ = function (filePath) {
  for (let i in this.unignores) {
    if (this.unignores[i].match(filePath)) {
      return true;
    }
  }
  return false;
};

Ignore.prototype.is_ignored_ = function (filePath) {
  for (let i in this.ignores) {
    if (this.ignores[i].match(filePath)) {
      return true;
    }
  }
  return false;
};

Ignore.prototype.is_ignored = function (absOSPath) {
  const gitIgnored = this.repo && this.repo.isPathIgnored(absOSPath) && absOSPath !== this.dir_path;
  const flooIgnored = this.is_ignored_(absOSPath);
  if (gitIgnored || flooIgnored) {
    if (this.is_unignored_(absOSPath)) {
      return false;
    }
    return true;
  }
  return false;
};

Ignore.prototype.getSize = function (filePath) {
  try {
    /*eslint-disable no-sync */
    const stats = fs.statSync(filePath);
    /*eslint-enable no-sync */
    return stats.size;
  } catch (e) {
    console.error(e);
    return 0;
  }
};

Ignore.prototype.is_too_big = function (size) {
  return size > MAX_FILE_SIZE;
};

Ignore.prototype.add_ignore_entry_ = function (filePath, line) {
  if (!line) {
    return;
  }
  const dir = path.dirname(filePath);
  const rel = utils.to_rel_path(dir);

  // console.log("s:", line);
  const negate = line[0] === "!";
  if (negate) {
    line = line.slice(1);
  }
  if (line[0] === "/") {
    line = path.join(dir, line);
  } else {
    line = path.join(rel, "**", line);
  }

  if (line[line.length - 1] === "/") {
    line += "**";
  }
  const match = new Minimatch(line);
  if (negate) {
    this.unignores.push(match);
  } else {
    this.ignores.push(match);
  }
};

Ignore.prototype.add_ignore = function (file) {
  const name = file.getBaseName();

  if (name !== IGNORE_FILE) {
    return;
  }

  let data;

  try {
    /*eslint-disable no-sync */
    data = file.readSync();
    /*eslint-enable no-sync */
  } catch (e) {
    console.error(e);
    return;
  }

  /* eslint-disable no-sync */
  const p = file.getRealPathSync();
  /* eslint-enable no-sync */
  _.each(data.split(/\n/), this.add_ignore_entry_.bind(this, p));
};

module.exports = new Ignore();
<commit_msg>Add ignore rules to ignore object on initial flooignore creation. This fixes issues with crazy big things like node_modules getting uploaded on initial workspace join/creation.<commit_after>"use strict";

const fs = require("fs");
const path = require("path");

const _ = require("lodash");
const Minimatch = require("minimatch").Minimatch;

const utils = require("../utils");

const IGNORE_FILE = ".flooignore";

// const HIDDEN_WHITELIST = [".floo"] + IGNORE_FILES;
const BLACKLIST = [
  ".DS_Store",
  ".git",
  ".svn",
  ".hg",
];

const DEFAULT_IGNORES = [
  "#*",
  "*.o",
  "*.pyc",
  "*~",
  "extern/",
  "node_modules/",
  "tmp",
  "vendor/",
];

const MAX_FILE_SIZE = 1024 * 1024 * 5;

// const IS_IG_IGNORED = 1;
// const IS_IG_CHECK_CHILD = 2;

function Ignore() {
  this.ignores = [];
  this.unignores = [];
  this.repo = null;
}

Ignore.prototype.init = function (directory, cb) {
  /* eslint-disable no-sync */
  this.dir_path = directory.getRealPathSync();
  const pretend_path = path.join(this.dir_path, IGNORE_FILE);
  /* eslint-enable no-sync */
  _.each(BLACKLIST, this.add_ignore_entry_.bind(this, pretend_path));
  this.create_flooignore_(this.dir_path);
  atom.project.repositoryForDirectory(directory).then((repo) => {
    this.repo = repo;
    return cb();
  }, cb);
};

Ignore.prototype.create_flooignore_ = function () {
  const flooignore = path.join(this.dir_path, IGNORE_FILE);
  try {
    /*eslint-disable no-sync */
    if (!fs.existsSync(flooignore)) {
      fs.writeFileSync(flooignore, DEFAULT_IGNORES.join("\n"));
    }
    /*eslint-enable no-sync */
  } catch (e) {
    console.error(e);
  }
  try {
    /*eslint-disable no-sync */
    const data = fs.readFileSync(flooignore);
    /*eslint-enable no-sync */
    _.each(data.split(/\n/), this.add_ignore_entry_.bind(this, flooignore));
  } catch (e) {
    console.error(e);
  }
};

Ignore.prototype.is_unignored_ = function (filePath) {
  for (let i in this.unignores) {
    if (this.unignores[i].match(filePath)) {
      return true;
    }
  }
  return false;
};

Ignore.prototype.is_ignored_ = function (filePath) {
  for (let i in this.ignores) {
    if (this.ignores[i].match(filePath)) {
      return true;
    }
  }
  return false;
};

Ignore.prototype.is_ignored = function (absOSPath) {
  const gitIgnored = this.repo && this.repo.isPathIgnored(absOSPath) && absOSPath !== this.dir_path;
  const flooIgnored = this.is_ignored_(absOSPath);
  if (gitIgnored || flooIgnored) {
    if (this.is_unignored_(absOSPath)) {
      return false;
    }
    return true;
  }
  return false;
};

Ignore.prototype.getSize = function (filePath) {
  try {
    /*eslint-disable no-sync */
    const stats = fs.statSync(filePath);
    /*eslint-enable no-sync */
    return stats.size;
  } catch (e) {
    console.error(e);
    return 0;
  }
};

Ignore.prototype.is_too_big = function (size) {
  return size > MAX_FILE_SIZE;
};

Ignore.prototype.add_ignore_entry_ = function (filePath, line) {
  if (!line) {
    return;
  }
  const dir = path.dirname(filePath);
  const rel = utils.to_rel_path(dir);

  // console.log("s:", line);
  const negate = line[0] === "!";
  if (negate) {
    line = line.slice(1);
  }
  if (line[0] === "/") {
    line = path.join(dir, line);
  } else {
    line = path.join(rel, "**", line);
  }

  if (line[line.length - 1] === "/") {
    line += "**";
  }
  const match = new Minimatch(line);
  if (negate) {
    this.unignores.push(match);
  } else {
    this.ignores.push(match);
  }
};

Ignore.prototype.add_ignore = function (file) {
  const name = file.getBaseName();
  if (name !== IGNORE_FILE) {
    return;
  }

  let data;
  try {
    /*eslint-disable no-sync */
    data = file.readSync();
    /*eslint-enable no-sync */
  } catch (e) {
    console.error(e);
    return;
  }

  /* eslint-disable no-sync */
  const p = file.getRealPathSync();
  /* eslint-enable no-sync */
  _.each(data.split(/\n/), this.add_ignore_entry_.bind(this, p));
};

module.exports = new Ignore();
<|endoftext|>


<commit_before>var VeryCollection = require('./collection');
var VeryValidator = require('./validator');
var Types = require('./definition').Types;
var underscore = require('underscore');

/* VeryModel, for spawning models out of a definition
 * Instances of VeryModel are factories for models themselves.
 */
function VeryModel(definition, args) {
    args = args || {};
    if (Array.isArray(definition)) {
        this.definition = [];
    } else {
        this.definition = {};
    }
    this.controllers = {};

    //initialize sub model definitions recursively
    this.fields = [];
    this.addDefinition(definition);
}

(function () {

    function merge(a, b) {
        Object.keys(b).forEach(function (key) {
            if (key !== 'type' && typeof b[key] === 'object' && !Array.isArray(b[key]) && !(b[key] instanceof VeryModel)) {
                if (!a.hasOwnProperty(key)) {
                    a[key] = {};
                }
                merge(a[key], b[key]);
            } else {
                a[key] = b[key];
            }
        });
    }

    this.addDefinition = function (defs) {
        var newfields = Object.keys(defs);
        if (!Array.isArray(this.definition)) {
            merge(this.definition, defs);
        } else {
            this.definition = this.definition.concat(defs);
        }
        this.fields = underscore.union(newfields, this.fields);
        newfields.forEach(function (field) {
            this.setupField(field);
        }.bind(this));
    };

    this.inherit = function (parentModel) {
        var fields = parentModel.fields;

        fields.forEach(function _inheritField(field) {
            if (this.definition[field]) return;

            this.fields.push(field);
            this.definition[field] = parentModel.definition[field];

            this.setupField(field);
        }.bind(this));
    };

    this.setupField = function (field) {
        var submodel;
        if (this.definition[field].hasOwnProperty('model')) {
            //if we get a VeryModel instance instead of a definition object
            //we have to switch things up
            submodel = this.definition[field].model;
            if (submodel === 'this') {
                submodel = this;
            }
            if (submodel instanceof VeryModel) {
                this.definition[field].subModel = submodel;
                this.definition[field].model = this.definition[field].subModel.definition;
            } else {
                //initialize sub VeryModel
                this.definition[field].subModel = new VeryModel(submodel);
            }
        } else if (this.definition[field].hasOwnProperty('collection')) {
            //if we get a VeryModel instance instead of a definition object
            //we have to switch things up
            submodel = this.definition[field].collection;
            if (submodel === 'this') {
                submodel = this;
            }
            if (submodel instanceof VeryModel) {
                this.definition[field].subVeryCollection = submodel;
                this.definition[field].collection = this.definition[field].subVeryCollection.definition;
            } else {
                //initialize sub model defintion
                this.definition[field].subVeryCollection = new VeryModel(submodel);
            }
        }
    };

    /* create (optionally with the value object)
     * generates a model for populating, reading, and validating
     * the object over time
     */
    this.create = function (value, ctx) {
        var model = {};
        model.ctx = ctx;

        var meta = model.__verymeta = {
            model: this,
            defs: this.definition,
            data: {},
            map: {},
            reverseMap: {},
            primaryKey: null,
            creating: true,
            isEmpty: true
        };

        if (Array.isArray(meta.defs)) {
            meta.data = [];
        }

        //run through the definition fields
        this.fields.forEach(function _createField(field) {

            //hidden value attribute accessor
            if (typeof meta.defs[field].keyword !== 'undefined') {
                meta.map[meta.defs[field].keyword] = field;
                meta.reverseMap[field] = meta.defs[field].keyword;
                model.__defineGetter__(meta.defs[field].keyword, function () {
                    return model[meta.map[meta.defs[field].keyword]];
                });
            }

            if (meta.defs[field].primary === true) {
                meta.primaryKey = field;
            }

            model.__defineGetter__(field, function () {
                var meta = this.__verymeta;
                if (meta.defs[field].hasOwnProperty('derive')) {
                    meta.data[field] = meta.defs[field].derive.call(this, this);
                }
                return meta.data[field];
            }.bind(model));

            //handle assignment to sub models, sub arraymodels, and values differently
            if (meta.defs[field].hasOwnProperty('model')) {
                //recursively instatiate submodel
                meta.data[field] = meta.defs[field].subModel.create();
                meta.data[field].__verymeta.parent = model;

                //assigning to the submodel should call loadData on it
                model.__defineSetter__(field, function (value) {
                    this.__verymeta.data[field].loadData(value, false);
                });

                return;
            }

            if (meta.defs[field].hasOwnProperty('collection')) {
                //create an array-like object for a collection of the sub model
                meta.data[field] = new VeryCollection(meta.defs[field].subVeryCollection, model);

                return;
            }

            //assign the default value to required fields
            //this could get overwritten later at the loadData phase
            if (meta.defs[field].required) {
                if (typeof meta.defs[field].default === 'function') {
                    meta.data[field] = meta.defs[field].default(model);
                } else {
                    meta.data[field] = meta.defs[field].default;
                }
            }

            //validate values as they come in
            //hidden value style setter
            model.__defineSetter__(field, function (value) {
                var meta = this.__verymeta;

                if (meta.defs[field].static === true && !meta.creating) {
                    throw new Error('Cannot set static values');
                }

                meta.data[field] = value;

                meta.isEmpty = false;
            });
        }.bind(this));

        //load data en masse into the model
        //works recursively
        model.loadData = function (value, process) {
            process = process !== false;
            var meta = this.__verymeta;
            var processIn;

            if (Array.isArray(meta.defs)) {
                meta.data = [];
                var valueoff = 0;
                for (var vidx in meta.defs) {
                    processIn = process && meta.defs[vidx].processIn && typeof meta.defs[vidx].processIn === 'function' ? meta.defs[vidx].processIn.bind(this) : false;
                    if (!meta.defs[vidx].required && value.length + valueoff < meta.defs.length) {
                        if (meta.defs[vidx].default === 'function') {
                            this[vidx] = meta.defs[vidx].default(this);
                        } else {
                            this[vidx] = meta.defs[vidx].default;
                        }
                        valueoff += 1;
                    } else {
                        if (processIn) {
                            this[vidx] = processIn(value[vidx - valueoff]).bind(this);
                        } else {
                            this[vidx] = value[vidx - valueoff];
                        }
                    }
                }
            } else {
                Object.keys(value).forEach(function (key) {
                    if (!meta.defs.hasOwnProperty(key)) return;
                    processIn = process && meta.defs[key].processIn && typeof meta.defs[key].processIn === 'function' ? meta.defs[key].processIn.bind(this) : false;

                    if (meta.defs[key].hasOwnProperty('collection')) {
                        for (var vidx in value[key]) {
                            meta.isEmpty = false;
                            if (processIn) {
                                meta.data[key].push(processIn(value[key][vidx]));
                            } else {
                                meta.data[key].push(value[key][vidx]);
                            }
                        }
                    } else if (meta.defs[key].hasOwnProperty('model') && meta.creating) {
                        meta.data[key].loadData(value[key]);
                    } else {
                        meta.isEmpty = false;
                        if (processIn) {
                            model[key] = processIn(value[key]);
                        } else {
                            model[key] = value[key];
                        }
                    }
                }.bind(this));
            }
        };

        //create a JSON serializable Javascript object out of the model data
        //no more helper functions or accessors
        model.toJSON = function (opts) {
            opts = opts || {};

            var meta = this.__verymeta;
            var obj;

            if (Array.isArray(meta.defs) && !opts.useKeywords) {
                obj = [];
            } else {
                obj = {};
            }

            Object.keys(meta.defs).forEach(function (field) {
                var processOut = meta.defs[field].processOut && typeof meta.defs[field].processOut === 'function' ? meta.defs[field].processOut.bind(this) : false;
                var key = field;
                if (meta.defs[field].private && !opts.withPrivate) {
                    return;
                }

                if (opts.useKeywords && meta.reverseMap.hasOwnProperty(field)) {
                    key = meta.reverseMap[field];
                }

                if (meta.defs[field].hasOwnProperty('model')) {
                    if (!meta.data[field].__verymeta.isEmpty) {
                        obj[key] = meta.data[field].toJSON();
                    }
                    return;
                }

                if (meta.defs[field].hasOwnProperty('collection')) {
                    obj[key] = [];
                    meta.data[field].forEach(function (inst) {
                        if (!inst.__verymeta.isEmpty) {
                            obj[key].push(inst.toJSON());
                        }
                    });
                    if (obj[key].length === 0) {
                        delete obj[key];
                    }

                    return;
                }

                obj[key] = processOut ? processOut(this[field]) : this[field];
                if (typeof obj[key] === 'undefined') {
                    delete obj[key];
                }
            }.bind(this));

            return obj;
        };

        //validate that a model follows the rules and types
        //works recursively
        //returns a list of errors
        //if the list of errors.length === 0, you're golden
        model.doValidate = function () {
            var meta = this.__verymeta;
            var errors = [];

            Object.keys(meta.defs).forEach(function (field) {
                var fidx;
                var merrors;
                //if field is set and dependency is set
                if (meta.data.hasOwnProperty(field) && meta.defs[field].depends) {
                    for (fidx in meta.defs[field].depends) {
                        //check to see if other field is set
                        if (!meta.data.hasOwnProperty(fidx) || meta.data[fidx] === undefined) {
                            errors.push(field + ": Dependency -> " + fidx + ": not set");
                        //check to see if dependency has a validator
                        } else if (meta.defs[field].depends instanceof VeryValidator) {
                            merrors = meta.defs[field].depends[fidx].validate(meta.data[fidx]);
                            merrors.forEach(function (error) {
                                errors.push(field + ": Dependency  -> " + fidx + ": " + error);
                            });
                        }
                    }
                }
                //if field is reuqired and it's not set
                if (meta.defs[field].required && (!meta.data.hasOwnProperty(field) || meta.data[field] === undefined)) {
                    errors.push(field + ": required");
                }
                //if this field is another model
                //recursively validate it
                //add errors to our own
                //only if the submodule is required or has been populated
                if (meta.defs[field].hasOwnProperty('model') && meta.data.hasOwnProperty(field) && (!meta.data[field].__verymeta.isEmpty || meta.defs[field].required)) {
                    merrors = meta.data[field].doValidate();
                    for (var eidx in merrors) {
                        merrors[eidx] = field + '.' + merrors[eidx];
                    }
                    errors = errors.concat(merrors);
                //if field is an array of models
                //recursively validate them
                //and add their errors to our own
                } else if (meta.defs[field].hasOwnProperty('collection') && meta.data.hasOwnProperty(field)) {
                    var arrayerrors = [];
                    var idx = 0;
                    meta.data[field].forEach(function (model) {
                        //is this collection required? has the model been populated?
                        if (meta.defs[field].required || !model.__verymeta.isEmpty) {
                            merrors = model.doValidate();
                            for (var eidx in merrors) {
                                merrors[eidx] = field + '[' + idx + '].' + merrors[eidx];
                            }
                            errors = errors.concat(merrors);
                        }
                        idx += 1;
                    }.bind(this));
                //if we have a VeryValidator to validate against, validate it
                } else if (meta.data.hasOwnProperty(field) && meta.defs[field].hasOwnProperty('type')) {
                    if (typeof meta.defs[field].type === 'string' && Types.hasOwnProperty(meta.defs[field].type)) {
                        meta.defs[field].type = Types[meta.defs[field].type];
                    }
                    merrors = meta.defs[field].type.validate(meta.data[field]);
                    if (typeof merrors === 'boolean') {
                        if (merrors) {
                            merrors = [];
                        } else {
                            merrors = ["Failed."];
                        }
                    }
                    merrors.forEach(function (error) {
                        errors.push(field + ": " + error);
                    });
                } else if (meta.data.hasOwnProperty(field) && meta.defs[field].hasOwnProperty('array')) {
                    var tidx = 0;
                    meta.defs[field].array.forEach(function (type) {
                        merrors = type.validate(meta.data[field][tidx]);
                        merrors.forEach(function (error) {
                            errors.push(field + "[" + tidx + "]: " + error);
                        });
                        tidx++;
                    }.bind(this));
                }

            }.bind(this));
            return errors;
        };

        model.makeClone = function () {
            return this.__verymeta.model.create(this.toJSON());
        };

        //generate a JSON string from the model data
        model.toString = function (args) {
            return JSON.stringify(this.toJSON(args));
        };

        //extend controllers
        Object.keys(this.controllers).forEach(function (controller) {
            model[controller] = this.controllers[controller];
        }.bind(this));

        //if model.create passed in initial values, load them
        if (typeof value !== 'undefined') {
            model.loadData(value);
        }

        meta.creating = false;

        return model;
    };

    this.extendModel = function (controllers) {
        this.controllers = underscore.extend(this.controllers, controllers);
    };

    this.addModelVar = function (name, value) {
        this.controllers[name] = value;
    };

}).call(VeryModel.prototype);

module.exports = VeryModel;
<commit_msg>map options to __verymeta<commit_after>var VeryCollection = require('./collection');
var VeryValidator = require('./validator');
var Types = require('./definition').Types;
var underscore = require('underscore');

/* VeryModel, for spawning models out of a definition
 * Instances of VeryModel are factories for models themselves.
 */
function VeryModel(definition, options) {
    this.options = options || {};
    if (Array.isArray(definition)) {
        this.definition = [];
    } else {
        this.definition = {};
    }
    this.controllers = {};

    //initialize sub model definitions recursively
    this.fields = [];
    this.addDefinition(definition);
}

(function () {

    function merge(a, b) {
        Object.keys(b).forEach(function (key) {
            if (key !== 'type' && typeof b[key] === 'object' && !Array.isArray(b[key]) && !(b[key] instanceof VeryModel)) {
                if (!a.hasOwnProperty(key)) {
                    a[key] = {};
                }
                merge(a[key], b[key]);
            } else {
                a[key] = b[key];
            }
        });
    }

    this.addDefinition = function (defs) {
        var newfields = Object.keys(defs);
        if (!Array.isArray(this.definition)) {
            merge(this.definition, defs);
        } else {
            this.definition = this.definition.concat(defs);
        }
        this.fields = underscore.union(newfields, this.fields);
        newfields.forEach(function (field) {
            this.setupField(field);
        }.bind(this));
    };

    this.inherit = function (parentModel) {
        var fields = parentModel.fields;

        fields.forEach(function _inheritField(field) {
            if (this.definition[field]) return;

            this.fields.push(field);
            this.definition[field] = parentModel.definition[field];

            this.setupField(field);
        }.bind(this));
    };

    this.setupField = function (field) {
        var submodel;
        if (this.definition[field].hasOwnProperty('model')) {
            //if we get a VeryModel instance instead of a definition object
            //we have to switch things up
            submodel = this.definition[field].model;
            if (submodel === 'this') {
                submodel = this;
            }
            if (submodel instanceof VeryModel) {
                this.definition[field].subModel = submodel;
                this.definition[field].model = this.definition[field].subModel.definition;
            } else {
                //initialize sub VeryModel
                this.definition[field].subModel = new VeryModel(submodel);
            }
        } else if (this.definition[field].hasOwnProperty('collection')) {
            //if we get a VeryModel instance instead of a definition object
            //we have to switch things up
            submodel = this.definition[field].collection;
            if (submodel === 'this') {
                submodel = this;
            }
            if (submodel instanceof VeryModel) {
                this.definition[field].subVeryCollection = submodel;
                this.definition[field].collection = this.definition[field].subVeryCollection.definition;
            } else {
                //initialize sub model defintion
                this.definition[field].subVeryCollection = new VeryModel(submodel);
            }
        }
    };

    /* create (optionally with the value object)
     * generates a model for populating, reading, and validating
     * the object over time
     */
    this.create = function (value, ctx) {
        var model = {};
        var meta = {};

        model.ctx = ctx;

        underscore.extend(meta, this.options, {
            model: this,
            defs: this.definition,
            data: {},
            map: {},
            reverseMap: {},
            primaryKey: null,
            creating: true,
            isEmpty: true
        });

        model.__verymeta = meta;

        if (Array.isArray(meta.defs)) {
            meta.data = [];
        }

        //run through the definition fields
        this.fields.forEach(function _createField(field) {

            //hidden value attribute accessor
            if (typeof meta.defs[field].keyword !== 'undefined') {
                meta.map[meta.defs[field].keyword] = field;
                meta.reverseMap[field] = meta.defs[field].keyword;
                model.__defineGetter__(meta.defs[field].keyword, function () {
                    return model[meta.map[meta.defs[field].keyword]];
                });
            }

            if (meta.defs[field].primary === true) {
                meta.primaryKey = field;
            }

            model.__defineGetter__(field, function () {
                var meta = this.__verymeta;
                if (meta.defs[field].hasOwnProperty('derive')) {
                    meta.data[field] = meta.defs[field].derive.call(this, this);
                }
                return meta.data[field];
            }.bind(model));

            //handle assignment to sub models, sub arraymodels, and values differently
            if (meta.defs[field].hasOwnProperty('model')) {
                //recursively instatiate submodel
                meta.data[field] = meta.defs[field].subModel.create();
                meta.data[field].__verymeta.parent = model;

                //assigning to the submodel should call loadData on it
                model.__defineSetter__(field, function (value) {
                    this.__verymeta.data[field].loadData(value, false);
                });

                return;
            }

            if (meta.defs[field].hasOwnProperty('collection')) {
                //create an array-like object for a collection of the sub model
                meta.data[field] = new VeryCollection(meta.defs[field].subVeryCollection, model);

                return;
            }

            //assign the default value to required fields
            //this could get overwritten later at the loadData phase
            if (meta.defs[field].required) {
                if (typeof meta.defs[field].default === 'function') {
                    meta.data[field] = meta.defs[field].default(model);
                } else {
                    meta.data[field] = meta.defs[field].default;
                }
            }

            //validate values as they come in
            //hidden value style setter
            model.__defineSetter__(field, function (value) {
                var meta = this.__verymeta;

                if (meta.defs[field].static === true && !meta.creating) {
                    throw new Error('Cannot set static values');
                }

                meta.data[field] = value;

                meta.isEmpty = false;
            });
        }.bind(this));

        //load data en masse into the model
        //works recursively
        model.loadData = function (value, process) {
            process = process !== false;
            var meta = this.__verymeta;
            var processIn;

            if (Array.isArray(meta.defs)) {
                meta.data = [];
                var valueoff = 0;
                for (var vidx in meta.defs) {
                    processIn = process && meta.defs[vidx].processIn && typeof meta.defs[vidx].processIn === 'function' ? meta.defs[vidx].processIn.bind(this) : false;
                    if (!meta.defs[vidx].required && value.length + valueoff < meta.defs.length) {
                        if (meta.defs[vidx].default === 'function') {
                            this[vidx] = meta.defs[vidx].default(this);
                        } else {
                            this[vidx] = meta.defs[vidx].default;
                        }
                        valueoff += 1;
                    } else {
                        if (processIn) {
                            this[vidx] = processIn(value[vidx - valueoff]).bind(this);
                        } else {
                            this[vidx] = value[vidx - valueoff];
                        }
                    }
                }
            } else {
                Object.keys(value).forEach(function (key) {
                    if (!meta.defs.hasOwnProperty(key)) return;
                    processIn = process && meta.defs[key].processIn && typeof meta.defs[key].processIn === 'function' ? meta.defs[key].processIn.bind(this) : false;

                    if (meta.defs[key].hasOwnProperty('collection')) {
                        for (var vidx in value[key]) {
                            meta.isEmpty = false;
                            if (processIn) {
                                meta.data[key].push(processIn(value[key][vidx]));
                            } else {
                                meta.data[key].push(value[key][vidx]);
                            }
                        }
                    } else if (meta.defs[key].hasOwnProperty('model') && meta.creating) {
                        meta.data[key].loadData(value[key]);
                    } else {
                        meta.isEmpty = false;
                        if (processIn) {
                            model[key] = processIn(value[key]);
                        } else {
                            model[key] = value[key];
                        }
                    }
                }.bind(this));
            }
        };

        //create a JSON serializable Javascript object out of the model data
        //no more helper functions or accessors
        model.toJSON = function (opts) {
            opts = opts || {};

            var meta = this.__verymeta;
            var obj;

            if (Array.isArray(meta.defs) && !opts.useKeywords) {
                obj = [];
            } else {
                obj = {};
            }

            Object.keys(meta.defs).forEach(function (field) {
                var processOut = meta.defs[field].processOut && typeof meta.defs[field].processOut === 'function' ? meta.defs[field].processOut.bind(this) : false;
                var key = field;
                if (meta.defs[field].private && !opts.withPrivate) {
                    return;
                }

                if (opts.useKeywords && meta.reverseMap.hasOwnProperty(field)) {
                    key = meta.reverseMap[field];
                }

                if (meta.defs[field].hasOwnProperty('model')) {
                    if (!meta.data[field].__verymeta.isEmpty) {
                        obj[key] = meta.data[field].toJSON();
                    }
                    return;
                }

                if (meta.defs[field].hasOwnProperty('collection')) {
                    obj[key] = [];
                    meta.data[field].forEach(function (inst) {
                        if (!inst.__verymeta.isEmpty) {
                            obj[key].push(inst.toJSON());
                        }
                    });
                    if (obj[key].length === 0) {
                        delete obj[key];
                    }

                    return;
                }

                obj[key] = processOut ? processOut(this[field]) : this[field];
                if (typeof obj[key] === 'undefined') {
                    delete obj[key];
                }
            }.bind(this));

            return obj;
        };

        //validate that a model follows the rules and types
        //works recursively
        //returns a list of errors
        //if the list of errors.length === 0, you're golden
        model.doValidate = function () {
            var meta = this.__verymeta;
            var errors = [];

            Object.keys(meta.defs).forEach(function (field) {
                var fidx;
                var merrors;
                //if field is set and dependency is set
                if (meta.data.hasOwnProperty(field) && meta.defs[field].depends) {
                    for (fidx in meta.defs[field].depends) {
                        //check to see if other field is set
                        if (!meta.data.hasOwnProperty(fidx) || meta.data[fidx] === undefined) {
                            errors.push(field + ": Dependency -> " + fidx + ": not set");
                        //check to see if dependency has a validator
                        } else if (meta.defs[field].depends instanceof VeryValidator) {
                            merrors = meta.defs[field].depends[fidx].validate(meta.data[fidx]);
                            merrors.forEach(function (error) {
                                errors.push(field + ": Dependency  -> " + fidx + ": " + error);
                            });
                        }
                    }
                }
                //if field is reuqired and it's not set
                if (meta.defs[field].required && (!meta.data.hasOwnProperty(field) || meta.data[field] === undefined)) {
                    errors.push(field + ": required");
                }
                //if this field is another model
                //recursively validate it
                //add errors to our own
                //only if the submodule is required or has been populated
                if (meta.defs[field].hasOwnProperty('model') && meta.data.hasOwnProperty(field) && (!meta.data[field].__verymeta.isEmpty || meta.defs[field].required)) {
                    merrors = meta.data[field].doValidate();
                    for (var eidx in merrors) {
                        merrors[eidx] = field + '.' + merrors[eidx];
                    }
                    errors = errors.concat(merrors);
                //if field is an array of models
                //recursively validate them
                //and add their errors to our own
                } else if (meta.defs[field].hasOwnProperty('collection') && meta.data.hasOwnProperty(field)) {
                    var arrayerrors = [];
                    var idx = 0;
                    meta.data[field].forEach(function (model) {
                        //is this collection required? has the model been populated?
                        if (meta.defs[field].required || !model.__verymeta.isEmpty) {
                            merrors = model.doValidate();
                            for (var eidx in merrors) {
                                merrors[eidx] = field + '[' + idx + '].' + merrors[eidx];
                            }
                            errors = errors.concat(merrors);
                        }
                        idx += 1;
                    }.bind(this));
                //if we have a VeryValidator to validate against, validate it
                } else if (meta.data.hasOwnProperty(field) && meta.defs[field].hasOwnProperty('type')) {
                    if (typeof meta.defs[field].type === 'string' && Types.hasOwnProperty(meta.defs[field].type)) {
                        meta.defs[field].type = Types[meta.defs[field].type];
                    }
                    merrors = meta.defs[field].type.validate(meta.data[field]);
                    if (typeof merrors === 'boolean') {
                        if (merrors) {
                            merrors = [];
                        } else {
                            merrors = ["Failed."];
                        }
                    }
                    merrors.forEach(function (error) {
                        errors.push(field + ": " + error);
                    });
                } else if (meta.data.hasOwnProperty(field) && meta.defs[field].hasOwnProperty('array')) {
                    var tidx = 0;
                    meta.defs[field].array.forEach(function (type) {
                        merrors = type.validate(meta.data[field][tidx]);
                        merrors.forEach(function (error) {
                            errors.push(field + "[" + tidx + "]: " + error);
                        });
                        tidx++;
                    }.bind(this));
                }

            }.bind(this));
            return errors;
        };

        model.makeClone = function () {
            return this.__verymeta.model.create(this.toJSON());
        };

        //generate a JSON string from the model data
        model.toString = function (args) {
            return JSON.stringify(this.toJSON(args));
        };

        //extend controllers
        Object.keys(this.controllers).forEach(function (controller) {
            model[controller] = this.controllers[controller];
        }.bind(this));

        //if model.create passed in initial values, load them
        if (typeof value !== 'undefined') {
            model.loadData(value);
        }

        meta.creating = false;

        return model;
    };

    this.extendModel = function (controllers) {
        this.controllers = underscore.extend(this.controllers, controllers);
    };

    this.addModelVar = function (name, value) {
        this.controllers[name] = value;
    };

}).call(VeryModel.prototype);

module.exports = VeryModel;
<|endoftext|>


<commit_before>/**
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/

var childProcess = require('child_process'),
    path = require('path'),
    tempFolder = '.tmp'+Date.now(),
    appFolder = path.join(tempFolder, 'tempCordovaApp'),
    wrench = require('wrench'),
    utils = require('../../../templates/project/cordova/lib/utils'),
    fs = require('fs'),
    shell = require("shelljs"),
    configPath = utils.getPropertiesFilePath(),
    testAppCreated = false,
    _output = "",
    _code,
    CREATE_COMMAND = path.normalize(path.join(__dirname, "..", "..", "..", "create")) + (utils.isWindows() ? ".bat" : ""),
    TARGET_COMMAND = path.normalize(path.join(appFolder, "cordova", "target")) + (utils.isWindows() ? ".bat" : "");

function executeScript(shellCommand, args, shouldFail) {
    var strCommand = "\"" + shellCommand + "\" " + args.join(" "),
        result;

    //console.log("CREATE About to execute ", strCommand, (new Date()), "\n\n\n");
    result = shell.exec(strCommand, {silent: true, async: false});
    //console.log(result.output, "\n\n\n");
    //console.log("Finished executing  with code ", result.code, " at ", (new Date()), "\n\n\n");
    _output = result.output;
    _code = result.code;
}

describe("cordova/target tests", function () {
    beforeEach(function () {
        utils.copyFile(configPath, path.join(utils.getCordovaDir(), "bb10bak"));
        fs.unlinkSync(configPath);
        if (!testAppCreated) {
            executeScript(CREATE_COMMAND, [appFolder]);
            testAppCreated = true;
        }
    });

    afterEach(function () {
        utils.copyFile(path.join(utils.getCordovaDir(), "bb10bak", utils.getPropertiesFileName()), path.join(utils.getCordovaDir()));
        wrench.rmdirSyncRecursive(path.join(utils.getCordovaDir(), "bb10bak"));
    });

    it("should add a target", function () {
        var project,
            target;

        executeScript(TARGET_COMMAND, ["add", "z10", "169.254.0.1", "-t", "device", "-p", "pass", "--pin", "DEADBEEF"]);
        project = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
        expect(Object.keys(project.targets).length).toEqual(1);
        target = project.targets.z10;
        expect(target.ip).toEqual("169.254.0.1");
        expect(target.type).toEqual("device");
        expect(target.password).toEqual("pass");
        expect(target.pin).toEqual("DEADBEEF");
        expect(_code).toEqual(0);
    });

    it("should remove a target", function () {
        var project;

        executeScript(TARGET_COMMAND, ["add", "z10", "169.254.0.1", "-t", "device", "-p", "pass", "--pin", "DEADBEEF"]);
        executeScript(TARGET_COMMAND, ["remove", "z10"]);
        project = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
        expect(Object.keys(project.targets).length).toEqual(0);
    });

    it("should list targets", function () {
        executeScript(TARGET_COMMAND, ["add", "z10", "169.254.0.1", "-t", "device", "-p", "pass", "--pin", "DEADBEEF"]);
        executeScript(TARGET_COMMAND, ["add", "q10", "169.254.0.2", "-t", "device", "-p", "p455w02D", "--pin", "FACEFACE"]);
        executeScript(TARGET_COMMAND, []);
        expect(_output).toContain("z10\nq10");
    });

    it("should require name for add/remove", function () {
        executeScript(TARGET_COMMAND, ["add"], true);
        expect(_output).toContain("Target details not specified");
    });

    it("should require host for add", function () {
        executeScript(TARGET_COMMAND, ["add", "z10"], true);
        expect(_output).toContain("host is required");
    });

    it("should warn unrecognized command", function () {
        executeScript(TARGET_COMMAND, ["bleh"], true);
        expect(_output).toContain("Unrecognized command");
    });

    it("should warn invalid type", function () {
        executeScript(TARGET_COMMAND, ["add", "z10", "169.254.0.1", "-t", "bleh"], true);
        expect(_output).toContain("Invalid target type: bleh");
    });

    it("should warn invalid pin", function () {

        //keep this in last test to remove test app
        this.after(function () {
            wrench.rmdirSyncRecursive(tempFolder);
        });

        executeScript(TARGET_COMMAND, ["add", "z10", "169.254.0.1", "-t", "device", "--pin", "NOTAPIN!"], true);
        expect(_output).toContain("Invalid PIN: NOTAPIN!");
    });
});
<commit_msg>CB-7250 test/cordova/integration/target use private home<commit_after>/**
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/

var childProcess = require('child_process'),
    path = require('path'),
    utils = require('../../../templates/project/cordova/lib/utils'),
    fs = require('fs'),
    shell = require("shelljs"),
    homevar = (process.platform === 'win32') ? 'USERPROFILE' : 'HOME',
    envhome = process.env[homevar],
    extension = utils.isWindows() ? ".bat" : "",
    CREATE_COMMAND = path.normalize(path.join(__dirname, "..", "..", "..", "create")) + extension,
    TARGET_COMMAND,
    _output,
    _code,
    tempFolder,
    appFolder,
    configPath;

function executeScript(shellCommand, args, shouldFail) {
    var strCommand = "\"" + shellCommand + "\" " + args.join(" "),
        result;

    //console.log("CREATE About to execute ", strCommand, (new Date()), "\n\n\n");
    result = shell.exec(strCommand, {silent: true, async: false});
    //console.log(result.output, "\n\n\n");
    //console.log("Finished executing  with code ", result.code, " at ", (new Date()), "\n\n\n");
    _output = result.output;
    _code = result.code;
}

describe("cordova/target tests", function () {
    beforeEach(function () {
        tempFolder = path.resolve('.tmp'+Date.now());
        appFolder = path.join(tempFolder, 'tempCordovaApp');
        TARGET_COMMAND = path.normalize(path.join(appFolder, "cordova", "target")) + extension;
        process.env[homevar] = tempFolder;
        shell.mkdir('-p', tempFolder);
        configPath = utils.getPropertiesFilePath();
        executeScript(CREATE_COMMAND, [appFolder]);
        _output = "";
    });
    afterEach(function () {
        shell.rm('-rf', tempFolder);
        process.env[homevar] = envhome;
    });

    it("should add a target", function () {
        var project,
            target;

        executeScript(TARGET_COMMAND, ["add", "z10", "169.254.0.1", "-t", "device", "-p", "pass", "--pin", "DEADBEEF"]);
        project = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
        expect(Object.keys(project.targets).length).toEqual(1);
        target = project.targets.z10;
        expect(target.ip).toEqual("169.254.0.1");
        expect(target.type).toEqual("device");
        expect(target.password).toEqual("pass");
        expect(target.pin).toEqual("DEADBEEF");
        expect(_code).toEqual(0);
    });

    it("should remove a target", function () {
        var project;

        executeScript(TARGET_COMMAND, ["add", "z10", "169.254.0.1", "-t", "device", "-p", "pass", "--pin", "DEADBEEF"]);
        executeScript(TARGET_COMMAND, ["remove", "z10"]);
        project = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
        expect(Object.keys(project.targets).length).toEqual(0);
    });

    it("should list targets", function () {
        executeScript(TARGET_COMMAND, ["add", "z10", "169.254.0.1", "-t", "device", "-p", "pass", "--pin", "DEADBEEF"]);
        executeScript(TARGET_COMMAND, ["add", "q10", "169.254.0.2", "-t", "device", "-p", "p455w02D", "--pin", "FACEFACE"]);
        executeScript(TARGET_COMMAND, []);
        expect(_output).toContain("z10\nq10");
    });

    it("should require name for add/remove", function () {
        executeScript(TARGET_COMMAND, ["add"], true);
        expect(_output).toContain("Target details not specified");
    });

    it("should require host for add", function () {
        executeScript(TARGET_COMMAND, ["add", "z10"], true);
        expect(_output).toContain("host is required");
    });

    it("should warn unrecognized command", function () {
        executeScript(TARGET_COMMAND, ["bleh"], true);
        expect(_output).toContain("Unrecognized command");
    });

    it("should warn invalid type", function () {
        executeScript(TARGET_COMMAND, ["add", "z10", "169.254.0.1", "-t", "bleh"], true);
        expect(_output).toContain("Invalid target type: bleh");
    });

    it("should warn invalid pin", function () {
        executeScript(TARGET_COMMAND, ["add", "z10", "169.254.0.1", "-t", "device", "--pin", "NOTAPIN!"], true);
        expect(_output).toContain("Invalid PIN: NOTAPIN!");
    });
});
<|endoftext|>