"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createGrid = exports.createTable = void 0;
var tslib_1 = require("tslib");
var test_1 = require("../../test");
var _1 = require(".");
var common_1 = require("../../common");
var libs_Handsontable_1 = require("../../common/libs.Handsontable");
exports.createTable = function () {
    var el = document.createElement('div');
    var settings = {};
    return new libs_Handsontable_1.Handsontable(el, settings);
};
exports.createGrid = function (args) {
    if (args === void 0) { args = {}; }
    var table = exports.createTable();
    return _1.Grid.create(tslib_1.__assign({ ns: 'foo', table: table, totalColumns: 3, totalRows: 5 }, args));
};
describe('Grid', function () {
    describe('static', function () {
        it('isDefaultValue', function () {
            var defaults = _1.Grid.defaults();
            var test = function (kind, value, expected) {
                var res = _1.Grid.isDefaultValue({ defaults: defaults, kind: kind, value: value });
                test_1.expect(res).to.eql(expected);
            };
            test('CELL', undefined, true);
            test('CELL', { value: 0 }, false);
            test('CELL', { props: {} }, true);
            test('CELL', { props: { style: { bold: true } } }, false);
            test('COLUMN', undefined, true);
            test('COLUMN', { width: defaults.columnWidth }, true);
            test('COLUMN', { width: 456 }, false);
            test('COLUMN', { foo: true }, false);
            test('ROW', undefined, true);
            test('ROW', { height: defaults.rowHeight }, true);
            test('ROW', { height: 456 }, false);
            test('ROW', { foo: true }, false);
        });
    });
    it('constructs (initialized)', function () {
        var cells = { A1: { value: 123 } };
        var columns = { A: { props: { grid: { width: 200 } } } };
        var rows = { '10': { props: { grid: { height: 200 } } } };
        var ns = 'ns:foo';
        var grid = exports.createGrid({ totalColumns: 10, totalRows: 5, ns: ns, cells: cells, columns: columns, rows: rows });
        test_1.expect(grid.isInitialized).to.eql(true);
        test_1.expect(grid.isEditing).to.eql(false);
        test_1.expect(grid.totalColumns).to.eql(10);
        test_1.expect(grid.totalRows).to.eql(5);
        test_1.expect(grid.data.ns.id).to.eql('foo');
        test_1.expect(grid.data.cells).to.eql(cells);
        test_1.expect(grid.data.columns).to.eql(columns);
        test_1.expect(grid.data.rows).to.eql(rows);
    });
    it('constructs without table (isInitialized: false)', function () {
        var table = exports.createTable();
        var grid1 = _1.Grid.create({ ns: 'foo', totalColumns: 3, totalRows: 5 });
        test_1.expect(grid1.isInitialized).to.eql(false);
        test_1.expect(grid1.id).to.eql('');
        var grid2 = grid1.initialize({ table: table });
        test_1.expect(grid2).to.equal(grid1);
        test_1.expect(grid1.isInitialized).to.eql(true);
        test_1.expect(grid1.id.startsWith('grid/')).to.eql(true);
    });
    it('constructs with given NS identifier', function () {
        var grid1 = _1.Grid.create({ ns: 'foo' });
        var grid2 = _1.Grid.create({ ns: { id: 'foo' } });
        test_1.expect(grid1.data.ns.id).to.eql('foo');
        test_1.expect(grid2.data.ns.id).to.eql('foo');
    });
    it('dispose', function () {
        var grid = exports.createGrid();
        test_1.expect(grid.isDisposed).to.eql(false);
        var count = 0;
        grid.dispose$.subscribe(function () { return count++; });
        grid.dispose();
        grid.dispose();
        grid.dispose();
        test_1.expect(grid.isDisposed).to.eql(true);
        test_1.expect(count).to.eql(1);
    });
    describe('updateHashes', function () {
        it('force: true', function () {
            var cells = { A1: { value: 123 }, A2: { value: 456 } };
            var grid = exports.createGrid({ cells: cells, ns: 'foo' });
            test_1.expect(grid.data.cells).to.eql(cells);
            grid.updateHashes({ force: true });
            cells = grid.data.cells;
            test_1.expect(cells.A1.hash).to.eql(common_1.util.cell.value.hash.cell({ uri: 'cell:foo:A1', data: { value: 123 } }));
            test_1.expect(cells.A2.hash).to.eql(common_1.util.cell.value.hash.cell({ uri: 'cell:foo:A2', data: { value: 456 } }));
        });
        it('force: false (default)', function () {
            var cells = { A1: { value: 123, hash: 'foo' }, A2: { value: 456 } };
            var grid = exports.createGrid({ cells: cells, ns: 'foo' });
            test_1.expect(grid.data.cells).to.eql(cells);
            grid.updateHashes();
            cells = grid.data.cells;
            test_1.expect(cells.A1.hash).to.eql('foo');
            test_1.expect(cells.A2.hash).to.eql(common_1.util.cell.value.hash.cell({ uri: 'cell:foo:A2', data: { value: 456 } }));
        });
    });
    describe('keyBindings', function () {
        it('default key bindings', function () {
            var grid = exports.createGrid();
            test_1.expect(grid.keyBindings).to.eql(common_1.constants.DEFAULT.KEY_BINDINGS);
        });
        it('overrides key bindings (merged with defaults)', function () {
            var grid = exports.createGrid({ keyBindings: [{ command: 'PASTE', key: 'Shift+W' }] });
            test_1.expect(grid.keyBindings).to.not.eql(common_1.constants.DEFAULT.KEY_BINDINGS);
            var paste = grid.keyBindings.find(function (b) { return b.command === 'PASTE'; });
            test_1.expect(paste && paste.key).to.eql('Shift+W');
        });
    });
    describe('cell', function () {
        it('from row/column', function () {
            var grid = exports.createGrid();
            var cell = grid.cell({ row: 0, column: 0 });
            test_1.expect(cell.row).to.eql(0);
            test_1.expect(cell.column).to.eql(0);
            test_1.expect(cell.key).to.eql('A1');
        });
        it('from key', function () {
            var grid = exports.createGrid();
            var cell = grid.cell('B5');
            test_1.expect(cell.column).to.eql(1);
            test_1.expect(cell.row).to.eql(4);
        });
    });
    describe('changeCells', function () {
        it('changes an existing value', function () {
            var grid = exports.createGrid({ cells: { A1: { value: 123 } } });
            var res1 = grid.data.cells;
            test_1.expect(res1).to.equal(grid.data.cells);
            test_1.expect(res1).to.eql({ A1: { value: 123 } });
            grid.changeCells({ A1: { value: 456 } });
            var res2 = grid.data.cells;
            test_1.expect(res1).to.not.equal(res2);
            test_1.expect(res2.A1.value).to.eql(456);
        });
        it('adds a new value', function () {
            var grid = exports.createGrid({ cells: { A1: { value: 123 } } });
            grid.changeCells({ B1: { value: 'hello' } });
            var cells = grid.data.cells;
            test_1.expect(cells.A1.value).to.eql(123);
            test_1.expect(cells.B1.value).to.eql('hello');
        });
        it('does not store empty cell values', function () {
            var grid = exports.createGrid();
            test_1.expect(grid.data.cells).to.eql({});
            grid.changeCells({
                A1: { value: '' },
                A2: { value: undefined },
                A3: { value: undefined, props: {} },
                A4: { value: '', props: {} },
            });
            test_1.expect(grid.data.cells).to.eql({});
        });
        it('deletes empty cell values', function () {
            var grid = exports.createGrid({
                cells: {
                    A1: { value: 123 },
                    A2: { value: 456 },
                    A3: { value: 789 },
                },
            });
            test_1.expect(Object.keys(grid.data.cells)).to.eql(['A1', 'A2', 'A3']);
            grid.changeCells({
                A1: { value: '', props: {} },
                A2: { value: undefined, props: { style: { bold: true } } },
                A3: undefined,
            });
            test_1.expect(Object.keys(grid.data.cells)).to.eql(['A2']);
        });
        it('does nothing with column/row values', function () {
            var grid = exports.createGrid();
            grid.changeCells({
                A1: { value: 123 },
                '1': { height: 250 },
                A: { width: 400 },
            });
            var cells = grid.data.cells;
            test_1.expect(Object.keys(cells)).to.eql(['A1']);
            test_1.expect(cells.A1.value).to.eql(123);
        });
        it('assigns hash (to changed values)', function () {
            var grid = exports.createGrid({ ns: 'foo', cells: { A1: { value: 123 } } });
            test_1.expect(grid.data.cells).to.eql({ A1: { value: 123 } });
            grid.changeCells({ A2: { value: 'hello' } });
            var cells = grid.data.cells;
            test_1.expect(cells.A1).to.eql({ value: 123 });
            test_1.expect(cells.A2.value).to.eql('hello');
            test_1.expect(cells.A2.hash).to.eql(common_1.util.cell.value.hash.cell({ uri: 'cell:foo:A2', data: { value: 'hello' } }));
        });
        it('replaces values (init:true)', function () {
            var grid = exports.createGrid({ cells: { A1: { value: 123 } } });
            grid.changeCells({ A2: { value: 456 } }, { init: true });
            var cells = grid.data.cells;
            test_1.expect(cells.A1).to.eql(undefined);
            test_1.expect(cells.A2.value).to.eql(456);
        });
        it('deletes empty props objects', function () {
            var grid = exports.createGrid({ cells: { A1: { value: 123, props: {} } } });
            var cells = grid.data.cells;
            test_1.expect(cells.A1.props).to.eql({});
            grid.changeCells({ A1: { value: 456 } });
            cells = grid.data.cells;
            test_1.expect(cells.A1.props).to.eql(undefined);
        });
    });
    describe('selection', function () {
        var cells = {
            A1: { value: 123 },
            A2: { value: 456 },
            A3: { value: 789 },
            A5: { value: 'hello' },
        };
        it('no selection', function () {
            var grid = exports.createGrid({ cells: cells });
            var res = grid.selection;
            test_1.expect(res.cell).to.eql(undefined);
            test_1.expect(res.ranges).to.eql([]);
        });
        it('select: single cell', function () {
            var grid = exports.createGrid({ cells: cells }).select({ cell: 'A1' });
            var res = grid.selection;
            test_1.expect(res.cell).to.eql('A1');
        });
    });
});
