<commit_before>'use strict';

module.exports = Parse.create = Parse;

require("setimmediate");
var Transform = require('stream').Transform;
var inherits = require('util').inherits;
var zlib = require('zlib');
var binary = require('binary');
var PullStream = require('pullstream');
var MatchStream = require('match-stream');
var Entry = require('./entry');

if (!Transform) {
  Transform = require('readable-stream/transform');
}

inherits(Parse, Transform);

function Parse(opts) {
  var self = this;
  if (!(this instanceof Parse)) {
    return new Parse(opts);
  }

  Transform.call(this, { lowWaterMark: 0 });
  this._opts = opts || { verbose: false };
  this._hasEntryListener = false;

  this._pullStream = new PullStream();
  this._pullStream.on("error", function (e) {
    self.emit('error', e);
  });
  this._pullStream.once("end", function () {
    self._streamEnd = true;
  });
  this._pullStream.once("finish", function () {
    self._streamFinish = true;
  });

  this._readRecord();
}

Parse.prototype._readRecord = function () {
  var self = this;
  this._pullStream.pull(4, function (err, data) {
    if (err) {
      return self.emit('error', err);
    }

    if (data.length === 0) {
      return;
    }

    var signature = data.readUInt32LE(0);
    if (signature === 0x04034b50) {
      self._readFile();
    } else if (signature === 0x02014b50) {
      self._readCentralDirectoryFileHeader();
    } else if (signature === 0x06054b50) {
      self._readEndOfCentralDirectoryRecord();
    } else {
      err = new Error('invalid signature: 0x' + signature.toString(16));
      self.emit('error', err);
    }
  });
};

Parse.prototype._readFile = function () {
  var self = this;
  this._pullStream.pull(26, function (err, data) {
    if (err) {
      return self.emit('error', err);
    }

    var vars = binary.parse(data)
      .word16lu('versionsNeededToExtract')
      .word16lu('flags')
      .word16lu('compressionMethod')
      .word16lu('lastModifiedTime')
      .word16lu('lastModifiedDate')
      .word32lu('crc32')
      .word32lu('compressedSize')
      .word32lu('uncompressedSize')
      .word16lu('fileNameLength')
      .word16lu('extraFieldLength')
      .vars;

    return self._pullStream.pull(vars.fileNameLength, function (err, fileName) {
      if (err) {
        return self.emit('error', err);
      }
      fileName = fileName.toString('utf8');
      var entry = new Entry();
      entry.path = fileName;
      entry.props.path = fileName;
      entry.type = (vars.compressedSize === 0 && /[\/\\]$/.test(fileName)) ? 'Directory' : 'File';

      if (self._opts.verbose) {
        if (entry.type === 'Directory') {
          console.log('   creating:', fileName);
        } else if (entry.type === 'File') {
          if (vars.compressionMethod === 0) {
            console.log(' extracting:', fileName);
          } else {
            console.log('  inflating:', fileName);
          }
        }
      }

      var hasEntryListener = self._hasEntryListener;
      if (hasEntryListener) {
        self.emit('entry', entry);
      }

      self._pullStream.pull(vars.extraFieldLength, function (err, extraField) {
        if (err) {
          return self.emit('error', err);
        }
        if (entry.type === 'Directory') {
          self._pullStream.pull(vars.compressedSize, function (err, compressedData) {
            if (err) {
              return self.emit('error', err);
            }

            if (hasEntryListener) {
              entry.write(compressedData);
              entry.end();
            }

            return self._readRecord();
          });
        } else {
          var fileSizeKnown = !(vars.flags & 0x08);
          var has_compression = !(vars.compressionMethod === 0);
          var inflater;

          if(has_compression) {
            inflater = zlib.createInflateRaw();
            inflater.on('error', function (err) {
              self.emit('error', err);
            });
          }

          if (fileSizeKnown) {
            entry.size = vars.uncompressedSize;
            if (hasEntryListener) {
              entry.on('finish', self._readRecord.bind(self));
              if(has_compression) {
                self._pullStream.pipe(vars.compressedSize, inflater).pipe(entry);
              } else {
                self._pullStream.pipe(vars.compressedSize, entry);
              }
            } else {
              self._pullStream.drain(vars.compressedSize, function (err) {
                if (err) {
                  return self.emit('error', err);
                }
                self._readRecord();
              });
            }
          } else {
            var descriptorSig = new Buffer(4);
            descriptorSig.writeUInt32LE(0x08074b50, 0);

            var matchStream = new MatchStream({ pattern: descriptorSig }, function (buf, matched, extra) {
              if (hasEntryListener) {
                if (!matched) {
                  return this.push(buf);
                }
                this.push(buf);
              }
              self._pullStream.unpipe();
              self._pullStream.prepend(extra);
              setImmediate(function() {
                self._processDataDescriptor(entry);
              });
              return this.push(null);
            });

            self._pullStream.pipe(matchStream);
            if (hasEntryListener) {
              if(has_compression) {
                matchStream.pipe(inflater).pipe(entry);
              } else {
                matchStream.pipe(entry);
              }
            }
          }
        }
      });
    });
  });
};

Parse.prototype._processDataDescriptor = function (entry) {
  var self = this;
  this._pullStream.pull(16, function (err, data) {
    if (err) {
      return self.emit('error', err);
    }

    var vars = binary.parse(data)
      .word32lu('dataDescriptorSignature')
      .word32lu('crc32')
      .word32lu('compressedSize')
      .word32lu('uncompressedSize')
      .vars;

    entry.size = vars.uncompressedSize;
    self._readRecord();
  });
};

Parse.prototype._readCentralDirectoryFileHeader = function () {
  var self = this;
  this._pullStream.pull(42, function (err, data) {
    if (err) {
      return self.emit('error', err);
    }

    var vars = binary.parse(data)
      .word16lu('versionMadeBy')
      .word16lu('versionsNeededToExtract')
      .word16lu('flags')
      .word16lu('compressionMethod')
      .word16lu('lastModifiedTime')
      .word16lu('lastModifiedDate')
      .word32lu('crc32')
      .word32lu('compressedSize')
      .word32lu('uncompressedSize')
      .word16lu('fileNameLength')
      .word16lu('extraFieldLength')
      .word16lu('fileCommentLength')
      .word16lu('diskNumber')
      .word16lu('internalFileAttributes')
      .word32lu('externalFileAttributes')
      .word32lu('offsetToLocalFileHeader')
      .vars;

    return self._pullStream.pull(vars.fileNameLength, function (err, fileName) {
      if (err) {
        return self.emit('error', err);
      }
      fileName = fileName.toString('utf8');

      self._pullStream.pull(vars.extraFieldLength, function (err, extraField) {
        if (err) {
          return self.emit('error', err);
        }
        self._pullStream.pull(vars.fileCommentLength, function (err, fileComment) {
          if (err) {
            return self.emit('error', err);
          }
          return self._readRecord();
        });
      });
    });
  });
};

Parse.prototype._readEndOfCentralDirectoryRecord = function () {
  var self = this;
  this._pullStream.pull(18, function (err, data) {
    if (err) {
      return self.emit('error', err);
    }

    var vars = binary.parse(data)
      .word16lu('diskNumber')
      .word16lu('diskStart')
      .word16lu('numberOfRecordsOnDisk')
      .word16lu('numberOfRecords')
      .word32lu('sizeOfCentralDirectory')
      .word32lu('offsetToStartOfCentralDirectory')
      .word16lu('commentLength')
      .vars;

    if (vars.commentLength) {
      setImmediate(function() {
        self._pullStream.pull(vars.commentLength, function (err, comment) {
          if (err) {
            return self.emit('error', err);
          }
          comment = comment.toString('utf8');
          return self._pullStream.end();
        });
      });

    } else {
      self._pullStream.end();
    }
  });
};

Parse.prototype._transform = function (chunk, encoding, callback) {
  if (this._pullStream.write(chunk)) {
    return callback();
  }

  this._pullStream.once('drain', callback);
};

Parse.prototype.pipe = function (dest, opts) {
  var self = this;
  if (typeof dest.add === "function") {
    self.on("entry", function (entry) {
      dest.add(entry);
    })
  }
  return Transform.prototype.pipe.apply(this, arguments);
};

Parse.prototype._flush = function (callback) {
  if (!this._streamEnd || !this._streamFinish) {
    return setImmediate(this._flush.bind(this, callback));
  }

  this.emit('close');
  return callback();
};

Parse.prototype.addListener = function(type, listener) {
  if ('entry' === type) {
    this._hasEntryListener = true;
  }
  return Transform.prototype.addListener.call(this, type, listener);
};

Parse.prototype.on = Parse.prototype.addListener;<commit_msg>issue #4 bugfix<commit_after>'use strict';

module.exports = Parse.create = Parse;

require("setimmediate");
var Transform = require('stream').Transform;
var inherits = require('util').inherits;
var zlib = require('zlib');
var binary = require('binary');
var PullStream = require('pullstream');
var MatchStream = require('match-stream');
var Entry = require('./entry');

if (!Transform) {
  Transform = require('readable-stream/transform');
}

inherits(Parse, Transform);

function Parse(opts) {
  var self = this;
  if (!(this instanceof Parse)) {
    return new Parse(opts);
  }

  Transform.call(this, { lowWaterMark: 0 });
  this._opts = opts || { verbose: false };
  this._hasEntryListener = false;

  this._pullStream = new PullStream();
  this._pullStream.on("error", function (e) {
    self.emit('error', e);
  });
  this._pullStream.once("end", function () {
    self._streamEnd = true;
  });
  this._pullStream.once("finish", function () {
    self._streamFinish = true;
  });

  this._readRecord();
}

Parse.prototype._readRecord = function () {
  var self = this;
  this._pullStream.pull(4, function (err, data) {
    if (err) {
      return self.emit('error', err);
    }

    if (data.length === 0) {
      return;
    }

    var signature = data.readUInt32LE(0);
    if (signature === 0x04034b50) {
      self._readFile();
    } else if (signature === 0x02014b50) {
      self._readCentralDirectoryFileHeader();
    } else if (signature === 0x06054b50) {
      self._readEndOfCentralDirectoryRecord();
    } else {
      err = new Error('invalid signature: 0x' + signature.toString(16));
      self.emit('error', err);
    }
  });
};

Parse.prototype._readFile = function () {
  var self = this;
  this._pullStream.pull(26, function (err, data) {
    if (err) {
      return self.emit('error', err);
    }

    var vars = binary.parse(data)
      .word16lu('versionsNeededToExtract')
      .word16lu('flags')
      .word16lu('compressionMethod')
      .word16lu('lastModifiedTime')
      .word16lu('lastModifiedDate')
      .word32lu('crc32')
      .word32lu('compressedSize')
      .word32lu('uncompressedSize')
      .word16lu('fileNameLength')
      .word16lu('extraFieldLength')
      .vars;

    return self._pullStream.pull(vars.fileNameLength, function (err, fileName) {
      if (err) {
        return self.emit('error', err);
      }
      fileName = fileName.toString('utf8');
      var entry = new Entry();
      entry.path = fileName;
      entry.props.path = fileName;
      entry.type = (vars.compressedSize === 0 && /[\/\\]$/.test(fileName)) ? 'Directory' : 'File';

      if (self._opts.verbose) {
        if (entry.type === 'Directory') {
          console.log('   creating:', fileName);
        } else if (entry.type === 'File') {
          if (vars.compressionMethod === 0) {
            console.log(' extracting:', fileName);
          } else {
            console.log('  inflating:', fileName);
          }
        }
      }

      var hasEntryListener = self._hasEntryListener;
      if (hasEntryListener) {
        self.emit('entry', entry);
      }

      self._pullStream.pull(vars.extraFieldLength, function (err, extraField) {
        if (err) {
          return self.emit('error', err);
        }
        if (entry.type === 'Directory') {
          self._pullStream.pull(vars.compressedSize, function (err, compressedData) {
            if (err) {
              return self.emit('error', err);
            }

            if (hasEntryListener) {
              entry.write(compressedData);
              entry.end();
            }

            return self._readRecord();
          });
        } else {
          var fileSizeKnown = !(vars.flags & 0x08);
          var has_compression = !(vars.compressionMethod === 0);
          var inflater;

          if(has_compression) {
            inflater = zlib.createInflateRaw();
            inflater.on('error', function (err) {
              self.emit('error', err);
            });
          }

          if (fileSizeKnown) {
            entry.size = vars.uncompressedSize;
            if (hasEntryListener) {
              entry.on('finish', self._readRecord.bind(self));
              if(has_compression) {
                self._pullStream.pipe(vars.compressedSize, inflater).pipe(entry);
              } else {
                self._pullStream.pipe(vars.compressedSize, entry);
              }
            } else {
              self._pullStream.drain(vars.compressedSize, function (err) {
                if (err) {
                  return self.emit('error', err);
                }
                self._readRecord();
              });
            }
          } else {
            var descriptorSig = new Buffer(4);
            descriptorSig.writeUInt32LE(0x08074b50, 0);

            var matchStream = new MatchStream({ pattern: descriptorSig }, function (buf, matched, extra) {
              if (hasEntryListener) {
                if (!matched) {
                  return this.push(buf);
                }
                this.push(buf);
              }
              self._pullStream.unpipe();
              self._pullStream.prepend(extra);
              setImmediate(function() {
                self._processDataDescriptor(entry);
              });
              return this.push(null);
            });

            self._pullStream.pipe(matchStream);
            if (hasEntryListener) {
              if(has_compression) {
                matchStream.pipe(inflater).pipe(entry);
              } else {
                matchStream.pipe(entry);
              }
            }
          }
        }
      });
    });
  });
};

Parse.prototype._processDataDescriptor = function (entry) {
  var self = this;
  this._pullStream.pull(16, function (err, data) {
    if (err) {
      return self.emit('error', err);
    }

    var vars = binary.parse(data)
      .word32lu('dataDescriptorSignature')
      .word32lu('crc32')
      .word32lu('compressedSize')
      .word32lu('uncompressedSize')
      .vars;

    entry.size = vars.uncompressedSize;
    self._readRecord();
  });
};

Parse.prototype._readCentralDirectoryFileHeader = function () {
  var self = this;
  this._pullStream.pull(42, function (err, data) {
    if (err) {
      return self.emit('error', err);
    }

    var vars = binary.parse(data)
      .word16lu('versionMadeBy')
      .word16lu('versionsNeededToExtract')
      .word16lu('flags')
      .word16lu('compressionMethod')
      .word16lu('lastModifiedTime')
      .word16lu('lastModifiedDate')
      .word32lu('crc32')
      .word32lu('compressedSize')
      .word32lu('uncompressedSize')
      .word16lu('fileNameLength')
      .word16lu('extraFieldLength')
      .word16lu('fileCommentLength')
      .word16lu('diskNumber')
      .word16lu('internalFileAttributes')
      .word32lu('externalFileAttributes')
      .word32lu('offsetToLocalFileHeader')
      .vars;

    return self._pullStream.pull(vars.fileNameLength, function (err, fileName) {
      if (err) {
        return self.emit('error', err);
      }
      fileName = fileName.toString('utf8');

      self._pullStream.pull(vars.extraFieldLength, function (err, extraField) {
        if (err) {
          return self.emit('error', err);
        }
        self._pullStream.pull(vars.fileCommentLength, function (err, fileComment) {
          if (err) {
            return self.emit('error', err);
          }
          return self._readRecord();
        });
      });
    });
  });
};

Parse.prototype._readEndOfCentralDirectoryRecord = function () {
  var self = this;
  this._pullStream.pull(18, function (err, data) {
    if (err) {
      return self.emit('error', err);
    }

    var vars = binary.parse(data)
      .word16lu('diskNumber')
      .word16lu('diskStart')
      .word16lu('numberOfRecordsOnDisk')
      .word16lu('numberOfRecords')
      .word32lu('sizeOfCentralDirectory')
      .word32lu('offsetToStartOfCentralDirectory')
      .word16lu('commentLength')
      .vars;

    if (vars.commentLength) {
      setImmediate(function() {
        self._pullStream.pull(vars.commentLength, function (err, comment) {
          if (err) {
            return self.emit('error', err);
          }
          comment = comment.toString('utf8');
          return self._pullStream.end();
        });
      });

    } else {
      self._pullStream.end();
    }
  });
};

Parse.prototype._transform = function (chunk, encoding, callback) {
  if (this._pullStream.write(chunk)) {
    return callback();
  }

  this._pullStream.once('drain', callback);
};

Parse.prototype.pipe = function (dest, opts) {
  var self = this;
  if (typeof dest.add === "function") {
    self.on("entry", function (entry) {
      dest.add(entry);
    })
  }
  return Transform.prototype.pipe.apply(this, arguments);
};

Parse.prototype._flush = function (callback) {
  if (!this._streamEnd || !this._streamFinish) {
    return setImmediate(this._flush.bind(this, callback));
  }

  var r = callback();
  this.emit('close');
  return r;
};

Parse.prototype.addListener = function(type, listener) {
  if ('entry' === type) {
    this._hasEntryListener = true;
  }
  return Transform.prototype.addListener.call(this, type, listener);
};

Parse.prototype.on = Parse.prototype.addListener;
<|endoftext|>


<commit_before>'use strict';

/* deps: mocha */
var assert = require('assert');
var minimist = require('minimist');
var plugins = require('./');
var cli;

describe('minimist', function () {
  beforeEach(function () {
    cli = plugins(minimist);
  });

  it('should throw if `minimist` not function', function (done) {
    function fixture () {
      plugins(123);
    }
    assert.throws(fixture, TypeError);
    assert.throws(fixture, /expect `minimist` be function/);
    done();
  });

  it('should pass error from async plugins', function (done) {
    cli.use(function () {
      return function (argv, next) {
        argv.foo = 'bar';
        next(new Error('foo bar'));
      };
    });
    cli.parse(['--foo=bar'], function (err, argv) {
      assert.ifError(!err);
      assert.ok(!argv);
      assert.equal(err.message, 'foo bar');
      done();
    });
  });

  it('should parse arguments without any plugins:', function (done) {
    cli.parse(['--a', '--b'], function (err, argv) {
      assert.ifError(err);
      assert.equal(argv.a, true);
      assert.equal(argv.b, true);
      done();
    });
  });

  it('should chain plugins:', function () {
    cli.use(function () {
        return function (argv) {
          argv.foo = 'bar';
        };
      })
      .use(function () {
        return function (argv) {
          argv.baz = 'quux';
        };
      });

    cli.parse(['--a', '--b'], function (err, argv) {
      assert.ifError(err);
      assert.equal(argv.foo === 'bar', true);
      assert.equal(argv.baz === 'quux', true);
      assert.equal(argv.a === true, true);
      assert.equal(argv.b === true, true);
      done();
    });
  });

  it('should expose args on the `argv` object:', function (done) {
    cli.parse(['a', 'b', 'c'], function (err, res) {
      assert.ifError(err);
      assert.deepEqual(res._, ['a', 'b', 'c']);
      done();
    });
  });

  it('should expose options on the `argv` object:', function (done) {
    cli.parse(['a', 'b', 'c', '--foo=bar'], function (err, res) {
      assert.ifError(err);
      assert.equal(res.foo, 'bar');
      done();
    });
  });

  it('should emit `end` after all args are emitted:', function (done) {
    var i = 0;
    function set(key, value) {
      return function (cli) {
        return function (argv, next) {
          argv[key] = value;
          next(null, argv);
        };
      };
    }

    cli.use(set('aaa', 'bbb'))
    cli.use(set('ccc', 'ddd'))
    cli.use(set('eee', 'fff'))

    cli.on('end', function (argv) {
      assert.equal(argv.aaa, 'bbb');
      assert.equal(argv.ccc, 'ddd');
      assert.equal(argv.eee, 'fff');
      i++;
    });

    cli.parse(['a', 'b', 'c', '--foo=bar'], function (err, argv) {
      assert.ifError(err);
      assert.equal(i, 1);
      assert.equal(argv.aaa, 'bbb');
      assert.equal(argv.ccc, 'ddd');
      assert.equal(argv.eee, 'fff');
      done();
    });
  });

  it('should done callback be optional', function (done) {
    var res = cli.parse(['a', 'b']);
    assert.equal(typeof res.minimist, 'function');
    done();
  });

  it('should result have parsed `.argv` property', function (done) {
    var res = cli.parse(['--foo=bar', '--baz=qux']);
    assert.equal(typeof res.minimist, 'function');
    assert.equal(res.argv.foo, 'bar');
    assert.equal(res.argv.baz, 'qux');
    done();
  });

  it('should result have processed `.argv` property', function (done) {
    cli.use(function () {
      return function (argv, next) {
        argv.foo = 'bar2';
        argv.baz = 'qux2';
        next(null, argv);
      };
    });
    var res = cli.parse(['--foo=bar', '--baz=qux']);
    assert.equal(typeof res.minimist, 'function');
    assert.equal(res.argv.foo, 'bar2');
    assert.equal(res.argv.baz, 'qux2');
    done();
  });

  it('should merge options', function (done) {
    cli = plugins(minimist, {a: 'b'});
    var res = cli.parse(['--foo=bar'], {c: 'd'});
    assert.equal(res.options.a, 'b');
    assert.equal(res.options.c, 'd');
    assert.equal(res.argv.foo, 'bar');
    done();
  });

  it('should add/modify options from plugins', function (done) {
    cli = plugins(minimist, {foo: 'bar'});
    cli.use(function (self) {
      return function (argv, next) {
        self.options.foo = 'abc';
        self.options.baz = 'qux';
        next(null, argv);
      };
    });

    cli.parse(['--abc=def'], function (err, argv) {
      assert.ifError(err);
      assert.equal(argv.abc, 'def');
      assert.equal(cli.options.foo, 'abc');
      assert.equal(cli.options.baz, 'qux');
      done();
    });
  });

  it('should be able to emit events from plugins', function (done) {
    var i = 0;
    cli.use(function (self) {
      return function (argv, next) {
        self.emit('custom', argv.foo);
        i++;
        next(null, argv)
      };
    });
    cli.on('custom', function (foo) {
      assert.equal(foo, 'bar');
      i++;
    });
    cli.parse(['--foo=bar'], function (err, argv) {
      assert.ifError(err);
      assert.equal(i, 2);
      assert.equal(argv.foo, 'bar');
      done();
    });
  });
});
<commit_msg>update tests, test chaining<commit_after>'use strict';

/* deps: mocha */
var assert = require('assert');
var minimist = require('minimist');
var plugins = require('./');
var cli;

describe('minimist', function () {
  beforeEach(function () {
    cli = plugins(minimist);
  });

  it('should throw if `minimist` not function', function (done) {
    function fixture () {
      plugins(123);
    }
    assert.throws(fixture, TypeError);
    assert.throws(fixture, /expect `minimist` be function/);
    done();
  });

  it('should pass error from async plugins', function (done) {
    cli.use(function () {
      return function (argv, next) {
        argv.foo = 'bar';
        next(new Error('foo bar'));
      };
    });
    cli.parse(['--foo=bar'], function (err, argv) {
      assert.ifError(!err);
      assert.ok(!argv);
      assert.equal(err.message, 'foo bar');
      done();
    });
  });

  it('should parse arguments without any plugins:', function (done) {
    cli.parse(['--a', '--b'], function (err, argv) {
      assert.ifError(err);
      assert.equal(argv.a, true);
      assert.equal(argv.b, true);
      done();
    });
  });

  it('should chain plugins:', function () {
    cli
      .use(function () {
        return function (argv) {
          argv.foo = 'bar';
        };
      })
      .use(function () {
        return function (argv) {
          argv.baz = 'quux';
        };
      });

    cli.parse(['--a', '--b'], function (err, argv) {
      assert.ifError(err);
      assert.equal(argv.foo === 'bar', true);
      assert.equal(argv.baz === 'quux', true);
      assert.equal(argv.a === true, true);
      assert.equal(argv.b === true, true);
      done();
    });
  });

  it('should expose args on the `argv` object:', function (done) {
    cli.parse(['a', 'b', 'c'], function (err, res) {
      assert.ifError(err);
      assert.deepEqual(res._, ['a', 'b', 'c']);
      done();
    });
  });

  it('should expose options on the `argv` object:', function (done) {
    cli.parse(['a', 'b', 'c', '--foo=bar'], function (err, res) {
      assert.ifError(err);
      assert.equal(res.foo, 'bar');
      done();
    });
  });

  it('should emit `end` after all args are emitted:', function (done) {
    var i = 0;
    function set(key, value) {
      return function (cli) {
        return function (argv, next) {
          argv[key] = value;
          next(null, argv);
        };
      };
    }

    cli.use(set('aaa', 'bbb'))
    cli.use(set('ccc', 'ddd'))
    cli.use(set('eee', 'fff'))

    cli.on('end', function (argv) {
      assert.equal(argv.aaa, 'bbb');
      assert.equal(argv.ccc, 'ddd');
      assert.equal(argv.eee, 'fff');
      i++;
    });

    cli.parse(['a', 'b', 'c', '--foo=bar'], function (err, argv) {
      assert.ifError(err);
      assert.equal(i, 1);
      assert.equal(argv.aaa, 'bbb');
      assert.equal(argv.ccc, 'ddd');
      assert.equal(argv.eee, 'fff');
      done();
    });
  });

  it('should done callback be optional', function (done) {
    var res = cli.parse(['a', 'b']);
    assert.equal(typeof res.minimist, 'function');
    done();
  });

  it('should result have parsed `.argv` property', function (done) {
    var res = cli.parse(['--foo=bar', '--baz=qux']);
    assert.equal(typeof res.minimist, 'function');
    assert.equal(res.argv.foo, 'bar');
    assert.equal(res.argv.baz, 'qux');
    done();
  });

  it('should result have processed `.argv` property', function (done) {
    cli
      .use(function () {
        return function (argv, next) {
          argv.foo = 'bar2';
          argv.baz = 'qux2';
          next(null, argv);
        };
      })
      .use(function () {
        return function (argv, next) {
          argv.qux = 'jon2';
          next(null, argv);
        };
      });
    var res = cli.parse(['--foo=bar', '--baz=qux']);
    assert.equal(typeof res.minimist, 'function');
    assert.equal(res.argv.foo, 'bar2');
    assert.equal(res.argv.baz, 'qux2');
    assert.equal(res.argv.qux, 'jon2');
    done();
  });

  it('should merge options', function (done) {
    cli = plugins(minimist, {a: 'b'});
    var res = cli.parse(['--foo=bar'], {c: 'd'});
    assert.equal(res.options.a, 'b');
    assert.equal(res.options.c, 'd');
    assert.equal(res.argv.foo, 'bar');
    done();
  });

  it('should add/modify options from plugins', function (done) {
    cli = plugins(minimist, {foo: 'bar'});
    cli
      .use(function (self) {
        return function (argv, next) {
          self.options.foo = 'abc';
          self.options.baz = 'qux';
          next(null, argv);
        };
      })
      .use(function (self) {
        return function (argv, next) {
          self.options.qux = 'jon';
          next(null, argv);
        };
      });

    cli.parse(['--abc=def'], function (err, argv) {
      assert.ifError(err);
      assert.equal(argv.abc, 'def');
      assert.equal(cli.options.foo, 'abc');
      assert.equal(cli.options.baz, 'qux');
      assert.equal(cli.options.qux, 'jon');
      done();
    });
  });

  it('should be able to emit events from plugins', function (done) {
    var i = 0;
    cli
      .use(function (self) {
        return function (argv, next) {
          self.emit('custom1', argv.foo);
          i++;
          next(null, argv)
        };
      })
      .use(function (self) {
        return function (argv, next) {
          self.emit('custom2', argv.foo);
          i++;
          next(null, argv)
        };
      });

    cli
      .on('custom1', function (foo) {
        assert.equal(foo, 'bar');
        i++;
      })
      .on('custom2', function (foo) {
        assert.equal(foo, 'bar');
        i++;
      });

    cli.parse(['--foo=bar'], function (err, argv) {
      assert.ifError(err);
      assert.equal(i, 4);
      assert.equal(argv.foo, 'bar');
      done();
    });
  });
});
<|endoftext|>


<commit_before>var test = require('tape');
var request = require('request');
var http = require('http');
var sendJson = require('./');

http.createServer(function(req, res) {
  sendJson(req, res, {hello: 'world'});
}).listen(3456);

test('basic', function(t) {
  request('http://localhost:3456', function(err, res) {
    t.ok(!err);
    t.equal(res.statusCode, 200);
    var obj = JSON.parse(res.body);
    t.equal(obj.hello, 'world')
    t.end();
  });
});

test('end', function(t) {
  t.end();
  process.exit();
});
<commit_msg>Update tests.<commit_after>var test = require('tape');
var request = require('request');
var http = require('http');
var sendJson = require('./');

http.createServer(function(req, res) {
  sendJson(res, {hello: 'world'});
}).listen(3456);

test('basic', function(t) {
  request('http://localhost:3456', function(err, res) {
    t.ok(!err);
    t.equal(res.statusCode, 200);
    var obj = JSON.parse(res.body);
    t.equal(obj.hello, 'world')
    t.end();
  });
});

test('end', function(t) {
  t.end();
  process.exit();
});
<|endoftext|>


<commit_before>/*
Name:           bolcom - test.js
Description:    Module for node.js to access Bol.com Open API service
Author:         Franklin (https://fvdm.com)
Source & docs:  https://github.com/fvdm/nodejs-bolcom
License:        Unlicense (Public Domain, see LICENSE file)
*/

const dotest = require ('dotest');
const app = require ('./');

// Setup
// set env BOLCOM_APIKEY  (Travis CI)
const apikey = process.env.BOLCOM_APIKEY || null;
const timeout = process.env.BOLCOM_TIMEOUT || null;

const bol = new app ({
  apikey,
  timeout,
});

/**
 * Check data and products result
 *
 * @return  {Test}              Processed doTest.test() chain
 *
 * @param   {Test}        test  doTest.test() chain
 * @param   {Error|null}  err   Callback error
 * @param   {object}      data  Callback data
 */

function dataProducts (test, err, data) {
  const products = data && data.products;
  const item = products && products[0];

  return test (err)
    .isObject ('fail', 'data', data)
    .isArray ('fail', 'data.products', products)
    .isObject ('fail', 'data.products[0]', item)
    .isString ('fail', 'data.products[0].id', item && item.id);
}

dotest.add ('ping', async test => {
  let error;
  let data;

  try {
    data = await bol.ping ();
  }
  catch (err) {
    error = err;
  }

  test (error)
    .isObject ('fail', 'data', data)
    .isExactly ('warn', 'data.Message', data && data.Message, 'Hello World!')
    .done ()
  ;
});

dotest.add ('catalogSearch', async test => {
  let error;
  let data;

  const params = {
    q: 'node.js',
    limit: 1,
    includeattributes: true,
  };

  try {
    data = await bol.catalogSearch (params);
  }
  catch (err) {
    error = err;
  }

  const products = data && data.products;
  const item = products && products[0];

  dataProducts (test, error, data)
    .isObject ('fail', 'data.products[0].attributeGroups', item && item.attributeGroups)
    .done ()
  ;
});

dotest.add ('catalogProducts', async test => {
  let error;
  let data;

  try {
    data = await bol.catalogProducts ('9200000023292527');
  }
  catch (err) {
    error = err;
  }

  dataProducts (test, error, data).done ();
});

dotest.add ('incomplete product', async test => {
  let error;
  let data;

  try {
    data = await bol.catalogProducts ('9200000009223738');
  }
  catch (err) {
    error = err;
  }

  const products = data && data.products;
  const item = products && products[0];

  dataProducts (test, error, data)
    .isUndefined ('fail', 'data.products[0].images', item && item.images)
    .done ()
  ;
});

dotest.add ('catalogLists', async test => {
  let error;
  let data;

  try {
    data = await bol.catalogLists ();
  }
  catch (err) {
    error = err;
  }

  dataProducts (test, error, data).done ();
});

dotest.add ('catalogOffers', async test => {
  let error;
  let data;

  try {
    data = await bol.catalogOffers ('9200000023292527');
  }
  catch (err) {
    error = err;
  }

  const offers = data && data.offers;
  const item = offers && offers[0];

  test (error)
    .isObject ('fail', 'data', data)
    .isArray ('fail', 'data.offers', offers)
    .isObject ('fail', 'data.offers[0]', item)
    .isString ('fail', 'data.offers[0[.id', item && item.id)
    .done ()
  ;
});

dotest.add ('catalogRecommendations', async test => {
  let error;
  let data;

  try {
    data = await bol.catalogRecommendations ('9200000023292527');
  }
  catch (err) {
    error = err;
  }

  const products = data && data.products;
  const item = products && products[0];

  test (error)
    .isObject ('fail', 'data', data)
    .isArray ('fail', 'data.products', products)
    .isObject ('fail', 'data.products[0]', item)
    .isString ('fail', 'data.products[0].id', item && item.id)
    .done ()
  ;
});

dotest.add ('catalogRelatedProducts', async test => {
  let error;
  let data;

  try {
    data = await bol.catalogRelatedProducts ('9200000010839998');
  }
  catch (err) {
    error = err;
  }

  const bind = data && data.Binding;

  test (error)
    .isObject ('fail', 'data', data)
    .isObject ('fail', 'data.Binding', bind)
    .isObject ('fail', 'data.Binding.productFamilyMembers', bind && bind.productFamilyMembers)
    .done ()
  ;
});

dotest.add ('API error', async test => {
  const tmp = new app ({
    apikey: '',
    timeout,
  });

  let error;
  let data;

  try {
    data = await tmp.ping();
  }
  catch (err) {
    error = err;
  }

  test()
    .isError ('fail', 'error', error)
    .isNumber ('fail', 'error.status', error && error.status)
    .isUndefined ('fail', 'data', data)
    .done()
  ;
});

// Start the tests
dotest.run ();
<commit_msg>Test: Removed obsolete checks<commit_after>/*
Name:           bolcom - test.js
Description:    Module for node.js to access Bol.com Open API service
Author:         Franklin (https://fvdm.com)
Source & docs:  https://github.com/fvdm/nodejs-bolcom
License:        Unlicense (Public Domain, see LICENSE file)
*/

const dotest = require ('dotest');
const app = require ('./');

// Setup
// set env BOLCOM_APIKEY  (Travis CI)
const apikey = process.env.BOLCOM_APIKEY || null;
const timeout = process.env.BOLCOM_TIMEOUT || null;

const bol = new app ({
  apikey,
  timeout,
});

/**
 * Check data and products result
 *
 * @return  {Test}              Processed doTest.test() chain
 *
 * @param   {Test}        test  doTest.test() chain
 * @param   {Error|null}  err   Callback error
 * @param   {object}      data  Callback data
 */

function dataProducts (test, err, data) {
  const products = data && data.products;
  const item = products && products[0];

  return test (err)
    .isObject ('fail', 'data', data)
    .isArray ('fail', 'data.products', products)
    .isObject ('fail', 'data.products[0]', item)
    .isString ('fail', 'data.products[0].id', item && item.id);
}

dotest.add ('ping', async test => {
  let error;
  let data;

  try {
    data = await bol.ping ();
  }
  catch (err) {
    error = err;
  }

  test (error)
    .isObject ('fail', 'data', data)
    .isExactly ('warn', 'data.Message', data && data.Message, 'Hello World!')
    .done ()
  ;
});

dotest.add ('catalogSearch', async test => {
  let error;
  let data;

  const params = {
    q: 'node.js',
    limit: 1,
    includeattributes: true,
  };

  try {
    data = await bol.catalogSearch (params);
  }
  catch (err) {
    error = err;
  }

  const products = data && data.products;
  const item = products && products[0];

  dataProducts (test, error, data)
    .isObject ('fail', 'data.products[0].attributeGroups', item && item.attributeGroups)
    .done ()
  ;
});

dotest.add ('catalogProducts', async test => {
  let error;
  let data;

  try {
    data = await bol.catalogProducts ('9200000023292527');
  }
  catch (err) {
    error = err;
  }

  dataProducts (test, error, data).done ();
});

dotest.add ('incomplete product', async test => {
  let error;
  let data;

  try {
    data = await bol.catalogProducts ('9200000009223738');
  }
  catch (err) {
    error = err;
  }

  const products = data && data.products;
  const item = products && products[0];

  dataProducts (test, error, data)
    .isUndefined ('fail', 'data.products[0].images', item && item.images)
    .done ()
  ;
});

dotest.add ('catalogLists', async test => {
  let error;
  let data;

  try {
    data = await bol.catalogLists ();
  }
  catch (err) {
    error = err;
  }

  dataProducts (test, error, data).done ();
});

dotest.add ('catalogOffers', async test => {
  let error;
  let data;

  try {
    data = await bol.catalogOffers ('9200000023292527');
  }
  catch (err) {
    error = err;
  }

  const offers = data && data.offers;
  const item = offers && offers[0];

  test (error)
    .isObject ('fail', 'data', data)
    .isArray ('fail', 'data.offers', offers)
    .isObject ('fail', 'data.offers[0]', item)
    .isString ('fail', 'data.offers[0[.id', item && item.id)
    .done ()
  ;
});

dotest.add ('catalogRecommendations', async test => {
  let error;
  let data;

  try {
    data = await bol.catalogRecommendations ('9200000023292527');
  }
  catch (err) {
    error = err;
  }

  const products = data && data.products;
  const item = products && products[0];

  test (error)
    .isObject ('fail', 'data', data)
    .isArray ('fail', 'data.products', products)
    .isObject ('fail', 'data.products[0]', item)
    .isString ('fail', 'data.products[0].id', item && item.id)
    .done ()
  ;
});

dotest.add ('catalogRelatedProducts', async test => {
  let error;
  let data;

  try {
    data = await bol.catalogRelatedProducts ('9200000010839998');
  }
  catch (err) {
    error = err;
  }

  test (error)
    .isArray ('fail', 'data', data)
    .done ()
  ;
});

dotest.add ('API error', async test => {
  const tmp = new app ({
    apikey: '',
    timeout,
  });

  let error;
  let data;

  try {
    data = await tmp.ping();
  }
  catch (err) {
    error = err;
  }

  test()
    .isError ('fail', 'error', error)
    .isNumber ('fail', 'error.status', error && error.status)
    .isUndefined ('fail', 'data', data)
    .done()
  ;
});

// Start the tests
dotest.run ();
<|endoftext|>


<commit_before>#!/usr/bin/env node

/**
 * Clones several projects that are known to follow "JavaScript Standard Style" and runs
 * the `standard` style checker to verify that it passes without warnings. This helps
 * ensure we don't accidentally introduce new style rules that cause previously "good"
 * code to start failing with new warnings! (And if we do, then that needs to be a MAJOR
 * VERSION BUMP.)
 */

var cp = require('child_process')
var extend = require('extend.js')
var mkdirp = require('mkdirp')
var path = require('path')
var rimraf = require('rimraf')
var series = require('run-series')

var TMP = path.join(__dirname, 'tmp')
var STANDARD = path.join(__dirname, 'bin', 'cmd.js')

var urls = [
  'https://github.com/beatgammit/base64-js.git',
  'https://github.com/feross/bittorrent-dht.git',
  'https://github.com/feross/bittorrent-tracker.git',
  'https://github.com/feross/buffer.git',
  'https://github.com/feross/parse-torrent.git',
  'https://github.com/feross/studynotes.git',
  'https://github.com/feross/webtorrent.git',
  'https://github.com/mafintosh/level-temp.git',
  'https://github.com/mafintosh/peerflix.git',
  'https://github.com/mafintosh/what-line-is-this.git'
]

var modules = {}
urls.forEach(function (url) {
  var name = /\/([^.\/]+)\.git$/.exec(url)[1]
  modules[name] = url
})

rimraf.sync(TMP)
mkdirp.sync(TMP)

series(Object.keys(modules).map(function (name) {
  var url = modules[name]
  return function (cb) {
    var args = [ 'clone', url, path.join(TMP, name) ]
    // TODO: Start `git` in a way that works on Windows – PR welcome!
    spawn('git', args, {}, cb)
  }
}), runTests)

function runTests (err) {
  if (err) return error(err)
  series(Object.keys(modules).map(function (name) {
    return function (cb) {
      process.stderr.write(name + ': ')
      var cwd = path.join(TMP, name)
      spawn(STANDARD, ['--verbose'], { cwd: cwd }, function (err) {
        if (err) return cb(err)
        console.error('ok')
        cb(null)
      })
    }
  }), function (err) {
    if (err) return error(err)
  })
}

function spawn (command, args, opts, cb) {
  var child = cp.spawn(command, args, extend({ stdio: 'inherit' }, opts))
  child.on('error', error)
  child.on('close', function (code) {
    if (code !== 0) cb(new Error('non-zero exit code: ' + code))
    else cb(null)
  })
  return child
}

function error (err) {
  console.error(err.stack || err.message || err)
  process.exit(1)
}
<commit_msg>tests: add bittorrent-protocol/magnet-uri/simple-peer<commit_after>#!/usr/bin/env node

/**
 * Clones several projects that are known to follow "JavaScript Standard Style" and runs
 * the `standard` style checker to verify that it passes without warnings. This helps
 * ensure we don't accidentally introduce new style rules that cause previously "good"
 * code to start failing with new warnings! (And if we do, then that needs to be a MAJOR
 * VERSION BUMP.)
 */

var cp = require('child_process')
var extend = require('extend.js')
var mkdirp = require('mkdirp')
var path = require('path')
var rimraf = require('rimraf')
var series = require('run-series')

var TMP = path.join(__dirname, 'tmp')
var STANDARD = path.join(__dirname, 'bin', 'cmd.js')

var urls = [
  'https://github.com/beatgammit/base64-js.git',
  'https://github.com/feross/bittorrent-dht.git',
  'https://github.com/feross/bittorrent-protocol.git',
  'https://github.com/feross/bittorrent-tracker.git',
  'https://github.com/feross/buffer.git',
  'https://github.com/feross/magnet-uri.git',
  'https://github.com/feross/parse-torrent.git',
  'https://github.com/feross/simple-peer.git',
  'https://github.com/feross/studynotes.git',
  'https://github.com/feross/webtorrent.git',
  'https://github.com/mafintosh/level-temp.git',
  'https://github.com/mafintosh/peerflix.git',
  'https://github.com/mafintosh/what-line-is-this.git'
]

var modules = {}
urls.forEach(function (url) {
  var name = /\/([^.\/]+)\.git$/.exec(url)[1]
  modules[name] = url
})

rimraf.sync(TMP)
mkdirp.sync(TMP)

series(Object.keys(modules).map(function (name) {
  var url = modules[name]
  return function (cb) {
    var args = [ 'clone', url, path.join(TMP, name) ]
    // TODO: Start `git` in a way that works on Windows – PR welcome!
    spawn('git', args, {}, cb)
  }
}), runTests)

function runTests (err) {
  if (err) return error(err)
  series(Object.keys(modules).map(function (name) {
    return function (cb) {
      process.stderr.write(name + ': ')
      var cwd = path.join(TMP, name)
      spawn(STANDARD, ['--verbose'], { cwd: cwd }, function (err) {
        if (err) return cb(err)
        console.error('ok')
        cb(null)
      })
    }
  }), function (err) {
    if (err) return error(err)
  })
}

function spawn (command, args, opts, cb) {
  var child = cp.spawn(command, args, extend({ stdio: 'inherit' }, opts))
  child.on('error', error)
  child.on('close', function (code) {
    if (code !== 0) cb(new Error('non-zero exit code: ' + code))
    else cb(null)
  })
  return child
}

function error (err) {
  console.error(err.stack || err.message || err)
  process.exit(1)
}
<|endoftext|>


<commit_before>'use strict';

var app = require(__dirname + './app');
var expect = require('chai').expect;

describe('unique', function() {
   it('should return an array with any duplicate removed', function() {
      var testArray = [1, 2, 3, 2, 5];
      expect(app.unique(testArray)).to.eql([1, 2, 3, 5]);
   });
});

describe('frequencyTwo', function() {
   it('should find the letter most used in the English language', function() {
      var testArray = ['david, dude, add, daddy'];
      expect(app.frequencyTwo(testArray)).to.eql(['d']);
   });
});
<commit_msg>updating our tests<commit_after>'use strict';

var app = require(__dirname + './app');
var expect = require('chai').expect;
var unique = require('./app');
var frequencyTwo = require('./app');

describe('unique', function() {
   it('should return an array with any duplicate removed', function() {
      var testArray = [1, 2, 3, 2, 5];
      expect(app.unique(testArray)).to.eql([1, 2, 3, 5]);
   });
});

describe('frequencyTwo', function() {
   it('should find the letter most used in the English language', function() {
      var testArray = ['david, dude, add, daddy'];
      expect(app.frequencyTwo(testArray)).to.eql(['d']);
   });
});
<|endoftext|>


<commit_before>;(function (exports, DOMParser, xmlbuilder) {
	// Checks if running in a non-browser environment
 	var inNode = typeof window === 'undefined' ? true : false
 	  , utf8_to_b64
 	  , b64_to_utf8;

 	// this library runs in browsers and nodejs, set up functions accordingly
 	if (inNode) {
 		exports.parseFile = function (filename, callback) {
 			console.warn('parseFile is deprecated. Please use parseFileSync instead.');
    		var fs = require('fs');
			var inxml = fs.readFileSync(filename, 'utf8');
			exports.parseString(inxml, callback);
  		}

  		exports.parseFileSync = function (filename) {
    		var fs = require('fs');
			var inxml = fs.readFileSync(filename, 'utf8');
			return exports.parseStringSync(inxml);
  		}

  		// set up base64 encode/decode functions
  		utf8_to_b64= function ( str ) {
  			return new Buffer(str).toString('base64');
		}
		b64_to_utf8 = function ( str ) {
		    return new Buffer(str, 'base64').toString('utf8');
		}
  	} else {
  		// we're in a browser context, find the DOMParser
		if (typeof window.DOMParser != 'undefined') {
		    DOMParser = function(xmlStr) {
		        return ( new window.DOMParser() ).parseFromString(xmlStr, 'text/xml');
		    };
		} else if (typeof window.ActiveXObject != 'undefined' &&
		       new window.ActiveXObject('Microsoft.XMLDOM')) {
		    DOMParser = function(xmlStr) {
		        var xmlDoc = new window.ActiveXObject('Microsoft.XMLDOM');
		        xmlDoc.async = 'false';
		        xmlDoc.loadXML(xmlStr);
		        return xmlDoc;
		    };
		} else {
		    throw new Error('No XML parser found');
		}

		// set up base64 encode/decode functions
		if (typeof window.btoa == 'undefined') {
			throw new Error('No base64 support found');
			// TODO: shim btoa and atob if not present (ie < 10)
			//http://stackoverflow.com/questions/246801/how-can-you-encode-to-base64-using-javascript/247261#247261
		} else {
			utf8_to_b64= function ( str ) {
			    return window.btoa(unescape(encodeURIComponent( str )));
			}

			b64_to_utf8 = function ( str ) {
			    return decodeURIComponent(escape(window.atob( str )));
			}
		}

	}

	exports.parseString = function (xml, callback) {
		console.warn('parseString is deprecated. Please use parseStringSync instead.');
		var doc, error, plist;
		try {
			doc = new DOMParser().parseFromString(xml);
			plist = parsePlistXML(doc.documentElement);
		} catch(e) {
			error = e;
		}
		callback(error, plist);
	}

	exports.parseStringSync = function (xml) {
		var doc = new DOMParser().parseFromString(xml);
    var plist;
		if (doc.documentElement.nodeName !== 'plist') {
			throw new Error('malformed document. First element should be <plist>');
		}
		plist = parsePlistXML(doc.documentElement);

		// if the plist is an array with 1 element, pull it out of the array
		if(isArray(plist) && plist.length == 1) {
			plist = plist[0];
		}
		return plist;
	}

	/**
	 * convert an XML based plist document into a JSON representation
	 *
	 * @param object xml_node current XML node in the plist
	 * @return built up JSON object
	 */
	function parsePlistXML(node) {
		var i, new_obj, key, val, new_arr;
		if (!node)
			return null;

		if (node.nodeName === 'plist') {
			new_arr = [];
			for (i=0;i < node.childNodes.length;i++) {
				// ignore comment nodes (text)
				if (node.childNodes[i].nodeType !== 3) {
					new_arr.push( parsePlistXML(node.childNodes[i]));
				}
			}
			return new_arr;
		}
		else if(node.nodeName === 'dict') {
			new_obj = {};
			key = null;
			for (i=0;i < node.childNodes.length;i++) {
				// ignore comment nodes (text)
				if (node.childNodes[i].nodeType !== 3) {
					if (key === null) {
						key = parsePlistXML(node.childNodes[i]);
					} else {
						new_obj[key] = parsePlistXML(node.childNodes[i]);
						key = null;
					}
				}
			}
			return new_obj;
		}
		else if(node.nodeName === 'array') {
			new_arr = [];
			for (i=0;i < node.childNodes.length;i++) {
				// ignore comment nodes (text)
				if (node.childNodes[i].nodeType !== 3) {
					res = parsePlistXML(node.childNodes[i]);
					if (res) new_arr.push( res );
				}
			}
			return new_arr;
		}
		else if(node.nodeName === '#text') {
			// TODO: what should we do with text types? (CDATA sections)
		}
		else if(node.nodeName === 'key') {
			return node.childNodes[0].nodeValue;
		}
		else if(node.nodeName === 'string') {
			var res = '';
			for (var d=0; d < node.childNodes.length; d++)
			{
				res += node.childNodes[d].nodeValue;
			}
			return res;
		}
		else if(node.nodeName === 'integer') {
			// parse as base 10 integer
			return parseInt(node.childNodes[0].nodeValue, 10);
		}
		else if(node.nodeName === 'real') {
			var res = '';
			for (var d=0; d < node.childNodes.length; d++)
			{
				if(node.childNodes[d].nodeType === 3) {
					res += node.childNodes[d].nodeValue;
				}
			}
			return parseFloat(res);
		}
		else if(node.nodeName === 'data') {
			var res = '';
			for (var d=0; d < node.childNodes.length; d++)
			{
				if(node.childNodes[d].nodeType === 3) {
					res += node.childNodes[d].nodeValue;
				}
			}

			// validate that the string is encoded as base64
			var base64Matcher = new RegExp("^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$");
			if (!base64Matcher.test(res.replace(/\s/g,'')) ) {
				throw new Error('malformed document. <data> element is not base64 encoded');
			}

			// decode base64 data as utf8 string
			return b64_to_utf8(res);
		}
		else if(node.nodeName === 'date') {
			return new Date(node.childNodes[0].nodeValue);
		}
		else if(node.nodeName === 'true') {
			return true;
		}
		else if(node.nodeName === 'false') {
			return false;
		}
	}

  function ISODateString(d){
    function pad(n){return n<10 ? '0'+n : n}
    return d.getUTCFullYear()+'-'
        + pad(d.getUTCMonth()+1)+'-'
        + pad(d.getUTCDate())+'T'
        + pad(d.getUTCHours())+':'
        + pad(d.getUTCMinutes())+':'
        + pad(d.getUTCSeconds())+'Z'
  }

  // instanceof is horribly unreliable so we use these hackish but safer checks
  // http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray
  function isArray(obj) {
    return Object.prototype.toString.call(obj) === '[object Array]';
  }

  function isDate(obj) {
    return Object.prototype.toString.call(obj) === '[object Date]';
  }

  function isBoolean(obj) {
    return (obj === true || obj === false || toString.call(obj) == '[object Boolean]');
  }

  function isNumber(obj) {
    return Object.prototype.toString.call(obj) === '[object Number]';
  }

  function isObject(obj) {
    return Object.prototype.toString.call(obj) === '[object Object]';
  }

  function isString(obj) {
    return Object.prototype.toString.call(obj) === '[object String]';
  }

  /**
   * generate an XML plist string from the input object
   *
   * @param object obj the object to convert
   * @return string converted plist
   */
  exports.build = function(obj) {
    var XMLHDR = { 'version': '1.0','encoding': 'UTF-8'}
        , XMLDTD = { 'ext': 'PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"'}
        , doc = xmlbuilder.create()
        , child = doc.begin('plist', XMLHDR, XMLDTD).att('version', '1.0');

    walk_obj(obj, child);
    return child.end({pretty: true });
  }

  // depth first, recursive traversal of a javascript object. when complete,
  // next_child contains a reference to the build XML object.
  function walk_obj(next, next_child) {
    var tag_type, i, prop;

    if(isArray(next)) {
      next_child = next_child.ele('array');
      for(i=0 ;i < next.length;i++) {
        walk_obj(next[i], next_child);
      }
    }
    else if (isObject(next)) {
      if (inNode && next instanceof Buffer) {
        next_child.ele('data').raw(next.toString('base64'));
      } else {
        next_child = next_child.ele('dict');
        for(prop in next) {
          if(next.hasOwnProperty(prop)) {
            next_child.ele('key').txt(prop);
            walk_obj(next[prop], next_child);
          }
        }
      }
    }
    else if(isNumber(next)) {
      // detect if this is an integer or real
      tag_type =(next % 1 === 0) ? 'integer' : 'real';
      next_child.ele(tag_type).txt(next.toString());
    }
    else if(isDate(next)) {
      next_child.ele('date').raw(ISODateString(new Date(next)));
    }
    else if(isBoolean(next)) {
      val = next ? 'true' : 'false';
      next_child.ele(val);
    }
    else if(isString(next)) {
      //if (str!=obj || str.indexOf("\n")>=0) str = "<![CDATA["+str+"]]>";
      var base64Matcher = new RegExp("^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$");
      if (!inNode && base64Matcher.test(next.replace(/\s/g,''))) {
      	// data is base 64 encoded so assume it's a <data> node
        next_child.ele('data').raw(utf8_to_b64(next));
      } else {
      	// it's not base 64 encoded, assume it's a <string> node
      	next_child.ele('string').raw(next);
      }
    }
  };

})(typeof exports === 'undefined' ? plist = {} : exports, typeof window === 'undefined' ? require('xmldom').DOMParser : null, typeof window === 'undefined' ? require('xmlbuilder') : xmlbuilder)
// the above line checks for exports (defined in node) and uses it, or creates
// a global variable and exports to that. also, if in node, require DOMParser
// node-style, in browser it should already be present
<commit_msg>node-webkit support<commit_after>;(function (exports, DOMParser, xmlbuilder) {
	// Checks if running in a non-browser environment
 	var inNode = (typeof window === 'undefined' || typeof global === 'object') ? true : false
 	  , utf8_to_b64
 	  , b64_to_utf8;

 	// this library runs in browsers and nodejs, set up functions accordingly
 	if (inNode) {
 		exports.parseFile = function (filename, callback) {
 			console.warn('parseFile is deprecated. Please use parseFileSync instead.');
    		var fs = require('fs');
			var inxml = fs.readFileSync(filename, 'utf8');
			exports.parseString(inxml, callback);
  		}

  		exports.parseFileSync = function (filename) {
    		var fs = require('fs');
			var inxml = fs.readFileSync(filename, 'utf8');
			return exports.parseStringSync(inxml);
  		}

  		// set up base64 encode/decode functions
  		utf8_to_b64= function ( str ) {
  			return new Buffer(str).toString('base64');
		}
		b64_to_utf8 = function ( str ) {
		    return new Buffer(str, 'base64').toString('utf8');
		}
  	} else {
  		// we're in a browser context, find the DOMParser
		if (typeof window.DOMParser != 'undefined') {
		    DOMParser = function(xmlStr) {
		        return ( new window.DOMParser() ).parseFromString(xmlStr, 'text/xml');
		    };
		} else if (typeof window.ActiveXObject != 'undefined' &&
		       new window.ActiveXObject('Microsoft.XMLDOM')) {
		    DOMParser = function(xmlStr) {
		        var xmlDoc = new window.ActiveXObject('Microsoft.XMLDOM');
		        xmlDoc.async = 'false';
		        xmlDoc.loadXML(xmlStr);
		        return xmlDoc;
		    };
		} else {
		    throw new Error('No XML parser found');
		}

		// set up base64 encode/decode functions
		if (typeof window.btoa == 'undefined') {
			throw new Error('No base64 support found');
			// TODO: shim btoa and atob if not present (ie < 10)
			//http://stackoverflow.com/questions/246801/how-can-you-encode-to-base64-using-javascript/247261#247261
		} else {
			utf8_to_b64= function ( str ) {
			    return window.btoa(unescape(encodeURIComponent( str )));
			}

			b64_to_utf8 = function ( str ) {
			    return decodeURIComponent(escape(window.atob( str )));
			}
		}

	}

	exports.parseString = function (xml, callback) {
		console.warn('parseString is deprecated. Please use parseStringSync instead.');
		var doc, error, plist;
		try {
			doc = new DOMParser().parseFromString(xml);
			plist = parsePlistXML(doc.documentElement);
		} catch(e) {
			error = e;
		}
		callback(error, plist);
	}

	exports.parseStringSync = function (xml) {
		var doc = new DOMParser().parseFromString(xml);
    var plist;
		if (doc.documentElement.nodeName !== 'plist') {
			throw new Error('malformed document. First element should be <plist>');
		}
		plist = parsePlistXML(doc.documentElement);

		// if the plist is an array with 1 element, pull it out of the array
		if(isArray(plist) && plist.length == 1) {
			plist = plist[0];
		}
		return plist;
	}

	/**
	 * convert an XML based plist document into a JSON representation
	 *
	 * @param object xml_node current XML node in the plist
	 * @return built up JSON object
	 */
	function parsePlistXML(node) {
		var i, new_obj, key, val, new_arr;
		if (!node)
			return null;

		if (node.nodeName === 'plist') {
			new_arr = [];
			for (i=0;i < node.childNodes.length;i++) {
				// ignore comment nodes (text)
				if (node.childNodes[i].nodeType !== 3) {
					new_arr.push( parsePlistXML(node.childNodes[i]));
				}
			}
			return new_arr;
		}
		else if(node.nodeName === 'dict') {
			new_obj = {};
			key = null;
			for (i=0;i < node.childNodes.length;i++) {
				// ignore comment nodes (text)
				if (node.childNodes[i].nodeType !== 3) {
					if (key === null) {
						key = parsePlistXML(node.childNodes[i]);
					} else {
						new_obj[key] = parsePlistXML(node.childNodes[i]);
						key = null;
					}
				}
			}
			return new_obj;
		}
		else if(node.nodeName === 'array') {
			new_arr = [];
			for (i=0;i < node.childNodes.length;i++) {
				// ignore comment nodes (text)
				if (node.childNodes[i].nodeType !== 3) {
					res = parsePlistXML(node.childNodes[i]);
					if (res) new_arr.push( res );
				}
			}
			return new_arr;
		}
		else if(node.nodeName === '#text') {
			// TODO: what should we do with text types? (CDATA sections)
		}
		else if(node.nodeName === 'key') {
			return node.childNodes[0].nodeValue;
		}
		else if(node.nodeName === 'string') {
			var res = '';
			for (var d=0; d < node.childNodes.length; d++)
			{
				res += node.childNodes[d].nodeValue;
			}
			return res;
		}
		else if(node.nodeName === 'integer') {
			// parse as base 10 integer
			return parseInt(node.childNodes[0].nodeValue, 10);
		}
		else if(node.nodeName === 'real') {
			var res = '';
			for (var d=0; d < node.childNodes.length; d++)
			{
				if(node.childNodes[d].nodeType === 3) {
					res += node.childNodes[d].nodeValue;
				}
			}
			return parseFloat(res);
		}
		else if(node.nodeName === 'data') {
			var res = '';
			for (var d=0; d < node.childNodes.length; d++)
			{
				if(node.childNodes[d].nodeType === 3) {
					res += node.childNodes[d].nodeValue;
				}
			}

			// validate that the string is encoded as base64
			var base64Matcher = new RegExp("^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$");
			if (!base64Matcher.test(res.replace(/\s/g,'')) ) {
				throw new Error('malformed document. <data> element is not base64 encoded');
			}

			// decode base64 data as utf8 string
			return b64_to_utf8(res);
		}
		else if(node.nodeName === 'date') {
			return new Date(node.childNodes[0].nodeValue);
		}
		else if(node.nodeName === 'true') {
			return true;
		}
		else if(node.nodeName === 'false') {
			return false;
		}
	}

  function ISODateString(d){
    function pad(n){return n<10 ? '0'+n : n}
    return d.getUTCFullYear()+'-'
        + pad(d.getUTCMonth()+1)+'-'
        + pad(d.getUTCDate())+'T'
        + pad(d.getUTCHours())+':'
        + pad(d.getUTCMinutes())+':'
        + pad(d.getUTCSeconds())+'Z'
  }

  // instanceof is horribly unreliable so we use these hackish but safer checks
  // http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray
  function isArray(obj) {
    return Object.prototype.toString.call(obj) === '[object Array]';
  }

  function isDate(obj) {
    return Object.prototype.toString.call(obj) === '[object Date]';
  }

  function isBoolean(obj) {
    return (obj === true || obj === false || toString.call(obj) == '[object Boolean]');
  }

  function isNumber(obj) {
    return Object.prototype.toString.call(obj) === '[object Number]';
  }

  function isObject(obj) {
    return Object.prototype.toString.call(obj) === '[object Object]';
  }

  function isString(obj) {
    return Object.prototype.toString.call(obj) === '[object String]';
  }

  /**
   * generate an XML plist string from the input object
   *
   * @param object obj the object to convert
   * @return string converted plist
   */
  exports.build = function(obj) {
    var XMLHDR = { 'version': '1.0','encoding': 'UTF-8'}
        , XMLDTD = { 'ext': 'PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"'}
        , doc = xmlbuilder.create()
        , child = doc.begin('plist', XMLHDR, XMLDTD).att('version', '1.0');

    walk_obj(obj, child);
    return child.end({pretty: true });
  }

  // depth first, recursive traversal of a javascript object. when complete,
  // next_child contains a reference to the build XML object.
  function walk_obj(next, next_child) {
    var tag_type, i, prop;

    if(isArray(next)) {
      next_child = next_child.ele('array');
      for(i=0 ;i < next.length;i++) {
        walk_obj(next[i], next_child);
      }
    }
    else if (isObject(next)) {
      if (inNode && next instanceof Buffer) {
        next_child.ele('data').raw(next.toString('base64'));
      } else {
        next_child = next_child.ele('dict');
        for(prop in next) {
          if(next.hasOwnProperty(prop)) {
            next_child.ele('key').txt(prop);
            walk_obj(next[prop], next_child);
          }
        }
      }
    }
    else if(isNumber(next)) {
      // detect if this is an integer or real
      tag_type =(next % 1 === 0) ? 'integer' : 'real';
      next_child.ele(tag_type).txt(next.toString());
    }
    else if(isDate(next)) {
      next_child.ele('date').raw(ISODateString(new Date(next)));
    }
    else if(isBoolean(next)) {
      val = next ? 'true' : 'false';
      next_child.ele(val);
    }
    else if(isString(next)) {
      //if (str!=obj || str.indexOf("\n")>=0) str = "<![CDATA["+str+"]]>";
      var base64Matcher = new RegExp("^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$");
      if (!inNode && base64Matcher.test(next.replace(/\s/g,''))) {
      	// data is base 64 encoded so assume it's a <data> node
        next_child.ele('data').raw(utf8_to_b64(next));
      } else {
      	// it's not base 64 encoded, assume it's a <string> node
      	next_child.ele('string').raw(next);
      }
    }
  };

})(typeof exports === 'undefined' ? plist = {} : exports, (typeof window === 'undefined' || typeof global === 'object') ? require('xmldom').DOMParser : null, (typeof window === 'undefined' || typeof global === 'object') ? require('xmlbuilder') : xmlbuilder)
// the above line checks for exports (defined in node) and uses it, or creates
// a global variable and exports to that. also, if in node, require DOMParser
// node-style, in browser it should already be present
<|endoftext|>


<commit_before>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length > 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<commit_msg>🤖(break): 2017-6-13 20:32:53<commit_after>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length < 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<|endoftext|>


<commit_before>/*global afterEach, beforeEach, it */
'use strict';
var assert = require('assert');
var fs = require('fs');
var rm = require('rimraf');
var pageres = require('./index');

afterEach(function (cb) {
	process.chdir('../');
	rm('tmp', cb);
});

beforeEach(function (cb) {
	fs.mkdirSync('tmp');
	process.chdir('tmp');
	cb();
});

it('should generate screenshots', function (cb) {
	pageres(['yeoman.io', 'todomvc.com'], ['1024x768', '640x480'], function () {
		assert(fs.existsSync('yeoman.io-640x480.png'));
		assert(fs.existsSync('yeoman.io-1024x768.png'));
		assert(fs.existsSync('todomvc.com-640x480.png'));
		assert(fs.existsSync('todomvc.com-1024x768.png'));
		cb();
	});
});
<commit_msg>Close GH-40: Issue 39: Test failed because of Mocha 2000ms timeout.<commit_after>/*global afterEach, beforeEach, it */
'use strict';
var assert = require('assert');
var fs = require('fs');
var rm = require('rimraf');
var pageres = require('./index');

afterEach(function (cb) {
	process.chdir('../');
	rm('tmp', cb);
});

beforeEach(function (cb) {
	fs.mkdirSync('tmp');
	process.chdir('tmp');
	cb();
});

it('should generate screenshots', function (cb) {
	this.timeout(20000);
	pageres(['yeoman.io', 'todomvc.com'], ['1024x768', '640x480'], function () {
		assert(fs.existsSync('yeoman.io-640x480.png'));
		assert(fs.existsSync('yeoman.io-1024x768.png'));
		assert(fs.existsSync('todomvc.com-640x480.png'));
		assert(fs.existsSync('todomvc.com-1024x768.png'));
		cb();
	});
});
<|endoftext|>


<commit_before>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length < 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<commit_msg>🤖(fix): 2017-6-14 19:18:32<commit_after>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length > 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<|endoftext|>


<commit_before>/**++++++++++++++++++
*  Pring App Server
* +++++++++++++++++++
*
*
The MIT License (MIT)

Copyright (c) 2014 Equan Pr.

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

var express = require('express'),
    pring = express(),
    config = require('./config'),
    routes = require('./routes'),
    app = require('../package.json'),
    engine = require('consolidate'),
    root = require('./util');

pring.configure(function() {

    pring.use(express.bodyParser());
    pring.use(express.methodOverride());

    pring.use(express.static(root.path() + '/public'));

    pring.set('views', root.path() + '/views');
    pring.engine('html', engine.handlebars);
    pring.set('view engine', 'html');
});

pring.get('/', routes.home);
pring.post('/post', routes.save);

pring.listen(config.get('express:port'), function() {
    console.log('Pagedek is running on port '+config.get('express:port'));
});

module.exports = pring;<commit_msg>strict mode<commit_after>/**++++++++++++++++++
*  Pring App Server
* +++++++++++++++++++
*
*
The MIT License (MIT)

Copyright (c) 2014 Equan Pr.

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

"use strict";

var express = require('express'),
    pring = express(),
    config = require('./config'),
    routes = require('./routes'),
    app = require('../package.json'),
    engine = require('consolidate'),
    root = require('./util');

pring.configure(function() {

    pring.use(express.bodyParser());
    pring.use(express.methodOverride());

    pring.use(express.static(root.path() + '/public'));

    pring.set('views', root.path() + '/views');
    pring.engine('html', engine.handlebars);
    pring.set('view engine', 'html');
});

pring.get('/', routes.home);
pring.post('/post', routes.save);

pring.listen(config.get('express:port'), function() {
    console.log('Pagedek is running on port '+config.get('express:port'));
});

module.exports = pring;<|endoftext|>


<commit_before>import test from 'ava';
import fn from './';

test(async t => {
	const binName = process.platform === 'win32' ? 'node.exe' : 'ava';
	const list = await fn();

	t.true(list.some(x => x.name.includes(binName)));
	t.true(list.every(x =>
		typeof x.pid === 'number' &&
		typeof x.name === 'string' &&
		typeof x.cmd === 'string'));
});
<commit_msg>Removed String.includes usage<commit_after>import test from 'ava';
import fn from './';

test(async t => {
	const binName = process.platform === 'win32' ? 'node.exe' : 'ava';
	const list = await fn();

	t.true(list.some(x => x.name.indexOf(binName) !== -1));
	t.true(list.every(x =>
		typeof x.pid === 'number' &&
		typeof x.name === 'string' &&
		typeof x.cmd === 'string'));
});
<|endoftext|>


<commit_before><commit_msg>implemented in index.js<commit_after><|endoftext|>


<commit_before>var assert = require('assert')
var testit = require('testit')
var lineJSON = require('.')

testit('combined', function () {
  function test (array) {
    testit(JSON.stringify(array), function () {
      var stringified = lineJSON.stringify(array)
      assert.deepEqual(lineJSON.parse(stringified), array);
    })
  }

  test(['abc', {'afds': 'adsf'}, 4, null, false])
  test([null, ['a', 'b', null, false]])
})

testit('parse', function () {
  testit('throws on invalid input', function () {
    ['', '\n', '"abc"\n', "'abc'"].forEach(function (input) {
      assert.throws(function () {
        lineJSON.parse(input)
      })
    })
  })
})

testit('stringify', function () {
  testit('throws on non-array input', function () {
    [{}, 'a', undefined, null, false, true, 5].forEach(function (input) {
      assert.throws(function () {
        lineJSON.stringify(input)
      }, /not an array/)
    })
  })
  testit('replacer works', function () {
    var input = [ 'a', 'b', { 'c': 'd' } ]
    var i = 0
    var actual = lineJSON.stringify(input, function (a, original) {
      assert.deepEqual(input[i++], original)
      return 'SENTINEL'
    })
    assert.equal(actual, '"SENTINEL"\n"SENTINEL"\n"SENTINEL"')
  })
})
<commit_msg>Fix test on Node.js<commit_after>var assert = require('assert')
var testit = require('testit')
var lineJSON = require('./')

testit('combined', function () {
  function test (array) {
    testit(JSON.stringify(array), function () {
      var stringified = lineJSON.stringify(array)
      assert.deepEqual(lineJSON.parse(stringified), array);
    })
  }

  test(['abc', {'afds': 'adsf'}, 4, null, false])
  test([null, ['a', 'b', null, false]])
})

testit('parse', function () {
  testit('throws on invalid input', function () {
    ['', '\n', '"abc"\n', "'abc'"].forEach(function (input) {
      assert.throws(function () {
        lineJSON.parse(input)
      })
    })
  })
})

testit('stringify', function () {
  testit('throws on non-array input', function () {
    [{}, 'a', undefined, null, false, true, 5].forEach(function (input) {
      assert.throws(function () {
        lineJSON.stringify(input)
      }, /not an array/)
    })
  })
  testit('replacer works', function () {
    var input = [ 'a', 'b', { 'c': 'd' } ]
    var i = 0
    var actual = lineJSON.stringify(input, function (a, original) {
      assert.deepEqual(input[i++], original)
      return 'SENTINEL'
    })
    assert.equal(actual, '"SENTINEL"\n"SENTINEL"\n"SENTINEL"')
  })
})
<|endoftext|>


<commit_before>// Mini port of the github.com/cockroachdb/cockroach/proto
// Specifically the api.go file
var Proto = {
	// RPC commands (Constants)
	// See: https://github.com/cockroachdb/cockroach/blob/81f95062c69552fdbbb3c1387ae79becdc58eb80/proto/api.go#L86
	//
	// Contains determines whether the KV map contains the specified key.
	Contains: "Contains",
	// Get fetches the value for a key from the KV map, respecting a
	// possibly historical timestamp. If the timestamp is 0, returns
	// the most recent value.
	Get: "Get",
	// Put sets the value for a key at the specified timestamp. If the
	// timestamp is 0, the value is set with the current time as timestamp.
	Put: "Put",
	// ConditionalPut sets the value for a key if the existing value
	// matches the value specified in the request. Specifying a null value
	// for existing means the value must not yet exist.
	ConditionalPut: "ConditionalPut",
	// Increment increments the value at the specified key. Once called
	// for a key, Put & Get will return errors; only Increment will
	// continue to be a valid command. The value must be deleted before
	// it can be reset using Put.
	Increment: "Increment",
	// Delete removes the value for the specified key.
	Delete: "Delete",
	// DeleteRange removes all values for keys which fall between
	// args.RequestHeader.Key and args.RequestHeader.EndKey, with
	// the latter endpoint excluded.
	DeleteRange: "DeleteRange",
	// Scan fetches the values for all keys which fall between
	// args.RequestHeader.Key and args.RequestHeader.EndKey, with
	// the latter endpoint excluded.
	Scan: "Scan",
	// EndTransaction either commits or aborts an ongoing transaction.
	EndTransaction: "EndTransaction",
	// ReapQueue scans and deletes messages from a recipient message
	// queue. ReapQueueRequest invocations must be part of an extant
	// transaction or they fail. Returns the reaped queue messsages, up to
	// the requested maximum. If fewer than the maximum were returned,
	// then the queue is empty.
	ReapQueue: "ReapQueue",
	// EnqueueUpdate enqueues an update for eventual execution.
	EnqueueUpdate: "EnqueueUpdate",
	// EnqueueMessage enqueues a message for delivery to an inbox.
	EnqueueMessage: "EnqueueMessage",
	// Batch executes a set of commands in parallel.
	Batch: "Batch",
	// AdminSplit is called to coordinate a split of a range.
	AdminSplit: "AdminSplit",
}

// Request returns a basic request object
Proto.Request = function Request() {
	return {
		header: {
			user: 'root',
		}
	}
}

// GetArgs returns a GetRequest object initialized to get the
// value at key.
Proto.GetRequest = function GetRequest(key) {
	var request = Proto.Request()

	request.header.key = base64(key)

	return request
}

// IncrementArgs returns an IncrementRequest object initialized to
// increment the value at key by increment.
Proto.IncrementRequest = function IncrementRequest(key, increment) {
	var request = Proto.Request()

	request.header.key = base64(key)
	request.increment = increment

	return request
}

// PutArgs returns a PutRequest object initialized to put value
// as a byte slice at key.
Proto.PutRequest = function PutRequest(key, value) {
	var request = Proto.Request()

	request.header.key = base64(key)
	request.value = {
		bytes: base64(value),
		// TODO: calculate checksum
	}

	return request
}

// DeleteArgs returns a DeleteRequest object initialized to delete
// the value at key.
Proto.DeleteRequest = function DeleteRequest(key) {
	var request = Proto.Request()

	request.header.key = base64(key)

	return request
}

// ScanArgs returns a ScanRequest object initialized to scan
// from start to end keys with max results.
Proto.ScanRequest = function ScanRequest(key, endKey, maxResults) {
	var request = Proto.Request()

	request.header.key = base64(key)
	request.header.end_key = base64(endKey)
	request.max_results = maxResults

	return request
}

// Prepare batch request body
// Encapsulate the request in its correct json propertie
// Ported from https://github.com/cockroachdb/cockroach/blob/master/proto/api.proto#L303
Proto.BatchRequestPrepare = function BatchRequestPrepare(method, request) {
	switch(method) {
		case Proto.Contains:
			return {
				contains: request,
			}
		case Proto.Get:
			return {
				get: request,
			}
		case Proto.Put:
			return {
				put: request,
			}
		case Proto.ConditionalPut:
			return {
				conditional_put: request,
			}
		case Proto.Increment:
			return {
				increment: request,
			}
		case Proto.Delete:
			return {
				'delete': request,
			}
		case Proto.DeleteRange:
			return {
				delete_range: request,
			}
		case Proto.Scan:
			return {
				scan: request,
			}
		case Proto.EndTransaction:
			return {
				end_transaction: request,
			}
		case Proto.ReapQueue:
			return {
				reap_queue: request,
			}
		case Proto.EnqueueUpdate:
			return {
				enqueue_update: request,
			}
		case Proto.EnqueueMessage:
			return {
				enqueue_message: request,
			}
		default:
			return {
				// WHAT?
				// TODO:
			}
	}
}

// Batch request
Proto.BatchRequest = function BatchRequest(batch) {
	var request = Proto.Request()

	request.requests = []

	for(var i in batch) {
		request.requests[i] = batch[i]
	}

	return request
}

// Internal helper function, to base64 value
function base64(value) {
	if(typeof value === 'number') {
		value = value.toString()
	}

	return new Buffer(value).toString('base64')
}

// Exports
module.exports = Proto
<commit_msg>added more rpc request data structures<commit_after>// Mini port of the github.com/cockroachdb/cockroach/proto
// Specifically the api.go file
var Proto = {
	// RPC commands (Constants)
	// See: https://github.com/cockroachdb/cockroach/blob/81f95062c69552fdbbb3c1387ae79becdc58eb80/proto/api.go#L86
	//
	// Contains determines whether the KV map contains the specified key.
	Contains: "Contains",
	// Get fetches the value for a key from the KV map, respecting a
	// possibly historical timestamp. If the timestamp is 0, returns
	// the most recent value.
	Get: "Get",
	// Put sets the value for a key at the specified timestamp. If the
	// timestamp is 0, the value is set with the current time as timestamp.
	Put: "Put",
	// ConditionalPut sets the value for a key if the existing value
	// matches the value specified in the request. Specifying a null value
	// for existing means the value must not yet exist.
	ConditionalPut: "ConditionalPut",
	// Increment increments the value at the specified key. Once called
	// for a key, Put & Get will return errors; only Increment will
	// continue to be a valid command. The value must be deleted before
	// it can be reset using Put.
	Increment: "Increment",
	// Delete removes the value for the specified key.
	Delete: "Delete",
	// DeleteRange removes all values for keys which fall between
	// args.RequestHeader.Key and args.RequestHeader.EndKey, with
	// the latter endpoint excluded.
	DeleteRange: "DeleteRange",
	// Scan fetches the values for all keys which fall between
	// args.RequestHeader.Key and args.RequestHeader.EndKey, with
	// the latter endpoint excluded.
	Scan: "Scan",
	// EndTransaction either commits or aborts an ongoing transaction.
	EndTransaction: "EndTransaction",
	// ReapQueue scans and deletes messages from a recipient message
	// queue. ReapQueueRequest invocations must be part of an extant
	// transaction or they fail. Returns the reaped queue messsages, up to
	// the requested maximum. If fewer than the maximum were returned,
	// then the queue is empty.
	ReapQueue: "ReapQueue",
	// EnqueueUpdate enqueues an update for eventual execution.
	EnqueueUpdate: "EnqueueUpdate",
	// EnqueueMessage enqueues a message for delivery to an inbox.
	EnqueueMessage: "EnqueueMessage",
	// Batch executes a set of commands in parallel.
	Batch: "Batch",
	// AdminSplit is called to coordinate a split of a range.
	AdminSplit: "AdminSplit",
}

// Request returns a basic request object
Proto.Request = function Request() {
	return {
		header: {
			user: 'root',
		}
	}
}

Proto.GetRequest = function GetRequest(key) {
	var request = Proto.Request()

	request.header.key = base64(key)

	return request
}

Proto.IncrementRequest = function IncrementRequest(key, increment) {
	var request = Proto.Request()

	request.header.key = base64(key)
	request.increment = increment

	return request
}

Proto.PutRequest = function PutRequest(key, value) {
	var request = Proto.Request()

	request.header.key = base64(key)
	request.value = {
		bytes: base64(value),
		// TODO: calculate checksum
	}

	return request
}

Proto.ConditionalPutRequest = function ConditionalPutRequest(key, value, expectedValue) {
	var request = Proto.Request()

	request.header.key = base64(key)
	request.value = {
		bytes: base64(value),
		// TODO: calculate checksum
	}
	request.exp_value = {
		bytes: base64(expectedValue),
	}

	return request
}

Proto.DeleteRequest = function DeleteRequest(key) {
	var request = Proto.Request()

	request.header.key = base64(key)

	return request
}

Proto.DeleteRangeRequest = function DeleteRangeRequest(key, keyEnd, maxEntries) {
	var request = Proto.Request()

	request.header.key = base64(key)
	request.header.end_key = base64(endKey)
	request.max_entries_to_delete = maxEntries

	return request
}

Proto.ScanRequest = function ScanRequest(key, endKey, maxResults) {
	var request = Proto.Request()

	request.header.key = base64(key)
	request.header.end_key = base64(endKey)
	request.max_results = maxResults

	return request
}

Proto.ContainsRequest = function ContainsRequest(key) {
	var request = Proto.Request()

	request.header.key = base64(key)

	return request
}

// Prepare batch request body
// Encapsulate the request in its correct json propertie
// Ported from https://github.com/cockroachdb/cockroach/blob/master/proto/api.proto#L303
Proto.BatchRequestPrepare = function BatchRequestPrepare(method, request) {
	switch(method) {
		case Proto.Contains:
			return {
				contains: request,
			}
		case Proto.Get:
			return {
				get: request,
			}
		case Proto.Put:
			return {
				put: request,
			}
		case Proto.ConditionalPut:
			return {
				conditional_put: request,
			}
		case Proto.Increment:
			return {
				increment: request,
			}
		case Proto.Delete:
			return {
				'delete': request,
			}
		case Proto.DeleteRange:
			return {
				delete_range: request,
			}
		case Proto.Scan:
			return {
				scan: request,
			}
		case Proto.EndTransaction:
			return {
				end_transaction: request,
			}
		case Proto.ReapQueue:
			return {
				reap_queue: request,
			}
		case Proto.EnqueueUpdate:
			return {
				enqueue_update: request,
			}
		case Proto.EnqueueMessage:
			return {
				enqueue_message: request,
			}
		default:
			return {
				// WHAT?
				// TODO:
			}
	}
}

// Batch request
Proto.BatchRequest = function BatchRequest(batch) {
	var request = Proto.Request()

	request.requests = []

	for(var i in batch) {
		request.requests[i] = batch[i]
	}

	return request
}

// Internal helper function, to base64 value
function base64(value) {
	if(typeof value === 'number') {
		value = value.toString()
	}

	return new Buffer(value).toString('base64')
}

// Exports
module.exports = Proto
<|endoftext|>


<commit_before>// Define our main test function
function spritesmithEngineTest(engine, options) {
  describe('interpretting an image file', function () {
    it('gathers statistics on an image file', function () {

    });
  });
  describe('parsing multiple images', function () {
    describe('rendering them into a canvas', function () {
      it('can output an image', function () {

      });

    });
  });
  describe('interpretting a ridiculous amount of images', function () {
    describe('rendering them into a canvas', function () {
      it('does not crash', function () {

      });
      it('returns an image', function () {

      });
    });
  });

  // DEV: This is testing an edge case of phantomjssmith
  describe('interpretting a large image', function () {
    it('gathers proper image size', function () {

    });
  });
}

// Export the test function
module.exports = spritesmithEngineTest;
<commit_msg>Beginning to assert and document parameters<commit_after>/**
 * Define our main test function
 * @param {Object} params Container for paramters
 * @param {Object} params.engine Spritemith engine to test
 * @param {String} params.engineName Name of engine to test
 * @param {Object} [params.flags] Options to enable/disable tests
 */
function spritesmithEngineTest(params) {
  // Assert and localize parameters
  assert(params, '`params` was not provided to `spritesmith-engine-test`');
  var engine = params.engine;
  assert(engine, '`params.engine` was not provided to `spritesmith-engine-test`');
  assert(params.engineName, '`params.engineName` was not provided to `spritesmith-engine-test`, please provide one (e.g. \'phantomjssmith\')');

  // Define our tests
  describe(params.engineName, function () {
    describe('interpretting an image file', function () {
      it('gathers statistics on an image file', function () {

      });
    });
    describe('parsing multiple images', function () {
      describe('rendering them into a canvas', function () {
        it('can output an image', function () {

        });

      });
    });
    describe('interpretting a ridiculous amount of images', function () {
      describe('rendering them into a canvas', function () {
        it('does not crash', function () {

        });
        it('returns an image', function () {

        });
      });
    });

    // DEV: This is testing an edge case of phantomjssmith
    describe('interpretting a large image', function () {
      it('gathers proper image size', function () {

      });
    });
  });
}

// Export the test function
module.exports = spritesmithEngineTest;
<|endoftext|>


<commit_before>/**
 * @run: node proxy.js ./config.json
 */

/** @namespace require */
/** @namespace process */
/** @namespace process.argv */

var
	  fest      = require('./fest')
	, fs        = require('fs')
	, URL       = require('url')
	, http      = require('http')
	, argv      = process.argv
;

// Get config
if( argv[2] ){
	fs.readFile(argv[2], function (err, config) {
		if( err ){ throw err; }
		new Proxy(JSON.parse(config));
	});
} else {
	new Proxy();
}

function Proxy(config){
	// default
	config = extend({
		  host:         '127.0.0.1'
		, port:         '8090'
		, compile:      null
		, clientMask:   'fest/'
		, templateDir:  'fest/'
		, compileDir:   null
	}, config);

	var _rext = /\.js(\?.*$|$)/;

	/** @namespace http.createServer */
	http.createServer(function (Req, Res){
		var rootDir = Req.headers['x-fest-dir'] ? Req.headers['x-fest-dir'] + '/' : '';
		var file    = URL.parse(Req.url).pathname.replace(_rext, '');
		var pos     = file.indexOf(config.clientMask);

		if( ~pos ){
			file    = file.substr(pos + config.clientMask.length);
		}

		var result  = compile(file, rootDir+config.templateDir, config.compile);

		if( config.compileDir ) try {
			fs.writeFileSync(rootDir+config.compileDir+file+'.js', result, 'utf-8');
		} catch (_){
			console.log(_);
		}

		/** @namespace http.writeHead */
		Res.writeHead(200, { 'Content-Type': 'text/javascript; charset=utf-8' });
		Res.write(result);
		Res.end();
	}).listen(config.port, config.host);
}

function compile(file, srcPath, options){
	var source;

	try {
		// file exists
		fs.lstatSync(srcPath+file+'.xml');
	} catch( err ){
		console.log(err);
		return  compileErrorTpl(file, srcPath+file + ' -- template not found');
	}

	try {
		// fest compile
		source  = fest.compile(srcPath+file+'.xml', options);
	} catch( err ){
		console.log(err);
		return  compileErrorTpl(file, 'fest.compile failed');
	}

	return  complieTpl(file, source);
}

function complieTpl(file, source){
	return  ';(function(x){if(!x.fest)x.fest={};x.fest["'+file+'"]='+source+'})(this);';
}

function compileErrorTpl(file, txt){
	return  complieTpl(file, 'function(){return "[fest.proxy.compile.error] '+ txt +'"}');
}

function extend(dst, src){
	for( var key in src ) if( src.hasOwnProperty(key) ){
		dst[key]    = src[key];
	}
	return  dst;
}

function request(url, fn){
	url = URL.parse(url);
	var opts = {
		  host:     url.hostname
		, port:     url.port
		, method:   'GET'
		, path:     url.pathname
	};

	http.request(opts, function(res){
		var content = '';
		res.on('data', function (chunk){ content += chunk; });
		res.on('end', function (){
			fn(content);
		});
	}).end();
}
<commit_msg>remove leading slash<commit_after>/**
 * @run: node proxy.js ./config.json
 */

/** @namespace require */
/** @namespace process */
/** @namespace process.argv */

var
	  fest      = require('./fest')
	, fs        = require('fs')
	, URL       = require('url')
	, http      = require('http')
	, argv      = process.argv
;

// Get config
if( argv[2] ){
	fs.readFile(argv[2], function (err, config) {
		if( err ){ throw err; }
		new Proxy(JSON.parse(config));
	});
} else {
	new Proxy();
}

function Proxy(config){
	// default
	config = extend({
		  host:         '127.0.0.1'
		, port:         '8090'
		, compile:      null
		, clientMask:   'fest/'
		, templateDir:  'fest/'
		, compileDir:   null
	}, config);

	var _rext = /\.js(\?.*$|$)/;

	/** @namespace http.createServer */
	http.createServer(function (Req, Res){
		var rootDir = Req.headers['x-fest-dir'] ? Req.headers['x-fest-dir'] + '/' : '';
		var file    = URL.parse(Req.url).pathname.replace(/^\//, '').replace(_rext, '');
		var pos     = file.indexOf(config.clientMask);

		if( ~pos ){
			file    = file.substr(pos + config.clientMask.length);
		}

		var result  = compile(file, rootDir+config.templateDir, config.compile);

		if( config.compileDir ) try {
			fs.writeFileSync(rootDir+config.compileDir+file+'.js', result, 'utf-8');
		} catch (_){
			console.log(_);
		}

		/** @namespace http.writeHead */
		Res.writeHead(200, { 'Content-Type': 'text/javascript; charset=utf-8' });
		Res.write(result);
		Res.end();
	}).listen(config.port, config.host);
}

function compile(file, srcPath, options){
	var source;

	try {
		// file exists
		fs.lstatSync(srcPath+file+'.xml');
	} catch( err ){
		console.log(err);
		return  compileErrorTpl(file, srcPath+file + ' -- template not found');
	}

	try {
		// fest compile
		source  = fest.compile(srcPath+file+'.xml', options);
	} catch( err ){
		console.log(err);
		return  compileErrorTpl(file, 'fest.compile failed');
	}

	return  complieTpl(file, source);
}

function complieTpl(file, source){
	return  ';(function(x){if(!x.fest)x.fest={};x.fest["'+file+'"]='+source+'})(this);';
}

function compileErrorTpl(file, txt){
	return  complieTpl(file, 'function(){return "[fest.proxy.compile.error] '+ txt +'"}');
}

function extend(dst, src){
	for( var key in src ) if( src.hasOwnProperty(key) ){
		dst[key]    = src[key];
	}
	return  dst;
}

function request(url, fn){
	url = URL.parse(url);
	var opts = {
		  host:     url.hostname
		, port:     url.port
		, method:   'GET'
		, path:     url.pathname
	};

	http.request(opts, function(res){
		var content = '';
		res.on('data', function (chunk){ content += chunk; });
		res.on('end', function (){
			fn(content);
		});
	}).end();
}
<|endoftext|>