<!doctype html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script src="resources/table-utilities.js"></script>
<script>
function test()
{
    InspectorTest.redirectRequestAnimationFrame();

    let suite = InspectorTest.createSyncSuite("Table.RemoveRows");

    function logTable(table, rowsToRemove = []) {
        for (let rowIndex = 0; rowIndex < table.numberOfRows; ++rowIndex) {
            let type = " ";
            if (rowsToRemove.includes(rowIndex))
                type = "-";
            else if (table.selectedRows.includes(rowIndex))
                type = "*";
            InspectorTest.log(` ${type} Row ${rowIndex}`);
        }
    }

    class RemoveRowTestDelegate extends InspectorTest.TableDelegate
    {
        constructor()
        {
            super();

            this._rowIndex = NaN;
        }

        // Public

        triggerRemoveRow(table, rowIndex)
        {
            InspectorTest.assert(isNaN(this._rowIndex));

            this._rowIndex = rowIndex;

            InspectorTest.log(`Given a Table with selected rows [${table.selectedRows}], remove row ${rowIndex}.`);
            table.removeRow(rowIndex);
        }

        // Table delegate

        tableDidRemoveRows(table, rowIndexes)
        {
            super.tableDidRemoveRows(table, rowIndexes);

            InspectorTest.expectShallowEqual(rowIndexes, [this._rowIndex], `Should remove row ${this._rowIndex}.`);
            this._rowIndex = NaN;
        }

        tableSelectionDidChange(table)
        {
            if (isNaN(this._rowIndex))
                return;

            InspectorTest.log(`Selection changed to [${table.selectedRows}] before removing row ${this._rowIndex}.`);
        }
    }

    class RemoveSelectedRowsTestDelegate extends InspectorTest.TableDelegate
    {
        constructor()
        {
            super();

            this._rowIndexes = null;
        }

        // Public

        triggerRemoveSelectedRows(table)
        {
            InspectorTest.assert(!this._rowIndexes);

            this._rowIndexes = table.selectedRows;

            InspectorTest.log(`Given a Table with selected rows [${this._rowIndexes}]:`);
            logTable(table);

            table.removeSelectedRows();
        }

        // Table delegate

        tableDidRemoveRows(table, rowIndexes)
        {
            super.tableDidRemoveRows(table, rowIndexes);

            InspectorTest.expectShallowEqual(rowIndexes, this._rowIndexes, `Should remove rows [${this._rowIndexes}].`);
            this._rowIndexes = null;
        }

        tableSelectionDidChange(table)
        {
            if (!this._rowIndexes)
                return;

            InspectorTest.log(`Selection changed before removing rows:`);
            logTable(table, this._rowIndexes);
        }
    }

    const numberOfRows = 4;
    const lastRowIndex = numberOfRows - 1;

    suite.addTestCase({
        name: "Table.RemoveRow.NoneSelected",
        description: "Remove a row from a table with no selected rows.",
        test() {
            let testDelegate = new RemoveRowTestDelegate;
            let table = InspectorTest.createTableWithDelegate(testDelegate, numberOfRows);

            testDelegate.triggerRemoveRow(table, 0);

            return true;
        }
    });

    suite.addTestCase({
        name: "Table.RemoveRow.Selected",
        description: "Remove the only selected table row.",
        test() {
            let testDelegate = new RemoveRowTestDelegate;
            let table = InspectorTest.createTableWithDelegate(testDelegate, numberOfRows);

            table.selectRow(0);
            testDelegate.triggerRemoveRow(table, 0);

            return true;
        }
    });

    suite.addTestCase({
        name: "Table.RemoveRow.PrecedingSelected",
        description: "Remove a row preceding the selection, causing the selection to shift up.",
        test() {
            let testDelegate = new RemoveRowTestDelegate;
            let table = InspectorTest.createTableWithDelegate(testDelegate, numberOfRows);
            table.allowsMultipleSelection = true;

            table.selectRow(1);
            table.selectRow(3, true);
            testDelegate.triggerRemoveRow(table, 0);

            InspectorTest.expectShallowEqual(table.selectedRows, [0, 2], "Selected row indexes should be adjusted.");

            return true;
        }
    });

    function addTestCase({name, description, rowIndexes}) {
        suite.addTestCase({
            name, description,
            test() {
                let testDelegate = new RemoveSelectedRowsTestDelegate;
                let table = InspectorTest.createTableWithDelegate(testDelegate, numberOfRows);
                table.allowsMultipleSelection = true;

                for (let rowIndex of rowIndexes)
                    table.selectRow(rowIndex, true);

                testDelegate.triggerRemoveSelectedRows(table);

                return true;
            }
        });
    }

    addTestCase({
        name: "Table.RemoveSelectedRows.Single.SelectFollowing",
        description: "Remove a selected row not preceded by a selectable row.",
        rowIndexes: [0],
    });

    addTestCase({
        name: "Table.RemoveSelectedRows.Single.SelectPreceding",
        description: "Remove a selected row not followed by a selectable row.",
        rowIndexes: [lastRowIndex],
    });

    addTestCase({
        name: "Table.RemoveSelectedRows.Single.SelectPrecedingOverFollowing",
        description: "Remove a selected row between two selectable rows.",
        rowIndexes: [lastRowIndex - 1],
    });

    addTestCase({
        name: "Table.RemoveSelectedRows.Multiple.SelectFollowing",
        description: "Remove a contiguous selection not preceded by a selectable row.",
        rowIndexes: [0, 1],
    });

    addTestCase({
        name: "Table.RemoveSelectedRows.Multiple.SelectPreceding",
        description: "Remove a contiguous selection not followed by a selectable row.",
        rowIndexes: [lastRowIndex - 1, lastRowIndex],
    });

    addTestCase({
        name: "Table.RemoveSelectedRows.Multiple.SelectPrecedingOverFollowing",
        description: "Remove a contiguous selection between two selectable rows.",
        rowIndexes: [1, 2],
    });

    addTestCase({
        name: "Table.RemoveSelectedRows.Multiple.SelectPrecedingOverGap",
        description: "Remove a non-contiguous selection preceded by a selectable row.",
        rowIndexes: [1, 3],
    });

    addTestCase({
        name: "Table.RemoveSelectedRows.Multiple.SelectGapOverFollowing",
        description: "Remove a non-contiguous selection followed by a selectable row.",
        rowIndexes: [0, 2],
    });

    suite.addTestCase({
        name: "Table.RemoveRow.NotCached",
        description: "Remove a row that is not in the table cache.",
        test() {
            let testDelegate = new RemoveRowTestDelegate;
            let table = InspectorTest.createTableWithDelegate(testDelegate, 1000);

            testDelegate.triggerRemoveRow(table, 999);

            return true;
        }
    });

    suite.runTestCasesAndFinish();
}
</script>
</head>
<body onLoad="runTest()">
    <p>Tests that rows can be removed from Table, and that the selection is updated when removing selected rows.</p>
    <p>An asterix (*) indicates a selected row; a hyphen (-) indicates a removed row.</p>
</body>
</html>
