<!DOCTYPE html>
<script src='../../resources/testharness.js'></script>
<script src='../../resources/testharnessreport.js'></script>
<script>
// This is updated till https://github.com/whatwg/streams/commit/4ba861e6f60c248060811830e11271c84b439cc3

test(function() {
    var theError = new Error('a unique string');

    assert_throws_exactly(theError, function() {
        new WritableStream({}, {
            get size() {
                throw theError;
            },
            highWaterMark: 5
        });
    }, 'construction should re-throw the error');
}, 'Writable stream: throwing strategy.size getter');

var test1 = async_test('Writable stream: throwing strategy.size method');
test1.step(function() {
    var theError = new Error('a unique string');
    var writeCalled = false;
    var ws = new WritableStream({ },
        {
            size: function() {
                throw theError;
            },
            highWaterMark: 5
        }
    ); // Initial construction should not throw.

    ws.write('a').then(
        test1.step_func(function() { assert_unreached('write should not fulfill'); }),
        test1.step_func(function(r) {
            assert_equals(r, theError, 'write should reject with the thrown error');
            writeCalled = true;
        })
    );

    ws.closed.then(
        test1.step_func(function() { assert_unreached('closed should not fulfill'); }),
        test1.step_func(function(r) {
            assert_equals(r, theError, 'closed should reject with the thrown error');
            assert_true(writeCalled);
            test1.done();
        })
    );
});

var test2 = async_test('Writable stream: invalid strategy.size return value');
test2.step(function() {
    var numberOfCalls = 0;
    var elements = [NaN, -Infinity, +Infinity, -1];
    var theError = [];
    var numberOfCalls = 0;
    for (var i = 0; i < elements.length; i++) {
        var ws = new WritableStream({},
        {
            size: function() {
                return elements[i];
            },
            highWaterMark: 5
        });

        var writeFunction = function(i, r) {
            assert_throws_js(RangeError, function() { throw r; }, 'write should reject with a RangeError for ' + elements[i]);
            theError[i] = r;
        };
        ws.write('a').then(
            test2.step_func(function() { assert_unreached('write should not fulfill'); }),
            test2.step_func(writeFunction.bind(this, i))
        );

        var catchFunction = function(i, e) {
            assert_equals(e, theError[i], 'closed should reject with the error for ' + elements[i]);
            if (++numberOfCalls, elements.length) {
                test2.done();
            }
        };

        ws.closed.catch(test2.step_func(catchFunction.bind(this, i)));
    }
});

test(function() {
    var theError = new Error('a unique string');

    assert_throws_exactly(theError, function() {
        new WritableStream({}, {
            size: function() {
                return 1;
            },
            get highWaterMark() {
                throw theError;
            }
        });
    }, 'construction should re-throw the error');
}, 'Writable stream: throwing strategy.highWaterMark getter');

test(function() {
    for (var highWaterMark of [-1, -Infinity]) {
        assert_throws_js(RangeError, function() {
            new WritableStream({}, {
                size: function() {
                    return 1;
                },
                highWaterMark
            });
        }, 'construction should throw a RangeError for ' + highWaterMark);
    }

    for (var highWaterMark of [NaN, 'foo', {}]) {
        assert_throws_js(RangeError, function() {
            new WritableStream({}, {
                size: function() {
                    return 1;
                },
                highWaterMark
            });
        }, 'construction should throw a TypeError for ' + highWaterMark);
    }
}, 'Writable stream: invalid strategy.highWaterMark');
</script>
