<commit_before>(function(window, undefined) {

  /** Use a single load function */
  var load = typeof require == 'function' ? require : window.load;

  /** The unit testing framework */
  var QUnit =
    window.QUnit || (
      window.setTimeout || (window.addEventListener = window.setTimeout = / /),
      window.QUnit = load('../vendor/qunit/qunit/qunit.js') || window.QUnit,
      load('../vendor/qunit-clib/qunit-clib.js'),
      (window.addEventListener || 0).test && delete window.addEventListener,
      window.QUnit
    );

  /** The `lodash` function to test */
  var _ =
    window._ || (
      _ = load('../lodash.js') || window._,
      _._ || _
    );

  /** Shortcut used to convert array-like objects to arrays */
  var slice = [].slice;

  /** Used to resolve a value's internal [[Class]] */
  var toString = {}.toString;

  /** Used to check problem JScript properties (a.k.a. the [[DontEnum]] bug) */
  var shadowed = {
    'constructor': 1,
    'hasOwnProperty': 2,
    'isPrototypeOf': 3,
    'propertyIsEnumerable': 4,
    'toLocaleString': 5,
    'toString': 6,
    'valueOf': 7
  };

  /*--------------------------------------------------------------------------*/

  /**
   * Skips a given number of tests with a passing result.
   *
   * @private
   * @param {Number} count The number of tests to skip.
   */
  function skipTest(count) {
    while (count--) {
      ok(true, 'test skipped');
    }
  }

  /*--------------------------------------------------------------------------*/

  // must explicitly use `QUnit.module` instead of `module()`
  // in case we are in a CLI environment
  QUnit.module('lodash');

  (function() {
    test('supports loading lodash.js as the "lodash" module', function() {
      if (window.document && window.require) {
        equal((_2 || {}).moduleName, 'lodash');
      } else {
        skipTest(1)
      }
    });

    test('supports loading lodash.js as the "underscore" module', function() {
      if (window.document && window.require) {
        equal((_3 || {}).moduleName, 'underscore');
      } else {
        skipTest(1)
      }
    });

    test('avoids overwritten native methods', function() {
      if (window.lodashBadKeys) {
        notDeepEqual(lodashBadKeys.keys({ 'a': 1 }), []);
      } else {
        skipTest(1);
      }
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash constructor');

  (function() {
    test('creates a new instance when called without the `new` operator', function() {
      ok(_() instanceof _);
    });

    test('should pass through LoDash instances', function() {
      var wrapped = _([]);
      equal(_(wrapped), wrapped);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.bind');

  (function() {
    test('supports lazy bind', function() {
      var object = {
        'name': 'moe',
        'greet': function(greeting) {
          return greeting + ': ' + this.name;
        }
      };

      var func = _.bind(object, 'greet', 'hi');
      equal(func(), 'hi: moe');

      object.greet = function(greeting) {
        return greeting + ' ' + this.name + '!';
      };
      equal(func(), 'hi moe!');
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.debounce');

  (function() {
    test('subsequent "immediate" debounced calls should return the result of the first call', function() {
      var debounced = _.debounce(function(value) { return value; }, 100, true),
          result = [debounced('x'), debounced('y')];

      deepEqual(result, ['x', 'x']);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.escape');

  (function() {
    test('should not escape the ">" character', function() {
      equal(_.escape('>'), '>');
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.extend');

  (function() {
    test('skips the prototype property of functions (test in Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1)', function() {
      function Foo() {}
      Foo.prototype.c = 3;

      Foo.a = 1;
      Foo.b = 2;

      var expected = { 'a': 1, 'b': 2 };
      deepEqual(_.extend({}, Foo), expected);

      Foo.prototype = { 'c': 3 };
      deepEqual(_.extend({}, Foo), expected);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.forEach');

  (function() {
    test('returns the collection', function() {
      var collection = [1, 2, 3, 4];
      equal(_.forEach(collection, Boolean), collection);
    });

    test('fixes the JScript [[DontEnum]] bug (test in IE < 9)', function() {
      var object = {};
      _.forEach(shadowed, function(value, key) {
        object[key] = value;
      });

      deepEqual(object, shadowed);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.groupBy');

  (function() {
    test('supports the `thisArg` argument', function() {
      var actual = _.groupBy([1.3, 2.1, 2.4], function(num) {
        return this.floor(num);
      }, Math);

      deepEqual(actual, { '1': [1.3], '2': [2.1, 2.4] });
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.initial');

  (function() {
    test('returns an empty collection for `n` of `0`', function() {
      var array = [1, 2, 3, 4];
      deepEqual(_.initial(array, 0), []);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.isEmpty');

  (function() {
    test('fixes the JScript [[DontEnum]] bug (test in IE < 9)', function() {
      equal(_.isEmpty(shadowed), false);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.isEqual');

  (function() {
    test('fixes the JScript [[DontEnum]] bug (test in IE < 9)', function() {
      equal(_.isEqual(shadowed, {}), false);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.isNaN');

  (function() {
    test('returns `true` for `new Number(NaN)`', function() {
      equal(_.isNaN(new Number(NaN)), true)
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.keys');

  (function() {
    test('fixes the JScript [[DontEnum]] bug (test in IE < 9)', function() {
      function Foo() {}
      Foo.prototype.a = 1;

      deepEqual(_.keys(Foo.prototype), ['a']);
      deepEqual(_.keys(shadowed).sort(),
        'constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf'.split(' '));
    });
  }());

  /*--------------------------------------------------------------------------*/

  (function() {
    var i = -1,
        largeArray = [];

    while (++i <= 1e6) {
      largeArray[i] = i;
    }
    _.each(['max', 'min'], function(methodName) {
      QUnit.module('lodash.' + methodName);

      test('does not error when computing the ' + methodName + ' value of massive arrays', function() {
        try {
          var actual = _[methodName](largeArray);
        } catch(e) { }

        equal(actual, methodName == 'max' ? 1e6 : 0);
      });
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.partial');

  (function() {
    test('partially applies an argument, without additional arguments', function() {
      var arg = 'catnip',
          func = function(x) { return x; };

      equal(_.partial(func, arg)(), arg);
    });

    test('partially applies an argument, with additional arguments', function() {
      var arg1 = 'catnip',
          arg2 = 'cheese',
          func = function(x, y) { return [x, y]; };

      deepEqual(_.partial(func, arg1)(arg2), [arg1, arg2]);
    });

    test('works without partially applying arguments, without additional arguments', function() {
      var func = function() { return arguments.length; };

      equal(_.partial(func)(), 0);
    });

    test('works without partially applying arguments, with additional arguments', function() {
      var arg = 'catnip',
          func = function(x) { return x; };

      equal(_.partial(func)(arg), arg);
    });

    test('should not alter the `this` binding of either function', function() {
      var o = { 'cat': 'nip' },
          func = function() { return this.cat; };

      equal(_.partial(_.bind(func, o))(), o.cat);
      equal(_.bind(_.partial(func), o)(), o.cat);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.reduceRight');

  (function() {
    test('should pass the correct `callback` arguments when iterating an object', function() {
      var args,
          object = { 'a': 'A', 'b': 'B', 'c': 'C' },
          keys = _.keys(object);

      _.reduceRight(object, function() {
        args || (args = slice.call(arguments));
      });

      deepEqual(args, ['C', 'B', 'b', object]);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.size');

  (function() {
    test('should detect the size of a string value', function() {
      equal(_.size('abc'), 3);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.sortBy');

  (function() {
    test('supports the `thisArg` argument', function() {
      var actual = _.sortBy([1, 2, 3, 4], function(num) {
        return this.sin(num);
      }, Math);

      deepEqual(actual, [4, 3, 1, 2]);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.template');

  (function() {
    test('supports recursive calls', function() {
      var compiled = _.template('<%= a %><% a = _.template(c, object) %><%= a %>'),
          data = { 'a': 'A', 'b': 'B', 'c': '<%= b %>' };

      equal(compiled(data), 'AB');
    });

    test('should not augment the `options` object', function() {
      var options = {};
      _.template('', null, options);
      deepEqual(options, {});
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.throttle');

  (function() {
    test('subsequent calls should return the result of the first call', function() {
      var throttled = _.throttle(function(value) { return value; }, 100),
          result = [throttled('x'), throttled('y')];

      deepEqual(result, ['x', 'x']);
    });

    test('supports calls in a loop', function() {
      var counter = 0,
          throttled = _.throttle(function() { counter++; }, 100),
          start = new Date,
          limit = 220;

      while ((new Date - start) < limit) {
        throttled();
      }
      equal(counter, 3);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.toArray');

  (function() {
    var args = arguments;

    test('should call custom `toArray` method of an array', function() {
      var array = [1, 2, 3];
      array.toArray = function() { return [3, 2, 1]; };
      deepEqual(_.toArray(array), [3, 2, 1]);
    });

    test('should treat array-like-objects like arrays', function() {
      var object = { '0': 'a', '1': 'b', '2': 'c', 'length': 3 };
      deepEqual(_.toArray(object), ['a', 'b', 'c']);
      deepEqual(_.toArray(args), [1, 2, 3]);
    });
  }(1, 2, 3));

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash(...).shift');

  (function() {
    test('should remove the value at index `0` when length is `0` (test in IE 8 compatibility mode)', function() {
      var wrapped = _({ '0': 1, 'length': 1 });
      wrapped.shift();

      deepEqual(wrapped.keys(), ['length']);
      equal(wrapped.first(), undefined);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash(...).splice');

  (function() {
    test('should remove the value at index `0` when length is `0` (test in IE < 9, and in compatibility mode for IE9)', function() {
      var wrapped = _({ '0': 1, 'length': 1 });
      wrapped.splice(0, 1);

      deepEqual(wrapped.keys(), ['length']);
      equal(wrapped.first(), undefined);
    });
  }());

  /*--------------------------------------------------------------------------*/

  // explicitly call `QUnit.start()` in a CLI environment
  if (!window.document) {
    QUnit.start();
  }
}(typeof global == 'object' && global || this));<commit_msg>Add JScript [[DontEnum]] _.size unit test.<commit_after>(function(window, undefined) {

  /** Use a single load function */
  var load = typeof require == 'function' ? require : window.load;

  /** The unit testing framework */
  var QUnit =
    window.QUnit || (
      window.setTimeout || (window.addEventListener = window.setTimeout = / /),
      window.QUnit = load('../vendor/qunit/qunit/qunit.js') || window.QUnit,
      load('../vendor/qunit-clib/qunit-clib.js'),
      (window.addEventListener || 0).test && delete window.addEventListener,
      window.QUnit
    );

  /** The `lodash` function to test */
  var _ =
    window._ || (
      _ = load('../lodash.js') || window._,
      _._ || _
    );

  /** Shortcut used to convert array-like objects to arrays */
  var slice = [].slice;

  /** Used to resolve a value's internal [[Class]] */
  var toString = {}.toString;

  /** Used to check problem JScript properties (a.k.a. the [[DontEnum]] bug) */
  var shadowed = {
    'constructor': 1,
    'hasOwnProperty': 2,
    'isPrototypeOf': 3,
    'propertyIsEnumerable': 4,
    'toLocaleString': 5,
    'toString': 6,
    'valueOf': 7
  };

  /*--------------------------------------------------------------------------*/

  /**
   * Skips a given number of tests with a passing result.
   *
   * @private
   * @param {Number} count The number of tests to skip.
   */
  function skipTest(count) {
    while (count--) {
      ok(true, 'test skipped');
    }
  }

  /*--------------------------------------------------------------------------*/

  // must explicitly use `QUnit.module` instead of `module()`
  // in case we are in a CLI environment
  QUnit.module('lodash');

  (function() {
    test('supports loading lodash.js as the "lodash" module', function() {
      if (window.document && window.require) {
        equal((_2 || {}).moduleName, 'lodash');
      } else {
        skipTest(1)
      }
    });

    test('supports loading lodash.js as the "underscore" module', function() {
      if (window.document && window.require) {
        equal((_3 || {}).moduleName, 'underscore');
      } else {
        skipTest(1)
      }
    });

    test('avoids overwritten native methods', function() {
      if (window.lodashBadKeys) {
        notDeepEqual(lodashBadKeys.keys({ 'a': 1 }), []);
      } else {
        skipTest(1);
      }
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash constructor');

  (function() {
    test('creates a new instance when called without the `new` operator', function() {
      ok(_() instanceof _);
    });

    test('should pass through LoDash instances', function() {
      var wrapped = _([]);
      equal(_(wrapped), wrapped);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.bind');

  (function() {
    test('supports lazy bind', function() {
      var object = {
        'name': 'moe',
        'greet': function(greeting) {
          return greeting + ': ' + this.name;
        }
      };

      var func = _.bind(object, 'greet', 'hi');
      equal(func(), 'hi: moe');

      object.greet = function(greeting) {
        return greeting + ' ' + this.name + '!';
      };
      equal(func(), 'hi moe!');
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.debounce');

  (function() {
    test('subsequent "immediate" debounced calls should return the result of the first call', function() {
      var debounced = _.debounce(function(value) { return value; }, 100, true),
          result = [debounced('x'), debounced('y')];

      deepEqual(result, ['x', 'x']);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.escape');

  (function() {
    test('should not escape the ">" character', function() {
      equal(_.escape('>'), '>');
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.extend');

  (function() {
    test('skips the prototype property of functions (test in Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1)', function() {
      function Foo() {}
      Foo.prototype.c = 3;

      Foo.a = 1;
      Foo.b = 2;

      var expected = { 'a': 1, 'b': 2 };
      deepEqual(_.extend({}, Foo), expected);

      Foo.prototype = { 'c': 3 };
      deepEqual(_.extend({}, Foo), expected);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.forEach');

  (function() {
    test('returns the collection', function() {
      var collection = [1, 2, 3, 4];
      equal(_.forEach(collection, Boolean), collection);
    });

    test('fixes the JScript [[DontEnum]] bug (test in IE < 9)', function() {
      var object = {};
      _.forEach(shadowed, function(value, key) {
        object[key] = value;
      });

      deepEqual(object, shadowed);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.groupBy');

  (function() {
    test('supports the `thisArg` argument', function() {
      var actual = _.groupBy([1.3, 2.1, 2.4], function(num) {
        return this.floor(num);
      }, Math);

      deepEqual(actual, { '1': [1.3], '2': [2.1, 2.4] });
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.initial');

  (function() {
    test('returns an empty collection for `n` of `0`', function() {
      var array = [1, 2, 3, 4];
      deepEqual(_.initial(array, 0), []);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.isEmpty');

  (function() {
    test('fixes the JScript [[DontEnum]] bug (test in IE < 9)', function() {
      equal(_.isEmpty(shadowed), false);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.isEqual');

  (function() {
    test('fixes the JScript [[DontEnum]] bug (test in IE < 9)', function() {
      equal(_.isEqual(shadowed, {}), false);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.isNaN');

  (function() {
    test('returns `true` for `new Number(NaN)`', function() {
      equal(_.isNaN(new Number(NaN)), true)
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.keys');

  (function() {
    test('fixes the JScript [[DontEnum]] bug (test in IE < 9)', function() {
      function Foo() {}
      Foo.prototype.a = 1;

      deepEqual(_.keys(Foo.prototype), ['a']);
      deepEqual(_.keys(shadowed).sort(),
        'constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf'.split(' '));
    });
  }());

  /*--------------------------------------------------------------------------*/

  (function() {
    var i = -1,
        largeArray = [];

    while (++i <= 1e6) {
      largeArray[i] = i;
    }
    _.each(['max', 'min'], function(methodName) {
      QUnit.module('lodash.' + methodName);

      test('does not error when computing the ' + methodName + ' value of massive arrays', function() {
        try {
          var actual = _[methodName](largeArray);
        } catch(e) { }

        equal(actual, methodName == 'max' ? 1e6 : 0);
      });
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.partial');

  (function() {
    test('partially applies an argument, without additional arguments', function() {
      var arg = 'catnip',
          func = function(x) { return x; };

      equal(_.partial(func, arg)(), arg);
    });

    test('partially applies an argument, with additional arguments', function() {
      var arg1 = 'catnip',
          arg2 = 'cheese',
          func = function(x, y) { return [x, y]; };

      deepEqual(_.partial(func, arg1)(arg2), [arg1, arg2]);
    });

    test('works without partially applying arguments, without additional arguments', function() {
      var func = function() { return arguments.length; };

      equal(_.partial(func)(), 0);
    });

    test('works without partially applying arguments, with additional arguments', function() {
      var arg = 'catnip',
          func = function(x) { return x; };

      equal(_.partial(func)(arg), arg);
    });

    test('should not alter the `this` binding of either function', function() {
      var o = { 'cat': 'nip' },
          func = function() { return this.cat; };

      equal(_.partial(_.bind(func, o))(), o.cat);
      equal(_.bind(_.partial(func), o)(), o.cat);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.reduceRight');

  (function() {
    test('should pass the correct `callback` arguments when iterating an object', function() {
      var args,
          object = { 'a': 'A', 'b': 'B', 'c': 'C' },
          keys = _.keys(object);

      _.reduceRight(object, function() {
        args || (args = slice.call(arguments));
      });

      deepEqual(args, ['C', 'B', 'b', object]);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.size');

  (function() {
    test('should detect the size of a string value', function() {
      equal(_.size('abc'), 3);
    });

    test('fixes the JScript [[DontEnum]] bug (test in IE < 9)', function() {
      equal(_.size(shadowed), 7);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.sortBy');

  (function() {
    test('supports the `thisArg` argument', function() {
      var actual = _.sortBy([1, 2, 3, 4], function(num) {
        return this.sin(num);
      }, Math);

      deepEqual(actual, [4, 3, 1, 2]);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.template');

  (function() {
    test('supports recursive calls', function() {
      var compiled = _.template('<%= a %><% a = _.template(c, object) %><%= a %>'),
          data = { 'a': 'A', 'b': 'B', 'c': '<%= b %>' };

      equal(compiled(data), 'AB');
    });

    test('should not augment the `options` object', function() {
      var options = {};
      _.template('', null, options);
      deepEqual(options, {});
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.throttle');

  (function() {
    test('subsequent calls should return the result of the first call', function() {
      var throttled = _.throttle(function(value) { return value; }, 100),
          result = [throttled('x'), throttled('y')];

      deepEqual(result, ['x', 'x']);
    });

    test('supports calls in a loop', function() {
      var counter = 0,
          throttled = _.throttle(function() { counter++; }, 100),
          start = new Date,
          limit = 220;

      while ((new Date - start) < limit) {
        throttled();
      }
      equal(counter, 3);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash.toArray');

  (function() {
    var args = arguments;

    test('should call custom `toArray` method of an array', function() {
      var array = [1, 2, 3];
      array.toArray = function() { return [3, 2, 1]; };
      deepEqual(_.toArray(array), [3, 2, 1]);
    });

    test('should treat array-like-objects like arrays', function() {
      var object = { '0': 'a', '1': 'b', '2': 'c', 'length': 3 };
      deepEqual(_.toArray(object), ['a', 'b', 'c']);
      deepEqual(_.toArray(args), [1, 2, 3]);
    });
  }(1, 2, 3));

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash(...).shift');

  (function() {
    test('should remove the value at index `0` when length is `0` (test in IE 8 compatibility mode)', function() {
      var wrapped = _({ '0': 1, 'length': 1 });
      wrapped.shift();

      deepEqual(wrapped.keys(), ['length']);
      equal(wrapped.first(), undefined);
    });
  }());

  /*--------------------------------------------------------------------------*/

  QUnit.module('lodash(...).splice');

  (function() {
    test('should remove the value at index `0` when length is `0` (test in IE < 9, and in compatibility mode for IE9)', function() {
      var wrapped = _({ '0': 1, 'length': 1 });
      wrapped.splice(0, 1);

      deepEqual(wrapped.keys(), ['length']);
      equal(wrapped.first(), undefined);
    });
  }());

  /*--------------------------------------------------------------------------*/

  // explicitly call `QUnit.start()` in a CLI environment
  if (!window.document) {
    QUnit.start();
  }
}(typeof global == 'object' && global || this));<|endoftext|>


<commit_before>import React from "react"
import Annotation from "./Annotation"
import classnames from "./classnames"

export default class EditableAnnotation extends React.Component {
  state = {
    x: 0,
    y: 0,
    dx: 0,
    dy: 0
  }

  componentWillMount() {
    this.setState({
      x: this.props.x,
      y: this.props.y,
      dx: this.props.dx,
      dy: this.props.dy
    })
  }

  getData() {
    return Object.assign({}, this.props, this.state)
  }

  dragEnd() {
    if (this.props.onDragEnd) {
      this.props.onDragEnd(this.getData())
    }
  }

  dragStart() {
    if (this.props.onDragStart) {
      this.props.onDragStart(this.getData())
    }
  }

  dragSubject(event, data) {
    console.log("in drag", data)
    // if (data.deltaX || data.deltaY) {
    this.setState(
      {
        x: this.state.x + data.deltaX,
        y: this.state.y + data.deltaY
      },
      () => {
        if (this.props.onDrag) this.props.onDrag(this.getData())
      }
    )
    // }
  }

  dragSubjectSettings(event, data) {
    this.setState(data, () => {
      if (this.props.onDrag) this.props.onDrag(this.getData())
    })
  }

  dragNote(event, data) {
    this.setState(
      {
        dx: this.state.dx + data.deltaX,
        dy: this.state.dy + data.deltaY
      },
      () => {
        if (this.props.onDrag) this.props.onDrag(this.getData())
      }
    )
  }

  render() {
    const cleanedProps = Object.assign({}, this.props, {
      ...this.state,
      dragSubject: this.dragSubject.bind(this),
      dragNote: this.dragNote.bind(this),
      dragSubjectSettings: this.dragSubjectSettings.bind(this),
      dragEnd: this.dragEnd.bind(this),
      dragStart: this.dragStart.bind(this),
      editMode: true,
      className: classnames(this.props.className, "editable")
    })

    return <Annotation {...cleanedProps} />
  }
}
<commit_msg>remove log<commit_after>import React from "react"
import Annotation from "./Annotation"
import classnames from "./classnames"

export default class EditableAnnotation extends React.Component {
  state = {
    x: 0,
    y: 0,
    dx: 0,
    dy: 0
  }

  componentWillMount() {
    this.setState({
      x: this.props.x,
      y: this.props.y,
      dx: this.props.dx,
      dy: this.props.dy
    })
  }

  getData() {
    return Object.assign({}, this.props, this.state)
  }

  dragEnd() {
    if (this.props.onDragEnd) {
      this.props.onDragEnd(this.getData())
    }
  }

  dragStart() {
    if (this.props.onDragStart) {
      this.props.onDragStart(this.getData())
    }
  }

  dragSubject(event, data) {
    this.setState(
      {
        x: this.state.x + data.deltaX,
        y: this.state.y + data.deltaY
      },
      () => {
        if (this.props.onDrag) this.props.onDrag(this.getData())
      }
    )
  }

  dragSubjectSettings(event, data) {
    this.setState(data, () => {
      if (this.props.onDrag) this.props.onDrag(this.getData())
    })
  }

  dragNote(event, data) {
    this.setState(
      {
        dx: this.state.dx + data.deltaX,
        dy: this.state.dy + data.deltaY
      },
      () => {
        if (this.props.onDrag) this.props.onDrag(this.getData())
      }
    )
  }

  render() {
    const cleanedProps = Object.assign({}, this.props, {
      ...this.state,
      dragSubject: this.dragSubject.bind(this),
      dragNote: this.dragNote.bind(this),
      dragSubjectSettings: this.dragSubjectSettings.bind(this),
      dragEnd: this.dragEnd.bind(this),
      dragStart: this.dragStart.bind(this),
      editMode: true,
      className: classnames(this.props.className, "editable")
    })

    return <Annotation {...cleanedProps} />
  }
}
<|endoftext|>


<commit_before>'use strict';

var test = require('tape');
var runner = require('../lib/runner');
var fs = require('fs');
var Interfake = require('interfake');
var _ = require('lodash');

//
//
//
test('Basics', function(t) {

  fs.readFile('test/scripts/hello.json', 'utf-8', function(err, contents) {

    if (err) {
      t.end(err);
    }

    var testScript = JSON.parse(contents);

    //
    // Check our assumptions about the test script
    //
    t.assert(
      testScript.config.phases.length === 1,
      'Expecting the test script to have one phase');
    t.assert(
      testScript.scenarios.length === 1,
      'Expecting the test script to have one scenario'
    );
    t.assert(
      testScript.scenarios[0].flow.length === 1,
      'Expecting the scenario to consist of just one request'
    );

    //
    // Set up our target
    //
    var interfakeOpts = {};
    if (process.env.DEBUG && process.env.DEBUG.match(/interfake/)) {
      interfakeOpts.debug = true;
    }
    var target = new Interfake(interfakeOpts);
    target.get('/test').status(200);
    target.listen(3000);

    //
    // Run the test
    //
    var ee = runner(testScript);

    ee.on('phaseStarted', function(opts) {

      t.ok(opts, 'phaseStarted event emitted');
    });

    ee.on('phaseCompleted', function(opts) {

      t.ok(opts, 'phaseCompleted event emitted');
    });

    ee.on('stats', function(stats) {

      t.ok(stats, 'intermediate stats event emitted');
    });

    ee.on('done', function(stats) {

      t.ok(stats, 'done event emitted');
      // var plausibleMax = testScript.config.phases[0].users * 1.1;
      // var plausibleMin = plausibleMax * 0.8;

      var requests = stats.completedRequests.toJSON();
      var scenarios = stats.completedScenarios.toJSON();
      console.log('requests = %s, scenarios = %s', requests, scenarios);
      // t.assert(
      //   requests >= plausibleMin && requests <= plausibleMax,
      //   'Reported plausible # of requests performed');
      // t.assert(
      //   scenarios >= plausibleMin && scenarios <= plausibleMax,
      //   'Reported plausible # of scenarios performed');
      target.stop();
      t.end();
    });
    ee.run();
  });

});

//
//
//
test('Multiple phases', function(t) {
  fs.readFile('test/scripts/multiple_phases.json', 'utf-8',
    function(err, contents) {

      if (err) {
        t.end(err);
      }

      var testScript = JSON.parse(contents);

      //
      // Set up our target
      //
      var interfakeOpts = {};
      if (process.env.DEBUG && process.env.DEBUG.match(/interfake/)) {
        interfakeOpts.debug = true;
      }
      var target = new Interfake(interfakeOpts);
      target.get('/test').status(200);
      target.listen(3001);

      var expectedPhases = testScript.config.phases.length * 2;
      var expectedStats = Math.floor(_.foldl(
        testScript.config.phases, function(acc, phase) {
          acc += phase.duration / 10;
          return acc;
        }, 0));

      console.log('expectedPhases: %s, expectedStats: %s',
        expectedPhases, expectedStats);

      //t.plan(expectedPhases + expectedStats);

      //
      // Run the test
      //
      var ee = runner(testScript);
      ee.on('phaseStarted', function(x) {
        t.ok(x, 'phaseStarted event emitted');
      });
      ee.on('phaseCompleted', function(x) {
        t.ok(x, 'phaseCompleted event emitted');
      });
      ee.on('stats', function(stats) {
        t.ok(stats, 'intermediate stats event emitted');
      });
      ee.on('done', function(stats) {
        target.stop();
        t.end();
      });

      ee.run();
    });
});

//
//
//
test('All features', function(t) {
  fs.readFile('test/scripts/all_features.json', 'utf-8',
    function(err, contents) {

      if (err) {
        t.end(err);
      }

      var testScript = JSON.parse(contents);

      //
      // Set up our target
      //
      var interfakeOpts = {};
      if (process.env.DEBUG && process.env.DEBUG.match(/interfake/)) {
        interfakeOpts.debug = true;
      }
      var target = new Interfake(interfakeOpts);
      target.get('/test').status(200);
      target.post('/test').status(200);
      target.listen(3002);

      //
      // Run the test
      //
      var ee = runner(testScript);
      ee.on('phaseStarted', function(x) {
        t.ok(x, 'phaseStarted event emitted');
      });
      ee.on('phaseCompleted', function(x) {
        t.ok(x, 'phaseCompleted event emitted');
      });
      ee.on('stats', function(stats) {
        t.ok(stats, 'intermediate stats event emitted');
      });
      ee.on('done', function(stats) {
        _.each(stats, function(v, k) {
          console.log('%s -> %s', k, JSON.stringify(v));
        });
        target.stop();
        t.end();
      });

      ee.run();
    });
});
<commit_msg>Tests: minor output fix<commit_after>'use strict';

var test = require('tape');
var runner = require('../lib/runner');
var fs = require('fs');
var Interfake = require('interfake');
var _ = require('lodash');

//
//
//
test('Basics', function(t) {

  fs.readFile('test/scripts/hello.json', 'utf-8', function(err, contents) {

    if (err) {
      t.end(err);
    }

    var testScript = JSON.parse(contents);

    //
    // Check our assumptions about the test script
    //
    t.assert(
      testScript.config.phases.length === 1,
      'Expecting the test script to have one phase');
    t.assert(
      testScript.scenarios.length === 1,
      'Expecting the test script to have one scenario'
    );
    t.assert(
      testScript.scenarios[0].flow.length === 1,
      'Expecting the scenario to consist of just one request'
    );

    //
    // Set up our target
    //
    var interfakeOpts = {};
    if (process.env.DEBUG && process.env.DEBUG.match(/interfake/)) {
      interfakeOpts.debug = true;
    }
    var target = new Interfake(interfakeOpts);
    target.get('/test').status(200);
    target.listen(3000);

    //
    // Run the test
    //
    var ee = runner(testScript);

    ee.on('phaseStarted', function(opts) {

      t.ok(opts, 'phaseStarted event emitted');
    });

    ee.on('phaseCompleted', function(opts) {

      t.ok(opts, 'phaseCompleted event emitted');
    });

    ee.on('stats', function(stats) {

      t.ok(stats, 'intermediate stats event emitted');
    });

    ee.on('done', function(stats) {

      t.ok(stats, 'done event emitted');
      // var plausibleMax = testScript.config.phases[0].users * 1.1;
      // var plausibleMin = plausibleMax * 0.8;

      var requests = stats.aggregate.completedRequests;
      var scenarios = stats.aggregate.completedScenarios;
      console.log('requests = %s, scenarios = %s', requests, scenarios);
      // t.assert(
      //   requests >= plausibleMin && requests <= plausibleMax,
      //   'Reported plausible # of requests performed');
      // t.assert(
      //   scenarios >= plausibleMin && scenarios <= plausibleMax,
      //   'Reported plausible # of scenarios performed');
      target.stop();
      t.end();
    });
    ee.run();
  });

});

//
//
//
test('Multiple phases', function(t) {
  fs.readFile('test/scripts/multiple_phases.json', 'utf-8',
    function(err, contents) {

      if (err) {
        t.end(err);
      }

      var testScript = JSON.parse(contents);

      //
      // Set up our target
      //
      var interfakeOpts = {};
      if (process.env.DEBUG && process.env.DEBUG.match(/interfake/)) {
        interfakeOpts.debug = true;
      }
      var target = new Interfake(interfakeOpts);
      target.get('/test').status(200);
      target.listen(3001);

      var expectedPhases = testScript.config.phases.length * 2;
      var expectedStats = Math.floor(_.foldl(
        testScript.config.phases, function(acc, phase) {
          acc += phase.duration / 10;
          return acc;
        }, 0));

      console.log('expectedPhases: %s, expectedStats: %s',
        expectedPhases, expectedStats);

      //t.plan(expectedPhases + expectedStats);

      //
      // Run the test
      //
      var ee = runner(testScript);
      ee.on('phaseStarted', function(x) {
        t.ok(x, 'phaseStarted event emitted');
      });
      ee.on('phaseCompleted', function(x) {
        t.ok(x, 'phaseCompleted event emitted');
      });
      ee.on('stats', function(stats) {
        t.ok(stats, 'intermediate stats event emitted');
      });
      ee.on('done', function(stats) {
        target.stop();
        t.end();
      });

      ee.run();
    });
});

//
//
//
test('All features', function(t) {
  fs.readFile('test/scripts/all_features.json', 'utf-8',
    function(err, contents) {

      if (err) {
        t.end(err);
      }

      var testScript = JSON.parse(contents);

      //
      // Set up our target
      //
      var interfakeOpts = {};
      if (process.env.DEBUG && process.env.DEBUG.match(/interfake/)) {
        interfakeOpts.debug = true;
      }
      var target = new Interfake(interfakeOpts);
      target.get('/test').status(200);
      target.post('/test').status(200);
      target.listen(3002);

      //
      // Run the test
      //
      var ee = runner(testScript);
      ee.on('phaseStarted', function(x) {
        t.ok(x, 'phaseStarted event emitted');
      });
      ee.on('phaseCompleted', function(x) {
        t.ok(x, 'phaseCompleted event emitted');
      });
      ee.on('stats', function(stats) {
        t.ok(stats, 'intermediate stats event emitted');
      });
      ee.on('done', function(stats) {
        _.each(stats, function(v, k) {
          console.log('%s -> %s', k, JSON.stringify(v));
        });
        target.stop();
        t.end();
      });

      ee.run();
    });
});
<|endoftext|>


<commit_before>export function updateValues(active, pct, values, scale) {
  return values.map(item => {
    if (item.key === active) {
      const { key, val } = item;
      const [min, max] = scale.domain();

      return { key, val: scale.invert(scale(val + (max - min) * pct)) };
    }

    return item;
  });
}

export function getSliderLength(slider, vertical) {
  if (!slider) {
    return 0;
  }

  const rect = slider.getBoundingClientRect();
  return vertical ? rect.height : rect.width;
}
<commit_msg>add precision function<commit_after>export function updateValues(active, pct, values, scale) {
  return values.map(item => {
    if (item.key === active) {
      const { key, val } = item;
      const [min, max] = scale.domain();

      return { key, val: scale.invert(scale(val + (max - min) * pct)) };
    }

    return item;
  });
}

export function getSliderLength(slider, vertical) {
  if (!slider) {
    return 0;
  }

  const rect = slider.getBoundingClientRect();
  return vertical ? rect.height : rect.width;
}

export function precision(a) {
  var match = ("" + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
  if (!match) {
    return 0;
  }

  return Math.max(
    0,
    (match[1] ? match[1].length : 0) - (match[2] ? +match[2] : 0)
  );
}
<|endoftext|>


<commit_before>const chai = require('chai');
const chaiHTTP = require('chai-http');
const server = require('../server/app');
const should = chai.should();

chai.use(chaiHTTP);

describe('Todos', function() {
  it('should list ALL todos on /api/todos GET', (done) => {
    chai.request(server)
      .get('/api/todos')
      .end((err, res) => {
        res.should.have.status(200);
        res.should.be.json;
        res.body.should.be.a('object');
        res.body.status.should.eq('success');
      done();
      });
  });
  it('should add a SINGLE todo on /todos POST');
  it('should update a SINGLE todo on /todo/<id> PUT');
  it('should delete a SINGLE todo on /todo/<id> DELETE');
});
<commit_msg>Add tests for Post Put and Delete<commit_after>const chai = require('chai');
const chaiHTTP = require('chai-http');
const server = require('../server/app');
const should = chai.should();

chai.use(chaiHTTP);

describe('Todos', function() {
  it('should list ALL todos on /api/todos GET', (done) => {
    chai.request(server)
      .get('/api/todos')
      .end((err, res) => {
        res.should.have.status(200);
        res.should.be.json;
        res.body.should.be.a('object');
        res.body.status.should.eq('success');
      done();
      });
  });

  it('should add a SINGLE todo on /api/todos POST', (done) => {
    chai.request(server)
      .post('/api/todos')
      .send({ "description": "fix hair", "status": false, "due": "09:00" })
      .end((err, res) => {
        res.should.have.status(200);
        res.should.be.json;
        res.body.message.should.equal('inserted a todo')
      done();
    });
  });

  it('should update a SINGLE todo on /todo/<id> PUT', (done) => {
      chai.request(server)
        .put('/api/todos/1')
        .send({ "description": "finish challenge", "status": false, "due": "10:00" })
        .end((err, res) => {
          res.should.have.status(200);
          res.body.message.should.equal('updated todo');
          res.should.be.json;
        done();
      });
  });

  it('should delete a SINGLE todo on /todo/<id> DELETE', (done) => {
    chai.request(server)
      .delete('/api/todos/1')
      .end((err, res) => {
        res.should.have.status(200);
        res.body.message.should.equal('Removed 1 todo');
      done();
    });
  });
});
<|endoftext|>


<commit_before>import test from 'ava';
import Next from '../src';

test('normal flow', async t => {
  let steps = [];

  await Next({
    for: () => {
      const list = [1, 2];
      steps.push(`for ${list}`);
      return list;
    },
    each: (d) => {
      steps.push(`each ${d}`);
      return {
        for: () => {
          steps.push(`each for ${d}`);
          return d;
        },
        each: (d) => {
          steps.push(`each each ${d}`);
          return d;
        },
        next: () => {
          steps.push(`each next ${d}`);
        },
      }
    },
    next: () => {
      steps.push('next');
    },
  });
  t.deepEqual(steps, [
    'for 1,2',
    'each 1',
    'each for 1',
    'each each 1',
    'each next 1',
    'each 2',
    'each for 2',
    'each each 2',
    'each next 2',
    'next',
  ]);
});

test('shouldNext', async t => {
  let steps = [];

  await Next({
    for: () => {
      const list = [1, 2];
      steps.push(`for ${list}`);
      return list;
    },
    each: (d) => {
      steps.push(`each ${d}`);
      return {
        for: () => {
          steps.push(`each for ${d}`);
          return d;
        },
        each: (data) => {
          steps.push(`each each ${data}`);
          return d;
        },
        shouldNext: () => {
          if (d === 1) {
            return true;
          }
        },
        next: () => {
          steps.push(`each next ${d}`);
        },
      };
    },
    shouldNext: () => {
      return false;
    },
    next: () => {
      steps.push('next');
    },
  });
  t.deepEqual(steps, [
    'for 1,2',
    'each 1',
    'each for 1',
    'each each 1',
    'each next 1',
    'each 2',
    'each for 2',
    'each each 2',
  ]);
});

test('catch error', async t => {
  let steps = [];

  await Next({
    for: () => {
      const list = [1, 2];
      steps.push(`for ${list}`);
      return list;
    },
    each: (d) => {
      steps.push(`each ${d}`);
      if (d === 2) {
        throw new Error(d);
      }
      return {
        for: () => {
          steps.push(`each for ${d}`);
          return d;
        },
        each: (d) => {
          steps.push(`each each ${d}`);
          return {
            next: () => {
              if (d == 1) {
                throw new Error(d);
              }
            },
          };
        },
        catch: (err) => {
          steps.push(`each catch`);
        },
        next: () => {
          steps.push(`each next ${d}`);
        },
      };
    },
    next: () => {
      steps.push('next');
    },
    catch: (err) => {
      steps.push('catch')
    },
  });
  t.deepEqual(steps, [
    'for 1,2',
    'each 1',
    'each for 1',
    'each each 1',
    'each catch',
    'each 2',
    'catch'
  ]);
});
<commit_msg>update test<commit_after>import test from 'ava';
import Next from '../src';

test('normal flow', async t => {
  let steps = [];

  await Next({
    for: () => {
      const list = [1, 2];
      steps.push(`for ${list}`);
      return list;
    },
    each: (d) => {
      steps.push(`each ${d}`);
      return {
        for: () => {
          steps.push(`each for ${d}`);
          return d;
        },
        each: (d) => {
          steps.push(`each each ${d}`);
          return d;
        },
        next: () => {
          steps.push(`each next ${d}`);
        },
      }
    },
    next: () => {
      steps.push('next');
    },
  });
  t.deepEqual(steps, [
    'for 1,2',
    'each 1',
    'each for 1',
    'each each 1',
    'each next 1',
    'each 2',
    'each for 2',
    'each each 2',
    'each next 2',
    'next',
  ]);
});

test('shouldNext', async t => {
  let steps = [];

  await Next({
    for: () => {
      const list = [1, 2];
      steps.push(`for ${list}`);
      return list;
    },
    each: (d) => {
      steps.push(`each ${d}`);
      return {
        for: () => {
          steps.push(`each for ${d}`);
          return d;
        },
        each: (data) => {
          steps.push(`each each ${data}`);
          return d;
        },
        shouldNext: () => {
          if (d === 1) {
            return true;
          }
        },
        next: () => {
          steps.push(`each next ${d}`);
        },
      };
    },
    shouldNext: () => {
      return false;
    },
    next: () => {
      steps.push('next');
    },
  });
  t.deepEqual(steps, [
    'for 1,2',
    'each 1',
    'each for 1',
    'each each 1',
    'each next 1',
    'each 2',
    'each for 2',
    'each each 2',
  ]);
});

test('catch error', async t => {
  let steps = [];

  await Next({
    for: () => {
      const list = [1, 2];
      steps.push(`for ${list}`);
      return list;
    },
    each: (d) => {
      steps.push(`each ${d}`);
      if (d === 2) {
        throw new Error(d);
      }
      return {
        for: () => {
          steps.push(`each for ${d}`);
          return d;
        },
        each: (d) => {
          steps.push(`each each ${d}`);
          return {
            next: () => {
              if (d == 1) {
                throw new Error(d);
              }
            },
          };
        },
        catch: (err) => {
          steps.push(`each catch`);
        },
        next: () => {
          steps.push(`each next ${d}`);
        },
      };
    },
    next: () => {
      steps.push('next');
    },
    catch: (err) => {
      steps.push('catch')
    },
  });
  t.deepEqual(steps, [
    'for 1,2',
    'each 1',
    'each for 1',
    'each each 1',
    'each catch',
    'each next 1',
    'each 2',
    'catch',
    'next',
  ]);
});
<|endoftext|>


<commit_before>'use strict';
var should       = require('should');
var mkdirp       = require('mkdirp');
var cp           = require('child_process');
var path         = require('path');
var rimraf       = require('rimraf');
var outpath      = path.join(__dirname, '/project');
var jlboxPath    = path.join(__dirname, '../bin/jlbox.js');
var fs           = require('fs');
var events       = require('events');
var jlboxEmitter = new events.EventEmitter();
var child;
require('mocha');

describe('jlbox', function() {
  before(function(done) {
    mkdirp(outpath, done);
  });

  describe('jlbox commands', function() {
    it('should bootstrap project via init command', function(done) {
      this.timeout(60000);
      cp.exec(jlboxPath + ' init', {cwd: outpath}, function(err, stdout) {
        if (err) return done(err);
        console.log(stdout);
        fs.existsSync(path.join(outpath, 'test')).should.be.true;
        fs.existsSync(path.join(outpath, 'src')).should.be.true;
        fs.existsSync(path.join(outpath, 'gulpfile.js')).should.be.true;
        fs.existsSync(path.join(outpath, 'gulp.jl')).should.be.true;
        fs.existsSync(path.join(outpath, 'package.json')).should.be.true;
        fs.existsSync(path.join(outpath, 'node_modules')).should.be.true;
        fs.existsSync(path.join(outpath, 'test/helper.jl')).should.be.true;
        return done();
      });
    });

    it('should bootstrap module files via module command', function(done) {
      cp.exec(jlboxPath + ' module Sample', {cwd: outpath}, function(err) {
        if(err) return done(err);
        fs.existsSync(path.join(outpath, 'src/Sample.jl')).should.be.true;
        fs.existsSync(path.join(outpath, 'src/Sample.jl')).should.be.true;
        fs.existsSync(path.join(outpath, 'test/Sample_test.jl')).should.be.true;
        return done();
      });
    });
  });

  describe('jlbox watch', function() {
    before(function(done) {
      this.timeout(15000);
      child = cp.spawn('gulp', {cwd: outpath});
      var count = 0;
      child.stdout.setEncoding('utf8');
      child.stdout.on('data', function(data) {
        data = data.trim();
        if (data) {
          console.log(data);
          if (data.match(/Waiting for changes/)) {
            // if it's the first time, then call done
            if (count === 0) {
              count += 1;
              done();
            }
            // otherwise emit an event that the test should list for
            else {
              jlboxEmitter.emit('jlbox:done', true);
            }
          }
        }
      });

      child.stderr.setEncoding('utf8');
      child.stderr.on('data', function(data) {
        console.log('err');
        console.log(data);
      });
    });

    var hook;
    beforeEach(function(){
      hook = captureStream(process.stdout);
    });

    afterEach(function(){
      hook.unhook();
    });

    // clean up child process and folder at the end
    after(function(done) {
      child.kill('SIGINT');
      return rimraf(outpath, done);
    });

    // NOTE: use different file names for each test, otherwise gulp/gaze will think they are the same event, given they happen so quickly, and ignore one.
    // alternatively, you can use setTimeout on each test of about 1000ms if you want to modify the same file twice
    it('should re-run test when module is changed', function(done) {
      this.timeout(15000);
      fs.writeFile(path.join(outpath, '/src/Sample.jl'), "module Sample\n\nend\n", function(err) {
        if (err) return done(err);
        return jlboxEmitter.once('jlbox:done', function() {
          should.exist(hook.captured().match(/0 facts verified/));
          return done();
        });
      });
    });

    it('should re-run test when test is changed', function(done) {
      this.timeout(15000);
      var content = 'module SampleTest\n' +
            'include("$(pwd())/test/helper.jl")\n' +
            'reload("$(pwd())/src/Sample.jl")\n' +
            'using Sample\n' +
            'facts("Sample") do\n' +
            '@fact 1 => 1\n' +
            'end\n' +
            'end # module SampleTest\n';
      fs.writeFile(path.join(outpath, '/test/Sample_test.jl'), content, function(err) {
        if (err) return done(err);
        return jlboxEmitter.once('jlbox:done', function() {
          should.exist(hook.captured().match(/1 fact verified/));
          return done();
        });
      });
    });

    it('should restart julia when there is a syntax error', function(done) {
      this.timeout(15000);
      var content = 'module SampleTest2\n' +
            'include("$(pwd())/test/helper.jl")\n' +
            'facts("Sample2") do\n' +
            '@fact 1 => 1:\n' +
            'end\n' +
            'end # module Sample2Test\n';
      fs.writeFile(path.join(outpath, '/test/Sample_test2.jl'), content, function(err) {
        if (err) return done(err);
        return jlboxEmitter.once('jlbox:done', function() {
          should.exist(hook.captured().match(/ZMQ bound/));
          return done();
        });
      });
    });

    // http://stackoverflow.com/questions/18543047/mocha-monitor-application-output
    function captureStream(stream){
      var oldWrite = stream.write;
      var buf = '';
      stream.write = function(chunk, encoding, callback){
        buf += chunk.toString(); // chunk is a String or Buffer
        oldWrite.apply(stream, arguments);
      };

      return {
        unhook: function unhook(){
          stream.write = oldWrite;
        },
        captured: function(){
          return buf;
        }
      };
    }
  });
});
<commit_msg>increase test timeouts<commit_after>'use strict';
var should       = require('should');
var mkdirp       = require('mkdirp');
var cp           = require('child_process');
var path         = require('path');
var rimraf       = require('rimraf');
var outpath      = path.join(__dirname, '/project');
var jlboxPath    = path.join(__dirname, '../bin/jlbox.js');
var fs           = require('fs');
var events       = require('events');
var jlboxEmitter = new events.EventEmitter();
var child;
require('mocha');

describe('jlbox', function() {
  before(function(done) {
    mkdirp(outpath, done);
  });

  describe('jlbox commands', function() {
    it('should bootstrap project via init command', function(done) {
      this.timeout(60000);
      cp.exec(jlboxPath + ' init', {cwd: outpath}, function(err, stdout) {
        if (err) return done(err);
        console.log(stdout);
        fs.existsSync(path.join(outpath, 'test')).should.be.true;
        fs.existsSync(path.join(outpath, 'src')).should.be.true;
        fs.existsSync(path.join(outpath, 'gulpfile.js')).should.be.true;
        fs.existsSync(path.join(outpath, 'gulp.jl')).should.be.true;
        fs.existsSync(path.join(outpath, 'package.json')).should.be.true;
        fs.existsSync(path.join(outpath, 'node_modules')).should.be.true;
        fs.existsSync(path.join(outpath, 'test/helper.jl')).should.be.true;
        return done();
      });
    });

    it('should bootstrap module files via module command', function(done) {
      cp.exec(jlboxPath + ' module Sample', {cwd: outpath}, function(err) {
        if(err) return done(err);
        fs.existsSync(path.join(outpath, 'src/Sample.jl')).should.be.true;
        fs.existsSync(path.join(outpath, 'src/Sample.jl')).should.be.true;
        fs.existsSync(path.join(outpath, 'test/Sample_test.jl')).should.be.true;
        return done();
      });
    });
  });

  describe('jlbox watch', function() {
    before(function(done) {
      this.timeout(60000);
      child = cp.spawn('gulp', {cwd: outpath});
      var count = 0;
      child.stdout.setEncoding('utf8');
      child.stdout.on('data', function(data) {
        data = data.trim();
        if (data) {
          console.log(data);
          if (data.match(/Waiting for changes/)) {
            // if it's the first time, then call done
            if (count === 0) {
              count += 1;
              done();
            }
            // otherwise emit an event that the test should list for
            else {
              jlboxEmitter.emit('jlbox:done', true);
            }
          }
        }
      });

      child.stderr.setEncoding('utf8');
      child.stderr.on('data', function(data) {
        console.log('err');
        console.log(data);
      });
    });

    var hook;
    beforeEach(function(){
      hook = captureStream(process.stdout);
    });

    afterEach(function(){
      hook.unhook();
    });

    // clean up child process and folder at the end
    after(function(done) {
      child.kill('SIGINT');
      return rimraf(outpath, done);
    });

    // NOTE: use different file names for each test, otherwise gulp/gaze will think they are the same event, given they happen so quickly, and ignore one.
    // alternatively, you can use setTimeout on each test of about 1000ms if you want to modify the same file twice
    it('should re-run test when module is changed', function(done) {
      this.timeout(60000);
      fs.writeFile(path.join(outpath, '/src/Sample.jl'), "module Sample\n\nend\n", function(err) {
        if (err) return done(err);
        return jlboxEmitter.once('jlbox:done', function() {
          should.exist(hook.captured().match(/0 facts verified/));
          return done();
        });
      });
    });

    it('should re-run test when test is changed', function(done) {
      this.timeout(60000);
      var content = 'module SampleTest\n' +
            'include("$(pwd())/test/helper.jl")\n' +
            'reload("$(pwd())/src/Sample.jl")\n' +
            'using Sample\n' +
            'facts("Sample") do\n' +
            '@fact 1 => 1\n' +
            'end\n' +
            'end # module SampleTest\n';
      fs.writeFile(path.join(outpath, '/test/Sample_test.jl'), content, function(err) {
        if (err) return done(err);
        return jlboxEmitter.once('jlbox:done', function() {
          should.exist(hook.captured().match(/1 fact verified/));
          return done();
        });
      });
    });

    it('should restart julia when there is a syntax error', function(done) {
      this.timeout(60000);
      var content = 'module SampleTest2\n' +
            'include("$(pwd())/test/helper.jl")\n' +
            'facts("Sample2") do\n' +
            '@fact 1 => 1:\n' +
            'end\n' +
            'end # module Sample2Test\n';
      fs.writeFile(path.join(outpath, '/test/Sample_test2.jl'), content, function(err) {
        if (err) return done(err);
        return jlboxEmitter.once('jlbox:done', function() {
          should.exist(hook.captured().match(/ZMQ bound/));
          return done();
        });
      });
    });

    // http://stackoverflow.com/questions/18543047/mocha-monitor-application-output
    function captureStream(stream){
      var oldWrite = stream.write;
      var buf = '';
      stream.write = function(chunk, encoding, callback){
        buf += chunk.toString(); // chunk is a String or Buffer
        oldWrite.apply(stream, arguments);
      };

      return {
        unhook: function unhook(){
          stream.write = oldWrite;
        },
        captured: function(){
          return buf;
        }
      };
    }
  });
});
<|endoftext|>


<commit_before>import React from 'react'
import PropTypes from 'prop-types'
import {
  Badge,
  Button,
  Card,
  CardHeading,
  CardTitle,
  CardBody,
  CardFooter,
  Icon,
  noop,
  excludeKeys,
} from 'patternfly-react'

import style from './style.css'
import CardEditButton from './CardEditButton'

/**
 * Base VM details card.  Support common layouts and view vs edit modes.
 *
 * Specifying __editMode__ allows the containing component to control the card's
 * edit state.  Leave __editMode__ undefined to allow the card to control itself.
 *
 * When the user interacts with the card, the card will fire event handler:
 *  - When in non-edit state, user clicks the __Edit__ icon -> onStartEdit() is called
 *  - When in edit state, user clicks the __Cancel__ button -> onCancel() is called
 *  - When in edit state, user clicks the __Save__ button -> onSave() is called
 *
 * If any of the event handlers return false, the card will not transition its edit state.
 * This allows data validation or async operation completion.
 */
class BaseCard extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      edit: props.editMode,
    }
    this.propTypeKeys = Object.keys(BaseCard.propTypes)
  }

  clickEdit = () => {
    if (this.props.onStartEdit() !== false) {
      this.setState({ edit: true })
    }
  }

  clickCancel = () => {
    if (this.props.onCancel() !== false) {
      this.setState({ edit: false })
    }
  }

  clickSave = () => {
    if (this.props.onSave() !== false) {
      this.setState({ edit: false })
    }
  }

  render () {
    const {
      title = undefined,
      icon = undefined,
      itemCount = undefined,
      editMode = undefined,
      editable = true,
      editTooltip,
      children = noop,
    } = this.props
    const editing = editMode === undefined ? this.state.edit : editMode
    const hasHeading = !!title
    const hasBadge = itemCount !== undefined
    const hasIcon = icon && icon.type && icon.name

    return (
      <Card className={style['base-card']} {...excludeKeys(this.props, this.propTypeKeys)}>
        {hasHeading && (
          <CardHeading className={style['base-card-heading']}>
            {editable && <CardEditButton tooltip={editTooltip} editEnabled={editing} onClick={this.clickEdit} />}
            <CardTitle>
              {hasIcon && <Icon type={icon.type} name={icon.name} className={style['base-card-title-icon']} />}
              {title}
              {hasBadge && <Badge className={style['base-card-item-count-badge']}>{itemCount}</Badge>}
            </CardTitle>
          </CardHeading>
        )}

        <CardBody className={style['base-card-body']}>
          {(!hasHeading && editable) && (
            <CardEditButton tooltip={editTooltip} editEnabled={editing} onClick={this.clickEdit} />
          )}

          {children({ isEditing: editing })}
        </CardBody>

        {editing && (
          <CardFooter className={style['base-card-footer']}>
            <Button bsStyle='primary' onClick={this.clickSave}><Icon type='fa' name='check' /></Button>
            <Button onClick={this.clickCancel}><Icon type='pf' name='close' /></Button>
          </CardFooter>
        )}
      </Card>
    )
  }
}
BaseCard.propTypes = {
  title: PropTypes.string,
  icon: PropTypes.shape({
    type: PropTypes.string.isRequired,
    name: PropTypes.string.isRequired,
  }),
  itemCount: PropTypes.number,

  editMode: PropTypes.bool,
  editable: PropTypes.bool,
  editTooltip: PropTypes.string,

  onStartEdit: PropTypes.func,
  onCancel: PropTypes.func,
  onSave: PropTypes.func,
  children: PropTypes.func,
}
BaseCard.defaultProps = {
  onStartEdit: noop,
  onCancel: noop,
  onSave: noop,
}

export default BaseCard
<commit_msg>refine BaseCard event handlers and children render<commit_after>import React from 'react'
import PropTypes from 'prop-types'
import {
  Badge,
  Button,
  Card,
  CardHeading,
  CardTitle,
  CardBody,
  CardFooter,
  Icon,
  noop,
  excludeKeys,
} from 'patternfly-react'

import style from './style.css'
import CardEditButton from './CardEditButton'

/**
 * Base VM details card.  Support common layouts and view vs edit modes.
 *
 * Content of the component may vary based on the edit state of the card. Children
 * may be a function of the form -
 *   ({ isEditing }) => ...
 *
 * an element of the form -
 *   <Element isEditing={true/false} />
 *
 * or any other node type.
 *
 * __editMode__ allows the containing component to control the card's edit state.
 *              Leave it undefined to allow the card to control itself.
 *
 * As a user interacts with the card, events are fired. If any of the event
 * handlers return false, the card will not transition its edit state. This
 * allows data validation or async operation completion.
 *
 *   Events while in non-edit state -
 *     user clicks the __Edit__ icon -> onStartEdit()
 *
 *   Events while in edit state -
 *     user clicks the __Cancel__ button -> onCancel()
 *     user clicks the __Save__ button -> onSave()
 */
class BaseCard extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      edit: props.editMode,
    }
    this.propTypeKeys = Object.keys(BaseCard.propTypes)

    this.clickEdit = this.clickEdit.bind(this)
    this.clickCancel = this.clickCancel.bind(this)
    this.clickSave = this.clickSave.bind(this)
    this.renderChildren = this.renderChildren.bind(this)
  }

  clickEdit () {
    if (this.props.onStartEdit() !== false) {
      this.setState({ edit: true })
    }
  }

  clickCancel () {
    if (this.props.onCancel() !== false) {
      this.setState({ edit: false })
    }
  }

  clickSave () {
    if (this.props.onSave() !== false) {
      this.setState({ edit: false })
    }
  }

  renderChildren (childProps) {
    const children = this.props.children || noop
    return typeof children === 'function' ? children(childProps)
      : React.isValidElement(children) ? React.cloneElement(children, childProps)
        : children
  }

  render () {
    const {
      title = undefined,
      icon = undefined,
      itemCount = undefined,
      editMode = undefined,
      editable = true,
      editTooltip,
    } = this.props
    const editing = editMode === undefined ? this.state.edit : editMode
    const hasHeading = !!title
    const hasBadge = itemCount !== undefined
    const hasIcon = icon && icon.type && icon.name

    const RenderChildren = this.renderChildren
    return (
      <Card className={style['base-card']} {...excludeKeys(this.props, this.propTypeKeys)}>
        {hasHeading && (
          <CardHeading className={style['base-card-heading']}>
            {editable && <CardEditButton tooltip={editTooltip} editEnabled={editing} onClick={this.clickEdit} />}
            <CardTitle>
              {hasIcon && <Icon type={icon.type} name={icon.name} className={style['base-card-title-icon']} />}
              {title}
              {hasBadge && <Badge className={style['base-card-item-count-badge']}>{itemCount}</Badge>}
            </CardTitle>
          </CardHeading>
        )}

        <CardBody className={style['base-card-body']}>
          {(!hasHeading && editable) && (
            <CardEditButton tooltip={editTooltip} editEnabled={editing} onClick={this.clickEdit} />
          )}

          <RenderChildren isEditing={editing} />
        </CardBody>

        {editing && (
          <CardFooter className={style['base-card-footer']}>
            <Button bsStyle='primary' onClick={this.clickSave}><Icon type='fa' name='check' /></Button>
            <Button onClick={this.clickCancel}><Icon type='pf' name='close' /></Button>
          </CardFooter>
        )}
      </Card>
    )
  }
}
BaseCard.propTypes = {
  title: PropTypes.string,
  icon: PropTypes.shape({
    type: PropTypes.string.isRequired,
    name: PropTypes.string.isRequired,
  }),
  itemCount: PropTypes.number,

  editMode: PropTypes.bool,
  editable: PropTypes.bool,
  editTooltip: PropTypes.string,

  onStartEdit: PropTypes.func,
  onCancel: PropTypes.func,
  onSave: PropTypes.func,
  children: PropTypes.oneOfType([ PropTypes.func, PropTypes.node ]).isRequired,
}
BaseCard.defaultProps = {
  onStartEdit: noop,
  onCancel: noop,
  onSave: noop,
}

export default BaseCard
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import Touchable from 'rc-touchable';

class InputHandler extends Component {
  render() {
    const props = { ...this.props };
    const { prefixCls, disabled } = props;
    delete props.prefixCls;
    return (
      <Touchable
        disabled={disabled}
        activeClassName={`${prefixCls}-handler-active`}
      >
      <span {...props}>
        {props.children}
      </span>
      </Touchable>);
  }
}

export default InputHandler;
<commit_msg>refactor code<commit_after>import React, { Component } from 'react';
import Touchable from 'rc-touchable';

export default class InputHandler extends Component {
  render() {
    const { prefixCls, disabled, ...otherProps } = this.props;
    return (
      <Touchable disabled={disabled} activeClassName={`${prefixCls}-handler-active`}>
        <span {...otherProps} />
      </Touchable>
    );
  }
}
<|endoftext|>


<commit_before>/*
 * evaluate.js
 * Objective-J
 *
 * Created by Francisco Tolmasky.
 * Copyright 2008, 280 North, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

var objj_included_files = { };

var FRAGMENT_CODE   = 1,

    FRAGMENT_FILE   = 1 << 2,
    FRAGMENT_LOCAL  = 1 << 3;

function objj_fragment()
{
    this.info       = NULL;
    this.type       = 0;
    this.context    = NULL;
    this.bundle     = NULL;
    this.file       = NULL;
}

#define EVALUATION_PERIOD 3000

function objj_context()
{
    this.fragments  = [];
    this.scheduled  = NO;
    this.blocked    = NO;
}

#define SET_CONTEXT(aFragment, aContext) aFragment.context = aContext
#define GET_CONTEXT(aFragment) aFragment.context

#define SET_TYPE(aFragment, aType) aFragment.type = (aType)
#define GET_TYPE(aFragment) aFragment.type

#define GET_CODE(aFragment) aFragment.info
#define SET_CODE(aFragment, aCode) aFragment.info = (aCode)

#define GET_PATH(aFragment) aFragment.info
#define SET_PATH(aFragment, aPath) aFragment.info = aPath

#define GET_BUNDLE(aFragment) aFragment.bundle
#define SET_BUNDLE(aFragment, aBundle) aFragment.bundle = aBundle

#define GET_FILE(aFragment) aFragment.file
#define SET_FILE(aFragment, aFile) aFragment.file = aFile

#define IS_FILE(aFragment) (aFragment.type & FRAGMENT_FILE)
#define IS_LOCAL(aFragment) (aFragment.type & FRAGMENT_LOCAL)

objj_fragment.prototype.toMarkedString = function()
{
    return IS_FILE(this) ?  (IS_LOCAL(this) ? MARKER_IMPORT_LOCAL : MARKER_IMPORT_STD) + ';' + GET_PATH(this).length + ';' + GET_PATH(this) :
                            MARKER_CODE + ';' + GET_CODE(this).length + ';' + GET_CODE(this);
}

function fragment_create_code(aCode, aBundle, aFile)
{
    var fragment = new objj_fragment();

    SET_TYPE(fragment, FRAGMENT_CODE);
    SET_CODE(fragment, aCode);
    SET_BUNDLE(fragment, aBundle);
    SET_FILE(fragment, aFile);

    return fragment;
}

function fragment_create_file(aPath, aBundle, isLocal, aFile)
{
    var fragment = new objj_fragment();

    SET_TYPE(fragment, FRAGMENT_FILE | (FRAGMENT_LOCAL * isLocal));
    SET_PATH(fragment, aPath);
    SET_BUNDLE(fragment, aBundle);
    SET_FILE(fragment, aFile);

    return fragment;
}

objj_context.prototype.evaluate = function()
{
    this.scheduled = NO;

    // If we're blocked by IO, then just reschedule.
    if (this.blocked)
        return this.schedule();

    // If not, begin the evaluation loop.
    var sleep = NO,
        start = new Date(),
        fragments = this.fragments;

    while (!sleep && fragments.length)
    {
        var fragment = fragments.pop();

        if (IS_FILE(fragment))
            sleep = fragment_evaluate_file(fragment);
        else
            sleep = fragment_evaluate_code(fragment);

        // Sleep evaluation if we've been at it too long to avoid
        // unresponsive script errors.
        sleep = sleep || ((new Date() - start) > EVALUATION_PERIOD);
    }

    if (sleep)
        this.schedule();

    else if (this.didCompleteCallback)
        this.didCompleteCallback(this);
}

objj_context.prototype.schedule = function()
{
    if (this.scheduled)
        return;

    this.scheduled = YES;

    var context = this;

    window.setNativeTimeout(function () { context.evaluate(); }, 0);
}

objj_context.prototype.pushFragment = function(aFragment)
{
    SET_CONTEXT(aFragment, this);

    this.fragments.push(aFragment);
}

function fragment_evaluate_code(aFragment)
{
    var compiled;

    OBJJ_CURRENT_BUNDLE = GET_BUNDLE(aFragment);

    try
    {
#if RHINO
        var functionText = "function(){"+GET_CODE(aFragment)+"/**/\n}";
        if (window.isRhino)
            compiled = Packages.org.mozilla.javascript.Context.getCurrentContext().compileFunction(window, functionText, GET_FILE(aFragment).path, 0, null);
        else
            compiled = eval(functionText);
#else
        compiled = new Function(GET_CODE(aFragment));
        compiled.displayName = GET_FILE(aFragment).path;
#endif
    }
    catch(anException)
    {
        objj_exception_report(anException, GET_FILE(aFragment));
    }

#if RHINO
    compiled();
#else
    try
    {
        compiled();
    }
    catch(anException)
    {
        objj_exception_report(anException, GET_FILE(aFragment));
    }
#endif

    return NO;
}

function fragment_evaluate_file(aFragment)
{
    var context = GET_CONTEXT(aFragment),
        requiresSleep = YES;

    // Make us IO Blocked until we receive the file.
    context.blocked = YES;

    objj_request_file(GET_PATH(aFragment), IS_LOCAL(aFragment), function(aFile)
    {
        // Use the captured value from the closure.  If objj_request_file
        // returns immediately, then this will cause us to avoid breaking,
        // but if it doesn't, then this will have no effect.
        requiresSleep = NO;

        // We've received the file, so no longer block execution.
        context.blocked = NO;

        // FIXME: We need to actually support this, and handle it better
        // as well.
        if (aFile == OBJJ_NO_FILE)
            objj_alert("uh oh!");

        // If this file has already been included, skip it and bail.
        if (objj_included_files[aFile.path])
            return;

        // If not, then mark it as included, for future imports.
        objj_included_files[aFile.path] = YES;

        // Grab the file's fragments if it has them, or preprocess it if not.
        if (!aFile.fragments)
            aFile.fragments = objj_preprocess(aFile.contents, aFile.bundle, aFile, OBJJ_PREPROCESSOR_DEBUG_SYMBOLS);

        var fragments = aFile.fragments,
            count = fragments.length,
            directory = aFile.path.substr(0, aFile.path.lastIndexOf('/') + 1);

        // Put the individual fragments at the head of the evaluation
        // stack to be evaluated.
        while (count--)
        {
            var fragment = fragments[count];

            if (IS_FILE(fragment))
            {
                if (IS_LOCAL(fragment))
                    SET_PATH(fragment, directory + GET_PATH(fragment));

                objj_request_file(GET_PATH(fragment), IS_LOCAL(fragment), NULL);
            }

            context.pushFragment(fragment);
        }
    });

    return requiresSleep;
}

function objj_import(/*String | Array*/ pathOrPaths, /*BOOL*/ isLocal, /*Function*/ didCompleteCallback)
{
    var context = new objj_context(),
        paths = pathOrPaths;

    if (typeof paths === "string")
        paths = [paths];

    var index = 0,
        count = paths.length;

    for (; index < count; ++index)
        context.pushFragment(fragment_create_file(paths[index], new objj_bundle(""), isLocal, NULL));

    context.didCompleteCallback = didCompleteCallback;

    context.evaluate();
}
<commit_msg>Added support for the "//@ sourceName" convention tell debuggers our file names. http://pmuellr.blogspot.com/2009/06/debugger-friendly.html<commit_after>/*
 * evaluate.js
 * Objective-J
 *
 * Created by Francisco Tolmasky.
 * Copyright 2008, 280 North, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

var objj_included_files = { };

var FRAGMENT_CODE   = 1,

    FRAGMENT_FILE   = 1 << 2,
    FRAGMENT_LOCAL  = 1 << 3;

function objj_fragment()
{
    this.info       = NULL;
    this.type       = 0;
    this.context    = NULL;
    this.bundle     = NULL;
    this.file       = NULL;
}

#define EVALUATION_PERIOD 3000

function objj_context()
{
    this.fragments  = [];
    this.scheduled  = NO;
    this.blocked    = NO;
}

#define SET_CONTEXT(aFragment, aContext) aFragment.context = aContext
#define GET_CONTEXT(aFragment) aFragment.context

#define SET_TYPE(aFragment, aType) aFragment.type = (aType)
#define GET_TYPE(aFragment) aFragment.type

#define GET_CODE(aFragment) aFragment.info
#define SET_CODE(aFragment, aCode) aFragment.info = (aCode)

#define GET_PATH(aFragment) aFragment.info
#define SET_PATH(aFragment, aPath) aFragment.info = aPath

#define GET_BUNDLE(aFragment) aFragment.bundle
#define SET_BUNDLE(aFragment, aBundle) aFragment.bundle = aBundle

#define GET_FILE(aFragment) aFragment.file
#define SET_FILE(aFragment, aFile) aFragment.file = aFile

#define IS_FILE(aFragment) (aFragment.type & FRAGMENT_FILE)
#define IS_LOCAL(aFragment) (aFragment.type & FRAGMENT_LOCAL)

objj_fragment.prototype.toMarkedString = function()
{
    return IS_FILE(this) ?  (IS_LOCAL(this) ? MARKER_IMPORT_LOCAL : MARKER_IMPORT_STD) + ';' + GET_PATH(this).length + ';' + GET_PATH(this) :
                            MARKER_CODE + ';' + GET_CODE(this).length + ';' + GET_CODE(this);
}

function fragment_create_code(aCode, aBundle, aFile)
{
    var fragment = new objj_fragment();

    SET_TYPE(fragment, FRAGMENT_CODE);
    SET_CODE(fragment, aCode);
    SET_BUNDLE(fragment, aBundle);
    SET_FILE(fragment, aFile);

    return fragment;
}

function fragment_create_file(aPath, aBundle, isLocal, aFile)
{
    var fragment = new objj_fragment();

    SET_TYPE(fragment, FRAGMENT_FILE | (FRAGMENT_LOCAL * isLocal));
    SET_PATH(fragment, aPath);
    SET_BUNDLE(fragment, aBundle);
    SET_FILE(fragment, aFile);

    return fragment;
}

objj_context.prototype.evaluate = function()
{
    this.scheduled = NO;

    // If we're blocked by IO, then just reschedule.
    if (this.blocked)
        return this.schedule();

    // If not, begin the evaluation loop.
    var sleep = NO,
        start = new Date(),
        fragments = this.fragments;

    while (!sleep && fragments.length)
    {
        var fragment = fragments.pop();

        if (IS_FILE(fragment))
            sleep = fragment_evaluate_file(fragment);
        else
            sleep = fragment_evaluate_code(fragment);

        // Sleep evaluation if we've been at it too long to avoid
        // unresponsive script errors.
        sleep = sleep || ((new Date() - start) > EVALUATION_PERIOD);
    }

    if (sleep)
        this.schedule();

    else if (this.didCompleteCallback)
        this.didCompleteCallback(this);
}

objj_context.prototype.schedule = function()
{
    if (this.scheduled)
        return;

    this.scheduled = YES;

    var context = this;

    window.setNativeTimeout(function () { context.evaluate(); }, 0);
}

objj_context.prototype.pushFragment = function(aFragment)
{
    SET_CONTEXT(aFragment, this);

    this.fragments.push(aFragment);
}

function fragment_evaluate_code(aFragment)
{
    var compiled;

    OBJJ_CURRENT_BUNDLE = GET_BUNDLE(aFragment);

    try
    {
#if RHINO
        var functionText = "function(){"+GET_CODE(aFragment)+"/**/\n}";
        if (window.isRhino)
            compiled = Packages.org.mozilla.javascript.Context.getCurrentContext().compileFunction(window, functionText, GET_FILE(aFragment).path, 0, null);
        else
            compiled = eval(functionText);
#else
        // "//@ sourceURL=" at the end lets us name our eval'd files for debuggers, etc.
        // * WebKit:  http://pmuellr.blogspot.com/2009/06/debugger-friendly.html
        // * Firebug: http://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/
        //if (true) {
            var functionText = GET_CODE(aFragment)+"/**/\n//@ sourceURL="+GET_FILE(aFragment).path;
            compiled = new Function(functionText);
        //} else {
        //    // Firebug only does it for "eval()", not "new Function()". Ugh. Slower.
        //    var functionText = "(function(){"+GET_CODE(aFragment)+"/**/\n})\n//@ sourceURL="+GET_FILE(aFragment).path;
        //    compiled = eval(functionText);
        //}
        compiled.displayName = GET_FILE(aFragment).path;
#endif
    }
    catch(anException)
    {
        objj_exception_report(anException, GET_FILE(aFragment));
    }

#if RHINO
    compiled();
#else
    try
    {
        compiled();
    }
    catch(anException)
    {
        objj_exception_report(anException, GET_FILE(aFragment));
    }
#endif

    return NO;
}

function fragment_evaluate_file(aFragment)
{
    var context = GET_CONTEXT(aFragment),
        requiresSleep = YES;

    // Make us IO Blocked until we receive the file.
    context.blocked = YES;

    objj_request_file(GET_PATH(aFragment), IS_LOCAL(aFragment), function(aFile)
    {
        // Use the captured value from the closure.  If objj_request_file
        // returns immediately, then this will cause us to avoid breaking,
        // but if it doesn't, then this will have no effect.
        requiresSleep = NO;

        // We've received the file, so no longer block execution.
        context.blocked = NO;

        // FIXME: We need to actually support this, and handle it better
        // as well.
        if (aFile == OBJJ_NO_FILE)
            objj_alert("uh oh!");

        // If this file has already been included, skip it and bail.
        if (objj_included_files[aFile.path])
            return;

        // If not, then mark it as included, for future imports.
        objj_included_files[aFile.path] = YES;

        // Grab the file's fragments if it has them, or preprocess it if not.
        if (!aFile.fragments)
            aFile.fragments = objj_preprocess(aFile.contents, aFile.bundle, aFile, OBJJ_PREPROCESSOR_DEBUG_SYMBOLS);

        var fragments = aFile.fragments,
            count = fragments.length,
            directory = aFile.path.substr(0, aFile.path.lastIndexOf('/') + 1);

        // Put the individual fragments at the head of the evaluation
        // stack to be evaluated.
        while (count--)
        {
            var fragment = fragments[count];

            if (IS_FILE(fragment))
            {
                if (IS_LOCAL(fragment))
                    SET_PATH(fragment, directory + GET_PATH(fragment));

                objj_request_file(GET_PATH(fragment), IS_LOCAL(fragment), NULL);
            }

            context.pushFragment(fragment);
        }
    });

    return requiresSleep;
}

function objj_import(/*String | Array*/ pathOrPaths, /*BOOL*/ isLocal, /*Function*/ didCompleteCallback)
{
    var context = new objj_context(),
        paths = pathOrPaths;

    if (typeof paths === "string")
        paths = [paths];

    var index = 0,
        count = paths.length;

    for (; index < count; ++index)
        context.pushFragment(fragment_create_file(paths[index], new objj_bundle(""), isLocal, NULL));

    context.didCompleteCallback = didCompleteCallback;

    context.evaluate();
}
<|endoftext|>


<commit_before>var undef;

// Some shims for IE
if (!Object.keys) {
    Object.keys = function(obj) {
        var arr = [];
        for (var key in obj) {
            arr.push(key);
        }

        return arr;
    };
}

var opts = {
	step: 100
}

test("encode_id_with_array ", function() {
	var r1 = encode_id_with_array(opts,[1 ]);
	ok( r1 == 1, "[1] = 1 = 1 = 1");

	var r1_2 = encode_id_with_array(opts,[2 ]);
	ok( r1_2 == 2, "[2] = 2 = 2 = 2");

	var r2 = encode_id_with_array(opts,[1 ,1]);
	ok( r2 == 101, "[1 ,1 ] = 1.1 =  1*100 + 1 = 101");

	var r2_2 = encode_id_with_array(opts,[1 ,2]);
    ok( r2_2 == 102, "[1 ,2] = 1.2 =  1*100 + 2 = 102");

	var r2_3 = encode_id_with_array(opts,[2 ,3]);
    ok( r2_3 == 203, "[2 ,3] = 2.3 =  2*100 + 3 = 203");

	var r3 = encode_id_with_array(opts,[1 ,1 ,1]);
	ok( r3 == 10101, "[1 ,1 ,1] = 1.1.1 = 1*100*100 + 1*100 + 1 = 10101");

	var r3_2_3 = encode_id_with_array(opts,[1 ,2 ,3]);
    ok( r3_2_3 == 10203, "[1 ,2, 3] = 1.2.3 =  1*100*100 + 2*100 + 3= 10203");
});

test("get_parent_id_with_array ", function() {
	var r1 = get_parent_id_with_array(opts,[1]);
	ok( r1 == 0, "[1] pid = 0");

	var r1_2 = get_parent_id_with_array(opts,[2 ]);
	ok( r1_2 == 0, "[2] pid = 0");

	var r2 = get_parent_id_with_array(opts,[1 ,1]);
	ok( r2 == 1, "[1 ,1] pid = 1");

	var r2_2 = get_parent_id_with_array(opts,[1 ,2]);
    ok( r2_2 == 1, "[1 ,2] pid = 1");

	var r3 = get_parent_id_with_array(opts,[1 ,1 ,1]);
	ok( r3 == 101, "[1 ,1 ,1] pid = 101");

	var r3_2_3 = get_parent_id_with_array(opts,[1 ,2 ,3]);
    ok( r3_2_3 == 102, "[1 ,2, 3] pid = 102");

	var r3_2_3_1 = get_parent_id_with_array(opts,[2 ,3 ,1]);
    ok( r3_2_3_1 == 203, "[2, 3, 1] pid = 203");
});

test("factor util method", function() {
	var r3 = factor(opts,3,1);
	var r2 = factor(opts,2,1);

    ok( r3 == 100*100, "m(opts,3) = 100*100");
	ok( r2 == 100, "m(opts,2) = 100");
});
<commit_msg>use equal instead of ok for test 更好的显示测试结果<commit_after>var undef;

// Some shims for IE
if (!Object.keys) {
    Object.keys = function(obj) {
        var arr = [];
        for (var key in obj) {
            arr.push(key);
        }

        return arr;
    };
}

var opts = {
	step: 100
}

QUnit.test("encode_id_with_array ", function(assert) {
	var r1 = encode_id_with_array(opts,[1 ]);
	assert.equal( r1, 1, "[1] = 1 = 1 = 1");

	var r1_2 = encode_id_with_array(opts,[2 ]);
	assert.equal( r1_2, 2, "[2] = 2 = 2 = 2");

	var r2 = encode_id_with_array(opts,[1 ,1]);
	assert.equal( r2, 101, "[1 ,1 ] = 1.1 =  1*100 + 1 = 101");

	var r2_2 = encode_id_with_array(opts,[1 ,2]);
	assert.equal( r2_2, 102, "[1 ,2] = 1.2 =  1*100 + 2 = 102");

	var r2_3 = encode_id_with_array(opts,[2 ,3]);
	assert.equal( r2_3, 203, "[2 ,3] = 2.3 =  2*100 + 3 = 203");

	var r3 = encode_id_with_array(opts,[1 ,1 ,1]);
	assert.equal( r3, 10101, "[1 ,1 ,1] = 1.1.1 = 1*100*100 + 1*100 + 1 = 10101");

	var r3_2_3 = encode_id_with_array(opts,[1 ,2 ,3]);
	assert.equal( r3_2_3, 10203, "[1 ,2, 3] = 1.2.3 =  1*100*100 + 2*100 + 3= 10203");
});

QUnit.test("get_parent_id_with_array ", function(assert) {
	var r1 = get_parent_id_with_array(opts,[1]);
	assert.equal( r1, 0, "[1] pid = 0");

	var r1_2 = get_parent_id_with_array(opts,[2 ]);
	assert.equal( r1_2, 0, "[2] pid = 0");

	var r2 = get_parent_id_with_array(opts,[1 ,1]);
	assert.equal( r2, 1, "[1 ,1] pid = 1");

	var r2_2 = get_parent_id_with_array(opts,[1 ,2]);
	assert.equal( r2_2, 1, "[1 ,2] pid = 1");

	var r3 = get_parent_id_with_array(opts,[1 ,1 ,1]);
	assert.equal( r3, 101, "[1 ,1 ,1] pid = 101");

	var r3_2_3 = get_parent_id_with_array(opts,[1 ,2 ,3]);
	assert.equal( r3_2_3, 102, "[1 ,2, 3] pid = 102");

	var r3_2_3_1 = get_parent_id_with_array(opts,[2 ,3 ,1]);
	assert.equal( r3_2_3_1, 203, "[2, 3, 1] pid = 203");
});

QUnit.test("factor util method", function(assert) {
	var r3 = factor(opts,3,1);
	var r2 = factor(opts,2,1);

	assert.equal( r3, 100*100, "m(opts,3) = 100*100");
	assert.equal( r2, 100, "m(opts,2) = 100");
});
<|endoftext|>


<commit_before>var assert = require('assert');
var JobQueue = require('../lib');
var fakeredis = require('fakeredis');
var sinon = require('sinon');

describe("JobQueue", function() {

	describe("#send(job, callback)", function() {

		it("Should send the job data to the queue", function() {
			var q = new JobQueue({
				redis: fakeredis.createClient("testsend"),
				queuename: 'myqueue'
			});

			q.send({test: 'data'}, function(error, data) {
				if (error) {
					assert.fail('error', 'no error', error);
					return;
				}

				// Test in queue
				q.redisClient.rpop(['myqueue'], function(error, data) {
					if (error) {
						assert.fail('error', 'no error', error);
						return;
					}

					assert.equal('data', JSON.parse(data).test);
				});
			});
		});

		it("Should callback with error if the job parameter is not an object", function() {
			var q = new JobQueue({
				redis: fakeredis.createClient("testsend"),
				queuename: 'myqueue'
			});

			q.send(null, function(error, data) {
				if (!error) {
					assert.fail("no error", "error");
					return;
				}
			});
		});

	});

	describe("#registerProcessor(processor)", function() {

		it("Should only register the first processor registered", function() {
			var q = new JobQueue({
				redis: fakeredis.createClient("test-registerprocessor0"),
				queuename: 'myqueue'
			});
			var mockProcessorA = function() { console.log("A"); };
			var mockProcessorB = function() { console.log("B"); };

			q.registerProcessor(mockProcessorA);
			q.registerProcessor(mockProcessorB);

			assert.equal(q.registeredProcessor, mockProcessorA);
		});

		it("Should begin receiving sent job data", function(done) {
			var q = new JobQueue({
				redis: fakeredis.createClient("test-registerprocessor1"),
				queuename: 'myqueue-test'
			});

			q.send({some: "data"}, function(error, data) {
				if (error) {
					assert.fail("error", "no error");
					done();
				}
			});

			/// Must Send before register for fakeredis to work properly..
			q.registerProcessor(function(data) {
				assert.equal("data", data.some);
				done();
			});
		});

		it("Should only receive as many jobs concurrently as specified in the constructor", function(done) {
			this.timeout(100000);
			var q = new JobQueue({
				redis: fakeredis.createClient("test-registerprocessor2"),
				queuename: 'myqueue-test',
				concurrency: 2
			});

			var spy = sinon.spy();

			q.send({some: "data1"}, function(error, data) {
				if (error) {
					assert.fail("error", "no error");
					done();
				}
			});

			q.send({some: "data2"}, function(error, data) {
				if (error) {
					assert.fail("error", "no error");
					done();
				}
			});

			q.send({some: "data3"}, function(error, data) {
				if (error) {
					assert.fail("error", "no error");
					done();
				}
			});

			var receivedData1 = false;
			var receivedData2 = false;

			var redisClient = q.redisClient;
			q.registerProcessor(function(data) {
				if (data.some === 'data1') {
					receivedData1 = true;
				} else if (data.some === 'data2') {
					receivedData2 = true;
				} else {
					assert.fail(data, "should not of received value");
					done();
				}

				if (receivedData2 && receivedData1) {
					process.nextTick(function() {
						redisClient.rpop("myqueue-test", function(error, data) {
							var parsedData = JSON.parse(data);
							assert.equal("data3", parsedData.some);
							done();
						});
					});
				}
			});
		});
	});
});
<commit_msg>Make all tests async and att waitQueueLength test<commit_after>var assert = require('assert');
var JobQueue = require('../lib');
var fakeredis = require('fakeredis');
var sinon = require('sinon');

describe("JobQueue", function() {

	describe("#send(job, callback)", function() {

		it("Should send the job data to the queue", function(done) {
			var q = new JobQueue({
				redis: fakeredis.createClient("testsend"),
				queuename: 'myqueue'
			});

			q.send({test: 'data'}, function(error, data) {
				if (error) {
					assert.fail('error', 'no error', error);
					return;
				}

				// Test in queue
				q.redisClient.rpop(['myqueue'], function(error, data) {
					if (error) {
						assert.fail('error', 'no error', error);
						done();
						return;
					}

					assert.equal('data', JSON.parse(data).test);
					done();
				});
			});
		});

		it("Should callback with error if the job parameter is not an object", function(done) {
			var q = new JobQueue({
				redis: fakeredis.createClient("testsend"),
				queuename: 'myqueue'
			});

			q.send(null, function(error, data) {
				if (!error) {
					assert.fail("no error", "error");
					done();
					return;
				}

				done();
			});
		});

	});

	describe("#registerProcessor(processor)", function() {

		it("Should only register the first processor registered", function() {
			var q = new JobQueue({
				redis: fakeredis.createClient("test-registerprocessor0"),
				queuename: 'myqueue'
			});
			var mockProcessorA = function() { console.log("A"); };
			var mockProcessorB = function() { console.log("B"); };

			q.registerProcessor(mockProcessorA);
			q.registerProcessor(mockProcessorB);

			assert.equal(q.registeredProcessor, mockProcessorA);
		});

		it("Should begin receiving sent job data", function(done) {
			var q = new JobQueue({
				redis: fakeredis.createClient("test-registerprocessor1"),
				queuename: 'myqueue-test'
			});

			q.send({some: "data"}, function(error, data) {
				if (error) {
					assert.fail("error", "no error");
					done();
				}
			});

			/// Must Send before register for fakeredis to work properly..
			q.registerProcessor(function(data) {
				assert.equal("data", data.some);
				done();
			});
		});

		it("Should only receive as many jobs concurrently as specified in the constructor", function(done) {
			var q = new JobQueue({
				redis: fakeredis.createClient("test-registerprocessor2"),
				queuename: 'myqueue-test',
				concurrency: 2
			});

			q.send({some: "data1"}, function(error, data) {
				if (error) {
					assert.fail("error", "no error");
					done();
				}
			});

			q.send({some: "data2"}, function(error, data) {
				if (error) {
					assert.fail("error", "no error");
					done();
				}
			});

			q.send({some: "data3"}, function(error, data) {
				if (error) {
					assert.fail("error", "no error");
					done();
				}
			});

			var receivedData1 = false;
			var receivedData2 = false;

			var redisClient = q.redisClient;
			q.registerProcessor(function(data) {
				if (data.some === 'data1') {
					receivedData1 = true;
				} else if (data.some === 'data2') {
					receivedData2 = true;
				} else {
					assert.fail(data, "should not of received value");
					done();
				}

				if (receivedData2 && receivedData1) {
					process.nextTick(function() {
						redisClient.rpop("myqueue-test", function(error, data) {
							var parsedData = JSON.parse(data);
							assert.equal("data3", parsedData.some);
							done();
						});
					});
				}
			});
		});
	});

	describe("#waitQueueLength(callback)", function() {
		it("Should receive the length of the wait queue as its callback data argument", function(done) {
			var q = new JobQueue({
				redis: fakeredis.createClient("test-waitqueuelength1"),
				queuename: 'myqueue-test'
			});

			q.send({data: "some"}, function(error, data) {
				q.waitQueueLength(function(error, data) {
					assert.equal(1, data);
					done();
				});
			});
		});
	});
});
<|endoftext|>