accessible/tests/mochitest/table.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/accessible/tests/mochitest/table.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,759 @@
     1.4 +/**
     1.5 + * This file provides set of helper functions to test nsIAccessibleTable
     1.6 + * interface.
     1.7 + *
     1.8 + * Required:
     1.9 + *   common.js
    1.10 + *   role.js
    1.11 + *   states.js
    1.12 + */
    1.13 +
    1.14 +/**
    1.15 + * Constants used to describe cells array.
    1.16 + */
    1.17 +const kDataCell = 1; // Indicates the cell is origin data cell
    1.18 +const kRowHeaderCell = 2; // Indicates the cell is row header cell
    1.19 +const kColHeaderCell = 4; // Indicated the cell is column header cell
    1.20 +const kOrigin = kDataCell | kRowHeaderCell | kColHeaderCell;
    1.21 +
    1.22 +const kRowSpanned = 8; // Indicates the cell is not origin and row spanned 
    1.23 +const kColSpanned = 16; // Indicates the cell is not origin and column spanned
    1.24 +const kSpanned = kRowSpanned | kColSpanned;
    1.25 +
    1.26 +/**
    1.27 + * Constants to define column header type.
    1.28 + */
    1.29 +const kNoColumnHeader = 0;
    1.30 +const kListboxColumnHeader = 1;
    1.31 +const kTreeColumnHeader = 2;
    1.32 +
    1.33 +/**
    1.34 + * Test table structure and related methods.
    1.35 + *
    1.36 + * @param  aIdentifier     [in] table accessible identifier
    1.37 + * @param  aCellsArray     [in] two dimensional array (row X columns) of
    1.38 + *                          cell types (see constants defined above).
    1.39 + * @param  aColHeaderType  [in] specifies wether column header cells are
    1.40 + *                          arranged into the list.
    1.41 + * @param  aCaption        [in] caption text if any
    1.42 + * @param  aSummary        [in] summary text if any
    1.43 + * @param  aIsTreeTable    [in] specifies whether given table is tree table
    1.44 + */
    1.45 +function testTableStruct(aIdentifier, aCellsArray, aColHeaderType,
    1.46 +                         aCaption, aSummary, aIsTreeTable)
    1.47 +{
    1.48 +  var tableNode = getNode(aIdentifier);
    1.49 +  var isGrid = tableNode.getAttribute("role") == "grid" ||
    1.50 +    tableNode.getAttribute("role") == "treegrid" ||
    1.51 +    tableNode.localName == "tree";
    1.52 +
    1.53 +  var rowCount = aCellsArray.length;
    1.54 +  var colsCount = aCellsArray[0] ? aCellsArray[0].length : 0;
    1.55 +
    1.56 +  // Test table accessible tree.
    1.57 +  var tableObj = {
    1.58 +    role: aIsTreeTable ? ROLE_TREE_TABLE : ROLE_TABLE,
    1.59 +    children: []
    1.60 +  };
    1.61 +
    1.62 +  // caption accessible handling
    1.63 +  if (aCaption) {
    1.64 +    var captionObj = {
    1.65 +      role: ROLE_CAPTION,
    1.66 +      children: [
    1.67 +        {
    1.68 +          role: ROLE_TEXT_LEAF,
    1.69 +          name: aCaption
    1.70 +        }
    1.71 +      ]
    1.72 +    };
    1.73 +
    1.74 +    tableObj.children.push(captionObj);
    1.75 +  }
    1.76 +
    1.77 +  // special types of column headers handling
    1.78 +  if (aColHeaderType) {
    1.79 +    var headersObj = {
    1.80 +      role: ROLE_LIST,
    1.81 +      children: []
    1.82 +    };
    1.83 +
    1.84 +    for (var idx = 0; idx < colsCount; idx++) {
    1.85 +      var headerCellObj = {
    1.86 +        role: ROLE_COLUMNHEADER
    1.87 +      };
    1.88 +      headersObj.children.push(headerCellObj);
    1.89 +    }
    1.90 +
    1.91 +    if (aColHeaderType == kTreeColumnHeader) {
    1.92 +      var columnPickerObj = {
    1.93 +        role: ROLE_PUSHBUTTON
    1.94 +      };
    1.95 +
    1.96 +      headersObj.children.push(columnPickerObj);
    1.97 +    }
    1.98 +
    1.99 +    tableObj.children.push(headersObj);
   1.100 +  }
   1.101 +
   1.102 +  // rows and cells accessibles
   1.103 +  for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
   1.104 +    var rowObj = {
   1.105 +      role: ROLE_ROW,
   1.106 +      children: []
   1.107 +    };
   1.108 +
   1.109 +    for (var colIdx = 0; colIdx < colsCount; colIdx++) {
   1.110 +      var celltype = aCellsArray[rowIdx][colIdx];
   1.111 +
   1.112 +      var role = ROLE_NOTHING;
   1.113 +      switch (celltype) {
   1.114 +        case kDataCell:
   1.115 +          role = (isGrid ? ROLE_GRID_CELL : ROLE_CELL);
   1.116 +          break;
   1.117 +        case kRowHeaderCell:
   1.118 +          role = ROLE_ROWHEADER;
   1.119 +          break;
   1.120 +        case kColHeaderCell:
   1.121 +          role = ROLE_COLUMNHEADER;
   1.122 +          break;
   1.123 +      }
   1.124 +
   1.125 +      if (role != ROLE_NOTHING) {
   1.126 +        var cellObj = {
   1.127 +          role: role
   1.128 +        };
   1.129 +        rowObj.children.push(cellObj);
   1.130 +      }
   1.131 +    }
   1.132 +
   1.133 +    tableObj.children.push(rowObj);
   1.134 +  }
   1.135 +
   1.136 +  testAccessibleTree(aIdentifier, tableObj);
   1.137 +
   1.138 +  // Test table table interface.
   1.139 +  var table = getAccessible(aIdentifier, [nsIAccessibleTable]);
   1.140 +
   1.141 +  // summary
   1.142 +  if (aSummary)
   1.143 +    is(table.summary, aSummary,
   1.144 +       "Wrong summary of the table " + prettyName(aIdentifier));
   1.145 +
   1.146 +  // rowCount and columnCount
   1.147 +  is(table.rowCount, rowCount,
   1.148 +     "Wrong rows count of " + prettyName(aIdentifier));
   1.149 +  is(table.columnCount, colsCount,
   1.150 +     "Wrong columns count of " + prettyName(aIdentifier));
   1.151 +
   1.152 +  // rows and columns extents
   1.153 +  for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
   1.154 +    for (var colIdx = 0; colIdx < colsCount; colIdx++) {
   1.155 +      var celltype = aCellsArray[rowIdx][colIdx];
   1.156 +      if (celltype & kOrigin) {
   1.157 +
   1.158 +        // table getRowExtentAt
   1.159 +        var rowExtent = table.getRowExtentAt(rowIdx, colIdx);
   1.160 +        for (var idx = rowIdx + 1;
   1.161 +             idx < rowCount && (aCellsArray[idx][colIdx] & kRowSpanned);
   1.162 +             idx++);
   1.163 +
   1.164 +        var expectedRowExtent = idx - rowIdx;
   1.165 +        is(rowExtent, expectedRowExtent,
   1.166 +           "getRowExtentAt: Wrong number of spanned rows at (" + rowIdx + ", " +
   1.167 +           colIdx + ") for " + prettyName(aIdentifier));
   1.168 +
   1.169 +        // table getColumnExtentAt
   1.170 +        var colExtent = table.getColumnExtentAt(rowIdx, colIdx);
   1.171 +        for (var idx = colIdx + 1;
   1.172 +             idx < colsCount && (aCellsArray[rowIdx][idx] & kColSpanned);
   1.173 +             idx++);
   1.174 +
   1.175 +        var expectedColExtent = idx - colIdx;
   1.176 +        is(colExtent, expectedColExtent,
   1.177 +           "getColumnExtentAt: Wrong number of spanned columns at (" + rowIdx +
   1.178 +           ", " + colIdx + ") for " + prettyName(aIdentifier));
   1.179 +
   1.180 +        // cell rowExtent and columnExtent
   1.181 +        var cell = getAccessible(table.getCellAt(rowIdx, colIdx),
   1.182 +                                 [nsIAccessibleTableCell]);
   1.183 +
   1.184 +        is(cell.rowExtent, expectedRowExtent,
   1.185 +           "rowExtent: Wrong number of spanned rows at (" + rowIdx + ", " +
   1.186 +           colIdx + ") for " + prettyName(aIdentifier));
   1.187 +
   1.188 +        is(cell.columnExtent, expectedColExtent,
   1.189 +           "columnExtent: Wrong number of spanned column at (" + rowIdx + ", " +
   1.190 +           colIdx + ") for " + prettyName(aIdentifier));
   1.191 +      }
   1.192 +    }
   1.193 +  }
   1.194 +}
   1.195 +
   1.196 +/**
   1.197 + * Test table indexes.
   1.198 + *
   1.199 + * @param  aIdentifier  [in] table accessible identifier
   1.200 + * @param  aIdxes       [in] two dimensional array of cell indexes
   1.201 + */
   1.202 +function testTableIndexes(aIdentifier, aIdxes)
   1.203 +{
   1.204 +  var tableAcc = getAccessible(aIdentifier, [nsIAccessibleTable]);
   1.205 +  if (!tableAcc)
   1.206 +    return;
   1.207 +
   1.208 +  var obtainedRowIdx, obtainedColIdx, obtainedIdx;
   1.209 +  var cellAcc;
   1.210 +
   1.211 +  var id = prettyName(aIdentifier);
   1.212 +
   1.213 +  var rowCount = aIdxes.length;
   1.214 +  for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
   1.215 +    var colCount = aIdxes[rowIdx].length;
   1.216 +    for (var colIdx = 0; colIdx < colCount; colIdx++) {
   1.217 +      var idx = aIdxes[rowIdx][colIdx];
   1.218 +
   1.219 +      // getCellAt
   1.220 +      try {
   1.221 +        cellAcc = null;
   1.222 +        cellAcc = tableAcc.getCellAt(rowIdx, colIdx);
   1.223 +      } catch (e) { }
   1.224 +
   1.225 +      ok(idx != -1 && cellAcc || idx == -1 && !cellAcc,
   1.226 +         id + ": Can't get cell accessible at row = " + rowIdx + ", column = " + colIdx);
   1.227 +
   1.228 +      if (idx != - 1) {
   1.229 +
   1.230 +        // getRowIndexAt
   1.231 +        var origRowIdx = rowIdx;
   1.232 +        while (origRowIdx > 0 &&
   1.233 +               aIdxes[rowIdx][colIdx] == aIdxes[origRowIdx - 1][colIdx])
   1.234 +          origRowIdx--;
   1.235 +
   1.236 +        try {
   1.237 +          obtainedRowIdx = tableAcc.getRowIndexAt(idx);
   1.238 +        } catch (e) {
   1.239 +          ok(false, id + ": can't get row index for cell index " + idx + "," + e);
   1.240 +        }
   1.241 +
   1.242 +        is(obtainedRowIdx, origRowIdx,
   1.243 +           id + ": row for index " + idx + " is not correct (getRowIndexAt)");
   1.244 +
   1.245 +        // getColumnIndexAt
   1.246 +        var origColIdx = colIdx;
   1.247 +        while (origColIdx > 0 &&
   1.248 +               aIdxes[rowIdx][colIdx] == aIdxes[rowIdx][origColIdx - 1])
   1.249 +          origColIdx--;
   1.250 +
   1.251 +        try {
   1.252 +          obtainedColIdx = tableAcc.getColumnIndexAt(idx);
   1.253 +        } catch (e) {
   1.254 +          ok(false, id + ": can't get column index for cell index " + idx + "," + e);
   1.255 +        }
   1.256 +
   1.257 +        is(obtainedColIdx, origColIdx,
   1.258 +           id + ": column  for index " + idx + " is not correct (getColumnIndexAt)");
   1.259 +
   1.260 +        // getRowAndColumnIndicesAt
   1.261 +        var obtainedRowIdxObj = { }, obtainedColIdxObj = { };
   1.262 +        try {
   1.263 +          tableAcc.getRowAndColumnIndicesAt(idx, obtainedRowIdxObj,
   1.264 +                                            obtainedColIdxObj);
   1.265 +        } catch (e) {
   1.266 +          ok(false, id + ": can't get row and column indices for cell index " + idx + "," + e);
   1.267 +        }
   1.268 +
   1.269 +        is(obtainedRowIdxObj.value, origRowIdx,
   1.270 +           id + ": row for index " + idx + " is not correct (getRowAndColumnIndicesAt)");
   1.271 +        is(obtainedColIdxObj.value, origColIdx,
   1.272 +           id + ": column  for index " + idx + " is not correct (getRowAndColumnIndicesAt)");
   1.273 +
   1.274 +        if (cellAcc) {
   1.275 +
   1.276 +          var cellId = prettyName(cellAcc);
   1.277 +          cellAcc = getAccessible(cellAcc, [nsIAccessibleTableCell]);
   1.278 +
   1.279 +          // cell: 'table-cell-index' attribute
   1.280 +          var attrs = cellAcc.attributes;
   1.281 +          var strIdx = "";
   1.282 +          try {
   1.283 +            strIdx = attrs.getStringProperty("table-cell-index");
   1.284 +          } catch (e) {
   1.285 +            ok(false,
   1.286 +               cellId + ": no cell index from object attributes on the cell accessible at index " + idx + ".");
   1.287 +          }
   1.288 +
   1.289 +          if (strIdx) {
   1.290 +            is (parseInt(strIdx), idx,
   1.291 +                cellId + ": cell index from object attributes of cell accessible isn't corrent.");
   1.292 +          }
   1.293 +
   1.294 +          // cell: table
   1.295 +          try {
   1.296 +            is(cellAcc.table, tableAcc,
   1.297 +               cellId + ": wrong table accessible for the cell.");
   1.298 +
   1.299 +          } catch (e) {
   1.300 +            ok(false,
   1.301 +               cellId + ": can't get table accessible from the cell.");
   1.302 +          }
   1.303 +
   1.304 +          // cell: getRowIndex
   1.305 +          try {
   1.306 +            obtainedRowIdx = cellAcc.rowIndex;
   1.307 +          } catch (e) {
   1.308 +            ok(false,
   1.309 +               cellId + ": can't get row index of the cell at index " + idx + "," + e);
   1.310 +          }
   1.311 +
   1.312 +          is(obtainedRowIdx, origRowIdx,
   1.313 +             cellId + ": row for the cell at index " + idx +" is not correct");
   1.314 +
   1.315 +          // cell: getColumnIndex
   1.316 +          try {
   1.317 +            obtainedColIdx = cellAcc.columnIndex;
   1.318 +          } catch (e) {
   1.319 +            ok(false,
   1.320 +               cellId + ": can't get column index of the cell at index " + idx + "," + e);
   1.321 +          }
   1.322 +
   1.323 +          is(obtainedColIdx, origColIdx,
   1.324 +             id + ": column for the cell at index " + idx +" is not correct");
   1.325 +        }
   1.326 +      }
   1.327 +
   1.328 +      // getCellIndexAt
   1.329 +      try {
   1.330 +        obtainedIdx = tableAcc.getCellIndexAt(rowIdx, colIdx);
   1.331 +      } catch (e) {
   1.332 +        obtainedIdx = -1;
   1.333 +      }
   1.334 +
   1.335 +      is(obtainedIdx, idx,
   1.336 +         id + ": row " + rowIdx + " /column " + colIdx + " and index " + obtainedIdx + " aren't inconsistent.");
   1.337 +    }
   1.338 +  }
   1.339 +}
   1.340 +
   1.341 +/**
   1.342 + * Test table getters selection methods.
   1.343 + *
   1.344 + * @param  aIdentifier  [in] table accessible identifier
   1.345 + * @param  aCellsArray  [in] two dimensional array (row X columns) of cells
   1.346 + *                       states (either boolean (selected/unselected) if cell is
   1.347 + *                       origin, otherwise kRowSpanned or kColSpanned constant).
   1.348 + * @param  aMsg         [in] text appended before every message
   1.349 + */
   1.350 +function testTableSelection(aIdentifier, aCellsArray, aMsg)
   1.351 +{
   1.352 +  var msg = aMsg ? aMsg : "";
   1.353 +  var acc = getAccessible(aIdentifier, [nsIAccessibleTable]);
   1.354 +  if (!acc)
   1.355 +    return;
   1.356 +
   1.357 +  var rowCount = aCellsArray.length;
   1.358 +  var colsCount = aCellsArray[0].length;
   1.359 +
   1.360 +  // Columns selection tests.
   1.361 +  var selCols = new Array();
   1.362 +
   1.363 +  // isColumnSelected test
   1.364 +  for (var colIdx = 0; colIdx < colsCount; colIdx++) {
   1.365 +    var isColSelected = true;
   1.366 +    for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
   1.367 +      if (aCellsArray[rowIdx][colIdx] == false ||
   1.368 +          aCellsArray[rowIdx][colIdx] == undefined) {
   1.369 +        isColSelected = false;
   1.370 +        break;
   1.371 +      }
   1.372 +    }
   1.373 +
   1.374 +    is(acc.isColumnSelected(colIdx), isColSelected,
   1.375 +       msg + "Wrong selection state of " + colIdx + " column for " +
   1.376 +       prettyName(aIdentifier));
   1.377 +
   1.378 +    if (isColSelected)
   1.379 +      selCols.push(colIdx);
   1.380 +  }
   1.381 +
   1.382 +  // selectedColsCount test
   1.383 +  is(acc.selectedColumnCount, selCols.length,
   1.384 +     msg + "Wrong count of selected columns for " + prettyName(aIdentifier));
   1.385 +
   1.386 +  // getSelectedColumns test
   1.387 +  var actualSelColsCountObj = { value: null };
   1.388 +  var actualSelCols = acc.getSelectedColumnIndices(actualSelColsCountObj);
   1.389 +
   1.390 +  var actualSelColsCount = actualSelColsCountObj.value;
   1.391 +  is (actualSelColsCount, selCols.length,
   1.392 +      msg + "Wrong count of selected columns for " + prettyName(aIdentifier) +
   1.393 +      "from getSelectedColumns.");
   1.394 +
   1.395 +  for (var i = 0; i < actualSelColsCount; i++) {
   1.396 +    is (actualSelCols[i], selCols[i],
   1.397 +        msg + "Column at index " + selCols[i] + " should be selected.");
   1.398 +  }
   1.399 +
   1.400 +  // Rows selection tests.
   1.401 +  var selRows = new Array();
   1.402 +
   1.403 +  // isRowSelected test
   1.404 +  var selrowCount = 0;
   1.405 +  for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
   1.406 +    var isRowSelected = true;
   1.407 +    for (var colIdx = 0; colIdx < colsCount; colIdx++) {
   1.408 +      if (aCellsArray[rowIdx][colIdx] == false ||
   1.409 +          aCellsArray[rowIdx][colIdx] == undefined) {
   1.410 +        isRowSelected = false;
   1.411 +        break;
   1.412 +      }
   1.413 +    }
   1.414 +
   1.415 +    is(acc.isRowSelected(rowIdx), isRowSelected,
   1.416 +       msg + "Wrong selection state of " + rowIdx + " row for " +
   1.417 +       prettyName(aIdentifier));
   1.418 +
   1.419 +    if (isRowSelected)
   1.420 +      selRows.push(rowIdx);
   1.421 +  }
   1.422 +
   1.423 +  // selectedRowCount test
   1.424 +  is(acc.selectedRowCount, selRows.length,
   1.425 +     msg + "Wrong count of selected rows for " + prettyName(aIdentifier));
   1.426 +
   1.427 +  // getSelectedRows test
   1.428 +  var actualSelrowCountObj = { value: null };
   1.429 +  var actualSelRows = acc.getSelectedRowIndices(actualSelrowCountObj);
   1.430 +
   1.431 +  var actualSelrowCount = actualSelrowCountObj.value;
   1.432 +  is (actualSelrowCount, selRows.length,
   1.433 +      msg + "Wrong count of selected rows for " + prettyName(aIdentifier) +
   1.434 +      "from getSelectedRows.");
   1.435 +
   1.436 +  for (var i = 0; i < actualSelrowCount; i++) {
   1.437 +    is (actualSelRows[i], selRows[i],
   1.438 +        msg + "Row at index " + selRows[i] + " should be selected.");
   1.439 +  }
   1.440 +
   1.441 +  // Cells selection tests.
   1.442 +  var selCells = new Array();
   1.443 +
   1.444 +  // isCellSelected test
   1.445 +  for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
   1.446 +    for (var colIdx = 0; colIdx < colsCount; colIdx++) {
   1.447 +      if (aCellsArray[rowIdx][colIdx] & kSpanned)
   1.448 +        continue;
   1.449 +
   1.450 +      var isSelected = aCellsArray[rowIdx][colIdx] == true;
   1.451 +      is(acc.isCellSelected(rowIdx, colIdx), isSelected,
   1.452 +         msg + "Wrong selection state of cell at " + rowIdx + " row and " +
   1.453 +         colIdx + " column for " + prettyName(aIdentifier));
   1.454 +
   1.455 +      if (aCellsArray[rowIdx][colIdx])
   1.456 +        selCells.push(acc.getCellIndexAt(rowIdx, colIdx));
   1.457 +    }
   1.458 +  }
   1.459 +
   1.460 +  // selectedCellCount tests
   1.461 +  is(acc.selectedCellCount, selCells.length,
   1.462 +     msg + "Wrong count of selected cells for " + prettyName(aIdentifier));
   1.463 +
   1.464 +  // getSelectedCellIndices test
   1.465 +  var actualSelCellsCountObj = { value: null };
   1.466 +  var actualSelCells = acc.getSelectedCellIndices(actualSelCellsCountObj);
   1.467 +
   1.468 +  var actualSelCellsCount = actualSelCellsCountObj.value;
   1.469 +  is(actualSelCellsCount, selCells.length,
   1.470 +     msg + "Wrong count of selected cells for " + prettyName(aIdentifier) +
   1.471 +     "from getSelectedCells.");
   1.472 +
   1.473 +  for (var i = 0; i < actualSelCellsCount; i++) {
   1.474 +    is(actualSelCells[i], selCells[i],
   1.475 +       msg + "getSelectedCellIndices: Cell at index " + selCells[i] +
   1.476 +       " should be selected.");
   1.477 +  }
   1.478 +
   1.479 +  // selectedCells and isSelected tests
   1.480 +  var actualSelCellsArray = acc.selectedCells;
   1.481 +  for (var i = 0; i < actualSelCellsCount; i++) {
   1.482 +    var actualSelCellAccessible =
   1.483 +      actualSelCellsArray.queryElementAt(i, nsIAccessibleTableCell);
   1.484 +
   1.485 +    var colIdx = acc.getColumnIndexAt(selCells[i]);
   1.486 +    var rowIdx = acc.getRowIndexAt(selCells[i]);
   1.487 +    var expectedSelCellAccessible = acc.getCellAt(rowIdx, colIdx);
   1.488 +
   1.489 +    ok(actualSelCellAccessible, expectedSelCellAccessible,
   1.490 +       msg + "getSelectedCells: Cell at index " + selCells[i] +
   1.491 +       " should be selected.");
   1.492 +
   1.493 +    ok(actualSelCellAccessible.isSelected(),
   1.494 +       "isSelected: Cell at index " + selCells[i] + " should be selected.");
   1.495 +  }
   1.496 +
   1.497 +  // selected states tests
   1.498 +  for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
   1.499 +    for (var colIdx = 0; colIdx < colsCount; colIdx++) {
   1.500 +      if (aCellsArray[rowIdx][colIdx] & kSpanned)
   1.501 +        continue;
   1.502 +
   1.503 +      var cell = acc.getCellAt(rowIdx, colIdx);
   1.504 +      var isSel = aCellsArray[rowIdx][colIdx];
   1.505 +      if (isSel == undefined)
   1.506 +        testStates(cell, 0, 0, STATE_SELECTABLE | STATE_SELECTED);
   1.507 +      else if (isSel == true)
   1.508 +        testStates(cell, STATE_SELECTED);
   1.509 +      else
   1.510 +        testStates(cell, STATE_SELECTABLE, 0, STATE_SELECTED);
   1.511 +    }
   1.512 +  }
   1.513 +}
   1.514 +
   1.515 +/**
   1.516 + * Test unselectColumn method of accessible table.
   1.517 + */
   1.518 +function testUnselectTableColumn(aIdentifier, aColIdx, aCellsArray)
   1.519 +{
   1.520 +  var acc = getAccessible(aIdentifier, [nsIAccessibleTable]);
   1.521 +  if (!acc)
   1.522 +    return;
   1.523 +
   1.524 +  var rowCount = aCellsArray.length;
   1.525 +  for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
   1.526 +    var cellState = aCellsArray[rowIdx][aColIdx];
   1.527 +    // Unselect origin cell.
   1.528 +    var [origRowIdx, origColIdx] =
   1.529 +      getOrigRowAndColumn(aCellsArray, rowIdx, aColIdx);
   1.530 +    aCellsArray[origRowIdx][origColIdx] = false;
   1.531 +  }
   1.532 +
   1.533 +  acc.unselectColumn(aColIdx);
   1.534 +  testTableSelection(aIdentifier, aCellsArray,
   1.535 +                     "Unselect " + aColIdx + " column: ");
   1.536 +}
   1.537 +
   1.538 +/**
   1.539 + * Test selectColumn method of accessible table.
   1.540 + */
   1.541 +function testSelectTableColumn(aIdentifier, aColIdx, aCellsArray)
   1.542 +{
   1.543 +  var acc = getAccessible(aIdentifier, [nsIAccessibleTable]);
   1.544 +  if (!acc)
   1.545 +    return;
   1.546 +
   1.547 +  var rowCount = aCellsArray.length;
   1.548 +  var colsCount = aCellsArray[0].length;
   1.549 +
   1.550 +  for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
   1.551 +    for (var colIdx = 0; colIdx < colsCount; colIdx++) {
   1.552 +      var cellState = aCellsArray[rowIdx][colIdx];
   1.553 +
   1.554 +      if (colIdx == aColIdx) { // select target column
   1.555 +        if (!(cellState & kSpanned)) {
   1.556 +          // Select the cell if it is origin.
   1.557 +          aCellsArray[rowIdx][colIdx] = true;
   1.558 +
   1.559 +        } else {
   1.560 +          // If the cell is spanned then search origin cell and select it.
   1.561 +          var [origRowIdx, origColIdx] = getOrigRowAndColumn(aCellsArray,
   1.562 +                                                             rowIdx, colIdx);
   1.563 +          aCellsArray[origRowIdx][origColIdx] = true;
   1.564 +        }
   1.565 +
   1.566 +      } else if (!(cellState & kSpanned)) { // unselect other columns
   1.567 +        if (colIdx > aColIdx) {
   1.568 +          // Unselect the cell if traversed column index is greater than column
   1.569 +          // index of target cell.
   1.570 +          aCellsArray[rowIdx][colIdx] = false;
   1.571 +
   1.572 +        } else if (!(aCellsArray[rowIdx][aColIdx] & kColSpanned)) {
   1.573 +          // Unselect the cell if the target cell is not row spanned.
   1.574 +          aCellsArray[rowIdx][colIdx] = false;
   1.575 +
   1.576 +        } else {
   1.577 +          // Unselect the cell if it is not spanned to the target cell.
   1.578 +          for (var spannedColIdx = colIdx + 1; spannedColIdx < aColIdx;
   1.579 +               spannedColIdx++) {
   1.580 +            var spannedCellState = aCellsArray[rowIdx][spannedColIdx];
   1.581 +            if (!(spannedCellState & kRowSpanned)) {
   1.582 +              aCellsArray[rowIdx][colIdx] = false;
   1.583 +              break;
   1.584 +            }
   1.585 +          }
   1.586 +        }
   1.587 +      }
   1.588 +    }
   1.589 +  }
   1.590 +
   1.591 +  acc.selectColumn(aColIdx);
   1.592 +  testTableSelection(aIdentifier, aCellsArray,
   1.593 +                     "Select " + aColIdx + " column: ");
   1.594 +}
   1.595 +
   1.596 +/**
   1.597 + * Test unselectRow method of accessible table.
   1.598 + */
   1.599 +function testUnselectTableRow(aIdentifier, aRowIdx, aCellsArray)
   1.600 +{
   1.601 +  var acc = getAccessible(aIdentifier, [nsIAccessibleTable]);
   1.602 +  if (!acc)
   1.603 +    return;
   1.604 +
   1.605 +  var colsCount = aCellsArray[0].length;
   1.606 +  for (var colIdx = 0; colIdx < colsCount; colIdx++) {
   1.607 +    // Unselect origin cell.
   1.608 +    var [origRowIdx, origColIdx] = getOrigRowAndColumn(aCellsArray,
   1.609 +                                                       aRowIdx, colIdx);
   1.610 +    aCellsArray[origRowIdx][origColIdx] = false;
   1.611 +  }
   1.612 +
   1.613 +  acc.unselectRow(aRowIdx);
   1.614 +  testTableSelection(aIdentifier, aCellsArray,
   1.615 +                     "Unselect " + aRowIdx + " row: ");
   1.616 +}
   1.617 +
   1.618 +/**
   1.619 + * Test selectRow method of accessible table.
   1.620 + */
   1.621 +function testSelectTableRow(aIdentifier, aRowIdx, aCellsArray)
   1.622 +{
   1.623 +  var acc = getAccessible(aIdentifier, [nsIAccessibleTable]);
   1.624 +  if (!acc)
   1.625 +    return;
   1.626 +
   1.627 +  var rowCount = aCellsArray.length;
   1.628 +  var colsCount = aCellsArray[0].length;
   1.629 +
   1.630 +  for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
   1.631 +    for (var colIdx = 0; colIdx < colsCount; colIdx++) {
   1.632 +      var cellState = aCellsArray[rowIdx][colIdx];
   1.633 +
   1.634 +      if (rowIdx == aRowIdx) { // select the given row
   1.635 +        if (!(cellState & kSpanned)) {
   1.636 +          // Select the cell if it is origin.
   1.637 +          aCellsArray[rowIdx][colIdx] = true;
   1.638 +
   1.639 +        } else {
   1.640 +          // If the cell is spanned then search origin cell and select it.
   1.641 +          var [origRowIdx, origColIdx] = getOrigRowAndColumn(aCellsArray,
   1.642 +                                                             rowIdx, colIdx);
   1.643 +
   1.644 +          aCellsArray[origRowIdx][origColIdx] = true;
   1.645 +        }
   1.646 +
   1.647 +      } else if (!(cellState & kSpanned)) { // unselect other rows
   1.648 +        if (rowIdx > aRowIdx) {
   1.649 +          // Unselect the cell if traversed row index is greater than row
   1.650 +          // index of target cell.
   1.651 +          aCellsArray[rowIdx][colIdx] = false;
   1.652 +
   1.653 +        } else if (!(aCellsArray[aRowIdx][colIdx] & kRowSpanned)) {
   1.654 +          // Unselect the cell if the target cell is not row spanned.
   1.655 +          aCellsArray[rowIdx][colIdx] = false;
   1.656 +
   1.657 +        } else {
   1.658 +          // Unselect the cell if it is not spanned to the target cell.
   1.659 +          for (var spannedRowIdx = rowIdx + 1; spannedRowIdx < aRowIdx;
   1.660 +               spannedRowIdx++) {
   1.661 +            var spannedCellState = aCellsArray[spannedRowIdx][colIdx];
   1.662 +            if (!(spannedCellState & kRowSpanned)) {
   1.663 +              aCellsArray[rowIdx][colIdx] = false;
   1.664 +              break;
   1.665 +            }
   1.666 +          }
   1.667 +        }
   1.668 +      }
   1.669 +    }
   1.670 +  }
   1.671 +
   1.672 +  acc.selectRow(aRowIdx);
   1.673 +  testTableSelection(aIdentifier, aCellsArray,
   1.674 +                     "Select " + aRowIdx + " row: ");
   1.675 +}
   1.676 +
   1.677 +/**
   1.678 + * Test columnHeaderCells and rowHeaderCells of accessible table.
   1.679 + */
   1.680 +function testHeaderCells(aHeaderInfoMap)
   1.681 +{
   1.682 +  for (var testIdx = 0; testIdx < aHeaderInfoMap.length; testIdx++) {
   1.683 +    var dataCellIdentifier = aHeaderInfoMap[testIdx].cell;
   1.684 +    var dataCell = getAccessible(dataCellIdentifier, [nsIAccessibleTableCell]);
   1.685 +
   1.686 +    // row header cells
   1.687 +    var rowHeaderCells = aHeaderInfoMap[testIdx].rowHeaderCells;
   1.688 +    var rowHeaderCellsCount = rowHeaderCells.length;
   1.689 +    var actualRowHeaderCells = dataCell.rowHeaderCells;
   1.690 +    var actualRowHeaderCellsCount = actualRowHeaderCells.length;
   1.691 +
   1.692 +    is(actualRowHeaderCellsCount, rowHeaderCellsCount,
   1.693 +       "Wrong number of row header cells for the cell " +
   1.694 +       prettyName(dataCellIdentifier));
   1.695 +
   1.696 +    if (actualRowHeaderCellsCount == rowHeaderCellsCount) {
   1.697 +      for (var idx = 0; idx < rowHeaderCellsCount; idx++) {
   1.698 +        var rowHeaderCell = getAccessible(rowHeaderCells[idx]);
   1.699 +        var actualRowHeaderCell =
   1.700 +          actualRowHeaderCells.queryElementAt(idx, nsIAccessible);
   1.701 +        ok(actualRowHeaderCell, rowHeaderCell,
   1.702 +           "Wrong row header cell at index " + idx + " for the cell " +
   1.703 +           prettyName(rowHeaderCells[idx]));
   1.704 +      }
   1.705 +    }
   1.706 +
   1.707 +    // column header cells
   1.708 +    var colHeaderCells = aHeaderInfoMap[testIdx].columnHeaderCells;
   1.709 +    var colHeaderCellsCount = colHeaderCells.length;
   1.710 +    var actualColHeaderCells = dataCell.columnHeaderCells;
   1.711 +    var actualColHeaderCellsCount = actualColHeaderCells.length;
   1.712 +
   1.713 +    is(actualColHeaderCellsCount, colHeaderCellsCount,
   1.714 +       "Wrong number of column header cells for the cell " +
   1.715 +       prettyName(dataCellIdentifier));
   1.716 +
   1.717 +    if (actualColHeaderCellsCount == colHeaderCellsCount) {
   1.718 +      for (var idx = 0; idx < colHeaderCellsCount; idx++) {
   1.719 +        var colHeaderCell = getAccessible(colHeaderCells[idx]);
   1.720 +        var actualColHeaderCell =
   1.721 +          actualColHeaderCells.queryElementAt(idx, nsIAccessible);
   1.722 +        ok(actualColHeaderCell, colHeaderCell,
   1.723 +           "Wrong column header cell at index " + idx + " for the cell " +
   1.724 +           prettyName(colHeaderCells[idx]));
   1.725 +      }
   1.726 +    }
   1.727 +  }
   1.728 +}
   1.729 +
   1.730 +////////////////////////////////////////////////////////////////////////////////
   1.731 +// private implementation
   1.732 +
   1.733 +/**
   1.734 + * Return row and column of orig cell for the given spanned cell.
   1.735 + */
   1.736 +function getOrigRowAndColumn(aCellsArray, aRowIdx, aColIdx)
   1.737 +{
   1.738 +  var cellState = aCellsArray[aRowIdx][aColIdx];
   1.739 +
   1.740 +  var origRowIdx = aRowIdx, origColIdx = aColIdx;
   1.741 +  if (cellState & kRowSpanned) {
   1.742 +    for (var prevRowIdx = aRowIdx - 1; prevRowIdx >= 0; prevRowIdx--) {
   1.743 +      var prevCellState = aCellsArray[prevRowIdx][aColIdx];
   1.744 +      if (!(prevCellState & kRowSpanned)) {
   1.745 +        origRowIdx = prevRowIdx;
   1.746 +        break;
   1.747 +      }
   1.748 +    }
   1.749 +  }
   1.750 +
   1.751 +  if (cellState & kColSpanned) {
   1.752 +    for (var prevColIdx = aColIdx - 1; prevColIdx >= 0; prevColIdx--) {
   1.753 +      var prevCellState = aCellsArray[aRowIdx][prevColIdx];
   1.754 +      if (!(prevCellState & kColSpanned)) {
   1.755 +        origColIdx = prevColIdx;
   1.756 +        break;
   1.757 +      }
   1.758 +    }
   1.759 +  }
   1.760 +
   1.761 +  return [origRowIdx, origColIdx];
   1.762 +}

mercurial