<commit_before>var JoinedA = new Mongo.Collection('JoinedA');
var JoinedB = new Mongo.Collection('JoinedB');

if (Meteor.isServer) {
  var idFieldWasNotAvailable; // How many times fields._id was undefined in addDependency callback
  var addDependencyCount;     // How many times addDependency callback was called

  Meteor.methods({
    joins_initDb: function() {
      idFieldWasNotAvailable = 0;
      addDependencyCount = 0;

      JoinedA.remove({});
      JoinedB.remove({});
      for (var i = 10; i <= 20; i++) {
        JoinedA.insert({val: i});
      }
      JoinedA.insert({val: 1, l: 1, r: 7 , extra: {val: 14}});
      JoinedA.insert({val: 2, l: 4, r: 10, extra: {val: 15}});

      for (var i = 1; i <= 15; i++) {
        JoinedB.insert({val: i});
      }
    },
    joins_setEnabled: function(val, enabled) {
      JoinedA.update({val: val}, {$set: {enabled: enabled}});
    },
    idFieldWasAvailable: function() {
      return {
        fail: idFieldWasNotAvailable,
        total: addDependencyCount
      };
    }
  });

  Meteor.smartPublish('joins_items', function() {
    this.addDependency('JoinedA', ['l', 'r'], function(fields) {
      if (_.isUndefined(fields.l) || _.isUndefined(fields.r)) return [];

      // Check for fields._id's correctness
      var el = undefined;
      if (fields._id) {
        el = JoinedA.findOne(fields._id);
      }
      if (!el || el.l != fields.l || el.r != fields.r) {
        idFieldWasNotAvailable++;
      }
      addDependencyCount++;

      return JoinedB.find({$and: [
        {val: {$gte: fields.l}},
        {val: {$lte: fields.r}}
      ]});
    });
    this.addDependency('JoinedA', 'extra.val', function(fields) {
      if (_.isUndefined(fields.extra) || _.isUndefined(fields.extra.val)) return [];
      return JoinedB.find({val: fields.extra.val});
    });
    this.addDependency('JoinedB', 'val', function(fields) {
      return JoinedA.find({val: 9 + fields.val});
    });
    return JoinedA.find({enabled: true});
  });
}

if (Meteor.isClient) {
  Tinytest.addAsync('joins: init', function(test, next) {
    Meteor.call('joins_initDb', function(err) {
      test.isUndefined(err, 'error during initialization: ' + err);
      test.equal(JoinedA.find().count(), 0, 'JoinedA is not empty');
      test.equal(JoinedB.find().count(), 0, 'JoinedB is not empty');
      next();
    });
  });

  var subscr;
  Tinytest.addAsync('joins: subscription start', function(test, next) {
    subscr = Meteor.subscribe('joins_items', function() {
      test.equal(JoinedA.find().count(), 0, 'JoinedA is not empty');
      test.equal(JoinedB.find().count(), 0, 'JoinedB is not empty');
      next();
    });
  });

  function getVals(coll, filter) {
    return _.pluck(coll.find(filter || {}, {fields: {val: 1}}).fetch(), 'val')
  }

  Tinytest.addAsync('joins: enabling 1..7', function(test, next) {
    Meteor.call('joins_setEnabled', 1, true, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(getVals(JoinedA), [10,11,12,13,14,15,16,1], 'JoinedA is invalid');
      test.equal(getVals(JoinedB), [1,2,3,4,5,6,7,14], 'JoinedB is invalid');
      next();
    });
  });

  Tinytest.addAsync('joins: enabling 4..10', function(test, next) {
    Meteor.call('joins_setEnabled', 2, true, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(getVals(JoinedA), [10,11,12,13,14,15,16,1,17,18,19,2], 'JoinedA is invalid');
      test.equal(getVals(JoinedB), [1,2,3,4,5,6,7,14,8,9,10,15], 'JoinedB is invalid');
      next();
    });
  });

  Tinytest.addAsync('joins: disabling 1..7', function(test, next) {
    Meteor.call('joins_setEnabled', 1, false, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(getVals(JoinedA), [13,14,15,16,17,18,19,2], 'JoinedA is invalid');
      test.equal(getVals(JoinedB), [4,5,6,7,8,9,10,15], 'JoinedB is invalid');
      next();
    });
  });

  Tinytest.addAsync('joins: changing 4..10 to 4..8', function(test, next) {
    JoinedA.update(JoinedA.findOne({l: 4, r: 10})._id, {$set: {r: 8}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(getVals(JoinedA), [13,14,15,16,17,2], 'JoinedA is invalid');
      test.equal(getVals(JoinedB), [4,5,6,7,8,15], 'JoinedB is invalid');
      next();
    });
  });

  Tinytest.addAsync('joins: adding nested property from scratch', function(test, next) {
    JoinedA.update(JoinedA.findOne({val: 14})._id, {$set: {'extra.val': 12}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(getVals(JoinedA), [13,14,15,16,17,2], 'JoinedA is invalid');
      test.equal(getVals(JoinedB), [4,5,6,7,8,15,12], 'JoinedB is invalid');
      next();
    });
  });

  Tinytest.addAsync('joins: adding invalid nested property holder', function(test, next) {
    JoinedA.update(JoinedA.findOne({val: 14})._id, {$set: {'extra': 'invalid'}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(getVals(JoinedA), [13,14,15,16,17,2], 'JoinedA is invalid');
      test.equal(getVals(JoinedB), [4,5,6,7,8,15], 'JoinedB is invalid');
      next();
    });
  });

  Tinytest.addAsync('joins: adding nested property', function(test, next) {
    JoinedA.update(JoinedA.findOne({val: 14})._id, {$set: {'extra': {'val': 13}}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(getVals(JoinedA), [13,14,15,16,17,2], 'JoinedA is invalid');
      test.equal(getVals(JoinedB), [4,5,6,7,8,15,13], 'JoinedB is invalid');
      next();
    });
  });

  Tinytest.addAsync('joins: changing nested property', function(test, next) {
    JoinedA.update(JoinedA.findOne({val: 14})._id, {$set: {'extra.val': 14}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(getVals(JoinedA), [13,14,15,16,17,2], 'JoinedA is invalid');
      test.equal(getVals(JoinedB), [4,5,6,7,8,15,14], 'JoinedB is invalid');
      next();
    });
  });

  Tinytest.addAsync('joins: removing nested property holder', function(test, next) {
    JoinedA.update(JoinedA.findOne({val: 14})._id, {$unset: {'extra': 1}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(getVals(JoinedA), [13,14,15,16,17,2], 'JoinedA is invalid');
      test.equal(getVals(JoinedB), [4,5,6,7,8,15], 'JoinedB is invalid');
      next();
    });
  });

  Tinytest.addAsync('joins: disabling 4..10', function(test, next) {
    Meteor.call('joins_setEnabled', 2, false, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(JoinedA.find().count(), 0, 'JoinedA is not empty');
      test.equal(JoinedB.find().count(), 0, 'JoinedB is not empty');
      next();
    });
  });

  Tinytest.addAsync('joins: subscription stop', function(test, next) {
    subscr.stop();
    Meteor.setTimeout(function() {
      test.equal(JoinedA.find().count(), 0, 'JoinedA is not empty');
      test.equal(JoinedB.find().count(), 0, 'JoinedB is not empty');
      next();
    }, 100);
  });

  Tinytest.addAsync('joins: fields._id was correct in all addDependency callbacks', function(test, next) {
    Meteor.call('idFieldWasAvailable', function(err, res) {
      test.equal(res.fail, 0, 'was not available or invalid in some of ' + res.total + ' callbacks');
      next();
    });
  });
}
<commit_msg>#6: added join test when some of _ids are Mongo.ObjectID<commit_after>var JoinedA = new Mongo.Collection('JoinedA');
var JoinedB = new Mongo.Collection('JoinedB');

if (Meteor.isServer) {
  var idFieldWasNotAvailable; // How many times fields._id was undefined in addDependency callback
  var addDependencyCount;     // How many times addDependency callback was called

  Meteor.methods({
    joins_initDb: function() {
      idFieldWasNotAvailable = 0;
      addDependencyCount = 0;

      JoinedA.remove({});
      JoinedB.remove({});
      for (var i = 10; i <= 20; i++) {
        if (i % 2 == 0) {
          JoinedA.insert({val: i});
        } else {
          JoinedA.insert({_id: new Mongo.ObjectID(), val: i});
        }
      }
      JoinedA.insert({val: 1, l: 1, r: 7 , extra: {val: 14}});
      JoinedA.insert({val: 2, l: 4, r: 10, extra: {val: 15}});

      for (var i = 1; i <= 15; i++) {
        JoinedB.insert({val: i});
      }
    },
    joins_setEnabled: function(val, enabled) {
      JoinedA.update({val: val}, {$set: {enabled: enabled}});
    },
    idFieldWasAvailable: function() {
      return {
        fail: idFieldWasNotAvailable,
        total: addDependencyCount
      };
    }
  });

  Meteor.smartPublish('joins_items', function() {
    this.addDependency('JoinedA', ['l', 'r'], function(fields) {
      if (_.isUndefined(fields.l) || _.isUndefined(fields.r)) return [];

      // Check for fields._id's correctness
      var el = undefined;
      if (fields._id) {
        el = JoinedA.findOne(fields._id);
      }
      if (!el || el.l != fields.l || el.r != fields.r) {
        idFieldWasNotAvailable++;
      }
      addDependencyCount++;

      return JoinedB.find({$and: [
        {val: {$gte: fields.l}},
        {val: {$lte: fields.r}}
      ]});
    });
    this.addDependency('JoinedA', 'extra.val', function(fields) {
      if (_.isUndefined(fields.extra) || _.isUndefined(fields.extra.val)) return [];
      return JoinedB.find({val: fields.extra.val});
    });
    this.addDependency('JoinedB', 'val', function(fields) {
      return JoinedA.find({val: 9 + fields.val});
    });
    return JoinedA.find({enabled: true});
  });
}

if (Meteor.isClient) {
  Tinytest.addAsync('joins: init', function(test, next) {
    Meteor.call('joins_initDb', function(err) {
      test.isUndefined(err, 'error during initialization: ' + err);
      test.equal(JoinedA.find().count(), 0, 'JoinedA is not empty');
      test.equal(JoinedB.find().count(), 0, 'JoinedB is not empty');
      next();
    });
  });

  var subscr;
  Tinytest.addAsync('joins: subscription start', function(test, next) {
    subscr = Meteor.subscribe('joins_items', function() {
      test.equal(JoinedA.find().count(), 0, 'JoinedA is not empty');
      test.equal(JoinedB.find().count(), 0, 'JoinedB is not empty');
      next();
    });
  });

  function getVals(coll, filter) {
    return _.pluck(coll.find(filter || {}, {fields: {val: 1}}).fetch(), 'val')
  }

  Tinytest.addAsync('joins: enabling 1..7', function(test, next) {
    Meteor.call('joins_setEnabled', 1, true, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(getVals(JoinedA), [10,11,12,13,14,15,16,1], 'JoinedA is invalid');
      test.equal(getVals(JoinedB), [1,2,3,4,5,6,7,14], 'JoinedB is invalid');
      next();
    });
  });

  Tinytest.addAsync('joins: enabling 4..10', function(test, next) {
    Meteor.call('joins_setEnabled', 2, true, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(getVals(JoinedA), [10,11,12,13,14,15,16,1,17,18,19,2], 'JoinedA is invalid');
      test.equal(getVals(JoinedB), [1,2,3,4,5,6,7,14,8,9,10,15], 'JoinedB is invalid');
      next();
    });
  });

  Tinytest.addAsync('joins: disabling 1..7', function(test, next) {
    Meteor.call('joins_setEnabled', 1, false, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(getVals(JoinedA), [13,14,15,16,17,18,19,2], 'JoinedA is invalid');
      test.equal(getVals(JoinedB), [4,5,6,7,8,9,10,15], 'JoinedB is invalid');
      next();
    });
  });

  Tinytest.addAsync('joins: changing 4..10 to 4..8', function(test, next) {
    JoinedA.update(JoinedA.findOne({l: 4, r: 10})._id, {$set: {r: 8}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(getVals(JoinedA), [13,14,15,16,17,2], 'JoinedA is invalid');
      test.equal(getVals(JoinedB), [4,5,6,7,8,15], 'JoinedB is invalid');
      next();
    });
  });

  Tinytest.addAsync('joins: adding nested property from scratch', function(test, next) {
    JoinedA.update(JoinedA.findOne({val: 14})._id, {$set: {'extra.val': 12}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(getVals(JoinedA), [13,14,15,16,17,2], 'JoinedA is invalid');
      test.equal(getVals(JoinedB), [4,5,6,7,8,15,12], 'JoinedB is invalid');
      next();
    });
  });

  Tinytest.addAsync('joins: adding invalid nested property holder', function(test, next) {
    JoinedA.update(JoinedA.findOne({val: 14})._id, {$set: {'extra': 'invalid'}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(getVals(JoinedA), [13,14,15,16,17,2], 'JoinedA is invalid');
      test.equal(getVals(JoinedB), [4,5,6,7,8,15], 'JoinedB is invalid');
      next();
    });
  });

  Tinytest.addAsync('joins: adding nested property', function(test, next) {
    JoinedA.update(JoinedA.findOne({val: 14})._id, {$set: {'extra': {'val': 13}}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(getVals(JoinedA), [13,14,15,16,17,2], 'JoinedA is invalid');
      test.equal(getVals(JoinedB), [4,5,6,7,8,15,13], 'JoinedB is invalid');
      next();
    });
  });

  Tinytest.addAsync('joins: changing nested property', function(test, next) {
    JoinedA.update(JoinedA.findOne({val: 14})._id, {$set: {'extra.val': 14}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(getVals(JoinedA), [13,14,15,16,17,2], 'JoinedA is invalid');
      test.equal(getVals(JoinedB), [4,5,6,7,8,15,14], 'JoinedB is invalid');
      next();
    });
  });

  Tinytest.addAsync('joins: removing nested property holder', function(test, next) {
    JoinedA.update(JoinedA.findOne({val: 14})._id, {$unset: {'extra': 1}}, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(getVals(JoinedA), [13,14,15,16,17,2], 'JoinedA is invalid');
      test.equal(getVals(JoinedB), [4,5,6,7,8,15], 'JoinedB is invalid');
      next();
    });
  });

  Tinytest.addAsync('joins: disabling 4..10', function(test, next) {
    Meteor.call('joins_setEnabled', 2, false, function(err, res) {
      test.isUndefined(err, 'error during update: ' + err);
      test.equal(JoinedA.find().count(), 0, 'JoinedA is not empty');
      test.equal(JoinedB.find().count(), 0, 'JoinedB is not empty');
      next();
    });
  });

  Tinytest.addAsync('joins: subscription stop', function(test, next) {
    subscr.stop();
    Meteor.setTimeout(function() {
      test.equal(JoinedA.find().count(), 0, 'JoinedA is not empty');
      test.equal(JoinedB.find().count(), 0, 'JoinedB is not empty');
      next();
    }, 100);
  });

  Tinytest.addAsync('joins: fields._id was correct in all addDependency callbacks', function(test, next) {
    Meteor.call('idFieldWasAvailable', function(err, res) {
      test.equal(res.fail, 0, 'was not available or invalid in some of ' + res.total + ' callbacks');
      next();
    });
  });
}
<|endoftext|>


<commit_before>/* eslint-disable no-unused-vars */
import dotf from '.';
import test from 'ava';
const fs = require('fs');
const path = require('path');
const os = require('os');

// Creates
test('write', async (t) => {
  // overwrite data
  const dotglobalfullpath = path.join(os.homedir(), '.myrc1');
  const dotlocalfullpath = path.join(__dirname, '.myignore1');
  const dotglobal = dotf('~', 'myrc1'); // Global (~)
  const dotlocal = dotf(__dirname, 'myignore1'); // Local (./)
  const writeGlobal = await dotglobal.write({a: 1});
  const writeLocal = await dotlocal.write({a: 1});
  if ('600' !== (fs.statSync(dotglobalfullpath).mode &&
      parseInt(777, 8)).toString(8)) {
    t.fail();
  }
  if ('600' !== (fs.statSync(dotlocalfullpath).mode &&
      parseInt(777, 8)).toString(8)) {
    t.fail();
  }
  t.pass();
  await dotglobal.delete();
  await dotlocal.delete();
});
test('exists', async (t) => {
  const dotglobal = dotf('~', 'myrc2'); // Global (~)
  const dotlocal = dotf(__dirname, 'myignore2'); // Local (./)
  await dotglobal.write({a: 1});
  await dotlocal.write({a: 1});
  const existsGlobal = await dotglobal.exists();
  const existsLocal = await dotlocal.exists();
  t.pass();
  await dotglobal.delete();
  await dotlocal.delete();
});
test('read', async (t) => {
  const dotglobal = dotf('~', 'myrc3'); // Global (~)
  const dotlocal = dotf(__dirname, 'myignore3'); // Local (./)
  await dotglobal.write({a: 1});
  await dotlocal.write({a: 1});
  const readGlobal = await dotglobal.read();
  const readLocal = await dotlocal.read();
  t.pass();
  await dotglobal.delete();
  await dotlocal.delete();
});
test('delete', async (t) => {
  const dotglobal = dotf('~', 'myrc4'); // Global (~)
  const dotlocal = dotf(__dirname, 'myignore4'); // Local (./)
  dotglobal.write({a: 1}).then(() => {
    dotglobal.delete().then(() => {
      t.pass();
    });
  });
  dotlocal.write({a: 1}).then(() => {
    dotlocal.delete().then(() => {
      t.pass();
    });
  });
});
<commit_msg>fix test<commit_after>/* eslint-disable no-unused-vars */
import dotf from '.';
import test from 'ava';
const fs = require('fs');
const path = require('path');
const os = require('os');

// Creates
test('write', async (t) => {
  // overwrite data
  const dotglobalfullpath = path.join(os.homedir(), '.myrc1');
  const dotlocalfullpath = path.join(__dirname, '.myignore1');
  const dotglobal = dotf('~', 'myrc1'); // Global (~)
  const dotlocal = dotf(__dirname, 'myignore1'); // Local (./)
  const writeGlobal = await dotglobal.write({a: 1});
  const writeLocal = await dotlocal.write({a: 1});
  if ('600' !== (fs.statSync(dotglobalfullpath).mode & parseInt(777, 8)).toString(8)) {
    t.fail();
  }
  if ('600' !== (fs.statSync(dotlocalfullpath).mode & parseInt(777, 8)).toString(8)) {
    t.fail();
  }
  t.pass();
  await dotglobal.delete();
  await dotlocal.delete();
});
test('exists', async (t) => {
  const dotglobal = dotf('~', 'myrc2'); // Global (~)
  const dotlocal = dotf(__dirname, 'myignore2'); // Local (./)
  await dotglobal.write({a: 1});
  await dotlocal.write({a: 1});
  const existsGlobal = await dotglobal.exists();
  const existsLocal = await dotlocal.exists();
  t.pass();
  await dotglobal.delete();
  await dotlocal.delete();
});
test('read', async (t) => {
  const dotglobal = dotf('~', 'myrc3'); // Global (~)
  const dotlocal = dotf(__dirname, 'myignore3'); // Local (./)
  await dotglobal.write({a: 1});
  await dotlocal.write({a: 1});
  const readGlobal = await dotglobal.read();
  const readLocal = await dotlocal.read();
  t.pass();
  await dotglobal.delete();
  await dotlocal.delete();
});
test('delete', async (t) => {
  const dotglobal = dotf('~', 'myrc4'); // Global (~)
  const dotlocal = dotf(__dirname, 'myignore4'); // Local (./)
  dotglobal.write({a: 1}).then(() => {
    dotglobal.delete().then(() => {
      t.pass();
    });
  });
  dotlocal.write({a: 1}).then(() => {
    dotlocal.delete().then(() => {
      t.pass();
    });
  });
});
<|endoftext|>


<commit_before>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length > 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<commit_msg>🤖(break): 2017-6-13 20:54:13<commit_after>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length < 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<|endoftext|>


<commit_before>"use strict";

var Assert = require("./assert").Assert

var ERR_COMPLETED_ASSERT = "Assert in completed test"
var ERR_COMPLETED_COMPLETE = "Attemt to complete test more then one times"
var ERR_EXPECT = "AssertionError"

/**
 * Creates a test function.
 */
function Test(name, unit, logger, Assert) {
  var isSync = unit.length <= 1
  var isFailFast = !unit.length
  var isDone = false
  return function test(next) {
    logger = logger.section(name)
    var assert = Assert(logger)
    function done() {
      if (isDone) return logger.error(new Error(ERR_COMPLETED_COMPLETE))
      isDone = true
      next()
    }
    try {
      var result = unit(assert, done)
      // If it"s async test that returns a promise.
      if (result && typeof(result.then) === "function") {
        result.then(function passed() {
          logger.pass("passed")
          done()
        }, function failed(reason) {
          logger.fail(reason)
          done()
        })
      } else {
        if (isFailFast) logger.pass("passed")
        if (isSync) done()
      }
    } catch (exception) {
      if (ERR_EXPECT === exception.name) assert.fail(exception)
      else logger.error(exception)
      done()
    }
  }
}

/**
 * Creates a test suite / group. Calling returned function will execute
 * all test in the given suite.
 */
function Suite(name, units, logger, Assert) {
  // Collecting properties that represent test functions or suits.
  var names = Object.keys(units).filter(function isTest(name) {
    return 0 === name.indexOf("test")
  })
  // Returning a function that executes all test in this suite and all it"s
  // sub-suits.
  return function suite(done) {
    // Chaining test / suits so that each is executed after last is done.
    (function next() {
      var name = names.shift()
      if (name) Unit(name, units[name], logger, units.Assert || Assert)(next)
      else done()
    })(logger = logger.section(name))
  }
}
function Unit(name, units, logger, Assert) {
  return typeof(units) === "function" ? Test(name, units, logger, Assert)
                                      : Suite(name, units, logger, Assert)
}

/**
 * Test runner function.
 */
exports.run = function run(units, logger) {
  Unit("Running all tests:", units, logger, Assert)(function done() {
    var results = logger.results
    logger.report()
    if (results.errors === 0 && results.fails === 0) process.exit(0)
    else process.exit(1)
  })
}
<commit_msg>Fix bug that exited process with wrong code.<commit_after>"use strict";

var Assert = require("./assert").Assert

var ERR_COMPLETED_ASSERT = "Assert in completed test"
var ERR_COMPLETED_COMPLETE = "Attemt to complete test more then one times"
var ERR_EXPECT = "AssertionError"

/**
 * Creates a test function.
 */
function Test(name, unit, logger, Assert) {
  var isSync = unit.length <= 1
  var isFailFast = !unit.length
  var isDone = false
  return function test(next) {
    logger = logger.section(name)
    var assert = Assert(logger)
    function done() {
      if (isDone) return logger.error(new Error(ERR_COMPLETED_COMPLETE))
      isDone = true
      next()
    }
    try {
      var result = unit(assert, done)
      // If it"s async test that returns a promise.
      if (result && typeof(result.then) === "function") {
        result.then(function passed() {
          logger.pass("passed")
          done()
        }, function failed(reason) {
          logger.fail(reason)
          done()
        })
      } else {
        if (isFailFast) logger.pass("passed")
        if (isSync) done()
      }
    } catch (exception) {
      if (ERR_EXPECT === exception.name) assert.fail(exception)
      else logger.error(exception)
      done()
    }
  }
}

/**
 * Creates a test suite / group. Calling returned function will execute
 * all test in the given suite.
 */
function Suite(name, units, logger, Assert) {
  // Collecting properties that represent test functions or suits.
  var names = Object.keys(units).filter(function isTest(name) {
    return 0 === name.indexOf("test")
  })
  // Returning a function that executes all test in this suite and all it"s
  // sub-suits.
  return function suite(done) {
    // Chaining test / suits so that each is executed after last is done.
    (function next() {
      var name = names.shift()
      if (name) Unit(name, units[name], logger, units.Assert || Assert)(next)
      else done()
    })(logger = logger.section(name))
  }
}
function Unit(name, units, logger, Assert) {
  return typeof(units) === "function" ? Test(name, units, logger, Assert)
                                      : Suite(name, units, logger, Assert)
}

/**
 * Test runner function.
 */
exports.run = function run(units, logger) {
  Unit("Running all tests:", units, logger, Assert)(function done() {
    logger.report()
    var results = logger.results
    var failed = results.errors.length !== 0 || results.fails.length !== 0
    process.exit(failed ? 1 : 0)
  })
}
<|endoftext|>


<commit_before>'use strict'

var test = require('tape').test
var persistence = require('./')
var MongoClient = require('mongodb').MongoClient
var abs = require('aedes-cached-persistence/abstract')
var mqemitterMongo = require('mqemitter-mongodb')
var clean = require('mongo-clean')
var dbname = 'aedes-test'
var mongourl = 'mongodb://127.0.0.1/' + dbname
var cleanopts = {
  action: 'remove'
}

MongoClient.connect(mongourl, { w: 1 }, function (err, client) {
  if (err) {
    throw err
  }

  var db = client.db(dbname)

  clean(db, cleanopts, function (err, db) {
    if (err) {
      throw err
    }

    runTest(client, db)
  })
})

function runTest (client, db) {
  test.onFinish(function () {
    client.close()
  })

  var dbopts = {
    url: mongourl
  }

  abs({
    test: test,
    buildEmitter: function () {
      var emitter = mqemitterMongo(dbopts)
      return emitter
    },
    persistence: function build (cb) {
      clean(db, cleanopts, function (err) {
        if (err) {
          return cb(err)
        }

        var instance = persistence(dbopts)

        var oldDestroy = instance.destroy

        instance.destroy = function (cb) {
          instance.destroy = oldDestroy
          instance.destroy(function () {
            instance.broker.mq.close(function () {
              cb()
            })
          })
        }

        cb(null, instance)
      })
    }
  })

  function toBroker (id, emitter) {
    return {
      id: id,
      publish: emitter.emit.bind(emitter),
      subscribe: emitter.on.bind(emitter),
      unsubscribe: emitter.removeListener.bind(emitter)
    }
  }

  test('multiple persistences', function (t) {
    t.plan(12)

    clean(db, cleanopts, function (err) {
      t.error(err)

      var emitter = mqemitterMongo(dbopts)

      emitter.status.once('stream', function () {
        t.pass('mqemitter 1 ready')

        var emitter2 = mqemitterMongo(dbopts)

        emitter2.status.once('stream', function () {
          t.pass('mqemitter 2 ready')

          var instance = persistence(dbopts)
          instance.broker = toBroker('1', emitter)

          instance.on('ready', function () {
            t.pass('instance ready')

            var instance2 = persistence(dbopts)
            instance2.broker = toBroker('2', emitter2)

            instance2.on('ready', function () {
              t.pass('instance2 ready')

              var client = { id: 'abcde' }
              var subs = [{
                topic: 'hello',
                qos: 1
              }, {
                topic: 'hello/#',
                qos: 1
              }, {
                topic: 'matteo',
                qos: 1
              }]

              instance.addSubscriptions(client, subs, function (err) {
                t.notOk(err, 'no error')
                setTimeout(function () {
                  instance2.subscriptionsByTopic('hello', function (err, resubs) {
                    t.notOk(err, 'no error')
                    t.deepEqual(resubs, [{
                      clientId: client.id,
                      topic: 'hello/#',
                      qos: 1
                    }, {
                      clientId: client.id,
                      topic: 'hello',
                      qos: 1
                    }])
                    instance.destroy(function () {
                      t.pass('first dies')
                      emitter.close(function () {
                        t.pass('first emitter dies')
                        instance2.destroy(function () {
                          t.pass('seond dies')
                          emitter2.close(t.pass.bind(t, 'second emitter dies'))
                        })
                      })
                    })
                  })
                }, 100)
              })
            })
          })
        })
      })
    })
  })
}
<commit_msg>added unit test case for all combination of options<commit_after>'use strict'

var test = require('tape').test
var persistence = require('./')
var MongoClient = require('mongodb').MongoClient
var abs = require('aedes-cached-persistence/abstract')
var mqemitterMongo = require('mqemitter-mongodb')
var clean = require('mongo-clean')
var dbname = 'aedes-test'
var mongourl = 'mongodb://127.0.0.1/' + dbname
var cleanopts = {
  action: 'remove'
}

MongoClient.connect(mongourl, { w: 1 }, function (err, client) {
  if (err) {
    throw err
  }

  var db = client.db(dbname)

  clean(db, cleanopts, function (err, db) {
    if (err) {
      throw err
    }

    runTest(client, db)
  })
})

function runTest (client, db) {
  test.onFinish(function () {
    client.close()
  })

  var dbopts = {
    url: mongourl
  }

  abs({
    test: test,
    buildEmitter: function () {
      var emitter = mqemitterMongo(dbopts)
      return emitter
    },
    persistence: function build (cb) {
      clean(db, cleanopts, function (err) {
        if (err) {
          return cb(err)
        }

        var instance = persistence(dbopts)

        var oldDestroy = instance.destroy

        instance.destroy = function (cb) {
          instance.destroy = oldDestroy
          instance.destroy(function () {
            instance.broker.mq.close(function () {
              cb()
            })
          })
        }

        cb(null, instance)
      })
    }
  })

  function toBroker (id, emitter) {
    return {
      id: id,
      publish: emitter.emit.bind(emitter),
      subscribe: emitter.on.bind(emitter),
      unsubscribe: emitter.removeListener.bind(emitter)
    }
  }

  test('multiple persistences', function (t) {
    t.plan(12)

    clean(db, cleanopts, function (err) {
      t.error(err)

      var emitter = mqemitterMongo(dbopts)

      emitter.status.once('stream', function () {
        t.pass('mqemitter 1 ready')

        var emitter2 = mqemitterMongo(dbopts)

        emitter2.status.once('stream', function () {
          t.pass('mqemitter 2 ready')

          var instance = persistence(dbopts)
          instance.broker = toBroker('1', emitter)

          instance.on('ready', function () {
            t.pass('instance ready')

            var instance2 = persistence(dbopts)
            instance2.broker = toBroker('2', emitter2)

            instance2.on('ready', function () {
              t.pass('instance2 ready')

              var client = { id: 'abcde' }
              var subs = [{
                topic: 'hello',
                qos: 1
              }, {
                topic: 'hello/#',
                qos: 1
              }, {
                topic: 'matteo',
                qos: 1
              }]

              instance.addSubscriptions(client, subs, function (err) {
                t.notOk(err, 'no error')
                setTimeout(function () {
                  instance2.subscriptionsByTopic('hello', function (err, resubs) {
                    t.notOk(err, 'no error')
                    t.deepEqual(resubs, [{
                      clientId: client.id,
                      topic: 'hello/#',
                      qos: 1
                    }, {
                      clientId: client.id,
                      topic: 'hello',
                      qos: 1
                    }])
                    instance.destroy(function () {
                      t.pass('first dies')
                      emitter.close(function () {
                        t.pass('first emitter dies')
                        instance2.destroy(function () {
                          t.pass('seond dies')
                          emitter2.close(t.pass.bind(t, 'second emitter dies'))
                        })
                      })
                    })
                  })
                }, 100)
              })
            })
          })
        })
      })
    })
  })

  var dboptsWithDbObjectAndUrl = {
    url: mongourl,
    db: db
  }

  test('multiple persistences with passed db object and url', function (t) {
    t.plan(12)

    clean(db, cleanopts, function (err) {
      t.error(err)

      var emitter = mqemitterMongo(dboptsWithDbObjectAndUrl)

      emitter.status.once('stream', function () {
        t.pass('mqemitter 1 ready')

        var emitter2 = mqemitterMongo(dboptsWithDbObjectAndUrl)

        emitter2.status.once('stream', function () {
          t.pass('mqemitter 2 ready')

          var instance = persistence(dboptsWithDbObjectAndUrl)
          instance.broker = toBroker('1', emitter)

          instance.on('ready', function () {
            t.pass('instance ready')

            var instance2 = persistence(dboptsWithDbObjectAndUrl)
            instance2.broker = toBroker('2', emitter2)

            instance2.on('ready', function () {
              t.pass('instance2 ready')

              var client = { id: 'abcde' }
              var subs = [{
                topic: 'hello',
                qos: 1
              }, {
                topic: 'hello/#',
                qos: 1
              }, {
                topic: 'matteo',
                qos: 1
              }]

              instance.addSubscriptions(client, subs, function (err) {
                t.notOk(err, 'no error')
                setTimeout(function () {
                  instance2.subscriptionsByTopic('hello', function (err, resubs) {
                    t.notOk(err, 'no error')
                    t.deepEqual(resubs, [{
                      clientId: client.id,
                      topic: 'hello/#',
                      qos: 1
                    }, {
                      clientId: client.id,
                      topic: 'hello',
                      qos: 1
                    }])
                    instance.destroy(function () {
                      t.pass('first dies')
                      emitter.close(function () {
                        t.pass('first emitter dies')
                        instance2.destroy(function () {
                          t.pass('seond dies')
                          emitter2.close(t.pass.bind(t, 'second emitter dies'))
                        })
                      })
                    })
                  })
                }, 100)
              })
            })
          })
        })
      })
    })
  })

  var dboptsWithOnlyDbObject = {
    db: db
  }

  test('multiple persistences with passed only db object', function (t) {
    t.plan(12)

    clean(db, cleanopts, function (err) {
      t.error(err)

      var emitter = mqemitterMongo(dboptsWithOnlyDbObject)

      emitter.status.once('stream', function () {
        t.pass('mqemitter 1 ready')

        var emitter2 = mqemitterMongo(dboptsWithOnlyDbObject)

        emitter2.status.once('stream', function () {
          t.pass('mqemitter 2 ready')

          var instance = persistence(dboptsWithOnlyDbObject)
          instance.broker = toBroker('1', emitter)

          instance.on('ready', function () {
            t.pass('instance ready')

            var instance2 = persistence(dboptsWithOnlyDbObject)
            instance2.broker = toBroker('2', emitter2)

            instance2.on('ready', function () {
              t.pass('instance2 ready')

              var client = { id: 'abcde' }
              var subs = [{
                topic: 'hello',
                qos: 1
              }, {
                topic: 'hello/#',
                qos: 1
              }, {
                topic: 'matteo',
                qos: 1
              }]

              instance.addSubscriptions(client, subs, function (err) {
                t.notOk(err, 'no error')
                setTimeout(function () {
                  instance2.subscriptionsByTopic('hello', function (err, resubs) {
                    t.notOk(err, 'no error')
                    t.deepEqual(resubs, [{
                      clientId: client.id,
                      topic: 'hello/#',
                      qos: 1
                    }, {
                      clientId: client.id,
                      topic: 'hello',
                      qos: 1
                    }])
                    instance.destroy(function () {
                      t.pass('first dies')
                      emitter.close(function () {
                        t.pass('first emitter dies')
                        instance2.destroy(function () {
                          t.pass('seond dies')
                          emitter2.close(t.pass.bind(t, 'second emitter dies'))
                        })
                      })
                    })
                  })
                }, 100)
              })
            })
          })
        })
      })
    })
  })
}
<|endoftext|>


<commit_before>'use strict';

var util = require('util');
var test = require('tape');
var cache = require('./');

test('should call the function first time', function (t) {
  var ran = false;
  var run = cache(function (cb) {
    ran = true;
    cb();
  }, 1000);
  run(function () {
    t.ok(ran);
    t.end();
  });
});

test('should allow the callback to be optional', function (t) {
  var run = cache(function (cb) {
    cb();
    t.ok(true);
    t.end();
  });
  run();
});

test('should call the callback with the fn callback arguments', function (t) {
  var run = cache(function (cb) {
    cb(1,2,3);
  });
  run(function (a,b,c,d) {
    t.equal(a, 1);
    t.equal(b, 2);
    t.equal(c, 3);
    t.end();
  });
});

test('should cache the result for a 2nd call', function (t) {
  var run = cache(function (cb) {
    cb(Math.random());
  });
  run(function (r1) {
    run(function (r2) {
      t.equal(r1, r2);
      t.end();
    });
  });
});

test('should expire the cache after the timeout', function (t) {
  var run = cache(50, function (cb) {
    cb(Math.random());
  });
  run(function (r1) {
    setTimeout(function () {
      run(function (r2) {
        t.notEqual(r1, r2);
        t.end();
      });
    }, 80);
  });
});

test('should clear the cache if an error occurs', function (t) {
  var run = cache(function (cb) {
    cb(new Error(), Math.random());
  });
  run(function (err, r1) {
    t.ok(util.isError(err));
    run(function (err, r2) {
      t.ok(util.isError(err));
      t.notEqual(r1, r2);
      t.end();
    });
  });
});
<commit_msg>Clean up tests<commit_after>'use strict';

var util = require('util');
var test = require('tape');
var cache = require('./');

test('should call the function first time', function (t) {
  var ran = false;
  var run = cache(function (cb) {
    ran = true;
    cb();
  }, 1000);
  run(function () {
    t.ok(ran);
    t.end();
  });
});

test('should allow the callback to be optional', function (t) {
  var run = cache(function (cb) {
    cb();
    t.ok(true);
    t.end();
  });
  run();
});

test('should parse on all arugments to the callback', function (t) {
  var run = cache(function (cb) {
    cb(1,2,3);
  });
  run(function (a,b,c) {
    t.equal(a, 1);
    t.equal(b, 2);
    t.equal(c, 3);
    t.end();
  });
});

test('should use the cached arguments for a 2nd call', function (t) {
  var run = cache(function (cb) {
    cb(Math.random());
  });
  run(function (r1) {
    run(function (r2) {
      t.equal(r1, r2);
      t.end();
    });
  });
});

test('should expire the cache after the timeout', function (t) {
  var run = cache(30, function (cb) {
    cb(Math.random());
  });
  run(function (r1) {
    setTimeout(function () {
      run(function (r2) {
        t.notEqual(r1, r2);
        t.end();
      });
    }, 50);
  });
});

test('should clear the cache if an error occurs', function (t) {
  var run = cache(function (cb) {
    cb(new Error(), Math.random());
  });
  run(function (err, r1) {
    t.ok(util.isError(err));
    run(function (err, r2) {
      t.ok(util.isError(err));
      t.notEqual(r1, r2);
      t.end();
    });
  });
});
<|endoftext|>


<commit_before>'use strict';

var net  = require('net');
var test = require('tape');
var http = require('http');
var request = require('request');
var port = process.argv[2] || 1942;
var url  = 'http://127.0.0.1:' + port;
var parseUrl = require('url').parse;

var conn = net.connect(port).on('error', function(e) {
    if (e.code === 'ECONNREFUSED') {
        console.error('=====================================================');
        console.error(' ERROR:');
        console.error(' HTTP server doesn\'t seem to be running on port ' + port);
        console.error('=====================================================\n');
        process.exit(1);
    }
}).on('connect', function() {
    conn.end();
    runTests();
});

function runTests() {

    test('gives 404 on undefined resource', function(t) {
        t.plan(1);
        var req = http.get(url + '/undefined', function(res) {
            t.equal(res.statusCode, 404, '/undefined should give a 404');
            req.abort();
        });
    });

    test('gives a connection count on /connections', function(t) {
        var req = http.get(url + '/connections', function(res) {
            t.equal(res.statusCode, 200, '/connections should give a 200');
            t.equal(res.headers['content-type'], 'text/plain', 'type should be text/plain');
            t.equal(res.headers['cache-control'], 'no-cache', 'cache-control should be no-cache');
            t.equal(res.headers['connection'], 'close', 'connection should be close');

            var body = '';
            res.on('data', function(chunk) {
                body += chunk;
            });

            req.on('close', function() {
                t.ok(body.toString().match(/^\d+$/), 'connection count should be an integer');
                t.end();
            });
        });
    });

    test('sends correct cors-header', function(t) {
        t.plan(8);

        http.get(url + '/connections', function(res) {
            t.equal(res.headers['access-control-allow-origin'], '*', '/connections should send cors header');
        });

        var req = http.get(url + '/sse', function(res) {
            t.equal(res.headers['access-control-allow-origin'], '*', '/sse should send cors header');
            req.abort();
        });

        var options = parseUrl(url + '/connections');
        options.method = 'OPTIONS';

        http.request(options, function(res) {
            t.equal(res.statusCode, 204, 'OPTIONS /connections should give a 204');
            t.equal(res.headers['access-control-allow-origin'], '*', 'OPTIONS /connections should send cors header');
            t.equal(res.headers['connection'], 'close', 'OPTIONS /connections should send `connection: close`');
        }).end();

        options.path = '/sse';
        http.request(options, function(res) {
            t.equal(res.statusCode, 204, 'OPTIONS /sse should give a 204');
            t.equal(res.headers['access-control-allow-origin'], '*', 'OPTIONS /sse should send cors header');
            t.equal(res.headers['connection'], 'close', 'OPTIONS /sse should send `connection: close`');
        }).end();
    });

    test('gives an SSE-connection on /sse', function(t) {
        var timeout = setTimeout(function() {
            req.abort();
            t.fail('did not receive :ok within 250ms');
        }, 250);

        var req = http.get(url + '/sse', function(res) {
            t.equal(res.statusCode, 200, '/sse should give a 200');
            t.equal(res.headers['content-type'], 'text/event-stream', 'type should be text/event-stream');
            t.equal(res.headers['cache-control'], 'no-cache', 'cache-control should be no-cache');

            var body = '';
            res.on('data', function(chunk) {
                body += chunk.toString();

                if (body.indexOf('\n\n') !== -1) {
                    t.equal(body.indexOf(':ok\n\n'), 0, 'should send :ok message as first bytes');
                    t.end();

                    req.abort();
                    clearTimeout(timeout);
                }
            });
        });
    });

    test('sends messages received by POST to /broadcast', function(t) {
        var payload1 = '' + Date.now() + Math.random();
        var payload2 = '' + Date.now() + Math.random();
        var body = '', statusCode;
        var req = http.get(url + '/sse', function(res) {
            res.on('data', function(chunk) {
                body += chunk.toString();
            });
        });

        request({
            uri: url + '/broadcast',
            method: 'POST',
            body: payload1
        }, function(err, res) {
            t.equal(res.statusCode, 202, 'server should give 202 when posting to /broadcast');
        });

        request({
            uri: url + '/broadcast',
            method: 'POST',
            body: payload2
        }, function(err, res) {
            t.equal(res.statusCode, 202, 'server should give 202 when posting to /broadcast');
        });

        setTimeout(function() {
            req.abort();

            t.ok(body.indexOf('data: ' + payload1 + '\n\n') > -1, 'should receive broadcasted messages')
            t.ok(body.indexOf('data: ' + payload2 + '\n\n') > -1, 'should receive broadcasted messages')

            t.end();
        }, 150);
    });

    test('either discards or accepts chunked transfers (with no content-length)', function(t) {
        var sseBody = '';
        var sseReq = http.get(url + '/sse', function(res) {
            res.on('data', function(chunk) {
                sseBody += chunk.toString();
            });
        });

        var response = '';
        var conn = net.connect(port).on('error', function() {
            // Disregard errors, they're usually "connection is closed"-messages
        }).on('data', function(data) {
            response += data.toString();
        }).on('connect', function() {
            conn.write('POST /broadcast HTTP/1.1\r\n');
            conn.write('Host: localhost:' + port + '\r\n');
            conn.write('content-type: text/plain\r\n');
            conn.write('Transfer-Encoding: chunked\r\n');
            conn.write('\r\n');
            conn.write('6\r\n');
            conn.write('We are\r\n');

            setTimeout(function() {
                conn.write('9\r\n');
                conn.write(' winners!');
                conn.write('0\r\n\r\n')
                conn.end();
            }, 50);
        }).on('end', function() {
            setTimeout(function() {
                sseReq.abort();

                var match = response.match(/^HTTP\/\d\.\d\s(\d+)/),
                    resCode = match ? match[1] | 0 : null,
                    msgRcvd = sseBody.indexOf('data: We are winners!') > -1;

                if (!resCode) {
                    t.fail('Failed to get a proper HTTP response from /broadcast');
                } else if (resCode === 202) {
                    t.ok(msgRcvd, '"We are winners!"-message should be broadcasted')
                } else {
                    t.ok(resCode === 411, 'Response code should be 411 if rejected');
                }

                t.end();
            }, 150);
        });
    });

}<commit_msg>Disabled the 411/202 test<commit_after>'use strict';

var net  = require('net');
var test = require('tape');
var http = require('http');
var request = require('request');
var port = process.argv[2] || 1942;
var url  = 'http://127.0.0.1:' + port;
var parseUrl = require('url').parse;

var conn = net.connect(port).on('error', function(e) {
    if (e.code === 'ECONNREFUSED') {
        console.error('=====================================================');
        console.error(' ERROR:');
        console.error(' HTTP server doesn\'t seem to be running on port ' + port);
        console.error('=====================================================\n');
        process.exit(1);
    }
}).on('connect', function() {
    conn.end();
    runTests();
});

function runTests() {

    test('gives 404 on undefined resource', function(t) {
        t.plan(1);
        var req = http.get(url + '/undefined', function(res) {
            t.equal(res.statusCode, 404, '/undefined should give a 404');
            req.abort();
        });
    });

    test('gives a connection count on /connections', function(t) {
        var req = http.get(url + '/connections', function(res) {
            t.equal(res.statusCode, 200, '/connections should give a 200');
            t.equal(res.headers['content-type'], 'text/plain', 'type should be text/plain');
            t.equal(res.headers['cache-control'], 'no-cache', 'cache-control should be no-cache');
            t.equal(res.headers['connection'], 'close', 'connection should be close');

            var body = '';
            res.on('data', function(chunk) {
                body += chunk;
            });

            req.on('close', function() {
                t.ok(body.toString().match(/^\d+$/), 'connection count should be an integer');
                t.end();
            });
        });
    });

    test('sends correct cors-header', function(t) {
        t.plan(8);

        http.get(url + '/connections', function(res) {
            t.equal(res.headers['access-control-allow-origin'], '*', '/connections should send cors header');
        });

        var req = http.get(url + '/sse', function(res) {
            t.equal(res.headers['access-control-allow-origin'], '*', '/sse should send cors header');
            req.abort();
        });

        var options = parseUrl(url + '/connections');
        options.method = 'OPTIONS';

        http.request(options, function(res) {
            t.equal(res.statusCode, 204, 'OPTIONS /connections should give a 204');
            t.equal(res.headers['access-control-allow-origin'], '*', 'OPTIONS /connections should send cors header');
            t.equal(res.headers['connection'], 'close', 'OPTIONS /connections should send `connection: close`');
        }).end();

        options.path = '/sse';
        http.request(options, function(res) {
            t.equal(res.statusCode, 204, 'OPTIONS /sse should give a 204');
            t.equal(res.headers['access-control-allow-origin'], '*', 'OPTIONS /sse should send cors header');
            t.equal(res.headers['connection'], 'close', 'OPTIONS /sse should send `connection: close`');
        }).end();
    });

    test('gives an SSE-connection on /sse', function(t) {
        var timeout = setTimeout(function() {
            req.abort();
            t.fail('did not receive :ok within 250ms');
        }, 250);

        var req = http.get(url + '/sse', function(res) {
            t.equal(res.statusCode, 200, '/sse should give a 200');
            t.equal(res.headers['content-type'], 'text/event-stream', 'type should be text/event-stream');
            t.equal(res.headers['cache-control'], 'no-cache', 'cache-control should be no-cache');

            var body = '';
            res.on('data', function(chunk) {
                body += chunk.toString();

                if (body.indexOf('\n\n') !== -1) {
                    t.equal(body.indexOf(':ok\n\n'), 0, 'should send :ok message as first bytes');
                    t.end();

                    req.abort();
                    clearTimeout(timeout);
                }
            });
        });
    });

    test('sends messages received by POST to /broadcast', function(t) {
        var payload1 = '' + Date.now() + Math.random();
        var payload2 = '' + Date.now() + Math.random();
        var body = '', statusCode;
        var req = http.get(url + '/sse', function(res) {
            res.on('data', function(chunk) {
                body += chunk.toString();
            });
        });

        request({
            uri: url + '/broadcast',
            method: 'POST',
            body: payload1
        }, function(err, res) {
            t.equal(res.statusCode, 202, 'server should give 202 when posting to /broadcast');
        });

        request({
            uri: url + '/broadcast',
            method: 'POST',
            body: payload2
        }, function(err, res) {
            t.equal(res.statusCode, 202, 'server should give 202 when posting to /broadcast');
        });

        setTimeout(function() {
            req.abort();

            t.ok(body.indexOf('data: ' + payload1 + '\n\n') > -1, 'should receive broadcasted messages')
            t.ok(body.indexOf('data: ' + payload2 + '\n\n') > -1, 'should receive broadcasted messages')

            t.end();
        }, 150);
    });

    /*
    test('either discards or accepts chunked transfers (with no content-length)', function(t) {
        var sseBody = '';
        var sseReq = http.get(url + '/sse', function(res) {
            res.on('data', function(chunk) {
                sseBody += chunk.toString();
            });
        });

        var response = '';
        var conn = net.connect(port).on('error', function() {
            // Disregard errors, they're usually "connection is closed"-messages
        }).on('data', function(data) {
            response += data.toString();
        }).on('connect', function() {
            conn.write('POST /broadcast HTTP/1.1\r\n');
            conn.write('Host: localhost:' + port + '\r\n');
            conn.write('content-type: text/plain\r\n');
            conn.write('Transfer-Encoding: chunked\r\n');
            conn.write('\r\n');
            conn.write('6\r\n');
            conn.write('We are\r\n');

            setTimeout(function() {
                conn.write('9\r\n');
                conn.write(' winners!');
                conn.write('0\r\n\r\n')
                conn.end();
            }, 50);
        }).on('end', function() {
            setTimeout(function() {
                sseReq.abort();

                var match = response.match(/^HTTP\/\d\.\d\s(\d+)/),
                    resCode = match ? match[1] | 0 : null,
                    msgRcvd = sseBody.indexOf('data: We are winners!') > -1;

                if (!resCode) {
                    t.fail('Failed to get a proper HTTP response from /broadcast');
                } else if (resCode === 202) {
                    t.ok(msgRcvd, '"We are winners!"-message should be broadcasted')
                } else {
                    t.ok(resCode === 411, 'Response code should be 411 if rejected');
                }

                t.end();
            }, 150);
        });
    });
    */

}<|endoftext|>


<commit_before>var csvLine = require('./csv-line')

require('tape')(function (t) {
  t.equal(csvLine()([ 'foo', 'bar', undefined, 1 ]), 'foo,bar,,1')
  t.equal(csvLine()([ '"hello"', ',beep']), '"""hello""",",beep"')
  t.equal(csvLine({ separator: '\t'})([ 'foo', 'bar' ]), 'foo\tbar')
  t.equal(csvLine({ escapeNewlines: true })([ '\nfoo\nbar\n' ]), '\\nfoo\\nbar\\n')
  t.equal(csvLine({ escapeNewlines: true })([ 1, undefined, 2 ]), '1,,2')
  t.end()
})
<commit_msg>test encoding and decoding<commit_after>var csvLine = require('./csv-line')

var tape = require('tape')

var examples = [
  {
    decoded: [ 'foo', 'bar', undefined, 1 ],
    encoded: 'foo,bar,,1'
  },
  {
    decoded: [ '"hello"', ',beep'],
    encoded: '"""hello""",",beep"'
  },
  {
    decoded: [ 1, undefined, 2 ],
    encoded: '1,,2'
  }
]

tape('options', function (t) {
  t.equal(csvLine({ separator: '\t'})([ 'foo', 'bar' ]), 'foo\tbar')
  t.equal(csvLine({ escapeNewlines: true })([ '\nfoo\nbar\n' ]), '\\nfoo\\nbar\\n')
  t.equal(csvLine({ escapeNewlines: true })([ 1, undefined, 2 ]), '1,,2')
  t.end()
})

tape('encode', function (t) {
  examples.forEach(function (ex) {
    t.equal(csvLine.encode(ex.decoded), ex.encoded)
  })
  t.end()
})

tape('decode', function (t) {
  examples.forEach(function (ex) {
    t.deepEqual(csvLine.decode(ex.encoded), ex.decoded)
  })
  t.end()

})
<|endoftext|>


<commit_before>import test from 'ava'
import singleTrailingNewline from './'

const strings = [
  'foo\nbar',
  'foo\nbar\n',
  'foo\nbar\n\n',
  'foo\nbar\n\r\n',
  'foo\nbar\n\n\n\r\n\r\n'
]

const carriageReturnStrings = [
  'foo\r\nbar',
  'foo\r\nbar\r\n',
  'foo\r\nbar\r\n\r\n',
  'foo\r\nbar\n\r\n',
  'foo\nbar\r\n\r\n'
]

test('single-trailing-newline detects \\n strings and ensures only one trailing newline', t => {
  t.plan(strings.length)

  strings.forEach(str => {
    t.same(singleTrailingNewline(str), 'foo\nbar\n')
  })
})
<commit_msg>Add \r\n tests<commit_after>import test from 'ava'
import singleTrailingNewline from './'

const strings = [
  'foo\nbar',
  'foo\nbar\n',
  'foo\nbar\n\n',
  'foo\nbar\n\r\n',
  'foo\nbar\n\n\n\r\n\r\n'
]

const carriageReturnStrings = [
  'foo\r\nbar',
  'foo\r\nbar\r\n',
  'foo\r\nbar\r\n\r\n',
  'foo\r\nbar\n\r\n',
  'foo\r\nbar\r\n\r\n'
]

test('single-trailing-newline detects \\n strings and ensures only one trailing newline', t => {
  t.plan(strings.length)

  strings.forEach(str => {
    t.same(singleTrailingNewline(str), 'foo\nbar\n')
  })
})

test('single-trailing-newline detects \\r\\n strings and ensures only one trailing newline', t => {
  t.plan(carriageReturnStrings.length)

  carriageReturnStrings.forEach(str => {
    t.same(singleTrailingNewline(str), 'foo\r\nbar\r\n')
  })
})
<|endoftext|>


<commit_before>import test from 'ava';
import Paratree from './';
import _ from 'lodash';

let text = `Bottlenose dolphins living off the coast of southwest Australia have a dilemma. The local octopuses are tasty and packed with protein, but they are also intelligent, fierce fighters. It's not enough to bite the cephalopods' heads off, because octopus nervous systems are so decentralized that their legs can continue the battle even when detached. Nevertheless, the dolphins have persisted in their pursuit of tentacled meals. Now, after years of observation with video, scientists have seen dozens of examples of the dolphins' elaborate octopus hunting strategy.

Bottlenose dolphins are known for problem-solving when it comes to hunting difficult prey. Previously, researchers have seen the dolphins protecting their soft snouts with sponges while digging in the seafloor for fish. Octopus hunting requires other skills, however. First, the octopus has to be disarmed—literally. And then those arms have to be bashed into submission. Those who do not learn this trick are likely to die. In a paper published recently in Marine Mammal Science, Murdoch University marine biologist Kate R. Sprogis and colleagues report that they've come across two dolphins killed while trying to eat octopuses:

It is apparent that octopus handling is a risky behavior, as within our study area a known adult male stranded and a necropsy confirmed the cause of death was from suffocation from a large 2.1 kg octopus. The dolphin had attempted to swallow the octopus, however, the octopus was found almost intact, with the head and the mantle of the octopus in the dolphin's stomach and the 1.3 m long arms separated from the head and extending out of its mouth. Similarly, another [bottlenose dolphin] died from suspected asphyxiation due to an octopus lodged in its mouth and pharynx.

Essentially, the octopuses' tentacles keep fighting, blocking the dolphins' airways, even after most of their bodies have been swallowed. It's a terrifying way to die, but Sprogis and the researchers observe that octopuses must be such valuable prey that they are worth it. Over seven years of observation, she and her team watched 33 dolphins "handling" octopuses in ways that made them meal-ready. Typically, the encounter would start with the dolphin biting the octopus' head off, followed by tossing the legs into the air so that they smack hard into the water over and over. Dolphins would execute the grab-and-toss move about 10-15 times before they were satisfied.`;

let para = new Paratree(text);
test('Should has 4 paragraphs', t => {
  t.is(para.paragraphs.length, 4);
});

test('Should has an id', t => {
  t.truthy(para.id);
});

test('Should capable add, and get a data', t => {
  const answer = 42;
  para.data.add('the meaning of life', 42);

  t.is(para.data.get('the meaning of life'), answer);
});

test('Paragraphs should has same parent', t => {
  para.paragraphs.forEach(paragraph => {
    let parent = paragraph.parent();
    t.is(parent, para);
  });
});

test('Should has 21 sentences', t => {
  t.is(para.sentences.length, 21);
});

test('Sentences should has parent and equals with its siblings.', t => {
  para.paragraphs.forEach(paragraph => {
    paragraph.sentencesCollection.forEach(sentence => {
      t.is(sentence.parent(), paragraph);
    });
  });
});

test('Should has 389 words', t => {
  t.is(para.words.length, 389);
});

test('Words should has parent and equals with its siblings.', t => {
  para.paragraphs.forEach(paragraph => {
    paragraph.sentencesCollection.forEach(sentence => {
      sentence.wordsCollection.forEach(word => {
        t.is(word.parent(), sentence);
      });
    });
  });
});

test('Should has 223 unique words', t => {
  t.is(para.uniqueWords().length, 223);
});

test('Should has 2243 characters', t => {
  t.is(para.charactersLength(), 2443);
});

test('Should has 2052 characters with no spaces', t => {
  t.is(para.charactersNoSpaceLength(), 2052);
});

test('Should has 44 words in longest sentences', t => {
  t.is(para.longestSentence().words.length, 44);
});

test('Should has 6 words in shortest sentences', t => {
  t.is(para.shortestSentence().words.length, 6);
});

test('Should has 18.xx average words length per sentence', t => {
  t.truthy(para.averageWordSentence() > 18);
});

test('Should has more than 100 average characters length per sentence', t => {
  t.truthy(para.averageCharacterSentence() > 100);
});

test('Should has more than 5 char average length in word', t => {
  t.truthy(para.averageWordLength() > 5);
});

test('Find paragraph by id\'s equals to sample data', t => {
  let sampleParagraph = _.sample(para.paragraphs);
  let {id} = sampleParagraph;
  t.is(sampleParagraph, para.findParagraphById(id));
});

test('Find paragraph by index\'s result equals to sample data', t => {
  let sampleParagraph = _.sample(para.paragraphs);
  let {index} = sampleParagraph;
  t.is(sampleParagraph, para.findParagraphByIndex(index));
});

test('Find sentence by id\'s result equals to sample data ', t => {
  let sampleSentence = _.sample(para.sentences);
  let {id} = sampleSentence;

  t.is(sampleSentence, para.findSentenceById(id));
  t.is(sampleSentence, sampleSentence.parent().findSentenceById(id));
});

test('Find sentence by index\'s result equals to sample data', t => {
  let sampleParagraph = _.sample(para.paragraphs);
  let sampleSentence = _.sample(sampleParagraph.sentencesCollection);
  let {index} = sampleSentence;

  t.is(sampleSentence, sampleParagraph.findSentenceByIndex(index));
});

test('Find word by id\'s result equals to sample data ', t => {
  let sampleWord = _.sample(para.words);
  let {id} = sampleWord;

  t.is(sampleWord, para.findWordById(id));
  t.is(sampleWord, sampleWord.parent().findWordById(id));
});

test('Find word by index\'s result equals to sample data ', t => {
  let sampleParagraph = _.sample(para.paragraphs);
  let sampleSentence = _.sample(sampleParagraph.sentencesCollection);
  let sampleWord = _.sample(sampleSentence.wordsCollection);
  let {index} = sampleWord;

  t.is(sampleWord, sampleSentence.findWordByIndex(index));
});

test('Capable to navigate to the next or previous paragraph', t => {
  let sampleParagraph = _.sample(para.paragraphs);
  let {index} = sampleParagraph;

  let nextParagraph = sampleParagraph.next();
  let prevParagraph = sampleParagraph.prev();

  if (nextParagraph) {
    let {index: nextParagraphIndex} = nextParagraph;
    t.is(nextParagraphIndex, index + 1);
  }

  if (prevParagraph) {
    let {index: prevParagraphIndex} = prevParagraph;
    t.is(prevParagraphIndex, index - 1);
  }

});

test('Capable able to navigate to the next or previous sentence in a paragraph', t => {
  let sampleParagraph = _.sample(para.paragraphs);
  let sampleSentence = _.sample(sampleParagraph.sentencesCollection);
  let {index} = sampleSentence;

  let nextSentence = sampleSentence.next();
  let prevSentence = sampleSentence.prev();

  if (nextSentence) {
    let {index: nextSentenceIndex} = nextSentence;
    t.is(nextSentenceIndex, index + 1);
  }

  if (prevSentence) {
    let {index: prevSentenceIndex} = prevSentence;
    t.is(prevSentenceIndex, index - 1);
  }
});

test('Capable to navigate to the next or previous words in a sentence', t => {
  let sampleParagraph = _.sample(para.paragraphs);
  let sampleSentence = _.sample(sampleParagraph.sentencesCollection);
  let sampleWord = _.sample(sampleSentence.wordsCollection);
  let {index} = sampleWord;

  let nextWord = sampleWord.next();
  let prevWord = sampleWord.prev();

  if (nextWord) {
    let {index: nextWordIndex} = nextWord;
    t.is(nextWordIndex, index + 1);
  }

  if (prevWord) {
    let {index: prevWordIndex} = prevWord;
    t.is(prevWordIndex, index - 1);
  }
});

test('Do data operation to a paragraph', t => {
  let sampleParagraph = _.sample(para.paragraphs);
  let id = sampleParagraph.id;

  t.is(sampleParagraph, para.findParagraphById(id));

  let label = 'What the fuck';
  let startTime = new Date();
  let randomData = [234, 341];

  sampleParagraph.data.add('label', label);
  sampleParagraph.data.add('start time', startTime);
  sampleParagraph.data.add('random data', randomData);

  t.is(sampleParagraph.data.get('label'), label);
  t.is(sampleParagraph.data.get('label'),
    para.findParagraphById(id).data.get('label'));
  t.is(sampleParagraph.data.get('start time'), startTime);
  t.is(sampleParagraph.data.get('random data'), randomData);

  sampleParagraph.data.delete('random data');
  t.falsy(sampleParagraph.data.get('random data'));
});

test('Do data operation to a sentence', t => {
  let sampleParagraph = _.sample(para.paragraphs);
  let sampleSentence = _.sample(sampleParagraph.sentencesCollection);
  let id = sampleSentence.id;

  t.is(sampleSentence, sampleParagraph.findSentenceById(id));

  let label = 'What the fuck';
  let startTime = new Date();
  let randomData = [234, 341];

  sampleSentence.data.add('label', label);
  sampleSentence.data.add('start time', startTime);
  sampleSentence.data.add('random data', randomData);

  t.is(sampleSentence.data.get('label'), label);
  t.is(sampleSentence.data.get('label'),
    sampleParagraph.findSentenceById(id).data.get('label'));
  t.is(sampleSentence.data.get('start time'), startTime);
  t.is(sampleSentence.data.get('random data'), randomData);

  sampleSentence.data.delete('random data');
  t.falsy(sampleSentence.data.get('random data'));
});

test('Do data operation to a word', t => {
  let sampleParagraph = _.sample(para.paragraphs);
  let sampleSentence = _.sample(sampleParagraph.sentencesCollection);
  let sampleWord = _.sample(sampleSentence.wordsCollection);
  let id = sampleWord.id;

  t.is(sampleWord, sampleSentence.findWordById(id));

  let label = 'What the fuck';
  let startTime = new Date();
  let randomData = [234, 341];

  sampleWord.data.add('label', label);
  sampleWord.data.add('start time', startTime);
  sampleWord.data.add('random data', randomData);

  t.is(sampleWord.data.get('label'), label);
  t.is(sampleWord.data.get('label'),
    sampleSentence.findWordById(id).data.get('label'));
  t.is(sampleWord.data.get('start time'), startTime);
  t.is(sampleWord.data.get('random data'), randomData);

  sampleWord.data.delete('random data');
  t.falsy(sampleWord.data.get('random data'));
});<commit_msg>Add test for "add method"<commit_after>import test from 'ava';
import Paratree from './';
import _ from 'lodash';

let text = `Bottlenose dolphins living off the coast of southwest Australia have a dilemma. The local octopuses are tasty and packed with protein, but they are also intelligent, fierce fighters. It's not enough to bite the cephalopods' heads off, because octopus nervous systems are so decentralized that their legs can continue the battle even when detached. Nevertheless, the dolphins have persisted in their pursuit of tentacled meals. Now, after years of observation with video, scientists have seen dozens of examples of the dolphins' elaborate octopus hunting strategy.

Bottlenose dolphins are known for problem-solving when it comes to hunting difficult prey. Previously, researchers have seen the dolphins protecting their soft snouts with sponges while digging in the seafloor for fish. Octopus hunting requires other skills, however. First, the octopus has to be disarmed—literally. And then those arms have to be bashed into submission. Those who do not learn this trick are likely to die. In a paper published recently in Marine Mammal Science, Murdoch University marine biologist Kate R. Sprogis and colleagues report that they've come across two dolphins killed while trying to eat octopuses:

It is apparent that octopus handling is a risky behavior, as within our study area a known adult male stranded and a necropsy confirmed the cause of death was from suffocation from a large 2.1 kg octopus. The dolphin had attempted to swallow the octopus, however, the octopus was found almost intact, with the head and the mantle of the octopus in the dolphin's stomach and the 1.3 m long arms separated from the head and extending out of its mouth. Similarly, another [bottlenose dolphin] died from suspected asphyxiation due to an octopus lodged in its mouth and pharynx.

Essentially, the octopuses' tentacles keep fighting, blocking the dolphins' airways, even after most of their bodies have been swallowed. It's a terrifying way to die, but Sprogis and the researchers observe that octopuses must be such valuable prey that they are worth it. Over seven years of observation, she and her team watched 33 dolphins "handling" octopuses in ways that made them meal-ready. Typically, the encounter would start with the dolphin biting the octopus' head off, followed by tossing the legs into the air so that they smack hard into the water over and over. Dolphins would execute the grab-and-toss move about 10-15 times before they were satisfied.`;

let para = new Paratree(text);
test('Should has 4 paragraphs', t => {
  t.is(para.paragraphs.length, 4);
});

test('Should has an id', t => {
  t.truthy(para.id);
});

test('add method on text', t => {
  let id = para.id;
  para.method('getId', function() {
    return this.id;
  });

  t.is(para.getId(), id);
});

test('Should capable add, and get a data', t => {
  const answer = 42;
  para.data.add('the meaning of life', 42);

  t.is(para.data.get('the meaning of life'), answer);
});

test('Paragraphs should has same parent', t => {
  para.paragraphs.forEach(paragraph => {
    let parent = paragraph.parent();
    t.is(parent, para);
  });
});

test('Should has 21 sentences', t => {
  t.is(para.sentences.length, 21);
});

test('Sentences should has parent and equals with its siblings.', t => {
  para.paragraphs.forEach(paragraph => {
    paragraph.sentencesCollection.forEach(sentence => {
      t.is(sentence.parent(), paragraph);
    });
  });
});

test('Should has 389 words', t => {
  t.is(para.words.length, 389);
});

test('Words should has parent and equals with its siblings.', t => {
  para.paragraphs.forEach(paragraph => {
    paragraph.sentencesCollection.forEach(sentence => {
      sentence.wordsCollection.forEach(word => {
        t.is(word.parent(), sentence);
      });
    });
  });
});

test('Should has 223 unique words', t => {
  t.is(para.uniqueWords().length, 223);
});

test('Should has 2243 characters', t => {
  t.is(para.charactersLength(), 2443);
});

test('Should has 2052 characters with no spaces', t => {
  t.is(para.charactersNoSpaceLength(), 2052);
});

test('Should has 44 words in longest sentences', t => {
  t.is(para.longestSentence().words.length, 44);
});

test('Should has 6 words in shortest sentences', t => {
  t.is(para.shortestSentence().words.length, 6);
});

test('Should has 18.xx average words length per sentence', t => {
  t.truthy(para.averageWordSentence() > 18);
});

test('Should has more than 100 average characters length per sentence', t => {
  t.truthy(para.averageCharacterSentence() > 100);
});

test('Should has more than 5 char average length in word', t => {
  t.truthy(para.averageWordLength() > 5);
});

test('Find paragraph by id\'s equals to sample data', t => {
  let sampleParagraph = _.sample(para.paragraphs);
  let {id} = sampleParagraph;
  t.is(sampleParagraph, para.findParagraphById(id));
});

test('Find paragraph by index\'s result equals to sample data', t => {
  let sampleParagraph = _.sample(para.paragraphs);
  let {index} = sampleParagraph;
  t.is(sampleParagraph, para.findParagraphByIndex(index));
});

test('Find sentence by id\'s result equals to sample data ', t => {
  let sampleSentence = _.sample(para.sentences);
  let {id} = sampleSentence;

  t.is(sampleSentence, para.findSentenceById(id));
  t.is(sampleSentence, sampleSentence.parent().findSentenceById(id));
});

test('Find sentence by index\'s result equals to sample data', t => {
  let sampleParagraph = _.sample(para.paragraphs);
  let sampleSentence = _.sample(sampleParagraph.sentencesCollection);
  let {index} = sampleSentence;

  t.is(sampleSentence, sampleParagraph.findSentenceByIndex(index));
});

test('Find word by id\'s result equals to sample data ', t => {
  let sampleWord = _.sample(para.words);
  let {id} = sampleWord;

  t.is(sampleWord, para.findWordById(id));
  t.is(sampleWord, sampleWord.parent().findWordById(id));
});

test('Find word by index\'s result equals to sample data ', t => {
  let sampleParagraph = _.sample(para.paragraphs);
  let sampleSentence = _.sample(sampleParagraph.sentencesCollection);
  let sampleWord = _.sample(sampleSentence.wordsCollection);
  let {index} = sampleWord;

  t.is(sampleWord, sampleSentence.findWordByIndex(index));
});

test('Capable to navigate to the next or previous paragraph', t => {
  let sampleParagraph = _.sample(para.paragraphs);
  let {index} = sampleParagraph;

  let nextParagraph = sampleParagraph.next();
  let prevParagraph = sampleParagraph.prev();

  if (nextParagraph) {
    let {index: nextParagraphIndex} = nextParagraph;
    t.is(nextParagraphIndex, index + 1);
  }

  if (prevParagraph) {
    let {index: prevParagraphIndex} = prevParagraph;
    t.is(prevParagraphIndex, index - 1);
  }

});

test('Capable able to navigate to the next or previous sentence in a paragraph', t => {
  let sampleParagraph = _.sample(para.paragraphs);
  let sampleSentence = _.sample(sampleParagraph.sentencesCollection);
  let {index} = sampleSentence;

  let nextSentence = sampleSentence.next();
  let prevSentence = sampleSentence.prev();

  if (nextSentence) {
    let {index: nextSentenceIndex} = nextSentence;
    t.is(nextSentenceIndex, index + 1);
  }

  if (prevSentence) {
    let {index: prevSentenceIndex} = prevSentence;
    t.is(prevSentenceIndex, index - 1);
  }
});

test('Capable to navigate to the next or previous words in a sentence', t => {
  let sampleParagraph = _.sample(para.paragraphs);
  let sampleSentence = _.sample(sampleParagraph.sentencesCollection);
  let sampleWord = _.sample(sampleSentence.wordsCollection);
  let {index} = sampleWord;

  let nextWord = sampleWord.next();
  let prevWord = sampleWord.prev();

  if (nextWord) {
    let {index: nextWordIndex} = nextWord;
    t.is(nextWordIndex, index + 1);
  }

  if (prevWord) {
    let {index: prevWordIndex} = prevWord;
    t.is(prevWordIndex, index - 1);
  }
});

test('Do data operation to a paragraph', t => {
  let sampleParagraph = _.sample(para.paragraphs);
  let id = sampleParagraph.id;

  t.is(sampleParagraph, para.findParagraphById(id));

  let label = 'What the fuck';
  let startTime = new Date();
  let randomData = [234, 341];

  sampleParagraph.data.add('label', label);
  sampleParagraph.data.add('start time', startTime);
  sampleParagraph.data.add('random data', randomData);

  t.is(sampleParagraph.data.get('label'), label);
  t.is(sampleParagraph.data.get('label'),
    para.findParagraphById(id).data.get('label'));
  t.is(sampleParagraph.data.get('start time'), startTime);
  t.is(sampleParagraph.data.get('random data'), randomData);

  sampleParagraph.data.delete('random data');
  t.falsy(sampleParagraph.data.get('random data'));
});

test('Do data operation to a sentence', t => {
  let sampleParagraph = _.sample(para.paragraphs);
  let sampleSentence = _.sample(sampleParagraph.sentencesCollection);
  let id = sampleSentence.id;

  t.is(sampleSentence, sampleParagraph.findSentenceById(id));

  let label = 'What the fuck';
  let startTime = new Date();
  let randomData = [234, 341];

  sampleSentence.data.add('label', label);
  sampleSentence.data.add('start time', startTime);
  sampleSentence.data.add('random data', randomData);

  t.is(sampleSentence.data.get('label'), label);
  t.is(sampleSentence.data.get('label'),
    sampleParagraph.findSentenceById(id).data.get('label'));
  t.is(sampleSentence.data.get('start time'), startTime);
  t.is(sampleSentence.data.get('random data'), randomData);

  sampleSentence.data.delete('random data');
  t.falsy(sampleSentence.data.get('random data'));
});

test('Do data operation to a word', t => {
  let sampleParagraph = _.sample(para.paragraphs);
  let sampleSentence = _.sample(sampleParagraph.sentencesCollection);
  let sampleWord = _.sample(sampleSentence.wordsCollection);
  let id = sampleWord.id;

  t.is(sampleWord, sampleSentence.findWordById(id));

  let label = 'What the fuck';
  let startTime = new Date();
  let randomData = [234, 341];

  sampleWord.data.add('label', label);
  sampleWord.data.add('start time', startTime);
  sampleWord.data.add('random data', randomData);

  t.is(sampleWord.data.get('label'), label);
  t.is(sampleWord.data.get('label'),
    sampleSentence.findWordById(id).data.get('label'));
  t.is(sampleWord.data.get('start time'), startTime);
  t.is(sampleWord.data.get('random data'), randomData);

  sampleWord.data.delete('random data');
  t.falsy(sampleWord.data.get('random data'));
});<|endoftext|>


<commit_before>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length < 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<commit_msg>🤖(fix): 2017-7-24 01:07:25<commit_after>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length > 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<|endoftext|>