<commit_before>'use strict';

var base = process.cwd();

var DependencyManager = require(base + '/src/core/dependency_manager');

describe('core', function () {
	describe('DependencyManager', function () {
		var manager;

		beforeEach(function () {
			manager = new DependencyManager({
				dependencies: {
					'lodash': '~3.10.1',
					'globby': '^2.1.0'
				},
				devDependencies: {
					"chai": "^3.2.0",
					"chai-as-promised": "^5.1.0",
					"mocha": "^2.3.4",
					"semver": "^5.1.0"
				}
			});
		});

		describe('#register()', function () {
			it('should add newest required version', function () {
			});
			it('should not add entry, if there is existing module in dependencies or devDependencies', function () {
			});
			it('should only touch devDependencies', function () {
			});
		});
		describe('#flush()', function () {
			it('should report dirty if new entry added', function () {
			});
		});
	});
});<commit_msg>test learning semver<commit_after>'use strict';

var Chai = require('chai'),
	expect = Chai.expect;

var semver = require('semver');

var base = process.cwd();
var DependencyManager = require(base + '/src/core/dependency_manager');

describe('core', function () {
	describe.only('semver', function () {
		describe('.clean() & .compare() & .valid()', function () {
			it('do not accept range', function () {
				expect(semver.clean('1.0.9')).to.equal('1.0.9');
				expect(semver.clean('~1.0.9')).to.be.null;
				expect(semver.clean('^1.0.9')).to.be.null;
				expect(semver.clean('>=1.0.9')).to.be.null;
				expect(semver.clean('*')).to.be.null;

				expect(semver.compare('1.0.9', '1.0.9')).to.equal(0);
				expect(function () { semver.compare('~1.0.9', '1.0.9'); }).to.throw;
				expect(function () { semver.compare('1.0.9', '^1.0.9'); }).to.throw;
				expect(function () { semver.compare('~1.0.9', '^1.0.9'); }).to.throw;
				expect(function () { semver.compare('^1.0.9', '1.0.9'); }).to.throw;
				expect(function () { semver.compare('1.0.9', '~1.0.9'); }).to.throw;
				expect(function () { semver.compare('^1.0.9', '~1.0.9'); }).to.throw;

				expect(semver.valid('1.0.9')).to.equal('1.0.9');
				expect(semver.valid('^1.0.9')).to.be.null;
				expect(semver.valid('~1.0.9')).to.be.null;
				expect(semver.valid('*')).to.be.null;
			});
		});
		describe('.validRange()', function () {
			it('accept version & range', function () {
				expect(semver.validRange('1.0.9')).to.equal('1.0.9');
				expect(semver.validRange('^1.0.9')).to.equal('>=1.0.9 <2.0.0');
				expect(semver.validRange('~1.0.9')).to.equal('>=1.0.9 <1.1.0');
			});
			it('just do simple join when multiple ranges provided', function () {
				expect(semver.validRange('~1.0.9 ~1.0.7')).to.equal('>=1.0.9 <1.1.0 >=1.0.7 <1.1.0');
				expect(semver.validRange('~1.0.7 ~1.0.9')).to.equal('>=1.0.7 <1.1.0 >=1.0.9 <1.1.0');
				expect(semver.validRange('^1.0.9 ~1.0.7')).to.equal('>=1.0.9 <2.0.0 >=1.0.7 <1.1.0');
				expect(semver.validRange('^1.0.7 ~1.0.9')).to.equal('>=1.0.7 <2.0.0 >=1.0.9 <1.1.0');
			});
		});
	});

	describe('DependencyManager', function () {
		var manager;

		beforeEach(function () {
			manager = new DependencyManager({
				dependencies: {
					'lodash': '~3.10.1',
					'globby': '^2.1.0'
				},
				devDependencies: {
					"chai": "^3.2.0",
					"chai-as-promised": "^5.1.0",
					"mocha": "^2.3.4",
					"semver": "^5.1.0"
				}
			});
		});

		describe('#register()', function () {
			it('should add newest required version', function () {
			});
			it('should not add entry, if there is existing module in dependencies or devDependencies', function () {
			});
			it('should only touch devDependencies', function () {
			});
		});
		describe('#flush()', function () {
			it('should report dirty if new entry added', function () {
			});
		});
	});
});
<|endoftext|>


<commit_before>/* Copyright (c) 2011 by The Authors.
 * Published under the LGPL 2.1 license.
 * See /license-notice.txt for the full text of the license notice.
 * See /license.txt for the full text of the license.
 */

/**
 * A GraphComponent is the parent class for the objects' that form a graph. Each
 * GraphComponent can carry a Label.
 *
 * @constructor
 */
jsts.geomgraph.GraphComponent = function(label) {
  this.label = label;
};

/**
 * @type {Label}
 * @protected
 */
jsts.geomgraph.GraphComponent.prototype.label = null;

/**
 * isInResult indicates if this component has already been included in the
 * result
 *
 * @type {boolean}
 * @private
 */
jsts.geomgraph.GraphComponent.prototype._isInResult = false;

/**
 * @type {boolean}
 * @private
 */
jsts.geomgraph.GraphComponent.prototype._isCovered = false;

/**
 * @type {boolean}
 * @private
 */
jsts.geomgraph.GraphComponent.prototype._isCoveredSet = false;

/**
 * @type {boolean}
 * @private
 */
jsts.geomgraph.GraphComponent.prototype._isVisited = false;

jsts.geomgraph.GraphComponent.prototype.getLabel = function() {
  return this.label;
};
jsts.geomgraph.GraphComponent.prototype.setLabel = function(label) {
  if (arguments.length === 2) {
    this.setLabel2.apply(this, arguments);
    return;
  }

  this.label = label;
};

/**
 * @param {boolean}
 *          isInResult
 */
jsts.geomgraph.GraphComponent.prototype.setInResult = function(isInResult) {
  this._isInResult = isInResult;
};

/**
 * @return {boolean}
 */
jsts.geomgraph.GraphComponent.prototype.isInResult = function() {
  return this._isInResult;
};

/**
 * @param {boolean}
 *          isCovered
 */
jsts.geomgraph.GraphComponent.prototype.setCovered = function(isCovered) {
  this._isCovered = isCovered;
  this._isCoveredSet = true;
};

/**
 * @return {boolean}
 */
jsts.geomgraph.GraphComponent.prototype.isCovered = function() {
  return this._isCovered;
};

/**
 * @return {boolean}
 */
jsts.geomgraph.GraphComponent.prototype.isCoveredSet = function() {
  return this._isCoveredSet;
};

/**
 * @return {boolean}
 */
jsts.geomgraph.GraphComponent.prototype.isVisited = function() {
  return this._isVisited;
};

/**
 * @param {boolean}
 *          isVisited
 */
jsts.geomgraph.GraphComponent.prototype.setVisited = function(isVisited) {
  this._isVisited = isVisited;
};

/**
 * @return {Coordinate} a coordinate in this component (or null, if there are
 *         none).
 */
jsts.geomgraph.GraphComponent.prototype.getCoordinate = function() {
  throw new jsts.error.AbstractMethodInvocationError();
};

/**
 * compute the contribution to an IM for this component
 *
 * @param {IntersectionMatrix}
 *          im
 * @protected
 */
jsts.geomgraph.GraphComponent.prototype.computeIM = function(im) {
  throw new jsts.error.AbstractMethodInvocationError();
};

/**
 * An isolated component is one that does not intersect or touch any other
 * component. This is the case if the label has valid locations for only a
 * single Geometry.
 *
 * @return true if this component is isolated.
 */
jsts.geomgraph.GraphComponent.prototype.isIsolated = function() {
  throw new jsts.error.AbstractMethodInvocationError();
};

/**
 * Update the IM with the contribution for this component. A component only
 * contributes if it has a labelling for both parent geometries
 *
 * @param {IntersectionMatrix}
 *          im
 */
jsts.geomgraph.GraphComponent.prototype.updateIM = function(im) {
  jsts.util.Assert.isTrue(this.label.getGeometryCount() >= 2, 'found partial label');
  this.computeIM(im);
};
<commit_msg>Refactored GraphComponent.<commit_after>/* Copyright (c) 2011 by The Authors.
 * Published under the LGPL 2.1 license.
 * See /license-notice.txt for the full text of the license notice.
 * See /license.txt for the full text of the license.
 */

(function() {

  /**
   * @requires jsts/util/Assert.js
   */

  var Assert = jsts.util.Assert;

  /**
   * A GraphComponent is the parent class for the objects' that form a graph.
   * Each GraphComponent can carry a Label.
   *
   * @constructor
   */
  var GraphComponent = function(label) {
    this.label = label;
  };

  /**
   * @type {Label}
   * @protected
   */
  GraphComponent.prototype.label = null;

  /**
   * isInResult indicates if this component has already been included in the
   * result
   *
   * @type {boolean}
   * @private
   */
  GraphComponent.prototype._isInResult = false;

  /**
   * @type {boolean}
   * @private
   */
  GraphComponent.prototype._isCovered = false;

  /**
   * @type {boolean}
   * @private
   */
  GraphComponent.prototype._isCoveredSet = false;

  /**
   * @type {boolean}
   * @private
   */
  GraphComponent.prototype._isVisited = false;

  GraphComponent.prototype.getLabel = function() {
    return this.label;
  };
  GraphComponent.prototype.setLabel = function(label) {
    if (arguments.length === 2) {
      this.setLabel2.apply(this, arguments);
      return;
    }

    this.label = label;
  };

  /**
   * @param {boolean}
   *          isInResult
   */
  GraphComponent.prototype.setInResult = function(isInResult) {
    this._isInResult = isInResult;
  };

  /**
   * @return {boolean}
   */
  GraphComponent.prototype.isInResult = function() {
    return this._isInResult;
  };

  /**
   * @param {boolean}
   *          isCovered
   */
  GraphComponent.prototype.setCovered = function(isCovered) {
    this._isCovered = isCovered;
    this._isCoveredSet = true;
  };

  /**
   * @return {boolean}
   */
  GraphComponent.prototype.isCovered = function() {
    return this._isCovered;
  };

  /**
   * @return {boolean}
   */
  GraphComponent.prototype.isCoveredSet = function() {
    return this._isCoveredSet;
  };

  /**
   * @return {boolean}
   */
  GraphComponent.prototype.isVisited = function() {
    return this._isVisited;
  };

  /**
   * @param {boolean}
   *          isVisited
   */
  GraphComponent.prototype.setVisited = function(isVisited) {
    this._isVisited = isVisited;
  };

  /**
   * @return {Coordinate} a coordinate in this component (or null, if there are
   *         none).
   */
  GraphComponent.prototype.getCoordinate = function() {
    throw new jsts.error.AbstractMethodInvocationError();
  };

  /**
   * compute the contribution to an IM for this component
   *
   * @param {IntersectionMatrix}
   *          im
   * @protected
   */
  GraphComponent.prototype.computeIM = function(im) {
    throw new jsts.error.AbstractMethodInvocationError();
  };

  /**
   * An isolated component is one that does not intersect or touch any other
   * component. This is the case if the label has valid locations for only a
   * single Geometry.
   *
   * @return true if this component is isolated.
   */
  GraphComponent.prototype.isIsolated = function() {
    throw new jsts.error.AbstractMethodInvocationError();
  };

  /**
   * Update the IM with the contribution for this component. A component only
   * contributes if it has a labelling for both parent geometries
   *
   * @param {IntersectionMatrix}
   *          im
   */
  GraphComponent.prototype.updateIM = function(im) {
    Assert.isTrue(this.label.getGeometryCount() >= 2, 'found partial label');
    this.computeIM(im);
  };

  jsts.geomgraph.GraphComponent = GraphComponent;

})();
<|endoftext|>


<commit_before>var test = require('tape'),
    parse = require('../src/parser').parse,
    evaluate = require('../src/evaluate'),
    Environment = require('../src/environment'),
    Closure = require('../src/closure');

// This part is all about defining and using functions.
// We'll start by implementing the `lambda` form which is used to create
// function closures.

test('lambda evaluates to lambda', function(t) {
    // The lambda form should evaluate to a Closure
    t.plan(1);

    var ast = ['lambda', [], 42];

    t.ok(evaluate(ast) instanceof Closure);
});

test('lambda closure keeps defining env', function(t) {
    // The closure should keep a copy of the environment where it was defined.
    // Once we start calling functions later, we'll need access to the
    // environment from when the function was created in order to resolve all
    // free variables.
    t.plan(1);

    var env = new Environment({ foo: 1, bar: 2 });
    var ast = ['lambda', [], 42];

    t.equals(evaluate(ast, env).env, env);
});

test('lambda closure holds function', function(t) {
    // The closure contains the parameter list and function body too.
    t.plan(2);

    var closure = evaluate(parse('(lambda (x y) (+ x y))'));

    t.looseEquals(closure.params, [new String('x'), new String('y')]);
    t.looseEquals(closure.body, [new String('+'), new String('x'),
                                 new String('y')]);
});

test('lambda arguments are list', function(t) {
    // The parameters of a `lambda` should be a list.
    t.plan(1);

    var closure = evaluate(parse('(lambda (x y) (+ x y))'));

    t.ok(Array.isArray(closure.params));
});

test('lambda number of arguments', function(t) {
    // The `lambda` form should expect exactly two arguments.
    t.plan(1);

    t.throws(function() {
        evaluate(parse('(lambda (foo) (bar) (baz))'));
    }, /Malformed foo, too many arguments/);
});

test('lambda variable nubmber of arguments', function(t) {
    t.plan(1);

    var closure = evaluate(parse('(lambda args (length args))'));

    t.ok(closure.params instanceof String);
});

test('lambda fails on invalid argument definition', function(t) {
    t.plan(1);

    t.throws(function() {
        evaluate(parse('(lambda 55 (body of fn))'));
    }, /Closure argument must be a list or symbol/);
});

test('defining lambda with error in body', function(t) {
    // The function body should not be evaluated when the lambda is defined.
    // The call to `lambda` should return a function closure holding, among
    // other things the function body. The body should not be evaluated before
    // the function is called.
    t.plan(1);

    var ast = parse('(lambda (x y) (function body ((that would never) work)))');

    t.ok(evaluate(ast) instanceof Closure);
});

// Now that we have the `lambda` form implemented, let's see if we can call
// some functions.
// When evaluating ASTs which are lists, if the first element isn't one of the
// special forms we have been working with so far, it is a function call.
// The first element of the list is the function, and the rest of the elements
// are arguments.

test('evaluating call to closure', function(t) {
    // The first case we'll handle is when the AST is a list with an actual
    // closure as the first element.
    // In this first test, we'll start with a closure with no arguments and no
    // free variables. All we need to do is to evaluate and return the function
    // body.
    t.plan(1);

    var closure = evaluate(parse('(lambda () (+ 1 2))'));

    t.equals(evaluate([closure]), 3);
});

test('evaluating call to closure with arguments', function(t) {
    // The function body must be evaluated in an environment where the
    // parameters are bound.
    // Create an environment where the function parameters (which are stored
    // in the closure) are bound to the actual argument values in the function
    // call. Use this environment when evaluating the function body.
    t.plan(1);

    var env = new Environment({});
    var closure = evaluate(parse('(lambda (a b) (+ a b))'), env);

    t.looseEquals(evaluate([closure, 4, 5], env), 9);
});

test('evaluating call to closure with variable list of arguments', function(t) {
    t.plan(1);

    var env = new Environment();
    var closure = evaluate(parse('(lambda args (+ (head args) (head (tail args))))'), env);

    t.equals(evaluate([closure, 4, 5], env), 9);
});

test('call to function should evaluate arguments', function(t) {
    // Call to function should evaluate all arguments.
    // When a function is applied, the arguments should be evaluated before
    // being bound to the parameter names.
    t.plan(1);

    var env = new Environment();
    var closure = evaluate(parse('(lambda (a) (+ a 5))'), env);
    var ast = [closure, parse('(if #f 0 (+ 10 10))')];

    t.equals(evaluate(ast, env), 25);
});

test('evaluating call to closure with free variables', function(t) {
    // The body should be evaluated in the environment from the closure.
    // The function's free variables, i.e. those not specified as part of the
    // parameter list, should be looked up in the environment from where the
    // function was defined. This is the environment included in the closure.
    // Make sure this environment is used when evaluating the body.
    t.plan(1);

    var closure = evaluate(parse('(lambda (x) (+ x y))'),
                           new Environment({ y: 1 }));

    var ast = [closure, 0];

    t.equals(evaluate(ast, new Environment({ y: 2 })), 1);
});

// Okay, now we're able to evaluate ASTs with closures as the first element.
// But normally the closures don't just happen to be there all by themselves.
// Generally we'll find some expression, evaluate it to a closure, and then
// evaluate a new AST with the closure just like we did above.
// (some-exp arg1 arg2 ...) -> (closure arg1 arg2 ...) -> result-of-function-call

test('calling very simple function in environment', function(t) {
    // A call to a symbol corresponds to a call to its value in the environment.
    // When a symbol is the first element of the AST list, it is resolved to its
    // value in the environment (which should be a function closure). An AST
    // with the variables replaced with its value should then be
    // evaluated instead.
    t.plan(2);

    var env = new Environment();

    evaluate(parse('(define add (lambda (x y) (+ x y)))'), env);

    t.ok(env.lookup('add') instanceof Closure);

    t.equals(evaluate(parse('(add 1 2)'), env), 3);
});

test('calling lambda directly', function(t) {
    // It should be possible to define and call functions directly.
    // A lambda definition in the call position of an AST should be evaluated,
    // and then evaluated as before.
    t.plan(1);

    t.equals(evaluate(parse('((lambda (x) x) 42)'), new Environment()), 42);
});

test('calling complex expression which evaluates to function', function(t) {
    // Actually, all ASTs that are not atoms should be evaluated and then
    // called. In this test, a call is done to the if-expression. The `if`
    // should be evaluated, which will result in a `lambda` expression.
    // The lambda is evaluated, giving a closure. The result is an AST with a
    // `closure` as the first element, which we already know how to evaluate.
    t.plan(1);

    var ast = parse('((if #f\
                    wont-evaluate-this-branch\
                    (lambda (x) (+ x y)))\
                    2)');

    t.equals(evaluate(ast, new Environment({ y: 3 })), 5);
});

// Now that we have the happy cases working, let's see what should happen when
// function calls are done incorrectly.

test('calling atom raises exception', function(t) {
    // A function call to a non-function should result in an error
    t.plan(2);

    t.throws(function() {
        evaluate(parse("(#t 'foo 'bar)"), new Environment());
    }, /not a function/);

    t.throws(function() {
        evaluate(parse('(42)'), new Environment());
    }, /not a function/);
});

test('test make sure arguments to functions are evaluated', function(t) {
    // The arguments passed to functions should be evaluated
    // We should accept parameters that are produced through function
    // calls.
    t.plan(1);

    t.equals(evaluate(parse('((lambda (x) x) (+ 1 2))'), new Environment()), 3);
});

test('calling with wrong number of arguments', function(t) {
    // Functions should raise exceptions when called with wrong number of arguments.
    t.plan(1);

    var env = new Environment();

    evaluate(parse("(define fn (lambda (p1 p2) 'whatever))"), env);

    t.throws(function() {
        evaluate(parse('(fn 1 2 3)'), env);
    }, /Wrong number of arguments, expected 2 got 3/);
});

// One final test to see that recursive functions are working as expected.
// The good news: this should already be working by now :)

test('calling function recursively', function(t) {
    // Tests that a named function is included in the environment
    // where it is evaluated.
    t.plan(2);

    var env = new Environment();

    evaluate(parse("(define my-fn\n\
                   ;; A meaningless, but recursive, function\n\
                   (lambda (x)\n\
                   (if (eq x 0)\n\
                   42\n\
                   (my-fn (- x 1)))))"), env);

    t.equals(evaluate(parse('(my-fn 0)'), env), 42);
    t.equals(evaluate(parse('(my-fn 10)'), env), 42);
});
<commit_msg>No need to use looseEquals here.<commit_after>var test = require('tape'),
    parse = require('../src/parser').parse,
    evaluate = require('../src/evaluate'),
    Environment = require('../src/environment'),
    Closure = require('../src/closure');

// This part is all about defining and using functions.
// We'll start by implementing the `lambda` form which is used to create
// function closures.

test('lambda evaluates to lambda', function(t) {
    // The lambda form should evaluate to a Closure
    t.plan(1);

    var ast = ['lambda', [], 42];

    t.ok(evaluate(ast) instanceof Closure);
});

test('lambda closure keeps defining env', function(t) {
    // The closure should keep a copy of the environment where it was defined.
    // Once we start calling functions later, we'll need access to the
    // environment from when the function was created in order to resolve all
    // free variables.
    t.plan(1);

    var env = new Environment({ foo: 1, bar: 2 });
    var ast = ['lambda', [], 42];

    t.equals(evaluate(ast, env).env, env);
});

test('lambda closure holds function', function(t) {
    // The closure contains the parameter list and function body too.
    t.plan(2);

    var closure = evaluate(parse('(lambda (x y) (+ x y))'));

    t.looseEquals(closure.params, [new String('x'), new String('y')]);
    t.looseEquals(closure.body, [new String('+'), new String('x'),
                                 new String('y')]);
});

test('lambda arguments are list', function(t) {
    // The parameters of a `lambda` should be a list.
    t.plan(1);

    var closure = evaluate(parse('(lambda (x y) (+ x y))'));

    t.ok(Array.isArray(closure.params));
});

test('lambda number of arguments', function(t) {
    // The `lambda` form should expect exactly two arguments.
    t.plan(1);

    t.throws(function() {
        evaluate(parse('(lambda (foo) (bar) (baz))'));
    }, /Malformed foo, too many arguments/);
});

test('lambda variable nubmber of arguments', function(t) {
    t.plan(1);

    var closure = evaluate(parse('(lambda args (length args))'));

    t.ok(closure.params instanceof String);
});

test('lambda fails on invalid argument definition', function(t) {
    t.plan(1);

    t.throws(function() {
        evaluate(parse('(lambda 55 (body of fn))'));
    }, /Closure argument must be a list or symbol/);
});

test('defining lambda with error in body', function(t) {
    // The function body should not be evaluated when the lambda is defined.
    // The call to `lambda` should return a function closure holding, among
    // other things the function body. The body should not be evaluated before
    // the function is called.
    t.plan(1);

    var ast = parse('(lambda (x y) (function body ((that would never) work)))');

    t.ok(evaluate(ast) instanceof Closure);
});

// Now that we have the `lambda` form implemented, let's see if we can call
// some functions.
// When evaluating ASTs which are lists, if the first element isn't one of the
// special forms we have been working with so far, it is a function call.
// The first element of the list is the function, and the rest of the elements
// are arguments.

test('evaluating call to closure', function(t) {
    // The first case we'll handle is when the AST is a list with an actual
    // closure as the first element.
    // In this first test, we'll start with a closure with no arguments and no
    // free variables. All we need to do is to evaluate and return the function
    // body.
    t.plan(1);

    var closure = evaluate(parse('(lambda () (+ 1 2))'));

    t.equals(evaluate([closure]), 3);
});

test('evaluating call to closure with arguments', function(t) {
    // The function body must be evaluated in an environment where the
    // parameters are bound.
    // Create an environment where the function parameters (which are stored
    // in the closure) are bound to the actual argument values in the function
    // call. Use this environment when evaluating the function body.
    t.plan(1);

    var env = new Environment({});
    var closure = evaluate(parse('(lambda (a b) (+ a b))'), env);

    t.equals(evaluate([closure, 4, 5], env), 9);
});

test('evaluating call to closure with variable list of arguments', function(t) {
    t.plan(1);

    var env = new Environment();
    var closure = evaluate(parse('(lambda args (+ (head args) (head (tail args))))'), env);

    t.equals(evaluate([closure, 4, 5], env), 9);
});

test('call to function should evaluate arguments', function(t) {
    // Call to function should evaluate all arguments.
    // When a function is applied, the arguments should be evaluated before
    // being bound to the parameter names.
    t.plan(1);

    var env = new Environment();
    var closure = evaluate(parse('(lambda (a) (+ a 5))'), env);
    var ast = [closure, parse('(if #f 0 (+ 10 10))')];

    t.equals(evaluate(ast, env), 25);
});

test('evaluating call to closure with free variables', function(t) {
    // The body should be evaluated in the environment from the closure.
    // The function's free variables, i.e. those not specified as part of the
    // parameter list, should be looked up in the environment from where the
    // function was defined. This is the environment included in the closure.
    // Make sure this environment is used when evaluating the body.
    t.plan(1);

    var closure = evaluate(parse('(lambda (x) (+ x y))'),
                           new Environment({ y: 1 }));

    var ast = [closure, 0];

    t.equals(evaluate(ast, new Environment({ y: 2 })), 1);
});

// Okay, now we're able to evaluate ASTs with closures as the first element.
// But normally the closures don't just happen to be there all by themselves.
// Generally we'll find some expression, evaluate it to a closure, and then
// evaluate a new AST with the closure just like we did above.
// (some-exp arg1 arg2 ...) -> (closure arg1 arg2 ...) -> result-of-function-call

test('calling very simple function in environment', function(t) {
    // A call to a symbol corresponds to a call to its value in the environment.
    // When a symbol is the first element of the AST list, it is resolved to its
    // value in the environment (which should be a function closure). An AST
    // with the variables replaced with its value should then be
    // evaluated instead.
    t.plan(2);

    var env = new Environment();

    evaluate(parse('(define add (lambda (x y) (+ x y)))'), env);

    t.ok(env.lookup('add') instanceof Closure);

    t.equals(evaluate(parse('(add 1 2)'), env), 3);
});

test('calling lambda directly', function(t) {
    // It should be possible to define and call functions directly.
    // A lambda definition in the call position of an AST should be evaluated,
    // and then evaluated as before.
    t.plan(1);

    t.equals(evaluate(parse('((lambda (x) x) 42)'), new Environment()), 42);
});

test('calling complex expression which evaluates to function', function(t) {
    // Actually, all ASTs that are not atoms should be evaluated and then
    // called. In this test, a call is done to the if-expression. The `if`
    // should be evaluated, which will result in a `lambda` expression.
    // The lambda is evaluated, giving a closure. The result is an AST with a
    // `closure` as the first element, which we already know how to evaluate.
    t.plan(1);

    var ast = parse('((if #f\
                    wont-evaluate-this-branch\
                    (lambda (x) (+ x y)))\
                    2)');

    t.equals(evaluate(ast, new Environment({ y: 3 })), 5);
});

// Now that we have the happy cases working, let's see what should happen when
// function calls are done incorrectly.

test('calling atom raises exception', function(t) {
    // A function call to a non-function should result in an error
    t.plan(2);

    t.throws(function() {
        evaluate(parse("(#t 'foo 'bar)"), new Environment());
    }, /not a function/);

    t.throws(function() {
        evaluate(parse('(42)'), new Environment());
    }, /not a function/);
});

test('test make sure arguments to functions are evaluated', function(t) {
    // The arguments passed to functions should be evaluated
    // We should accept parameters that are produced through function
    // calls.
    t.plan(1);

    t.equals(evaluate(parse('((lambda (x) x) (+ 1 2))'), new Environment()), 3);
});

test('calling with wrong number of arguments', function(t) {
    // Functions should raise exceptions when called with wrong number of arguments.
    t.plan(1);

    var env = new Environment();

    evaluate(parse("(define fn (lambda (p1 p2) 'whatever))"), env);

    t.throws(function() {
        evaluate(parse('(fn 1 2 3)'), env);
    }, /Wrong number of arguments, expected 2 got 3/);
});

// One final test to see that recursive functions are working as expected.
// The good news: this should already be working by now :)

test('calling function recursively', function(t) {
    // Tests that a named function is included in the environment
    // where it is evaluated.
    t.plan(2);

    var env = new Environment();

    evaluate(parse("(define my-fn\n\
                   ;; A meaningless, but recursive, function\n\
                   (lambda (x)\n\
                   (if (eq x 0)\n\
                   42\n\
                   (my-fn (- x 1)))))"), env);

    t.equals(evaluate(parse('(my-fn 0)'), env), 42);
    t.equals(evaluate(parse('(my-fn 10)'), env), 42);
});
<|endoftext|>


<commit_before>/*
    BRouter web - web client for BRouter bike routing engine

    Licensed under the MIT license.
*/

(function() {

    var map,
        layersControl;

    function initMap() {
        var osmAttribution = '© OpenStreetMap contributors';

        var osm = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            maxZoom: 19,
            attribution: 'tiles ' + osmAttribution
        });

        var osmde = L.tileLayer('http://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png', {
            maxZoom: 19,
            attribution: 'tiles by openstreetmap.de ' + osmAttribution
        });

        var topo = L.tileLayer('http://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
            minZoom: 5,
            maxZoom: 15,
            attribution: 'tiles © OpenTopoMap, CC-BY-SA'
                + ', SRTM'
        });

        var thunderforestAttribution = 'tiles © Thunderforest '
            + '(CC-BY-SA 2.0)';
        var cycle = L.tileLayer('http://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png', {
            maxZoom: 18,
            attribution: thunderforestAttribution
        });
        var outdoors = L.tileLayer('http://{s}.tile.thunderforest.com/outdoors/{z}/{x}/{y}.png', {
            maxZoom: 18,
            attribution: thunderforestAttribution
        });

        var cycling = L.tileLayer('http://tile.waymarkedtrails.org/cycling/{z}/{x}/{y}.png', {
          maxZoom: 19,
          opacity: 0.7,
          attribution: 'Cycling © Waymarked Trails '
                  + '(CC-BY-SA 3.0 DE)'
        });
        var hiking = L.tileLayer('http://tile.waymarkedtrails.org/hiking/{z}/{x}/{y}.png', {
          maxZoom: 19,
          opacity: 0.7,
          attribution: 'Hiking © Waymarked Trails '
                  + '(CC-BY-SA 3.0 DE)'
        });

        // COPYING: Please get your own Bing maps key at http://www.microsoft.com/maps/default.aspx
        var bing = new BR.BingLayer();
        BR.Util.get(BR.conf.bingKeyUrl, function (err, key) {
            if (err) {
                layersControl.removeLayer(bing);
                return;
            }

            bing._key = key;
            bing.loadMetadata();
        });

        map = new L.Map('map', {
            layers: [osm],
            center: new L.LatLng(50.99, 9.86),
            zoom: 6,
            worldCopyJump: true
        });
        map.attributionControl.addAttribution(
                'BRouter © Arndt Brenschede, '
                + 'routing + map data © OpenStreetMap contributors '
                + '(ODbL)');

        layersControl = L.control.layers({
            'OpenStreetMap': osm,
            'OpenStreetMap.de': osmde,
            'OpenTopoMap': topo,
            'OpenCycleMap (Thunderf.)': cycle,
            'Outdoors (Thunderforest)': outdoors,
            'Bing Aerial': bing
        }, {
             'Cycling (Waymarked Trails)': cycling,
             'Hiking (Waymarked Trails)': hiking
        }).addTo(map);

        map.addControl(new BR.Search());

        // expose map instance for console debugging
        BR.debug = BR.debug || {};
        BR.debug.map = map;
    }

    function initApp() {
        var router,
            routing,
            routesLayer,
            routingOptions,
            nogos,
            stats,
            elevation,
            download,
            profile,
            trackMessages,
            leftPaneId = 'leftpane',
            saveWarningShown = false;

        // left sidebar as additional control position
        map._controlCorners[leftPaneId] = L.DomUtil.create('div', 'leaflet-' + leftPaneId, map._controlContainer);

        router = L.bRouter(); //brouterCgi dummyRouter

        function updateRoute(evt) {
            router.setOptions(evt.options);

            // abort pending requests from previous rerouteAllSegments
            if (!router.queue.idle()) {
                router.queue.kill();
            }
            routing.rerouteAllSegments(onUpdate);
        }

        function requestUpdate(updatable) {
            var track = routing.toPolyline(),
                segments = routing.getSegments();

            updatable.update(track, segments);
        }

        routingOptions = new BR.RoutingOptions();
        routingOptions.on('update', updateRoute);
        routingOptions.on('update', function(evt) {
            profile.update(evt.options);
        });

        nogos = new BR.NogoAreas();
        nogos.on('update', updateRoute);

        stats = new BR.TrackStats();
        download = new BR.Download();
        elevation = new BR.Elevation();
        profile = new BR.Profile();
        profile.on('update', function(evt) {
            BR.message.hideError();
            var profileId = routingOptions.getCustomProfile();
            router.uploadProfile(profileId, evt.profileText, function(err, profile) {
                if (!err) {
                    routingOptions.setCustomProfile(profile);
                    if (!saveWarningShown) {
                        BR.message.showWarning('Note: Uploaded custom profiles are only cached temporarily on the server.'
                            + '
Please save your edits to your local PC.');
                        saveWarningShown = true;
                    }
                } else {
                    BR.message.showError(err);
                    if (profile) {
                        routingOptions.setCustomProfile(profile, true);
                        router.setOptions(routingOptions.getOptions());
                    }
                }

                if (evt.callback) {
                    evt.callback();
                }
            });
        });
        profile.on('clear', function(evt) {
            BR.message.hideError();
            routingOptions.setCustomProfile(null);
        });
        trackMessages = new BR.TrackMessages({
            requestUpdate: requestUpdate
        });

        routing = new BR.Routing({
            routing: {
                router: L.bind(router.getRouteSegment, router)
            },
            styles: {
                trailer: {
                    dashArray: [10, 10],
                    opacity: 0.4
                },
                track: {},
                nodata: {
                    color: 'darkred'
                }
            }
        });
        routing.on('routing:routeWaypointEnd routing:setWaypointsEnd', function(evt) {
            onUpdate(evt && evt.err);
        });

        function onUpdate(err) {
            if (err) {
                if (err !== L.BRouter.ABORTED_ERROR) {
                    BR.message.showError(err);
                }
                return;
            } else {
                BR.message.hideError();
            }

            var track = routing.toPolyline(),
                segments = routing.getSegments(),
                latLngs = routing.getWaypoints(),
                urls = {};

            elevation.update(track);
            stats.update(track, segments);
            trackMessages.update(track, segments);

            if (latLngs.length > 1) {
                urls.gpx = router.getUrl(latLngs, 'gpx');
                urls.kml = router.getUrl(latLngs, 'kml');
                urls.geojson = router.getUrl(latLngs, 'geojson');
                urls.csv = router.getUrl(latLngs, 'csv');
            }

            download.update(urls);
        };

        map.addControl(new BR.Control({
             heading: '',
             divId: 'header'
        }));
        routingOptions.addTo(map);
        stats.addTo(map);
        download.addTo(map);
        elevation.addTo(map);
        map.addControl(new BR.Tabs({
            tabs: {
                '#tab_profile': profile,
                '#tab_data': trackMessages
            }
        }));

        nogos.addTo(map);
        routing.addTo(map);

        // initial option settings (after controls are added and initialized with onAdd, before permalink)
        router.setOptions(nogos.getOptions());
        router.setOptions(routingOptions.getOptions());
        profile.update(routingOptions.getOptions());

        map.addControl(new L.Control.Permalink({
            text: 'Permalink',
            position: 'bottomright',
            layers: layersControl,
            routingOptions: routingOptions,
            nogos: nogos,
            router: router,
            routing: routing,
            profile: profile
        }));
    }

    initMap();
    initApp();

})();
<commit_msg>avoid update event cycle when setting custom profile<commit_after>/*
    BRouter web - web client for BRouter bike routing engine

    Licensed under the MIT license.
*/

(function() {

    var map,
        layersControl;

    function initMap() {
        var osmAttribution = '© OpenStreetMap contributors';

        var osm = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            maxZoom: 19,
            attribution: 'tiles ' + osmAttribution
        });

        var osmde = L.tileLayer('http://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png', {
            maxZoom: 19,
            attribution: 'tiles by openstreetmap.de ' + osmAttribution
        });

        var topo = L.tileLayer('http://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
            minZoom: 5,
            maxZoom: 15,
            attribution: 'tiles © OpenTopoMap, CC-BY-SA'
                + ', SRTM'
        });

        var thunderforestAttribution = 'tiles © Thunderforest '
            + '(CC-BY-SA 2.0)';
        var cycle = L.tileLayer('http://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png', {
            maxZoom: 18,
            attribution: thunderforestAttribution
        });
        var outdoors = L.tileLayer('http://{s}.tile.thunderforest.com/outdoors/{z}/{x}/{y}.png', {
            maxZoom: 18,
            attribution: thunderforestAttribution
        });

        var cycling = L.tileLayer('http://tile.waymarkedtrails.org/cycling/{z}/{x}/{y}.png', {
          maxZoom: 19,
          opacity: 0.7,
          attribution: 'Cycling © Waymarked Trails '
                  + '(CC-BY-SA 3.0 DE)'
        });
        var hiking = L.tileLayer('http://tile.waymarkedtrails.org/hiking/{z}/{x}/{y}.png', {
          maxZoom: 19,
          opacity: 0.7,
          attribution: 'Hiking © Waymarked Trails '
                  + '(CC-BY-SA 3.0 DE)'
        });

        // COPYING: Please get your own Bing maps key at http://www.microsoft.com/maps/default.aspx
        var bing = new BR.BingLayer();
        BR.Util.get(BR.conf.bingKeyUrl, function (err, key) {
            if (err) {
                layersControl.removeLayer(bing);
                return;
            }

            bing._key = key;
            bing.loadMetadata();
        });

        map = new L.Map('map', {
            layers: [osm],
            center: new L.LatLng(50.99, 9.86),
            zoom: 6,
            worldCopyJump: true
        });
        map.attributionControl.addAttribution(
                'BRouter © Arndt Brenschede, '
                + 'routing + map data © OpenStreetMap contributors '
                + '(ODbL)');

        layersControl = L.control.layers({
            'OpenStreetMap': osm,
            'OpenStreetMap.de': osmde,
            'OpenTopoMap': topo,
            'OpenCycleMap (Thunderf.)': cycle,
            'Outdoors (Thunderforest)': outdoors,
            'Bing Aerial': bing
        }, {
             'Cycling (Waymarked Trails)': cycling,
             'Hiking (Waymarked Trails)': hiking
        }).addTo(map);

        map.addControl(new BR.Search());

        // expose map instance for console debugging
        BR.debug = BR.debug || {};
        BR.debug.map = map;
    }

    function initApp() {
        var router,
            routing,
            routesLayer,
            routingOptions,
            nogos,
            stats,
            elevation,
            download,
            profile,
            trackMessages,
            leftPaneId = 'leftpane',
            saveWarningShown = false;

        // left sidebar as additional control position
        map._controlCorners[leftPaneId] = L.DomUtil.create('div', 'leaflet-' + leftPaneId, map._controlContainer);

        router = L.bRouter(); //brouterCgi dummyRouter

        function updateRoute(evt) {
            router.setOptions(evt.options);

            // abort pending requests from previous rerouteAllSegments
            if (!router.queue.idle()) {
                router.queue.kill();
            }
            routing.rerouteAllSegments(onUpdate);
        }

        function requestUpdate(updatable) {
            var track = routing.toPolyline(),
                segments = routing.getSegments();

            updatable.update(track, segments);
        }

        routingOptions = new BR.RoutingOptions();
        routingOptions.on('update', updateRoute);
        routingOptions.on('update', function(evt) {
            profile.update(evt.options);
        });

        nogos = new BR.NogoAreas();
        nogos.on('update', updateRoute);

        stats = new BR.TrackStats();
        download = new BR.Download();
        elevation = new BR.Elevation();
        profile = new BR.Profile();
        profile.on('update', function(evt) {
            BR.message.hideError();
            var profileId = routingOptions.getCustomProfile();
            router.uploadProfile(profileId, evt.profileText, function(err, profile) {
                if (!err) {
                    routingOptions.setCustomProfile(profile, true);
                    updateRoute({
                        options: routingOptions.getOptions()
                    });
                    if (!saveWarningShown) {
                        BR.message.showWarning('Note: Uploaded custom profiles are only cached temporarily on the server.'
                            + '
Please save your edits to your local PC.');
                        saveWarningShown = true;
                    }
                } else {
                    BR.message.showError(err);
                    if (profile) {
                        routingOptions.setCustomProfile(profile, true);
                        router.setOptions(routingOptions.getOptions());
                    }
                }

                if (evt.callback) {
                    evt.callback();
                }
            });
        });
        profile.on('clear', function(evt) {
            BR.message.hideError();
            routingOptions.setCustomProfile(null);
        });
        trackMessages = new BR.TrackMessages({
            requestUpdate: requestUpdate
        });

        routing = new BR.Routing({
            routing: {
                router: L.bind(router.getRouteSegment, router)
            },
            styles: {
                trailer: {
                    dashArray: [10, 10],
                    opacity: 0.4
                },
                track: {},
                nodata: {
                    color: 'darkred'
                }
            }
        });
        routing.on('routing:routeWaypointEnd routing:setWaypointsEnd', function(evt) {
            onUpdate(evt && evt.err);
        });

        function onUpdate(err) {
            if (err) {
                if (err !== L.BRouter.ABORTED_ERROR) {
                    BR.message.showError(err);
                }
                return;
            } else {
                BR.message.hideError();
            }

            var track = routing.toPolyline(),
                segments = routing.getSegments(),
                latLngs = routing.getWaypoints(),
                urls = {};

            elevation.update(track);
            stats.update(track, segments);
            trackMessages.update(track, segments);

            if (latLngs.length > 1) {
                urls.gpx = router.getUrl(latLngs, 'gpx');
                urls.kml = router.getUrl(latLngs, 'kml');
                urls.geojson = router.getUrl(latLngs, 'geojson');
                urls.csv = router.getUrl(latLngs, 'csv');
            }

            download.update(urls);
        };

        map.addControl(new BR.Control({
             heading: '',
             divId: 'header'
        }));
        routingOptions.addTo(map);
        stats.addTo(map);
        download.addTo(map);
        elevation.addTo(map);
        map.addControl(new BR.Tabs({
            tabs: {
                '#tab_profile': profile,
                '#tab_data': trackMessages
            }
        }));

        nogos.addTo(map);
        routing.addTo(map);

        // initial option settings (after controls are added and initialized with onAdd, before permalink)
        router.setOptions(nogos.getOptions());
        router.setOptions(routingOptions.getOptions());
        profile.update(routingOptions.getOptions());

        map.addControl(new L.Control.Permalink({
            text: 'Permalink',
            position: 'bottomright',
            layers: layersControl,
            routingOptions: routingOptions,
            nogos: nogos,
            router: router,
            routing: routing,
            profile: profile
        }));
    }

    initMap();
    initApp();

})();
<|endoftext|>


<commit_before>/**
 * @fileoverview OAuth client.
 *
 */

goog.provide('ydn.client.OAuthClient');
goog.provide('ydn.client.OAuthProvider');
goog.require('goog.async.Deferred');
goog.require('ydn.client.Client');
goog.require('ydn.client.SimpleHttpRequest');

/**
 * @interface
 */
ydn.client.OAuthProvider = function() {};

/**
 * @return {goog.async.Deferred}
 */
ydn.client.OAuthProvider.prototype.getOAuthToken = goog.abstractMethod;

/**
 * OAuth client.
 * @param {ydn.client.OAuthProvider} provider
 * @param {goog.net.XhrManager} xm xhr manager.
 * @constructor
 * @implements {ydn.client.Client}
 * @const
 */
ydn.client.OAuthClient = function(provider, xm) {
  /**
   * @protected
   * @type {ydn.client.OAuthProvider}
   */
  this.provider = provider;
  /**
   * @protected
   * @type {goog.net.XhrManager}
   */
  this.xm = xm;
  /**
   * @protected
   * @type {YdnApiToken}
   */
  this.token = null;
};

/**
 * @inheritDoc
 */
ydn.client.OAuthClient.prototype.request = function(req) {
  return new ydn.client.OAuthClient.Request(req, this);
};

/**
 * Request data.
 * @param {ydn.client.HttpRequestData} args
 * @param {ydn.client.OAuthClient} parent xhr manager.
 * @constructor
 * @extends {ydn.client.SimpleHttpRequest}
 */
ydn.client.OAuthClient.Request = function(args, parent) {
  goog.base(this, args, parent.xm);
  /**
   * @final
   * @type {ydn.client.OAuthClient}
   */
  this.parent = parent;
  this.no_retry_ = false;
};
goog.inherits(ydn.client.OAuthClient.Request, ydn.client.SimpleHttpRequest);

/**
 * @const
 * @type {boolean}
 */
ydn.client.OAuthClient.USE_AUTHORIZATION_HEADER = false;

/**
 * Execute the request.
 * @param {function(this: T, Object, ydn.client.HttpRespondData)?} cb
 * @param {T=} opt_scope scope.
 * @template T
 */
ydn.client.OAuthClient.Request.prototype.execute = function(cb, opt_scope) {
  var token = this.parent.token;
  if (!token || token.expires > goog.now()) {
    if (this.no_retry_) {
      if (cb) {
        cb.call(opt_scope, null, new ydn.client.HttpRespondData(0));
      }
    } else {
      this.no_retry_ = true;
      this.parent.provider.getOAuthToken().addCallbacks(function(x) {
        this.parent.token = /** @type {YdnApiToken} */ (x);
        this.execute(cb, opt_scope);
      }, function(e) {
        this.parent.token = null;
        if (cb) {
          cb.call(opt_scope, null, new ydn.client.HttpRespondData(0));
        }
      }, this);
    }

  } else {
    if (ydn.client.OAuthClient.USE_AUTHORIZATION_HEADER) {
      this.req_data.headers['Authorization'] = 'Bearer ' + token.access_token;
    } else {
      this.req_data.params['access_token'] = token.access_token;
    }
    goog.base(this, 'execute', cb, opt_scope);
  }

};

<commit_msg>oauth refresher fixed.<commit_after>/**
 * @fileoverview OAuth client.
 *
 */

goog.provide('ydn.client.OAuthClient');
goog.provide('ydn.client.OAuthProvider');
goog.require('goog.async.Deferred');
goog.require('ydn.client.Client');
goog.require('ydn.client.SimpleHttpRequest');

/**
 * @interface
 */
ydn.client.OAuthProvider = function() {};

/**
 * @return {goog.async.Deferred}
 */
ydn.client.OAuthProvider.prototype.getOAuthToken = goog.abstractMethod;

/**
 * OAuth client.
 * @param {ydn.client.OAuthProvider} provider
 * @param {goog.net.XhrManager} xm xhr manager.
 * @constructor
 * @implements {ydn.client.Client}
 * @const
 */
ydn.client.OAuthClient = function(provider, xm) {
  /**
   * @protected
   * @type {ydn.client.OAuthProvider}
   */
  this.provider = provider;
  /**
   * @protected
   * @type {goog.net.XhrManager}
   */
  this.xm = xm;
  /**
   * @protected
   * @type {YdnApiToken}
   */
  this.token = null;
};

/**
 * @inheritDoc
 */
ydn.client.OAuthClient.prototype.request = function(req) {
  return new ydn.client.OAuthClient.Request(req, this);
};

/**
 * Request data.
 * @param {ydn.client.HttpRequestData} args
 * @param {ydn.client.OAuthClient} parent xhr manager.
 * @constructor
 * @extends {ydn.client.SimpleHttpRequest}
 */
ydn.client.OAuthClient.Request = function(args, parent) {
  goog.base(this, args, parent.xm);
  /**
   * @final
   * @type {ydn.client.OAuthClient}
   */
  this.parent = parent;
  this.no_retry_ = false;
};
goog.inherits(ydn.client.OAuthClient.Request, ydn.client.SimpleHttpRequest);

/**
 * @const
 * @type {boolean}
 */
ydn.client.OAuthClient.USE_AUTHORIZATION_HEADER = false;

/**
 * Insert oauth header.
 * @param {function(this: T, boolean, ydn.client.HttpRespondData)} cb
 * @param {T=} opt_scope scope.
 * @template T
 */
ydn.client.OAuthClient.Request.prototype.insertHeader_ = function(cb, opt_scope) {
  var token = this.parent.token;
  // window.console.log(token);
  if (!token || token.expires > goog.now()) {
    if (this.no_retry_) {
      cb.call(opt_scope, false, new ydn.client.HttpRespondData(0, null, null,
          'refreshing token fail'));
    } else {
      this.no_retry_ = true;
      // window.console.log('refreshing token');
      this.parent.provider.getOAuthToken().addCallbacks(function(x) {
        this.parent.token = /** @type {YdnApiToken} */ (x);
        if (ydn.client.OAuthClient.USE_AUTHORIZATION_HEADER) {
          this.req_data.headers['Authorization'] = 'Bearer ' +
              this.parent.token.access_token;
        } else {
          this.req_data.params['access_token'] = this.parent.token.access_token;
        }
        cb.call(opt_scope, true, null);
      }, function(e) {
        this.parent.token = null;
        cb.call(opt_scope, false, new ydn.client.HttpRespondData(0, null, null,
            'refreshing token fail'));
      }, this);
    }

  } else {
    if (ydn.client.OAuthClient.USE_AUTHORIZATION_HEADER) {
      this.req_data.headers['Authorization'] = 'Bearer ' + token.access_token;
    } else {
      this.req_data.params['access_token'] = token.access_token;
    }
    cb.call(opt_scope, true, null);
  }
};

/**
 * Execute the request.
 * @param {function(this: T, Object, ydn.client.HttpRespondData)?} cb
 * @param {T=} opt_scope scope.
 * @template T
 */
ydn.client.OAuthClient.Request.prototype.execute = function(cb, opt_scope) {
  this.insertHeader_(function(ok, raw) {
    if (ok) {
      ydn.client.OAuthClient.Request.superClass_.execute.call(this, cb, opt_scope);
    } else {
      if (cb) {
        cb.call(opt_scope, null, raw);
      }
    }
  }, this);
};

<|endoftext|>


<commit_before>$(document).ready(function() {
  /*
   * LOVELY INITIATIVES
   */

  // These shows what kind of items can be filtered
  var options = {
    valueNames: ['name', 'description', 'category']
  };

  var featureList = new List('lovely-things-list', options);

  // ID of the Google Spreadsheet
  var spreadsheetID = "13-ozrkaBha3CQIwP9J_FuEF3hnQpXYrKzVxNqS0Hzoo";

  // Make sure it is public or set to Anyone with link can view
  var url = "https://spreadsheets.google.com/feeds/list/" + spreadsheetID + "/od6/public/values?alt=json";

  // Append all data unto the screen
  function getData() {
    $.getJSON(url, function(data) {

      var entry = data.feed.entry;

      $(".list").empty();

      for (var i = 0; i < entry.length; i++) {
        var ititle = entry[i].title.$t;
        var icategory = entry[i].gsx$category.$t;
        var idescription = entry[i].gsx$description.$t;
        var iwebsite = entry[i].gsx$website.$t;
        var iimage = entry[i].gsx$image.$t;

        $('.list').append('

' + ititle + ' ' + '- ' + icategory + '

' + idescription + '

');

      };
    });
  }

  // Filters data
  function filterData(filteredword) {
    $.getJSON(url, function(data) {

      var entry = data.feed.entry;

      $(".list").empty();

      for (var i = 0; i < entry.length; i++) {
        var ititle = entry[i].title.$t;
        var icategory = entry[i].gsx$category.$t;
        var idescription = entry[i].gsx$description.$t;
        var iwebsite = entry[i].gsx$website.$t;
        var iimage = entry[i].gsx$image.$t;

        if (filteredword == icategory) {
          $('.list').append('

' + ititle + ' ' + '- ' + icategory + '

' + idescription + '

');
        };
      };
    });
  }

  // Search Query
  function searchedData(searchword) {
    $.getJSON(url, function(data) {

      var entry = data.feed.entry;

      $(".list").empty();

      for (var i = 0; i < entry.length; i++) {
        var ititle = entry[i].title.$t;
        var icategory = entry[i].gsx$category.$t;
        var idescription = entry[i].gsx$description.$t;
        var iwebsite = entry[i].gsx$website.$t;
        var iimage = entry[i].gsx$image.$t;

        if (ititle.indexOf(searchword) >= 0 || idescription.indexOf(searchword) >= 0) {
          $('.list').append('

' + ititle + ' ' + '- ' + icategory + '

' + idescription + '

');
        };
      };
    });
  }

  // Generate the Initial Data
  getData();

  // These are the filter buttons function
  // Search Button
  $("#search_button").click(function() {
    var user_input = $(".searched").val();
    searchedData(user_input);
  });

  // Search Keypress
  $(".searched").keypress(function(event) {
    if(event.which == 13) {
      var user_input = $(".searched").val();
      searchedData(user_input);
    }
  });

  // Subject Specific
  $('#filter-subject-specific').click(function() {
    filterData("Subject Specific");
  });

  // Literacy
  $('#filter-literacy').click(function() {
    filterData("Literacy");
  });

  // Teaching Quality
  $('#filter-teaching-quality').click(function() {
    filterData("Teaching Quality");
  });

  // Career Development
  $('#filter-career-development').click(function() {
    filterData("Career Development");
  });

  // Show all
  $('#filter-none').click(function() {
    getData();
  });
});
<commit_msg>Update index.js<commit_after>$(document).ready(function() {
  /*
   * LOVELY INITIATIVES
   */

  // These shows what kind of items can be filtered
  var options = {
    valueNames: ['name', 'description', 'category']
  };

  var featureList = new List('lovely-things-list', options);

  // ID of the Google Spreadsheet
  var spreadsheetID = "13-ozrkaBha3CQIwP9J_FuEF3hnQpXYrKzVxNqS0Hzoo";

  // Make sure it is public or set to Anyone with link can view
  var url = "https://spreadsheets.google.com/feeds/list/" + spreadsheetID + "/od6/public/values?alt=json";

  // Append all data unto the screen
  function getData() {
    $.getJSON(url, function(data) {

      var entry = data.feed.entry;

      $(".list").empty();

      for (var i = 0; i < entry.length; i++) {
        var ititle = entry[i].title.$t;
        var icategory = entry[i].gsx$category.$t;
        var idescription = entry[i].gsx$description.$t;
        var iwebsite = entry[i].gsx$website.$t;
        var iimage = entry[i].gsx$image.$t;

        $('.list').append('

' + ititle + ' ' + '- ' + icategory + '

' + idescription + '

');

      };
    });
  }

  // Filters data
  function filterData(filteredword) {
    $.getJSON(url, function(data) {

      var entry = data.feed.entry;

      $(".list").empty();

      for (var i = 0; i < entry.length; i++) {
        var ititle = entry[i].title.$t;
        var icategory = entry[i].gsx$category.$t;
        var idescription = entry[i].gsx$description.$t;
        var iwebsite = entry[i].gsx$website.$t;
        var iimage = entry[i].gsx$image.$t;

        if (filteredword == icategory) {
          $('.list').append('

' + ititle + ' ' + '- ' + icategory + '

' + idescription + '

');
        };
      };
    });
  }

  // Search Query
  function searchedData(searchword) {
    $.getJSON(url, function(data) {

      var entry = data.feed.entry;

      $(".list").empty();

      for (var i = 0; i < entry.length; i++) {
        var ititle = entry[i].title.$t;
        var icategory = entry[i].gsx$category.$t;
        var idescription = entry[i].gsx$description.$t;
        var iwebsite = entry[i].gsx$website.$t;
        var iimage = entry[i].gsx$image.$t;

        if (ititle.indexOf(searchword) >= 0 || idescription.indexOf(searchword) >= 0 || icategory.indexOf(searchword) >= 0) {
          $('.list').append('

' + ititle + ' ' + '- ' + icategory + '

' + idescription + '

');
        };
      };
    });
  }

  // Generate the Initial Data
  getData();

  // These are the filter buttons function
  // Search Button
  $("#search_button").click(function() {
    var user_input = $(".searched").val();
    searchedData(user_input);
  });

  // Search Keypress
  $(".searched").keypress(function(event) {
    if (event.which == 13) {
      var user_input = $(".searched").val();
      searchedData(user_input);
    }
  });

  // Subject Specific
  $('#filter-subject-specific').click(function() {
    filterData("Subject Specific");
  });

  // Literacy
  $('#filter-literacy').click(function() {
    filterData("Literacy");
  });

  // Teaching Quality
  $('#filter-teaching-quality').click(function() {
    filterData("Teaching Quality");
  });

  // Career Development
  $('#filter-career-development').click(function() {
    filterData("Career Development");
  });

  // Show all
  $('#filter-none').click(function() {
    getData();
  });
});
<|endoftext|>


<commit_before>/////
// Tests the driver API for making connections and excercising the networking code
/////

var fs = require('fs');
var spawn = require('child_process').spawn

var assert = require('assert');

var r = require('../../../build/packages/js/rethinkdb');
var build_dir = process.env.BUILD_DIR || '../../../build/debug'
var testDefault = process.env.TEST_DEFAULT_PORT == "1"

var port = null;

var assertErr = function(err, type, msg) {
    assertNotNull(err);
    assert.equal(err.constructor.name, type);
    var _msg = err.message.replace(/ in:\n([\r\n]|.)*/m, "");
    _msg = _msg.replace(/\nFailed assertion:(.|\n)*/m, "")
    assert.equal(_msg, msg);
};

var givesError = function(type, msg, done){
    return function(err){
        assertErr(err, type, msg);
        if(done) {
          done();
        }
    };
};

var checkError = function(type, msg) {
    return function(err) {
      assertErr(err, type, msg);
      return true; // error is correct
    }
};

var withConnection = function(f){
    return function(done){
        r.connect({port:port}, function(err, c){
            assertNull(err);
            f(done, c);
        });
    };
};

var testSimpleQuery = function(c, done){
    r(1).run(c, function(err, res){
        assertNull(err);
        assert.equal(res, 1);
        done();
    });
};

var noError = function(f){
    return function(err){
        assertNull(err);
        f.apply({}, arguments);
    };
}

var assertNull = function(x){
    assert.equal(x, null);
}

var assertNotNull = function(x){
    assert.notEqual(x, null);
}

var ifTestDefault = function(f, c){
    if(testDefault){
        return f(c);
    }else{
        return c();
    }
}

describe('Javascript connection API', function(){
    it("times out with a server that doesn't do the handshake correctly", function(done){
        var port = 8990;

        // Setup dummy sever
        require('net').createServer(function(c) {
            // Do nothing
        }).listen(port);

        r.connect({port:port, timeout:1}, givesError("RqlDriverError", "Handshake timedout", done));
    });

    describe('With no server', function(){
        it("fails when trying to connect", function(done){
            ifTestDefault(
                function(cont){
                    r.connect({}, givesError("RqlDriverError", "Could not connect to localhost:28015.\nconnect ECONNREFUSED", function(){
                        r.connect({host:'0.0.0.0'}, givesError("RqlDriverError", "Could not connect to 0.0.0.0:28015.\nconnect ECONNREFUSED", cont))})); },
                function(){
                    r.connect({port:11221}, givesError("RqlDriverError", "Could not connect to localhost:11221.\nconnect ECONNREFUSED", function(){
                        r.connect({host:'0.0.0.0', port:11221}, givesError("RqlDriverError", "Could not connect to 0.0.0.0:11221.\nconnect ECONNREFUSED", done))}))});
        });

        it("empty run", function(done) {
            r.expr(1).run().then(function() {
                done(new Error("Was expecting an error"))
            }).error(givesError("RqlDriverError", "First argument to `run` must be an open connection.", done));
        });
        it("run with an object", function(done) {
            r.expr(1).run({}).then(function() {
                done(new Error("Was expecting an error"))
            }).error(givesError("RqlDriverError", "First argument to `run` must be an open connection.", done));
        });
    });

    describe('With a server', function(){

        var cpp_server;
        var server_out_log;
        var server_err_log;
        var cluster_port;

        beforeEach(function(done){
            function setup() {
                port = Math.floor(Math.random()*(65535 - 1025)+1025);
                cluster_port = port + 1;
                server_out_log = fs.openSync('run/server-log.txt', 'a');
                server_err_log = fs.openSync('run/server-error-log.txt', 'a');
                cpp_server = spawn(
                    build_dir + '/rethinkdb',
                    ['--driver-port', port, '--http-port', '0', '--cluster-port', cluster_port, '--cache-size', '512'],
                    {stdio: ['ignore', 'pipe', 'pipe']});

                cpp_server.stderr.on('data', function(data) {
                    fs.write(server_err_log, data)
                    // Somehow, rethinkdb dump things in stderr
                    if (data.toString().match(/Server ready/)) {
                        cpp_server.removeAllListeners();
                        setTimeout(done, 500); // We give the server 500ms to avoid errors like ("Cannot compute blueprint...")
                    }

                    if (data.toString().match(/Could not bind to/)) {
                        // The port is somehow used by someone else, let's spin up another server
                        cpp_server.removeAllListeners();
                        setup();
                    }
                });
                cpp_server.stdout.on('data', function(data) {
                    fs.write(server_out_log, data)
                });
            }

            setup();
        });

        afterEach(function(done){
            cpp_server.kill();
            cpp_server.removeAllListeners();
            spawn('rm', ['-rf', 'rethinkdb_data']);
            setTimeout(done, 10);
            fs.close(server_out_log);
            fs.close(server_err_log);
        });

        it("authorization key when none needed", function(done){
            r.connect({port: port, authKey: "hunter2"}, givesError("RqlDriverError", "Server dropped connection with message: \"ERROR: Incorrect authorization key.\"", done));
        });

        it("correct authorization key", function(done){
            spawn(build_dir + '/rethinkdb',
                  ['admin', '--join', 'localhost:' + cluster_port, 'set', 'auth', 'hunter3'],
                  {stdio: ['ignore', server_out_log, server_err_log]});
            setTimeout(function(){
                r.connect({port: port, authKey: "hunter3"}, function(e, c){
                    assertNull(e);
                    r.expr(1).run(c, noError(done));
                });
            }, 500);

        });

        it("wrong authorization key", function(done){
            spawn(build_dir + '/rethinkdb',
                  ['admin', '--join', 'localhost:' + cluster_port, 'set', 'auth', 'hunter4'],
                  {stdio: ['ignore', server_out_log, server_err_log]});

            setTimeout(function(){
                r.connect({port: port, authKey: "hunter-wrong"}, givesError("RqlDriverError", "Server dropped connection with message: \"ERROR: Incorrect authorization key.\"", done));
            }, 500);
        });

        // TODO: test default port

        it("close twice (synchronously) and reconnect", withConnection(function(done, c){
            testSimpleQuery(c, function(){
                assert.doesNotThrow(function(){
                    c.close({noreplyWait: false});
                    c.close({noreplyWait: false});
                    c.reconnect(function(err, c){
                        assertNull(err);
                        testSimpleQuery(c, done);
                    });
                });
            });
        }));
        it("close twice and reconnect", withConnection(function(done, c){
            testSimpleQuery(c, function(){
                assert.doesNotThrow(function(){
                    c.close();
                    c.close();
                    c.reconnect(function(err, c){
                        assertNull(err);
                        testSimpleQuery(c, done);
                    });
                });
            });
        }));

        it("fails to query after close", withConnection(function(done, c){
            c.close({noreplyWait: false});
            r(1).run(c, givesError("RqlDriverError", "Connection is closed.", done));
        }));

        it("noreplyWait waits", withConnection(function(done, c){
            var t = new Date().getTime();
            r.js('while(true);', {timeout: 0.5}).run(c, {noreply: true});
            c.noreplyWait(function (err) {
                assertNull(err);
                var duration = new Date().getTime() - t;
                assert(duration >= 500);
                done();
            });
        }));

        it("close waits by default", withConnection(function(done, c){
            var t = new Date().getTime();
            r.js('while(true);', {timeout: 0.5}).run(c, {noreply: true});
            c.close(function (err) {
                assertNull(err);
                var duration = new Date().getTime() - t;
                assert(duration >= 500);
                done();
            });
        }));

        it("reconnect waits by default", withConnection(function(done, c){
            var t = new Date().getTime();
            r.js('while(true);', {timeout: 0.5}).run(c, {noreply: true});
            c.reconnect(function (err) {
                assertNull(err);
                var duration = new Date().getTime() - t;
                assert(duration >= 500);
                done();
            });
        }));

        it("close does not wait if we want it not to", withConnection(function(done, c){
            var t = new Date().getTime();
            r.js('while(true);', {timeout: 0.5}).run(c, {noreply: true});
            c.close({'noreplyWait': false}, function (err) {
                assertNull(err);
                var duration = new Date().getTime() - t;
                assert(duration < 500);
                done();
            });
        }));

        it("reconnect does not wait if we want it not to", withConnection(function(done, c){
            var t = new Date().getTime();
            r.js('while(true);', {timeout: 0.5}).run(c, {noreply: true});
            c.reconnect({'noreplyWait': false}, function (err) {
                assertNull(err);
                var duration = new Date().getTime() - t;
                assert(duration < 500);
                done();
            });
        }));

        it("close waits even without callback", withConnection(function(done, c){
            var start = Date.now();
            var timeout = 1.5;
            r.js('while(true);', {timeout: timeout}).run(c, {noreply: true});
            c.close(function(err) {
                if (err) throw err;
                var duration = Date.now()-start;
                assert(duration > timeout*1000);
                done()
            });
        }));

        it("test use", withConnection(function(done, c){
            r.db('test').tableCreate('t1').run(c, noError(function(){
                r.dbCreate('db2').run(c, noError(function(){
                    r.db('db2').tableCreate('t2').run(c, noError(function(){
                        c.use('db2');
                        r.table('t2').run(c, noError(function(){
                            c.use('test');
                            r.table('t2').run(c, givesError("RqlRuntimeError", "Table `test.t2` does not exist",
                                                            done));
                        }));}));}));}));}));

        it("useOutdated", withConnection(function(done, c){
            r.db('test').tableCreate('t1').run(c, function(){
                r.db('test').table('t1', {useOutdated:true}).run(c, function(){
                    r.table('t1').run(c, {useOutdated: true}, done);});});
        }));

        it("test default durability", withConnection(function(done, c){
            r.db('test').tableCreate('t1').run(c, noError(function(){
                r.db('test').table('t1').insert({data:"5"}).run(c, {durability: "default"},
                    givesError("RqlRuntimeError", "Durability option `default` unrecognized (options are \"hard\" and \"soft\")", done));
            }));
        }));

        it("test wrong durability", withConnection(function(done, c){
            r.db('test').tableCreate('t1').run(c, noError(function(){
                r.db('test').table('t1').insert({data:"5"}).run(c, {durability: "wrong"},
                    givesError("RqlRuntimeError", "Durability option `wrong` unrecognized (options are \"hard\" and \"soft\")", done))
            }));
        }));

        it("test soft durability", withConnection(function(done, c){
            r.db('test').tableCreate('t1').run(c, noError(function(){
                r.db('test').table('t1').insert({data:"5"}).run(c, {durability: "soft"}, noError(done));
            }));
        }));

        it("test hard durability", withConnection(function(done, c){
            r.db('test').tableCreate('t1').run(c, noError(function(){
                r.db('test').table('t1').insert({data:"5"}).run(c, {durability: "hard"}, noError(done));
            }));
        }));

        it("test non-deterministic durability", withConnection(function(done, c){
            r.db('test').tableCreate('t1').run(c, noError(function(){
                r.db('test').table('t1').insert({data:"5"}).run(c, {durability: r.js("'so' + 'ft'")}, noError(done));
            }));
        }));

        it("fails to query after kill", withConnection(function(done, c){
            cpp_server.kill();
            setTimeout(function() {
                r(1).run(c, givesError("RqlDriverError", "Connection is closed.", done));
            }, 100);
        }));

        it("pretty-printing", function(){
            assert.equal(r.db('db1').table('tbl1').map(function(x){ return x; }).toString(),
                        'r.db("db1").table("tbl1").map(function(var_0) { return var_0; })')
        });

        it("connect() with default db", withConnection(function(done, c){
            r.dbCreate('foo').run(c, function(err, res){
                r.db('foo').tableCreate('bar').run(c, function(err, res){
                    c.close();
                    r.connect({port:port, db:'foo'}, noError(function(err, c){
                        r.table('bar').run(c, noError(done));
                    }));
                });
            });
        }));

        it("missing arguments cause exception", withConnection(function(done,c){
            assert.throws(function(){ c.use(); });
            done();
        }));

        // Test the event emitter interface

        it("Emits connect event on connect", withConnection(function(done, c){
            c.on('connect', function(err, c2) {
                done();
            });

            c.reconnect(function(){});
        }));

        it("Emits close event on close", withConnection(function(done, c){
            c.on('close', function() {
                done();
            });

            c.close();
        }));

        it("Non valid optarg", withConnection(function(done, c){
            r.expr(1).run(c, {nonValidOption: true}).then(function() {
                done(new Error("Was expecting an error"))
            }).error(givesError("RqlDriverError", "Found nonValidOption which is not a valid option. valid options are {useOutdated: <bool>, noreply: <bool>, timeFormat: <string>, groupFormat: <string>, binaryFormat: <string>, profile: <bool>, durability: <string>, arrayLimit: <number>}.", done));
        }));

        it("Extra argument", withConnection(function(done, c){
            r.expr(1).run(c, givesError("RqlDriverError", "Second argument to `run` cannot be a function if a third argument is provided.", done), 1)
        }));

        it("Callback must be a function", withConnection(function(done, c){
            r.expr(1).run(c, {}, "not_a_function").error(givesError("RqlDriverError", "If provided, the callback must be a function. Please use `run(connection[, options], callback])", done))
        }));
    });
});

<commit_msg>Typo -- also fix test<commit_after>/////
// Tests the driver API for making connections and excercising the networking code
/////

var fs = require('fs');
var spawn = require('child_process').spawn

var assert = require('assert');

var r = require('../../../build/packages/js/rethinkdb');
var build_dir = process.env.BUILD_DIR || '../../../build/debug'
var testDefault = process.env.TEST_DEFAULT_PORT == "1"

var port = null;

var assertErr = function(err, type, msg) {
    assertNotNull(err);
    assert.equal(err.constructor.name, type);
    var _msg = err.message.replace(/ in:\n([\r\n]|.)*/m, "");
    _msg = _msg.replace(/\nFailed assertion:(.|\n)*/m, "")
    assert.equal(_msg, msg);
};

var givesError = function(type, msg, done){
    return function(err){
        assertErr(err, type, msg);
        if(done) {
          done();
        }
    };
};

var checkError = function(type, msg) {
    return function(err) {
      assertErr(err, type, msg);
      return true; // error is correct
    }
};

var withConnection = function(f){
    return function(done){
        r.connect({port:port}, function(err, c){
            assertNull(err);
            f(done, c);
        });
    };
};

var testSimpleQuery = function(c, done){
    r(1).run(c, function(err, res){
        assertNull(err);
        assert.equal(res, 1);
        done();
    });
};

var noError = function(f){
    return function(err){
        assertNull(err);
        f.apply({}, arguments);
    };
}

var assertNull = function(x){
    assert.equal(x, null);
}

var assertNotNull = function(x){
    assert.notEqual(x, null);
}

var ifTestDefault = function(f, c){
    if(testDefault){
        return f(c);
    }else{
        return c();
    }
}

describe('Javascript connection API', function(){
    it("times out with a server that doesn't do the handshake correctly", function(done){
        var port = 8990;

        // Setup dummy sever
        require('net').createServer(function(c) {
            // Do nothing
        }).listen(port);

        r.connect({port:port, timeout:1}, givesError("RqlDriverError", "Handshake timedout", done));
    });

    describe('With no server', function(){
        it("fails when trying to connect", function(done){
            ifTestDefault(
                function(cont){
                    r.connect({}, givesError("RqlDriverError", "Could not connect to localhost:28015.\nconnect ECONNREFUSED", function(){
                        r.connect({host:'0.0.0.0'}, givesError("RqlDriverError", "Could not connect to 0.0.0.0:28015.\nconnect ECONNREFUSED", cont))})); },
                function(){
                    r.connect({port:11221}, givesError("RqlDriverError", "Could not connect to localhost:11221.\nconnect ECONNREFUSED", function(){
                        r.connect({host:'0.0.0.0', port:11221}, givesError("RqlDriverError", "Could not connect to 0.0.0.0:11221.\nconnect ECONNREFUSED", done))}))});
        });

        it("empty run", function(done) {
            r.expr(1).run().then(function() {
                done(new Error("Was expecting an error"))
            }).error(givesError("RqlDriverError", "First argument to `run` must be an open connection.", done));
        });
        it("run with an object", function(done) {
            r.expr(1).run({}).then(function() {
                done(new Error("Was expecting an error"))
            }).error(givesError("RqlDriverError", "First argument to `run` must be an open connection.", done));
        });
    });

    describe('With a server', function(){

        var cpp_server;
        var server_out_log;
        var server_err_log;
        var cluster_port;

        beforeEach(function(done){
            function setup() {
                port = Math.floor(Math.random()*(65535 - 1025)+1025);
                cluster_port = port + 1;
                server_out_log = fs.openSync('run/server-log.txt', 'a');
                server_err_log = fs.openSync('run/server-error-log.txt', 'a');
                cpp_server = spawn(
                    build_dir + '/rethinkdb',
                    ['--driver-port', port, '--http-port', '0', '--cluster-port', cluster_port, '--cache-size', '512'],
                    {stdio: ['ignore', 'pipe', 'pipe']});

                cpp_server.stderr.on('data', function(data) {
                    fs.write(server_err_log, data)
                    // Somehow, rethinkdb dump things in stderr
                    if (data.toString().match(/Server ready/)) {
                        cpp_server.removeAllListeners();
                        setTimeout(done, 500); // We give the server 500ms to avoid errors like ("Cannot compute blueprint...")
                    }

                    if (data.toString().match(/Could not bind to/)) {
                        // The port is somehow used by someone else, let's spin up another server
                        cpp_server.removeAllListeners();
                        setup();
                    }
                });
                cpp_server.stdout.on('data', function(data) {
                    fs.write(server_out_log, data)
                });
            }

            setup();
        });

        afterEach(function(done){
            cpp_server.kill();
            cpp_server.removeAllListeners();
            spawn('rm', ['-rf', 'rethinkdb_data']);
            setTimeout(done, 10);
            fs.close(server_out_log);
            fs.close(server_err_log);
        });

        it("authorization key when none needed", function(done){
            r.connect({port: port, authKey: "hunter2"}, givesError("RqlDriverError", "Server dropped connection with message: \"ERROR: Incorrect authorization key.\"", done));
        });

        it("correct authorization key", function(done){
            spawn(build_dir + '/rethinkdb',
                  ['admin', '--join', 'localhost:' + cluster_port, 'set', 'auth', 'hunter3'],
                  {stdio: ['ignore', server_out_log, server_err_log]});
            setTimeout(function(){
                r.connect({port: port, authKey: "hunter3"}, function(e, c){
                    assertNull(e);
                    r.expr(1).run(c, noError(done));
                });
            }, 500);

        });

        it("wrong authorization key", function(done){
            spawn(build_dir + '/rethinkdb',
                  ['admin', '--join', 'localhost:' + cluster_port, 'set', 'auth', 'hunter4'],
                  {stdio: ['ignore', server_out_log, server_err_log]});

            setTimeout(function(){
                r.connect({port: port, authKey: "hunter-wrong"}, givesError("RqlDriverError", "Server dropped connection with message: \"ERROR: Incorrect authorization key.\"", done));
            }, 500);
        });

        // TODO: test default port

        it("close twice (synchronously) and reconnect", withConnection(function(done, c){
            testSimpleQuery(c, function(){
                assert.doesNotThrow(function(){
                    c.close({noreplyWait: false});
                    c.close({noreplyWait: false});
                    c.reconnect(function(err, c){
                        assertNull(err);
                        testSimpleQuery(c, done);
                    });
                });
            });
        }));
        it("close twice and reconnect", withConnection(function(done, c){
            testSimpleQuery(c, function(){
                assert.doesNotThrow(function(){
                    c.close();
                    c.close();
                    c.reconnect(function(err, c){
                        assertNull(err);
                        testSimpleQuery(c, done);
                    });
                });
            });
        }));

        it("fails to query after close", withConnection(function(done, c){
            c.close({noreplyWait: false});
            r(1).run(c, givesError("RqlDriverError", "Connection is closed.", done));
        }));

        it("noreplyWait waits", withConnection(function(done, c){
            var t = new Date().getTime();
            r.js('while(true);', {timeout: 0.5}).run(c, {noreply: true});
            c.noreplyWait(function (err) {
                assertNull(err);
                var duration = new Date().getTime() - t;
                assert(duration >= 500);
                done();
            });
        }));

        it("close waits by default", withConnection(function(done, c){
            var t = new Date().getTime();
            r.js('while(true);', {timeout: 0.5}).run(c, {noreply: true});
            c.close(function (err) {
                assertNull(err);
                var duration = new Date().getTime() - t;
                assert(duration >= 500);
                done();
            });
        }));

        it("reconnect waits by default", withConnection(function(done, c){
            var t = new Date().getTime();
            r.js('while(true);', {timeout: 0.5}).run(c, {noreply: true});
            c.reconnect(function (err) {
                assertNull(err);
                var duration = new Date().getTime() - t;
                assert(duration >= 500);
                done();
            });
        }));

        it("close does not wait if we want it not to", withConnection(function(done, c){
            var t = new Date().getTime();
            r.js('while(true);', {timeout: 0.5}).run(c, {noreply: true});
            c.close({'noreplyWait': false}, function (err) {
                assertNull(err);
                var duration = new Date().getTime() - t;
                assert(duration < 500);
                done();
            });
        }));

        it("reconnect does not wait if we want it not to", withConnection(function(done, c){
            var t = new Date().getTime();
            r.js('while(true);', {timeout: 0.5}).run(c, {noreply: true});
            c.reconnect({'noreplyWait': false}, function (err) {
                assertNull(err);
                var duration = new Date().getTime() - t;
                assert(duration < 500);
                done();
            });
        }));

        it("close waits even without callback", withConnection(function(done, c){
            var start = Date.now();
            var timeout = 1.5;
            r.js('while(true);', {timeout: timeout}).run(c, {noreply: true});
            c.close(function(err) {
                if (err) throw err;
                var duration = Date.now()-start;
                assert(duration > timeout*1000);
                done()
            });
        }));

        it("test use", withConnection(function(done, c){
            r.db('test').tableCreate('t1').run(c, noError(function(){
                r.dbCreate('db2').run(c, noError(function(){
                    r.db('db2').tableCreate('t2').run(c, noError(function(){
                        c.use('db2');
                        r.table('t2').run(c, noError(function(){
                            c.use('test');
                            r.table('t2').run(c, givesError("RqlRuntimeError", "Table `test.t2` does not exist",
                                                            done));
                        }));}));}));}));}));

        it("useOutdated", withConnection(function(done, c){
            r.db('test').tableCreate('t1').run(c, function(){
                r.db('test').table('t1', {useOutdated:true}).run(c, function(){
                    r.table('t1').run(c, {useOutdated: true}, done);});});
        }));

        it("test default durability", withConnection(function(done, c){
            r.db('test').tableCreate('t1').run(c, noError(function(){
                r.db('test').table('t1').insert({data:"5"}).run(c, {durability: "default"},
                    givesError("RqlRuntimeError", "Durability option `default` unrecognized (options are \"hard\" and \"soft\")", done));
            }));
        }));

        it("test wrong durability", withConnection(function(done, c){
            r.db('test').tableCreate('t1').run(c, noError(function(){
                r.db('test').table('t1').insert({data:"5"}).run(c, {durability: "wrong"},
                    givesError("RqlRuntimeError", "Durability option `wrong` unrecognized (options are \"hard\" and \"soft\")", done))
            }));
        }));

        it("test soft durability", withConnection(function(done, c){
            r.db('test').tableCreate('t1').run(c, noError(function(){
                r.db('test').table('t1').insert({data:"5"}).run(c, {durability: "soft"}, noError(done));
            }));
        }));

        it("test hard durability", withConnection(function(done, c){
            r.db('test').tableCreate('t1').run(c, noError(function(){
                r.db('test').table('t1').insert({data:"5"}).run(c, {durability: "hard"}, noError(done));
            }));
        }));

        it("test non-deterministic durability", withConnection(function(done, c){
            r.db('test').tableCreate('t1').run(c, noError(function(){
                r.db('test').table('t1').insert({data:"5"}).run(c, {durability: r.js("'so' + 'ft'")}, noError(done));
            }));
        }));

        it("fails to query after kill", withConnection(function(done, c){
            cpp_server.kill();
            setTimeout(function() {
                r(1).run(c, givesError("RqlDriverError", "Connection is closed.", done));
            }, 100);
        }));

        it("pretty-printing", function(){
            assert.equal(r.db('db1').table('tbl1').map(function(x){ return x; }).toString(),
                        'r.db("db1").table("tbl1").map(function(var_0) { return var_0; })')
        });

        it("connect() with default db", withConnection(function(done, c){
            r.dbCreate('foo').run(c, function(err, res){
                r.db('foo').tableCreate('bar').run(c, function(err, res){
                    c.close();
                    r.connect({port:port, db:'foo'}, noError(function(err, c){
                        r.table('bar').run(c, noError(done));
                    }));
                });
            });
        }));

        it("missing arguments cause exception", withConnection(function(done,c){
            assert.throws(function(){ c.use(); });
            done();
        }));

        // Test the event emitter interface

        it("Emits connect event on connect", withConnection(function(done, c){
            c.on('connect', function(err, c2) {
                done();
            });

            c.reconnect(function(){});
        }));

        it("Emits close event on close", withConnection(function(done, c){
            c.on('close', function() {
                done();
            });

            c.close();
        }));

        it("Non valid optarg", withConnection(function(done, c){
            r.expr(1).run(c, {nonValidOption: true}).then(function() {
                done(new Error("Was expecting an error"))
            }).error(givesError("RqlDriverError", "Found nonValidOption which is not a valid option. valid options are {useOutdated: <bool>, noreply: <bool>, timeFormat: <string>, groupFormat: <string>, binaryFormat: <string>, profile: <bool>, durability: <string>, arrayLimit: <number>}.", done));
        }));

        it("Extra argument", withConnection(function(done, c){
            r.expr(1).run(c, givesError("RqlDriverError", "Second argument to `run` cannot be a function if a third argument is provided.", done), 1)
        }));

        it("Callback must be a function", withConnection(function(done, c){
            r.expr(1).run(c, {}, "not_a_function").error(givesError("RqlDriverError", "If provided, the callback must be a function. Please use `run(connection[, options][, callback])", done))
        }));
    });
});

<|endoftext|>