<commit_before>'use strict';

var tape = require('../lib/thaliTape');
if (!tape.coordinated) {
  return;
}

var testUtils = require('../lib/testUtils.js');

var extend = require('js-extend').extend;
var fs = require('fs-extra-promise');
var path = require('path');
var crypto = require('crypto');
var Promise = require('lie');
var PouchDB = require('pouchdb');
var ExpressPouchDB = require('express-pouchdb');
var LeveldownMobile = require('leveldown-mobile');

var sinon = require('sinon');

var PouchDBGenerator = require('thali/NextGeneration/utils/pouchDBGenerator');
var thaliConfig = require('thali/NextGeneration/thaliConfig');
var ThaliManager = require('thali/NextGeneration/thaliManager');
var ThaliPeerPoolDefault =
  require('thali/NextGeneration/thaliPeerPool/thaliPeerPoolDefault');

// DB defaultDirectory should be unique among all tests
// and any instance of this test.
// This is especially required for tape.coordinated.
var defaultDirectory = path.join(
  testUtils.getPouchDBTestDirectory(),
  'thali-manager-db-' + testUtils.getUniqueRandomName()
);

// Public key for local device should be passed
// to the tape 'setup' as 'tape.data'.
var ecdhForLocalDevice = crypto.createECDH(thaliConfig.BEACON_CURVE);
var publicKeyForLocalDevice = ecdhForLocalDevice.generateKeys();
var publicBase64KeyForLocalDevice = ecdhForLocalDevice.getPublicKey('base64');

// PouchDB name should be the same between peers.
var DB_NAME = 'ThaliManagerCoordinated';

PouchDB = PouchDBGenerator(PouchDB, defaultDirectory, {
  defaultAdapter: LeveldownMobile
});

var thaliManager;

var TEST_TIMEOUT = 5 * 60 * 1000; // 5 minutes

var thisWasTheLastTest = false;
var test = tape({
  setup: function (t) {
    t.data = publicKeyForLocalDevice.toJSON();
    fs.ensureDirSync(defaultDirectory);
    t.end();
  },
  teardown: function (t) {
    Promise.resolve()
    .then(function () {
      if (thaliManager) {
        return thaliManager.stop();
      }
    })
    .then(function () {
      if (thisWasTheLastTest) {
        fs.removeSync(defaultDirectory);
      }
      t.end();
    });
  }
});

// We have 'localDoc' and 'oldRemoteDocs' already in DB.
// We are waiting until 'newRemoteDocs' will appears in DB.
// We are waiting for confirmation that 'localDoc' is in DB too.
// Our changes handler should receive 'localDoc' and
// 'newRemoteDocs' only once.
// It can receive 'oldRemoteDocs' once or never.
function waitForRemoteDocs(
  pouchDB, localDoc, oldRemoteDocs, newRemoteDocs, ignoreRev
) {
  var allDocsFound = false;

  // We can remove '_rev' key from compared values.
  // We can just stringify docs, they wont be circular.
  function toString(doc) {
    var keys = Object.keys(doc);
    var keyIndex = keys.indexOf('_rev');
    if (keyIndex !== -1) {
      keys.splice(keyIndex, 1);
    }
    return JSON.stringify(doc, keys.sort());
  }

  var localDocString = toString(localDoc);
  var oldRemoteDocStrings = oldRemoteDocs.map(toString);
  var newRemoteDocStrings = newRemoteDocs.map(toString);

  function findDoc(doc) {
    var docString = toString(doc);

    var oldIndex = oldRemoteDocStrings.indexOf(docString);
    var newIndex = newRemoteDocStrings.indexOf(docString);
    if (localDocString && docString === localDocString) {
      localDocString = undefined;
      if (newRemoteDocStrings.length === 0) {
        allDocsFound = true;
      }
      return true;
    }
    else if (oldIndex !== - 1) {
      oldRemoteDocStrings.splice(oldIndex, 1);
      return true;
    } else if (newIndex !== -1) {
      newRemoteDocStrings.splice(newIndex, 1);
      if (newRemoteDocStrings.length === 0) {
        allDocsFound = true;
      }
      return true;
    } else {
      console.log('ololo', docString);
      return false;
    }
  }

  return new Promise(function (resolve, reject) {
    var error;
    var completed = false;
    function complete () {
      if (completed) {
        return;
      }
      completed = true;

      if (error) {
        reject(error);
      } else {
        resolve();
      }
    }
    var changesFeed = pouchDB.changes({
      since: 0,
      live: true,
      include_docs: true
    })
    .on('change', function (change) {
      if (findDoc(change.doc)) {
        if (allDocsFound) {
          changesFeed.cancel();
        }
      } else {
        error = new Error('invalid doc');
        changesFeed.cancel();
      }
    })<commit_msg>cosmetics<commit_after>'use strict';

var tape = require('../lib/thaliTape');
if (!tape.coordinated) {
  return;
}

var testUtils = require('../lib/testUtils.js');

var extend = require('js-extend').extend;
var fs = require('fs-extra-promise');
var path = require('path');
var crypto = require('crypto');
var Promise = require('lie');
var PouchDB = require('pouchdb');
var ExpressPouchDB = require('express-pouchdb');
var LeveldownMobile = require('leveldown-mobile');

var sinon = require('sinon');

var PouchDBGenerator = require('thali/NextGeneration/utils/pouchDBGenerator');
var thaliConfig = require('thali/NextGeneration/thaliConfig');
var ThaliManager = require('thali/NextGeneration/thaliManager');
var ThaliPeerPoolDefault =
  require('thali/NextGeneration/thaliPeerPool/thaliPeerPoolDefault');

// DB defaultDirectory should be unique among all tests
// and any instance of this test.
// This is especially required for tape.coordinated.
var defaultDirectory = path.join(
  testUtils.getPouchDBTestDirectory(),
  'thali-manager-db-' + testUtils.getUniqueRandomName()
);

// Public key for local device should be passed
// to the tape 'setup' as 'tape.data'.
var ecdhForLocalDevice = crypto.createECDH(thaliConfig.BEACON_CURVE);
var publicKeyForLocalDevice = ecdhForLocalDevice.generateKeys();
var publicBase64KeyForLocalDevice = ecdhForLocalDevice.getPublicKey('base64');

// PouchDB name should be the same between peers.
var DB_NAME = 'ThaliManagerCoordinated';

PouchDB = PouchDBGenerator(PouchDB, defaultDirectory, {
  defaultAdapter: LeveldownMobile
});

var thaliManager;

var TEST_TIMEOUT = 5 * 60 * 1000; // 5 minutes

var thisWasTheLastTest = false;
var test = tape({
  setup: function (t) {
    t.data = publicKeyForLocalDevice.toJSON();
    fs.ensureDirSync(defaultDirectory);
    t.end();
  },
  teardown: function (t) {
    Promise.resolve()
    .then(function () {
      if (thaliManager) {
        return thaliManager.stop();
      }
    })
    .then(function () {
      if (thisWasTheLastTest) {
        fs.removeSync(defaultDirectory);
      }
      t.end();
    });
  }
});

// We have 'localDoc' and 'oldRemoteDocs' already in DB.
// We are waiting until 'newRemoteDocs' will appears in DB.
// We are waiting for confirmation that 'localDoc' and 'oldRemoteDocs' is in DB too.
function waitForRemoteDocs(
  pouchDB, localDoc, oldRemoteDocs, newRemoteDocs, ignoreRev
) {
  // We can remove '_rev' key from compared values.
  // We can just stringify docs, they wont be circular.
  function toString(doc) {
    var keys = Object.keys(doc);
    var keyIndex = keys.indexOf('_rev');
    if (keyIndex !== -1) {
      keys.splice(keyIndex, 1);
    }
    return JSON.stringify(doc, keys.sort());
  }

  var localDocString = toString(localDoc);
  var oldRemoteDocStrings = oldRemoteDocs.map(toString);
  var newRemoteDocStrings = newRemoteDocs.map(toString);

  function allDocsFound() {
    return (
      !localDocString &&
      newRemoteDocStrings.length === 0 &&
      oldRemoteDocStrings.length === 0
    );
  }

  function findDoc(doc) {
    var docString = toString(doc);

    var oldIndex = oldRemoteDocStrings.indexOf(docString);
    var newIndex = newRemoteDocStrings.indexOf(docString);
    if (localDocString && docString === localDocString) {
      localDocString = undefined;
      return true;
    }
    else if (oldIndex !== - 1) {
      oldRemoteDocStrings.splice(oldIndex, 1);
      return true;
    }
    else if (newIndex !== -1) {
      newRemoteDocStrings.splice(newIndex, 1);
      return true;
    }
    else {
      return false;
    }
  }

  return new Promise(function (resolve, reject) {
    var error;
    var completed = false;
    function complete () {
      if (completed) {
        return;
      }
      completed = true;

      if (error) {
        reject(error);
      } else {
        resolve();
      }
    }
    var changesFeed = pouchDB.changes({
      since: 0,
      live: true,
      include_docs: true
    })
    .on('change', function (change) {
      if (findDoc(change.doc)) {
        if (allDocsFound()) {
          changesFeed.cancel();
        }
      } else {
        error = new Error('invalid doc');
        changesFeed.cancel();
      }
    })
{'fraction_non_alphanumeric': 0.12402830954867154, 'fraction_numerical': 0.004872955099199443, 'mean_word_length': 3.2421259842519685, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '824007', 'n_tokens_mistral': 2699, 'n_tokens_neox': 2647, 'n_words': 664}