dom/flex/test/chrome/test_flex_items.html
author Daniel Holbert <dholbert@cs.stanford.edu>
Wed, 17 Oct 2018 21:42:54 +0000
changeset 500306 f6642653fb17ce9626fdc8afdba6208fcbe0e7fb
parent 500043 99c45aca2d8a868eb9e6c3c5543af78954839934
child 500473 2ce0ac92bee586c4e67a302929e1532ec8831505
permissions -rw-r--r--
Bug 1499569: Rewrite test_flex_items.html to be simpler & easier to extend. r=bradwerth Primary changes: - Rewrap some lines that are too long. - Adjust some failure-messages with s/has/should have/ etc. - Replace 'nearlyEqual' function with the standard mochitest 'isfuzzy()' API (which is like 'is()' with an extra epsilon arg) - Remove dependence on hardcoded element IDs, and simply walk over the flex container's children in order instead (still noting each child node and making sure it matches the node in the flex API). Differential Revision: https://phabricator.services.mozilla.com/D8933

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<style>
  .container {
    display: flex;
    background-color: grey;
    font: 14px sans-serif;
    width: 800px;
    height: 50px;
  }

  .base        { align-self: baseline; }
  .lastbase    { align-self: last baseline; }

  .offset      { margin-top: 10px;
                 margin-bottom: 3px; }

  .lime        { background: lime;   }
  .yellow      { background: yellow; }
  .orange      { background: orange; }
  .pink        { background: pink;   }
  .white       { background: white;  }

  .crossMinMax { min-height: 40px;
                 max-height: 120px; }

  .mainMinMax  { min-width: 120px;
                 max-width: 500px; }

  .flexGrow    { flex-grow: 1; }
</style>

<script>
"use strict";

SimpleTest.waitForExplicitFinish();

const TEXT_NODE = Node.TEXT_NODE;

function testItemMatchesExpectedValues(item, values, index) {
  if (typeof(values.node) != "undefined") {
    is(item.node, values.node, "Item index " + index + " has expected node.");
  }

  if (typeof(values.node_todo) != "undefined") {
    todo_is(item.node, values.node_todo, "Item index " + index + " has expected node.");
  }

  if (typeof(values.mainBaseSize) != "undefined") {
    is(item.mainBaseSize, values.mainBaseSize, "Item index " + index + " has expected mainBaseSize.");
  }

  if (typeof(values.mainDeltaSize) != "undefined") {
    is(item.mainDeltaSize, values.mainDeltaSize, "Item index " + index + " has expected mainDeltaSize.");
  }

  if (typeof(values.mainMinSize) != "undefined") {
    is(item.mainMinSize, values.mainMinSize, "Item index " + index + " has expected mainMinSize.");
  }

  if (typeof(values.mainMaxSize) != "undefined") {
    is(item.mainMaxSize, values.mainMaxSize, "Item index " + index + " has expected mainMaxSize.");
  } else {
    // If we didn't specify an expected mainMaxSize, then it's implied
    // that the max main-size property (max-width/max-height) is at its
    // default "none" value, which our FlexItem API represents as +infinity.
    is(item.mainMaxSize, Number.POSITIVE_INFINITY,
       "Item index " + index + " has expected (default) mainMaxSize.");
  }

  if (typeof(values.crossMinSize) != "undefined") {
    is(item.crossMinSize, values.crossMinSize, "Item index " + index + " has expected crossMinSize.");
  }

  if (typeof(values.crossMaxSize) != "undefined") {
    is(item.crossMaxSize, values.crossMaxSize, "Item index " + index + " has expected crossMaxSize.");
  } else {
    // As above for mainMaxSize, no-expected-value implies we expect +infinity.
    is(item.crossMaxSize, Number.POSITIVE_INFINITY,
       "Item index " + index + " has expected (default) crossMaxSize.");
  }
}

function runTests() {
  let container = document.getElementById("wrapper");
  let flex = container.getAsFlexContainer();
  let lines = flex.getLines();
  is(lines.length, 1, "Container should have expected number of lines.");

  let line = lines[0];
  let containerHeight = container.getBoundingClientRect().height;
  is(line.crossSize, containerHeight,
     "Line crossSize should equal the height of the container.");

  // We can't compare baselines precisely, so we'll just confirm that they
  // appear somewhere within the elements that determine them.
  // (This assumes the first rect is baseline-aligned.)
  let firstRect = container.firstElementChild.getBoundingClientRect();
  ok(line.firstBaselineOffset > firstRect.top &&
     line.firstBaselineOffset < firstRect.bottom,
     "Line firstBaselineOffset should land somewhere within the element " +
     "that determines it.");

  // For last baseline, it's measured from the bottom, so we have to compare
  // against the element bounds subtracted from the container height.
  // We use the first node which uses last-baseline ("lb") alignment to
  // provide the rect:
  let lbElem = document.querySelector(".lastbase");
  let lbElemBoundingRect = lbElem.getBoundingClientRect();
  ok(line.lastBaselineOffset > containerHeight - lbElemBoundingRect.bottom &&
     line.lastBaselineOffset < containerHeight - lbElemBoundingRect.top,
     "Line lastBaselineOffset should land somewhere within the element" +
     "that determines it.");

  let expectedValues = [
    { crossMinSize: 0 },
    { mainBaseSize: lbElemBoundingRect.width,
      mainDeltaSize: 0 },
    { crossMinSize: 40,
      crossMaxSize: 120,
      mainDeltaSize: 0 },
    { mainMinSize: 120,
      mainMaxSize: 500,
      mainDeltaSize: 0 },
    { mainDeltaSize: 0 },
    { /* final item is anonymous flex item */ },
  ];

  let items = line.getItems();
  is(items.length, expectedValues.length,
     "Line should have expected number of items.");
  is(items.length, container.children.length + 1,
     "Line should have as many items as the flex container has child elems, " +
     "plus 1 for anonymous flex item");

  for (let i = 0; i < items.length; ++i) {
    let item = items[i];
    let values = expectedValues[i];
    // set the expected node to the node we're currently iterating over,
    // except for:
    // - the display:contents element (whose item is its first child)
    // - the final item (which is an anonymous flex item around text)
    if (i < container.children.length) {
      let curElem = container.children[i];
      values.node = (curElem.style.display == "contents"
                     ? curElem.firstElementChild
                     : curElem);
    } else {
      is(container.lastChild.nodeType, TEXT_NODE,
         "container's last child should be a text node");
      values.node = container.lastChild;
    }
    testItemMatchesExpectedValues(item, values, i);
  }

  // Check that the delta size of the first item is (roughly) equal to the
  // actual size minus the base size.
  isfuzzy(items[0].mainDeltaSize, firstRect.width - items[0].mainBaseSize, 1e-4,
          "flex-grow item should have expected mainDeltaSize.");

  SimpleTest.finish();
}
</script>
</head>

<body onLoad="runTests();">
  <div id="wrapper" class="container">
    <div class="lime base flexGrow">one line (first)</div>
    <div class="yellow lastbase" style="width: 100px">one line (last)</div>
    <div class="orange offset lastbase crossMinMax">two<br/>lines and offset (last)</div>
    <div class="pink offset base mainMinMax">offset (first)</div>
    <div style="display:contents">
      <div class="white">replaced</div>
    </div>
    anonymous text node
  </div>
</body>
</html>