<commit_before>var _ = require('./lib/test'),
    id = _.Parser.regexp(/^[a-zA-Z_]+/),
    alpha = _.Parser.regexp(/^[a-zA-Z]+/),
    number = _.Parser.regexp(/^[\+\-]?\d+(\.\d+)?/),
    whitespace = _.Parser.regexp(/^\s+/),
    optionalWhitespace = _.Parser.regexp(/^\s*/),
    leftBracket = _.Parser.string('('),
    rightBracket = _.Parser.string(')');

function toInt(a) {
    return ~~a;
}

function toFloat(a) {
    return a.toFixed(2);
}

exports.parser = {
   'when testing a number in brackets should return correct value': _.check(
        function(a) {
            var round = number.map(toInt).map(toFloat),
                parser = leftBracket.skip(whitespace).chain(function(a, b, c, d) {
                    return round.skip(whitespace).chain(function(a, b, c, d) {
                        return rightBracket;
                    });
                }),
                value = '(' + a + ')',
                expected = toFloat(toInt(a)).toString();

            return _.expect(parser.parse(value)).toBe(_.Success(['(', expected, ')']));
        },
        [Number]
    ),
    'when testing a number with whitespace in brackets should return correct value': _.check(
        function(a) {
            var round = number.map(toInt).map(toFloat),
                parser = leftBracket.skip(whitespace).chain(function() {
                    return round.skip(whitespace).chain(function() {
                        return rightBracket;
                    });
                }),
                value = '( ' + a + ' )',
                expected = toFloat(toInt(a)).toString();

            return _.expect(parser.parse(value)).toBe(_.Success(['(', expected, ')']));
        },
        [Number]
    ),
    'when testing a alpha character in brackets should return attempt failure': _.check(
        function(a) {
            var round = number.map(toInt).map(toFloat),
                parser = leftBracket.skip(whitespace).chain(function() {
                    return round.skip(whitespace).chain(function() {
                        return rightBracket;
                    });
                }),
                value = '(' + a + ')';

            return _.expect(parser.parse(value)).toBe(_.Failure([[a + ')', 1]]));
        },
        [_.NonEmptyAlphaChar]
    ),
    'when testing a number or alpha character or leftBracket should return correct value': _.check(
        function(a) {
            var parser = leftBracket.orElse(alpha).orElse(number);

            return _.expect(parser.parse(a)).toBe(_.Success([a]));
        },
        [_.NumericOrAlphaChar]
    ),
    'when testing a alpha character or leftBracket or rightBracket but got number should return failure': _.check(
        function(a) {
            var parser = rightBracket.orElse(leftBracket).orElse(alpha),
                value = a.toString();

            return _.expect(parser.parse(value)).toBe(_.Failure([[value, 0]]));
        },
        [Number]
    ),
    'when testing two numbers brackets in should return correct value': _.check(
        function(a, b) {
            var parser = leftBracket.chain(function() {
                    return number.skip(whitespace).chain(function() {
                          return number.chain(function() {
                              return rightBracket;
                          });
                    });
                }),
                value = '(' + a + ' ' + b + ')',
                expected = ['(', a.toString(), b.toString(), ')'];

            return _.expect(parser.parse(value)).toBe(_.Success(expected));
        },
        [Number, Number]
    ),
    'when testing a number or alpha character in brackets should return correct value': _.check(
        function(a) {
            var round = number.map(toInt).map(toFloat),
                parser = leftBracket.skip(whitespace).chain(function() {
                    return round.orElse(alpha).skip(whitespace).chain(function() {
                        return rightBracket;
                    });
                }),
                value = '(' + a + ')',
                possibleNumber = parseFloat(a, 10),
                expected = _.isNaN(possibleNumber) ? a : toFloat(toInt(possibleNumber)).toString();

            return _.expect(parser.parse(value)).toBe(_.Success(['(', expected, ')']));
        },
        [_.NumericOrAlphaChar]
    ),
    'when testing nested values in brackets or atom should return atom': _.check(
        function(a) {
            var round = number.map(toInt),
                atom = round.orElse(id),
                form = leftBracket.skip(optionalWhitespace).chain(function() {
                    return expr.many().skip(rightBracket);
                }),
                expr = form.orElse(atom).skip(optionalWhitespace),
                value = a.toString();

            return _.expect(expr.parse(value)).toBe(_.Success([toInt(value)]));
        },
        [Number]
    ),
    'when testing two numbers in brackets should return correct value': _.check(
        function(a, b) {
            var block = leftBracket.skip(optionalWhitespace).chain(function() {
                    return expr.many().chain(function() {
                        return rightBracket;
                    });
                }),
                expr = block.orElse(number).skip(optionalWhitespace),
                value = '(' + a + ' ' + b + ')',
                expected = ['(', a.toString(), b.toString(), ')'];

            return _.expect(expr.parse(value)).toBe(_.Success(expected));
        },
        [Number, Number]
    ),
    'when testing three numbers in brackets should return correct value': _.check(
        function(a, b, c) {
            var block = leftBracket.skip(optionalWhitespace).chain(function() {
                    return expr.many().chain(function() {
                        return rightBracket;
                    });
                }),
                expr = block.orElse(number).skip(optionalWhitespace),
                value = '(' + a + ' ' + b + ' ' +c + ')',
                expected = ['(', a.toString(), b.toString(), c.toString(), ')'];

            return _.expect(expr.parse(value)).toBe(_.Success(expected));
        },
        [Number, Number, Number]
    ),
    'when testing one string and two numbers in brackets should return correct value': _.check(
        function(a, b, c) {
            var block = leftBracket.skip(optionalWhitespace).chain(function() {
                    return expr.many().chain(function() {
                        return rightBracket;
                    });
                }),
                atom = number.orElse(id),
                expr = block.orElse(atom).skip(optionalWhitespace),
                value = '(' + a + ' ' + b + ' ' +c + ')',
                expected = ['(', a, b.toString(), c.toString(), ')'];

            return _.expect(expr.parse(value)).toBe(_.Success(expected));
        },
        [_.NonEmptyAlphaChar, Number, Number]
    ),
    'when testing `(add 1 2)` should return correct value': function(test) {
        var block = leftBracket.skip(optionalWhitespace).chain(function() {
                return expr.many().chain(function() {
                    return rightBracket;
                });
            }),
            atom = number.orElse(id),
            expr = block.orElse(atom).skip(optionalWhitespace),
            value = '(add 1 2)',
            expected = ['(', 'add', '1', '2', ')'];

        test.ok(_.expect(expr.parse(value)).toBe(_.Success(expected)));
        test.done();
    },
    'when testing `(add (mul 1 2) 3)` should return correct value': function(test) {
        var block = leftBracket.skip(optionalWhitespace).chain(function() {
                return expr.many().chain(function() {
                    return rightBracket;
                });
            }),
            atom = number.orElse(id),
            expr = block.orElse(atom).skip(optionalWhitespace),
            value = '(add (mul 1 2) 3)',
            expected = ['(', 'add', '(', 'mul', '1', '2', ')', '3', ')'];

        test.ok(_.expect(expr.parse(value)).toBe(_.Success(expected)));
        test.done();
    }
};
<commit_msg>Adding a more complex test around parser.<commit_after>var _ = require('./lib/test'),
    id = _.Parser.regexp(/^[a-zA-Z_]+/),
    alpha = _.Parser.regexp(/^[a-zA-Z]+/),
    number = _.Parser.regexp(/^[\+\-]?\d+(\.\d+)?/),
    whitespace = _.Parser.regexp(/^\s+/),
    optionalWhitespace = _.Parser.regexp(/^\s*/),
    leftBracket = _.Parser.string('('),
    rightBracket = _.Parser.string(')');

function toInt(a) {
    return ~~a;
}

function toFloat(a) {
    return a.toFixed(2);
}

exports.parser = {
   'when testing a number in brackets should return correct value': _.check(
        function(a) {
            var round = number.map(toInt).map(toFloat),
                parser = leftBracket.skip(whitespace).chain(function(a, b, c, d) {
                    return round.skip(whitespace).chain(function(a, b, c, d) {
                        return rightBracket;
                    });
                }),
                value = '(' + a + ')',
                expected = toFloat(toInt(a)).toString();

            return _.expect(parser.parse(value)).toBe(_.Success(['(', expected, ')']));
        },
        [Number]
    ),
    'when testing a number with whitespace in brackets should return correct value': _.check(
        function(a) {
            var round = number.map(toInt).map(toFloat),
                parser = leftBracket.skip(whitespace).chain(function() {
                    return round.skip(whitespace).chain(function() {
                        return rightBracket;
                    });
                }),
                value = '( ' + a + ' )',
                expected = toFloat(toInt(a)).toString();

            return _.expect(parser.parse(value)).toBe(_.Success(['(', expected, ')']));
        },
        [Number]
    ),
    'when testing a alpha character in brackets should return attempt failure': _.check(
        function(a) {
            var round = number.map(toInt).map(toFloat),
                parser = leftBracket.skip(whitespace).chain(function() {
                    return round.skip(whitespace).chain(function() {
                        return rightBracket;
                    });
                }),
                value = '(' + a + ')';

            return _.expect(parser.parse(value)).toBe(_.Failure([[a + ')', 1]]));
        },
        [_.NonEmptyAlphaChar]
    ),
    'when testing a number or alpha character or leftBracket should return correct value': _.check(
        function(a) {
            var parser = leftBracket.orElse(alpha).orElse(number);

            return _.expect(parser.parse(a)).toBe(_.Success([a]));
        },
        [_.NumericOrAlphaChar]
    ),
    'when testing a alpha character or leftBracket or rightBracket but got number should return failure': _.check(
        function(a) {
            var parser = rightBracket.orElse(leftBracket).orElse(alpha),
                value = a.toString();

            return _.expect(parser.parse(value)).toBe(_.Failure([[value, 0]]));
        },
        [Number]
    ),
    'when testing two numbers brackets in should return correct value': _.check(
        function(a, b) {
            var parser = leftBracket.chain(function() {
                    return number.skip(whitespace).chain(function() {
                          return number.chain(function() {
                              return rightBracket;
                          });
                    });
                }),
                value = '(' + a + ' ' + b + ')',
                expected = ['(', a.toString(), b.toString(), ')'];

            return _.expect(parser.parse(value)).toBe(_.Success(expected));
        },
        [Number, Number]
    ),
    'when testing a number or alpha character in brackets should return correct value': _.check(
        function(a) {
            var round = number.map(toInt).map(toFloat),
                parser = leftBracket.skip(whitespace).chain(function() {
                    return round.orElse(alpha).skip(whitespace).chain(function() {
                        return rightBracket;
                    });
                }),
                value = '(' + a + ')',
                possibleNumber = parseFloat(a, 10),
                expected = _.isNaN(possibleNumber) ? a : toFloat(toInt(possibleNumber)).toString();

            return _.expect(parser.parse(value)).toBe(_.Success(['(', expected, ')']));
        },
        [_.NumericOrAlphaChar]
    ),
    'when testing nested values in brackets or atom should return atom': _.check(
        function(a) {
            var round = number.map(toInt),
                atom = round.orElse(id),
                form = leftBracket.skip(optionalWhitespace).chain(function() {
                    return expr.many().skip(rightBracket);
                }),
                expr = form.orElse(atom).skip(optionalWhitespace),
                value = a.toString();

            return _.expect(expr.parse(value)).toBe(_.Success([toInt(value)]));
        },
        [Number]
    ),
    'when testing two numbers in brackets should return correct value': _.check(
        function(a, b) {
            var block = leftBracket.skip(optionalWhitespace).chain(function() {
                    return expr.many().chain(function() {
                        return rightBracket;
                    });
                }),
                expr = block.orElse(number).skip(optionalWhitespace),
                value = '(' + a + ' ' + b + ')',
                expected = ['(', a.toString(), b.toString(), ')'];

            return _.expect(expr.parse(value)).toBe(_.Success(expected));
        },
        [Number, Number]
    ),
    'when testing three numbers in brackets should return correct value': _.check(
        function(a, b, c) {
            var block = leftBracket.skip(optionalWhitespace).chain(function() {
                    return expr.many().chain(function() {
                        return rightBracket;
                    });
                }),
                expr = block.orElse(number).skip(optionalWhitespace),
                value = '(' + a + ' ' + b + ' ' +c + ')',
                expected = ['(', a.toString(), b.toString(), c.toString(), ')'];

            return _.expect(expr.parse(value)).toBe(_.Success(expected));
        },
        [Number, Number, Number]
    ),
    'when testing one string and two numbers in brackets should return correct value': _.check(
        function(a, b, c) {
            var block = leftBracket.skip(optionalWhitespace).chain(function() {
                    return expr.many().chain(function() {
                        return rightBracket;
                    });
                }),
                atom = number.orElse(id),
                expr = block.orElse(atom).skip(optionalWhitespace),
                value = '(' + a + ' ' + b + ' ' +c + ')',
                expected = ['(', a, b.toString(), c.toString(), ')'];

            return _.expect(expr.parse(value)).toBe(_.Success(expected));
        },
        [_.NonEmptyAlphaChar, Number, Number]
    ),
    'when testing `(add 1 2)` should return correct value': function(test) {
        var block = leftBracket.skip(optionalWhitespace).chain(function() {
                return expr.many().chain(function() {
                    return rightBracket;
                });
            }),
            atom = number.orElse(id),
            expr = block.orElse(atom).skip(optionalWhitespace),
            value = '(add 1 2)',
            expected = ['(', 'add', '1', '2', ')'];

        test.ok(_.expect(expr.parse(value)).toBe(_.Success(expected)));
        test.done();
    },
    'when testing `(add (mul 1 2) 3)` should return correct value': function(test) {
        var block = leftBracket.skip(optionalWhitespace).chain(function() {
                return expr.many().chain(function() {
                    return rightBracket;
                });
            }),
            atom = number.orElse(id),
            expr = block.orElse(atom).skip(optionalWhitespace),
            value = '(add (mul 1 2) 3)',
            expected = ['(', 'add', '(', 'mul', '1', '2', ')', '3', ')'];

        test.ok(_.expect(expr.parse(value)).toBe(_.Success(expected)));
        test.done();
    },
    'when testing `(add (mul 10 (add 3 4)) (add 7 8))` should return correct value': function(test) {
        var block = leftBracket.skip(optionalWhitespace).chain(function() {
                return expr.many().chain(function() {
                    return rightBracket;
                });
            }),
            atom = number.orElse(id),
            expr = block.orElse(atom).skip(optionalWhitespace),
            value = '(add (mul 10 (add 3 4)) (add 7 8))',
            expected = ['(', 'add', '(', 'mul', '10', '(', 'add', '3', '4', ')', ')', '(', 'add', '7', '8', ')', ')'];

        test.ok(_.expect(expr.parse(value)).toBe(_.Success(expected)));
        test.done();
    }
};
<|endoftext|>


<commit_before>var chai = require('chai');
var expect = chai.expect;
var sinon = require('sinon');
var u = require('./util');
var Readable = require('stream').Readable;
var Writable = require('stream').Writable;

chai.use(require('sinon-chai'));

describe('Phrase', function () {
  var parser;
  beforeEach(function() {
    parser = new u.lacona.Parser();
  });

  it('handles phrases with extension', function (done) {
    var extended = u.lacona.createPhrase({
      name: 'test/extended',
      describe: function () {
        return u.lacona.literal({text: 'test a'});
      }
    });

    var extender = u.lacona.createPhrase({
      name: 'test/extender',
      extends: ['test/extended'],
      describe: function () {
        return u.lacona.literal({text: 'test b'});
      }
    });

    var test = u.lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        return extended();
      }
    });

    function callback(data) {
      expect(data).to.have.length(4);
      expect(u.ft.suggestion(data[1].data)).to.equal('test b');
      expect(u.ft.suggestion(data[2].data)).to.equal('test a');
      done();
    }

    parser.sentences = [test()];
    parser.extensions = [extender];

    u.toStream(['t'])
    .pipe(parser)
    .pipe(u.toArray(callback));
  });

  it('handles phrases with overriding', function (done) {
    var overridden = u.lacona.createPhrase({
      name: 'test/overridden',
      describe: function () {
        return u.lacona.literal({text: 'test a'});
      }
    });

    var overrider = u.lacona.createPhrase({
      name: 'test/overrider',
      overrides: ['test/overridden'],
      describe: function () {
        return u.lacona.literal({text: 'test b'});
      }
    });

    var test = u.lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        return overridden();
      }
    });

    function callback(data) {
      expect(data).to.have.length(3);
      expect(u.ft.suggestion(data[1].data)).to.equal('test b');
      done();
    }

    parser.sentences = [test()];
    parser.extensions = [overrider];

    u.toStream(['t'])
    .pipe(parser)
    .pipe(u.toArray(callback));
  });

  it('allows for recursive phrases without creating an infinite loop', function (done) {
    var test = u.lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        return u.lacona.sequence({children: [
          u.lacona.literal({text: 'na '}),
          u.lacona.choice({children: [
            u.lacona.literal({text: 'nopeman'}),
            test()
          ]})
        ]});
      }
    });

    function callback(data) {
      expect(data).to.have.length(4);
      expect(u.ft.match(data[1].data)).to.equal('na ');
      expect(u.ft.suggestion(data[1].data)).to.equal('nopeman');
      expect(u.ft.match(data[2].data)).to.equal('na ');
      expect(u.ft.suggestion(data[2].data)).to.equal('na ');
      done();
    }

    parser.sentences = [test()];
    u.toStream(['na n'])
      .pipe(parser)
      .pipe(u.toArray(callback));
  });

  it('allows for nested phrases with the same id', function (done) {
    var test = u.lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        return include1({id: 'test'});
      }
    });
    var include1 = u.lacona.createPhrase({
      name: 'test/include1',
      describe: function () {
        return include2({id: 'test'});
      }
    });
    var include2 = u.lacona.createPhrase({
      name: 'test/include2',
      describe: function () {
        return u.lacona.literal({value: 'val', text: 'disp', id: 'test'});
      }
    });

    function callback(data) {
      expect(data).to.have.length(3);
      expect(u.ft.suggestion(data[1].data)).to.equal('disp');
      expect(data[1].data.result.test.test.test).to.equal('val');
      done();
    }

    parser.sentences = [test()];
    u.toStream(['d'])
      .pipe(parser)
      .pipe(u.toArray(callback));
  });

  it('caches calls to describe', function (done) {
    var callbackSpy = sinon.spy();
    var describeSpy = sinon.spy();

    var test = u.lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        describeSpy();
        return u.lacona.literal({text: 'test'});
      }
    });

    var start = new Readable({objectMode: true});
    var end = new Writable({objectMode: true});
    start._read = function noop() {};
    end.write = function (obj) {
      if (obj.event === 'data') {
        callbackSpy();
        if (callbackSpy.calledOnce) {
          start.push('t');
          start.push();
        } else {
          expect(describeSpy).to.have.been.calledOnce;
          done();
        }
      }
    };

    parser.sentences = [test()];

    start.pipe(parser).pipe(end);
    start.push('t');
  });

  it('can clear the describe cache', function (done) {
    var callbackSpy = sinon.spy();
    var describeSpy = sinon.spy();

    var test = u.lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        describeSpy();
        return u.lacona.literal({text: 'test'});
      }
    });

    var start = new Readable({objectMode: true});
    var end = new Writable({objectMode: true});
    start._read = function noop() {};
    end.write = function (obj) {
      if (obj.event === 'data') {
        callbackSpy();
        if (callbackSpy.calledOnce) {
          parser.sentences[0]._clearDescribeCache();
          start.push('t');
          start.push();
        } else {
          expect(describeSpy).to.have.been.calledTwice;
          done();
        }
      }
    };

    parser.sentences = [test()];

    start.pipe(parser).pipe(end);
    start.push('t');
  });

  it('throws for phrases without a default-lang schema', function () {
    expect(function() {
      u.lacona.createPhrase({
        name: 'test/test',
        translations: [{
          langs: ['en-US'],
          describe: function () {
            return u.lacona.literal({text: 'whatever'});
          }
        }]
      });
    }).to.throw(u.lacona.Error);
  });

  it('throws for translations without a lang', function () {
    expect(function() {
      u.lacona.createPhrase({
        name: 'test/test',
        translations: [{
          describe: function () {
            return u.lacona.literal({text: 'whatever'});
          }
        }]
      });
    }).to.throw(u.lacona.Error);
  });

  it('throws for phrases without a root', function () {
    expect(function() {
      u.lacona.createPhrase({
        name: 'test/test'
      });
    }).to.throw(u.lacona.Error);
  });

  it('throws for phrases without a name', function () {
    expect(function() {
      u.lacona.createPhrase({
        describe: function() {
          return u.lacona.literal({text: 'test'});
        }
      });
    }).to.throw(u.lacona.Error);
  });

});
<commit_msg>Fixed bug effecting Node 0.11.x<commit_after>var chai = require('chai');
var expect = chai.expect;
var sinon = require('sinon');
var u = require('./util');
var Readable = require('stream').Readable;
var Writable = require('stream').Writable;

chai.use(require('sinon-chai'));

describe('Phrase', function () {
  var parser;
  beforeEach(function() {
    parser = new u.lacona.Parser();
  });

  it('handles phrases with extension', function (done) {
    var extended = u.lacona.createPhrase({
      name: 'test/extended',
      describe: function () {
        return u.lacona.literal({text: 'test a'});
      }
    });

    var extender = u.lacona.createPhrase({
      name: 'test/extender',
      extends: ['test/extended'],
      describe: function () {
        return u.lacona.literal({text: 'test b'});
      }
    });

    var test = u.lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        return extended();
      }
    });

    function callback(data) {
      expect(data).to.have.length(4);
      expect(u.ft.suggestion(data[1].data)).to.equal('test b');
      expect(u.ft.suggestion(data[2].data)).to.equal('test a');
      done();
    }

    parser.sentences = [test()];
    parser.extensions = [extender];

    u.toStream(['t'])
    .pipe(parser)
    .pipe(u.toArray(callback));
  });

  it('handles phrases with overriding', function (done) {
    var overridden = u.lacona.createPhrase({
      name: 'test/overridden',
      describe: function () {
        return u.lacona.literal({text: 'test a'});
      }
    });

    var overrider = u.lacona.createPhrase({
      name: 'test/overrider',
      overrides: ['test/overridden'],
      describe: function () {
        return u.lacona.literal({text: 'test b'});
      }
    });

    var test = u.lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        return overridden();
      }
    });

    function callback(data) {
      expect(data).to.have.length(3);
      expect(u.ft.suggestion(data[1].data)).to.equal('test b');
      done();
    }

    parser.sentences = [test()];
    parser.extensions = [overrider];

    u.toStream(['t'])
    .pipe(parser)
    .pipe(u.toArray(callback));
  });

  it('allows for recursive phrases without creating an infinite loop', function (done) {
    var test = u.lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        return u.lacona.sequence({children: [
          u.lacona.literal({text: 'na '}),
          u.lacona.choice({children: [
            u.lacona.literal({text: 'nopeman'}),
            test()
          ]})
        ]});
      }
    });

    function callback(data) {
      expect(data).to.have.length(4);
      expect(u.ft.match(data[1].data)).to.equal('na ');
      expect(u.ft.suggestion(data[1].data)).to.equal('nopeman');
      expect(u.ft.match(data[2].data)).to.equal('na ');
      expect(u.ft.suggestion(data[2].data)).to.equal('na ');
      done();
    }

    parser.sentences = [test()];
    u.toStream(['na n'])
      .pipe(parser)
      .pipe(u.toArray(callback));
  });

  it('allows for nested phrases with the same id', function (done) {
    var test = u.lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        return include1({id: 'test'});
      }
    });
    var include1 = u.lacona.createPhrase({
      name: 'test/include1',
      describe: function () {
        return include2({id: 'test'});
      }
    });
    var include2 = u.lacona.createPhrase({
      name: 'test/include2',
      describe: function () {
        return u.lacona.literal({value: 'val', text: 'disp', id: 'test'});
      }
    });

    function callback(data) {
      expect(data).to.have.length(3);
      expect(u.ft.suggestion(data[1].data)).to.equal('disp');
      expect(data[1].data.result.test.test.test).to.equal('val');
      done();
    }

    parser.sentences = [test()];
    u.toStream(['d'])
      .pipe(parser)
      .pipe(u.toArray(callback));
  });

  it('caches calls to describe', function (done) {
    var callbackSpy = sinon.spy();
    var describeSpy = sinon.spy();

    var test = u.lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        describeSpy();
        return u.lacona.literal({text: 'test'});
      }
    });

    var start = new Readable({objectMode: true});
    var end = new Writable({objectMode: true});
    start._read = function noop() {};
    end.write = function (obj) {
      if (obj.event === 'data') {
        callbackSpy();
        if (callbackSpy.calledOnce) {
          start.push('t');
          start.push(null);
        } else {
          expect(describeSpy).to.have.been.calledOnce;
          done();
        }
      }
    };

    parser.sentences = [test()];

    start.pipe(parser).pipe(end);
    start.push('t');
  });

  it('can clear the describe cache', function (done) {
    var callbackSpy = sinon.spy();
    var describeSpy = sinon.spy();

    var test = u.lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        describeSpy();
        return u.lacona.literal({text: 'test'});
      }
    });

    var start = new Readable({objectMode: true});
    var end = new Writable({objectMode: true});
    start._read = function noop() {};
    end.write = function (obj) {
      if (obj.event === 'data') {
        callbackSpy();
        if (callbackSpy.calledOnce) {
          parser.sentences[0]._clearDescribeCache();
          start.push('t');
          start.push(null);
        } else {
          expect(describeSpy).to.have.been.calledTwice;
          done();
        }
      }
    };

    parser.sentences = [test()];

    start.pipe(parser).pipe(end);
    start.push('t');
  });

  it('throws for phrases without a default-lang schema', function () {
    expect(function() {
      u.lacona.createPhrase({
        name: 'test/test',
        translations: [{
          langs: ['en-US'],
          describe: function () {
            return u.lacona.literal({text: 'whatever'});
          }
        }]
      });
    }).to.throw(u.lacona.Error);
  });

  it('throws for translations without a lang', function () {
    expect(function() {
      u.lacona.createPhrase({
        name: 'test/test',
        translations: [{
          describe: function () {
            return u.lacona.literal({text: 'whatever'});
          }
        }]
      });
    }).to.throw(u.lacona.Error);
  });

  it('throws for phrases without a root', function () {
    expect(function() {
      u.lacona.createPhrase({
        name: 'test/test'
      });
    }).to.throw(u.lacona.Error);
  });

  it('throws for phrases without a name', function () {
    expect(function() {
      u.lacona.createPhrase({
        describe: function() {
          return u.lacona.literal({text: 'test'});
        }
      });
    }).to.throw(u.lacona.Error);
  });

});
<|endoftext|>


<commit_before>var tape = require('tape');
var ginga = require('../');

function Clock(){
  this._tick = 'tick';
  this._tock = 'tock';
}

function base(ctx, next){
  ctx.logs = ['clock'];
  next();
}
function tick(ctx, next){
  ctx.logs.push(this._tick);
  next();
}
function tock(ctx, next){
  ctx.logs.push(this._tock);
  next();
}
function end(ctx, done){
  ctx.logs.push('done');
  done(null, ctx.logs);
}
ginga(Clock.prototype)
  .define('tick', base, tick, end)
  .define('tock', base, tick, tock, end);

var plugin = ginga()
  .use(
    'tick',
    function(ctx, next){
      ctx.logs.push('more');
      next();
    },
    function(ctx, next){
      ctx.logs.push('and more tick');
      next();
    }
  )
  .use('tock',function(ctx, next){
    next('booooom');
  })
  .define('doom', function(ctx, next){
    next('dooooom');
  });

tape('ginga plugin', function (t) {
  t.plan(10);

  var clock = new Clock();

  clock.tick(function(err,res){
    t.notOk(err, 'no error');
    t.deepEqual(res,['clock','tick','done']);
  });
  clock.tock(function(err,res){
    t.notOk(err, 'no error');
    t.deepEqual(res,['clock','tick','tock','done']);
  });

  clock.use(plugin);

  clock.tick(function(err,res){
    t.notOk(err, 'no error');
    t.deepEqual(res,['clock','tick','more','and more tick','done']);
  });
  clock.tock(function(err,res){
    t.notOk(res, 'no result');
    t.equal(err,'booooom', 'return error');
  });
  clock.doom(function(err, res){
    t.notOk(res, 'no result');
    t.equal(err,'dooooom', 'return error');
  });
});
<commit_msg>fix test case<commit_after>var tape = require('tape');
var ginga = require('../');

function Clock(){
  this._tick = 'tick';
  this._tock = 'tock';
}

function base(ctx, next){
  ctx.logs = ['clock'];
  next();
}
function tick(ctx, next){
  ctx.logs.push(this._tick);
  next();
}
function tock(ctx, next){
  ctx.logs.push(this._tock);
  next();
}
function end(ctx, done){
  ctx.logs.push('done');
  done(null, ctx.logs);
}
ginga(Clock.prototype)
  .define('tick', base, tick, end)
  .define('tock', base, tick, tock, end);

var plugin = ginga()
  .use(
    'tick',
    function(ctx, next){
      ctx.logs.push('more');
      next();
    },
    function(ctx, next){
      ctx.logs.push('and more tick');
      next();
    }
  )
  .use('tock',function(ctx, next){
    next('booooom');
  });

tape('ginga plugin', function (t) {
  t.plan(10);

  var clock = new Clock();

  clock.tick(function(err,res){
    t.notOk(err, 'no error');
    t.deepEqual(res,['clock','tick','done']);
  });
  clock.tock(function(err,res){
    t.notOk(err, 'no error');
    t.deepEqual(res,['clock','tick','tock','done']);
  });

  clock.use(plugin);

  clock.tick(function(err,res){
    t.notOk(err, 'no error');
    t.deepEqual(res,['clock','tick','more','and more tick','done']);
  });
  clock.tock(function(err,res){
    t.notOk(res, 'no result');
    t.equal(err,'booooom', 'return error');
  });
});
<|endoftext|>


<commit_before>var _ = require('underscore');
var async = require('async');
var Pulsar = require('../lib/pulsar');
var PulsarJob = require('../lib/pulsar/job');
var PulsarDb = require('../lib/pulsar/db');
var assert = require('chai').assert;
var jobArgs = require('./job-args');
var Config = require('../lib/config');

describe('tests of pulsar API', function() {

  this.timeout(2000);

  var testConfig = new Config('./test/config.yaml').asHash();
  require('../lib/logger').configure(testConfig);

  beforeEach(function(done) {
    var self = this;

    new PulsarDb(testConfig.mongodb, function(err, db) {
      if (err) {
        done(err);
        return;
      }
      self.pulsarDb = db;
      //remove all items from collection that might remain from previous tests.
      db.collection.remove(function(err) {
        self.pulsar = new Pulsar(db, testConfig.pulsar);
        process.setMaxListeners(15);
        done(err);
      });
    });
  });

  after(function(done) {
    this.pulsarDb.collection.remove(done);
  });

  it('check if taskVariables are validated', function() {
    var app = jobArgs.app.example;
    var env = jobArgs.env.production;
    var task = jobArgs.task.dummySleepy;

    function callback(err, job) {
    }

    var self = this;
    assert.throw(function() {
      self.pulsar.createJob(app, env, task, [], callback);
    }, ValidationError);
    assert.throw(function() {
      self.pulsar.createJob(app, env, task, {key: []}, callback);
    }, ValidationError);
    assert.throw(function() {
      self.pulsar.createJob(app, env, task, {key: {}}, callback);
    }, ValidationError);
    assert.throw(function() {
      self.pulsar.createJob(app, env, task, {'key df': ''}, callback);
    }, ValidationError);
    assert.throw(function() {
      self.pulsar.createJob(app, env, task, {'ke"ydf': ''}, callback);
    }, ValidationError);
    assert.throw(function() {
      self.pulsar.createJob(app, env, task, {'keydf\'': ''}, callback);
    }, ValidationError);

    _.each(Pulsar.ILLEGAL_TASKS, function(task) {
      assert.throw(function() {
        self.pulsar.createJob(app, env, task, {'keydf\'': ''}, callback);
      }, ValidationError);
    });
    var hiddenIllegalTask = _.map(Pulsar.ILLEGAL_TASKS, function(task) {
      var illegals = ['\n', '\r', '\\', '\t'];
      var injection = _.sample(illegals, _.random(1, illegals.length - 1));
      injection = [].concat(injection).join('');
      var to = _.random(0, task.length - 1);
      return task.substring(0, to) + injection + task.substring(to);
    });

    _.each(hiddenIllegalTask, function(task) {
      assert.throw(function() {
        self.pulsar.createJob(app, env, task, {'keydf\'': ''}, callback);
      }, ValidationError);
    });

  });

  it('check if job is created', function(done) {
    this.pulsar.createJob(
      jobArgs.app.example,
      jobArgs.env.production,
      jobArgs.task.dummySleepy,
      function(err, job) {
        assert(!err && job.status == PulsarJob.STATUS.CREATED);
        done();
      });
  });

  it('tests a normal job\'s lifecycle', function(done) {
    this.timeout(12000);
    var self = this;
    this.pulsar.createJob(
      jobArgs.app.example,
      jobArgs.env.production,
      jobArgs.task.dummySleepy,
      function(err, job) {
        assert(!err && job.status == PulsarJob.STATUS.CREATED);
        var hadRun = false;
        job.on('change', function() {
          hadRun = job.status == PulsarJob.STATUS.RUNNING;
        });
        job.on('close', function() {
          assert(hadRun);
          self.pulsar.getJob(job.id, function(err, job) {
            assert(!err && job.status == PulsarJob.STATUS.FINISHED);
            done();
          });
        });
        job.execute();
      });
  });

  it('check if job can be got after it is created', function(done) {
    this.pulsar.createJob(
      jobArgs.app.example,
      jobArgs.env.production,
      jobArgs.task.dummySleepy,
      function(err, job) {
        assert(!err);
        this.pulsar.getJob(job.id, function(err, result) {
          assert.deepEqual(result.getData(), job.getData());
          done();
        });
      }.bind(this));
  });

  it('check if created job in the list of current jobs of pulsar', function(done) {
    this.pulsar.createJob(
      jobArgs.app.example,
      jobArgs.env.production,
      jobArgs.task.dummySleepy,
      function(err, job) {
        assert(!err);
        this.pulsar.getJobList(function(err, jobList) {
          assert(jobList.length === 1);
          assert.deepEqual(job.getData(), jobList[0].getData());
          assert.deepEqual(job.getArgs(), jobList[0].getArgs());
          done();
        });
      }.bind(this));
  });

  it('check if created job returns available tasks', function(done) {
    this.pulsar.getAvailableTasks(jobArgs.app.example, jobArgs.env.production, function(err, tasks) {
      assert(!err);
      assert(tasks['shell'], 'Shell task must be always present in available tasks');
      done();
    });
  });

  it('check if created job can be killed with SIG TERM signal', function(done) {
    this.pulsar.createJob(
      jobArgs.app.example,
      jobArgs.env.production,
      jobArgs.task.dummySleepy,
      function(err, job) {
        assert(!err);
        job.execute();
        job.once('change', function() {
          job.kill();
        });
        job.on('close', function() {
          assert(job.status == PulsarJob.STATUS.KILLED, 'The job kill (SIGTERM) does not work');
          done();
        });
      });
  });

  it('check if created job can be killed with SIG KILL signal', function(done) {
    //only for the sake of the test
    PulsarJob._KILL_TIMEOUT = 200;
    this.pulsar.createJob(
      jobArgs.app.example,
      jobArgs.env.production,
      jobArgs.task.dummyUnKillable,
      function(err, job) {
        assert(!err);
        job.execute();
        job.once('change', function() {
          setTimeout(function() {
            assert(job.status == PulsarJob.STATUS.RUNNING, 'Job should still be running');
          }, PulsarJob._KILL_TIMEOUT - 1);

          setTimeout(function() {
            assert(job.status == PulsarJob.STATUS.KILLED, 'The job kill (SIGKILL) does not work');
            done();
          }, PulsarJob._KILL_TIMEOUT + 50);

          job.kill();
        });
      });
  });

  it('check if the current jobs are shutdowned when the api process is killed', function(done) {
    var self = this;
    async.map([null, null], function(dummy, callback) {
      self.pulsar.createJob(
        jobArgs.app.example,
        jobArgs.env.production,
        jobArgs.task.dummySleepy,
        function(err, job) {
          assert(!err);
          job.execute();
          job.once('change', function() {
            assert(job.status == PulsarJob.STATUS.RUNNING, 'Job should be running');
            callback(null, job);
          });
        });
    }, function(err, jobs) {
      assert(jobs && jobs.length === 2);
      process.on('exit', function() {
        _.each(jobs, function(job) {
          assert(job.status == PulsarJob.STATUS.KILLED, 'Job should be killed');
        });
        //because `_shutdown` kills the process, we need to clean after the test manually.
        self.pulsarDb.collection.remove(done);
      });
      self.pulsar._shutdown('SIGINT');
    });
  });

});
<commit_msg>Disallow pulsar tasks: invoke, shell.<commit_after>var _ = require('underscore');
var async = require('async');
var Pulsar = require('../lib/pulsar');
var PulsarJob = require('../lib/pulsar/job');
var PulsarDb = require('../lib/pulsar/db');
var assert = require('chai').assert;
var jobArgs = require('./job-args');
var Config = require('../lib/config');

describe('tests of pulsar API', function() {

  this.timeout(2000);

  var testConfig = new Config('./test/config.yaml').asHash();
  require('../lib/logger').configure(testConfig);

  beforeEach(function(done) {
    var self = this;

    new PulsarDb(testConfig.mongodb, function(err, db) {
      if (err) {
        done(err);
        return;
      }
      self.pulsarDb = db;
      //remove all items from collection that might remain from previous tests.
      db.collection.remove(function(err) {
        self.pulsar = new Pulsar(db, testConfig.pulsar);
        process.setMaxListeners(15);
        done(err);
      });
    });
  });

  after(function(done) {
    this.pulsarDb.collection.remove(done);
  });

  it('check if taskVariables are validated', function() {
    var app = jobArgs.app.example;
    var env = jobArgs.env.production;
    var task = jobArgs.task.dummySleepy;

    function callback(err, job) {
    }

    var self = this;
    assert.throw(function() {
      self.pulsar.createJob(app, env, task, [], callback);
    }, ValidationError);
    assert.throw(function() {
      self.pulsar.createJob(app, env, task, {key: []}, callback);
    }, ValidationError);
    assert.throw(function() {
      self.pulsar.createJob(app, env, task, {key: {}}, callback);
    }, ValidationError);
    assert.throw(function() {
      self.pulsar.createJob(app, env, task, {'key df': ''}, callback);
    }, ValidationError);
    assert.throw(function() {
      self.pulsar.createJob(app, env, task, {'ke"ydf': ''}, callback);
    }, ValidationError);
    assert.throw(function() {
      self.pulsar.createJob(app, env, task, {'keydf\'': ''}, callback);
    }, ValidationError);

    _.each(Pulsar.ILLEGAL_TASKS, function(task) {
      assert.throw(function() {
        self.pulsar.createJob(app, env, task, {'key': ''}, callback);
      }, ValidationError);
    });
    var hiddenIllegalTask = _.map(Pulsar.ILLEGAL_TASKS, function(task) {
      var illegals = ['\n', '\r', '\\', '\t'];
      var injection = _.sample(illegals, _.random(1, illegals.length - 1));
      injection = [].concat(injection).join('');
      var to = _.random(0, task.length - 1);
      return task.substring(0, to) + injection + task.substring(to);
    });

    _.each(hiddenIllegalTask, function(task) {
      assert.throw(function() {
        self.pulsar.createJob(app, env, task, {'key': ''}, callback);
      }, ValidationError);
    });

  });

  it('check if job is created', function(done) {
    this.pulsar.createJob(
      jobArgs.app.example,
      jobArgs.env.production,
      jobArgs.task.dummySleepy,
      function(err, job) {
        assert(!err && job.status == PulsarJob.STATUS.CREATED);
        done();
      });
  });

  it('tests a normal job\'s lifecycle', function(done) {
    this.timeout(12000);
    var self = this;
    this.pulsar.createJob(
      jobArgs.app.example,
      jobArgs.env.production,
      jobArgs.task.dummySleepy,
      function(err, job) {
        assert(!err && job.status == PulsarJob.STATUS.CREATED);
        var hadRun = false;
        job.on('change', function() {
          hadRun = job.status == PulsarJob.STATUS.RUNNING;
        });
        job.on('close', function() {
          assert(hadRun);
          self.pulsar.getJob(job.id, function(err, job) {
            assert(!err && job.status == PulsarJob.STATUS.FINISHED);
            done();
          });
        });
        job.execute();
      });
  });

  it('check if job can be got after it is created', function(done) {
    this.pulsar.createJob(
      jobArgs.app.example,
      jobArgs.env.production,
      jobArgs.task.dummySleepy,
      function(err, job) {
        assert(!err);
        this.pulsar.getJob(job.id, function(err, result) {
          assert.deepEqual(result.getData(), job.getData());
          done();
        });
      }.bind(this));
  });

  it('check if created job in the list of current jobs of pulsar', function(done) {
    this.pulsar.createJob(
      jobArgs.app.example,
      jobArgs.env.production,
      jobArgs.task.dummySleepy,
      function(err, job) {
        assert(!err);
        this.pulsar.getJobList(function(err, jobList) {
          assert(jobList.length === 1);
          assert.deepEqual(job.getData(), jobList[0].getData());
          assert.deepEqual(job.getArgs(), jobList[0].getArgs());
          done();
        });
      }.bind(this));
  });

  it('check if created job returns available tasks', function(done) {
    this.pulsar.getAvailableTasks(jobArgs.app.example, jobArgs.env.production, function(err, tasks) {
      assert(!err);
      assert(tasks['shell'], 'Shell task must be always present in available tasks');
      done();
    });
  });

  it('check if created job can be killed with SIG TERM signal', function(done) {
    this.pulsar.createJob(
      jobArgs.app.example,
      jobArgs.env.production,
      jobArgs.task.dummySleepy,
      function(err, job) {
        assert(!err);
        job.execute();
        job.once('change', function() {
          job.kill();
        });
        job.on('close', function() {
          assert(job.status == PulsarJob.STATUS.KILLED, 'The job kill (SIGTERM) does not work');
          done();
        });
      });
  });

  it('check if created job can be killed with SIG KILL signal', function(done) {
    //only for the sake of the test
    PulsarJob._KILL_TIMEOUT = 200;
    this.pulsar.createJob(
      jobArgs.app.example,
      jobArgs.env.production,
      jobArgs.task.dummyUnKillable,
      function(err, job) {
        assert(!err);
        job.execute();
        job.once('change', function() {
          setTimeout(function() {
            assert(job.status == PulsarJob.STATUS.RUNNING, 'Job should still be running');
          }, PulsarJob._KILL_TIMEOUT - 1);

          setTimeout(function() {
            assert(job.status == PulsarJob.STATUS.KILLED, 'The job kill (SIGKILL) does not work');
            done();
          }, PulsarJob._KILL_TIMEOUT + 50);

          job.kill();
        });
      });
  });

  it('check if the current jobs are shutdowned when the api process is killed', function(done) {
    var self = this;
    async.map([null, null], function(dummy, callback) {
      self.pulsar.createJob(
        jobArgs.app.example,
        jobArgs.env.production,
        jobArgs.task.dummySleepy,
        function(err, job) {
          assert(!err);
          job.execute();
          job.once('change', function() {
            assert(job.status == PulsarJob.STATUS.RUNNING, 'Job should be running');
            callback(null, job);
          });
        });
    }, function(err, jobs) {
      assert(jobs && jobs.length === 2);
      process.on('exit', function() {
        _.each(jobs, function(job) {
          assert(job.status == PulsarJob.STATUS.KILLED, 'Job should be killed');
        });
        //because `_shutdown` kills the process, we need to clean after the test manually.
        self.pulsarDb.collection.remove(done);
      });
      self.pulsar._shutdown('SIGINT');
    });
  });

});
<|endoftext|>


<commit_before>var u = require('../util')
var sim = require('../simulate')

function print_network (network) {
  for(var k in network) {
    var s = k + ': '
    for(var j in network) {
      s += k == j ? ' ' : network[k].connections[j] ? j : '.'
    }
    console.log(s)
  }
}

function isConnected (network) {
  var reach = {}
  ;(function search (k) {
    reach[k] = true
    for(var j in network[k].connections)
      if(!reach[j]) search(j)
  }(Object.keys(network)[0]))

  return Object.keys(network).length === Object.keys(reach).length
}

var tape = require('tape')
var letters = 'abcdefghijklmnopqrstuzwxyz'
var RNG = require('rng')
function run (t, seed) {
  if(seed % 100 == 0)
  console.log('seed', seed)
  var rng = new RNG.MT(seed)

  function random() {
    return rng.random()
  }

  var M = 10, N = 10, C = 10
//  var L = 5 + ~~(random()*5)

  var a_log = []

  for(var i = 0; i < M; i++)
    a_log.push({author: 'A', sequence: a_log.length + 1, content: 'msg:'+letters[i]})

  var network = {}

  network = sim.peer(network, 'A', a_log)

  for(var i = 1; i < N; i++) {
    var me = letters[i].toUpperCase()
    network = sim.peer(network, me, [])
    //at least one connection to a peer currently in the network, gaurantees a connected network.
    network = sim.connection(network, me, letters[~~((i-1)*random())].toUpperCase())
  }

//  network = sim.peer(network, 'B', [])
//  network = sim.peer(network, 'C', [])
//  network = sim.connection(network, 'A', 'B')
//  network = sim.connection(network, 'B', 'C')
//  network = sim.connection(network, 'A', 'C')

  for(var i = 0; i < C; i++) {
    var me = letters[i%N].toUpperCase()
    var other
    while(me == (other = letters[~~(random()*N)].toUpperCase()))
      ;
//    console.log(me,'-->',other)
    network = sim.connection(network, me, other)
  }

//  print_network(network)

  //initialize

  var msglog = []

  network = sim.evolveNetwork(network, msglog, seed)

  if(!sim.isConsistent(network)) {
    print_network(network)
    var obj = {}
    for(var k in network)
      obj[k] = network[k].log.length + 1
    msglog.forEach(function (op) {
      console.log(op.from+'>'+op.to, op.data)
    })
    console.log(obj)
    throw new Error('network not consistent')
  }
  //add one more item to A's log

  network.A.emit = {author: 'a', sequence: a_log.length+1, content: 'LIVE'}

  network = sim.evolveNetwork(network, msglog, seed*2)
  if(!sim.isConsistent(network))
    throw new Error('network not consistent')
  //todo: make this a processable event log thing
  network.A.emit = {author: 'a', sequence: a_log.length+1, content: 'LIVE'}

  network = sim.evolveNetwork(network, msglog, seed*2)
  if(!sim.isConsistent(network))
    throw new Error('network not consistent')

}

if(process.argv[2])
  tape('run 3 message test with 2 peers, seed:'+ (+process.argv[2]), function (t) {
    run(t, +process.argv[2])
    t.end()
  })
else
  //running each test is O(Number of tests!)
  tape('run 3 message test with 2 peers, seeds', function (t) {
    for(var i = 0; i < 1000; i++) (function (i) {
      try {
        run(t, i)
      } catch (err) {
        console.log(i)
        throw err
//        t.ok(false, 'failed on seed: '+i)
      }
    })(i)
    t.end()
  })

<commit_msg>comment<commit_after>var u = require('../util')
var sim = require('../simulate')

function print_network (network) {
  for(var k in network) {
    var s = k + ': '
    for(var j in network) {
      s += k == j ? ' ' : network[k].connections[j] ? j : '.'
    }
    console.log(s)
  }
}

function isConnected (network) {
  var reach = {}
  ;(function search (k) {
    reach[k] = true
    for(var j in network[k].connections)
      if(!reach[j]) search(j)
  }(Object.keys(network)[0]))

  return Object.keys(network).length === Object.keys(reach).length
}

var tape = require('tape')
var letters = 'abcdefghijklmnopqrstuzwxyz'
var RNG = require('rng')
function run (t, seed) {
  if(seed % 100 == 0)
  console.log('seed', seed)
  var rng = new RNG.MT(seed)

  function random() {
    return rng.random()
  }

  //generate a random network, with 10 nodes, plus 10 extra connections
  //then send 10 messages over it.
  var M = 10, N = 10, C = 10
//  var L = 5 + ~~(random()*5)

  var a_log = []

  for(var i = 0; i < M; i++)
    a_log.push({author: 'A', sequence: a_log.length + 1, content: 'msg:'+letters[i]})

  var network = {}

  network = sim.peer(network, 'A', a_log)

  for(var i = 1; i < N; i++) {
    var me = letters[i].toUpperCase()
    network = sim.peer(network, me, [])
    //at least one connection to a peer currently in the network, gaurantees a connected network.
    network = sim.connection(network, me, letters[~~((i-1)*random())].toUpperCase())
  }

//  network = sim.peer(network, 'B', [])
//  network = sim.peer(network, 'C', [])
//  network = sim.connection(network, 'A', 'B')
//  network = sim.connection(network, 'B', 'C')
//  network = sim.connection(network, 'A', 'C')

  for(var i = 0; i < C; i++) {
    var me = letters[i%N].toUpperCase()
    var other
    while(me == (other = letters[~~(random()*N)].toUpperCase()))
      ;
//    console.log(me,'-->',other)
    network = sim.connection(network, me, other)
  }

//  print_network(network)

  //initialize

  var msglog = []

  network = sim.evolveNetwork(network, msglog, seed)

  if(!sim.isConsistent(network)) {
    print_network(network)
    var obj = {}
    for(var k in network)
      obj[k] = network[k].log.length + 1
    msglog.forEach(function (op) {
      console.log(op.from+'>'+op.to, op.data)
    })
    console.log(obj)
    throw new Error('network not consistent')
  }
  //add one more item to A's log

  network.A.emit = {author: 'a', sequence: a_log.length+1, content: 'LIVE'}

  network = sim.evolveNetwork(network, msglog, seed*2)
  if(!sim.isConsistent(network))
    throw new Error('network not consistent')
  //todo: make this a processable event log thing
  network.A.emit = {author: 'a', sequence: a_log.length+1, content: 'LIVE'}

  network = sim.evolveNetwork(network, msglog, seed*2)
  if(!sim.isConsistent(network))
    throw new Error('network not consistent')

}

if(process.argv[2])
  tape('run 3 message test with 2 peers, seed:'+ (+process.argv[2]), function (t) {
    run(t, +process.argv[2])
    t.end()
  })
else
  //running each test is O(Number of tests!)
  tape('run 3 message test with 2 peers, seeds', function (t) {
    for(var i = 0; i < 1000; i++) (function (i) {
      try {
        run(t, i)
      } catch (err) {
        console.log(i)
        throw err
//        t.ok(false, 'failed on seed: '+i)
      }
    })(i)
    t.end()
  })

<|endoftext|>


<commit_before>var trumpet = require('../');
var fs = require('fs');
var test = require('tape');
var through = require('through');

test('rebase selector', function (t) {
    t.plan(1);

    var tr = trumpet();
    var elem = tr.select('.c');
    elem.getAttribute('class', function (value) {
        t.equal(value, 'c');
    });
    fs.createReadStream(__dirname + '/rebase.html').pipe(tr);
});
<commit_msg>rebase selector test just works somehow<commit_after>var trumpet = require('../');
var fs = require('fs');
var test = require('tape');
var through = require('through');

test('wonky duplicated classes selector', function (t) {
    t.plan(1);

    var tr = trumpet();
    var elem = tr.select('.c');
    elem.getAttribute('class', function (value) {
        t.equal(value, 'c');
    });
    fs.createReadStream(__dirname + '/rebase.html').pipe(tr);
});

test('rebase selector', function (t) {
    t.plan(1);

    var tr = trumpet();
    var elem = tr.select('.a > .b > * > .d');
    elem.getAttribute('class', function (value) {
        t.equal(value, 'd');
    });
    fs.createReadStream(__dirname + '/rebase.html').pipe(tr);
});
<|endoftext|>


<commit_before>describe('Records', function () {
  helpers.testRequest(
    'when you get a record',
    function () { return client.get('people', 1) },
    function (call) {
      it('should return the record', function () {
        return expect(helpers.removeUrl(call.response)).eventually.deep.equal({
          "id":1,
          "name":"Paul Jacobs",
          "role":"Group Manager",
          "phone":"573-356-3327",
          "tasks":[{"id":3, "summary":"Finalize next iteration of test plan"}, {"id":10, "summary":"Publish industry analysis"}]
        });
      })
    }
  )

  helpers.testRequest(
    'when you get a record with options',
    function () { return client.get('people', 1, {include: 'role', exclude: 'id,record_url'}) },
    function (call) {
      it('should return the record', function () {
        return expect(call.response).eventually.deep.equal({role:"Group Manager"});
      })
    }
  );

  helpers.testRequest(
    'when you create a record',
    function () { return client.create('people', {name: 'Ben B', role: 'Engineer'}) },
    function (call) {
      it('should return the record', function () {
        var response = call.response.then(function (data) {
          return _.omit(data, 'id', 'record_url');
        })
        return expect(response).eventually.deep.equal({
          name: 'Ben B',
          role: 'Engineer',
          phone: null,
          tasks: []
        });
      })

      var needsDelete = true;
      describe('when you get the response', function () {
        var id;
        before(function () {
          return call.response.then(function (data) { id = data.id })
        })

        helpers.testRequest(
          'when you update a record',
          function () { return client.update('people', id, {phone: '510-867-5309'}) },
          function (call) {
            it('should return the modified record', function () {
              var response = call.response.then(function (data) {
                return _.omit(data, 'id', 'record_url');
              })

              return expect(response).eventually.deep.equal({
                name: 'Ben B',
                role: 'Engineer',
                phone: '510-867-5309',
                tasks: []
              });
            })
          }
        )

        helpers.testRequest(
          'when you delete a record',
          function () {
            needsDelete = false;
            return client.destroy('people', id)
          },
          function (call) {
            it('should complete successfully', function () {
              return expect(call.response).eventually.equal('ok');
            })
          }
        )
      })

      after(function () {
        // Cleanup if we haven't already run the delete
        if (needsDelete) {
          return call.response.then(function (data) {
            return client.destroy('people', data.id);
          })
        }
      })
    }
  )

  helpers.testRequest(
    'when you request a record and get an error',
    function () { return client.get('people', 99) },
    function (call) {
      it('should throw an error', function () {
        return expect(call.response).eventually.rejectedWith(/Record id not found/)
      })
    }
  )
});
<commit_msg>Test unicode requests<commit_after>describe('Records', function () {
  helpers.testRequest(
    'when you get a record',
    function () { return client.get('people', 1) },
    function (call) {
      it('should return the record', function () {
        return expect(helpers.removeUrl(call.response)).eventually.deep.equal({
          "id":1,
          "name":"Paul Jacobs",
          "role":"Group Manager",
          "phone":"573-356-3327",
          "tasks":[{"id":3, "summary":"Finalize next iteration of test plan"}, {"id":10, "summary":"Publish industry analysis"}]
        });
      })
    }
  )

  helpers.testRequest(
    'when you get a record with options',
    function () { return client.get('people', 1, {include: 'role', exclude: 'id,record_url'}) },
    function (call) {
      it('should return the record', function () {
        return expect(call.response).eventually.deep.equal({role:"Group Manager"});
      })
    }
  );

  helpers.testRequest(
    'when you create a record',
    function () { return client.create('people', {name: 'Ben B', role: 'Engineer'}) },
    function (call) {
      it('should return the record', function () {
        var response = call.response.then(function (data) {
          return _.omit(data, 'id', 'record_url');
        })
        return expect(response).eventually.deep.equal({
          name: 'Ben B',
          role: 'Engineer',
          phone: null,
          tasks: []
        });
      })

      var needsDelete = true;
      describe('when you get the response', function () {
        var id;
        before(function () {
          return call.response.then(function (data) { id = data.id })
        })

        helpers.testRequest(
          'when you update a record',
          function () { return client.update('people', id, {phone: '510-867-5309'}) },
          function (call) {
            it('should return the modified record', function () {
              var response = call.response.then(function (data) {
                return _.omit(data, 'id', 'record_url');
              })

              return expect(response).eventually.deep.equal({
                name: 'Ben B',
                role: 'Engineer',
                phone: '510-867-5309',
                tasks: []
              });
            })
          }
        )

        helpers.testRequest(
          'when you update a record with unicode characters',
          function () { return client.update('people', id, {role: 'مهندس'}) },
          function (call) {
            it('should return the modified record', function () {
              var response = call.response.then(function (data) {
                return _.omit(data, 'id', 'record_url', 'phone');
              })

              return expect(response).eventually.deep.equal({
                name: 'Ben B',
                role: 'مهندس',
                tasks: []
              });
            })
          }
        )

        helpers.testRequest(
          'when you delete a record',
          function () {
            needsDelete = false;
            return client.destroy('people', id)
          },
          function (call) {
            it('should complete successfully', function () {
              return expect(call.response).eventually.equal('ok');
            })
          }
        )
      })

      after(function () {
        // Cleanup if we haven't already run the delete
        if (needsDelete) {
          return call.response.then(function (data) {
            return client.destroy('people', data.id);
          })
        }
      })
    }
  )

  helpers.testRequest(
    'when you request a record and get an error',
    function () { return client.get('people', 99) },
    function (call) {
      it('should throw an error', function () {
        return expect(call.response).eventually.rejectedWith(/Record id not found/)
      })
    }
  )
});
<|endoftext|>


<commit_before>const Router = require('../dist/commonjs/router.js').Router;

const assert = require('assert');

describe('Router', () => {

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

    it('should return a Router object (empty constructor)', () => {
      assert.ok(new Router() instanceof Router);
    });
    it('should return a Router object (no routes)', () => {
      assert.ok(new Router({}) instanceof Router);
    });
    it('should return a Router object (one route)', () => {
      assert.ok(new Router({'foo': 'bar'}) instanceof Router);
    });
  });

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

    it('should return no matches (empty constructor, no URL)', () => {
      const r = new Router();
      assert.deepEqual(r.match(), []);
    });
    it('should return no matches (no routes, no URL)', () => {
      const r = new Router({});
      assert.deepEqual(r.match(), []);
    });
    it('should return no matches (one route, no URL)', () => {
      const r = new Router({'foo': 'bar'});
      assert.deepEqual(r.match(), []);
    });
    it('should return no matches (no routes, URL)', () => {
      const r = new Router();
      assert.deepEqual(r.match('qqq'), []);
    });
    it('should return no matches (one route, URL)', () => {
      const r = new Router({'foo': 'bar'});
      assert.deepEqual(r.match('qqq'), []);
    });
    it('should return one match (one route, URL)', () => {
      const r = new Router({'foo': 'bar'});
      assert.deepEqual(
        r.match('foo'),
        [['bar', 'foo'.match(new RegExp('foo'))]]
      );
    });
    it('should support prefix', () => {
      const r = new Router({'/foo': 'bar'}, '/quux');
      assert.equal(r.match('/quux/foo').length, 1);
    });
    it('should match on regexp /foo/(.*)', () => {
      const r = new Router({'/foo/(.*)': 'bar'});
      const m = r.match('/foo/43');
      assert.equal(m.length, 1);
      assert.equal(m[0][0], 'bar');
      assert.equal(m[0][1][0], '/foo/43');
      assert.equal(m[0][1][1], '43');
    });
    it('should match on regexp /foo/quux-(.*)/(\\d+)', () => {
      const r = new Router({'/foo/quux-(.*)/(\\d+)': 'bar'});
      const m = r.match('/foo/quux-clem/54');
      assert.equal(m.length, 1);
      assert.equal(m[0][0], 'bar');
      assert.equal(m[0][1][1], 'clem'); // first capture
      assert.equal(m[0][1][2], '54'); // second capture
    });
    it('should return a single match', () => {
      const r = new Router({'foo1': 'bar1', 'foo2': 'bar2'});
      const m1 = r.match('foo1');
      assert.equal(m1.length, 1);
      assert.equal(m1[0][0], 'bar1');
      const m2 = r.match('foo2');
      assert.equal(m2.length, 1);
      assert.equal(m2[0][0], 'bar2');
    });
    it('should return two matches', () => {
      const r = new Router({'foo': 'bar', '.*': 'baz'});
      const m = r.match('foo');
      assert.equal(m.length, 2);
      assert.equal(m[0][0], 'bar');
      assert.equal(m[1][0], 'baz');
    });
    it('should match http hostnames', () => {
      const r = new Router({'^https?://foo.com/': true});
      const m = r.match('http://foo.com/some/path?foo=bar');
      assert.equal(m.length, 1);
    });
    it('should match https hostnames', () => {
      const r = new Router({'^https?://foo.com/': true});
      const m = r.match('https://foo.com/some/path?foo=bar');
      assert.equal(m.length, 1);
    });

  });

  describe('#firstMatch()', () => {
    it('should return null', () => {
      const r = new Router({'foo': 'bar'});
      assert.deepEqual(r.firstMatch('/bar'), null);
    });
    it('should return the first match', () => {
      const r = new Router({'foo': 'bar', '.*': 'baz'});
      const m = r.firstMatch('foo');
      assert.deepEqual(m, 'bar');
    });
  });

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

    it('should return a single match', () => {
      const r = new Router({'foo': 'bar'});
      r.loop('foo', (v) => {
        assert.equal(v, 'bar');
      });
    });
    it('should return two matches', () => {
      const r = new Router({'foo': 'bar1', '.*': 'bar2'});
      let count = 0;
      r.loop('foo', (v, m, n) => {
        switch (count) {
          // First time through the value should be 'bar1' ...
          case 0:
            assert.equal(v, 'bar1');
            break;
          // ... and the second time (after n()) the value should be 'bar2'
          case 1:
            assert.equal(v, 'bar2');
            break;
        }
        count++;
        n();
      });
    });
    it('should match on regexp /foo-(\\d+)', () => {
      const r = new Router({'/foo-(\\d+)': 'bar'});
      r.loop('/foo-333', (v, m) => {
        assert.equal(v, 'bar');
        assert.equal(m[1], '333');
      });
    });

  });
});
<commit_msg>Add test/example for question mark<commit_after>const Router = require('../dist/commonjs/router.js').Router;

const assert = require('assert');

describe('Router', () => {

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

    it('should return a Router object (empty constructor)', () => {
      assert.ok(new Router() instanceof Router);
    });
    it('should return a Router object (no routes)', () => {
      assert.ok(new Router({}) instanceof Router);
    });
    it('should return a Router object (one route)', () => {
      assert.ok(new Router({'foo': 'bar'}) instanceof Router);
    });
  });

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

    it('should return no matches (empty constructor, no URL)', () => {
      const r = new Router();
      assert.deepEqual(r.match(), []);
    });
    it('should return no matches (no routes, no URL)', () => {
      const r = new Router({});
      assert.deepEqual(r.match(), []);
    });
    it('should return no matches (one route, no URL)', () => {
      const r = new Router({'foo': 'bar'});
      assert.deepEqual(r.match(), []);
    });
    it('should return no matches (no routes, URL)', () => {
      const r = new Router();
      assert.deepEqual(r.match('qqq'), []);
    });
    it('should return no matches (one route, URL)', () => {
      const r = new Router({'foo': 'bar'});
      assert.deepEqual(r.match('qqq'), []);
    });
    it('should return one match (one route, URL)', () => {
      const r = new Router({'foo': 'bar'});
      assert.deepEqual(
        r.match('foo'),
        [['bar', 'foo'.match(new RegExp('foo'))]]
      );
    });
    it('should support prefix', () => {
      const r = new Router({'/foo': 'bar'}, '/quux');
      assert.equal(r.match('/quux/foo').length, 1);
    });
    it('should match on regexp /foo/(.*)', () => {
      const r = new Router({'/foo/(.*)': 'bar'});
      const m = r.match('/foo/43');
      assert.equal(m.length, 1);
      assert.equal(m[0][0], 'bar');
      assert.equal(m[0][1][0], '/foo/43');
      assert.equal(m[0][1][1], '43');
    });
    it('should match on regexp /foo/quux-(.*)/(\\d+)', () => {
      const r = new Router({'/foo/quux-(.*)/(\\d+)': 'bar'});
      const m = r.match('/foo/quux-clem/54');
      assert.equal(m.length, 1);
      assert.equal(m[0][0], 'bar');
      assert.equal(m[0][1][1], 'clem'); // first capture
      assert.equal(m[0][1][2], '54'); // second capture
    });
    it('should match on regexp /foo\\?token=(.*)', () => {
      const r = new Router({'/foo\\?token=(.*)': 'bar'});
      const m = r.match('/foo?token=quux');
      assert.equal(m.length, 1);
      assert.equal(m[0][0], 'bar');
      assert.equal(m[0][1][1], 'quux');
    });
    it('should return a single match', () => {
      const r = new Router({'foo1': 'bar1', 'foo2': 'bar2'});
      const m1 = r.match('foo1');
      assert.equal(m1.length, 1);
      assert.equal(m1[0][0], 'bar1');
      const m2 = r.match('foo2');
      assert.equal(m2.length, 1);
      assert.equal(m2[0][0], 'bar2');
    });
    it('should return two matches', () => {
      const r = new Router({'foo': 'bar', '.*': 'baz'});
      const m = r.match('foo');
      assert.equal(m.length, 2);
      assert.equal(m[0][0], 'bar');
      assert.equal(m[1][0], 'baz');
    });
    it('should match http hostnames', () => {
      const r = new Router({'^https?://foo.com/': true});
      const m = r.match('http://foo.com/some/path?foo=bar');
      assert.equal(m.length, 1);
    });
    it('should match https hostnames', () => {
      const r = new Router({'^https?://foo.com/': true});
      const m = r.match('https://foo.com/some/path?foo=bar');
      assert.equal(m.length, 1);
    });

  });

  describe('#firstMatch()', () => {
    it('should return null', () => {
      const r = new Router({'foo': 'bar'});
      assert.deepEqual(r.firstMatch('/bar'), null);
    });
    it('should return the first match', () => {
      const r = new Router({'foo': 'bar', '.*': 'baz'});
      const m = r.firstMatch('foo');
      assert.deepEqual(m, 'bar');
    });
  });

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

    it('should return a single match', () => {
      const r = new Router({'foo': 'bar'});
      r.loop('foo', (v) => {
        assert.equal(v, 'bar');
      });
    });
    it('should return two matches', () => {
      const r = new Router({'foo': 'bar1', '.*': 'bar2'});
      let count = 0;
      r.loop('foo', (v, m, n) => {
        switch (count) {
          // First time through the value should be 'bar1' ...
          case 0:
            assert.equal(v, 'bar1');
            break;
          // ... and the second time (after n()) the value should be 'bar2'
          case 1:
            assert.equal(v, 'bar2');
            break;
        }
        count++;
        n();
      });
    });
    it('should match on regexp /foo-(\\d+)', () => {
      const r = new Router({'/foo-(\\d+)': 'bar'});
      r.loop('/foo-333', (v, m) => {
        assert.equal(v, 'bar');
        assert.equal(m[1], '333');
      });
    });

  });
});
<|endoftext|>


<commit_before>/*globals require:true, define:true, exports:true, load:true, console:true, print:true, module:true, emit:true, process:true */
/*jshint eqeqeq:false */
(function (root) {
  var isLoader = typeof define === 'function' && !!define.amd
    , isModule = typeof require === 'function' && typeof exports === 'object' && exports && !isLoader
    , isBrowser = 'window' in root && root.window == root && typeof root.navigator !== 'undefined'
    , isEngine = !isBrowser && !isModule && typeof root.load === 'function'
    , isTestem = isBrowser && root.location.hash === '#testem'
    // Use the console reporter
    , isConsole = typeof process == 'object' && process.argv && process.argv.indexOf('--console') >= 0;

  var load = function load(mod, path) {
    if (root[mod]) return root[mod];
    if (isModule) return require(path);
    if (isEngine) {
      root.load(path.replace(/\.js$/, '') + '.js');
      return root[mod];
    }
  };

  var Spec = load('Spec', './lib/spec')
    , Newton = load('Newton', './lib/newton')
    , luaparse = load('luaparse', '../luaparse')
    , options = { scope: true, locations: true, ranges: true }
    , specs = root.specs = [
        './spec/assignments'
      , './spec/comments'
      , './spec/conditional'
      , './spec/do'
      , './spec/escapesequences'
      , './spec/expressions'
      , './spec/for'
      , './spec/functioncalls'
      , './spec/functions'
      , './spec/literals'
      , './spec/local'
      , './spec/misc'
      , './spec/operators'
      , './spec/repeat'
      , './spec/return'
      , './spec/scope'
      , './spec/statements'
      , './spec/tableconstructors'
      , './spec/while'
    ]
    // Print function used for Spec reporters.
    , output = (function() {
      if (typeof console !== 'undefined' && console.log) return function(value) { console.log(value); };
      // In browsers, the global `print` function prints the current page.
      else if (typeof print === 'function' && !isBrowser) return print;
      else return function(value) { };
    }())
    // Create the test suite.
    , suite = new Spec.Suite('Luaparse Unit Tests');

  function escapeString(string) {
    return string.replace(/\n/g, '\\n')
      .replace(/\r/g, '\\r')
      .replace(/\t/g, '\\t')
      .replace(/\f/g, '\\f')
      .replace(/\v/g, '\\v');
  }

  // Expect a parse error to occur
  Spec.Test.prototype.parseError = function (source, expected, options) {
    var ok = false, actual;
    try {
      actual = luaparse.parse(source, options);
    } catch (exception) {
      actual = exception.message;
      ok = actual === expected;
    }
    return this.ok(ok, {
      'expected': expected,
      'actual': actual,
      'message': escapeString(source)
    });
  };

  // Expect the parsed AST to match.
  Spec.Test.prototype.parses = function (source, expected, options) {
    return this.deepEqual(luaparse.parse(source, options), expected, escapeString(source));
  };

  Spec.Test.prototype.equalPrecedence = function (source, expected, options) {
    function normalise(node) {
      if (!node || typeof node !== 'object')
        return node;
      node.inParens = null;
      for (var key in node) if (node.hasOwnProperty(key)) {
        normalise(node[key]);
      }
      return node;
    }

    return this.deepEqual(
      normalise(luaparse.parse('a = ' + source, options)),
      normalise(luaparse.parse('a = ' + expected, options)),
      source + ' is equal to ' + expected
    );
  };

  // Create a test, and delegate to appropiate test function.
  function addTest(testName, tests) {
    suite.addTest(testName, function() {
      var count = 0;
      for (var source in tests) if (tests.hasOwnProperty(source)) {
        var expected = tests[source];
        if (typeof expected === 'string') this.parseError(source, expected, options);
        else if (typeof expected.result === 'object')
          this.deepEqual(luaparse.parse(source, expected.options || options), expected.result, expected.name || escapeString(source));
        else if (typeof expected.result === 'string') this.parseError(source, expected.result, expected.options || options);
        else this.parses(source, expected, options);

        count++;
      }
      this.done(count);
    });
  }

  // Reporters ----------------------------------------------------------------

  // Beautify console output Mocha-style.
  var consoleReporter = (function() {
    var failures = []
      , colors = {
          'red': 31
        , 'green': 32
        , 'gray': 90
        , 'white': 0
      }
      , line = '-------------------------------------------------'
      , colorize = function colorize(color, string) {
        return '\u001b[' + colors[color] + 'm' + string + '\u001b[0m';
      };

    return function consoleReporter(event) {
      switch (event.type) {
        case 'assertion':
          output('    ' + colorize('green', '✓ ') + colorize('gray', event.message));
          break;
        case 'failure':
          output('    ' + colorize('red', '✖ ' + event.message));
          failures.push(event);
          break;
        case 'start':
          output(this.name);
          break;
        case 'setup':
          output('\n  ' + colorize('white', event.target.name));
          break;
        case 'complete':
          var assertionCount = event.target.assertions
            , failureCount = event.target.failures
            , totalCount = assertionCount + failureCount;

          for (var i = 0, l = failures.length; i < l; i++) {
            var failure = failures[i]
              , expected = Newton.stringify(failure.expected)
              , actual = Newton.stringify(failure.actual);
            output(Newton.substitute('\n%s\n  Expected: %s\n  Actual:   %s', colorize('red', failure.message + ' ' + line), colorize('gray', expected), colorize('gray', actual)));
          }
          output('\n' + assertionCount + '/' + totalCount + ' assertions');
          break;
      }
    };
  }());

  var testemReporter = (function() {
    var id = 0
      , testResults = [];

    return function(event) {
      var test, isSuccess;
      switch (event.type) {
        case 'assertion':
        case 'failure':
          isSuccess = (event.type === 'assertion');
          test = {
              passed: isSuccess ? 1 : 0
            , failed: isSuccess ? 0 : 1
            , total: 1
            , id: id++
            , name: event.message
            , items: []
          };
          if (!isSuccess) {
            test.items.push({
                passed: false
              , message: Newton.substitute('Expected %o to match %o', event.expected, event.actual)
            });
          }
          testResults.push(test);
          root.Testem.emit('test-result', test);
          break;
        case 'complete':
          root.Testem.emit('all-test-results', {
              failed: this.failures
            , total: this.assertions
            , tests: []
          });
          break;
        case 'start':
          root.Testem.emit('tests-start');
          break;
      }
    };
  }());

  // Use the appropiate reporter depending on enviroment.
  var reporter = isBrowser ? Newton.createReport('suite') :
    isConsole ? consoleReporter :
    Newton.createTAP(output);

  if (isTestem) suite.on('all', testemReporter);

  suite.on('all', reporter);

  // Additional tests ---------------------------------------------------------

  suite.addTest('API', function() {
    this.equal(typeof luaparse, 'object', 'luaparse is an object');
    this.equal(typeof luaparse.parse, 'function', 'luaparse.parse() is a function');
    this.equal(typeof luaparse.write, 'function', 'luaparse.write() is a function');
    this.equal(typeof luaparse.end, 'function', 'luaparse.end() is a function');
    var parse = luaparse.parse({ wait: true });
    this.deepEqual(parse.end('break'), {
      "type": "Chunk",
      "body": [
        {
          "type": "BreakStatement"
        }
      ],
      "comments": []
    }, 'should support waiting on input');

    var nodes = []
      , createdScopes = 0
      , destroyedScopes = 0;

    parse = luaparse.parse('do local a = 1 b = 1 end -- comment', {
        scope: true
      , locations: true
      , ranges: true
      , onCreateNode: function(node) { nodes.push(node); }
      , onCreateScope: function() { createdScopes++; }
      , onDestroyScope: function() { destroyedScopes++; }
    });
    this.equal(createdScopes, 2, 'should invoke onCreateScope callback');
    this.equal(createdScopes, destroyedScopes, 'should invoke onDestroyScope callback');
    this.equal(nodes.length, 9, 'should invoke onCreateNode callback');
    this.deepEqual(
        nodes[0]
      , {"type": "Identifier", "name": "a", "loc": {"start": {"line": 1, "column": 9}, "end": {"line": 1, "column": 10}}, "range": [9, 10], "isLocal": true}
      , 'should invoke onCreateNode callback with syntax node parameter'
    );

    this.deepEqual(luaparse.parse('#!/usr/bin/lua\nbreak', { locations: true, ranges: true }), {
      "type": "Chunk", "body": [{"type": "BreakStatement", "loc": {"start": {"line": 2, "column": 0}, "end": {"line": 2, "column": 5}}, "range": [15, 20]}], "loc": {"start": {"line": 2, "column": 0}, "end": {"line": 2, "column": 5}}, "range": [15, 20], "comments": []
    }, 'should ignore shebangs');

    this.done(10);
  });

  suite.addTest('Precedence', function() {
    this.equalPrecedence('2^3^2', '2^(3^2)');
    this.equalPrecedence('2^3*4', '(2^3)*4');
    this.equalPrecedence('2^2^3', '2^(2^3)');
    this.equalPrecedence('2^2^3^4', '2^(2^(3^4))');
    this.equalPrecedence('2^2^3^4+1', '2^(2^(3^4))+1');
    this.equalPrecedence('1*2/3', '(1*2)/3');
    this.equalPrecedence('1 + 1 * 2 > 3', '( 1 + ( 1 * 2 ) ) > 3');
    this.equalPrecedence('1 < 2 and 2 < 1', '(1 < 2) and (2 < 1)');
    this.equalPrecedence('1 / 2 + 4 * 2 > 8', '((1 / 2) + (4 * 2)) > 8');
    this.equalPrecedence('2 < 1 == true', '(2 < 1) == true');
    this.equalPrecedence('2 < 1 + 1 == true', '(2 < (1 + 1)) == true');
    this.equalPrecedence('not 1 + 1', '(not 1) + 1');
    this.equalPrecedence('not not 1 + 1', '(not (not (1)) + 1)');
    this.equalPrecedence('1 + #1', '1 + (#1)');
    this.equalPrecedence('-x^2', '-(x^2)');
    this.equalPrecedence('3~2&1', '3~(2&1)', { "luaVersion": "5.3" });
    this.equalPrecedence('3~2|1', '(3~2)|1', { "luaVersion": "5.3" });
    this.equalPrecedence('1<<2 ..3', '1<<(2 ..3)', { "luaVersion": "5.3" });
    this.done(18);
  });

  suite.addTest('EOL sequences', function() {
    var options = { locations: true }
      , baseline = luaparse.parse('foo = 1\nbar = 1', options);

    this.deepEqual(baseline, luaparse.parse('foo = 1\rbar = 1', options), 'carriage return');
    this.deepEqual(baseline, luaparse.parse('foo = 1\n\rbar = 1', options), 'newline followed by carriage return');
    this.deepEqual(baseline, luaparse.parse('foo = 1\r\nbar = 1', options), 'carriage return followed by newline');
    this.done(3);
  });

  if (isLoader) {
    define(specs, function () {
      Spec.forEach(arguments, function(test) {
        addTest(test.name, test.spec);
      });
      suite.shuffle();
      return suite;
    });
  } else if (isBrowser || (!isModule || (typeof module === 'object' && module === require.main))) {
    var run = root.run = function() {
      // Add all tests. In a browser the tests are expected to be loaded
      // therefore this function is exposed as a wrapper around the test suites
      // `run()` so that it can run on load.
      Spec.forEach(specs, function(spec) {
        var name = spec.replace(/^[\s\S]*\/([^\/]+)$/, '$1')
          , tests = load(name, spec);

        addTest(tests.name, tests.spec);
      });
      suite.shuffle();
      suite.run();
    };

    if (!isBrowser) run();
  }
}(this));
<commit_msg>Add a testcase for the onLocalDeclaration callback<commit_after>/*globals require:true, define:true, exports:true, load:true, console:true, print:true, module:true, emit:true, process:true */
/*jshint eqeqeq:false */
(function (root) {
  var isLoader = typeof define === 'function' && !!define.amd
    , isModule = typeof require === 'function' && typeof exports === 'object' && exports && !isLoader
    , isBrowser = 'window' in root && root.window == root && typeof root.navigator !== 'undefined'
    , isEngine = !isBrowser && !isModule && typeof root.load === 'function'
    , isTestem = isBrowser && root.location.hash === '#testem'
    // Use the console reporter
    , isConsole = typeof process == 'object' && process.argv && process.argv.indexOf('--console') >= 0;

  var load = function load(mod, path) {
    if (root[mod]) return root[mod];
    if (isModule) return require(path);
    if (isEngine) {
      root.load(path.replace(/\.js$/, '') + '.js');
      return root[mod];
    }
  };

  var Spec = load('Spec', './lib/spec')
    , Newton = load('Newton', './lib/newton')
    , luaparse = load('luaparse', '../luaparse')
    , options = { scope: true, locations: true, ranges: true }
    , specs = root.specs = [
        './spec/assignments'
      , './spec/comments'
      , './spec/conditional'
      , './spec/do'
      , './spec/escapesequences'
      , './spec/expressions'
      , './spec/for'
      , './spec/functioncalls'
      , './spec/functions'
      , './spec/literals'
      , './spec/local'
      , './spec/misc'
      , './spec/operators'
      , './spec/repeat'
      , './spec/return'
      , './spec/scope'
      , './spec/statements'
      , './spec/tableconstructors'
      , './spec/while'
    ]
    // Print function used for Spec reporters.
    , output = (function() {
      if (typeof console !== 'undefined' && console.log) return function(value) { console.log(value); };
      // In browsers, the global `print` function prints the current page.
      else if (typeof print === 'function' && !isBrowser) return print;
      else return function(value) { };
    }())
    // Create the test suite.
    , suite = new Spec.Suite('Luaparse Unit Tests');

  function escapeString(string) {
    return string.replace(/\n/g, '\\n')
      .replace(/\r/g, '\\r')
      .replace(/\t/g, '\\t')
      .replace(/\f/g, '\\f')
      .replace(/\v/g, '\\v');
  }

  // Expect a parse error to occur
  Spec.Test.prototype.parseError = function (source, expected, options) {
    var ok = false, actual;
    try {
      actual = luaparse.parse(source, options);
    } catch (exception) {
      actual = exception.message;
      ok = actual === expected;
    }
    return this.ok(ok, {
      'expected': expected,
      'actual': actual,
      'message': escapeString(source)
    });
  };

  // Expect the parsed AST to match.
  Spec.Test.prototype.parses = function (source, expected, options) {
    return this.deepEqual(luaparse.parse(source, options), expected, escapeString(source));
  };

  Spec.Test.prototype.equalPrecedence = function (source, expected, options) {
    function normalise(node) {
      if (!node || typeof node !== 'object')
        return node;
      node.inParens = null;
      for (var key in node) if (node.hasOwnProperty(key)) {
        normalise(node[key]);
      }
      return node;
    }

    return this.deepEqual(
      normalise(luaparse.parse('a = ' + source, options)),
      normalise(luaparse.parse('a = ' + expected, options)),
      source + ' is equal to ' + expected
    );
  };

  // Create a test, and delegate to appropiate test function.
  function addTest(testName, tests) {
    suite.addTest(testName, function() {
      var count = 0;
      for (var source in tests) if (tests.hasOwnProperty(source)) {
        var expected = tests[source];
        if (typeof expected === 'string') this.parseError(source, expected, options);
        else if (typeof expected.result === 'object')
          this.deepEqual(luaparse.parse(source, expected.options || options), expected.result, expected.name || escapeString(source));
        else if (typeof expected.result === 'string') this.parseError(source, expected.result, expected.options || options);
        else this.parses(source, expected, options);

        count++;
      }
      this.done(count);
    });
  }

  // Reporters ----------------------------------------------------------------

  // Beautify console output Mocha-style.
  var consoleReporter = (function() {
    var failures = []
      , colors = {
          'red': 31
        , 'green': 32
        , 'gray': 90
        , 'white': 0
      }
      , line = '-------------------------------------------------'
      , colorize = function colorize(color, string) {
        return '\u001b[' + colors[color] + 'm' + string + '\u001b[0m';
      };

    return function consoleReporter(event) {
      switch (event.type) {
        case 'assertion':
          output('    ' + colorize('green', '✓ ') + colorize('gray', event.message));
          break;
        case 'failure':
          output('    ' + colorize('red', '✖ ' + event.message));
          failures.push(event);
          break;
        case 'start':
          output(this.name);
          break;
        case 'setup':
          output('\n  ' + colorize('white', event.target.name));
          break;
        case 'complete':
          var assertionCount = event.target.assertions
            , failureCount = event.target.failures
            , totalCount = assertionCount + failureCount;

          for (var i = 0, l = failures.length; i < l; i++) {
            var failure = failures[i]
              , expected = Newton.stringify(failure.expected)
              , actual = Newton.stringify(failure.actual);
            output(Newton.substitute('\n%s\n  Expected: %s\n  Actual:   %s', colorize('red', failure.message + ' ' + line), colorize('gray', expected), colorize('gray', actual)));
          }
          output('\n' + assertionCount + '/' + totalCount + ' assertions');
          break;
      }
    };
  }());

  var testemReporter = (function() {
    var id = 0
      , testResults = [];

    return function(event) {
      var test, isSuccess;
      switch (event.type) {
        case 'assertion':
        case 'failure':
          isSuccess = (event.type === 'assertion');
          test = {
              passed: isSuccess ? 1 : 0
            , failed: isSuccess ? 0 : 1
            , total: 1
            , id: id++
            , name: event.message
            , items: []
          };
          if (!isSuccess) {
            test.items.push({
                passed: false
              , message: Newton.substitute('Expected %o to match %o', event.expected, event.actual)
            });
          }
          testResults.push(test);
          root.Testem.emit('test-result', test);
          break;
        case 'complete':
          root.Testem.emit('all-test-results', {
              failed: this.failures
            , total: this.assertions
            , tests: []
          });
          break;
        case 'start':
          root.Testem.emit('tests-start');
          break;
      }
    };
  }());

  // Use the appropiate reporter depending on enviroment.
  var reporter = isBrowser ? Newton.createReport('suite') :
    isConsole ? consoleReporter :
    Newton.createTAP(output);

  if (isTestem) suite.on('all', testemReporter);

  suite.on('all', reporter);

  // Additional tests ---------------------------------------------------------

  suite.addTest('API', function() {
    this.equal(typeof luaparse, 'object', 'luaparse is an object');
    this.equal(typeof luaparse.parse, 'function', 'luaparse.parse() is a function');
    this.equal(typeof luaparse.write, 'function', 'luaparse.write() is a function');
    this.equal(typeof luaparse.end, 'function', 'luaparse.end() is a function');
    var parse = luaparse.parse({ wait: true });
    this.deepEqual(parse.end('break'), {
      "type": "Chunk",
      "body": [
        {
          "type": "BreakStatement"
        }
      ],
      "comments": []
    }, 'should support waiting on input');

    var nodes = []
      , createdScopes = 0
      , destroyedScopes = 0
      , localDeclarations = [];

    parse = luaparse.parse('do local a = 1 b = 1 end -- comment', {
        scope: true
      , locations: true
      , ranges: true
      , onCreateNode: function(node) { nodes.push(node); }
      , onCreateScope: function() { createdScopes++; }
      , onDestroyScope: function() { destroyedScopes++; }
      , onLocalDeclaration: function(ident) { localDeclarations.push(ident); }
    });
    this.equal(createdScopes, 2, 'should invoke onCreateScope callback');
    this.equal(createdScopes, destroyedScopes, 'should invoke onDestroyScope callback');
    this.deepEqual(localDeclarations, ['a'], 'should invoke onLocalDeclaration callback');
    this.equal(nodes.length, 9, 'should invoke onCreateNode callback');
    this.deepEqual(
        nodes[0]
      , {"type": "Identifier", "name": "a", "loc": {"start": {"line": 1, "column": 9}, "end": {"line": 1, "column": 10}}, "range": [9, 10], "isLocal": true}
      , 'should invoke onCreateNode callback with syntax node parameter'
    );

    this.deepEqual(luaparse.parse('#!/usr/bin/lua\nbreak', { locations: true, ranges: true }), {
      "type": "Chunk", "body": [{"type": "BreakStatement", "loc": {"start": {"line": 2, "column": 0}, "end": {"line": 2, "column": 5}}, "range": [15, 20]}], "loc": {"start": {"line": 2, "column": 0}, "end": {"line": 2, "column": 5}}, "range": [15, 20], "comments": []
    }, 'should ignore shebangs');

    this.done(11);
  });

  suite.addTest('Precedence', function() {
    this.equalPrecedence('2^3^2', '2^(3^2)');
    this.equalPrecedence('2^3*4', '(2^3)*4');
    this.equalPrecedence('2^2^3', '2^(2^3)');
    this.equalPrecedence('2^2^3^4', '2^(2^(3^4))');
    this.equalPrecedence('2^2^3^4+1', '2^(2^(3^4))+1');
    this.equalPrecedence('1*2/3', '(1*2)/3');
    this.equalPrecedence('1 + 1 * 2 > 3', '( 1 + ( 1 * 2 ) ) > 3');
    this.equalPrecedence('1 < 2 and 2 < 1', '(1 < 2) and (2 < 1)');
    this.equalPrecedence('1 / 2 + 4 * 2 > 8', '((1 / 2) + (4 * 2)) > 8');
    this.equalPrecedence('2 < 1 == true', '(2 < 1) == true');
    this.equalPrecedence('2 < 1 + 1 == true', '(2 < (1 + 1)) == true');
    this.equalPrecedence('not 1 + 1', '(not 1) + 1');
    this.equalPrecedence('not not 1 + 1', '(not (not (1)) + 1)');
    this.equalPrecedence('1 + #1', '1 + (#1)');
    this.equalPrecedence('-x^2', '-(x^2)');
    this.equalPrecedence('3~2&1', '3~(2&1)', { "luaVersion": "5.3" });
    this.equalPrecedence('3~2|1', '(3~2)|1', { "luaVersion": "5.3" });
    this.equalPrecedence('1<<2 ..3', '1<<(2 ..3)', { "luaVersion": "5.3" });
    this.done(18);
  });

  suite.addTest('EOL sequences', function() {
    var options = { locations: true }
      , baseline = luaparse.parse('foo = 1\nbar = 1', options);

    this.deepEqual(baseline, luaparse.parse('foo = 1\rbar = 1', options), 'carriage return');
    this.deepEqual(baseline, luaparse.parse('foo = 1\n\rbar = 1', options), 'newline followed by carriage return');
    this.deepEqual(baseline, luaparse.parse('foo = 1\r\nbar = 1', options), 'carriage return followed by newline');
    this.done(3);
  });

  if (isLoader) {
    define(specs, function () {
      Spec.forEach(arguments, function(test) {
        addTest(test.name, test.spec);
      });
      suite.shuffle();
      return suite;
    });
  } else if (isBrowser || (!isModule || (typeof module === 'object' && module === require.main))) {
    var run = root.run = function() {
      // Add all tests. In a browser the tests are expected to be loaded
      // therefore this function is exposed as a wrapper around the test suites
      // `run()` so that it can run on load.
      Spec.forEach(specs, function(spec) {
        var name = spec.replace(/^[\s\S]*\/([^\/]+)$/, '$1')
          , tests = load(name, spec);

        addTest(tests.name, tests.spec);
      });
      suite.shuffle();
      suite.run();
    };

    if (!isBrowser) run();
  }
}(this));
<|endoftext|>


<commit_before>const Trie = require('../secure.js')
const async = require('async')
const rlp = require('rlp')
const assert = require('assert')
const jsonTests = require('ethereum-tests').trieTests.trietest_secureTrie
const ethUtil = require('ethereumjs-util')

var trie = new Trie()

describe('secure tests', function() {
  it('empty values', function(done) {
    async.eachSeries(jsonTests.emptyValues.in, function(row, cb) {
      trie.put(row[0], row[1], cb)
    }, function(){
      assert('0x' + trie.root.toString('hex') === jsonTests.emptyValues.root)
      done()
    })
  })

  it('branchingTests', function(done) {
    trie = new Trie()
    async.eachSeries(jsonTests.branchingTests.in, function(row, cb) {
      trie.put(row[0], row[1], cb)
    }, function(){
      assert('0x' + trie.root.toString('hex') === jsonTests.branchingTests.root)
      done()
    })
  })

  it('jeff', function(done) {
    async.eachSeries(jsonTests.jeff.in, function(row, cb) {

      var val = row[1]
      if(val)
        val = new Buffer(row[1].slice(2), 'hex')

      trie.put(new Buffer(row[0].slice(2), 'hex'), val, cb)
    }, function(){
      assert('0x' + trie.root.toString('hex') === jsonTests.jeff.root)
      done()
    })
  })
})
<commit_msg>fix tests<commit_after>const Trie = require('../secure.js')
const async = require('async')
const rlp = require('rlp')
const assert = require('assert')
const jsonTests = require('ethereumjs-testing').test.trieTests.trietest_secureTrie
const ethUtil = require('ethereumjs-util')

var trie = new Trie()

describe('secure tests', function() {
  it('empty values', function(done) {
    async.eachSeries(jsonTests.emptyValues.in, function(row, cb) {
      trie.put(row[0], row[1], cb)
    }, function(){
      assert('0x' + trie.root.toString('hex') === jsonTests.emptyValues.root)
      done()
    })
  })

  it('branchingTests', function(done) {
    trie = new Trie()
    async.eachSeries(jsonTests.branchingTests.in, function(row, cb) {
      trie.put(row[0], row[1], cb)
    }, function(){
      assert('0x' + trie.root.toString('hex') === jsonTests.branchingTests.root)
      done()
    })
  })

  it('jeff', function(done) {
    async.eachSeries(jsonTests.jeff.in, function(row, cb) {

      var val = row[1]
      if(val)
        val = new Buffer(row[1].slice(2), 'hex')

      trie.put(new Buffer(row[0].slice(2), 'hex'), val, cb)
    }, function(){
      assert('0x' + trie.root.toString('hex') === jsonTests.jeff.root)
      done()
    })
  })
})
<|endoftext|>