<!DOCTYPE html>
<html>
<body>
<script src="../w3c/resources/testharness.js"></script>
<script src="../w3c/resources/testharnessreport.js"></script>
<script type="text/javascript">
test(function()
{
    var xhr = new XMLHttpRequest;
    xhr.onreadystatechange = this.step_func(function() {
        assert_unreached("Received readystatechange event unexpectedly: readyState=" + xhr.readyState)
    });
    xhr.abort();
    assert_equals(xhr.readyState, xhr.UNSENT, "xhr.readyState after abort() call");
}, "Test onreadystatechange invocation when abort()-ed in UNSENT state.");

test(function()
{
    var xhr = new XMLHttpRequest;
    var seenStates = [];
    xhr.onreadystatechange = this.step_func(function() {
        seenStates.push(xhr.readyState);

        switch (xhr.readyState) {
        case xhr.OPENED:
            return;

        case xhr.UNSENT:
        case xhr.HEADERS_RECEIVED:
        case xhr.LOADING:
        case xhr.DONE:
        default:
            assert_unreached("Unexpected readyState: " + xhr.readyState);
            return;
        }
    });
    xhr.open("GET", "resources/test.ogv", true);
    xhr.abort();
    assert_equals(xhr.readyState, xhr.UNSENT, "xhr.readyState after abort() call");
    assert_array_equals(seenStates, [xhr.OPENED]);
}, "Test onreadystatechange invocation when abort()-ed in OPENED state.");

test(function()
{
    var xhr = new XMLHttpRequest;
    var seenStates = [];
    xhr.onreadystatechange = this.step_func(function() {
        seenStates.push(xhr.readyState);

        switch (xhr.readyState) {
        case xhr.OPENED:
        case xhr.DONE:
            return;

        case xhr.UNSENT:
        case xhr.HEADERS_RECEIVED:
        case xhr.LOADING:
        default:
            assert_unreached("Unexpected readyState: " + xhr.readyState);
            return;
        }
    });
    xhr.open("GET", "resources/test.ogv", true);
    xhr.send();
    xhr.abort();
    assert_equals(xhr.readyState, xhr.UNSENT, "xhr.readyState after abort() call");
    assert_array_equals(seenStates, [xhr.OPENED, xhr.DONE]);
}, "Test onreadystatechange invocation when abort()-ed right after calling send().");

var abortInHeadersReceivedTest = async_test("Test onreadystatechange invocation when abort()-ed in HEADERS_RECEIVED state.");
abortInHeadersReceivedTest.step(function()
{
    var xhr = new XMLHttpRequest;
    var seenStates = [];
    xhr.onreadystatechange = abortInHeadersReceivedTest.step_func(function() {
        seenStates.push(xhr.readyState);

        switch (xhr.readyState) {
        case xhr.OPENED:
        case xhr.DONE:
            return;

        case xhr.HEADERS_RECEIVED:
            xhr.abort();
            assert_equals(xhr.readyState, xhr.UNSENT, "xhr.readyState after abort() call");
            assert_array_equals(seenStates, [xhr.OPENED, xhr.HEADERS_RECEIVED, xhr.DONE]);
            abortInHeadersReceivedTest.done();
            return;

        case xhr.UNSENT:
        case xhr.LOADING:
        default:
            assert_unreached("Unexpected readyState: " + xhr.readyState)
            return;
        }
    });
    xhr.open("GET", "resources/test.ogv", true);
    xhr.send();
});

var abortInLoadingTest = async_test("Test onreadystatechange invocation when abort()-ed in LOADING state.");
abortInLoadingTest.step(function()
{
    var xhr = new XMLHttpRequest;
    var seenStates = [];
    xhr.onreadystatechange = abortInLoadingTest.step_func(function() {
        seenStates.push(xhr.readyState);

        switch (xhr.readyState) {
        case xhr.OPENED:
        case xhr.HEADERS_RECEIVED:
        case xhr.DONE:
            return;

        case xhr.LOADING:
            xhr.abort();
            assert_equals(xhr.readyState, xhr.UNSENT, "xhr.readyState after abort() call");
            assert_array_equals(seenStates, [xhr.OPENED, xhr.HEADERS_RECEIVED, xhr.LOADING, xhr.DONE]);
            abortInLoadingTest.done();
            return;

        case xhr.UNSENT:
        default:
            assert_unreached("Unexpected readyState: " + xhr.readyState)
            return;
        }
    });
    xhr.open("GET", "resources/test.ogv", true);
    xhr.send();
});

var abortInDoneTest = async_test("Test onreadystatechange invocation when abort()-ed in DONE state.");
abortInDoneTest.step(function()
{
    var xhr = new XMLHttpRequest;
    var seenStates = [];
    xhr.onreadystatechange = abortInDoneTest.step_func(function() {
        seenStates.push(xhr.readyState);

        switch (xhr.readyState) {
        case xhr.OPENED:
        case xhr.HEADERS_RECEIVED:
        case xhr.LOADING:
            return;

        case xhr.DONE:
            xhr.abort();
            assert_equals(xhr.readyState, xhr.UNSENT, "xhr.readyState after abort() call");
            assert_array_equals(seenStates, [xhr.OPENED, xhr.HEADERS_RECEIVED, xhr.LOADING, xhr.DONE]);
            abortInDoneTest.done();
            return;

        case xhr.UNSENT:
        default:
            assert_unreached("Unexpected readyState: " + xhr.readyState)
            return;
        }
    });
    xhr.open("GET", "resources/test.ogv", true);
    xhr.send();
});
</script>
</body>
</html>
