<commit_before>var test = require('prova');
var mercury = require('mercury');
var _ = require('lodash');
var proxyquire = require('proxyquireify')(require);
var mockLRUCache = require('./mocks/lru-cache');

// 8885 is the expected wspr port to be running for the tests
// @noCallThru ensures this completely overrdies the original config
// instead of inheriting the properties that are not defined here from
// the original dependency
var veyronConfigForTest = {
  'authenticate': false,
  'wspr': 'http://localhost:8885',
  '@noCallThru': true
};

// Require namespaceService but using test specific mocks and configs
var namespaceService =
  proxyquire('../../../../src/services/namespace/service.js', {
    '../../veyron-config': veyronConfigForTest,
    'lru-cache': function() {
      return mockLRUCache;
    }
  });

test('getChildren of default namespace root', function(t) {
  namespaceService.getChildren().
  then(function assertResult(result) {
    // Wait until we receive the 2 top level items: cottage, house
    assertIsImmutable(t, result);
    var numMutations = 0;
    result(function(children) {
      numMutations++;
      // TODO(aghassemi) namespace glob can return duplicate results, glob
      // function replaces duplicate nodes so we wait until 4 mutations
      // are done (two adds and two replaces of house and cottage)
      if (numMutations === 4) {
        children = _.sortBy(children, 'mountedName');
        assertCottage(children[0]);
        assertHouse(children[1]);
        t.end();
      }
    });
  }).catch(t.end);

  function assertCottage(item) {
    assertServer(t, item, {
      name: 'cottage',
      objectName: 'cottage',
      isGlobbable: true,
      type: 'mounttable'
    });
  }

  function assertHouse(item) {
    assertServer(t, item, {
      name: 'house',
      objectName: 'house',
      isGlobbable: true,
      type: 'mounttable'
    });
  }
});

test('getChildren of cottage/lawn', function(t) {
  namespaceService.getChildren('cottage/lawn').
  then(function assertResult(result) {
    // Wait until we receive the 3 items,
    // back, front and master-sprinkler come back
    assertIsImmutable(t, result);
    var numReturnedChildren;
    result(function(children) {
      numReturnedChildren = children.length;
      if (numReturnedChildren === 3) {
        children = _.sortBy(children, 'mountedName');
        assertBack(children[0]);
        assertSprinkler(children[2]);
        t.end();
      }
    });
  }).catch(t.end);

  function assertSprinkler(item) {
    assertServer(t, item, {
      name: 'master-sprinkler',
      objectName: 'cottage/lawn/master-sprinkler',
      isGlobbable: false,
      type: 'unknown'
    });
  }

  function assertBack(item) {
    assertIntermediaryName(t, item, {
      name: 'back',
      objectName: 'cottage/lawn/back'
    });
  }
});

test('getChildren of rooted /localhost:8881/house/kitchen', function(t) {

  // 8881 is the expected root mounttable port to be running for the tests
  namespaceService.getChildren('/localhost:8881/house/kitchen').
  then(function assertResult(result) {
    // Wait until we receive the 2 items, lights and smoke-detector
    assertIsImmutable(t, result);
    var numReturnedChildren;
    result(function(children) {
      numReturnedChildren = children.length;
      if (numReturnedChildren === 2) {
        children = _.sortBy(children, 'mountedName');
        assertLightSwitch(children[0]);
        assertSmokeDetector(children[1]);
        t.end();
      }
    });
  }).catch(t.end);

  function assertLightSwitch(item) {
    assertServer(t, item, {
      name: 'lights',
      objectName: '/localhost:8881/house/kitchen/lights',
      isGlobbable: false,
      type: 'unknown'
    });
  }

  function assertSmokeDetector(item) {
    assertServer(t, item, {
      name: 'smoke-detector',
      objectName: '/localhost:8881/house/kitchen/smoke-detector',
      isGlobbable: false,
      type: 'unknown'
    });
  }
});

test('getChildren of non-existing mounttable', function(t) {
  // TODO(aghassemi) why does namespace library return empty results instead of
  // error when globbing rooted names that don't exist?
  namespaceService.getChildren('/DoesNotExist:666/What/Ever').
  then(function assertResult(result) {
    // Expect empty results
    mercury.watch(result, function(children) {
      t.deepEqual(children, []);
      t.end();
    });
  }).catch(t.end);
});

// TODO(aghassemi) enable when getNamespaceItem is properly implemented
test('getNamespaceItem of leaf server', function(t) {
  namespaceService.getNamespaceItem('cottage/lawn/master-sprinkler').
  then(function assertItem(itemObs) {
    assertIsImmutable(t, itemObs);
    var item = itemObs();
    assertServer(t, item, {
      name: 'master-sprinkler',
      objectName: 'cottage/lawn/master-sprinkler',
      isGlobbable: false,
      type: 'unknown'
    });
    t.end();
  }).catch(t.end);
});

test('getNamespaceItem of intermediary name', function(t) {
  namespaceService.getNamespaceItem('cottage/lawn/back').
  then(function assertItem(itemObs) {
    assertIsImmutable(t, itemObs);
    var item = itemObs();
    assertIntermediaryName(t, item, {
      name: 'back',
      objectName: 'cottage/lawn/back'
    });
    t.end();
  }).catch(t.end);
});

test('getNamespaceItem of mounttable leaf server', function(t) {
  namespaceService.getNamespaceItem('cottage').
  then(function assertItem(itemObs) {
    assertIsImmutable(t, itemObs);
    var item = itemObs();
    assertServer(t, item, {
      name: 'cottage',
      objectName: 'cottage',
      isGlobbable: true,
      type: 'mounttable'
    });
    t.end();
  }).catch(t.end);
});

test('search uses caching', function(t) {
  mockLRUCache.reset();

  namespaceService.search('house', '*').
  then(function assertNoCacheHit() {
    t.notOk(mockLRUCache.wasCacheHit('glob|house/*'),
      'first glob call is not a cache hit');

    // Call second time, there should have been a cache hit
    return namespaceService.search('house', '*');
  }).then(function assertCacheHit() {
    t.ok(mockLRUCache.wasCacheHit('glob|house/*'),
      'second glob call is a cache hit');

    // Call glob with same name, different query
    return namespaceService.search('house', 'foo*');
  }).then(function assertNoCacheHit() {
    t.notOk(mockLRUCache.wasCacheHit('glob|house/foo*'),
      'third glob call with different query is not a cache hit');
    t.end();
  }).catch(t.end);
});

test('getSignature uses caching', function(t) {
  mockLRUCache.reset();

  namespaceService.getSignature('house/alarm').then(function() {
    t.notOk(mockLRUCache.wasCacheHit('getSignature|house/alarm'),
      'first getSignature call is not a cache hit');
    // Call a second time
    return namespaceService.getSignature('house/alarm');
  }).then(function() {
    t.ok(mockLRUCache.wasCacheHit('getSignature|house/alarm'),
      'second getSignature call is a cache hit');
    // Call a different name
    return namespaceService.getSignature('house/kitchen/smoke-detector');
  }).then(function() {
    t.notOk(mockLRUCache.wasCacheHit(
      'getSignature|house/kitchen/smoke-detector'
    ),'third getSignature call to a different name is not a cache hit');
    t.end();
  }).catch(t.end);
});

//TODO(aghassemi)
//Tests for:
// Recursive glob
// Glob with some keyword
// Ensuring array is updated when nodes get mounted and unmounted (when we use
// watchGlob)

// Make RPC: good inputs => no error
var okRPCs = {
  'no input':     ['house/alarm', 'status', []],
  'bool input':   ['house/living-room/lights', 'flipSwitch', [true]],
  'int input':    ['cottage/smoke-detector', 'sensitivity', [2]],
  'float input':  ['house/alarm', 'delayArm', [2.5]],
  'string input': ['cottage/pool/speaker', 'playSong', ['Happy Birthday']],
  'slice input':  ['house/master-bedroom/speaker', 'addSongs', [['A', 'B']]],
  '2+ inputs':    ['cottage/pool/heater', 'start', [70, 5]],
};

_.forOwn(okRPCs, function run(params, inputType) {
  test(
    'makeRPC accepts good input - ' + inputType,
    testMakeRPCNoError.bind(null, params)
  );
});

// Make RPC: bad inputs => error
var badRPCs = {
  'no service':    ['mansion/smoke-detector', 'status', []],
  'no method':     ['cottage/pool/speaker', 'status', []],
  'no input':      ['cottage/lights','flipSwitch', null],
  'bad type':      ['cottage/lights','flipSwitch', ['notBool']],
  'lacks input':   ['cottage/pool/heater','start', [80]],
  'invalid input': ['house/living-room/blast-speaker','playSong', ['notThere']]
};

_.forOwn(badRPCs, function run(params, inputType) {
  test(
    'makeRPC errors on bad input - ' + inputType,
    testMakeRPCHasError.bind(null, params)
  );
});

// Make RPC: outputs have the expected # of outputs
test('makeRPC returns output properly', function(t) {
  namespaceService.makeRPC('cottage/alarm', 'panic', []).then(
    function got0Outputs(res) { // 0 outputs: has [] as a result.
      t.ok(res instanceof Array && res.length === 0, '0 outputs => []');

      return namespaceService.makeRPC('house/alarm', 'status', []);
    }
  ).then( // 1 output: (Non-array/slice output) is not an Array.
    function got1Output(res) {
      t.notOk(res instanceof Array, '1 output => not an Array');

      return namespaceService.makeRPC('cottage/smoke-detector', 'test', []);
    }
  ).then( // 1 output: Delayed return. Also not an array.
    function got1OutputDelayed(res) {
      t.notOk(res instanceof Array, '1 output => not an Array');

      return namespaceService.makeRPC('cottage/pool/heater', 'status', []);
    }
  ).then( // 2 outputs: Is an Array of the correct length.
    function got2Outputs(res) {
      var ok = res instanceof Array && res.length === 2;
      t.ok(ok, '2 outputs => length 2 Array');
      t.end();
    }
  ).catch(t.end);
});

/*
 * Test helpers
 */
function assertServer(t, item, vals) {
  assertMountedName(t, item, vals.name);
  assertObjectName(t, item, vals.objectName);
  assertIsServer(t, item);
  if (vals.isGlobbable === true) {
    assertIsGlobbable(t, item);
  } else if(vals.isGlobbable === false) {
    assertIsNotGlobbable(t, item);
  }
  assertHasSignature(t, item);
  assertIsAccessible(t, item);

  if (vals.type === 'unknown') {
    assertUnknownServiceTypeInfo(t, item);
  } else if (vals.type === 'mounttable') {
    assertMounttableServiceTypeInfo(t, item);
  } else {
    t.fail('Unknown type: ' + vals.type);
  }
}

function assertIntermediaryName(t, item, vals) {
  assertMountedName(t, item, vals.name);
  assertObjectName(t, item, vals.objectName);
  assertIsNotServer(t, item);
  assertIsGlobbable(t, item);
}

function assertMountedName(t, item, val) {
  t.ok(item.mountedName, item.mountedName + ': has a mounted name');
  t.equal(item.mountedName, val, item.mountedName + ': mounted name matches');
}

function assertObjectName(t, item, val) {
  t.ok(item.objectName, item.mountedName + ': has an object name');
  t.equal(item.objectName, val, item.mountedName + ': object name matches');
}

function assertIsServer(t, item) {
  t.equal(item.isServer, true, item.mountedName + ': is a server');
  t.ok(item.serverInfo, item.mountedName + ': has server info');
}

function assertIsNotServer(t, item) {
  t.equal(item.isServer, false, item.mountedName + ': is not a server');
  t.notOk(item.serverInfo, item.mountedName + ': does not have server info');
}

function assertIsGlobbable(t, item) {
  t.equal(item.isGlobbable, true, item.mountedName + ': is globbable');
}

function assertIsNotGlobbable(t, item) {
  t.equal(item.isGlobbable, false, item.mountedName + ': is not globbable');
}

function assertHasSignature(t, item) {
  t.ok(item.serverInfo.signature, item.mountedName + ': has a signature');
}

function assertIsAccessible(t, item) {
  t.ok(item.serverInfo.isAccessible, item.mountedName + ': is accessible');
}

function assertIsImmutable(t, observable) {
  t.ok(observable.set === undefined, 'is immutable');
}

/*
 * Asserts that a ServiceTypeInfo is of predefined type of Unknown Service.
 */
function assertUnknownServiceTypeInfo(t, item) {
  var typeInfo = item.serverInfo.typeInfo;
  t.equal(typeInfo.key, 'veyron-unknown',
    item.mountedName + ': unknown type info has the right key');

  t.equal(typeInfo.typeName, 'Service',
    item.mountedName + ': unknown type info has the type name');

  t.equal(typeInfo.description, null,
    item.mountedName + ': unknown type info does not have description');
}

/*
 * Asserts that a ServiceTypeInfo is of predefined type of mounttable.
 */
function assertMounttableServiceTypeInfo(t, item) {
  var typeInfo = item.serverInfo.typeInfo;
  t.equal(typeInfo.key, 'veyron-mounttable',
    item.mountedName + ': mounttable type info has the right key');

  t.equal(typeInfo.typeName, 'Mount Table',
    item.mountedName + ': mounttable type info has the type name');

  t.ok(typeInfo.description,
    item.mountedName + ': mounttable type info has a description');
}
/*
 * Runs a test to ensure the makeRPC call terminates without error.
 */
function testMakeRPCNoError(args, t) {
  namespaceService.makeRPC.apply(null, args).then(function(result) {
    t.pass('completed without error');
    t.end();
  }).catch(function(err) {
    t.fail('should not have returned an error');
    t.end();
  });
}

/*
 * Runs a test to ensure the makeRPC call terminates with an error.
 */
function testMakeRPCHasError(args, t) {
  namespaceService.makeRPC.apply(null, args).then(function(result) {
    t.fail('should not have completed without error');
    t.end();
  }).catch(function(err) {
    t.pass('correctly returned an error');
    t.end();
  });
}<commit_msg>veyron-browser: TBR: Fixing a test's reliance on order of rpcs which was not good and easily broken by a low level change like adding channel encryption.<commit_after>var test = require('prova');
var mercury = require('mercury');
var _ = require('lodash');
var proxyquire = require('proxyquireify')(require);
var mockLRUCache = require('./mocks/lru-cache');

// 8885 is the expected wspr port to be running for the tests
// @noCallThru ensures this completely overrdies the original config
// instead of inheriting the properties that are not defined here from
// the original dependency
var veyronConfigForTest = {
  'authenticate': false,
  'wspr': 'http://localhost:8885',
  '@noCallThru': true
};

// Require namespaceService but using test specific mocks and configs
var namespaceService =
  proxyquire('../../../../src/services/namespace/service.js', {
    '../../veyron-config': veyronConfigForTest,
    'lru-cache': function() {
      return mockLRUCache;
    }
  });

test('getChildren of default namespace root', function(t) {
  var TIMEOUT = 1000;
  namespaceService.getChildren().
  then(function assertResult(result) {
    assertIsImmutable(t, result);
    // Wait until we receive the 2 top level items: cottage, house
    setTimeout(function validate() {
      mercury.watch(result, function(children) {
        children = _.sortBy(children, 'mountedName');
        assertCottage(children[0]);
        assertHouse(children[1]);
        t.end();
      });
    }, TIMEOUT);
    // TODO(aghassemi), TIMEOUT is sill not good, but events such as oncomplete
    // are coming to Glob soon, so change when that's available.
  }).catch(t.end);

  function assertCottage(item) {
    assertServer(t, item, {
      name: 'cottage',
      objectName: 'cottage',
      isGlobbable: true,
      type: 'mounttable'
    });
  }

  function assertHouse(item) {
    assertServer(t, item, {
      name: 'house',
      objectName: 'house',
      isGlobbable: true,
      type: 'mounttable'
    });
  }
});

test('getChildren of cottage/lawn', function(t) {
  namespaceService.getChildren('cottage/lawn').
  then(function assertResult(result) {
    // Wait until we receive the 3 items,
    // back, front and master-sprinkler come back
    assertIsImmutable(t, result);
    var numReturnedChildren;
    result(function(children) {
      numReturnedChildren = children.length;
      if (numReturnedChildren === 3) {
        children = _.sortBy(children, 'mountedName');
        assertBack(children[0]);
        assertSprinkler(children[2]);
        t.end();
      }
    });
  }).catch(t.end);

  function assertSprinkler(item) {
    assertServer(t, item, {
      name: 'master-sprinkler',
      objectName: 'cottage/lawn/master-sprinkler',
      isGlobbable: false,
      type: 'unknown'
    });
  }

  function assertBack(item) {
    assertIntermediaryName(t, item, {
      name: 'back',
      objectName: 'cottage/lawn/back'
    });
  }
});

test('getChildren of rooted /localhost:8881/house/kitchen', function(t) {

  // 8881 is the expected root mounttable port to be running for the tests
  namespaceService.getChildren('/localhost:8881/house/kitchen').
  then(function assertResult(result) {
    // Wait until we receive the 2 items, lights and smoke-detector
    assertIsImmutable(t, result);
    var numReturnedChildren;
    result(function(children) {
      numReturnedChildren = children.length;
      if (numReturnedChildren === 2) {
        children = _.sortBy(children, 'mountedName');
        assertLightSwitch(children[0]);
        assertSmokeDetector(children[1]);
        t.end();
      }
    });
  }).catch(t.end);

  function assertLightSwitch(item) {
    assertServer(t, item, {
      name: 'lights',
      objectName: '/localhost:8881/house/kitchen/lights',
      isGlobbable: false,
      type: 'unknown'
    });
  }

  function assertSmokeDetector(item) {
    assertServer(t, item, {
      name: 'smoke-detector',
      objectName: '/localhost:8881/house/kitchen/smoke-detector',
      isGlobbable: false,
      type: 'unknown'
    });
  }
});

test('getChildren of non-existing mounttable', function(t) {
  // TODO(aghassemi) why does namespace library return empty results instead of
  // error when globbing rooted names that don't exist?
  namespaceService.getChildren('/DoesNotExist:666/What/Ever').
  then(function assertResult(result) {
    // Expect empty results
    mercury.watch(result, function(children) {
      t.deepEqual(children, []);
      t.end();
    });
  }).catch(t.end);
});

// TODO(aghassemi) enable when getNamespaceItem is properly implemented
test('getNamespaceItem of leaf server', function(t) {
  namespaceService.getNamespaceItem('cottage/lawn/master-sprinkler').
  then(function assertItem(itemObs) {
    assertIsImmutable(t, itemObs);
    var item = itemObs();
    assertServer(t, item, {
      name: 'master-sprinkler',
      objectName: 'cottage/lawn/master-sprinkler',
      isGlobbable: false,
      type: 'unknown'
    });
    t.end();
  }).catch(t.end);
});

test('getNamespaceItem of intermediary name', function(t) {
  namespaceService.getNamespaceItem('cottage/lawn/back').
  then(function assertItem(itemObs) {
    assertIsImmutable(t, itemObs);
    var item = itemObs();
    assertIntermediaryName(t, item, {
      name: 'back',
      objectName: 'cottage/lawn/back'
    });
    t.end();
  }).catch(t.end);
});

test('getNamespaceItem of mounttable leaf server', function(t) {
  namespaceService.getNamespaceItem('cottage').
  then(function assertItem(itemObs) {
    assertIsImmutable(t, itemObs);
    var item = itemObs();
    assertServer(t, item, {
      name: 'cottage',
      objectName: 'cottage',
      isGlobbable: true,
      type: 'mounttable'
    });
    t.end();
  }).catch(t.end);
});

test('search uses caching', function(t) {
  mockLRUCache.reset();

  namespaceService.search('house', '*').
  then(function assertNoCacheHit() {
    t.notOk(mockLRUCache.wasCacheHit('glob|house/*'),
      'first glob call is not a cache hit');

    // Call second time, there should have been a cache hit
    return namespaceService.search('house', '*');
  }).then(function assertCacheHit() {
    t.ok(mockLRUCache.wasCacheHit('glob|house/*'),
      'second glob call is a cache hit');

    // Call glob with same name, different query
    return namespaceService.search('house', 'foo*');
  }).then(function assertNoCacheHit() {
    t.notOk(mockLRUCache.wasCacheHit('glob|house/foo*'),
      'third glob call with different query is not a cache hit');
    t.end();
  }).catch(t.end);
});

test('getSignature uses caching', function(t) {
  mockLRUCache.reset();

  namespaceService.getSignature('house/alarm').then(function() {
    t.notOk(mockLRUCache.wasCacheHit('getSignature|house/alarm'),
      'first getSignature call is not a cache hit');
    // Call a second time
    return namespaceService.getSignature('house/alarm');
  }).then(function() {
    t.ok(mockLRUCache.wasCacheHit('getSignature|house/alarm'),
      'second getSignature call is a cache hit');
    // Call a different name
    return namespaceService.getSignature('house/kitchen/smoke-detector');
  }).then(function() {
    t.notOk(mockLRUCache.wasCacheHit(
      'getSignature|house/kitchen/smoke-detector'
    ),'third getSignature call to a different name is not a cache hit');
    t.end();
  }).catch(t.end);
});

//TODO(aghassemi)
//Tests for:
// Recursive glob
// Glob with some keyword
// Ensuring array is updated when nodes get mounted and unmounted (when we use
// watchGlob)

// Make RPC: good inputs => no error
var okRPCs = {
  'no input':     ['house/alarm', 'status', []],
  'bool input':   ['house/living-room/lights', 'flipSwitch', [true]],
  'int input':    ['cottage/smoke-detector', 'sensitivity', [2]],
  'float input':  ['house/alarm', 'delayArm', [2.5]],
  'string input': ['cottage/pool/speaker', 'playSong', ['Happy Birthday']],
  'slice input':  ['house/master-bedroom/speaker', 'addSongs', [['A', 'B']]],
  '2+ inputs':    ['cottage/pool/heater', 'start', [70, 5]],
};

_.forOwn(okRPCs, function run(params, inputType) {
  test(
    'makeRPC accepts good input - ' + inputType,
    testMakeRPCNoError.bind(null, params)
  );
});

// Make RPC: bad inputs => error
var badRPCs = {
  'no service':    ['mansion/smoke-detector', 'status', []],
  'no method':     ['cottage/pool/speaker', 'status', []],
  'no input':      ['cottage/lights','flipSwitch', null],
  'bad type':      ['cottage/lights','flipSwitch', ['notBool']],
  'lacks input':   ['cottage/pool/heater','start', [80]],
  'invalid input': ['house/living-room/blast-speaker','playSong', ['notThere']]
};

_.forOwn(badRPCs, function run(params, inputType) {
  test(
    'makeRPC errors on bad input - ' + inputType,
    testMakeRPCHasError.bind(null, params)
  );
});

// Make RPC: outputs have the expected # of outputs
test('makeRPC returns output properly', function(t) {
  namespaceService.makeRPC('cottage/alarm', 'panic', []).then(
    function got0Outputs(res) { // 0 outputs: has [] as a result.
      t.ok(res instanceof Array && res.length === 0, '0 outputs => []');

      return namespaceService.makeRPC('house/alarm', 'status', []);
    }
  ).then( // 1 output: (Non-array/slice output) is not an Array.
    function got1Output(res) {
      t.notOk(res instanceof Array, '1 output => not an Array');

      return namespaceService.makeRPC('cottage/smoke-detector', 'test', []);
    }
  ).then( // 1 output: Delayed return. Also not an array.
    function got1OutputDelayed(res) {
      t.notOk(res instanceof Array, '1 output => not an Array');

      return namespaceService.makeRPC('cottage/pool/heater', 'status', []);
    }
  ).then( // 2 outputs: Is an Array of the correct length.
    function got2Outputs(res) {
      var ok = res instanceof Array && res.length === 2;
      t.ok(ok, '2 outputs => length 2 Array');
      t.end();
    }
  ).catch(t.end);
});

/*
 * Test helpers
 */
function assertServer(t, item, vals) {
  assertMountedName(t, item, vals.name);
  assertObjectName(t, item, vals.objectName);
  assertIsServer(t, item);
  if (vals.isGlobbable === true) {
    assertIsGlobbable(t, item);
  } else if(vals.isGlobbable === false) {
    assertIsNotGlobbable(t, item);
  }
  assertHasSignature(t, item);
  assertIsAccessible(t, item);

  if (vals.type === 'unknown') {
    assertUnknownServiceTypeInfo(t, item);
  } else if (vals.type === 'mounttable') {
    assertMounttableServiceTypeInfo(t, item);
  } else {
    t.fail('Unknown type: ' + vals.type);
  }
}

function assertIntermediaryName(t, item, vals) {
  assertMountedName(t, item, vals.name);
  assertObjectName(t, item, vals.objectName);
  assertIsNotServer(t, item);
  assertIsGlobbable(t, item);
}

function assertMountedName(t, item, val) {
  t.ok(item.mountedName, item.mountedName + ': has a mounted name');
  t.equal(item.mountedName, val, item.mountedName + ': mounted name matches');
}

function assertObjectName(t, item, val) {
  t.ok(item.objectName, item.mountedName + ': has an object name');
  t.equal(item.objectName, val, item.mountedName + ': object name matches');
}

function assertIsServer(t, item) {
  t.equal(item.isServer, true, item.mountedName + ': is a server');
  t.ok(item.serverInfo, item.mountedName + ': has server info');
}

function assertIsNotServer(t, item) {
  t.equal(item.isServer, false, item.mountedName + ': is not a server');
  t.notOk(item.serverInfo, item.mountedName + ': does not have server info');
}

function assertIsGlobbable(t, item) {
  t.equal(item.isGlobbable, true, item.mountedName + ': is globbable');
}

function assertIsNotGlobbable(t, item) {
  t.equal(item.isGlobbable, false, item.mountedName + ': is not globbable');
}

function assertHasSignature(t, item) {
  t.ok(item.serverInfo.signature, item.mountedName + ': has a signature');
}

function assertIsAccessible(t, item) {
  t.ok(item.serverInfo.isAccessible, item.mountedName + ': is accessible');
}

function assertIsImmutable(t, observable) {
  t.ok(observable.set === undefined, 'is immutable');
}

/*
 * Asserts that a ServiceTypeInfo is of predefined type of Unknown Service.
 */
function assertUnknownServiceTypeInfo(t, item) {
  var typeInfo = item.serverInfo.typeInfo;
  t.equal(typeInfo.key, 'veyron-unknown',
    item.mountedName + ': unknown type info has the right key');

  t.equal(typeInfo.typeName, 'Service',
    item.mountedName + ': unknown type info has the type name');

  t.equal(typeInfo.description, null,
    item.mountedName + ': unknown type info does not have description');
}

/*
 * Asserts that a ServiceTypeInfo is of predefined type of mounttable.
 */
function assertMounttableServiceTypeInfo(t, item) {
  var typeInfo = item.serverInfo.typeInfo;
  t.equal(typeInfo.key, 'veyron-mounttable',
    item.mountedName + ': mounttable type info has the right key');

  t.equal(typeInfo.typeName, 'Mount Table',
    item.mountedName + ': mounttable type info has the type name');

  t.ok(typeInfo.description,
    item.mountedName + ': mounttable type info has a description');
}
/*
 * Runs a test to ensure the makeRPC call terminates without error.
 */
function testMakeRPCNoError(args, t) {
  namespaceService.makeRPC.apply(null, args).then(function(result) {
    t.pass('completed without error');
    t.end();
  }).catch(function(err) {
    t.fail('should not have returned an error');
    t.end();
  });
}

/*
 * Runs a test to ensure the makeRPC call terminates with an error.
 */
function testMakeRPCHasError(args, t) {
  namespaceService.makeRPC.apply(null, args).then(function(result) {
    t.fail('should not have completed without error');
    t.end();
  }).catch(function(err) {
    t.pass('correctly returned an error');
    t.end();
  });
}<|endoftext|>


<commit_before>var winston = require('winston');

winston.logger.add('http_access',{
file: {
      filename: process.cwd()+'/http_access.log'
    }
});

winston.logger.add('users',{
file: {
      filename: process.cwd()+'/users.log'
    }
});

winston.logger.add('notify',{
file: {
      filename: process.cwd()+'/notifies.log'
    }
});

winston.logger.add('errors',{
file: {
      filename: process.cwd()+'/errors.log'
    }
});

var httpLog = winston.loggers.get('http_access'),
  userLog = winston.loggers.get('user'),
  notifyLog = winston.loggers.get('notifies'),
  errorLog = winston.loggers.get('errors');

exports.name = 'kabamPluginLoggerFile';

exports.exports.listeners = {
  'html' : function(html){
    httpLog.info('info',
    html.startTime, '-',
    html.method,
    html.uri,
    html.code, ' - ',
    html.duration, 'ms', '/',
    html.ip,
    html.username, ':'
    html.email);
  },
  'error': function(err){
    errorLog.error(err));
  }
};
<commit_msg>[feature] - http log<commit_after>var winston = require('winston');

winston.loggers.add('http_access',{
file: {
      filename: process.cwd()+'/logs/http_access.log'
    }
});

winston.loggers.add('users',{
file: {
      filename: process.cwd()+'/logs/users.log'
    }
});

winston.loggers.add('notify',{
file: {
      filename: process.cwd()+'/logs/notifies.log'
    }
});

winston.loggers.add('errors',{
file: {
      filename: process.cwd()+'/logs/errors.log'
    }
});

var httpLog = winston.loggers.get('http_access'),
  userLog = winston.loggers.get('user'),
  notifyLog = winston.loggers.get('notifies'),
  errorLog = winston.loggers.get('errors');

exports.name = 'kabamPluginLoggerFile';

exports.listeners = {
  'http' : function(html){
/*
    httpLog.info('info',
      html.startTime,' - ',
      html.method,
      html.uri,
      html.statusCode,' - ',
      html.duration, 'ms', '/',
      html.ip,
      html.username, ':',
      html.email
    );
*/
  httpLog.info(html);
  },
  'error': function(err){
    errorLog.error(err);
  }
};
<|endoftext|>


<commit_before>const DISCORD = require('discord.js');
const FUBUKI = new DISCORD.Client();

let config = require('./config');
let booru = require('./booru.js');
let remind = require('./remind.js');
let music_player = require('./musicplayer.js');
let misc = require('./misc.js');
let quote = require('./quote.js');
let finance = require('./finance.js');

FUBUKI.on('ready', () => {
  console.log('Ready');
});

FUBUKI.on('message', message => {
  let cmds = message.content.toLowerCase().split(' ');

  switch (cmds[0]) {
    case '!ping':
      message.channel.send('pong')
        .then(console.log(cmds))
        .catch( reason => { console.log("Rejected Pong Promise for " + reason); });
      break;
    case '!sleep':
      message.channel.send('Logging off. Bye!')
        .then(console.log('Logging off.'))
        .catch( reason => { console.log("Rejected Sleep Promise for " + reason); });
      message.delete()
        .catch( reason => { console.log("Rejected Sleepe Delete Promise for " + reason); });
      setTimeout(function(){
        FUBUKI.destroy();
        process.exit(0);
      }, 500);
      break;
    case '!booru':
      booru.getDanbooru(message, cmds);
      message.delete()
        .catch( reason => { console.log("Rejected Booru Delete Promise for " + reason); });
      break;
    case '!b':
      booru.getDanbooru(message, cmds);
      message.delete()
        .catch( reason => { console.log("Rejected Booru Delete Promise for " + reason); });
      break;
    case '!bsafe':
      let new_cmd = cmds;
      new_cmd.push('rating:safe');
      booru.getDanbooru(message, new_cmd);
      message.delete()
        .catch( reason => { console.log("Rejected Booru Delete Promise for " + reason); });
      break;
    case '!remindme':
      remind.remindMe(message);
      break;
    case '!play':
      music_player.play(message);
      message.delete()
        .then(msg => { console.log('Deleted message from ' + msg.author); })
        .catch( reason => { console.log("Rejected Music Delete Promise for " + reason); });
      break;
    case '!connect':
      music_player.connect(message.guild);
      break;
    case '!disconnect':
      music_player.disconnect(message.guild);
      break;
    case '!skip':
      music_player.skip(message);
      break;
    case '!repeat':
      music_player.repeat(message);
      break;
    case '!nowplaying':
      music_player.nowPlaying(message.channel);
      break;
    case '!radio':
      music_player.radio(message);
      message.delete()
        .then(msg => { console.log('Deleted message from ' + msg.author); })
        .catch( reason => { console.log("Rejected Radio Delete Promise for " + reason); });
      break;
    case '!stopradio':
      music_player.stopRadio();
      break;
    case '!urban':
      misc.urbanDefine(message, cmds);
      break;
    case '!a':
      misc.getAvatar(message, cmds);
      break;
    case '!coinflip':
      misc.coinFlip(message);
      break;
    case '!rate':
      misc.rate(message, cmds);
      break;
    case '!quote':
      if (cmds[1] !== 'fubuki' && cmds[2] !== "fubuki") {
        quote.quote(message, cmds, message.content.split(' '));
      } else {
        message.channel.send("I can't quote from myself dummy!")
          .then(function () {
            console.log("Refused to quote self");
          })
          .catch( reason => { console.log("Rejected Quote Fubuki Promise for " + reason); });
      }
      break;
    case '!stock':
      finance.getStock(message, cmds[1]);
      break;
    case '!help':
      let helpText = 'The following commands are avalible to this bot:\n\n' +
        '!ping Reply with "pong" if the bot is still functional.\n\n' +
        '!booru [tags] or !b [tags] Returns a link to a random Danbooru post' +
          ' with the given tags. If you have more than one tag, seperate' +
          ' them with a space.\n\n' +
        '!bsafe [tags] Functions the same as !booru and !b, but appends' +
        ' "rating:safe" to your request automatically.\n\n' +
        '!help The bot will DM you this help text.\n\n' +
        '!remindme [Message] in [number] [hour(s)/minute(s)] and [number] ' +
          '[hour(s)/minute(s)] The bot will @ you after the specified time. ' +
          'You can omit the "and" and everything after if desired. ' +
          'Case does not matter.\n\n' +
        '!connect The bot joins the music channel.\n\n' +
        '!play [youtube link] The bot plays the selected link in ' +
          'the music channel. If it was already playing something ' +
          'your link is added to the queue.\n\n' +
        '!disconnect The bot leaves the music channel ' +
          'and clears the queue of links to playback.\n\n' +
        '!skip Skips the current song in the queue.\n\n' +
        '!repeat Repeats the current song being played. This will be ' +
          'the last song played if no songs are currently playing.\n\n' +
        '!urban [term] Replies with the definition and example from Urban ' +
          'Dictionary if it exists\n\n' +
        '!a [username] Returns a link to the user\'s avatar\n\n' +
        '!rate [text] Gives a rating from 1 to 10';
      message.channel.send('Help is on the way! Check your DMs.')
        .catch( reason => { console.log("Rejected Help Public Promise for " + reason); });
      message.author.send(helpText)
        .catch( reason => { console.log("Rejected Help DM Promise for " + reason); });
      break;
    default:
  }
});

FUBUKI.on('disconnected', function() {
  console.log('Disconnected');
  process.exit(1);
});

FUBUKI.login(config.discord_token);
<commit_msg>Disabled Fubuki responses in DM<commit_after>const DISCORD = require('discord.js');
const FUBUKI = new DISCORD.Client();

let config = require('./config');
let booru = require('./booru.js');
let remind = require('./remind.js');
let music_player = require('./musicplayer.js');
let misc = require('./misc.js');
let quote = require('./quote.js');
let finance = require('./finance.js');

FUBUKI.on('ready', () => {
  console.log('Ready');
});

FUBUKI.on('message', message => {
  if (message.guild != undefined) {
    let cmds = message.content.toLowerCase().split(' ');

    switch (cmds[0]) {
      case '!ping':
        message.channel.send('pong')
          .then(console.log(cmds))
          .catch( reason => { console.log("Rejected Pong Promise for " + reason); });
        break;
      case '!sleep':
        message.channel.send('Logging off. Bye!')
          .then(console.log('Logging off.'))
          .catch( reason => { console.log("Rejected Sleep Promise for " + reason); });
        message.delete()
          .catch( reason => { console.log("Rejected Sleepe Delete Promise for " + reason); });
        setTimeout(function(){
          FUBUKI.destroy();
          process.exit(0);
        }, 500);
        break;
      case '!booru':
        booru.getDanbooru(message, cmds);
        message.delete()
          .catch( reason => { console.log("Rejected Booru Delete Promise for " + reason); });
        break;
      case '!b':
        booru.getDanbooru(message, cmds);
        message.delete()
          .catch( reason => { console.log("Rejected Booru Delete Promise for " + reason); });
        break;
      case '!bsafe':
        let new_cmd = cmds;
        new_cmd.push('rating:safe');
        booru.getDanbooru(message, new_cmd);
        message.delete()
          .catch( reason => { console.log("Rejected Booru Delete Promise for " + reason); });
        break;
      case '!remindme':
        remind.remindMe(message);
        break;
      case '!play':
        music_player.play(message);
        message.delete()
          .then(msg => { console.log('Deleted message from ' + msg.author); })
          .catch( reason => { console.log("Rejected Music Delete Promise for " + reason); });
        break;
      case '!connect':
        music_player.connect(message.guild);
        break;
      case '!disconnect':
        music_player.disconnect(message.guild);
        break;
      case '!skip':
        music_player.skip(message);
        break;
      case '!repeat':
        music_player.repeat(message);
        break;
      case '!nowplaying':
        music_player.nowPlaying(message.channel);
        break;
      case '!radio':
        music_player.radio(message);
        message.delete()
          .then(msg => { console.log('Deleted message from ' + msg.author); })
          .catch( reason => { console.log("Rejected Radio Delete Promise for " + reason); });
        break;
      case '!stopradio':
        music_player.stopRadio();
        break;
      case '!urban':
        misc.urbanDefine(message, cmds);
        break;
      case '!a':
        misc.getAvatar(message, cmds);
        break;
      case '!coinflip':
        misc.coinFlip(message);
        break;
      case '!rate':
        misc.rate(message, cmds);
        break;
      case '!quote':
        if (cmds[1] !== 'fubuki' && cmds[2] !== "fubuki") {
          quote.quote(message, cmds, message.content.split(' '));
        } else {
          message.channel.send("I can't quote from myself dummy!")
            .then(function () {
              console.log("Refused to quote self");
            })
            .catch( reason => { console.log("Rejected Quote Fubuki Promise for " + reason); });
        }
        break;
      case '!stock':
        finance.getStock(message, cmds[1]);
        break;
      case '!help':
        let helpText = 'The following commands are avalible to this bot:\n\n' +
          '!ping Reply with "pong" if the bot is still functional.\n\n' +
          '!booru [tags] or !b [tags] Returns a link to a random Danbooru post' +
            ' with the given tags. If you have more than one tag, seperate' +
            ' them with a space.\n\n' +
          '!bsafe [tags] Functions the same as !booru and !b, but appends' +
          ' "rating:safe" to your request automatically.\n\n' +
          '!help The bot will DM you this help text.\n\n' +
          '!remindme [Message] in [number] [hour(s)/minute(s)] and [number] ' +
            '[hour(s)/minute(s)] The bot will @ you after the specified time. ' +
            'You can omit the "and" and everything after if desired. ' +
            'Case does not matter.\n\n' +
          '!connect The bot joins the music channel.\n\n' +
          '!play [youtube link] The bot plays the selected link in ' +
            'the music channel. If it was already playing something ' +
            'your link is added to the queue.\n\n' +
          '!disconnect The bot leaves the music channel ' +
            'and clears the queue of links to playback.\n\n' +
          '!skip Skips the current song in the queue.\n\n' +
          '!repeat Repeats the current song being played. This will be ' +
            'the last song played if no songs are currently playing.\n\n' +
          '!urban [term] Replies with the definition and example from Urban ' +
            'Dictionary if it exists\n\n' +
          '!a [username] Returns a link to the user\'s avatar\n\n' +
          '!rate [text] Gives a rating from 1 to 10';
        message.channel.send('Help is on the way! Check your DMs.')
          .catch( reason => { console.log("Rejected Help Public Promise for " + reason); });
        message.author.send(helpText)
          .catch( reason => { console.log("Rejected Help DM Promise for " + reason); });
        break;
      default:
    }
  }
});

FUBUKI.on('disconnected', function() {
  console.log('Disconnected');
  process.exit(1);
});

FUBUKI.login(config.discord_token);
<|endoftext|>


<commit_before>var isolines = require('turf-isolines'),
    grid = require('turf-grid'),
    destination = require('turf-destination'),
    point = require('turf-point'),
    distance = require('turf-distance'),
    extent = require('turf-extent'),
    featureCollection = require('turf-featurecollection'),
    polylineDecode = require('polyline').decode,
    OSRM = require('osrm');

module.exports = function (center, time, options, done) {
    if (!options) throw 'options is mandatory';
    if (!options.resolution) throw 'resolution is mandatory in options';
    if (!options.network) throw 'network is mandatory in options';
    if (!options.maxspeed) throw 'maxspeed is mandatory in options';
    var unit = options.unit || 'miles';
    if (options && options.draw) {
        this.draw = options.draw;
    } else {
        this.draw = function(destinations) {
            return isolines(destinations, 'eta', options.resolution, [time]);
        };
    }
    this.getIsochrone = function() {
        var osrm = options.network instanceof OSRM ? options.network : new OSRM(options.network);
        // compute bbox
        // bbox should go out 1.4 miles in each direction for each minute
        // this will account for a driver going a bit above the max safe speed
        var centerPt = point(center[0], center[1]);
        var spokes = featureCollection([]);
        var length = (time/3600) * options.maxspeed;
        spokes.features.push(destination(centerPt, length, 180, unit));
        spokes.features.push(destination(centerPt, length, 0, unit));
        spokes.features.push(destination(centerPt, length, 90, unit));
        spokes.features.push(destination(centerPt, length, -90, unit));
        var bbox = this.bbox = extent(spokes);
        var sizeCellGrid = this.sizeCellGrid = distance(point(bbox[0], bbox[1]), point(bbox[0], bbox[3]), unit) / options.resolution;

        //compute destination grid
        var targets = grid(bbox, options.resolution);
        targets.features = targets.features.filter(function(feat) {
            return distance(point(feat.geometry.coordinates[0], feat.geometry.coordinates[1]), centerPt, unit) <= length;
        });
        var destinations = featureCollection([]);

        var coord = targets.features.map(function(feat) {
            return [feat.geometry.coordinates[1], feat.geometry.coordinates[0]]
        });
        osrm.table({
                destinations: coord,
                sources: [[center[1], center[0]]]
            }, function(err, res) {
                if (err) {
                    console.log(err);
                    return done(err);
                }
                if (res.distance_table &&
                    res.distance_table[0] && res.destination_coordinates &&
                    res.distance_table[0].length == res.destination_coordinates.length) {

                    res.distance_table[0].forEach(function(time, idx) {
                        var distanceMapped = distance(
                            point(coord[idx][1], coord[idx][0]),
                            point(res.destination_coordinates[idx][1], res.destination_coordinates[idx][0]),
                            unit
                        );
                        if (distanceMapped < sizeCellGrid) {
                            destinations.features.push({
                                type: 'Feature',
                                properties: {
                                    eta: time / 10
                                },
                                geometry: {
                                    type: 'Point',
                                    coordinates: [res.destination_coordinates[idx][1], res.destination_coordinates[idx][0]]
                                }
                            });
                        }
                        // specific for isoline algorithm: exclude some points from grid
                        else {
                            destinations.features.push({
                                type: 'Feature',
                                properties: {
                                    // this point cannot be routed => a penality 2 is applied to maxspeed
                                    eta: time + (distanceMapped - sizeCellGrid) / (options.maxspeed / 3600) * 2
                                },
                                geometry: {
                                    type: 'Point',
                                    coordinates: [coord[idx][1], coord[idx][0]]
                                }
                            });
                        }
                    });
                }
                var result = self.draw(destinations);
                return done(null, result);
            }
        );
    };
    var self = this;

    // in case module is called directly
    if (this.process && this.process.title == 'node')
        return getIsochrone();
}
<commit_msg>Update to new osrm-backend API.<commit_after>var isolines = require('turf-isolines'),
    grid = require('turf-grid'),
    destination = require('turf-destination'),
    point = require('turf-point'),
    distance = require('turf-distance'),
    extent = require('turf-extent'),
    featureCollection = require('turf-featurecollection'),
    polylineDecode = require('polyline').decode,
    OSRM = require('osrm');

module.exports = function (center, time, options, done) {
    if (!options) throw 'options is mandatory';
    if (!options.resolution) throw 'resolution is mandatory in options';
    if (!options.network) throw 'network is mandatory in options';
    if (!options.maxspeed) throw 'maxspeed is mandatory in options';
    var unit = options.unit || 'miles';
    if (options && options.draw) {
        this.draw = options.draw;
    } else {
        this.draw = function(destinations) {
            return isolines(destinations, 'eta', options.resolution, [time]);
        };
    }
    this.getIsochrone = function() {
        var osrm = options.network instanceof OSRM ? options.network : new OSRM(options.network);
        // compute bbox
        // bbox should go out 1.4 miles in each direction for each minute
        // this will account for a driver going a bit above the max safe speed
        var centerPt = point(center[0], center[1]);
        var spokes = featureCollection([]);
        var length = (time/3600) * options.maxspeed;
        spokes.features.push(destination(centerPt, length, 180, unit));
        spokes.features.push(destination(centerPt, length, 0, unit));
        spokes.features.push(destination(centerPt, length, 90, unit));
        spokes.features.push(destination(centerPt, length, -90, unit));
        var bbox = this.bbox = extent(spokes);
        var sizeCellGrid = this.sizeCellGrid = distance(point(bbox[0], bbox[1]), point(bbox[0], bbox[3]), unit) / options.resolution;

        //compute destination grid
        var targets = grid(bbox, options.resolution);
        targets.features = targets.features.filter(function(feat) {
            return distance(point(feat.geometry.coordinates[0], feat.geometry.coordinates[1]), centerPt, unit) <= length;
        });
        var destinations = featureCollection([]);

        var coord = targets.features.map(function(feat) {
            return [feat.geometry.coordinates[1], feat.geometry.coordinates[0]]
        });
        coord.push([center[1], center[0]]);
        osrm.table({
                coordinates: coord,
                sources: coord.length - 1;
            }, function(err, res) {
                if (err) {
                    console.log(err);
                    return done(err);
                }
                if (res.distance_table &&
                    res.distance_table[0] && res.destination_coordinates &&
                    res.distance_table[0].length == res.destination_coordinates.length) {

                    res.distance_table[0].forEach(function(time, idx) {
                        var distanceMapped = distance(
                            point(coord[idx][1], coord[idx][0]),
                            point(res.destination_coordinates[idx][1], res.destination_coordinates[idx][0]),
                            unit
                        );
                        if (distanceMapped < sizeCellGrid) {
                            destinations.features.push({
                                type: 'Feature',
                                properties: {
                                    eta: time / 10
                                },
                                geometry: {
                                    type: 'Point',
                                    coordinates: [res.destination_coordinates[idx][1], res.destination_coordinates[idx][0]]
                                }
                            });
                        }
                        // specific for isoline algorithm: exclude some points from grid
                        else {
                            destinations.features.push({
                                type: 'Feature',
                                properties: {
                                    // this point cannot be routed => a penality 2 is applied to maxspeed
                                    eta: time + (distanceMapped - sizeCellGrid) / (options.maxspeed / 3600) * 2
                                },
                                geometry: {
                                    type: 'Point',
                                    coordinates: [coord[idx][1], coord[idx][0]]
                                }
                            });
                        }
                    });
                }
                var result = self.draw(destinations);
                return done(null, result);
            }
        );
    };
    var self = this;

    // in case module is called directly
    if (this.process && this.process.title == 'node')
        return getIsochrone();
}
<|endoftext|>


<commit_before>'use strict';

var percentile = {
  name: 'percentile'
  , label: 'Percentile Chart'
  , pluginType: 'report'
};

function init() {
  return percentile;
}

module.exports = init;

percentile.html = function html(client) {
  var translate = client.translate;
  var ret =
      '
' + translate('Glucose Percentile report') + '
'
    + '
'
    + '

'
    + '
'
    ;
  return ret;
};

percentile.css =
    '#percentile-chart {'
  + '  width: 100%;'
  + '  height: 100%;'
  + '}'
  ;

percentile.report = function report_percentile(datastorage, sorteddaystoshow, options) {
  var Nightscout = window.Nightscout;
  var client = Nightscout.client;
  var translate = client.translate;
  var ss = require('simple-statistics');

  var minutewindow = 30; //minute-window should be a divisor of 60

  var data = datastorage.allstatsrecords;

  var bins = [];
  for (var hour = 0; hour < 24; hour++) {
    for (var minute = 0; minute < 60; minute = minute + minutewindow) {
      var date = new Date();
      date.setHours(hour);
      date.setMinutes(minute);
      var readings = data.filter(function(record) {
        var recdate = new Date(record.displayTime);
        return recdate.getHours() === hour && recdate.getMinutes() >= minute &&
          recdate.getMinutes() < minute + minutewindow;
      });
      readings = readings.map(function(record) {
        return record.sgv;
      });
      bins.push([date, readings]);
      //console.log(date +  " - " + readings.length);
      //readings.forEach(function(x){console.log(x)});
    }
  }
  var dat10 = bins.map(function(bin) {
    return [bin[0], ss.quantile(bin[1], 0.1)];
  });
  var dat25 = bins.map(function(bin) {
    return [bin[0], ss.quantile(bin[1], 0.25)];
  });
  var dat50 = bins.map(function(bin) {
    return [bin[0], ss.quantile(bin[1], 0.5)];
  });
  var dat75 = bins.map(function(bin) {
    return [bin[0], ss.quantile(bin[1], 0.75)];
  });
  var dat90 = bins.map(function(bin) {
    return [bin[0], ss.quantile(bin[1], 0.9)];
  });
  var high = options.targetHigh;
  var low = options.targetLow;
  //dat50.forEach(function(x){console.log(x[0] + " - " + x[1])});
  $.plot(
    '#percentile-chart', [{
      label: translate('Median'),
      data: dat50,
      id: 'c50',
      color: '#000000',
      points: {
        show: false
      },
      lines: {
        show: true,
        //fill: true
      }
    }, {
      label: '25%/75% '+translate('percentile'),
      data: dat25,
      id: 'c25',
      color: '#000055',
      points: {
        show: false
      },
      lines: {
        show: true,
        fill: true
      },
      fillBetween: 'c50'
    }, {
      data: dat75,
      id: 'c75',
      color: '#000055',
      points: {
        show: false
      },
      lines: {
        show: true,
        fill: true
      },
      fillBetween: 'c50'
    }, {
      label: '10%/90% '+translate('percentile'),
      data: dat10,
      id: 'c10',
      color: '#a0a0FF',
      points: {
        show: false
      },
      lines: {
        show: true,
        fill: true
      },
      fillBetween: 'c25'
    }, {
      data: dat90,
      id: 'c90',
      color: '#a0a0FF',
      points: {
        show: false
      },
      lines: {
        show: true,
        fill: true
      },
      fillBetween: 'c75'
    }, {
      label: translate('High'),
      data: [],
      color: '#FFFF00',
    }, {
      label: translate('Low'),
      data: [],
      color: '#FF0000',
    }], {
      xaxis: {
        mode: 'time',
        timezone: 'browser',
        timeformat: '%H:%M',
        tickColor: '#555',
      },
      yaxis: {
        min: 0,
        max: options.units === 'mmol' ? 22: 400,
        tickColor: '#555',
      },
      grid: {
        markings: [{
          color: '#FF0000',
          lineWidth: 2,
          yaxis: {
            from: low,
            to: low
          }
        }, {
          color: '#FFFF00',
          lineWidth: 2,
          yaxis: {
            from: high,
            to: high
          }
        }],
        //hoverable: true
      }
    }
  );
};
<commit_msg>codacy percentil.js<commit_after>'use strict';

var percentile = {
  name: 'percentile'
  , label: 'Percentile Chart'
  , pluginType: 'report'
};

function init() {
  return percentile;
}

module.exports = init;

percentile.html = function html(client) {
  var translate = client.translate;
  var ret =
      '
' + translate('Glucose Percentile report') + '
'
    + '
'
    + '

'
    + '
'
    ;
  return ret;
};

percentile.css =
    '#percentile-chart {'
  + '  width: 100%;'
  + '  height: 100%;'
  + '}'
  ;

percentile.report = function report_percentile(datastorage, sorteddaystoshow, options) {
  var Nightscout = window.Nightscout;
  var client = Nightscout.client;
  var translate = client.translate;
  var ss = require('simple-statistics');

  var minutewindow = 30; //minute-window should be a divisor of 60

  var data = datastorage.allstatsrecords;

  var bins = [];
  var filterFunc = function withinWindow(record) {
    var recdate = new Date(record.displayTime);
    return recdate.getHours() === hour && recdate.getMinutes() >= minute && recdate.getMinutes() < minute + minutewindow;
  };

  for (var hour = 0; hour < 24; hour++) {
    for (var minute = 0; minute < 60; minute = minute + minutewindow) {
      var date = new Date();
      date.setHours(hour);
      date.setMinutes(minute);
      var readings = data.filter(filterFunc);
      readings = readings.map(function(record) {
        return record.sgv;
      });
      bins.push([date, readings]);
      //console.log(date +  " - " + readings.length);
      //readings.forEach(function(x){console.log(x)});
    }
  }
  var dat10 = bins.map(function(bin) {
    return [bin[0], ss.quantile(bin[1], 0.1)];
  });
  var dat25 = bins.map(function(bin) {
    return [bin[0], ss.quantile(bin[1], 0.25)];
  });
  var dat50 = bins.map(function(bin) {
    return [bin[0], ss.quantile(bin[1], 0.5)];
  });
  var dat75 = bins.map(function(bin) {
    return [bin[0], ss.quantile(bin[1], 0.75)];
  });
  var dat90 = bins.map(function(bin) {
    return [bin[0], ss.quantile(bin[1], 0.9)];
  });
  var high = options.targetHigh;
  var low = options.targetLow;
  //dat50.forEach(function(x){console.log(x[0] + " - " + x[1])});
  $.plot(
    '#percentile-chart', [{
      label: translate('Median'),
      data: dat50,
      id: 'c50',
      color: '#000000',
      points: {
        show: false
      },
      lines: {
        show: true,
        //fill: true
      }
    }, {
      label: '25%/75% '+translate('percentile'),
      data: dat25,
      id: 'c25',
      color: '#000055',
      points: {
        show: false
      },
      lines: {
        show: true,
        fill: true
      },
      fillBetween: 'c50'
    }, {
      data: dat75,
      id: 'c75',
      color: '#000055',
      points: {
        show: false
      },
      lines: {
        show: true,
        fill: true
      },
      fillBetween: 'c50'
    }, {
      label: '10%/90% '+translate('percentile'),
      data: dat10,
      id: 'c10',
      color: '#a0a0FF',
      points: {
        show: false
      },
      lines: {
        show: true,
        fill: true
      },
      fillBetween: 'c25'
    }, {
      data: dat90,
      id: 'c90',
      color: '#a0a0FF',
      points: {
        show: false
      },
      lines: {
        show: true,
        fill: true
      },
      fillBetween: 'c75'
    }, {
      label: translate('High'),
      data: [],
      color: '#FFFF00',
    }, {
      label: translate('Low'),
      data: [],
      color: '#FF0000',
    }], {
      xaxis: {
        mode: 'time',
        timezone: 'browser',
        timeformat: '%H:%M',
        tickColor: '#555',
      },
      yaxis: {
        min: 0,
        max: options.units === 'mmol' ? 22: 400,
        tickColor: '#555',
      },
      grid: {
        markings: [{
          color: '#FF0000',
          lineWidth: 2,
          yaxis: {
            from: low,
            to: low
          }
        }, {
          color: '#FFFF00',
          lineWidth: 2,
          yaxis: {
            from: high,
            to: high
          }
        }],
        //hoverable: true
      }
    }
  );
};
<|endoftext|>


<commit_before>// A quick and dirty coffee wrapper ☕
require('coffee-script/register');
module.exports = require('./src/TileGrinder');
<commit_msg>:open_file_folder: optimizing folder path in main<commit_after>// A quick and dirty coffee wrapper ☕
require('coffee-script/register');
module.exports = require(__dirname+'/src/TileGrinder');
<|endoftext|>


<commit_before>const E2eHelpers = require('../e2e/e2e-helpers');
const Timeouts = require('../e2e/timeouts.js');
const GibsHelpers = require('../e2e/post-911-gib-status-helpers.js');
const LoginHelpers = require('../e2e/login-helpers');

module.exports = E2eHelpers.createE2eTest(
  (client) => {
    const token = LoginHelpers.getUserToken();

    GibsHelpers.initApplicationMock(token);

    // Ensure main status page renders.
    LoginHelpers.logIn(token, client, '/education/gi-bill/post-9-11/ch-33-benefit', 3)
      .waitForElementVisible('body', Timeouts.normal)
      .axeCheck('.main')
      .assert.title('Check Benefit: Vets.gov')
      .waitForElementVisible('.schemaform-title', Timeouts.slow);  // First render of React may be slow.

    // Checking field in UserInfoSection has rendered
    client.expect.element('#fullName').text.to.contain('First Last');

    // Checking field in EnrollmentHistory has rendered
    client.expect.element('#enrollment-0 h4').text.to.contain('11/01/2012 to 12/01/2012 at Purdue University');

    // Click on print page
    client
      .click('#print-button')
      .windowHandles((result) => {
        const newWindow = result.value[1];
        client.switchWindow(newWindow);
      });

    // Ensure print page renders.
    // We need to log in again here because Electron loses the session
    // when opening a new window.
    LoginHelpers.logIn(token, client, '/education/gi-bill/post-9-11/ch-33-benefit/print', 3)
      .waitForElementVisible('body', Timeouts.normal)
      .axeCheck('.main')
      .assert.title('Check Benefit: Vets.gov')
      .waitForElementVisible('.print-status', Timeouts.slow);  // First render of React may be slow.

    client.expect.element('.section-header').text.to.contain('Post-9/11 GI Bill Benefit Information');

    client.axeCheck('.main');

    client.end();
  }
);
<commit_msg>Change to window_handle<commit_after>const E2eHelpers = require('../e2e/e2e-helpers');
const Timeouts = require('../e2e/timeouts.js');
const GibsHelpers = require('../e2e/post-911-gib-status-helpers.js');
const LoginHelpers = require('../e2e/login-helpers');

module.exports = E2eHelpers.createE2eTest(
  (client) => {
    const token = LoginHelpers.getUserToken();

    GibsHelpers.initApplicationMock(token);

    // Ensure main status page renders.
    LoginHelpers.logIn(token, client, '/education/gi-bill/post-9-11/ch-33-benefit', 3)
      .waitForElementVisible('body', Timeouts.normal)
      .axeCheck('.main')
      .assert.title('Check Benefit: Vets.gov')
      .waitForElementVisible('.schemaform-title', Timeouts.slow);  // First render of React may be slow.

    // Checking field in UserInfoSection has rendered
    client.expect.element('#fullName').text.to.contain('First Last');

    // Checking field in EnrollmentHistory has rendered
    client.expect.element('#enrollment-0 h4').text.to.contain('11/01/2012 to 12/01/2012 at Purdue University');

    // Click on print page
    client
      .click('#print-button')
      .window_handles((result) => {
        const newWindow = result.value[1];
        client.switchWindow(newWindow);
      });

    // Ensure print page renders.
    // We need to log in again here because Electron loses the session
    // when opening a new window.
    LoginHelpers.logIn(token, client, '/education/gi-bill/post-9-11/ch-33-benefit/print', 3)
      .waitForElementVisible('body', Timeouts.normal)
      .axeCheck('.main')
      .assert.title('Check Benefit: Vets.gov')
      .waitForElementVisible('.print-status', Timeouts.slow);  // First render of React may be slow.

    client.expect.element('.section-header').text.to.contain('Post-9/11 GI Bill Benefit Information');

    client.axeCheck('.main');

    client.end();
  }
);
<|endoftext|>


<commit_before>// Import self, even though we don't use it, because otherwise our pageshow
// event handler doesn't get called.
var self = require('sdk/self');

var { ActionButton } = require("sdk/ui/button/action");
var tabs = require("sdk/tabs");
var { Cu } = require("chrome");
Cu.import("resource://gre/modules/Services.jsm");

const TCP_SOCKET_PERM = "tcp-socket";
const CONTACTS_READ_PERM = "contacts-read";
const LABEL_DISABLED = "mozTCPSocket/mozContacts APIs disabled";
const LABEL_ENABLED = "mozTCPSocket/mozContacts APIs enabled";
const ICON_DISABLED = "./unplugged.svg";
const ICON_ENABLED = "./plugged.svg";
const STATE_DISABLED = {
  label: LABEL_DISABLED,
  icon: ICON_DISABLED,
};
const STATE_ENABLED = {
  label: LABEL_ENABLED,
  icon: ICON_ENABLED,
};

function getPrincipal(tab) {
  var uri = Services.io.newURI(tab.url, null, null);
  var principal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(uri);
  return principal;
}

var button = ActionButton({
  id: "action-button",
  label: LABEL_DISABLED,
  icon: ICON_DISABLED,
  onClick: function(state) {
    if (state.label == LABEL_DISABLED) {
      Services.perms.addFromPrincipal(getPrincipal(tabs.activeTab), TCP_SOCKET_PERM, Services.perms.ALLOW_ACTION);
      Services.perms.addFromPrincipal(getPrincipal(tabs.activeTab), CONTACTS_READ_PERM, Services.perms.ALLOW_ACTION);
      button.state("tab", STATE_ENABLED);
    }
    else {
      Services.perms.removeFromPrincipal(getPrincipal(tabs.activeTab), TCP_SOCKET_PERM);
      Services.perms.removeFromPrincipal(getPrincipal(tabs.activeTab), CONTACTS_READ_PERM);
      button.state("tab", STATE_DISABLED);
    }
  },

});

tabs.on("pageshow", function(tab) {
  if (Services.perms.testPermissionFromPrincipal(getPrincipal(tab), TCP_SOCKET_PERM) == Services.perms.ALLOW_ACTION &&
      Services.perms.testPermissionFromPrincipal(getPrincipal(tab), CONTACTS_READ_PERM) == Services.perms.ALLOW_ACTION) {
    button.state(tab, STATE_ENABLED);
  }
  else {
    button.state(tab, STATE_DISABLED);
  }
});
<commit_msg>import ContactService.jsm so mozContacts API actually works; enable contacts write and create so user can populate database<commit_after>// Import self, even though we don't use it, because otherwise our pageshow
// event handler doesn't get called.
var self = require('sdk/self');

var { ActionButton } = require("sdk/ui/button/action");
var tabs = require("sdk/tabs");
var { Cu } = require("chrome");
Cu.import("resource://gre/modules/Services.jsm");

// We don't use this directly (which is why we import it into an object literal
// that we then discard), but nothing in the browser imports it, and it
// needs to be imported in order for mozContacts to work, so we do it ourselves.
Cu.import("resource://gre/modules/ContactService.jsm", {});

const TCP_SOCKET_PERM = "tcp-socket";
const CONTACTS_READ_PERM = "contacts-read";
const CONTACTS_WRITE_PERM = "contacts-write";
const CONTACTS_CREATE_PERM = "contacts-create";
const LABEL_DISABLED = "mozTCPSocket/mozContacts APIs disabled";
const LABEL_ENABLED = "mozTCPSocket/mozContacts APIs enabled";
const ICON_DISABLED = "./unplugged.svg";
const ICON_ENABLED = "./plugged.svg";
const STATE_DISABLED = {
  label: LABEL_DISABLED,
  icon: ICON_DISABLED,
};
const STATE_ENABLED = {
  label: LABEL_ENABLED,
  icon: ICON_ENABLED,
};

function getPrincipal(tab) {
  var uri = Services.io.newURI(tab.url, null, null);
  var principal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(uri);
  return principal;
}

var button = ActionButton({
  id: "action-button",
  label: LABEL_DISABLED,
  icon: ICON_DISABLED,
  onClick: function(state) {
    if (state.label == LABEL_DISABLED) {
      Services.perms.addFromPrincipal(getPrincipal(tabs.activeTab), TCP_SOCKET_PERM, Services.perms.ALLOW_ACTION);
      Services.perms.addFromPrincipal(getPrincipal(tabs.activeTab), CONTACTS_READ_PERM, Services.perms.ALLOW_ACTION);
      Services.perms.addFromPrincipal(getPrincipal(tabs.activeTab), CONTACTS_WRITE_PERM, Services.perms.ALLOW_ACTION);
      Services.perms.addFromPrincipal(getPrincipal(tabs.activeTab), CONTACTS_CREATE_PERM, Services.perms.ALLOW_ACTION);
      button.state("tab", STATE_ENABLED);
    }
    else {
      Services.perms.removeFromPrincipal(getPrincipal(tabs.activeTab), TCP_SOCKET_PERM);
      Services.perms.removeFromPrincipal(getPrincipal(tabs.activeTab), CONTACTS_READ_PERM);
      Services.perms.removeFromPrincipal(getPrincipal(tabs.activeTab), CONTACTS_WRITE_PERM);
      Services.perms.removeFromPrincipal(getPrincipal(tabs.activeTab), CONTACTS_CREATE_PERM);
      button.state("tab", STATE_DISABLED);
    }
  },

});

tabs.on("pageshow", function(tab) {
  if (Services.perms.testPermissionFromPrincipal(getPrincipal(tab), TCP_SOCKET_PERM) == Services.perms.ALLOW_ACTION &&
      Services.perms.testPermissionFromPrincipal(getPrincipal(tab), CONTACTS_READ_PERM) == Services.perms.ALLOW_ACTION &&
      Services.perms.testPermissionFromPrincipal(getPrincipal(tab), CONTACTS_WRITE_PERM) == Services.perms.ALLOW_ACTION &&
      Services.perms.testPermissionFromPrincipal(getPrincipal(tab), CONTACTS_CREATE_PERM) == Services.perms.ALLOW_ACTION) {
    button.state(tab, STATE_ENABLED);
  }
  else {
    button.state(tab, STATE_DISABLED);
  }
});
<|endoftext|>


<commit_before>var request = require('request');
var _ = require('underscore');
_.mixin( require('underscore.deferred') );
var Twit = require('twit');
var T = new Twit(require('./config.js'));
var wordfilter = require('wordfilter');
var ent = require('ent');
var wordnikKey = require('./permissions.js').key;

var getNounUrl = 'http://api.wordnik.com:80/v4/words.json/randomWord?hasDictionaryDef=true&includePartOfSpeech=noun&excludePartOfSpeech=noun-plural,noun-posessive,proper-noun,proper-noun-plural,proper-noun-posessive&minCorpusCount=100&minDictionaryCount=13&minLength=3&maxLength=8&api_key=' + wordnikKey;

Array.prototype.pick = function() {
  return this[Math.floor(Math.random()*this.length)];
};

fruits = ['berries', 'fruit'];

function tweetWord(word) {
    T.post('statuses/update', { status: word }, function(err, reply) {
        if (err) {
            console.log('error:', err);
        } else {
            console.log('tweet:', reply);
        }
    });
}

function tweetSnozz() {
    var noun = '',
        tweet = 'The ',
        fruitstring;
    //let's get some adjectives!
    request(getNounUrl, function(error, response, data) {
        // let's make sure we're dealing with JSON
        var nounData = JSON.parse(data);
        console.log(nounData);
        if (!error) {
            noun = nounData.word;
            // if we got back some data from the API and it didn't error
            if (!wordfilter.blacklisted(noun) && !(word[0] === word[0].toUpperCase())){
                console.log(noun);
                fruitstring = noun + fruits.pick();
                tweet += fruitstring + ' taste like ' + fruitstring +'!';
                console.log(tweet);
                tweetWord(tweet);
                return;
            } else {
                tweetSnozz();
            }
        }
    });
}

// // Tweet every 30 minutes
// setInterval(function () {
//     try {
//         tweetLegend();
//     }
//     catch (e) {
//         console.log(e);
//     }
// }, 1000 * 60 * 30);

// Tweet once on initialization
tweetSnozz();
<commit_msg>Fix bug, before pushing to prod.<commit_after>var request = require('request');
var _ = require('underscore');
_.mixin( require('underscore.deferred') );
var Twit = require('twit');
var T = new Twit(require('./config.js'));
var wordfilter = require('wordfilter');
var ent = require('ent');
var wordnikKey = require('./permissions.js').key;

var getNounUrl = 'http://api.wordnik.com:80/v4/words.json/randomWord?hasDictionaryDef=true&includePartOfSpeech=noun&excludePartOfSpeech=noun-plural,noun-posessive,proper-noun,proper-noun-plural,proper-noun-posessive&minCorpusCount=100&minDictionaryCount=13&minLength=3&maxLength=8&api_key=' + wordnikKey;

Array.prototype.pick = function() {
  return this[Math.floor(Math.random()*this.length)];
};

fruits = ['berries', 'fruit'];

function tweetWord(word) {
    T.post('statuses/update', { status: word }, function(err, reply) {
        if (err) {
            console.log('error:', err);
        } else {
            console.log('tweet:', reply);
        }
    });
}

function tweetSnozz() {
    var noun = '',
        tweet = 'The ',
        fruitstring;
    //let's get some adjectives!
    request(getNounUrl, function(error, response, data) {
        // let's make sure we're dealing with JSON
        var nounData = JSON.parse(data);
        console.log(nounData);
        if (!error) {
            noun = nounData.word;
            // if we got back some data from the API and it didn't error
            if (!wordfilter.blacklisted(noun) && !(noun[0] === noun[0].toUpperCase())){
                console.log(noun);
                fruitstring = noun + fruits.pick();
                tweet += fruitstring + ' taste like ' + fruitstring +'!';
                console.log(tweet);
                tweetWord(tweet);
                return;
            } else {
                tweetSnozz();
            }
        }
    });
}

// // Tweet every 30 minutes
// setInterval(function () {
//     try {
//         tweetLegend();
//     }
//     catch (e) {
//         console.log(e);
//     }
// }, 1000 * 60 * 30);

// Tweet once on initialization
tweetSnozz();
<|endoftext|>


<commit_before>/* jshint node: true */
'use strict';

var path = require('path');
var fs = require('fs');
var Funnel = require('broccoli-funnel');
var VersionChecker = require('ember-cli-version-checker');

// The different types/area for which we have content for.
var ALLOWED_CONTENT_FOR = [
  'head-footer',
  'test-head-footer',
  'test-body-footer'
];

module.exports = {
  name: 'ember-a11y-testing',

  /**
   * Includes axe-core in non-production builds. It includes the un-minified
   * version in case of a need to debug.
   * @override
   */
  included: function(app) {
    this._super.included(app);

    app.import('vendor/axe-core/axe.js', { type: 'test' });
  },

  treeForVendor: function() {
    var axePath = path.dirname(require.resolve('axe-core'));
    return new Funnel(axePath, {
      files: ['axe.js'],
      destDir: 'axe-core'
    });
  },

  /**
   * Adds content for the areas specified in the array above. It appends the
   * contents of the files with the same name to the content-for block.
   * @override
   */
  contentFor: function(type) {
    if (~ALLOWED_CONTENT_FOR.indexOf(type)) {
      return fs.readFileSync(path.join(__dirname, 'content-for', type + '.html'));
    }
  },

  /**
   * Exclude the self-auditing components code during build if this is a
   * production build or if the version of Ember being used is less than 1.13.
   * @override
   */
  treeForApp: function(tree) {
    var checker = new VersionChecker(this);
    var isProductionBuild = this.app.env === 'production';
    var isOldEmber = checker.for('ember', 'bower').lt('1.13.0');

    if (isProductionBuild || isOldEmber) {
      tree = new Funnel(tree, {
        exclude: [/instance-initializers\/axe-component|violations-helper.js/]
      });
    }

    return tree;
  }
};
<commit_msg>Include axe-core in all non-prod environments<commit_after>/* jshint node: true */
'use strict';

var path = require('path');
var fs = require('fs');
var Funnel = require('broccoli-funnel');
var VersionChecker = require('ember-cli-version-checker');

// The different types/area for which we have content for.
var ALLOWED_CONTENT_FOR = [
  'head-footer',
  'test-head-footer',
  'test-body-footer'
];

module.exports = {
  name: 'ember-a11y-testing',

  /**
   * Includes axe-core in non-production builds. It includes the un-minified
   * version in case of a need to debug.
   * @override
   */
  included: function(app) {
    this._super.included(app);

    if (app.env !== 'production') {
      app.import('vendor/axe-core/axe.js');
    }
  },

  treeForVendor: function() {
    var axePath = path.dirname(require.resolve('axe-core'));
    return new Funnel(axePath, {
      files: ['axe.js'],
      destDir: 'axe-core'
    });
  },

  /**
   * Adds content for the areas specified in the array above. It appends the
   * contents of the files with the same name to the content-for block.
   * @override
   */
  contentFor: function(type) {
    if (~ALLOWED_CONTENT_FOR.indexOf(type)) {
      return fs.readFileSync(path.join(__dirname, 'content-for', type + '.html'));
    }
  },

  /**
   * Exclude the self-auditing components code during build if this is a
   * production build or if the version of Ember being used is less than 1.13.
   * @override
   */
  treeForApp: function(tree) {
    var checker = new VersionChecker(this);
    var isProductionBuild = this.app.env === 'production';
    var isOldEmber = checker.for('ember', 'bower').lt('1.13.0');

    if (isProductionBuild || isOldEmber) {
      tree = new Funnel(tree, {
        exclude: [/instance-initializers\/axe-component|violations-helper.js/]
      });
    }

    return tree;
  }
};
<|endoftext|>


<commit_before>import faker from 'faker'
import React from 'react'
import { Simulate } from 'react-addons-test-utils'

import Message from 'src/collections/Message/Message'
import * as common from 'test/specs/commonTests'

describe('Message', () => {
  common.isConformant(Message)
  common.hasUIClassName(Message)
  common.rendersChildren(Message)

  describe('with header', () => {
    it('has a header', () => {
      const header = faker.hacker.phrase()
      const message = deprecatedRender(<Message header={header} />)

      message.findClass('sd-message-header')
      message.assertText(header)
    })
  })
  describe('without header', () => {
    it('has no header', () => {
      deprecatedRender(<Message />)
        .scryClass('sd-message-header')
        .should.have.a.lengthOf(0)
    })
  })
  describe('with icon', () => {
    it('has an icon', () => {
      deprecatedRender(<Message icon='inbox' />).findClass('sd-message-icon')
    })
    it('has a "content" wrapper', () => {
      deprecatedRender(<Message icon='inbox' />).findClass('sd-message-content')
    })
  })
  describe('without icon', () => {
    it('has no icon', () => {
      deprecatedRender(<Message />)
        .scryClass('sd-message-icon')
        .should.have.a.lengthOf(0)
    })
    it('has no "content" wrapper', () => {
      deprecatedRender(<Message />)
        .scryClass('sd-message-content')
        .should.have.a.lengthOf(0)
    })
  })
  describe('dismissable', () => {
    it('adds a close icon', () => {
      deprecatedRender(<Message dismissable />).findClass('sd-message-close-icon')
    })

    it('calls transition "fade" when dismissed', () => {
      const tree = deprecatedRender(<Message dismissable />)
      const message = tree.first()
      const closeIcon = tree.findClass('sd-message-close-icon')

      message.messageElm.transition.called.should.equal(false)
      Simulate.click(closeIcon)
      message.messageElm.transition.calledWith('fade').should.equal(true)
    })
  })
  describe('not dismissable', () => {
    it('has no close icon', () => {
      deprecatedRender(<Message />)
        .scryClass('sd-message-close-icon')
        .should.have.a.lengthOf(0)
    })
  })
})
<commit_msg>test(Message): use enzyme<commit_after>import faker from 'faker'
import React from 'react'

import Message from 'src/collections/Message/Message'
import * as common from 'test/specs/commonTests'

describe('Message', () => {
  common.isConformant(Message)
  common.hasUIClassName(Message)
  common.rendersChildren(Message)

  describe('with header', () => {
    it('has a header', () => {
      const header = faker.hacker.phrase()
      const message = shallow(<Message header={header} />)

      message.should.have.descendants('.sd-message-header')
      message.should.contain.text(header)
    })
  })
  describe('without header', () => {
    it('has no header', () => {
      shallow(<Message />)
        .should.not.have.descendants('.sd-message-header')
    })
  })
  describe('with icon', () => {
    it('adds an Icon', () => {
      shallow(<Message icon='inbox' />)
        .should.have.descendants('Icon')
    })
    it('has a "content" wrapper', () => {
      shallow(<Message icon='inbox' />)
        .should.have.descendants('.sd-message-content')
    })
  })
  describe('without icon', () => {
    it('has no icon', () => {
      shallow(<Message />)
        .should.not.have.descendants('Icon')
    })
    it('has no "content" wrapper', () => {
      shallow(<Message />)
        .should.not.have.descendants('.sd-message-content')
    })
  })
  describe('dismissable', () => {
    it('adds a close icon', () => {
      shallow(<Message dismissable />)
        .should.have.descendants('.sd-message-close-icon')
    })

    it('calls transition "fade" when dismissed', () => {
      const wrapper = mount(<Message dismissable />)
      const instance = wrapper.instance()

      instance.messageElm.transition
        .should.not.have.been.called()

      wrapper
        .find('.sd-message-close-icon')
        .simulate('click')

      instance.messageElm.transition
        .should.have.been.calledWith('fade')
    })
  })
  describe('not dismissable', () => {
    it('has no close icon', () => {
      shallow(<Message />)
        .should.not.have.descendants('.sd-message-close-icon')
    })
  })
})
<|endoftext|>


<commit_before>// set sonar.genericcoverage.unitTestReportPaths to reports/TEST-xunit.xml
var os = require('os')
var path = require('path')
var fs = require('fs')
var builder = require('xmlbuilder')

var SonarQubeUnitReporter = function (baseReporterDecorator, config, logger, helper, formatError) {
  var log = logger.create('reporter.sonarqubeUnit')
  var reporterConfig = config.sonarQubeUnitReporter || {}
  var pkgName = reporterConfig.suite || ''
  var outputDir = reporterConfig.outputDir
  var outputFile = reporterConfig.outputFile
  var useBrowserName = reporterConfig.useBrowserName

  var transformName = reporterConfig.transformName || function(name){return name;}

  var suites
  var pendingFileWritings = 0
  var fileWritingFinished = function () {}
  var allMessages = []

  if (outputDir == null) {
    outputDir = '.'
  }

  outputDir = helper.normalizeWinPath(path.resolve(config.basePath, outputDir)) + path.sep

  if (typeof useBrowserName === 'undefined') {
    useBrowserName = true
  }

  baseReporterDecorator(this)

  this.adapters = [
    function (msg) {
      allMessages.push(msg)
    }
  ]

  var initliazeXmlForBrowser = function (browser) {
    var timestamp = (new Date()).toISOString().substr(0, 19)
    var unitTest = suites[browser.id] = builder.create('unitTest',
                                                       {version: '1.0', encoding: 'UTF-8', standalone: true},
                                                       {pubID: null, sysID: null},
                                                       {allowSurrogateChars: false, skipNullAttributes: false, headless: true, ignoreDecorators: false, separateArrayItems: false, noDoubleEncoding: false, stringify: {}})
    unitTest.att('version', '1')

  }

  var writeXmlForBrowser = function (browser) {
    var safeBrowserName = browser.name.replace(/ /g, '_')
    var newOutputFile
    if (outputFile != null) {
      var dir = useBrowserName ? path.join(outputDir, safeBrowserName)
                               : outputDir
      newOutputFile = path.join(dir, outputFile)
    } else if (useBrowserName) {
      newOutputFile = path.join(outputDir, 'ut_report-' + safeBrowserName + '.xml')
    } else {
      newOutputFile = path.join(outputDir, 'ut_report.xml')
    }

    var xmlToOutput = suites[browser.id]
    if (!xmlToOutput) {
      return // don't die if browser didn't start
    }

    pendingFileWritings++
    helper.mkdirIfNotExists(path.dirname(newOutputFile), function () {
      fs.writeFile(newOutputFile, xmlToOutput.end({pretty: true}), function (err) {
        if (err) {
          log.warn('Cannot write JUnit xml\n\t' + err.message)
        } else {
          log.debug('JUnit results written to "%s".', newOutputFile)
        }

        if (!--pendingFileWritings) {
          fileWritingFinished()
        }
      })
    })
  }

  var getClassName = function (browser, result) {
    var browserName = browser.name.replace(/ /g, '_').replace(/\./g, '_') + '.'

    return (useBrowserName ? browserName : '') + (pkgName ? pkgName + '.' : '') + result.suite[0]
  }

  this.onRunStart = function (browsers) {
    suites = Object.create(null)

    // TODO(vojta): remove once we don't care about Karma 0.10
    browsers.forEach(initliazeXmlForBrowser)
  }

  this.onBrowserStart = function (browser) {
    initliazeXmlForBrowser(browser)
  }

  this.onBrowserComplete = function (browser) {
    var suite = suites[browser.id]
    var result = browser.lastResult
    if (!suite || !result) {
      return // don't die if browser didn't start
    }

    writeXmlForBrowser(browser)
  }

  this.onRunComplete = function () {
    suites = null
    allMessages.length = 0
  }

  this.specSuccess = this.specSkipped = this.specFailure = function (browser, result) {
	var preMapped = nextPath = getClassName(browser, result).replace(/\\/g, '/');
  nextPath = transformName(nextPath);
  if( preMapped !== nextPath) log.debug('mapped test: ' + preMapped + ' -> ' + nextPath);

	var fileNodes = suites[browser.id];
	var lastFilePath;

	var numberOfFileNodes = fileNodes.children.length;
	if (numberOfFileNodes > 0) {
	  lastFilePath = fileNodes.children[numberOfFileNodes-1].attributes.path.value;
	  if (lastFilePath !== nextPath) {
	    suites[browser.id].ele('file', {
		  path: nextPath
	    })
	  }
	} else {
	  suites[browser.id].ele('file', {
        path: nextPath
	  })
	}
	lastFilePath = nextPath;

	var appendToThisNode = suites[browser.id].children[suites[browser.id].children.length - 1];

  var testCase = appendToThisNode.ele('testCase', {name: result.description, duration : (result.time || 0)});

  if (result.skipped) {
    testCase.ele('skipped', {message: 'Skipped'});
  }

  if (!result.success) {
    testCase.ele('failure', {message: 'Error'}, formatError(result.log.join('\n\n')));
  }

  }

  // wait for writing all the xml files, before exiting
  this.onExit = function (done) {
    if (pendingFileWritings) {
      fileWritingFinished = done
    } else {
      done()
    }
  }
}

SonarQubeUnitReporter.$inject = ['baseReporterDecorator', 'config', 'logger', 'helper', 'formatError']

// PUBLISH DI MODULE
module.exports = {
  'reporter:sonarqubeUnit': ['type', SonarQubeUnitReporter]
}
<commit_msg>rename transform to name formatter<commit_after>// set sonar.genericcoverage.unitTestReportPaths to reports/TEST-xunit.xml
var os = require('os')
var path = require('path')
var fs = require('fs')
var builder = require('xmlbuilder')

var SonarQubeUnitReporter = function (baseReporterDecorator, config, logger, helper, formatError) {
  var log = logger.create('reporter.sonarqubeUnit')
  var reporterConfig = config.sonarQubeUnitReporter || {}
  var pkgName = reporterConfig.suite || ''
  var outputDir = reporterConfig.outputDir
  var outputFile = reporterConfig.outputFile
  var useBrowserName = reporterConfig.useBrowserName

  var nameFormatter = reporterConfig.nameFormatter || function(name){return name;}

  var suites
  var pendingFileWritings = 0
  var fileWritingFinished = function () {}
  var allMessages = []

  if (outputDir == null) {
    outputDir = '.'
  }

  outputDir = helper.normalizeWinPath(path.resolve(config.basePath, outputDir)) + path.sep

  if (typeof useBrowserName === 'undefined') {
    useBrowserName = true
  }

  baseReporterDecorator(this)

  this.adapters = [
    function (msg) {
      allMessages.push(msg)
    }
  ]

  var initliazeXmlForBrowser = function (browser) {
    var timestamp = (new Date()).toISOString().substr(0, 19)
    var unitTest = suites[browser.id] = builder.create('unitTest',
                                                       {version: '1.0', encoding: 'UTF-8', standalone: true},
                                                       {pubID: null, sysID: null},
                                                       {allowSurrogateChars: false, skipNullAttributes: false, headless: true, ignoreDecorators: false, separateArrayItems: false, noDoubleEncoding: false, stringify: {}})
    unitTest.att('version', '1')

  }

  var writeXmlForBrowser = function (browser) {
    var safeBrowserName = browser.name.replace(/ /g, '_')
    var newOutputFile
    if (outputFile != null) {
      var dir = useBrowserName ? path.join(outputDir, safeBrowserName)
                               : outputDir
      newOutputFile = path.join(dir, outputFile)
    } else if (useBrowserName) {
      newOutputFile = path.join(outputDir, 'ut_report-' + safeBrowserName + '.xml')
    } else {
      newOutputFile = path.join(outputDir, 'ut_report.xml')
    }

    var xmlToOutput = suites[browser.id]
    if (!xmlToOutput) {
      return // don't die if browser didn't start
    }

    pendingFileWritings++
    helper.mkdirIfNotExists(path.dirname(newOutputFile), function () {
      fs.writeFile(newOutputFile, xmlToOutput.end({pretty: true}), function (err) {
        if (err) {
          log.warn('Cannot write JUnit xml\n\t' + err.message)
        } else {
          log.debug('JUnit results written to "%s".', newOutputFile)
        }

        if (!--pendingFileWritings) {
          fileWritingFinished()
        }
      })
    })
  }

  var getClassName = function (browser, result) {
    var browserName = browser.name.replace(/ /g, '_').replace(/\./g, '_') + '.'

    return (useBrowserName ? browserName : '') + (pkgName ? pkgName + '.' : '') + result.suite[0]
  }

  this.onRunStart = function (browsers) {
    suites = Object.create(null)

    // TODO(vojta): remove once we don't care about Karma 0.10
    browsers.forEach(initliazeXmlForBrowser)
  }

  this.onBrowserStart = function (browser) {
    initliazeXmlForBrowser(browser)
  }

  this.onBrowserComplete = function (browser) {
    var suite = suites[browser.id]
    var result = browser.lastResult
    if (!suite || !result) {
      return // don't die if browser didn't start
    }

    writeXmlForBrowser(browser)
  }

  this.onRunComplete = function () {
    suites = null
    allMessages.length = 0
  }

  this.specSuccess = this.specSkipped = this.specFailure = function (browser, result) {
	var preMapped = nextPath = getClassName(browser, result).replace(/\\/g, '/');
  nextPath = nameFormatter(nextPath);
  if( preMapped !== nextPath) log.debug('mapped test: ' + preMapped + ' -> ' + nextPath);

	var fileNodes = suites[browser.id];
	var lastFilePath;

	var numberOfFileNodes = fileNodes.children.length;
	if (numberOfFileNodes > 0) {
	  lastFilePath = fileNodes.children[numberOfFileNodes-1].attributes.path.value;
	  if (lastFilePath !== nextPath) {
	    suites[browser.id].ele('file', {
		  path: nextPath
	    })
	  }
	} else {
	  suites[browser.id].ele('file', {
        path: nextPath
	  })
	}
	lastFilePath = nextPath;

	var appendToThisNode = suites[browser.id].children[suites[browser.id].children.length - 1];

  var testCase = appendToThisNode.ele('testCase', {name: result.description, duration : (result.time || 0)});

  if (result.skipped) {
    testCase.ele('skipped', {message: 'Skipped'});
  }

  if (!result.success) {
    testCase.ele('failure', {message: 'Error'}, formatError(result.log.join('\n\n')));
  }

  }

  // wait for writing all the xml files, before exiting
  this.onExit = function (done) {
    if (pendingFileWritings) {
      fileWritingFinished = done
    } else {
      done()
    }
  }
}

SonarQubeUnitReporter.$inject = ['baseReporterDecorator', 'config', 'logger', 'helper', 'formatError']

// PUBLISH DI MODULE
module.exports = {
  'reporter:sonarqubeUnit': ['type', SonarQubeUnitReporter]
}
<|endoftext|>


<commit_before>'use strict';

const winston = require('winston');
const Transport = require('winston-transport');
const moment = require('moment');
const _ = require('lodash');
const elasticsearch = require('elasticsearch');
const { LEVEL, SPLAT } = require('triple-beam');
const defaultTransformer = require('./transformer');
const BulkWriter = require('./bulk_writer');

module.exports = class Elasticsearch extends Transport {
  constructor(opts) {
    super(opts);
    this.name = 'elasticsearch';

    this.opts = opts || {};
    if (!opts.timestamp) {
      this.opts.timestamp = function timestamp() { return new Date().toISOString(); };
    }
    // Enforce context
    // if (!(this instanceof Elasticsearch)) {
    //   return new Elasticsearch(opts);
    // }

    // Set defaults
    const defaults = {
      level: 'info',
      index: null,
      indexPrefix: 'logs',
      indexSuffixPattern: 'YYYY.MM.DD',
      messageType: '_doc',
      transformer: defaultTransformer,
      ensureMappingTemplate: true,
      flushInterval: 2000,
      waitForActiveShards: 1,
      handleExceptions: false,
      pipeline: null
    };
    _.defaults(opts, defaults);

    // Use given client or create one
    if (opts.client) {
      this.client = opts.client;
    } else {
      const defaultClientOpts = {
        clientOpts: {
          log: [
            {
              type: 'console',
              level: 'error',
            }
          ]
        }
      };
      _.defaults(opts, defaultClientOpts);

      // Create a new ES client
      // http://localhost:9200 is the default of the client already
      this.client = new elasticsearch.Client(_.clone(this.opts.clientOpts));
    }

    const bulkWriteropts = {
      interval: opts.flushInterval,
      waitForActiveShards: opts.waitForActiveShards,
      pipeline: opts.pipeline,
      ensureMappingTemplate: opts.ensureMappingTemplate,
      mappingTemplate: opts.mappingTemplate,
      indexPrefix: opts.indexPrefix
    };

    this.bulkWriter = new BulkWriter(
      this.client,
      bulkWriteropts
    );
    this.bulkWriter.start();
  }

  log(info, callback) {
    const level = info[LEVEL];
    const { message } = info;
    let meta = info[SPLAT];
    if (meta !== undefined) {
      // eslint-disable-next-line prefer-destructuring
      meta = meta[0];
    } else {
      meta = info;
      delete meta.message;
      delete meta.level;
    }
    setImmediate(() => {
      this.emit('logged', level);
    });

    const logData = {
      message,
      level,
      meta,
      // timestamp: this.opts.timestamp()
    };

    const entry = this.opts.transformer(logData);
    this.bulkWriter.append(
      this.getIndexName(this.opts),
      this.opts.messageType,
      entry
    );

    callback();
  }

  query(options, callback) {
    // const opts = this.normalizeQuery(options);
    const index = this.getIndexName(this.opts);
    const query = {
      index,
      // q
    };
    return this.client.search(query);
  }

  search(q) {
    const index = this.getIndexName(this.opts);
    const query = {
      index,
      q
    };
    return this.client.search(query);
  }

  getIndexName(opts) {
    this.test = 'test';
    let indexName = opts.index;
    if (indexName === null) {
      let indexPrefix = opts.indexPrefix;
      if (typeof indexPrefix === 'function') {
        // eslint-disable-next-line prefer-destructuring
        indexPrefix = opts.index();
      }
      const now = moment();
      const dateString = now.format(opts.indexSuffixPattern);
      indexName = indexPrefix + '-' + dateString;
    }
    return indexName;
  }
};

winston.transports.Elasticsearch = module.exports;
<commit_msg>added possibility to use a function for the indexPrefix option to enable to log to multiple indices within one transport<commit_after>'use strict';

const winston = require('winston');
const Transport = require('winston-transport');
const moment = require('moment');
const _ = require('lodash');
const elasticsearch = require('elasticsearch');
const { LEVEL, SPLAT } = require('triple-beam');
const defaultTransformer = require('./transformer');
const BulkWriter = require('./bulk_writer');

module.exports = class Elasticsearch extends Transport {
  constructor(opts) {
    super(opts);
    this.name = 'elasticsearch';

    this.opts = opts || {};
    if (!opts.timestamp) {
      this.opts.timestamp = function timestamp() { return new Date().toISOString(); };
    }
    // Enforce context
    // if (!(this instanceof Elasticsearch)) {
    //   return new Elasticsearch(opts);
    // }

    // Set defaults
    const defaults = {
      level: 'info',
      index: null,
      indexPrefix: 'logs',
      indexSuffixPattern: 'YYYY.MM.DD',
      messageType: '_doc',
      transformer: defaultTransformer,
      ensureMappingTemplate: true,
      flushInterval: 2000,
      waitForActiveShards: 1,
      handleExceptions: false,
      pipeline: null
    };
    _.defaults(opts, defaults);

    // Use given client or create one
    if (opts.client) {
      this.client = opts.client;
    } else {
      const defaultClientOpts = {
        clientOpts: {
          log: [
            {
              type: 'console',
              level: 'error',
            }
          ]
        }
      };
      _.defaults(opts, defaultClientOpts);

      // Create a new ES client
      // http://localhost:9200 is the default of the client already
      this.client = new elasticsearch.Client(_.clone(this.opts.clientOpts));
    }

    const bulkWriteropts = {
      interval: opts.flushInterval,
      waitForActiveShards: opts.waitForActiveShards,
      pipeline: opts.pipeline,
      ensureMappingTemplate: opts.ensureMappingTemplate,
      mappingTemplate: opts.mappingTemplate,
      indexPrefix: opts.indexPrefix
    };

    this.bulkWriter = new BulkWriter(
      this.client,
      bulkWriteropts
    );
    this.bulkWriter.start();
  }

  log(info, callback) {
    const level = info[LEVEL];
    const { message } = info;
    let meta = info[SPLAT];
    if (meta !== undefined) {
      // eslint-disable-next-line prefer-destructuring
      meta = meta[0];
    } else {
      meta = info;
      delete meta.message;
      delete meta.level;
    }
    setImmediate(() => {
      this.emit('logged', level);
    });

    const logData = {
      message,
      level,
      meta,
      // timestamp: this.opts.timestamp()
    };

    const entry = this.opts.transformer(logData);
    this.bulkWriter.append(
      this.getIndexName(this.opts),
      this.opts.messageType,
      entry
    );

    callback();
  }

  query(options, callback) {
    // const opts = this.normalizeQuery(options);
    const index = this.getIndexName(this.opts);
    const query = {
      index,
      // q
    };
    return this.client.search(query);
  }

  search(q) {
    const index = this.getIndexName(this.opts);
    const query = {
      index,
      q
    };
    return this.client.search(query);
  }

  getIndexName(opts) {
    this.test = 'test';
    let indexName = opts.index;
    if (indexName === null) {
      let indexPrefix = opts.indexPrefix;
      if (typeof indexPrefix === 'function') {
        // eslint-disable-next-line prefer-destructuring
        indexPrefix = opts.indexPrefix();
      }
      const now = moment();
      const dateString = now.format(opts.indexSuffixPattern);
      indexName = indexPrefix + '-' + dateString;
    }
    return indexName;
  }
};

winston.transports.Elasticsearch = module.exports;
<|endoftext|>


<commit_before>var pkg = require(process.cwd() + '/package.json');
var meanVersion = pkg.mean || pkg.version;

if (meanVersion < '0.3.2') {
  if (meanVersion === '0.3.1')
    module.exports = require('./lib/mean0.3.1');
  else
    module.exports = require('./lib/mean0.3.0');
} else {
  // current version
  module.exports = require('./lib/mean');
}
<commit_msg>Removed mean version check. Wouldn't work even if the versions were found.<commit_after>'use strict';

module.exports = require('./lib/mean');
<|endoftext|>