<commit_before>'use strict';

let spawn = require('cross-spawn-async'),
  Promise = require('bluebird'),
  log = require('intel'),
  merge = require('lodash.merge');

const defaults = {
  'java': 'java',
  'stdoutLogLevel': log.INFO,
  'stderrLogLevel': log.ERROR,
  'startupCriteria': {
    'success': {
      'stdout': null,
      'stderr': null
    },
    'failure': {
      'stdout': null,
      'stderr': null
    }
  }
};

function launchJar(java, jarPath, args) {
  args = ['-jar', jarPath].concat(args || []);

  log.debug('launching java process with args: %j', args);

  // FIXME should promisify spawn, see https://github.com/petkaantonov/bluebird/blob/master/API.md#option-filter
  return spawn(java, args);
}

function addLogListener(stream, level) {
  stream.on('data', function(data) {
    log.log(level, data.toString());
  });
}

function setupProcessLogging(process, options) {
  if (log.isEnabledFor(options.stdoutLogLevel)) {
    addLogListener(process.stdout, options.stdoutLogLevel);
  }
  if (log.isEnabledFor(options.stderrLogLevel)) {
    addLogListener(process.stderr, options.stderrLogLevel);
  }
}

function hasStartupCriteria(startupCriteria, streamName) {
  let success = startupCriteria.success,
    failure = startupCriteria.failure;
  return success[streamName] || failure[streamName];
}

function getStartupCriteriaListener(startupCriteria, streamName, resolve, reject) {
  let success = startupCriteria.success[streamName];
  let failure = startupCriteria.failure[streamName];

  return function(data) {
    const logLine = data.toString();
    if (logLine.match(success)) {
      return resolve();
    } else if (logLine.match(failure)) {
      return reject(new Error('Process logged: ' + logLine));
    }
  }
}

class JarLauncher {
  constructor(options) {
    this.options = merge({}, defaults, options);
    if (!this.options.jarPath) {
      throw new Error('jarPath must be set!');
    }
  }

  start(args) {
    this.javaProcess = launchJar(this.options.java, this.options.jarPath, args);

    setupProcessLogging(this.javaProcess, this.options);

    let startupCriteria = this.options.startupCriteria;

    if (hasStartupCriteria(startupCriteria, 'stdout') || hasStartupCriteria(startupCriteria, 'stderr')) {
      let javaProcess = this.javaProcess;

      return new Promise(function(resolve, reject) {
        if (hasStartupCriteria(startupCriteria, 'stdout')) {
          javaProcess.stdout
            .on('data', getStartupCriteriaListener(startupCriteria, 'stdout', resolve, reject));
        }
        if (hasStartupCriteria(startupCriteria, 'stderr')) {
          javaProcess.stderr
            .on('data', getStartupCriteriaListener(startupCriteria, 'stderr', resolve, reject));
        }
      });
    } else {
      return Promise.resolve();
    }
  }

  stop() {
    if (this.javaProcess) {
      this.javaProcess.stdout.removeAllListeners('data');
      this.javaProcess.stderr.removeAllListeners('data');

      return new Promise((resolve, reject) => {
        this.javaProcess.once('exit', () => {
          // guard against exit event sent after error event,
          // see https://nodejs.org/api/child_process.html#child_process_event_error
          if (this.javaProcess) {
            this.javaProcess = null;
            resolve();
          }
        }).once('error', (err) => {
          this.javaProcess = null;
          reject(err);
        });

        this.javaProcess.kill('SIGKILL');
      });
    }

    return Promise.resolve();
  }
}

module.exports = JarLauncher;
<commit_msg>Clarify log slightlt when proxy fails<commit_after>'use strict';

let spawn = require('cross-spawn-async'),
  Promise = require('bluebird'),
  log = require('intel'),
  merge = require('lodash.merge');

const defaults = {
  'java': 'java',
  'stdoutLogLevel': log.INFO,
  'stderrLogLevel': log.ERROR,
  'startupCriteria': {
    'success': {
      'stdout': null,
      'stderr': null
    },
    'failure': {
      'stdout': null,
      'stderr': null
    }
  }
};

function launchJar(java, jarPath, args) {
  args = ['-jar', jarPath].concat(args || []);

  log.debug('launching java process with args: %j', args);

  // FIXME should promisify spawn, see https://github.com/petkaantonov/bluebird/blob/master/API.md#option-filter
  return spawn(java, args);
}

function addLogListener(stream, level) {
  stream.on('data', function(data) {
    log.log(level, data.toString());
  });
}

function setupProcessLogging(process, options) {
  if (log.isEnabledFor(options.stdoutLogLevel)) {
    addLogListener(process.stdout, options.stdoutLogLevel);
  }
  if (log.isEnabledFor(options.stderrLogLevel)) {
    addLogListener(process.stderr, options.stderrLogLevel);
  }
}

function hasStartupCriteria(startupCriteria, streamName) {
  let success = startupCriteria.success,
    failure = startupCriteria.failure;
  return success[streamName] || failure[streamName];
}

function getStartupCriteriaListener(startupCriteria, streamName, resolve, reject) {
  let success = startupCriteria.success[streamName];
  let failure = startupCriteria.failure[streamName];

  return function(data) {
    const logLine = data.toString();
    if (logLine.match(success)) {
      return resolve();
    } else if (logLine.match(failure)) {
      return reject(new Error('Java process logged: ' + logLine));
    }
  }
}

class JarLauncher {
  constructor(options) {
    this.options = merge({}, defaults, options);
    if (!this.options.jarPath) {
      throw new Error('jarPath must be set!');
    }
  }

  start(args) {
    this.javaProcess = launchJar(this.options.java, this.options.jarPath, args);

    setupProcessLogging(this.javaProcess, this.options);

    let startupCriteria = this.options.startupCriteria;

    if (hasStartupCriteria(startupCriteria, 'stdout') || hasStartupCriteria(startupCriteria, 'stderr')) {
      let javaProcess = this.javaProcess;

      return new Promise(function(resolve, reject) {
        if (hasStartupCriteria(startupCriteria, 'stdout')) {
          javaProcess.stdout
            .on('data', getStartupCriteriaListener(startupCriteria, 'stdout', resolve, reject));
        }
        if (hasStartupCriteria(startupCriteria, 'stderr')) {
          javaProcess.stderr
            .on('data', getStartupCriteriaListener(startupCriteria, 'stderr', resolve, reject));
        }
      });
    } else {
      return Promise.resolve();
    }
  }

  stop() {
    if (this.javaProcess) {
      this.javaProcess.stdout.removeAllListeners('data');
      this.javaProcess.stderr.removeAllListeners('data');

      return new Promise((resolve, reject) => {
        this.javaProcess.once('exit', () => {
          // guard against exit event sent after error event,
          // see https://nodejs.org/api/child_process.html#child_process_event_error
          if (this.javaProcess) {
            this.javaProcess = null;
            resolve();
          }
        }).once('error', (err) => {
          this.javaProcess = null;
          reject(err);
        });

        this.javaProcess.kill('SIGKILL');
      });
    }

    return Promise.resolve();
  }
}

module.exports = JarLauncher;
<|endoftext|>


<commit_before>// This file defines grunt tasks used by [Grunt.js](http://gruntjs.com/sample-gruntfile)
module.exports = function ( grunt ) {

  // Project configuration
  grunt.initConfig( {

    // Metadata
    pkg: grunt.file.readJSON( "package.json" ),
    banner: "/* ==========================================================\n"
          + " *                  GitGraph v<%= pkg.version %>\n"
          + " *      <%= pkg.repository.url %>\n"
          + " * ==========================================================\n"
          + " * Copyright (c) <%= grunt.template.today('yyyy') %>"
          + " Nicolas CARLO (@nicoespeon) ٩(^‿^)۶\n"
          + " * Copyright (c) <%= grunt.template.today('yyyy') %>"
          + " Fabien BERNARD (@fabien0102) ✌(✰‿✰)✌\n"
          + " *\n"
          + " * GitGraph.js may be freely distributed under the"
          + " <%= pkg.license %> Licence\n"
          + " * ========================================================== */\n",

    // The `clean` task ensures all files are removed from the misc. directories
    // so that no files linger from previous builds.
    clean: {
      dist: [ "dist/" ],
      jsdoc: [ "dist/jsdoc/" ],
      release: [ "build/", "docs/" ]
    },

    // The `concat` task copies the source file into the `build/` directory with
    // the compiled banner for release use.
    concat: {
      options: {
        banner: "<%= banner %>\n"
      },
      dist: {
        src: [ "src/gitgraph.js" ],
        dest: "dist/gitgraph.js"
      },
      release: {
        src: [ "src/gitgraph.js" ],
        dest: "build/gitgraph.js"
      }
    },

    // The `copy` task copies the CSS into the target directory.
    copy: {
      dist: {
        files: [ {
          src: [ "src/gitgraph.css" ],
          dest: "dist/gitgraph.css"
        } ]
      },
      release: {
        files: [ {
          src: [ "src/gitgraph.css" ],
          dest: "build/gitgraph.css"
        } ]
      },
      server: {
        files: [ {
          "dist/server/": "src/*",
          "dist/server/index.html": "examples/index.html",
          "dist/server/index.js": "examples/index.js"
        } ]
      }
    },

    // The `express` task will launch a server for livereload purposes.
    express: {
      server: {
        options: {
          port: 9000,
          hostname: "127.0.0.1",
          bases: [ "dist/server/" ],
          livereload: true
        }
      }
    },

    // The `jsdoc` task will produce the code documentation for the whole project,
    // from the temporary directory.
    jsdoc: {
      dist: {
        src: [ "dist/jsdoc/src/*.js", "README.md" ],
        options: {
          configure: ".jsdocrc",
          destination: "dist/docs"
        }
      },
      release: {
        src: [ "dist/jsdoc/src/*.js", "README.md" ],
        options: {
          configure: ".jsdocrc",
          destination: "docs"
        }
      }
    },

    // The `jasmine` task run unit tests over the source code
    jasmine: {
      gitgraph: {
        src: "src/*.js",
        options: {
          specs: "tests/*.js"
        }
      }
    },

    // The `jshint` task lint all the JavaScript code against best practices.
    // Warnings are here to help us improve code and follow best standards.
    jshint: {
      src: [ "src/*.js" ],
      options: {
        force: true,
        jshintrc: ".jshintrc"
      }
    },

    // The `uglify` task will minified the JavaScript source code for production.
    uglify: {
      options: {
        banner: "<%= banner %>"
      },
      dist: {
        src: [ "src/gitgraph.js" ],
        dest: "dist/gitgraph.min.js",
        options: {
          report: "min"
        }
      },
      release: {
        src: [ "src/gitgraph.js" ],
        dest: "build/gitgraph.min.js",
        options: {
          report: "min"
        }
      }
    },

    // The `open` task will open the livereload page in your favorite browser.
    open: {
      server: {
        path: "http://<%= express.server.options.hostname %>:<%= express.server.options.port %>"
      }
    },
    "string-replace": {
       server: {
         files: {
           "server/index.html": "examples/index.html"
         },
         options: {
           replacements: [
             {
               pattern: "../src/gitgraph.css",
               replacement: "gitgraph.css"
             },
             {
               pattern: "../src/gitgraph.js",
               replacement: "gitgraph.js"
             },
           ]
         }
       },
       jsdoc: {
         files: {
           "temp/": "src/*.js"
          },
          options: {
            replacements: [
              {
                pattern: "(function () {",
                replacement: ""
              },
              {
                pattern: "})();",
                replacement: ""
              },
            ]
          }
        }
      }

  } );

  // Loads grunt tasks from `package.json`
  require( "load-grunt-tasks" )( grunt, [ "grunt-*" ] );

  // `grunt lint` will check code by running JSHint and unit tests over it.
  grunt.registerTask( "lint", [ "jshint", "jasmine" ] );

  // `grunt docs` will create non-versioned documentation for development use.
  grunt.registerTask( "docs", [ "string-replace:jsdoc", "jsdoc:dist", "clean:temp" ] );

  // `grunt dist` will create a non-versioned new release for development use.
  grunt.registerTask( "dist", [
    "clean:dist",
    "lint",
    "copy:dist",
    "uglify:dist",
    "string-replace:jsdoc",
    "jsdoc:dist",
    "clean:temp"
  ] );

  // `grunt release` will create a new release of the source code.
  grunt.registerTask( "release", [
    "lint",
    "copy:release",
    "concat:release",
    "uglify:release",
    "string-replace:jsdoc",
    "jsdoc:release",
    "clean:temp"
  ] );

  // `grunt server` will open a live reload server on your favorite browser
  grunt.registerTask('server', [
    "copy:server",
    "string-replace:server",
    "express:server",
    "open",
    "watch:server"
  ]);
};
<commit_msg>Refactor the string-replace task<commit_after>// This file defines grunt tasks used by [Grunt.js](http://gruntjs.com/sample-gruntfile)
module.exports = function ( grunt ) {

  // Project configuration
  grunt.initConfig( {

    // Metadata
    pkg: grunt.file.readJSON( "package.json" ),
    banner: "/* ==========================================================\n"
          + " *                  GitGraph v<%= pkg.version %>\n"
          + " *      <%= pkg.repository.url %>\n"
          + " * ==========================================================\n"
          + " * Copyright (c) <%= grunt.template.today('yyyy') %>"
          + " Nicolas CARLO (@nicoespeon) ٩(^‿^)۶\n"
          + " * Copyright (c) <%= grunt.template.today('yyyy') %>"
          + " Fabien BERNARD (@fabien0102) ✌(✰‿✰)✌\n"
          + " *\n"
          + " * GitGraph.js may be freely distributed under the"
          + " <%= pkg.license %> Licence\n"
          + " * ========================================================== */\n",

    // The `clean` task ensures all files are removed from the misc. directories
    // so that no files linger from previous builds.
    clean: {
      dist: [ "dist/" ],
      jsdoc: [ "dist/jsdoc/" ],
      release: [ "build/", "docs/" ]
    },

    // The `concat` task copies the source file into the `build/` directory with
    // the compiled banner for release use.
    concat: {
      options: {
        banner: "<%= banner %>\n"
      },
      dist: {
        src: [ "src/gitgraph.js" ],
        dest: "dist/gitgraph.js"
      },
      release: {
        src: [ "src/gitgraph.js" ],
        dest: "build/gitgraph.js"
      }
    },

    // The `copy` task copies the CSS into the target directory.
    copy: {
      dist: {
        files: [ {
          src: [ "src/gitgraph.css" ],
          dest: "dist/gitgraph.css"
        } ]
      },
      release: {
        files: [ {
          src: [ "src/gitgraph.css" ],
          dest: "build/gitgraph.css"
        } ]
      },
      server: {
        files: [ {
          "dist/server/": "src/*",
          "dist/server/index.html": "examples/index.html",
          "dist/server/index.js": "examples/index.js"
        } ]
      }
    },

    // The `express` task will launch a server for livereload purposes.
    express: {
      server: {
        options: {
          port: 9000,
          hostname: "127.0.0.1",
          bases: [ "dist/server/" ],
          livereload: true
        }
      }
    },

    // The `jsdoc` task will produce the code documentation for the whole project,
    // from the temporary directory.
    jsdoc: {
      dist: {
        src: [ "dist/jsdoc/src/*.js", "README.md" ],
        options: {
          configure: ".jsdocrc",
          destination: "dist/docs"
        }
      },
      release: {
        src: [ "dist/jsdoc/src/*.js", "README.md" ],
        options: {
          configure: ".jsdocrc",
          destination: "docs"
        }
      }
    },

    // The `jasmine` task run unit tests over the source code
    jasmine: {
      gitgraph: {
        src: "src/*.js",
        options: {
          specs: "tests/*.js"
        }
      }
    },

    // The `jshint` task lint all the JavaScript code against best practices.
    // Warnings are here to help us improve code and follow best standards.
    jshint: {
      src: [ "src/*.js" ],
      options: {
        force: true,
        jshintrc: ".jshintrc"
      }
    },

    // The `uglify` task will minified the JavaScript source code for production.
    uglify: {
      options: {
        banner: "<%= banner %>"
      },
      dist: {
        src: [ "src/gitgraph.js" ],
        dest: "dist/gitgraph.min.js",
        options: {
          report: "min"
        }
      },
      release: {
        src: [ "src/gitgraph.js" ],
        dest: "build/gitgraph.min.js",
        options: {
          report: "min"
        }
      }
    },

    // The `open` task will open the livereload page in your favorite browser.
    open: {
      server: {
        path: "http://<%= express.server.options.hostname %>:<%= express.server.options.port %>"
      }
    },

    // The `string-replace` task will remove the closure around the source code
    // so we can properly generate the documentation.
    //
    // JSDoc currently doesn't handle properly IIFE for now: [Github issue](https://github.com/jsdoc3/jsdoc/issues/456)
    "string-replace": {
      jsdoc: {
        files: {
          "dist/jsdoc/": "src/*.js"
        },
        options: {
          replacements: [ {
            pattern: "(function () {",
            replacement: ""
          }, {
            pattern: "})();",
            replacement: ""
          } ]
        }
      }

  } );

  // Loads grunt tasks from `package.json`
  require( "load-grunt-tasks" )( grunt, [ "grunt-*" ] );

  // `grunt lint` will check code by running JSHint and unit tests over it.
  grunt.registerTask( "lint", [ "jshint", "jasmine" ] );

  // `grunt docs` will create non-versioned documentation for development use.
  grunt.registerTask( "docs", [ "string-replace:jsdoc", "jsdoc:dist", "clean:temp" ] );

  // `grunt dist` will create a non-versioned new release for development use.
  grunt.registerTask( "dist", [
    "clean:dist",
    "lint",
    "copy:dist",
    "uglify:dist",
    "string-replace:jsdoc",
    "jsdoc:dist",
    "clean:temp"
  ] );

  // `grunt release` will create a new release of the source code.
  grunt.registerTask( "release", [
    "lint",
    "copy:release",
    "concat:release",
    "uglify:release",
    "string-replace:jsdoc",
    "jsdoc:release",
    "clean:temp"
  ] );

  // `grunt server` will open a live reload server on your favorite browser
  grunt.registerTask('server', [
    "copy:server",
    "string-replace:server",
    "express:server",
    "open",
    "watch:server"
  ]);
};
<|endoftext|>


<commit_before>var fs = require('fs');
var path = require('path');
var expect = require('chai').expect;
var engine = require('../')();

var testFile = path.normalize(__dirname + '/data/test.jade');
var malformedFile = path.normalize(__dirname + '/data/malformed.jade');

describe('jade', function() {

  var test;
  var malformed;
  before(function() {
    test = fs.readFileSync(testFile, { encoding: 'utf8' });
    malformed = fs.readFileSync(malformedFile, { encoding: 'utf8' });
  });

  describe('compiler', function() {

    it ('should return error on malformed jade', function(done) {
      engine.compile(malformedFile, malformed, {}, function(err, data) {
        expect(err).to.be.instanceof(Error);
        done();
      });
    });

    it ('should return compiled jade', function(done) {
      engine.compile(testFile, test, {}, function(err, data) {
        expect(err).to.be.null;
        expect(data).to.be.a('string');
        expect(function() {
          var fn = new Function('return ' + data);
          fn()();
        }).not.to.throw(Error);
        done();
      });
    });

  });

  describe('renderer', function() {

    it ('should render html from compiled jade', function(done) {
      engine.compile(testFile, test, {}, function(err, data, files) {
        expect(err).to.be.null;
        expect(data).to.be.a('string');
        expect(files).to.deep.equal([testFile]);
        engine.render(null, data, {}, function(err, data) {
          expect(err).to.be.null;
          expect(data).to.be.equal('
this is jade
');
          done();
        });
      });
    });

  });

});
<commit_msg>Use strict.<commit_after>/*jshint expr: true*/

'use strict';

var fs = require('fs');
var path = require('path');
var expect = require('chai').expect;
var engine = require('../')();

var testFile = path.normalize(__dirname + '/data/test.jade');
var malformedFile = path.normalize(__dirname + '/data/malformed.jade');

describe('jade', function() {

  var test;
  var malformed;
  before(function() {
    test = fs.readFileSync(testFile, { encoding: 'utf8' });
    malformed = fs.readFileSync(malformedFile, { encoding: 'utf8' });
  });

  describe('compiler', function() {

    it ('should return error on malformed jade', function(done) {
      engine.compile(malformedFile, malformed, {}, function(err, data) {
        expect(err).to.be.instanceof(Error);
        done();
      });
    });

    it ('should return compiled jade', function(done) {
      engine.compile(testFile, test, {}, function(err, data) {
        expect(err).to.be.null;
        expect(data).to.be.a('string');
        expect(function() {
          var fn = new Function('return ' + data);
          fn()();
        }).not.to.throw(Error);
        done();
      });
    });

  });

  describe('renderer', function() {

    it ('should render html from compiled jade', function(done) {
      engine.compile(testFile, test, {}, function(err, data, files) {
        expect(err).to.be.null;
        expect(data).to.be.a('string');
        expect(files).to.deep.equal([testFile]);
        engine.render(null, data, {}, function(err, data) {
          expect(err).to.be.null;
          expect(data).to.be.equal('
this is jade
');
          done();
        });
      });
    });

  });

});
<|endoftext|>


<commit_before>var vows = require('vows');
var assert = require('assert');
var dbmeta = require('db-meta');
var dataType = require('../../lib/data_type');
var driver = require('../../lib/driver');

var config = require('../db.config.json').mongodb;

global.migrationTable = 'migrations';

var dbName = config.database;
driver.connect(config, function(err, db) {
  assert.isNull(err);
  vows.describe('mongodb')
  .addBatch({
    'createCollection': {
      topic: function() {
        db.createCollection('event', this.callback);
      },

      teardown: function() {
        db.dropCollection('event', this.callback);
      },

      'has table metadata': {
        topic: function() {
          db._getCollectionNames(this.callback);
        },

        'containing the event table': function(err, tables) {
          assert.equal(tables.length, 2);	// Should be 2 b/c of the system collection
        }
      }
    }
  })
  .addBatch({
    'dropCollection': {
      topic: function() {
        db.createCollection('event', function(err, collection) {
          if(err) {
            return this.callback(err);
          }

          db.dropCollection('event', this.callback);
        }.bind(this));
      },

      'has table metadata': {
        topic: function() {
          db._getCollectionNames(this.callback);
        },

        'containing no tables': function(err, tables) {
          assert.isNotNull(tables);
          assert.equal(tables.length, 1);	// Should be 1 b/c of the system collection
        }
      }
    }
  })
  .addBatch({
    'renameCollection': {
      topic: function() {
        db.createCollection('event', function(err, collection) {
          if(err) {
            return this.callback(err);
          }

          db.renameCollection('event', 'functions', this.callback);
        }.bind(this));
      },

      teardown: function() {
        db.dropCollection('functions', this.callback);
      },

      'has table metadata': {
        topic: function() {
          db._getCollectionNames(this.callback);
        },

        'containing the functions table': function(err, tables) {
          assert.isNotNull(tables);
          assert.equal(tables.length, 2);	// Should be 2 b/c of the system collection
          assert.equal(tables[1].collectionName, 'functions');
        }
      }
    }
  })
  .addBatch({
    'addIndex': {
      topic: function() {
        db.createCollection('event', function(err, collection) {
          if(err) {
            return this.callback(err);
          }

          db.addIndex('event', 'event_title', 'title', false, this.callback);
        }.bind(this));
      },

      teardown: function() {
        db.dropCollection('event', this.callback);
      },

      'preserves case': {
        topic: function() {
          db._getCollectionNames(this.callback);
        },

        'of the functions original table': function(err, tables) {
          assert.isNotNull(tables);
          assert.equal(tables.length, 2);	// Should be 2 b/c of the system collection
          assert.equal(tables[1].collectionName, 'event');
        }
      },

      'has resulting index metadata': {
        topic: function() {
          db._getIndexes('event', this.callback);
        },

        'with additional index': function(err, indexes) {
          assert.isDefined(indexes);
          assert.isNotNull(indexes);
          assert.include(indexes, 'event_title');
        }
      }
    }
  })
  .addBatch({
    'insert': {
      topic: function() {
        db.createCollection('event', function(err, collection) {
          if(err) {
            return this.callback(err);
          }
          db.insert('event', [{id: 2, title: 'title'}], function(err) { console.log(err); this.callback(err);}.bind(this));
        }.bind(this));
      },

      teardown: function() {
        db.dropCollection('event', this.callback);
      },

      'with additional row' : function() {
        db._find('event', {title: 'title'}, function(err, data) {
          if(err) {
            return this.callback(err);
          }

          assert.equal(data.length, 1);
        });
      }
    }
  })
  .addBatch({
    'removeIndex': {
      topic: function() {
        db.createCollection('event', function(err, collection) {
          if(err) {
            return this.callback(err);
          }

          db.addIndex('event', 'event_title', 'title', false, function(err, data) {

            if(err) {
              return this.callback(err);
            }

            db.removeIndex('event', 'event_title', this.callback);
          }.bind(this));
        }.bind(this));
      },

      teardown: function() {
        db.dropCollection('event', this.callback);
      },

      'has resulting index metadata': {
        topic: function() {
          db._getIndexes('event', this.callback);
        },

        'without index': function(err, indexes) {
          if(err) {
            return this.callback(err);
          }

          assert.isDefined(indexes);
          assert.isNotNull(indexes);
          assert.notInclude(indexes, 'event_title');
        }
      }
    }
  })
  .addBatch({
    'createMigrationsTable': {
      topic: function() {
        db._createMigrationsCollection(this.callback);
      },

      teardown: function() {
        db.dropCollection('migrations', this.callback);
      },

      'has migrations table': {
        topic: function() {
          db._getCollectionNames(this.callback);
        },

        'has migrations table' : function(err, tables) {
          assert.isNull(err);
          assert.isNotNull(tables);
          assert.equal(tables.length, 2);	// Should be 2 b/c of the system collection
          assert.equal(tables[1].collectionName, 'migrations');
        }
      }
    }
  })
  .addBatch({
    'removeIndex': {
      topic: function() {
        db.createCollection('event', function(err, collection) {
          if(err) {
            return this.callback(err);
          }

          db.addIndex('event', 'event_title', 'title', false, function(err, data) {

            if(err) {
              return this.callback(err);
            }

            db.removeIndex('event', 'event_title', this.callback);
          }.bind(this));
        }.bind(this));
      },

      teardown: function() {
        db.dropCollection('event', this.callback);
      },

      'has resulting index metadata': {
        topic: function() {
          db._getIndexes('event', this.callback);
        },

        'without index': function(err, indexes) {
          if(err) {
            return this.callback(err);
          }

          assert.isDefined(indexes);
          assert.isNotNull(indexes);
          assert.notInclude(indexes, 'event_title');
        }
      }
    }
  })
  .addBatch({
    'createMigrationsTable': {
      topic: function() {
        db._createMigrationsCollection(this.callback);
      },

      teardown: function() {
        db.dropCollection('migrations', this.callback);
      },

      'has migrations table': {
        topic: function() {
          db._getCollectionNames(this.callback);
        },

        'has migrations table' : function(err, tables) {
          assert.isNull(err);
          assert.isNotNull(tables);
          assert.equal(tables.length, 2);	// Should be 2 b/c of the system collection
          assert.equal(tables[1].collectionName, 'migrations');
        }
      }
    }
  })
 .export(module);
});

<commit_msg>remove debug messages<commit_after>var vows = require('vows');
var assert = require('assert');
var dbmeta = require('db-meta');
var dataType = require('../../lib/data_type');
var driver = require('../../lib/driver');

var config = require('../db.config.json').mongodb;

global.migrationTable = 'migrations';

var dbName = config.database;
driver.connect(config, function(err, db) {
  assert.isNull(err);
  vows.describe('mongodb')
  .addBatch({
    'createCollection': {
      topic: function() {
        db.createCollection('event', this.callback);
      },

      teardown: function() {
        db.dropCollection('event', this.callback);
      },

      'has table metadata': {
        topic: function() {
          db._getCollectionNames(this.callback);
        },

        'containing the event table': function(err, tables) {
          assert.equal(tables.length, 2);	// Should be 2 b/c of the system collection
        }
      }
    }
  })
  .addBatch({
    'dropCollection': {
      topic: function() {
        db.createCollection('event', function(err, collection) {
          if(err) {
            return this.callback(err);
          }

          db.dropCollection('event', this.callback);
        }.bind(this));
      },

      'has table metadata': {
        topic: function() {
          db._getCollectionNames(this.callback);
        },

        'containing no tables': function(err, tables) {
          assert.isNotNull(tables);
          assert.equal(tables.length, 1);	// Should be 1 b/c of the system collection
        }
      }
    }
  })
  .addBatch({
    'renameCollection': {
      topic: function() {
        db.createCollection('event', function(err, collection) {
          if(err) {
            return this.callback(err);
          }

          db.renameCollection('event', 'functions', this.callback);
        }.bind(this));
      },

      teardown: function() {
        db.dropCollection('functions', this.callback);
      },

      'has table metadata': {
        topic: function() {
          db._getCollectionNames(this.callback);
        },

        'containing the functions table': function(err, tables) {
          assert.isNotNull(tables);
          assert.equal(tables.length, 2);	// Should be 2 b/c of the system collection
          assert.equal(tables[1].collectionName, 'functions');
        }
      }
    }
  })
  .addBatch({
    'addIndex': {
      topic: function() {
        db.createCollection('event', function(err, collection) {
          if(err) {
            return this.callback(err);
          }

          db.addIndex('event', 'event_title', 'title', false, this.callback);
        }.bind(this));
      },

      teardown: function() {
        db.dropCollection('event', this.callback);
      },

      'preserves case': {
        topic: function() {
          db._getCollectionNames(this.callback);
        },

        'of the functions original table': function(err, tables) {
          assert.isNotNull(tables);
          assert.equal(tables.length, 2);	// Should be 2 b/c of the system collection
          assert.equal(tables[1].collectionName, 'event');
        }
      },

      'has resulting index metadata': {
        topic: function() {
          db._getIndexes('event', this.callback);
        },

        'with additional index': function(err, indexes) {
          assert.isDefined(indexes);
          assert.isNotNull(indexes);
          assert.include(indexes, 'event_title');
        }
      }
    }
  })
  .addBatch({
    'insert': {
      topic: function() {
        db.createCollection('event', function(err, collection) {
          if(err) {
            return this.callback(err);
          }
          db.insert('event', [{id: 2, title: 'title'}], this.callback);
        }.bind(this));
      },

      teardown: function() {
        db.dropCollection('event', this.callback);
      },

      'with additional row' : function() {
        db._find('event', {title: 'title'}, function(err, data) {
          if(err) {
            return this.callback(err);
          }

          assert.equal(data.length, 1);
        });
      }
    }
  })
  .addBatch({
    'removeIndex': {
      topic: function() {
        db.createCollection('event', function(err, collection) {
          if(err) {
            return this.callback(err);
          }

          db.addIndex('event', 'event_title', 'title', false, function(err, data) {

            if(err) {
              return this.callback(err);
            }

            db.removeIndex('event', 'event_title', this.callback);
          }.bind(this));
        }.bind(this));
      },

      teardown: function() {
        db.dropCollection('event', this.callback);
      },

      'has resulting index metadata': {
        topic: function() {
          db._getIndexes('event', this.callback);
        },

        'without index': function(err, indexes) {
          if(err) {
            return this.callback(err);
          }

          assert.isDefined(indexes);
          assert.isNotNull(indexes);
          assert.notInclude(indexes, 'event_title');
        }
      }
    }
  })
  .addBatch({
    'createMigrationsTable': {
      topic: function() {
        db._createMigrationsCollection(this.callback);
      },

      teardown: function() {
        db.dropCollection('migrations', this.callback);
      },

      'has migrations table': {
        topic: function() {
          db._getCollectionNames(this.callback);
        },

        'has migrations table' : function(err, tables) {
          assert.isNull(err);
          assert.isNotNull(tables);
          assert.equal(tables.length, 2);	// Should be 2 b/c of the system collection
          assert.equal(tables[1].collectionName, 'migrations');
        }
      }
    }
  })
  .addBatch({
    'removeIndex': {
      topic: function() {
        db.createCollection('event', function(err, collection) {
          if(err) {
            return this.callback(err);
          }

          db.addIndex('event', 'event_title', 'title', false, function(err, data) {

            if(err) {
              return this.callback(err);
            }

            db.removeIndex('event', 'event_title', this.callback);
          }.bind(this));
        }.bind(this));
      },

      teardown: function() {
        db.dropCollection('event', this.callback);
      },

      'has resulting index metadata': {
        topic: function() {
          db._getIndexes('event', this.callback);
        },

        'without index': function(err, indexes) {
          if(err) {
            return this.callback(err);
          }

          assert.isDefined(indexes);
          assert.isNotNull(indexes);
          assert.notInclude(indexes, 'event_title');
        }
      }
    }
  })
  .addBatch({
    'createMigrationsTable': {
      topic: function() {
        db._createMigrationsCollection(this.callback);
      },

      teardown: function() {
        db.dropCollection('migrations', this.callback);
      },

      'has migrations table': {
        topic: function() {
          db._getCollectionNames(this.callback);
        },

        'has migrations table' : function(err, tables) {
          assert.isNull(err);
          assert.isNotNull(tables);
          assert.equal(tables.length, 2);	// Should be 2 b/c of the system collection
          assert.equal(tables[1].collectionName, 'migrations');
        }
      }
    }
  })
 .export(module);
});

<|endoftext|>


<commit_before>module.exports = function(grunt) {

  grunt.initConfig({
    concat: {
      norm: {
        src: ['src/valence.js', 'src/*.js'],
        dest: 'build/duedateadjustment.js'
      }
    },
    watch: {
      files: ['src/*.js'],
      tasks: ['w'],
      options: {
        reload: true
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-watch');

  grunt.registerTask('default', ['w', 'watch']);
  grunt.registerTask('w', ['concat']);
};  <commit_msg>update master<commit_after><|endoftext|>


<commit_before>let chai				= require("chai");
let expect				= chai.expect;
let assert				= chai.assert;

const API_KEY = process.env.API_KEY;
const API_SECRET = process.env.API_SECRET;

chai.should();

let PostcodeClient		= require("../lib/postcode");
let JSONRequest			= require("../lib/request");

describe("Postcode.nl API wrapper", () => {
	describe("PostcodeClient", () => {
		describe("#constructor()", () => {
			it("requires 'options.key' and 'options.secret'", () => {
				(() => {
					new PostcodeClient();
				}).should.throw(TypeError);

				(() => {
					new PostcodeClient({});
				}).should.throw(TypeError);

				(() => {
					new PostcodeClient({key: "test"});
				}).should.throw(TypeError);

				(() => {
					new PostcodeClient({secret: "test"});
				}).should.throw(TypeError);

				(() => {
					new PostcodeClient({key: "test", secret: "test"});
				}).should.not.throw(TypeError);
			});

			it("should have an instance of JSONRequest and options", () => {
				var client = new PostcodeClient({key: "test", secret: "test"});
				client._r.should.be.instanceof(JSONRequest);
				client._options.should.be.an("object");
			});
		});

		describe("#address()", () => {
			it("should throw an error on invalid postcodes", () => {
				var client = new PostcodeClient({key: "test", secret: "test"});

				(() => {
					client.address("0000");
				}).should.throw(TypeError);

				(() => {
					client.address("0000AA");
				}).should.throw(TypeError);
			});

			it("should fix simple client errors in postcodes", () => {
				var client = new PostcodeClient({key: "test", secret: "test"});

				(() => {
					client.address("1111    Aa", 1);
				}).should.not.throw(TypeError);
			});

			it("should not accept non-integers or invalid ranges", () => {
				var client = new PostcodeClient({key: "test", secret: "test"});

				(() => {
					client.address("1111AA", -1);
				}).should.throw(TypeError);

				(() => {
					client.address("1111AA", 100000);
				}).should.throw(TypeError);

				(() => {
					client.address("1111AA", 3.14);
				}).should.throw(TypeError);

				(() => {
					client.address("1111AA", "10");
				}).should.throw(TypeError);

				(() => {
					client.address("1111AA", {foo: "bar"});
				}).should.throw(TypeError);

				(() => {
					client.address("1111AA", () => {});
				}).should.throw(TypeError);
			});

			it("should be able to start requesting the address", () => {
                var client = new PostcodeClient({
    				key: API_KEY,
    				secret: API_SECRET
    			});

				(() => {
					client.address("1111AA", 1);
				}).should.not.throw(TypeError);
			});

			it("should be able to return valid address info", (done) => {
				expect(API_KEY).to.be.ok;
				expect(API_SECRET).to.be.ok;

				var client = new PostcodeClient({
					key: API_KEY,
					secret: API_SECRET
				});

				return client.address("1111AA", 1)
					.then((addressDetails) => {
						addressDetails.should.be.an("object");
					})
					.catch((err) => {
						assert(err === undefined, "Bad credentials supplied in environment variables");
						done();
					});
			});
		});

		describe("#signal()", () => {
			expect(API_KEY).to.be.ok;
			expect(API_SECRET).to.be.ok;

			var client = new PostcodeClient({
				key: API_KEY,
				secret: API_SECRET
			});

			it("should error on empty / invalid options object", () => {
				(() => {
					client.signal();
				}).should.throw(TypeError);

				(() => {
					client.signal({});
				}).should.throw(TypeError);
			});

			it("should return a promise on 'valid' options object", () => {
				client.signal({
					test: "test"
				}).should.be.instanceof(Promise);
			});

			it("should be able to generate a response", (done) => {
				return client.signal({
						transaction: {
							deliveryAddress: {
								postcode: "1111AA",
								houseNumber: 1,
								country: "NL"
							}
						}
					})
					.then((signalDetails) => {
						signalDetails.should.be.an("object");
						signalDetails.checkId.should.be.a("string");
					})
					.catch((err) => {
						assert(err === undefined, "Error calling the API: "+err.message);
						done();
					});
			});
		});
	});
});<commit_msg>Fix more whitespace issues<commit_after>let chai				= require("chai");
let expect				= chai.expect;
let assert				= chai.assert;

const API_KEY = process.env.API_KEY;
const API_SECRET = process.env.API_SECRET;

chai.should();

let PostcodeClient		= require("../lib/postcode");
let JSONRequest			= require("../lib/request");

describe("Postcode.nl API wrapper", () => {
	describe("PostcodeClient", () => {
		describe("#constructor()", () => {
			it("requires 'options.key' and 'options.secret'", () => {
				(() => {
					new PostcodeClient();
				}).should.throw(TypeError);

				(() => {
					new PostcodeClient({});
				}).should.throw(TypeError);

				(() => {
					new PostcodeClient({key: "test"});
				}).should.throw(TypeError);

				(() => {
					new PostcodeClient({secret: "test"});
				}).should.throw(TypeError);

				(() => {
					new PostcodeClient({key: "test", secret: "test"});
				}).should.not.throw(TypeError);
			});

			it("should have an instance of JSONRequest and options", () => {
				var client = new PostcodeClient({key: "test", secret: "test"});
				client._r.should.be.instanceof(JSONRequest);
				client._options.should.be.an("object");
			});
		});

		describe("#address()", () => {
			it("should throw an error on invalid postcodes", () => {
				var client = new PostcodeClient({key: "test", secret: "test"});

				(() => {
					client.address("0000");
				}).should.throw(TypeError);

				(() => {
					client.address("0000AA");
				}).should.throw(TypeError);
			});

			it("should fix simple client errors in postcodes", () => {
				var client = new PostcodeClient({key: "test", secret: "test"});

				(() => {
					client.address("1111    Aa", 1);
				}).should.not.throw(TypeError);
			});

			it("should not accept non-integers or invalid ranges", () => {
				var client = new PostcodeClient({key: "test", secret: "test"});

				(() => {
					client.address("1111AA", -1);
				}).should.throw(TypeError);

				(() => {
					client.address("1111AA", 100000);
				}).should.throw(TypeError);

				(() => {
					client.address("1111AA", 3.14);
				}).should.throw(TypeError);

				(() => {
					client.address("1111AA", "10");
				}).should.throw(TypeError);

				(() => {
					client.address("1111AA", {foo: "bar"});
				}).should.throw(TypeError);

				(() => {
					client.address("1111AA", () => {});
				}).should.throw(TypeError);
			});

			it("should be able to start requesting the address", () => {
					var client = new PostcodeClient({
						key: API_KEY,
						secret: API_SECRET
					});

				(() => {
					client.address("1111AA", 1);
				}).should.not.throw(TypeError);
			});

			it("should be able to return valid address info", (done) => {
				expect(API_KEY).to.be.ok;
				expect(API_SECRET).to.be.ok;

				var client = new PostcodeClient({
					key: API_KEY,
					secret: API_SECRET
				});

				return client.address("1111AA", 1)
					.then((addressDetails) => {
						addressDetails.should.be.an("object");
					})
					.catch((err) => {
						assert(err === undefined, "Bad credentials supplied in environment variables");
						done();
					});
			});
		});

		describe("#signal()", () => {
			expect(API_KEY).to.be.ok;
			expect(API_SECRET).to.be.ok;

			var client = new PostcodeClient({
				key: API_KEY,
				secret: API_SECRET
			});

			it("should error on empty / invalid options object", () => {
				(() => {
					client.signal();
				}).should.throw(TypeError);

				(() => {
					client.signal({});
				}).should.throw(TypeError);
			});

			it("should return a promise on 'valid' options object", () => {
				client.signal({
					test: "test"
				}).should.be.instanceof(Promise);
			});

			it("should be able to generate a response", (done) => {
				return client.signal({
						transaction: {
							deliveryAddress: {
								postcode: "1111AA",
								houseNumber: 1,
								country: "NL"
							}
						}
					})
					.then((signalDetails) => {
						signalDetails.should.be.an("object");
						signalDetails.checkId.should.be.a("string");
					})
					.catch((err) => {
						assert(err === undefined, "Error calling the API: "+err.message);
						done();
					});
			});
		});
	});
});<|endoftext|>


<commit_before>goog.provide('OL3PanZoom');

goog.require('OL3ZoomSlider');
goog.require('goog.asserts');
goog.require('goog.events');
goog.require('goog.events.EventType');

/**
 * @constructor
 * @param {olx.control.PanZoomOptions=} opt_options Options.
 * @extends {ol.control.Control}
 * @api
 */
OL3PanZoom = function(opt_options) {

  var options = opt_options || {};

  /**
   * @type {?string}
   * @private
   */
  this.className_ = options.className ? options.className : 'ol-panzoom';

  var element = this.createEl_();

  goog.base(this, {
    element: element,
    target: options.target
  });

  /**
   * @type {Array.<goog.events.Key>}
   * @private
   */
  this.listenerKeys_ = [];

  /**
   * @type {number}
   * @private
   */
  this.duration_ = options.duration !== undefined ? options.duration : 100;

  /**
   * @type {?string}
   * @private
   */
  this.imgPath_ = options.imgPath ? options.imgPath : null;

  /**
   * @type {?ol.Extent}
   * @private
   */
  this.maxExtent_ = options.maxExtent ? options.maxExtent : null;

  /**
   * @type {number}
   * @private
   */
  this.maxZoom_ = options.maxZoom ? options.maxZoom : 19;

  /**
   * @type {number}
   * @private
   */
  this.minZoom_ = options.minZoom ? options.minZoom : 0;

  /**
   * @type {number}
   * @private
   */
  this.pixelDelta_ = options.pixelDelta !== undefined ?
      options.pixelDelta : 128;

  /**
   * @type {boolean}
   * @private
   */
  this.slider_ = options.slider !== undefined ? options.slider : false;

  /**
   * @type {number}
   * @private
   */
  this.zoomDelta_ = options.zoomDelta !== undefined ? options.zoomDelta : 1;

  /**
   * @type {Element}
   * @private
   */
  this.panEastEl_ = this.createButtonEl_('pan-east');

  /**
   * @type {Element}
   * @private
   */
  this.panNorthEl_ = this.createButtonEl_('pan-north');

  /**
   * @type {Element}
   * @private
   */
  this.panSouthEl_ = this.createButtonEl_('pan-south');

  /**
   * @type {Element}
   * @private
   */
  this.panWestEl_ = this.createButtonEl_('pan-west');

  /**
   * @type {Element}
   * @private
   */
  this.zoomInEl_ = this.createButtonEl_('zoom-in');

  /**
   * @type {Element}
   * @private
   */
  this.zoomOutEl_ = this.createButtonEl_('zoom-out');

  /**
   * @type {?Element}
   * @private
   */
  this.zoomMaxEl_ = (!this.slider_ && this.maxExtent_) ?
      this.createButtonEl_('zoom-max') : null;

  /**
   * @type {?OL3ZoomSlider}
   * @private
   */
  this.zoomSliderCtrl_ = (this.slider_) ? new OL3ZoomSlider() : null;

  element.appendChild(this.panNorthEl_);
  element.appendChild(this.panWestEl_);
  element.appendChild(this.panEastEl_);
  element.appendChild(this.panSouthEl_);
  element.appendChild(this.zoomInEl_);
  element.appendChild(this.zoomOutEl_);
  if (this.zoomMaxEl_) {
    element.appendChild(this.zoomMaxEl_);
  }

  /**
   * @type {Element}
   * @private
   */
  this.element_ = element;

};
goog.inherits(OL3PanZoom, ol.control.Control);

/**
 * @api
 */
ol.control.PanZoom = OL3PanZoom;

/**
 * @param {ol.Map} map
 * @api
 */
OL3PanZoom.prototype.setMap = function(map) {

  var keys = this.listenerKeys_;
  var zoomSlider = this.zoomSliderCtrl_;

  var currentMap = this.getMap();
  if (currentMap && currentMap instanceof ol.Map) {
    keys.forEach(ol.Observable.unByKey);
    keys.length = 0;
    if (this.zoomSliderCtrl_) {
      this.zoomSliderCtrl_.setTarget(null);
      window.setTimeout(function() {
        currentMap.removeControl(zoomSlider);
      }, 0);
    }
  }

  goog.base(this, 'setMap', map);

  if (map) {
    keys.push(goog.events.listen(this.panEastEl_, goog.events.EventType.CLICK,
        this.handlePanEastClick_, false, this));
    keys.push(goog.events.listen(this.panNorthEl_, goog.events.EventType.CLICK,
        this.handlePanNorthClick_, false, this));
    keys.push(goog.events.listen(this.panSouthEl_, goog.events.EventType.CLICK,
        this.handlePanSouthClick_, false, this));
    keys.push(goog.events.listen(this.panWestEl_, goog.events.EventType.CLICK,
        this.handlePanWestClick_, false, this));
    keys.push(goog.events.listen(this.zoomInEl_, goog.events.EventType.CLICK,
        this.handleZoomInClick_, false, this));
    keys.push(goog.events.listen(this.zoomOutEl_, goog.events.EventType.CLICK,
        this.handleZoomOutClick_, false, this));
    if (this.maxExtent_ && !this.slider_) {
      keys.push(goog.events.listen(this.zoomMaxEl_, goog.events.EventType.CLICK,
          this.handleZoomMaxClick_, false, this));
    }
    if (this.slider_) {
      zoomSlider.setTarget(this.element_);
      window.setTimeout(function() {
        map.addControl(zoomSlider);
      }, 0);
      this.adjustZoomSlider_();
    }
  }
};

/**
 * @return {Element}
 * @private
 */
OL3PanZoom.prototype.createEl_ = function() {
  var path = this.imgPath_;
  var className = this.className_;
  var cssClasses = [
    className,
    'ol-unselectable',
    'ol-control'
  ].join(' ');

  var element = document.createElement('div');
  element.className = cssClasses;

  if (path) {
    element.style.left = '4px';
    element.style.top = '4px';
  }

  return element;
};

/**
 * @param {string} action
 * @return {Element}
 * @private
 */
OL3PanZoom.prototype.createButtonEl_ = function(action) {
  var divEl = document.createElement('div');
  var path = this.imgPath_;
  var maxExtent = this.maxExtent_;
  var slider = this.slider_;

  if (path) {
    divEl.style.width = '18px';
    divEl.style.height = '18px';
    divEl.style.position = 'absolute';
    divEl.style.cursor = 'pointer';

    var imgEl = document.createElement('img');
    imgEl.style.width = '18px';
    imgEl.style.height = '18px';

    switch (action) {
      case 'pan-east':
        imgEl.id = 'OpenLayers_Control_PanZoom_panright_innerImage';
        imgEl.src = [path, 'east-mini.png'].join('/');
        divEl.id = 'OpenLayers_Control_PanZoom_panright';
        divEl.style.top = '22px';
        divEl.style.left = '22px';
        break;
      case 'pan-north':
        imgEl.id = 'OpenLayers_Control_PanZoom_panup_innerImage';
        imgEl.src = [path, 'north-mini.png'].join('/');
        divEl.id = 'OpenLayers_Control_PanZoom_panup';
        divEl.style.top = '4px';
        divEl.style.left = '13px';
        break;
      case 'pan-south':
        imgEl.id = 'OpenLayers_Control_PanZoom_pandown_innerImage';
        imgEl.src = [path, 'south-mini.png'].join('/');
        divEl.id = 'OpenLayers_Control_PanZoom_pandown';
        divEl.style.top = '40px';
        divEl.style.left = '13px';
        break;
      case 'pan-west':
        imgEl.id = 'OpenLayers_Control_PanZoom_panleft_innerImage';
        imgEl.src = [path, 'west-mini.png'].join('/');
        divEl.id = 'OpenLayers_Control_PanZoom_panleft';
        divEl.style.top = '22px';
        divEl.style.left = '4px';
        break;
      case 'zoom-in':
        imgEl.id = 'OpenLayers_Control_PanZoom_zoomin_innerImage';
        imgEl.src = [path, 'zoom-plus-mini.png'].join('/');
        divEl.id = 'OpenLayers_Control_PanZoom_zoomin';
        divEl.style.top = '63px';
        divEl.style.left = '13px';
        break;
      case 'zoom-out':
        imgEl.id = 'OpenLayers_Control_PanZoom_zoomout_innerImage';
        imgEl.src = [path, 'zoom-minus-mini.png'].join('/');
        divEl.id = 'OpenLayers_Control_PanZoom_zoomout';
        if (slider) {
          divEl.style.top = [this.getSliderSize_() + 81, 'px'].join('');
        } else if (maxExtent) {
          divEl.style.top = '99px';
        } else {
          divEl.style.top = '81px';
        }
        divEl.style.left = '13px';
        break;
      case 'zoom-max':
        imgEl.id = 'OpenLayers_Control_PanZoom_zoomworld_innerImage';
        imgEl.src = [path, 'zoom-world-mini.png'].join('/');
        divEl.id = 'OpenLayers_Control_PanZoom_zoomworld';
        divEl.style.top = '81px';
        divEl.style.left = '13px';
        break;
    }
    divEl.appendChild(imgEl);
  }

  return divEl;
};

/**
 * @param {goog.events.BrowserEvent} evt
 * @return {boolean}
 * @private
 */
OL3PanZoom.prototype.handlePanEastClick_ = function(evt) {
  return this.pan_(evt, 'east');
};

/**
 * @param {goog.events.BrowserEvent} evt
 * @return {boolean}
 * @private
 */
OL3PanZoom.prototype.handlePanNorthClick_ = function(evt) {
  return this.pan_(evt, 'north');
};

/**
 * @param {goog.events.BrowserEvent} evt
 * @return {boolean}
 * @private
 */
OL3PanZoom.prototype.handlePanSouthClick_ = function(evt) {
  return this.pan_(evt, 'south');
};

/**
 * @param {goog.events.BrowserEvent} evt
 * @return {boolean}
 * @private
 */
OL3PanZoom.prototype.handlePanWestClick_ = function(evt) {
  return this.pan_(evt, 'west');
};

/**
 * @param {goog.events.BrowserEvent} evt
 * @private
 */
OL3PanZoom.prototype.handleZoomInClick_ = function(evt) {
  this.zoomByDelta_(this.zoomDelta_);
};

/**
 * @param {goog.events.BrowserEvent} evt
 * @private
 */
OL3PanZoom.prototype.handleZoomOutClick_ = function(evt) {
  this.zoomByDelta_(-this.zoomDelta_);
};

/**
 * @param {goog.events.BrowserEvent} evt
 * @private
 */
OL3PanZoom.prototype.handleZoomMaxClick_ = function(evt) {
  var map = this.getMap();
  var view = map.getView();
  var extent = !this.maxExtent_ ?
      view.getProjection().getExtent() : this.maxExtent_;
  var size = map.getSize();
  goog.asserts.assert(size, 'size should be defined');
  view.fit(extent, size);
};

/**
 * @param {goog.events.BrowserEvent} evt
 * @param {string} direction
 * @return {boolean}
 * @private
 */
OL3PanZoom.prototype.pan_ = function(evt, direction) {
  var stopEvent = false;

  var map = this.getMap();
  goog.asserts.assert(map, 'map must be set');
  var view = map.getView();
  goog.asserts.assert(view, 'map must have view');
  var mapUnitsDelta = view.getResolution() * this.pixelDelta_;
  var deltaX = 0, deltaY = 0;
  if (direction == 'south') {
    deltaY = -mapUnitsDelta;
  } else if (direction == 'west') {
    deltaX = -mapUnitsDelta;
  } else if (direction == 'east') {
    deltaX = mapUnitsDelta;
  } else {
    deltaY = mapUnitsDelta;
  }
  var delta = [deltaX, deltaY];
  ol.coordinate.rotate(delta, view.getRotation());

  // pan
  var currentCenter = view.getCenter();
  if (currentCenter) {
    if (this.duration_ && this.duration_ > 0) {
      map.beforeRender(ol.animation.pan({
        source: currentCenter,
        duration: this.duration_,
        easing: ol.easing.linear
      }));
    }
    var center = view.constrainCenter(
        [currentCenter[0] + delta[0], currentCenter[1] + delta[1]]);
    view.setCenter(center);
  }

  evt.preventDefault();
  stopEvent = true;

  return !stopEvent;
};

/**
 * @param {number} delta Zoom delta.
 * @private
 */
OL3PanZoom.prototype.zoomByDelta_ = function(delta) {
  var map = this.getMap();
  var view = map.getView();
  if (!view) {
    // the map does not have a view, so we can't act
    // upon it
    return;
  }
  var currentResolution = view.getResolution();
  if (currentResolution) {
    if (this.duration_ > 0) {
      map.beforeRender(ol.animation.zoom({
        undefined: null, // ? the compiler complains otherwise
        resolution: currentResolution,
        duration: this.duration_,
        easing: ol.easing.easeOut
      }));
    }
    var newResolution = view.constrainResolution(currentResolution, delta);
    view.setResolution(newResolution);
  }
};

/**
 * @private
 */
OL3PanZoom.prototype.adjustZoomSlider_ = function() {
  var zoomSlider = this.zoomSliderCtrl_;
  var path = this.imgPath_;

  if (!zoomSlider || !path) {
    return;
  }

  var height = [this.getSliderSize_(), 'px'].join('');

  // bar
  var zoomSliderEl = zoomSlider.getElement();
  zoomSliderEl.style.background =
      ['url(', path, '/', 'zoombar.png', ')'].join('');
  zoomSliderEl.style.border = '0';
  zoomSliderEl.style['border-radius'] = '0';
  zoomSliderEl.style.height = height;
  zoomSliderEl.style.left = '13px';
  zoomSliderEl.style.width = '18px';
  zoomSliderEl.style.top = '84px';

  // slider
  var sliderEl = zoomSliderEl.children[0];
  goog.asserts.assertInstanceof(sliderEl, Element);
  sliderEl.style.background = ['url(', path, '/', 'slider.png', ')'].join('');
  sliderEl.style.border = 0;
  sliderEl.style.height = '9px';
  sliderEl.style.margin = '0 -1px';
  sliderEl.style.width = '20px';
};

/**
 * @private
 * @return {number}
 */
OL3PanZoom.prototype.getSliderSize_ = function() {
  return (this.maxZoom_ - this.minZoom_ + 1) * 11;
};
<commit_msg>Fix issue with 'west' and 'north' on dist version<commit_after>goog.provide('OL3PanZoom');

goog.require('OL3ZoomSlider');
goog.require('goog.asserts');
goog.require('goog.events');
goog.require('goog.events.EventType');

/**
 * @constructor
 * @param {olx.control.PanZoomOptions=} opt_options Options.
 * @extends {ol.control.Control}
 * @api
 */
OL3PanZoom = function(opt_options) {

  var options = opt_options || {};

  /**
   * @type {?string}
   * @private
   */
  this.className_ = options.className ? options.className : 'ol-panzoom';

  var element = this.createEl_();

  goog.base(this, {
    element: element,
    target: options.target
  });

  /**
   * @type {Array.<goog.events.Key>}
   * @private
   */
  this.listenerKeys_ = [];

  /**
   * @type {number}
   * @private
   */
  this.duration_ = options.duration !== undefined ? options.duration : 100;

  /**
   * @type {?string}
   * @private
   */
  this.imgPath_ = options.imgPath ? options.imgPath : null;

  /**
   * @type {?ol.Extent}
   * @private
   */
  this.maxExtent_ = options.maxExtent ? options.maxExtent : null;

  /**
   * @type {number}
   * @private
   */
  this.maxZoom_ = options.maxZoom ? options.maxZoom : 19;

  /**
   * @type {number}
   * @private
   */
  this.minZoom_ = options.minZoom ? options.minZoom : 0;

  /**
   * @type {number}
   * @private
   */
  this.pixelDelta_ = options.pixelDelta !== undefined ?
      options.pixelDelta : 128;

  /**
   * @type {boolean}
   * @private
   */
  this.slider_ = options.slider !== undefined ? options.slider : false;

  /**
   * @type {number}
   * @private
   */
  this.zoomDelta_ = options.zoomDelta !== undefined ? options.zoomDelta : 1;

  /**
   * @type {Element}
   * @private
   */
  this.panEastEl_ = this.createButtonEl_('pan-east');

  /**
   * @type {Element}
   * @private
   */
  this.panNorthEl_ = this.createButtonEl_('pan-north');

  /**
   * @type {Element}
   * @private
   */
  this.panSouthEl_ = this.createButtonEl_('pan-south');

  /**
   * @type {Element}
   * @private
   */
  this.panWestEl_ = this.createButtonEl_('pan-west');

  /**
   * @type {Element}
   * @private
   */
  this.zoomInEl_ = this.createButtonEl_('zoom-in');

  /**
   * @type {Element}
   * @private
   */
  this.zoomOutEl_ = this.createButtonEl_('zoom-out');

  /**
   * @type {?Element}
   * @private
   */
  this.zoomMaxEl_ = (!this.slider_ && this.maxExtent_) ?
      this.createButtonEl_('zoom-max') : null;

  /**
   * @type {?OL3ZoomSlider}
   * @private
   */
  this.zoomSliderCtrl_ = (this.slider_) ? new OL3ZoomSlider() : null;

  element.appendChild(this.panNorthEl_);
  element.appendChild(this.panWestEl_);
  element.appendChild(this.panEastEl_);
  element.appendChild(this.panSouthEl_);
  element.appendChild(this.zoomInEl_);
  element.appendChild(this.zoomOutEl_);
  if (this.zoomMaxEl_) {
    element.appendChild(this.zoomMaxEl_);
  }

  /**
   * @type {Element}
   * @private
   */
  this.element_ = element;

};
goog.inherits(OL3PanZoom, ol.control.Control);

/**
 * @api
 */
ol.control.PanZoom = OL3PanZoom;

/**
 * @param {ol.Map} map
 * @api
 */
OL3PanZoom.prototype.setMap = function(map) {

  var keys = this.listenerKeys_;
  var zoomSlider = this.zoomSliderCtrl_;

  var currentMap = this.getMap();
  if (currentMap && currentMap instanceof ol.Map) {
    keys.forEach(ol.Observable.unByKey);
    keys.length = 0;
    if (this.zoomSliderCtrl_) {
      this.zoomSliderCtrl_.setTarget(null);
      window.setTimeout(function() {
        currentMap.removeControl(zoomSlider);
      }, 0);
    }
  }

  goog.base(this, 'setMap', map);

  if (map) {
    keys.push(goog.events.listen(this.panEastEl_, goog.events.EventType.CLICK,
        this.pan_.bind(this, 'east'), false, this));
    keys.push(goog.events.listen(this.panNorthEl_, goog.events.EventType.CLICK,
        this.pan_.bind(this, 'north'), false, this));
    keys.push(goog.events.listen(this.panSouthEl_, goog.events.EventType.CLICK,
        this.pan_.bind(this, 'south'), false, this));
    keys.push(goog.events.listen(this.panWestEl_, goog.events.EventType.CLICK,
        this.pan_.bind(this, 'west'), false, this));
    keys.push(goog.events.listen(this.zoomInEl_, goog.events.EventType.CLICK,
        this.handleZoomInClick_, false, this));
    keys.push(goog.events.listen(this.zoomOutEl_, goog.events.EventType.CLICK,
        this.handleZoomOutClick_, false, this));
    if (this.maxExtent_ && !this.slider_) {
      keys.push(goog.events.listen(this.zoomMaxEl_, goog.events.EventType.CLICK,
          this.handleZoomMaxClick_, false, this));
    }
    if (this.slider_) {
      zoomSlider.setTarget(this.element_);
      window.setTimeout(function() {
        map.addControl(zoomSlider);
      }, 0);
      this.adjustZoomSlider_();
    }
  }
};

/**
 * @return {Element}
 * @private
 */
OL3PanZoom.prototype.createEl_ = function() {
  var path = this.imgPath_;
  var className = this.className_;
  var cssClasses = [
    className,
    'ol-unselectable',
    'ol-control'
  ].join(' ');

  var element = document.createElement('div');
  element.className = cssClasses;

  if (path) {
    element.style.left = '4px';
    element.style.top = '4px';
  }

  return element;
};

/**
 * @param {string} action
 * @return {Element}
 * @private
 */
OL3PanZoom.prototype.createButtonEl_ = function(action) {
  var divEl = document.createElement('div');
  var path = this.imgPath_;
  var maxExtent = this.maxExtent_;
  var slider = this.slider_;

  if (path) {
    divEl.style.width = '18px';
    divEl.style.height = '18px';
    divEl.style.position = 'absolute';
    divEl.style.cursor = 'pointer';

    var imgEl = document.createElement('img');
    imgEl.style.width = '18px';
    imgEl.style.height = '18px';

    switch (action) {
      case 'pan-east':
        imgEl.id = 'OpenLayers_Control_PanZoom_panright_innerImage';
        imgEl.src = [path, 'east-mini.png'].join('/');
        divEl.id = 'OpenLayers_Control_PanZoom_panright';
        divEl.style.top = '22px';
        divEl.style.left = '22px';
        break;
      case 'pan-north':
        imgEl.id = 'OpenLayers_Control_PanZoom_panup_innerImage';
        imgEl.src = [path, 'north-mini.png'].join('/');
        divEl.id = 'OpenLayers_Control_PanZoom_panup';
        divEl.style.top = '4px';
        divEl.style.left = '13px';
        break;
      case 'pan-south':
        imgEl.id = 'OpenLayers_Control_PanZoom_pandown_innerImage';
        imgEl.src = [path, 'south-mini.png'].join('/');
        divEl.id = 'OpenLayers_Control_PanZoom_pandown';
        divEl.style.top = '40px';
        divEl.style.left = '13px';
        break;
      case 'pan-west':
        imgEl.id = 'OpenLayers_Control_PanZoom_panleft_innerImage';
        imgEl.src = [path, 'west-mini.png'].join('/');
        divEl.id = 'OpenLayers_Control_PanZoom_panleft';
        divEl.style.top = '22px';
        divEl.style.left = '4px';
        break;
      case 'zoom-in':
        imgEl.id = 'OpenLayers_Control_PanZoom_zoomin_innerImage';
        imgEl.src = [path, 'zoom-plus-mini.png'].join('/');
        divEl.id = 'OpenLayers_Control_PanZoom_zoomin';
        divEl.style.top = '63px';
        divEl.style.left = '13px';
        break;
      case 'zoom-out':
        imgEl.id = 'OpenLayers_Control_PanZoom_zoomout_innerImage';
        imgEl.src = [path, 'zoom-minus-mini.png'].join('/');
        divEl.id = 'OpenLayers_Control_PanZoom_zoomout';
        if (slider) {
          divEl.style.top = [this.getSliderSize_() + 81, 'px'].join('');
        } else if (maxExtent) {
          divEl.style.top = '99px';
        } else {
          divEl.style.top = '81px';
        }
        divEl.style.left = '13px';
        break;
      case 'zoom-max':
        imgEl.id = 'OpenLayers_Control_PanZoom_zoomworld_innerImage';
        imgEl.src = [path, 'zoom-world-mini.png'].join('/');
        divEl.id = 'OpenLayers_Control_PanZoom_zoomworld';
        divEl.style.top = '81px';
        divEl.style.left = '13px';
        break;
    }
    divEl.appendChild(imgEl);
  }

  return divEl;
};

/**
 * @param {goog.events.BrowserEvent} evt
 * @private
 */
OL3PanZoom.prototype.handleZoomInClick_ = function(evt) {
  this.zoomByDelta_(this.zoomDelta_);
};

/**
 * @param {goog.events.BrowserEvent} evt
 * @private
 */
OL3PanZoom.prototype.handleZoomOutClick_ = function(evt) {
  this.zoomByDelta_(-this.zoomDelta_);
};

/**
 * @param {goog.events.BrowserEvent} evt
 * @private
 */
OL3PanZoom.prototype.handleZoomMaxClick_ = function(evt) {
  var map = this.getMap();
  var view = map.getView();
  var extent = !this.maxExtent_ ?
      view.getProjection().getExtent() : this.maxExtent_;
  var size = map.getSize();
  goog.asserts.assert(size, 'size should be defined');
  view.fit(extent, size);
};

/**
 * @param {string} direction
 * @param {goog.events.BrowserEvent} evt
 * @return {boolean}
 * @private
 */
OL3PanZoom.prototype.pan_ = function(direction, evt) {
  var stopEvent = false;

  var map = this.getMap();
  goog.asserts.assert(map, 'map must be set');
  var view = map.getView();
  goog.asserts.assert(view, 'map must have view');
  var mapUnitsDelta = view.getResolution() * this.pixelDelta_;
  var deltaX = 0, deltaY = 0;
  if (direction == 'south') {
    deltaY = -mapUnitsDelta;
  } else if (direction == 'west') {
    deltaX = -mapUnitsDelta;
  } else if (direction == 'east') {
    deltaX = mapUnitsDelta;
  } else {
    deltaY = mapUnitsDelta;
  }
  var delta = [deltaX, deltaY];
  ol.coordinate.rotate(delta, view.getRotation());

  // pan
  var currentCenter = view.getCenter();
  if (currentCenter) {
    if (this.duration_ && this.duration_ > 0) {
      map.beforeRender(ol.animation.pan({
        source: currentCenter,
        duration: this.duration_,
        easing: ol.easing.linear
      }));
    }
    var center = view.constrainCenter(
        [currentCenter[0] + delta[0], currentCenter[1] + delta[1]]);
    view.setCenter(center);
  }

  evt.preventDefault();
  stopEvent = true;

  return !stopEvent;
};

/**
 * @param {number} delta Zoom delta.
 * @private
 */
OL3PanZoom.prototype.zoomByDelta_ = function(delta) {
  var map = this.getMap();
  var view = map.getView();
  if (!view) {
    // the map does not have a view, so we can't act
    // upon it
    return;
  }
  var currentResolution = view.getResolution();
  if (currentResolution) {
    if (this.duration_ > 0) {
      map.beforeRender(ol.animation.zoom({
        undefined: null, // ? the compiler complains otherwise
        resolution: currentResolution,
        duration: this.duration_,
        easing: ol.easing.easeOut
      }));
    }
    var newResolution = view.constrainResolution(currentResolution, delta);
    view.setResolution(newResolution);
  }
};

/**
 * @private
 */
OL3PanZoom.prototype.adjustZoomSlider_ = function() {
  var zoomSlider = this.zoomSliderCtrl_;
  var path = this.imgPath_;

  if (!zoomSlider || !path) {
    return;
  }

  var height = [this.getSliderSize_(), 'px'].join('');

  // bar
  var zoomSliderEl = zoomSlider.getElement();
  zoomSliderEl.style.background =
      ['url(', path, '/', 'zoombar.png', ')'].join('');
  zoomSliderEl.style.border = '0';
  zoomSliderEl.style['border-radius'] = '0';
  zoomSliderEl.style.height = height;
  zoomSliderEl.style.left = '13px';
  zoomSliderEl.style.width = '18px';
  zoomSliderEl.style.top = '84px';

  // slider
  var sliderEl = zoomSliderEl.children[0];
  goog.asserts.assertInstanceof(sliderEl, Element);
  sliderEl.style.background = ['url(', path, '/', 'slider.png', ')'].join('');
  sliderEl.style.border = 0;
  sliderEl.style.height = '9px';
  sliderEl.style.margin = '0 -1px';
  sliderEl.style.width = '20px';
};

/**
 * @private
 * @return {number}
 */
OL3PanZoom.prototype.getSliderSize_ = function() {
  return (this.maxZoom_ - this.minZoom_ + 1) * 11;
};
<|endoftext|>


<commit_before>const chai = require('chai');
const grandiloquent = require('./../grandiloquent.js');
chai.should();

describe('Pronoun', () => {
  describe('plural to singular', () => {
    it('should convert 3rd person pronoun', () => {
      var pronoun = grandiloquent
        .pronoun('they')
        .toSingular()
        .toString();
      pronoun.should.be.a('string');
      pronoun.should.equal('he');
    });

    it('should convert 3rd person female pronoun', () => {
      var pronoun = grandiloquent
        .pronoun('they')
        .setGender('female')
        .toSingular()
        .toString();
      pronoun.should.be.a('string');
      pronoun.should.equal('she');
    });

    it('should convert 3rd person male or female pronoun', () => {
      var pronoun = grandiloquent
        .pronoun('they')
        .setGender('or')
        .toSingular()
        .toString();
      pronoun.should.be.a('string');
      pronoun.should.equal('he or she');
    });

    it('should convert 3rd person male or female pronoun', () => {
      var pronoun = grandiloquent
        .pronoun('they')
        .setGender('slash')
        .toSingular()
        .toString();
      pronoun.should.be.a('string');
      pronoun.should.equal('he/she');
    });

    it('should convert 1st person pronoun', () => {
      var pronoun = grandiloquent
        .pronoun('we')
        .toSingular()
        .toString();
      pronoun.should.be.a('string');
      pronoun.should.equal('I');
    });

    it('should convert 2nd person pronoun', () => {
      var pronoun = grandiloquent
        .pronoun('you')
        .toSingular()
        .toString();
      pronoun.should.be.a('string');
      pronoun.should.equal('you');
    });
  });

  describe('change person', () => {
    it('should convert to 1st person', () => {
      var pronoun = grandiloquent
        .pronoun('he')
        .toFirstPerson()
        .toString();
      pronoun.should.be.a('string');
      pronoun.should.equal('I');
    });

    it('should convert to 2nd person', () => {
      var pronoun = grandiloquent
        .pronoun('we')
        .toSecondPerson()
        .toString();
      pronoun.should.be.a('string');
      pronoun.should.equal('you');
    });

    it('should convert to 3rd person', () => {
      var pronoun = grandiloquent
        .pronoun('I')
        .setGender('or')
        .toThirdPerson()
        .toString();
      pronoun.should.be.a('string');
      pronoun.should.equal('he or she');
    });
  });
});

describe('Verb', () => {
  describe('base', () => {
    it('should convert singular 3rd person present tense regular verb to base form', () => {
      var verb = grandiloquent
        .verb('walks')
        .toBase()
        .toString();
      verb.should.be.a('string');
      verb.should.equal('walk');
    });

    it('should convert singular 3rd person present tense regular verb to infinitive form', () => {
      var verb = grandiloquent
        .verb('walks')
        .toInfinitive()
        .toString();
      verb.should.be.a('string');
      verb.should.equal('to walk');
    });

    it('should convert base regular verb to present form', () => {
      var verb = grandiloquent
        .verb('walk')
        .toPresent()
        .toString();
      verb.should.be.a('string');
      verb.should.equal('walk');
    });

    it('should convert base regular verb to future form', () => {
      var verb = grandiloquent
        .verb('walk')
        .toFuture()
        .toString();
      verb.should.be.a('string');
      verb.should.equal('will walk');
    });

    it('should convert base regular verb to past form', () => {
      var verb = grandiloquent
        .verb('walk')
        .toPast()
        .toString();
      verb.should.be.a('string');
      verb.should.equal('walked');
    });
  });
});

describe('Sentence', () => {
  describe('init', () => {
    it('should it a sentence without changing it', () => {
      var sentence = grandiloquent
        .sentence('If you wanna be my lover, you gotta get with my friends.')
        .toString();
      sentence.should.be.a('string');
      sentence.should.equal('If you wanna be my lover, you gotta get with my friends.');
    });

    it('should normalize a sentence to prepare for tagging', () => {
      var sentence = grandiloquent
        .sentence('If you wanna be my lover, you gotta get with my friends.');
      sentence.normalized.should.be.a('string');
      sentence.normalized.should.equal('If you want to be my lover , you got to get with my friends . ');
    });
  });

  describe('tokenize', () => {
    it('should split a sentence into words', () => {
      var sentence = grandiloquent
        .sentence('If you wanna be my lover, you gotta get with my friends.');
      sentence.tagged.should.be.an('array');
      sentence.tagged.should.have.lengthOf(16);
    });

    it('should not split proper names', () => {
      var sentence = grandiloquent
        .sentence('Are you the legal guardian of John Connor?');
      sentence.tagged.should.be.an('array');
      sentence.tagged.should.have.lengthOf(8);
      sentence.tagged[6].should.have.property('word', 'John Connor');
      sentence.tagged[6].should.have.deep.property('tags.current', 'NP');
    });
  });

  describe('meta', () => {
    it('should identify a question', () => {
      var sentence = grandiloquent
        .sentence('Are you the legal guardian of John Connor?');
      sentence.isQuestion().should.be.true;
    });

    it('should not falsely identify a question', () => {
      var sentence = grandiloquent
        .sentence('You are the legal guardian of John Connor.');
      sentence.isQuestion().should.be.false;
    });

    it('should identify a subordinate clause', () => {
      var sentence = grandiloquent
        .sentence('I was sleeping when you came home.');
      sentence.hasSubordinateClause().should.be.true;
    });

    it('should identify a subordinate clause at the start of the sentence', () => {
      var sentence = grandiloquent
        .sentence('When you came home, I was sleeping.');
      sentence.hasSubordinateClause().should.be.true;
    });

    it('should identify the main verb', () => {
      var verb = grandiloquent
        .sentence('While you walked to the car, I called Uber to pick me up.')
        .getMainVerb();
      verb.should.be.an.object;
      verb.should.have.property('word', 'called');
    });

    it('should identify the main verb', () => {
      var verb = grandiloquent
        .sentence('I cannot understand why you called Uber to pick me up.')
        .getMainVerb();
      verb.should.be.an.object;
      verb.should.have.property('word', 'understand');
    });

    it('should identify the subject', () => {
      var verb = grandiloquent
        .sentence('I cannot understand why you called Uber to pick me up.')
        .getSubject();
      verb.should.be.an.object;
      verb.should.have.property('word', 'I');
    });

    it('should identify the subject-verb phrase', () => {
      var verb = grandiloquent
        .sentence('I cannot understand why you called Uber to pick me up.')
        .getSubjectVerbPhrase();
      verb.should.be.a.string;
      verb.should.equal('I can not understand');
    });
  });
});
<commit_msg>Change var to let in tests for ES6 consistency<commit_after>const chai = require('chai');
const grandiloquent = require('./../grandiloquent.js');
chai.should();

describe('Pronoun', () => {
  describe('plural to singular', () => {
    it('should convert 3rd person pronoun', () => {
      let pronoun = grandiloquent
        .pronoun('they')
        .toSingular()
        .toString();
      pronoun.should.be.a('string');
      pronoun.should.equal('he');
    });

    it('should convert 3rd person female pronoun', () => {
      let pronoun = grandiloquent
        .pronoun('they')
        .setGender('female')
        .toSingular()
        .toString();
      pronoun.should.be.a('string');
      pronoun.should.equal('she');
    });

    it('should convert 3rd person male or female pronoun', () => {
      let pronoun = grandiloquent
        .pronoun('they')
        .setGender('or')
        .toSingular()
        .toString();
      pronoun.should.be.a('string');
      pronoun.should.equal('he or she');
    });

    it('should convert 3rd person male or female pronoun', () => {
      let pronoun = grandiloquent
        .pronoun('they')
        .setGender('slash')
        .toSingular()
        .toString();
      pronoun.should.be.a('string');
      pronoun.should.equal('he/she');
    });

    it('should convert 1st person pronoun', () => {
      let pronoun = grandiloquent
        .pronoun('we')
        .toSingular()
        .toString();
      pronoun.should.be.a('string');
      pronoun.should.equal('I');
    });

    it('should convert 2nd person pronoun', () => {
      let pronoun = grandiloquent
        .pronoun('you')
        .toSingular()
        .toString();
      pronoun.should.be.a('string');
      pronoun.should.equal('you');
    });
  });

  describe('change person', () => {
    it('should convert to 1st person', () => {
      let pronoun = grandiloquent
        .pronoun('he')
        .toFirstPerson()
        .toString();
      pronoun.should.be.a('string');
      pronoun.should.equal('I');
    });

    it('should convert to 2nd person', () => {
      let pronoun = grandiloquent
        .pronoun('we')
        .toSecondPerson()
        .toString();
      pronoun.should.be.a('string');
      pronoun.should.equal('you');
    });

    it('should convert to 3rd person', () => {
      let pronoun = grandiloquent
        .pronoun('I')
        .setGender('or')
        .toThirdPerson()
        .toString();
      pronoun.should.be.a('string');
      pronoun.should.equal('he or she');
    });
  });
});

describe('Verb', () => {
  describe('base', () => {
    it('should convert singular 3rd person present tense regular verb to base form', () => {
      let verb = grandiloquent
        .verb('walks')
        .toBase()
        .toString();
      verb.should.be.a('string');
      verb.should.equal('walk');
    });

    it('should convert singular 3rd person present tense regular verb to infinitive form', () => {
      let verb = grandiloquent
        .verb('walks')
        .toInfinitive()
        .toString();
      verb.should.be.a('string');
      verb.should.equal('to walk');
    });

    it('should convert base regular verb to present form', () => {
      let verb = grandiloquent
        .verb('walk')
        .toPresent()
        .toString();
      verb.should.be.a('string');
      verb.should.equal('walk');
    });

    it('should convert base regular verb to future form', () => {
      let verb = grandiloquent
        .verb('walk')
        .toFuture()
        .toString();
      verb.should.be.a('string');
      verb.should.equal('will walk');
    });

    it('should convert base regular verb to past form', () => {
      let verb = grandiloquent
        .verb('walk')
        .toPast()
        .toString();
      verb.should.be.a('string');
      verb.should.equal('walked');
    });
  });
});

describe('Sentence', () => {
  describe('init', () => {
    it('should it a sentence without changing it', () => {
      let sentence = grandiloquent
        .sentence('If you wanna be my lover, you gotta get with my friends.')
        .toString();
      sentence.should.be.a('string');
      sentence.should.equal('If you wanna be my lover, you gotta get with my friends.');
    });

    it('should normalize a sentence to prepare for tagging', () => {
      let sentence = grandiloquent
        .sentence('If you wanna be my lover, you gotta get with my friends.');
      sentence.normalized.should.be.a('string');
      sentence.normalized.should.equal('If you want to be my lover , you got to get with my friends . ');
    });
  });

  describe('tokenize', () => {
    it('should split a sentence into words', () => {
      let sentence = grandiloquent
        .sentence('If you wanna be my lover, you gotta get with my friends.');
      sentence.tagged.should.be.an('array');
      sentence.tagged.should.have.lengthOf(16);
    });

    it('should not split proper names', () => {
      let sentence = grandiloquent
        .sentence('Are you the legal guardian of John Connor?');
      sentence.tagged.should.be.an('array');
      sentence.tagged.should.have.lengthOf(8);
      sentence.tagged[6].should.have.property('word', 'John Connor');
      sentence.tagged[6].should.have.deep.property('tags.current', 'NP');
    });
  });

  describe('meta', () => {
    it('should identify a question', () => {
      let sentence = grandiloquent
        .sentence('Are you the legal guardian of John Connor?');
      sentence.isQuestion().should.be.true;
    });

    it('should not falsely identify a question', () => {
      let sentence = grandiloquent
        .sentence('You are the legal guardian of John Connor.');
      sentence.isQuestion().should.be.false;
    });

    it('should identify a subordinate clause', () => {
      let sentence = grandiloquent
        .sentence('I was sleeping when you came home.');
      sentence.hasSubordinateClause().should.be.true;
    });

    it('should identify a subordinate clause at the start of the sentence', () => {
      let sentence = grandiloquent
        .sentence('When you came home, I was sleeping.');
      sentence.hasSubordinateClause().should.be.true;
    });

    it('should identify the main verb', () => {
      let verb = grandiloquent
        .sentence('While you walked to the car, I called Uber to pick me up.')
        .getMainVerb();
      verb.should.be.an.object;
      verb.should.have.property('word', 'called');
    });

    it('should identify the main verb', () => {
      let verb = grandiloquent
        .sentence('I cannot understand why you called Uber to pick me up.')
        .getMainVerb();
      verb.should.be.an.object;
      verb.should.have.property('word', 'understand');
    });

    it('should identify the subject', () => {
      let verb = grandiloquent
        .sentence('I cannot understand why you called Uber to pick me up.')
        .getSubject();
      verb.should.be.an.object;
      verb.should.have.property('word', 'I');
    });

    it('should identify the subject-verb phrase', () => {
      let verb = grandiloquent
        .sentence('I cannot understand why you called Uber to pick me up.')
        .getSubjectVerbPhrase();
      verb.should.be.a.string;
      verb.should.equal('I can not understand');
    });
  });
});
<|endoftext|>


<commit_before>// some packages, plugins, and presets referenced/required in this webpack
// config are deps of embark and will be transitive dapp deps unless specified
// in the dapp's own package.json

// embark modifies process.env.NODE_PATH so that when running dapp scripts in
// embark's child processes, embark's own node_modules directory will be
// searched by node's require(); however, webpack and babel do not directly
// support NODE_PATH, so modules such as babel plugins and presets must be
// resolved with require.resolve(); that is only necessary if a plugin/preset
// is in embark's node_modules vs. the dapp's node_modules

const cloneDeep = require('lodash.clonedeep');
// const CompressionPlugin = require('compression-webpack-plugin');
const glob = require('glob');
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
const path = require('path');

const dappPath = process.env.DAPP_PATH;
const embarkPath = process.env.EMBARK_PATH;

const embarkAliases = require(path.join(dappPath, '.embark/embark-aliases.json'));
const embarkAssets = require(path.join(dappPath, '.embark/embark-assets.json'));
const embarkNodeModules = path.join(embarkPath, 'node_modules');
const embarkJson = require(path.join(dappPath, 'embark.json'));

const buildDir = path.join(dappPath, embarkJson.buildDir);

// it's important to `embark reset` if a pkg version is specified in
// embark.json and changed/removed later, otherwise pkg resolution may behave
// unexpectedly
let versions;
try {
  versions = glob.sync(path.join(dappPath, '.embark/versions/*/*'));
} catch (e) {
  versions = [];
}

const entry = Object.keys(embarkAssets)
  .filter(key => key.match(/\.js$/))
  .reduce((obj, key) => {
    // webpack entry paths should start with './' if they're relative to the
    // webpack context; embark.json "app" keys correspond to lists of .js
    // source paths relative to the top-level dapp dir and may be missing the
    // leading './'
    obj[key] = embarkAssets[key]
      .map(file => {
        let file_path = file.path;
        if (!file.path.match(/^\.\//)) {
          file_path = './' + file_path;
        }
        return file_path;
      });
    return obj;
  }, {});

function resolve(pkgName) {
  if (Array.isArray(pkgName)) {
    const _pkgName = pkgName[0];
    pkgName[0] = require.resolve(_pkgName);
    return pkgName;
  }
  return require.resolve(pkgName);
}

// base config
// -----------------------------------------------------------------------------

const base = {
  context: dappPath,
  entry: entry,
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [{loader: 'style-loader'}, {loader: 'css-loader'}]
      },
      {
        test: /\.scss$/,
        use: [{loader: 'style-loader'}, {loader: 'css-loader'}]
      },
      {
        test: /\.(png|woff|woff2|eot|ttf|svg)$/,
        loader: 'url-loader?limit=100000'
      },
      {
        test: /\.jsx?$/,
        loader: 'babel-loader',
        exclude: /(node_modules|bower_components|\.embark[\\/]versions)/,
        options: {
          plugins: [
            [
              'babel-plugin-module-resolver', {
                'alias': embarkAliases
              }
            ],
            [
              '@babel/plugin-transform-runtime', {
                corejs: 2,
                useESModules: true
              }
            ]
          ].map(resolve),
          presets: [
            [
              '@babel/preset-env', {
                modules: false,
                targets: {
                  browsers: ['last 1 version', 'not dead', '> 0.2%']
                }
              }
            ],
            '@babel/preset-react'
          ].map(resolve)
        }
      }
    ]
  },
  output: {
    filename: (chunkData) => chunkData.chunk.name,
    // globalObject workaround for node-compatible UMD builds with webpack 4
    // see: https://github.com/webpack/webpack/issues/6522#issuecomment-371120689
    globalObject: 'typeof self !== \'undefined\' ? self : this',
    libraryTarget: 'umd',
    path: buildDir
  },
  plugins: [new HardSourceWebpackPlugin()],
  // profiling and generating verbose stats increases build time; if stats
  // are generated embark will write the output to:
  //   path.join(dappPath, '.embark/stats.[json,report]')
  // to visualize the stats info in a browser run:
  //   npx webpack-bundle-analyzer .embark/stats.json <buildDir>
  profile: true, stats: 'verbose',
  resolve: {
    alias: embarkAliases,
    modules: [
      ...versions,
      'node_modules',
      embarkNodeModules
    ]
  },
  resolveLoader: {
    modules: [
      'node_modules',
      embarkNodeModules
    ]
  }
};

// development config
// -----------------------------------------------------------------------------

const development = cloneDeep(base);
// full source maps increase build time but are useful during dapp development
development.devtool = 'source-map';
development.mode = 'development';
// alternatively:
// development.mode = 'none';
development.name = 'development';
const devBabelLoader = development.module.rules[3];
devBabelLoader.options.compact = false;

// production config
// -----------------------------------------------------------------------------

const production = cloneDeep(base);
production.mode = 'production';
production.name = 'production';
// compression of webpack's JS output not enabled by default
// production.plugins.push(new CompressionPlugin());

// export a list of named configs
// -----------------------------------------------------------------------------

module.exports = [
  development,
  production
];
<commit_msg>explain babel plugin, preset order<commit_after>// some packages, plugins, and presets referenced/required in this webpack
// config are deps of embark and will be transitive dapp deps unless specified
// in the dapp's own package.json

// embark modifies process.env.NODE_PATH so that when running dapp scripts in
// embark's child processes, embark's own node_modules directory will be
// searched by node's require(); however, webpack and babel do not directly
// support NODE_PATH, so modules such as babel plugins and presets must be
// resolved with require.resolve(); that is only necessary if a plugin/preset
// is in embark's node_modules vs. the dapp's node_modules

const cloneDeep = require('lodash.clonedeep');
// const CompressionPlugin = require('compression-webpack-plugin');
const glob = require('glob');
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
const path = require('path');

const dappPath = process.env.DAPP_PATH;
const embarkPath = process.env.EMBARK_PATH;

const embarkAliases = require(path.join(dappPath, '.embark/embark-aliases.json'));
const embarkAssets = require(path.join(dappPath, '.embark/embark-assets.json'));
const embarkNodeModules = path.join(embarkPath, 'node_modules');
const embarkJson = require(path.join(dappPath, 'embark.json'));

const buildDir = path.join(dappPath, embarkJson.buildDir);

// it's important to `embark reset` if a pkg version is specified in
// embark.json and changed/removed later, otherwise pkg resolution may behave
// unexpectedly
let versions;
try {
  versions = glob.sync(path.join(dappPath, '.embark/versions/*/*'));
} catch (e) {
  versions = [];
}

const entry = Object.keys(embarkAssets)
  .filter(key => key.match(/\.js$/))
  .reduce((obj, key) => {
    // webpack entry paths should start with './' if they're relative to the
    // webpack context; embark.json "app" keys correspond to lists of .js
    // source paths relative to the top-level dapp dir and may be missing the
    // leading './'
    obj[key] = embarkAssets[key]
      .map(file => {
        let file_path = file.path;
        if (!file.path.match(/^\.\//)) {
          file_path = './' + file_path;
        }
        return file_path;
      });
    return obj;
  }, {});

function resolve(pkgName) {
  if (Array.isArray(pkgName)) {
    const _pkgName = pkgName[0];
    pkgName[0] = require.resolve(_pkgName);
    return pkgName;
  }
  return require.resolve(pkgName);
}

// base config
// -----------------------------------------------------------------------------

// + Plugins run before Presets.
// + Plugin ordering is first to last.
// + Preset ordering is reversed (last to first).
// see: https://babeljs.io/docs/en/plugins#plugin-ordering

const base = {
  context: dappPath,
  entry: entry,
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [{loader: 'style-loader'}, {loader: 'css-loader'}]
      },
      {
        test: /\.scss$/,
        use: [{loader: 'style-loader'}, {loader: 'css-loader'}]
      },
      {
        test: /\.(png|woff|woff2|eot|ttf|svg)$/,
        loader: 'url-loader?limit=100000'
      },
      {
        test: /\.jsx?$/,
        loader: 'babel-loader',
        exclude: /(node_modules|bower_components|\.embark[\\/]versions)/,
        options: {
          plugins: [
            [
              'babel-plugin-module-resolver', {
                'alias': embarkAliases
              }
            ],
            [
              '@babel/plugin-transform-runtime', {
                corejs: 2,
                useESModules: true
              }
            ]
          ].map(resolve),
          presets: [
            [
              '@babel/preset-env', {
                modules: false,
                targets: {
                  browsers: ['last 1 version', 'not dead', '> 0.2%']
                }
              }
            ],
            '@babel/preset-react'
          ].map(resolve)
        }
      }
    ]
  },
  output: {
    filename: (chunkData) => chunkData.chunk.name,
    // globalObject workaround for node-compatible UMD builds with webpack 4
    // see: https://github.com/webpack/webpack/issues/6522#issuecomment-371120689
    globalObject: 'typeof self !== \'undefined\' ? self : this',
    libraryTarget: 'umd',
    path: buildDir
  },
  plugins: [new HardSourceWebpackPlugin()],
  // profiling and generating verbose stats increases build time; if stats
  // are generated embark will write the output to:
  //   path.join(dappPath, '.embark/stats.[json,report]')
  // to visualize the stats info in a browser run:
  //   npx webpack-bundle-analyzer .embark/stats.json <buildDir>
  profile: true, stats: 'verbose',
  resolve: {
    alias: embarkAliases,
    modules: [
      ...versions,
      'node_modules',
      embarkNodeModules
    ]
  },
  resolveLoader: {
    modules: [
      'node_modules',
      embarkNodeModules
    ]
  }
};

// development config
// -----------------------------------------------------------------------------

const development = cloneDeep(base);
// full source maps increase build time but are useful during dapp development
development.devtool = 'source-map';
development.mode = 'development';
// alternatively:
// development.mode = 'none';
development.name = 'development';
const devBabelLoader = development.module.rules[3];
devBabelLoader.options.compact = false;

// production config
// -----------------------------------------------------------------------------

const production = cloneDeep(base);
production.mode = 'production';
production.name = 'production';
// compression of webpack's JS output not enabled by default
// production.plugins.push(new CompressionPlugin());

// export a list of named configs
// -----------------------------------------------------------------------------

module.exports = [
  development,
  production
];
<|endoftext|>


<commit_before>module.exports = function (grunt) {

    // Project configuration.
    grunt.initConfig({

      pkg: grunt.file.readJSON('package.json'),

      simplemocha: {
          options: {
              ui: 'exports'
          },
          unit: {
              src: ['test/unit/example.js']
          }
      },

      mocha_browser: {
          all: {options: {urls: ['http://localhost:<%= connect.options.port %>']}}
      },

      shell: {
        npmLink: {
          command: 'npm link && npm link hoodie-plugin-template'
        },
        npmUnlink: {
          command: 'npm unlink && npm unlink hoodie-plugin-template'
        },
        installPlugin: {
          command: 'hoodie install template'
        },
        removePlugin: {
          command: 'hoodie uninstall template'
        }
      },

      hoodie: {
        start: {
          options: {
            www: 'test/browser',
            callback: function (config) {
              grunt.config.set('connect.options.port', config.stack.www.port);
            }
          }
        }
      }

    });

    grunt.loadNpmTasks('grunt-mocha-browser');
    grunt.loadNpmTasks('grunt-continue');
    grunt.loadNpmTasks('grunt-hoodie');
    grunt.loadNpmTasks('grunt-simple-mocha');
    grunt.loadNpmTasks('grunt-shell');

    grunt.registerTask('default', []);
    grunt.registerTask('test', [
        'simplemocha:unit',
        'shell:npmLink',
        'shell:installPlugin',
        'hoodie',
        'continueOn',
        'mocha_browser:all',
        'continueOff',
        'hoodie_stop',
        'shell:npmUnlink',
        'shell:removePlugin'
    ]);

};
<commit_msg>re-indent gruntfile<commit_after>module.exports = function (grunt) {

  // Project configuration.
  grunt.initConfig({

    pkg: grunt.file.readJSON('package.json'),

    simplemocha: {
      options: {
        ui: 'exports'
      },
      unit: {
        src: ['test/unit/example.js']
      }
    },

    mocha_browser: {
      all: {options: {urls: ['http://localhost:<%= connect.options.port %>']}}
    },

    shell: {
      npmLink: {
        command: 'npm link && npm link hoodie-plugin-template'
      },
      npmUnlink: {
        command: 'npm unlink && npm unlink hoodie-plugin-template'
      },
      installPlugin: {
        command: 'hoodie install template'
      },
      removePlugin: {
        command: 'hoodie uninstall template'
      }
    },

    hoodie: {
      start: {
        options: {
          www: 'test/browser',
          callback: function (config) {
            grunt.config.set('connect.options.port', config.stack.www.port);
          }
        }
      }
    }

  });

  grunt.loadNpmTasks('grunt-mocha-browser');
  grunt.loadNpmTasks('grunt-continue');
  grunt.loadNpmTasks('grunt-hoodie');
  grunt.loadNpmTasks('grunt-simple-mocha');
  grunt.loadNpmTasks('grunt-shell');

  grunt.registerTask('default', []);
  grunt.registerTask('test', [
    'simplemocha:unit',
    'shell:npmLink',
    'shell:installPlugin',
    'hoodie',
    'continueOn',
    'mocha_browser:all',
    'continueOff',
    'hoodie_stop',
    'shell:npmUnlink',
    'shell:removePlugin'
  ]);

};
<|endoftext|>