<commit_before>'use strict';

var adapters = [
  ['http', 'http'],
  ['http', 'local'],
  ['local', 'http'],
  ['local', 'local']
];

if ('saucelabs' in testUtils.params()) {
  adapters = [['local', 'http'], ['http', 'local']];
}

adapters.forEach(function (adapters) {
  describe('test.issue3179.js-' + adapters[0] + '-' + adapters[1], function () {

    var dbs = {};

    beforeEach(function (done) {
      dbs.name = testUtils.adapterUrl(adapters[0], 'testdb');
      dbs.remote = testUtils.adapterUrl(adapters[1], 'test_repl_remote');
      testUtils.cleanup([dbs.name, dbs.remote], done);
    });

    after(function (done) {
      testUtils.cleanup([dbs.name, dbs.remote], done);
    });

    it('#3179 conflicts synced, non-live replication', function () {
      var local = new PouchDB(dbs.name);
      var remote = new PouchDB(dbs.remote);

      return local.put({ _id: '1'}).then(function () {
        return local.replicate.to(remote).then(function () {
          return remote.replicate.to(local);
        });
      }).then(function () {
        return local.get('1').then(function (doc) {
          doc.foo = Math.random();
          return local.put(doc);
        });
      }).then(function () {
        return remote.get('1').then(function (doc) {
          doc.foo = Math.random();
          return remote.put(doc);
        });
      }).then(function () {
        return local.replicate.to(remote).then(function () {
          return remote.replicate.to(local);
        });
      }).then(function () {
        return local.get('1', {conflicts: true}).then(function (doc) {
          return local.remove(doc._id, doc._conflicts[0]);
        });
      }).then(function () {
        return local.replicate.to(remote).then(function () {
          return remote.replicate.to(local);
        });
      }).then(function () {
        return local.get('1', {conflicts: true, revs: true});
      }).then(function (localDoc) {
        return remote.get('1', {
          conflicts: true,
          revs: true
        }).then(function (remoteDoc) {
          remoteDoc.should.deep.equal(localDoc);
        });
      });
    });

    it('#3179 conflicts synced, non-live sync', function () {
      var local = new PouchDB(dbs.name);
      var remote = new PouchDB(dbs.remote);

      return local.put({ _id: '1'}).then(function () {
        return local.sync(remote);
      }).then(function () {
        return local.get('1').then(function (doc) {
          doc.foo = Math.random();
          return local.put(doc);
        });
      }).then(function () {
        return remote.get('1').then(function (doc) {
          doc.foo = Math.random();
          return remote.put(doc);
        });
      }).then(function () {
        return local.sync(remote);
      }).then(function () {
        return local.get('1', {conflicts: true}).then(function (doc) {
          return local.remove(doc._id, doc._conflicts[0]);
        });
      }).then(function () {
        return local.sync(remote);
      }).then(function () {
        return local.get('1', {conflicts: true, revs: true});
      }).then(function (localDoc) {
        return remote.get('1', {
          conflicts: true,
          revs: true
        }).then(function (remoteDoc) {
          remoteDoc.should.deep.equal(localDoc);
        });
      });
    });

    it('#3179 conflicts synced, live sync', function () {
      var local = new PouchDB(dbs.name);
      var remote = new PouchDB(dbs.remote);

      var sync = local.sync(remote, { live: true });

      function waitForUptodate() {

        function defaultToEmpty(promise) {
          return promise.catch(function (err) {
            if (err.status !== 404) {
              throw err;
            }
            return {_revisions: []};
          });
        }

        return defaultToEmpty(local.get('1', {
          revs: true,
          conflicts: true
        })).then(function (localDoc) {
          return defaultToEmpty(remote.get('1', {
            revs: true,
            conflicts: true
          })).then(function (remoteDoc) {
            var revsEqual = JSON.stringify(localDoc._revisions) ===
              JSON.stringify(remoteDoc._revisions);
            var conflictsEqual = JSON.stringify(localDoc._conflicts || []) ===
              JSON.stringify(remoteDoc._conflicts || []);
            if (!revsEqual || !conflictsEqual) {
              return waitForUptodate();
            }
          });
        });
      }

      function delay() {
        // prove a negative
        return new PouchDB.utils.Promise(function (resolve) {
          setTimeout(resolve, 1000);
        });
      }

      function cleanup() {
        return new PouchDB.utils.Promise(function (resolve, reject) {
          sync.on('complete', resolve);
          sync.on('error', reject);
          sync.cancel();
          sync = null;
        });
      }

      return local.put({ _id: '1'}).then(function () {
        return waitForUptodate();
      }).then(function () {
        sync.cancel();
        return waitForUptodate();
      }).then(function () {
        return local.get('1').then(function (doc) {
          doc.foo = Math.random();
          return local.put(doc);
        });
      }).then(function () {
        return remote.get('1').then(function (doc) {
          doc.foo = Math.random();
          return remote.put(doc);
        });
      }).then(function () {
        sync = local.sync(remote, { live: true });
        return waitForUptodate();
      }).then(function () {
        return local.get('1', {conflicts: true}).then(function (doc) {
          return local.remove(doc._id, doc._conflicts[0]);
        });
      }).then(function () {
        return delay();
      }).then(function () {
        return local.get('1', {conflicts: true, revs: true});
      }).then(function (localDoc) {
        return remote.get('1', {
          conflicts: true,
          revs: true
        }).then(function (remoteDoc) {
          remoteDoc.should.deep.equal(localDoc);
        });
      }).then(function () {
        return cleanup();
      }, function (err) {
        return cleanup().then(function () {
          throw err;
        });
      });
    });

    it('#3179 conflicts synced, live repl', function () {
      var local = new PouchDB(dbs.name);
      var remote = new PouchDB(dbs.remote);

      var repl1 = local.replicate.to(remote, { live: true });
      var repl2 = local.replicate.from(remote, { live: true });

      function waitForUptodate() {

        function defaultToEmpty(promise) {
          return promise.catch(function (err) {
            if (err.status !== 404) {
              throw err;
            }
            return {_revisions: []};
          });
        }

        return defaultToEmpty(local.get('1', {
          revs: true,
          conflicts: true
        })).then(function (localDoc) {
          return defaultToEmpty(remote.get('1', {
            revs: true,
            conflicts: true
          })).then(function (remoteDoc) {
            var revsEqual = JSON.stringify(localDoc._revisions) ===
              JSON.stringify(remoteDoc._revisions);
            var conflictsEqual = JSON.stringify(localDoc._conflicts || []) ===
              JSON.stringify(remoteDoc._conflicts || []);
            if (!revsEqual || !conflictsEqual) {
              return waitForUptodate();
            }
          });
        });
      }

      function delay() {
        // prove a negative
        return new PouchDB.utils.Promise(function (resolve) {
          setTimeout(resolve, 1000);
        });
      }

      function cleanup() {
        return new PouchDB.utils.Promise(function (resolve, reject) {
          var numDone = 0;

          function checkDone() {
            if (++numDone === 2) {
              resolve();
            }
          }
          repl1.on('complete', checkDone);
          repl2.on('complete', checkDone);
          repl1.on('error', reject);
          repl2.on('error', reject);
          repl1.cancel();
          repl2.cancel();
          repl1 = null;
          repl2 = null;
        });
      }

      return local.put({ _id: '1'}).then(function () {
        return waitForUptodate();
      }).then(function () {
        repl1.cancel();
        repl2.cancel();
        return waitForUptodate();
      }).then(function () {
        return local.get('1').then(function (doc) {
          doc.foo = Math.random();
          return local.put(doc);
        });
      }).then(function () {
        return remote.get('1').then(function (doc) {
          doc.foo = Math.random();
          return remote.put(doc);
        });
      }).then(function () {
        repl1 = local.replicate.to(remote, { live: true });
        repl2 = local.replicate.from(remote, { live: true });
        return waitForUptodate();
      }).then(function () {
        return local.get('1', {conflicts: true}).then(function (doc) {
          return local.remove(doc._id, doc._conflicts[0]);
        });
      }).then(function () {
        return delay();<commit_msg>(#3983) - Avoid settimeout usage in tests<commit_after>'use strict';

var adapters = [
  ['http', 'http'],
  ['http', 'local'],
  ['local', 'http'],
  ['local', 'local']
];

if ('saucelabs' in testUtils.params()) {
  adapters = [['local', 'http'], ['http', 'local']];
}

adapters.forEach(function (adapters) {
  describe('test.issue3179.js-' + adapters[0] + '-' + adapters[1], function () {

    var dbs = {};

    beforeEach(function (done) {
      dbs.name = testUtils.adapterUrl(adapters[0], 'testdb');
      dbs.remote = testUtils.adapterUrl(adapters[1], 'test_repl_remote');
      testUtils.cleanup([dbs.name, dbs.remote], done);
    });

    after(function (done) {
      testUtils.cleanup([dbs.name, dbs.remote], done);
    });

    it('#3179 conflicts synced, non-live replication', function () {
      var local = new PouchDB(dbs.name);
      var remote = new PouchDB(dbs.remote);

      return local.put({ _id: '1'}).then(function () {
        return local.replicate.to(remote).then(function () {
          return remote.replicate.to(local);
        });
      }).then(function () {
        return local.get('1').then(function (doc) {
          doc.foo = Math.random();
          return local.put(doc);
        });
      }).then(function () {
        return remote.get('1').then(function (doc) {
          doc.foo = Math.random();
          return remote.put(doc);
        });
      }).then(function () {
        return local.replicate.to(remote).then(function () {
          return remote.replicate.to(local);
        });
      }).then(function () {
        return local.get('1', {conflicts: true}).then(function (doc) {
          return local.remove(doc._id, doc._conflicts[0]);
        });
      }).then(function () {
        return local.replicate.to(remote).then(function () {
          return remote.replicate.to(local);
        });
      }).then(function () {
        return local.get('1', {conflicts: true, revs: true});
      }).then(function (localDoc) {
        return remote.get('1', {
          conflicts: true,
          revs: true
        }).then(function (remoteDoc) {
          remoteDoc.should.deep.equal(localDoc);
        });
      });
    });

    it('#3179 conflicts synced, non-live sync', function () {
      var local = new PouchDB(dbs.name);
      var remote = new PouchDB(dbs.remote);

      return local.put({ _id: '1'}).then(function () {
        return local.sync(remote);
      }).then(function () {
        return local.get('1').then(function (doc) {
          doc.foo = Math.random();
          return local.put(doc);
        });
      }).then(function () {
        return remote.get('1').then(function (doc) {
          doc.foo = Math.random();
          return remote.put(doc);
        });
      }).then(function () {
        return local.sync(remote);
      }).then(function () {
        return local.get('1', {conflicts: true}).then(function (doc) {
          return local.remove(doc._id, doc._conflicts[0]);
        });
      }).then(function () {
        return local.sync(remote);
      }).then(function () {
        return local.get('1', {conflicts: true, revs: true});
      }).then(function (localDoc) {
        return remote.get('1', {
          conflicts: true,
          revs: true
        }).then(function (remoteDoc) {
          remoteDoc.should.deep.equal(localDoc);
        });
      });
    });

    it('#3179 conflicts synced, live sync', function () {
      var local = new PouchDB(dbs.name);
      var remote = new PouchDB(dbs.remote);

      var sync = local.sync(remote, { live: true });

      function waitForUptodate() {

        function defaultToEmpty(promise) {
          return promise.catch(function (err) {
            if (err.status !== 404) {
              throw err;
            }
            return {_revisions: []};
          });
        }

        return defaultToEmpty(local.get('1', {
          revs: true,
          conflicts: true
        })).then(function (localDoc) {
          return defaultToEmpty(remote.get('1', {
            revs: true,
            conflicts: true
          })).then(function (remoteDoc) {
            var revsEqual = JSON.stringify(localDoc._revisions) ===
              JSON.stringify(remoteDoc._revisions);
            var conflictsEqual = JSON.stringify(localDoc._conflicts || []) ===
              JSON.stringify(remoteDoc._conflicts || []);
            if (!revsEqual || !conflictsEqual) {
              return waitForUptodate();
            }
          });
        });
      }

      function waitForConflictsResolved() {
        return new PouchDB.utils.Promise(function (resolve, reject) {
          var changes = remote.changes({
            live: true,
            include_docs: true,
            conflicts: true
          }).on('change', function(change) {
            if (!('_conflicts' in change.doc)) {
              changes.cancel();
            }
          });
          changes.on('complete', resolve);
        });
      }

      function cleanup() {
        return new PouchDB.utils.Promise(function (resolve, reject) {
          sync.on('complete', resolve);
          sync.on('error', reject);
          sync.cancel();
          sync = null;
        });
      }

      return local.put({ _id: '1'}).then(function () {
        return waitForUptodate();
      }).then(function () {
        sync.cancel();
        return waitForUptodate();
      }).then(function () {
        return local.get('1').then(function (doc) {
          doc.foo = Math.random();
          return local.put(doc);
        });
      }).then(function () {
        return remote.get('1').then(function (doc) {
          doc.foo = Math.random();
          return remote.put(doc);
        });
      }).then(function () {
        sync = local.sync(remote, { live: true });
        return waitForUptodate();
      }).then(function () {
        return local.get('1', {conflicts: true}).then(function (doc) {
          return local.remove(doc._id, doc._conflicts[0]);
        });
      }).then(function (x) {
        return waitForConflictsResolved();
      }).then(function () {
        return local.get('1', {conflicts: true, revs: true});
      }).then(function (localDoc) {
        return remote.get('1', {
          conflicts: true,
          revs: true
        }).then(function (remoteDoc) {
          remoteDoc.should.deep.equal(localDoc);
        });
      }).then(function () {
        return cleanup();
      }, function (err) {
        return cleanup().then(function () {
          throw err;
        });
      });
    });

    it('#3179 conflicts synced, live repl', function () {
      var local = new PouchDB(dbs.name);
      var remote = new PouchDB(dbs.remote);

      var repl1 = local.replicate.to(remote, { live: true });
      var repl2 = local.replicate.from(remote, { live: true });

      function waitForConflictsResolved() {
        return new PouchDB.utils.Promise(function (resolve, reject) {
          var changes = remote.changes({
            live: true,
            include_docs: true,
            conflicts: true
          }).on('change', function(change) {
            if (!('_conflicts' in change.doc)) {
              changes.cancel();
            }
          });
          changes.on('complete', resolve);
        });
      }

      function waitForUptodate() {

        function defaultToEmpty(promise) {
          return promise.catch(function (err) {
            if (err.status !== 404) {
              throw err;
            }
            return {_revisions: []};
          });
        }

        return defaultToEmpty(local.get('1', {
          revs: true,
          conflicts: true
        })).then(function (localDoc) {
          return defaultToEmpty(remote.get('1', {
            revs: true,
            conflicts: true
          })).then(function (remoteDoc) {
            var revsEqual = JSON.stringify(localDoc._revisions) ===
              JSON.stringify(remoteDoc._revisions);
            var conflictsEqual = JSON.stringify(localDoc._conflicts || []) ===
              JSON.stringify(remoteDoc._conflicts || []);
            if (!revsEqual || !conflictsEqual) {
              return waitForUptodate();
            }
          });
        });
      }

      function cleanup() {
        return new PouchDB.utils.Promise(function (resolve, reject) {
          var numDone = 0;

          function checkDone() {
            if (++numDone === 2) {
              resolve();
            }
          }
          repl1.on('complete', checkDone);
          repl2.on('complete', checkDone);
          repl1.on('error', reject);
          repl2.on('error', reject);
          repl1.cancel();
          repl2.cancel();
          repl1 = null;
          repl2 = null;
        });
      }

      return local.put({ _id: '1'}).then(function () {
        return waitForUptodate();
      }).then(function () {
        repl1.cancel();
        repl2.cancel();
        return waitForUptodate();
      }).then(function () {
        return local.get('1').then(function (doc) {
          doc.foo = Math.random();
          return local.put(doc);
        });
      }).then(function () {
        return remote.get('1').then(function (doc) {
          doc.foo = Math.random();
          return remote.put(doc);
        });
      }).then(function () {
        repl1 = local.replicate.to(remote, { live: true });
        repl2 = local.replicate.from(remote, { live: true });
        return waitForUptodate();
      }).then(function () {
        return local.get('1', {conflicts: true}).then(function (doc) {
          return local.remove(doc._id, doc._conflicts[0]);
        });
      }).then(function() {
        return waitForConflictsResolved();
{'fraction_non_alphanumeric': 0.16051364365971107, 'fraction_numerical': 0.008774745853397539, 'mean_word_length': 1.8839685233760222, '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': '2630718', 'n_tokens_mistral': 5505, 'n_tokens_neox': 5384, 'n_words': 1045}