<commit_before>var helper = require('./util/helper');

var buildObjectFromKeyedArray = helper.buildObjectFromKeyedArray;
var buildObjectFromStringArray = helper.buildObjectFromStringArray;

// native interface constructor

function NativeInterface(client) {
    this.client = client;
    console.log('GeoRedis using NATIVE interface.');
}

// Native Geo Commands

NativeInterface.prototype.geoadd = function(locationName, point, zSetName, callBack) {
    this.client.send_command('geoadd', [zSetName, point.longitude, point.latitude, locationName], callBack);
};

NativeInterface.prototype.geoadd_multi = function(locationSet, zSetName, callBack) {

    var argArray = [zSetName];
    var locationName;
    var location;

    for (locationName in locationSet) {
        location = locationSet[locationName];
        argArray.push(location.longitude, location.latitude, locationName);
    }

    this.client.send_command('geoadd', argArray, callBack);
};

NativeInterface.prototype.geodist = function(locationA, locationB, units, zSetName, callBack) {
    this.client.send_command('geodist', [zSetName, locationA, locationB, units || 'm'], function(err, results) {
        if (err) {
            callBack(err, null);
        } else {
            callBack(null, results);
        }
    });
};

NativeInterface.prototype.geohash = function(member, zSetName, callBack) {

    var argArray = [zSetName].concat([member]);

    this.client.send_command('geohash', argArray, function(err, results) {
        if (err) {
            callBack(err, null);
        } else {
            callBack(null, results[0]);
        }
    });
};

NativeInterface.prototype.geohash_multi = function(members, zSetName, callBack) {

    var argArray = [zSetName].concat(members);
    var locationSet = {};
    var i;

    this.client.send_command('geohash', argArray, function(err, results) {
        if (err) {
            callBack(err, null);
        } else {
            for (i = 0; i < results.length; i++) {
                locationSet[members[i]] = {
                    hash: results[i]
                };
            }
            callBack(null, locationSet);
        }
    });
};

NativeInterface.prototype.geopos = function(member, zSetName, callBack) {

    var argArray = [zSetName].concat([member]);
    var location;

    this.client.send_command('geopos', argArray, function(err, results) {
        if (err) {
            callBack(err, null);
        } else {
            if (results[0] !== null) {
                location = {
                    latitude: results[0][1],
                    longitude: results[0][0]
                };
            } else {
                location = null;
            }
            callBack(null, location);
        }
    });
};

NativeInterface.prototype.geopos_multi = function(members, zSetName, callBack) {

    var argArray = [zSetName].concat(members);
    var locationSet = {};
    var i;

    this.client.send_command('geopos', argArray, function(err, results) {
        if (err) {
            callBack(err, null);
        } else {
            for (i = 0; i < results.length; i++) {
                if (results[i] !== null) {
                    locationSet[members[i]] = {
                        latitude: results[i][1],
                        longitude: results[i][0]
                    };
                } else {
                    locationSet[members[i]] = null;
                }
            }
            callBack(null, locationSet);
        }
    });
};

NativeInterface.prototype.georadius = function(point, radius, options, zSetName, callBack) {
    var argArray = [zSetName].concat([point.longitude, point.latitude]);
    georadiusGeneric(this.client, 'georadius', argArray, radius, options, callBack);
};

NativeInterface.prototype.georadiusbymember = function(member, radius, options, zSetName, callBack) {
    var argArray = [zSetName].concat([member]);
    georadiusGeneric(this.client, 'georadiusbymember', argArray, radius, options, callBack);
};

NativeInterface.prototype.nearby = NativeInterface.prototype.georadius;
NativeInterface.prototype.nearbymember = NativeInterface.prototype.georadiusbymember;

// Native Ordered Set Commands

NativeInterface.prototype.del = function(zSetName, callBack) {
    this.client.del(zSetName, callBack);
};

NativeInterface.prototype.zrem = function(locations, zSetName, callBack) {
    var argArray = [zSetName].concat(locations);
    this.client.zrem(argArray, callBack);
};

function georadiusGeneric(client, type, argArray, radius, options, callBack) {

    var units = options.units || 'm';
    var withDistances = options.withDistances;
    var withCoordinates = options.withCoordinates;
    var withHashes = options.withHashes;
    var order = options.order;
    var count = options.count;

    argArray.push(radius, units);

    if (withDistances === true) {
        argArray.push('WITHDIST');
    }

    if (withHashes === true) {
        argArray.push('WITHHASH');
    }

    if (withCoordinates === true) {
        argArray.push('WITHCOORD');
    }

    if (order) {
        argArray.push(order === true ? 'ASC' : order);
    }

    if (count) {
        argArray.push('COUNT', count);
    }

    client.send_command(type, argArray, function(err, locations) {

        if (err) {
            callBack(err, null);
        } else {
            if (withCoordinates || withDistances || withHashes) {
                locations = processLocations(locations, withCoordinates, withDistances, withHashes, units);
            } else {
                Object.defineProperty(locations, 'locationSet', {
                    get: function() {
                        return buildObjectFromStringArray(this);
                    }
                });
            }

            callBack(null, locations);
        }
    });
}

function processLocations(results, withCoordinates, withDistances, withHashes, units) {

    var locations = [];
    var location;
    var result;
    var i;
    var j;

    for (i = 0; i < results.length; i++) {

        j = 1;
        result = results[i];

        if (result !== null) {

            location = {
                key: result[0]
            };

            if (withDistances === true) {
                location.distance = parseFloat(result[j]);
                j++;
            }

            if (withHashes === true) {
                location.hash = result[j];
                j++;
            }

            if (withCoordinates === true) {
                location.latitude = parseFloat(result[j][1]);
                location.longitude = parseFloat(result[j][0]);
            }
        } else {
            location = null;
        }

        locations.push(location);
    }

    Object.defineProperty(locations, 'locationSet', {
        get: function() {
            return buildObjectFromKeyedArray(this);
        }
    });

    return locations;
}

module.exports = NativeInterface;
<commit_msg>Cleanup.<commit_after>var helper = require('./util/helper');

var buildObjectFromKeyedArray = helper.buildObjectFromKeyedArray;
var buildObjectFromStringArray = helper.buildObjectFromStringArray;

// native interface constructor

function NativeInterface(client) {
    this.client = client;
}

// Native Geo Commands

NativeInterface.prototype.geoadd = function(locationName, point, zSetName, callBack) {
    this.client.send_command('geoadd', [zSetName, point.longitude, point.latitude, locationName], callBack);
};

NativeInterface.prototype.geoadd_multi = function(locationSet, zSetName, callBack) {

    var argArray = [zSetName];
    var locationName;
    var location;

    for (locationName in locationSet) {
        location = locationSet[locationName];
        argArray.push(location.longitude, location.latitude, locationName);
    }

    this.client.send_command('geoadd', argArray, callBack);
};

NativeInterface.prototype.geodist = function(locationA, locationB, units, zSetName, callBack) {
    this.client.send_command('geodist', [zSetName, locationA, locationB, units || 'm'], function(err, results) {
        if (err) {
            callBack(err, null);
        } else {
            callBack(null, results);
        }
    });
};

NativeInterface.prototype.geohash = function(member, zSetName, callBack) {

    var argArray = [zSetName].concat([member]);

    this.client.send_command('geohash', argArray, function(err, results) {
        if (err) {
            callBack(err, null);
        } else {
            callBack(null, results[0]);
        }
    });
};

NativeInterface.prototype.geohash_multi = function(members, zSetName, callBack) {

    var argArray = [zSetName].concat(members);
    var locationSet = {};
    var i;

    this.client.send_command('geohash', argArray, function(err, results) {
        if (err) {
            callBack(err, null);
        } else {
            for (i = 0; i < results.length; i++) {
                locationSet[members[i]] = {
                    hash: results[i]
                };
            }
            callBack(null, locationSet);
        }
    });
};

NativeInterface.prototype.geopos = function(member, zSetName, callBack) {

    var argArray = [zSetName].concat([member]);
    var location;

    this.client.send_command('geopos', argArray, function(err, results) {
        if (err) {
            callBack(err, null);
        } else {
            if (results[0] !== null) {
                location = {
                    latitude: results[0][1],
                    longitude: results[0][0]
                };
            } else {
                location = null;
            }
            callBack(null, location);
        }
    });
};

NativeInterface.prototype.geopos_multi = function(members, zSetName, callBack) {

    var argArray = [zSetName].concat(members);
    var locationSet = {};
    var i;

    this.client.send_command('geopos', argArray, function(err, results) {
        if (err) {
            callBack(err, null);
        } else {
            for (i = 0; i < results.length; i++) {
                if (results[i] !== null) {
                    locationSet[members[i]] = {
                        latitude: results[i][1],
                        longitude: results[i][0]
                    };
                } else {
                    locationSet[members[i]] = null;
                }
            }
            callBack(null, locationSet);
        }
    });
};

NativeInterface.prototype.georadius = function(point, radius, options, zSetName, callBack) {
    var argArray = [zSetName].concat([point.longitude, point.latitude]);
    georadiusGeneric(this.client, 'georadius', argArray, radius, options, callBack);
};

NativeInterface.prototype.georadiusbymember = function(member, radius, options, zSetName, callBack) {
    var argArray = [zSetName].concat([member]);
    georadiusGeneric(this.client, 'georadiusbymember', argArray, radius, options, callBack);
};

NativeInterface.prototype.nearby = NativeInterface.prototype.georadius;
NativeInterface.prototype.nearbymember = NativeInterface.prototype.georadiusbymember;

// Native Ordered Set Commands

NativeInterface.prototype.del = function(zSetName, callBack) {
    this.client.del(zSetName, callBack);
};

NativeInterface.prototype.zrem = function(locations, zSetName, callBack) {
    var argArray = [zSetName].concat(locations);
    this.client.zrem(argArray, callBack);
};

function georadiusGeneric(client, type, argArray, radius, options, callBack) {

    var units = options.units || 'm';
    var withDistances = options.withDistances;
    var withCoordinates = options.withCoordinates;
    var withHashes = options.withHashes;
    var order = options.order;
    var count = options.count;

    argArray.push(radius, units);

    if (withDistances === true) {
        argArray.push('WITHDIST');
    }

    if (withHashes === true) {
        argArray.push('WITHHASH');
    }

    if (withCoordinates === true) {
        argArray.push('WITHCOORD');
    }

    if (order) {
        argArray.push(order === true ? 'ASC' : order);
    }

    if (count) {
        argArray.push('COUNT', count);
    }

    client.send_command(type, argArray, function(err, locations) {

        if (err) {
            callBack(err, null);
        } else {
            if (withCoordinates || withDistances || withHashes) {
                locations = processLocations(locations, withCoordinates, withDistances, withHashes, units);
            } else {
                Object.defineProperty(locations, 'locationSet', {
                    get: function() {
                        return buildObjectFromStringArray(this);
                    }
                });
            }

            callBack(null, locations);
        }
    });
}

function processLocations(results, withCoordinates, withDistances, withHashes, units) {

    var locations = [];
    var location;
    var result;
    var i;
    var j;

    for (i = 0; i < results.length; i++) {

        j = 1;
        result = results[i];

        if (result !== null) {

            location = {
                key: result[0]
            };

            if (withDistances === true) {
                location.distance = parseFloat(result[j]);
                j++;
            }

            if (withHashes === true) {
                location.hash = result[j];
                j++;
            }

            if (withCoordinates === true) {
                location.latitude = parseFloat(result[j][1]);
                location.longitude = parseFloat(result[j][0]);
            }
        } else {
            location = null;
        }

        locations.push(location);
    }

    Object.defineProperty(locations, 'locationSet', {
        get: function() {
            return buildObjectFromKeyedArray(this);
        }
    });

    return locations;
}

module.exports = NativeInterface;
<|endoftext|>


<commit_before>/*jshint node:true*/
module.exports = {
  scenarios: [
    {
      name: 'ember-lts-2.4',
      bower: {
        dependencies: {
          'ember': 'components/ember#lts-2-4'
        },
        resolutions: {
          'ember': 'lts-2-4'
        }
      }
    },
    {
      name: 'ember-lts-2.8',
      bower: {
        dependencies: {
          'ember': 'components/ember#lts-2-8'
        },
        resolutions: {
          'ember': 'lts-2-8'
        }
      }
    },
    {
      name: 'ember-release',
      bower: {
        dependencies: {
          'ember': 'components/ember#release'
        },
        resolutions: {
          'ember': 'release'
        }
      }
    },
    {
      name: 'ember-beta',
      bower: {
        dependencies: {
          'ember': 'components/ember#beta'
        },
        resolutions: {
          'ember': 'beta'
        }
      }
    }
  ]
};
<commit_msg>Remove LTS 2.4 from ember-try config<commit_after>/*jshint node:true*/
module.exports = {
  scenarios: [
    {
      name: 'ember-lts-2.8',
      bower: {
        dependencies: {
          'ember': 'components/ember#lts-2-8'
        },
        resolutions: {
          'ember': 'lts-2-8'
        }
      }
    },
    {
      name: 'ember-release',
      bower: {
        dependencies: {
          'ember': 'components/ember#release'
        },
        resolutions: {
          'ember': 'release'
        }
      }
    },
    {
      name: 'ember-beta',
      bower: {
        dependencies: {
          'ember': 'components/ember#beta'
        },
        resolutions: {
          'ember': 'beta'
        }
      }
    }
  ]
};
<|endoftext|>


<commit_before>'use strict';

const getChannelURL = require('ember-source-channel-url');

module.exports = function() {
  return Promise.all([
    getChannelURL('release'),
  ]).then(urls => {
    return {
      useYarn: false,
      scenarios: [
        {
          name: 'ember-lts-2.12',
          npm: {
            devDependencies: {
              'ember-source': '~2.12.0',
            }
          }
        },
        {
          name: 'ember-lts-2.16',
          npm: {
            devDependencies: {
              'ember-source': '~2.16.0',
            }
          }
        },
        {
          name: 'ember-lts-2.18',
          npm: {
            devDependencies: {
              'ember-source': '~2.18.0',
            }
          }
        },
        {
          name: 'ember-lts-3.4.7',
          npm: {
            devDependencies: {
              'ember-source': '~3.4.7',
            }
          }
        },
        {
          name: 'ember-3.5.0 current DEV version',
          npm: {
            devDependencies: {
              'ember-source': '~3.5.0',
            }
          }
        }
      ]
    };
  });
};
<commit_msg>debugging travis build error<commit_after>'use strict';

const getChannelURL = require('ember-source-channel-url');

module.exports = function() {
  return Promise.all([
    getChannelURL('release'),
  ]).then(urls => {
    return {
      useYarn: false,
      scenarios: [
        {
          name: 'ember-lts-2.12',
          npm: {
            devDependencies: {
              'ember-source': '~2.12.0',
            }
          }
        },
        {
          name: 'ember-lts-2.16',
          npm: {
            devDependencies: {
              'ember-source': '~2.16.0',
            }
          }
        },
        {
          name: 'ember-lts-2.18',
          npm: {
            devDependencies: {
              'ember-source': '~2.18.0',
            }
          }
        },
        {
          name: 'ember-lts-3.4.7',
          npm: {
            devDependencies: {
              'ember-source': '~3.4.7',
            }
          }
        },
        {
          name: 'ember-3.5.0',
          npm: {
            devDependencies: {
              'ember-source': '~3.5.0',
            }
          }
        }
      ]
    };
  });
};
<|endoftext|>


<commit_before>/*jshint node:true*/
module.exports = {
  scenarios: [
    {
      name: 'ember-lts-2.4',
      bower: {
        dependencies: {
          'ember': 'components/ember#lts-2-4'
        },
        resolutions: {
          'ember': 'lts-2-4'
        }
      },
      npm: {
        devDependencies: {
          'ember-source': null
        }
      }
    },
    {
      name: 'ember-lts-2.8',
      bower: {
        dependencies: {
          'ember': 'components/ember#lts-2-8'
        },
        resolutions: {
          'ember': 'lts-2-8'
        }
      },
      npm: {
        devDependencies: {
          'ember-source': null
        }
      }
    },
    {
      name: 'ember-default',
      npm: {
        devDependencies: {}
      }
    }
  ]
};
<commit_msg>Arreglo menor.<commit_after>/*jshint node:true*/
module.exports = {
  scenarios: [
    {
      name: 'ember-lts-2.4',
      bower: {
        dependencies: {
          'ember': 'components/ember#lts-2-4'
        },
        resolutions: {
          'ember': 'lts-2-4'
        }
      },
      npm: {
        devDependencies: {
          'ember-source': null
        }
      }
    },
    {
      name: 'ember-lts-2.8',
      bower: {
        dependencies: {
          'ember': 'components/ember#lts-2-8'
        },
        resolutions: {
          'ember': 'lts-2-8'
        }
      },
      npm: {
        devDependencies: {
          'ember-source': null
        }
      }
    },
  ]
};
<|endoftext|>


<commit_before>/* eslint-env node */
module.exports = {
  scenarios: [
    {
      name: 'ember-lts-2.8',
      bower: {
        dependencies: {
          'ember': 'components/ember#lts-2-8'
        },
        resolutions: {
          'ember': 'lts-2-8'
        }
      },
      npm: {
        devDependencies: {
          'ember-source': null
        }
      }
    },
    {
      name: 'ember-lts-2.12',
      npm: {
        devDependencies: {
          'ember-source': '~2.12.0'
        }
      }
    },
    {
      name: 'ember-release',
      bower: {
        dependencies: {
          'ember': 'components/ember#release'
        },
        resolutions: {
          'ember': 'release'
        }
      },
      npm: {
        devDependencies: {
          'ember-source': null
        }
      }
    },
    {
      name: 'ember-beta',
      bower: {
        dependencies: {
          'ember': 'components/ember#beta'
        },
        resolutions: {
          'ember': 'beta'
        }
      },
      npm: {
        devDependencies: {
          'ember-source': null
        }
      }
    },
    {
      name: 'ember-canary',
      bower: {
        dependencies: {
          'ember': 'components/ember#canary'
        },
        resolutions: {
          'ember': 'canary'
        }
      },
      npm: {
        devDependencies: {
          'ember-source': null
        }
      }
    },
    {
      name: 'ember-default',
      npm: {
        devDependencies: {}
      }
    }
  ]
};
<commit_msg>Updated ember-try config<commit_after>'use strict';

const getChannelURL = require('ember-source-channel-url');

module.exports = function() {
  return Promise.all([
    getChannelURL('release'),
    getChannelURL('beta'),
    getChannelURL('canary')
  ]).then((urls) => {
    return {
      scenarios: [
        {
          name: 'ember-lts-2.18',
          env: {
            EMBER_OPTIONAL_FEATURES: JSON.stringify({ 'jquery-integration': true })
          },
          npm: {
            devDependencies: {
              '@ember/jquery': '^0.5.1',
              'ember-source': '~2.18.0'
            }
          }
        },
        {
          name: 'ember-lts-3.4',
          npm: {
            devDependencies: {
              'ember-source': '~3.4.0'
            }
          }
        },
        {
          name: 'ember-release',
          npm: {
            devDependencies: {
              'ember-source': urls[0]
            }
          }
        },
        {
          name: 'ember-beta',
          npm: {
            devDependencies: {
              'ember-source': urls[1]
            }
          }
        },
        {
          name: 'ember-canary',
          npm: {
            devDependencies: {
              'ember-source': urls[2]
            }
          }
        },
        // The default `.travis.yml` runs this scenario via `npm test`,
        // not via `ember try`. It's still included here so that running
        // `ember try:each` manually or from a customized CI config will run it
        // along with all the other scenarios.
        {
          name: 'ember-default',
          npm: {
            devDependencies: {}
          }
        },
        {
          name: 'ember-default-with-jquery',
          env: {
            EMBER_OPTIONAL_FEATURES: JSON.stringify({
              'jquery-integration': true
            })
          },
          npm: {
            devDependencies: {
              '@ember/jquery': '^0.5.1'
            }
          }
        }
      ]
    };
  });
};
<|endoftext|>


<commit_before>/* @flow */

import { Emitter, CompositeDisposable } from 'atom'
import type { TextEditor, Disposable } from 'atom'
import { linter as validateLinter, messages as validateMessages, messagesLegacy as validateMessagesLegacy } from './validate'
import { normalizeMessages, normalizeMessagesLegacy, isPathIgnored, shouldTriggerLinter, $version, $activated, $requestLatest, $requestLastReceived } from './helpers'
import type { Linter } from './types'

export default class LinterRegistry {
  emitter: Emitter;
  linters: Set<Linter>;
  lintOnFly: boolean;
  ignoreVCS: boolean;
  ignoreGlob: string;
  lintPreviewTabs: boolean;
  subscriptions: CompositeDisposable;

  constructor() {
    this.emitter = new Emitter()
    this.linters = new Set()
    this.subscriptions = new CompositeDisposable()

    this.subscriptions.add(atom.config.observe('linter.lintOnFly', lintOnFly => {
      this.lintOnFly = lintOnFly
    }))
    this.subscriptions.add(atom.config.observe('core.excludeVcsIgnoredPaths', ignoreVCS => {
      this.ignoreVCS = ignoreVCS
    }))
    this.subscriptions.add(atom.config.observe('linter.ignoreGlob', ignoreGlob => {
      this.ignoreGlob = ignoreGlob
    }))
    this.subscriptions.add(atom.config.observe('linter.lintPreviewTabs', lintPreviewTabs => {
      this.lintPreviewTabs = lintPreviewTabs
    }))
    this.subscriptions.add(this.emitter)
  }
  hasLinter(linter: Linter): boolean {
    return this.linters.has(linter)
  }
  addLinter(linter: Linter, legacy: boolean = false) {
    if (!validateLinter(linter)) {
      return
    }
    linter[$activated] = true
    if (typeof linter[$requestLatest] === 'undefined') {
      linter[$requestLatest] = 0
    }
    if (typeof linter[$requestLastReceived] === 'undefined') {
      linter[$requestLastReceived] = 0
    }
    linter[$version] = legacy ? 1 : 2
    this.linters.add(linter)
  }
  deleteLinter(linter: Linter) {
    if (!this.linters.has(linter)) {
      return
    }
    linter[$activated] = false
    this.linters.delete(linter)
  }
  async lint({ onChange, editor } : { onChange: boolean, editor: TextEditor }): Promise<boolean> {
    /* eslint-disable no-multi-spaces */
    const filePath = editor.getPath()

    if (
      (onChange && !this.lintOnFly)                                             || // Lint-on-fly mismatch
      !filePath                                                                 || // Not saved anywhere yet
      editor !== atom.workspace.getActiveTextEditor()                           || // Not active
      isPathIgnored(editor.getPath(), this.ignoreGlob, this.ignoreVCS)          || // Ignored by VCS or Glob
      (!this.lintPreviewTabs && editor.hasTerminatedPendingState === false)        // Ignore Preview tabs
    ) {
      return false
    }

    const scopes = editor.scopeDescriptorForBufferPosition(editor.getCursorBufferPosition()).getScopesArray()
    scopes.push('*')

    const promises = []
    for (const linter of this.linters) {
      if (!shouldTriggerLinter(linter, onChange, scopes)) {
        continue
      }
      const number = ++linter[$requestLatest]
      const statusBuffer = linter.scope === 'file' ? null : editor.getBuffer()
      const statusFilePath = linter.scope === 'file' ? filePath : null

      this.emitter.emit('did-begin-linting', { number, linter, filePath: statusFilePath })
      promises.push(new Promise(function(resolve) {
        resolve(linter.lint(editor))
      }).then(messages => {
        this.emitter.emit('did-finish-linting', { number, linter, filePath: statusFilePath })
        if (linter[$requestLastReceived] >= number || !linter[$activated]) {
          return
        }
        linter[$requestLastReceived] = number

        let validity = Array.isArray(messages) && (statusBuffer === null || statusBuffer.isAlive())
        if (validity && atom.inDevMode()) {
          validity = linter[$version] === 2 ? validateMessages(linter.name, messages) : validateMessagesLegacy(linter.name, messages)
        }
        if (validity) {
          if (linter[$version] === 2) {
            normalizeMessages(linter.name, messages)
          } else {
            normalizeMessagesLegacy(linter.name, messages)
          }
        }
        this.emitter.emit('did-update-messages', { messages: messages || [], linter, buffer: statusBuffer })
      }, error => {
        this.emitter.emit('did-finish-linting', { number, linter, filePath: statusFilePath })
        atom.notifications.addError(`[Linter] Error running ${linter.name}`, {
          detail: 'See console for more info',
        })
        console.error(`[Linter] Error running ${linter.name}`, error)
      }))
    }

    await Promise.all(promises)
    return true
  }
  onDidUpdateMessages(callback: Function): Disposable {
    return this.emitter.on('did-update-messages', callback)
  }
  onDidBeginLinting(callback: Function): Disposable {
    return this.emitter.on('did-begin-linting', callback)
  }
  onDidFinishLinting(callback: Function): Disposable {
    return this.emitter.on('did-finish-linting', callback)
  }
  dispose() {
    this.linters.clear()
    this.subscriptions.dispose()
  }
}
<commit_msg>:bug: Fix buffer status for file/project scoped linters<commit_after>/* @flow */

import { Emitter, CompositeDisposable } from 'atom'
import type { TextEditor, Disposable } from 'atom'
import { linter as validateLinter, messages as validateMessages, messagesLegacy as validateMessagesLegacy } from './validate'
import { normalizeMessages, normalizeMessagesLegacy, isPathIgnored, shouldTriggerLinter, $version, $activated, $requestLatest, $requestLastReceived } from './helpers'
import type { Linter } from './types'

export default class LinterRegistry {
  emitter: Emitter;
  linters: Set<Linter>;
  lintOnFly: boolean;
  ignoreVCS: boolean;
  ignoreGlob: string;
  lintPreviewTabs: boolean;
  subscriptions: CompositeDisposable;

  constructor() {
    this.emitter = new Emitter()
    this.linters = new Set()
    this.subscriptions = new CompositeDisposable()

    this.subscriptions.add(atom.config.observe('linter.lintOnFly', lintOnFly => {
      this.lintOnFly = lintOnFly
    }))
    this.subscriptions.add(atom.config.observe('core.excludeVcsIgnoredPaths', ignoreVCS => {
      this.ignoreVCS = ignoreVCS
    }))
    this.subscriptions.add(atom.config.observe('linter.ignoreGlob', ignoreGlob => {
      this.ignoreGlob = ignoreGlob
    }))
    this.subscriptions.add(atom.config.observe('linter.lintPreviewTabs', lintPreviewTabs => {
      this.lintPreviewTabs = lintPreviewTabs
    }))
    this.subscriptions.add(this.emitter)
  }
  hasLinter(linter: Linter): boolean {
    return this.linters.has(linter)
  }
  addLinter(linter: Linter, legacy: boolean = false) {
    if (!validateLinter(linter)) {
      return
    }
    linter[$activated] = true
    if (typeof linter[$requestLatest] === 'undefined') {
      linter[$requestLatest] = 0
    }
    if (typeof linter[$requestLastReceived] === 'undefined') {
      linter[$requestLastReceived] = 0
    }
    linter[$version] = legacy ? 1 : 2
    this.linters.add(linter)
  }
  deleteLinter(linter: Linter) {
    if (!this.linters.has(linter)) {
      return
    }
    linter[$activated] = false
    this.linters.delete(linter)
  }
  async lint({ onChange, editor } : { onChange: boolean, editor: TextEditor }): Promise<boolean> {
    /* eslint-disable no-multi-spaces */
    const filePath = editor.getPath()

    if (
      (onChange && !this.lintOnFly)                                             || // Lint-on-fly mismatch
      !filePath                                                                 || // Not saved anywhere yet
      editor !== atom.workspace.getActiveTextEditor()                           || // Not active
      isPathIgnored(editor.getPath(), this.ignoreGlob, this.ignoreVCS)          || // Ignored by VCS or Glob
      (!this.lintPreviewTabs && editor.hasTerminatedPendingState === false)        // Ignore Preview tabs
    ) {
      return false
    }

    const scopes = editor.scopeDescriptorForBufferPosition(editor.getCursorBufferPosition()).getScopesArray()
    scopes.push('*')

    const promises = []
    for (const linter of this.linters) {
      if (!shouldTriggerLinter(linter, onChange, scopes)) {
        continue
      }
      const number = ++linter[$requestLatest]
      const statusBuffer = linter.scope === 'file' ? editor.getBuffer() : null
      const statusFilePath = linter.scope === 'file' ? filePath : null

      this.emitter.emit('did-begin-linting', { number, linter, filePath: statusFilePath })
      promises.push(new Promise(function(resolve) {
        resolve(linter.lint(editor))
      }).then(messages => {
        this.emitter.emit('did-finish-linting', { number, linter, filePath: statusFilePath })
        if (linter[$requestLastReceived] >= number || !linter[$activated]) {
          return
        }
        linter[$requestLastReceived] = number

        let validity = Array.isArray(messages) && (statusBuffer === null || statusBuffer.isAlive())
        if (validity && atom.inDevMode()) {
          validity = linter[$version] === 2 ? validateMessages(linter.name, messages) : validateMessagesLegacy(linter.name, messages)
        }
        if (validity) {
          if (linter[$version] === 2) {
            normalizeMessages(linter.name, messages)
          } else {
            normalizeMessagesLegacy(linter.name, messages)
          }
        }
        this.emitter.emit('did-update-messages', { messages: messages || [], linter, buffer: statusBuffer })
      }, error => {
        this.emitter.emit('did-finish-linting', { number, linter, filePath: statusFilePath })
        atom.notifications.addError(`[Linter] Error running ${linter.name}`, {
          detail: 'See console for more info',
        })
        console.error(`[Linter] Error running ${linter.name}`, error)
      }))
    }

    await Promise.all(promises)
    return true
  }
  onDidUpdateMessages(callback: Function): Disposable {
    return this.emitter.on('did-update-messages', callback)
  }
  onDidBeginLinting(callback: Function): Disposable {
    return this.emitter.on('did-begin-linting', callback)
  }
  onDidFinishLinting(callback: Function): Disposable {
    return this.emitter.on('did-finish-linting', callback)
  }
  dispose() {
    this.linters.clear()
    this.subscriptions.dispose()
  }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

var websocket = null

var logger = (function () { // eslint-disable-line no-unused-vars
  const sep = '\n/* ### NEXT TESTCASE ############################## */'
  const color = {
    red: '\033[1;31m', // eslint-disable-line
    green: '\033[1;32m', // eslint-disable-line
    clear: '\033[0m' // eslint-disable-line
  }
  if (utils.platform.isWindows) {
    color.red = ''
    color.green = ''
    color.clear = ''
  }

  function console (msg) {
    if (websocket) {
      websocket.send(msg)
    }
    if (typeof window === 'undefined') {
      print(msg)  // eslint-disable-line no-undef
    } else if (window.dump) {
      window.dump(msg)
    } else if (window.console && window.console.log) {
      window.console.log(msg)
    } else {
      throw new Error('Unable to run console logger.')
    }
  }

  function dump (msg) {
    console(msg)
  }

  function testcase (msg) {
    dump('/*L*/ ' + utils.common.quote(msg) + '\n')
  }

  function dumpln (msg) {
    dump(msg + '\n')
  }

  function error (msg) {
    dumpln(color.red + msg + color.clear)
  }

  function JSError (msg) {
    error(comment("ERROR: " + msg))
  }

  function comment (msg) {
    return '/* ' + msg + ' */'
  }

  function separator () {
    dumpln(color.green + sep + color.clear)
  }

  function traceback () {
    error('===[ Traceback ]')
    try {
      throw new Error()
    } catch (e) {
      dump(e.stack || e.stacktrace || '')
    }
    error('================')
  }

  return {
    console: console,
    dump: dump,
    error: error,
    JSError: JSError,
    dumpln: dumpln,
    comment: comment,
    testcase: testcase,
    separator: separator,
    traceback: traceback
  }
})()
<commit_msg>Hex is the correct escape in strict mode<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

var websocket = null

var logger = (function () { // eslint-disable-line no-unused-vars
  const sep = '\n/* ### NEXT TESTCASE ############################## */'
  const color = {
    red: '\u{1b}[1;31m',
    green: '\u{1b}[1;32m',
    clear: '\u{1b}[0m'
  }
  if (utils.platform.isWindows) {
    color.red = ''
    color.green = ''
    color.clear = ''
  }

  function console (msg) {
    if (websocket) {
      websocket.send(msg)
    }
    if (typeof window === 'undefined') {
      print(msg)  // eslint-disable-line no-undef
    } else if (window.dump) {
      window.dump(msg)
    } else if (window.console && window.console.log) {
      window.console.log(msg)
    } else {
      throw new Error('Unable to run console logger.')
    }
  }

  function dump (msg) {
    console(msg)
  }

  function testcase (msg) {
    dump('/*L*/ ' + utils.common.quote(msg) + '\n')
  }

  function dumpln (msg) {
    dump(msg + '\n')
  }

  function error (msg) {
    dumpln(color.red + msg + color.clear)
  }

  function JSError (msg) {
    error(comment('ERROR: ' + msg))
  }

  function comment (msg) {
    return '/* ' + msg + ' */'
  }

  function separator () {
    dumpln(color.green + sep + color.clear)
  }

  function traceback () {
    error('===[ Traceback ]')
    try {
      throw new Error()
    } catch (e) {
      dump(e.stack || e.stacktrace || '')
    }
    error('================')
  }

  return {
    console: console,
    dump: dump,
    error: error,
    JSError: JSError,
    dumpln: dumpln,
    comment: comment,
    testcase: testcase,
    separator: separator,
    traceback: traceback
  }
})()
<|endoftext|>


<commit_before>/*!
 *
 * Copyright (c) 2013 Sebastian Golasch
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

'use strict';

// int. libs
var Log = require('./level0');

/**
 * @class LogLevel1
 * @constructor
 * @param {object} opts
 */

var LogLevel1 = Log;

/**
 * @module LogLevel1
 */

module.exports = LogLevel1;

/**
 * Outputs a message when the testrunner starts
 *
 * @method outputRunnerStarted
 * @return {LogLevel1}
 */

LogLevel1.prototype.outputRunnerStarted = function () {
  this.echo('Running tests', {foreground: 'magentaBright'});
  return this;
};

/**
 * Outputs a message when a test is finished
 *
 * @method outputTestFinished
 * @param {object} data
 * @return {LogLevel1}
 */

LogLevel1.prototype.outputTestFinished = function (data) {
  this.echo('.', {nl: false, foreground: (data.status ? 'greenBright' : 'redBright')});
  return this;
};

/**
 * Outputs a message when the testrunner has been finished
 *
 * @method outputRunnerFinished
 * @param {object} data
 * @return {LogLevel1}
 */

LogLevel1.prototype.outputRunnerFinished = function (data) {
  var elapsedTime = data.elapsedTime;
  var timeOutput = '';

  // generate formatted time output
  if (elapsedTime.hours > 0) {
    timeOutput += elapsedTime.hours + ' hrs ';
  }

  if (elapsedTime.minutes > 0) {
    timeOutput += elapsedTime.minutes + ' min ';
  }

  timeOutput += Math.round(elapsedTime.seconds * Math.pow(10, 2)) / Math.pow(10, 2) + ' sec';

  // newline FTW!
  this.echo('', {nl: true});

  // echo the assertion & time status
  this.echo(' ' +
    data.assertionsPassed + '/' + data.assertions + ' assertions passed.' + ' Elapsed Time: ' + timeOutput + ' ',
    {foreground: 'black', background: (data.status ? 'bgGreenBright' : 'bgRedBright')}
  );
  return this;
};
<commit_msg>Update level1.js<commit_after>/*!
 *
 * Copyright (c) 2013 Sebastian Golasch
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

'use strict';

// int. libs
var Log = require('./level0');

/**
 * @class LogLevel1
 * @constructor
 * @param {object} opts
 */

var LogLevel1 = Log;

/**
 * @module LogLevel1
 */

module.exports = LogLevel1;

/**
 * Outputs a message when the testrunner starts
 *
 * @method outputRunnerStarted
 * @return {LogLevel1}
 */

LogLevel1.prototype.outputRunnerStarted = function () {
  this.echo('Running tests', {foreground: 'magentaBright'});
  return this;
};

/**
 * Outputs a message when a test is finished
 *
 * @method outputTestFinished
 * @param {object} data
 * @return {LogLevel1}
 */

LogLevel1.prototype.outputTestFinished = function (data) {
  this.echo('.', {nl: false, foreground: (data.status ? 'greenBright' : 'redBright')});
  return this;
};

/**
 * Outputs a message when the testrunner has been finished
 *
 * @method outputRunnerFinished
 * @param {object} data
 * @return {LogLevel1}
 */

LogLevel1.prototype.outputRunnerFinished = function (data) {
  var elapsedTime = data.elapsedTime;
  var timeOutput = '';

  // generate formatted time output
  if (elapsedTime.hours > 0) {
    timeOutput += elapsedTime.hours + ' hrs ';
  }

  if (elapsedTime.minutes > 0) {
    timeOutput += elapsedTime.minutes + ' min ';
  }

  timeOutput += Math.round(elapsedTime.seconds * Math.pow(10, 2)) / Math.pow(10, 2) + ' sec';

  // newline FTW!
  this.echo('', {nl: true});

  // echo the assertion & time status
  this.echo(' ' +
    data.assertionsPassed + '/' + data.assertions + ' assertions passed.' + ' Elapsed Time: ' + timeOutput + ' ',
    {foreground: (data.status ? 'black' : 'whiteBright'), background: (data.status ? 'bgGreenBright' : 'bgRedBright')}
  );
  return this;
};
<|endoftext|>


<commit_before>// Require the libraries.
var async =   require('async'),
    $ =       require('jquerygo'),
    prompt =  require('prompt'),
    config =  require('nconf');

// Function to easily get a configuration or prompt for it...
var get = function(param, value, done) {
  var self = this;

  // Allow them to provide a done function.
  if (typeof value === 'function') {
    done = value;
    value = null;
  }

  // Get the parameter name.
  var paramName = (typeof param === 'string') ? param : param.name;
  if (value) {
    config.set(paramName, value);
  }
  else {
    value = config.get(paramName);
  }

  if (!value) {
    prompt.get([param], function (err, result) {
      value = result[paramName];
      config.set(paramName, value);
      done(null, value);
    });
  }
  else if(done) {
    done(null, value);
  }
  else {
    return value;
  }
};

// Load the configuration.
config.argv().env();
var configFile = config.get('o');
if (configFile) {
  config.file({file:configFile});
}

// Start the prompt.
prompt.start();

// Jimmy Johns already has jquery.
$.config.addJQuery = false;

/**
 * Input a value.
 *
 * @param {type} selector
 * @param {type} value
 * @param {type} done
 * @returns {undefined}
 */
var input = function(selector, value, done) {
  $(selector).val(value, function() {
    this.blur(done);
  });
};

/**
 * Helper to set an input within an async series.
 * @param {type} selector
 * @param {type} config
 * @returns {unresolved}
 */
var setInput = function(selector, param, direct) {
  direct = !!direct;
  return function(done) {
    if (direct) {
      input(selector, config.get(param), done);
    }
    else {
      get(param, function(err, value) {
        input(selector, value, done);
      });
    }
  };
};

/**
 * Select a value.
 *
 * @param {type} selector
 * @param {type} value
 * @param {type} done
 * @returns {undefined}
 */
var select = function(selector, value, done) {
  if (value) {
    $(selector + ' li:contains("' + value + '") a:eq(0)').click(function() {
      this.blur(done);
    });
  }
  else {
    done();
  }
};

/**
 * Helper to select a value within an async series.
 * @param {type} selector
 * @param {type} value
 * @returns {unresolved}
 */
var selectVal = function(selector, param, direct) {
  direct = !!direct;
  return function(done) {
    selector += 'SelectBoxItOptions';
    if (direct) {
      var value = config.get(param);
      if (!value) {
        value = param;
      }
      select(selector, value, done);
    }
    else {
      get(param, function(err, value) {
        select(selector, value, done);
      });
    }
  };
};

/**
 * Selects an ingredient.
 *
 * @param {type} param
 * @returns {unresolved}
 */
var selectIngredient = function(param) {
  return function(done) {
    get(param, function(err, value) {
      if (value) {
        var query = 'div.includedIngredientsWrap ';
        query += 'h4:contains("' + param + '") ';
        query += '~ span:contains("' + value + '")';
        $(query).click(function() {
          this.blur(done);
        });
      }
      else {
        done();
      }
    });
  };
};

/**
 * Helper to print something when it is executed.
 *
 * @param {type} text
 * @returns {unresolved}
 */
var print = function(text) {
  return function(done) {
    console.log(text);
    done();
  };
};

/**
 * Helper function to take a pause...
 *
 * @param {type} time
 * @returns {unresolved}
 */
var sleep = function(time) {
  return function(done) {
    setTimeout(done, time);
  };
};

/**
 * Login to Jimmy Johns.
 */
var login = function(done) {
  async.series([
    print('Logging in.'),
    $.go(false, 'visit', 'https://online.jimmyjohns.com/#/login'),
    $.go(false, 'waitForElement', '#email'),
    setInput('#email', 'email'),
    setInput('#loginPassword', {name: 'pass', hidden: true}),
    $('#loginButton').go(false, 'click'),
    $.go(false, 'waitForElement', 'p.welcomeMsg'),
    print('Successfully logged in.')
  ], done);
};

/**
 * Fill out the new delivery stuff..
 * @param {type} done
 * @returns {undefined}
 */
var newDelivery = function(done) {
  async.series([
    print('Filling out delivery information.'),
    $.go(false, 'visit', 'https://online.jimmyjohns.com/#/deliveryaddress'),
    $.go(false, 'waitForElement', '#companyInput'),
    setInput('#companyInput', 'company', true),
    setInput('#addressInput', 'address'),
    setInput('#aptNoInput', 'apt/suite', true),
    setInput('#cityInput', 'city'),
    selectVal('#stateSelect', 'state'),
    setInput('#zip', 'zip'),
    sleep(1000),
    $('#verifyAddressBtn').go(false, 'click'),
    $.go(false, 'waitForElement', '#confirmDeliveryAddressBtn'),
    sleep(1000),
    $('#confirmDeliveryAddressBtn').go(false, 'click'),
    $.go(false, 'waitForElement', 'a.menuTab'),
    print('Sucessfully filled out delivery information.'),
  ], done);
};

/**
 * Select your sandwich on the page.
 *
 * @param {type} done
 * @returns {selectSandwich}
 */
var selectSandwich = function(done) {
  console.log('Selecting sandwich.');
  var sandwich = config.get('sandwich');
  if (!sandwich) {
    console.log('No sandwich specified in your config file.');
    done(true);
  }
  else {
    sandwich = sandwich.toLowerCase();
    var found = false, selection = 0, query = 'a.menuItem span.displayName';

    // Iterate over each sandwich.
    $(query).each(function(index, item, done) {
      item.text(function(text) {
        if (text.toLowerCase().indexOf(sandwich) != -1) {
          selection = index;
          found = true;
        }
        done();
      });
    }, function() {
      if (!found) {
        console.log('Could not find your sandwich.');
        done();
      }
      else {

        // Select this sandwich.
        query += ':eq(' + selection + ')';
        console.log('Sandwich found...');
        $(query).click(function() {
          $.waitForElement('h1:contains("Customize Your Order")', done);
        });
      }
    });
  }
};

/**
 * Customize your order.
 *
 * @param {type} done
 * @returns {customizeOrder}
 */
var customizeOrder = function(done) {
  async.series([
    print('Customizing order...'),
    sleep(2000),
    $.go(false, 'waitForElement', '#textInput'),
    setInput('#textInput', 'who'),
    selectVal('#select_2944', 'bread'),
    $.go(false, 'waitForElement', 'span:contains("Cut in half")'),
    function(done) {
      if (config.get('cut')) {
        $('#chk_3894').click(done);
      }
    },
    selectVal('#select_3963', 'drink'),
    selectVal('#select_3882', 'chips'),
    selectVal('#select_3992', 'cookie'),
    selectVal('#select_3943', 'pickle'),
    selectIngredient('Tomato'),
    $('a:contains("Add To Order")').go(false, 'click'),
    $.go(false, 'waitForElement', 'h1:contains("Your Order For Delivery")'),
    print('Done customizing order.'),
  ], done);
};

/**
 * Select a credit card.
 *
 * @param {type} done
 * @returns {undefined}
 */
var selectCard = function(done) {
  // Have them chose their credit card.
  console.log("Please select your card type:\n\
  1.) American Express\n\
  2.) Visa\n\
  3.) Mastercard\n\
  4.) Discover Card");
  prompt.get(['card'], function (err, result) {
    switch (result.card) {
      case '1':
        $('a#radio_Amex').click(done);
        break;
      case '2':
        $('a#radio_Visa').click(done);
        break;
      case '3':
        $('a#radio_Mastercard').click(done);
        break;
      case '4':
        $('a#radio_Discover').click(done);
        break;
      default:
        done(true);
        break;
    }
  });
};

/**
 * Enter their card number.
 *
 * @param {type} done
 * @returns {undefined}
 */
var enterCardNumber = function(done) {
  console.log("Enter your card number:");
  prompt.get(['cardnum'], function(err, result) {
    input('#cardNumber', result.cardnum, done);
  });
};

/**
 * Enter the card expiration date.
 *
 * @param {type} done
 * @returns {undefined}
 */
var enterCardExpire = function(done) {
  console.log("Enter the card expiration: Format MM-YY:");
  prompt.get(['expire'], function(err, result) {
    var parts = result.expire.split('-');
    select('#expMonthSelectBoxItOptions', parts[0], function() {
      select('#expYearSelectBoxItOptions', '20' + parts[1], done);
    });
  });
};

/**
 * Enter the card code.
 *
 * @param {type} done
 * @returns {undefined}
 */
var enterCardCode = function(done) {
  console.log("Enter the card security code (on back):");
  prompt.get(['code'], function(err, result) {
    input('#securityCode', result.code, done);
  });
};

/**
 * Enter the name on the card.
 *
 * @param {type} done
 * @returns {undefined}
 */
var enterCardName = function(done) {
  console.log("Enter the name on the card:");
  prompt.get(['name'], function(err, result) {
    input('#nameOnCard', result.name, done);
  });
};

/**
 * Now checkout...
 * @param {type} done
 * @returns {undefined}
 */
var checkout = function(done) {
  async.series([
    print('Checking out...'),
    $.go(false, 'waitForElement', 'a#gotoCheckoutBtn'),
    $('a#gotoCheckoutBtn').go(false, 'click'),
    $.go(false, 'waitForElement', '#selectPaymentType'),
    selectVal('#selectPaymentType', 'Credit Card', true),
    $.go(false, 'waitForElement', 'div#cards'),
    selectCard,
    selectVal('#selectPaymentType', 'Credit Card', true),
    enterCardNumber,
    enterCardExpire,
    enterCardCode,
    enterCardName,
    setInput('#tipAmount', 'tip'),
    setInput('#billingAddress', 'billing_address'),
    setInput('#billingCity', 'billing_city'),
    selectVal('#stateSelect', 'billing_state'),
    setInput('#billingZip', 'billing_zip'),
    $('a:contains("Review Order")').go(false, 'click'),
    $.go(false, 'waitForElement', 'h1:contains("Review & Place Order")'),
    setInput('#companyInput', 'company', true),
    setInput('#aptNoInput', 'apt/suite', true),
    setInput('#gateCode', 'gate_code', true),
    setInput('#deliveryInstructions', 'delivery_instructions', true),
    sleep(1000),
    print('Placing order...'),
    $('a:contains("Place Order")').go(false, 'click'),
    $.go(false, 'waitForElement', 'h1:contains("Thank you for your order")'),
    $.go('capture', __dirname + '/complete.png'),
    print('Delivery on its way! Order details at ' + __dirname + '/complete.png')
  ], done);
};

// Order a sandwich!!!
async.series([
  login,
  newDelivery,
  selectSandwich,
  customizeOrder,
  checkout
], function() {
  $.close();
});
<commit_msg>Fixed an issue where the contains would not pull from the right element.<commit_after>// Require the libraries.
var async =   require('async'),
    $ =       require('jquerygo'),
    prompt =  require('prompt'),
    config =  require('nconf');

// Function to easily get a configuration or prompt for it...
var get = function(param, value, done) {
  var self = this;

  // Allow them to provide a done function.
  if (typeof value === 'function') {
    done = value;
    value = null;
  }

  // Get the parameter name.
  var paramName = (typeof param === 'string') ? param : param.name;
  if (value) {
    config.set(paramName, value);
  }
  else {
    value = config.get(paramName);
  }

  if (!value) {
    prompt.get([param], function (err, result) {
      value = result[paramName];
      config.set(paramName, value);
      done(null, value);
    });
  }
  else if(done) {
    done(null, value);
  }
  else {
    return value;
  }
};

// Load the configuration.
config.argv().env();
var configFile = config.get('o');
if (configFile) {
  config.file({file:configFile});
}

// Start the prompt.
prompt.start();

// Jimmy Johns already has jquery.
$.config.addJQuery = false;

/**
 * Input a value.
 *
 * @param {type} selector
 * @param {type} value
 * @param {type} done
 * @returns {undefined}
 */
var input = function(selector, value, done) {
  $(selector).val(value, function() {
    this.blur(done);
  });
};

/**
 * Helper to set an input within an async series.
 * @param {type} selector
 * @param {type} config
 * @returns {unresolved}
 */
var setInput = function(selector, param, direct) {
  direct = !!direct;
  return function(done) {
    if (direct) {
      input(selector, config.get(param), done);
    }
    else {
      get(param, function(err, value) {
        input(selector, value, done);
      });
    }
  };
};

/**
 * Select a value.
 *
 * @param {type} selector
 * @param {type} value
 * @param {type} done
 * @returns {undefined}
 */
var select = function(selector, value, done) {
  if (value) {
    $(selector + ' li:contains("' + value + '") a:eq(0)').click(function() {
      this.blur(done);
    });
  }
  else {
    done();
  }
};

/**
 * Helper to select a value within an async series.
 * @param {type} selector
 * @param {type} value
 * @returns {unresolved}
 */
var selectVal = function(selector, param, direct) {
  direct = !!direct;
  return function(done) {
    selector += 'SelectBoxItOptions';
    if (direct) {
      var value = config.get(param);
      if (!value) {
        value = param;
      }
      select(selector, value, done);
    }
    else {
      get(param, function(err, value) {
        select(selector, value, done);
      });
    }
  };
};

/**
 * Selects an ingredient.
 *
 * @param {type} param
 * @returns {unresolved}
 */
var selectIngredient = function(param) {
  return function(done) {
    get(param, function(err, value) {
      if (value) {
        var query = 'div.includedIngredientsWrap ';
        query += 'h4:contains("' + param + '") ';
        query += '~ span:contains("' + value + '")';
        $(query).click(function() {
          this.blur(done);
        });
      }
      else {
        done();
      }
    });
  };
};

/**
 * Helper to print something when it is executed.
 *
 * @param {type} text
 * @returns {unresolved}
 */
var print = function(text) {
  return function(done) {
    console.log(text);
    done();
  };
};

/**
 * Helper function to take a pause...
 *
 * @param {type} time
 * @returns {unresolved}
 */
var sleep = function(time) {
  return function(done) {
    setTimeout(done, time);
  };
};

/**
 * Login to Jimmy Johns.
 */
var login = function(done) {
  async.series([
    print('Logging in.'),
    $.go(false, 'visit', 'https://online.jimmyjohns.com/#/login'),
    $.go(false, 'waitForElement', '#email'),
    setInput('#email', 'email'),
    setInput('#loginPassword', {name: 'pass', hidden: true}),
    $('#loginButton').go(false, 'click'),
    $.go(false, 'waitForElement', 'p.welcomeMsg'),
    print('Successfully logged in.')
  ], done);
};

/**
 * Fill out the new delivery stuff..
 * @param {type} done
 * @returns {undefined}
 */
var newDelivery = function(done) {
  async.series([
    print('Filling out delivery information.'),
    $.go(false, 'visit', 'https://online.jimmyjohns.com/#/deliveryaddress'),
    $.go(false, 'waitForElement', '#companyInput'),
    setInput('#companyInput', 'company', true),
    setInput('#addressInput', 'address'),
    setInput('#aptNoInput', 'apt/suite', true),
    setInput('#cityInput', 'city'),
    selectVal('#stateSelect', 'state'),
    setInput('#zip', 'zip'),
    sleep(1000),
    $('#verifyAddressBtn').go(false, 'click'),
    $.go(false, 'waitForElement', '#confirmDeliveryAddressBtn'),
    sleep(1000),
    $('#confirmDeliveryAddressBtn').go(false, 'click'),
    $.go(false, 'waitForElement', 'a.menuTab'),
    print('Sucessfully filled out delivery information.'),
  ], done);
};

/**
 * Select your sandwich on the page.
 *
 * @param {type} done
 * @returns {selectSandwich}
 */
var selectSandwich = function(done) {
  console.log('Selecting sandwich.');
  var sandwich = config.get('sandwich');
  if (!sandwich) {
    console.log('No sandwich specified in your config file.');
    done(true);
  }
  else {
    sandwich = sandwich.toLowerCase();
    var found = false, selection = 0, query = 'a.menuItem span.displayName';

    // Iterate over each sandwich.
    $(query).each(function(index, item, done) {
      item.text(function(text) {
        if (text.toLowerCase().indexOf(sandwich) != -1) {
          selection = index;
          found = true;
        }
        done();
      });
    }, function() {
      if (!found) {
        console.log('Could not find your sandwich.');
        done();
      }
      else {

        // Select this sandwich.
        query += ':eq(' + selection + ')';
        console.log('Sandwich found...');
        $(query).click(function() {
          $.waitForElement('*:contains("Customize Your Order")', done);
        });
      }
    });
  }
};

/**
 * Customize your order.
 *
 * @param {type} done
 * @returns {customizeOrder}
 */
var customizeOrder = function(done) {
  async.series([
    print('Customizing order...'),
    sleep(2000),
    $.go(false, 'waitForElement', '#textInput'),
    setInput('#textInput', 'who'),
    selectVal('#select_2944', 'bread'),
    $.go(false, 'waitForElement', 'span:contains("Cut in half")'),
    function(done) {
      if (config.get('cut')) {
        $('#chk_3894').click(done);
      }
    },
    selectVal('#select_3963', 'drink'),
    selectVal('#select_3882', 'chips'),
    selectVal('#select_3992', 'cookie'),
    selectVal('#select_3943', 'pickle'),
    selectIngredient('Tomato'),
    $('*:contains("Add To Order")').go(false, 'click'),
    $.go(false, 'waitForElement', '*:contains("Your Order For Delivery")'),
    print('Done customizing order.'),
  ], done);
};

/**
 * Select a credit card.
 *
 * @param {type} done
 * @returns {undefined}
 */
var selectCard = function(done) {
  // Have them chose their credit card.
  console.log("Please select your card type:\n\
  1.) American Express\n\
  2.) Visa\n\
  3.) Mastercard\n\
  4.) Discover Card");
  prompt.get(['card'], function (err, result) {
    switch (result.card) {
      case '1':
        $('a#radio_Amex').click(done);
        break;
      case '2':
        $('a#radio_Visa').click(done);
        break;
      case '3':
        $('a#radio_Mastercard').click(done);
        break;
      case '4':
        $('a#radio_Discover').click(done);
        break;
      default:
        done(true);
        break;
    }
  });
};

/**
 * Enter their card number.
 *
 * @param {type} done
 * @returns {undefined}
 */
var enterCardNumber = function(done) {
  console.log("Enter your card number:");
  prompt.get(['cardnum'], function(err, result) {
    input('#cardNumber', result.cardnum, done);
  });
};

/**
 * Enter the card expiration date.
 *
 * @param {type} done
 * @returns {undefined}
 */
var enterCardExpire = function(done) {
  console.log("Enter the card expiration: Format MM-YY:");
  prompt.get(['expire'], function(err, result) {
    var parts = result.expire.split('-');
    select('#expMonthSelectBoxItOptions', parts[0], function() {
      select('#expYearSelectBoxItOptions', '20' + parts[1], done);
    });
  });
};

/**
 * Enter the card code.
 *
 * @param {type} done
 * @returns {undefined}
 */
var enterCardCode = function(done) {
  console.log("Enter the card security code (on back):");
  prompt.get(['code'], function(err, result) {
    input('#securityCode', result.code, done);
  });
};

/**
 * Enter the name on the card.
 *
 * @param {type} done
 * @returns {undefined}
 */
var enterCardName = function(done) {
  console.log("Enter the name on the card:");
  prompt.get(['name'], function(err, result) {
    input('#nameOnCard', result.name, done);
  });
};

/**
 * Now checkout...
 * @param {type} done
 * @returns {undefined}
 */
var checkout = function(done) {
  async.series([
    print('Checking out...'),
    $.go(false, 'waitForElement', 'a#gotoCheckoutBtn'),
    $('a#gotoCheckoutBtn').go(false, 'click'),
    $.go(false, 'waitForElement', '#selectPaymentType'),
    selectVal('#selectPaymentType', 'Credit Card', true),
    $.go(false, 'waitForElement', 'div#cards'),
    selectCard,
    selectVal('#selectPaymentType', 'Credit Card', true),
    enterCardNumber,
    enterCardExpire,
    enterCardCode,
    enterCardName,
    setInput('#tipAmount', 'tip'),
    setInput('#billingAddress', 'billing_address'),
    setInput('#billingCity', 'billing_city'),
    selectVal('#stateSelect', 'billing_state'),
    setInput('#billingZip', 'billing_zip'),
    $('*:contains("Review Order")').go(false, 'click'),
    $.go(false, 'waitForElement', '*:contains("Review & Place Order")'),
    setInput('#companyInput', 'company', true),
    setInput('#aptNoInput', 'apt/suite', true),
    setInput('#gateCode', 'gate_code', true),
    setInput('#deliveryInstructions', 'delivery_instructions', true),
    sleep(1000),
    print('Placing order...'),
    $('*:contains("Place Order")').go(false, 'click'),
    $.go(false, 'waitForElement', '*:contains("Thank you for your order")'),
    $.go('capture', __dirname + '/complete.png'),
    print('Delivery on its way! Order details at ' + __dirname + '/complete.png')
  ], done);
};

// Order a sandwich!!!
async.series([
  login,
  newDelivery,
  selectSandwich,
  customizeOrder,
  checkout
], function() {
  $.close();
});
<|endoftext|>


<commit_before>const memwatch = require('memwatch-ng')
const heapdump = require('heapdump')
const knox = require('knox')
const path = require('path')
const os = require('os')
const chalk = require('chalk')

const { NODE_ENV } = process.env
const { S3_KEY, S3_SECRET, S3_BUCKET } = require('../desktop/config')

function log (message) {
  console.log(chalk.red(`[MEMORY] ${message}`))
}

function upload (pathname, callback) {
  const filename = path.basename(pathname)
  const client = knox.createClient({ key: S3_KEY, secret: S3_SECRET, bucket: S3_BUCKET })
  client.putFile(pathname, path.join('/heap-dumps', filename), (err, res) => {
    if (err) {
      log(`Failed to upload heap dump ${pathname}: ${err.message}`)
    } else {
      if (res.statusCode === 200) {
        log(`Uploaded heap dump to https://${S3_BUCKET}.s3.amazonaws.com/${S3_BUCKET}/${filename}`)
      } else {
        log(`Failed to upload heap dump ${pathname}: HTTP ${res.statusCode}`)
      }
      res.resume()
    }
    callback()
  })
}

// Every second, this program "leaks" a little bit. Add `--enable-gc` to the `node` CLI options of the `start` script.
function startLeaking () {
  log('Start leaking in order to test memory profiling!')
  var leak = []
  setInterval(() => {
    for (var i = 0; i < 10; i++) {
      var str = i.toString() + ' on a stick, short and stout!'
      leak.push(str)
    }
  }, 1000)
  setInterval(global.gc, 10000)
}

module.exports = () => {
  log('Enabling memory profiling.')

  if (NODE_ENV !== 'production' && global.gc) {
    startLeaking()
  }

  let lastReportedAt = new Date()
  let working = false

  memwatch.on('leak', ({ growth }) => {
    const prev = lastReportedAt
    const now = new Date()
    lastReportedAt = now

    const start = prev.toLocaleTimeString()
    const end = now.toLocaleTimeString()
    log(`A leak was detected between ${start} and ${end} which grew the heap by ${growth} bytes.`)

    if (working) {
      log(`Still processing previous leak, skipping this report.`)
    } else {
      working = true

      const pathname = path.join(os.tmpdir(), `heapdump-${Date.now()}.heapsnapshot`)
      heapdump.writeSnapshot(pathname, (err) => {
        if (err) {
          log(`Failed to generate heap dump ${pathname}: ${err.message}`)
          working = false
        } else {
          if (NODE_ENV === 'production') {
            upload(pathname, () => {
              working = false
            })
          } else {
            log(`Written heap dump to ${pathname}`)
            working = false
          }
        }
      })
    }
  })
}
<commit_msg>[memory] Upload heap dumps in staging as well.<commit_after>const memwatch = require('memwatch-ng')
const heapdump = require('heapdump')
const knox = require('knox')
const path = require('path')
const os = require('os')
const chalk = require('chalk')

const { NODE_ENV } = process.env
const { S3_KEY, S3_SECRET, S3_BUCKET } = require('../desktop/config')

function log (message) {
  console.log(chalk.red(`[MEMORY] ${message}`))
}

function upload (pathname, callback) {
  const filename = path.basename(pathname)
  const client = knox.createClient({ key: S3_KEY, secret: S3_SECRET, bucket: S3_BUCKET })
  client.putFile(pathname, path.join('/heap-dumps', filename), (err, res) => {
    if (err) {
      log(`Failed to upload heap dump ${pathname}: ${err.message}`)
    } else {
      if (res.statusCode === 200) {
        log(`Uploaded heap dump to https://${S3_BUCKET}.s3.amazonaws.com/${S3_BUCKET}/${filename}`)
      } else {
        log(`Failed to upload heap dump ${pathname}: HTTP ${res.statusCode}`)
      }
      res.resume()
    }
    callback()
  })
}

// Every second, this program "leaks" a little bit. Add `--enable-gc` to the `node` CLI options of the `start` script.
function startLeaking () {
  log('Start leaking in order to test memory profiling!')
  var leak = []
  setInterval(() => {
    for (var i = 0; i < 10; i++) {
      var str = i.toString() + ' on a stick, short and stout!'
      leak.push(str)
    }
  }, 1000)
  setInterval(global.gc, 10000)
}

module.exports = () => {
  log('Enabling memory profiling.')

  if (NODE_ENV !== 'production' && global.gc) {
    startLeaking()
  }

  let lastReportedAt = new Date()
  let working = false

  memwatch.on('leak', ({ growth }) => {
    const prev = lastReportedAt
    const now = new Date()
    lastReportedAt = now

    const start = prev.toLocaleTimeString()
    const end = now.toLocaleTimeString()
    log(`A leak was detected between ${start} and ${end} which grew the heap by ${growth} bytes.`)

    if (working) {
      log(`Still processing previous leak, skipping this report.`)
    } else {
      working = true

      const pathname = path.join(os.tmpdir(), `heapdump-${Date.now()}.heapsnapshot`)
      heapdump.writeSnapshot(pathname, (err) => {
        if (err) {
          log(`Failed to generate heap dump ${pathname}: ${err.message}`)
          working = false
        } else {
          if (NODE_ENV === 'development') {
            log(`Written heap dump to ${pathname}`)
            working = false
          } else {
            upload(pathname, () => {
              working = false
            })
          }
        }
      })
    }
  })
}
<|endoftext|>


<commit_before>const memwatch = require('memwatch-ng')
const heapdump = require('heapdump')
const knox = require('knox')
const path = require('path')
const os = require('os')
const chalk = require('chalk')

const { NODE_ENV } = process.env
const { S3_KEY, S3_SECRET, S3_BUCKET } = require('../desktop/config')

function log (message) {
  console.log(chalk.red(`[MEMORY] ${message}`))
}

function upload (pathname, callback) {
  const filename = path.basename(pathname)
  const client = knox.createClient({ key: S3_KEY, secret: S3_SECRET, bucket: S3_BUCKET })
  client.putFile(filename, pathname, (err, res) => {
    if (err) {
      log(`Failed to upload heap dump ${pathname}: ${err.message}`)
    } else {
      if (res.statusCode === 200) {
        log(`Uploaded heap dump to https://${S3_BUCKET}.s3.amazonaws.com/${S3_BUCKET}/${filename}`)
      } else {
        log(`Failed to upload heap dump ${pathname}: HTTP ${res.statusCode}`)
      }
      res.resume()
    }
    callback()
  })
}

// Every second, this program "leaks" a little bit. Add `--enable-gc` to the `node` CLI options of the `start` script.
function startLeaking () {
  log('Start leaking in order to test memory profiling!')
  var leak = []
  setInterval(() => {
    for (var i = 0; i < 10; i++) {
      var str = i.toString() + ' on a stick, short and stout!'
      leak.push(str)
    }
  }, 1000)
  setInterval(global.gc, 10000)
}

module.exports = () => {
  log('Enabling memory profiling.')

  if (NODE_ENV !== 'production' && global.gc) {
    startLeaking()
  }

  let lastReportedAt = new Date()
  let working = false

  memwatch.on('leak', ({ growth }) => {
    const prev = lastReportedAt
    const now = new Date()
    lastReportedAt = now

    const start = prev.toLocaleTimeString()
    const end = now.toLocaleTimeString()
    log(`A leak was detected between ${start} and ${end} which grew the heap by ${growth} bytes.`)

    if (working) {
      log(`Still processing previous leak, skipping this report.`)
    } else {
      working = true

      const pathname = path.join(os.tmpdir(), `heapdump-${Date.now()}.heapsnapshot`)
      heapdump.writeSnapshot(pathname, (err) => {
        if (err) {
          log(`Failed to generate heap dump ${pathname}: ${err.message}`)
          working = false
        } else {
          if (NODE_ENV === 'production') {
            upload(pathname, () => {
              working = false
            })
          } else {
            log(`Written heap dump to ${pathname}`)
            working = false
          }
        }
      })
    }
  })
}
<commit_msg>[memory] Fix S3 client argument order and prefix remote path.<commit_after>const memwatch = require('memwatch-ng')
const heapdump = require('heapdump')
const knox = require('knox')
const path = require('path')
const os = require('os')
const chalk = require('chalk')

const { NODE_ENV } = process.env
const { S3_KEY, S3_SECRET, S3_BUCKET } = require('../desktop/config')

function log (message) {
  console.log(chalk.red(`[MEMORY] ${message}`))
}

function upload (pathname, callback) {
  const filename = path.basename(pathname)
  const client = knox.createClient({ key: S3_KEY, secret: S3_SECRET, bucket: S3_BUCKET })
  client.putFile(pathname, path.join('/heap-dumps', filename), (err, res) => {
    if (err) {
      log(`Failed to upload heap dump ${pathname}: ${err.message}`)
    } else {
      if (res.statusCode === 200) {
        log(`Uploaded heap dump to https://${S3_BUCKET}.s3.amazonaws.com/${S3_BUCKET}/${filename}`)
      } else {
        log(`Failed to upload heap dump ${pathname}: HTTP ${res.statusCode}`)
      }
      res.resume()
    }
    callback()
  })
}

// Every second, this program "leaks" a little bit. Add `--enable-gc` to the `node` CLI options of the `start` script.
function startLeaking () {
  log('Start leaking in order to test memory profiling!')
  var leak = []
  setInterval(() => {
    for (var i = 0; i < 10; i++) {
      var str = i.toString() + ' on a stick, short and stout!'
      leak.push(str)
    }
  }, 1000)
  setInterval(global.gc, 10000)
}

module.exports = () => {
  log('Enabling memory profiling.')

  if (NODE_ENV !== 'production' && global.gc) {
    startLeaking()
  }

  let lastReportedAt = new Date()
  let working = false

  memwatch.on('leak', ({ growth }) => {
    const prev = lastReportedAt
    const now = new Date()
    lastReportedAt = now

    const start = prev.toLocaleTimeString()
    const end = now.toLocaleTimeString()
    log(`A leak was detected between ${start} and ${end} which grew the heap by ${growth} bytes.`)

    if (working) {
      log(`Still processing previous leak, skipping this report.`)
    } else {
      working = true

      const pathname = path.join(os.tmpdir(), `heapdump-${Date.now()}.heapsnapshot`)
      heapdump.writeSnapshot(pathname, (err) => {
        if (err) {
          log(`Failed to generate heap dump ${pathname}: ${err.message}`)
          working = false
        } else {
          if (NODE_ENV === 'production') {
            upload(pathname, () => {
              working = false
            })
          } else {
            log(`Written heap dump to ${pathname}`)
            working = false
          }
        }
      })
    }
  })
}
<|endoftext|>


<commit_before>// Copyright 2011 Mark Cavage, Inc.  All rights reserved.

var assert = require('assert');
var EventEmitter = require('events').EventEmitter;
var util = require('util');

var asn1 = require('asn1');

var AbandonRequest = require('./abandon_request');
var AddRequest = require('./add_request');
var AddResponse = require('./add_response');
var BindRequest = require('./bind_request');
var BindResponse = require('./bind_response');
var CompareRequest = require('./compare_request');
var CompareResponse = require('./compare_response');
var DeleteRequest = require('./del_request');
var DeleteResponse = require('./del_response');
var ExtendedRequest = require('./ext_request');
var ExtendedResponse = require('./ext_response');
var ModifyRequest = require('./modify_request');
var ModifyResponse = require('./modify_response');
var ModifyDNRequest = require('./moddn_request');
var ModifyDNResponse = require('./moddn_response');
var SearchRequest = require('./search_request');
var SearchEntry = require('./search_entry');
var SearchReference = require('./search_reference');
var SearchResponse = require('./search_response');
var UnbindRequest = require('./unbind_request');
var UnbindResponse = require('./unbind_response');

var LDAPResult = require('./result');
var Message = require('./message');

var Protocol = require('../protocol');

///--- Globals

var Ber = asn1.Ber;
var BerReader = asn1.BerReader;

///--- API

function Parser(options) {
  if (!options || typeof (options) !== 'object')
    throw new TypeError('options (object) required');
  if (typeof (options.log) !== 'object')
    throw new TypeError('options.log (object) required');

  EventEmitter.call(this);

  this.buffer = null;
  this.log = options.log;
}
util.inherits(Parser, EventEmitter);
module.exports = Parser;

Parser.prototype.write = function (data) {
  if (!data || !Buffer.isBuffer(data))
    throw new TypeError('data (buffer) required');

  var nextMessage = null;
  var self = this;

  function end() {
    if (nextMessage)
      return self.write(nextMessage);

    return true;
  }

  self.buffer = (self.buffer ? Buffer.concat([self.buffer, data]) : data);

  var ber = new BerReader(self.buffer);
  if (!ber.readSequence())
    return false;

  if (ber.remain < ber.length) { // ENOTENOUGH
    return false;
  } else if (ber.remain > ber.length) { // ETOOMUCH
    // This is sort of ugly, but allows us to make miminal copies
    nextMessage = self.buffer.slice(ber.offset + ber.length);
    ber._size = ber.offset + ber.length;
    assert.equal(ber.remain, ber.length);
  }

  // If we're here, ber holds the message, and nextMessage is temporarily
  // pointing at the next sequence of data (if it exists)
  self.buffer = null;

  var message = this.getMessage(ber);
  if (!message)
    return end();

  try {
    message.parse(ber);
  } catch (e) {
    this.emit('error', e, message);
    return false;
  }
  this.emit('message', message);

  return end();
};

Parser.prototype.getMessage = function (ber) {
  assert.ok(ber);

  var self = this;

  var messageID = ber.readInt();
  var type = ber.readSequence();

  var Message;
  switch (type) {

  case Protocol.LDAP_REQ_ABANDON:
    Message = AbandonRequest;
    break;

  case Protocol.LDAP_REQ_ADD:
    Message = AddRequest;
    break;

  case Protocol.LDAP_REP_ADD:
    Message = AddResponse;
    break;

  case Protocol.LDAP_REQ_BIND:
    Message = BindRequest;
    break;

  case Protocol.LDAP_REP_BIND:
    Message = BindResponse;
    break;

  case Protocol.LDAP_REQ_COMPARE:
    Message = CompareRequest;
    break;

  case Protocol.LDAP_REP_COMPARE:
    Message = CompareResponse;
    break;

  case Protocol.LDAP_REQ_DELETE:
    Message = DeleteRequest;
    break;

  case Protocol.LDAP_REP_DELETE:
    Message = DeleteResponse;
    break;

  case Protocol.LDAP_REQ_EXTENSION:
    Message = ExtendedRequest;
    break;

  case Protocol.LDAP_REP_EXTENSION:
    Message = ExtendedResponse;
    break;

  case Protocol.LDAP_REQ_MODIFY:
    Message = ModifyRequest;
    break;

  case Protocol.LDAP_REP_MODIFY:
    Message = ModifyResponse;
    break;

  case Protocol.LDAP_REQ_MODRDN:
    Message = ModifyDNRequest;
    break;

  case Protocol.LDAP_REP_MODRDN:
    Message = ModifyDNResponse;
    break;

  case Protocol.LDAP_REQ_SEARCH:
    Message = SearchRequest;
    break;

  case Protocol.LDAP_REP_SEARCH_ENTRY:
    Message = SearchEntry;
    break;

  case Protocol.LDAP_REP_SEARCH_REF:
    Message = SearchReference;
    break;

  case Protocol.LDAP_REP_SEARCH:
    Message = SearchResponse;
    break;

  case Protocol.LDAP_REQ_UNBIND:
    Message = UnbindRequest;
    break;

  default:
    this.emit('error',
              new Error('protocolOp 0x' +
                        (type ? type.toString(16) : '??') +
                        ' not supported'),
              new LDAPResult({
                messageID: messageID,
                protocolOp: type || Protocol.LDAP_REP_EXTENSION
              }));

    return false;
  }

  return new Message({
    messageID: messageID,
    log: self.log
  });
};
<commit_msg>Improve parser error handling<commit_after>// Copyright 2011 Mark Cavage, Inc.  All rights reserved.

var assert = require('assert');
var EventEmitter = require('events').EventEmitter;
var util = require('util');

var asn1 = require('asn1');

var AbandonRequest = require('./abandon_request');
var AddRequest = require('./add_request');
var AddResponse = require('./add_response');
var BindRequest = require('./bind_request');
var BindResponse = require('./bind_response');
var CompareRequest = require('./compare_request');
var CompareResponse = require('./compare_response');
var DeleteRequest = require('./del_request');
var DeleteResponse = require('./del_response');
var ExtendedRequest = require('./ext_request');
var ExtendedResponse = require('./ext_response');
var ModifyRequest = require('./modify_request');
var ModifyResponse = require('./modify_response');
var ModifyDNRequest = require('./moddn_request');
var ModifyDNResponse = require('./moddn_response');
var SearchRequest = require('./search_request');
var SearchEntry = require('./search_entry');
var SearchReference = require('./search_reference');
var SearchResponse = require('./search_response');
var UnbindRequest = require('./unbind_request');
var UnbindResponse = require('./unbind_response');

var LDAPResult = require('./result');
var Message = require('./message');

var Protocol = require('../protocol');

///--- Globals

var Ber = asn1.Ber;
var BerReader = asn1.BerReader;

///--- API

function Parser(options) {
  if (!options || typeof (options) !== 'object')
    throw new TypeError('options (object) required');
  if (typeof (options.log) !== 'object')
    throw new TypeError('options.log (object) required');

  EventEmitter.call(this);

  this.buffer = null;
  this.log = options.log;
}
util.inherits(Parser, EventEmitter);
module.exports = Parser;

Parser.prototype.write = function (data) {
  if (!data || !Buffer.isBuffer(data))
    throw new TypeError('data (buffer) required');

  var nextMessage = null;
  var self = this;

  function end() {
    if (nextMessage)
      return self.write(nextMessage);

    return true;
  }

  self.buffer = (self.buffer ? Buffer.concat([self.buffer, data]) : data);

  var ber = new BerReader(self.buffer);
  if (!ber.readSequence())
    return false;

  if (ber.remain < ber.length) { // ENOTENOUGH
    return false;
  } else if (ber.remain > ber.length) { // ETOOMUCH
    // This is sort of ugly, but allows us to make miminal copies
    nextMessage = self.buffer.slice(ber.offset + ber.length);
    ber._size = ber.offset + ber.length;
    assert.equal(ber.remain, ber.length);
  }

  // If we're here, ber holds the message, and nextMessage is temporarily
  // pointing at the next sequence of data (if it exists)
  self.buffer = null;

  var message = this.getMessage(ber);
  if (!message)
    return end();

  try {
    message.parse(ber);
  } catch (e) {
    this.emit('error', e, message);
    return false;
  }
  this.emit('message', message);

  return end();
};

Parser.prototype.getMessage = function (ber) {
  assert.ok(ber);

  var self = this;

  try {
    var messageID = ber.readInt();
    var type = ber.readSequence();
  } catch (e) {
    // Handle servers that aren't speaking the language at all
    this.emit('error', e);
    return false;
  }

  var Message;
  switch (type) {

  case Protocol.LDAP_REQ_ABANDON:
    Message = AbandonRequest;
    break;

  case Protocol.LDAP_REQ_ADD:
    Message = AddRequest;
    break;

  case Protocol.LDAP_REP_ADD:
    Message = AddResponse;
    break;

  case Protocol.LDAP_REQ_BIND:
    Message = BindRequest;
    break;

  case Protocol.LDAP_REP_BIND:
    Message = BindResponse;
    break;

  case Protocol.LDAP_REQ_COMPARE:
    Message = CompareRequest;
    break;

  case Protocol.LDAP_REP_COMPARE:
    Message = CompareResponse;
    break;

  case Protocol.LDAP_REQ_DELETE:
    Message = DeleteRequest;
    break;

  case Protocol.LDAP_REP_DELETE:
    Message = DeleteResponse;
    break;

  case Protocol.LDAP_REQ_EXTENSION:
    Message = ExtendedRequest;
    break;

  case Protocol.LDAP_REP_EXTENSION:
    Message = ExtendedResponse;
    break;

  case Protocol.LDAP_REQ_MODIFY:
    Message = ModifyRequest;
    break;

  case Protocol.LDAP_REP_MODIFY:
    Message = ModifyResponse;
    break;

  case Protocol.LDAP_REQ_MODRDN:
    Message = ModifyDNRequest;
    break;

  case Protocol.LDAP_REP_MODRDN:
    Message = ModifyDNResponse;
    break;

  case Protocol.LDAP_REQ_SEARCH:
    Message = SearchRequest;
    break;

  case Protocol.LDAP_REP_SEARCH_ENTRY:
    Message = SearchEntry;
    break;

  case Protocol.LDAP_REP_SEARCH_REF:
    Message = SearchReference;
    break;

  case Protocol.LDAP_REP_SEARCH:
    Message = SearchResponse;
    break;

  case Protocol.LDAP_REQ_UNBIND:
    Message = UnbindRequest;
    break;

  default:
    this.emit('error',
              new Error('protocolOp 0x' +
                        (type ? type.toString(16) : '??') +
                        ' not supported'),
              new LDAPResult({
                messageID: messageID,
                protocolOp: type || Protocol.LDAP_REP_EXTENSION
              }));

    return false;
  }

  return new Message({
    messageID: messageID,
    log: self.log
  });
};
<|endoftext|>


<commit_before>var Promise = require('bluebird');
var AutoLoader = require('../autoLoader');
var db = require('../database').getParams();
var NotFoundError = require('../exceptions/notFoundError');
var AclNotFoundError = require('../exceptions/aclNotFoundError');
var headerHelper = require('../utils/headerParser');

var isAllowed = function(resource, permission) {
  return function(req, res, callback) {
    var id = null;

		if (!permission) {
      permission = req.method;
    }

    return getUserId(req)
		.bind({})
    .then(function(userId) {
			id = userId;
      return AutoLoader.getModel(db.entities.policy.model).forge().fetchActivesByUserId(userId);
    })
    .then(function(policies) {
      for (var key in policies) {
        var policy = policies[key];
        if (policy.get('resource').get('name').toLowerCase() === resource.toLowerCase() && policy.get('permission').get('name').toLowerCase() === permission.toLowerCase()) {
          return true;
        }
      }
			return false;
    })
		.then(function(ret) {
			if (ret === false) {
				var message = 'Unable to find a policy for userId=' + id + ' over resource=' + resource.toLowerCase() + ' with permission=' + permission.toLowerCase();
				throw new AclNotFoundError(message);
			}
			return ret;
		})
    .nodeify(function(err, ret) {
			if (err) {
				return callback(err);
			}
			else {
				return callback(null, ret);
			}
    });
  }
}

var getUserId = function(req) {
	var promise = Promise.resolve();
  var idemanDbConfig = AutoLoader.getIdemanDbConfig();
  var user = null;
  var bearerToken = null;
  var credentials = headerHelper.getBasicAuthentication(req);

	if (credentials == null) {
		bearerToken = headerHelper.getBearerToken(req);

		promise = AutoLoader.getIdemanModel(idemanDbConfig.entities.token.model).forge()
		.where({
			token: bearerToken
		})
		.fetch({
			columns: ['userId']
		})
		.then(function(token) {
			if (!token) {
				throw new NotFoundError();
			}
			return Promise.resolve(token.get('userId'));
		})
		.catch(function(err) {
			return Promise.reject(err);
		});
	}
	else {
		promise = AutoLoader.getModel(idemanDbConfig.entities.user.model).forge()
		.where({
			username: credentials['username'],
			enabled: true
		})
		.fetch({
			columns: ['id', 'password']
		})
		.bind({})
		.then(function(user) {
			this.user = user;
			if (!user) {
				throw new NotFoundError();
			}
			return user.verifyPassword(credentials['password']);
		})
		.then(function(isMatch) {
			if (!isMatch) {
				throw new NotFoundError();
			}
			return Promise.resolve(this.user.get('id'));
		})
		.catch(function(err) {
			return Promise.reject(err);
		});
	}

	return promise;
}

exports.isAllowed = isAllowed;
<commit_msg>fixed promise in middleware<commit_after>var Promise = require('bluebird');
var AutoLoader = require('../autoLoader');
var db = require('../database').getParams();
var NotFoundError = require('../exceptions/notFoundError');
var AclNotFoundError = require('../exceptions/aclNotFoundError');
var headerHelper = require('../utils/headerParser');

var isAllowed = function(resource, permission) {
  return function(req, res, callback) {
    var id = null;

    if (!permission) {
      permission = req.method;
    }

    return getUserId(req)
    .bind({})
    .then(function(userId) {
      id = userId;
      return AutoLoader.getModel(db.entities.policy.model).forge().fetchActivesByUserId(userId);
    })
    .then(function(policies) {
      for (var key in policies) {
        var policy = policies[key];
        if (policy.get('resource').get('name').toLowerCase() === resource.toLowerCase() && policy.get('permission').get('name').toLowerCase() === permission.toLowerCase()) {
          return true;
        }
      }
      return false;
    })
    .then(function(ret) {
      if (ret === false) {
        var message = 'Unable to find a policy for userId=' + id + ' over resource=' + resource.toLowerCase() + ' with permission=' + permission.toLowerCase();
        throw new AclNotFoundError(message);
      }
      return ret;
    })
    .nodeify(function(err, ret) {
      if (err) {
        return callback(err);
      }
      else {
        return callback(null, ret);
      }
    });
  }
}

var getUserId = function(req) {
  var promise = Promise.resolve();
  var idemanDbConfig = AutoLoader.getIdemanDbConfig();
  var user = null;
  var bearerToken = null;
  var credentials = headerHelper.getBasicAuthentication(req);

  if (credentials == null) {
    bearerToken = headerHelper.getBearerToken(req);

    promise = AutoLoader.getIdemanModel(idemanDbConfig.entities.token.model).forge()
    .where({
      token: bearerToken
    })
    .fetch({
      columns: ['userId']
    })
    .then(function(token) {
      if (!token) {
        throw new NotFoundError();
      }
      return Promise.resolve(token.get('userId'));
    })
    .catch(function(err) {
      return Promise.reject(err);
    });
  }
  else {
    promise = AutoLoader.getModel(idemanDbConfig.entities.user.model).forge()
    .where({
      username: credentials['username'],
      enabled: true
    })
    .fetch({
      columns: ['id', 'password']
    })
    .bind({})
    .then(function(user) {
      this.user = user;
      if (!user) {
        throw new NotFoundError();
      }
      return user.verifyPassword(credentials['password']);
    })
    .then(function(isMatch) {
      if (!isMatch) {
        throw new NotFoundError();
      }
      return Promise.resolve(this.user.get('id'));
    })
    .catch(function(err) {
      return Promise.reject(err);
    });
  }

  return promise;
}

exports.isAllowed = isAllowed;
<|endoftext|>


<commit_before>/*jslint node: true */
'use strict';

var mongoose = require('mongoose');
var util = require('../util');
var __ = require('lodash');

var responseSchema = new mongoose.Schema({
  // We don't use the native mongo ID when communicating with clients.
  _id: { type: mongoose.Schema.Types.ObjectId, select: false },
  __v: { type: Number, select: false },
  id: String,
  survey: String,
  source: {
    type: { type: String },
    collector: String,
    started: Date,
    finished: Date
  },
  created: Date,
  geo_info: {
    centroid: [Number],
    parcel_id: String,
    points: { type: [], select: false },
    geometry: {
      type: { type: String },
      coordinates: []
    },
    humanReadableName: String
  },
  files: [String],
  parcel_id: String,
  object_id: String,
  responses: {
    type: Object,
    validate: validateResponses
  }
}, {
  autoIndex: false
});

// Indexes

// Ensure we have a geo index on the centroid field.
// We always restrict based on survey ID, so we use a compound index.
responseSchema.index({ 'geo_info.centroid': '2d', survey: 1 });

// Index the survey ID + creation date, which we use to sort
// Descending
responseSchema.index({ survey: 1, created: 1 });
// Ascending
responseSchema.index({ survey: 1, created: -1 });

// Index the survey ID, which we use to look up sets of responses
responseSchema.index({ survey: 1 });

// Index the parcel ID
responseSchema.index({ survey: 1, parcel_id: 1 });

responseSchema.set('toObject', {
  transform: function (doc, ret, options) {
    return {
      id: ret.id,
      survey: ret.survey,
      source: ret.source,
      created: ret.created,
      geo_info: {
        centroid: ret.geo_info.centroid,
        parcel_id: ret.geo_info.parcel_id,
        geometry: ret.geo_info.geometry,
        humanReadableName: ret.geo_info.humanReadableName
      },
      files: ret.files,
      parcel_id: ret.parcel_id,
      object_id: ret.object_id,
      responses: ret.responses
    };
  }
});

responseSchema.pre('save', function parseCentroid(next) {
  // check if there is a centroid. if yes, make sure the values are floats
  // TODO: abstract into a testable function.
  if (this.geo_info !== undefined) {
    var centroid = this.geo_info.centroid;
    if (centroid !== undefined) {
      centroid[0] = parseFloat(centroid[0]);
      centroid[1] = parseFloat(centroid[1]);
    }
  }
  next();
});

function validateResponses (val) {
  return val !== undefined;
}

function simplify(ring) {
  // FIXME: Simplify the ring
  return ring;
}

function collectRingPoints(memo, ring) {
  simplify(ring).forEach(function (point) {
    memo.push(point);
  });
}

function collectPolygonPoints(memo, polygon) {
  polygon.forEach(function (ring) {
    collectRingPoints(memo, ring);
  });
}

function collectMultiPolygonPoints(memo, multiPolygon) {
  multiPolygon.forEach(function (polygon) {
    collectPolygonPoints(memo, polygon);
  });
}

// Collect all of the coordinates into one array, so we can index them.
responseSchema.pre('save', function collectPoints(next) {
  if (this.geometry !== undefined) {
    if (this.geometry.type === 'MultiPolygon') {
      this.geo_info.points = [];
      collectMultiPolygonPoints(this.geo_info.points, this.geo_info.geometry.coordinates);
    } else if (this.geometry.type === 'Polygon') {
      this.geo_info.points = [];
      collectPolygonPoints(this.geo_info.points, this.geo_info.geometry.coordinates);
    } else if (this.geometry.type === 'Point') {
      this.geo_info.points = this.geo_info.geometry.coordinates;
    }
  }
  next();
});

// Set the ID.
responseSchema.pre('save', function setId(next) {
  this.id = util.uuidv1();
  next();
});

// Set the creation date.
responseSchema.pre('save', function setCreated(next) {
  if (this.created === undefined) {
    this.created = new Date();
  }
  next();
});

// Allow either parcel_id or object_id.
// Eventually we'll deprecate parcel_id.
responseSchema.pre('save', function setObjectId(next) {
  if (this.parcel_id !== undefined && this.object_id === undefined) {
    this.object_id = this.parcel_id;
  } else if (this.object_id !== undefined && this.parcel_id === undefined) {
    this.parcel_id = this.object_id;
  }
  next();
});

var Response = module.exports = mongoose.model('Response', responseSchema, 'responseCollection');
<commit_msg>we don't use lodash here anymore<commit_after>/*jslint node: true */
'use strict';

var mongoose = require('mongoose');
var util = require('../util');

var responseSchema = new mongoose.Schema({
  // We don't use the native mongo ID when communicating with clients.
  _id: { type: mongoose.Schema.Types.ObjectId, select: false },
  __v: { type: Number, select: false },
  id: String,
  survey: String,
  source: {
    type: { type: String },
    collector: String,
    started: Date,
    finished: Date
  },
  created: Date,
  geo_info: {
    centroid: [Number],
    parcel_id: String,
    points: { type: [], select: false },
    geometry: {
      type: { type: String },
      coordinates: []
    },
    humanReadableName: String
  },
  files: [String],
  parcel_id: String,
  object_id: String,
  responses: {
    type: Object,
    validate: validateResponses
  }
}, {
  autoIndex: false
});

// Indexes

// Ensure we have a geo index on the centroid field.
// We always restrict based on survey ID, so we use a compound index.
responseSchema.index({ 'geo_info.centroid': '2d', survey: 1 });

// Index the survey ID + creation date, which we use to sort
// Descending
responseSchema.index({ survey: 1, created: 1 });
// Ascending
responseSchema.index({ survey: 1, created: -1 });

// Index the survey ID, which we use to look up sets of responses
responseSchema.index({ survey: 1 });

// Index the parcel ID
responseSchema.index({ survey: 1, parcel_id: 1 });

responseSchema.set('toObject', {
  transform: function (doc, ret, options) {
    return {
      id: ret.id,
      survey: ret.survey,
      source: ret.source,
      created: ret.created,
      geo_info: {
        centroid: ret.geo_info.centroid,
        parcel_id: ret.geo_info.parcel_id,
        geometry: ret.geo_info.geometry,
        humanReadableName: ret.geo_info.humanReadableName
      },
      files: ret.files,
      parcel_id: ret.parcel_id,
      object_id: ret.object_id,
      responses: ret.responses
    };
  }
});

responseSchema.pre('save', function parseCentroid(next) {
  // check if there is a centroid. if yes, make sure the values are floats
  // TODO: abstract into a testable function.
  if (this.geo_info !== undefined) {
    var centroid = this.geo_info.centroid;
    if (centroid !== undefined) {
      centroid[0] = parseFloat(centroid[0]);
      centroid[1] = parseFloat(centroid[1]);
    }
  }
  next();
});

function validateResponses (val) {
  return val !== undefined;
}

function simplify(ring) {
  // FIXME: Simplify the ring
  return ring;
}

function collectRingPoints(memo, ring) {
  simplify(ring).forEach(function (point) {
    memo.push(point);
  });
}

function collectPolygonPoints(memo, polygon) {
  polygon.forEach(function (ring) {
    collectRingPoints(memo, ring);
  });
}

function collectMultiPolygonPoints(memo, multiPolygon) {
  multiPolygon.forEach(function (polygon) {
    collectPolygonPoints(memo, polygon);
  });
}

// Collect all of the coordinates into one array, so we can index them.
responseSchema.pre('save', function collectPoints(next) {
  if (this.geometry !== undefined) {
    if (this.geometry.type === 'MultiPolygon') {
      this.geo_info.points = [];
      collectMultiPolygonPoints(this.geo_info.points, this.geo_info.geometry.coordinates);
    } else if (this.geometry.type === 'Polygon') {
      this.geo_info.points = [];
      collectPolygonPoints(this.geo_info.points, this.geo_info.geometry.coordinates);
    } else if (this.geometry.type === 'Point') {
      this.geo_info.points = this.geo_info.geometry.coordinates;
    }
  }
  next();
});

// Set the ID.
responseSchema.pre('save', function setId(next) {
  this.id = util.uuidv1();
  next();
});

// Set the creation date.
responseSchema.pre('save', function setCreated(next) {
  if (this.created === undefined) {
    this.created = new Date();
  }
  next();
});

// Allow either parcel_id or object_id.
// Eventually we'll deprecate parcel_id.
responseSchema.pre('save', function setObjectId(next) {
  if (this.parcel_id !== undefined && this.object_id === undefined) {
    this.object_id = this.parcel_id;
  } else if (this.object_id !== undefined && this.parcel_id === undefined) {
    this.parcel_id = this.object_id;
  }
  next();
});

var Response = module.exports = mongoose.model('Response', responseSchema, 'responseCollection');
<|endoftext|>