<commit_before>'use strict';

var ObjectId = require("mongodb").ObjectId;
var should = require('should');
var helper = require("../../helper");
var Manager = require("../../../src/managers/garment-master-plan/booking-order-manager");
var manager = null;
var dataUtil =require("../../data-util/garment-master-plan/booking-order-data-util");
var validate = require("dl-models").validator.garmentMasterPlan.bookingOrder;

var moment = require('moment');

before('#00. connect db', function (done) {
    helper.getDb()
        .then(db => {
            manager = new Manager(db, {
                username: 'unit-test'
            });
            done();
        })
        .catch(e => {
            done(e);
        })
});

var createdId;
it("#01. should success when create new data", function (done) {
    dataUtil.getNewData()
        .then((data) => manager.create(data))
        .then((id) => {
            id.should.be.Object();
            createdId = id;
            done();
        })
        .catch((e) => {
            done(e);
        });
});

var createdData;
it(`#02. should success when get created data with id`, function (done) {
    manager.getSingleById(createdId)
        .then((data) => {
            data.should.instanceof(Object);
            validate(data);
            createdData = data;
            done();
        })
        .catch((e) => {
            done(e);
        });
});

it("#03. should error when confirm created data without data items", function (done) {
    createdData.type='confirm';
    createdData.items = [{
        quantity: 0,
        deliveryDate : ''
    }];
        manager.update(createdData)
            .then((id) => {
                    done("should error when confirm created data without data items");
                })
                .catch((e) => {
                    e.name.should.equal("ValidationError");
                    e.should.have.property("errors");
                    e.errors.should.instanceof(Object);
                    e.errors.should.have.property("items");
                    done();
                });
});
<commit_msg>fix unit test<commit_after>'use strict';

var ObjectId = require("mongodb").ObjectId;
var should = require('should');
var helper = require("../../helper");
var Manager = require("../../../src/managers/garment-master-plan/booking-order-manager");
var manager = null;
var dataUtil =require("../../data-util/garment-master-plan/booking-order-data-util");
var validate = require("dl-models").validator.garmentMasterPlan.bookingOrder;

var moment = require('moment');

before('#00. connect db', function (done) {
    helper.getDb()
        .then(db => {
            manager = new Manager(db, {
                username: 'unit-test'
            });
            done();
        })
        .catch(e => {
            done(e);
        })
});

var createdId;
it("#01. should success when create new data", function (done) {
    dataUtil.getNewData()
        .then((data) => manager.create(data))
        .then((id) => {
            id.should.be.Object();
            createdId = id;
            done();
        })
        .catch((e) => {
            done(e);
        });
});

var createdData;
it(`#02. should success when get created data with id`, function (done) {
    manager.getSingleById(createdId)
        .then((data) => {
            data.should.instanceof(Object);
            validate(data);
            createdData = data;
            done();
        })
        .catch((e) => {
            done(e);
        });
});

it("#03. should error when confirm created data without data items", function (done) {
    createdData.type='confirm';
    createdData.items = [{
        quantity: 0,
        deliveryDate : ''
    }];
        manager.update(createdData)
            .then((id) => {
                    done("should error when confirm created data without data items");
                })
                .catch((e) => {
                    e.name.should.equal("ValidationError");
                    e.should.have.property("errors");
                    e.errors.should.instanceof(Object);
                    e.errors.should.have.property("items");
                    done();
                });
});

it("#04. should error when confirm created data with deliveryDate items more than deliveryDate", function (done) {
    createdData.type='confirm';
    createdData.items[0].deliveryDate=new Date(createdData.deliveryDate.setDate(createdData.deliveryDate.getDate() + 10));
        manager.update(createdData)
            .then((id) => {
                    done("should error when confirm created data with deliveryDate items more than deliveryDate");
                })
                .catch((e) => {
                    e.name.should.equal("ValidationError");
                    e.should.have.property("errors");
                    e.errors.should.instanceof(Object);
                    e.errors.should.have.property("items");
                    done();
                });
});

it("#05. should error when confirm created data with deliveryDate items less than today", function (done) {
    createdData.type='confirm';
    var today=new Date();
    createdData.items[0].deliveryDate=new Date(today.setDate(today.getDate() - 10));
        manager.update(createdData)
            .then((id) => {
                    done("should error when confirm created data with deliveryDate items less than today");
                })
                .catch((e) => {
                    e.name.should.equal("ValidationError");
                    e.should.have.property("errors");
                    e.errors.should.instanceof(Object);
                    e.errors.should.have.property("items");
                    done();
                });
});<|endoftext|>


<commit_before>import DatatableFactory from "ember-easy-datatable/utils/datatable-factory";
import hbs from 'htmlbars-inline-precompile';
import { moduleForComponent, test } from 'ember-qunit';
import customHelpers from '../../helpers/_custom-helpers'

moduleForComponent('easy-datatable', 'Integration | Component | index cell', {
  integration: true,
  setup: function() {
    this.set('table', DatatableFactory.makeDatatable({
    headers: ['', 'Index', 'Original name'],
    body: [
      [{isHeader: true, isEditable: false}, {isIndex: true}, 'Row 1'],
      [{isHeader: true, isEditable: false}, {isIndex: true}, 'Row 2'],
      [{isHeader: true, isEditable: false}, {isIndex: true}, 'Row 3'],
      [{isHeader: true, isEditable: false}, {isIndex: true}, 'Row 4']
    ],
    makeDefaultRow: function () {
      var row = DatatableFactory.makeListOf(this.get('headers.cells.length'));
      row[0] = {
        isHeader: true,
        isEditable: false
      };
      row[1] = {
        isIndex: true
      };
      return row;
    }
  }));
  },
});

test('When isIndex is set to true, the cell displays the row + 1', function(assert) {
  assert.expect(1);

  this.render(hbs`{{easy-datatable table=table}}`);

  assert.deepEqual(customHelpers.getDatatableContent(), [
    ['1', 'Row 1'],
    ['2', 'Row 2'],
    ['3', 'Row 3'],
    ['4', 'Row 4']
  ]);
});

test('Is keeps showing the correct value after insertion, removing or reordering', async function (assert) {
  assert.expect(1);

  await this.render(hbs`{{easy-datatable table=table}}`);
  assert.deepEqual(customHelpers.getDatatableContent(), [
    ['1', 'Row 1'],
    ['2', 'Row 2'],
    ['3', 'Row 3'],
    ['4', 'Row 4']
  ]);
  //Problem with clickOnDatatableCell(), must be corrected so the assertions can pass

  await customHelpers.clickOnDatatableCell(1, 0);
  await customHelpers.pressCtrlInserKeyInDatatable();

  assert.deepEqual(customHelpers.getDatatableContent(), [
    ['1', 'Row 1'],
    ['2', ''],
    ['3', 'Row 2'],
    ['4', 'Row 3'],
    ['5', 'Row 4']
  ]);

  await customHelpers.pressCtrlDelKeyInDatatable();
  assert.deepEqual(customHelpers.getDatatableContent(), [
    ['1', 'Row 1'],
    ['2', 'Row 2'],
    ['3', 'Row 3'],
    ['4', 'Row 4']
  ]);
  await customHelpers.pressCtrlDownKeyInDatatable();
  assert.deepEqual(customHelpers.getDatatableContent(), [
    ['1', 'Row 1'],
    ['2', 'Row 3'],
    ['3', 'Row 2'],
    ['4', 'Row 4']
  ]);
});
<commit_msg>Fixed index-cell-test<commit_after>import DatatableFactory from "ember-easy-datatable/utils/datatable-factory";
import hbs from 'htmlbars-inline-precompile';
import { moduleForComponent, test } from 'ember-qunit';
import customHelpers from '../../helpers/_custom-helpers'

moduleForComponent('easy-datatable', 'Integration | Component | index cell', {
  integration: true,
  setup: function() {
    this.set('table', DatatableFactory.makeDatatable({
    headers: ['', 'Index', 'Original name'],
    body: [
      [{isHeader: true, isEditable: false}, {isIndex: true}, 'Row 1'],
      [{isHeader: true, isEditable: false}, {isIndex: true}, 'Row 2'],
      [{isHeader: true, isEditable: false}, {isIndex: true}, 'Row 3'],
      [{isHeader: true, isEditable: false}, {isIndex: true}, 'Row 4']
    ],
    makeDefaultRow: function () {
      var row = DatatableFactory.makeListOf(this.get('headers.cells.length'));
      row[0] = {
        isHeader: true,
        isEditable: false
      };
      row[1] = {
        isIndex: true
      };
      return row;
    }
  }));
  },
});

test('When isIndex is set to true, the cell displays the row + 1', function(assert) {
  assert.expect(1);

  this.render(hbs`{{easy-datatable table=table}}`);

  assert.deepEqual(customHelpers.getDatatableContent(), [
    ['1', 'Row 1'],
    ['2', 'Row 2'],
    ['3', 'Row 3'],
    ['4', 'Row 4']
  ]);
});

test('Is keeps showing the correct value after insertion, removing or reordering', async function (assert) {
  assert.expect(4);

  await this.render(hbs`{{easy-datatable table=table}}`);
  assert.deepEqual(customHelpers.getDatatableContent(), [
    ['1', 'Row 1'],
    ['2', 'Row 2'],
    ['3', 'Row 3'],
    ['4', 'Row 4']
  ]);

  await customHelpers.clickOnDatatableCell(1, 0);
  await customHelpers.pressCtrlInserKeyInDatatable();

  assert.deepEqual(customHelpers.getDatatableContent(), [
    ['1', 'Row 1'],
    ['2', ''],
    ['3', 'Row 2'],
    ['4', 'Row 3'],
    ['5', 'Row 4']
  ]);

  await customHelpers.pressCtrlDelKeyInDatatable();
  assert.deepEqual(customHelpers.getDatatableContent(), [
    ['1', 'Row 1'],
    ['2', 'Row 2'],
    ['3', 'Row 3'],
    ['4', 'Row 4']
  ]);
  await customHelpers.pressCtrlDownKeyInDatatable();
  assert.deepEqual(customHelpers.getDatatableContent(), [
    ['1', 'Row 1'],
    ['2', 'Row 3'],
    ['3', 'Row 2'],
    ['4', 'Row 4']
  ]);
});
<|endoftext|>


<commit_before>"use strict";

/**
 * @constructor
 * @param {CPU} dev
 */
function DMA(dev)
{
    /** @const */
    this.memory = dev.memory;

    this.channels = [
        { address: 0, count: 0 },
        { address: 0, count: 0 },
        { address: 0, count: 0 },
        { address: 0, count: 0 }
    ];

    this.lsb_msb_flipflop = 0;

    var io = dev.io;
    io.register_write(0x04, this, this.port_write.bind(this, 0x04));
    io.register_write(0x05, this, this.port_write.bind(this, 0x05));
    io.register_write(0x0A, this, this.portA_write);
    io.register_write(0x0B, this, this.portB_write);
    io.register_write(0x0C, this, this.portC_write);
    io.register_write(0x81, this, this.port81_write);

    /** @const */
    this._state_skip = [
        this.memory,
    ];
};

DMA.prototype.port_write = function(port, data_byte)
{
    dbg_log("port " + port + " write " + data_byte, LOG_DMA);

    if(port < 8)
    {
        var channel = port >> 1;

        if(port & 1)
        {
            this.channels[channel].count = this.flipflop_get(this.channels[channel].count, data_byte);
        }
        else
        {
            this.channels[channel].address = this.flipflop_get(this.channels[channel].address, data_byte);
        }
    }
};

DMA.prototype.port_read = function(port)
{
    if(port < 8)
    {
        var channel = port >> 1;

        if(port & 1)
        {
            return this.channels[channel].count;
        }
        else
        {
            // Bug?
            return this.channels[channel].address;
        }
    }
    else
    {
        dbg_log("port " + h(port) + " read", LOG_DMA);
    }
};

DMA.prototype.portA_write = function(data_byte)
{
    dbg_log("port A write: " + h(data_byte), LOG_DMA);
};

DMA.prototype.portB_write = function(data_byte)
{
    dbg_log("port B write: " + h(data_byte), LOG_DMA);
};

DMA.prototype.portC_write = function(data_byte)
{
    this.lsb_msb_flipflop = 0;
}

DMA.prototype.port81_write = function(data_byte)
{
    this.channels[2].address = this.channels[2].address & 0xFFFF | data_byte << 16;
}

// read data, write to memory
DMA.prototype.do_read = function(buffer, start, len, channel, fn)
{
    var read_count = this.channels[channel].count + 1,
        addr = this.channels[channel].address;

    dbg_log("DMA write channel " + channel, LOG_DMA);
    dbg_log("to " + h(addr) + " len " + h(read_count), LOG_DMA);

    if(len < read_count)
    {
        dbg_log("DMA should read more than provided: " + h(len) + " " + h(read_count), LOG_DMA);
    }

    if(start + read_count > buffer.byteLength)
    {
        dbg_log("DMA read outside of buffer", LOG_DMA);
        fn(true);
    }
    else
    {
        var memory = this.memory;
        this.channels[channel].address += read_count;

        buffer.get(start, read_count, function(data)
        {
            memory.write_blob(data, addr);
            fn(false);
        });
    }
};

// write data, read memory
DMA.prototype.do_write = function(buffer, start, len, channel, fn)
{
    var read_count = this.channels[channel].count,
        addr = this.channels[channel].address;

    dbg_log("DMA write channel " + channel, LOG_DMA);
    dbg_log("to " + h(addr) + " len " + h(read_count), LOG_DMA);
    //dbg_log(this.channels[channel], LOG_DMA);

    if(len < read_count)
    {
        dbg_log("DMA should read more than provided", LOG_DMA);
    }

    if(start + read_count > buffer.byteLength)
    {
        dbg_log("DMA write outside of buffer", LOG_DMA);
        fn(true);
    }
    else
    {
        this.channels[channel].address += read_count;

        buffer.set(start,
                new Uint8Array(this.memory.buffer, addr, read_count + 1),
                function() {
                    fn(false);
                }
            );
    }
}

DMA.prototype.flipflop_get = function(old_dword, new_byte)
{
    this.lsb_msb_flipflop ^= 1;

    if(this.lsb_msb_flipflop)
    {
        // low byte
        return old_dword & ~0xFF | new_byte;
    }
    else
    {
        // high byte
        return old_dword & ~0xFF00 | new_byte << 8;
    }
}
<commit_msg>Remove channel objects<commit_after>"use strict";

/**
 * @constructor
 * @param {CPU} dev
 */
function DMA(dev)
{
    /** @const */
    this.memory = dev.memory;

    this.channel_addr = new Int32Array(4);
    this.channel_count = new Int32Array(4);

    this.lsb_msb_flipflop = 0;

    var io = dev.io;
    io.register_write(0x04, this, this.port_write.bind(this, 0x04));
    io.register_write(0x05, this, this.port_write.bind(this, 0x05));
    io.register_write(0x0A, this, this.portA_write);
    io.register_write(0x0B, this, this.portB_write);
    io.register_write(0x0C, this, this.portC_write);
    io.register_write(0x81, this, this.port81_write);

    /** @const */
    this._state_skip = [
        this.memory,
    ];
};

DMA.prototype.port_write = function(port, data_byte)
{
    dbg_log("port " + port + " write " + data_byte, LOG_DMA);

    if(port < 8)
    {
        var channel = port >> 1;

        if(port & 1)
        {
            this.channel_count[channel] = this.flipflop_get(this.channel_count[channel], data_byte);
        }
        else
        {
            this.channel_addr[channel] = this.flipflop_get(this.channel_addr[channel], data_byte);
        }
    }
};

DMA.prototype.port_read = function(port)
{
    if(port < 8)
    {
        var channel = port >> 1;

        if(port & 1)
        {
            return this.channel_count[channel];
        }
        else
        {
            // Bug?
            return this.channel_addr[channel];
        }
    }
    else
    {
        dbg_log("port " + h(port) + " read", LOG_DMA);
    }
};

DMA.prototype.portA_write = function(data_byte)
{
    dbg_log("port A write: " + h(data_byte), LOG_DMA);
};

DMA.prototype.portB_write = function(data_byte)
{
    dbg_log("port B write: " + h(data_byte), LOG_DMA);
};

DMA.prototype.portC_write = function(data_byte)
{
    this.lsb_msb_flipflop = 0;
}

DMA.prototype.port81_write = function(data_byte)
{
    this.channel_addr[2] = this.channel_addr[2] & 0xFFFF | data_byte << 16;
}

// read data, write to memory
DMA.prototype.do_read = function(buffer, start, len, channel, fn)
{
    var read_count = this.channel_count[channel] + 1,
        addr = this.channel_addr[channel];

    dbg_log("DMA write channel " + channel, LOG_DMA);
    dbg_log("to " + h(addr) + " len " + h(read_count), LOG_DMA);

    if(len < read_count)
    {
        dbg_log("DMA should read more than provided: " + h(len) + " " + h(read_count), LOG_DMA);
    }

    if(start + read_count > buffer.byteLength)
    {
        dbg_log("DMA read outside of buffer", LOG_DMA);
        fn(true);
    }
    else
    {
        var memory = this.memory;
        this.channel_addr[channel] += read_count;

        buffer.get(start, read_count, function(data)
        {
            memory.write_blob(data, addr);
            fn(false);
        });
    }
};

// write data, read memory
DMA.prototype.do_write = function(buffer, start, len, channel, fn)
{
    var read_count = this.channel_count[channel],
        addr = this.channel_addr[channel];

    dbg_log("DMA write channel " + channel, LOG_DMA);
    dbg_log("to " + h(addr) + " len " + h(read_count), LOG_DMA);

    if(len < read_count)
    {
        dbg_log("DMA should read more than provided", LOG_DMA);
    }

    if(start + read_count > buffer.byteLength)
    {
        dbg_log("DMA write outside of buffer", LOG_DMA);
        fn(true);
    }
    else
    {
        this.channel_addr[channel] += read_count;

        buffer.set(start,
                new Uint8Array(this.memory.buffer, addr, read_count + 1),
                function() {
                    fn(false);
                }
            );
    }
}

DMA.prototype.flipflop_get = function(old_dword, new_byte)
{
    this.lsb_msb_flipflop ^= 1;

    if(this.lsb_msb_flipflop)
    {
        // low byte
        return old_dword & ~0xFF | new_byte;
    }
    else
    {
        // high byte
        return old_dword & ~0xFF00 | new_byte << 8;
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 Peter Titz
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/**
 * This file takes care of the test excecution
 */

var availableDcTests = {};
var selectedDcTestList = [];
var selectedDcTestNames = [];

// Run the next test
function dctestSwitcher(count) {
    if (count < selectedDcTestList.length) {
        try {
            run_dctest(selectedDcTestNames[count], selectedDcTestList[count]);
        } catch(err) {
            console.log("Error while executing test " + selectedDcTestList[count].description, err);
        }
    } else {
        done();
    }
}

// Finds all objects in space that start with dctests - all dataChannel test definitions
function getDcTests(obj) {
    var dctests = {};
    var count = 0;
    for (var o in obj) {
        if ( typeof obj[o] === "object") {
            var oParts = o.split("_");
            if (oParts.length === 2 && oParts[0] === "dctests") {
                dctests[oParts[1]] = obj[o];
                for (var testName in obj[o]) {
                    count++;
                }
            }
        }
    }
    $('#badgeTestcount').html(count);
    availableDcTests = dctests;
}

// Create the table with all available tests
function fillDcTestTable() {
    var testlistHTML = "
";

    for (var testCategory in availableDcTests) {
        testlistHTML += '
';
        testlistHTML += ' '+ testCategory + '	';
        testlistHTML += '
';
        for (var testName in availableDcTests[testCategory]) {
            var test = availableDcTests[testCategory][testName];
            var fullName = testCategory + '.' + testName;
            testlistHTML += '
';
            testlistHTML += ' <input type="checkbox" name="test" value="' + testCategory + '.' + testName + '"> '+ testName + ' - ' + test.description + '';
            if (test.scenario !== undefined) {
                testlistHTML += ' scenario';
            }
            if (test.references !== undefined) {
                for (var i=0; i<test.references.length; i++) {
                    testlistHTML += ' ' + (i+1) + '';
                }
            }
            if (test.scenario !== undefined) {
                testlistHTML += '
' + test.scenario + '
';
            }
            testlistHTML += '
';
        }

    }
    //testlistHTML += "
</form>";

    $('#testlist').append(testlistHTML);
}

function htmlEncode(value){
  // Create a in-memory div, set its inner text (which jQuery automatically encodes)
  // Then grab the encoded contents back out. The div never exists on the page.
  return $('
').text(value).html().replace(/"/g, '"');
}

// Create new TestList with only selected Tests
function generateNewDcTestList(all) {
    selectedDcTestList = [];
    selectedDcTestNames = [];
    if (all) {
        for (var testCategory in availableDcTests) {
            for (var testName in availableDcTests[testCategory]) {
                selectedDcTestNames.push(testCategory + "." + testName);
                selectedDcTestList.push(availableDcTests[testCategory][testName]);
            }
        }
    } else {
        $('#testlist input:checkbox').each(function(){
            if($(this).prop('checked')) {
                testParts = $(this).prop('value').split(".");
                selectedDcTestNames.push(testParts[0] + "." + testParts[1]);
                selectedDcTestList.push(availableDcTests[testParts[0]][testParts[1]]);
            }
        });
    }

    console.log('new list was generated: '+selectedDcTestList.length + ' items');
}

// check the tests from selected tests (eg loaded from cookies)
function setCertainCheckboxes(){
    $("#testlist INPUT[type='checkbox']").prop('checked',false);
    $.each(selectedDcTestNames,function(key,val) {
        $('#testlist input:checkbox[value="'+val+'"]').prop('checked',true);
     });
}

function setCookie(name) {
    localStorage.setItem(name,JSON.stringify(selectedDcTestList));
    localStorage.setItem(name+"Names",JSON.stringify(selectedDcTestNames));
    return true;
}

function loadCookie(name) {
    var cookie = localStorage.getItem(name);
    var cookieNames = localStorage.getItem(name+"Names");
    if (cookie !== null) {
        selectedDcTestList = JSON.parse(cookie);
        selectedDcTestNames = JSON.parse(cookieNames);
        setCertainCheckboxes();
    } else {
        alert("Sorry, no Data!");
    }
}

function startSelectedDcTests() {
    $('.progressbar').css('width', '0%').attr('aria-valuenow', 0).html('0/'+selectedDcTestList.length);
    dctestSwitcher(0);
    $('#logWrapper').show();
    $('#testWrapper').hide();
}

function countDcTests(tests) {
    var count = 0;
    for (var testCategory in tests) {
        for (var testName in tests[testCategory]) {
            count++;
        }
    }
    return count;
}

function run_dctest(name, attr) {
    if (attr.sync) {
        test(function() {
                attr.test_function(attr.parameters);
            }, name + ' - ' + attr.description, {
                timeout: attr.timeout
            }
        );
    } else {
        var atest = async_test(name + ' - ' + attr.description, {
            timeout: attr.timeout}
        );
        atest.step(function() {
            attr.test_function(atest, attr.parameters);
        });
    }
}

// Button - start all Tests
$('button#btnTestStartAll').click(function() {
    //setCookie("previous");
    generateNewDcTestList(true);

    startSelectedDcTests();
});

// Button - start selected Tests
$('button#btnTestStartSelected').click(function() {
    generateNewDcTestList(false);

    if (selectedDcTestList.length === 0) {
        alert("Please choose some tests");
    } else {
        setCookie("previous");
        startSelectedDcTests();
    }
});

// Dropdown - select Testgroup
$('ul#testGroupSelect li a').click(function(event){
    console.log('selecting: '+ $(this).data("testgroup"));
    $("#testlist INPUT[type='checkbox']").prop('checked',false);
    $("#testlist INPUT[type='checkbox'][value^='"+$(this).data('testgroup')+"']").prop('checked',true);
    event.preventDefault();
});

// Button - invert selection
$('button#btnTestSelectOpposite').click(function(){
    $("#testlist INPUT[type='checkbox']").each( function() {
        if($(this).prop('checked', !$(this).prop('checked'))){

    	};
    });
    return false;
});

// Button - unselect all
$('button#btnTestUnselect').click(function(){
    $("#testlist INPUT[type='checkbox']").prop('checked',false);
    return false;
});

// Button - load selection from cookie
$('button#btnTestLoad').click(function(){
    loadCookie("test");
});

// Button - save selection to cookie
$('button#btnTestSave').click(function(){
    generateNewDcTestList();
    setCookie("test");
});

$('button#btnTestLoadPrevious').click(function(){
    loadCookie("previous");
});

<commit_msg>made switcher aware that async tests include steps<commit_after>/*
 * Copyright (c) 2014 Peter Titz
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/**
 * This file takes care of the test excecution
 */

var availableDcTests = {};
var selectedDcTestList = [];
var selectedDcTestNames = [];

// Run the next test
function dctestSwitcher(count) {
    if (count < selectedDcTestList.length) {
        try {
            run_dctest(selectedDcTestNames[count], selectedDcTestList[count]);
        } catch(err) {
            console.log("Error while executing test " + selectedDcTestList[count].description, err);
        }
    } else {
        done();
    }
}

// Finds all objects in space that start with dctests - all dataChannel test definitions
function getDcTests(obj) {
    var dctests = {};
    var count = 0;
    for (var o in obj) {
        if ( typeof obj[o] === "object") {
            var oParts = o.split("_");
            if (oParts.length === 2 && oParts[0] === "dctests") {
                dctests[oParts[1]] = obj[o];
                for (var testName in obj[o]) {
                    count++;
                }
            }
        }
    }
    $('#badgeTestcount').html(count);
    availableDcTests = dctests;
}

// Create the table with all available tests
function fillDcTestTable() {
    var testlistHTML = "
";

    for (var testCategory in availableDcTests) {
        testlistHTML += '
';
        testlistHTML += ' '+ testCategory + '	';
        testlistHTML += '
';
        for (var testName in availableDcTests[testCategory]) {
            var test = availableDcTests[testCategory][testName];
            var fullName = testCategory + '.' + testName;
            testlistHTML += '
';
            testlistHTML += ' <input type="checkbox" name="test" value="' + testCategory + '.' + testName + '"> '+ testName + ' - ' + test.description + '';
            if (test.scenario !== undefined) {
                testlistHTML += ' scenario';
            }
            if (test.references !== undefined) {
                for (var i=0; i<test.references.length; i++) {
                    testlistHTML += ' ' + (i+1) + '';
                }
            }
            if (test.scenario !== undefined) {
                testlistHTML += '
' + test.scenario + '
';
            }
            testlistHTML += '
';
        }

    }
    //testlistHTML += "
</form>";

    $('#testlist').append(testlistHTML);
}

function htmlEncode(value){
  // Create a in-memory div, set its inner text (which jQuery automatically encodes)
  // Then grab the encoded contents back out. The div never exists on the page.
  return $('
').text(value).html().replace(/"/g, '"');
}

// Create new TestList with only selected Tests
function generateNewDcTestList(all) {
    selectedDcTestList = [];
    selectedDcTestNames = [];
    if (all) {
        for (var testCategory in availableDcTests) {
            for (var testName in availableDcTests[testCategory]) {
                selectedDcTestNames.push(testCategory + "." + testName);
                selectedDcTestList.push(availableDcTests[testCategory][testName]);
            }
        }
    } else {
        $('#testlist input:checkbox').each(function(){
            if($(this).prop('checked')) {
                testParts = $(this).prop('value').split(".");
                selectedDcTestNames.push(testParts[0] + "." + testParts[1]);
                selectedDcTestList.push(availableDcTests[testParts[0]][testParts[1]]);
            }
        });
    }

    console.log('new list was generated: '+selectedDcTestList.length + ' items');
}

// check the tests from selected tests (eg loaded from cookies)
function setCertainCheckboxes(){
    $("#testlist INPUT[type='checkbox']").prop('checked',false);
    $.each(selectedDcTestNames,function(key,val) {
        $('#testlist input:checkbox[value="'+val+'"]').prop('checked',true);
     });
}

function setCookie(name) {
    localStorage.setItem(name,JSON.stringify(selectedDcTestList));
    localStorage.setItem(name+"Names",JSON.stringify(selectedDcTestNames));
    return true;
}

function loadCookie(name) {
    var cookie = localStorage.getItem(name);
    var cookieNames = localStorage.getItem(name+"Names");
    if (cookie !== null) {
        selectedDcTestList = JSON.parse(cookie);
        selectedDcTestNames = JSON.parse(cookieNames);
        setCertainCheckboxes();
    } else {
        alert("Sorry, no Data!");
    }
}

function startSelectedDcTests() {
    $('.progressbar').css('width', '0%').attr('aria-valuenow', 0).html('0/'+selectedDcTestList.length);
    dctestSwitcher(0);
    $('#logWrapper').show();
    $('#testWrapper').hide();
}

function countDcTests(tests) {
    var count = 0;
    for (var testCategory in tests) {
        for (var testName in tests[testCategory]) {
            count++;
        }
    }
    return count;
}

function run_dctest(name, attr) {
    if (attr.sync) {
        test(function() {
                attr.test_function(attr.parameters);
            }, name + ' - ' + attr.description, {
                timeout: attr.timeout
            }
        );
    } else {
        var atest = async_test(name + ' - ' + attr.description, {
            timeout: attr.timeout}
        );
        /*
        atest.step(function() {
            attr.test_function(atest, attr.parameters);
        });
        */
       attr.test_function(atest, attr.parameters);
    }
}

// Button - start all Tests
$('button#btnTestStartAll').click(function() {
    //setCookie("previous");
    generateNewDcTestList(true);

    startSelectedDcTests();
});

// Button - start selected Tests
$('button#btnTestStartSelected').click(function() {
    generateNewDcTestList(false);

    if (selectedDcTestList.length === 0) {
        alert("Please choose some tests");
    } else {
        setCookie("previous");
        startSelectedDcTests();
    }
});

// Dropdown - select Testgroup
$('ul#testGroupSelect li a').click(function(event){
    console.log('selecting: '+ $(this).data("testgroup"));
    $("#testlist INPUT[type='checkbox']").prop('checked',false);
    $("#testlist INPUT[type='checkbox'][value^='"+$(this).data('testgroup')+"']").prop('checked',true);
    event.preventDefault();
});

// Button - invert selection
$('button#btnTestSelectOpposite').click(function(){
    $("#testlist INPUT[type='checkbox']").each( function() {
        if($(this).prop('checked', !$(this).prop('checked'))){

    	};
    });
    return false;
});

// Button - unselect all
$('button#btnTestUnselect').click(function(){
    $("#testlist INPUT[type='checkbox']").prop('checked',false);
    return false;
});

// Button - load selection from cookie
$('button#btnTestLoad').click(function(){
    loadCookie("test");
});

// Button - save selection to cookie
$('button#btnTestSave').click(function(){
    generateNewDcTestList();
    setCookie("test");
});

$('button#btnTestLoadPrevious').click(function(){
    loadCookie("previous");
});

<|endoftext|>


<commit_before>import isArray from '../utils/is-array';
import hasOwnProp from '../utils/has-own-prop';
import isUndefined from '../utils/is-undefined';
import compareArrays from '../utils/compare-arrays';
import { deprecateSimple } from '../utils/deprecate';
import { mergeConfigs } from './set';
import { Locale } from './constructor';
import keys from '../utils/keys';

import { baseConfig } from './base-config';

// internal storage for locale config files
var locales = {};
var localeFamilies = {};
var globalLocale;

function normalizeLocale(key) {
    return key ? key.toLowerCase().replace('_', '-') : key;
}

// pick the locale from the array
// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
function chooseLocale(names) {
    var i = 0, j, next, locale, split;

    while (i < names.length) {
        split = normalizeLocale(names[i]).split('-');
        j = split.length;
        next = normalizeLocale(names[i + 1]);
        next = next ? next.split('-') : null;
        while (j > 0) {
            locale = loadLocale(split.slice(0, j).join('-'));
            if (locale) {
                return locale;
            }
            if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
                //the next array item is better than a shallower substring of this one
                break;
            }
            j--;
        }
        i++;
    }
    return null;
}

function loadLocale(name) {
    var oldLocale = null;
    // TODO: Find a better way to register and load all the locales in Node
    if (!locales[name] && (typeof module !== 'undefined') &&
            module && module.exports) {
        try {
            oldLocale = globalLocale._abbr;
            var aliasedRequire = require;
            aliasedRequire('./locale/' + name);
            getSetGlobalLocale(oldLocale);
        } catch (e) {}
    }
    return locales[name];
}

// This function will load locale and then set the global locale.  If
// no arguments are passed in, it will simply return the current global
// locale key.
export function getSetGlobalLocale (key, values) {
    var data;
    if (key) {
        if (isUndefined(values)) {
            data = getLocale(key);
        }
        else {
            data = defineLocale(key, values);
        }

        if (data) {
            // moment.duration._locale = moment._locale = data;
            globalLocale = data;
        }
    }

    return globalLocale._abbr;
}

export function defineLocale (name, config) {
    if (config !== null) {
        var parentConfig = baseConfig;
        config.abbr = name;
        if (locales[name] != null) {
            deprecateSimple('defineLocaleOverride',
                    'use moment.updateLocale(localeName, config) to change ' +
                    'an existing locale. moment.defineLocale(localeName, ' +
                    'config) should only be used for creating a new locale ' +
                    'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');
            parentConfig = locales[name]._config;
        } else if (config.parentLocale != null) {
            if (locales[config.parentLocale] != null) {
                parentConfig = locales[config.parentLocale]._config;
            } else {
                if (!localeFamilies[config.parentLocale]) {
                    localeFamilies[config.parentLocale] = [];
                }
                localeFamilies[config.parentLocale].push({
                    name: name,
                    config: config
                });
                return null;
            }
        }
        locales[name] = new Locale(mergeConfigs(parentConfig, config));

        if (localeFamilies[name]) {
            localeFamilies[name].forEach(function (x) {
                defineLocale(x.name, x.config);
            });
        }

        // backwards compat for now: also set the locale
        // make sure we set the locale AFTER all child locales have been
        // created, so we won't end up with the child locale set.
        getSetGlobalLocale(name);

        return locales[name];
    } else {
        // useful for testing
        delete locales[name];
        return null;
    }
}

export function updateLocale(name, config) {
    if (config != null) {
        var locale, tmpLocale, parentConfig = baseConfig;
        // MERGE
        tmpLocale = loadLocale(name);
        if (tmpLocale != null) {
            parentConfig = tmpLocale._config;
        }
        config = mergeConfigs(parentConfig, config);
        locale = new Locale(config);
        locale.parentLocale = locales[name];
        locales[name] = locale;

        // backwards compat for now: also set the locale
        getSetGlobalLocale(name);
    } else {
        // pass null for config to unupdate, useful for tests
        if (locales[name] != null) {
            if (locales[name].parentLocale != null) {
                locales[name] = locales[name].parentLocale;
            } else if (locales[name] != null) {
                delete locales[name];
            }
        }
    }
    return locales[name];
}

// returns locale data
export function getLocale (key) {
    var locale;

    if (key && key._locale && key._locale._abbr) {
        key = key._locale._abbr;
    }

    if (!key) {
        return globalLocale;
    }

    if (!isArray(key)) {
        //short-circuit everything else
        locale = loadLocale(key);
        if (locale) {
            return locale;
        }
        key = [key];
    }

    return chooseLocale(key);
}

export function listLocales() {
    return keys(locales);
}
<commit_msg>[misc] Print console warning when setting non-existent locales (#4085)<commit_after>import isArray from '../utils/is-array';
import hasOwnProp from '../utils/has-own-prop';
import isUndefined from '../utils/is-undefined';
import compareArrays from '../utils/compare-arrays';
import { deprecateSimple } from '../utils/deprecate';
import { mergeConfigs } from './set';
import { Locale } from './constructor';
import keys from '../utils/keys';

import { baseConfig } from './base-config';

// internal storage for locale config files
var locales = {};
var localeFamilies = {};
var globalLocale;

function normalizeLocale(key) {
    return key ? key.toLowerCase().replace('_', '-') : key;
}

// pick the locale from the array
// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
function chooseLocale(names) {
    var i = 0, j, next, locale, split;

    while (i < names.length) {
        split = normalizeLocale(names[i]).split('-');
        j = split.length;
        next = normalizeLocale(names[i + 1]);
        next = next ? next.split('-') : null;
        while (j > 0) {
            locale = loadLocale(split.slice(0, j).join('-'));
            if (locale) {
                return locale;
            }
            if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
                //the next array item is better than a shallower substring of this one
                break;
            }
            j--;
        }
        i++;
    }
    return null;
}

function loadLocale(name) {
    var oldLocale = null;
    // TODO: Find a better way to register and load all the locales in Node
    if (!locales[name] && (typeof module !== 'undefined') &&
            module && module.exports) {
        try {
            oldLocale = globalLocale._abbr;
            var aliasedRequire = require;
            aliasedRequire('./locale/' + name);
            getSetGlobalLocale(oldLocale);
        } catch (e) {}
    }
    return locales[name];
}

// This function will load locale and then set the global locale.  If
// no arguments are passed in, it will simply return the current global
// locale key.
export function getSetGlobalLocale (key, values) {
    var data;
    if (key) {
        if (isUndefined(values)) {
            data = getLocale(key);
        }
        else {
            data = defineLocale(key, values);
        }

        if (data) {
            // moment.duration._locale = moment._locale = data;
            globalLocale = data;
        }
        else {
            if ((typeof console !==  'undefined') && console.warn) {
                //warn user if arguments are passed but the locale could not be set
                console.warn('Locale ' + key +  ' not found. Did you forget to load it?');
            }
        }
    }

    return globalLocale._abbr;
}

export function defineLocale (name, config) {
    if (config !== null) {
        var parentConfig = baseConfig;
        config.abbr = name;
        if (locales[name] != null) {
            deprecateSimple('defineLocaleOverride',
                    'use moment.updateLocale(localeName, config) to change ' +
                    'an existing locale. moment.defineLocale(localeName, ' +
                    'config) should only be used for creating a new locale ' +
                    'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');
            parentConfig = locales[name]._config;
        } else if (config.parentLocale != null) {
            if (locales[config.parentLocale] != null) {
                parentConfig = locales[config.parentLocale]._config;
            } else {
                if (!localeFamilies[config.parentLocale]) {
                    localeFamilies[config.parentLocale] = [];
                }
                localeFamilies[config.parentLocale].push({
                    name: name,
                    config: config
                });
                return null;
            }
        }
        locales[name] = new Locale(mergeConfigs(parentConfig, config));

        if (localeFamilies[name]) {
            localeFamilies[name].forEach(function (x) {
                defineLocale(x.name, x.config);
            });
        }

        // backwards compat for now: also set the locale
        // make sure we set the locale AFTER all child locales have been
        // created, so we won't end up with the child locale set.
        getSetGlobalLocale(name);

        return locales[name];
    } else {
        // useful for testing
        delete locales[name];
        return null;
    }
}

export function updateLocale(name, config) {
    if (config != null) {
        var locale, tmpLocale, parentConfig = baseConfig;
        // MERGE
        tmpLocale = loadLocale(name);
        if (tmpLocale != null) {
            parentConfig = tmpLocale._config;
        }
        config = mergeConfigs(parentConfig, config);
        locale = new Locale(config);
        locale.parentLocale = locales[name];
        locales[name] = locale;

        // backwards compat for now: also set the locale
        getSetGlobalLocale(name);
    } else {
        // pass null for config to unupdate, useful for tests
        if (locales[name] != null) {
            if (locales[name].parentLocale != null) {
                locales[name] = locales[name].parentLocale;
            } else if (locales[name] != null) {
                delete locales[name];
            }
        }
    }
    return locales[name];
}

// returns locale data
export function getLocale (key) {
    var locale;

    if (key && key._locale && key._locale._abbr) {
        key = key._locale._abbr;
    }

    if (!key) {
        return globalLocale;
    }

    if (!isArray(key)) {
        //short-circuit everything else
        locale = loadLocale(key);
        if (locale) {
            return locale;
        }
        key = [key];
    }

    return chooseLocale(key);
}

export function listLocales() {
    return keys(locales);
}
<|endoftext|>


<commit_before>import {isFunction} from 'lodash';
import * as amqp from 'amqplib';
import * as rpc from 'micro-node-json-rpc';

const debug = require('debug')('amqp');

const protocol = 'amqp';
const contentType = 'application/json';

const connections = [];
const callbacks = {};

/**
 *
 * The AMQP RPC Client
 *
 * @param addr
 * @returns {Function} client function
 */
export function client(addr, queue){

  let Q = assetQueue(addr, '', {exclusive: true});

  Q.then(function([ch, q]) {

    let replyTo = q.queue;

    debug('[client] Awaiting RPC response');

    ch.assertQueue(queue, {durable: false});

    ch.consume(replyTo, function (msg) {

      let callback = callbacks[msg.properties.correlationId];

      if(callback !== undefined){

        debug('[client] Receive RPC response %s', msg.properties.correlationId);
        debug('[client] Response data %s', msg.content.toString());

        let resp = JSON.parse(msg.content.toString());

        callback(resp.error, resp.result);

        delete callbacks[msg.properties.correlationId];
      }
    });
  });

  // the actual requester
  return function(req, options, callback){

    if(isFunction(options)){

      callback = options;
      options = {};
    }

    Q.then(function([ch, q]){

      let replyTo = q.queue;
      let stringReq = JSON.stringify(req);

      if(req.id)
        callbacks[req.id] = callback;

      if(options && options.timeout){

        timeout(req, options.timeout);
      }

      debug('[client] Send RPC request %s', req.id);
      debug('[client] Request data %s', stringReq);

      ch.sendToQueue(queue, new Buffer(stringReq), {correlationId: req.id, replyTo, contentType});

    }, callback);
  };
}

/**
 * The AMQP RPC Server
 *
 * @param addr
 * @param func server function
 * @returns {{on: proxy.on, close: proxy.close}}
 */
export function server(addr, queue, func, callback){

  let connection = createChannel(addr).then(function([conn, ch]){

    ch.assertQueue(queue, {durable: false});
    ch.prefetch(1);

    debug('[server] Awaiting RPC requests');

    ch.consume(queue, function reply(msg) {

      let req = JSON.parse(msg.content.toString());

      debug('[server] Request received %s', msg.properties.correlationId);
      debug('[server] Request data %s', msg.content.toString());

      try{

        func(req, function(resp){

          let stringResp = JSON.stringify(resp);

          debug('[server] Send RPC request %s', msg.properties.correlationId);
          debug('[server] Request data %s', stringResp);

          ch.sendToQueue(msg.properties.replyTo, new Buffer(stringResp), {correlationId: msg.properties.correlationId, contentType});
          ch.ack(msg);
        });

      }catch(err){

        debug('[server] Error for %s', msg.properties.correlationId);
        debug('[server] Error data', err);

        ch.sendToQueue(msg.properties.replyTo, new Buffer(JSON.stringify(rpc.error(req, err))), {correlationId: msg.properties.correlationId, contentType});
        ch.ack(msg);
      }
    });

    // call with connection
    callback && callback(null, conn);

    return conn;

  }, callback);

  let proxy = {

    on: function(...args){

      connection.then(conn => conn.on(...args));
    },

    close: function(){

      connection.then(conn => conn.close());
    }
  };

  return proxy;
}

/**
 * timeout handler
 * @param req
 * @param delay
 */
function timeout(req, delay){

  setTimeout(_timeout, delay);

  function _timeout(){

    let callback = callbacks[req.id];

    if(!callback) return;

    let err = new Error('request timeout');

    err.name = 'Timeout';

    callback(rpc.error(req, err).error);

    delete callbacks[req.id];
  }
}

/**
 * deleting queues is also usefull
 * @param addr
 * @param queue
 * @param options
 * @returns {Promise|*|Promise.<T>}
 */
export function deleteQueue(addr, queue, options){

  return createChannel(addr)
    .then(([_, ch])=> ch.deleteQueue(queue, options), debugError);
}

// asset queue helper
function assetQueue(addr, queue, options){

  return createChannel(addr).then((data) =>{

    let ch = data[1];

    return ch.assertQueue(queue, options).then(q => [ch, q]);
  });
}

// create channel helper
function createChannel(addr){

  return amqp.connect(genAddr(addr)).then((conn) => {

    return conn.createChannel().then(ch => {

      connections.push(conn);

      return [conn, ch];
    });

  }, debugError);
}

function genAddr(addr, proc = protocol){

  return `${proc}://${addr}`;
}

function debugError(err){

  debug('[error] ', err);

  return err;
}

// close all connections on exit
process.on('exit', ()=> connections.forEach((conn)=>conn.close()));
<commit_msg>better debug logs<commit_after>import {isFunction} from 'lodash';
import * as amqp from 'amqplib';
import * as rpc from 'micro-node-json-rpc';

const debug = require('debug');

const log = debug('amqp:log');
const logError = debug('amqp:error');
const logData = debug('amqp-data:log');

const protocol = 'amqp';
const contentType = 'application/json';

const connections = [];
const callbacks = {};

/**
 *
 * The AMQP RPC Client
 *
 * @param addr
 * @returns {Function} client function
 */
export function client(addr, queue){

  let Q = assetQueue(addr, '', {exclusive: true});

  Q.then(function([ch, q]) {

    let replyTo = q.queue;

    log('[client] Awaiting RPC response');

    ch.assertQueue(queue, {durable: false});

    ch.consume(replyTo, function (msg) {

      let callback = callbacks[msg.properties.correlationId];

      if(callback !== undefined){

        log('[client] Receive RPC response %s', msg.properties.correlationId);
        logData('[client] Response data %s', msg.content.toString());

        let resp = JSON.parse(msg.content.toString());

        callback(resp.error, resp.result);

        delete callbacks[msg.properties.correlationId];
      }
    });
  });

  // the actual requester
  return function(req, options, callback){

    if(isFunction(options)){

      callback = options;
      options = {};
    }

    Q.then(function([ch, q]){

      let replyTo = q.queue;
      let stringReq = JSON.stringify(req);

      if(req.id)
        callbacks[req.id] = callback;

      if(options && options.timeout){

        timeout(req, options.timeout);
      }

      log('[client] Send RPC request %s', req.id);
      logData('[client] Request data %s', stringReq);

      ch.sendToQueue(queue, new Buffer(stringReq), {correlationId: req.id, replyTo, contentType});

    }, callback);
  };
}

/**
 * The AMQP RPC Server
 *
 * @param addr
 * @param func server function
 * @returns {{on: proxy.on, close: proxy.close}}
 */
export function server(addr, queue, func, callback){

  let connection = createChannel(addr).then(function([conn, ch]){

    ch.assertQueue(queue, {durable: false});
    ch.prefetch(1);

    log('[server] Awaiting RPC requests');

    ch.consume(queue, function reply(msg) {

      let req = JSON.parse(msg.content.toString());

      log('[server] Request received %s', msg.properties.correlationId);
      logData('[server] Request data %s', msg.content.toString());

      try{

        func(req, function(resp){

          let stringResp = JSON.stringify(resp);

          log('[server] Send RPC request %s', msg.properties.correlationId);
          logData('[server] Request data %s', stringResp);

          ch.sendToQueue(msg.properties.replyTo, new Buffer(stringResp), {correlationId: msg.properties.correlationId, contentType});
          ch.ack(msg);
        });

      }catch(err){

        logError('[server] Error for %s', msg.properties.correlationId);
        logError('[server] Error data', err);

        ch.sendToQueue(msg.properties.replyTo, new Buffer(JSON.stringify(rpc.error(req, err))), {correlationId: msg.properties.correlationId, contentType});
        ch.ack(msg);
      }
    });

    // call with connection
    callback && callback(null, conn);

    return conn;

  }, callback);

  let proxy = {

    on: function(...args){

      connection.then(conn => conn.on(...args));
    },

    close: function(){

      connection.then(conn => conn.close());
    }
  };

  return proxy;
}

/**
 * timeout handler
 * @param req
 * @param delay
 */
function timeout(req, delay){

  setTimeout(_timeout, delay);

  function _timeout(){

    let callback = callbacks[req.id];

    if(!callback) return;

    let err = new Error('request timeout');

    err.name = 'Timeout';

    callback(rpc.error(req, err).error);

    delete callbacks[req.id];
  }
}

/**
 * deleting queues is also usefull
 * @param addr
 * @param queue
 * @param options
 * @returns {Promise|*|Promise.<T>}
 */
export function deleteQueue(addr, queue, options){

  return createChannel(addr)
    .then(([_, ch])=> ch.deleteQueue(queue, options), debugError);
}

// asset queue helper
function assetQueue(addr, queue, options){

  return createChannel(addr).then((data) =>{

    let ch = data[1];

    return ch.assertQueue(queue, options).then(q => [ch, q]);
  });
}

// create channel helper
function createChannel(addr){

  return amqp.connect(genAddr(addr)).then((conn) => {

    return conn.createChannel().then(ch => {

      connections.push(conn);

      return [conn, ch];
    });

  }, debugError);
}

function genAddr(addr, proc = protocol){

  return `${proc}://${addr}`;
}

function debugError(err){

  logError('[error] ', err);

  return err;
}

// close all connections on exit
process.on('exit', ()=> connections.forEach((conn)=>conn.close()));
<|endoftext|>


<commit_before>import { toArray } from './util'

export function $ (selector, el = document) {
  return el.querySelector(selector)
}

export function $$ (selector, el = document) {
  return toArray(el.querySelectorAll(selector))
}

export function id (name, el = document) {
  return el.getElementById(name)
}

export function replace (oldElement, newElement) {
  oldElement.parentNode.replaceChild(newElement, oldElement)
  return newElement
}

export function index (el) {
  let idx = 0
  while (el) {
    idx++
    el = el.previousElementSibling
  }
  return idx
}

export function remove (el) {
  el.parentNode && el.parentNode.removeChild(el)
  return el
}

export function rect (el) {
  const rect = el.getBoundingClientRect()

  return {
    top: window.pageYOffset + rect.top,
    left: window.pageXOffset + rect.left,
    width: rect.width,
    height: rect.height
  }
}

export function className (name) {
  return {
    add: (el, ...args) => {
      addClass(el, ...args.concat(name))
      return this
    },
    remove: (el, ...args) => {
      removeClass(el, ...args.concat(name))
      return this
    },
    toggle: (el, force = undefined) => {
      toggleClass(el, name, force)
      return this
    },
    selector: () => `.${name}`,
    toString: () => name
  }
}

export function addClass (el, ...args) {
  el.classList.add(...args)
  return el
}

export function toggleClass (el, className, force = undefined) {
  el.classList.toggle(className, force)
  return el
}

export function removeClass (el, ...args) {
  el.classList.remove(...args)
  return el
}

export function attr (name) {
  return {
    get: (el, ...args) => getAttr(el, name, ...args),
    set: (el, ...args) => {
      setAttr(el, name, ...args)
      return this
    },
    has: el => hasAttr(el, name),
    selector: (value = undefined) => `[${name}${value ? `="${value}"` : ''}]`,
    toString: () => name
  }
}

export function getAttr (el, name, defaultValue = undefined) {
  return el && el.hasAttribute(name) ? el.getAttribute(name) : defaultValue
}

export function setAttr (el, name, value, append = false) {
  const attrValue = append ? getAttr(el, name, '') + ' ' + value : value
  el.setAttribute(name, attrValue)
  return el
}

export function hasAttr (el, name) {
  return el && el.hasAttribute(name)
}

export function insertElement (position, node, newNode) {
  switch (position) {
    case 'beforebegin':
      node.parentNode.insertBefore(newNode, node)
      break
    case 'afterend':
      node.parentNode.insertBefore(newNode, node.nextElementSibling)
      break
  }

  return newNode
}

insertElement.before = (node, newNode) => insertElement('beforebegin', node, newNode)
insertElement.after = (node, newNode) => insertElement('afterend', node, newNode)

export default {
  $,
  $$,
  id,
  replace,
  index,
  remove,
  rect,
  className,
  addClass,
  toggleClass,
  removeClass,
  attr,
  getAttr,
  setAttr,
  hasAttr,
  insertElement
}
<commit_msg>add has test for className<commit_after>import { toArray } from './util'

export function $ (selector, el = document) {
  return el.querySelector(selector)
}

export function $$ (selector, el = document) {
  return toArray(el.querySelectorAll(selector))
}

export function id (name, el = document) {
  return el.getElementById(name)
}

export function replace (oldElement, newElement) {
  oldElement.parentNode.replaceChild(newElement, oldElement)
  return newElement
}

export function index (el) {
  let idx = 0
  while (el) {
    idx++
    el = el.previousElementSibling
  }
  return idx
}

export function remove (el) {
  el.parentNode && el.parentNode.removeChild(el)
  return el
}

export function rect (el) {
  const rect = el.getBoundingClientRect()

  return {
    top: window.pageYOffset + rect.top,
    left: window.pageXOffset + rect.left,
    width: rect.width,
    height: rect.height
  }
}

export function className (name) {
  return {
    add: (el, ...args) => {
      addClass(el, ...args.concat(name))
      return this
    },
    remove: (el, ...args) => {
      removeClass(el, ...args.concat(name))
      return this
    },
    toggle: (el, force = undefined) => {
      toggleClass(el, name, force)
      return this
    },
    has: el => {
      return el.classList.contains(name)
    },
    selector: () => `.${name}`,
    toString: () => name
  }
}

export function addClass (el, ...args) {
  el.classList.add(...args)
  return el
}

export function toggleClass (el, className, force = undefined) {
  el.classList.toggle(className, force)
  return el
}

export function removeClass (el, ...args) {
  el.classList.remove(...args)
  return el
}

export function attr (name) {
  return {
    get: (el, ...args) => getAttr(el, name, ...args),
    set: (el, ...args) => {
      setAttr(el, name, ...args)
      return this
    },
    has: el => hasAttr(el, name),
    selector: (value = undefined) => `[${name}${value ? `="${value}"` : ''}]`,
    toString: () => name
  }
}

export function getAttr (el, name, defaultValue = undefined) {
  return el && el.hasAttribute(name) ? el.getAttribute(name) : defaultValue
}

export function setAttr (el, name, value, append = false) {
  const attrValue = append ? getAttr(el, name, '') + ' ' + value : value
  el.setAttribute(name, attrValue)
  return el
}

export function hasAttr (el, name) {
  return el && el.hasAttribute(name)
}

export function insertElement (position, node, newNode) {
  switch (position) {
    case 'beforebegin':
      node.parentNode.insertBefore(newNode, node)
      break
    case 'afterend':
      node.parentNode.insertBefore(newNode, node.nextElementSibling)
      break
  }

  return newNode
}

insertElement.before = (node, newNode) => insertElement('beforebegin', node, newNode)
insertElement.after = (node, newNode) => insertElement('afterend', node, newNode)

export default {
  $,
  $$,
  id,
  replace,
  index,
  remove,
  rect,
  className,
  addClass,
  toggleClass,
  removeClass,
  attr,
  getAttr,
  setAttr,
  hasAttr,
  insertElement
}
<|endoftext|>


<commit_before>import Vue from 'vue';
import App from './App.vue';

Vue.config.productionTip = false;
Vue.config.devtools = false;

// Brutalism library support
import {
	ButtonGroup, Button, Col, Divider, Dropdown, Dropzone, FileInput, Fold, Icon, InputNumber, InputScroll, Menus, PanelInfo, Panel, Row, Tabs, Toggle, Wrapper, Altpan, Autofocus, Pan
} from "../../../../../Modules/brutalism/src/brutalism";

require("../node_modules/@mdi/font/css/materialdesignicons.css");

Vue.component("Button-Group", ButtonGroup);
Vue.component("Button", Button);
Vue.component("Col", Col);
Vue.component("Divider", Divider);
Vue.component("Dropdown", Dropdown);
Vue.component("Dropzone", Dropzone);
Vue.component("File-Input", FileInput);
Vue.component("Fold", Fold);
Vue.component("Icon", Icon);
Vue.component("Input-Number", InputNumber);
Vue.component("Input-Scroll", InputScroll);
Vue.component("Menus", Menus);
Vue.component("Panel-Info", PanelInfo);
Vue.component("Panel", Panel);
Vue.component("Row", Row);
Vue.component("Tabs", Tabs);
Vue.component("Toggle", Toggle);
Vue.component("Wrapper", Wrapper);
Vue.directive("altpan", Altpan);
Vue.directive("autofocus", Autofocus);
Vue.directive("pan", Pan);

new Vue({
  render: h => h(App)
}).$mount('#app');
<commit_msg>Cleanup<commit_after>import Vue from 'vue';
import App from './App.vue';

Vue.config.productionTip = false;
Vue.config.devtools = false;

// Brutalism library support
import {
	Alert, ButtonGroup, Button, Col, Divider, Dropdown, Dropzone, FileInput, Fold, Footer, Icon, InputNumber, InputScroll, Input, Menus, PanelInfo, Panel, RotationControl, Row, Tabs, TextArea, Toggle, Wrapper, Altpan, Autofocus, Pan
} from "../../../../../Modules/brutalism/src/brutalism";

require("../node_modules/@mdi/font/css/materialdesignicons.css");

Vue.component("Alert", Alert);
Vue.component("Button-Group", ButtonGroup);
Vue.component("Button", Button);
Vue.component("Col", Col);
Vue.component("Divider", Divider);
Vue.component("Dropdown", Dropdown);
Vue.component("Dropzone", Dropzone);
Vue.component("File-Input", FileInput);
Vue.component("Fold", Fold);
Vue.component("Footer", Footer);
Vue.component("Icon", Icon);
Vue.component("Input-Number", InputNumber);
Vue.component("Input-Scroll", InputScroll);
Vue.component("Input", Input);
Vue.component("Menus", Menus);
Vue.component("Panel-Info", PanelInfo);
Vue.component("Panel", Panel);
Vue.component("Rotation-Control", RotationControl);
Vue.component("Row", Row);
Vue.component("Tabs", Tabs);
Vue.component("TextArea", TextArea);
Vue.component("Toggle", Toggle);
Vue.component("Wrapper", Wrapper);
Vue.directive("altpan", Altpan);
Vue.directive("autofocus", Autofocus);
Vue.directive("pan", Pan);

new Vue({
  render: h => h(App)
}).$mount('#app');
<|endoftext|>


<commit_before>const assert = require('assert');
const coordinates = require('../../../../lib/cartodb/middleware/coordinates');

describe('coordinates middleware', function () {
    it('should return error: invalid zoom paramenter (-1)', function (done) {
        const coords = coordinates();
        const req = {
            params: {
                z: '-1',
                x: '0',
                y: '0'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.equal(
                err.message,
                'Invalid zoom value (-1). It should be an integer number greather or equal to 0'
            );
            assert.equal(err.http_status, 400);
            done();
        });
    });

    it('should return error: invalid zoom paramenter (1.1)', function (done) {
        const coords = coordinates();
        const req = {
            params: {
                z: '1.1',
                x: '0',
                y: '0'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.equal(
                err.message,
                'Invalid zoom value (1.1). It should be an integer number greather or equal to 0'
            );
            assert.equal(err.http_status, 400);
            done();
        });
    });

    it('should return error: invalid zoom paramenter (wadus)', function (done) {
        const coords = coordinates();
        const req = {
            params: {
                z: 'wadus',
                x: '0',
                y: '0'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.equal(
                err.message,
                'Invalid zoom value (wadus). It should be an integer number greather or equal to 0'
            );
            assert.equal(err.http_status, 400);
            done();
        });
    });

    it('should NOT return error: \'zoom\' paramenter (1)', function (done) {
        const coords = coordinates();
        const req = {
            params: {
                z: '1',
                x: '1',
                y: '0'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.ifError(err);
            done();
        });
    });

    it('should return error: invalid coordinate \'x\' paramenter (1.1)', function (done) {
        const coords = coordinates();
        const req = {
            params: {
                z: '1',
                x: '1.1',
                y: '0'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.equal(err.message, `Invalid coodinate 'x' value (1.1). It should be an integer number`);
            assert.equal(err.http_status, 400);
            done();
        });
    });

    it('should return error: invalid coordinate \'x\' paramenter (wadus)', function (done) {
        const coords = coordinates();
        const req = {
            params: {
                z: '1',
                x: 'wadus',
                y: '0'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.equal(err.message, `Invalid coodinate 'x' value (wadus). It should be an integer number`);
            assert.equal(err.http_status, 400);
            done();
        });
    });

    it('should NOT return error: \'x\' paramenter (-1)', function (done) {
        const coords = coordinates();
        const req = {
            params: {
                z: '1',
                x: '-3',
                y: '0'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.ifError(err);
            done();
        });
    });

    it('should return error: invalid coordinate \'y\' paramenter (-1)', function (done) {
        const coords = coordinates();
        const req = {
            params: {
                z: '1',
                x: '0',
                y: '-1'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.equal(
                err.message,
                `Invalid coodinate 'y' value (-1). It should be an integer number greather or equal to 0`
            );
            assert.equal(err.http_status, 400);
            done();
        });
    });

    it('should return error: invalid coordinate \'y\' paramenter (1.1)', function (done) {
        const coords = coordinates();
        const req = {
            params: {
                z: '1',
                x: '0',
                y: '1.1'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.equal(
                err.message,
                `Invalid coodinate 'y' value (1.1). It should be an integer number greather or equal to 0`
            );
            assert.equal(err.http_status, 400);
            done();
        });
    });

    it('should return error: invalid coordinate \'y\' paramenter (wadus)', function (done) {
        const coords = coordinates();
        const req = {
            params: {
                z: '1',
                x: '0',
                y: 'wadus'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.equal(
                err.message,
                `Invalid coodinate 'y' value (wadus). It should be an integer number greather or equal to 0`
            );
            assert.equal(err.http_status, 400);
            done();
        });
    });

    it('should NOT return error: \'y\' paramenter (1)', function (done) {
        const coords = coordinates();
        const req = {
            params: {
                z: '1',
                x: '1',
                y: '1'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.ifError(err);
            done();
        });
    });

    it('should validate zoom and should return error: invalid zoom paramenter (-1.1)', function (done) {
        const coords = coordinates({ z: true, x: false, y: false });
        const req = {
            params: {
                z: '-1.1'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.equal(
                err.message,
                'Invalid zoom value (-1.1). It should be an integer number greather or equal to 0'
            );
            assert.equal(err.http_status, 400);
            done();
        });
    });
});
<commit_msg>Add test to check that the regexp validates just digits<commit_after>const assert = require('assert');
const coordinates = require('../../../../lib/cartodb/middleware/coordinates');

describe('coordinates middleware', function () {
    it('should return error: invalid zoom paramenter (-1)', function (done) {
        const coords = coordinates();
        const req = {
            params: {
                z: '-1',
                x: '0',
                y: '0'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.equal(
                err.message,
                'Invalid zoom value (-1). It should be an integer number greather or equal to 0'
            );
            assert.equal(err.http_status, 400);
            done();
        });
    });

    it('should return error: invalid zoom paramenter (1.1)', function (done) {
        const coords = coordinates();
        const req = {
            params: {
                z: '1.1',
                x: '0',
                y: '0'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.equal(
                err.message,
                'Invalid zoom value (1.1). It should be an integer number greather or equal to 0'
            );
            assert.equal(err.http_status, 400);
            done();
        });
    });

    it('should return error: invalid zoom paramenter (0.1)', function (done) {
        const coords = coordinates();
        const req = {
            params: {
                z: '0.1',
                x: '0',
                y: '0'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.equal(
                err.message,
                'Invalid zoom value (0.1). It should be an integer number greather or equal to 0'
            );
            assert.equal(err.http_status, 400);
            done();
        });
    });

    it('should return error: invalid zoom paramenter (wadus)', function (done) {
        const coords = coordinates();
        const req = {
            params: {
                z: 'wadus',
                x: '0',
                y: '0'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.equal(
                err.message,
                'Invalid zoom value (wadus). It should be an integer number greather or equal to 0'
            );
            assert.equal(err.http_status, 400);
            done();
        });
    });

    it('should NOT return error: \'zoom\' paramenter (1)', function (done) {
        const coords = coordinates();
        const req = {
            params: {
                z: '1',
                x: '1',
                y: '0'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.ifError(err);
            done();
        });
    });

    it('should return error: invalid coordinate \'x\' paramenter (1.1)', function (done) {
        const coords = coordinates();
        const req = {
            params: {
                z: '1',
                x: '1.1',
                y: '0'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.equal(err.message, `Invalid coodinate 'x' value (1.1). It should be an integer number`);
            assert.equal(err.http_status, 400);
            done();
        });
    });

    it('should return error: invalid coordinate \'x\' paramenter (wadus)', function (done) {
        const coords = coordinates();
        const req = {
            params: {
                z: '1',
                x: 'wadus',
                y: '0'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.equal(err.message, `Invalid coodinate 'x' value (wadus). It should be an integer number`);
            assert.equal(err.http_status, 400);
            done();
        });
    });

    it('should NOT return error: \'x\' paramenter (-1)', function (done) {
        const coords = coordinates();
        const req = {
            params: {
                z: '1',
                x: '-3',
                y: '0'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.ifError(err);
            done();
        });
    });

    it('should return error: invalid coordinate \'y\' paramenter (-1)', function (done) {
        const coords = coordinates();
        const req = {
            params: {
                z: '1',
                x: '0',
                y: '-1'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.equal(
                err.message,
                `Invalid coodinate 'y' value (-1). It should be an integer number greather or equal to 0`
            );
            assert.equal(err.http_status, 400);
            done();
        });
    });

    it('should return error: invalid coordinate \'y\' paramenter (1.1)', function (done) {
        const coords = coordinates();
        const req = {
            params: {
                z: '1',
                x: '0',
                y: '1.1'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.equal(
                err.message,
                `Invalid coodinate 'y' value (1.1). It should be an integer number greather or equal to 0`
            );
            assert.equal(err.http_status, 400);
            done();
        });
    });

    it('should return error: invalid coordinate \'y\' paramenter (wadus)', function (done) {
        const coords = coordinates();
        const req = {
            params: {
                z: '1',
                x: '0',
                y: 'wadus'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.equal(
                err.message,
                `Invalid coodinate 'y' value (wadus). It should be an integer number greather or equal to 0`
            );
            assert.equal(err.http_status, 400);
            done();
        });
    });

    it('should NOT return error: \'y\' paramenter (1)', function (done) {
        const coords = coordinates();
        const req = {
            params: {
                z: '1',
                x: '1',
                y: '1'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.ifError(err);
            done();
        });
    });

    it('should validate zoom and should return error: invalid zoom paramenter (-1.1)', function (done) {
        const coords = coordinates({ z: true, x: false, y: false });
        const req = {
            params: {
                z: '-1.1'
            }
        };
        const res = {};

        coords(req, res, function (err) {
            assert.equal(
                err.message,
                'Invalid zoom value (-1.1). It should be an integer number greather or equal to 0'
            );
            assert.equal(err.http_status, 400);
            done();
        });
    });
});
<|endoftext|>


<commit_before>import Bus from './bus';
import Row from './row';
import { getIndex } from './utils';
import { AREA_NODE } from './constant';
import { ADD_COMPONENT, DUPLICATE_ROW, DELETE_ROW } from './events';

/**
 * Area is a member of Leylim and that manage update, delete, duplicate ~ row, etc. actions.
 * Area has contain and store all component as template.
 * Therefore can generate dirty html string.
 *
 * @export
 * @class Area
 * @extends {Bus}
 */
export default class Area {
  constructor(options) {
    this.options = options;
    this.rowList = [];

    const {
      beforeRowUpdate,
      rowUpdated
    } = this.options.events;

    Row.useEvents({
      beforeRowUpdate,
      rowUpdated
    })

    Bus.subscribe(this.handleEvents);
    this.generateRow();
    this.initArea();
    this.render();
  }
  /**
   * Return all rowlist data
   *
   * @memberof Area
   * @return {Object} Row list
   */
  getRowData() {
    const data = [];
    const list = this.rowList;
    for (var ii = 0; ii < list.length; ii++) {
      let rawData = list[ii].getRawData();
      data.push(JSON.stringify(rawData));
    }

    return data;
  }
  /**
   * For external row data generating.
   *
   * @example
   * ```
   *  const components = [...];
   *
   *  const rowList = [
   *    {
   *      name: 'hacucuao',
   *      template: `<div contenteditable>Template hacucuao</div>`
   *    }
   *  ]
   *  const leylim = new Leylim({
   *    el: '#app',
   *    components,
   *    rowList
   *  });
   * ```
   *
   * @memberof Area
  */
  generateRow() {
    const { rowList } = this.options;
    for (var ii = 0; ii < rowList.length; ii++) {
      this.rowList.push(new Row(rowList[ii]));
    }
  }
  /**
   * This actions trigger by listItem
   * @param {Object} row
   * @memberof Area
   */
  deleteAndDuplicateRow(_uuid, isDuplicate) {
    const {
      beforeRowDuplicate,
      rowDuplicated,
      beforeRowDelete,
      rowDeleted
    } = this.options.events;

    let interimRow;
    const row = {};
    const duplicatedRow = this.rowList.filter(r => r._uuid == _uuid)[0];
    const index = getIndex(this.rowList, duplicatedRow)

    row.component = Object.assign({}, duplicatedRow.component)

    if (isDuplicate) {
      beforeRowDuplicate(row.component, (newRow) => {
        interimRow = newRow;
        this.rowList.splice((index + 1), 0, new Row(newRow));
        this.render();
      });
      rowDuplicated(interimRow);
    } else {
      beforeRowDelete(row, (newRow) => {
        interimRow = newRow;
        this.rowList.splice(newRow.index, 1);
        this.render();
      });
      rowDeleted(interimRow);
    }
  }
  /**
   * Actions from listItem
   * This actions trigger by listItem
   * @param {any} component
   * @memberof Area
   */
  addComponent(row) {
    const {
      beforeRowAdd,
      rowAdded
    } = this.options.events;

    let interimRow;
    beforeRowAdd(row, (newRow) => {
      interimRow = newRow;
      this.rowList.push(new Row(newRow));
      this.render();
    });

    rowAdded(interimRow)
  }
  /**
   * It make out all relevant events .
   * @memberof Area
   */
  handleEvents = (type, params) => {
    switch (type) {
      case ADD_COMPONENT:
        this.addComponent(params);
        break;
      case DUPLICATE_ROW:
        this.deleteAndDuplicateRow(params, true);
        break;
      case DELETE_ROW:
        this.deleteAndDuplicateRow(params, false);
        break;
    }
  };
  /**
   * This method appendices itself to rootEl of leylim.
   */
  initArea() {
    const { rootNode } = this.options;
    const rootEl = document.querySelector(rootNode);
    const areaNode = document.createElement('div');
    areaNode.classList.add(AREA_NODE);
    rootEl.appendChild(areaNode);
    this.areaNode = areaNode;
  }
  /**
   * re-render and init render all row
   * @memberof Area
   */
  render() {
    const areaNode = this.areaNode;

    while (areaNode.firstChild) {
      areaNode.removeChild(areaNode.firstChild);
    }

    if (this.rowList.length) {
      for (var ii = 0; ii < this.rowList.length; ii++) {
        this.rowList[ii].render(ii);
      }
    } else {
      areaNode.innerHTML = `<div class="leylim__empty-area"><span>😒</span> </br> No content</div>`
    }
  }
}
<commit_msg>fix deleting issue<commit_after>import Bus from './bus';
import Row from './row';
import { getIndex } from './utils';
import { AREA_NODE } from './constant';
import { ADD_COMPONENT, DUPLICATE_ROW, DELETE_ROW } from './events';

/**
 * Area is a member of Leylim and that manage update, delete, duplicate ~ row, etc. actions.
 * Area has contain and store all component as template.
 * Therefore can generate dirty html string.
 *
 * @export
 * @class Area
 * @extends {Bus}
 */
export default class Area {
  constructor(options) {
    this.options = options;
    this.rowList = [];

    const {
      beforeRowUpdate,
      rowUpdated
    } = this.options.events;

    Row.useEvents({
      beforeRowUpdate,
      rowUpdated
    })

    Bus.subscribe(this.handleEvents);
    this.generateRow();
    this.initArea();
    this.render();
  }
  /**
   * Return all rowlist data
   *
   * @memberof Area
   * @return {Object} Row list
   */
  getRowData() {
    const data = [];
    const list = this.rowList;
    for (var ii = 0; ii < list.length; ii++) {
      let rawData = list[ii].getRawData();
      data.push(JSON.stringify(rawData));
    }

    return data;
  }
  /**
   * For external row data generating.
   *
   * @example
   * ```
   *  const components = [...];
   *
   *  const rowList = [
   *    {
   *      name: 'hacucuao',
   *      template: `<div contenteditable>Template hacucuao</div>`
   *    }
   *  ]
   *  const leylim = new Leylim({
   *    el: '#app',
   *    components,
   *    rowList
   *  });
   * ```
   *
   * @memberof Area
  */
  generateRow() {
    const { rowList } = this.options;
    for (var ii = 0; ii < rowList.length; ii++) {
      this.rowList.push(new Row(rowList[ii]));
    }
  }
  /**
   * This actions trigger by listItem
   * @param {Object} row
   * @memberof Area
   */
  deleteAndDuplicateRow(_uuid, isDuplicate) {
    const {
      beforeRowDuplicate,
      rowDuplicated,
      beforeRowDelete,
      rowDeleted
    } = this.options.events;

    let interimRow;
    const row = {};
    const duplicatedRow = this.rowList.filter(r => r._uuid == _uuid)[0];
    const index = getIndex(this.rowList, duplicatedRow)

    row.component = Object.assign({}, duplicatedRow.component)

    if (isDuplicate) {
      beforeRowDuplicate(row.component, (newRow) => {
        interimRow = newRow;
        this.rowList.splice((index + 1), 0, new Row(newRow));
        this.render();
      });
      rowDuplicated(interimRow);
    } else {
      beforeRowDelete(row, (newRow) => {
        interimRow = newRow;
        this.rowList.splice(index, 1);
        this.render();
      });
      rowDeleted(interimRow);
    }
  }
  /**
   * Actions from listItem
   * This actions trigger by listItem
   * @param {any} component
   * @memberof Area
   */
  addComponent(row) {
    const {
      beforeRowAdd,
      rowAdded
    } = this.options.events;

    let interimRow;
    beforeRowAdd(row, (newRow) => {
      interimRow = newRow;
      this.rowList.push(new Row(newRow));
      this.render();
    });

    rowAdded(interimRow)
  }
  /**
   * It make out all relevant events .
   * @memberof Area
   */
  handleEvents = (type, params) => {
    switch (type) {
      case ADD_COMPONENT:
        this.addComponent(params);
        break;
      case DUPLICATE_ROW:
        this.deleteAndDuplicateRow(params, true);
        break;
      case DELETE_ROW:
        this.deleteAndDuplicateRow(params, false);
        break;
    }
  };
  /**
   * This method appendices itself to rootEl of leylim.
   */
  initArea() {
    const { rootNode } = this.options;
    const rootEl = document.querySelector(rootNode);
    const areaNode = document.createElement('div');
    areaNode.classList.add(AREA_NODE);
    rootEl.appendChild(areaNode);
    this.areaNode = areaNode;
  }
  /**
   * re-render and init render all row
   * @memberof Area
   */
  render() {
    const areaNode = this.areaNode;

    while (areaNode.firstChild) {
      areaNode.removeChild(areaNode.firstChild);
    }

    if (this.rowList.length) {
      for (var ii = 0; ii < this.rowList.length; ii++) {
        this.rowList[ii].render(ii);
      }
    } else {
      areaNode.innerHTML = `<div class="leylim__empty-area"><span>😒</span> </br> No content</div>`
    }
  }
}
<|endoftext|>