<commit_before>import Board from '../../frontend/src/shogi/board';
import Piece from '../../frontend/src/shogi/piece';
import memo from 'memo-is';
import _ from 'lodash';

describe('Borad', () => {
  describe('#enhanceMovablePoint', () => {
    context('porn', () => {
      context('case of black', () => {
        context('exists movable coordinates', () => {
          var board = memo().is(() => {
            var _board = new Board;
            _board.setBoard(position());
            return(_board);
          });

          var position = memo().is(() => {
            return (
              [
                ['*', '*', '*'],
                ['*', 'P', '*']
              ]
            );
          });

          it('change property of piece that is moved', () => {
            var piece = new Piece({ type: 'P', x: 8, y: 2 });

            board().enhanceMovablePoint(piece);

            var movablePieces = board().board.map((row) => {
              return (
                row.filter((cell) => { return(cell.movable); })
              );
            });

            _.flattenDeep(movablePieces).should.eql(
              [new Piece({ type: '*', x: 8, y: 1, movable: true })]
            );
          });
        });

        context('does not exist movable coordinates', () => {
          var board = memo().is(() => {
            var _board = new Board;
            _board.setBoard(position());
            return(_board);
          });

          var position = memo().is(() => {
            return (
              [
                ['P', '*', '*'],
                ['*', '*', '*']
              ]
            );
          });

          it('does not change property of piece', () => {
            var piece = new Piece({ type: 'P', x: 9, y: 1 });

            board().enhanceMovablePoint(piece);

            var movablePieces = board().board.map((row) => {
              return (
                row.filter((cell) => { return(cell.movable); })
              );
            });

            _.flattenDeep(movablePieces).should.eql([]);
          });
        });

        context.skip('if move piece, king is taken', () => {
        });
      });
    });

    context('case of white', () => {
      context('exists movable coordinates', () => {
      });

      context('does not exist movable coordinates', () => {
      });

      context.skip('if move piece, king is taken', () => {
      });
    });
  });
});
<commit_msg>Add test examples<commit_after>import Board from '../../frontend/src/shogi/board';
import Piece from '../../frontend/src/shogi/piece';
import memo from 'memo-is';
import _ from 'lodash';

describe('Borad', () => {
  describe('#enhanceMovablePoint', () => {
    context('porn', () => {
      context('case of black', () => {
        context('exists movable coordinates', () => {
          var board = memo().is(() => {
            var _board = new Board;
            _board.setBoard(position());
            return(_board);
          });

          var position = memo().is(() => {
            return (
              [
                ['*', '*', '*'],
                ['*', 'P', '*']
              ]
            );
          });

          it('change property of piece that is moved', () => {
            var piece = new Piece({ type: 'P', x: 8, y: 2 });

            board().enhanceMovablePoint(piece);

            var movablePieces = board().board.map((row) => {
              return (
                row.filter((cell) => { return(cell.movable); })
              );
            });

            _.flattenDeep(movablePieces).should.eql(
              [new Piece({ type: '*', x: 8, y: 1, movable: true })]
            );
          });
        });

        context('does not exist movable coordinates', () => {
          var board = memo().is(() => {
            var _board = new Board;
            _board.setBoard(position());
            return(_board);
          });

          var position = memo().is(() => {
            return (
              [
                ['P', '*', '*'],
                ['*', '*', '*']
              ]
            );
          });

          it('does not change property of piece', () => {
            var piece = new Piece({ type: 'P', x: 9, y: 1 });

            board().enhanceMovablePoint(piece);

            var movablePieces = board().board.map((row) => {
              return (
                row.filter((cell) => { return(cell.movable); })
              );
            });

            _.flattenDeep(movablePieces).should.eql([]);
          });
        });

        context.skip('if move piece, king is taken', () => {
        });
      });
    });

    context('case of white', () => {
      context('exists movable coordinates', () => {
        var board = memo().is(() => {
          var _board = new Board;
          _board.setBoard(position());
          return(_board);
        });

        var position = memo().is(() => {
          return (
            [
              ['*', 'p', '*'],
              ['*', '*', '*']
            ]
          );
        });

        it('change property of piece that is moved', () => {
          var piece = new Piece({ type: 'p', x: 8, y: 1 });

          board().enhanceMovablePoint(piece);

          var movablePieces = board().board.map((row) => {
            return (
              row.filter((cell) => { return(cell.movable); })
            );
          });

          _.flattenDeep(movablePieces).should.eql(
            [new Piece({ type: '*', x: 8, y: 2, movable: true })]
          );
        });
      });

      context('does not exist movable coordinates', () => {
        var board = memo().is(() => {
          var _board = new Board;
          _board.setBoard(position());
          return(_board);
        });

        var position = memo().is(() => {
          return (
            [
              ['*', '*', '*'],
              ['p', '*', '*']
            ]
          );
        });

        it('does not change property of piece', () => {
          var piece = new Piece({ type: 'p', x: 9, y: 2 });

          board().enhanceMovablePoint(piece);

          var movablePieces = board().board.map((row) => {
            return (
              row.filter((cell) => { return(cell.movable); })
            );
          });

          _.flattenDeep(movablePieces).should.eql([]);
        });
      });

      context.skip('if move piece, king is taken', () => {
      });
    });
  });
});
<|endoftext|>


<commit_before>'use strict';

const UIDGenerator = require('../index');

const crypto = require('crypto');
const should = require('should');

describe('UIDGenerator', () => {

  describe('new UIDGenerator(bitSize, baseEncoding, uidLength)', () => {

    it('accepts 0 parameters', () => {
      const uidgen = new UIDGenerator();
      uidgen.should.be.an.instanceOf(UIDGenerator);
      uidgen.bitSize.should.be.exactly(128);
      uidgen.baseEncoding.should.be.exactly(UIDGenerator.BASE58);
      uidgen.uidLength.should.be.exactly(22);
      uidgen.base.should.be.exactly(58);
    });

    it('accepts just the bitSize parameter', () => {
      const uidgen = new UIDGenerator(256);
      uidgen.bitSize.should.be.exactly(256);
      uidgen.baseEncoding.should.be.exactly(UIDGenerator.BASE58);
      uidgen.uidLength.should.be.exactly(44);
      uidgen.base.should.be.exactly(58);
    });

    it('accepts just the baseEncoding parameter', () => {
      const uidgen = new UIDGenerator(UIDGenerator.BASE16);
      uidgen.bitSize.should.be.exactly(128);
      uidgen.baseEncoding.should.be.exactly(UIDGenerator.BASE16);
      uidgen.uidLength.should.be.exactly(32);
      uidgen.base.should.be.exactly(16);
    });

    it('accepts just the uidLength parameter', () => {
      const uidgen = new UIDGenerator(null, 10);
      uidgen.bitSize.should.be.exactly(59);
      uidgen.baseEncoding.should.be.exactly(UIDGenerator.BASE58);
      uidgen.uidLength.should.be.exactly(10);
      uidgen.base.should.be.exactly(58);
    });

    it('accepts the bitSize and baseEncoding parameters', () => {
      const uidgen = new UIDGenerator(512, UIDGenerator.BASE62);
      uidgen.bitSize.should.be.exactly(512);
      uidgen.baseEncoding.should.be.exactly(UIDGenerator.BASE62);
      uidgen.uidLength.should.be.exactly(86);
      uidgen.base.should.be.exactly(62);
    });

    it('accepts the baseEncoding and uidLength parameters', () => {
      const uidgen = new UIDGenerator(UIDGenerator.BASE62, 22);

      uidgen.bitSize.should.be.exactly(131);
      uidgen.baseEncoding.should.be.exactly(UIDGenerator.BASE62);
      uidgen.uidLength.should.be.exactly(22);
      uidgen.base.should.be.exactly(62);

      new UIDGenerator(null, UIDGenerator.BASE62, 22).should.deepEqual(uidgen);
      new UIDGenerator(undefined, UIDGenerator.BASE62, 22).should.deepEqual(uidgen);
    });

    it('accepts a custom baseEncoding', () => {
      new UIDGenerator('123abc').baseEncoding.should.be.exactly('123abc');
      new UIDGenerator(512, 'abc123').baseEncoding.should.be.exactly('abc123');
      new UIDGenerator('01', 9).baseEncoding.should.be.exactly('01');
    });

    it('throws if bitSize is not a positive integer that is a multiple of 8', () => {
      should.throws(() => new UIDGenerator(0), TypeError);
      should.throws(() => new UIDGenerator(1), TypeError);
      should.throws(() => new UIDGenerator(-8), TypeError);
      should.throws(() => new UIDGenerator(-128), TypeError);
      should.throws(() => new UIDGenerator(127), TypeError);
      should.throws(() => new UIDGenerator(1.5), TypeError);
      should.throws(() => new UIDGenerator(Math.PI), TypeError);
      should.throws(() => new UIDGenerator(Infinity), TypeError);
      should.throws(() => new UIDGenerator(true), TypeError);
      should.throws(() => new UIDGenerator({}), TypeError);
      should.throws(() => new UIDGenerator([]), TypeError);
      should.throws(() => new UIDGenerator(/regex/), TypeError);
    });

    it('throws if baseEncoding is not a string', () => {
      should.throws(() => new UIDGenerator(128, true), TypeError);
      should.throws(() => new UIDGenerator(128, 256), TypeError);
      should.throws(() => new UIDGenerator(128, {}), TypeError);
      should.throws(() => new UIDGenerator(128, []), TypeError);
      should.throws(() => new UIDGenerator(128, /regex/), TypeError);
      should.throws(() => new UIDGenerator(128, new Date()), TypeError);
    });

    it('throws if baseEncoding contains non-unique characters', () => {
      should.throws(() => new UIDGenerator('11'), Error);
      should.throws(() => new UIDGenerator('011'), Error);
      should.throws(() => new UIDGenerator('110'), Error);
      should.throws(() => new UIDGenerator('101'), Error);
      should.throws(() => new UIDGenerator('0121'), Error);
      should.throws(() => new UIDGenerator('01213'), Error);
    });

    it('throws if uidLength is not a positive integer', () => {
      should.throws(() => new UIDGenerator('01', 0), TypeError);
      should.throws(() => new UIDGenerator('01', -1), TypeError);
      should.throws(() => new UIDGenerator('01', -128), TypeError);
      should.throws(() => new UIDGenerator('01', 1.5), TypeError);
      should.throws(() => new UIDGenerator('01', Math.PI), TypeError);
      should.throws(() => new UIDGenerator('01', Infinity), TypeError);
      should.throws(() => new UIDGenerator('01', true), TypeError);
      should.throws(() => new UIDGenerator('01', false), TypeError);
      should.throws(() => new UIDGenerator('01', {}), TypeError);
      should.throws(() => new UIDGenerator('01', []), TypeError);
      should.throws(() => new UIDGenerator('01', /regex/), TypeError);
    });

    it('throws if both bitSize and uidLength are specified', () => {
      should.throws(() => new UIDGenerator(24, 24), TypeError);
      should.throws(() => new UIDGenerator(16, UIDGenerator.BASE16, 2), TypeError);
    });

  });

  describe('#bitSize', () => {

    it('is the same value as is passed to the constructor or calculated from uidLength', () => {
      new UIDGenerator().bitSize.should.be.exactly(128);
      new UIDGenerator(256).bitSize.should.be.exactly(256);
      new UIDGenerator(null, 11).bitSize.should.be.exactly(65);
    });

  });

  describe('#baseEncoding', () => {

    it('is the same value as is passed to the constructor', () => {
      new UIDGenerator().baseEncoding.should.be.exactly(UIDGenerator.BASE58);
      new UIDGenerator(UIDGenerator.BASE62).baseEncoding.should.be.exactly(UIDGenerator.BASE62);
      new UIDGenerator(8, '01').baseEncoding.should.be.exactly('01');
    });

  });

  describe('#base', () => {

    it('is the encoding base number (which is the length of the baseEncoding)', () => {
      new UIDGenerator().base.should.be.exactly(58);
      new UIDGenerator(UIDGenerator.BASE62).base.should.be.exactly(62);
      new UIDGenerator(UIDGenerator.BASE16, 11).base.should.be.exactly(16);
      new UIDGenerator(256, '123abc').base.should.be.exactly(6);
    });

  });

  describe('#uidLength', () => {

    it('is the same value as passed to the constructor or the calculated UID length', () => {
      new UIDGenerator(null, 1).uidLength.should.be.exactly(1);
      new UIDGenerator('abc', 10).uidLength.should.be.exactly(10);
      new UIDGenerator().uidLength.should.be.exactly(22);
      new UIDGenerator(256, UIDGenerator.BASE62).uidLength.should.be.exactly(43);
      new UIDGenerator(512, '01').uidLength.should.be.exactly(512);
    });

  });

  describe('UIDGenerator instance', () => {

    it('generates UIDs asynchronously with a callback', (done) => {
      new UIDGenerator().generate((err, uid) => {
        uid.should.have.type('string');
        done(err);
      });
    });

    it('generates UIDs asynchronously with a promise', (done) => {
      new UIDGenerator().generate()
        .then((uid) => {
          uid.should.have.type('string');
          done();
        })
        .catch(done);
    });

    it('generates UIDs synchronously', () => {
      new UIDGenerator().generateSync().should.have.type('string');
    });

    it('generates UIDs with the specified baseEncoding and bitSize or uidLength', () => {
      let uidgen = new UIDGenerator();
      let uid = uidgen.generateSync();
      uid.should.match(new RegExp('^[' + uidgen.baseEncoding + ']{' + uidgen.uidLength + '}$'));

      uidgen = new UIDGenerator(UIDGenerator.BASE16);
      uid = uidgen.generateSync();
      uid.should.match(new RegExp('^[' + uidgen.baseEncoding + ']{' + uidgen.uidLength + '}$'));

      uidgen = new UIDGenerator('01');
      uid = uidgen.generateSync();
      uid.should.match(new RegExp('^[' + uidgen.baseEncoding + ']{' + uidgen.uidLength + '}$'));

      uidgen = new UIDGenerator(256);
      uid = uidgen.generateSync();
      uid.should.match(new RegExp('^[' + uidgen.baseEncoding + ']{' + uidgen.uidLength + '}$'));

      uidgen = new UIDGenerator(null, 20);
      uid = uidgen.generateSync();
      uid.should.match(new RegExp('^[' + uidgen.baseEncoding + ']{' + uidgen.uidLength + '}$'));

      uidgen = new UIDGenerator(512, UIDGenerator.BASE62);
      uid = uidgen.generateSync();
      uid.should.match(new RegExp('^[' + uidgen.baseEncoding + ']{' + uidgen.uidLength + '}$'));

      uidgen = new UIDGenerator(UIDGenerator.BASE16, 20);
      uid = uidgen.generateSync();
      uid.should.match(new RegExp('^[' + uidgen.baseEncoding + ']{' + uidgen.uidLength + '}$'));
    });

    it('produces UIDs of the correct length even if crypto.randomBytes() returns a Buffer with leading zeros', () => {
      const randomBytes = crypto.randomBytes;

      // Mock crypto.randomBytes
      crypto.randomBytes = function(size) {
        return Buffer.alloc(size, 1);
      };
      let uidgen = new UIDGenerator(256);
      let uid = uidgen.generateSync();
      uid.should.match(new RegExp('^[' + uidgen.baseEncoding + ']{' + uidgen.uidLength + '}$'));

      crypto.randomBytes = function(size) {
        return Buffer.alloc(size);
      };
      uidgen = new UIDGenerator();
      uid = uidgen.generateSync();
      uid.should.match(new RegExp('^[' + uidgen.baseEncoding + ']{' + uidgen.uidLength + '}$'));

      uidgen = new UIDGenerator('abc', 3);
      uid = uidgen.generateSync();
      uid.should.match(new RegExp('^[' + uidgen.baseEncoding + ']{' + uidgen.uidLength + '}$'));

      crypto.randomBytes = function(size) {
        const buffer = Buffer.alloc(size);
        buffer[size - 1] = 255;
        return buffer;
      };
      uidgen = new UIDGenerator(null, 20);
      uid = uidgen.generateSync();
      uid.should.match(new RegExp('^[' + uidgen.baseEncoding + ']{' + uidgen.uidLength + '}$'));

      // Restore crypto.randomBytes
      crypto.randomBytes = randomBytes;
    });

    it('base-encodes UIDs in a standard fasion', () => {
      const randomBytes = crypto.randomBytes;
      let buffer;

      // Mock crypto.randomBytes
      crypto.randomBytes = function(size) {
        return buffer = randomBytes(size);
      };

      new UIDGenerator(UIDGenerator.BASE16).generateSync()
        .should.equal(buffer.toString('hex'));

      // Test to ensure that the digits.length > this.uidLength path is hit
      crypto.randomBytes = function(size) {
        const buf = Buffer.allocUnsafe(size);
        buf[0] = 3;
        return buf;
      };

      new UIDGenerator('01', 1).generateSync().should.equal('1');

      // Restore crypto.randomBytes
      crypto.randomBytes = randomBytes;
    });

    it('correctly handles asynchronous errors', (done) => {
      const randomBytes = crypto.randomBytes;
      const error = new Error('Fake error');

      // Mock crypto.randomBytes
      crypto.randomBytes = function(size, cb) {
        process.nextTick(() => {
          cb(error);
        });
      };

      new UIDGenerator().generate()
        .catch((err) => {
          err.should.be.exactly(error);
        })
        .then(() => {
          new UIDGenerator().generate((err) => {
            err.should.be.exactly(error);
            // Restore crypto.randomBytes
            crypto.randomBytes = randomBytes;
            done();
          });
        });
    });

  });

});
<commit_msg>test: Clean up code and fix typo<commit_after>'use strict';

const UIDGenerator = require('../index');

const crypto = require('crypto');
const should = require('should');

describe('UIDGenerator', () => {

  describe('new UIDGenerator(bitSize, baseEncoding, uidLength)', () => {

    it('accepts 0 parameters', () => {
      const uidgen = new UIDGenerator();

      uidgen.should.be.an.instanceOf(UIDGenerator);
      uidgen.bitSize.should.be.exactly(128);
      uidgen.baseEncoding.should.be.exactly(UIDGenerator.BASE58);
      uidgen.uidLength.should.be.exactly(22);
      uidgen.base.should.be.exactly(58);
    });

    it('accepts just the bitSize parameter', () => {
      const uidgen = new UIDGenerator(256);

      uidgen.bitSize.should.be.exactly(256);
      uidgen.baseEncoding.should.be.exactly(UIDGenerator.BASE58);
      uidgen.uidLength.should.be.exactly(44);
      uidgen.base.should.be.exactly(58);
    });

    it('accepts just the baseEncoding parameter', () => {
      const uidgen = new UIDGenerator(UIDGenerator.BASE16);

      uidgen.bitSize.should.be.exactly(128);
      uidgen.baseEncoding.should.be.exactly(UIDGenerator.BASE16);
      uidgen.uidLength.should.be.exactly(32);
      uidgen.base.should.be.exactly(16);
    });

    it('accepts just the uidLength parameter', () => {
      const uidgen = new UIDGenerator(null, 10);

      uidgen.bitSize.should.be.exactly(59);
      uidgen.baseEncoding.should.be.exactly(UIDGenerator.BASE58);
      uidgen.uidLength.should.be.exactly(10);
      uidgen.base.should.be.exactly(58);
    });

    it('accepts the bitSize and baseEncoding parameters', () => {
      const uidgen = new UIDGenerator(512, UIDGenerator.BASE62);

      uidgen.bitSize.should.be.exactly(512);
      uidgen.baseEncoding.should.be.exactly(UIDGenerator.BASE62);
      uidgen.uidLength.should.be.exactly(86);
      uidgen.base.should.be.exactly(62);
    });

    it('accepts the baseEncoding and uidLength parameters', () => {
      const uidgen = new UIDGenerator(UIDGenerator.BASE62, 22);

      uidgen.bitSize.should.be.exactly(131);
      uidgen.baseEncoding.should.be.exactly(UIDGenerator.BASE62);
      uidgen.uidLength.should.be.exactly(22);
      uidgen.base.should.be.exactly(62);

      new UIDGenerator(null, UIDGenerator.BASE62, 22).should.deepEqual(uidgen);
      new UIDGenerator(undefined, UIDGenerator.BASE62, 22).should.deepEqual(uidgen);
    });

    it('accepts a custom baseEncoding', () => {
      new UIDGenerator('123abc').baseEncoding.should.be.exactly('123abc');
      new UIDGenerator(512, 'abc123').baseEncoding.should.be.exactly('abc123');
      new UIDGenerator('01', 9).baseEncoding.should.be.exactly('01');
    });

    it('throws if bitSize is not a positive integer that is a multiple of 8', () => {
      should.throws(() => new UIDGenerator(0), TypeError);
      should.throws(() => new UIDGenerator(1), TypeError);
      should.throws(() => new UIDGenerator(-8), TypeError);
      should.throws(() => new UIDGenerator(-128), TypeError);
      should.throws(() => new UIDGenerator(127), TypeError);
      should.throws(() => new UIDGenerator(1.5), TypeError);
      should.throws(() => new UIDGenerator(Math.PI), TypeError);
      should.throws(() => new UIDGenerator(Infinity), TypeError);
      should.throws(() => new UIDGenerator(true), TypeError);
      should.throws(() => new UIDGenerator({}), TypeError);
      should.throws(() => new UIDGenerator([]), TypeError);
      should.throws(() => new UIDGenerator(/regex/), TypeError);
    });

    it('throws if baseEncoding is not a string', () => {
      should.throws(() => new UIDGenerator(128, true), TypeError);
      should.throws(() => new UIDGenerator(128, 256), TypeError);
      should.throws(() => new UIDGenerator(128, {}), TypeError);
      should.throws(() => new UIDGenerator(128, []), TypeError);
      should.throws(() => new UIDGenerator(128, /regex/), TypeError);
      should.throws(() => new UIDGenerator(128, new Date()), TypeError);
    });

    it('throws if baseEncoding contains non-unique characters', () => {
      should.throws(() => new UIDGenerator('11'), Error);
      should.throws(() => new UIDGenerator('011'), Error);
      should.throws(() => new UIDGenerator('110'), Error);
      should.throws(() => new UIDGenerator('101'), Error);
      should.throws(() => new UIDGenerator('0121'), Error);
      should.throws(() => new UIDGenerator('01213'), Error);
    });

    it('throws if uidLength is not a positive integer', () => {
      should.throws(() => new UIDGenerator('01', 0), TypeError);
      should.throws(() => new UIDGenerator('01', -1), TypeError);
      should.throws(() => new UIDGenerator('01', -128), TypeError);
      should.throws(() => new UIDGenerator('01', 1.5), TypeError);
      should.throws(() => new UIDGenerator('01', Math.PI), TypeError);
      should.throws(() => new UIDGenerator('01', Infinity), TypeError);
      should.throws(() => new UIDGenerator('01', true), TypeError);
      should.throws(() => new UIDGenerator('01', false), TypeError);
      should.throws(() => new UIDGenerator('01', {}), TypeError);
      should.throws(() => new UIDGenerator('01', []), TypeError);
      should.throws(() => new UIDGenerator('01', /regex/), TypeError);
    });

    it('throws if both bitSize and uidLength are specified', () => {
      should.throws(() => new UIDGenerator(24, 24), TypeError);
      should.throws(() => new UIDGenerator(16, UIDGenerator.BASE16, 2), TypeError);
    });

  });

  describe('#bitSize', () => {

    it('is the same value as is passed to the constructor or calculated from uidLength', () => {
      new UIDGenerator().bitSize.should.be.exactly(128);
      new UIDGenerator(256).bitSize.should.be.exactly(256);
      new UIDGenerator(null, 11).bitSize.should.be.exactly(65);
    });

  });

  describe('#baseEncoding', () => {

    it('is the same value as is passed to the constructor', () => {
      new UIDGenerator().baseEncoding.should.be.exactly(UIDGenerator.BASE58);
      new UIDGenerator(UIDGenerator.BASE62).baseEncoding.should.be.exactly(UIDGenerator.BASE62);
      new UIDGenerator(8, '01').baseEncoding.should.be.exactly('01');
    });

  });

  describe('#base', () => {

    it('is the encoding base number (which is the length of the baseEncoding)', () => {
      new UIDGenerator().base.should.be.exactly(58);
      new UIDGenerator(UIDGenerator.BASE62).base.should.be.exactly(62);
      new UIDGenerator(UIDGenerator.BASE16, 11).base.should.be.exactly(16);
      new UIDGenerator(256, '123abc').base.should.be.exactly(6);
    });

  });

  describe('#uidLength', () => {

    it('is the same value as passed to the constructor or the calculated UID length', () => {
      new UIDGenerator(null, 1).uidLength.should.be.exactly(1);
      new UIDGenerator('abc', 10).uidLength.should.be.exactly(10);
      new UIDGenerator().uidLength.should.be.exactly(22);
      new UIDGenerator(256, UIDGenerator.BASE62).uidLength.should.be.exactly(43);
      new UIDGenerator(512, '01').uidLength.should.be.exactly(512);
    });

  });

  describe('UIDGenerator instance', () => {

    it('generates UIDs asynchronously with a callback', (done) => {
      new UIDGenerator().generate((err, uid) => {
        uid.should.have.type('string');
        done(err);
      });
    });

    it('generates UIDs asynchronously with a promise', () => {
      return new UIDGenerator().generate()
        .then((uid) => {
          uid.should.have.type('string');
        });
    });

    it('generates UIDs synchronously', () => {
      new UIDGenerator().generateSync().should.have.type('string');
    });

    it('generates UIDs with the specified baseEncoding and bitSize or uidLength', () => {
      let uidgen = new UIDGenerator();
      let uid = uidgen.generateSync();
      uid.should.match(new RegExp('^[' + uidgen.baseEncoding + ']{' + uidgen.uidLength + '}$'));

      uidgen = new UIDGenerator(UIDGenerator.BASE16);
      uid = uidgen.generateSync();
      uid.should.match(new RegExp('^[' + uidgen.baseEncoding + ']{' + uidgen.uidLength + '}$'));

      uidgen = new UIDGenerator('01');
      uid = uidgen.generateSync();
      uid.should.match(new RegExp('^[' + uidgen.baseEncoding + ']{' + uidgen.uidLength + '}$'));

      uidgen = new UIDGenerator(256);
      uid = uidgen.generateSync();
      uid.should.match(new RegExp('^[' + uidgen.baseEncoding + ']{' + uidgen.uidLength + '}$'));

      uidgen = new UIDGenerator(null, 20);
      uid = uidgen.generateSync();
      uid.should.match(new RegExp('^[' + uidgen.baseEncoding + ']{' + uidgen.uidLength + '}$'));

      uidgen = new UIDGenerator(512, UIDGenerator.BASE62);
      uid = uidgen.generateSync();
      uid.should.match(new RegExp('^[' + uidgen.baseEncoding + ']{' + uidgen.uidLength + '}$'));

      uidgen = new UIDGenerator(UIDGenerator.BASE16, 20);
      uid = uidgen.generateSync();
      uid.should.match(new RegExp('^[' + uidgen.baseEncoding + ']{' + uidgen.uidLength + '}$'));
    });

    it('produces UIDs of the correct length even if crypto.randomBytes() returns a Buffer with leading zeros', () => {
      const randomBytes = crypto.randomBytes;

      // Mock crypto.randomBytes
      crypto.randomBytes = function(size) {
        return Buffer.alloc(size, 1);
      };

      let uidgen = new UIDGenerator(256);
      let uid = uidgen.generateSync();
      uid.should.match(new RegExp('^[' + uidgen.baseEncoding + ']{' + uidgen.uidLength + '}$'));

      crypto.randomBytes = function(size) {
        return Buffer.alloc(size);
      };

      uidgen = new UIDGenerator();
      uid = uidgen.generateSync();
      uid.should.match(new RegExp('^[' + uidgen.baseEncoding + ']{' + uidgen.uidLength + '}$'));

      uidgen = new UIDGenerator('abc', 3);
      uid = uidgen.generateSync();
      uid.should.match(new RegExp('^[' + uidgen.baseEncoding + ']{' + uidgen.uidLength + '}$'));

      crypto.randomBytes = function(size) {
        const buffer = Buffer.alloc(size);
        buffer[size - 1] = 255;
        return buffer;
      };

      uidgen = new UIDGenerator(null, 20);
      uid = uidgen.generateSync();
      uid.should.match(new RegExp('^[' + uidgen.baseEncoding + ']{' + uidgen.uidLength + '}$'));

      // Restore crypto.randomBytes
      crypto.randomBytes = randomBytes;
    });

    it('base-encodes UIDs in a standard fashion', () => {
      const randomBytes = crypto.randomBytes;
      let buffer;

      // Mock crypto.randomBytes
      crypto.randomBytes = function(size) {
        return buffer = randomBytes(size);
      };

      new UIDGenerator(UIDGenerator.BASE16).generateSync()
        .should.equal(buffer.toString('hex'));

      // Test to ensure that the digits.length > this.uidLength path is hit
      crypto.randomBytes = function(size) {
        const buf = Buffer.allocUnsafe(size);
        buf[0] = 3;
        return buf;
      };

      new UIDGenerator('01', 1).generateSync().should.equal('1');

      // Restore crypto.randomBytes
      crypto.randomBytes = randomBytes;
    });

    it('correctly handles asynchronous errors', (done) => {
      const randomBytes = crypto.randomBytes;
      const error = new Error('Fake error');

      // Mock crypto.randomBytes
      crypto.randomBytes = function(size, cb) {
        process.nextTick(() => {
          cb(error);
        });
      };

      new UIDGenerator().generate()
        .catch((err) => {
          err.should.be.exactly(error);
        })
        .then(() => {
          new UIDGenerator().generate((err) => {
            err.should.be.exactly(error);
            // Restore crypto.randomBytes
            crypto.randomBytes = randomBytes;
            done();
          });
        });
    });

  });

});
<|endoftext|>


<commit_before>/*!
 * handle-arguments <https://github.com/hybridables/handle-arguments>
 *
 * Copyright (c) 2015-2016 Charlike Mike Reagent <@tunnckoCore> (http://www.tunnckocore.tk)
 * Released under the MIT license.
 */

/* jshint asi:true */

'use strict'

var test = require('assertit')
var handleArguments = require('./index')

test('handle-arguments', function () {
  test('should throw error', function () {
    // test('when Object is given - handleArguments({name: 123})', function (done) {
    //   function fixture () {
    //     handleArguments({name: 123})
    //   }
    //   test.throws(fixture, /expect only Arguments object/)
    //   done()
    // })
    // test('when no params is given - handleArguments()', function (done) {
    //   function fixture () {
    //     handleArguments()
    //   }
    //   test.throws(fixture, /expect only Arguments object/)
    //   done()
    // })
    // test('when Number is given - handleArguments(123)', function (done) {
    //   function fixture () {
    //     handleArguments(123)
    //   }
    //   test.throws(fixture, /expect only Arguments object/)
    //   done()
    // })
    // test('when Array is given - handleArguments([1,2,3])', function (done) {
    //   function fixture () {
    //     handleArguments([1, 2, 3])
    //   }
    //   test.throws(fixture, /expect only Arguments object/)
    //   done()
    // })
    // test('when String is given - handleArguments("123")', function (done) {
    //   function fixture () {
    //     handleArguments('123')
    //   }
    //   test.throws(fixture, /expect only Arguments object/)
    //   done()
    // })
  })

  test('should work with real Arguments object', function () {
    test('when do not have `function` as last argument', function (done) {
      function fixture () {
        return handleArguments(arguments)
      }
      var actual = fixture(1, 2, 3)

      test.deepEqual(actual.arguments, [1, 2, 3])
      test.ok(!actual.callback)
      done()
    })
    test('when have `function` (cb) as last argument', function (done) {
      function fixture () {
        return handleArguments(arguments)
      }
      var actual = fixture(1, 2, 3, function callback () {})
      test.deepEqual(actual.arguments, [1, 2, 3])
      test.strictEqual(actual.callback.name, 'callback')
      test.strictEqual(typeof actual.callback, 'function')
      done()
    })
  })
})
<commit_msg>start tests<commit_after>/*!
 * handle-arguments <https://github.com/hybridables/handle-arguments>
 *
 * Copyright (c) 2015-2016 Charlike Mike Reagent <@tunnckoCore> (http://www.tunnckocore.tk)
 * Released under the MIT license.
 */

/* jshint asi:true */

'use strict'

var test = require('assertit')
var handle = require('./index')

test('should return object with `.arguments` and `.callback` properties', function (done) {
  function fixture () {
    return handle(arguments)
  }
  var actual = fixture(1, 2, 3)
  test.strictEqual(typeof actual === 'object', true)
  test.ok(!actual.callback)
  test.strictEqual(actual.callback, false)
  test.deepEqual(actual.arguments, [1, 2, 3])
  done()
})

// test('handle-arguments', function () {
//   test('should throw error', function () {
//     // test('when Object is given - handleArguments({name: 123})', function (done) {
//     //   function fixture () {
//     //     handleArguments({name: 123})
//     //   }
//     //   test.throws(fixture, /expect only Arguments object/)
//     //   done()
//     // })
//     // test('when no params is given - handleArguments()', function (done) {
//     //   function fixture () {
//     //     handleArguments()
//     //   }
//     //   test.throws(fixture, /expect only Arguments object/)
//     //   done()
//     // })
//     // test('when Number is given - handleArguments(123)', function (done) {
//     //   function fixture () {
//     //     handleArguments(123)
//     //   }
//     //   test.throws(fixture, /expect only Arguments object/)
//     //   done()
//     // })
//     // test('when Array is given - handleArguments([1,2,3])', function (done) {
//     //   function fixture () {
//     //     handleArguments([1, 2, 3])
//     //   }
//     //   test.throws(fixture, /expect only Arguments object/)
//     //   done()
//     // })
//     // test('when String is given - handleArguments("123")', function (done) {
//     //   function fixture () {
//     //     handleArguments('123')
//     //   }
//     //   test.throws(fixture, /expect only Arguments object/)
//     //   done()
//     // })
//   })

//   test('should work with real Arguments object', function () {
//     test('when do not have `function` as last argument', function (done) {
//       function fixture () {
//         return handleArguments(arguments)
//       }
//       var actual = fixture(1, 2, 3)

//       test.deepEqual(actual.arguments, [1, 2, 3])
//       test.ok(!actual.callback)
//       done()
//     })
//     test('when have `function` (cb) as last argument', function (done) {
//       function fixture () {
//         return handleArguments(arguments)
//       }
//       var actual = fixture(1, 2, 3, function callback () {})
//       test.deepEqual(actual.arguments, [1, 2, 3])
//       test.strictEqual(actual.callback.name, 'callback')
//       test.strictEqual(typeof actual.callback, 'function')
//       done()
//     })
//   })
// })
<|endoftext|>


<commit_before>var couchdb = require('../couchdb'),
    logger = require('../logger'),
    url = require('url');

exports.summary = 'Returns UUIDs generated by a CouchDB instance';
exports.usage = '' +
'kanso uuids [OPTIONS] URL\n' +
'\n' +
'Options:\n' +
'  -n [NUM]    The number of UUIDs to generate (default: 1)';

exports.run = function (args) {
    var count = 1;
    for (var i = 0; i < args.length; i += 1) {
        if (args[i] === '-n') {
            count = args[i + 1];
            args.splice(i, 2);
            i = 0;
        }
    }
    if (!args[0]) {
        logger.error('No CouchDB URL specified');
        logger.info('Usage: ' + exports.usage);
        return;
    }

    // /_uuids is at the root couchdb instance level, not the db level
    var parsed = url.parse(args[0]);
    delete parsed.pathname;
    delete parsed.query;
    delete parsed.search;
    var db = couchdb(url.format(parsed));

    db.uuids(count, function (err, uuids) {
        if (err) {
            return logger.error(err);
        }
        uuids.forEach(function (uuid) {
            console.log(uuid);
        });
        logger.clean_exit = true;
    });
};
<commit_msg>make couchdb url option when generating uuids<commit_after>var couchdb = require('../couchdb'),
    logger = require('../logger'),
    url = require('url');

exports.summary = 'Returns UUIDs generated by a CouchDB instance';
exports.usage = '' +
'kanso uuids [OPTIONS] [URL]\n' +
'\n' +
'Parameters:\n' +
'  URL         The CouchDB instance to generate UUIDs from\n' +
'              (defaults to http://localhost:5984)\n' +
'\n' +
'Options:\n' +
'  -n [NUM]    The number of UUIDs to generate (default: 1)';

exports.run = function (args) {
    var count = 1;
    for (var i = 0; i < args.length; i += 1) {
        if (args[i] === '-n') {
            count = args[i + 1];
            args.splice(i, 2);
            i = 0;
        }
    }
    // TODO: warn when defaulting to http://localhost:5984 ?
    /*if (!args[0]) {
        logger.error('No CouchDB URL specified');
        logger.info('Usage: ' + exports.usage);
        return;
    }*/
    var couchdb_url = args[0] || 'http://localhost:5984';

    // /_uuids is at the root couchdb instance level, not the db level
    var parsed = url.parse(couchdb_url);
    delete parsed.pathname;
    delete parsed.query;
    delete parsed.search;
    var db = couchdb(url.format(parsed));

    db.uuids(count, function (err, uuids) {
        if (err) {
            return logger.error(err);
        }
        uuids.forEach(function (uuid) {
            console.log(uuid);
        });
        logger.clean_exit = true;
    });
};
<|endoftext|>


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

var Stopwatch = require('../lib/Stopwatch');
var defaultPrecision = 15;
var assert = require('assert');
var should = require('should');

describe('stopwatch', function () {
    this.timeout(5000);

    describe('constructor', function () {
        it('w/no params', function () {
            var stopwatch = new Stopwatch();
            should.exist(stopwatch);
        });

        it('w/name as first param', function () {
            var stopwatch = new Stopwatch('metric-name');
            stopwatch.name().should.equal('metric-name');
        });

        it('w/autostart as first param', function () {
            var stopwatch = new Stopwatch(true);
            should.exist(stopwatch.name());
            stopwatch.name().should.not.equal(true);
        });

        it('w/both name and autostart', function () {
            var stopwatch = new Stopwatch('metric-name', true);
            stopwatch.name().should.equal('metric-name');
        });

        it('autocreated names are not constant', function () {
            var stopwatch1 = new Stopwatch(true);
            var stopwatch2 = new Stopwatch(true);
            stopwatch1.name().should.not.equal(stopwatch2.name());
        });
    });

    it('start and read (100ms)', function (done) {
        var testtime = 100;

        var stopwatch = new Stopwatch();
        stopwatch.start();
        setTimeout(function () {
            var delta = stopwatch.read();
            verifyDelta(testtime, delta, defaultPrecision);
            done();
        }, testtime);
    });

    it('start and read (10ms)', function (done) {
        var testtime = 10;

        var stopwatch = new Stopwatch();
        stopwatch.start();
        setTimeout(function () {
            var delta = stopwatch.read();
            verifyDelta(testtime, delta, defaultPrecision);
            done();
        }, testtime);
    });

    it('autostart set to true automatically starts stopwatch', function (done) {
        var testtime = 10;

        var stopwatch = new Stopwatch(true);
        setTimeout(function () {
            var delta = stopwatch.read();
            verifyDelta(testtime, delta, defaultPrecision);
            done();
        }, testtime);
    });

    it('autostart set to false does NOT automatically start stopwatch', function (done) {
        var testtime = 10;

        var stopwatch = new Stopwatch(false);
        setTimeout(function () {
            stopwatch.read().should.be.NaN();
            done();
        }, testtime);
    });

    it('with two stopwatches, do independent reads of each', function (done) {
        var stopwatch1 = new Stopwatch();
        var stopwatch2 = new Stopwatch();

        stopwatch1.start();

        //start first stopwatch, then do a read .3s later
        var testtimeA = 300;
        setTimeout(function () {
            var delta1 = stopwatch1.read();
            verifyDelta(testtimeA, delta1, defaultPrecision);
        }, testtimeA);

        //start second stopwatch .1s second after the first, then do a read .5s later
        var testtimeB = 500;
        setTimeout(function () {
            stopwatch2.start();
            setTimeout(function () {
                var delta2 = stopwatch2.read();
                verifyDelta(testtimeB, delta2, defaultPrecision);
                done();
            }, testtimeB);
        }, 100);
    });

    it('start, stop, and read should return the time at stop', function (done) {
        var testtime = 100;

        var stopwatch = new Stopwatch();
        stopwatch.start();
        setTimeout(function () {
            stopwatch.stop();

            setTimeout(function () {
                var delta = stopwatch.read();
                verifyDelta(testtime, delta, defaultPrecision);
                done();
            }, 500);
        }, testtime);
    });

    it('performing read without start() or stop() returns NaN', function (done) {
        var stopwatch = new Stopwatch();
        assert.ok(isNaN(stopwatch.read()));
        done();
    });

    it('performing read without start() returns NaN', function (done) {
        var stopwatch = new Stopwatch();
        stopwatch.stop();
        assert.ok(isNaN(stopwatch.read()));
        done();
    });

    it('executing stop twice should return time at second stop', function (done) {
        //start(), wait .1s, stop(), wait .2s, stop(), wait .5s, read(), ensure delta = .3s
        var stopwatch = new Stopwatch();
        stopwatch.start();
        setTimeout(function () {
            stopwatch.stop();

            setTimeout(function () {
                verifyDelta(100 + 200, stopwatch.stop(), defaultPrecision);

                setTimeout(function () {
                    var delta = stopwatch.read();
                    verifyDelta(100 + 200, delta, defaultPrecision);
                    done();
                }, 500);
            }, 200);
        }, 100);
    });

    it('ensure that stop() returns time', function (done) {
        var testtime = 100;
        var stopwatch = new Stopwatch();
        stopwatch.start();
        setTimeout(function () {
            var delta = stopwatch.stop();
            verifyDelta(testtime, delta, defaultPrecision);
            done();
        }, testtime);
    });

    describe('toString()', function () {
        it('idle', function () {
            var stopwatch = new Stopwatch('sw');
            //[sw => state:init; value:NaN]
            stopwatch.toString().should.containEql('state:init');
            stopwatch.toString().should.containEql('value:');
        });
        it('started', function () {
            var stopwatch = new Stopwatch('sw', true);
            //[sw => state:running; value:0.01]
            stopwatch.toString().should.containEql('state:running');
            stopwatch.toString().should.containEql('value:0');
        });
        it('stopped', function () {
            var stopwatch = new Stopwatch('sw', true);
            stopwatch.stop();
            //[sw => state:stopped; value:0.01]
            stopwatch.toString().should.containEql('state:stopped');
            stopwatch.toString().should.containEql('value:0');
        });
    });

    // https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/time/StopWatch.html
    describe('java stopwatch compliance', function () {
        it('time should equal read on a running stopwatch', function () {
            //TODO: list time as alias of read
            var stopwatch = new Stopwatch('sw');
            stopwatch.start();

            var readTime = stopwatch.read();
            var time = stopwatch.time();

            verifyDelta(readTime, time, 10);
        });
        it('time should equal read on a stopped stopwatch', function (done) {
            //TODO: list time as alias of read
            var stopwatch = new Stopwatch('sw');
            stopwatch.start();
            setTimeout(function () {
                stopwatch.stop();
                stopwatch.read().should.be.equal(stopwatch.time());
                done();
            }, 10);

        });
        describe('reset', function () {
            it('reseting a not-started stopwatch should have no effect', function () {
                var stopwatch = new Stopwatch('sw');
                stopwatch.reset();
                stopwatch.state().should.be.equal("init");
            });
            it('reseting a started stopwatch should bring it back to init', function () {
                var stopwatch = new Stopwatch('sw');
                stopwatch.start();
                stopwatch.reset();
                should.not.exist(stopwatch.startTime);
                should.not.exist(stopwatch.stopTime);
                stopwatch.state().should.be.equal("init");
            });
            it('reseting a stopped stopwatch should bring it back to init', function () {
                var stopwatch = new Stopwatch('sw');
                stopwatch.start();
                stopwatch.stop();
                stopwatch.reset();
                should.not.exist(stopwatch.startTime);
                should.not.exist(stopwatch.stopTime);
                stopwatch.state().should.be.equal("init");
            });
        });
        describe('split', function () {
            it('start, split, then getSplit will return the split time', function () {
                var stopwatch = new Stopwatch('sw');
                stopwatch.start();

                setTimeout(function () {
                    stopwatch.split();
                    setTimeout(function () {
                        verifyDelta(100, stopwatch.time, 10);
                        verifyDelta(200, stopwatch.splitTime, 10);
                        done();
                    }, 200);
                }, 100);
                stopwatch.stop();
                stopwatch.reset();
                should.not.exist(stopwatch.startTime);
                should.not.exist(stopwatch.stopTime);
                stopwatch.state().should.be.equal("init");
            });
            it('split/unsplit/getSplitTime', function () {
                // Split the time.  This method sets the stop time of the watch to allow a time to be extracted. The start time is unaffected, enabling unsplit() to continue the timing from the original start point.
                // Remove a split.  This method clears the stop time. The start time is unaffected, enabling timing from the original start point to continue.
                // IllegalStateException - if the StopWatch is not running. (on split)
                // IllegalStateException - if the StopWatch has not yet been split. (on unsplit)
            });
            it('split/unsplit/getSplitTime', function () {
                // Split the time.  This method sets the stop time of the watch to allow a time to be extracted. The start time is unaffected, enabling unsplit() to continue the timing from the original start point.
                // Remove a split.  This method clears the stop time. The start time is unaffected, enabling timing from the original start point to continue.
                // IllegalStateException - if the StopWatch is not running. (on split)
                // IllegalStateException - if the StopWatch has not yet been split. (on unsplit)
            });
        });
        it.skip('suspend/resume', function () {
            // This method suspends the watch until it is resumed. The watch will not include time between the suspend and resume calls in the total time.
            // IllegalStateException - if the StopWatch is not currently running.
            // IllegalStateException - if the StopWatch has not been suspended.
        });
        it.skip('start while already running', function () {
            // IllegalStateException - if the StopWatch is already running.
        });
        it.skip('stop while not running', function () {
            // IllegalStateException - if the StopWatch is not running.
        });
    });
});

//TODO:
//replace with: statman.TestHelper.assertCloseEnough(testtime, delta, defaultPrecision);
function verifyDelta(expected, actual, acceptedVariance) {
    var lowerThreshold = expected - acceptedVariance;
    var upperThreshold = expected + acceptedVariance;
    var message = "Expected " + expected + " ± " + acceptedVariance + ", was " + actual + ".";
    assert.ok((actual >= lowerThreshold) && (actual <= upperThreshold), message);
}<commit_msg>remove unneeded test code<commit_after>/*jslint node: true */
"use strict";

var Stopwatch = require('../lib/Stopwatch');
var defaultPrecision = 15;
var assert = require('assert');
var should = require('should');

describe('stopwatch', function () {
    this.timeout(5000);

    describe('constructor', function () {
        it('w/no params', function () {
            var stopwatch = new Stopwatch();
            should.exist(stopwatch);
        });

        it('w/name as first param', function () {
            var stopwatch = new Stopwatch('metric-name');
            stopwatch.name().should.equal('metric-name');
        });

        it('w/autostart as first param', function () {
            var stopwatch = new Stopwatch(true);
            should.exist(stopwatch.name());
            stopwatch.name().should.not.equal(true);
        });

        it('w/both name and autostart', function () {
            var stopwatch = new Stopwatch('metric-name', true);
            stopwatch.name().should.equal('metric-name');
        });

        it('autocreated names are not constant', function () {
            var stopwatch1 = new Stopwatch(true);
            var stopwatch2 = new Stopwatch(true);
            stopwatch1.name().should.not.equal(stopwatch2.name());
        });
    });

    it('start and read (100ms)', function (done) {
        var testtime = 100;

        var stopwatch = new Stopwatch();
        stopwatch.start();
        setTimeout(function () {
            var delta = stopwatch.read();
            verifyDelta(testtime, delta, defaultPrecision);
            done();
        }, testtime);
    });

    it('start and read (10ms)', function (done) {
        var testtime = 10;

        var stopwatch = new Stopwatch();
        stopwatch.start();
        setTimeout(function () {
            var delta = stopwatch.read();
            verifyDelta(testtime, delta, defaultPrecision);
            done();
        }, testtime);
    });

    it('autostart set to true automatically starts stopwatch', function (done) {
        var testtime = 10;

        var stopwatch = new Stopwatch(true);
        setTimeout(function () {
            var delta = stopwatch.read();
            verifyDelta(testtime, delta, defaultPrecision);
            done();
        }, testtime);
    });

    it('autostart set to false does NOT automatically start stopwatch', function (done) {
        var testtime = 10;

        var stopwatch = new Stopwatch(false);
        setTimeout(function () {
            stopwatch.read().should.be.NaN();
            done();
        }, testtime);
    });

    it('with two stopwatches, do independent reads of each', function (done) {
        var stopwatch1 = new Stopwatch();
        var stopwatch2 = new Stopwatch();

        stopwatch1.start();

        //start first stopwatch, then do a read .3s later
        var testtimeA = 300;
        setTimeout(function () {
            var delta1 = stopwatch1.read();
            verifyDelta(testtimeA, delta1, defaultPrecision);
        }, testtimeA);

        //start second stopwatch .1s second after the first, then do a read .5s later
        var testtimeB = 500;
        setTimeout(function () {
            stopwatch2.start();
            setTimeout(function () {
                var delta2 = stopwatch2.read();
                verifyDelta(testtimeB, delta2, defaultPrecision);
                done();
            }, testtimeB);
        }, 100);
    });

    it('start, stop, and read should return the time at stop', function (done) {
        var testtime = 100;

        var stopwatch = new Stopwatch();
        stopwatch.start();
        setTimeout(function () {
            stopwatch.stop();

            setTimeout(function () {
                var delta = stopwatch.read();
                verifyDelta(testtime, delta, defaultPrecision);
                done();
            }, 500);
        }, testtime);
    });

    it('performing read without start() or stop() returns NaN', function (done) {
        var stopwatch = new Stopwatch();
        assert.ok(isNaN(stopwatch.read()));
        done();
    });

    it('performing read without start() returns NaN', function (done) {
        var stopwatch = new Stopwatch();
        stopwatch.stop();
        assert.ok(isNaN(stopwatch.read()));
        done();
    });

    it('executing stop twice should return time at second stop', function (done) {
        //start(), wait .1s, stop(), wait .2s, stop(), wait .5s, read(), ensure delta = .3s
        var stopwatch = new Stopwatch();
        stopwatch.start();
        setTimeout(function () {
            stopwatch.stop();

            setTimeout(function () {
                verifyDelta(100 + 200, stopwatch.stop(), defaultPrecision);

                setTimeout(function () {
                    var delta = stopwatch.read();
                    verifyDelta(100 + 200, delta, defaultPrecision);
                    done();
                }, 500);
            }, 200);
        }, 100);
    });

    it('ensure that stop() returns time', function (done) {
        var testtime = 100;
        var stopwatch = new Stopwatch();
        stopwatch.start();
        setTimeout(function () {
            var delta = stopwatch.stop();
            verifyDelta(testtime, delta, defaultPrecision);
            done();
        }, testtime);
    });

    describe('toString()', function () {
        it('idle', function () {
            var stopwatch = new Stopwatch('sw');
            //[sw => state:init; value:NaN]
            stopwatch.toString().should.containEql('state:init');
            stopwatch.toString().should.containEql('value:');
        });
        it('started', function () {
            var stopwatch = new Stopwatch('sw', true);
            //[sw => state:running; value:0.01]
            stopwatch.toString().should.containEql('state:running');
            stopwatch.toString().should.containEql('value:0');
        });
        it('stopped', function () {
            var stopwatch = new Stopwatch('sw', true);
            stopwatch.stop();
            //[sw => state:stopped; value:0.01]
            stopwatch.toString().should.containEql('state:stopped');
            stopwatch.toString().should.containEql('value:0');
        });
    });

    // https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/time/StopWatch.html
    describe('java stopwatch compliance', function () {
        it('time should equal read on a running stopwatch', function () {
            //TODO: list time as alias of read
            var stopwatch = new Stopwatch('sw');
            stopwatch.start();

            var readTime = stopwatch.read();
            var time = stopwatch.time();

            verifyDelta(readTime, time, 10);
        });
        it('time should equal read on a stopped stopwatch', function (done) {
            //TODO: list time as alias of read
            var stopwatch = new Stopwatch('sw');
            stopwatch.start();
            setTimeout(function () {
                stopwatch.stop();
                stopwatch.read().should.be.equal(stopwatch.time());
                done();
            }, 10);

        });
        describe('reset', function () {
            it('reseting a not-started stopwatch should have no effect', function () {
                var stopwatch = new Stopwatch('sw');
                stopwatch.reset();
                stopwatch.state().should.be.equal("init");
            });
            it('reseting a started stopwatch should bring it back to init', function () {
                var stopwatch = new Stopwatch('sw');
                stopwatch.start();
                stopwatch.reset();
                should.not.exist(stopwatch.startTime);
                should.not.exist(stopwatch.stopTime);
                stopwatch.state().should.be.equal("init");
            });
            it('reseting a stopped stopwatch should bring it back to init', function () {
                var stopwatch = new Stopwatch('sw');
                stopwatch.start();
                stopwatch.stop();
                stopwatch.reset();
                should.not.exist(stopwatch.startTime);
                should.not.exist(stopwatch.stopTime);
                stopwatch.state().should.be.equal("init");
            });
        });
        describe('split', function () {
            it('start, split, then getSplit will return the split time', function () {
                var stopwatch = new Stopwatch('sw');
                stopwatch.start();

                setTimeout(function () {
                    stopwatch.split();
                    setTimeout(function () {
                        verifyDelta(100, stopwatch.time, 10);
                        verifyDelta(200, stopwatch.splitTime, 10);
                        done();
                    }, 200);
                }, 100);
            });
            it('split/unsplit/getSplitTime', function () {
                // Split the time.  This method sets the stop time of the watch to allow a time to be extracted. The start time is unaffected, enabling unsplit() to continue the timing from the original start point.
                // Remove a split.  This method clears the stop time. The start time is unaffected, enabling timing from the original start point to continue.
                // IllegalStateException - if the StopWatch is not running. (on split)
                // IllegalStateException - if the StopWatch has not yet been split. (on unsplit)
            });
            it('split/unsplit/getSplitTime', function () {
                // Split the time.  This method sets the stop time of the watch to allow a time to be extracted. The start time is unaffected, enabling unsplit() to continue the timing from the original start point.
                // Remove a split.  This method clears the stop time. The start time is unaffected, enabling timing from the original start point to continue.
                // IllegalStateException - if the StopWatch is not running. (on split)
                // IllegalStateException - if the StopWatch has not yet been split. (on unsplit)
            });
        });
        it.skip('suspend/resume', function () {
            // This method suspends the watch until it is resumed. The watch will not include time between the suspend and resume calls in the total time.
            // IllegalStateException - if the StopWatch is not currently running.
            // IllegalStateException - if the StopWatch has not been suspended.
        });
        it.skip('start while already running', function () {
            // IllegalStateException - if the StopWatch is already running.
        });
        it.skip('stop while not running', function () {
            // IllegalStateException - if the StopWatch is not running.
        });
    });
});

//TODO:
//replace with: statman.TestHelper.assertCloseEnough(testtime, delta, defaultPrecision);
function verifyDelta(expected, actual, acceptedVariance) {
    var lowerThreshold = expected - acceptedVariance;
    var upperThreshold = expected + acceptedVariance;
    var message = "Expected " + expected + " ± " + acceptedVariance + ", was " + actual + ".";
    assert.ok((actual >= lowerThreshold) && (actual <= upperThreshold), message);
}<|endoftext|>


<commit_before>

var pluck = function(key, arr) {
    var i, len, ret = [], cur = arr.length? arr[0] : undefined;

    for (i = 0, len = arr.length; cur = arr[i], i < len; cur = arr[i++])
        ret.push(cur[key]);

    return ret;
};

var print = function(t, level) {
    if (! t) return;

    if (typeof level === 'undefined')
        level = 1;

    var len = t.children && t.children.length? t.children.length : 0,
        indent = Array(level).join('    '),
        ret = indent + t.name + '\n';

    for (var i = 0; i < len; i++)
        ret += print(t.children[i], level + 1);

    return ret;
};

var t = require('t'),
    expect = require('chai').expect,
    data = require('test/fixtures');

describe('t', function(){
    var tree = data[0].tree,
        dict = data[0].dict,
        order = data[0].order,
        cur;

    describe('dfs', function() {
        beforeEach(function() {
            cur = 0;
        });

        it('correctly visit nodes', function() {
            t.dfs(tree, function(node, par) {
                var expected = dict[node.name];

                expect(node.name).to.be.equal(order.dfs[cur++]);

                if (par)
                    expect(par.name).to.be.equal(expected.par);
                else
                    expect(par).to.be.equal(expected.par);

                expect(pluck('name', node.children||[]))
                    .to.be.eql(expected.children);
            });
        });

        it('sets "this" properly', function() {
            t.dfs(tree, function() {
                expect(this.name).to.be.equal(order.dfs[cur++]);
            });
        });

        it('stops when ctrl.stop is set to true', function() {
            var stopNodeName = order.dfs[4];
            var includedSet = order.dfs.slice(0, 5);
            var visitedSet = [];
            t.dfs(tree, function(node, par, ctrl) {
                visitedSet.push(node.name);
                if (node.name === stopNodeName)
                    ctrl.stop = true;
            });
            expect(visitedSet).to.be.eql(includedSet);
        });

        it('doesn\'t visit children if ctrl.cutoff is set to true', function() {
            var cutoffNodeName = order.dfs[1];
            var includedSet = 'a b j k l m'.split(' ');
            var visitedSet = [];
            t.dfs(tree, function(node, par, ctrl) {
                visitedSet.push(node.name);
                if (node.name === cutoffNodeName)
                    ctrl.cutoff = true;
            });
            expect(visitedSet).to.be.eql(includedSet);
        });

        it('correctly traverses list of nodes', function() {
            var tree = data[1].tree,
                dict = data[1].dict,
                order = data[1].order;

            t.dfs(tree, function(node, par) {
                var expected = dict[node.name];

                expect(node.name).to.be.equal(order.dfs[cur++]);

                if (par)
                    expect(par.name).to.be.equal(expected.par);
                else
                    expect(par).to.be.equal(expected.par);

                expect(pluck('name', node.children||[]))
                    .to.be.eql(expected.children);
            });
        });

        it('returns immediately if first arg is undefined', function() {
            var tree = undefined, count = 0;

            t.dfs(tree, function() {
                count++;
            });

            expect(count).to.equal(0);
        });
    });

    describe('map', function() {
        var makeNode = function(node, par) {
            if (par)
                expect(par).to.include.keys('other');

            return {
                name: node.name,
                other: 'some other prop for ' + node.name,
                par: par
            };
        };

        it('correctly creates a new tree', function() {
            var tree2 = t.map(tree, makeNode);

            t.dfs(tree2, function(node, par) {
                expect(node.other)
                    .to.be.equal('some other prop for ' + node.name);
                expect(node).to.not.equal(dict[node.name]);
                if (node.par)
                    expect(node.par.name).to.be.equal(par.name);
                else
                    expect(par).to.equal(undefined);
            });
        });

        it('correctly creates a new tree from an array', function() {
            var tree = data[1].tree,
                dict = data[1].dict;

            var tree2 = t.map(tree, makeNode);
            t.dfs(tree2, function(node, par) {
                expect(node.other).to.be.equal('some other prop for ' + node.name);
                expect(node).to.not.equal(dict[node.name]);
                if (node.par)
                    expect(node.par.name).to.be.equal(par.name);
                else
                    expect(par).to.equal(undefined);
            });
        });
    });

    describe('filter', function() {
        var makeNode = function(node, par) {
            if (par)
                expect(par).to.include.keys('other');

            if (node.name !== 'i' && node.name !== 'd')
                return {
                    name: node.name,
                    other: 'some other prop for ' + node.name,
                    par: par
                };
        };

        it('correctly filters nodes that return false', function() {
            var tree2 = t.filter(tree, makeNode);
            var expected = 'a b c g h j k l m'.split(' ');
            var found = [];
            t.dfs(tree2, function() {
                found.push(this.name);
                if (this.par)
                    expect(this.par.name).to.be.equal(dict[this.name].par);
                else
                    expect(dict[this.name].par).to.equal(undefined);
            });
            expect(found).to.be.eql(expected);
        });

        it('correctly handles immediate false return', function() {
            var tree2 = t.filter(tree, function() { return false; });

            if (Object.prototype.toString.call(tree2) == '[object Array]')
                expect(tree2).to.eql([]);
            if (Object.prototype.toString.call(tree2) == '[object Object]')
                expect(tree2).to.eql({});
            else
                expect(tree2).to.equal(undefined);
        });

        it('correctly removes children arrays', function() {
            var tree2 = t.filter(tree, makeNode), correct = false;
            t.dfs(tree2, function() {
                if (this.name === 'h')
                    expect(this.children).to.equal(undefined);
            });
        });
    });

    describe('stroll', function() {
        // returns true if tree1 is a non-strict subset of tree2
        var isSubset = function(tree1, tree2) {
            var subset = true;

            t.stroll(tree1, tree2, function(node1, node2) {
                if (node1.name !== node2.name)
                    subset = false;

                var node2Children = node2.children?
                    pluck('name', node2.children) : [];

                if (node1.children)
                    node1.children.forEach(function(n, i) {
                        if (node2Children.indexOf(n.name) < 0)
                            subset = false;
                    });
            });

            return subset;
        };

        it('correctly walks through two trees', function() {
            var copy = t.map(tree, function(n) {
                return {name: n.name, other: 'this is node '+n.name};
            });

            t.stroll(tree, copy, function(first, second) {
                expect(first).to.not.equal(second);
                expect(first.name).to.equal(second.name);
                expect(second.other).to.equal('this is node '+second.name);
            });

            t.stroll(copy, tree, function(first, second) {
                expect(first).to.not.equal(second);
                expect(first.name).to.equal(second.name);
                expect(first.other).to.equal('this is node '+first.name);
            });
        });

        it('correctly walks through a subset tree', function() {
            expect(isSubset(data[2].tree, data[0].tree)).to.be.true;
        });

        it('correctly walks through a superset tree', function() {
            expect(isSubset(data[0].tree, data[2].tree)).to.be.false;
        });
    });

    describe('find', function() {
        it('finds a node that exists', function() {
            var res = t.find(tree, function() { return this.name === 'a'; });
            expect(res.name).to.equal('a');
        });

        it('returns undefined when no match found', function() {
            var res = t.find(tree, function() { return this.name === 'foo'; });
            expect(typeof res).to.equal('undefined');
        });

        it('stops traversing as soon as a match is found', function() {
            var visited = [],
                expected = 'a b c d e'.split(' '),
                res = t.find(tree, function() {
                    visited.push(this.name);
                    return this.name === 'e';
                });
            expect(res.name).to.equal('e');
            expect(visited).to.eql(expected);
        });

    });

    describe('post order dfs', function() {
        it('correctly captures return values', function() {
            var actualOrder = [], ret;
            ret = t.dfs(tree, {order: 'post'}, function(node, par, ctrl, ret) {
                var childNames = (node.children || []).map(function(child) {
                    return child.name;
                });
                expect(ret).to.eql(childNames);
                actualOrder.push(this.name);
                return node.name;
            });
            expect(ret).to.equal('a');
            expect(actualOrder).to.eql(order.dfsPost);
        });

        it('correctly captures return values of list', function() {
            var ret,
                tree = data[1].tree,
                dict = data[1].dict,
                order = data[1].order,
                actualOrder = [];
            expect(tree).to.be.an.instanceof(Array);
            ret = t.dfs(tree, {order: 'post'}, function(node, par, ctrl, ret) {
                var childNames = pluck('name', node.children || []);
                expect(ret).to.eql(childNames);
                actualOrder.push(this.name);
                return node.name;
            });
            expect(ret).to.eql(['a', 'd']);
        });

        it('correctly captures return values 2', function() {
            var ret,
                tree = data[2].tree,
                dict = data[2].dict,
                order = data[2].order,
                actualOrder = [];
            ret = t.dfs(tree, {order: 'post'}, function(node, par, ctrl, ret) {
                var childNames = pluck('name', node.children || []);
                expect(ret).to.eql(childNames);
                actualOrder.push(this.name);
                return node.name;
            });
            expect(ret).to.eql('a');
        });

        it('can build up a clone of the tree', function() {
            var ret;
            ret = t.dfs(tree, {order: 'post'}, function(node, par, ctrl, ret) {
                var newNode = {};
                if (ret.length) {
                    newNode.children = ret;
                }
                newNode.name = this.name;
                return newNode;
            });
            expect(ret).to.eql(tree);
        });

        it('can build up a clone of the tree 2', function() {
            var ret,
                tree = data[1].tree,
                dict = data[1].dict,
                order = data[1].order;
            expect(tree).to.be.an.instanceof(Array);
            ret = t.dfs(tree, {order: 'post'}, function(node, par, ctrl, ret) {
                var newNode = {};
                if (ret.length) {
                    newNode.children = ret;
                }
                newNode.name = this.name;
                return newNode;
            });
            expect(ret).to.eql(tree);
        });

        it('can build up a clone of the tree 3', function() {
            var ret,
                tree = data[2].tree,
                dict = data[2].dict,
                order = data[2].order;
            ret = t.dfs(tree, {order: 'post'}, function(node, par, ctrl, ret) {
                var newNode = {};
                if (ret.length) {
                    newNode.children = ret;
                }
                newNode.name = this.name;
                return newNode;
            });
            expect(ret).to.eql(tree);
        });
    });
});

<commit_msg>updated tests for changes in chai<commit_after>/*global expect:true, describe, it, beforeEach*/

var pluck = function(key, arr) {
    var i, len, ret = [], cur = arr.length? arr[0] : undefined;

    for (i = 0, len = arr.length; cur = arr[i], i < len; cur = arr[i++])
        ret.push(cur[key]);

    return ret;
};

var printTree = function(t, level) {
    if (! t) return;

    if (typeof level === 'undefined')
        level = 1;

    var len = t.children && t.children.length? t.children.length : 0,
        indent = Array(level).join('    '),
        ret = indent + t.name + '\n';

    for (var i = 0; i < len; i++)
        ret += printTree(t.children[i], level + 1);

    return ret;
};

var t = require('t'),
    expect = require('chai').expect,
    data = require('test/fixtures');

describe('t', function(){
    var tree = data[0].tree,
        dict = data[0].dict,
        order = data[0].order,
        cur;

    describe('dfs', function() {
        beforeEach(function() {
            cur = 0;
        });

        it('correctly visit nodes', function() {
            t.dfs(tree, function(node, par) {
                var expected = dict[node.name];

                expect(node.name).to.be.equal(order.dfs[cur++]);

                if (par)
                    expect(par.name).to.be.equal(expected.par);
                else
                    expect(par).to.be.equal(expected.par);

                expect(pluck('name', node.children||[]))
                    .to.be.eql(expected.children);
            });
        });

        it('sets "this" properly', function() {
            t.dfs(tree, function() {
                expect(this.name).to.be.equal(order.dfs[cur++]);
            });
        });

        it('stops when ctrl.stop is set to true', function() {
            var stopNodeName = order.dfs[4];
            var includedSet = order.dfs.slice(0, 5);
            var visitedSet = [];
            t.dfs(tree, function(node, par, ctrl) {
                visitedSet.push(node.name);
                if (node.name === stopNodeName)
                    ctrl.stop = true;
            });
            expect(visitedSet).to.be.eql(includedSet);
        });

        it('doesn\'t visit children if ctrl.cutoff is set to true', function() {
            var cutoffNodeName = order.dfs[1];
            var includedSet = 'a b j k l m'.split(' ');
            var visitedSet = [];
            t.dfs(tree, function(node, par, ctrl) {
                visitedSet.push(node.name);
                if (node.name === cutoffNodeName)
                    ctrl.cutoff = true;
            });
            expect(visitedSet).to.be.eql(includedSet);
        });

        it('correctly traverses list of nodes', function() {
            var tree = data[1].tree,
                dict = data[1].dict,
                order = data[1].order;

            t.dfs(tree, function(node, par) {
                var expected = dict[node.name];

                expect(node.name).to.be.equal(order.dfs[cur++]);

                if (par)
                    expect(par.name).to.be.equal(expected.par);
                else
                    expect(par).to.be.equal(expected.par);

                expect(pluck('name', node.children||[]))
                    .to.be.eql(expected.children);
            });
        });

        it('returns immediately if first arg is undefined', function() {
            var tree = undefined, count = 0;

            t.dfs(tree, function() {
                count++;
            });

            expect(count).to.equal(0);
        });
    });

    describe('map', function() {
        var makeNode = function(node, par) {
            if (par)
                expect(par).to.contain.keys('other');

            return {
                name: node.name,
                other: 'some other prop for ' + node.name,
                par: par
            };
        };

        it('correctly creates a new tree', function() {
            var tree2 = t.map(tree, makeNode);

            t.dfs(tree2, function(node, par) {
                expect(node.other)
                    .to.be.equal('some other prop for ' + node.name);
                expect(node).to.not.equal(dict[node.name]);
                if (node.par)
                    expect(node.par.name).to.be.equal(par.name);
                else
                    expect(par).to.equal(undefined);
            });
        });

        it('correctly creates a new tree from an array', function() {
            var tree = data[1].tree,
                dict = data[1].dict;

            var tree2 = t.map(tree, makeNode);
            t.dfs(tree2, function(node, par) {
                expect(node.other).to.be.equal('some other prop for ' + node.name);
                expect(node).to.not.equal(dict[node.name]);
                if (node.par)
                    expect(node.par.name).to.be.equal(par.name);
                else
                    expect(par).to.equal(undefined);
            });
        });
    });

    describe('filter', function() {
        var makeNode = function(node, par) {
            if (par)
                expect(par).to.contain.keys('other');

            if (node.name !== 'i' && node.name !== 'd')
                return {
                    name: node.name,
                    other: 'some other prop for ' + node.name,
                    par: par
                };
        };

        it('correctly filters nodes that return false', function() {
            var tree2 = t.filter(tree, makeNode);
            var expected = 'a b c g h j k l m'.split(' ');
            var found = [];
            t.dfs(tree2, function() {
                found.push(this.name);
                if (this.par)
                    expect(this.par.name).to.be.equal(dict[this.name].par);
                else
                    expect(dict[this.name].par).to.equal(undefined);
            });
            expect(found).to.be.eql(expected);
        });

        it('correctly handles immediate false return', function() {
            var tree2 = t.filter(tree, function() { return false; });

            if (Object.prototype.toString.call(tree2) === '[object Array]')
                expect(tree2).to.eql([]);
            if (Object.prototype.toString.call(tree2) === '[object Object]')
                expect(tree2).to.eql({});
            else
                expect(tree2).to.equal(undefined);
        });

        it('correctly removes children arrays', function() {
            var tree2 = t.filter(tree, makeNode), correct = false;
            t.dfs(tree2, function() {
                if (this.name === 'h')
                    expect(this.children).to.equal(undefined);
            });
        });
    });

    describe('stroll', function() {
        // returns true if tree1 is a non-strict subset of tree2
        var isSubset = function(tree1, tree2) {
            var subset = true;

            t.stroll(tree1, tree2, function(node1, node2) {
                if (node1.name !== node2.name)
                    subset = false;

                var node2Children = node2.children?
                    pluck('name', node2.children) : [];

                if (node1.children)
                    node1.children.forEach(function(n, i) {
                        if (node2Children.indexOf(n.name) < 0)
                            subset = false;
                    });
            });

            return subset;
        };

        it('correctly walks through two trees', function() {
            var copy = t.map(tree, function(n) {
                return {name: n.name, other: 'this is node '+n.name};
            });

            t.stroll(tree, copy, function(first, second) {
                expect(first).to.not.equal(second);
                expect(first.name).to.equal(second.name);
                expect(second.other).to.equal('this is node '+second.name);
            });

            t.stroll(copy, tree, function(first, second) {
                expect(first).to.not.equal(second);
                expect(first.name).to.equal(second.name);
                expect(first.other).to.equal('this is node '+first.name);
            });
        });

        it('correctly walks through a subset tree', function() {
            expect(isSubset(data[2].tree, data[0].tree)).to.be.true;
        });

        it('correctly walks through a superset tree', function() {
            expect(isSubset(data[0].tree, data[2].tree)).to.be.false;
        });
    });

    describe('find', function() {
        it('finds a node that exists', function() {
            var res = t.find(tree, function() { return this.name === 'a'; });
            expect(res.name).to.equal('a');
        });

        it('returns undefined when no match found', function() {
            var res = t.find(tree, function() { return this.name === 'foo'; });
            expect(typeof res).to.equal('undefined');
        });

        it('stops traversing as soon as a match is found', function() {
            var visited = [],
                expected = 'a b c d e'.split(' '),
                res = t.find(tree, function() {
                    visited.push(this.name);
                    return this.name === 'e';
                });
            expect(res.name).to.equal('e');
            expect(visited).to.eql(expected);
        });

    });

    describe('post order dfs', function() {
        it('correctly captures return values', function() {
            var actualOrder = [], ret;
            ret = t.dfs(tree, {order: 'post'}, function(node, par, ctrl, ret) {
                var childNames = (node.children || []).map(function(child) {
                    return child.name;
                });
                expect(ret).to.eql(childNames);
                actualOrder.push(this.name);
                return node.name;
            });
            expect(ret).to.equal('a');
            expect(actualOrder).to.eql(order.dfsPost);
        });

        it('correctly captures return values of list', function() {
            var ret,
                tree = data[1].tree,
                dict = data[1].dict,
                order = data[1].order,
                actualOrder = [];
            expect(tree).to.be.an.instanceof(Array);
            ret = t.dfs(tree, {order: 'post'}, function(node, par, ctrl, ret) {
                var childNames = pluck('name', node.children || []);
                expect(ret).to.eql(childNames);
                actualOrder.push(this.name);
                return node.name;
            });
            expect(ret).to.eql(['a', 'd']);
        });

        it('correctly captures return values 2', function() {
            var ret,
                tree = data[2].tree,
                dict = data[2].dict,
                order = data[2].order,
                actualOrder = [];
            ret = t.dfs(tree, {order: 'post'}, function(node, par, ctrl, ret) {
                var childNames = pluck('name', node.children || []);
                expect(ret).to.eql(childNames);
                actualOrder.push(this.name);
                return node.name;
            });
            expect(ret).to.eql('a');
        });

        it('can build up a clone of the tree', function() {
            var ret;
            ret = t.dfs(tree, {order: 'post'}, function(node, par, ctrl, ret) {
                var newNode = {};
                if (ret.length) {
                    newNode.children = ret;
                }
                newNode.name = this.name;
                return newNode;
            });
            expect(ret).to.eql(tree);
        });

        it('can build up a clone of the tree 2', function() {
            var ret,
                tree = data[1].tree,
                dict = data[1].dict,
                order = data[1].order;
            expect(tree).to.be.an.instanceof(Array);
            ret = t.dfs(tree, {order: 'post'}, function(node, par, ctrl, ret) {
                var newNode = {};
                if (ret.length) {
                    newNode.children = ret;
                }
                newNode.name = this.name;
                return newNode;
            });
            expect(ret).to.eql(tree);
        });

        it('can build up a clone of the tree 3', function() {
            var ret,
                tree = data[2].tree,
                dict = data[2].dict,
                order = data[2].order;
            ret = t.dfs(tree, {order: 'post'}, function(node, par, ctrl, ret) {
                var newNode = {};
                if (ret.length) {
                    newNode.children = ret;
                }
                newNode.name = this.name;
                return newNode;
            });
            expect(ret).to.eql(tree);
        });
    });
});

<|endoftext|>


<commit_before>var test = require('tape');
var Observable = require('./observer.js');
test('ObservableAddObserverTest', function(assert) {
	var observable = new Observable();
	var observer = function() {};

	observable.addObserver(observer);

	assert.equal(observer, observable.observers[0]);
	assert.end();
});

test('ObservableHasObserverTest', function(assert) {
	var observable = new Observable();
	var observer = function(){};
	observable.addObserver(observer);
	assert.ok(observable.hasObserver(observer));
	assert.end();
})

test('test should return false when no observers', function(assert) {
	var observable = new Observable();
	assert.notOk(observable.hasObserver(function(){}))
	assert.end();
})

test('test should store functions', function(assert) {
	var observable = new Observable();
	var observers = [function(){}, function(){}];

	observable.addObserver(observers[0]);
	observable.addObserver(observers[1]);

	assert.ok(observable.hasObserver(observers[0]));
	assert.ok(observable.hasObserver(observers[1]));

	assert.end();
})

test('ObservableNotifyObserversTest', function(assert) {
	//test should call all observers
	var observable = new Observable();
	var ob1 = function(){ob1.called = true};
	var ob2 = function(){ob2.called = true};

	observable.addObserver(ob1);
	observable.addObserver(ob2);
	observable.notifyObservers();

	assert.ok(ob1.called);
	assert.ok(ob2.called);

	assert.end();
})

test('testShouldPassArguments', function(assert) {
	var observable = new Observable();
	var actual;

	observable.addObserver(function() {
		actual = arguments;
	});

	observable.notifyObservers('String', 1, 32);

	assert.deepEqual(['String', 1,32], actual);

	assert.end();
})

test('should throw for uncallable observer', function(assert) {
	var observable = new Observable();

	assert.throws(function() {
		observable.addObserver({});
	}, 'TypeError');

	assert.end();
})

test('should notify all even when some fail', function(assert) {
	var observable = new Observable();
	var o1 = function() {throw new Error('oops')};
	var o2 = function() {o2.called = true};

	observable.addObserver(o1);
	observable.addObserver(o2);
	observable.notifyObservers();

	assert.ok(o2.called);

	assert.end();
})
<commit_msg>observers' call order is maintained<commit_after>var test = require('tape');
var Observable = require('./observer.js');
test('ObservableAddObserverTest', function(assert) {
	var observable = new Observable();
	var observer = function() {};

	observable.addObserver(observer);

	assert.equal(observer, observable.observers[0]);
	assert.end();
});

test('ObservableHasObserverTest', function(assert) {
	var observable = new Observable();
	var observer = function(){};
	observable.addObserver(observer);
	assert.ok(observable.hasObserver(observer));
	assert.end();
})

test('test should return false when no observers', function(assert) {
	var observable = new Observable();
	assert.notOk(observable.hasObserver(function(){}))
	assert.end();
})

test('test should store functions', function(assert) {
	var observable = new Observable();
	var observers = [function(){}, function(){}];

	observable.addObserver(observers[0]);
	observable.addObserver(observers[1]);

	assert.ok(observable.hasObserver(observers[0]));
	assert.ok(observable.hasObserver(observers[1]));

	assert.end();
})

test('ObservableNotifyObserversTest', function(assert) {
	//test should call all observers
	var observable = new Observable();
	var ob1 = function(){ob1.called = true};
	var ob2 = function(){ob2.called = true};

	observable.addObserver(ob1);
	observable.addObserver(ob2);
	observable.notifyObservers();

	assert.ok(ob1.called);
	assert.ok(ob2.called);

	assert.end();
})

test('testShouldPassArguments', function(assert) {
	var observable = new Observable();
	var actual;

	observable.addObserver(function() {
		actual = arguments;
	});

	observable.notifyObservers('String', 1, 32);

	assert.deepEqual(['String', 1,32], actual);

	assert.end();
})

test('should throw for uncallable observer', function(assert) {
	var observable = new Observable();

	assert.throws(function() {
		observable.addObserver({});
	}, 'TypeError');

	assert.end();
})

test('should notify all even when some fail', function(assert) {
	var observable = new Observable();
	var o1 = function() {throw new Error('oops')};
	var o2 = function() {o2.called = true};

	observable.addObserver(o1);
	observable.addObserver(o2);
	observable.notifyObservers();

	assert.ok(o2.called);

	assert.end();
})

test('should call observers in the order they were added', function(assert) {
	var observable = new Observable();
	var calls = [];
	var ob1 = function() {calls.push(ob1)};
	var ob2 = function() {calls.push(ob2)};

	observable.addObserver(ob1);
	observable.addObserver(ob2);

	observable.notifyObservers();

	assert.deepEqual(ob1, calls[0]);
	assert.deepEqual(ob2, calls[1]);
	assert.end();
})
<|endoftext|>


<commit_before>var assert = require('chai').assert;
var gw = require('../');

// point
function p(x, y) {
  return {
    x: x || 0,
    y: y || 0
  };
}

// coordinate
function c(column, row) {
  return {
    column: column || 0,
    row: row || 0
  };
}

function createCollector() {
  var coords = [];

  function collector(coord) {
    coords.push(coord)
  }

  collector.coords = coords;
  return collector;
}

describe('walker#walk', function() {
  var walker, collector;

  beforeEach(function() {
    var cellWidth = 20;
    var cellHeight = 10;

    walker = gw(cellWidth, cellHeight);
    collector = createCollector();
  });

  it('finds single cell when line is in one cell', function() {
    var start = p(21, 11);
    var end = p(22, 12);

    walker.walk(start, end, collector);

    assert.deepEqual(collector.coords, [c(2, 2)]);
  });
});
<commit_msg>move helpers out of the way<commit_after>var assert = require('chai').assert;
var gw = require('../');

describe('walker#walk', function() {
  var walker, collector;

  beforeEach(function() {
    var cellWidth = 20;
    var cellHeight = 10;

    walker = gw(cellWidth, cellHeight);
    collector = createCollector();
  });

  it('finds single cell when line is in one cell', function() {
    var start = p(21, 11);
    var end = p(22, 12);

    walker.walk(start, end, collector);

    assert.deepEqual(collector.coords, [c(2, 2)]);
  });
});

// point in space
function p(x, y) {
  return {
    x: x || 0,
    y: y || 0
  };
}

// coordinate in grid
function c(column, row) {
  return {
    column: column || 0,
    row: row || 0
  };
}

function createCollector() {
  var coords = [];

  function collector(coord) {
    coords.push(coord)
  }

  collector.coords = coords;
  return collector;
}
<|endoftext|>


<commit_before>'use strict';

const test = require('blue-tape');
const coroutine = require('co');

const createManageable = require('./');

test(
  'Factory throws if `destroy` and `initialize` or `dependencies` options are invalid.',
  coroutine.wrap(function* (assert) {
    assert.throws(
      createManageable,
      /`destroy` and `initialize` or `dependencies`/,
      'it throws if `destroy` and `initialize` or `dependencies` are missing.'
    );

    assert.throws(
      () => createManageable({ destroy: 'foo', initialize: 'bar' }),
      /`destroy` and `initialize` must be functions/,
      'it throws if `destroy` and `initialize` are not functions.'
    );

    assert.throws(
      () => createManageable({ dependencies: 42 }),
      /`dependencies` must respond to `map` method/,
      'it throws if `dependencies` is not `map`-able.'
    );
  })
);

test('#initialize throws if already initialized.', coroutine.wrap(function* (assert) {
  try {
    const manageable = createManageable({
      initialize: () => Promise.resolve(), destroy: () => Promise.resolve(),
    });

    yield manageable.initialize();
    yield manageable.initialize();
  } catch (err) {
    assert.ok(err);
    assert.ok(err.message.includes('already initialized'));
  }
}));

test('#initialize initializes dependencies when provided.', coroutine.wrap(function* (assert) {
  const dependencies = [
    {
      *destroy() {},
      *initialize() {},
    },
    {
      *destroy() {},
      *initialize() {},
    },
    {
      *destroy() {},
      *initialize() {},
    },
  ].map(createManageable);

  const manageable = createManageable({
    dependencies,
  });

  yield manageable.initialize();

  const dependenciesWereInitialized = dependencies.reduce(
    (result, d) => result && d.initialized, []
  );

  assert.ok(dependenciesWereInitialized, 'dependencies hould have been initialized.');
}));

test('#destroy throws if not initialized.', coroutine.wrap(function* (assert) {
  try {
    const manageable = createManageable({
      initialize: () => Promise.resolve(), destroy: () => Promise.resolve(),
    });

    yield manageable.destroy();
    yield manageable.destroy();
  } catch (err) {
    assert.ok(err);
    assert.ok(err.message.includes('not initialized'));
  }
}));

test('#destroy calls `destroy` option if present.', coroutine.wrap(function* (assert) {
  let destroyed = false;

  const destroy = () => new Promise(resolve => {
    destroyed = true;

    resolve();
  });
  const initialize = () => Promise.resolve();
  const manageable = createManageable({ destroy, initialize });

  yield manageable.initialize();
  yield manageable.destroy();

  assert.ok(destroyed, 'it calls #destroy.');
}));

test('#initialize calls `initialize` option if present.', coroutine.wrap(function* (assert) {
  let initialized = false;

  const destroy = () => Promise.resolve();
  const initialize = () => new Promise(resolve => {
    initialized = true;

    resolve();
  });
  const manageable = createManageable({ destroy, initialize });

  yield manageable.initialize();

  assert.ok(initialized, 'it calls #initialize');
}));
<commit_msg>Add deps should be destroyed when provided test.<commit_after>'use strict';

const test = require('blue-tape');
const coroutine = require('co');

const createManageable = require('./');

test(
  'Factory throws if `destroy` and `initialize` or `dependencies` options are invalid.',
  coroutine.wrap(function* (assert) {
    assert.throws(
      createManageable,
      /`destroy` and `initialize` or `dependencies`/,
      'it throws if `destroy` and `initialize` or `dependencies` are missing.'
    );

    assert.throws(
      () => createManageable({ destroy: 'foo', initialize: 'bar' }),
      /`destroy` and `initialize` must be functions/,
      'it throws if `destroy` and `initialize` are not functions.'
    );

    assert.throws(
      () => createManageable({ dependencies: 42 }),
      /`dependencies` must respond to `map` method/,
      'it throws if `dependencies` is not `map`-able.'
    );
  })
);

test('#initialize throws if already initialized.', coroutine.wrap(function* (assert) {
  try {
    const manageable = createManageable({
      initialize: () => Promise.resolve(), destroy: () => Promise.resolve(),
    });

    yield manageable.initialize();
    yield manageable.initialize();
  } catch (err) {
    assert.ok(err);
    assert.ok(err.message.includes('already initialized'));
  }
}));

test('#initialize initializes dependencies when provided.', coroutine.wrap(function* (assert) {
  const dependencies = createDependenciesMock();

  const manageable = createManageable({
    dependencies,
  });

  yield manageable.initialize();

  const dependenciesWereInitialized = dependencies.reduce(
    (result, d) => result && d.initialized, []
  );

  assert.ok(dependenciesWereInitialized, 'dependencies hould have been initialized.');
}));

test('#destroy throws if not initialized.', coroutine.wrap(function* (assert) {
  try {
    const manageable = createManageable({
      initialize: () => Promise.resolve(), destroy: () => Promise.resolve(),
    });

    yield manageable.destroy();
    yield manageable.destroy();
  } catch (err) {
    assert.ok(err);
    assert.ok(err.message.includes('not initialized'));
  }
}));

test('#destroy calls `destroy` option if present.', coroutine.wrap(function* (assert) {
  let destroyed = false;

  const destroy = () => new Promise(resolve => {
    destroyed = true;

    resolve();
  });
  const initialize = () => Promise.resolve();
  const manageable = createManageable({ destroy, initialize });

  yield manageable.initialize();
  yield manageable.destroy();

  assert.ok(destroyed, 'it calls #destroy.');
}));

test('#initialize calls `initialize` option if present.', coroutine.wrap(function* (assert) {
  let initialized = false;

  const destroy = () => Promise.resolve();
  const initialize = () => new Promise(resolve => {
    initialized = true;

    resolve();
  });
  const manageable = createManageable({ destroy, initialize });

  yield manageable.initialize();

  assert.ok(initialized, 'it calls #initialize');
}));

test('#destroy destroys dependencies when provided.', coroutine.wrap(function* (assert) {
  const dependencies = createDependenciesMock();
  const manageable = createManageable({
    dependencies,
  });

  yield manageable.initialize();
  yield manageable.destroy();

  const dependenciesWereDestroyed = dependencies.reduce((result, d) => result && d.initialize, []);

  assert.ok(dependenciesWereDestroyed, 'dependencies should have been destroyed.');
}));

function createDependenciesMock() {
  return [
    {
      *destroy() {},
      *initialize() {},
    },
    {
      *destroy() {},
      *initialize() {},
    },
    {
      *destroy() {},
      *initialize() {},
    },
  ].map(createManageable);
}
<|endoftext|>