diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/bindings/core/v8/to_v8_traits_test.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/bindings/core/v8/to_v8_traits_test.cc | 520 |
1 files changed, 520 insertions, 0 deletions
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_traits_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_traits_test.cc new file mode 100644 index 00000000000..f30f06a51df --- /dev/null +++ b/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_traits_test.cc @@ -0,0 +1,520 @@ +// 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 |