Commit 90cddd79 authored by Adam Rice's avatar Adam Rice Committed by Commit Bot

Streams: Update queuing strategies to match standard

Update the IDL for ByteLengthQueuingStrategy and CountQueuingStrategy
to match the standard.

The most noticeable semantic difference is that incorrect calls like
`new CountQueuingStrategy(10)`, which previously silently gave
you the default highWaterMark, will now throw an exception.

Also cache the "size" function on the global object. Add a test that
iframes have a different "size" function, since they have a different
global object.

Change-Id: I9b6763944c0abc278451c28a4fcf615f624e1fdb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2104815Reviewed-by: default avatarVictor Costan <pwnall@chromium.org>
Reviewed-by: default avatarYutaka Hirano <yhirano@chromium.org>
Commit-Queue: Adam Rice <ricea@chromium.org>
Cr-Commit-Position: refs/heads/master@{#788474}
parent f223da4a
...@@ -14,7 +14,7 @@ void ScriptFunction::Trace(Visitor* visitor) const { ...@@ -14,7 +14,7 @@ void ScriptFunction::Trace(Visitor* visitor) const {
CustomWrappableAdapter::Trace(visitor); CustomWrappableAdapter::Trace(visitor);
} }
v8::Local<v8::Function> ScriptFunction::BindToV8Function() { v8::Local<v8::Function> ScriptFunction::BindToV8Function(int length) {
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
DCHECK(!bind_to_v8_function_already_called_); DCHECK(!bind_to_v8_function_already_called_);
bind_to_v8_function_already_called_ = true; bind_to_v8_function_already_called_ = true;
...@@ -24,7 +24,7 @@ v8::Local<v8::Function> ScriptFunction::BindToV8Function() { ...@@ -24,7 +24,7 @@ v8::Local<v8::Function> ScriptFunction::BindToV8Function() {
// The wrapper is held alive by the CallHandlerInfo internally in V8 as long // The wrapper is held alive by the CallHandlerInfo internally in V8 as long
// as the function is alive. // as the function is alive.
return v8::Function::New(script_state_->GetContext(), CallCallback, wrapper, return v8::Function::New(script_state_->GetContext(), CallCallback, wrapper,
0, v8::ConstructorBehavior::kThrow) length, v8::ConstructorBehavior::kThrow)
.ToLocalChecked(); .ToLocalChecked();
} }
......
...@@ -64,7 +64,9 @@ class CORE_EXPORT ScriptFunction : public CustomWrappableAdapter { ...@@ -64,7 +64,9 @@ class CORE_EXPORT ScriptFunction : public CustomWrappableAdapter {
ScriptState* GetScriptState() const { return script_state_; } ScriptState* GetScriptState() const { return script_state_; }
v8::Local<v8::Function> BindToV8Function(); // It is not usually necessary to set |length| unless the function is exposed
// to JavaScript.
v8::Local<v8::Function> BindToV8Function(int length = 0);
private: private:
// Subclasses should implement one of Call() or CallRaw(). Most will implement // Subclasses should implement one of Call() or CallRaw(). Most will implement
......
...@@ -16,13 +16,27 @@ namespace blink { ...@@ -16,13 +16,27 @@ namespace blink {
namespace { namespace {
static const V8PrivateProperty::SymbolKey
kByteLengthQueuingStrategySizeFunction;
class ByteLengthQueuingStrategySizeFunction final : public ScriptFunction { class ByteLengthQueuingStrategySizeFunction final : public ScriptFunction {
public: public:
static v8::Local<v8::Function> CreateFunction(ScriptState* script_state) { static v8::Local<v8::Function> CreateFunction(ScriptState* script_state) {
ByteLengthQueuingStrategySizeFunction* self = ByteLengthQueuingStrategySizeFunction* self =
MakeGarbageCollected<ByteLengthQueuingStrategySizeFunction>( MakeGarbageCollected<ByteLengthQueuingStrategySizeFunction>(
script_state); script_state);
return self->BindToV8Function();
// https://streams.spec.whatwg.org/#byte-length-queuing-strategy-size-function
// 2. Let F be ! CreateBuiltinFunction(steps, « », globalObject’s relevant
// Realm).
// 4. Perform ! SetFunctionLength(F, 1).
v8::Local<v8::Function> function = self->BindToV8Function(/*length=*/1);
// 3. Perform ! SetFunctionName(F, "size").
function->SetName(V8String(script_state->GetIsolate(), "size"));
return function;
} }
explicit ByteLengthQueuingStrategySizeFunction(ScriptState* script_state) explicit ByteLengthQueuingStrategySizeFunction(ScriptState* script_state)
...@@ -40,8 +54,10 @@ class ByteLengthQueuingStrategySizeFunction final : public ScriptFunction { ...@@ -40,8 +54,10 @@ class ByteLengthQueuingStrategySizeFunction final : public ScriptFunction {
chunk = args[0]; chunk = args[0];
} }
// https://streams.spec.whatwg.org/#blqs-size // https://streams.spec.whatwg.org/#byte-length-queuing-strategy-size-function
// 1. Return ? GetV(chunk, "byteLength").
// 1. Let steps be the following steps, given chunk:
// 1. Return ? GetV(chunk, "byteLength").
// https://tc39.es/ecma262/#sec-getv // https://tc39.es/ecma262/#sec-getv
// 1. Assert: IsPropertyKey(P) is true. // 1. Assert: IsPropertyKey(P) is true.
...@@ -74,28 +90,18 @@ ByteLengthQueuingStrategy* ByteLengthQueuingStrategy::Create( ...@@ -74,28 +90,18 @@ ByteLengthQueuingStrategy* ByteLengthQueuingStrategy::Create(
ByteLengthQueuingStrategy::ByteLengthQueuingStrategy( ByteLengthQueuingStrategy::ByteLengthQueuingStrategy(
ScriptState* script_state, ScriptState* script_state,
const QueuingStrategyInit* init) const QueuingStrategyInit* init)
: high_water_mark_(script_state->GetIsolate(), : high_water_mark_(init->highWaterMark()) {}
HighWaterMarkOrUndefined(script_state, init)) {}
ByteLengthQueuingStrategy::~ByteLengthQueuingStrategy() = default; ByteLengthQueuingStrategy::~ByteLengthQueuingStrategy() = default;
ScriptValue ByteLengthQueuingStrategy::highWaterMark(
ScriptState* script_state) const {
return ScriptValue(script_state->GetIsolate(),
high_water_mark_.NewLocal(script_state->GetIsolate()));
}
ScriptValue ByteLengthQueuingStrategy::size(ScriptState* script_state) const { ScriptValue ByteLengthQueuingStrategy::size(ScriptState* script_state) const {
// We don't cache the result because normally this method will only be called // https://streams.spec.whatwg.org/#byte-length-queuing-strategy-size-function
// once anyway. // 5. Set globalObject’s byte length queuing strategy size function to a
return ScriptValue( // Function that represents a reference to F, with callback context equal
script_state->GetIsolate(), // to globalObject’s relevant settings object.
ByteLengthQueuingStrategySizeFunction::CreateFunction(script_state)); return GetCachedSizeFunction(
} script_state, kByteLengthQueuingStrategySizeFunction,
&ByteLengthQueuingStrategySizeFunction::CreateFunction);
void ByteLengthQueuingStrategy::Trace(Visitor* visitor) const {
visitor->Trace(high_water_mark_);
ScriptWrappable::Trace(visitor);
} }
} // namespace blink } // namespace blink
...@@ -14,7 +14,6 @@ namespace blink { ...@@ -14,7 +14,6 @@ namespace blink {
class QueuingStrategyInit; class QueuingStrategyInit;
class ScriptState; class ScriptState;
class ScriptValue; class ScriptValue;
class Visitor;
// https://streams.spec.whatwg.org/#blqs-class // https://streams.spec.whatwg.org/#blqs-class
class ByteLengthQueuingStrategy final : public ScriptWrappable { class ByteLengthQueuingStrategy final : public ScriptWrappable {
...@@ -27,13 +26,11 @@ class ByteLengthQueuingStrategy final : public ScriptWrappable { ...@@ -27,13 +26,11 @@ class ByteLengthQueuingStrategy final : public ScriptWrappable {
ByteLengthQueuingStrategy(ScriptState*, const QueuingStrategyInit*); ByteLengthQueuingStrategy(ScriptState*, const QueuingStrategyInit*);
~ByteLengthQueuingStrategy() override; ~ByteLengthQueuingStrategy() override;
ScriptValue highWaterMark(ScriptState*) const; double highWaterMark() const { return high_water_mark_; }
ScriptValue size(ScriptState*) const; ScriptValue size(ScriptState*) const;
void Trace(Visitor*) const override;
private: private:
const TraceWrapperV8Reference<v8::Value> high_water_mark_; const double high_water_mark_;
}; };
} // namespace blink } // namespace blink
......
...@@ -7,9 +7,9 @@ ...@@ -7,9 +7,9 @@
[ [
Exposed=(Window,Worker,Worklet) Exposed=(Window,Worker,Worklet)
] interface ByteLengthQueuingStrategy { ] interface ByteLengthQueuingStrategy {
[CallWith=ScriptState, MeasureAs=ByteLengthQueuingStrategyConstructor] constructor([PermissiveDictionaryConversion] QueuingStrategyInit init); [CallWith=ScriptState, MeasureAs=ByteLengthQueuingStrategyConstructor] constructor(QueuingStrategyInit init);
[CallWith=ScriptState] readonly attribute any highWaterMark; readonly attribute unrestricted double highWaterMark;
// size is an accessor that returns a function. // The standard specifies "Function" but the IDL compiler doesn't like it.
[CallWith=ScriptState] readonly attribute any size; [CallWith=ScriptState] readonly attribute any size;
}; };
...@@ -15,12 +15,24 @@ namespace blink { ...@@ -15,12 +15,24 @@ namespace blink {
namespace { namespace {
static const V8PrivateProperty::SymbolKey kCountQueuingStrategySizeFunction;
class CountQueuingStrategySizeFunction final : public ScriptFunction { class CountQueuingStrategySizeFunction final : public ScriptFunction {
public: public:
static v8::Local<v8::Function> CreateFunction(ScriptState* script_state) { static v8::Local<v8::Function> CreateFunction(ScriptState* script_state) {
CountQueuingStrategySizeFunction* self = CountQueuingStrategySizeFunction* self =
MakeGarbageCollected<CountQueuingStrategySizeFunction>(script_state); MakeGarbageCollected<CountQueuingStrategySizeFunction>(script_state);
return self->BindToV8Function();
// https://streams.spec.whatwg.org/#count-queuing-strategy-size-function
// 2. Let F be ! CreateBuiltinFunction(steps, « », globalObject’s relevant
// Realm).
// 4. Perform ! SetFunctionLength(F, 0).
v8::Local<v8::Function> function = self->BindToV8Function(/*length=*/0);
// 3. Perform ! SetFunctionName(F, "size").
function->SetName(V8String(script_state->GetIsolate(), "size"));
return function;
} }
explicit CountQueuingStrategySizeFunction(ScriptState* script_state) explicit CountQueuingStrategySizeFunction(ScriptState* script_state)
...@@ -28,8 +40,9 @@ class CountQueuingStrategySizeFunction final : public ScriptFunction { ...@@ -28,8 +40,9 @@ class CountQueuingStrategySizeFunction final : public ScriptFunction {
private: private:
void CallRaw(const v8::FunctionCallbackInfo<v8::Value>& args) override { void CallRaw(const v8::FunctionCallbackInfo<v8::Value>& args) override {
// https://streams.spec.whatwg.org/#cqs-size // https://streams.spec.whatwg.org/#count-queuing-strategy-size-function
// 1. Return 1. // 1. Let steps be the following steps:
// 1. Return 1.
args.GetReturnValue().Set( args.GetReturnValue().Set(
v8::Integer::New(GetScriptState()->GetIsolate(), 1)); v8::Integer::New(GetScriptState()->GetIsolate(), 1));
} }
...@@ -45,28 +58,18 @@ CountQueuingStrategy* CountQueuingStrategy::Create( ...@@ -45,28 +58,18 @@ CountQueuingStrategy* CountQueuingStrategy::Create(
CountQueuingStrategy::CountQueuingStrategy(ScriptState* script_state, CountQueuingStrategy::CountQueuingStrategy(ScriptState* script_state,
const QueuingStrategyInit* init) const QueuingStrategyInit* init)
: high_water_mark_(script_state->GetIsolate(), : high_water_mark_(init->highWaterMark()) {}
HighWaterMarkOrUndefined(script_state, init)) {}
CountQueuingStrategy::~CountQueuingStrategy() = default; CountQueuingStrategy::~CountQueuingStrategy() = default;
ScriptValue CountQueuingStrategy::highWaterMark(
ScriptState* script_state) const {
return ScriptValue(script_state->GetIsolate(),
high_water_mark_.NewLocal(script_state->GetIsolate()));
}
ScriptValue CountQueuingStrategy::size(ScriptState* script_state) const { ScriptValue CountQueuingStrategy::size(ScriptState* script_state) const {
// We don't cache the result because normally this method will only be called // https://streams.spec.whatwg.org/#count-queuing-strategy-size-function
// once anyway. // 5. Set globalObject’s count queuing strategy size function to a Function
return ScriptValue( // that represents a reference to F, with callback context equal to
script_state->GetIsolate(), // globalObject’s relevant settings object.
CountQueuingStrategySizeFunction::CreateFunction(script_state)); return GetCachedSizeFunction(
} script_state, kCountQueuingStrategySizeFunction,
&CountQueuingStrategySizeFunction::CreateFunction);
void CountQueuingStrategy::Trace(Visitor* visitor) const {
visitor->Trace(high_water_mark_);
ScriptWrappable::Trace(visitor);
} }
} // namespace blink } // namespace blink
...@@ -15,7 +15,6 @@ namespace blink { ...@@ -15,7 +15,6 @@ namespace blink {
class QueuingStrategyInit; class QueuingStrategyInit;
class ScriptState; class ScriptState;
class ScriptValue; class ScriptValue;
class Visitor;
// https://streams.spec.whatwg.org/#blqs-class // https://streams.spec.whatwg.org/#blqs-class
class CORE_EXPORT CountQueuingStrategy final : public ScriptWrappable { class CORE_EXPORT CountQueuingStrategy final : public ScriptWrappable {
...@@ -27,13 +26,11 @@ class CORE_EXPORT CountQueuingStrategy final : public ScriptWrappable { ...@@ -27,13 +26,11 @@ class CORE_EXPORT CountQueuingStrategy final : public ScriptWrappable {
CountQueuingStrategy(ScriptState*, const QueuingStrategyInit*); CountQueuingStrategy(ScriptState*, const QueuingStrategyInit*);
~CountQueuingStrategy() override; ~CountQueuingStrategy() override;
ScriptValue highWaterMark(ScriptState*) const; double highWaterMark() const { return high_water_mark_; }
ScriptValue size(ScriptState*) const; ScriptValue size(ScriptState*) const;
void Trace(Visitor*) const override;
private: private:
const TraceWrapperV8Reference<v8::Value> high_water_mark_; const double high_water_mark_;
}; };
} // namespace blink } // namespace blink
......
...@@ -7,9 +7,9 @@ ...@@ -7,9 +7,9 @@
[ [
Exposed=(Window,Worker,Worklet) Exposed=(Window,Worker,Worklet)
] interface CountQueuingStrategy { ] interface CountQueuingStrategy {
[CallWith=ScriptState, MeasureAs=CountQueuingStrategyConstructor] constructor([PermissiveDictionaryConversion] QueuingStrategyInit init); [CallWith=ScriptState, MeasureAs=CountQueuingStrategyConstructor] constructor(QueuingStrategyInit init);
[CallWith=ScriptState] readonly attribute any highWaterMark; readonly attribute unrestricted double highWaterMark;
// size is an accessor that returns a function. // The standard specifies "Function" but the IDL compiler doesn't like it.
[CallWith=ScriptState] readonly attribute any size; [CallWith=ScriptState] readonly attribute any size;
}; };
...@@ -4,20 +4,26 @@ ...@@ -4,20 +4,26 @@
#include "third_party/blink/renderer/core/streams/queuing_strategy_common.h" #include "third_party/blink/renderer/core/streams/queuing_strategy_common.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_queuing_strategy_init.h" #include "third_party/blink/renderer/bindings/core/v8/v8_queuing_strategy_init.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/bindings/script_state.h"
namespace blink { namespace blink {
v8::Local<v8::Value> HighWaterMarkOrUndefined(ScriptState* script_state, ScriptValue GetCachedSizeFunction(ScriptState* script_state,
const QueuingStrategyInit* init) { const V8PrivateProperty::SymbolKey& key,
v8::Local<v8::Value> high_water_mark; SizeFunctionFactory factory) {
if (init->hasHighWaterMark()) { auto* isolate = script_state->GetIsolate();
high_water_mark = init->highWaterMark().V8Value(); auto function_cache = V8PrivateProperty::GetSymbol(isolate, key);
} else { v8::Local<v8::Object> global_proxy = script_state->GetContext()->Global();
high_water_mark = v8::Undefined(script_state->GetIsolate()); v8::Local<v8::Value> function;
if (!function_cache.GetOrUndefined(global_proxy).ToLocal(&function) ||
function->IsUndefined()) {
function = factory(script_state);
bool is_set = function_cache.Set(global_proxy, function);
DCHECK(is_set || isolate->IsExecutionTerminating());
} }
return high_water_mark; return ScriptValue(isolate, function);
} }
} // namespace blink } // namespace blink
...@@ -5,15 +5,21 @@ ...@@ -5,15 +5,21 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_QUEUING_STRATEGY_COMMON_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_QUEUING_STRATEGY_COMMON_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_QUEUING_STRATEGY_COMMON_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_QUEUING_STRATEGY_COMMON_H_
#include "third_party/blink/renderer/platform/bindings/v8_private_property.h"
#include "v8/include/v8.h" #include "v8/include/v8.h"
namespace blink { namespace blink {
class ScriptState; class ScriptState;
class QueuingStrategyInit; class ScriptValue;
v8::Local<v8::Value> HighWaterMarkOrUndefined(ScriptState* script_state, using SizeFunctionFactory = v8::Local<v8::Function> (*)(ScriptState*);
const QueuingStrategyInit* init);
// Returns the value cached on the global proxy object under |key|, or, if that
// is not set, caches and returns the result of calling |factory|.
ScriptValue GetCachedSizeFunction(ScriptState*,
const V8PrivateProperty::SymbolKey& key,
SizeFunctionFactory factory);
} // namespace blink } // namespace blink
......
...@@ -2,9 +2,8 @@ ...@@ -2,9 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// https://streams.spec.whatwg.org/#cqs-class // https://streams.spec.whatwg.org/#dictdef-queuingstrategyinit
[PermissiveDictionaryConversion]
dictionary QueuingStrategyInit { dictionary QueuingStrategyInit {
any highWaterMark; required unrestricted double highWaterMark;
}; };
...@@ -203,8 +203,7 @@ WritableStream* WritableStream::CreateWithCountQueueingStrategy( ...@@ -203,8 +203,7 @@ WritableStream* WritableStream::CreateWithCountQueueingStrategy(
// introduces unnecessary trips through V8. Implement algorithms based on an // introduces unnecessary trips through V8. Implement algorithms based on an
// UnderlyingSinkBase. // UnderlyingSinkBase.
auto* init = QueuingStrategyInit::Create(); auto* init = QueuingStrategyInit::Create();
init->setHighWaterMark( init->setHighWaterMark(static_cast<double>(high_water_mark));
ScriptValue::From(script_state, static_cast<double>(high_water_mark)));
auto* strategy = CountQueuingStrategy::Create(script_state, init); auto* strategy = CountQueuingStrategy::Create(script_state, init);
ScriptValue strategy_value = ScriptValue::From(script_state, strategy); ScriptValue strategy_value = ScriptValue::From(script_state, strategy);
if (strategy_value.IsEmpty()) if (strategy_value.IsEmpty())
......
...@@ -36,8 +36,7 @@ NativeFileSystemWritableFileStream* NativeFileSystemWritableFileStream::Create( ...@@ -36,8 +36,7 @@ NativeFileSystemWritableFileStream* NativeFileSystemWritableFileStream::Create(
auto* init = QueuingStrategyInit::Create(); auto* init = QueuingStrategyInit::Create();
// HighWaterMark set to 1 here. This allows the stream to appear available // HighWaterMark set to 1 here. This allows the stream to appear available
// without adding additional buffering. // without adding additional buffering.
init->setHighWaterMark( init->setHighWaterMark(1);
ScriptValue::From(script_state, static_cast<double>(1)));
auto* strategy = CountQueuingStrategy::Create(script_state, init); auto* strategy = CountQueuingStrategy::Create(script_state, init);
ScriptValue strategy_value = ScriptValue::From(script_state, strategy); ScriptValue strategy_value = ScriptValue::From(script_state, strategy);
......
This is a testharness.js-based test.
PASS Can construct a ByteLengthQueuingStrategy with a valid high water mark
PASS Can construct a ByteLengthQueuingStrategy with any value as its high water mark
FAIL ByteLengthQueuingStrategy constructor behaves as expected with strange arguments assert_throws_js: construction fails with null function "() => new ByteLengthQueuingStrategy(null)" did not throw
FAIL ByteLengthQueuingStrategy size behaves as expected with strange arguments Illegal invocation
FAIL ByteLengthQueuingStrategy.prototype.size should work generically on its this and its arguments Illegal invocation
FAIL ByteLengthQueuingStrategy instances have the correct properties assert_object_equals: highWaterMark property should be a data property with the value passed the constructor value is undefined, expected object
FAIL ByteLengthQueuingStrategy's highWaterMark property can be set to anything Cannot assign to read only property 'highWaterMark' of object '#<ByteLengthQueuingStrategy>'
PASS ByteLengthQueuingStrategy.name is correct
PASS subclassing ByteLengthQueuingStrategy should work correctly
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Can construct a ByteLengthQueuingStrategy with a valid high water mark
PASS Can construct a ByteLengthQueuingStrategy with any value as its high water mark
FAIL ByteLengthQueuingStrategy constructor behaves as expected with strange arguments assert_throws_js: construction fails with null function "() => new ByteLengthQueuingStrategy(null)" did not throw
FAIL ByteLengthQueuingStrategy size behaves as expected with strange arguments Illegal invocation
FAIL ByteLengthQueuingStrategy.prototype.size should work generically on its this and its arguments Illegal invocation
FAIL ByteLengthQueuingStrategy instances have the correct properties assert_object_equals: highWaterMark property should be a data property with the value passed the constructor value is undefined, expected object
FAIL ByteLengthQueuingStrategy's highWaterMark property can be set to anything Cannot assign to read only property 'highWaterMark' of object '#<ByteLengthQueuingStrategy>'
PASS ByteLengthQueuingStrategy.name is correct
PASS subclassing ByteLengthQueuingStrategy should work correctly
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Can construct a ByteLengthQueuingStrategy with a valid high water mark
PASS Can construct a ByteLengthQueuingStrategy with any value as its high water mark
FAIL ByteLengthQueuingStrategy constructor behaves as expected with strange arguments assert_throws_js: construction fails with null function "() => new ByteLengthQueuingStrategy(null)" did not throw
FAIL ByteLengthQueuingStrategy size behaves as expected with strange arguments Illegal invocation
FAIL ByteLengthQueuingStrategy.prototype.size should work generically on its this and its arguments Illegal invocation
FAIL ByteLengthQueuingStrategy instances have the correct properties assert_object_equals: highWaterMark property should be a data property with the value passed the constructor value is undefined, expected object
FAIL ByteLengthQueuingStrategy's highWaterMark property can be set to anything Cannot assign to read only property 'highWaterMark' of object '#<ByteLengthQueuingStrategy>'
PASS ByteLengthQueuingStrategy.name is correct
PASS subclassing ByteLengthQueuingStrategy should work correctly
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Can construct a ByteLengthQueuingStrategy with a valid high water mark
PASS Can construct a ByteLengthQueuingStrategy with any value as its high water mark
FAIL ByteLengthQueuingStrategy constructor behaves as expected with strange arguments assert_throws_js: construction fails with null function "() => new ByteLengthQueuingStrategy(null)" did not throw
FAIL ByteLengthQueuingStrategy size behaves as expected with strange arguments Illegal invocation
FAIL ByteLengthQueuingStrategy.prototype.size should work generically on its this and its arguments Illegal invocation
FAIL ByteLengthQueuingStrategy instances have the correct properties assert_object_equals: highWaterMark property should be a data property with the value passed the constructor value is undefined, expected object
FAIL ByteLengthQueuingStrategy's highWaterMark property can be set to anything Cannot assign to read only property 'highWaterMark' of object '#<ByteLengthQueuingStrategy>'
PASS ByteLengthQueuingStrategy.name is correct
PASS subclassing ByteLengthQueuingStrategy should work correctly
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Can construct a CountQueuingStrategy with a valid high water mark
PASS Can construct a CountQueuingStrategy with any value as its high water mark
FAIL CountQueuingStrategy constructor behaves as expected with strange arguments assert_throws_js: construction fails with null function "() => new CountQueuingStrategy(null)" did not throw
FAIL CountQueuingStrategy.prototype.size should work generically on its this and its arguments Illegal invocation
FAIL CountQueuingStrategy size behaves as expected with strange arguments Illegal invocation
FAIL CountQueuingStrategy instances have the correct properties assert_object_equals: highWaterMark property should be a data property with the value passed the constructor value is undefined, expected object
FAIL CountQueuingStrategy's highWaterMark property can be set to anything Cannot assign to read only property 'highWaterMark' of object '#<CountQueuingStrategy>'
PASS CountQueuingStrategy.name is correct
PASS subclassing CountQueuingStrategy should work correctly
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Can construct a CountQueuingStrategy with a valid high water mark
PASS Can construct a CountQueuingStrategy with any value as its high water mark
FAIL CountQueuingStrategy constructor behaves as expected with strange arguments assert_throws_js: construction fails with null function "() => new CountQueuingStrategy(null)" did not throw
FAIL CountQueuingStrategy.prototype.size should work generically on its this and its arguments Illegal invocation
FAIL CountQueuingStrategy size behaves as expected with strange arguments Illegal invocation
FAIL CountQueuingStrategy instances have the correct properties assert_object_equals: highWaterMark property should be a data property with the value passed the constructor value is undefined, expected object
FAIL CountQueuingStrategy's highWaterMark property can be set to anything Cannot assign to read only property 'highWaterMark' of object '#<CountQueuingStrategy>'
PASS CountQueuingStrategy.name is correct
PASS subclassing CountQueuingStrategy should work correctly
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Can construct a CountQueuingStrategy with a valid high water mark
PASS Can construct a CountQueuingStrategy with any value as its high water mark
FAIL CountQueuingStrategy constructor behaves as expected with strange arguments assert_throws_js: construction fails with null function "() => new CountQueuingStrategy(null)" did not throw
FAIL CountQueuingStrategy.prototype.size should work generically on its this and its arguments Illegal invocation
FAIL CountQueuingStrategy size behaves as expected with strange arguments Illegal invocation
FAIL CountQueuingStrategy instances have the correct properties assert_object_equals: highWaterMark property should be a data property with the value passed the constructor value is undefined, expected object
FAIL CountQueuingStrategy's highWaterMark property can be set to anything Cannot assign to read only property 'highWaterMark' of object '#<CountQueuingStrategy>'
PASS CountQueuingStrategy.name is correct
PASS subclassing CountQueuingStrategy should work correctly
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Can construct a CountQueuingStrategy with a valid high water mark
PASS Can construct a CountQueuingStrategy with any value as its high water mark
FAIL CountQueuingStrategy constructor behaves as expected with strange arguments assert_throws_js: construction fails with null function "() => new CountQueuingStrategy(null)" did not throw
FAIL CountQueuingStrategy.prototype.size should work generically on its this and its arguments Illegal invocation
FAIL CountQueuingStrategy size behaves as expected with strange arguments Illegal invocation
FAIL CountQueuingStrategy instances have the correct properties assert_object_equals: highWaterMark property should be a data property with the value passed the constructor value is undefined, expected object
FAIL CountQueuingStrategy's highWaterMark property can be set to anything Cannot assign to read only property 'highWaterMark' of object '#<CountQueuingStrategy>'
PASS CountQueuingStrategy.name is correct
PASS subclassing CountQueuingStrategy should work correctly
Harness: the test ran to completion.
const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
for (const type of ['CountQueuingStrategy', 'ByteLengthQueuingStrategy']) {
test(() => {
const myQs = new window[type]({ highWaterMark: 1 });
const yourQs = new iframe.contentWindow[type]({ highWaterMark: 1 });
assert_not_equals(myQs.size, yourQs.size,
'size should not be the same object');
}, `${type} size should be different for objects in different realms`);
}
// Cleanup the document to avoid messing up the result page.
iframe.remove();
This is a testharness.js-based test.
PASS CountQueuingStrategy: Can construct a with a valid high water mark
FAIL CountQueuingStrategy: Constructor behaves as expected with strange arguments assert_throws_js: construction fails with null function "() => new QueuingStrategy(null)" did not throw
FAIL CountQueuingStrategy: highWaterMark constructor values are converted per the unrestricted double rules assert_equals: false gets set correctly expected (number) 0 but got (boolean) false
FAIL CountQueuingStrategy: size is the same function across all instances assert_equals: expected function "function () { [native code] }" but got function "function () { [native code] }"
FAIL CountQueuingStrategy: size should have the right name assert_equals: expected "size" but got ""
PASS CountQueuingStrategy: subclassing should work correctly
PASS ByteLengthQueuingStrategy: Can construct a with a valid high water mark
FAIL ByteLengthQueuingStrategy: Constructor behaves as expected with strange arguments assert_throws_js: construction fails with null function "() => new QueuingStrategy(null)" did not throw
FAIL ByteLengthQueuingStrategy: highWaterMark constructor values are converted per the unrestricted double rules assert_equals: false gets set correctly expected (number) 0 but got (boolean) false
FAIL ByteLengthQueuingStrategy: size is the same function across all instances assert_equals: expected function "function () { [native code] }" but got function "function () { [native code] }"
FAIL ByteLengthQueuingStrategy: size should have the right name assert_equals: expected "size" but got ""
PASS ByteLengthQueuingStrategy: subclassing should work correctly
PASS CountQueuingStrategy: size should have the right length
FAIL ByteLengthQueuingStrategy: size should have the right length assert_equals: expected 1 but got 0
PASS CountQueuingStrategy: size behaves as expected with strange arguments
PASS ByteLengthQueuingStrategy: size behaves as expected with strange arguments
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS CountQueuingStrategy: Can construct a with a valid high water mark
FAIL CountQueuingStrategy: Constructor behaves as expected with strange arguments assert_throws_js: construction fails with null function "() => new QueuingStrategy(null)" did not throw
FAIL CountQueuingStrategy: highWaterMark constructor values are converted per the unrestricted double rules assert_equals: false gets set correctly expected (number) 0 but got (boolean) false
FAIL CountQueuingStrategy: size is the same function across all instances assert_equals: expected function "function () { [native code] }" but got function "function () { [native code] }"
FAIL CountQueuingStrategy: size should have the right name assert_equals: expected "size" but got ""
PASS CountQueuingStrategy: subclassing should work correctly
PASS ByteLengthQueuingStrategy: Can construct a with a valid high water mark
FAIL ByteLengthQueuingStrategy: Constructor behaves as expected with strange arguments assert_throws_js: construction fails with null function "() => new QueuingStrategy(null)" did not throw
FAIL ByteLengthQueuingStrategy: highWaterMark constructor values are converted per the unrestricted double rules assert_equals: false gets set correctly expected (number) 0 but got (boolean) false
FAIL ByteLengthQueuingStrategy: size is the same function across all instances assert_equals: expected function "function () { [native code] }" but got function "function () { [native code] }"
FAIL ByteLengthQueuingStrategy: size should have the right name assert_equals: expected "size" but got ""
PASS ByteLengthQueuingStrategy: subclassing should work correctly
PASS CountQueuingStrategy: size should have the right length
FAIL ByteLengthQueuingStrategy: size should have the right length assert_equals: expected 1 but got 0
PASS CountQueuingStrategy: size behaves as expected with strange arguments
PASS ByteLengthQueuingStrategy: size behaves as expected with strange arguments
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS CountQueuingStrategy: Can construct a with a valid high water mark
FAIL CountQueuingStrategy: Constructor behaves as expected with strange arguments assert_throws_js: construction fails with null function "() => new QueuingStrategy(null)" did not throw
FAIL CountQueuingStrategy: highWaterMark constructor values are converted per the unrestricted double rules assert_equals: false gets set correctly expected (number) 0 but got (boolean) false
FAIL CountQueuingStrategy: size is the same function across all instances assert_equals: expected function "function () { [native code] }" but got function "function () { [native code] }"
FAIL CountQueuingStrategy: size should have the right name assert_equals: expected "size" but got ""
PASS CountQueuingStrategy: subclassing should work correctly
PASS ByteLengthQueuingStrategy: Can construct a with a valid high water mark
FAIL ByteLengthQueuingStrategy: Constructor behaves as expected with strange arguments assert_throws_js: construction fails with null function "() => new QueuingStrategy(null)" did not throw
FAIL ByteLengthQueuingStrategy: highWaterMark constructor values are converted per the unrestricted double rules assert_equals: false gets set correctly expected (number) 0 but got (boolean) false
FAIL ByteLengthQueuingStrategy: size is the same function across all instances assert_equals: expected function "function () { [native code] }" but got function "function () { [native code] }"
FAIL ByteLengthQueuingStrategy: size should have the right name assert_equals: expected "size" but got ""
PASS ByteLengthQueuingStrategy: subclassing should work correctly
PASS CountQueuingStrategy: size should have the right length
FAIL ByteLengthQueuingStrategy: size should have the right length assert_equals: expected 1 but got 0
PASS CountQueuingStrategy: size behaves as expected with strange arguments
PASS ByteLengthQueuingStrategy: size behaves as expected with strange arguments
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS CountQueuingStrategy: Can construct a with a valid high water mark
FAIL CountQueuingStrategy: Constructor behaves as expected with strange arguments assert_throws_js: construction fails with null function "() => new QueuingStrategy(null)" did not throw
FAIL CountQueuingStrategy: highWaterMark constructor values are converted per the unrestricted double rules assert_equals: false gets set correctly expected (number) 0 but got (boolean) false
FAIL CountQueuingStrategy: size is the same function across all instances assert_equals: expected function "function () { [native code] }" but got function "function () { [native code] }"
FAIL CountQueuingStrategy: size should have the right name assert_equals: expected "size" but got ""
PASS CountQueuingStrategy: subclassing should work correctly
PASS ByteLengthQueuingStrategy: Can construct a with a valid high water mark
FAIL ByteLengthQueuingStrategy: Constructor behaves as expected with strange arguments assert_throws_js: construction fails with null function "() => new QueuingStrategy(null)" did not throw
FAIL ByteLengthQueuingStrategy: highWaterMark constructor values are converted per the unrestricted double rules assert_equals: false gets set correctly expected (number) 0 but got (boolean) false
FAIL ByteLengthQueuingStrategy: size is the same function across all instances assert_equals: expected function "function () { [native code] }" but got function "function () { [native code] }"
FAIL ByteLengthQueuingStrategy: size should have the right name assert_equals: expected "size" but got ""
PASS ByteLengthQueuingStrategy: subclassing should work correctly
PASS CountQueuingStrategy: size should have the right length
FAIL ByteLengthQueuingStrategy: size should have the right length assert_equals: expected 1 but got 0
PASS CountQueuingStrategy: size behaves as expected with strange arguments
PASS ByteLengthQueuingStrategy: size behaves as expected with strange arguments
Harness: the test ran to completion.
...@@ -90,7 +90,7 @@ async function runTest() { ...@@ -90,7 +90,7 @@ async function runTest() {
close() { close() {
resolve(); resolve();
} }
}, new CountQueuingStrategy(10)); }, new CountQueuingStrategy({ highWaterMark: 10}));
emptyRS.pipeThrough({ emptyRS.pipeThrough({
writable: closeResolvesWS, writable: closeResolvesWS,
readable: new ReadableStream() readable: new ReadableStream()
...@@ -144,7 +144,7 @@ async function runTest() { ...@@ -144,7 +144,7 @@ async function runTest() {
} }
async function testWritableStreamClose() { async function testWritableStreamClose() {
const ws = new WritableStream({}, new ByteLengthQueuingStrategy(1024)); const ws = new WritableStream({}, new ByteLengthQueuingStrategy({ highWaterMark: 1024 }));
const writer = ws.getWriter(); const writer = ws.getWriter();
await writer.close(); await writer.close();
await writer.closed; await writer.closed;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment