| // Copyright 2021 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "third_party/blink/renderer/bindings/core/v8/to_v8_traits.h" |
| |
| #include "third_party/blink/renderer/bindings/core/v8/file_or_usv_string_or_form_data.h" |
| #include "third_party/blink/renderer/bindings/core/v8/v8_address_space.h" |
| #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" |
| #include "third_party/blink/renderer/bindings/core/v8/v8_create_html_callback.h" |
| #include "third_party/blink/renderer/bindings/core/v8/v8_dom_point_init.h" |
| #include "third_party/blink/renderer/bindings/core/v8/v8_event_listener.h" |
| #include "third_party/blink/renderer/core/dom/events/event_target.h" |
| #include "third_party/blink/renderer/core/streams/stream_promise_resolver.h" |
| #include "third_party/blink/renderer/core/testing/garbage_collected_script_wrappable.h" |
| #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" |
| #include "third_party/blink/renderer/platform/bindings/dictionary_base.h" |
| |
| namespace blink { |
| |
| namespace { |
| |
| #define TEST_TOV8_TRAITS(scope, IDLType, expected, value) \ |
| TestToV8Traits<IDLType>(scope, expected, value, __FILE__, __LINE__) |
| |
| template <typename IDLType, typename T> |
| void TestToV8Traits(const V8TestingScope& scope, |
| const String& expected, |
| T value, |
| const char* path, |
| int line_number) { |
| v8::Local<v8::Value> actual; |
| if (!ToV8Traits<IDLType>::ToV8(scope.GetScriptState(), value) |
| .ToLocal(&actual)) { |
| ADD_FAILURE_AT(path, line_number) << "ToV8 throws an exception."; |
| return; |
| } |
| String actual_string = |
| ToCoreString(actual->ToString(scope.GetContext()).ToLocalChecked()); |
| if (expected != actual_string) { |
| ADD_FAILURE_AT(path, line_number) |
| << "ToV8 returns an incorrect value.\n Actual: " |
| << actual_string.Utf8() << "\nExpected: " << expected; |
| return; |
| } |
| } |
| |
| TEST(ToV8TraitsTest, Any) { |
| const V8TestingScope scope; |
| ScriptValue value(scope.GetIsolate(), |
| v8::Number::New(scope.GetIsolate(), 1234.0)); |
| v8::Local<v8::Value> actual1; |
| ASSERT_TRUE(ToV8Traits<IDLAny>::ToV8(scope.GetScriptState(), value) |
| .ToLocal(&actual1)); |
| EXPECT_FALSE(actual1.IsEmpty()); |
| double actual_as_number1 = actual1.As<v8::Number>()->Value(); |
| EXPECT_EQ(1234.0, actual_as_number1); |
| } |
| |
| TEST(ToV8TraitsTest, Boolean) { |
| const V8TestingScope scope; |
| TEST_TOV8_TRAITS(scope, IDLBoolean, "true", true); |
| TEST_TOV8_TRAITS(scope, IDLBoolean, "false", false); |
| } |
| |
| TEST(ToV8TraitsTest, Integer) { |
| const V8TestingScope scope; |
| // Test type matching |
| // Integer |
| TEST_TOV8_TRAITS(scope, IDLByte, "0", static_cast<int8_t>(0)); |
| TEST_TOV8_TRAITS(scope, IDLByte, "1", static_cast<int8_t>(1)); |
| TEST_TOV8_TRAITS(scope, IDLByte, "-2", static_cast<int8_t>(-2)); |
| TEST_TOV8_TRAITS(scope, IDLShort, "0", static_cast<int16_t>(0)); |
| TEST_TOV8_TRAITS(scope, IDLLong, "0", static_cast<int32_t>(0)); |
| TEST_TOV8_TRAITS(scope, IDLLongLong, "0", static_cast<int64_t>(0)); |
| TEST_TOV8_TRAITS(scope, IDLOctet, "0", static_cast<uint8_t>(0)); |
| TEST_TOV8_TRAITS(scope, IDLUnsignedShort, "0", static_cast<uint16_t>(0)); |
| TEST_TOV8_TRAITS(scope, IDLUnsignedLong, "0", static_cast<uint32_t>(0)); |
| TEST_TOV8_TRAITS(scope, IDLUnsignedLongLong, "0", static_cast<uint64_t>(0)); |
| // [Clamp] Integer |
| TEST_TOV8_TRAITS(scope, IDLByteClamp, "0", static_cast<int8_t>(0)); |
| TEST_TOV8_TRAITS(scope, IDLShortClamp, "0", static_cast<int16_t>(0)); |
| TEST_TOV8_TRAITS(scope, IDLLongClamp, "0", static_cast<int32_t>(0)); |
| TEST_TOV8_TRAITS(scope, IDLLongLongClamp, "0", static_cast<int64_t>(0)); |
| TEST_TOV8_TRAITS(scope, IDLOctetClamp, "0", static_cast<uint8_t>(0)); |
| TEST_TOV8_TRAITS(scope, IDLUnsignedShortClamp, "0", static_cast<uint16_t>(0)); |
| TEST_TOV8_TRAITS(scope, IDLUnsignedLongClamp, "0", static_cast<uint32_t>(0)); |
| TEST_TOV8_TRAITS(scope, IDLUnsignedLongLongClamp, "0", |
| static_cast<uint64_t>(0)); |
| // [EnforceRange] Integer |
| TEST_TOV8_TRAITS(scope, IDLByteEnforceRange, "0", static_cast<int8_t>(0)); |
| TEST_TOV8_TRAITS(scope, IDLShortEnforceRange, "0", static_cast<int16_t>(0)); |
| TEST_TOV8_TRAITS(scope, IDLLongEnforceRange, "0", static_cast<int32_t>(0)); |
| TEST_TOV8_TRAITS(scope, IDLLongLongEnforceRange, "0", |
| static_cast<int64_t>(0)); |
| TEST_TOV8_TRAITS(scope, IDLOctetEnforceRange, "0", static_cast<uint8_t>(0)); |
| TEST_TOV8_TRAITS(scope, IDLUnsignedShortEnforceRange, "0", |
| static_cast<uint16_t>(0)); |
| TEST_TOV8_TRAITS(scope, IDLUnsignedLongEnforceRange, "0", |
| static_cast<uint32_t>(0)); |
| TEST_TOV8_TRAITS(scope, IDLUnsignedLongLongEnforceRange, "0", |
| static_cast<uint64_t>(0)); |
| |
| // Test the maximum and the minimum integer in the range |
| TEST_TOV8_TRAITS(scope, IDLLong, "-2147483648", |
| std::numeric_limits<int32_t>::min()); |
| TEST_TOV8_TRAITS(scope, IDLLong, "2147483647", |
| std::numeric_limits<int32_t>::max()); |
| TEST_TOV8_TRAITS(scope, IDLUnsignedLong, "4294967295", |
| std::numeric_limits<uint32_t>::max()); |
| |
| // v8::Number can represent exact numbers in [-(2^53-1), 2^53-1]. |
| TEST_TOV8_TRAITS(scope, IDLLongLong, "-9007199254740991", |
| static_cast<int64_t>(-9007199254740991)); // -(2^53-1) |
| TEST_TOV8_TRAITS(scope, IDLLongLong, "9007199254740991", |
| static_cast<int64_t>(9007199254740991)); // 2^53-1 |
| TEST_TOV8_TRAITS(scope, IDLUnsignedLongLong, "9007199254740991", |
| static_cast<uint64_t>(9007199254740991)); // 2^53-1 |
| } |
| |
| TEST(ToV8TraitsTest, FloatAndDouble) { |
| const V8TestingScope scope; |
| TEST_TOV8_TRAITS(scope, IDLFloat, "0.5", static_cast<float>(0.5)); |
| TEST_TOV8_TRAITS(scope, IDLUnrestrictedFloat, "-0.5", |
| static_cast<float>(-0.5)); |
| TEST_TOV8_TRAITS(scope, IDLDouble, "0.5", static_cast<double>(0.5)); |
| TEST_TOV8_TRAITS(scope, IDLUnrestrictedDouble, "-0.5", |
| static_cast<double>(-0.5)); |
| TEST_TOV8_TRAITS(scope, IDLUnrestrictedDouble, "NaN", |
| std::numeric_limits<double>::quiet_NaN()); |
| TEST_TOV8_TRAITS(scope, IDLUnrestrictedDouble, "Infinity", |
| std::numeric_limits<double>::infinity()); |
| TEST_TOV8_TRAITS(scope, IDLUnrestrictedDouble, "-Infinity", |
| -std::numeric_limits<double>::infinity()); |
| } |
| |
| TEST(ToV8TraitsTest, String) { |
| const V8TestingScope scope; |
| const String string("string"); |
| const char* const charptr_string = "charptrString"; |
| // ByteString |
| TEST_TOV8_TRAITS(scope, IDLByteStringV2, "string", string); |
| TEST_TOV8_TRAITS(scope, IDLByteStringV2, "charptrString", charptr_string); |
| // DOMString |
| TEST_TOV8_TRAITS(scope, IDLStringV2, "string", string); |
| TEST_TOV8_TRAITS(scope, IDLStringV2, "charptrString", charptr_string); |
| TEST_TOV8_TRAITS(scope, IDLStringTreatNullAsEmptyStringV2, "string", string); |
| TEST_TOV8_TRAITS(scope, IDLStringTreatNullAsEmptyStringV2, "charptrString", |
| charptr_string); |
| // USVString |
| TEST_TOV8_TRAITS(scope, IDLUSVStringV2, "string", string); |
| TEST_TOV8_TRAITS(scope, IDLUSVStringV2, "charptrString", charptr_string); |
| // [StringContext=TrustedHTML] DOMString |
| TEST_TOV8_TRAITS(scope, IDLStringStringContextTrustedHTMLV2, "string", |
| string); |
| TEST_TOV8_TRAITS(scope, IDLStringStringContextTrustedHTMLV2, "charptrString", |
| charptr_string); |
| TEST_TOV8_TRAITS(scope, |
| IDLStringStringContextTrustedHTMLTreatNullAsEmptyStringV2, |
| "string", string); |
| TEST_TOV8_TRAITS(scope, |
| IDLStringStringContextTrustedHTMLTreatNullAsEmptyStringV2, |
| "charptrString", charptr_string); |
| // [StringContext=TrustedScript] DOMString |
| TEST_TOV8_TRAITS(scope, IDLStringStringContextTrustedScriptV2, "string", |
| string); |
| TEST_TOV8_TRAITS(scope, IDLStringStringContextTrustedScriptV2, |
| "charptrString", charptr_string); |
| TEST_TOV8_TRAITS(scope, |
| IDLStringStringContextTrustedScriptTreatNullAsEmptyStringV2, |
| "string", string); |
| TEST_TOV8_TRAITS(scope, |
| IDLStringStringContextTrustedScriptTreatNullAsEmptyStringV2, |
| "charptrString", charptr_string); |
| // [StringContext=TrustedScriptURL] USVString |
| TEST_TOV8_TRAITS(scope, IDLUSVStringStringContextTrustedScriptURLV2, "string", |
| string); |
| TEST_TOV8_TRAITS(scope, IDLUSVStringStringContextTrustedScriptURLV2, |
| "charptrString", charptr_string); |
| } |
| |
| TEST(ToV8TraitsTest, EmptyString) { |
| const V8TestingScope scope; |
| const String empty_string(""); |
| TEST_TOV8_TRAITS(scope, IDLStringV2, "", empty_string); |
| const char* const empty = ""; |
| TEST_TOV8_TRAITS(scope, IDLStringV2, "", empty); |
| } |
| |
| TEST(ToV8TraitsTest, Object) { |
| const V8TestingScope scope; |
| Vector<String> string_vector; |
| string_vector.push_back("hello"); |
| string_vector.push_back("world"); |
| ScriptValue value(scope.GetIsolate(), |
| ToV8Traits<IDLSequence<IDLStringV2>>::ToV8( |
| scope.GetScriptState(), string_vector)); |
| TEST_TOV8_TRAITS(scope, IDLObject, "hello,world", value); |
| v8::Local<v8::Value> actual; |
| ASSERT_TRUE(ToV8Traits<IDLObject>::ToV8(scope.GetScriptState(), value) |
| .ToLocal(&actual)); |
| EXPECT_TRUE(actual->IsObject()); |
| } |
| |
| TEST(ToV8TraitsTest, Promise) { |
| const V8TestingScope scope; |
| ScriptPromise::InternalResolver resolver(scope.GetScriptState()); |
| ScriptPromise promise = resolver.Promise(); |
| TEST_TOV8_TRAITS(scope, IDLPromise, "[object Promise]", promise); |
| } |
| |
| TEST(ToV8TraitsTest, NotShared) { |
| const V8TestingScope scope; |
| auto not_shared = NotShared<DOMUint8Array>(DOMUint8Array::Create(2)); |
| not_shared->Data()[0] = static_cast<uint8_t>(0); |
| not_shared->Data()[1] = static_cast<uint8_t>(255); |
| TEST_TOV8_TRAITS(scope, NotShared<DOMUint8Array>, "0,255", not_shared); |
| } |
| |
| TEST(ToV8TraitsTest, MaybeShared) { |
| const V8TestingScope scope; |
| auto maybe_shared = MaybeShared<DOMInt8Array>(DOMInt8Array::Create(3)); |
| maybe_shared->Data()[0] = static_cast<int8_t>(-128); |
| maybe_shared->Data()[1] = static_cast<int8_t>(0); |
| maybe_shared->Data()[2] = static_cast<int8_t>(127); |
| TEST_TOV8_TRAITS(scope, MaybeShared<DOMInt8Array>, "-128,0,127", |
| maybe_shared); |
| } |
| |
| TEST(ToV8TraitsTest, Vector) { |
| const V8TestingScope scope; |
| Vector<String> string_vector; |
| string_vector.push_back("foo"); |
| string_vector.push_back("bar"); |
| TEST_TOV8_TRAITS(scope, IDLSequence<IDLStringV2>, "foo,bar", string_vector); |
| } |
| |
| TEST(ToV8TraitsTest, HeapVector) { |
| const V8TestingScope scope; |
| HeapVector<Member<GarbageCollectedScriptWrappable>> heap_vector; |
| heap_vector.push_back( |
| MakeGarbageCollected<GarbageCollectedScriptWrappable>("hoge")); |
| heap_vector.push_back( |
| MakeGarbageCollected<GarbageCollectedScriptWrappable>("fuga")); |
| TEST_TOV8_TRAITS(scope, IDLSequence<GarbageCollectedScriptWrappable>, |
| "hoge,fuga", heap_vector); |
| |
| HeapVector<Member<GarbageCollectedScriptWrappable>>* |
| garbage_collected_heap_vector = &heap_vector; |
| TEST_TOV8_TRAITS(scope, IDLSequence<GarbageCollectedScriptWrappable>, |
| "hoge,fuga", garbage_collected_heap_vector); |
| } |
| |
| TEST(ToV8TraitsTest, BasicIDLTypeVectors) { |
| const V8TestingScope scope; |
| |
| Vector<int32_t> int32_vector; |
| int32_vector.push_back(42); |
| int32_vector.push_back(23); |
| TEST_TOV8_TRAITS(scope, IDLSequence<IDLLong>, "42,23", int32_vector); |
| |
| Vector<int64_t> int64_vector; |
| int64_vector.push_back(31773); |
| int64_vector.push_back(404); |
| TEST_TOV8_TRAITS(scope, IDLSequence<IDLLongLong>, "31773,404", int64_vector); |
| |
| Vector<uint32_t> uint32_vector; |
| uint32_vector.push_back(1); |
| uint32_vector.push_back(2); |
| TEST_TOV8_TRAITS(scope, IDLSequence<IDLUnsignedLong>, "1,2", uint32_vector); |
| |
| Vector<uint64_t> uint64_vector; |
| uint64_vector.push_back(1001); |
| uint64_vector.push_back(2002); |
| TEST_TOV8_TRAITS(scope, IDLSequence<IDLUnsignedLongLong>, "1001,2002", |
| uint64_vector); |
| |
| Vector<float> float_vector; |
| float_vector.push_back(0.125); |
| float_vector.push_back(1.); |
| TEST_TOV8_TRAITS(scope, IDLSequence<IDLFloat>, "0.125,1", float_vector); |
| |
| Vector<double> double_vector; |
| double_vector.push_back(2.3); |
| double_vector.push_back(4.2); |
| TEST_TOV8_TRAITS(scope, IDLSequence<IDLDouble>, "2.3,4.2", double_vector); |
| |
| Vector<bool> bool_vector; |
| bool_vector.push_back(true); |
| bool_vector.push_back(true); |
| bool_vector.push_back(false); |
| TEST_TOV8_TRAITS(scope, IDLSequence<IDLBoolean>, "true,true,false", |
| bool_vector); |
| } |
| |
| TEST(ToV8TraitsTest, StringVectorVector) { |
| const V8TestingScope scope; |
| |
| Vector<String> string_vector1; |
| string_vector1.push_back("foo"); |
| string_vector1.push_back("bar"); |
| Vector<String> string_vector2; |
| string_vector2.push_back("quux"); |
| |
| Vector<Vector<String>> compound_vector; |
| compound_vector.push_back(string_vector1); |
| compound_vector.push_back(string_vector2); |
| |
| EXPECT_EQ(2U, compound_vector.size()); |
| TEST_TOV8_TRAITS(scope, IDLSequence<IDLSequence<IDLStringV2>>, "foo,bar,quux", |
| compound_vector); |
| |
| v8::Local<v8::Value> actual; |
| ASSERT_TRUE(ToV8Traits<IDLSequence<IDLSequence<IDLStringV2>>>::ToV8( |
| scope.GetScriptState(), compound_vector) |
| .ToLocal(&actual)) |
| << "ToV8 throws an exception."; |
| v8::Local<v8::Object> result = |
| actual->ToObject(scope.GetContext()).ToLocalChecked(); |
| v8::Local<v8::Value> vector1 = |
| result->Get(scope.GetContext(), 0).ToLocalChecked(); |
| EXPECT_TRUE(vector1->IsArray()); |
| EXPECT_EQ(2U, vector1.As<v8::Array>()->Length()); |
| v8::Local<v8::Value> vector2 = |
| result->Get(scope.GetContext(), 1).ToLocalChecked(); |
| EXPECT_TRUE(vector2->IsArray()); |
| EXPECT_EQ(1U, vector2.As<v8::Array>()->Length()); |
| } |
| |
| TEST(ToV8TraitsTest, PairVector) { |
| const V8TestingScope scope; |
| Vector<std::pair<String, int8_t>> pair_vector; |
| pair_vector.push_back(std::make_pair("one", 1)); |
| pair_vector.push_back(std::make_pair("two", 2)); |
| using ByteRecord = IDLRecord<IDLStringV2, IDLByte>; |
| TEST_TOV8_TRAITS(scope, ByteRecord, "[object Object]", pair_vector); |
| v8::Local<v8::Value> actual; |
| ASSERT_TRUE(ToV8Traits<ByteRecord>::ToV8(scope.GetScriptState(), pair_vector) |
| .ToLocal(&actual)) |
| << "ToV8 throws an exception."; |
| v8::Local<v8::Object> result = |
| actual->ToObject(scope.GetContext()).ToLocalChecked(); |
| v8::Local<v8::Value> one = |
| result->Get(scope.GetContext(), V8String(scope.GetIsolate(), "one")) |
| .ToLocalChecked(); |
| EXPECT_EQ(1, one->NumberValue(scope.GetContext()).FromJust()); |
| v8::Local<v8::Value> two = |
| result->Get(scope.GetContext(), V8String(scope.GetIsolate(), "two")) |
| .ToLocalChecked(); |
| EXPECT_EQ(2, two->NumberValue(scope.GetContext()).FromJust()); |
| } |
| |
| TEST(ToV8TraitsTest, PairHeapVector) { |
| const V8TestingScope scope; |
| HeapVector<std::pair<String, Member<GarbageCollectedScriptWrappable>>> |
| pair_heap_vector; |
| pair_heap_vector.push_back(std::make_pair( |
| "one", MakeGarbageCollected<GarbageCollectedScriptWrappable>("foo"))); |
| pair_heap_vector.push_back(std::make_pair( |
| "two", MakeGarbageCollected<GarbageCollectedScriptWrappable>("bar"))); |
| using HeapRecord = IDLRecord<IDLStringV2, GarbageCollectedScriptWrappable>; |
| TEST_TOV8_TRAITS(scope, HeapRecord, "[object Object]", pair_heap_vector); |
| v8::Local<v8::Value> actual; |
| ASSERT_TRUE( |
| ToV8Traits<HeapRecord>::ToV8(scope.GetScriptState(), pair_heap_vector) |
| .ToLocal(&actual)) |
| << "ToV8 throws an exception."; |
| v8::Local<v8::Object> result = |
| actual->ToObject(scope.GetContext()).ToLocalChecked(); |
| v8::Local<v8::Value> one = |
| result->Get(scope.GetContext(), V8String(scope.GetIsolate(), "one")) |
| .ToLocalChecked(); |
| EXPECT_TRUE(one->IsObject()); |
| EXPECT_EQ(String("foo"), |
| ToCoreString(one->ToString(scope.GetContext()).ToLocalChecked())); |
| v8::Local<v8::Value> two = |
| result->Get(scope.GetContext(), V8String(scope.GetIsolate(), "two")) |
| .ToLocalChecked(); |
| EXPECT_TRUE(two->IsObject()); |
| EXPECT_EQ(String("bar"), |
| ToCoreString(two->ToString(scope.GetContext()).ToLocalChecked())); |
| |
| HeapVector<std::pair<String, Member<GarbageCollectedScriptWrappable>>>* |
| garbage_collected_pair_heap_vector = &pair_heap_vector; |
| TEST_TOV8_TRAITS(scope, HeapRecord, "[object Object]", |
| garbage_collected_pair_heap_vector); |
| } |
| |
| TEST(ToV8TraitsTest, NullStringInputForNoneNullableType) { |
| const V8TestingScope scope; |
| const String null_string; |
| TEST_TOV8_TRAITS(scope, IDLStringV2, "", null_string); |
| const char* const null = nullptr; |
| TEST_TOV8_TRAITS(scope, IDLStringV2, "", null); |
| } |
| |
| TEST(ToV8TraitsTest, Nullable) { |
| const V8TestingScope scope; |
| // Nullable Boolean |
| TEST_TOV8_TRAITS(scope, IDLNullable<IDLBoolean>, "null", base::nullopt); |
| TEST_TOV8_TRAITS(scope, IDLNullable<IDLBoolean>, "true", true); |
| // Nullable Integer |
| TEST_TOV8_TRAITS(scope, IDLNullable<IDLByte>, "null", base::nullopt); |
| TEST_TOV8_TRAITS(scope, IDLNullable<IDLUnsignedLong>, "0", |
| base::Optional<uint32_t>(0)); |
| // Nullable Float |
| TEST_TOV8_TRAITS(scope, IDLNullable<IDLFloat>, "null", base::nullopt); |
| TEST_TOV8_TRAITS(scope, IDLNullable<IDLFloat>, "0.5", |
| base::Optional<float>(0.5)); |
| // Nullable Double |
| TEST_TOV8_TRAITS(scope, IDLNullable<IDLDouble>, "null", base::nullopt); |
| TEST_TOV8_TRAITS(scope, IDLNullable<IDLDouble>, "3.14", |
| base::Optional<double>(3.14)); |
| } |
| |
| TEST(ToV8TraitsTest, NullableString) { |
| const V8TestingScope scope; |
| TEST_TOV8_TRAITS(scope, IDLNullable<IDLStringV2>, "null", String()); |
| TEST_TOV8_TRAITS(scope, IDLNullable<IDLStringV2>, "string", String("string")); |
| TEST_TOV8_TRAITS(scope, IDLNullable<IDLStringV2>, "", String("")); |
| const char* const null = nullptr; |
| TEST_TOV8_TRAITS(scope, IDLNullable<IDLStringV2>, "null", null); |
| const char* const charptr_string = "charptrString"; |
| TEST_TOV8_TRAITS(scope, IDLNullable<IDLStringV2>, "charptrString", |
| charptr_string); |
| const char* const charptr_empty_string = ""; |
| TEST_TOV8_TRAITS(scope, IDLNullable<IDLStringV2>, "", charptr_empty_string); |
| } |
| |
| TEST(ToV8TraitsTest, NullableScriptWrappable) { |
| const V8TestingScope scope; |
| TEST_TOV8_TRAITS(scope, IDLNullable<EventTarget>, "null", nullptr); |
| EventTarget* event_target = EventTarget::Create(scope.GetScriptState()); |
| TEST_TOV8_TRAITS(scope, IDLNullable<EventTarget>, "[object EventTarget]", |
| event_target); |
| } |
| |
| TEST(ToV8TraitsTest, NullableDictionary) { |
| const V8TestingScope scope; |
| // bindings::DictionaryBase |
| TEST_TOV8_TRAITS(scope, IDLNullable<bindings::DictionaryBase>, "null", |
| nullptr); |
| // IDLDictionaryBase |
| DOMPointInit* dom_point_init = DOMPointInit::Create(); |
| TEST_TOV8_TRAITS(scope, IDLNullable<DOMPointInit>, "null", nullptr); |
| TEST_TOV8_TRAITS(scope, IDLNullable<DOMPointInit>, "[object Object]", |
| dom_point_init); |
| } |
| |
| TEST(ToV8TraitsTest, NullableCallbackFunction) { |
| const V8TestingScope scope; |
| TEST_TOV8_TRAITS(scope, IDLNullable<V8CreateHTMLCallback>, "null", nullptr); |
| V8CreateHTMLCallback* v8_create_html_callback = |
| V8CreateHTMLCallback::Create(scope.GetContext()->Global()); |
| TEST_TOV8_TRAITS(scope, IDLNullable<V8CreateHTMLCallback>, "[object Window]", |
| v8_create_html_callback); |
| } |
| |
| TEST(ToV8TraitsTest, NullableCallbackInterface) { |
| const V8TestingScope scope; |
| TEST_TOV8_TRAITS(scope, IDLNullable<V8CreateHTMLCallback>, "null", nullptr); |
| V8EventListener* v8_event_listener = |
| V8EventListener::Create(scope.GetContext()->Global()); |
| TEST_TOV8_TRAITS(scope, IDLNullable<V8EventListener>, "[object Window]", |
| v8_event_listener); |
| } |
| |
| TEST(ToV8TraitsTest, NullableEnumeration) { |
| const V8TestingScope scope; |
| TEST_TOV8_TRAITS(scope, IDLNullable<V8AddressSpace>, "null", base::nullopt); |
| const base::Optional<V8AddressSpace> v8_address_space = |
| V8AddressSpace::Create("public"); |
| TEST_TOV8_TRAITS(scope, IDLNullable<V8AddressSpace>, "public", |
| v8_address_space); |
| } |
| |
| TEST(ToV8TraitsTest, NullableDate) { |
| const V8TestingScope scope; |
| TEST_TOV8_TRAITS(scope, IDLNullable<IDLDate>, "null", base::nullopt); |
| |
| base::Time expected_date; |
| EXPECT_TRUE( |
| base::Time::FromString("Fri, 01 Jan 2021 00:00:00 GMT", &expected_date)); |
| v8::Local<v8::Value> result; |
| ASSERT_TRUE( |
| ToV8Traits<IDLNullable<IDLDate>>::ToV8( |
| scope.GetScriptState(), base::Optional<base::Time>(expected_date)) |
| .ToLocal(&result)); |
| String actual_string = |
| ToCoreString(result->ToString(scope.GetContext()).ToLocalChecked()); |
| base::Time actual_date; |
| EXPECT_TRUE( |
| base::Time::FromString(actual_string.Ascii().c_str(), &actual_date)); |
| EXPECT_EQ(expected_date, actual_date); |
| } |
| |
| TEST(ToV8TraitsTest, Union) { |
| const V8TestingScope scope; |
| const FileOrUSVStringOrFormData usv_string = |
| FileOrUSVStringOrFormData::FromUSVString("https://example.com/"); |
| TEST_TOV8_TRAITS(scope, IDLUnionNotINT<FileOrUSVStringOrFormData>, |
| "https://example.com/", usv_string); |
| } |
| |
| TEST(ToV8TraitsTest, Optional) { |
| const V8TestingScope scope; |
| TEST_TOV8_TRAITS(scope, IDLOptional<DOMPointInit>, "undefined", nullptr); |
| DOMPointInit* dom_point_init = DOMPointInit::Create(); |
| TEST_TOV8_TRAITS(scope, IDLOptional<DOMPointInit>, "[object Object]", |
| dom_point_init); |
| |
| TEST_TOV8_TRAITS(scope, IDLOptional<IDLAny>, "undefined", ScriptValue()); |
| ScriptValue value(scope.GetIsolate(), |
| v8::Number::New(scope.GetIsolate(), 3.14)); |
| TEST_TOV8_TRAITS(scope, IDLOptional<IDLAny>, "3.14", value); |
| } |
| |
| } // namespace |
| |
| } // namespace blink |