<!doctype html>
<title>Range setting tests</title>
<link rel="author" title="Aryeh Gregor" href=ayg@aryeh.name>
<meta name=timeout content=long>

<div id=log></div>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=../common.js></script>
<script>
"use strict";

function testSetStart(range, node, offset) {
  if (node.nodeType == Node.DOCUMENT_TYPE_NODE) {
    assert_throws("INVALID_NODE_TYPE_ERR", function() {
      range.setStart(node, offset);
    }, "setStart() to a doctype must throw INVALID_NODE_TYPE_ERR");
    return;
  }

  if (offset < 0 || offset > nodeLength(node)) {
    assert_throws("INDEX_SIZE_ERR", function() {
      range.setStart(node, offset);
    }, "setStart() to a too-large offset must throw INDEX_SIZE_ERR");
    return;
  }

  var newRange = range.cloneRange();
  newRange.setStart(node, offset);

  assert_equals(newRange.startContainer, node,
    "setStart() must change startContainer to the new node");
  assert_equals(newRange.startOffset, offset,
    "setStart() must change startOffset to the new offset");

  // FIXME: I'm assuming comparePoint() is correct, but the tests for that
  // will depend on setStart()/setEnd().
  if (furthestAncestor(node) != furthestAncestor(range.startContainer)
  || range.comparePoint(node, offset) > 0) {
    assert_equals(newRange.endContainer, node,
      "setStart(node, offset) where node is after current end or in different document must set the end node to node too");
    assert_equals(newRange.endOffset, offset,
      "setStart(node, offset) where node is after current end or in different document must set the end offset to offset too");
  } else {
    assert_equals(newRange.endContainer, range.endContainer,
      "setStart() must not change the end node if the new start is before the old end");
    assert_equals(newRange.endOffset, range.endOffset,
      "setStart() must not change the end offset if the new start is before the old end");
  }
}

function testSetEnd(range, node, offset) {
  if (node.nodeType == Node.DOCUMENT_TYPE_NODE) {
    assert_throws("INVALID_NODE_TYPE_ERR", function() {
      range.setEnd(node, offset);
    }, "setEnd() to a doctype must throw INVALID_NODE_TYPE_ERR");
    return;
  }

  if (offset < 0 || offset > nodeLength(node)) {
    assert_throws("INDEX_SIZE_ERR", function() {
      range.setEnd(node, offset);
    }, "setEnd() to a too-large offset must throw INDEX_SIZE_ERR");
    return;
  }

  var newRange = range.cloneRange();
  newRange.setEnd(node, offset);

  // FIXME: I'm assuming comparePoint() is correct, but the tests for that
  // will depend on setStart()/setEnd().
  if (furthestAncestor(node) != furthestAncestor(range.startContainer)
  || range.comparePoint(node, offset) < 0) {
    assert_equals(newRange.startContainer, node,
      "setEnd(node, offset) where node is before current start or in different document must set the end node to node too");
    assert_equals(newRange.startOffset, offset,
      "setEnd(node, offset) where node is before current start or in different document must set the end offset to offset too");
  } else {
    assert_equals(newRange.startContainer, range.startContainer,
      "setEnd() must not change the start node if the new end is after the old start");
    assert_equals(newRange.startOffset, range.startOffset,
      "setEnd() must not change the start offset if the new end is after the old start");
  }

  assert_equals(newRange.endContainer, node,
    "setEnd() must change endContainer to the new node");
  assert_equals(newRange.endOffset, offset,
    "setEnd() must change endOffset to the new offset");
}

function testSetStartBefore(range, node) {
  var parent = node.parentNode;
  if (parent === null) {
    assert_throws("INVALID_NODE_TYPE_ERR", function () {
      range.setStartBefore(node);
    }, "setStartBefore() to a node with null parent must throw INVALID_NODE_TYPE_ERR");
    return;
  }

  var idx = 0;
  while (node.parentNode.childNodes[idx] != node) {
    idx++;
  }

  testSetStart(range, node.parentNode, idx);
}

function testSetStartAfter(range, node) {
  var parent = node.parentNode;
  if (parent === null) {
    assert_throws("INVALID_NODE_TYPE_ERR", function () {
      range.setStartAfter(node);
    }, "setStartAfter() to a node with null parent must throw INVALID_NODE_TYPE_ERR");
    return;
  }

  var idx = 0;
  while (node.parentNode.childNodes[idx] != node) {
    idx++;
  }

  testSetStart(range, node.parentNode, idx + 1);
}

function testSetEndBefore(range, node) {
  var parent = node.parentNode;
  if (parent === null) {
    assert_throws("INVALID_NODE_TYPE_ERR", function () {
      range.setEndBefore(node);
    }, "setEndBefore() to a node with null parent must throw INVALID_NODE_TYPE_ERR");
    return;
  }

  var idx = 0;
  while (node.parentNode.childNodes[idx] != node) {
    idx++;
  }

  testSetEnd(range, node.parentNode, idx);
}

function testSetEndAfter(range, node) {
  var parent = node.parentNode;
  if (parent === null) {
    assert_throws("INVALID_NODE_TYPE_ERR", function () {
      range.setEndAfter(node);
    }, "setEndAfter() to a node with null parent must throw INVALID_NODE_TYPE_ERR");
    return;
  }

  var idx = 0;
  while (node.parentNode.childNodes[idx] != node) {
    idx++;
  }

  testSetEnd(range, node.parentNode, idx + 1);
}


var startTests = [];
var endTests = [];
var startBeforeTests = [];
var startAfterTests = [];
var endBeforeTests = [];
var endAfterTests = [];

// Don't want to eval() each point a bazillion times
var testPointsCached = testPoints.map(eval);
var testNodesCached = testNodesShort.map(eval);

for (var i = 0; i < testRangesShort.length; i++) {
  var endpoints = eval(testRangesShort[i]);
  var range;
  test(function() {
    range = ownerDocument(endpoints[0]).createRange();
    range.setStart(endpoints[0], endpoints[1]);
    range.setEnd(endpoints[2], endpoints[3]);
  }, "Set up range " + i + " " + testRangesShort[i]);

  for (var j = 0; j < testPoints.length; j++) {
    startTests.push(["setStart() with range " + i + " " + testRangesShort[i] + ", point " + j + " " + testPoints[j],
      range,
      testPointsCached[j][0],
      testPointsCached[j][1]
    ]);
    endTests.push(["setEnd() with range " + i + " " + testRangesShort[i] + ", point " + j + " " + testPoints[j],
      range,
      testPointsCached[j][0],
      testPointsCached[j][1]
    ]);
  }

  for (var j = 0; j < testNodesShort.length; j++) {
    startBeforeTests.push(["setStartBefore() with range " + i + " " + testRangesShort[i] + ", node " + j + " " + testNodesShort[j],
      range,
      testNodesCached[j]
    ]);
    startAfterTests.push(["setStartAfter() with range " + i + " " + testRangesShort[i] + ", node " + j + " " + testNodesShort[j],
      range,
      testNodesCached[j]
    ]);
    endBeforeTests.push(["setEndBefore() with range " + i + " " + testRangesShort[i] + ", node " + j + " " + testNodesShort[j],
      range,
      testNodesCached[j]
    ]);
    endAfterTests.push(["setEndAfter() with range " + i + " " + testRangesShort[i] + ", node " + j + " " + testNodesShort[j],
      range,
      testNodesCached[j]
    ]);
  }
}

generate_tests(testSetStart, startTests);
generate_tests(testSetEnd, endTests);
generate_tests(testSetStartBefore, startBeforeTests);
generate_tests(testSetStartAfter, startAfterTests);
generate_tests(testSetEndBefore, endBeforeTests);
generate_tests(testSetEndAfter, endAfterTests);

testDiv.style.display = "none";
</script>
