<commit_before>var assert = require ('assert');
var path = require ('path');
var rm = require ('rimraf');
var fs = require ('fs');
var async = require('async');
var proxyquire =  require('proxyquire');
var commands = proxyquire('../lib/cli/commands', {
    './commands-logic': {
        'generate' : function(projectDir, defaultPackage, itemType, itemName, callback){
          callback(null);
        },
        'newProject' : function(srcDir, destDir, callback){
          callback(null);
        }
    }
});

describe ('cli commands', function(){

  require('./includes/startup');

  var temp_folder = "test/tmp";
  var packagesLocalFolder = path.join(process.cwd(), "/test/fixtures/packages");

  //make sure temp folder is deleted even if tests fail (before and after)
  beforeEach(function(done){
    rm(temp_folder, function(){
      fs.mkdir(temp_folder, done);
    });
  });

  afterEach(function(done){
    rm(temp_folder, done);
  });

  describe ('generate', function(){

    it('should exit with errors if no args are passed', function(done){
      var args = [];
      commands.generate.run(args, function(err) {
        assert.ok(err);
        done();
      });
    });

    it('should exit with errors if only element type is passed', function(done){
      var args = ['job'];
      commands.generate.run(args, function(err) {
        assert.ok(err);
        done();
      });
    });

    it('should not exit with errors if correct arguments are passed', function(done){
      var args = ['job', 'test'];
      commands.generate.run(args, function(err) {
        assert.ok(!err, err);
        done();
      });
    });

  });

  describe ('new', function(){

    it('should exit with errors if bad arguments are passed', function(done){
      var args = [];
      commands.new.run(args, function(err) {
        assert.ok(err);
        done();
      });
    });

  });
});<commit_msg>Add more test asserting that the logic module is called with the right parameters<commit_after>var assert = require ('assert');
var path = require ('path');
var rm = require ('rimraf');
var fs = require ('fs');
var async = require('async');
var proxyquire =  require('proxyquire');

var commands;

describe ('cli commands', function(){

  require('./includes/startup');

  var temp_folder = "test/tmp";
  var packagesLocalFolder = path.join(process.cwd(), "/test/fixtures/packages");

  //make sure temp folder is deleted even if tests fail (before and after)
  beforeEach(function(done){
    commands = proxyquire('../lib/cli/commands', {
      './commands-logic': {
          'generate' : function(projectDir, defaultPackage, itemType, itemName, callback){
            callback(null);
          }
      }
    });

    rm(temp_folder, function(){
      fs.mkdir(temp_folder, done);
    });
  });

  afterEach(function(done){
    rm(temp_folder, done);
  });

  describe ('generate', function(){

    it('should exit with errors if no args are passed', function(done){
      var args = [];
      commands.generate.run(args, function(err) {
        assert.ok(err);
        done();
      });
    });

    it('should exit with errors if only element type is passed', function(done){
      var args = ['job'];
      commands.generate.run(args, function(err) {
        assert.ok(err);
        done();
      });
    });

    it('should not exit with errors if correct arguments are passed', function(done){
      var args = ['job', 'test'];
      commands.generate.run(args, function(err) {
        assert.ok(!err, err);
        done();
      });
    });

    it('should pass the right parameters to the logic module', function(done){
      var args = ['job', 'test'];
      commands = proxyquire('../lib/cli/commands', {
        './commands-logic': {
            'generate' : function(projectDir, defaultPackage, itemType, itemName, callback){
              assert.equal(defaultPackage, 'default');
              assert.equal(itemType, 'job');
              assert.equal(itemName, 'test');
              callback(null);
            }
        }
      });

      commands.generate.run(args, function(err) {
        assert.ok(!err, err);
        done();
      });
    });

    it('should pass the right parameters to the logic module when item includes package', function(done){
      var args = ['job', 'mypackage#test'];
      commands = proxyquire('../lib/cli/commands', {
        './commands-logic': {
            'generate' : function(projectDir, defaultPackage, itemType, itemName, callback){
              assert.equal(defaultPackage, 'mypackage');
              assert.equal(itemType, 'job');
              assert.equal(itemName, 'test');
              callback(null);
            }
        }
      });

      commands.generate.run(args, function(err) {
        assert.ok(!err, err);
        done();
      });
    });

  });

  describe ('new', function(){

    it('should exit with errors if bad arguments are passed', function(done){
      var args = [];
      commands.new.run(args, function(err) {
        assert.ok(err);
        done();
      });
    });

    it('should pass the right parameters to the logic module when item includes package', function(done){
      var args = ['mywallboard'];
      commands = proxyquire('../lib/cli/commands', {
        './commands-logic': {
            'newProject' : function(srcDir, destDir, callback){
              assert.equal(destDir.length - destDir.lastIndexOf('mywallboard'), 11);
              callback('error so we can interrupt execution and assert just for valid parameters');
            }
        }
      });

      commands.new.run(args, function(err) {
        assert.ok(err, err);
        done();
      });
    });

  });
});<|endoftext|>


<commit_before>// Copyright (C) 2014 Erik Ringsmuth - MIT license
'use strict';
var chai    = require('chai'),
    sinon   = require('sinon'),
    config  = require('../routes/config'),
    expect  = chai.expect;

// configure chai
// jshint expr:true
chai.use(require('sinon-chai'));

describe('config(req, res)', function () {
  it('should render the config view and pass it the session state', function() {
    // arrange
    var req = {
      session_state: { signedIn: true }
    };
    var res = {
      render: sinon.stub()
    };

    // act
    config(req, res);

    // assert
    expect(res.render).to.have.been.calledWith('config', req.session_state);
  });
});
<commit_msg>fixing config content-type<commit_after>// Copyright (C) 2014 Erik Ringsmuth - MIT license
'use strict';
var chai    = require('chai'),
    sinon   = require('sinon'),
    config  = require('../routes/config'),
    expect  = chai.expect;

// configure chai
// jshint expr:true
chai.use(require('sinon-chai'));

describe('config(req, res)', function () {
  it('should render the config view and pass it the session state', function() {
    // arrange
    var req = {
      session_state: { signedIn: true }
    };
    var res = {
      type: sinon.stub(),
      render: sinon.stub()
    };

    // act
    config(req, res);

    // assert
    expect(res.type).to.have.been.calledWith('application/javascript');
    expect(res.render).to.have.been.calledWith('config', req.session_state);
  });
});
<|endoftext|>


<commit_before>var thru = require('through2'),
    mail = require('mailgun-send');

exports.config = function (opts) { mail.config(opts) }
exports.send = function (obj) {
  console.log('inside',obj)
  var stream = thru.obj(transform, flush);
  if (obj) stream.write(obj);
  return stream;
}

function transform (obj, encoding, callback) {
  if (typeof obj != 'object') return callback("Expecting object, but got " + typeof obj);
  mail.send(obj, callback);
  this.push(obj);
}

function flush (callback) {
  callback();
}
<commit_msg>removed debug<commit_after>var thru = require('through2'),
    mail = require('mailgun-send');

exports.config = function (opts) { mail.config(opts) }
exports.send = function (obj) {
  var stream = thru.obj(transform, flush);
  if (obj) stream.write(obj);
  return stream;
}

function transform (obj, encoding, callback) {
  if (typeof obj != 'object') return callback("Expecting object, but got " + typeof obj);
  mail.send(obj, callback);
  this.push(obj);
}

function flush (callback) {
  callback();
}
<|endoftext|>


<commit_before>var assert = require('assert'),
    HeaderParser = require('../lib/HeaderParser');

var DCRLF = '\r\n\r\n';

var MAXED_BUFFER = new Buffer(128 * 1024);
MAXED_BUFFER.fill(0x41); // 'A'

[
  { source: DCRLF,
    expected: {},
    what: 'No header'
  },
  { source: ['Content-Type:\t  text/plain',
             'Content-Length:0'
            ].join('\r\n') + DCRLF,
    expected: {'content-type': ['  text/plain'], 'content-length': ['0']},
    what: 'Value spacing'
  },
  { source: ['Content-Type:\r\n text/plain',
             'Foo:\r\n bar\r\n baz',
            ].join('\r\n') + DCRLF,
    expected: {'content-type': [' text/plain'], 'foo': [' bar baz']},
    what: 'Folded values'
  },
  { source: ['Content-Type:',
             'Foo: ',
            ].join('\r\n') + DCRLF,
    expected: {'content-type': [''], 'foo': ['']},
    what: 'Empty values'
  },
  { source: MAXED_BUFFER.toString('ascii') + DCRLF,
    expected: {},
    what: 'Max header size (single chunk)'
  },
  { source: ['ABCDEFGHIJ', MAXED_BUFFER.toString('ascii'), DCRLF],
    expected: {},
    what: 'Max header size (multiple chunks #1)'
  },
  { source: [MAXED_BUFFER.toString('ascii'), MAXED_BUFFER.toString('ascii'), DCRLF],
    expected: {},
    what: 'Max header size (multiple chunk #2)'
  },
].forEach(function(v) {
  var parser = new HeaderParser(), fired = false;
  var errPrefix = '[' + v.what + ']: ';
  parser.on('header', function(header) {
    assert(!fired, errPrefix + 'Header event fired more than once');
    fired = true;
    assert.deepEqual(header, v.expected, errPrefix + 'Parsed result mismatch');
  });
  if (!Array.isArray(v.source))
    v.source = [v.source];
  v.source.forEach(function(s) {
    parser.push(s);
  });
  assert(fired, errPrefix + 'Did not receive header from parser');
});<commit_msg>test: update error displays<commit_after>var assert = require('assert'),
    path = require('path');

var HeaderParser = require('../lib/HeaderParser');

var DCRLF = '\r\n\r\n',
    MAXED_BUFFER = new Buffer(128 * 1024);
MAXED_BUFFER.fill(0x41); // 'A'

var group = path.basename(__filename, '.js') + '/';

[
  { source: DCRLF,
    expected: {},
    what: 'No header'
  },
  { source: ['Content-Type:\t  text/plain',
             'Content-Length:0'
            ].join('\r\n') + DCRLF,
    expected: {'content-type': ['  text/plain'], 'content-length': ['0']},
    what: 'Value spacing'
  },
  { source: ['Content-Type:\r\n text/plain',
             'Foo:\r\n bar\r\n baz',
            ].join('\r\n') + DCRLF,
    expected: {'content-type': [' text/plain'], 'foo': [' bar baz']},
    what: 'Folded values'
  },
  { source: ['Content-Type:',
             'Foo: ',
            ].join('\r\n') + DCRLF,
    expected: {'content-type': [''], 'foo': ['']},
    what: 'Empty values'
  },
  { source: MAXED_BUFFER.toString('ascii') + DCRLF,
    expected: {},
    what: 'Max header size (single chunk)'
  },
  { source: ['ABCDEFGHIJ', MAXED_BUFFER.toString('ascii'), DCRLF],
    expected: {},
    what: 'Max header size (multiple chunks #1)'
  },
  { source: [MAXED_BUFFER.toString('ascii'), MAXED_BUFFER.toString('ascii'), DCRLF],
    expected: {},
    what: 'Max header size (multiple chunk #2)'
  },
].forEach(function(v) {
  var parser = new HeaderParser(),
      fired = false;

  parser.on('header', function(header) {
    assert(!fired, makeMsg(v.what, 'Header event fired more than once'));
    fired = true;
    assert.deepEqual(header,
                     v.expected,
                     makeMsg(v.what, 'Parsed result mismatch'));
  });
  if (!Array.isArray(v.source))
    v.source = [v.source];
  v.source.forEach(function(s) {
    parser.push(s);
  });
  assert(fired, makeMsg(v.what, 'Did not receive header from parser'));
});

function makeMsg(what, msg) {
  return '[' + group + what + ']: ' + msg;
}<|endoftext|>


<commit_before>var request = require('superagent');
var config = require('./config');
var debug = require('debug')('cyan-git-stats');

// Config properties
var personalAccessToken = config.personalAccessToken;

debug('token', personalAccessToken);

request.get('https://api.github.com/user')
    .auth(personalAccessToken, 'x-oauth-basic')
    .accept('application/vnd.github.v3+json')
    .set('Agent', 'tylerpeterson')
    .end(function (res) {
      if (res.ok) {
        debug('ok', JSON.stringify(res.body, null, '  '));
      } else {
        debug('not ok');
      }
    });<commit_msg>compute rudimentary statistics<commit_after>var request = require('superagent');
var config = require('./config');
var debug = require('debug')('cyan-git-stats');

// Config properties
var personalAccessToken = config.personalAccessToken;
var team = config.teams[config.teams._order[0]];
var repo = team.repos[0];

debug('token', personalAccessToken);
debug('repo', repo);

request.get('https://api.github.com/repos/' + repo + '/stats/contributors')
    .auth(personalAccessToken, 'x-oauth-basic')
    .accept('application/vnd.github.v3+json')
    .set('Agent', 'tylerpeterson')
    .end(function (res) {
      if (res.ok) {
        // debug('ok', JSON.stringify(res.body, null, '  '));
        res.body.forEach(function (authorStatistics) {
          var login = authorStatistics.author.login;
          if (team.users.indexOf(login) === -1) {
            return;
          }
          debug('author: ', login, authorStatistics.total);
          var commits = 0;
          var additions = 0
          var net = 0;
          var weeks = authorStatistics.weeks;

          if (weeks.length > 12) {
            weeks = weeks.slice(-12);
          }

          weeks.forEach(function (week) {
            commits += week.c;
            additions += week.a;
            net += week.a - week.d;
          });
          debug('commits:', commits, 'additions:', additions, 'net:', net);
        })
      } else {
        debug('not ok');
      }
    });<|endoftext|>


<commit_before>"use strict";

let configRefs = {};

const path   = require("path");

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

const levels = {
    "0": "red",
    "1": "gray",
    "2": "orange",
    "3": "green",
    "4": "blue"
};
const stabilities = {
    "0": "Deprecated",
    "1": "In development",
    "2": "Unstable",
    "3": "Stable",
    "4": "Stable (Locked)"
};

// (^#+)\s(.+)$
module.exports = {
    hooks: {
        init: function() {
            configRefs = this.options.pluginsConfig.references || {}
        },

        "page:before": function(page) {
            const frontpageLink = path.relative(path.dirname(page.path), ".");

            let content, references;

            // Generate table of contents
            content    = toc(page.content);
            references = content[1];
            content    = content[0];

            // Replace <!-- logo --> with a link to the frontpage
            content = content.replace(/<!--\slogo\s-->/gmi, () => {
                return `[Blackbeard.js](${frontpageLink})`;
            });

            // Replace text references to headlines and standard JS objects
            content = content.replace(/(^[^#|[\s\*].+)(.*)/gmi, ($0, $1, $2) => {
                return $1.replace(/([^\[.]|^)`([\w|\.]+)`/gmi, ($0, $1, $2) => {
                    if (references[$2]) {
                        return ` [\`${$2}\`][]`;
                    }

                    return ` \`${$2}\``;
                })
            });

            // Replace "stability box" comments
            content = content.replace(/<!--\sstability:(\d)\s(.*)\s?-->/gmi, ($0, $1, $2) => {
                let further = $2 || "";

                further = further.trim();
                further = further != "" ? `: ${further}` : "";

                return `<span class="stability-level boxed ${levels[$1]}">Stability: ${stabilities[$1]}${further}</span>`;
            });

            // Replace "stability level" comments
            content = content.replace(/<!--\sstability-level:(\d)\s-->/gmi, ($0, $1) => {
                return `<span class="stability-level ${levels[$1]}" title="${stabilities[$1]}"> </span>`;
            });

            // Replace "support" comments
            content = content.replace(/<!--\ssupport:(\d):(\d):(\d)\s-->/gmi, ($0, $1, $2, $3) => {
                return `<div class="support"><span class="badge ios ${levels[$1]}" title="${stabilities[$1]}"></span><span class="badge android ${levels[$2]}" title="${stabilities[$2]}"></span></div>`;
            });

            // Finally, add a reference list to the bottom
            content += "\n\n\n";

            for(let key in configRefs) {
                references[key] = path.relative(path.dirname(page.path), path.dirname(configRefs[key]));
                references[key] = path.join(references[key], path.basename(configRefs[key]));
            }

            for(let key in references) {
                let link = references[key];
                    link = link.indexOf("/") !== -1 || link.indexOf(".html") !== -1 ? link : `#${link}`;

                content += `[\`${key}\`]: ${link}\n`;
            }

            page.content = content;

            return page;
        }
    }
};
<commit_msg>Respect URLs in reference list<commit_after>"use strict";

let configRefs = {};

const path   = require("path");

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

const levels = {
    "0": "red",
    "1": "gray",
    "2": "orange",
    "3": "green",
    "4": "blue"
};
const stabilities = {
    "0": "Deprecated",
    "1": "In development",
    "2": "Unstable",
    "3": "Stable",
    "4": "Stable (Locked)"
};

// (^#+)\s(.+)$
module.exports = {
    hooks: {
        init: function() {
            configRefs = this.options.pluginsConfig.references || {}
        },

        "page:before": function(page) {
            const frontpageLink = path.relative(path.dirname(page.path), ".");

            let content, references;

            // Generate table of contents
            content    = toc(page.content);
            references = content[1];
            content    = content[0];

            // Replace <!-- logo --> with a link to the frontpage
            content = content.replace(/<!--\slogo\s-->/gmi, () => {
                return `[Blackbeard.js](${frontpageLink})`;
            });

            // Replace text references to headlines and standard JS objects
            content = content.replace(/(^[^#|[\s\*].+)(.*)/gmi, ($0, $1, $2) => {
                return $1.replace(/([^\[.]|^)`([\w|\.]+)`/gmi, ($0, $1, $2) => {
                    if (references[$2]) {
                        return ` [\`${$2}\`][]`;
                    }

                    return ` \`${$2}\``;
                })
            });

            // Replace "stability box" comments
            content = content.replace(/<!--\sstability:(\d)\s(.*)\s?-->/gmi, ($0, $1, $2) => {
                let further = $2 || "";

                further = further.trim();
                further = further != "" ? `: ${further}` : "";

                return `<span class="stability-level boxed ${levels[$1]}">Stability: ${stabilities[$1]}${further}</span>`;
            });

            // Replace "stability level" comments
            content = content.replace(/<!--\sstability-level:(\d)\s-->/gmi, ($0, $1) => {
                return `<span class="stability-level ${levels[$1]}" title="${stabilities[$1]}"> </span>`;
            });

            // Replace "support" comments
            content = content.replace(/<!--\ssupport:(\d):(\d):(\d)\s-->/gmi, ($0, $1, $2, $3) => {
                return `<div class="support"><span class="badge ios ${levels[$1]}" title="${stabilities[$1]}"></span><span class="badge android ${levels[$2]}" title="${stabilities[$2]}"></span></div>`;
            });

            // Finally, add a reference list to the bottom
            content += "\n\n\n";

            for(let key in configRefs) {
                if (configRefs[key].indexOf("://")) {
                    references[key] = configRefs[key];
                } else {
                    references[key] = path.relative(path.dirname(page.path), path.dirname(configRefs[key]));
                    references[key] = path.join(references[key], path.basename(configRefs[key]));
                }
            }

            for(let key in references) {
                let link = references[key];
                    link = link.indexOf("/") !== -1 || link.indexOf(".html") !== -1 ? link : `#${link}`;

                content += `[\`${key}\`]: ${link}\n`;
            }

            page.content = content;

            return page;
        }
    }
};
<|endoftext|>


<commit_before>'use strict';

let fs = require('fs');
let path = require('path');
let resolvePath = path.resolve;
let basename = path.basename;
let _ = require('lodash');
let globSync = require('glob').sync;
let moment = require('moment');
let mkdirpSync = require('mkdirp').sync;

function jsonStringify(value) {
    return JSON.stringify(value, null, 4);
}

module.exports = function() {
    let handlers = globSync('handlers/*.process.js').map(function(handlerPath) {
        return require(resolvePath(handlerPath));
    });

    let context = (function() {
        let contextFilePath = process.cwd() + '/genesis.json';

        if(fs.existsSync(contextFilePath)) {
            return require(contextFilePath);
        }
        else {
            return {};
        }
    })();

    let currentSnapshotsDirectory = moment().format('YYYY-MM-DD HH-mm-ss');
    let currentSnapshotsPath = 'snapshots/' + currentSnapshotsDirectory;

    mkdirpSync(currentSnapshotsPath);

    let events = globSync('!(genesis).json').map(function(eventPath) {
        return require(resolvePath(eventPath));
    });

    events.forEach(function(event) {
        _.each(handlers, function(handler) {
            handler.call(context, event);
        });

        let currentSnapshotPath = (
            currentSnapshotsPath + '/' +
            event.moment.format('YYYY-MM-DD HH-mm-ss') + '.json'
        );

        fs.writeFileSync(currentSnapshotPath, jsonStringify(context));
    });

    let latestSnapshotsPath = 'snapshots/latest';

    if(fs.existsSync(latestSnapshotsPath)) {
        fs.unlinkSync(latestSnapshotsPath);
    }

    fs.symlinkSync(currentSnapshotsDirectory, latestSnapshotsPath);
};
<commit_msg>Add event.dateTime property based on event file name.<commit_after>'use strict';

let fs = require('fs');
let path = require('path');
let resolvePath = path.resolve;
let basename = path.basename;
let _ = require('lodash');
let globSync = require('glob').sync;
let moment = require('moment');
let mkdirpSync = require('mkdirp').sync;

function jsonStringify(value) {
    return JSON.stringify(value, null, 4);
}

module.exports = function() {
    let handlers = globSync('handlers/*.process.js').map(function(handlerPath) {
        return require(resolvePath(handlerPath));
    });

    let context = (function() {
        let contextFilePath = process.cwd() + '/genesis.json';

        if(fs.existsSync(contextFilePath)) {
            return require(contextFilePath);
        }
        else {
            return {};
        }
    })();

    let currentSnapshotsDirectory = moment().format('YYYY-MM-DD HH-mm-ss');
    let currentSnapshotsPath = 'snapshots/' + currentSnapshotsDirectory;

    mkdirpSync(currentSnapshotsPath);

    let events = globSync('!(genesis).json').map(function(eventPath) {
        let event = require(resolvePath(eventPath));

        event.dateTime = basename(eventPath, '.json');

        return event;
    });

    events.forEach(function(event) {
        _.each(handlers, function(handler) {
            handler.call(context, event);
        });

        let currentSnapshotPath = (
            currentSnapshotsPath + '/' + event.dateTime + '.json'
        );

        delete event.dateTime;

        fs.writeFileSync(currentSnapshotPath, jsonStringify(context));
    });

    let latestSnapshotsPath = 'snapshots/latest';

    if(fs.existsSync(latestSnapshotsPath)) {
        fs.unlinkSync(latestSnapshotsPath);
    }

    fs.symlinkSync(currentSnapshotsDirectory, latestSnapshotsPath);
};
<|endoftext|>


<commit_before>import craftai, { errors } from '../src';

describe('craftai(<token_or_cfg>)', function() {
  it('should create a valid client given a valid configuration', function() {
    const client = craftai(CRAFT_CFG);
    expect(client.cfg.url).to.be.defined;
    expect(client.cfg.owner).to.be.defined;
    expect(client.cfg.project).to.be.defined;
    expect(client.cfg.token).to.be.equal(CRAFT_CFG.token);
  });

  it('should create a valid client given a valid token', function() {
    const client = craftai(CRAFT_CFG.token);
    expect(client.cfg.url).to.be.defined;
    expect(client.cfg.owner).to.be.defined;
    expect(client.cfg.project).to.be.defined;
    expect(client.cfg.token).to.be.equal(CRAFT_CFG.token);
  });

  it('should fail properly given an invalid token', function() {
    expect(() => craftai('this is an invalid token')).to.throw(errors.CraftAiCredentialsError);
  });
});
<commit_msg>No longer using deprecated chai function<commit_after>import craftai, { errors } from '../src';

describe('craftai(<token_or_cfg>)', function() {
  it('should create a valid client given a valid configuration', function() {
    const client = craftai(CRAFT_CFG);
    expect(client.cfg.url).to.be.ok;
    expect(client.cfg.owner).to.be.ok;
    expect(client.cfg.project).to.be.ok;
    expect(client.cfg.token).to.be.equal(CRAFT_CFG.token);
  });

  it('should create a valid client given a valid token', function() {
    const client = craftai(CRAFT_CFG.token);
    expect(client.cfg.url).to.be.ok;
    expect(client.cfg.owner).to.be.ok;
    expect(client.cfg.project).to.be.ok;
    expect(client.cfg.token).to.be.equal(CRAFT_CFG.token);
  });

  it('should fail properly given an invalid token', function() {
    expect(() => craftai('this is an invalid token')).to.throw(errors.CraftAiCredentialsError);
  });
});
<|endoftext|>


<commit_before>'use strict';

var contpara  = require('continuable-para')
var pull      = require('pull-stream')
var pl        = require('pull-level')
var paramap   = require('pull-paramap')
var replicate = require('./replicate')
var timestamp = require('monotonic-timestamp')
var Feed      = require('./feed')
var assert    = require('assert')
var msgpack   = require('msgpack-js')

//this makes msgpack a valid level codec.
msgpack.buffer = true

//var u         = require('./util')

//53 bit integer
var MAX_INT  = 0x1fffffffffffff

function isString (s) {
  return 'string' === typeof s
}

function isFunction (f) {
  return 'function' === typeof f
}

var isBuffer = Buffer.isBuffer
var isArray = Array.isArray
function isObject (o) { return o && 'object' === typeof o }

function traverse (obj, each) {
  if(Buffer.isBuffer(obj) || !isObject(obj)) return
  if(!isArray(obj)) each(obj)
  for(var k in obj) {
    if(isObject(obj[k])) traverse(obj[k], each)
  }
}

function indexLinks (msg, each) {
  traverse(msg, function (obj) {
    if(obj.$rel && (obj.$msg || obj.$ext || obj.$feed)) each(obj)
  })
}

module.exports = function (db, opts) {

  var logDB   = db.sublevel('log')
  var feedDB  = db.sublevel('fd')
  var clockDB = db.sublevel('clk')
  var lastDB  = db.sublevel('lst')
  var indexDB = db.sublevel('idx', {valueEncoding: msgpack})
  var appsDB  = db.sublevel('app')

  function get (db, key) {
    return function (cb) { db.get(encode(key), cb) }
  }

  db.opts = opts

  var isHash = opts.isHash

  var validation = require('./validation')(db, opts)

  db.pre(function (op, add, _batch) {
    var msg = op.value
    var id = op.key
    // index by sequence number
    add({
      key: [msg.author, msg.sequence], value: id,
      type: 'put', prefix: clockDB
    })

    // index my timestamp, used to generate feed.
    add({
      key: [msg.timestamp, msg.author], value: id,
      type: 'put', prefix: feedDB
    })

    // index the latest message from each author
    add({
      key: msg.author, value: msg.sequence,
      type: 'put', prefix: lastDB
    })

    // index messages in the order _received_
    // this will be used to pass to plugins which
    // must create their indexes asyncly.
    add({
      key: timestamp(), value: id,
      type: 'put', prefix: logDB
    })

    if(isString(msg.type))
      add({
        key: ['type', msg.type.substring(0, 32), msg.timestamp],
        value: id, type: 'put', prefix: indexDB
      })

    indexLinks(msg.message, function (link) {

      if(isHash(link.$feed)) {
        add({
          key: ['feed', msg.author, link.$rel, link.$feed, msg.sequence, id],
          value: link,
          type: 'put', prefix: indexDB
        })
        add({
          key: ['_feed', link.$feed, link.$rel, msg.author, msg.sequence, id],
          value: link,
          type: 'put', prefix: indexDB
        })
      }

      if(isHash(link.$msg)) {
        // do not need forward index here, because
        // it's cheap to just read the message.

        add({
          key: ['_msg', link.$msg, link.$rel, id], value: link,
          type: 'put', prefix: indexDB
        })
      }

      //TODO, add $ext links

    })

  })

  db.getPublicKey = function (id, cb) {
    function cont (cb) {
      clockDB.get([id, 1], function (err, hash) {
      if(err) return cb(err)
        db.get(hash, function (err, msg) {
          if(err) return cb(err)
          cb(null, msg.message)
        })
      })
    }
    return cb ? cont(cb) : cont
  }

  //msg must be an already valid message, with signature.
  //since creating this involves some state (it must increment
  //the sequence and point to the previous message)
  //it's recommended to append messages via a Feed object
  //which will manage that for you. (see feed.js)

  db.add = function (msg, cb) {
    //check that msg is valid (follows from end of database)
    //then insert into database.
    var n = 1
    validation.validate(msg, function (err, msg, hash) {
      if(--n) throw new Error('called twice')
      cb && cb(err, msg, hash)
    })
  }

  db.createFeedStream = function (opts) {
    opts = opts || {}
    opts.keys = false
    return pull(
      pl.read(feedDB, opts),
      paramap(function (key, cb) {
        db.get(key, cb)
      })
    )
  }

  db.latest = function (opts) {
    return pull(
      pl.read(lastDB),
      pull.map(function (data) {
        var d = {id: data.key, sequence: data.value}
        return d
      })
    )
  }

  db.follow = function (other, cb) {
    if(!isHash(other)) return cb(new Error('follow *must* be called with id'))
    lastDB.put(other, 0, cb)
  }

  db.unfollow = function (other, cb) {
    lastDB.del(other, cb)
  }

  db.isFollowing = function (other, cb) {
    lastDB.get(other, cb)
  }

  db.following = function () {
    return pl.read(lastDB)
  }

  db.createHistoryStream = function (id, seq, live) {
    return pull(
      pl.read(clockDB, {
        gte:  [id, seq],
        lte:  [id, MAX_INT],
        tail: live, live: live,
        keys: false
      }),
      paramap(function (key, cb) {
        db.get(key, cb)
      })
    )
  }

  db.createWriteStream = function (cb) {
    return pull(
      paramap(function (data, cb) {
        db.add(data, cb)
      }),
      pull.drain(null, cb)
    )
  }

  db.createReplicationStream = function (opts, cb) {
    if(!cb) cb = opts, opts = {}
    return replicate(db, opts, cb || function (err) {
      if(err) throw err
    })
  }

  db.createFeed = function (keys) {
    if(!keys)
      keys = opts.keys.generate()
    return Feed(db, keys, opts)
  }

  db.createLatestLookupStream = function () {
    return paramap(function (id, cb) {
      return lastDB.get(id, function (err, seq) {
        cb(null, {id: id, sequence: err ? 0 : seq})
      })
    })
  }

  db.getLatest = function (id, cb) {
    lastDB.get(id, function (err, v) {
      if(err) return cb(err)
      clockDB.get([id, v], function (err, hash) {
        if(err) return cb(err)
        db.get(hash, cb)
      })
    })
  }

  db.createLogStream = function (opts) {
    opts = opts || {}
    var _opts = {
      gt : opts.gt || 0, tail: opts.tail || false
    }
    return pull(
      pl.read(logDB, _opts),
      paramap(function (data, cb) {
        var key = data.value
        var seq = data.key
        db.get(key, function (err, value) {
          cb(err, {key: key, value: value, timestamp: seq})
        })
      })
    )
  }

  var HI = undefined, LO = null

  db.messagesLinkedTo = function (hash, rel) {
    return pull(
      pl.read(indexDB, {
        gte: ['_msg', hash, rel || LO, LO],
        lte: ['_msg', hash, rel || LO, HI],
      }),
      paramap(function (op, cb) {
        if(!op.key[3]) return cb()
        db.get(op.key[3], function (err, msg) {
          cb(null, msg)
        })
      }),
      pull.filter(Boolean)
    )
  }

  db.messagesByType = function (type) {
    return pull(
      pl.read(indexDB, {
        gte: ['type', type, LO, LO]
        lte: ['type', type, LO, LO]
      }),
      paramap(function (id, cb) {
        ssb.get(id, function (err, msg) {
          cb(null, msg)
        })
      }),
      pull.filter()
    )
  }

  db.feedsLinkedTo = function (id, rel) {
    return pull(
      pl.read(indexDB, {
        gte: ['_feed', id, rel || LO, LO],
        lte: ['_feed', id, rel || HI, HI]
      }),
      pull.map(function (op) {
        return {
          source: op.key[3], dest: op.key[1],
          rel: op.key[2], message: op.key[5]
        }
      })
    )
  }

  db.feedsLinkedFrom = function (id, rel) {
    return pull(
      pl.read(indexDB, {
        gte: ['feed', id, rel || LO, LO],
        lte: ['feed', id, rel || HI, HI]
      }),
      pull.map(function (op) {
        return {
          source: op.key[1], dest: op.key[3],
          rel: op.key[2], message: op.key[5]
        }
      })
    )
  }

  return db
}
<commit_msg>fix message type index<commit_after>'use strict';

var contpara  = require('continuable-para')
var pull      = require('pull-stream')
var pl        = require('pull-level')
var paramap   = require('pull-paramap')
var replicate = require('./replicate')
var timestamp = require('monotonic-timestamp')
var Feed      = require('./feed')
var assert    = require('assert')
var msgpack   = require('msgpack-js')

//this makes msgpack a valid level codec.
msgpack.buffer = true

//var u         = require('./util')

//53 bit integer
var MAX_INT  = 0x1fffffffffffff

function isString (s) {
  return 'string' === typeof s
}

function isFunction (f) {
  return 'function' === typeof f
}

var isBuffer = Buffer.isBuffer
var isArray = Array.isArray
function isObject (o) { return o && 'object' === typeof o }

function traverse (obj, each) {
  if(Buffer.isBuffer(obj) || !isObject(obj)) return
  if(!isArray(obj)) each(obj)
  for(var k in obj) {
    if(isObject(obj[k])) traverse(obj[k], each)
  }
}

function indexLinks (msg, each) {
  traverse(msg, function (obj) {
    if(obj.$rel && (obj.$msg || obj.$ext || obj.$feed)) each(obj)
  })
}

module.exports = function (db, opts) {

  var logDB   = db.sublevel('log')
  var feedDB  = db.sublevel('fd')
  var clockDB = db.sublevel('clk')
  var lastDB  = db.sublevel('lst')
  var indexDB = db.sublevel('idx', {valueEncoding: msgpack})
  var appsDB  = db.sublevel('app')

  function get (db, key) {
    return function (cb) { db.get(encode(key), cb) }
  }

  db.opts = opts

  var isHash = opts.isHash

  var validation = require('./validation')(db, opts)

  db.pre(function (op, add, _batch) {
    var msg = op.value
    var id = op.key
    // index by sequence number
    add({
      key: [msg.author, msg.sequence], value: id,
      type: 'put', prefix: clockDB
    })

    // index my timestamp, used to generate feed.
    add({
      key: [msg.timestamp, msg.author], value: id,
      type: 'put', prefix: feedDB
    })

    // index the latest message from each author
    add({
      key: msg.author, value: msg.sequence,
      type: 'put', prefix: lastDB
    })

    // index messages in the order _received_
    // this will be used to pass to plugins which
    // must create their indexes asyncly.
    add({
      key: timestamp(), value: id,
      type: 'put', prefix: logDB
    })

//    if(isString(msg.type))
      add({
        key: ['type', msg.type.toString().substring(0, 32), msg.timestamp],
        value: id, type: 'put', prefix: indexDB
      })

    indexLinks(msg.message, function (link) {

      if(isHash(link.$feed)) {
        add({
          key: ['feed', msg.author, link.$rel, link.$feed, msg.sequence, id],
          value: link,
          type: 'put', prefix: indexDB
        })
        add({
          key: ['_feed', link.$feed, link.$rel, msg.author, msg.sequence, id],
          value: link,
          type: 'put', prefix: indexDB
        })
      }

      if(isHash(link.$msg)) {
        // do not need forward index here, because
        // it's cheap to just read the message.

        add({
          key: ['_msg', link.$msg, link.$rel, id], value: link,
          type: 'put', prefix: indexDB
        })
      }

      //TODO, add $ext links

    })

  })

  db.getPublicKey = function (id, cb) {
    function cont (cb) {
      clockDB.get([id, 1], function (err, hash) {
      if(err) return cb(err)
        db.get(hash, function (err, msg) {
          if(err) return cb(err)
          cb(null, msg.message)
        })
      })
    }
    return cb ? cont(cb) : cont
  }

  //msg must be an already valid message, with signature.
  //since creating this involves some state (it must increment
  //the sequence and point to the previous message)
  //it's recommended to append messages via a Feed object
  //which will manage that for you. (see feed.js)

  db.add = function (msg, cb) {
    //check that msg is valid (follows from end of database)
    //then insert into database.
    var n = 1
    validation.validate(msg, function (err, msg, hash) {
      if(--n) throw new Error('called twice')
      cb && cb(err, msg, hash)
    })
  }

  db.createFeedStream = function (opts) {
    opts = opts || {}
    opts.keys = false
    return pull(
      pl.read(feedDB, opts),
      paramap(function (key, cb) {
        db.get(key, cb)
      })
    )
  }

  db.latest = function (opts) {
    return pull(
      pl.read(lastDB),
      pull.map(function (data) {
        var d = {id: data.key, sequence: data.value}
        return d
      })
    )
  }

  db.follow = function (other, cb) {
    if(!isHash(other)) return cb(new Error('follow *must* be called with id'))
    lastDB.put(other, 0, cb)
  }

  db.unfollow = function (other, cb) {
    lastDB.del(other, cb)
  }

  db.isFollowing = function (other, cb) {
    lastDB.get(other, cb)
  }

  db.following = function () {
    return pl.read(lastDB)
  }

  db.createHistoryStream = function (id, seq, live) {
    return pull(
      pl.read(clockDB, {
        gte:  [id, seq],
        lte:  [id, MAX_INT],
        tail: live, live: live,
        keys: false
      }),
      paramap(function (key, cb) {
        db.get(key, cb)
      })
    )
  }

  db.createWriteStream = function (cb) {
    return pull(
      paramap(function (data, cb) {
        db.add(data, cb)
      }),
      pull.drain(null, cb)
    )
  }

  db.createReplicationStream = function (opts, cb) {
    if(!cb) cb = opts, opts = {}
    return replicate(db, opts, cb || function (err) {
      if(err) throw err
    })
  }

  db.createFeed = function (keys) {
    if(!keys)
      keys = opts.keys.generate()
    return Feed(db, keys, opts)
  }

  db.createLatestLookupStream = function () {
    return paramap(function (id, cb) {
      return lastDB.get(id, function (err, seq) {
        cb(null, {id: id, sequence: err ? 0 : seq})
      })
    })
  }

  db.getLatest = function (id, cb) {
    lastDB.get(id, function (err, v) {
      if(err) return cb(err)
      clockDB.get([id, v], function (err, hash) {
        if(err) return cb(err)
        db.get(hash, cb)
      })
    })
  }

  db.createLogStream = function (opts) {
    opts = opts || {}
    var _opts = {
      gt : opts.gt || 0, tail: opts.tail || false
    }
    return pull(
      pl.read(logDB, _opts),
      paramap(function (data, cb) {
        var key = data.value
        var seq = data.key
        db.get(key, function (err, value) {
          cb(err, {key: key, value: value, timestamp: seq})
        })
      })
    )
  }

  var HI = undefined, LO = null

  db.messagesLinkedTo = function (hash, rel) {
    return pull(
      pl.read(indexDB, {
        gte: ['_msg', hash, rel || LO, LO],
        lte: ['_msg', hash, rel || LO, HI],
      }),
      paramap(function (op, cb) {
        if(!op.key[3]) return cb()
        db.get(op.key[3], function (err, msg) {
          cb(null, msg)
        })
      }),
      pull.filter(Boolean)
    )
  }

  db.messagesByType = function (type) {
    return pull(
      pl.read(indexDB, {
        gte: ['type', type, LO, LO],
        lte: ['type', type, HI, HI],
        keys: false
      }),
      paramap(function (id, cb) {
        db.get(id, function (err, msg) {
          cb(null, msg)
        })
      }),
      pull.filter()
    )
  }

  db.feedsLinkedTo = function (id, rel) {
    return pull(
      pl.read(indexDB, {
        gte: ['_feed', id, rel || LO, LO],
        lte: ['_feed', id, rel || HI, HI]
      }),
      pull.map(function (op) {
        return {
          source: op.key[3], dest: op.key[1],
          rel: op.key[2], message: op.key[5]
        }
      })
    )
  }

  db.feedsLinkedFrom = function (id, rel) {
    return pull(
      pl.read(indexDB, {
        gte: ['feed', id, rel || LO, LO],
        lte: ['feed', id, rel || HI, HI]
      }),
      pull.map(function (op) {
        return {
          source: op.key[1], dest: op.key[3],
          rel: op.key[2], message: op.key[5]
        }
      })
    )
  }

  return db
}
<|endoftext|>


<commit_before>"use strict";

var mapnik = require('../');
var assert = require('assert');
var path = require('path');

mapnik.register_datasource(path.join(mapnik.settings.paths.input_plugins,'geojson.input'));
mapnik.register_datasource(path.join(mapnik.settings.paths.input_plugins,'ogr.input'));
mapnik.register_datasource(path.join(mapnik.settings.paths.input_plugins,'shape.input'));
mapnik.register_datasource(path.join(mapnik.settings.paths.input_plugins,'gdal.input'));

describe('mapnik.Datasource', function() {

    it('should throw with invalid usage', function() {
        assert.throws(function() { mapnik.Datasource('foo'); });
        assert.throws(function() { mapnik.Datasource({ 'foo': 1 }); });
        assert.throws(function() { mapnik.Datasource({ 'type': 'foo' }); });
        assert.throws(function() { mapnik.Datasource({ 'type': 'shape' }); });

        assert.throws(function() { new mapnik.Datasource('foo'); },
            /Must provide an object, eg \{type: 'shape', file : 'world.shp'\}/);

        assert.throws(function() { new mapnik.Datasource(); });
        assert.throws(function() { new mapnik.Datasource({ 'foo': 1 }); });

        assert.throws(function() { new mapnik.Datasource({ 'type': 'foo' }); });

        assert.throws(function() { new mapnik.Datasource({ 'type': 'shape' }); },
            /Shape Plugin: missing <file> parameter/);
    });

    it('should validate with known shapefile - ogr', function() {
        var options = {
            type: 'ogr',
            file: './test/data/world_merc.shp',
            layer: 'world_merc'
        };

        var ds = new mapnik.Datasource(options);
        assert.ok(ds);
        assert.deepEqual(ds.parameters(), options);

        var features = [];
        var featureset = ds.featureset();
        var feature;
        while ((feature = featureset.next())) {
            features.push(feature);
        }

        assert.equal(features.length, 245);
        assert.deepEqual(features[244].attributes(), {
            AREA: 1638094,
            FIPS: 'RS',
            ISO2: 'RU',
            ISO3: 'RUS',
            LAT: 61.988,
            LON: 96.689,
            NAME: 'Russia',
            POP2005: 143953092,
            REGION: 150,
            SUBREGION: 151,
            UN: 643
        });

        var expected = {
            type: 'vector',
            extent: [
                -20037508.342789248,
                -8283343.693882697,
                20037508.342789244,
                18365151.363070473
            ],
            encoding: 'utf-8',
            fields: {
                FIPS: 'String',
                ISO2: 'String',
                ISO3: 'String',
                UN: 'Number',
                NAME: 'String',
                AREA: 'Number',
                POP2005: 'Number',
                REGION: 'Number',
                SUBREGION: 'Number',
                LON: 'Number',
                LAT: 'Number'
            },
            geometry_type: 'polygon',
            proj4:'+proj=merc +lon_0=0 +lat_ts=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs'
        };
        var actual = ds.describe();
        assert.equal(actual.proj4, expected.proj4);
        assert.deepEqual(actual.type, expected.type);
        assert.deepEqual(actual.encoding, expected.encoding);
        assert.deepEqual(actual.fields, expected.fields);
        assert.deepEqual(actual.geometry_type, expected.geometry_type);

        assert.deepEqual(ds.extent(), expected.extent);

        assert.deepEqual(ds.fields(), expected.fields);
    });

    it('should validate with known shapefile', function() {
        var options = {
            type: 'shape',
            file: './test/data/world_merc.shp'
        };

        var ds = new mapnik.Datasource(options);
        assert.ok(ds);
        assert.deepEqual(ds.parameters(), options);

        var features = [];
        var featureset = ds.featureset();
        var feature;
        while ((feature = featureset.next())) {
            features.push(feature);
        }

        assert.equal(features.length, 245);
        assert.deepEqual(features[244].attributes(), {
            AREA: 1638094,
            FIPS: 'RS',
            ISO2: 'RU',
            ISO3: 'RUS',
            LAT: 61.988,
            LON: 96.689,
            NAME: 'Russia',
            POP2005: 143953092,
            REGION: 150,
            SUBREGION: 151,
            UN: 643
        });

        var expected = {
            type: 'vector',
            extent: [
                -20037508.342789248,
                -8283343.693882697,
                20037508.342789244,
                18365151.363070473
            ],
            encoding: 'utf-8',
            fields: {
                FIPS: 'String',
                ISO2: 'String',
                ISO3: 'String',
                UN: 'Number',
                NAME: 'String',
                AREA: 'Number',
                POP2005: 'Number',
                REGION: 'Number',
                SUBREGION: 'Number',
                LON: 'Number',
                LAT: 'Number'
            },
            geometry_type: 'polygon'
        };
        var actual = ds.describe();
        assert.deepEqual(actual.type, expected.type);
        assert.deepEqual(actual.encoding, expected.encoding);
        assert.deepEqual(actual.fields, expected.fields);
        assert.deepEqual(actual.geometry_type, expected.geometry_type);

        assert.deepEqual(ds.extent(), expected.extent);

        assert.deepEqual(ds.fields(), expected.fields);
    });

    it('test invalid use of memory datasource', function() {
        var ds = new mapnik.MemoryDatasource({'extent': '-180,-90,180,90'});
        assert.throws(function() { ds.add(); });
        assert.throws(function() { ds.add(null); });
        assert.throws(function() { ds.add({}, null); });
        assert.throws(function() { ds.add({'wkt': '1234'}); });
        assert.equal(false, ds.add({}));
    });

    it('test empty memory datasource', function() {
        var ds = new mapnik.MemoryDatasource({'extent': '-180,-90,180,90'});
        var empty_fs = ds.featureset();
        assert.equal(typeof(empty_fs),'undefined');
        assert.equal(empty_fs, null);
    });

    it('test empty geojson datasource', function() {
        var input = {
          "type": "Feature",
          "properties": {
            "something": []
          },
          "geometry": {
            "type": "Point",
            "coordinates": [ 1, 1 ]
          }
        };
        var ds = new mapnik.Datasource({ type:'geojson', inline: JSON.stringify(input) });
        var fs = ds.featureset()
        var feat = fs.next();
        var feature = JSON.parse(feat.toJSON());
        // pass invalid extent to filter all features out
        // resulting in empty featureset that should be returned
        // as a null object
        var empty_fs = ds.featureset({extent:[-1,-1,0,0]});
        assert.equal(typeof(empty_fs),'undefined');
        assert.equal(empty_fs, null);
    });

    it('test empty geojson datasource due to invalid json string', function() {
        var input = "{ \"type\": \"FeatureCollection\", \"features\": [{ \"oofda\" } ] }";
        // from string will fail to parse
        assert.throws(function() { new mapnik.Datasource({ type:'geojson', inline: inline, cache_features: false }); });
        assert.throws(function() { new mapnik.Datasource({ type:'geojson', inline: fs.readFileSync('./test/data/parse.error.json').toString(), cache_features: false }); });
    });

    it('test empty geojson datasource due to invalid json file', function() {
        var ds = new mapnik.Datasource({ type:'geojson', file: './test/data/parse.error.json', cache_features: false });
        var empty_fs = ds.featureset();
        assert.equal(typeof(empty_fs),'undefined');
        assert.equal(empty_fs, null);
    });

    it('test valid use of memory datasource', function() {
        var ds = new mapnik.MemoryDatasource({'extent': '-180,-90,180,90'});
        assert.equal(true, ds.add({ 'x': 0, 'y': 0 }));
        assert.equal(true, ds.add({ 'x': 0.23432, 'y': 0.234234 }));
        assert.equal(true, ds.add({ 'x': 1, 'y': 1 , 'properties': {'a':'b', 'c':1, 'd':0.23 }}));
        var expected_describe = {
            type: 'vector',
            encoding: 'utf-8',
            fields: {},
            geometry_type: 'collection'
        };
        assert.deepEqual(expected_describe, ds.describe());
        // Currently descriptors can not be added to memory datasource so will always be empty object
        assert.deepEqual({},ds.fields());
    });

    it('should validate with raster', function() {
        var options = {
            type: 'gdal',
            file: './test/data/images/sat_image.tif'
        };

        var ds = new mapnik.Datasource(options);
        assert.ok(ds);
        assert.deepEqual(ds.parameters(), options);
        var describe = ds.describe();
        var expected = {  type: 'raster',
                          encoding: 'utf-8',
                          fields: { nodata: 'Number' },
                          geometry_type: 'raster'
                       };
        assert.deepEqual(expected,describe);

        // Test that if added to layer, can get datasource back
        var layer = new mapnik.Layer('foo', '+init=epsg:4326');
        layer.datasource = ds;
        var ds2 = layer.datasource;
        assert.ok(ds2);
        assert.deepEqual(ds2.parameters(), options);
    });
});
<commit_msg>Parsing empty GeoJSON from file now throws<commit_after>"use strict";

var mapnik = require('../');
var assert = require('assert');
var path = require('path');

mapnik.register_datasource(path.join(mapnik.settings.paths.input_plugins,'geojson.input'));
mapnik.register_datasource(path.join(mapnik.settings.paths.input_plugins,'ogr.input'));
mapnik.register_datasource(path.join(mapnik.settings.paths.input_plugins,'shape.input'));
mapnik.register_datasource(path.join(mapnik.settings.paths.input_plugins,'gdal.input'));

describe('mapnik.Datasource', function() {

    it('should throw with invalid usage', function() {
        assert.throws(function() { mapnik.Datasource('foo'); });
        assert.throws(function() { mapnik.Datasource({ 'foo': 1 }); });
        assert.throws(function() { mapnik.Datasource({ 'type': 'foo' }); });
        assert.throws(function() { mapnik.Datasource({ 'type': 'shape' }); });

        assert.throws(function() { new mapnik.Datasource('foo'); },
            /Must provide an object, eg \{type: 'shape', file : 'world.shp'\}/);

        assert.throws(function() { new mapnik.Datasource(); });
        assert.throws(function() { new mapnik.Datasource({ 'foo': 1 }); });

        assert.throws(function() { new mapnik.Datasource({ 'type': 'foo' }); });

        assert.throws(function() { new mapnik.Datasource({ 'type': 'shape' }); },
            /Shape Plugin: missing <file> parameter/);
    });

    it('should validate with known shapefile - ogr', function() {
        var options = {
            type: 'ogr',
            file: './test/data/world_merc.shp',
            layer: 'world_merc'
        };

        var ds = new mapnik.Datasource(options);
        assert.ok(ds);
        assert.deepEqual(ds.parameters(), options);

        var features = [];
        var featureset = ds.featureset();
        var feature;
        while ((feature = featureset.next())) {
            features.push(feature);
        }

        assert.equal(features.length, 245);
        assert.deepEqual(features[244].attributes(), {
            AREA: 1638094,
            FIPS: 'RS',
            ISO2: 'RU',
            ISO3: 'RUS',
            LAT: 61.988,
            LON: 96.689,
            NAME: 'Russia',
            POP2005: 143953092,
            REGION: 150,
            SUBREGION: 151,
            UN: 643
        });

        var expected = {
            type: 'vector',
            extent: [
                -20037508.342789248,
                -8283343.693882697,
                20037508.342789244,
                18365151.363070473
            ],
            encoding: 'utf-8',
            fields: {
                FIPS: 'String',
                ISO2: 'String',
                ISO3: 'String',
                UN: 'Number',
                NAME: 'String',
                AREA: 'Number',
                POP2005: 'Number',
                REGION: 'Number',
                SUBREGION: 'Number',
                LON: 'Number',
                LAT: 'Number'
            },
            geometry_type: 'polygon',
            proj4:'+proj=merc +lon_0=0 +lat_ts=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs'
        };
        var actual = ds.describe();
        assert.equal(actual.proj4, expected.proj4);
        assert.deepEqual(actual.type, expected.type);
        assert.deepEqual(actual.encoding, expected.encoding);
        assert.deepEqual(actual.fields, expected.fields);
        assert.deepEqual(actual.geometry_type, expected.geometry_type);

        assert.deepEqual(ds.extent(), expected.extent);

        assert.deepEqual(ds.fields(), expected.fields);
    });

    it('should validate with known shapefile', function() {
        var options = {
            type: 'shape',
            file: './test/data/world_merc.shp'
        };

        var ds = new mapnik.Datasource(options);
        assert.ok(ds);
        assert.deepEqual(ds.parameters(), options);

        var features = [];
        var featureset = ds.featureset();
        var feature;
        while ((feature = featureset.next())) {
            features.push(feature);
        }

        assert.equal(features.length, 245);
        assert.deepEqual(features[244].attributes(), {
            AREA: 1638094,
            FIPS: 'RS',
            ISO2: 'RU',
            ISO3: 'RUS',
            LAT: 61.988,
            LON: 96.689,
            NAME: 'Russia',
            POP2005: 143953092,
            REGION: 150,
            SUBREGION: 151,
            UN: 643
        });

        var expected = {
            type: 'vector',
            extent: [
                -20037508.342789248,
                -8283343.693882697,
                20037508.342789244,
                18365151.363070473
            ],
            encoding: 'utf-8',
            fields: {
                FIPS: 'String',
                ISO2: 'String',
                ISO3: 'String',
                UN: 'Number',
                NAME: 'String',
                AREA: 'Number',
                POP2005: 'Number',
                REGION: 'Number',
                SUBREGION: 'Number',
                LON: 'Number',
                LAT: 'Number'
            },
            geometry_type: 'polygon'
        };
        var actual = ds.describe();
        assert.deepEqual(actual.type, expected.type);
        assert.deepEqual(actual.encoding, expected.encoding);
        assert.deepEqual(actual.fields, expected.fields);
        assert.deepEqual(actual.geometry_type, expected.geometry_type);

        assert.deepEqual(ds.extent(), expected.extent);

        assert.deepEqual(ds.fields(), expected.fields);
    });

    it('test invalid use of memory datasource', function() {
        var ds = new mapnik.MemoryDatasource({'extent': '-180,-90,180,90'});
        assert.throws(function() { ds.add(); });
        assert.throws(function() { ds.add(null); });
        assert.throws(function() { ds.add({}, null); });
        assert.throws(function() { ds.add({'wkt': '1234'}); });
        assert.equal(false, ds.add({}));
    });

    it('test empty memory datasource', function() {
        var ds = new mapnik.MemoryDatasource({'extent': '-180,-90,180,90'});
        var empty_fs = ds.featureset();
        assert.equal(typeof(empty_fs),'undefined');
        assert.equal(empty_fs, null);
    });

    it('test empty geojson datasource', function() {
        var input = {
          "type": "Feature",
          "properties": {
            "something": []
          },
          "geometry": {
            "type": "Point",
            "coordinates": [ 1, 1 ]
          }
        };
        var ds = new mapnik.Datasource({ type:'geojson', inline: JSON.stringify(input) });
        var fs = ds.featureset()
        var feat = fs.next();
        var feature = JSON.parse(feat.toJSON());
        // pass invalid extent to filter all features out
        // resulting in empty featureset that should be returned
        // as a null object
        var empty_fs = ds.featureset({extent:[-1,-1,0,0]});
        assert.equal(typeof(empty_fs),'undefined');
        assert.equal(empty_fs, null);
    });

    it('test empty geojson datasource due to invalid json string', function() {
        var input = "{ \"type\": \"FeatureCollection\", \"features\": [{ \"oofda\" } ] }";
        // from string will fail to parse
        assert.throws(function() { new mapnik.Datasource({ type:'geojson', inline: inline, cache_features: false }); });
        assert.throws(function() { new mapnik.Datasource({ type:'geojson', inline: fs.readFileSync('./test/data/parse.error.json').toString(), cache_features: false }); });
    });

    it('test empty geojson datasource due to invalid json file', function() {
        assert.throws(function() { new mapnik.Datasource({ type:'geojson', file: './test/data/parse.error.json', cache_features: false }); });
    });

    it('test valid use of memory datasource', function() {
        var ds = new mapnik.MemoryDatasource({'extent': '-180,-90,180,90'});
        assert.equal(true, ds.add({ 'x': 0, 'y': 0 }));
        assert.equal(true, ds.add({ 'x': 0.23432, 'y': 0.234234 }));
        assert.equal(true, ds.add({ 'x': 1, 'y': 1 , 'properties': {'a':'b', 'c':1, 'd':0.23 }}));
        var expected_describe = {
            type: 'vector',
            encoding: 'utf-8',
            fields: {},
            geometry_type: 'collection'
        };
        assert.deepEqual(expected_describe, ds.describe());
        // Currently descriptors can not be added to memory datasource so will always be empty object
        assert.deepEqual({},ds.fields());
    });

    it('should validate with raster', function() {
        var options = {
            type: 'gdal',
            file: './test/data/images/sat_image.tif'
        };

        var ds = new mapnik.Datasource(options);
        assert.ok(ds);
        assert.deepEqual(ds.parameters(), options);
        var describe = ds.describe();
        var expected = {  type: 'raster',
                          encoding: 'utf-8',
                          fields: { nodata: 'Number' },
                          geometry_type: 'raster'
                       };
        assert.deepEqual(expected,describe);

        // Test that if added to layer, can get datasource back
        var layer = new mapnik.Layer('foo', '+init=epsg:4326');
        layer.datasource = ds;
        var ds2 = layer.datasource;
        assert.ok(ds2);
        assert.deepEqual(ds2.parameters(), options);
    });
});
<|endoftext|>


<commit_before>var menubar = require('menubar')
var ipc = require('ipc')
var globalShortcut = require('global-shortcut')
var mb = menubar({ dir: __dirname + '/app', height: 175, x: 0, y: 0 })
var Menu = require('menu')

// Register a 'ctrl+shift+space' shortcut listener.
mb.app.on('ready', function () {
  var ret = globalShortcut.register('ctrl+shift+space', function () {
    // It gets angry not knowing where to put the window if bounds not passed
    mb.tray.emit('clicked', null, {x: 0, y: 0, width: 0, height: 0})
  })

  if (!ret) {
    console.log('registration failed')
  }
})

mb.app.on('will-quit', function () {
  globalShortcut.unregisterAll()
})

// when receive the abort message, close the app
ipc.on('abort', function () {
  mb.emit('hide')
  mb.window.hide()
  mb.emit('after-hide')
})

var template = [
  {
    label: 'Mojibar',
    submenu: [
      {
        label: 'Undo',
        accelerator: 'Command+Z',
        selector: 'undo:'
      },
      {
        label: 'Redo',
        accelerator: 'Shift+Command+Z',
        selector: 'redo:'
      },
      {
        label: 'Cut',
        accelerator: 'Command+X',
        selector: 'cut:'
      },
      {
        label: 'Copy',
        accelerator: 'Command+C',
        selector: 'copy:'
      },
      {
        label: 'Paste',
        accelerator: 'Command+V',
        selector: 'paste:'
      },
      {
        label: 'Select All',
        accelerator: 'Command+A',
        selector: 'selectAll:'
      },
      {
        label: 'Toggle DevTools',
        accelerator: 'Alt+Command+I',
        click: function () { mb.window.toggleDevTools() }
      }
    ]
  }
]

mb.on('ready', function ready () {
  // Build default menu for text editing and devtools. (gone since electron 0.25.2)
  var menu = Menu.buildFromTemplate(template)
  Menu.setApplicationMenu(menu)
})
<commit_msg>:x: bind app quitting<commit_after>var menubar = require('menubar')
var ipc = require('ipc')
var globalShortcut = require('global-shortcut')
var mb = menubar({ dir: __dirname + '/app', height: 175, x: 0, y: 0 })
var Menu = require('menu')

// Register a 'ctrl+shift+space' shortcut listener.
mb.app.on('ready', function () {
  var ret = globalShortcut.register('ctrl+shift+space', function () {
    // It gets angry not knowing where to put the window if bounds not passed
    mb.tray.emit('clicked', null, {x: 0, y: 0, width: 0, height: 0})
  })

  if (!ret) {
    console.log('registration failed')
  }
})

mb.app.on('will-quit', function () {
  globalShortcut.unregisterAll()
})

// when receive the abort message, close the app
ipc.on('abort', function () {
  mb.emit('hide')
  mb.window.hide()
  mb.emit('after-hide')
})

var template = [
  {
    label: 'Mojibar',
    submenu: [
      {
        label: 'Undo',
        accelerator: 'Command+Z',
        selector: 'undo:'
      },
      {
        label: 'Redo',
        accelerator: 'Shift+Command+Z',
        selector: 'redo:'
      },
      {
        label: 'Cut',
        accelerator: 'Command+X',
        selector: 'cut:'
      },
      {
        label: 'Copy',
        accelerator: 'Command+C',
        selector: 'copy:'
      },
      {
        label: 'Paste',
        accelerator: 'Command+V',
        selector: 'paste:'
      },
      {
        label: 'Select All',
        accelerator: 'Command+A',
        selector: 'selectAll:'
      },
      {
        label: 'Quit App',
        accelerator: 'Command+Q',
        selector: 'terminate:'
      },
      {
        label: 'Toggle DevTools',
        accelerator: 'Alt+Command+I',
        click: function () { mb.window.toggleDevTools() }
      }
    ]
  }
]

mb.on('ready', function ready () {
  // Build default menu for text editing and devtools. (gone since electron 0.25.2)
  var menu = Menu.buildFromTemplate(template)
  Menu.setApplicationMenu(menu)
})
<|endoftext|>


<commit_before>describe('Datepicker', function () {
    function addZero(num) {
        return (parseInt(num, 10) < 10) ? "0" + num : num;
    }

    var container = document.createElement('div'),
        datepickerHtml = [
            '<form action="/mock/ajax.html" class="YOUR_SELECTOR_FormDatepicker ch-form">',
                '
',
                    'Date: ',
                    '<input type="date" id="datepicker-1" placeholder="DD/MM/YYYY">',
                '
',
                '
',
                    'Date:',
                    '<input type="date" id="datepicker-2" placeholder="DD/MM/YYYY">',
                '
',
            '</form>'
        ].join(''),
        DATE = (function(){
            var date = new Date(),
                TODAY =  {
                    'day': addZero(date.getDate()),
                    'month': addZero((date.getMonth() + 1)),
                    'year': date.getFullYear()
                },
                FORMAT = {
                    'ddmmyyyy': [TODAY.day, TODAY.month, TODAY.year].join('/'),
                    'yyyymmdd': [TODAY.year, TODAY.month, TODAY.day].join('/')
                };
            return {
                'TODAY': TODAY,
                'FORMAT': FORMAT
            }
        })(),
        datepicker1,
        datepicker2,
        readyEvent,
        showEvent,
        hideEvent,
        selectEvent,
        nextmonthEvent,
        prevmonthEvent,
        nextyearEvent,
        prevyearEvent,
        destroyEvent;

    before(function () {
        container.innerHTML = datepickerHtml;
        document.body.appendChild(container);

        datepicker1 = new ch.Datepicker(document.getElementById('datepicker-1'));
        datepicker2 = new ch.Datepicker(document.getElementById('datepicker-2'));
        readyEvent = chai.spy();
        showEvent = chai.spy();
        hideEvent = chai.spy();
        selectEvent = chai.spy();
        nextmonthEvent = chai.spy();
        prevmonthEvent = chai.spy();
        nextyearEvent = chai.spy();
        prevyearEvent = chai.spy();
        destroyEvent = chai.spy();

        datepicker1
            .on('ready', readyEvent)
            .on('show', showEvent)
            .on('hide', hideEvent)
            .on('select', selectEvent)
            .on('nextmonth', nextmonthEvent)
            .on('prevmonth', prevmonthEvent)
            .on('nextyear', nextyearEvent)
            .on('prevyear', prevyearEvent);
    });

    after(function () {
        document.body.removeChild(container);
    });

    it('should be defined on ch object', function () {
        expect(ch.Datepicker).to.exist;
        expect(ch.Datepicker).to.be.a('function');
    });

    it('should be return a new instance', function () {
        expect(datepicker1).to.be.an.instanceof(ch.Datepicker);
    });

    it('should emit the "ready" event when it\'s created', function (done) {
        setTimeout(function(){
            expect(readyEvent).to.have.been.called();
            done();
        },50);
    });

    describe('should use the following abilities:', function () {
        it('EventEmitter', function () {
            expect(datepicker1.on).to.exist;
            expect(datepicker1.on).to.be.a('function');
        });
    });

    describe('It should have the following public properties:', function () {
        it('.field', function () {
            expect(datepicker1.field).to.exist;
            expect(datepicker1.field.nodeType).to.equal(1);
        });

        it('.name', function () {
            expect(datepicker1.name).to.exist;
            expect(datepicker1.name).to.be.a('string');
            expect(datepicker1.name).to.equal('datepicker');
        });

        it('.constructor', function () {
            expect(datepicker1.constructor).to.exist;
            expect(datepicker1.constructor).to.be.a('function');
        });

        it('.uid', function () {
            expect(datepicker1.uid).to.exist;
            expect(datepicker1.uid).to.be.a('number');
        });
    });

    describe('It should have the following public methods:', function () {
        var methods = ['destroy', 'show', 'hide', 'pick', 'getToday', 'setFrom', 'setTo', 'nextMonth', 'nextYear', 'prevMonth', 'prevYear', 'select', 'reset', 'enable', 'disable'],
            i = 0,
            len = methods.length;

        for (i; i < len; i += 1) {
            (function (i){
                it('.' + methods[i] + '()', function () {
                    expect(datepicker1[methods[i]]).to.exist;
                    expect(datepicker1[methods[i]]).to.be.a('function');
                });
            }(i));
        }
    });

    describe('It should have a input field associated', function () {
        var field;

        before(function(){
            field = datepicker1.field;
        });

        it('its type attribute should be updated to "text"', function () {
            expect(field.type).to.equal('text');
        });

        it('should have got the WAI-ARIA attribute "aria-describedby"', function () {
            expect(field.getAttribute('aria-describedby')).to.match(/^ch-popover-/);
        });
    });

    describe('It should create a trigger and', function () {
        var trigger;

        before(function(){
            trigger = datepicker1.trigger;
        });

        it('should be defined', function () {
            expect(datepicker1.trigger).to.exist;
            expect(datepicker1.trigger.nodeType).to.equal(1);
            expect(datepicker1.trigger).to.be.an.instanceof(HTMLElement);
        });

        describe('should have the following class names:', function () {
            it('.ch-datepicker-trigger', function () {
                expect(tiny.hasClass(trigger, 'ch-datepicker-trigger')).to.be.true;
            });

            it('.ch-icon-calendar', function () {
                expect(tiny.hasClass(trigger, 'ch-icon-calendar')).to.be.true;
            });
        });
    });

    describe('Its show() method', function () {
        it('should show a calendar', function () {
            datepicker1.show();
            expect(datepicker1._popover.isShown()).to.be.true;
        });

        it('should emit the "show" event', function () {
            expect(showEvent).to.have.been.called();
        });
    });

    describe('Its hide() method', function () {
        it('should hide a calendar', function () {
            datepicker1.hide();
            expect(datepicker1._popover.isShown()).to.be.false;
        });

        it('should emit the "hide" event', function () {
            expect(hideEvent).to.have.been.called();
        });
    });

    describe('Its select() method', function () {
        it('should return "undefined" when it hasn\'t got a date selected', function () {
            expect(datepicker1.select()).to.be.undefined;
        });

        it('should set a date as calendar.select(\'yyyy/mm/dd\')', function () {
            datepicker1.select(DATE.FORMAT['yyyymmdd']);
            expect(datepicker1.select()).to.equal(DATE.FORMAT['ddmmyyyy']);
        });

        it('should emit the "select" event', function () {
            expect(selectEvent).to.have.been.called();
        });
    });

    describe('Its pick() method', function () {
        it('should emit the "select" event', function () {
            datepicker1.pick("24");
            expect(selectEvent).to.have.been.called();
        });
    });

    describe('Its nextMonth() method', function(){
        var instance;

        before(function() {
            instance = datepicker1.nextMonth();
        });

        it('should emit the "nextmonth" event', function () {
            expect(nextmonthEvent).to.have.been.called();
        });

        it('should return the same instance than initialized component', function () {
            expect(instance).to.eql(datepicker1);
        });
    });

    describe('Its prevMonth() method', function(){
        var instance;

        before(function() {
            instance = datepicker1.prevMonth();
        });

        it('should emit the "prevmonth" event', function () {
            expect(prevmonthEvent).to.have.been.called();
        });

        it('should return the same instance than initialized component', function () {
            expect(instance).to.eql(datepicker1);
        });
    });

    describe('Its nextYear() method', function(){
        var instance;

        before(function() {
            instance = datepicker1.nextYear();
        });

        it('should emit the "nextyear" event', function () {
            expect(nextyearEvent).to.have.been.called();
        });

        it('should return the same instance than initialized component', function () {
            expect(instance).to.eql(datepicker1);
        });
    });

    describe('Its prevYear() method', function(){
        var instance;

        before(function() {
            instance = datepicker1.prevYear();
        });

        it('should emit the "prevyear" event', function () {
            expect(prevyearEvent).to.have.been.called();
        });

        it('should return the same instance than initialized component', function () {
            expect(instance).to.eql(datepicker1);
        });
    });

    describe('Its setFrom() method', function () {
        it('should return the same instance than initialized component', function () {
            expect(datepicker1.setFrom(DATE.FORMAT['yyyymmdd'])).to.equal(datepicker1);
        });
    });

    describe('Its setTo() method', function(){
        it('should return the same instance than initialized component', function () {
            expect(datepicker1.setTo(DATE.TODAY.year + 1 + '/' + DATE.TODAY.month + '/' + DATE.TODAY.day)).to.equal(datepicker1);
        });
    });

    describe('Its getToday() method', function(){
        it('should return the current date in the pre configured format DD/MM/YYYY or YYYY/MM/DD', function () {
            expect(datepicker1.getToday()).to.equal(DATE.FORMAT.ddmmyyyy);
        });
    });

    describe('Its destroy() method', function () {
        before(function(){
            datepicker2.on('destroy', function () { destroyEvent(); });
            datepicker2.destroy();
        });

        it('should update the field type attribute to "date"', function () {
            expect(document.getElementById('datepicker-2').type).to.equal('date');
        });

        it('should remove the calendar icon', function () {
            expect(datepicker2.field.nextElementSibling).to.be.null;
        });

        it('should emit the "destroy" event', function () {
            expect(destroyEvent).to.have.been.called();
        });
    });

});
<commit_msg>Update Datepicker test<commit_after>describe('Datepicker', function () {
    function addZero(num) {
        return (parseInt(num, 10) < 10) ? "0" + num : num;
    }

    var container = document.createElement('div'),
        datepickerHtml = [
            '<form action="/mock/ajax.html" class="YOUR_SELECTOR_FormDatepicker ch-form">',
                '
',
                    'Date: ',
                    '<input type="date" id="datepicker-1" placeholder="DD/MM/YYYY">',
                '
',
                '
',
                    'Date:',
                    '<input type="date" id="datepicker-2" placeholder="DD/MM/YYYY">',
                '
',
            '</form>'
        ].join(''),
        DATE = (function(){
            var date = new Date(),
                TODAY =  {
                    'day': addZero(date.getDate()),
                    'month': addZero((date.getMonth() + 1)),
                    'year': date.getFullYear()
                },
                FORMAT = {
                    'ddmmyyyy': [TODAY.day, TODAY.month, TODAY.year].join('/'),
                    'yyyymmdd': [TODAY.year, TODAY.month, TODAY.day].join('/')
                };
            return {
                'TODAY': TODAY,
                'FORMAT': FORMAT
            }
        })(),
        datepicker1,
        datepicker2,
        readyEvent,
        showEvent,
        hideEvent,
        selectEvent,
        nextmonthEvent,
        prevmonthEvent,
        nextyearEvent,
        prevyearEvent,
        destroyEvent;

    before(function () {
        container.innerHTML = datepickerHtml;
        document.body.appendChild(container);

        datepicker1 = new ch.Datepicker(document.getElementById('datepicker-1'));
        datepicker2 = new ch.Datepicker(document.getElementById('datepicker-2'));
        readyEvent = chai.spy();
        showEvent = chai.spy();
        hideEvent = chai.spy();
        selectEvent = chai.spy();
        nextmonthEvent = chai.spy();
        prevmonthEvent = chai.spy();
        nextyearEvent = chai.spy();
        prevyearEvent = chai.spy();
        destroyEvent = chai.spy();

        datepicker1
            .on('ready', readyEvent)
            .on('show', showEvent)
            .on('hide', hideEvent)
            .on('select', selectEvent)
            .on('nextmonth', nextmonthEvent)
            .on('prevmonth', prevmonthEvent)
            .on('nextyear', nextyearEvent)
            .on('prevyear', prevyearEvent);
    });

    after(function () {
        document.body.removeChild(container);
    });

    it('should be defined on ch object', function () {
        expect(ch.Datepicker).to.exist;
        expect(ch.Datepicker).to.be.a('function');
    });

    it('should be return a new instance', function () {
        expect(datepicker1).to.be.an.instanceof(ch.Datepicker);
    });

    it('should emit the "ready" event when it\'s created', function (done) {
        setTimeout(function(){
            expect(readyEvent).to.have.been.called();
            done();
        },50);
    });

    describe('should use the following abilities:', function () {
        it('EventEmitter', function () {
            expect(datepicker1.on).to.exist;
            expect(datepicker1.on).to.be.a('function');
        });
    });

    describe('It should have the following public properties:', function () {
        it('.field', function () {
            expect(datepicker1.field).to.exist;
            expect(datepicker1.field.nodeType).to.equal(1);
        });

        it('.name', function () {
            expect(datepicker1.name).to.exist;
            expect(datepicker1.name).to.be.a('string');
            expect(datepicker1.name).to.equal('datepicker');
        });

        it('.constructor', function () {
            expect(datepicker1.constructor).to.exist;
            expect(datepicker1.constructor).to.be.a('function');
        });

        it('.uid', function () {
            expect(datepicker1.uid).to.exist;
            expect(datepicker1.uid).to.be.a('number');
        });
    });

    describe('It should have the following public methods:', function () {
        var methods = ['destroy', 'show', 'hide', 'pick', 'getToday', 'setFrom', 'setTo', 'nextMonth', 'nextYear', 'prevMonth', 'prevYear', 'select', 'reset', 'enable', 'disable'],
            i = 0,
            len = methods.length;

        for (i; i < len; i += 1) {
            (function (i){
                it('.' + methods[i] + '()', function () {
                    expect(datepicker1[methods[i]]).to.exist;
                    expect(datepicker1[methods[i]]).to.be.a('function');
                });
            }(i));
        }
    });

    describe('It should have a input field associated', function () {
        var field;

        before(function(){
            field = datepicker1.field;
        });

        it('its type attribute should be updated to "text"', function () {
            expect(field.type).to.equal('text');
        });

        it('should have got the WAI-ARIA attribute "aria-describedby"', function () {
            expect(field.getAttribute('aria-describedby')).to.match(/^ch-popover-/);
        });
    });

    describe('It should create a trigger and', function () {
        var trigger;

        before(function(){
            trigger = datepicker1.trigger;
        });

        it('should be defined', function () {
            expect(datepicker1.trigger).to.exist;
            expect(datepicker1.trigger.nodeType).to.equal(1);
            expect(datepicker1.trigger).to.be.an.instanceof(HTMLElement);
        });

        describe('should have the following class names:', function () {
            it('.ch-datepicker-trigger', function () {
                expect(tiny.hasClass(trigger, 'ch-datepicker-trigger')).to.be.true;
            });

            it('.ch-icon-calendar', function () {
                expect(tiny.hasClass(trigger, 'ch-icon-calendar')).to.be.true;
            });
        });
    });

    describe('Its show() method', function () {
        it('should show a calendar', function () {
            datepicker1.show();
            expect(datepicker1._popover.isShown()).to.be.true;
        });

        it('should emit the "show" event', function () {
            expect(showEvent).to.have.been.called();
        });
    });

    describe('Its hide() method', function () {
        it('should hide a calendar', function () {
            datepicker1.hide();
            expect(datepicker1._popover.isShown()).to.be.false;
        });

        it('should emit the "hide" event', function () {
            expect(hideEvent).to.have.been.called();
        });
    });

    describe('Its select() method', function () {
        it('should return "undefined" when it hasn\'t got a date selected', function () {
            expect(datepicker1.select()).to.be.undefined;
        });

        it('should set a date as calendar.select(\'yyyy/mm/dd\')', function () {
            datepicker1.select(DATE.FORMAT['yyyymmdd']);
            expect(datepicker1.select()).to.equal(DATE.FORMAT['ddmmyyyy']);
        });

        it('should emit the "select" event', function () {
            expect(selectEvent).to.have.been.called();
        });
    });

    describe('Its pick() method', function () {
        it('should emit the "select" event', function () {
            datepicker1.pick("24");
            expect(selectEvent).to.have.been.called();
        });
    });

    describe('Its nextMonth() method', function(){
        var instance;

        before(function() {
            instance = datepicker1.nextMonth();
        });

        it('should emit the "nextmonth" event', function () {
            expect(nextmonthEvent).to.have.been.called();
        });

        it('should return the same instance than initialized component', function () {
            expect(instance).to.eql(datepicker1);
        });
    });

    describe('Its prevMonth() method', function(){
        var instance;

        before(function() {
            instance = datepicker1.prevMonth();
        });

        it('should emit the "prevmonth" event', function () {
            expect(prevmonthEvent).to.have.been.called();
        });

        it('should return the same instance than initialized component', function () {
            expect(instance).to.eql(datepicker1);
        });
    });

    describe('Its nextYear() method', function(){
        var instance;

        before(function() {
            instance = datepicker1.nextYear();
        });

        it('should emit the "nextyear" event', function () {
            expect(nextyearEvent).to.have.been.called();
        });

        it('should return the same instance than initialized component', function () {
            expect(instance).to.eql(datepicker1);
        });
    });

    describe('Its prevYear() method', function(){
        var instance;

        before(function() {
            instance = datepicker1.prevYear();
        });

        it('should emit the "prevyear" event', function () {
            expect(prevyearEvent).to.have.been.called();
        });

        it('should return the same instance than initialized component', function () {
            expect(instance).to.eql(datepicker1);
        });
    });

    describe('Its setFrom() method', function () {
        it('should return the same instance than initialized component', function () {
            expect(datepicker1.setFrom(DATE.FORMAT['yyyymmdd'])).to.equal(datepicker1);
        });
    });

    describe('Its setTo() method', function(){
        it('should return the same instance than initialized component', function () {
            expect(datepicker1.setTo(DATE.TODAY.year + 1 + '/' + DATE.TODAY.month + '/' + DATE.TODAY.day)).to.equal(datepicker1);
        });
    });

    describe('Its getToday() method', function(){
        it('should return the current date in the pre configured format DD/MM/YYYY or YYYY/MM/DD', function () {
            expect(datepicker1.getToday()).to.equal(DATE.FORMAT.ddmmyyyy);
        });
    });

    describe('Its destroy() method', function () {
        before(function(){
            datepicker2.on('destroy', function () { destroyEvent(); });
            datepicker2.destroy();
        });

        // TODO: Review this behaviour in PhantomJS v2.x and IE, skipped for now
        it.skip('should update the field type attribute to "date"', function () {
            expect(document.getElementById('datepicker-2').type).to.equal('date');
        });

        it('should remove the ARIA label', function () {
            expect(document.getElementById('datepicker-2').getAttribute('aria-describedby')).to.be.null;
        });

        it('should remove the calendar icon', function () {
            expect(datepicker2.field.nextElementSibling).to.be.null;
        });

        it('should emit the "destroy" event', function () {
            expect(destroyEvent).to.have.been.called();
        });
    });

});
<|endoftext|>


<commit_before>'use strict';

const test = require('tape');
const remote = require('../marklogic-remote')(/* connection */);
const parseTAP = require('../lib/tap-helpers').parseTAP;

test('assert.deepEqual()', (assert) => {
  assert.plan(7);
  remote('test/deep-equal.test.sjs') // CHANGE ME
    .then((tap) => parseTAP(tap))
    .then(tap => {
      assert.equal(tap.count, 2);
      assert.equal(tap.pass, 1);
      assert.equal(tap.fail, 1);
      const failure = tap.failures[0];
      assert.skip(failure.diag.expected, '?'); // Depends on #19
      assert.skip(failure.diag.actual, '?'); // Depends on #19
      assert.equal(failure.diag.at, 'Test.impl (/mltap/mltap.js:7:10)'); // Depends on #20
      assert.equal(failure.diag.operator, 'deepEqual', 'Operator is deepEqual');
    })
    .catch(error => assert.fail(error));
});

<commit_msg>Implements skipped tests<commit_after>'use strict';

const test = require('tape');
const remote = require('../marklogic-remote')(/* connection */);
const parseTAP = require('../lib/tap-helpers').parseTAP;

test('assert.deepEqual()', (assert) => {
  assert.plan(7);
  remote('test/deep-equal.test.sjs') // CHANGE ME
    .then((tap) => parseTAP(tap))
    .then(tap => {
      assert.equal(tap.count, 2, 'count');
      assert.equal(tap.pass, 1, 'pass');
      assert.equal(tap.fail, 1, 'fail');
      const failure = tap.failures[0];
      assert.equal(failure.diag.expected, 'Array []', 'expected Array');
      assert.equal(failure.diag.actual, 'Object {\n  "a": "A",\n}', 'actual Object');
      assert.equal(failure.diag.at, 'Test.impl (/mltap/mltap.js:7:10)', 'at stack frame');
      assert.equal(failure.diag.operator, 'deepEqual', 'operator is deepEqual');
    })
    .catch(error => assert.fail(error));
});

<|endoftext|>


<commit_before>module.exports = require('./lib/pty_win.js');
<commit_msg>Check if windows, then load pty_win.js if unix* then load pty.js<commit_after>var os = process.platform === 'win32' ? '_win' : '';
module.exports = require('./lib/pty'+ os +'.js');
<|endoftext|>


<commit_before>var toNum = function (str) {
  if (!str || typeof str !== 'string') {
    throw new Error('non-string input');
  }
  var i, j = str.length;
  var num = new Array(j);
  var c;
  for (i = 0; i < j; i++) {
    c = str.charCodeAt(i);
    if (c < 48 || c > 57) {
      throw new Error('non-numeric string');
    }
    num[i] = c - 48;
  }
  return num;
};

var toStr = function (num) {
  return num.join('');
};

var nextNum = function (num) {
  var i, j;
  var carry = 1;
  i = j = num.length;
  var next = new Array(j);
  while (i) {
    var dig = num[i - 1];
    var succ = (dig + carry) % 10;
    next[i - 1] = succ;
    carry = dig == 9;
    i--;
  }
  if (carry) {
    next.unshift(1);
  }
  return next;
};

var mkNum = function (num) {
  return {
    next: function () { return mkNum(nextNum(num)); },
    toString: function () { return toStr(num); },
    toJSON: function () { return toStr(num); }
  };
};

module.exports = function (str) {
  return mkNum(toNum(str));
};
<commit_msg>fix carry bit<commit_after>var toNum = function (str) {
  if (!str || typeof str !== 'string') {
    throw new Error('non-string input');
  }
  var i, j = str.length;
  var num = new Array(j);
  var c;
  for (i = 0; i < j; i++) {
    c = str.charCodeAt(i);
    if (c < 48 || c > 57) {
      throw new Error('non-numeric string');
    }
    num[i] = c - 48;
  }
  return num;
};

var toStr = function (num) {
  return num.join('');
};

var nextNum = function (num) {
  var i, j;
  var carry = 1;
  i = j = num.length;
  var next = new Array(j);
  while (i) {
    var dig = num[i - 1];
    var succ = (dig + carry) % 10;
    next[i - 1] = succ;
    carry = carry && dig == 9;
    i--;
  }
  if (carry) {
    next.unshift(1);
  }
  return next;
};

var mkNum = function (num) {
  return {
    next: function () { return mkNum(nextNum(num)); },
    toString: function () { return toStr(num); },
    toJSON: function () { return toStr(num); }
  };
};

module.exports = function (str) {
  return mkNum(toNum(str));
};
<|endoftext|>


<commit_before>'use strict'

const URL    = require('url'),
      http   = require('http'),
      https  = require('https'),
      zlib   = require('zlib'),
      wrapper = require('socks-wrapper'),
      extend = require('util')._extend

process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0

module.exports = (url, options, next) => {
  if (typeof url === 'undefined') {
    throw 'Nothing to request'
  }

  if (typeof options == 'undefined' || typeof options === 'function') {
    next = options
    options = {}
  }

  let headers = extend({
    'Accept-Encoding': 'gzip, deflate',
    'User-Agent': 'Mozilla/5.0 yareq/0.1'
  }, 'headers' in options ? options.headers : null)

  options = extend({
    socketTimeout: -1,
    followLocation: false,
    maxRedirect: 2,
    inflateContent: false
  }, options)

  options.headers = headers

  let data = null

  if ('data' in options) {
    data = options.data
    delete options.data
    if (data && !('method' in options)) {
      options.method = 'POST'
    }
  }

  let dummy = (err, res, body) => {
    if (err) throw err
    console.log(`HTTP/${res.httpVersion} ${res.statusCode} ${res.statusMessage}`)
    console.log(body.toString())
  }

  next = next || dummy

  function rewrite(url) {
    if (!/^\w+:/.test(url)) {
      if (url.substr(0,2) !== '//') {
        url = 'http://' + url
      }
      else {
        url = 'http:' + url
      }
    }
    return url
  }

  if (typeof url === 'string') {
    url = URL.parse(rewrite(url))
  }

  let redirectCount = 0

  let doGet = (url, next) => {
    extend(options, url)
    let proto = url.protocol === 'https:' ? https : http
    if (options.proxy) {
      let proxy = URL.parse(rewrite(options.proxy))
      if (/^socks/.test(proxy.protocol)) {
        let Agent = proto === http ? wrapper.HttpAgent : wrapper.HttpsAgent
        options.agent = new Agent(proxy.port, proxy.hostname)
      }
      else {
        proto = proxy.protocol === 'https:' ? https : http
        options.protocol = proxy.protocol
        options.host = proxy.hostname
        options.port = proxy.port
        options.path = url.href
        delete options.hostname
      }
    }

    let req = proto.request(options, (res) => {
      let chunks = []
      res.on('data', (chunk) => {
        chunks.push(chunk)
      })
      res.on('end', () => {
        if (options.followLocation && res.statusCode >= 300 &&
            res.statusCode <= 399 && 'location' in res.headers) {
          if (redirectCount++ >= options.maxRedirect) {
            return next('Too many redirects')
          }
          url = URL.parse(URL.resolve(url.href, res.headers.location))
          return doGet(url, next)
        }
        if (redirectCount > 0) {
          res.headers['x-effective-url'] = url.href
        }
        let encoding = res.headers['content-encoding'],
            content = Buffer.concat(chunks)
        if (options.inflateContent && (encoding === 'gzip'||
            encoding === 'deflate')) {
          if (encoding === 'gzip') {
            zlib.gunzip(content, function(err, buf) {
              next(err, res, buf)
            })
          }
          else {
            zlib.inflate(content, function(err, buf) {
              if (err) {
                zlib.inflateRaw(content, function(err, buf) {
                  next(err, res, buf)
                })
              }
              else {
                next(err, res, buf)
              }
            })
          }
        }
        else {
          next(null, res, content)
        }
      })
    })

    if (data) {
      if (typeof data === 'object' && !(data instanceof Buffer)) {
        data = JSON.stringify(data)
      }
      req.write(data)
    }

    if (options.socketTimeout > 0) {
      req.on('socket', function (socket) {
        socket.setTimeout(options.socketTimeout)
        socket.on('timeout', function() {
          // Socket timeout
          req.abort()
        })
      })
    }

    req.on('error', (err) => {
      next(err)
    })

    req.end()
  }

  doGet(url, next)
}
<commit_msg>Add support for cookie jar<commit_after>'use strict'

const URL    = require('url'),
      http   = require('http'),
      https  = require('https'),
      zlib   = require('zlib'),
      wrapper = require('socks-wrapper'),
      extend = require('util')._extend

process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0

module.exports = (url, options, next) => {
  if (typeof url === 'undefined') {
    throw 'Nothing to request'
  }

  if (typeof options == 'undefined' || typeof options === 'function') {
    next = options
    options = {}
  }

  let headers = extend({
    'Accept-Encoding': 'gzip, deflate',
    'User-Agent': 'Mozilla/5.0 yareq/0.1'
  }, 'headers' in options ? options.headers : null)

  options = extend({
    socketTimeout: -1,
    followLocation: false,
    maxRedirect: 2,
    inflateContent: false
  }, options)

  options.headers = headers

  let data = null

  if ('data' in options) {
    data = options.data
    delete options.data
    if (data && !('method' in options)) {
      options.method = 'POST'
    }
  }

  let dummy = (err, res, body) => {
    if (err) throw err
    console.log(`HTTP/${res.httpVersion} ${res.statusCode} ${res.statusMessage}`)
    console.log(body.toString())
  }

  next = next || dummy

  function rewrite(url) {
    if (!/^\w+:/.test(url)) {
      if (url.substr(0,2) !== '//') {
        url = 'http://' + url
      }
      else {
        url = 'http:' + url
      }
    }
    return url
  }

  if (typeof url === 'string') {
    url = URL.parse(rewrite(url))
  }

  // This can be an instance of touch-cookie's CookieJar
  let cookieJar = null
  if ('cookieJar' in options) {
    cookieJar = options.cookieJar
    delete options.cookieJar
    let cookie = cookieJar.getCookieStringSync(url)
    if (cookie) {
      options.headers['Cookie'] = cookie
    }
  }

  let redirectCount = 0

  let doGet = (url, next) => {
    extend(options, url)
    let proto = url.protocol === 'https:' ? https : http
    if (options.proxy) {
      let proxy = URL.parse(rewrite(options.proxy))
      if (/^socks/.test(proxy.protocol)) {
        let Agent = proto === http ? wrapper.HttpAgent : wrapper.HttpsAgent
        options.agent = new Agent(proxy.port, proxy.hostname)
      }
      else {
        proto = proxy.protocol === 'https:' ? https : http
        options.protocol = proxy.protocol
        options.host = proxy.hostname
        options.port = proxy.port
        options.path = url.href
        delete options.hostname
      }
    }

    let req = proto.request(options, (res) => {
      if (cookieJar && ('set-cookie' in res.headers)) {
        let cookies = res.headers['set-cookie']
        if (!Array.isArray(cookies)) {
          cookieJar.setCookieSync(cookies, url.href)
        }
        else {
          cookies.forEach(cookie => {
            cookieJar.setCookieSync(cookie, url)
          })
        }
      }

      let chunks = []
      res.on('data', (chunk) => {
        chunks.push(chunk)
      })
      res.on('end', () => {
        if (options.followLocation && res.statusCode >= 300 &&
            res.statusCode <= 399 && 'location' in res.headers) {
          if (redirectCount++ >= options.maxRedirect) {
            return next('Too many redirects')
          }
          url = URL.parse(URL.resolve(url.href, res.headers.location))
          return doGet(url, next)
        }
        if (redirectCount > 0) {
          res.headers['x-effective-url'] = url.href
        }
        let encoding = res.headers['content-encoding'],
            content = Buffer.concat(chunks)
        if (options.inflateContent && (encoding === 'gzip'||
            encoding === 'deflate')) {
          if (encoding === 'gzip') {
            zlib.gunzip(content, function(err, buf) {
              next(err, res, buf)
            })
          }
          else {
            zlib.inflate(content, function(err, buf) {
              if (err) {
                zlib.inflateRaw(content, function(err, buf) {
                  next(err, res, buf)
                })
              }
              else {
                next(err, res, buf)
              }
            })
          }
        }
        else {
          next(null, res, content)
        }
      })
    })

    if (data) {
      if (typeof data === 'object' && !(data instanceof Buffer)) {
        data = JSON.stringify(data)
      }
      req.write(data)
    }

    if (options.socketTimeout > 0) {
      req.on('socket', function (socket) {
        socket.setTimeout(options.socketTimeout)
        socket.on('timeout', function() {
          // Socket timeout
          req.abort()
        })
      })
    }

    req.on('error', (err) => {
      next(err)
    })

    req.end()
  }

  doGet(url, next)
}
<|endoftext|>