<commit_before>/* eslint-disable no-undef */
import assert from 'assert';
import { fixture, clearFixture } from './support/fixtures';
import { initRecurly, testBed } from './support/helpers';

describe.skip('Recurly.BankRedirect', function () {
  beforeEach(function () {
    this.recurly = initRecurly({ });
    this.bankRedirect = this.recurly.BankRedirect();
  });

  describe('iDeal', function () {
    describe('loadBanks', function () {
      beforeEach(function () {
        this.banksPayload = {
          payment_method_type: 'ideal',
        };
      });

      afterEach(function () {
        clearFixture();
      });

      it('raises an error for a missing type', function (done) {
        this.banksPayload.payment_method_type = undefined;

        this.bankRedirect.on('error', (error) => {
          assert.ok(error);
          assert.equal(error.code, 'validation');
          assert.equal(error.fields[0], 'payment_method_type cannot be blank');
          done();
        });
        this.bankRedirect.on('banks', assert.fail);

        this.bankRedirect.loadBanks(this.banksPayload);
      });

      it('raises an error for an invalid type', function (done) {
        this.banksPayload.payment_method_type = 'wrong';

        this.bankRedirect.on('error', (error) => {
          assert.ok(error);
          assert.equal(error.code, 'validation');
          assert.equal(error.fields[0], 'invalid payment_method_type');
          done();
        });
        this.bankRedirect.on('banks', assert.fail);

        this.bankRedirect.loadBanks(this.banksPayload);
      });

      it('raises an error for a failed api request', function (done) {
        this.banksPayload.error = true;

        this.bankRedirect.on('error', (error) => {
          assert.ok(error);
          assert.equal(error.code, 'banks-error');
          done();
        });
        this.bankRedirect.on('banks', assert.fail);

        this.bankRedirect.loadBanks(this.banksPayload);
      });

      it('emit the banks without error for a successfully api request', function (done) {
        this.bankRedirect.on('error', () => assert.fail);
        this.bankRedirect.on('banks', banks => {
          assert.ok(banks);
          done();
        });

        this.bankRedirect.loadBanks(this.banksPayload);
      });

      it('attach the banks to a select element', function (done) {
        fixture('selectBanks');
        const $select = testBed().querySelector('#issuer_id');

        this.bankRedirect.on('error', () => assert.fail);
        this.bankRedirect.on('banks', () => {
          assert.ok(new RegExp([
            '<select (id|name)="issuer_id" (id|name)="issuer_id">',
            '<option value="bank1">Bank 1</option>',
            '<option value="bank2">Bank 2</option>',
            '</select>'
          ].join('')).test($select.outerHTML));
          done();
        });

        this.bankRedirect.loadBanks(this.banksPayload, '#issuer_id');
      });

      it('attach the banks to a select element after cleanup the select', function (done) {
        fixture('selectBanksFull', [{ id: 'bank99', name: 'Bank 99' }]);
        const $select = testBed().querySelector('#issuer_id');

        this.bankRedirect.on('error', () => assert.fail);
        this.bankRedirect.on('banks', () => {
          assert.ok(new RegExp([
            '<select (id|name)="issuer_id" (id|name)="issuer_id">',
            '<option value="bank1">Bank 1</option>',
            '<option value="bank2">Bank 2</option>',
            '</select>'
          ].join('')).test($select.outerHTML));
          done();
        });

        this.bankRedirect.loadBanks(this.banksPayload, '#issuer_id');
      });

      it('attach the banks to a select element into a container', function (done) {
        fixture('emptyForm');
        const $form = testBed().querySelector('#test-form');

        this.bankRedirect.on('error', () => assert.fail);
        this.bankRedirect.on('banks', () => {
          assert.ok(new RegExp([
            '<form id="test-form">',
            '<select (id|name)="issuer_id" (id|name)="issuer_id">',
            '<option value="bank1">Bank 1</option>',
            '<option value="bank2">Bank 2</option>',
            '</select>',
            '</form>'
          ].join('')).test($form.outerHTML));
          done();
        });

        this.bankRedirect.loadBanks(this.banksPayload, '#test-form');
      });
    });

    describe('start', function () {
      beforeEach(function () {
        this.startPayload = {
          payment_method_type: 'ideal',
          issuer_id: 'issuer123',
          invoice_uuid: 'invoice123'
        };

        this.sandbox = sinon.createSandbox();
        this.sandbox.spy(this.recurly, 'Frame');
      });

      afterEach(function () {
        this.sandbox.restore();
      });

      it('raises an error for a missing type', function (done) {
        this.startPayload.payment_method_type = undefined;

        this.bankRedirect.on('error', (error) => {
          assert.ok(error);
          assert.equal(error.code, 'validation');
          assert.equal(error.fields[0], 'payment_method_type cannot be blank');
          done();
        });
        this.bankRedirect.on('token', assert.fail);

        this.bankRedirect.start(this.startPayload);
      });

      it('raises an error for an invalid type', function (done) {
        this.startPayload.payment_method_type = 'wrong';

        this.bankRedirect.on('error', (error) => {
          assert.ok(error);
          assert.equal(error.code, 'validation');
          assert.equal(error.fields[0], 'invalid payment_method_type');
          done();
        });
        this.bankRedirect.on('token', assert.fail);

        this.bankRedirect.start(this.startPayload);
      });

      it('raises an error for a missing issuer_id', function (done) {
        this.startPayload.issuer_id = '';

        this.bankRedirect.on('error', (error) => {
          assert.ok(error);
          assert.equal(error.code, 'validation');
          assert.equal(error.fields[0], 'issuer_id cannot be blank');
          done();
        });
        this.bankRedirect.on('token', assert.fail);

        this.bankRedirect.start(this.startPayload);
      });

      it('raises an error for a missing invoice_uuid', function (done) {
        this.startPayload.invoice_uuid = '';

        this.bankRedirect.on('error', (error) => {
          assert.ok(error);
          assert.equal(error.code, 'validation');
          assert.equal(error.fields[0], 'invoice_uuid cannot be blank');
          done();
        });
        this.bankRedirect.on('token', assert.fail);
        this.bankRedirect.start(this.startPayload);
      });

      it('create the iframe to make the payment', function () {
        // debugger
        this.bankRedirect.start(this.startPayload);

        assert(this.recurly.Frame.calledOnce);
        assert(this.recurly.Frame.calledWithMatch({
          height: 600,
          path: '/bank_redirect/start',
          payload: {
            payment_method_type: 'ideal',
            issuer_id: 'issuer123'
          }
        }));
      });

      it('emit an error if the iframe emits errors', function (done) {
        this.bankRedirect.on('error', (error) => {
          assert.ok(error);
          assert.equal(error.code, 'bank-redirect-error');
          assert.equal(error.cause, 'my-error');
          done();
        });
        this.bankRedirect.on('token', assert.fail);

        const frame = this.bankRedirect.start(this.startPayload);
        frame.emit('error', 'my-error');
      });

      it('emit a token if the iframe is done successfully', function (done) {
        this.bankRedirect.on('error', assert.fail);
        this.bankRedirect.on('token', token => {
          assert(token, 'my-token');
          done();
        });

        const frame = this.bankRedirect.start(this.startPayload);
        frame.emit('done', 'my-token');
      });
    });
  });
});
<commit_msg>fix failing tests<commit_after>/* eslint-disable no-undef */
import assert from 'assert';
import { fixture, clearFixture } from './support/fixtures';
import { initRecurly, testBed } from './support/helpers';

describe('Recurly.BankRedirect', function () {
  beforeEach(function (done) {
    this.recurly = initRecurly({ });
    this.bankRedirect = this.recurly.BankRedirect();
    this.recurly.ready(() => done());
  });

  afterEach(function () {
    this.recurly.destroy();
  });

  describe('iDeal', function () {
    describe('loadBanks', function () {
      beforeEach(function () {
        this.banksPayload = {
          payment_method_type: 'ideal',
        };
      });

      afterEach(function () {
        clearFixture();
      });

      it('raises an error for a missing type', function (done) {
        this.banksPayload.payment_method_type = undefined;

        this.bankRedirect.on('error', (error) => {
          assert.ok(error);
          assert.equal(error.code, 'validation');
          assert.equal(error.fields[0], 'payment_method_type cannot be blank');
          done();
        });
        this.bankRedirect.on('banks', assert.fail);

        this.bankRedirect.loadBanks(this.banksPayload);
      });

      it('raises an error for an invalid type', function (done) {
        this.banksPayload.payment_method_type = 'wrong';

        this.bankRedirect.on('error', (error) => {
          assert.ok(error);
          assert.equal(error.code, 'validation');
          assert.equal(error.fields[0], 'invalid payment_method_type');
          done();
        });
        this.bankRedirect.on('banks', assert.fail);

        this.bankRedirect.loadBanks(this.banksPayload);
      });

      it('raises an error for a failed api request', function (done) {
        this.banksPayload.error = true;

        this.bankRedirect.on('error', (error) => {
          assert.ok(error);
          assert.equal(error.code, 'banks-error');
          done();
        });
        this.bankRedirect.on('banks', assert.fail);

        this.bankRedirect.loadBanks(this.banksPayload);
      });

      it('emit the banks without error for a successfully api request', function (done) {
        this.bankRedirect.on('error', () => assert.fail);
        this.bankRedirect.on('banks', banks => {
          assert.ok(banks);
          done();
        });

        this.bankRedirect.loadBanks(this.banksPayload);
      });

      it('attach the banks to a select element', function (done) {
        fixture('selectBanks');
        const $select = testBed().querySelector('#issuer_id');

        this.bankRedirect.on('error', () => assert.fail);
        this.bankRedirect.on('banks', () => {
          assert.ok(new RegExp([
            '<select (id|name)="issuer_id" (id|name)="issuer_id">',
            '<option value="bank1">Bank 1</option>',
            '<option value="bank2">Bank 2</option>',
            '</select>'
          ].join('')).test($select.outerHTML));
          done();
        });

        this.bankRedirect.loadBanks(this.banksPayload, '#issuer_id');
      });

      it('attach the banks to a select element after cleanup the select', function (done) {
        fixture('selectBanksFull', [{ id: 'bank99', name: 'Bank 99' }]);
        const $select = testBed().querySelector('#issuer_id');

        this.bankRedirect.on('error', () => assert.fail);
        this.bankRedirect.on('banks', () => {
          assert.ok(new RegExp([
            '<select (id|name)="issuer_id" (id|name)="issuer_id">',
            '<option value="bank1">Bank 1</option>',
            '<option value="bank2">Bank 2</option>',
            '</select>'
          ].join('')).test($select.outerHTML));
          done();
        });

        this.bankRedirect.loadBanks(this.banksPayload, '#issuer_id');
      });

      it('attach the banks to a select element into a container', function (done) {
        fixture('emptyForm');
        const $form = testBed().querySelector('#test-form');

        this.bankRedirect.on('error', () => assert.fail);
        this.bankRedirect.on('banks', () => {
          assert.ok(new RegExp([
            '<form id="test-form">',
            '<select (id|name)="issuer_id" (id|name)="issuer_id">',
            '<option value="bank1">Bank 1</option>',
            '<option value="bank2">Bank 2</option>',
            '</select>',
            '</form>'
          ].join('')).test($form.outerHTML));
          done();
        });

        this.bankRedirect.loadBanks(this.banksPayload, '#test-form');
      });
    });

    describe('start', function () {
      beforeEach(function () {
        this.startPayload = {
          payment_method_type: 'ideal',
          issuer_id: 'issuer123',
          invoice_uuid: 'invoice123'
        };

        this.sandbox = sinon.createSandbox();
        this.sandbox.spy(this.recurly, 'Frame');
      });

      afterEach(function () {
        this.sandbox.restore();
      });

      it('raises an error for a missing type', function (done) {
        this.startPayload.payment_method_type = undefined;

        this.bankRedirect.on('error', (error) => {
          assert.ok(error);
          assert.equal(error.code, 'validation');
          assert.equal(error.fields[0], 'payment_method_type cannot be blank');
          done();
        });
        this.bankRedirect.on('token', assert.fail);

        this.bankRedirect.start(this.startPayload);
      });

      it('raises an error for an invalid type', function (done) {
        this.startPayload.payment_method_type = 'wrong';

        this.bankRedirect.on('error', (error) => {
          assert.ok(error);
          assert.equal(error.code, 'validation');
          assert.equal(error.fields[0], 'invalid payment_method_type');
          done();
        });
        this.bankRedirect.on('token', assert.fail);

        this.bankRedirect.start(this.startPayload);
      });

      it('raises an error for a missing issuer_id', function (done) {
        this.startPayload.issuer_id = '';

        this.bankRedirect.on('error', (error) => {
          assert.ok(error);
          assert.equal(error.code, 'validation');
          assert.equal(error.fields[0], 'issuer_id cannot be blank');
          done();
        });
        this.bankRedirect.on('token', assert.fail);

        this.bankRedirect.start(this.startPayload);
      });

      it('raises an error for a missing invoice_uuid', function (done) {
        this.startPayload.invoice_uuid = '';

        this.bankRedirect.on('error', (error) => {
          assert.ok(error);
          assert.equal(error.code, 'validation');
          assert.equal(error.fields[0], 'invoice_uuid cannot be blank');
          done();
        });
        this.bankRedirect.on('token', assert.fail);
        this.bankRedirect.start(this.startPayload);
      });

      it('create the iframe to make the payment', function () {
        // debugger
        this.bankRedirect.start(this.startPayload);

        assert(this.recurly.Frame.calledOnce);
        assert(this.recurly.Frame.calledWithMatch({
          height: 600,
          path: '/bank_redirect/start',
          payload: {
            payment_method_type: 'ideal',
            issuer_id: 'issuer123'
          }
        }));
      });

      it('emit an error if the iframe emits errors', function (done) {
        this.bankRedirect.on('error', (error) => {
          assert.ok(error);
          assert.equal(error.code, 'bank-redirect-error');
          assert.equal(error.cause, 'my-error');
          done();
        });
        this.bankRedirect.on('token', assert.fail);

        const frame = this.bankRedirect.start(this.startPayload);
        frame.emit('error', 'my-error');
      });

      it('emit a token if the iframe is done successfully', function (done) {
        this.bankRedirect.on('error', assert.fail);
        this.bankRedirect.on('token', token => {
          assert(token, 'my-token');
          done();
        });

        const frame = this.bankRedirect.start(this.startPayload);
        frame.emit('done', 'my-token');
      });
    });
  });
});
<|endoftext|>


<commit_before>const expect = require('chai').expect;
const Event = require('@antv/g').Event;
const G6 = require('../../../src');

const div = document.createElement('div');
div.id = 'pan-spec';
document.body.appendChild(div);

function createWheelEvent(canvas, delta, x, y) {
  const bbox = canvas.getBoundingClientRect();
  const e = new Event('wheel', {}, false, false);
  e.clientX = bbox.left + x;
  e.clientY = bbox.top + y;
  e.wheelDelta = delta;
  return e;
}

describe.only('zoom-canvas', () => {
  it('zoom canvas', () => {
    const graph = new G6.Graph({
      container: div,
      width: 500,
      height: 500,
      modes: {
        default: [ 'zoom-canvas' ]
      },
      pixelRatio: 2
    });
    const e = createWheelEvent(graph.get('canvas').get('el'), 100, 100, 100);
    graph.emit('wheel', e);
    let matrix = graph.get('group').getMatrix();
    expect(matrix[0]).to.equal(0.75);
    expect(matrix[4]).to.equal(0.75);
    expect(matrix[6]).to.equal(25);
    expect(matrix[7]).to.equal(25);
    graph.emit('wheel', e);
    matrix = graph.get('group').getMatrix();
    expect(matrix[0]).to.equal(0.75 * 0.75);
    expect(matrix[4]).to.equal(0.75 * 0.75);
    expect(matrix[6]).to.equal(100 - 100 * 0.75 * 0.75);
    expect(matrix[7]).to.equal(100 - 100 * 0.75 * 0.75);
    graph.destroy();
  });
  it('max zoom & min zoom', () => {
    const graph = new G6.Graph({
      container: div,
      width: 500,
      height: 500,
      modes: {
        default: [{
          type: 'zoom-canvas',
          maxZoom: 5,
          minZoom: 0.5
        }]
      },
      pixelRatio: 2
    });
    graph.zoom(5);
    let e = createWheelEvent(graph.get('canvas').get('el'), -100, 100, 100);
    graph.emit('wheel', e);
    let matrix = graph.get('group').getMatrix();
    expect(matrix[0]).to.equal(5);
    expect(matrix[4]).to.equal(5);
    graph.zoom(0.1);
    e = createWheelEvent(graph.get('canvas').get('el'), 100, 100, 100);
    graph.emit('wheel', e);
    matrix = graph.get('group').getMatrix();
    expect(matrix[0]).to.equal(0.5);
    expect(matrix[4]).to.equal(0.5);
  });
  it('unbind zoom', () => {
    const graph = new G6.Graph({
      container: div,
      width: 500,
      height: 500,
      modes: {
        default: [ 'zoom-canvas' ],
        custom: []
      },
      pixelRatio: 2
    });
    const e = createWheelEvent(graph.get('canvas').get('el'), -100, 100, 100);
    graph.emit('wheel', e);
    let matrix = graph.get('group').getMatrix();
    expect(matrix[0]).to.equal(1.25);
    expect(matrix[4]).to.equal(1.25);
    expect(matrix[6]).to.equal(-25);
    expect(matrix[7]).to.equal(-25);
    graph.setMode('custom');
    graph.emit('wheel', e);
    matrix = graph.get('group').getMatrix();
    expect(matrix[0]).to.equal(1.25);
    expect(matrix[4]).to.equal(1.25);
    expect(matrix[6]).to.equal(-25);
    expect(matrix[7]).to.equal(-25);
  });
});
<commit_msg>chore(behavior): add unit tests of zoom-canvas<commit_after>const expect = require('chai').expect;
const Event = require('@antv/g').Event;
const G6 = require('../../../src');

const div = document.createElement('div');
div.id = 'pan-spec';
document.body.appendChild(div);

function createWheelEvent(canvas, delta, x, y) {
  const bbox = canvas.getBoundingClientRect();
  const e = new Event('wheel', {}, false, false);
  e.clientX = bbox.left + x;
  e.clientY = bbox.top + y;
  e.wheelDelta = delta;
  return e;
}

describe('zoom-canvas', () => {
  it('zoom canvas', () => {
    const graph = new G6.Graph({
      container: div,
      width: 500,
      height: 500,
      modes: {
        default: [ 'zoom-canvas' ]
      },
      pixelRatio: 2
    });
    const e = createWheelEvent(graph.get('canvas').get('el'), 100, 100, 100);
    graph.emit('wheel', e);
    let matrix = graph.get('group').getMatrix();
    expect(matrix[0]).to.equal(0.75);
    expect(matrix[4]).to.equal(0.75);
    expect(matrix[6]).to.equal(25);
    expect(matrix[7]).to.equal(25);
    graph.emit('wheel', e);
    matrix = graph.get('group').getMatrix();
    expect(matrix[0]).to.equal(0.75 * 0.75);
    expect(matrix[4]).to.equal(0.75 * 0.75);
    expect(matrix[6]).to.equal(100 - 100 * 0.75 * 0.75);
    expect(matrix[7]).to.equal(100 - 100 * 0.75 * 0.75);
    graph.destroy();
  });
  it('max zoom & min zoom', () => {
    const graph = new G6.Graph({
      container: div,
      width: 500,
      height: 500,
      modes: {
        default: [{
          type: 'zoom-canvas',
          maxZoom: 5,
          minZoom: 0.5
        }]
      },
      pixelRatio: 2
    });
    graph.zoom(5);
    let e = createWheelEvent(graph.get('canvas').get('el'), -100, 100, 100);
    graph.emit('wheel', e);
    let matrix = graph.get('group').getMatrix();
    expect(matrix[0]).to.equal(5);
    expect(matrix[4]).to.equal(5);
    graph.zoom(0.1);
    e = createWheelEvent(graph.get('canvas').get('el'), 100, 100, 100);
    graph.emit('wheel', e);
    matrix = graph.get('group').getMatrix();
    expect(matrix[0]).to.equal(0.5);
    expect(matrix[4]).to.equal(0.5);
  });
  it('unbind zoom', () => {
    const graph = new G6.Graph({
      container: div,
      width: 500,
      height: 500,
      modes: {
        default: [ 'zoom-canvas' ],
        custom: []
      },
      pixelRatio: 2
    });
    const e = createWheelEvent(graph.get('canvas').get('el'), -100, 100, 100);
    graph.emit('wheel', e);
    let matrix = graph.get('group').getMatrix();
    expect(matrix[0]).to.equal(1.25);
    expect(matrix[4]).to.equal(1.25);
    expect(matrix[6]).to.equal(-25);
    expect(matrix[7]).to.equal(-25);
    graph.setMode('custom');
    graph.emit('wheel', e);
    matrix = graph.get('group').getMatrix();
    expect(matrix[0]).to.equal(1.25);
    expect(matrix[4]).to.equal(1.25);
    expect(matrix[6]).to.equal(-25);
    expect(matrix[7]).to.equal(-25);
  });
});
<|endoftext|>


<commit_before>const chai = require('chai');
const auth = require('../../../services/auth');

const { expect } = chai;

describe('/services/auth', () => {
  it('should authenticate a vendor', async () => {
    const user = await auth('vendor', 1);
    expect(user.id).to.equal(1);
    expect(user.name).to.equal('vendor 1');
  });

  it('should authenticate a client', async () => {
    const user = await auth('client', 1);
    expect(user.id).to.equal(1);
    expect(user.name).to.equal('client 1');
  });
});
<commit_msg>Auth unit test<commit_after>const chai = require('chai');
const auth = require('../../../services/auth');

const { expect } = chai;

describe('/services/auth', () => {
  it('should authenticate a vendor', async () => {
    const user = await auth('vendor', 1);
    expect(user.id).to.equal(1);
    expect(user.name).to.equal('vendor 1');
  });

  it('should authenticate a client', async () => {
    const user = await auth('client', 1);
    expect(user.id).to.equal(1);
    expect(user.name).to.equal('client 1');
  });

  it('should throw an error calling a non configured method', async () => {
    try {
      await auth('error', 1);
    } catch (error) {
      expect(error.message).to.match(/Authentication method not configured/);
    }
  });
});
<|endoftext|>


<commit_before>#!/usr/bin/env node

/*
  oref0 autotuning data prep tool

  Collects and divides up glucose data for periods dominated by carb absorption,
  correction insulin, or basal insulin, and adds in avgDelta and deviations,
  for use in oref0 autotuning algorithm

  Released under MIT license. See the accompanying LICENSE.txt file for
  full terms and conditions

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.

*/

var generate = require('oref0/lib/autotune-prep');
function usage ( ) {
        console.error('usage: ', process.argv.slice(0, 2), '<pumphistory.json> <profile.json> <glucose.json> [carbhistory.json] [autotune/glucose.json]');
}

if (!module.parent) {
    var pumphistory_input = process.argv.slice(2, 3).pop();
    if ([null, '--help', '-h', 'help'].indexOf(pumphistory_input) > 0) {
      usage( );
      process.exit(0)
    }
    var profile_input = process.argv.slice(3, 4).pop();
    var glucose_input = process.argv.slice(4, 5).pop();
    var carb_input = process.argv.slice(5, 6).pop()
    var prepped_glucose_input = process.argv.slice(6, 7).pop()

    if ( !pumphistory_input || !profile_input || !glucose_input ) {
        usage( );
        console.log('{ "error": "Insufficient arguments" }');
        process.exit(1);
    }

    var fs = require('fs');
    try {
        var pumphistory_data = JSON.parse(fs.readFileSync(pumphistory_input, 'utf8'));
        var profile_data = JSON.parse(fs.readFileSync(profile_input, 'utf8'));
    } catch (e) {
        console.log('{ "error": "Could not parse input data" }');
        return console.error("Could not parse input data: ", e);
    }

    // if carb_ratio is null buy we have a valid carb_ratios object, use that
    if (! profile.carb_ratio && profile.carb_ratios.schedule[0].ratio) {
        profile.carb_ratio = profile.carb_ratios.schedule[0].ratio
    }

    // disallow impossibly low carbRatios due to bad decoding
    if ( typeof(profile_data.carb_ratio) == 'undefined' || profile_data.carb_ratio < 2 ) {
        console.log('{ "carbs": 0, "mealCOB": 0, "reason": "carb_ratio ' + profile_data.carb_ratio + ' out of bounds" }');
        return console.error("Error: carb_ratio " + profile_data.carb_ratio + " out of bounds");
    }

    try {
        var glucose_data = JSON.parse(fs.readFileSync(glucose_input, 'utf8'));
    } catch (e) {
        console.error("Warning: could not parse "+glucose_input);
    }

    var carb_data = { };
    if (typeof carb_input != 'undefined') {
        try {
            carb_data = JSON.parse(fs.readFileSync(carb_input, 'utf8'));
        } catch (e) {
            console.error("Warning: could not parse "+carb_input);
        }
    }
    var prepped_glucose_data = { };
    if (typeof prepped_glucose_input != 'undefined') {
        try {
            carb_data = JSON.parse(fs.readFileSync(prepped_glucose_input, 'utf8'));
        } catch (e) {
            console.error("Warning: could not parse "+prepped_glucose_input);
        }
    }

    var inputs = {
        history: pumphistory_data
    , profile: profile_data
    , carbs: carb_data
    , glucose: glucose_data
    , prepped_glucose: prepped_glucose_data
    };

    var prepped_glucose = generate(inputs);
    console.log(JSON.stringify(prepped_glucose));
}

<commit_msg>variable name<commit_after>#!/usr/bin/env node

/*
  oref0 autotuning data prep tool

  Collects and divides up glucose data for periods dominated by carb absorption,
  correction insulin, or basal insulin, and adds in avgDelta and deviations,
  for use in oref0 autotuning algorithm

  Released under MIT license. See the accompanying LICENSE.txt file for
  full terms and conditions

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.

*/

var generate = require('oref0/lib/autotune-prep');
function usage ( ) {
        console.error('usage: ', process.argv.slice(0, 2), '<pumphistory.json> <profile.json> <glucose.json> [carbhistory.json] [autotune/glucose.json]');
}

if (!module.parent) {
    var pumphistory_input = process.argv.slice(2, 3).pop();
    if ([null, '--help', '-h', 'help'].indexOf(pumphistory_input) > 0) {
      usage( );
      process.exit(0)
    }
    var profile_input = process.argv.slice(3, 4).pop();
    var glucose_input = process.argv.slice(4, 5).pop();
    var carb_input = process.argv.slice(5, 6).pop()
    var prepped_glucose_input = process.argv.slice(6, 7).pop()

    if ( !pumphistory_input || !profile_input || !glucose_input ) {
        usage( );
        console.log('{ "error": "Insufficient arguments" }');
        process.exit(1);
    }

    var fs = require('fs');
    try {
        var pumphistory_data = JSON.parse(fs.readFileSync(pumphistory_input, 'utf8'));
        var profile_data = JSON.parse(fs.readFileSync(profile_input, 'utf8'));
    } catch (e) {
        console.log('{ "error": "Could not parse input data" }');
        return console.error("Could not parse input data: ", e);
    }

    // if carb_ratio is null buy we have a valid carb_ratios object, use that
    if (! profile_data.carb_ratio && profile_data.carb_ratios.schedule[0].ratio) {
        profile_data.carb_ratio = profile_data.carb_ratios.schedule[0].ratio
    }

    // disallow impossibly low carbRatios due to bad decoding
    if ( typeof(profile_data.carb_ratio) == 'undefined' || profile_data.carb_ratio < 2 ) {
        console.log('{ "carbs": 0, "mealCOB": 0, "reason": "carb_ratio ' + profile_data.carb_ratio + ' out of bounds" }');
        return console.error("Error: carb_ratio " + profile_data.carb_ratio + " out of bounds");
    }

    try {
        var glucose_data = JSON.parse(fs.readFileSync(glucose_input, 'utf8'));
    } catch (e) {
        console.error("Warning: could not parse "+glucose_input);
    }

    var carb_data = { };
    if (typeof carb_input != 'undefined') {
        try {
            carb_data = JSON.parse(fs.readFileSync(carb_input, 'utf8'));
        } catch (e) {
            console.error("Warning: could not parse "+carb_input);
        }
    }
    var prepped_glucose_data = { };
    if (typeof prepped_glucose_input != 'undefined') {
        try {
            carb_data = JSON.parse(fs.readFileSync(prepped_glucose_input, 'utf8'));
        } catch (e) {
            console.error("Warning: could not parse "+prepped_glucose_input);
        }
    }

    var inputs = {
        history: pumphistory_data
    , profile: profile_data
    , carbs: carb_data
    , glucose: glucose_data
    , prepped_glucose: prepped_glucose_data
    };

    var prepped_glucose = generate(inputs);
    console.log(JSON.stringify(prepped_glucose));
}

<|endoftext|>


<commit_before>$.ajaxSetup({cache: false});
CKEDITOR.disableAutoInline = true;

$(document).ready(function () {
    new Imcms.Bootstrapper().bootstrap(Imcms.isEditMode);
});

$(document).ajaxError(function (event, jqxhr) {
    Imcms.BackgroundWorker.closeProcessWindow();
    console.log(jqxhr);
});
<commit_msg>IMCMS-150 - Rewrite js hell in imCMS and use AMD mechanism: - Imcms start module refactored.<commit_after>(function (Imcms) {
    $.ajaxSetup({cache: false});
    CKEDITOR.disableAutoInline = true;

    $(document).ready(function () {
        new Imcms.Bootstrapper().bootstrap(Imcms.isEditMode);
    });

    $(document).ajaxError(function (event, jqxhr) {
        Imcms.BackgroundWorker.closeProcessWindow();
        console.log(jqxhr);
    });

    return Imcms;
})(Imcms);
<|endoftext|>


<commit_before>define([
    'events/messages',
    'text!fixtures/chat.active.html',
    'text!fixtures/chat.message.html'
], function (
    messages,
    chatActiveFixture,
    chatMessageFixture
) {

    'use strict';

    var storageMock;

    var resourceMessageMock;

    var renderMessageMock;

    var renderSystemMessageMock;

    beforeEach(function() {
        // storage mock
        storageMock = {
            removeData: function(key) {

            },
            removeAllData: function() {

            },
            addData: function(key, data) {

            },
            setData:     function(key, data) {

            },
            getData: function(key) {

            },
            getChatToken: function() {

            }
        };
        messages._storage = storageMock;

        // resource mock
        resourceMessageMock = {
            postMessage: function(msg, eventOptions) {

            },

            getMessage: function(eventOptions) {

            },

            deleteMessage: function(data, eventOptions) {

            }
        };
        messages._messages = resourceMessageMock;

        // dom element mock
        setFixtures(chatActiveFixture);
        messages.options.chatBodyDom = $j('#chat-body');
        messages.options.chatTypeDom = $j('#chat-type textarea');

        // render message mock
        renderMessageMock = {
            render: function(msg, date, msgSource) {

            }
        };
        messages._renderMessages = renderMessageMock;

        // render system message mock
        renderSystemMessageMock = {
            render: function(msg) {

            }
        };
        messages._renderSystemMessages = renderSystemMessageMock;
    });

    describe('Event->Messages->postMessage', function () {

        it('should reject posting empty message', function () {
            var messageVal = '  ';

            // message text
            spyOn(messages.options.chatTypeDom, 'val').and.returnValue(messageVal);

            // resource message mock
            spyOn(resourceMessageMock, 'postMessage');

            messages.postMessage();
            expect(resourceMessageMock.postMessage.calls.count()).toEqual(0);
        });

        it('should post message', function () {
            var messageVal = 'message';

            // message text
            spyOn(messages.options.chatTypeDom, 'val').and.returnValue(messageVal);

            // resource message mock
            spyOn(resourceMessageMock, 'postMessage');

            messages.postMessage();
            expect(resourceMessageMock.postMessage.calls.count()).toEqual(1);
            expect(resourceMessageMock.postMessage.calls.argsFor(0)).toEqual([messageVal, {
                manager: messages.options.chatBodyDom,
                event:  'showPostedMessage'
            }]);
        });
    });

    describe('Event->Messages->getMessage', function () {

        it('should get messages', function () {
            // resource message mock
            spyOn(resourceMessageMock, 'getMessage');

            messages.getMessage();
            expect(resourceMessageMock.getMessage.calls.count()).toEqual(1);
            expect(resourceMessageMock.getMessage.calls.argsFor(0)).toEqual([{
                manager: messages.options.chatBodyDom,
                event:  'showReceivedMessage'
            }]);
        });
    });

    describe('Event->Messages->deleteMessage', function () {

        it('should delete messages', function () {
            var eventMock = {},
                data = [{
                    "_id": "5845301c55e4307073b4028d",
                    "msg": "Hi, how are you doing?",
                    "system": false

                }];

            // resource message mock
            spyOn(resourceMessageMock, 'deleteMessage');

            messages.deleteMessage(eventMock, data);
            expect(resourceMessageMock.deleteMessage.calls.count()).toEqual(1);
            expect(resourceMessageMock.deleteMessage.calls.argsFor(0)).toEqual([
                {
                    data: {
                        messages: [{'_id': data[0]['_id']}]
                    }
                }, {
                    manager: messages.options.chatBodyDom,
                    event:  'showDeletedMessage'
            }]);
        });
    });

    describe('Event->Messages->showPostedMessage', function () {

        it('should show posted messages', function () {
            var eventMock = {},
                request = {
                    data: {
                        messages: [{
                            msg: 'Hello SFChat!'
                        }]
                    }
                },
                response = {
                    results: {
                        code: 200
                    }
                };

            // message text
            spyOn(messages.options.chatTypeDom, 'val');
            spyOn(messages.options.chatBodyDom, 'trigger');

            // render message mock
            spyOn(renderMessageMock, 'render').and.returnValue($j(chatMessageFixture));

            // render system message mock
            spyOn(renderSystemMessageMock, 'render');

            // storage mock
            spyOn(storageMock, 'addData');

            messages.showPostedMessage(eventMock, request, response);
            expect(messages.options.chatTypeDom.val.calls.count()).toEqual(1);
            expect(messages.options.chatTypeDom.val.calls.argsFor(0)).toEqual(['']);

            expect(messages.options.chatBodyDom.trigger.calls.count()).toEqual(1);
            expect(messages.options.chatBodyDom.trigger.calls.argsFor(0)).toEqual(['clearTitle']);

            expect(renderMessageMock.render.calls.count()).toEqual(1);
            expect(renderSystemMessageMock.render.calls.count()).toEqual(0);

            expect(storageMock.addData.calls.count()).toEqual(1);
        });

        it('should show system messages', function () {
            var eventMock = {},
                request = {
                    data: {
                        messages: [{
                            msg: 'Hello SFChat!',
                            system: true
                        }]
                    }
                },
                response = {
                    results: {
                        code: 200
                    }
                };

            // message text
            spyOn(messages.options.chatTypeDom, 'val');
            spyOn(messages.options.chatBodyDom, 'trigger');

            // render message mock
            spyOn(renderMessageMock, 'render');

            // render system message mock
            spyOn(renderSystemMessageMock, 'render').and.returnValue($j(chatMessageFixture));

            // storage mock
            spyOn(storageMock, 'addData');

            messages.showPostedMessage(eventMock, request, response);
            expect(messages.options.chatTypeDom.val.calls.count()).toEqual(1);
            expect(messages.options.chatTypeDom.val.calls.argsFor(0)).toEqual(['']);

            expect(messages.options.chatBodyDom.trigger.calls.count()).toEqual(1);
            expect(messages.options.chatBodyDom.trigger.calls.argsFor(0)).toEqual(['clearTitle']);

            expect(renderMessageMock.render.calls.count()).toEqual(0);
            expect(renderSystemMessageMock.render.calls.count()).toEqual(1);

            expect(storageMock.addData.calls.count()).toEqual(1);
        });

        it('should throw error', function () {
            var eventMock = {},
                request = {
                    data: {
                        messages: [{
                            msg: 'Hello SFChat!',
                            system: true
                        }]
                    }
                },
                response = {
                    results: {
                        code: 500
                    }
                };

            // message text
            spyOn(messages.options.chatTypeDom, 'val');
            spyOn(messages.options.chatBodyDom, 'trigger');

            // render message mock
            spyOn(renderMessageMock, 'render');

            // render system message mock
            spyOn(renderSystemMessageMock, 'render');

            // storage mock
            spyOn(storageMock, 'addData');

            expect(function() {
                messages.showPostedMessage(eventMock, request, response);
            }).toThrowError();
            expect(messages.options.chatTypeDom.val.calls.count()).toEqual(0);
            expect(messages.options.chatBodyDom.trigger.calls.count()).toEqual(0);

            expect(renderMessageMock.render.calls.count()).toEqual(0);
            expect(renderSystemMessageMock.render.calls.count()).toEqual(0);

            expect(storageMock.addData.calls.count()).toEqual(0);
        });
    });
});
<commit_msg>Added unti tests for events/messages:showReceivedMessage<commit_after>define([
    'events/messages',
    'text!fixtures/chat.active.html',
    'text!fixtures/chat.message.html'
], function (
    messages,
    chatActiveFixture,
    chatMessageFixture
) {

    'use strict';

    var storageMock;

    var resourceMessageMock;

    var renderMessageMock;

    var renderSystemMessageMock;

    beforeEach(function() {
        // storage mock
        storageMock = {
            removeData: function(key) {

            },
            removeAllData: function() {

            },
            addData: function(key, data) {

            },
            setData:     function(key, data) {

            },
            getData: function(key) {

            },
            getChatToken: function() {

            }
        };
        messages._storage = storageMock;

        // resource mock
        resourceMessageMock = {
            postMessage: function(msg, eventOptions) {

            },

            getMessage: function(eventOptions) {

            },

            deleteMessage: function(data, eventOptions) {

            }
        };
        messages._messages = resourceMessageMock;

        // dom element mock
        setFixtures(chatActiveFixture);
        messages.options.chatBodyDom = $j('#chat-body');
        messages.options.chatTypeDom = $j('#chat-type textarea');

        // render message mock
        renderMessageMock = {
            render: function(msg, date, msgSource) {

            }
        };
        messages._renderMessages = renderMessageMock;

        // render system message mock
        renderSystemMessageMock = {
            render: function(msg) {

            }
        };
        messages._renderSystemMessages = renderSystemMessageMock;
    });

    describe('Event->Messages->postMessage', function () {

        it('should reject posting empty message', function () {
            var messageVal = '  ';

            // message text
            spyOn(messages.options.chatTypeDom, 'val').and.returnValue(messageVal);

            // resource message mock
            spyOn(resourceMessageMock, 'postMessage');

            messages.postMessage();
            expect(resourceMessageMock.postMessage.calls.count()).toEqual(0);
        });

        it('should post message', function () {
            var messageVal = 'message';

            // message text
            spyOn(messages.options.chatTypeDom, 'val').and.returnValue(messageVal);

            // resource message mock
            spyOn(resourceMessageMock, 'postMessage');

            messages.postMessage();
            expect(resourceMessageMock.postMessage.calls.count()).toEqual(1);
            expect(resourceMessageMock.postMessage.calls.argsFor(0)).toEqual([messageVal, {
                manager: messages.options.chatBodyDom,
                event:  'showPostedMessage'
            }]);
        });
    });

    describe('Event->Messages->getMessage', function () {

        it('should get messages', function () {
            // resource message mock
            spyOn(resourceMessageMock, 'getMessage');

            messages.getMessage();
            expect(resourceMessageMock.getMessage.calls.count()).toEqual(1);
            expect(resourceMessageMock.getMessage.calls.argsFor(0)).toEqual([{
                manager: messages.options.chatBodyDom,
                event:  'showReceivedMessage'
            }]);
        });
    });

    describe('Event->Messages->deleteMessage', function () {

        it('should delete messages', function () {
            var eventMock = {},
                data = [{
                    "_id": "5845301c55e4307073b4028d",
                    "msg": "Hi, how are you doing?",
                    "system": false

                }];

            // resource message mock
            spyOn(resourceMessageMock, 'deleteMessage');

            messages.deleteMessage(eventMock, data);
            expect(resourceMessageMock.deleteMessage.calls.count()).toEqual(1);
            expect(resourceMessageMock.deleteMessage.calls.argsFor(0)).toEqual([
                {
                    data: {
                        messages: [{'_id': data[0]['_id']}]
                    }
                }, {
                    manager: messages.options.chatBodyDom,
                    event:  'showDeletedMessage'
            }]);
        });
    });

    describe('Event->Messages->showPostedMessage', function () {

        it('should show posted messages', function () {
            var eventMock = {},
                request = {
                    data: {
                        messages: [{
                            msg: 'Hello SFChat!'
                        }]
                    }
                },
                response = {
                    results: {
                        code: 200
                    }
                };

            // message text
            spyOn(messages.options.chatTypeDom, 'val');
            spyOn(messages.options.chatBodyDom, 'trigger');

            // render message mock
            spyOn(renderMessageMock, 'render').and.returnValue($j(chatMessageFixture));

            // render system message mock
            spyOn(renderSystemMessageMock, 'render');

            // storage mock
            spyOn(storageMock, 'addData');

            messages.showPostedMessage(eventMock, request, response);
            expect(messages.options.chatTypeDom.val.calls.count()).toEqual(1);
            expect(messages.options.chatTypeDom.val.calls.argsFor(0)).toEqual(['']);

            expect(messages.options.chatBodyDom.trigger.calls.count()).toEqual(1);
            expect(messages.options.chatBodyDom.trigger.calls.argsFor(0)).toEqual(['clearTitle']);

            expect(renderMessageMock.render.calls.count()).toEqual(1);
            expect(renderSystemMessageMock.render.calls.count()).toEqual(0);

            expect(storageMock.addData.calls.count()).toEqual(1);
        });

        it('should show system messages', function () {
            var eventMock = {},
                request = {
                    data: {
                        messages: [{
                            msg: 'Hello SFChat!',
                            system: true
                        }]
                    }
                },
                response = {
                    results: {
                        code: 200
                    }
                };

            // message text
            spyOn(messages.options.chatTypeDom, 'val');
            spyOn(messages.options.chatBodyDom, 'trigger');

            // render message mock
            spyOn(renderMessageMock, 'render');

            // render system message mock
            spyOn(renderSystemMessageMock, 'render').and.returnValue($j(chatMessageFixture));

            // storage mock
            spyOn(storageMock, 'addData');

            messages.showPostedMessage(eventMock, request, response);
            expect(messages.options.chatTypeDom.val.calls.count()).toEqual(1);
            expect(messages.options.chatTypeDom.val.calls.argsFor(0)).toEqual(['']);

            expect(messages.options.chatBodyDom.trigger.calls.count()).toEqual(1);
            expect(messages.options.chatBodyDom.trigger.calls.argsFor(0)).toEqual(['clearTitle']);

            expect(renderMessageMock.render.calls.count()).toEqual(0);
            expect(renderSystemMessageMock.render.calls.count()).toEqual(1);

            expect(storageMock.addData.calls.count()).toEqual(1);
        });

        it('should throw error', function () {
            var eventMock = {},
                request = {
                    data: {
                        messages: [{
                            msg: 'Hello SFChat!',
                            system: true
                        }]
                    }
                },
                response = {
                    results: {
                        code: 500
                    }
                };

            // message text
            spyOn(messages.options.chatTypeDom, 'val');
            spyOn(messages.options.chatBodyDom, 'trigger');

            // render message mock
            spyOn(renderMessageMock, 'render');

            // render system message mock
            spyOn(renderSystemMessageMock, 'render');

            // storage mock
            spyOn(storageMock, 'addData');

            expect(function() {
                messages.showPostedMessage(eventMock, request, response);
            }).toThrowError();
            expect(messages.options.chatTypeDom.val.calls.count()).toEqual(0);
            expect(messages.options.chatBodyDom.trigger.calls.count()).toEqual(0);

            expect(renderMessageMock.render.calls.count()).toEqual(0);
            expect(renderSystemMessageMock.render.calls.count()).toEqual(0);

            expect(storageMock.addData.calls.count()).toEqual(0);
        });
    });

    describe('Event->Messages->showReceivedMessage', function () {
        it('should start long-polling', function () {
            var eventMock = {},
                request = {
                    data: {
                        messages: []
                    }
                },
                response = {
                    results: {
                        code: 200,
                        messages: [],
                        status: 'ready'
                    }
                };

            // message text
            spyOn(messages.options.chatBodyDom, 'trigger');

            messages.showReceivedMessage(eventMock, request, response);
            expect(messages.options.chatBodyDom.trigger.calls.count()).toEqual(1);
            expect(messages.options.chatBodyDom.trigger.calls.argsFor(0)).toEqual(['getMessage']);

        });

         it('should show messages', function () {
                 var eventMock = {},
                request = {
                    data: {
                        messages: []
                    }
                },
                response = {
                    results: {
                        code: 200,
                        messages: [{
                            _id: "5845301c55e4307073b4028d",
                            msg: 'Hello SFChat!',
                            system: false
                        }, {
                            _id: "5845301c55e4307073b40288",
                            msg: 'Hello SFChat!',
                            system: true
                        }],
                        status: 'ready'
                    }
                };

                // render message mock
                spyOn(renderMessageMock, 'render').and.returnValue($j(chatMessageFixture));

                // render system message mock
                spyOn(renderSystemMessageMock, 'render').and.returnValue($j(chatMessageFixture));

                // storage mock
                spyOn(storageMock, 'addData');

                 // message text
                spyOn(messages.options.chatBodyDom, 'trigger');

                messages.showReceivedMessage(eventMock, request, response);
                expect(renderMessageMock.render.calls.count()).toEqual(1);
                expect(renderSystemMessageMock.render.calls.count()).toEqual(1);

                expect(storageMock.addData.calls.count()).toEqual(2);

                expect(messages.options.chatBodyDom.trigger.calls.count()).toEqual(3);
                expect(messages.options.chatBodyDom.trigger.calls.argsFor(0)).toEqual(['showTitle', [response.results.messages.length]]);
                expect(messages.options.chatBodyDom.trigger.calls.argsFor(1)).toEqual(['deleteMessage', [response.results.messages]]);
                expect(messages.options.chatBodyDom.trigger.calls.argsFor(2)).toEqual(['setChatStatus', [response.results.status]]);
         });

        it('should show closed chat messages', function () {
                 var eventMock = {},
                request = {
                    data: {
                        messages: []
                    }
                },
                response = {
                    results: {
                        code: 200,
                        messages: [{
                            _id: "5845301c55e4307073b4028d",
                            msg: 'Hello SFChat!',
                            system: false
                        }, {
                            _id: "5845301c55e4307073b40288",
                            msg: 'Hello SFChat!',
                            system: true
                        }],
                        status: 'closed'
                    }
                };

                // render message mock
                spyOn(renderMessageMock, 'render').and.returnValue($j(chatMessageFixture));

                // render system message mock
                spyOn(renderSystemMessageMock, 'render').and.returnValue($j(chatMessageFixture));

                // storage mock
                spyOn(storageMock, 'addData');

                 // message text
                spyOn(messages.options.chatBodyDom, 'trigger');

                messages.showReceivedMessage(eventMock, request, response);
                expect(renderMessageMock.render.calls.count()).toEqual(1);
                expect(renderSystemMessageMock.render.calls.count()).toEqual(1);

                expect(storageMock.addData.calls.count()).toEqual(2);

                expect(messages.options.chatBodyDom.trigger.calls.count()).toEqual(1);
                expect(messages.options.chatBodyDom.trigger.calls.argsFor(0)).toEqual(['setChatStatus', [response.results.status]]);
        });

        it('should throw error', function () {
            var eventMock = {},
                request = {
                    data: {
                        messages: []
                    }
                },
                response = {
                    results: {
                        messages: [],
                        code: 500
                    }
                };

            // message text
            spyOn(messages.options.chatBodyDom, 'trigger');

            // render message mock
            spyOn(renderMessageMock, 'render');

            // render system message mock
            spyOn(renderSystemMessageMock, 'render');

            // storage mock
            spyOn(storageMock, 'addData');

            expect(function() {
                messages.showReceivedMessage(eventMock, request, response);
            }).toThrowError();
            expect(messages.options.chatBodyDom.trigger.calls.count()).toEqual(0);

            expect(renderMessageMock.render.calls.count()).toEqual(0);
            expect(renderSystemMessageMock.render.calls.count()).toEqual(0);

            expect(storageMock.addData.calls.count()).toEqual(0);
        });
    });
});
<|endoftext|>


<commit_before>// The id will be the tag string.
App.Tag = DS.Model.extend({
    url: 'utils/tags',
    // Hack to make sure that newly added tags won't conflict when they are saved embedded.
    loadedData: function() {
        if (this.get('isDirty') === false) {
            this._super.apply(this, arguments);
        }
    }
});

<commit_msg>Avoid putting tags<commit_after>// The id will be the tag string.
App.Tag = DS.Model.extend({
    url: 'utils/tags',

    // Hack to make sure that newly added tags won't conflict when they are saved embedded.
    loadedData: function() {
        if (this.get('isDirty') === false) {
            this._super.apply(this, arguments);
        }
    },

    unDirtySoWeNeverCommit: function(){
        // Ugly fix to avoid putting tags
        if (this.get('isDirty')){
           this.transitionTo('loaded.created.uncommitted');
        }
    }.observes('isDirty')

});

<|endoftext|>


<commit_before>import { test } from 'qunit';
import moduleForAcceptance from 'cargo/tests/helpers/module-for-acceptance';

moduleForAcceptance('Acceptance | search');

test('searching for "rust"', function(assert) {
    visit('/');
    fillIn('input.search', 'rust');
    andThen(function() {
        findWithAssert('form.search').submit();
    });
    wait();

    andThen(function() {
        assert.equal(currentURL(), '/search?q=rust');
        assert.equal(document.title, 'Search Results for \'rust\' - Cargo: packages for Rust');

        findWithAssert('a[href="/search?page=2&q=rust"]');
        assert.notOk(find('a[href="/search?page=3&q=rust"]')[0]);

        hasText(assert, '#crates-heading', 'Search Results for \'rust\'');
        hasText(assert, '#results', 'Displaying 1-10 of 18 total results Sort by Relevance Relevance Downloads');

        hasText(assert, '#crates .row:first .desc .info', 'rust_mixin');
        findWithAssert('#crates .row:first .desc .info .vers img[alt="0.0.1"]');

        findWithAssert('#crates .row:first .desc .info .badge:first a img[src="https://ci.appveyor.com/api/projects/status/github/huonw/external_mixin?svg=true&branch=master"]');
        findWithAssert('#crates .row:first .desc .info .badge:eq(1) a img[src="https://travis-ci.org/huonw/external_mixin.svg?branch=master"]');

        hasText(assert, '#crates .row:first .desc .summary', 'Yo dawg, use Rust to generate Rust, right in your Rust. (See `external_mixin` to use scripting languages.)');
        hasText(assert, '#crates .row:first .downloads', '477');
    });
    click('a[href="/search?page=2&q=rust"]');

    andThen(function() {
        assert.equal(currentURL(), '/search?page=2&q=rust');
        assert.equal(document.title, 'Search Results for \'rust\' - Cargo: packages for Rust');

        findWithAssert('a[href="/search?q=rust"]');
        assert.notOk(find('a[href="/search?page=3&q=rust"]')[0]);

        hasText(assert, '#crates-heading', 'Search Results for \'rust\'');
        hasText(assert, '#results', 'Displaying 11-18 of 18 total results Sort by Relevance Relevance Downloads');

        hasText(assert, '#crates .row:first .desc .info', 'rusted_cypher');
        findWithAssert('#crates .row:first .desc .info .vers img[alt="0.7.1"]');
    });
});
<commit_msg>Add extra URL tests to badges<commit_after>import { test } from 'qunit';
import moduleForAcceptance from 'cargo/tests/helpers/module-for-acceptance';

moduleForAcceptance('Acceptance | search');

test('searching for "rust"', function(assert) {
    visit('/');
    fillIn('input.search', 'rust');
    andThen(function() {
        findWithAssert('form.search').submit();
    });
    wait();

    andThen(function() {
        assert.equal(currentURL(), '/search?q=rust');
        assert.equal(document.title, 'Search Results for \'rust\' - Cargo: packages for Rust');

        findWithAssert('a[href="/search?page=2&q=rust"]');
        assert.notOk(find('a[href="/search?page=3&q=rust"]')[0]);

        hasText(assert, '#crates-heading', 'Search Results for \'rust\'');
        hasText(assert, '#results', 'Displaying 1-10 of 18 total results Sort by Relevance Relevance Downloads');

        hasText(assert, '#crates .row:first .desc .info', 'rust_mixin');
        findWithAssert('#crates .row:first .desc .info .vers img[alt="0.0.1"]');

        findWithAssert('#crates .row:first .desc .info .badge:first a[href="https://ci.appveyor.com/project/huonw/external_mixin"]');
        findWithAssert('#crates .row:first .desc .info .badge:first a img[src="https://ci.appveyor.com/api/projects/status/github/huonw/external_mixin?svg=true&branch=master"]');
        findWithAssert('#crates .row:first .desc .info .badge:eq(1) a[href="https://travis-ci.org/huonw/external_mixin"]');
        findWithAssert('#crates .row:first .desc .info .badge:eq(1) a img[src="https://travis-ci.org/huonw/external_mixin.svg?branch=master"]');

        hasText(assert, '#crates .row:first .desc .summary', 'Yo dawg, use Rust to generate Rust, right in your Rust. (See `external_mixin` to use scripting languages.)');
        hasText(assert, '#crates .row:first .downloads', '477');
    });
    click('a[href="/search?page=2&q=rust"]');

    andThen(function() {
        assert.equal(currentURL(), '/search?page=2&q=rust');
        assert.equal(document.title, 'Search Results for \'rust\' - Cargo: packages for Rust');

        findWithAssert('a[href="/search?q=rust"]');
        assert.notOk(find('a[href="/search?page=3&q=rust"]')[0]);

        hasText(assert, '#crates-heading', 'Search Results for \'rust\'');
        hasText(assert, '#results', 'Displaying 11-18 of 18 total results Sort by Relevance Relevance Downloads');

        hasText(assert, '#crates .row:first .desc .info', 'rusted_cypher');
        findWithAssert('#crates .row:first .desc .info .vers img[alt="0.7.1"]');
    });
});
<|endoftext|>


<commit_before>import { test } from 'qunit';
import moduleForAcceptance from 'cargo/tests/helpers/module-for-acceptance';

moduleForAcceptance('Acceptance | search');

test('searching for "rust"', function(assert) {
    visit('/');
    fillIn('input.search', 'rust');
    andThen(function() {
        findWithAssert('form.search').submit();
    });
    wait();

    andThen(function() {
        assert.equal(currentURL(), '/search?q=rust');
        assert.equal(document.title, 'Search Results for \'rust\' - Cargo: packages for Rust');

        findWithAssert('a[href="/search?page=2&q=rust"]');
        assert.notOk(find('a[href="/search?page=3&q=rust"]')[0]);

        hasText(assert, '#crates-heading', 'Search Results for \'rust\'');
        hasText(assert, '#results', 'Displaying 1-10 of 18 total results Sort by Relevance Relevance Downloads');

        hasText(assert, '#crates .row:first .desc .info', 'rust_mixin 0.0.1');
        hasText(assert, '#crates .row:first .desc .summary', 'Yo dawg, use Rust to generate Rust, right in your Rust. (See `external_mixin` to use scripting languages.)');
        hasText(assert, '#crates .row:first .downloads', '477');
    });
    click('a[href="/search?page=2&q=rust"]');

    andThen(function() {
        assert.equal(currentURL(), '/search?page=2&q=rust');
        assert.equal(document.title, 'Search Results for \'rust\' - Cargo: packages for Rust');

        findWithAssert('a[href="/search?q=rust"]');
        assert.notOk(find('a[href="/search?page=3&q=rust"]')[0]);

        hasText(assert, '#crates-heading', 'Search Results for \'rust\'');
        hasText(assert, '#results', 'Displaying 11-18 of 18 total results Sort by Relevance Relevance Downloads');

        hasText(assert, '#crates .row:first .desc .info', 'rusted_cypher 0.7.1');
    });
});
<commit_msg>Fix the frontend search test looking for the version<commit_after>import { test } from 'qunit';
import moduleForAcceptance from 'cargo/tests/helpers/module-for-acceptance';

moduleForAcceptance('Acceptance | search');

test('searching for "rust"', function(assert) {
    visit('/');
    fillIn('input.search', 'rust');
    andThen(function() {
        findWithAssert('form.search').submit();
    });
    wait();

    andThen(function() {
        assert.equal(currentURL(), '/search?q=rust');
        assert.equal(document.title, 'Search Results for \'rust\' - Cargo: packages for Rust');

        findWithAssert('a[href="/search?page=2&q=rust"]');
        assert.notOk(find('a[href="/search?page=3&q=rust"]')[0]);

        hasText(assert, '#crates-heading', 'Search Results for \'rust\'');
        hasText(assert, '#results', 'Displaying 1-10 of 18 total results Sort by Relevance Relevance Downloads');

        hasText(assert, '#crates .row:first .desc .info', 'rust_mixin');
        findWithAssert('#crates .row:first .desc .info .vers img[alt="0.0.1"]');
        hasText(assert, '#crates .row:first .desc .summary', 'Yo dawg, use Rust to generate Rust, right in your Rust. (See `external_mixin` to use scripting languages.)');
        hasText(assert, '#crates .row:first .downloads', '477');
    });
    click('a[href="/search?page=2&q=rust"]');

    andThen(function() {
        assert.equal(currentURL(), '/search?page=2&q=rust');
        assert.equal(document.title, 'Search Results for \'rust\' - Cargo: packages for Rust');

        findWithAssert('a[href="/search?q=rust"]');
        assert.notOk(find('a[href="/search?page=3&q=rust"]')[0]);

        hasText(assert, '#crates-heading', 'Search Results for \'rust\'');
        hasText(assert, '#results', 'Displaying 11-18 of 18 total results Sort by Relevance Relevance Downloads');

        hasText(assert, '#crates .row:first .desc .info', 'rusted_cypher');
        findWithAssert('#crates .row:first .desc .info .vers img[alt="0.7.1"]');
    });
});
<|endoftext|>


<commit_before>/* @TODO Enable 'use strict', remove all these globals */
/* global describe, xit, it, jsPDF, comparePdf, ComboBox, ListBox, PushButton, CheckBox, TextField, PasswordField, RadioButton, AcroForm */
/**
 * Acroform testing
 */

describe('Acroform', function () {

  it('ComboBox', function () {
    var doc = jsPDF()
    doc.setFontSize(12)
    doc.text(10, 105, 'ComboBox:')

    var d = new ComboBox()
    d.T = 'ChoiceField1'
    d.TI = 1
    d.Rect = [50, 100, 30, 10]
    d.Opt = '[(a)(b)(c)]'
    d.V = '(b)'
    d.DV = '(b)'
    doc.addField(d)

    comparePdf(doc.output(), 'combobox.pdf', 'acroform')
  })

  it('should add a CheckBox', function () {
    var doc = jsPDF()
    doc.text(10, 125, 'CheckBox:')
    var checkBox = new CheckBox()
    checkBox.T = 'CheckBox1'
    checkBox.Rect = [50, 120, 30, 10]
    doc.addField(checkBox)

    comparePdf(doc.output(), 'checkbox.pdf', 'acroform')
  })

  it('should add a ListBox', function () {
    var doc = jsPDF()
    doc.setFontSize(12)
    doc.text(10, 115, 'ListBox:')
    var d2 = new ListBox()
    d2.edit = false
    d2.T = 'ChoiceField2'
    d2.TI = 2
    d2.Rect = [50, 110, 30, 10]
    d2.Opt = '[(c)(a)(d)(f)(b)(s)]'
    d2.V = '(s)'
    d2.BG = [0, 1, 1]
    doc.addField(d2)

    comparePdf(doc.output(), 'listbox.pdf', 'acroform')
  })

  it('should add a PushButton', function () {
    var doc = jsPDF()
    doc.text(10, 135, 'PushButton:')
    var pushButton = new PushButton()
    pushButton.T = 'PushButton1'
    pushButton.Rect = [50, 130, 30, 10]
    pushButton.BG = [1, 0, 0]
    doc.addField(pushButton)

    comparePdf(doc.output(), 'pushbutton.pdf', 'acroform')
  })

  it('should add a TextField', function () {
    var doc = jsPDF()
    doc.text(10, 145, 'TextField:')
    var textField = new TextField()
    textField.Rect = [50, 140, 30, 10]
    textField.multiline = true
    textField.V = 'The quick brown fox ate the lazy mouse The quick brown fox ate the lazy mouse The quick brown fox ate the lazy mouse'//
    textField.T = 'TestTextBox'
     // textField.Q = 2; // Text-Alignment
    doc.addField(textField)

    comparePdf(doc.output(), 'textfield.pdf', 'acroform')
  })

  it('should add a Password', function () {
    var doc = jsPDF()
    doc.text(10, 155, 'Password:')
    var passwordField = new PasswordField()
    passwordField.Rect = [50, 150, 30, 10]
    doc.addField(passwordField)

    comparePdf(doc.output(), 'password.pdf', 'acroform')
  })

  it('should add a RadioGroup', function () {
    var doc = jsPDF()
    doc.text(50, 165, 'RadioGroup:')
    var radioGroup = new RadioButton()
    radioGroup.V = '/Test'
    radioGroup.Subtype = 'Form'

    doc.addField(radioGroup)

    var radioButton1 = radioGroup.createOption('Test')
    radioButton1.Rect = [50, 170, 30, 10]
    radioButton1.AS = '/Test'

    var radioButton2 = radioGroup.createOption('Test2')
    radioButton2.Rect = [50, 180, 30, 10]

    var radioButton3 = radioGroup.createOption('Test3')
    radioButton3.Rect = [50, 190, 20, 10]

    radioGroup.setAppearance(AcroForm.Appearance.RadioButton.Cross)

    comparePdf(doc.output(), 'radiogroup.pdf', 'acroform')
  })
})
<commit_msg>Update standard.spec.js<commit_after>/* @TODO Enable 'use strict', remove all these globals */
/* global describe, xit, it, jsPDF, comparePdf, ComboBox, ListBox, PushButton, CheckBox, TextField, PasswordField, RadioButton, AcroForm */
/**
 * Acroform testing
 */

describe('Acroform', function () {

  it('ComboBox', function () {
    var doc = jsPDF()
    doc.setFontSize(12)
    doc.text(10, 105, 'ComboBox:')

    var d = new ComboBox()
    d.T = 'ChoiceField1'
    d.TI = 1
    d.Rect = [50, 100, 30, 10]
    d.Opt = '[(a)(b)(c)]'
    d.V = '(b)'
    d.DV = '(b)'
    doc.addField(d)

    comparePdf(doc.output(), 'combobox.pdf', 'acroform')
  })

  xit('should add a CheckBox', function () {
    var doc = jsPDF()
    doc.text(10, 125, 'CheckBox:')
    var checkBox = new CheckBox()
    checkBox.T = 'CheckBox1'
    checkBox.Rect = [50, 120, 30, 10]
    doc.addField(checkBox)

    comparePdf(doc.output(), 'checkbox.pdf', 'acroform')
  })

  it('should add a ListBox', function () {
    var doc = jsPDF()
    doc.setFontSize(12)
    doc.text(10, 115, 'ListBox:')
    var d2 = new ListBox()
    d2.edit = false
    d2.T = 'ChoiceField2'
    d2.TI = 2
    d2.Rect = [50, 110, 30, 10]
    d2.Opt = '[(c)(a)(d)(f)(b)(s)]'
    d2.V = '(s)'
    d2.BG = [0, 1, 1]
    doc.addField(d2)

    comparePdf(doc.output(), 'listbox.pdf', 'acroform')
  })

  it('should add a PushButton', function () {
    var doc = jsPDF()
    doc.text(10, 135, 'PushButton:')
    var pushButton = new PushButton()
    pushButton.T = 'PushButton1'
    pushButton.Rect = [50, 130, 30, 10]
    pushButton.BG = [1, 0, 0]
    doc.addField(pushButton)

    comparePdf(doc.output(), 'pushbutton.pdf', 'acroform')
  })

  it('should add a TextField', function () {
    var doc = jsPDF()
    doc.text(10, 145, 'TextField:')
    var textField = new TextField()
    textField.Rect = [50, 140, 30, 10]
    textField.multiline = true
    textField.V = 'The quick brown fox ate the lazy mouse The quick brown fox ate the lazy mouse The quick brown fox ate the lazy mouse'//
    textField.T = 'TestTextBox'
     // textField.Q = 2; // Text-Alignment
    doc.addField(textField)

    comparePdf(doc.output(), 'textfield.pdf', 'acroform')
  })

  it('should add a Password', function () {
    var doc = jsPDF()
    doc.text(10, 155, 'Password:')
    var passwordField = new PasswordField()
    passwordField.Rect = [50, 150, 30, 10]
    doc.addField(passwordField)

    comparePdf(doc.output(), 'password.pdf', 'acroform')
  })

  it('should add a RadioGroup', function () {
    var doc = jsPDF()
    doc.text(50, 165, 'RadioGroup:')
    var radioGroup = new RadioButton()
    radioGroup.V = '/Test'
    radioGroup.Subtype = 'Form'

    doc.addField(radioGroup)

    var radioButton1 = radioGroup.createOption('Test')
    radioButton1.Rect = [50, 170, 30, 10]
    radioButton1.AS = '/Test'

    var radioButton2 = radioGroup.createOption('Test2')
    radioButton2.Rect = [50, 180, 30, 10]

    var radioButton3 = radioGroup.createOption('Test3')
    radioButton3.Rect = [50, 190, 20, 10]

    radioGroup.setAppearance(AcroForm.Appearance.RadioButton.Cross)

    comparePdf(doc.output(), 'radiogroup.pdf', 'acroform')
  })
})
<|endoftext|>


<commit_before>var buster = require("buster-node");

buster.testRunner.onCreate(function (runner) {
    runner.on("suite:end", function (results) {
        process.nextTick(function () {
            process.exit(results.ok ? 0 : 1);
        });
    });
});

require("./test/run-analyzer-test");
require("./test/test-cli-test");
require("./test/runners/node-test");
require("./test/runners/browser-test");
require("./test/runners/browser/remote-runner-test");
<commit_msg>Even simpler test runner<commit_after>var buster = require("buster-node");
require("./test/run-analyzer-test");
require("./test/test-cli-test");
require("./test/runners/node-test");
require("./test/runners/browser-test");
require("./test/runners/browser/remote-runner-test");
<|endoftext|>


<commit_before>const os = require('os')
const path = require('path')
const _glob = require('glob')
const fs = require('fs-extra')
const nodeFetch = require('node-fetch')
const vercelFetch = require('@vercel/fetch')
const fetch = vercelFetch(nodeFetch)
const { promisify } = require('util')
const { Sema } = require('async-sema')
const { spawn, exec: execOrig } = require('child_process')
const { createNextInstall } = require('./test/lib/create-next-install')
const glob = promisify(_glob)
const exec = promisify(execOrig)

const timings = []
const DEFAULT_NUM_RETRIES = os.platform() === 'win32' ? 2 : 1
const DEFAULT_CONCURRENCY = 2
const RESULTS_EXT = `.results.json`
const isTestJob = !!process.env.NEXT_TEST_JOB
const TIMINGS_API = `https://api.github.com/gists/4500dd89ae2f5d70d9aaceb191f528d1`
const TIMINGS_API_HEADERS = {
  Accept: 'application/vnd.github.v3+json',
}

const testFilters = {
  unit: 'unit/',
  e2e: 'e2e/',
  production: 'production/',
  development: 'development/',
}

// which types we have configured to run separate
const configuredTestTypes = Object.values(testFilters)

const cleanUpAndExit = async (code) => {
  if (process.env.NEXT_TEST_STARTER) {
    await fs.remove(process.env.NEXT_TEST_STARTER)
  }
  console.log(`exiting with code ${code}`)
  process.exit(code)
}

async function getTestTimings() {
  const timingsRes = await fetch(TIMINGS_API, {
    headers: {
      ...TIMINGS_API_HEADERS,
    },
  })

  if (!timingsRes.ok) {
    throw new Error(`request status: ${timingsRes.status}`)
  }
  const timingsData = await timingsRes.json()
  return JSON.parse(timingsData.files['test-timings.json'].content)
}

async function main() {
  let numRetries = DEFAULT_NUM_RETRIES
  let concurrencyIdx = process.argv.indexOf('-c')
  let concurrency =
    (concurrencyIdx > -1 && parseInt(process.argv[concurrencyIdx + 1], 10)) ||
    DEFAULT_CONCURRENCY

  const hideOutput = !process.argv.includes('--debug')
  const outputTimings = process.argv.includes('--timings')
  const writeTimings = process.argv.includes('--write-timings')
  const groupIdx = process.argv.indexOf('-g')
  const groupArg = groupIdx !== -1 && process.argv[groupIdx + 1]

  const testTypeIdx = process.argv.indexOf('--type')
  const testType = testTypeIdx > -1 ? process.argv[testTypeIdx + 1] : undefined
  let filterTestsBy

  switch (testType) {
    case 'unit': {
      numRetries = 0
      filterTestsBy = testFilters.unit
      break
    }
    case 'development': {
      filterTestsBy = testFilters.development
      break
    }
    case 'production': {
      filterTestsBy = testFilters.production
      break
    }
    case 'e2e': {
      filterTestsBy = testFilters.e2e
      break
    }
    case 'all':
      filterTestsBy = 'none'
      break
    default:
      break
  }

  console.log('Running tests with concurrency:', concurrency)

  let tests = process.argv.filter((arg) => arg.match(/\.test\.(js|ts|tsx)/))
  let prevTimings

  if (tests.length === 0) {
    tests = (
      await glob('**/*.test.{js,ts,tsx}', {
        nodir: true,
        cwd: path.join(__dirname, 'test'),
      })
    ).filter((test) => {
      if (filterTestsBy) {
        // only include the specified type
        return filterTestsBy === 'none' ? true : test.startsWith(filterTestsBy)
      } else {
        // include all except the separately configured types
        return !configuredTestTypes.some((type) => test.startsWith(type))
      }
    })

    if (outputTimings && groupArg) {
      console.log('Fetching previous timings data')
      try {
        const timingsFile = path.join(__dirname, 'test-timings.json')
        try {
          prevTimings = JSON.parse(await fs.readFile(timingsFile, 'utf8'))
          console.log('Loaded test timings from disk successfully')
        } catch (_) {}

        if (!prevTimings) {
          prevTimings = await getTestTimings()
          console.log('Fetched previous timings data successfully')

          if (writeTimings) {
            await fs.writeFile(timingsFile, JSON.stringify(prevTimings))
            console.log('Wrote previous timings data to', timingsFile)
            await cleanUpAndExit(0)
          }
        }
      } catch (err) {
        console.log(`Failed to fetch timings data`, err)
        await cleanUpAndExit(1)
      }
    }
  }

  let testNames = [
    ...new Set(
      tests.map((f) => {
        let name = `${f.replace(/\\/g, '/').replace(/\/test$/, '')}`
        if (!name.startsWith('test/')) name = `test/${name}`
        return name
      })
    ),
  ]

  if (groupArg) {
    const groupParts = groupArg.split('/')
    const groupPos = parseInt(groupParts[0], 10)
    const groupTotal = parseInt(groupParts[1], 10)

    if (prevTimings) {
      const groups = [[]]
      const groupTimes = [0]

      for (const testName of testNames) {
        let smallestGroup = groupTimes[0]
        let smallestGroupIdx = 0

        // get the smallest group time to add current one to
        for (let i = 1; i < groupTotal; i++) {
          if (!groups[i]) {
            groups[i] = []
            groupTimes[i] = 0
          }

          const time = groupTimes[i]
          if (time < smallestGroup) {
            smallestGroup = time
            smallestGroupIdx = i
          }
        }
        groups[smallestGroupIdx].push(testName)
        groupTimes[smallestGroupIdx] += prevTimings[testName] || 1
      }

      const curGroupIdx = groupPos - 1
      testNames = groups[curGroupIdx]

      console.log(
        'Current group previous accumulated times:',
        Math.round(groupTimes[curGroupIdx]) + 's'
      )
    } else {
      const numPerGroup = Math.ceil(testNames.length / groupTotal)
      let offset = (groupPos - 1) * numPerGroup
      testNames = testNames.slice(offset, offset + numPerGroup)
    }
  }

  if (testNames.length === 0) {
    console.log('No tests found for', testType, 'exiting..')
    return cleanUpAndExit(0)
  }

  console.log('Running tests:', '\n', ...testNames.map((name) => `${name}\n`))

  const hasIsolatedTests = testNames.some((test) => {
    return configuredTestTypes.some(
      (type) => type !== testFilters.unit && test.startsWith(`test/${type}`)
    )
  })

  if (
    process.env.NEXT_TEST_MODE !== 'deploy' &&
    ((testType && testType !== 'unit') || hasIsolatedTests)
  ) {
    // for isolated next tests: e2e, dev, prod we create
    // a starter Next.js install to re-use to speed up tests
    // to avoid having to run yarn each time
    console.log('Creating Next.js install for isolated tests')
    const reactVersion = process.env.NEXT_TEST_REACT_VERSION || 'latest'
    const testStarter = await createNextInstall({
      react: reactVersion,
      'react-dom': reactVersion,
    })
    process.env.NEXT_TEST_STARTER = testStarter
  }

  const sema = new Sema(concurrency, { capacity: testNames.length })
  const children = new Set()
  const jestPath = path.join(
    __dirname,
    'node_modules',
    '.bin',
    `jest${process.platform === 'win32' ? '.CMD' : ''}`
  )

  const runTest = (test = '', isFinalRun) =>
    new Promise((resolve, reject) => {
      const start = new Date().getTime()
      let outputChunks = []
      const child = spawn(
        jestPath,
        [
          '--runInBand',
          '--forceExit',
          '--verbose',
          ...(isTestJob
            ? ['--json', `--outputFile=${test}${RESULTS_EXT}`]
            : []),
          test,
        ],
        {
          stdio: ['ignore', 'pipe', 'pipe'],
          env: {
            ...process.env,
            // run tests in headless mode by default
            HEADLESS: 'true',
            TRACE_PLAYWRIGHT: 'true',
            ...(isFinalRun
              ? {
                  // Events can be finicky in CI. This switches to a more
                  // reliable polling method.
                  // CHOKIDAR_USEPOLLING: 'true',
                  // CHOKIDAR_INTERVAL: 500,
                  // WATCHPACK_POLLING: 500,
                }
              : {}),
          },
        }
      )
      const handleOutput = (type) => (chunk) => {
        if (hideOutput) {
          outputChunks.push({ type, chunk })
        } else {
          process.stderr.write(chunk)
        }
      }
      child.stdout.on('data', handleOutput('stdout'))
      child.stderr.on('data', handleOutput('stderr'))

      children.add(child)

      child.on('exit', async (code, signal) => {
        children.delete(child)
        if (code !== 0 || signal !== null) {
          if (isFinalRun && hideOutput) {
            // limit out to last 64kb so that we don't
            // run out of log room in CI
            outputChunks.forEach(({ type, chunk }) => {
              if (type === 'stdout') {
                process.stdout.write(chunk)
              } else {
                process.stderr.write(chunk)
              }
            })
          }
          return reject(
            new Error(
              code
                ? `failed with code: ${code}`
                : `failed with signal: ${signal}`
            )
          )
        }
        await fs
          .remove(
            path.join(
              __dirname,
              'test/traces',
              path
                .relative(path.join(__dirname, 'test'), test)
                .replace(/\//g, '-')
            )
          )
          .catch(() => {})
        resolve(new Date().getTime() - start)
      })
    })

  const directorySemas = new Map()

  await Promise.all(
    testNames.map(async (test) => {
      const dirName = path.dirname(test)
      let dirSema = directorySemas.get(dirName)
      if (dirSema === undefined)
        directorySemas.set(dirName, (dirSema = new Sema(1)))
      await dirSema.acquire()
      await sema.acquire()
      let passed = false

      for (let i = 0; i < numRetries + 1; i++) {
        try {
          console.log(`Starting ${test} retry ${i}/${numRetries}`)
          const time = await runTest(test, i === numRetries)
          timings.push({
            file: test,
            time,
          })
          passed = true
          console.log(
            `Finished ${test} on retry ${i}/${numRetries} in ${time / 1000}s`
          )
          break
        } catch (err) {
          if (i < numRetries) {
            try {
              const testDir = path.dirname(path.join(__dirname, test))
              console.log('Cleaning test files at', testDir)
              await exec(`git clean -fdx "${testDir}"`)
              await exec(`git checkout "${testDir}"`)
            } catch (err) {}
          } else {
            console.error(`${test} failed due to ${err}`)
          }
        }
      }
      if (!passed) {
        console.error(`${test} failed to pass within ${numRetries} retries`)
        children.forEach((child) => child.kill())

        if (isTestJob) {
          try {
            const testsOutput = await fs.readFile(
              `${test}${RESULTS_EXT}`,
              'utf8'
            )
            console.log(
              `--test output start--`,
              testsOutput,
              `--test output end--`
            )
          } catch (err) {
            console.log(`Failed to load test output`, err)
          }
        }
        cleanUpAndExit(1)
      }
      sema.release()
      dirSema.release()
    })
  )

  if (outputTimings) {
    const curTimings = {}
    // let junitData = `<testsuites name="jest tests">`
    /*
      <testsuite name="/__tests__/bar.test.js" tests="1" errors="0" failures="0" skipped="0" timestamp="2017-10-10T21:56:49" time="0.323">
        <testcase classname="bar-should be bar" name="bar-should be bar" time="0.004">
        </testcase>
      </testsuite>
    */

    for (const timing of timings) {
      const timeInSeconds = timing.time / 1000
      curTimings[timing.file] = timeInSeconds

      // junitData += `
      //   <testsuite name="${timing.file}" file="${
      //   timing.file
      // }" tests="1" errors="0" failures="0" skipped="0" timestamp="${new Date().toJSON()}" time="${timeInSeconds}">
      //     <testcase classname="tests suite should pass" name="${
      //       timing.file
      //     }" time="${timeInSeconds}"></testcase>
      //   </testsuite>
      // `
    }
    // junitData += `</testsuites>`
    // console.log('output timing data to junit.xml')

    if (prevTimings && process.env.TEST_TIMINGS_TOKEN) {
      try {
        const newTimings = {
          ...(await getTestTimings()),
          ...curTimings,
        }

        for (const test of Object.keys(newTimings)) {
          if (!(await fs.pathExists(path.join(__dirname, test)))) {
            console.log('removing stale timing', test)
            delete newTimings[test]
          }
        }

        const timingsRes = await fetch(TIMINGS_API, {
          method: 'PATCH',
          headers: {
            ...TIMINGS_API_HEADERS,
            Authorization: `Bearer ${process.env.TEST_TIMINGS_TOKEN}`,
          },
          body: JSON.stringify({
            files: {
              'test-timings.json': {
                content: JSON.stringify(newTimings),
              },
            },
          }),
        })

        if (!timingsRes.ok) {
          throw new Error(`request status: ${timingsRes.status}`)
        }
        console.log(
          'Sent updated timings successfully',
          await timingsRes.json()
        )
      } catch (err) {
        console.log('Failed to update timings data', err)
      }
    }
  }
  await cleanUpAndExit(0)
}

main().catch((err) => {
  console.error(err)
  process.exit(1)
})
<commit_msg>Add delay before exiting tests for log flushing (#39302)<commit_after>const os = require('os')
const path = require('path')
const _glob = require('glob')
const fs = require('fs-extra')
const nodeFetch = require('node-fetch')
const vercelFetch = require('@vercel/fetch')
const fetch = vercelFetch(nodeFetch)
const { promisify } = require('util')
const { Sema } = require('async-sema')
const { spawn, exec: execOrig } = require('child_process')
const { createNextInstall } = require('./test/lib/create-next-install')
const glob = promisify(_glob)
const exec = promisify(execOrig)

const timings = []
const DEFAULT_NUM_RETRIES = os.platform() === 'win32' ? 2 : 1
const DEFAULT_CONCURRENCY = 2
const RESULTS_EXT = `.results.json`
const isTestJob = !!process.env.NEXT_TEST_JOB
const TIMINGS_API = `https://api.github.com/gists/4500dd89ae2f5d70d9aaceb191f528d1`
const TIMINGS_API_HEADERS = {
  Accept: 'application/vnd.github.v3+json',
}

const testFilters = {
  unit: 'unit/',
  e2e: 'e2e/',
  production: 'production/',
  development: 'development/',
}

// which types we have configured to run separate
const configuredTestTypes = Object.values(testFilters)

const cleanUpAndExit = async (code) => {
  if (process.env.NEXT_TEST_STARTER) {
    await fs.remove(process.env.NEXT_TEST_STARTER)
  }
  console.log(`exiting with code ${code}`)

  setTimeout(() => {
    process.exit(code)
  }, 1)
}

async function getTestTimings() {
  const timingsRes = await fetch(TIMINGS_API, {
    headers: {
      ...TIMINGS_API_HEADERS,
    },
  })

  if (!timingsRes.ok) {
    throw new Error(`request status: ${timingsRes.status}`)
  }
  const timingsData = await timingsRes.json()
  return JSON.parse(timingsData.files['test-timings.json'].content)
}

async function main() {
  let numRetries = DEFAULT_NUM_RETRIES
  let concurrencyIdx = process.argv.indexOf('-c')
  let concurrency =
    (concurrencyIdx > -1 && parseInt(process.argv[concurrencyIdx + 1], 10)) ||
    DEFAULT_CONCURRENCY

  const hideOutput = !process.argv.includes('--debug')
  const outputTimings = process.argv.includes('--timings')
  const writeTimings = process.argv.includes('--write-timings')
  const groupIdx = process.argv.indexOf('-g')
  const groupArg = groupIdx !== -1 && process.argv[groupIdx + 1]

  const testTypeIdx = process.argv.indexOf('--type')
  const testType = testTypeIdx > -1 ? process.argv[testTypeIdx + 1] : undefined
  let filterTestsBy

  switch (testType) {
    case 'unit': {
      numRetries = 0
      filterTestsBy = testFilters.unit
      break
    }
    case 'development': {
      filterTestsBy = testFilters.development
      break
    }
    case 'production': {
      filterTestsBy = testFilters.production
      break
    }
    case 'e2e': {
      filterTestsBy = testFilters.e2e
      break
    }
    case 'all':
      filterTestsBy = 'none'
      break
    default:
      break
  }

  console.log('Running tests with concurrency:', concurrency)

  let tests = process.argv.filter((arg) => arg.match(/\.test\.(js|ts|tsx)/))
  let prevTimings

  if (tests.length === 0) {
    tests = (
      await glob('**/*.test.{js,ts,tsx}', {
        nodir: true,
        cwd: path.join(__dirname, 'test'),
      })
    ).filter((test) => {
      if (filterTestsBy) {
        // only include the specified type
        return filterTestsBy === 'none' ? true : test.startsWith(filterTestsBy)
      } else {
        // include all except the separately configured types
        return !configuredTestTypes.some((type) => test.startsWith(type))
      }
    })

    if (outputTimings && groupArg) {
      console.log('Fetching previous timings data')
      try {
        const timingsFile = path.join(__dirname, 'test-timings.json')
        try {
          prevTimings = JSON.parse(await fs.readFile(timingsFile, 'utf8'))
          console.log('Loaded test timings from disk successfully')
        } catch (_) {}

        if (!prevTimings) {
          prevTimings = await getTestTimings()
          console.log('Fetched previous timings data successfully')

          if (writeTimings) {
            await fs.writeFile(timingsFile, JSON.stringify(prevTimings))
            console.log('Wrote previous timings data to', timingsFile)
            await cleanUpAndExit(0)
          }
        }
      } catch (err) {
        console.log(`Failed to fetch timings data`, err)
        await cleanUpAndExit(1)
      }
    }
  }

  let testNames = [
    ...new Set(
      tests.map((f) => {
        let name = `${f.replace(/\\/g, '/').replace(/\/test$/, '')}`
        if (!name.startsWith('test/')) name = `test/${name}`
        return name
      })
    ),
  ]

  if (groupArg) {
    const groupParts = groupArg.split('/')
    const groupPos = parseInt(groupParts[0], 10)
    const groupTotal = parseInt(groupParts[1], 10)

    if (prevTimings) {
      const groups = [[]]
      const groupTimes = [0]

      for (const testName of testNames) {
        let smallestGroup = groupTimes[0]
        let smallestGroupIdx = 0

        // get the smallest group time to add current one to
        for (let i = 1; i < groupTotal; i++) {
          if (!groups[i]) {
            groups[i] = []
            groupTimes[i] = 0
          }

          const time = groupTimes[i]
          if (time < smallestGroup) {
            smallestGroup = time
            smallestGroupIdx = i
          }
        }
        groups[smallestGroupIdx].push(testName)
        groupTimes[smallestGroupIdx] += prevTimings[testName] || 1
      }

      const curGroupIdx = groupPos - 1
      testNames = groups[curGroupIdx]

      console.log(
        'Current group previous accumulated times:',
        Math.round(groupTimes[curGroupIdx]) + 's'
      )
    } else {
      const numPerGroup = Math.ceil(testNames.length / groupTotal)
      let offset = (groupPos - 1) * numPerGroup
      testNames = testNames.slice(offset, offset + numPerGroup)
    }
  }

  if (testNames.length === 0) {
    console.log('No tests found for', testType, 'exiting..')
    return cleanUpAndExit(0)
  }

  console.log('Running tests:', '\n', ...testNames.map((name) => `${name}\n`))

  const hasIsolatedTests = testNames.some((test) => {
    return configuredTestTypes.some(
      (type) => type !== testFilters.unit && test.startsWith(`test/${type}`)
    )
  })

  if (
    process.env.NEXT_TEST_MODE !== 'deploy' &&
    ((testType && testType !== 'unit') || hasIsolatedTests)
  ) {
    // for isolated next tests: e2e, dev, prod we create
    // a starter Next.js install to re-use to speed up tests
    // to avoid having to run yarn each time
    console.log('Creating Next.js install for isolated tests')
    const reactVersion = process.env.NEXT_TEST_REACT_VERSION || 'latest'
    const testStarter = await createNextInstall({
      react: reactVersion,
      'react-dom': reactVersion,
    })
    process.env.NEXT_TEST_STARTER = testStarter
  }

  const sema = new Sema(concurrency, { capacity: testNames.length })
  const children = new Set()
  const jestPath = path.join(
    __dirname,
    'node_modules',
    '.bin',
    `jest${process.platform === 'win32' ? '.CMD' : ''}`
  )

  const runTest = (test = '', isFinalRun) =>
    new Promise((resolve, reject) => {
      const start = new Date().getTime()
      let outputChunks = []
      const child = spawn(
        jestPath,
        [
          '--runInBand',
          '--forceExit',
          '--verbose',
          ...(isTestJob
            ? ['--json', `--outputFile=${test}${RESULTS_EXT}`]
            : []),
          test,
        ],
        {
          stdio: ['ignore', 'pipe', 'pipe'],
          env: {
            ...process.env,
            // run tests in headless mode by default
            HEADLESS: 'true',
            TRACE_PLAYWRIGHT: 'true',
            ...(isFinalRun
              ? {
                  // Events can be finicky in CI. This switches to a more
                  // reliable polling method.
                  // CHOKIDAR_USEPOLLING: 'true',
                  // CHOKIDAR_INTERVAL: 500,
                  // WATCHPACK_POLLING: 500,
                }
              : {}),
          },
        }
      )
      const handleOutput = (type) => (chunk) => {
        if (hideOutput) {
          outputChunks.push({ type, chunk })
        } else {
          process.stderr.write(chunk)
        }
      }
      child.stdout.on('data', handleOutput('stdout'))
      child.stderr.on('data', handleOutput('stderr'))

      children.add(child)

      child.on('exit', async (code, signal) => {
        children.delete(child)
        if (code !== 0 || signal !== null) {
          if (isFinalRun && hideOutput) {
            // limit out to last 64kb so that we don't
            // run out of log room in CI
            outputChunks.forEach(({ type, chunk }) => {
              if (type === 'stdout') {
                process.stdout.write(chunk)
              } else {
                process.stderr.write(chunk)
              }
            })
          }
          return reject(
            new Error(
              code
                ? `failed with code: ${code}`
                : `failed with signal: ${signal}`
            )
          )
        }
        await fs
          .remove(
            path.join(
              __dirname,
              'test/traces',
              path
                .relative(path.join(__dirname, 'test'), test)
                .replace(/\//g, '-')
            )
          )
          .catch(() => {})
        resolve(new Date().getTime() - start)
      })
    })

  const directorySemas = new Map()

  await Promise.all(
    testNames.map(async (test) => {
      const dirName = path.dirname(test)
      let dirSema = directorySemas.get(dirName)
      if (dirSema === undefined)
        directorySemas.set(dirName, (dirSema = new Sema(1)))
      await dirSema.acquire()
      await sema.acquire()
      let passed = false

      for (let i = 0; i < numRetries + 1; i++) {
        try {
          console.log(`Starting ${test} retry ${i}/${numRetries}`)
          const time = await runTest(test, i === numRetries)
          timings.push({
            file: test,
            time,
          })
          passed = true
          console.log(
            `Finished ${test} on retry ${i}/${numRetries} in ${time / 1000}s`
          )
          break
        } catch (err) {
          if (i < numRetries) {
            try {
              const testDir = path.dirname(path.join(__dirname, test))
              console.log('Cleaning test files at', testDir)
              await exec(`git clean -fdx "${testDir}"`)
              await exec(`git checkout "${testDir}"`)
            } catch (err) {}
          } else {
            console.error(`${test} failed due to ${err}`)
          }
        }
      }
      if (!passed) {
        console.error(`${test} failed to pass within ${numRetries} retries`)
        children.forEach((child) => child.kill())

        if (isTestJob) {
          try {
            const testsOutput = await fs.readFile(
              `${test}${RESULTS_EXT}`,
              'utf8'
            )
            console.log(
              `--test output start--`,
              testsOutput,
              `--test output end--`
            )
          } catch (err) {
            console.log(`Failed to load test output`, err)
          }
        }
        cleanUpAndExit(1)
      }
      sema.release()
      dirSema.release()
    })
  )

  if (outputTimings) {
    const curTimings = {}
    // let junitData = `<testsuites name="jest tests">`
    /*
      <testsuite name="/__tests__/bar.test.js" tests="1" errors="0" failures="0" skipped="0" timestamp="2017-10-10T21:56:49" time="0.323">
        <testcase classname="bar-should be bar" name="bar-should be bar" time="0.004">
        </testcase>
      </testsuite>
    */

    for (const timing of timings) {
      const timeInSeconds = timing.time / 1000
      curTimings[timing.file] = timeInSeconds

      // junitData += `
      //   <testsuite name="${timing.file}" file="${
      //   timing.file
      // }" tests="1" errors="0" failures="0" skipped="0" timestamp="${new Date().toJSON()}" time="${timeInSeconds}">
      //     <testcase classname="tests suite should pass" name="${
      //       timing.file
      //     }" time="${timeInSeconds}"></testcase>
      //   </testsuite>
      // `
    }
    // junitData += `</testsuites>`
    // console.log('output timing data to junit.xml')

    if (prevTimings && process.env.TEST_TIMINGS_TOKEN) {
      try {
        const newTimings = {
          ...(await getTestTimings()),
          ...curTimings,
        }

        for (const test of Object.keys(newTimings)) {
          if (!(await fs.pathExists(path.join(__dirname, test)))) {
            console.log('removing stale timing', test)
            delete newTimings[test]
          }
        }

        const timingsRes = await fetch(TIMINGS_API, {
          method: 'PATCH',
          headers: {
            ...TIMINGS_API_HEADERS,
            Authorization: `Bearer ${process.env.TEST_TIMINGS_TOKEN}`,
          },
          body: JSON.stringify({
            files: {
              'test-timings.json': {
                content: JSON.stringify(newTimings),
              },
            },
          }),
        })

        if (!timingsRes.ok) {
          throw new Error(`request status: ${timingsRes.status}`)
        }
        console.log(
          'Sent updated timings successfully',
          await timingsRes.json()
        )
      } catch (err) {
        console.log('Failed to update timings data', err)
      }
    }
  }
  await cleanUpAndExit(0)
}

main().catch((err) => {
  console.error(err)
  process.exit(1)
})
<|endoftext|>