text:
const sinon = require('sinon');
const { assert, expect } = require('chai');
const q = require('q');
const Query = require('../../../lib/util/query');
const Batch = require('../../../lib/util/batch');

describe('lib/util/batch.js', function () {

  let batch, db;

  beforeEach(function () {
    db = {
      poolConfig: {},
      config: { parsedCqlVersion: { major: 3, minor: 1, patch: 0 } },
      param: function (value, hint) {
        return { value: value, hint: hint };
      },
      consistencyLevel: { // from helenus: cassandra_types.js
        one: 1,
        quorum: 2,
        localQuorum: 3,
        eachQuorum: 4,
        all: 5,
        any: 6,
        two: 7,
        three: 8
      }
    };
    batch = new Batch(db);
  });

  describe('interface', function () {

    it('is a constructor function', function () {
      assert.strictEqual(typeof Query, 'function', 'is a constructor function');
    });

    it('throws error if db not provided', function (done) {
      // act
      expect(function () { new Batch(); }).to.throw(Error);

      done();
    });
  });

  describe('constructed instance', function () {

    function validateFunctionExists(name, argCount) {
      // assert
      assert.strictEqual(typeof batch[name], 'function');
      assert.strictEqual(batch[name].length, argCount, `${name} takes ${argCount} arguments`);
    }

    it('provides an add function', function () {
      validateFunctionExists('add', 1);
    });

    it('provides an addQuery function', function () {
      validateFunctionExists('addQuery', 1);
    });

    it('provides an addBatch function', function () {
      validateFunctionExists('addBatch', 1);
    });

    it('provides a timestamp function', function () {
      validateFunctionExists('timestamp', 1);
    });

    it('provides a consistency function', function () {
      validateFunctionExists('consistency', 1);
    });

    it('provides an options function', function () {
      validateFunctionExists('options', 1);
    });

    it('provides an execute function', function () {
      validateFunctionExists('execute', 1);
    });

  });

  describe('#add()', function () {

    it('iterates an array', function () {
      // arrange
      const query1 = new Query(db);
      const query2 = new Query(db);
      const batch1 = new Batch(db);

      // act
      batch.add([query1, query2, batch1]);

      // assert
      assert.strictEqual(batch.context.queries.length, 3, 'queries are added to list');
      assert.strictEqual(batch.context.queries[0], query1, 'query1 is added to list');
      assert.strictEqual(batch.context.queries[1], query2, 'query2 is added to list');
      assert.strictEqual(batch.context.queries[2], batch1, 'batch1 is added to list of queries');
      assert.strictEqual(batch.context.errors.length, 0, 'no error is generated');
    });

    it('adds the query to the query list', function (done) {
      // arrange
      const query = new Query(db);

      // act
      batch.add(query);

      // assert
      assert.strictEqual(batch.context.queries.length, 1, 'query is added to list');
      assert.strictEqual(batch.context.queries[0], query, 'query is added to list');
      assert.strictEqual(batch.context.errors.length, 0, 'no error is generated');
      done();
    });

    it('adds the batch to the query list', function (done) {
      // arrange
      const newBatch = new Batch(db);

      // act
      batch.add(newBatch);

      // assert
      assert.strictEqual(batch.context.queries.length, 1, 'batch is added to list');
      assert.strictEqual(batch.context.queries[0], newBatch, 'batch is added to list of queries');
      assert.strictEqual(batch.context.errors.length, 0, 'no error is generated');
      done();
    });

    it('adds error if query is not a valid Query or Batch object', function (done) {
      // arrange
      const query = { cql: 'mySql', queryName: 'myQueryName' };

      // act
      batch.add(query);

      // assert
      assert.strictEqual(batch.context.queries.length, 0, 'query is NOT added to list');
      assert.strictEqual(batch.context.errors.length, 1, 'error is added to list');
      done();
    });

    it('does not add error if query is null', function (done) {
      // arrange
      const query = null;

      // act
      batch.add(query);

      // assert
      assert.strictEqual(batch.context.queries.length, 0, 'query is NOT added to list');
      assert.strictEqual(batch.context.errors.length, 0, 'no error is generated');
      done();
    });

    it('adds error if query is undefined', function (done) {
      // act
      batch.add();

      // assert
      assert.strictEqual(batch.context.queries.length, 0, 'query is NOT added to list');
      assert.strictEqual(batch.context.errors.length, 1, 'error is added to list');
      done();
    });

    it('returns self', function (done) {
      // arrange
      const query = new Query(db);

      // act
      const result = batch.add(query);

      // assert
      assert.equal(result, batch, 'returns self');
      done();
    });
  });

  describe('#addQuery()', function () {
    it('adds the query to the query list', function (done) {
      // arrange
      const query = new Query(db);

      // act
      batch.addQuery(query);

      // assert
      assert.strictEqual(batch.context.queries.length, 1, 'query is added to list');
      assert.strictEqual(batch.context.queries[0], query, 'query is added to list');
      assert.strictEqual(batch.context.errors.length, 0, 'no error is generated');
      done();
    });

    it('adds error if query is not a valid Query object', function (done) {
      // arrange
      const query = { cql: 'mySql', queryName: 'myQueryName' };

      // act
      batch.addQuery(query);

      // assert
      assert.strictEqual(batch.context.queries.length, 0, 'query is NOT added to list');
      assert.strictEqual(batch.context.errors.length, 1, 'error is added to list');
      done();
    });

    it('adds error if query is null', function (done) {
      // arrange
      const query = null;

      // act
      batch.addQuery(query);

      // assert
      assert.strictEqual(batch.context.queries.length, 0, 'query is NOT added to list');
      assert.strictEqual(batch.context.errors.length, 1, 'error is added to list');
      done();
    });

    it('returns self', function (done) {
      // arrange
      const query = new Query(db);

      // act
      const result = batch.addQuery(query);

      // assert
      assert.equal(result, batch, 'returns self');
      done();
    });
  });

  describe('#addBatch()', function () {
    it('adds the batch to the query list', function (done) {
      // arrange
      const newBatch = new Batch(db);

      // act
      batch.addBatch(newBatch);

      // assert
      assert.strictEqual(batch.context.queries.length, 1, 'batch is added to list');
      assert.strictEqual(batch.context.queries[0], newBatch, 'batch is added to list of queries');
      assert.strictEqual(batch.context.errors.length, 0, 'no error is generated');
      done();
    });

    it('adds error if the added batch contains the batch it is being added to', function (done) {
      // arrange
      const newBatch = new Batch(db);
      newBatch.addBatch(batch);

      // act
      batch.addBatch(newBatch);

      // assert
      assert.strictEqual(batch.context.queries.length, 0, 'batch is NOT added to list');
      assert.strictEqual(batch.context.errors.length, 1, 'error is added to list');
      done();
    });

    it('adds error if the added batch contains the batch it is being added to (nested)', function (done) {
      // arrange
      const newBatch1 = new Batch(db);
      const newBatch2 = new Batch(db);
      newBatch1.addBatch(newBatch2);
      newBatch2.addBatch(batch);

      // act
      batch.addBatch(newBatch1);

      // assert
      assert.strictEqual(batch.context.queries.length, 0, 'batch is NOT added to list');
      assert.strictEqual(batch.context.errors.length, 1, 'error is added to list');
      done();
    });

    it('adds error if the added batch is already in the tree', function (done) {
      // arrange
      const newBatch = new Batch(db);
      batch.addBatch(newBatch);

      // act
      batch.addBatch(newBatch);

      // assert
      assert.strictEqual(batch.context.queries.length, 1, 'batch is NOT added to list');
      assert.strictEqual(batch.context.errors.length, 1, 'error is added to list');
      done();
    });

    it('adds error if the added batch is already in the tree (nseted)', function (done) {
      // arrange
      const newBatch1 = new Batch(db);
      const newBatch2 = new Batch(db);
      newBatch1.addBatch(newBatch2);
      batch.addBatch(newBatch1);

      // act
      batch.addBatch(newBatch2);

      // assert
      assert.strictEqual(batch.context.queries.length, 1, 'batch is NOT added to list');
      assert.strictEqual(batch.context.errors.length, 1, 'error is added to list');
      done();
    });

    it('adds error if batch is not a valid Batch object', function (done) {
      // arrange
      const newBatch = { context: { queries: [] } };

      // act
      batch.addBatch(newBatch);

      // assert
      assert.strictEqual(batch.context.queries.length, 0, 'batch is NOT added to list');
      assert.strictEqual(batch.context.errors.length, 1, 'error is added to list');
      done();
    });

    it('adds error if batch is null', function (done) {
      // arrange
      const newBatch = null;

      // act
      batch.addQuery(newBatch);

      // assert
      assert.strictEqual(batch.context.queries.length, 0, 'batch is NOT added to list');
      assert.strictEqual(batch.context.errors.length, 1, 'error is added to list');
      done();
    });

    it('returns self', function (done) {
      // arrange
      const newBatch = new Batch(db);

      // act
      const result = batch.addBatch(newBatch);

      // assert
      assert.equal(result, batch, 'returns self');
      done();
    });
  });

  describe('#consistency()', function () {
    it('adds consistency level to the options context if valid consistency is given', function (done) {
      // arrange
      // act
      batch.consistency('one');

      // assert
      assert.strictEqual(batch.context.options.consistency, db.consistencyLevel.one, 'consistency is populated');
      done();
    });

    it('does not add consistency level to the options context if invalid consistency is given', function (done) {
      // arrange
      // act
      batch.consistency('someInvalidConsistency');

      // assert
      assert.notOk(batch.context.options.consistency, 'consistency is not populated');
      done();
    });

    it('returns self', function (done) {
      // arrange
      // act
      const result = batch.consistency('one');

      // assert
      assert.equal(result, batch, 'returns self');
      done();
    });
  });

  describe('#timestamp()', function () {
    it('adds timestamp to context if given', function (done) {
      // arrange
      const timestamp = 1234567;

      // act
      batch.timestamp(timestamp);

      // assert
      assert.strictEqual(batch.context.timestamp, timestamp, 'timestamp is populated');
      done();
    });

    it('adds default timestamp if not given', function (done) {
      // arrange
      // act
      batch.timestamp();

      // assert
      assert.ok(batch.context.timestamp, 'timestamp is populated');
      done();
    });

    it('returns self', function (done) {
      // arrange
      // act
      const result = batch.timestamp();

      // assert
      assert.equal(result, batch, 'returns self');
      done();
    });
  });

  describe('#options()', function () {
    it('extends the options context', function (done) {
      // arrange
      // act
      batch.options({ one: 'one' });
      batch.options({ two: 2 });

      // assert
      assert.deepEqual(batch.context.options, { one: 'one', two: 2 }, 'options is populated');
      done();
    });

    it('returns self', function (done) {
      // arrange
      // act
      const result = batch.options({ one: 'one' });

      // assert
      assert.equal(result, batch, 'returns self');
      done();
    });
  });

  describe('#type()', function () {
    it('defaults to standard', function (done) {
      // arrange
      // act
      // assert
      assert.strictEqual(batch.context.batchType, batch.batchType.standard, 'batch type should be standard');
      done();
    });

    it('changes the batch type if valid type given', function (done) {
      // arrange
      // act
      batch.type('unlogged');

      // assert
      assert.strictEqual(batch.context.batchType, batch.batchType.unlogged, 'batch type should be unlogged');
      done();
    });

    it('does not change the batch type if invalid type given', function (done) {
      // arrange
      // act
      batch.type('someInvalidBatchType');

      // assert
      assert.notOk(batch.context.options.batchType, 'batchType is not populated');
      done();
    });

    it('returns self', function (done) {
      // arrange
      // act
      const result = batch.type('counter');

      // assert
      assert.equal(result, batch, 'returns self');
      done();
    });
  });

  describe('#execute()', function () {

    beforeEach(function () {
      db.cql = sinon.stub().yields(null, [
        {}
      ]);
    });

    it('returns void if callback supplied', function (done) {
      // arrange
      const
        query1 = new Query(db),
        query2 = new Query(db);
      query1.context.cql = 'myCqlQuery1';
      query2.context.cql = 'myCqlQuery2';
      batch.context.queries = [query1, query2];

      // act
      const result = batch.execute(function () { });

      // assert
      assert.equal(result, void 0, 'returns void');
      done();
    });

    it('returns promise if callback not supplied', function (done) {
      // arrange
      const
        query1 = new Query(db),
        query2 = new Query(db);
      query1.context.cql = 'myCqlQuery1';
      query2.context.cql = 'myCqlQuery2';
      batch.context.queries = [query1, query2];

      // act
      const result = batch.execute({ one: 'one' });

      // assert
      assert.ok(q.isPromise(result), 'returns promise');
      done();
    });

    function testCallbacks(isPromise) {
      describe(isPromise ? 'with promise' : 'with callback', function () {

        it('yields [] if query list is not populated', function (done) {
          // arrange
          batch.context.queries = [];

          // act
          if (isPromise) {
            let e = null;
            batch
              .execute()
              .catch(function (error) {
                e = error;
              })
              .done(function (data) {
                asserts(e, data);
              });
          } else {
            batch.execute(asserts);
          }

          // assert
          function asserts(err, data) {
            expect(err).to.not.exist;
            expect(data).to.deep.equal([]);
            done();
          }
        });

        it('yields error if db yields error', function (done) {
          // arrange
          const
            query1 = new Query(db),
            query2 = new Query(db);
          query1.context.cql = 'myCqlQuery1';
          query2.context.cql = 'myCqlQuery2';
          batch.context.queries = [query1, query2];
          db.cql = sinon.stub().yields(new Error('Cassandra error'));

          // act
          if (isPromise) {
            let e = null;
            batch
              .execute()
              .catch(function (error) {
                e = error;
              })
              .done(function (data) {
                if (e) {
                  asserts(e);
                } else {
                  asserts(null, data);
                }
              });
          } else {
            batch.execute(asserts);
          }

          // assert
          function asserts(err, data) {
            assert.ok(err, 'error is populated');
            assert.notOk(data, 'data is not populated');
            done();
          }
        });

        it('yields multiple errors if triggered', function (done) {
          // arrange
          const
            query1 = new Query(db),
            query2 = { not: 'a query' };
          query1.context.cql = 'myCqlQuery1';
          db.cql = sinon.stub().yields(new Error('Cassandra error'));
          batch.addQuery(query1);
          batch.addQuery(query2); // fails

          // act
          if (isPromise) {
            let e = null;
            batch
              .execute()
              .catch(function (error) {
                e = error;
              })
              .done(function (data) {
                if (e) {
                  asserts(e);
                } else {
                  asserts(null, data);
                }
              });
          } else {
            batch.execute(asserts);
          }

          // assert
          function asserts(err, data) {
            assert.ok(err, 'error is populated');
            assert.ok(Array.isArray(err.inner), 'error inner array is populated');
            assert.strictEqual(err.inner.length, 2, 'error inner array is populated with 2 errors');
            assert.notOk(data, 'data is not populated');
            done();
          }
        });

        it('yields empty result set if no query text is available', function (done) {
          // arrange
          const data = [{}];
          const
            query1 = new Query(db),
            query2 = new Query(db);
          query1.context.cql = '';
          query2.context.cql = '';
          batch.context.queries = [query1, query2];
          db.cql = sinon.stub().yields(null, data);

          // act
          if (isPromise) {
            let e = null;
            batch
              .execute()
              .catch(function (error) {
                e = error;
              })
              .done(function (data) {
                if (e) {
                  asserts(e);
                } else {
                  asserts(null, data);
                }
              });
          } else {
            batch.execute(asserts);
          }

          // assert
          function asserts(err, data) {
            assert.notOk(err, 'error is not populated');
            assert.deepEqual(data, [], 'data is populated with empty array');
            done();
          }
        });

        it('yields data if db yields data', function (done) {
          // arrange
          const data = [{}];
          const
            query1 = new Query(db),
            query2 = new Query(db);
          query1.context.cql = 'myCqlQuery1';
          query2.context.cql = 'myCqlQuery2';
          batch.context.queries = [query1, query2];
          db.cql = sinon.stub().yields(null, data);

          // act
          if (isPromise) {
            let e = null;
            batch
              .execute()
              .catch(function (error) {
                e = error;
              })
              .done(function (data) {
                if (e) {
                  asserts(e);
                } else {
                  asserts(null, data);
                }
              });
          } else {
            batch.execute(asserts);
          }

          // assert
          function asserts(err, data) {
            assert.notOk(err, 'error is not populated');
            assert.equal(data, data, 'data is populated');
            done();
          }
        });

        it('joins queries correctly', function (done) {
          // arrange
          const data = [{}];
          const query1 = new Query(db)
              .query('myCqlQuery1')
              .consistency('localQuorum')
              .param('param1', 'ascii')
              .param('param2', 'ascii'),
            query2 = new Query(db)
              .query('myCqlQuery2;\n')
              .consistency('eachQuorum')
              .param('param3', 'ascii')
              .param('param4', 'ascii'),
            query3 = new Query(db)
              .query('myCqlQuery3')
              .options({ suppressDebugLog: true })
              .consistency('one')
              .param('param5', 'ascii')
              .param('param6', 'ascii');

          batch.context.queries = [query1, query2, query3];
          batch.timestamp(1234567);

          db.cql = sinon.stub().yields(null, data);

          // act
          if (isPromise) {
            let e = null;
            batch
              .execute()
              .catch(function (error) {
                e = error;
              })
              .done(function (data) {
                if (e) {
                  asserts(e);
                } else {
                  asserts(null, data);
                }
              });
          } else {
            batch.execute(asserts);
          }

          // assert
          function asserts(err, result) {
            assert.strictEqual(db.cql.callCount, 1, 'cql is only called once');
            const callArgs = db.cql.getCall(0).args;
            assert.strictEqual(callArgs[0], 'BEGIN BATCH\nUSING TIMESTAMP ?\nmyCqlQuery1;\nmyCqlQuery2;\nmyCqlQuery3;\nAPPLY BATCH;\n', 'Query text is joined');
            const queryParams = callArgs[1];
            assert.strictEqual(queryParams.length, 7, 'Query params are joined with timestamp');
            assert.strictEqual(callArgs[2].consistency, db.consistencyLevel.eachQuorum, 'Strictest consistency is set');
            assert.strictEqual(callArgs[2].suppressDebugLog, true, 'Debug log is suppressed');
            assert.notOk(err, 'error is not populated');
            assert.equal(data, result, 'result is populated');
            assert.equal(queryParams[0].value, 1234567, 'timestamp param is populated');
            for (let i = 1; i < queryParams.length; i++) {
              assert.equal(queryParams[i].value, `param${i}`, `query param ${i} is populated`);
            }
            done();
          }
        });

        it('can join a query with an empty batch', function (done) {
          // arrange
          const data = [{}];
          const query = new Query(db)
            .query('myCqlQuery1')
            .consistency('localQuorum')
            .param('param1', 'ascii')
            .param('param2', 'ascii');

          batch.add(query);
          batch.add(new Batch(db));
          batch.timestamp(1234567);

          db.cql = sinon.stub().yields(null, data);

          // act
          if (isPromise) {
            let e = null;
            batch
              .execute()
              .catch(function (error) {
                e = error;
              })
              .done(function (data) {
                if (e) {
                  asserts(e);
                } else {
                  asserts(null, data);
                }
              });
          } else {
            batch.execute(asserts);
          }

          // assert
          function asserts(err, result) {
            assert.strictEqual(db.cql.callCount, 1, 'cql is only called once');
            const callArgs = db.cql.getCall(0).args;
            assert.strictEqual(callArgs[0], 'BEGIN BATCH\nmyCqlQuery1\nUSING TIMESTAMP ?;\nAPPLY BATCH;\n', 'Query text is joined');
            const queryParams = callArgs[1];
            assert.strictEqual(queryParams.length, 3, 'Query params are joined with timestamp');
            assert.notOk(err, 'error is not populated');
            assert.equal(data, result, 'result is populated');
            assert.equal(queryParams[2].value, 1234567, 'timestamp param is populated');
            for (let i = 0; i < queryParams.length - 1; i++) {
              assert.equal(queryParams[i].value, `param${i + 1}`, `query param ${i + 1} is populated`);
            }
            done();
          }
        });

        it('can join a query with an empty query', function (done) {
          // arrange
          const data = [{}];
          const query = new Query(db)
            .query('myCqlQuery1')
            .consistency('localQuorum')
            .param('param1', 'ascii')
            .param('param2', 'ascii');

          batch.add(query);
          batch.add(new Query(db));
          batch.timestamp(1234567);

          db.cql = sinon.stub().yields(null, data);

          // act
          if (isPromise) {
            let e = null;
            batch
              .execute()
              .catch(function (error) {
                e = error;
              })
              .done(function (data) {
                if (e) {
                  asserts(e);
                } else {
                  asserts(null, data);
                }
              });
          } else {
            batch.execute(asserts);
          }

          // assert
          function asserts(err, result) {
            assert.strictEqual(db.cql.callCount, 1, 'cql is only called once');
            const callArgs = db.cql.getCall(0).args;
            assert.strictEqual(callArgs[0], 'BEGIN BATCH\nUSING TIMESTAMP ?\nmyCqlQuery1;\nAPPLY BATCH;\n', 'Query text is joined');
            const queryParams = callArgs[1];
            assert.strictEqual(queryParams.length, 3, 'Query params are joined with timestamp');
            assert.notOk(err, 'error is not populated');
            assert.equal(data, result, 'result is populated');
            assert.equal(queryParams[0].value, 1234567, 'timestamp param is populated');
            for (let i = 1; i < queryParams.length; i++) {
              assert.equal(queryParams[i].value, `param${i}`, `query param ${i} is populated`);
            }
            done();
          }
        });

        it('can join a query with an empty string query', function (done) {
          // arrange
          const data = [{}];
          const query = new Query(db)
            .query('myCqlQuery1')
            .consistency('localQuorum')
            .param('param1', 'ascii')
            .param('param2', 'ascii');

          batch.add(query);
          batch.add(new Query(db).query(''));
          batch.timestamp(1234567);

          db.cql = sinon.stub().yields(null, data);

          // act
          if (isPromise) {
            let e = null;
            batch
              .execute()
              .catch(function (error) {
                e = error;
              })
              .done(function (data) {
                if (e) {
                  asserts(e);
                } else {
                  asserts(null, data);
                }
              });
          } else {
            batch.execute(asserts);
          }

          // assert
          function asserts(err, result) {
            assert.strictEqual(db.cql.callCount, 1, 'cql is only called once');
            const callArgs = db.cql.getCall(0).args;
            assert.strictEqual(callArgs[0], 'BEGIN BATCH\nUSING TIMESTAMP ?\nmyCqlQuery1;\nAPPLY BATCH;\n', 'Query text is joined');
            const queryParams = callArgs[1];
            assert.strictEqual(queryParams.length, 3, 'Query params are joined with timestamp');
            assert.notOk(err, 'error is not populated');
            assert.equal(data, result, 'result is populated');
            assert.equal(queryParams[0].value, 1234567, 'timestamp param is populated');
            for (let i = 1; i < queryParams.length; i++) {
              assert.equal(queryParams[i].value, `param${i}`, `query param ${i} is populated`);
            }
            done();
          }
        });

        it('sets batch type appropriately', function (done) {
          // arrange
          const data = [{}];
          const query1 = new Query(db)
            .query('myCqlQuery1')
            .consistency('localQuorum')
            .param('param1', 'ascii')
            .param('param2', 'ascii');

          batch.context.queries = [query1];
          batch.type('counter');

          db.cql = sinon.stub().yields(null, data);

          // act
          if (isPromise) {
            let e = null;
            batch
              .execute()
              .catch(function (error) {
                e = error;
              })
              .done(function (data) {
                if (e) {
                  asserts(e);
                } else {
                  asserts(null, data);
                }
              });
          } else {
            batch.execute(asserts);
          }

          // assert
          function asserts(err, result) {
            assert.strictEqual(db.cql.callCount, 1, 'cql is only called once');
            const callArgs = db.cql.getCall(0).args;
            assert.strictEqual(callArgs[0], 'BEGIN COUNTER BATCH\nmyCqlQuery1;\nAPPLY BATCH;\n', 'Query text is joined');
            assert.notOk(err, 'error is not populated');
            assert.equal(result, data, 'result is populated');
            done();
          }
        });

        it('ignores bad batch types', function (done) {
          // arrange
          const data = [{}];
          const query1 = new Query(db)
            .query('myCqlQuery1')
            .consistency('localQuorum')
            .param('param1', 'ascii')
            .param('param2', 'ascii');

          batch.context.queries = [query1];
          batch.context.batchType = 123456789; // invalid

          db.cql = sinon.stub().yields(null, data);

          // act
          if (isPromise) {
            let e = null;
            batch
              .execute()
              .catch(function (error) {
                e = error;
              })
              .done(function (data) {
                if (e) {
                  asserts(e);
                } else {
                  asserts(null, data);
                }
              });
          } else {
            batch.execute(asserts);
          }

          // assert
          function asserts(err, result) {
            assert.strictEqual(db.cql.callCount, 1, 'cql is only called once');
            const callArgs = db.cql.getCall(0).args;
            assert.strictEqual(callArgs[0], 'BEGIN BATCH\nmyCqlQuery1;\nAPPLY BATCH;\n', 'Query text is joined');
            assert.notOk(err, 'error is not populated');
            assert.equal(result, data, 'result is populated');
            done();
          }
        });

        it('joins nested batches correctly', function (done) {
          // arrange
          const data = [{}];
          const query1 = new Query(db)
              .query('myCqlQuery1')
              .consistency('localQuorum')
              .param('param1', 'ascii')
              .param('param2', 'ascii'),
            query2 = new Query(db)
              .query('myCqlQuery2;\n')
              .consistency('eachQuorum')
              .param('param3', 'ascii')
              .param('param4', 'ascii'),
            query3 = new Query(db)
              .query('myCqlQuery3')
              .options({ suppressDebugLog: true })
              .consistency('one')
              .param('param5', 'ascii')
              .param('param6', 'ascii'),
            childBatch = new Batch(db);

          childBatch.addQuery(query2);
          childBatch.addQuery(query3);
          batch.addQuery(query1);
          batch.addBatch(childBatch);

          db.cql = sinon.stub().yields(null, data);

          // act
          if (isPromise) {
            let e = null;
            batch
              .execute()
              .catch(function (error) {
                e = error;
              })
              .done(function (data) {
                if (e) {
                  asserts(e);
                } else {
                  asserts(null, data);
                }
              });
          } else {
            batch.execute(asserts);
          }

          // assert
          function asserts(err, result) {
            assert.strictEqual(db.cql.callCount, 1, 'cql is only called once');
            const callArgs = db.cql.getCall(0).args;
            assert.strictEqual(callArgs[0], 'BEGIN BATCH\nmyCqlQuery1;\nmyCqlQuery2;\nmyCqlQuery3;\nAPPLY BATCH;\n', 'Query text is joined');
            const queryParams = callArgs[1];
            assert.strictEqual(queryParams.length, 6, 'Query params are joined');
            assert.strictEqual(callArgs[2].consistency, db.consistencyLevel.eachQuorum, 'Strictest consistency is set');
            assert.strictEqual(callArgs[2].suppressDebugLog, true, 'Debug log is suppressed');
            assert.notOk(err, 'error is not populated');
            assert.equal(result, data, 'result is populated');
            for (let i = 0; i < queryParams.length; i++) {
              const num = i + 1;
              assert.equal(queryParams[i].value, `param${num}`, `query param ${num} is populated`);
            }
            done();
          }
        });

        it('joins nested batches correctly through multiple levels', function (done) {
          // arrange
          const data = [{}];
          const query1 = new Query(db)
              .query('myCqlQuery1')
              .consistency('localQuorum')
              .param('param1', 'ascii')
              .param('param2', 'ascii'),
            query2 = new Query(db)
              .query('myCqlQuery2;\n')
              .consistency('eachQuorum')
              .param('param3', 'ascii')
              .param('param4', 'ascii'),
            query3 = new Query(db)
              .query('myCqlQuery3')
              .options({ suppressDebugLog: true })
              .consistency('one')
              .param('param5', 'ascii')
              .param('param6', 'ascii'),
            childBatch1 = new Batch(db),
            childBatch2 = new Batch(db);

          batch.addQuery(query1);
          batch.addBatch(childBatch1);
          childBatch1.addQuery(query2);
          childBatch1.addBatch(childBatch2);
          childBatch2.addQuery(query3);

          db.cql = sinon.stub().yields(null, data);

          // act
          if (isPromise) {
            let e = null;
            batch
              .execute()
              .catch(function (error) {
                e = error;
              })
              .done(function (data) {
                if (e) {
                  asserts(e);
                } else {
                  asserts(null, data);
                }
              });
          } else {
            batch.execute(asserts);
          }

          // assert
          function asserts(err, result) {
            assert.strictEqual(db.cql.callCount, 1, 'cql is only called once');
            const callArgs = db.cql.getCall(0).args;
            assert.strictEqual(callArgs[0], 'BEGIN BATCH\nmyCqlQuery1;\nmyCqlQuery2;\nmyCqlQuery3;\nAPPLY BATCH;\n', 'Query text is joined');
            const queryParams = callArgs[1];
            assert.strictEqual(queryParams.length, 6, 'Query params are joined');
            assert.strictEqual(callArgs[2].consistency, db.consistencyLevel.eachQuorum, 'Strictest consistency is set');
            assert.strictEqual(callArgs[2].suppressDebugLog, true, 'Debug log is suppressed');
            assert.notOk(err, 'error is not populated');
            assert.equal(result, data, 'result is populated');
            for (let i = 0; i < queryParams.length; i++) {
              const num = i + 1;
              assert.equal(queryParams[i].value, `param${num}`, `query param ${num} is populated`);
            }
            done();
          }
        });

        it('joins nested batches correctly with empty batches through multiple levels', function (done) {
          // arrange
          const data = [{}];
          const query1 = new Query(db)
              .query('myCqlQuery1')
              .consistency('localQuorum')
              .param('param1', 'ascii')
              .param('param2', 'ascii'),
            query2 = new Query(db)
              .query('myCqlQuery2;\n')
              .consistency('eachQuorum')
              .param('param3', 'ascii')
              .param('param4', 'ascii'),
            query3 = new Query(db)
              .query('myCqlQuery3')
              .options({ suppressDebugLog: true })
              .consistency('one')
              .param('param5', 'ascii')
              .param('param6', 'ascii'),
            childBatch1 = new Batch(db),
            childBatch2 = new Batch(db);

          batch.addQuery(query1);
          batch.addBatch(childBatch1);
          batch.addBatch(new Batch(db));
          childBatch1.addBatch(new Batch(db));
          childBatch1.addQuery(query2);
          childBatch1.addBatch(childBatch2);
          childBatch2.addQuery(query3);

          db.cql = sinon.stub().yields(null, data);

          // act
          if (isPromise) {
            let e = null;
            batch
              .execute()
              .catch(function (error) {
                e = error;
              })
              .done(function (data) {
                if (e) {
                  asserts(e);
                } else {
                  asserts(null, data);
                }
              });
          } else {
            batch.execute(asserts);
          }

          // assert
          function asserts(err, result) {
            assert.strictEqual(db.cql.callCount, 1, 'cql is only called once');
            const callArgs = db.cql.getCall(0).args;
            assert.strictEqual(callArgs[0], 'BEGIN BATCH\nmyCqlQuery1;\nmyCqlQuery2;\nmyCqlQuery3;\nAPPLY BATCH;\n', 'Query text is joined');
            const queryParams = callArgs[1];
            assert.strictEqual(queryParams.length, 6, 'Query params are joined');
            assert.strictEqual(callArgs[2].consistency, db.consistencyLevel.eachQuorum, 'Strictest consistency is set');
            assert.strictEqual(callArgs[2].suppressDebugLog, true, 'Debug log is suppressed');
            assert.notOk(err, 'error is not populated');
            assert.equal(result, data, 'result is populated');
            for (let i = 0; i < queryParams.length; i++) {
              const num = i + 1;
              assert.equal(queryParams[i].value, `param${num}`, `query param ${num} is populated`);
            }
            done();
          }
        });

        it('joins empty nested batches correctly through multiple levels', function (done) {
          // arrange
          const data = [{}];
          const query1 = new Query(db)
              .query('')
              .consistency('localQuorum')
              .param('param1', 'ascii')
              .param('param2', 'ascii'),
            query2 = new Query(db)
              .query('')
              .consistency('eachQuorum')
              .param('param3', 'ascii')
              .param('param4', 'ascii'),
            query3 = new Query(db)
              .query('')
              .options({ suppressDebugLog: true })
              .consistency('one')
              .param('param5', 'ascii')
              .param('param6', 'ascii'),
            childBatch1 = new Batch(db),
            childBatch2 = new Batch(db);

          batch.addQuery(query1);
          batch.addBatch(childBatch2);
          childBatch1.addQuery(query2);
          childBatch1.addQuery(query3);
          childBatch2.addBatch(childBatch1);

          db.cql = sinon.stub().yields(null, data);

          // act
          if (isPromise) {
            let e = null;
            batch
              .execute()
              .catch(function (error) {
                e = error;
              })
              .done(function (data) {
                if (e) {
                  asserts(e);
                } else {
                  asserts(null, data);
                }
              });
          } else {
            batch.execute(asserts);
          }

          // assert
          function asserts(err, result) {
            assert.notOk(db.cql.called, 'cql is NOT called');
            assert.notOk(err, 'error is not populated');
            assert.deepEqual(result, [], 'result is populated with empty array');
            done();
          }
        });

        it('joins nested batches correctly when the parent has a timestamp and child does not', function (done) {
          // arrange
          const data = [{}];
          const query1 = new Query(db)
              .query('myCqlQuery1')
              .consistency('localQuorum')
              .param('param1', 'ascii')
              .param('param2', 'ascii'),
            query2 = new Query(db)
              .query('myCqlQuery2;\n')
              .consistency('eachQuorum')
              .param('param3', 'ascii')
              .param('param4', 'ascii'),
            query3 = new Query(db)
              .query('myCqlQuery3')
              .options({ suppressDebugLog: true })
              .consistency('one')
              .param('param5', 'ascii')
              .param('param6', 'ascii'),
            childBatch = new Batch(db);

          childBatch.addQuery(query2);
          childBatch.addQuery(query3);
          batch.addQuery(query1);
          batch.addBatch(childBatch);
          batch.timestamp(1234567);

          db.cql = sinon.stub().yields(null, data);

          // act
          if (isPromise) {
            let e = null;
            batch
              .execute()
              .catch(function (error) {
                e = error;
              })
              .done(function (data) {
                if (e) {
                  asserts(e);
                } else {
                  asserts(null, data);
                }
              });
          } else {
            batch.execute(asserts);
          }

          // assert
          function asserts(err, data) {
            assert.strictEqual(db.cql.callCount, 1, 'cql is only called once');
            const callArgs = db.cql.getCall(0).args;
            assert.strictEqual(callArgs[0], 'BEGIN BATCH\nmyCqlQuery1\nUSING TIMESTAMP ?;\nmyCqlQuery2\nUSING TIMESTAMP ?;\nmyCqlQuery3\nUSING TIMESTAMP ?;\nAPPLY BATCH;\n', 'Query text is joined');
            const queryParams = callArgs[1];
            assert.strictEqual(queryParams.length, 9, 'Query params are joined with timestamps');
            assert.strictEqual(callArgs[2].consistency, db.consistencyLevel.eachQuorum, 'Strictest consistency is set');
            assert.strictEqual(callArgs[2].suppressDebugLog, true, 'Debug log is suppressed');
            assert.notOk(err, 'error is not populated');
            assert.equal(data, data, 'data is populated');
            assert.equal(queryParams[0].value, 'param1', 'query param 1 is populated');
            assert.equal(queryParams[1].value, 'param2', 'query param 2 is populated');
            assert.equal(queryParams[2].value, 1234567, 'query timestamp 1 is populated');
            assert.equal(queryParams[3].value, 'param3', 'query param 3 is populated');
            assert.equal(queryParams[4].value, 'param4', 'query param 4 is populated');
            assert.equal(queryParams[5].value, 1234568, 'query timestamp 2 is populated');
            assert.equal(queryParams[6].value, 'param5', 'query param 5 is populated');
            assert.equal(queryParams[7].value, 'param6', 'query param 6 is populated');
            assert.equal(queryParams[8].value, 1234568, 'query timestamp 3 is populated');
            done();
          }
        });

        it('sets nested batch timestamps correctly', function (done) {
          // arrange
          const data = [{}];
          const query1 = new Query(db)
              .query('myCqlQuery1')
              .consistency('localQuorum')
              .param('param1', 'ascii')
              .param('param2', 'ascii'),
            query2 = new Query(db)
              .query('myCqlQuery2;\n')
              .consistency('eachQuorum')
              .param('param3', 'ascii')
              .param('param4', 'ascii'),
            query3 = new Query(db)
              .query('myCqlQuery3')
              .options({ suppressDebugLog: true })
              .consistency('one')
              .param('param5', 'ascii')
              .param('param6', 'ascii'),
            childBatch = new Batch(db);

          childBatch.addQuery(query2);
          childBatch.addQuery(query3);
          childBatch.timestamp(1234567);
          batch.addQuery(query1);
          batch.addBatch(childBatch);
          batch.timestamp(7654321);

          db.cql = sinon.stub().yields(null, data);

          // act
          if (isPromise) {
            let e = null;
            batch
              .execute()
              .catch(function (error) {
                e = error;
              })
              .done(function (data) {
                if (e) {
                  asserts(e);
                } else {
                  asserts(null, data);
                }
              });
          } else {
            batch.execute(asserts);
          }

          // assert
          function asserts(err, result) {
            assert.strictEqual(db.cql.callCount, 1, 'cql is only called once');
            const callArgs = db.cql.getCall(0).args;
            assert.strictEqual(callArgs[0], 'BEGIN BATCH\nmyCqlQuery1\nUSING TIMESTAMP ?;\nmyCqlQuery2\nUSING TIMESTAMP ?;\nmyCqlQuery3\nUSING TIMESTAMP ?;\nAPPLY BATCH;\n', 'Query text is joined');
            const queryParams = callArgs[1];
            assert.strictEqual(queryParams.length, 9, 'Query params are joined with timestamps');
            assert.strictEqual(callArgs[2].consistency, db.consistencyLevel.eachQuorum, 'Strictest consistency is set');
            assert.strictEqual(callArgs[2].suppressDebugLog, true, 'Debug log is suppressed');
            assert.notOk(err, 'error is not populated');
            assert.equal(result, data, 'result is populated');
            assert.equal(queryParams[0].value, 'param1', 'query param 1 is populated');
            assert.equal(queryParams[1].value, 'param2', 'query param 2 is populated');
            assert.equal(queryParams[2].value, 7654321, 'query timestamp 1 is populated');
            assert.equal(queryParams[3].value, 'param3', 'query param 3 is populated');
            assert.equal(queryParams[4].value, 'param4', 'query param 4 is populated');
            assert.equal(queryParams[5].value, 1234567, 'query timestamp 2 is populated');
            assert.equal(queryParams[6].value, 'param5', 'query param 5 is populated');
            assert.equal(queryParams[7].value, 'param6', 'query param 6 is populated');
            assert.equal(queryParams[8].value, 1234567, 'query timestamp 3 is populated');
            done();
          }
        });

        it('sets nested batch timestamps correctly for CQL versions that don\'t support DML timestamps inside of a batch', function (done) {
          // arrange
          const data = [{}];
          const query1 = new Query(db)
              .query('myCqlQuery1')
              .consistency('localQuorum')
              .param('param1', 'ascii')
              .param('param2', 'ascii'),
            query2 = new Query(db)
              .query('myCqlQuery2;\n')
              .consistency('eachQuorum')
              .param('param3', 'ascii')
              .param('param4', 'ascii'),
            query3 = new Query(db)
              .query('myCqlQuery3')
              .options({ suppressDebugLog: true })
              .consistency('one')
              .param('param5', 'ascii')
              .param('param6', 'ascii'),
            childBatch = new Batch(db);

          childBatch.addQuery(query2);
          childBatch.addQuery(query3);
          childBatch.timestamp(1234567);
          batch.addQuery(query1);
          batch.addBatch(childBatch);
          batch.timestamp(7654321);

          db.config.parsedCqlVersion = { major: 3, minor: 0, patch: 0 };
          db.cql = sinon.stub().yields(null, data);

          // act
          if (isPromise) {
            let e = null;
            batch
              .execute()
              .catch(function (error) {
                e = error;
              })
              .done(function (data) {
                if (e) {
                  asserts(e);
                } else {
                  asserts(null, data);
                }
              });
          } else {
            batch.execute(asserts);
          }

          // assert
          function asserts(err, result) {
            assert.strictEqual(db.cql.callCount, 1, 'cql is only called once');
            const callArgs = db.cql.getCall(0).args;
            assert.strictEqual(callArgs[0], 'BEGIN BATCH\nUSING TIMESTAMP ?\nmyCqlQuery1;\nmyCqlQuery2;\nmyCqlQuery3;\nAPPLY BATCH;\n', 'Query text is joined');
            const queryParams = callArgs[1];
            assert.strictEqual(queryParams.length, 7, 'Query params are joined with timestamps');
            assert.strictEqual(callArgs[2].consistency, db.consistencyLevel.eachQuorum, 'Strictest consistency is set');
            assert.strictEqual(callArgs[2].suppressDebugLog, true, 'Debug log is suppressed');
            assert.notOk(err, 'error is not populated');
            assert.equal(result, data, 'result is populated');
            assert.equal(queryParams[0].value, 7654321, 'query timestamp is populated');
            assert.equal(queryParams[1].value, 'param1', 'query param 1 is populated');
            assert.equal(queryParams[2].value, 'param2', 'query param 2 is populated');
            assert.equal(queryParams[3].value, 'param3', 'query param 3 is populated');
            assert.equal(queryParams[4].value, 'param4', 'query param 4 is populated');
            assert.equal(queryParams[5].value, 'param5', 'query param 5 is populated');
            assert.equal(queryParams[6].value, 'param6', 'query param 6 is populated');
            done();
          }
        });

        it('sets nested batch timestamps correctly for queries that don\'t support DML timestamps inside of a batch', function (done) {
          // arrange
          const data = [{}];
          const query1 = new Query(db)
              .query('myCqlQuery1')
              .consistency('localQuorum')
              .param('param1', 'ascii')
              .param('param2', 'ascii'),
            query2 = new Query(db)
              .query('UPDATE something;\n')
              .consistency('eachQuorum')
              .param('param3', 'ascii')
              .param('param4', 'ascii'),
            query3 = new Query(db)
              .query('myCqlQuery3')
              .options({ suppressDebugLog: true })
              .consistency('one')
              .param('param5', 'ascii')
              .param('param6', 'ascii'),
            childBatch = new Batch(db);

          childBatch.addQuery(query2);
          childBatch.addQuery(query3);
          childBatch.timestamp(1234567);
          batch.addQuery(query1);
          batch.addBatch(childBatch);
          batch.timestamp(7654321);

          db.cql = sinon.stub().yields(null, data);

          // act
          if (isPromise) {
            let e = null;
            batch
              .execute()
              .catch(function (error) {
                e = error;
              })
              .done(function (data) {
                if (e) {
                  asserts(e);
                } else {
                  asserts(null, data);
                }
              });
          } else {
            batch.execute(asserts);
          }

          // assert
          function asserts(err, result) {
            assert.strictEqual(db.cql.callCount, 1, 'cql is only called once');
            const callArgs = db.cql.getCall(0).args;
            assert.strictEqual(callArgs[0], 'BEGIN BATCH\nUSING TIMESTAMP ?\nmyCqlQuery1;\nUPDATE something;\nmyCqlQuery3;\nAPPLY BATCH;\n', 'Query text is joined');
            const queryParams = callArgs[1];
            assert.strictEqual(queryParams.length, 7, 'Query params are joined with timestamps');
            assert.strictEqual(callArgs[2].consistency, db.consistencyLevel.eachQuorum, 'Strictest consistency is set');
            assert.strictEqual(callArgs[2].suppressDebugLog, true, 'Debug log is suppressed');
            assert.notOk(err, 'error is not populated');
            assert.equal(result, data, 'result is populated');
            assert.equal(queryParams[0].value, 7654321, 'query timestamp is populated');
            assert.equal(queryParams[1].value, 'param1', 'query param 1 is populated');
            assert.equal(queryParams[2].value, 'param2', 'query param 2 is populated');
            assert.equal(queryParams[3].value, 'param3', 'query param 3 is populated');
            assert.equal(queryParams[4].value, 'param4', 'query param 4 is populated');
            assert.equal(queryParams[5].value, 'param5', 'query param 5 is populated');
            assert.equal(queryParams[6].value, 'param6', 'query param 6 is populated');
            done();
          }
        });

        it('sets nested batch timestamps correctly for child batches that don\'t support DML timestamps inside of a batch', function (done) {
          // arrange
          const data = [{}];
          const query1 = new Query(db)
              .query('myCqlQuery1')
              .consistency('localQuorum')
              .param('param1', 'ascii')
              .param('param2', 'ascii'),
            insertQuery1 = new Query(db)
              .query('INSERT something;\n')
              .consistency('eachQuorum')
              .param('param3', 'ascii')
              .param('param4', 'ascii'),
            deleteQuery = new Query(db)
              .query('DELETE something;\n')
              .consistency('eachQuorum')
              .param('param5', 'ascii')
              .param('param6', 'ascii'),
            insertQuery2 = new Query(db)
              .query('INSERT something;\n')
              .consistency('eachQuorum')
              .param('param7', 'ascii')
              .param('param8', 'ascii'),
            query3 = new Query(db)
              .query('myCqlQuery3')
              .options({ suppressDebugLog: true })
              .consistency('one')
              .param('param9', 'ascii')
              .param('param10', 'ascii'),
            childBatch = new Batch(db);

          childBatch.addQuery(insertQuery1);
          childBatch.addQuery(deleteQuery);
          childBatch.addQuery(insertQuery2);
          childBatch.timestamp(1234567);
          batch.addQuery(query1);
          batch.addBatch(childBatch);
          batch.addQuery(query3);
          batch.timestamp(7654321);

          db.cql = sinon.stub().yields(null, data);

          // act
          if (isPromise) {
            let e = null;
            batch
              .execute()
              .catch(function (error) {
                e = error;
              })
              .done(function (data) {
                if (e) {
                  asserts(e);
                } else {
                  asserts(null, data);
                }
              });
          } else {
            batch.execute(asserts);
          }

          // assert
          function asserts(err, result) {
            assert.strictEqual(db.cql.callCount, 1, 'cql is only called once');
            const callArgs = db.cql.getCall(0).args;
            assert.strictEqual(callArgs[0], 'BEGIN BATCH\nUSING TIMESTAMP ?\nmyCqlQuery1;\nINSERT something;\nDELETE something;\nINSERT something;\nmyCqlQuery3;\nAPPLY BATCH;\n', 'Query text is joined');
            const queryParams = callArgs[1];
            assert.strictEqual(queryParams.length, 11, 'Query params are joined with timestamps');
            assert.strictEqual(callArgs[2].consistency, db.consistencyLevel.eachQuorum, 'Strictest consistency is set');
            assert.strictEqual(callArgs[2].suppressDebugLog, true, 'Debug log is suppressed');
            assert.notOk(err, 'error is not populated');
            assert.equal(result, data, 'result is populated');
            assert.equal(queryParams[0].value, 7654321, 'query timestamp is populated');
            assert.equal(queryParams[1].value, 'param1', 'query param 1 is populated');
            assert.equal(queryParams[2].value, 'param2', 'query param 2 is populated');
            assert.equal(queryParams[3].value, 'param3', 'query param 3 is populated');
            assert.equal(queryParams[4].value, 'param4', 'query param 4 is populated');
            assert.equal(queryParams[5].value, 'param5', 'query param 5 is populated');
            assert.equal(queryParams[6].value, 'param6', 'query param 6 is populated');
            assert.equal(queryParams[7].value, 'param7', 'query param 7 is populated');
            assert.equal(queryParams[8].value, 'param8', 'query param 8 is populated');
            assert.equal(queryParams[9].value, 'param9', 'query param 9 is populated');
            assert.equal(queryParams[10].value, 'param10', 'query param 10 is populated');
            done();
          }
        });
      });
    }

    testCallbacks(false);
    testCallbacks(true);

    describe('sets timestamp to current time', function () {
      let clock;
      beforeEach(function () {
        clock = this.clock = sinon.useFakeTimers();
      });

      afterEach(function () {
        clock.restore();
      });

      // NOTE: Fake timers break Promises, so can only test coverage on this for standard execute.

      it('and propagates to child batches appropriately', function (done) {
        // arrange
        const data = [{}];
        clock.tick(123456789);
        const nowTs = (Date.now() * 1000);
        const query1 = new Query(db)
            .query('myCqlQuery1')
            .consistency('localQuorum')
            .param('param1', 'ascii')
            .param('param2', 'ascii'),
          query2 = new Query(db)
            .query('myCqlQuery2;\n')
            .consistency('eachQuorum')
            .param('param3', 'ascii')
            .param('param4', 'ascii'),
          query3 = new Query(db)
            .query('myCqlQuery3')
            .options({ suppressDebugLog: true })
            .consistency('one')
            .param('param5', 'ascii')
            .param('param6', 'ascii'),
          childBatch = new Batch(db);

        childBatch.addQuery(query3);
        childBatch.timestamp();
        batch.addQuery(query1);
        batch.addQuery(query2);
        batch.addBatch(childBatch);
        batch.timestamp();

        db.cql = sinon.stub().yields(null, data);

        // act
        batch.execute(asserts);

        // assert
        function asserts(err, data) {
          assert.strictEqual(db.cql.callCount, 1, 'cql is only called once');
          const callArgs = db.cql.getCall(0).args;
          assert.strictEqual(callArgs[0], 'BEGIN BATCH\nmyCqlQuery1\nUSING TIMESTAMP ?;\nmyCqlQuery2\nUSING TIMESTAMP ?;\nmyCqlQuery3\nUSING TIMESTAMP ?;\nAPPLY BATCH;\n', 'Query text is joined');
          const queryParams = callArgs[1];
          assert.strictEqual(queryParams.length, 9, 'Query params are joined with timestamps');
          assert.strictEqual(callArgs[2].consistency, db.consistencyLevel.eachQuorum, 'Strictest consistency is set');
          assert.strictEqual(callArgs[2].suppressDebugLog, true, 'Debug log is suppressed');
          assert.notOk(err, 'error is not populated');
          assert.equal(data, data, 'data is populated');
          assert.equal(queryParams[0].value, 'param1', 'query param 1 is populated');
          assert.equal(queryParams[1].value, 'param2', 'query param 2 is populated');
          assert.equal(queryParams[2].value, nowTs, 'query timestamp 1 is populated');
          assert.equal(queryParams[3].value, 'param3', 'query param 3 is populated');
          assert.equal(queryParams[4].value, 'param4', 'query param 4 is populated');
          assert.equal(queryParams[5].value, nowTs, 'query timestamp 2 is populated');
          assert.equal(queryParams[6].value, 'param5', 'query param 5 is populated');
          assert.equal(queryParams[7].value, 'param6', 'query param 6 is populated');
          assert.equal(queryParams[8].value, nowTs + 1, 'query timestamp 3 is populated');
          done();
        }
      });
    });

  });
});


The European Commission is launching a major public consultation – the Next Generation Internet Initiative – to find out what concerns and hopes EU citizens have about the future of the internet.
After high-profile data leaks and reports of major organisations falling prey to cyber-attacks, the fear surrounding internet privacy and security is on the rise.
The European Commission is composed of 28 senior members, with one appointed from each member state of the EU. The survey aims to give European policymakers a comprehensive idea of public priorities. This could be a smart move, given that the commission is frequently attacked for not being directly elected and for being detached from popular attitudes and concerns.
The consultation comprises of a succession of surveys which ask participants about how they think the internet should be governed. Questions cover a range of subjects including net neutrality, privacy, security, blockchain, public understanding of new technology and the impact of the internet on day-to-day life.
It also covers some prickly issues for legislators, such as the rapid expansion of sharing economy platforms like Uber and Airbnb. Uber, for instance, is already facing a European Court of Justice ruling that could result in the company operating under tougher regulations.
In Juncker's state of the union speech last September, he called for every town and village to have free Wi-Fi by 2020 - an ambitious target. The European Commission has also urged the telecoms industry to upgrade internet speeds across the continent and the EU's regulatory powers extend to guaranteeing 'net neutrality'; ensuring all data on the internet is treated equally. As emerging technologies – such as driverless cars – become commercially available and widespread, EU officials will need to start thinking about how they will be regulated.
The results of the consultation will be compiled in June and will be used to inform supranational internet and technology policies.
The project is being led by REIsearch, a non-profit initiative co-funded by the European Commission. Various newspapers and other publications across Europe are involved in promoting the consultation, including The Lancet, Cell, and the Guardian.


text:
/**
 * Created by Peter on 27.01.2015.
 */
var loc1 = {
    description: "Густий ліс, дорога прямує із півдня на північ.",
    event: "Посеред дороги стоїть розбійник з іржавою шабелю у руці.",
    eventCheck1: true,
    encounter1: {
        enemies1Name: enemy_1,
        enemies1Quantity: 5
    },
    setActions: function() {
        if (loc1.eventCheck1 == true) {
            document.getElementById("event_field").innerHTML = loc1.event;
            changeActionList("Оглянути розбійника,loc1.examineBandit1()",
                "Залякати розбійника,loc1.intimidateBandit1()",
                "Розпочати бій,loc1.attackBandit1()",
                "Втекти від розбійника,loc1.escapeBandit1()");
        } else {
            document.getElementById("event_field").innerHTML = " ";
            changeActionList("Іти на північ,loc1.goNorth()", "Іти на південь,loc1.goSouth()");
        }},
    examineBandit1: function() {
        var result1 = "Важко оцінити розбійника, проте він здається небезпечним.";
        var result2_1 = "слабший, ";
        var result2_2 = "сильніший, ";
        var result3_1 = "повільніший, ";
        var result3_2 = "швидший, ";
        var result4_1 = "менш досвідчений.";
        var result4_2 = "більш досвідчений.";
        var resultField = document.getElementById("result_field");
        if (hero.intelligence < 15) {
            resultField.innerHTML = result1;
        }
        else {
            resultField.innerHTML = "Розбійник ";
            if (hero.strength > bandit1.strength) {
                resultField.innerHTML += result2_1;
            }
            else {
                resultField.innerHTML += result2_2;
            }
            if (hero.speed > bandit1.speed) {
                resultField.innerHTML += result3_1;
            }
            else {
                resultField.innerHTML += result3_2;
            }
            if (hero.level > bandit1.level) {
                resultField.innerHTML += result4_1;
            }
            else {
                resultField.innerHTML += result4_2;
            }
        }
    },
    intimidateBandit1: function() {
        var result1 = "Розбійник розсміявся та сплюнув на дорогу.";
        var result2 = "Розбійник зблід та швидко зник у лісі.";
        if (hero.level < bandit1.level) {
            document.getElementById("result_field").innerHTML = result1;
        }
        else {
            document.getElementById("result_field").innerHTML = result2;
            document.getElementById("event_field").innerHTML = " ";
            bandit1.present = false;
            loc1.eventCheck1 = false;
            changeLocation(loc1);
        }
    },

    attackBandit1: function() {
        heroAttack(bandit1, loc1);
    },

    escapeBandit1: function() {
        var result1 = "Ви спробували втекти, проте розбіник швидко наздогнав вас.";
        var result2 = "Ви дуже швидкі, і дуже скоро робійник залишився далеко позаду десь посеред лісу.";
        if (hero.constitution < bandit1.constitution) {
            document.getElementById("result_field").innerHTML = result1;
        }
        else {
            document.getElementById("result_field").innerHTML = result2;
            changeLocation(loc4);
        }
    },
    goSouth: function() {
            changeLocation(loc2);
    },
    goNorth: function() {
            changeLocation(loc3);
    }
};
var loc2 = {
    description: "Дерева тут маленькі та криві, здається ліс не дуже хоче рости у цій місцевості. На півдні дорога добігає до краю великого каньону та обривається. Багато років потому тут був міст, проте зараз про той міст нагадують лише кам'яні уламки даелко внизу." +
    "На північ дорога поринає глибоко в ліс, та ще є маленька стежка поміж деревами, що прямує на захід.",
    eventCheck1: false,
    setActions: function() {
        if (loc4.eventCheck1 == true) {
        } else  {
            document.getElementById("event_field").innerHTML = " ";
            changeActionList("Іти західною стежкою,loc2.goWest()", "Іти на північ,loc2.goNorth()");
        }
    },
    goWest: function() {
        changeLocation(loc4);
    },
    goNorth: function() {
        changeLocation(loc1);
    }
};
var loc3 = {
    description: "З обох боків дороги ростуть могутні дерева. На півночі понад найвишими деревами видно велику башту. На захід від дороги віддідяється стара дорога, що заросла густою травою.",
    eventCheck1: false,
    setActions: function() {
        if (loc4.eventCheck1 == true) {
        } else  {
            document.getElementById("event_field").innerHTML = " ";
            changeActionList("Іти на північ,loc3.goNorth()", "Іти на південь,loc3.goSouth()", "Іти на захід,loc3.goWest()");
        }
    },
    goNorth: function() {
        changeLocation(loc5);
    },
    goSouth: function() {
        changeLocation(loc1);
    },
    goWest: function() {
        changeLocation(loc6);
    }
};
var loc4 = {
    description: "Схил пагорба, що порос густи лісом. Дерева дуже високі, неба майже не видно. Поміж деревами в'ється стежка. У східному напрямку вона спускається з пагорба, а на північ піднімається на його вершину.",
    eventCheck1: false,
    setActions: function() {
        if (loc4.eventCheck1 == true) {
        } else  {
            document.getElementById("event_field").innerHTML = " ";
            changeActionList("Піднятися схилом,loc4.goUphill()", "Спуститися схилом,loc4.goDownhill()");
        }
    },
    goUphill: function() {
        changeLocation(loc6);
    },
    goDownhill: function() {
        changeLocation(loc2);
    }
};
var loc5 = {
    description: "Посеред лісу стоїть старий замок. Десь на заході та південніше посеред лісу встає великий пагорб. Ворота замка закриті, дорога від цих воріт уходить на південь. Серед дерев, що впритул підступили до стін замку, видно стежку, що мабуть веде до вершини далекого пагорбу",
    eventCheck1: false,
    setActions: function() {
        if (loc4.eventCheck1 == true) {
        } else  {
            document.getElementById("event_field").innerHTML = " ";
            changeActionList("Іти на південь по дорозі,loc5.goSouth()", "Іти стежкою убік пагорбу,loc5.goSW()");
        }
    },
    goSouth: function() {
        changeLocation(loc3);
    },
    goSW: function() {
        changeLocation(loc6);
    }
};
var loc6 = {
    description: "Вершина пагорба, видно дуже далеко. Десь на сході посеред лісу простежується дорога. На півночі поміж великих дерев височіть замок. На півдні ліс сходить схилами пагорба і рпатово обривається, здається десь там проходить великий каньон.",
    eventCheck1: false,
    setActions: function() {
        if (loc4.eventCheck1 == true) {
        } else  {
            document.getElementById("event_field").innerHTML = " ";
            changeActionList("Іти на північ до замку,loc6.goNorth()", "Іти на схід до дороги,loc6.goEast()", "Іти на південь до каньону,loc6.goSouth()");
        }
    },
    goNorth: function() {
        changeLocation(loc5);
    },
    goEast: function() {
        changeLocation(loc3);
    },
    goSouth: function() {
        changeLocation(loc4);
    }
};

redpajama_set_name: RedPajamaGithub


text:
Promoted by University of Sussex
Sussex Electrical and Electronic Engineering: Learn to shape the future of electronics and its applications
John Kinghorn knows the profound impact of a University of Sussex Electrical and Electronic Engineering degree.
Since graduating with a BEng (Hons) Electrical and Electronic Engineering in 1968, John has led an illustrious career: 14 years with Mullard Limited (developing systems for the Royal Navy), close to 20 years with international engineering company Philips and nearly 10 years with the Wessex Round Table of Inventors.
As a child, John could be found building radios and other electronics in the garden shed. By his early teens, he knew he wanted to build a career that revolved around electronics. The University of Sussex made this possible. "I chose to study for my degree at Sussex partly because of the campus — the architecture and the beautiful setting in a lovely National park — and partly because Sussex wasn't hidebound by tradition. There was a real willingness to make a fundamental difference, and a robust independence from traditional ways of doing things which appealed to me very much."
Sussex empowered his desire to innovate — at Philips, he was heavily involved in the development of our modern television broadcast systems. More recently, he's worked on and published a book on high-speed train design and engineering. Today, as Secretary of the Wessex Round Table of Inventors, he offers support to aspiring inventors. Through this route, he is now feeding back his wealth of engineering experiences in helping to promote the next generation of engineering entrepreneurs and inventors.
When he returned to campus for an alumni reunion, John remarked, "It reminded me of how much I liked the atmosphere of it – both the physical atmosphere and the intellectual independence of the University. It also reminded me how much I owed the place."
Source: University of Sussex
As technology becomes more prevalent in the world we live in, Sussex's bold approach to Electrical and Electronic Engineering education has never been more relevant and exciting. Smartphones have evolved from a mere device to call others to something that we depend on to shop, create, date, learn and many more facets of our contemporary existence. Cars are becoming self-driving, and with the advances in Artificial Intelligence they are becoming safer than human drivers even in difficult driving conditions. The Internet of Things is already happening, where doors, streets and even hydroelectric dams, are wirelessly connected to far-off data centres and operate automatically and, most importantly, smartly.
A revolution is underway in the application of innovative sensor technology and embedded solutions — and the Electrical and Electronic engineer is in the thick of it all. A profession that has evolved rapidly in the last few decades, today's Electrical and Electronic engineers need to have multidisciplinary know-how and skill set to match the upcoming challenges that the Manufacturing, Healthcare, Automation, Robotics, Transport and 5G Wireless Communication industries bring.
A Sussex Electrical and Electronic Engineering degree explores the potential wider applications of electronics. Our students will not only learn about, but will also be involved in creating, new types of technologies and innovative electronic systems for the future. Our teaching staff are world experts in their fileds and will provide you with guidance and insight into modern technologies such as robotic manufacturing, sustainability, wearables, AI in healthcare, the Internet of Things, advanced transportation, and modern wireless communications. Sussex is at the forefront of these emerging innovations that are now becoming realities.
Through our practical approach to engineering education our students gain hardware skills and hands-on experience. For their final year project, they work alongside researchers in one of the departmental research groups such as the "Advanced Communications, Mobile Technology and IoT Research Centre," the "Industrial Informatics and Signal Processing Research Group," the "Sensors Technology Research Centre," or the "Robotics and Mechatronics Systems Research Centre." These will not only provide a solid foundation to their degree but will also make them more employable. One of the exciting projects we work on is monitoring the heart of new-born babies. The Electro-Potential Sensor technology developed by our emeritus professor Robert Prance and his team allows electro-cardiograms (ECG) to be taken without the need of direct contact. Our academics Drs. Rendon-Morales and Aviles Espinosa are using the EPS technology to create a non-invasive wearable device for monitoring the cardiac activity of babies within seconds of birth. They are leading the multidisciplinary Neosense research project in collaboration with the Neonatal Intensive Care Unit at Brighton and Sussex University hospitals.
The Sussex Department of Engineering and Design offers the following programmes: Electrical and Electronic Engineering (BEng and MEng), Electrical and Electronic Engineering with an industrial placement year (BEng and MEng), Electrical and Electronic Engineering with Robotics (BEng and MEng), Electrical and Electronic Engineering with Robotics with an industrial placement year (BEng and MEng), Advanced Electronic and Electrical Engineering MSc and 5G Mobile Communications and Intelligent Embedded Systems (with an industrial placement year) MSc
Follow the School of Engineering and Informatics on Facebook and Twitter
View University profile

redpajama_set_name: RedPajamaCommonCrawl


text:
Кушниров — фамилия. Известные носители:
 Кушниров, Арон Давидович (1890—1949) — еврейский советский поэт, прозаик, драматург и переводчик.
 Кушниров, Денис Вячеславович (род. 1992) — украинский спортивный стрелок.
 Кушниров, Дмитрий Александрович (род. 1990) — украинский футболист.
 Кушниров, Марк Аронович (род. 1937) — киновед, кинокритик, писатель и сценарист.
 Кушниров, Михаил Алексеевич (1868— после 1918) — военспец.
 Кушниров, Николай Александрович (род. 1945) — украинский политик.
 Кушниров, Радий Аронович (1931—2010) — прозаик и сценарист.

См. также

redpajama_set_name: RedPajamaWikipedia


Design a home that's beautiful, meditative, and peaceful with our specially curated home decor collections. Feel inspired to bring bold, worldly elements into your living space with unique pieces from around the globe. Display flowers in tall decorative vases, and add earthy accents to your space with handcrafted ceramic pieces. Discover bold prints and framed wall art by talented artists, including the Vietnamese Buddhist monk, Thich Nhat Hanh, to infuse your space with tranquility and inspiration. Add wall decor to complete your home design with a sophisticated style that's unique, distinctive, and 100-percent yours.


Dr. Jones @DrLeeJones is a Senior Lecturer at Queen Mary University of London. His research interests revolve around questions of state-society relations, governance, political economy, sovereignty and intervention. His area of expertise is the Asia-Pacific, especially Southeast Asia. Lee is author of ASEAN, Sovereignty and Intervention in Southeast Asia (2012) and many scholarly articles. He has also advised government agencies and civil society groups from a wide range of countries including Australia, Britain, Denmark, France, Myanmar and Timor-Leste.


text:
Removing the Restrainer
Posted on March 16, 2014 April 17, 2017 by Mark
THE past month has been one of palpable sorrow as the Lord continues to warn that there is So Little Time Left. The times are sorrowful because mankind is about to reap what God has begged us not to sow. It is sorrowful because many souls do not realize that they are on the precipice of eternal separation from Him. It is sorrowful because the hour of the Church's own passion has come when a Judas will rise up against her. [1]cf. The Seven Year Trial-Part VI It is sorrowful because Jesus is not only being neglected and forgotten throughout the world, but abused and mocked once again. Hence, the Time of times has come when all lawlessness will, and is, breaking forth across the globe.
Before I go on, ponder for a moment the truth-filled words of a saint:
Do not fear what may happen tomorrow. The same loving Father who cares for you today will care for you tomorrow and everyday. Either he will shield you from suffering or He will give you unfailing strength to bear it. Be at peace then and put aside all anxious thoughts and imaginings. —St. Francis de Sales, 17th century bishop
Indeed, this blog is not here to scare or frighten, but to confirm and prepare you so that, like the five wise virgins, the light of your faith will not be snuffed out, but glow ever brighter when the light of God in the world is fully dimmed, and darkness fully unrestrained. [2]cf. Matt 25:1-13
Therefore, stay awake, for you know neither the day nor the hour. (Matt 25:13)
THE RESTRAINER…
In 2005, I wrote in The Restrainer (under the urging of a Canadian bishop) how I was driving alone in British Columbia, Canada, making my way to my next concert, enjoying the scenery, drifting in thought, when suddenly I heard within my heart the words:
I have lifted the restrainer.
I felt something in my spirit that is hard to explain. It was as if a shock wave traversed the earth—as if something in the spiritual realm had been released.
That night in my motel room, I asked the Lord if what I heard was in the Scriptures, since the word "restrainer" was unfamiliar to me. I grabbed my Bible which opened straight to 2 Thessalonians 2:3. I began to read:
…[do not be] shaken out of your minds suddenly, or… alarmed either by a "spirit," or by an oral statement, or by a letter allegedly from us to the effect that the day of the Lord is at hand. Let no one deceive you in any way. For unless the apostasy comes first and the lawless one is revealed…
That is, the "apostasy" (rebellion) and "the lawless one" (Antichrist) essentially usher in "the day of the Lord," says St. Paul, a day of both vindication and justice [3]cf. The Vindication of Wisdom (the Day of the Lord being, not a 24 hour period, but what could rightly be called the final era before the end of the world. See Two More Days). How can one not recall at this point the startling words of the popes in this regard?
Apostasy, the loss of the faith, is spreading throughout the world and into the highest levels within the Church. —POPE PAUL VI, Address on the Sixtieth Anniversary of the Fatima Apparitions, October 13, 1977
In fact, Pope Pius X—in an encyclical, no less—suggested that both the apostasy and the Antichrist may already be present:
Who can fail to see that society is at the present time, more than in any past age, suffering from a terrible and deep-rooted malady which, developing every day and eating into its inmost being, is dragging it to destruction? You understand, Venerable Brethren, what this disease is—apostasy from God… When all this is considered there is good reason to fear lest this great perversity may be as it were a foretaste, and perhaps the beginning of those evils which are reserved for the last days; and that there may be already in the world the "Son of Perdition" of whom the Apostle speaks. —E Supremi, Encyclical On the Restoration of All Things in Christ, n. 3, 5; October 4th, 1903
But there is something "restraining" the appearance of this Antichrist. For, with my jaw wide open that night, I went on to read:
And you know what is restraining him now so that he may be revealed in his time. For the mystery of lawlessness is already at work; only he who now restrains it will do so until he is out of the way. And then the lawless one will be revealed…
Now, this April 2012 [March 2014], I hear new words which I have pondered for weeks, spoken about several times with my spiritual director, and which I write now in obedience: that the Lord is going to remove the restrainer altogether.
WHAT IS THE RESTRAINER?
Theologians are divided about the meaning of these mysterious words of St. Paul. "What" is it that restrains? And who is "he who now restrains?" The Early Church Fathers often held that the restrainer was the Roman Empire, based on Daniel 7:24:
Out of this kingdom ten kings shall arise, and another shall arise after them; he shall be different from the former ones, and shall put down three kings. (Dan 7:24)
Now this restraining power [is] generally admitted to be the Roman empire… I do not grant that the Roman empire is gone. Far from it: the Roman empire remains even to this day. —Blessed Cardinal John Henry Newman (1801-1890), Advent Sermons on Antichrist, Sermon I
And yet, St. Paul also refers to "he who restrains," as in a person or possibly angelic entity. From the Navarre biblical commentary:
Although it is not altogether clear what St. Paul means here (commentators ancient and modern have offered all kinds of interpretations), the general thrust of his remarks seems clear enough: he is exhorting people to persevere in doing good, because that is the best way to avoid doing evil (evil being the "mystery of lawlessness"). However, it is difficult to say precisely what this mystery of lawlessness consists in or who is restraining it.
Some commentators think that the mystery of lawlessness is the activity of the man of lawlessness, which is being restrained by the rigid laws enforced by the Roman Empire. Others suggest that St. Michael is the one who is holding lawlessness back (cf. Rev 12:1; Rev 12:7-9; 20:1-3, 7)… which show him combating Satan, restraining him or letting him free… others think that the curb on the man of lawlessness is the active presence of Christians in the world, who through word and example bring Christ's teaching and grace to many. If Christians let their zeal grow cold (this interpretation says), then the curb on evil will cease to apply and the rebellion will ensue. —The Navarre Bible commentary on 2 Thess 2:6-7, Thessalonians and Pastoral Epistles, p. 69-70
The original Roman Empire collapsed, though not completely some historians argue, essentially because of political and moral corruption. Speaking to the Roman Curia, Pope Benedict XVI said:
The disintegration of the key principles of law and of the fundamental moral attitudes underpinning them burst open the dams which until that time had protected peaceful coexistence among peoples. The sun was setting over an entire world. Frequent natural disasters further increased this sense of insecurity. There was no power in sight that could put a stop to this decline. All the more insistent, then, was the invocation of the power of God: the plea that he might come and protect his people from all these threats. —POPE BENEDICT XVI, Address to the Roman Curia, December 20th, 2010
I believe few realize the prophetic thrust of Pope Benedict's words that were carefully chosen on the eve of the winter solstice—the darkest day of the year in the northern hemisphere. [4]cf. On the Eve He was comparing the decline of Rome with our generation. He was underlining how "the key principles of law and of the fundamental moral attitudes underpinning" our society, are beginning to collapse:
…our world is at the same time troubled by the sense that moral consensus is collapsing, consensus without which juridical and political structures cannot function… Only if there is such a consensus on the essentials can constitutions and law function. This fundamental consensus derived from the Christian heritage is at risk… In reality, this makes reason blind to what is essential. To resist this eclipse of reason and to preserve its capacity for seeing the essential, for seeing God and man, for seeing what is good and what is true, is the common interest that must unite all people of good will. The very future of the world is at stake. —Ibid.
Essentially, the world is on the brink of lawlessness. Now, this does not necessarily mean to be without laws, but rather to embrace, codify, and promote falsehoods as though they were truths. For to abandon objective truth, which under-girds the principles of just law, is to allow the whole structure to collapse.
Therefore, God handed them over to impurity through the lusts of their hearts for the mutual degradation of their bodies. They exchanged the truth of God for a lie and revered and worshiped the creature rather than the creator, who is blessed forever. (Rom 1:24-25)
The voice of truth that restrains men from their passions by calling them to repentance and back to the right path, has been entrusted to the Church…
THE CHURCH RESTRAINS
Jesus promised the Apostles "when he comes, the Spirit of truth, he will guide you to all truth." [5]cf. John 16:13 But they were not to hide this truth beneath a bushel basket; rather, they were commissioned to:
Go, therefore, and make disciples of all nations… teaching them to observe all that I have commanded you. (Matt 28:19-20)
…sinful man needs grace and revelation so moral and religious truths may be known "by everyone with facility, with firm certainty and with no admixture of error." The natural law provides revealed law and grace with a foundation prepared by God and in accordance with the work of the Spirit. —Catechism of the Catholic Church, n. 1960
With the French Revolution, [6]1789-99 A.D. the division between Church and state became systematized and human rights began to be defined, no longer by the natural and moral law, but by the state. Henceforth, the Church's moral authority has continually been eroded, such that today:
…the Christian faith is no longer allowed to express itself visibly… in the name of tolerance, tolerance is being abolished. —POPE BENEDICT XVI, Light of the World, A Conversation with Peter Seewald, p. 52-53
The illusive concept of "tolerance", [7]eg. http://radio.foxnews.com/ while creating an illusion of "freedom", has led to the rejection of inspired truth thus leading mankind to a new kind of slavery:
The Church invites political authorities to measure their judgments and decisions against this inspired truth about God and man: Societies not recognizing this vision or rejecting it in the name of their independence from God are brought to seek their criteria and goal in themselves or to borrow them from some ideology. Since they do not admit that one can defend an objective criterion of good and evil, they arrogate to themselves an explicit or implicit totalitarian power over man and his destiny, as history shows. —POPE JOHN PAUL II, Centesimus annus, n. 45, 46
With tragic consequences, a long historical process is reaching a turning-point. The process which once led to discovering the idea o f "human rights"—rights inherent in every person and prior to any Constitution and State legislation—is today marked by a surprising contradiction… the very right to life is being denied or trampled upon… the original and inalienable right to life is questioned or denied on the basis of a parliamentary vote or the will of one part of the people—even if it is the majority. This is the sinister result of a relativism which reigns unopposed: the "right" ceases to be such, because it is no longer firmly founded on the inviolable dignity of the person, but is made subject to the will of the stronger part. In this way democracy, contradicting its own principles, effectively moves towards a form of totalitarianism. —POPE JOHN PAUL II, Evangelium Vitae, "The Gospel of Life", n. 18, 20
A totalitarianism that is now global in nature, thanks to the phenomenon of globalization. Add to this the repeated calls for a global currency and a "new world order", [8]cf. The Writing on the Wall as the world economy as we know it continues to disintegrate. [9]cf. The Collapse of Babylon But it is not merely an economic or political dictatorship forming, but a religious one controlled by "those with the power to "create" opinion and impose it on others." [10]POPE JOHN PAUL II, Cherry Creek State Park Homily, Denver, Colorado, 1993
…an abstract, negative religion is being made into a tyrannical standard that everyone must follow. —POPE BENEDICT XVI, Light of the World, A Conversation with Peter Seewald, p. 52
A new world order in itself is not necessarily evil; but if truth is rejected—and the Church who proclaims it—it will ultimately lead to the acceptance of the one whom Jesus calls a "liar and the father of lies". [11]cf. John 8:44 For…
…without the guidance of charity in truth, this global force could cause unprecedented damage and create new divisions within the human family… humanity runs new risks of enslavement and manipulation… —Caritas in Veritate, n.33, 26
…enslavement to the one whom "the manipulator" gives his power to: a Judas, [12]cf. John 13:27 the lawless one, the "son of perdition", the Antichrist or beast:
To it the dragon gave its own power and throne, along with great authority. (Rev 13:2)
He comes to power when that which is "restraining" him is removed.
THE ROCK AND THE RESTRAINER
When still a cardinal, Pope Benedict XVI wrote:
Abraham, the father of faith, is by his faith the rock that holds back chaos, the onrushing primordial flood of destruction, and thus sustains creation. Simon, the first to confess Jesus as the Christ… now becomes by virtue of his Abrahamic faith, which is renewed in Christ, the rock that stands against the impure tide of unbelief and its destruction of man. —POPE BENEDICT XVI (Cardinal Ratzinger), Called to Communion, Understanding the Church Today, Adrian Walker, Tr., p. 55-56
The Pope, Simon Peter's successor, by virtue of his divine office as "rock" and custodian of the "keys of the kingdom", [13]cf. Matt 16:18-19 holds back the "mystery of lawlessness" in its fullness. The Pope, however, is not alone; there are "living stones" [14]cf. 1 Pet 2:5 built with him upon the foundation who is Christ, the cornerstone, [15]cf. 1 Cor 3:11 who leads the whole Church into all truth through His Spirit.
The whole body of the faithful… cannot err in matters of belief. This characteristic is shown in the supernatural appreciation of faith (sensus fidei) on the part of the whole people, when, from the bishops to the last of the faithful, they manifest a universal consent in matters of faith and morals. —Catechism of the Catholic Church, n. 92
Thus, the entire body of Christ shares in the Petrine ministry insofar as they remain in communion with him. So then, is that which restrains unbridled lawlessness—indeed, the Antichrist—the moral witness and voice of the Church, in communion with the Holy Father?
The Church is always called upon to do what God asked of Abraham, which is to see to it that there are enough righteous men to repress evil and destruction. —POPE BENEDICT XVI, Light of the World, A Conversation with Peter Seewald, p. 166
When Christians cease to shine [16]cf. A Sliver of His Light, or when that light has been dulled by sin and corruption, that authoritative "voice" loses its moral force and credence. Then the future is determined no longer by absolutes, but by what Pope Benedict calls "a dictatorship of relativism"….
…which leaves as the ultimate measure only one's ego and desires… —Cardinal Ratzinger (POPE BENEDICT XVI) pre-conclave Homily, April 18th, 2005
We can better understand, then, why now, at this hour, the restrainer is being removed, particularly in light of the widespread sexual scandals in the priesthood. Regarding these sins, Pope Benedict has not been vague:
As a result, the faith as such becomes unbelievable, and the Church can no longer present herself credibly as the herald of the Lord. —POPE BENEDICT XVI, Light of the World, A Conversation with Peter Seewald, p. 25
Even St. Michael the Archangel, as protector of the Church, is himself bound by the free will of its members if they so choose to slide into apostasy.
THE ROMAN EMPIRE
What of the Roman Empire? Western civilization is built in part upon principles of the Roman Empire, particularly the Judaeo-Christian principles that it adopted. Under Emperor Constantine, Rome became Christian and from there, Catholicism spread throughout Europe and beyond. The collapse of the Roman Empire, hence, could be understood, in part, as the collapse of those Christian morals that supported it.
This revolt [apostasy], or falling off, is generally understood, by the ancient fathers, of a revolt from the Roman empire, which was first to be destroyed, before the coming of Antichrist. It may, perhaps, be understood also of a revolt of many nations from the Catholic Church which has, in part, happened already, by the means of Mahomet, Luther, etc. and it may be supposed, will be more general in the days of the Antichrist. —footnote on 2 Thess 2:3, Douay-Rheims Holy Bible, Baronius Press Limited, 2003; p. 235
Today, the Roman Empire is believed to subsist in some form through the European Union, which embraced the Treaty of Rome in forming its economic union. America, I might add, finds its roots in the European people, and through a nearly constant history of war, has built an empire of sorts throughout the Middle East and beyond. Others believe the Roman Empire has yet to rise in its final form before it falls for good. The point, however, is this: Western civilization is in a collapse, says Pope Benedict.
God is disappearing from the human horizon, and, with the dimming of the light which comes from God, humanity is losing its bearings, with increasingly evident destructive effects. —Letter of His Holiness Pope Benedict XVI to All the Bishops of the World, March 10, 2009; Catholic Online
The dam of lawlessness is about to burst open upon a world whose future, he warned, "is at stake."
WHAT WOULD HE SAY?
If Pope Pius X were alive today… walking through our malls on Sunday, noting our empty and closed churches, [17]nb. there are places, such as in Africa and parts of India where the Church is thriving; I am speaking here of the Western world that, for the most part, dominates the political and economic future of the world, for better or worse… watching a sampling of evening sitcoms and Hollywood movies, spending a day browsing the internet, listening to our radio shock jocks, watching pagan parades, comparing plump North Americans to starving Africans, and counting the number of unborn who are decimated in the womb by the thousands each and every day… I am almost certain we would hear him shouting… [18]cf. Why Aren't the Popes Shouting?
…there may be already in the world the "Son of Perdition" of whom the Apostle speaks. —E Supremi, Encyclical On the Restoration of All Things in Christ, n. 5; October 4th, 1903
In our rationalism, and in the face of the rising power of dictatorships, God shows us the humility of the Mother, who appears to little children and speaks to them of the essentials: faith, hope, love, penance. —POPE BENEDICT XVI, Light of the World, A Conversation with Peter Seewald, p. 164
In the end, my Immaculate Heart will triumph. The Holy Father will consecrate Russia to me, and she shall be converted, and a period of peace will be granted to the world. —Our Lady of Fatima to the three children of Portugal; Message of Fatima, www.vatican.va
First published April 27th, 2012.
Click here to Unsubscribe or Subscribe to this Journal.
WATCH the VIDEO: Church and State?
with MARK MALLETT at: EmbracingHope.tv
Does the Antichrist come before or after the "era of peace"… or both? Read The Last Two Eclipses and On Heresies and More Questions
Dream of the Lawless One
Like a Thief
The Coming Refuges and Solitudes
Global Revolution!
Quest for Freedom
The Great Revolution
Living the Book of Revelation
Understanding the Final Confrontation
Why Aren't the Popes Shouting?
The Great Vacuum
A Short Story of the Anti-Christ by Vladimir Solovëv
The end of Antichrist and beginning of a new era: The End of the Age
The Popes, and the Dawning Era
Watch: The Big Picture & The Big Picture – Part II
Watch: We Were Warned
Watch: The Prophecy at Rome series
1. ↑ cf. The Seven Year Trial-Part VI
2. ↑ cf. Matt 25:1-13
3. ↑ cf. The Vindication of Wisdom
4. ↑ cf. On the Eve
5. ↑ cf. John 16:13
6. ↑ 1789-99 A.D.
7. ↑ eg. http://radio.foxnews.com/
8. ↑ cf. The Writing on the Wall
9. ↑ cf. The Collapse of Babylon
10. ↑ POPE JOHN PAUL II, Cherry Creek State Park Homily, Denver, Colorado, 1993
11. ↑ cf. John 8:44
12. ↑ cf. John 13:27
13. ↑ cf. Matt 16:18-19
14. ↑ cf. 1 Pet 2:5
15. ↑ cf. 1 Cor 3:11
16. ↑ cf. A Sliver of His Light
17. ↑ nb. there are places, such as in Africa and parts of India where the Church is thriving; I am speaking here of the Western world that, for the most part, dominates the political and economic future of the world, for better or worse…
18. ↑ cf. Why Aren't the Popes Shouting?
Posted in HOME, THE GREAT TRIALS and tagged apocalypse, revelation, end times, john paul ii, catholic, pope, truth, benedict, antichrist, apostasy, pius x, bible, relativism, false prophet, newman, lawless one, son of perdition, judas, restrainer.
← Be Merciful
Who Am I to Judge? →