<commit_before>/* global describe, it, before, after, afterEach */
'use strict'

var _ = require('lodash')
var flic = require('../lib/flic')
var Node = flic.Node
var Bridge = flic.Bridge

var assert = require('assert')

var async = require('async')

describe('Bridge', function () {
  describe('construction', function () {
    var testBridge

    it('can still be accessed through flic.bridge', function () {
      assert(Bridge === flic.bridge)
    })

    it('should construct normally', function (done) {
      testBridge = flic.createBridge(function () {
        assert(testBridge instanceof Bridge)
        assert.equal(testBridge._config.port, 8221)
        testBridge._server.close(done)
      })
      testBridge._server.unref()
    })

    it('should allow setting of the listening port', function (done) {
      testBridge = flic.createBridge({
        port: 9003
      }, function (err) {
        assert.ifError(err)
        assert.equal(testBridge._config.port, 9003)
        testBridge._server.close(done)
      })
      testBridge._server.unref()
    })

    it('should pass any errors to a listener callback', function (done) {
      testBridge = flic.createBridge(function () {
        var dupeBridge = flic.createBridge(function (err) {
          assert(err)
          testBridge._server.close(done)
        })
        dupeBridge._server.unref()
      })
      testBridge._server.unref()
    })
  })

  describe('close', function () {
    var b, goodNodes

    goodNodes = []

    before(function (done) {
      done = _.after(2, done)
      b = flic.createBridge()
      b._server.unref()
      goodNodes.push(flic.createNode({
        id: 'node_1',
        connect_callback: function (err) {
          assert.ifError(err)
          done()
        }
      }))
      goodNodes.push(flic.createNode({
        id: 'node_2',
        connect_callback: function (err) {
          assert.ifError(err)
          done()
        }
      }))
    })

    after(function () {
      b._server && b._server._handle && b._server.close()
    })

    it('should send a close message to all connected nodes', function (done) {
      async.parallel([
        function (cb) {
          goodNodes[0].on('close', function (partingData) {
            assert.equal(partingData, 'live long and prosper')
            cb()
          })
        },
        function (cb) {
          goodNodes[1].on('close', function (partingData) {
            assert.equal(partingData, 'live long and prosper')
            cb()
          })
        }
      ], done)

      b.close(['live long and prosper'])
    })
  })
})

describe('Node', function () {
  describe('construction', function () {
    var b, b2

    before(function () {
      b2 = flic.createBridge({
        port: 9823
      })
      b = flic.createBridge()
      b._server.unref()
      b2._server.unref()
    })

    after(function () {
      b._server && b._server._handle && b._server.close()
      b2._server && b2._server._handle && b2._server.close()
    })

    it('can still be accessed through flic.node', function () {
      assert(Node === flic.node)
    })

    it('should be backwards compatible with v1.x', function (done) {
      done = _.after(2, done)
      var node = new Node('node_22', function (err) {
        assert.ifError(err)
        done()
      })
      assert(node instanceof Node)

      var node2 = flic.createNode('node_34', function (err) {
        assert.ifError(err)
        done()
      })
      assert(node2 instanceof Node)
    })

    it('should construct normally and callback when connected to the bridge', function (done) {
      flic.createNode({
        id: 'node_1',
        connect_callback: function (err) {
          assert.ifError(err)
          done()
        }
      })
    })

    it('should fail because the name is taken', function (done) {
      flic.createNode({
        id: 'node_1',
        connect_callback: function (err) {
          assert(err)
          done()
        }
      })
    })

    it('should fail because there is no bridge listening on specified port', function (done) {
      this.timeout(3000)

      flic.createNode({
        id: 'muh_dumb_node',
        port: 9999,
        connect_callback: function (err) {
          assert(err)
          done()
        }
      })
    })

    it('should be able to connect normally to a server on a different port', function (done) {
      flic.createNode({
        id: 'node_3',
        port: 9823,
        connect_callback: function (err) {
          assert.ifError(err)
          done()
        }
      })
    })
  })

  describe('tell', function () {
    var b, goodNodes

    goodNodes = []

    before(function (done) {
      done = _.after(2, done)
      b = new Bridge()
      b._server.unref()
      goodNodes.push(flic.createNode({
        id: 'node_1',
        connect_callback: function (err) {
          assert.ifError(err)
          done()
        }
      }))
      goodNodes.push(flic.createNode({
        id: 'node_2',
        connect_callback: function (err) {
          assert.ifError(err)
          done()
        }
      }))
    })

    after(function () {
      b._server && b._server._handle && b._server.close()
    })

    afterEach(function () {
      goodNodes.forEach(function (n) {
        n.removeAllListeners()
      })
    })

    it('should be able to contact another node', function (done) {
      goodNodes[0].on('test_event', function (param1) {
        assert.equal(param1, 'test_param')
        done()
      })
      goodNodes[1].tell('node_1:test_event', 'test_param')
    })

    it('should be able to contact another node and send callbacks', function (done) {
      goodNodes[0].on('test_event', function (param1, ack) {
        assert.equal(param1, 'test_param')
        ack('my-reply')
      })
      goodNodes[1].tell('node_1:test_event', 'test_param', function (a) {
        assert.equal(a, 'my-reply')
        done()
      })
    })

    it("should fail if the who and what format is not valid ('node_name:remote_event')", function () {
      assert.throws(function () {
        goodNodes[1].tell('node_1-what-the-hell')
      })
      assert.throws(function () {
        goodNodes[1].tell('node_1:too:many:colons')
      })
    })

    it('should fail if the node being told does not exist', function (done) {
      goodNodes[0].tell('me-no-exist:remote_event', function (err) {
        assert.equal(err, 'unknown-node')
        done()
      })
    })
  })

  describe('shout', function () {
    var b, goodNodes

    goodNodes = []

    before(function (done) {
      b = flic.createBridge()
      async.parallel([
        function (cb) {
          goodNodes.push(flic.createNode({id: 'node_1', connect_callback: cb}))
        },
        function (cb) {
          goodNodes.push(flic.createNode({id: 'node_2', connect_callback: cb}))
        },
        function (cb) {
          goodNodes.push(flic.createNode({id: 'node_3', connect_callback: cb}))
        }
      ], function (err) {
        assert.ifError(err)
        done()
      })
    })

    after(function () {
      b._server && b._server._handle && b._server.close()
    })

    afterEach(function () {
      goodNodes.forEach(function (n) {
        n.removeAllListeners()
      })
    })

    it('should send events to all connected nodes', function (done) {
      async.parallel([
        function (done) {
          goodNodes[0].on('shout_eve', function (param1) {
            assert.equal(param1, 'test-param')
            done()
          })
        },
        function (done) {
          goodNodes[1].on('shout_eve', function (param1) {
            assert.equal(param1, 'test-param')
            done()
          })
        }
      ], done)

      goodNodes[2].shout('shout_eve', 'test-param')
    })
  })

  describe('leave', function () {
    var b

    before(function () {
      b = flic.createBridge()
      b._server.unref()
    })

    after(function () {
      b._server && b._server._handle && b._server.close()
    })

    it('should tell the bridge that it is leaving', function (done) {
      var x = flic.createNode({
        id: 'leaving_node',
        connect_callback: function (err) {
          assert.ifError(err)
          x.leave()
          setTimeout(function () {
            assert.ok(!b._sockets.hasOwnProperty('leaving_node'), b._sockets)
            done()
          }, 20)
        }
      })
    })
  })
})
<commit_msg>add test for coalesced TCP packets<commit_after>/* global describe, it, before, after, afterEach */
'use strict'

var _ = require('lodash')
var flic = require('../lib/flic')
var Node = flic.Node
var Bridge = flic.Bridge

var assert = require('assert')

var async = require('async')

describe('Bridge', function () {
  describe('construction', function () {
    var testBridge

    it('can still be accessed through flic.bridge', function () {
      assert(Bridge === flic.bridge)
    })

    it('should construct normally', function (done) {
      testBridge = flic.createBridge(function () {
        assert(testBridge instanceof Bridge)
        assert.equal(testBridge._config.port, 8221)
        testBridge._server.close(done)
      })
      testBridge._server.unref()
    })

    it('should allow setting of the listening port', function (done) {
      testBridge = flic.createBridge({
        port: 9003
      }, function (err) {
        assert.ifError(err)
        assert.equal(testBridge._config.port, 9003)
        testBridge._server.close(done)
      })
      testBridge._server.unref()
    })

    it('should pass any errors to a listener callback', function (done) {
      testBridge = flic.createBridge(function () {
        var dupeBridge = flic.createBridge(function (err) {
          assert(err)
          testBridge._server.close(done)
        })
        dupeBridge._server.unref()
      })
      testBridge._server.unref()
    })
  })

  describe('close', function () {
    var b, goodNodes

    goodNodes = []

    before(function (done) {
      done = _.after(2, done)
      b = flic.createBridge()
      b._server.unref()
      goodNodes.push(flic.createNode({
        id: 'node_1',
        connect_callback: function (err) {
          assert.ifError(err)
          done()
        }
      }))
      goodNodes.push(flic.createNode({
        id: 'node_2',
        connect_callback: function (err) {
          assert.ifError(err)
          done()
        }
      }))
    })

    after(function () {
      b._server && b._server._handle && b._server.close()
    })

    it('should send a close message to all connected nodes', function (done) {
      async.parallel([
        function (cb) {
          goodNodes[0].on('close', function (partingData) {
            assert.equal(partingData, 'live long and prosper')
            cb()
          })
        },
        function (cb) {
          goodNodes[1].on('close', function (partingData) {
            assert.equal(partingData, 'live long and prosper')
            cb()
          })
        }
      ], done)

      b.close(['live long and prosper'])
    })
  })
})

describe('Node', function () {
  describe('construction', function () {
    var b, b2

    before(function () {
      b2 = flic.createBridge({
        port: 9823
      })
      b = flic.createBridge()
      b._server.unref()
      b2._server.unref()
    })

    after(function () {
      b._server && b._server._handle && b._server.close()
      b2._server && b2._server._handle && b2._server.close()
    })

    it('can still be accessed through flic.node', function () {
      assert(Node === flic.node)
    })

    it('should be backwards compatible with v1.x', function (done) {
      done = _.after(2, done)
      var node = new Node('node_22', function (err) {
        assert.ifError(err)
        done()
      })
      assert(node instanceof Node)

      var node2 = flic.createNode('node_34', function (err) {
        assert.ifError(err)
        done()
      })
      assert(node2 instanceof Node)
    })

    it('should construct normally and callback when connected to the bridge', function (done) {
      flic.createNode({
        id: 'node_1',
        connect_callback: function (err) {
          assert.ifError(err)
          done()
        }
      })
    })

    it('should fail because the name is taken', function (done) {
      flic.createNode({
        id: 'node_1',
        connect_callback: function (err) {
          assert(err)
          done()
        }
      })
    })

    it('should fail because there is no bridge listening on specified port', function (done) {
      this.timeout(3000)

      flic.createNode({
        id: 'muh_dumb_node',
        port: 9999,
        connect_callback: function (err) {
          assert(err)
          done()
        }
      })
    })

    it('should be able to connect normally to a server on a different port', function (done) {
      flic.createNode({
        id: 'node_3',
        port: 9823,
        connect_callback: function (err) {
          assert.ifError(err)
          done()
        }
      })
    })
  })

  describe('tell', function () {
    var b, goodNodes

    goodNodes = []

    before(function (done) {
      done = _.after(2, done)
      b = new Bridge()
      b._server.unref()
      goodNodes.push(flic.createNode({
        id: 'node_1',
        connect_callback: function (err) {
          assert.ifError(err)
          done()
        }
      }))
      goodNodes.push(flic.createNode({
        id: 'node_2',
        connect_callback: function (err) {
          assert.ifError(err)
          done()
        }
      }))
    })

    after(function () {
      b._server && b._server._handle && b._server.close()
    })

    afterEach(function () {
      goodNodes.forEach(function (n) {
        n.removeAllListeners()
      })
    })

    it('should be able to contact another node', function (done) {
      goodNodes[0].on('test_event', function (param1) {
        assert.equal(param1, 'test_param')
        done()
      })
      goodNodes[1].tell('node_1:test_event', 'test_param')
    })

    it('should be able to contact another node and send callbacks', function (done) {
      goodNodes[0].on('test_event', function (param1, ack) {
        assert.equal(param1, 'test_param')
        ack('my-reply')
      })
      goodNodes[1].tell('node_1:test_event', 'test_param', function (a) {
        assert.equal(a, 'my-reply')
        done()
      })
    })

    it("should fail if the who and what format is not valid ('node_name:remote_event')", function () {
      assert.throws(function () {
        goodNodes[1].tell('node_1-what-the-hell')
      })
      assert.throws(function () {
        goodNodes[1].tell('node_1:too:many:colons')
      })
    })

    it('should fail if the node being told does not exist', function (done) {
      goodNodes[0].tell('me-no-exist:remote_event', function (err) {
        assert.equal(err, 'unknown-node')
        done()
      })
    })
  })

  describe('shout', function () {
    var b, goodNodes

    goodNodes = []

    before(function (done) {
      b = flic.createBridge()
      async.parallel([
        function (cb) {
          goodNodes.push(flic.createNode({id: 'node_1', connect_callback: cb}))
        },
        function (cb) {
          goodNodes.push(flic.createNode({id: 'node_2', connect_callback: cb}))
        },
        function (cb) {
          goodNodes.push(flic.createNode({id: 'node_3', connect_callback: cb}))
        }
      ], function (err) {
        assert.ifError(err)
        done()
      })
    })

    after(function () {
      b._server && b._server._handle && b._server.close()
    })

    afterEach(function () {
      goodNodes.forEach(function (n) {
        n.removeAllListeners()
      })
    })

    it('should send events to all connected nodes', function (done) {
      async.parallel([
        function (done) {
          goodNodes[0].on('shout_eve', function (param1) {
            assert.equal(param1, 'test-param')
            done()
          })
        },
        function (done) {
          goodNodes[1].on('shout_eve', function (param1) {
            assert.equal(param1, 'test-param')
            done()
          })
        }
      ], done)

      goodNodes[2].shout('shout_eve', 'test-param')
    })

    it('should catch events shouted very quickly', function (done) {
      async.parallel([
        function (done) {
          goodNodes[0].on('shout_eve', function (param1) {
            var isParamOk = param1 === 'test-param 1' ||
              param1 === 'test-param 2' ||
              param1 === 'test-param 3'

            assert.ok(isParamOk)
            done()
          })
        }
      ], done)

      goodNodes[2].shout('shout_eve', 'test-param 1')
      goodNodes[2].shout('shout_eve', 'test-param 2')
      goodNodes[2].shout('shout_eve', 'test-param 3')
    })
  })

  describe('leave', function () {
    var b

    before(function () {
      b = flic.createBridge()
      b._server.unref()
    })

    after(function () {
      b._server && b._server._handle && b._server.close()
    })

    it('should tell the bridge that it is leaving', function (done) {
      var x = flic.createNode({
        id: 'leaving_node',
        connect_callback: function (err) {
          assert.ifError(err)
          x.leave()
          setTimeout(function () {
            assert.ok(!b._sockets.hasOwnProperty('leaving_node'), b._sockets)
            done()
          }, 20)
        }
      })
    })
  })
})
<|endoftext|>


<commit_before>'use strict'

const co = require('co');
const compose = require('..');
const assert = require('assert');

function wait(ms) {
  return new Promise(resolve => setTimeout(resolve, ms || 1))
}

describe('Koa Compose', function(){
  it('should work', function(){
    var arr = [];
    var stack = [];

    stack.push(function *(context, next){
      arr.push(1);
      yield wait(1);
      yield next();
      yield wait(1);
      arr.push(6);
    })

    stack.push(function *(context, next){
      arr.push(2);
      yield wait(1);
      yield next();
      yield wait(1);
      arr.push(5);
    })

    stack.push(function *(context, next){
      arr.push(3);
      yield wait(1);
      yield next();
      yield wait(1);
      arr.push(4);
    })

    return compose(stack.map(fn => co.wrap(fn)))({}).then(function () {
      arr.should.eql([1, 2, 3, 4, 5, 6]);
    })
  })

  it('should only accept an array', function () {
    var err;
    try {
      (compose()).should.throw();
    } catch(e) {
      err = e;
    }
    return (err).should.be.instanceof(TypeError);
  })

  it('should work with 0 middleware', function(){
    return compose([])({});
  })

  it('should only accept middleware as functions', function(){
    var err;
    try {
      (compose([{}])).should.throw();
    } catch(e) {
      err = e;
    }
    return (err).should.be.instanceof(TypeError);
  })

  it('should work when yielding at the end of the stack', function() {
    var stack = [];
    var called = false;

    stack.push(function *(ctx, next){
      yield next();
      called = true;
    });

    return compose(stack.map(co.wrap))({}).then(function () {
      assert(called)
    });
  })

  it('should reject on errors in middleware', function(){
    var stack = [];

    stack.push(function *(){throw new Error});

    return compose(stack.map(co.wrap))({})
        .then(function () {
          throw 'promise was not rejected'
        })
        .catch(function (e) {
          e.should.be.instanceof(Error)
        });
  })

  it('should work when yielding at the end of the stack with yield*', function() {
    var stack = [];

    stack.push(function *(ctx, next){
      yield next;
    });

    compose(stack.map(co.wrap))({});
  })

  it('should keep the context', function(){
    var ctx = {};

    var stack = [];

    stack.push(function *(ctx2, next){
      yield next();
      ctx2.should.equal(ctx);
    })

    stack.push(function *(ctx2, next){
      yield next()
      ctx2.should.equal(ctx);
    })

    stack.push(function *(ctx2, next){
      yield next()
      ctx2.should.equal(ctx);
    })

    return compose(stack.map(co.wrap))(ctx);
  })

  it('should catch downstream errors', function(){
    var arr = [];
    var stack = [];

    stack.push(function *(ctx, next){
      arr.push(1);
      try {
        arr.push(6);
        yield next();
        arr.push(7);
      } catch (err) {
        arr.push(2);
      }
      arr.push(3);
    })

    stack.push(function *(ctx, next){
      arr.push(4);
      throw new Error();
      arr.push(5);
    })

    return compose(stack.map(co.wrap))({}).then(function () {
      arr.should.eql([1, 6, 4, 2, 3]);
    })
  })

  it('should compose w/ next', function() {
    var called = false;

    return compose([])({}, co.wrap(function* () {
      called = true
    })).then(function () {
      assert(called)
    })
  })

  it('should handle errors in wrapped non-async functions', function () {
    var arr = [];
    var stack = [];

    stack.push(function () {
      throw new Error();
    })

    return compose(stack.map(co.wrap))({}).then(function () {
      throw 'promise was not rejected'
    })
    .catch(function (e) {
      e.should.be.instanceof(Error)
    })
  })

  // https://github.com/koajs/compose/pull/27#issuecomment-143109739
  it('should compose w/ other compositions', function() {
    var called = [];

    return compose([
        compose([
            (ctx, next) => {
                called.push(1)
                return next()
            },
            (ctx, next) => {
                called.push(2)
                return next()
            }
        ]),
        (ctx, next) => {
            called.push(3)
            return next()
        }
    ])({}).then(() => assert.deepEqual(called, [1, 2, 3]))
  })

  it('should throw if next() is called multiple times', function() {
    return compose([
      co.wrap(function* (ctx, next) {
        yield next()
        yield next()
      })
    ])({}).then(() => {throw new Error('boom')}, err => {})
  })

  it('should support ctx.next().then()', function(){
    var arr = [];
    var stack = [];

    stack.push(function *(ctx){
      arr.push(1);
      arr.push(2);
      yield ctx.next();
      arr.push(7);
      arr.push(8);
    })

    stack.push(function *(ctx){
      arr.push(3);
      yield ctx.next();
      arr.push(6);
    })

    stack.push(function *(ctx){
      arr.push(4);
      yield ctx.next();
      arr.push(5);
    })

    return compose(stack.map(co.wrap))({}).then(function () {
      arr.should.eql([1, 2, 3, 4, 5, 6, 7, 8]);
    })
  })
})
<commit_msg>another test for @gyson<commit_after>'use strict'

const co = require('co');
const compose = require('..');
const assert = require('assert');

function wait(ms) {
  return new Promise(resolve => setTimeout(resolve, ms || 1))
}

describe('Koa Compose', function(){
  it('should work', function(){
    var arr = [];
    var stack = [];

    stack.push(function *(context, next){
      arr.push(1);
      yield wait(1);
      yield next();
      yield wait(1);
      arr.push(6);
    })

    stack.push(function *(context, next){
      arr.push(2);
      yield wait(1);
      yield next();
      yield wait(1);
      arr.push(5);
    })

    stack.push(function *(context, next){
      arr.push(3);
      yield wait(1);
      yield next();
      yield wait(1);
      arr.push(4);
    })

    return compose(stack.map(fn => co.wrap(fn)))({}).then(function () {
      arr.should.eql([1, 2, 3, 4, 5, 6]);
    })
  })

  it('should only accept an array', function () {
    var err;
    try {
      (compose()).should.throw();
    } catch(e) {
      err = e;
    }
    return (err).should.be.instanceof(TypeError);
  })

  it('should work with 0 middleware', function(){
    return compose([])({});
  })

  it('should only accept middleware as functions', function(){
    var err;
    try {
      (compose([{}])).should.throw();
    } catch(e) {
      err = e;
    }
    return (err).should.be.instanceof(TypeError);
  })

  it('should work when yielding at the end of the stack', function() {
    var stack = [];
    var called = false;

    stack.push(function *(ctx, next){
      yield next();
      called = true;
    });

    return compose(stack.map(co.wrap))({}).then(function () {
      assert(called)
    });
  })

  it('should reject on errors in middleware', function(){
    var stack = [];

    stack.push(function *(){throw new Error});

    return compose(stack.map(co.wrap))({})
        .then(function () {
          throw 'promise was not rejected'
        })
        .catch(function (e) {
          e.should.be.instanceof(Error)
        });
  })

  it('should work when yielding at the end of the stack with yield*', function() {
    var stack = [];

    stack.push(function *(ctx, next){
      yield next;
    });

    compose(stack.map(co.wrap))({});
  })

  it('should keep the context', function(){
    var ctx = {};

    var stack = [];

    stack.push(function *(ctx2, next){
      yield next();
      ctx2.should.equal(ctx);
    })

    stack.push(function *(ctx2, next){
      yield next()
      ctx2.should.equal(ctx);
    })

    stack.push(function *(ctx2, next){
      yield next()
      ctx2.should.equal(ctx);
    })

    return compose(stack.map(co.wrap))(ctx);
  })

  it('should catch downstream errors', function(){
    var arr = [];
    var stack = [];

    stack.push(function *(ctx, next){
      arr.push(1);
      try {
        arr.push(6);
        yield next();
        arr.push(7);
      } catch (err) {
        arr.push(2);
      }
      arr.push(3);
    })

    stack.push(function *(ctx, next){
      arr.push(4);
      throw new Error();
      arr.push(5);
    })

    return compose(stack.map(co.wrap))({}).then(function () {
      arr.should.eql([1, 6, 4, 2, 3]);
    })
  })

  it('should compose w/ next', function() {
    var called = false;

    return compose([])({}, co.wrap(function* () {
      called = true
    })).then(function () {
      assert(called)
    })
  })

  it('should handle errors in wrapped non-async functions', function () {
    var arr = [];
    var stack = [];

    stack.push(function () {
      throw new Error();
    })

    return compose(stack.map(co.wrap))({}).then(function () {
      throw 'promise was not rejected'
    }).catch(function (e) {
      e.should.be.instanceof(Error)
    })
  })

  // https://github.com/koajs/compose/pull/27#issuecomment-143109739
  it('should compose w/ other compositions', function() {
    var called = [];

    return compose([
        compose([
            (ctx, next) => {
                called.push(1)
                return next()
            },
            (ctx, next) => {
                called.push(2)
                return next()
            }
        ]),
        (ctx, next) => {
            called.push(3)
            return next()
        }
    ])({}).then(() => assert.deepEqual(called, [1, 2, 3]))
  })

  it('should throw if next() is called multiple times', function() {
    return compose([
      co.wrap(function* (ctx, next) {
        yield next()
        yield next()
      })
    ])({}).then(() => {
      throw new Error('boom')
    }, err => {
      assert(/multiple times/.test(err.message))
    })
  })

  it('should throw if next() is called multiple times #2', function() {
    return compose([
      co.wrap(function* (ctx, next) {
        yield next()
        yield next()
      }),
      co.wrap(function* (ctx) {

      })
    ])({}).then(() => {
      throw new Error('boom')
    }, err => {
      assert(/multiple times/.test(err.message))
    })
  })

  it('should support ctx.next().then()', function(){
    var arr = [];
    var stack = [];

    stack.push(function *(ctx){
      arr.push(1);
      arr.push(2);
      yield ctx.next();
      arr.push(7);
      arr.push(8);
    })

    stack.push(function *(ctx){
      arr.push(3);
      yield ctx.next();
      arr.push(6);
    })

    stack.push(function *(ctx){
      arr.push(4);
      yield ctx.next();
      arr.push(5);
    })

    return compose(stack.map(co.wrap))({}).then(function () {
      arr.should.eql([1, 2, 3, 4, 5, 6, 7, 8]);
    })
  })

  it('should return a valid middleware', function () {
    var val = 0
    compose([
      compose([
        (ctx, next) => {
          val++
          return next()
        },
        (ctx, next) => {
          val++
          return next()
        }
      ]),
      (ctx, next) => {
        val++
        return next()
      }
    ])({}).then(function () {
      val.should.equal(3)
    })
  })

  it('should expose next on the context', function () {
    var stack = [];

    stack.push(function (context, next) {
      context.next.should.equal(next)
    })

    return compose(stack.map(co.wrap))({})
  })
})
<|endoftext|>


<commit_before>module.exports = function(grunt) {

	grunt.initConfig({
		clean: {
			dist: {
				src: ['dist']
			}
		},
		watch: {
			scripts: {
					files: ['src/kopf/**/*.*','src/kopf/*.*'],
					tasks: ['build'],
					options: {
					spawn: false
				}
			}
		},
		copy: {
			main: {
				files: [
					{expand: true, flatten: true, src: ['src/lib/ace/mode-json.js'], dest: './dist/'},
					{expand: true, flatten: true, src: ['src/lib/ace/worker-json.js'], dest: './dist/'},
					{expand: true, flatten: true, src: ['src/kopf/theme-kopf.js'], dest: './dist/'},
					{expand: true, flatten: true, src: ['src/kopf/css/dark_style.css'], dest: './dist/'},
					{expand: true, flatten: true, src: ['src/kopf/css/light_style.css'], dest: './dist/'}
				]
			}
		},
		concat: {
			vendorjs: {
				src: [
					'src/lib/jquery/jquery-1.10.2.min.js',
					'src/lib/angularjs/angular.min.js',
					'src/lib/ace/ace.js',
					'src/lib/jsontree/jsontree.min.js',
					'src/lib/bootstrap/js/bootstrap.js'
				],
				dest: 'dist/lib.js'
			},
			vendorcss: {
				src: [
					'src/lib/bootstrap/css/bootstrap.css'
				],
				dest: 'dist/lib.css'
			},
			appjs: {
				src: [
					'src/kopf/elastic/alias.js',
					'src/kopf/elastic/cluster_changes.js',
					'src/kopf/elastic/cluster_health.js',
					'src/kopf/elastic/cluster_settings.js',
					'src/kopf/elastic/cluster.js',
					'src/kopf/elastic/elastic_client.js',
					'src/kopf/elastic/es_connection.js',
					'src/kopf/elastic/index.js',
					'src/kopf/elastic/editable_index_settings.js',
					'src/kopf/elastic/node.js',
					'src/kopf/elastic/shard.js',
					'src/kopf/elastic/token.js',
					'src/kopf/elastic/repository.js',
					'src/kopf/elastic/snapshot.js',
                    'src/kopf/elastic/warmer.js',
                    'src/kopf/elastic/percolator.js',
                    'src/kopf/elastic/index_metadata.js',
					// CONTROLLERS
					'src/kopf/kopf.js',
					'src/kopf/controllers/aliases.js',
					'src/kopf/controllers/analysis.js',
					'src/kopf/controllers/cluster_health.js',
					'src/kopf/controllers/cluster_overview.js',
					'src/kopf/controllers/cluster_settings.js',
					'src/kopf/controllers/create_index.js',
					'src/kopf/controllers/global.js',
					'src/kopf/controllers/index_settings.js',
					'src/kopf/controllers/navbar.js',
					'src/kopf/controllers/rest.js',
					'src/kopf/controllers/percolator.js',
					'src/kopf/controllers/repository.js',
					'src/kopf/controllers/confirm_dialog.js',
					'src/kopf/controllers/warmup.js',
					'src/kopf/controllers/benchmark.js',
					// SERVICES
					'src/kopf/services/alerts.js',
					'src/kopf/services/settings.js',
					'src/kopf/services/aceeditor.js',
					'src/kopf/services/theme.js',
                    'src/kopf/services/elastic.js',
                    'src/kopf/services/host_history.js',
                    'src/kopf/services/external_settings.js',
					// MODELS
					'src/kopf/models/ace_editor.js',
					'src/kopf/models/gist.js',
					'src/kopf/models/benchmark.js',
                    'src/kopf/models/request.js',
                    'src/kopf/models/modal_controls.js',
                    'src/kopf/models/paginator.js',
                    'src/kopf/models/alias_filter.js',
                    'src/kopf/models/snapshot_filter.js',
                    'src/kopf/models/warmer_filter.js',
                    'src/kopf/models/index_filter.js',
                    'src/kopf/models/node_filter.js',
					// UTIL
					'src/kopf/util.js'
				],
				dest: 'dist/kopf.js'
			},
			appcss: {
				src: [
					'src/kopf/kopf.css',
					'src/kopf/css/percolator.css',
					'src/kopf/css/common.css',
					'src/kopf/css/aliases.css',
					'src/kopf/css/analysis.css',
					'src/kopf/css/cluster_health.css',
					'src/kopf/css/cluster_overview.css',
					'src/kopf/css/gist_share.css',
					'src/kopf/css/json_tree.css',
					'src/kopf/css/navbar.css',
					'src/kopf/css/rest_client.css',
					'src/kopf/css/warmup.css',
					'src/kopf/css/repository.css'
				],
				dest: 'dist/kopf.css'
			}

		},
		connect: {
			server: {
				options: {
					port: 9000,
					base: '.',
					keepalive: true
				}
			}
		},
		jshint: {
			kopf: {
				src: [
					'src/kopf/elastic/alias.js',
					'src/kopf/elastic/cluster_changes.js',
					'src/kopf/elastic/cluster_health.js',
					'src/kopf/elastic/cluster_settings.js',
					'src/kopf/elastic/cluster.js',
					'src/kopf/elastic/elastic_client.js',
					'src/kopf/elastic/es_connection.js',
					'src/kopf/elastic/index.js',
					'src/kopf/elastic/editable_index_settings.js',
					'src/kopf/elastic/node.js',
					'src/kopf/elastic/shard.js',
					'src/kopf/elastic/token.js',
					'src/kopf/elastic/repository.js',
					'src/kopf/elastic/snapshot.js',
                    'src/kopf/elastic/warmer.js',
                    'src/kopf/elastic/percolator.js',
                    'src/kopf/elastic/index_metadata.js',
					// CONTROLLERS
					'src/kopf/kopf.js',
					'src/kopf/controllers/aliases.js',
					'src/kopf/controllers/analysis.js',
					'src/kopf/controllers/cluster_health.js',
					'src/kopf/controllers/cluster_overview.js',
					'src/kopf/controllers/cluster_settings.js',
					'src/kopf/controllers/create_index.js',
					'src/kopf/controllers/global.js',
					'src/kopf/controllers/index_settings.js',
					'src/kopf/controllers/navbar.js',
					'src/kopf/controllers/rest.js',
					'src/kopf/controllers/percolator.js',
					'src/kopf/controllers/repository.js',
					'src/kopf/controllers/confirm_dialog.js',
					'src/kopf/controllers/warmup.js',
					'src/kopf/controllers/benchmark.js',
					// SERVICES
					'src/kopf/services/alerts.js',
					'src/kopf/services/settings.js',
					'src/kopf/services/aceeditor.js',
					'src/kopf/services/theme.js',
                    'src/kopf/services/elastic.js',
                    'src/kopf/services/host_history.js',
                    'src/kopf/services/external_settings.js',
					// MODELS
					'src/kopf/models/ace_editor.js',
					'src/kopf/models/gist.js',
					'src/kopf/models/benchmark.js',
                    'src/kopf/models/request.js',
                    'src/kopf/models/modal_controls.js',
                    'src/kopf/models/paginator.js',
                    'src/kopf/models/alias_filter.js',
                    'src/kopf/models/snapshot_filter.js',
                    'src/kopf/models/warmer_filter.js',
                    'src/kopf/models/index_filter.js',
                    'src/kopf/models/node_filter.js',
					// UTIL
					'src/kopf/util.js'
				]
			}
		},
		qunit: {
			all: ['tests/all.html']
		},
		karma: {
			unit: { configFile: 'tests/karma.config.js', keepalive: true }
		},
        jscs: {
            main: [ 'src/kopf/**/*.js' ],
            except: [ 'src/kopf/theme-kopf.js' ],
            options: {
                preset: 'google'
            }
        }
	});
	grunt.loadNpmTasks('grunt-contrib-clean');
	grunt.loadNpmTasks('grunt-contrib-concat');
	grunt.loadNpmTasks('grunt-contrib-connect');
	grunt.loadNpmTasks('grunt-contrib-copy');
	grunt.loadNpmTasks('grunt-contrib-watch');
	grunt.loadNpmTasks('grunt-contrib-jshint');
	grunt.loadNpmTasks('grunt-contrib-qunit');
	grunt.loadNpmTasks('grunt-karma');
    grunt.loadNpmTasks("grunt-jscs");
	grunt.registerTask('dev', ['karma', 'watch'])
	grunt.registerTask('test', ['karma'])
	grunt.registerTask('build', ['clean', 'jshint', 'qunit', 'copy', 'concat', 'jscs']);
	grunt.registerTask('server', ['clean', 'jshint', 'qunit', 'copy', 'concat','connect:server']);
};
<commit_msg>added style check to grunt<commit_after>module.exports = function(grunt) {

	grunt.initConfig({
		clean: {
			dist: {
				src: ['dist']
			}
		},
		watch: {
			scripts: {
					files: ['src/kopf/**/*.*','src/kopf/*.*'],
					tasks: ['build'],
					options: {
					spawn: false
				}
			}
		},
		copy: {
			main: {
				files: [
					{expand: true, flatten: true, src: ['src/lib/ace/mode-json.js'], dest: './dist/'},
					{expand: true, flatten: true, src: ['src/lib/ace/worker-json.js'], dest: './dist/'},
					{expand: true, flatten: true, src: ['src/kopf/theme-kopf.js'], dest: './dist/'},
					{expand: true, flatten: true, src: ['src/kopf/css/dark_style.css'], dest: './dist/'},
					{expand: true, flatten: true, src: ['src/kopf/css/light_style.css'], dest: './dist/'}
				]
			}
		},
		concat: {
			vendorjs: {
				src: [
					'src/lib/jquery/jquery-1.10.2.min.js',
					'src/lib/angularjs/angular.min.js',
					'src/lib/ace/ace.js',
					'src/lib/jsontree/jsontree.min.js',
					'src/lib/bootstrap/js/bootstrap.js'
				],
				dest: 'dist/lib.js'
			},
			vendorcss: {
				src: [
					'src/lib/bootstrap/css/bootstrap.css'
				],
				dest: 'dist/lib.css'
			},
			appjs: {
				src: [
					'src/kopf/elastic/alias.js',
					'src/kopf/elastic/cluster_changes.js',
					'src/kopf/elastic/cluster_health.js',
					'src/kopf/elastic/cluster_settings.js',
					'src/kopf/elastic/cluster.js',
					'src/kopf/elastic/elastic_client.js',
					'src/kopf/elastic/es_connection.js',
					'src/kopf/elastic/index.js',
					'src/kopf/elastic/editable_index_settings.js',
					'src/kopf/elastic/node.js',
					'src/kopf/elastic/shard.js',
					'src/kopf/elastic/token.js',
					'src/kopf/elastic/repository.js',
					'src/kopf/elastic/snapshot.js',
                    'src/kopf/elastic/warmer.js',
                    'src/kopf/elastic/percolator.js',
                    'src/kopf/elastic/index_metadata.js',
					// CONTROLLERS
					'src/kopf/kopf.js',
					'src/kopf/controllers/aliases.js',
					'src/kopf/controllers/analysis.js',
					'src/kopf/controllers/cluster_health.js',
					'src/kopf/controllers/cluster_overview.js',
					'src/kopf/controllers/cluster_settings.js',
					'src/kopf/controllers/create_index.js',
					'src/kopf/controllers/global.js',
					'src/kopf/controllers/index_settings.js',
					'src/kopf/controllers/navbar.js',
					'src/kopf/controllers/rest.js',
					'src/kopf/controllers/percolator.js',
					'src/kopf/controllers/repository.js',
					'src/kopf/controllers/confirm_dialog.js',
					'src/kopf/controllers/warmup.js',
					'src/kopf/controllers/benchmark.js',
					// SERVICES
					'src/kopf/services/alerts.js',
					'src/kopf/services/settings.js',
					'src/kopf/services/aceeditor.js',
					'src/kopf/services/theme.js',
                    'src/kopf/services/elastic.js',
                    'src/kopf/services/host_history.js',
                    'src/kopf/services/external_settings.js',
					// MODELS
					'src/kopf/models/ace_editor.js',
					'src/kopf/models/gist.js',
					'src/kopf/models/benchmark.js',
                    'src/kopf/models/request.js',
                    'src/kopf/models/modal_controls.js',
                    'src/kopf/models/paginator.js',
                    'src/kopf/models/alias_filter.js',
                    'src/kopf/models/snapshot_filter.js',
                    'src/kopf/models/warmer_filter.js',
                    'src/kopf/models/index_filter.js',
                    'src/kopf/models/node_filter.js',
					// UTIL
					'src/kopf/util.js'
				],
				dest: 'dist/kopf.js'
			},
			appcss: {
				src: [
					'src/kopf/kopf.css',
					'src/kopf/css/percolator.css',
					'src/kopf/css/common.css',
					'src/kopf/css/aliases.css',
					'src/kopf/css/analysis.css',
					'src/kopf/css/cluster_health.css',
					'src/kopf/css/cluster_overview.css',
					'src/kopf/css/gist_share.css',
					'src/kopf/css/json_tree.css',
					'src/kopf/css/navbar.css',
					'src/kopf/css/rest_client.css',
					'src/kopf/css/warmup.css',
					'src/kopf/css/repository.css'
				],
				dest: 'dist/kopf.css'
			}

		},
		connect: {
			server: {
				options: {
					port: 9000,
					base: '.',
					keepalive: true
				}
			}
		},
		jshint: {
			kopf: {
				src: [
					'src/kopf/elastic/alias.js',
					'src/kopf/elastic/cluster_changes.js',
					'src/kopf/elastic/cluster_health.js',
					'src/kopf/elastic/cluster_settings.js',
					'src/kopf/elastic/cluster.js',
					'src/kopf/elastic/elastic_client.js',
					'src/kopf/elastic/es_connection.js',
					'src/kopf/elastic/index.js',
					'src/kopf/elastic/editable_index_settings.js',
					'src/kopf/elastic/node.js',
					'src/kopf/elastic/shard.js',
					'src/kopf/elastic/token.js',
					'src/kopf/elastic/repository.js',
					'src/kopf/elastic/snapshot.js',
                    'src/kopf/elastic/warmer.js',
                    'src/kopf/elastic/percolator.js',
                    'src/kopf/elastic/index_metadata.js',
					// CONTROLLERS
					'src/kopf/kopf.js',
					'src/kopf/controllers/aliases.js',
					'src/kopf/controllers/analysis.js',
					'src/kopf/controllers/cluster_health.js',
					'src/kopf/controllers/cluster_overview.js',
					'src/kopf/controllers/cluster_settings.js',
					'src/kopf/controllers/create_index.js',
					'src/kopf/controllers/global.js',
					'src/kopf/controllers/index_settings.js',
					'src/kopf/controllers/navbar.js',
					'src/kopf/controllers/rest.js',
					'src/kopf/controllers/percolator.js',
					'src/kopf/controllers/repository.js',
					'src/kopf/controllers/confirm_dialog.js',
					'src/kopf/controllers/warmup.js',
					'src/kopf/controllers/benchmark.js',
					// SERVICES
					'src/kopf/services/alerts.js',
					'src/kopf/services/settings.js',
					'src/kopf/services/aceeditor.js',
					'src/kopf/services/theme.js',
                    'src/kopf/services/elastic.js',
                    'src/kopf/services/host_history.js',
                    'src/kopf/services/external_settings.js',
					// MODELS
					'src/kopf/models/ace_editor.js',
					'src/kopf/models/gist.js',
					'src/kopf/models/benchmark.js',
                    'src/kopf/models/request.js',
                    'src/kopf/models/modal_controls.js',
                    'src/kopf/models/paginator.js',
                    'src/kopf/models/alias_filter.js',
                    'src/kopf/models/snapshot_filter.js',
                    'src/kopf/models/warmer_filter.js',
                    'src/kopf/models/index_filter.js',
                    'src/kopf/models/node_filter.js',
					// UTIL
					'src/kopf/util.js'
				]
			}
		},
		qunit: {
			all: ['tests/all.html']
		},
		karma: {
			unit: { configFile: 'tests/karma.config.js', keepalive: true }
		},
        jscs: {
            src: [ 'src/kopf/**/*.js' ],
            options: {
                preset: 'google',
                excludeFiles: [ 'src/kopf/theme-kopf.js' ]
            }
        }
	});
	grunt.loadNpmTasks('grunt-contrib-clean');
	grunt.loadNpmTasks('grunt-contrib-concat');
	grunt.loadNpmTasks('grunt-contrib-connect');
	grunt.loadNpmTasks('grunt-contrib-copy');
	grunt.loadNpmTasks('grunt-contrib-watch');
	grunt.loadNpmTasks('grunt-contrib-jshint');
	grunt.loadNpmTasks('grunt-contrib-qunit');
	grunt.loadNpmTasks('grunt-karma');
    grunt.loadNpmTasks("grunt-jscs");
	grunt.registerTask('dev', ['karma', 'watch'])
	grunt.registerTask('test', ['karma'])
	grunt.registerTask('build', ['clean', 'jshint', 'qunit', 'copy', 'concat', 'jscs']);
	grunt.registerTask('server', ['clean', 'jshint', 'qunit', 'copy', 'concat','connect:server']);
};
<|endoftext|>


<commit_before>var zlib = require('zlib')
  , dgram = require('dgram')
  , util = require('util')
  , md5 = require('blueimp-md5').md5
  , buffer = require('bufferpack');

GLOBAL.LOG_EMERG=0;    // system is unusable
GLOBAL.LOG_ALERT=1;    // action must be taken immediately
GLOBAL.LOG_CRIT=2;     // critical conditions
GLOBAL.LOG_ERR=3;      // error conditions
GLOBAL.LOG_ERROR=3;    // because people WILL typo
GLOBAL.LOG_WARNING=4;  // warning conditions
GLOBAL.LOG_NOTICE=5;   // normal, but significant, condition
GLOBAL.LOG_INFO=6;     // informational message
GLOBAL.LOG_DEBUG=7;    // debug-level message

GLOBAL.graylogHost = 'localhost';
GLOBAL.graylogPort = 12201;
GLOBAL.graylogHostname = require('os').hostname();
GLOBAL.graylogToConsole = false;
GLOBAL.graylogFacility = 'Node.js';
GLOBAL.graylogSequence = 0;
GLOBAL.chunkSize = 192; // 8192 is the maximum

function generateMessageId() {
	return parseFloat(Date.now() + Math.floor(Math.random()*10000));
}

function _logToConsole(shortMessage, opts) {
	var consoleString = shortMessage
	  ,	additionalFields = [];

	if (opts.full_message) {
		consoleString+=" ("+opts.full_message+")\n";
	}

	Object.keys(opts).forEach(function(key) {
		if (key[0]=='_' && key!="_logSequence") {
			additionalFields.push(
				"  " +
				key.substr(1,1024) +
				": " +
				'\033[' + 34 + 'm' +
				opts[key] +
				'\033[' + 39 + 'm'
			);
		}
	});

	if (additionalFields.length>0) {
		consoleString+="\n"+additionalFields.join("\n");
	}

	util.log(consoleString);
}

function log(shortMessage, a, b) {
	var opts = {};
	if (typeof a == 'string'){
		opts = b || {};
		opts.full_message=a;
	} else if (typeof a == 'object') {
		opts = a || {};
	}

	opts.version="1.0";
	opts.timestamp = opts.timestamp || new Date().getTime()/1000 >> 0;
	opts.host = opts.host || GLOBAL.graylogHostname;
	opts.level = opts.level !== undefined ? opts.level : GLOBAL.LOG_INFO;
	opts.facility = opts.facility || GLOBAL.graylogFacility;

	if (opts.stack) {
		retrieveFileInfo(opts);
	}

	if (GLOBAL.graylogSequence) {
		opts['_logSequence'] = GLOBAL.graylogSequence++;
	}

	opts.short_message = shortMessage;

	if (GLOBAL.graylogToConsole) {
		_logToConsole(shortMessage, opts);
	}

	var message = new Buffer(JSON.stringify(opts));
	zlib.deflate(message, function (err, compressedMessage) {
		if (err) {
			return;
		}

		var graylog2Client = dgram.createSocket("udp4");

		if (compressedMessage.length>GLOBAL.chunkSize) {
			var regex = new RegExp('.{' + GLOBAL.chunkSize + '}', 'g')
			  , messageString = compressedMessage.toString()
			  ,	chunks = messageString.match(regex)
			  , messageId = generateMessageId()
			  , sequenceSize = chunks.length;

			if (sequenceSize > 128) {
				util.debug("Graylog oops: log message is larger than 128 chunks, I print to stderr and give up: \n" + message.toString());
				return;
			}

			chunks.forEach(function(chunk, sequence) {
				var chunkSize = chunk.length
				  ,	hash = md5(messageId, null, true).substring(0, 8)
				  , start = buffer.pack('CC', 30, 15).toString()
				  , middle = buffer.pack('CC', sequence, sequenceSize).toString()
				  , dataString = [start, hash, middle, chunk].join('');

				graylog2Client.send(new Buffer(dataString), 0, dataString.length, GLOBAL.graylogPort, GLOBAL.graylogHost, function (err, byteCount) {
					if (sequence + 1 == sequenceSize) {
						console.log('Last chunk')
						graylog2Client.close();
					}
				});
			});

			return;
		}

		graylog2Client.send(compressedMessage, 0, compressedMessage.length, GLOBAL.graylogPort, GLOBAL.graylogHost, function (err, byteCount) {
			graylog2Client.close();
		});
	});
}

/**
 * Retrieves the filename and line number where log() was called
 *
 * @param {Object} opts The options object that will be altered with 'file' and 'line' properties
 */
function retrieveFileInfo(opts){
	var err = new Error("test"),
		stack = (err.stack || "").toString().split(/\r?\n/),
		match;

	for(var i=0, len = stack.length; i<len; i++){
		if((match = stack[i].match(/^\s*at\s[^\(]+\(([^\):]+):(\d+):\d+\)/))){
			if(__filename.substr(-match[1].length) == match[1]){
				continue;
			}
			opts.file = match[1];
			opts.line = Number(match[2]) || 0;
			break;
		}
	}

}

GLOBAL.log = log;

<commit_msg>Getting closer, just a small discrepancy in total bytes sent so it cannot inflate<commit_after>var zlib = require('zlib')
  , dgram = require('dgram')
  , util = require('util')
  , md5 = require('blueimp-md5').md5
  , buffer = require('bufferpack');

GLOBAL.LOG_EMERG=0;    // system is unusable
GLOBAL.LOG_ALERT=1;    // action must be taken immediately
GLOBAL.LOG_CRIT=2;     // critical conditions
GLOBAL.LOG_ERR=3;      // error conditions
GLOBAL.LOG_ERROR=3;    // because people WILL typo
GLOBAL.LOG_WARNING=4;  // warning conditions
GLOBAL.LOG_NOTICE=5;   // normal, but significant, condition
GLOBAL.LOG_INFO=6;     // informational message
GLOBAL.LOG_DEBUG=7;    // debug-level message

GLOBAL.graylogHost = 'localhost';
GLOBAL.graylogPort = 12201;
GLOBAL.graylogHostname = require('os').hostname();
GLOBAL.graylogToConsole = false;
GLOBAL.graylogFacility = 'Node.js';
GLOBAL.graylogSequence = 0;
GLOBAL.chunkSize = 192; // 8192 is the maximum

function generateMessageId() {
	return '' + (Date.now() + Math.floor(Math.random()*10000));
}

function _logToConsole(shortMessage, opts) {
	var consoleString = shortMessage
	  ,	additionalFields = [];

	if (opts.full_message) {
		consoleString+=" ("+opts.full_message+")\n";
	}

	Object.keys(opts).forEach(function(key) {
		if (key[0]=='_' && key!="_logSequence") {
			additionalFields.push(
				"  " +
				key.substr(1,1024) +
				": " +
				'\033[' + 34 + 'm' +
				opts[key] +
				'\033[' + 39 + 'm'
			);
		}
	});

	if (additionalFields.length>0) {
		consoleString+="\n"+additionalFields.join("\n");
	}

	util.log(consoleString);
}

function log(shortMessage, a, b) {
	var opts = {};
	if (typeof a == 'string'){
		opts = b || {};
		opts.full_message=a;
	} else if (typeof a == 'object') {
		opts = a || {};
	}

	opts.version="1.0";
	opts.timestamp = opts.timestamp || new Date().getTime()/1000 >> 0;
	opts.host = opts.host || GLOBAL.graylogHostname;
	opts.level = opts.level !== undefined ? opts.level : GLOBAL.LOG_INFO;
	opts.facility = opts.facility || GLOBAL.graylogFacility;

	if (opts.stack) {
		retrieveFileInfo(opts);
	}

	if (GLOBAL.graylogSequence) {
		opts['_logSequence'] = GLOBAL.graylogSequence++;
	}

	opts.short_message = shortMessage;

	if (GLOBAL.graylogToConsole) {
		_logToConsole(shortMessage, opts);
	}

	var message = new Buffer(JSON.stringify(opts));
	zlib.deflate(message, function (err, compressedMessage) {
		if (err) {
			return;
		}

		var graylog2Client = dgram.createSocket("udp4");

		console.log(compressedMessage.length)
		if (compressedMessage.length > GLOBAL.chunkSize) {
			var regex = new RegExp('.{' + GLOBAL.chunkSize + '}', 'g')
			  , messageString = compressedMessage.toString()
			  ,	chunks = messageString.match(regex)
			  , messageId = generateMessageId()
			  , sequenceSize = chunks.length
			  , offset = 0;

			if (sequenceSize > 128) {
				util.debug("Graylog oops: log message is larger than 128 chunks, I print to stderr and give up: \n" + message.toString());
				return;
			}

			chunks.forEach(function(chunk, sequence) {
				var chunkSize = chunk.length
				  ,	bytesToSend = (offset + chunkSize < compressedMessage.length ? this.chunkSize : compressedMessage.length - offset)
				  , dataChunk = new Buffer(chunkSize + 12);

				dataChunk[0] = 0x1e;
				dataChunk[1] = 0x0f;
				dataChunk.write(messageId, 2, 8, 'ascii');
				dataChunk[10] = sequence;
				dataChunk[11] = sequenceSize;

				console.log(offset, offset+bytesToSend)
				compressedMessage.copy(dataChunk, 12, offset, offset+bytesToSend)
        		offset += bytesToSend;

				graylog2Client.send(dataChunk, 0, bytesToSend, GLOBAL.graylogPort, GLOBAL.graylogHost, function (err, byteCount) {
					if (sequence + 1 == sequenceSize) {
						console.log('closing UDP Client');
						graylog2Client.close();
					}
				});
			});

			return;
		}

		graylog2Client.send(compressedMessage, 0, compressedMessage.length, GLOBAL.graylogPort, GLOBAL.graylogHost, function (err, byteCount) {
			graylog2Client.close();
		});
	});
}

/**
 * Retrieves the filename and line number where log() was called
 *
 * @param {Object} opts The options object that will be altered with 'file' and 'line' properties
 */
function retrieveFileInfo(opts){
	var err = new Error("test"),
		stack = (err.stack || "").toString().split(/\r?\n/),
		match;

	for(var i=0, len = stack.length; i<len; i++){
		if((match = stack[i].match(/^\s*at\s[^\(]+\(([^\):]+):(\d+):\d+\)/))){
			if(__filename.substr(-match[1].length) == match[1]){
				continue;
			}
			opts.file = match[1];
			opts.line = Number(match[2]) || 0;
			break;
		}
	}

}

GLOBAL.log = log;

<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import StyledTableHeader from './table-header.style';
import Icon from '../../icon/icon';
import { validProps } from '../../../utils/ether/ether';
import OptionsHelper from '../../../utils/helpers/options-helper';

/**
 * A TableHeader widget.
 *
 * == How to use a TableHeader in a component:
 *
 * See documentation for Table component.
 *
 * You can set a property of 'align' which should be a string. This will
 * align the content to either "left", "center" or "right".
 *
 * == Sortable Columns:
 *
 * To make a column sortable, pass a prop of 'sortable={ true }' to the corresponding
 * TableHeader.
 * Sortable columns also require a 'name' prop which must correspond to the database key.
 *
 * You can also provide a custom sortOrder - 'asc' (ascending) or 'desc' (descending).
 * By Default columns are sorted in ascending order.
 *
 * See the Table documentation for more information on hooking up a change handler
 * to setup sort functionality in your app.
 */
class TableHeader extends React.Component {
  /**
   * Event handler for clicks on the <a> tag used for activating
   * column sorting.
   *
   * Used to prevent the default action of the <a> tag.
   */
  onSortableColumnClick(event) {
    event.preventDefault();
  }

  /**
   * Returns props to be used on the TH element.
   */
  get tableHeaderProps() {
    const { ...props } = validProps(this);

    delete props.children;

    if (this.props.sortable) props.onClick = this.emitSortEvent;
    return props;
  }

  get isCurrentSortedColumn() {
    return this.props.sortable && this.props.name === this.context.sortedColumn;
  }

  /**
   * Returns sort icon HTML if column is sortable and has been sorted.
   */
  get sortIconHTML() {
    if (this.sorted) {
      const type = this.context.sortOrder === 'desc' ? 'sort-down' : 'sort-up';
      return <Icon type={ type } />;
    }
    return null;
  }

  /**
   * Determines if this column is currently sorted.
   */
  get sorted() {
    return this.props.sortable && this.context.sortedColumn === this.props.name;
  }

  /**
   * Returns descriptive text to describe the sortable column, and about
   * what will happen when they next attempt to sort the column i.e. which
   * direction it will sort in.
   *
   * NB If the current sortOrder is undefined, assume the next sort order
   */
  get sortDescription() {
    if (!this.props.sortable) {
      return null;
    }

    const currentSortOrder = this.context.sortOrder;
    let nextSortOrder = null;
    let currentSortDescription = null;

    if (currentSortOrder) {
      nextSortOrder = currentSortOrder === 'asc' ? 'descending' : 'ascending';
      currentSortDescription = `sorted ${currentSortOrder === 'desc' ? 'descending' : 'ascending'}, `;
    } else {
      nextSortOrder = 'descending';
      currentSortDescription = '';
    }

    return `Sortable column, ${currentSortDescription}activate to sort column ${nextSortOrder}`;
  }

  ariaAttributes() {
    const aria = {};
    if (this.context.sortOrder && this.isCurrentSortedColumn) {
      aria['aria-sort'] = this.context.sortOrder === 'asc' ? 'ascending' : 'descending';
    }

    return aria;
  }

  /**
   * Emits sort event to parent context - table.
   */
  emitSortEvent = () => {
    let sortOrder = this.context.sortOrder || 'desc';

    // If this is the current sorted column. flip order
    if (this.sorted) {
      sortOrder = this.context.sortOrder === 'asc' ? 'desc' : 'asc';
    }

    this.context.onSort(this.props.name, sortOrder);
  }

  componentTags(props) {
    return {
      'data-component': 'table-header',
      'data-element': props['data-element'],
      'data-role': props['data-role']
    };
  }

  styledComponent() {
    return this.props.styledComponent || StyledTableHeader;
  }

  /**
   * Renders the component.
   */
  render() {
    let contents = null;

    if (this.props.sortable) {
      const sortOrder = this.context.sortOrder === 'asc' ? 'desc' : 'asc';
      contents = (
        <a
          href={ `#sort-${sortOrder}` }
          aria-label={ this.sortDescription }
          onClick={ this.onSortableColumnClick }
        >
          { this.sortIconHTML }
          { this.props.children }
        </a>
      );
    } else {
      contents = this.props.children;
    }

    const headerProps = {
      align: this.props.align,
      sortable: this.props.sortable
    };

    if (/^\d+$/.test(this.props.width)) headerProps.width = this.props.width;

    return (
      React.createElement(
        this.styledComponent(),
        {
          ...this.componentTags(this.props),
          ...this.tableHeaderProps,
          ...this.ariaAttributes(),
          ...headerProps
        },
        contents
      )
    );
  }
}

TableHeader.propTypes = {

  /** Aligns the content of the cell (can be "left", "center" or "right"). */
  align: PropTypes.oneOf(OptionsHelper.alignFull),

  /** The body of the content component. */
  children: PropTypes.node,

  /** Name of the column to sort. Should correspond to name in database. */
  name(props, propName) {
    if (props.sortable) {
      if (!props[propName]) {
        throw new Error('Sortable columns require a prop of name of type String');
      }
      if (typeof props[propName] !== 'string') {
        throw new Error('name must be a string');
      }
    }
  },

  /** Whether column is sortable. */
  sortable: PropTypes.bool,

  /** Whether component is a subheader. */
  styledComponent: PropTypes.node,

  /** A width value to constrain a column eg '250'. */
  width: PropTypes.string
};

TableHeader.defaultProps = {
  children: null,
  name: '',
  sortable: false,
  align: 'left'
};

/** Sort handler passed from table context  */
TableHeader.contextTypes = {
  onSort: PropTypes.func,
  sortedColumn: PropTypes.string,
  sortOrder: PropTypes.string
};

export default TableHeader;
<commit_msg>Uses isNaN instead of regex<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import StyledTableHeader from './table-header.style';
import Icon from '../../icon/icon';
import { validProps } from '../../../utils/ether/ether';
import OptionsHelper from '../../../utils/helpers/options-helper';

/**
 * A TableHeader widget.
 *
 * == How to use a TableHeader in a component:
 *
 * See documentation for Table component.
 *
 * You can set a property of 'align' which should be a string. This will
 * align the content to either "left", "center" or "right".
 *
 * == Sortable Columns:
 *
 * To make a column sortable, pass a prop of 'sortable={ true }' to the corresponding
 * TableHeader.
 * Sortable columns also require a 'name' prop which must correspond to the database key.
 *
 * You can also provide a custom sortOrder - 'asc' (ascending) or 'desc' (descending).
 * By Default columns are sorted in ascending order.
 *
 * See the Table documentation for more information on hooking up a change handler
 * to setup sort functionality in your app.
 */
class TableHeader extends React.Component {
  /**
   * Event handler for clicks on the <a> tag used for activating
   * column sorting.
   *
   * Used to prevent the default action of the <a> tag.
   */
  onSortableColumnClick(event) {
    event.preventDefault();
  }

  /**
   * Returns props to be used on the TH element.
   */
  get tableHeaderProps() {
    const { ...props } = validProps(this);

    delete props.children;

    if (this.props.sortable) props.onClick = this.emitSortEvent;
    return props;
  }

  get isCurrentSortedColumn() {
    return this.props.sortable && this.props.name === this.context.sortedColumn;
  }

  /**
   * Returns sort icon HTML if column is sortable and has been sorted.
   */
  get sortIconHTML() {
    if (this.sorted) {
      const type = this.context.sortOrder === 'desc' ? 'sort-down' : 'sort-up';
      return <Icon type={ type } />;
    }
    return null;
  }

  /**
   * Determines if this column is currently sorted.
   */
  get sorted() {
    return this.props.sortable && this.context.sortedColumn === this.props.name;
  }

  /**
   * Returns descriptive text to describe the sortable column, and about
   * what will happen when they next attempt to sort the column i.e. which
   * direction it will sort in.
   *
   * NB If the current sortOrder is undefined, assume the next sort order
   */
  get sortDescription() {
    if (!this.props.sortable) {
      return null;
    }

    const currentSortOrder = this.context.sortOrder;
    let nextSortOrder = null;
    let currentSortDescription = null;

    if (currentSortOrder) {
      nextSortOrder = currentSortOrder === 'asc' ? 'descending' : 'ascending';
      currentSortDescription = `sorted ${currentSortOrder === 'desc' ? 'descending' : 'ascending'}, `;
    } else {
      nextSortOrder = 'descending';
      currentSortDescription = '';
    }

    return `Sortable column, ${currentSortDescription}activate to sort column ${nextSortOrder}`;
  }

  ariaAttributes() {
    const aria = {};
    if (this.context.sortOrder && this.isCurrentSortedColumn) {
      aria['aria-sort'] = this.context.sortOrder === 'asc' ? 'ascending' : 'descending';
    }

    return aria;
  }

  /**
   * Emits sort event to parent context - table.
   */
  emitSortEvent = () => {
    let sortOrder = this.context.sortOrder || 'desc';

    // If this is the current sorted column. flip order
    if (this.sorted) {
      sortOrder = this.context.sortOrder === 'asc' ? 'desc' : 'asc';
    }

    this.context.onSort(this.props.name, sortOrder);
  }

  componentTags(props) {
    return {
      'data-component': 'table-header',
      'data-element': props['data-element'],
      'data-role': props['data-role']
    };
  }

  styledComponent() {
    return this.props.styledComponent || StyledTableHeader;
  }

  /**
   * Renders the component.
   */
  render() {
    let contents = null;

    if (this.props.sortable) {
      const sortOrder = this.context.sortOrder === 'asc' ? 'desc' : 'asc';
      contents = (
        <a
          href={ `#sort-${sortOrder}` }
          aria-label={ this.sortDescription }
          onClick={ this.onSortableColumnClick }
        >
          { this.sortIconHTML }
          { this.props.children }
        </a>
      );
    } else {
      contents = this.props.children;
    }

    const headerProps = {
      align: this.props.align,
      sortable: this.props.sortable
    };

    if (!Number.isNaN(Number(this.props.width))) headerProps.width = this.props.width;

    return (
      React.createElement(
        this.styledComponent(),
        {
          ...this.componentTags(this.props),
          ...this.tableHeaderProps,
          ...this.ariaAttributes(),
          ...headerProps
        },
        contents
      )
    );
  }
}

TableHeader.propTypes = {

  /** Aligns the content of the cell (can be "left", "center" or "right"). */
  align: PropTypes.oneOf(OptionsHelper.alignFull),

  /** The body of the content component. */
  children: PropTypes.node,

  /** Name of the column to sort. Should correspond to name in database. */
  name(props, propName) {
    if (props.sortable) {
      if (!props[propName]) {
        throw new Error('Sortable columns require a prop of name of type String');
      }
      if (typeof props[propName] !== 'string') {
        throw new Error('name must be a string');
      }
    }
  },

  /** Whether column is sortable. */
  sortable: PropTypes.bool,

  /** Whether component is a subheader. */
  styledComponent: PropTypes.node,

  /** A width value to constrain a column eg '250'. */
  width: PropTypes.string
};

TableHeader.defaultProps = {
  children: null,
  name: '',
  sortable: false,
  align: 'left'
};

/** Sort handler passed from table context  */
TableHeader.contextTypes = {
  onSort: PropTypes.func,
  sortedColumn: PropTypes.string,
  sortOrder: PropTypes.string
};

export default TableHeader;
<|endoftext|>


<commit_before>var fs   = require('fs'),
    path = require('path'),
    glob = require('glob');

var settings = {
	web_root     : '/js/',
	include_file : 'client_require.js',
	app_root     : process.env.PWD,
	env          : process.env.NODE_ENV,
	uglify       : true
}, require_paths = [], initPaths = [];

function config(k,v) {
	settings[k] = v;
}

var REQUIRE_METH = '__fhtagn__.req';

var scripts = false, scriptCallbacks = [], scriptPending = false;
function getScripts(cb) {

	if (!cb) return;

	if (scripts) return cb(false, scripts);

	scriptCallbacks.push(cb);

	if (scriptPending) return;

	scriptPending = true;

	var modules = [], pending = 0;

	function unpend() {
		if (pending==0) {
			scriptPending = false;
			scripts = modules;
			var s = scriptCallbacks.shift();
			while(s) {
				s(null,modules);
				s = scriptCallbacks.shift();
			}
		}
	}

	function contextualize(p,modulePath) {

		var file, mod, web, index, rpath,
		    fpath   = p.split('/');

		function rel(f) {
			return path.relative(settings.app_root,f).replace(/\.\.\//g, '');
		}

		if (fpath[fpath.length-2]=="server"||fpath[fpath.length-2]=="client") {
			fpath[fpath.length-2] = "client";
			file = fpath.join('/');
			fpath.splice(-2,1);
			mod = fpath.join('/');
		} else {
			file = p;
			mod  = p;
		}

		file  = file;
		mod   = rel(mod);
		web   = settings.web_root+rel(file);
		index = (modulePath) ? (rel(modulePath) || "__index__") : false;
		rpath = rel(p);

		return {file:file, module:mod, web:web, relative:rpath, index: index};

	}

	function grabFile(file, modulePath, initPath) {
		var paths = contextualize(file,modulePath);
		var module_path = modulePath || paths.module;
		pending++;
		fs.readFile(paths.file,'utf-8',function (err, f){
			pending--;
			modules.push({
				content: f,
				module_path: paths.module,
				file_path: paths.file,
				web_path: paths.web,
				relative_path: paths.relative,
				index_path: paths.index
			});
			if (initPath) initPaths.push(paths.module);
			unpend();
		});
	}

	function walk(p,initPath) {
		p = path.normalize(p);
		pending++;
		fs.readFile(path.join(p, 'package.json'), 'utf-8', function(e,d) {

			if (e) throw e;
			pending--;
			d = JSON.parse(d || "{}");
			var deps  = d.client_dependencies || [],
			    index = d.main;
			if (!index.match(/\.js$/)) index += '.js';
			deps.forEach(function(dep) {
				walk(path.join(p, 'node_modules', dep));
			});

			grabFile(path.join(p, index), p, initPath);

			if (!d.client_require) return unpend();
			pending++;

			// Glob up everything else in the path.
			glob(path.join(p, "**", "*.js"), function(e,files) {
				pending--;
				if (!files) return unpend();
				files.forEach(function(file) {
					// If we went through all the node modules recursively as if
					// they were all full client-side requires, we'd end up with
					// a crapload of test code and server-side stuff loading on
					// the client.
					if (file.match(new RegExp('^'+p+'/node_modules'))) {
						return;
					}
					// Explicitly ignore things in /server/.
					if (file.match(/\/server\//)) return;
					grabFile(file);
				});
				unpend();
			});
		});
	};

	for (var p in require_paths) walk(require_paths[p], true);
	walk(settings.app_root, true);

}

var packed = false, packCallbacks = [], packPending = false;
function packScripts(scripts,cb) {

	if (!cb) return;

	if (packed) return cb(false, packed);

	packCallbacks.push(cb);

	if (packPending) return;

	packPending = true;

	// Separating the manifest from the files allows us to load each file once
	// without losing its module path aliases.
	var files = {}, manifest = {};

	function callback(e) {
		packed = files;
		var p = packCallbacks.shift();
		while(p) {
			p(null,packed);
			p = packCallbacks.shift();
		}
	}

	var moduleTemplate = path.join(__dirname, '..', 'templates', 'module.js');
	var indexFile;

	fs.readFile(moduleTemplate, 'utf-8', function(e,tmp) {
		tmp = tmp.replace(/\s+/g, " ");
		files[settings.web_root+'fhtagn.js'] = function(fun) {
			var fhtagn = path.join(__dirname, '..', 'client', 'fhtagn.js');
			fs.readFile(fhtagn,'utf-8',function (err, txt){
				fun(null,txt);
			});
		};
		scripts.forEach(function(f) {
			if (!manifest[f.web_path]) manifest[f.web_path] = [];
			manifest[f.web_path].push(f.module_path);
			if (f.module_path != f.relative_path) {
				manifest[f.web_path].push(f.relative_path);
			}
			if (f.index_path) {
				manifest[f.web_path].push(f.index_path);
			}
			if (f.module_path=="__index__") indexFile = true;
			var pack = function(cb) {
				fs.readFile(f.file_path,'utf-8',function (err, d){
					if (err) throw "Error loading file "+f.file_path+': '+e;
					var o = {};
					o.content = '\n'+d+'\n';
					o.module_path    = JSON.stringify(manifest[f.web_path]);
					o.canonical_path = path.dirname(f.relative_path);
					if (o.caninical_path = '.') o.caninical_path = "";
					o.canonical_path = JSON.stringify(o.canonical_path);
					var c = tmp.replace(/{{(\w*)}}/g, function(m,k) {
						return o[k] || '';
					});
					cb(err, c);
				});
			};
			files[f.web_path] = pack;
		});
		callback();
	});

}

function getInitCode() {
	var out = "";
	initPaths.forEach(function(p) {
		out += '\n'+REQUIRE_METH+'("'+p+'");';
	});
	return out;
}

var compiled = false, compilerCallbacks = [], compiling = false;
function compileScripts(cb) {

	if (compiled) return cb(null, compiled);
	if (cb) compilerCallbacks.push(cb);
	if (compiling) return;

	compiling = true;

	function callback(e) {
		compiling = false;
		var p = compilerCallbacks.shift();
		while(p) {
			p(null,packed);
			p = compilerCallbacks.shift();
		}
	}

	getScripts(function(e,scripts) {

		packScripts(scripts, function(e,files) {

			var q = [], modules = "";

			for (var f in files) q.push(files[f]);
			function next() {
				var f = q.shift();
				if (!f) return serveModules();
				f(function(e,d) {
					modules += d;
					next();
				});
			} next();

			function serveModules() {
				var app = path.join(
					__dirname, '..', 'templates', 'global_closure.js'
				), fhtagn = path.join(
					__dirname, '..', 'client', 'fhtagn.js'
				);
				fs.readFile(app, 'utf-8', function(e,tmp) {
					fs.readFile(fhtagn, 'utf-8', function(e,fhtagn) {
						if (e) return cb(e);
						tmp = tmp.split("{{fhtagn.js}}").join(fhtagn);
						tmp = tmp.split("{{modules}}").join(modules);
						tmp = tmp.split("{{initialize}}").join(getInitCode());
						if (settings.uglify) {
							//Compress with UglifyJs
							var jsp  = require("uglify-js").parser,
							    pro  = require("uglify-js").uglify,
							    code = jsp.parse(tmp);
							code = pro.ast_mangle(code);
							code = pro.ast_squeeze(code);
							tmp  = pro.gen_code(code);
						}
						compiled = tmp;
						callback();
					});
				});
			}

		});

	});

	function callback(e) {
		compiling = false;
		var p = compilerCallbacks.shift();
		while(p) {
			p(null,packed);
			p = compilerCallbacks.shift();
		}
	}

}

function new_require(p) {

	if (!p.match(/^(\/|\\)/)) {
		p = path.normalize(path.join(path.dirname(module.parent.id),p));
	}

	var mpath = path.dirname(module.parent.filename),
	    sp    = mpath.replace(/server/, '')+p;

	//If the module doesn't exist, check in the server/ path.
	if (!path.existsSync(p) && path.existsSync(sp)) p = sp;

	return module.parent.require(p);

}

function getSrcs(cb) {
	getScripts(function(e,scripts) {
		packScripts(scripts,function(e,d) {
			var srcs = [];
			for (var k in d) srcs.push(k);
			cb(null, srcs);
		});
	});
}

function serveScript(p, cb) {

	p = settings.web_root+p;

	var is_app = (p==settings.web_root+settings.include_file);

	getScripts(function(e,scripts) {

		packScripts(scripts, function(e,files) {

			if (settings.env!="production") {

				if (is_app) {
					var tmp = path.join(__dirname, '..', 'templates', 'client_require.js'),
					    lab = path.join(__dirname, '..', 'templates', 'LAB.js');
					getSrcs(function(e,srcs) {
						var includes = "$LAB";
						srcs.forEach(function(src) {
							includes += ".script('"+src+"')\n";
						});
						fs.readFile(tmp, 'utf-8', function(e,tmp) {
							tmp = tmp.replace('{{LABScripts}}', includes);
							var inits = "";
							tmp = tmp.replace('{{initialize}}', getInitCode());
							fs.readFile(lab, 'utf-8', function(e,f) {
								tmp = tmp.replace('{{LAB.js}}', f);
								cb(null, tmp);
							});
						});
					});
					return;
				}

				if (files[p]) {
					files[p](function(e,d) { cb(e,d); });
				} else {
					cb(e||"File not found");
				}

			} else {

				if (is_app) return compileScripts(cb);

			}

		});

	});

}

function handle(req,res) {

	var url  = require('url').parse(req.url).path,
	    patt = '^'+settings.web_root.replace('/', '\/')+'(.*)$',
	    m    = url.match(new RegExp(patt));

	if (!m) return false;

	serveScript(m[1], function(e,d) {
		if (e) {
			res.writeHead('404');
			res.end("File not found");
		} else {
			res.writeHead('200');
			res.end(d);
		}
	});

	return true;

}

function listen(server) {

	server.on('request', function (req,res) {
		handle(req, res);
	});

}

function connect_server() {

	return function(req, res, next) {
		if (!handle(req,res)) next();
	}

}

function getIncludePath() {
	return settings.web_root+settings.include_file;
}

function add_path(p) {
	require_paths.push(p);
}

if (settings.env=="production") {
	compileScripts();
}

module.exports = {
	set      : config,
	require  : new_require,
	connect  : connect_server,
	add_path : add_path,
	get_src  : getIncludePath,
	handle   : handle
};<commit_msg>Changed to be consistently only spaces.<commit_after>var fs   = require('fs'),
    path = require('path'),
    glob = require('glob');

var settings = {
	web_root     : '/js/',
	include_file : 'client_require.js',
	app_root     : process.env.PWD,
	env          : process.env.NODE_ENV,
	uglify       : true
}, require_paths = [], initPaths = [];

function config(k,v) {
	settings[k] = v;
}

var REQUIRE_METH = '__fhtagn__.req';

var scripts = false, scriptCallbacks = [], scriptPending = false;
function getScripts(cb) {

	if (!cb) return;

	if (scripts) return cb(false, scripts);

	scriptCallbacks.push(cb);

	if (scriptPending) return;

	scriptPending = true;

	var modules = [], pending = 0;

	function unpend() {
		if (pending==0) {
			scriptPending = false;
			scripts = modules;
			var s = scriptCallbacks.shift();
			while(s) {
				s(null,modules);
				s = scriptCallbacks.shift();
			}
		}
	}

	function contextualize(p,modulePath) {

		var file, mod, web, index, rpath,
			fpath   = p.split('/');

		function rel(f) {
			return path.relative(settings.app_root,f).replace(/\.\.\//g, '');
		}

		if (fpath[fpath.length-2]=="server"||fpath[fpath.length-2]=="client") {
			fpath[fpath.length-2] = "client";
			file = fpath.join('/');
			fpath.splice(-2,1);
			mod = fpath.join('/');
		} else {
			file = p;
			mod  = p;
		}

		file  = file;
		mod   = rel(mod);
		web   = settings.web_root+rel(file);
		index = (modulePath) ? (rel(modulePath) || "__index__") : false;
		rpath = rel(p);

		return {file:file, module:mod, web:web, relative:rpath, index: index};

	}

	function grabFile(file, modulePath, initPath) {
		var paths = contextualize(file,modulePath);
		var module_path = modulePath || paths.module;
		pending++;
		fs.readFile(paths.file,'utf-8',function (err, f){
			pending--;
			modules.push({
				content: f,
				module_path: paths.module,
				file_path: paths.file,
				web_path: paths.web,
				relative_path: paths.relative,
				index_path: paths.index
			});
			if (initPath) initPaths.push(paths.module);
			unpend();
		});
	}

	function walk(p,initPath) {
		p = path.normalize(p);
		pending++;
		fs.readFile(path.join(p, 'package.json'), 'utf-8', function(e,d) {

			if (e) throw e;
			pending--;
			d = JSON.parse(d || "{}");
			var deps  = d.client_dependencies || [],
				index = d.main;
			if (!index.match(/\.js$/)) index += '.js';
			deps.forEach(function(dep) {
				walk(path.join(p, 'node_modules', dep));
			});

			grabFile(path.join(p, index), p, initPath);

			if (!d.client_require) return unpend();
			pending++;

			// Glob up everything else in the path.
			glob(path.join(p, "**", "*.js"), function(e,files) {
				pending--;
				if (!files) return unpend();
				files.forEach(function(file) {
					// If we went through all the node modules recursively as if
					// they were all full client-side requires, we'd end up with
					// a crapload of test code and server-side stuff loading on
					// the client.
					if (file.match(new RegExp('^'+p+'/node_modules'))) {
						return;
					}
					// Explicitly ignore things in /server/.
					if (file.match(/\/server\//)) return;
					grabFile(file);
				});
				unpend();
			});
		});
	};

	for (var p in require_paths) walk(require_paths[p], true);
	walk(settings.app_root, true);

}

var packed = false, packCallbacks = [], packPending = false;
function packScripts(scripts,cb) {

	if (!cb) return;

	if (packed) return cb(false, packed);

	packCallbacks.push(cb);

	if (packPending) return;

	packPending = true;

	// Separating the manifest from the files allows us to load each file once
	// without losing its module path aliases.
	var files = {}, manifest = {};

	function callback(e) {
		packed = files;
		var p = packCallbacks.shift();
		while(p) {
			p(null,packed);
			p = packCallbacks.shift();
		}
	}

	var moduleTemplate = path.join(__dirname, '..', 'templates', 'module.js');
	var indexFile;

	fs.readFile(moduleTemplate, 'utf-8', function(e,tmp) {
		tmp = tmp.replace(/\s+/g, " ");
		files[settings.web_root+'fhtagn.js'] = function(fun) {
			var fhtagn = path.join(__dirname, '..', 'client', 'fhtagn.js');
			fs.readFile(fhtagn,'utf-8',function (err, txt){
				fun(null,txt);
			});
		};
		scripts.forEach(function(f) {
			if (!manifest[f.web_path]) manifest[f.web_path] = [];
			manifest[f.web_path].push(f.module_path);
			if (f.module_path != f.relative_path) {
				manifest[f.web_path].push(f.relative_path);
			}
			if (f.index_path) {
				manifest[f.web_path].push(f.index_path);
			}
			if (f.module_path=="__index__") indexFile = true;
			var pack = function(cb) {
				fs.readFile(f.file_path,'utf-8',function (err, d){
					if (err) throw "Error loading file "+f.file_path+': '+e;
					var o = {};
					o.content = '\n'+d+'\n';
					o.module_path    = JSON.stringify(manifest[f.web_path]);
					o.canonical_path = path.dirname(f.relative_path);
					if (o.caninical_path = '.') o.caninical_path = "";
					o.canonical_path = JSON.stringify(o.canonical_path);
					var c = tmp.replace(/{{(\w*)}}/g, function(m,k) {
						return o[k] || '';
					});
					cb(err, c);
				});
			};
			files[f.web_path] = pack;
		});
		callback();
	});

}

function getInitCode() {
	var out = "";
	initPaths.forEach(function(p) {
		out += '\n'+REQUIRE_METH+'("'+p+'");';
	});
	return out;
}

var compiled = false, compilerCallbacks = [], compiling = false;
function compileScripts(cb) {

	if (compiled) return cb(null, compiled);
	if (cb) compilerCallbacks.push(cb);
	if (compiling) return;

	compiling = true;

	function callback(e) {
		compiling = false;
		var p = compilerCallbacks.shift();
		while(p) {
			p(null,packed);
			p = compilerCallbacks.shift();
		}
	}

	getScripts(function(e,scripts) {

		packScripts(scripts, function(e,files) {

			var q = [], modules = "";

			for (var f in files) q.push(files[f]);
			function next() {
				var f = q.shift();
				if (!f) return serveModules();
				f(function(e,d) {
					modules += d;
					next();
				});
			} next();

			function serveModules() {
				var app = path.join(
					__dirname, '..', 'templates', 'global_closure.js'
				), fhtagn = path.join(
					__dirname, '..', 'client', 'fhtagn.js'
				);
				fs.readFile(app, 'utf-8', function(e,tmp) {
					fs.readFile(fhtagn, 'utf-8', function(e,fhtagn) {
						if (e) return cb(e);
						tmp = tmp.split("{{fhtagn.js}}").join(fhtagn);
						tmp = tmp.split("{{modules}}").join(modules);
						tmp = tmp.split("{{initialize}}").join(getInitCode());
						if (settings.uglify) {
							//Compress with UglifyJs
							var jsp  = require("uglify-js").parser,
								pro  = require("uglify-js").uglify,
								code = jsp.parse(tmp);
							code = pro.ast_mangle(code);
							code = pro.ast_squeeze(code);
							tmp  = pro.gen_code(code);
						}
						compiled = tmp;
						callback();
					});
				});
			}

		});

	});

	function callback(e) {
		compiling = false;
		var p = compilerCallbacks.shift();
		while(p) {
			p(null,packed);
			p = compilerCallbacks.shift();
		}
	}

}

function new_require(p) {

	if (!p.match(/^(\/|\\)/)) {
		p = path.normalize(path.join(path.dirname(module.parent.id),p));
	}

	var mpath = path.dirname(module.parent.filename),
		sp    = mpath.replace(/server/, '')+p;

	//If the module doesn't exist, check in the server/ path.
	if (!path.existsSync(p) && path.existsSync(sp)) p = sp;

	return module.parent.require(p);

}

function getSrcs(cb) {
	getScripts(function(e,scripts) {
		packScripts(scripts,function(e,d) {
			var srcs = [];
			for (var k in d) srcs.push(k);
			cb(null, srcs);
		});
	});
}

function serveScript(p, cb) {

	p = settings.web_root+p;

	var is_app = (p==settings.web_root+settings.include_file);

	getScripts(function(e,scripts) {

		packScripts(scripts, function(e,files) {

			if (settings.env!="production") {

				if (is_app) {
					var tmp = path.join(__dirname, '..', 'templates', 'client_require.js'),
						lab = path.join(__dirname, '..', 'templates', 'LAB.js');
					getSrcs(function(e,srcs) {
						var includes = "$LAB";
						srcs.forEach(function(src) {
							includes += ".script('"+src+"')\n";
						});
						fs.readFile(tmp, 'utf-8', function(e,tmp) {
							tmp = tmp.replace('{{LABScripts}}', includes);
							var inits = "";
							tmp = tmp.replace('{{initialize}}', getInitCode());
							fs.readFile(lab, 'utf-8', function(e,f) {
								tmp = tmp.replace('{{LAB.js}}', f);
								cb(null, tmp);
							});
						});
					});
					return;
				}

				if (files[p]) {
					files[p](function(e,d) { cb(e,d); });
				} else {
					cb(e||"File not found");
				}

			} else {

				if (is_app) return compileScripts(cb);

			}

		});

	});

}

function handle(req,res) {

	var url  = require('url').parse(req.url).path,
		patt = '^'+settings.web_root.replace('/', '\/')+'(.*)$',
		m    = url.match(new RegExp(patt));

	if (!m) return false;

	serveScript(m[1], function(e,d) {
		if (e) {
			res.writeHead('404');
			res.end("File not found");
		} else {
			res.writeHead('200');
			res.end(d);
		}
	});

	return true;

}

function listen(server) {

	server.on('request', function (req,res) {
		handle(req, res);
	});

}

function connect_server() {

	return function(req, res, next) {
		if (!handle(req,res)) next();
	}

}

function getIncludePath() {
	return settings.web_root+settings.include_file;
}

function add_path(p) {
	require_paths.push(p);
}

if (settings.env=="production") {
	compileScripts();
}

module.exports = {
	set      : config,
	require  : new_require,
	connect  : connect_server,
	add_path : add_path,
	get_src  : getIncludePath,
	handle   : handle
};<|endoftext|>


<commit_before>const express = require('express');

const generateErrors = require('../generate-errors');
const dbConnect = require('../db-connect');

const router = express.Router();

const TABLE_NAME = 'test_table';

// Retrieve a list of every `test` resource
router.get('/', (req, res) => {
  dbConnect(res, (client, done) => {
    client.query(`SELECT * FROM ${TABLE_NAME}`, (err, result) => {
      done();
      if (err) {
        console.error(err);
        res.status(500).send({
          errors: [generateErrors.generateGenericError()]
        });
      } else {
        res.send({
          data: result.rows
        });
      }
    });
  });
});

// Create a new "test" resource
router.post('/', (req, res) => {
  const id = req.body.id;
  const name = req.body.name;

  // Ensure that the user has submitted the required fields
  var errors = [];
  if (!id) {
    errors.push({
      title: "Missing Field",
      description: "An id attribute is required."
    });
  }
  if (!name) {
    errors.push({
      title: "Missing Field",
      description: "A name attribute is required."
    });
  }

  if (errors.length) {
    res.status(400).send({
      errors
    });
  } else {
    dbConnect(res, (client, done) => {
      client.query(`INSERT INTO ${TABLE_NAME} VALUES (${id}, '${name}')`, (err, result) => {
        done();
        if (err) {
          console.error(err);
          res.status(500).send({
            errors: [generateErrors.generateGenericError()]
          });
        } else {
          res.send({
            data: result.rows[0]
          });
        }
      });
    });
  }
});

// Return a single `test` resource
router.get('/:id', (req, res) => {
  dbConnect(res, (client, done) => {
    client.query(`SELECT * FROM ${TABLE_NAME} WHERE id = ${req.params.id}`, (err, result) => {
      done();
      if (err) {
        console.error(err);
        res.status(500).send({
          errors: [generateErrors.generateGenericError()]
        });
      } else {
        if (!result.rows.length) {
          res.status(404).send({
            errors: [generateErrors.generateNotFoundError()]
          });
        } else {
          res.send({
            data: result.rows[0]
          });
        }
      }
    });
  });
});

router.delete('/:id', (req, res) => {
  const id = req.params.id;

  dbConnect(res, (client, done) => {
    client.query(`DELETE FROM ${TABLE_NAME} WHERE id = ${id}`, (err, result) => {
      done();
      if (err) {
        console.error(err);
        res.status(500).send({
          errors: [generateErrors.generateGenericError()]
        });
      } else {
        res.end();
      }
    });
  });
});

module.exports = router;
<commit_msg>Add patch HTTP method to API for "test" resource<commit_after>const express = require('express');

const generateErrors = require('../generate-errors');
const dbConnect = require('../db-connect');

const router = express.Router();

const TABLE_NAME = 'test_table';

// Retrieve a list of every `test` resource
router.get('/', (req, res) => {
  dbConnect(res, (client, done) => {
    client.query(`SELECT * FROM ${TABLE_NAME}`, (err, result) => {
      done();
      if (err) {
        console.error(err);
        res.status(500).send({
          errors: [generateErrors.generateGenericError()]
        });
      } else {
        res.send({
          data: result.rows
        });
      }
    });
  });
});

// Create a new `test` resource
router.post('/', (req, res) => {
  const id = req.body.id;
  const name = req.body.name;

  // Ensure that the user has submitted the required fields
  var errors = [];
  if (typeof id === 'undefined') {
    errors.push({
      title: "Missing Field",
      description: "An id attribute is required."
    });
  }
  if (typeof name === 'undefined') {
    errors.push({
      title: "Missing Field",
      description: "A name attribute is required."
    });
  }

  if (errors.length) {
    res.status(400).send({
      errors
    });
  } else {
    dbConnect(res, (client, done) => {
      client.query(`INSERT INTO ${TABLE_NAME} VALUES (${id}, '${name}')`, (err, result) => {
        done();
        if (err) {
          console.error(err);
          res.status(500).send({
            errors: [generateErrors.generateGenericError()]
          });
        } else {
          res.end();
        }
      });
    });
  }
});

// Return a single `test` resource
router.get('/:id', (req, res) => {
  dbConnect(res, (client, done) => {
    client.query(`SELECT * FROM ${TABLE_NAME} WHERE id = ${req.params.id}`, (err, result) => {
      done();
      if (err) {
        console.error(err);
        res.status(500).send({
          errors: [generateErrors.generateGenericError()]
        });
      } else {
        if (!result.rows.length) {
          res.status(404).send({
            errors: [generateErrors.generateNotFoundError()]
          });
        } else {
          res.send({
            data: result.rows[0]
          });
        }
      }
    });
  });
});

// Update a `test` resource
router.patch('/:id', (req, res) => {
  const id = req.params.id;
  const name = req.body.name;

  if (typeof name === 'undefined') {
    res.status(400).send({
      errors: [{
        title: "Missing Field",
        description: "An name attribute is required."
      }]
    });
  }

  dbConnect(res, (client, done) => {
    client.query(`UPDATE ${TABLE_NAME} SET name = '${name}' WHERE id = ${id}`, (err, result) => {
      done();
      if (err) {
        console.error(err);
        res.status(500).send({
          errors: [generateErrors.generateGenericError()]
        });
      } else {
        res.send({
          data: result.rows[0]
        });
      }
    });
  });
});

// Delete a `test` resource
router.delete('/:id', (req, res) => {
  const id = req.params.id;

  dbConnect(res, (client, done) => {
    client.query(`DELETE FROM ${TABLE_NAME} WHERE id = ${id}`, (err, result) => {
      done();
      if (err) {
        console.error(err);
        res.status(500).send({
          errors: [generateErrors.generateGenericError()]
        });
      } else {
        res.end();
      }
    });
  });
});

module.exports = router;
<|endoftext|>


<commit_before>/*!
 * Gruntfile for Sortable Web Parts
 * Christopher Parsons <cparsons@habaneroconsulting.com>
 * Habanero Consulting Group - Licensed under MIT
 */

module.exports = function(grunt) {

	/**
	 * Load required Grunt tasks.
	 */
	grunt.loadNpmTasks('grunt-bookmarklet-thingy');
	grunt.loadNpmTasks('grunt-contrib-clean');
	grunt.loadNpmTasks('grunt-contrib-copy');
	grunt.loadNpmTasks('grunt-contrib-jshint');
	grunt.loadNpmTasks('grunt-contrib-uglify');

	/**
	 * Task configuration
	 */
	var taskConfig = {
		dirs: {
			build: 'bin',
			bookmarklet: '<%= dirs.build %>/bookmarklet',
			plugin: '<%= dirs.build %>/plugin',
			src: 'src'
		},

		files: {
			bookmarlet: 'sp-sortablewebparts.bookmarklet.js',
			main: 'sp-sortablewebparts.js',
			plugin: 'sp-sortablewebparts.min.js'
		},

		pkg: grunt.file.readJSON('package.json'),

		clean: {
			bookmarklet: '<%= dirs.bookmarklet %>/*',
			plugin: '<%= dirs.plugin %>/*'
		},

		jshint: {
			src: [
				'<%= dirs.src %>/*.js'
			],
			gruntfile: [
				'Gruntfile.js'
			],
			options: {
				ignores: ['/**/*.min.js'],
				curly: true,
				immed: true,
				newcap: false,
				noarg: true,
				sub: true,
				boss: true,
				eqnull: true,
				multistr: true,
				scripturl: true,
				smarttabs: true,
				'-W099': true,
				loopfunc: true
			}
		},

		bookmarklet: {
			generate: {
				js: [
					'https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js',
					'https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js'
				],
				jsIds: [
					'jquery-min',
					'jquery-ui-min'
				],
				body: '<%= dirs.src %>/<%= files.main %>',
				out: '<%= dirs.bookmarklet %>/<%= files.bookmarlet %>',
				amdify: false,
				timestamp: false
			}
		},

		uglify: {
			plugin: {
				files: {
					'<%= dirs.plugin %>/<%= files.plugin %>': ['<%= dirs.src %>/<%= files.main %>']
				},
				options: {
					preserveComments: 'some'
				}
			}
		},

		copy: {
			plugin: {
				files: [
					{
						src: ['**', '.**/*'],
						dest: '<%= dirs.plugin %>/vendor',
						cwd: '<%= dirs.src %>/vendor',
						expand: true
					}
				]
			}
		}
	};

	grunt.initConfig(taskConfig);

	/**
	 * Register tasks
	 */
	grunt.registerTask('plugin', [
		'clean:plugin', 'jshint', 'uglify:plugin', 'copy:plugin'
	]);

	grunt.registerTask('bookmark', [
		'clean:bookmarklet', 'jshint', 'bookmarklet'
	]);

	grunt.registerTask('build', [
		'plugin', 'bookmark'
	]);
};<commit_msg>Added VS solution copy/package into gruntfile<commit_after>/*!
 * Gruntfile for Sortable Web Parts
 * Christopher Parsons <cparsons@habaneroconsulting.com>
 * Habanero Consulting Group - Licensed under MIT
 */

module.exports = function(grunt) {

	/**
	 * Load required Grunt tasks.
	 */
	grunt.loadNpmTasks('grunt-bookmarklet-thingy');
	grunt.loadNpmTasks('grunt-contrib-clean');
	grunt.loadNpmTasks('grunt-contrib-copy');
	grunt.loadNpmTasks('grunt-contrib-jshint');
	grunt.loadNpmTasks('grunt-contrib-uglify');

	/**
	 * Task configuration
	 */
	var taskConfig = {
		dirs: {
			build: 'bin',
			bookmarklet: '<%= dirs.build %>/bookmarklet',
			pkg: 'pkg',
			plugin: '<%= dirs.build %>/plugin',
			src: 'src',
			vs: '<%= dirs.build %>/vs',
			vsScripts: '<%= dirs.build %>/vs/Habanero.SortableWebParts/SortableWebParts/Scripts'
		},

		files: {
			bookmarlet: 'sp-sortablewebparts.bookmarklet.js',
			main: 'sp-sortablewebparts.js',
			plugin: 'sp-sortablewebparts.min.js'
		},

		pkg: grunt.file.readJSON('package.json'),

		clean: {
			bookmarklet: '<%= dirs.bookmarklet %>/*',
			plugin: '<%= dirs.plugin %>/*',
			vs: '<%= dirs.vs %>/*'
		},

		jshint: {
			src: [
				'<%= dirs.src %>/*.js'
			],
			gruntfile: [
				'Gruntfile.js'
			],
			options: {
				ignores: ['/**/*.min.js'],
				curly: true,
				immed: true,
				newcap: false,
				noarg: true,
				sub: true,
				boss: true,
				eqnull: true,
				multistr: true,
				scripturl: true,
				smarttabs: true,
				'-W099': true,
				loopfunc: true
			}
		},

		bookmarklet: {
			generate: {
				js: [
					'https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js',
					'https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js'
				],
				jsIds: [
					'jquery-min',
					'jquery-ui-min'
				],
				body: '<%= dirs.src %>/<%= files.main %>',
				out: '<%= dirs.bookmarklet %>/<%= files.bookmarlet %>',
				amdify: false,
				timestamp: false
			}
		},

		uglify: {
			plugin: {
				files: {
					'<%= dirs.plugin %>/<%= files.plugin %>': ['<%= dirs.src %>/<%= files.main %>']
				},
				options: {
					preserveComments: 'some'
				}
			},
			vs: {
				files: {
					'<%= dirs.vsScripts %>/<%= files.plugin %>': ['<%= dirs.src %>/<%= files.main %>']
				},
				options: {
					preserveComments: 'some'
				}
			}
		},

		copy: {
			plugin: {
				files: [
					{
						src: ['**', '.**/*'],
						dest: '<%= dirs.plugin %>/vendor',
						cwd: '<%= dirs.src %>/vendor',
						expand: true
					}
				]
			},
			vs: {
				files: [
					{
						src: ['**', '.**/*'],
						dest: '<%= dirs.vs %>',
						cwd: '<%= dirs.pkg %>',
						expand: true
					},
					{
						src: ['**', '.**/*'],
						dest: '<%= dirs.vsScripts %>/vendor',
						cwd: '<%= dirs.src %>/vendor',
						expand: true
					}
				]
			}
		}
	};

	grunt.initConfig(taskConfig);

	/**
	 * Register tasks
	 */
	grunt.registerTask('plugin', [
		'clean:plugin', 'jshint', 'uglify:plugin', 'copy:plugin'
	]);

	grunt.registerTask('bookmark', [
		'clean:bookmarklet', 'jshint', 'bookmarklet'
	]);

	grunt.registerTask('vs', [
		'clean:vs', 'jshint', 'copy:vs', 'uglify:vs'
	]);

	grunt.registerTask('default', [
		'plugin', 'bookmark', 'vs'
	]);
};<|endoftext|>