<!doctype html>
<title>Selection.collapse() tests</title>
<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 testCollapse(range, point) {
    selection.removeAllRanges();
    var addedRange;
    if (range) {
        addedRange = range.cloneRange();
        selection.addRange(addedRange);
    }

    if (point[0].nodeType == Node.DOCUMENT_TYPE_NODE) {
        assert_throws("INVALID_NODE_TYPE_ERR", function() {
            selection.collapse(point[0], point[1]);
        }, "Must throw INVALID_NODE_TYPE_ERR when collapse()ing if the node is a DocumentType");
        return;
    }

    if (point[1] < 0 || point[1] > getNodeLength(point[0])) {
        assert_throws("INDEX_SIZE_ERR", function() {
            selection.collapse(point[0], point[1]);
        }, "Must throw INDEX_SIZE_ERR when collapse()ing if the offset is negative or greater than the node's length");
        return;
    }

    selection.collapse(point[0], point[1]);

    assert_equals(selection.rangeCount, 1,
        "selection.rangeCount must equal 1 after collapse()");
    assert_equals(selection.focusNode, point[0],
        "focusNode must equal the node we collapse()d to");
    assert_equals(selection.focusOffset, point[1],
        "focusOffset must equal the offset we collapse()d to");
    assert_equals(selection.focusNode, selection.anchorNode,
        "focusNode and anchorNode must be equal after collapse()");
    assert_equals(selection.focusOffset, selection.anchorOffset,
        "focusOffset and anchorOffset must be equal after collapse()");
    if (range) {
        assert_equals(addedRange.startContainer, range.startContainer,
            "collapse() must not change the startContainer of a preexisting Range");
        assert_equals(addedRange.endContainer, range.endContainer,
            "collapse() must not change the endContainer of a preexisting Range");
        assert_equals(addedRange.startOffset, range.startOffset,
            "collapse() must not change the startOffset of a preexisting Range");
        assert_equals(addedRange.endOffset, range.endOffset,
            "collapse() must not change the endOffset of a preexisting Range");
    }
}

// Also test a selection with no ranges
testRanges.unshift("[]");

// Don't want to eval() each point a bazillion times
var testPointsCached = [];
for (var i = 0; i < testPoints.length; i++) {
    testPointsCached.push(eval(testPoints[i]));
}

var tests = [];
for (var i = 0; i < testRanges.length; i++) {
    var endpoints = eval(testRanges[i]);
    var range;
    test(function() {
        if (endpoints.length) {
            range = ownerDocument(endpoints[0]).createRange();
            range.setStart(endpoints[0], endpoints[1]);
            range.setEnd(endpoints[2], endpoints[3]);
        } else {
            // Empty selection
            range = null;
        }
    }, "Set up range " + i + " " + testRanges[i]);
    for (var j = 0; j < testPoints.length; j++) {
        tests.push(["Range " + i + " " + testRanges[i] + ", point " + j + " " + testPoints[j], range, testPointsCached[j]]);
    }
}

generate_tests(testCollapse, tests);

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