blob: 0c3275090d63dc1826850ec9e79e9a6ef253a03e [file] [log] [blame]
// Copyright 2014 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/core/testing/dictionary_test.h"
#include "third_party/blink/renderer/bindings/core/v8/script_iterator.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/testing/internal_dictionary.h"
#include "third_party/blink/renderer/core/testing/internal_dictionary_derived.h"
#include "third_party/blink/renderer/core/testing/internal_dictionary_derived_derived.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
namespace blink {
namespace {
ScriptIterator GetIterator(const Dictionary& iterable,
ExecutionContext* execution_context) {
v8::Local<v8::Value> iterator_getter;
v8::Isolate* isolate = iterable.GetIsolate();
if (!iterable.Get(v8::Symbol::GetIterator(isolate), iterator_getter) ||
!iterator_getter->IsFunction()) {
return nullptr;
}
v8::Local<v8::Value> iterator;
if (!V8ScriptRunner::CallFunction(
v8::Local<v8::Function>::Cast(iterator_getter), execution_context,
iterable.V8Value(), 0, nullptr, isolate)
.ToLocal(&iterator))
return nullptr;
if (!iterator->IsObject())
return nullptr;
return ScriptIterator(v8::Local<v8::Object>::Cast(iterator), isolate);
}
} // namespace
DictionaryTest::DictionaryTest() : required_boolean_member_(false) {}
DictionaryTest::~DictionaryTest() = default;
void DictionaryTest::set(const InternalDictionary& testing_dictionary) {
Reset();
if (testing_dictionary.hasLongMember())
long_member_ = testing_dictionary.longMember();
if (testing_dictionary.hasLongMemberWithClamp())
long_member_with_clamp_ = testing_dictionary.longMemberWithClamp();
if (testing_dictionary.hasLongMemberWithEnforceRange())
long_member_with_enforce_range_ =
testing_dictionary.longMemberWithEnforceRange();
long_member_with_default_ = testing_dictionary.longMemberWithDefault();
if (testing_dictionary.hasLongOrNullMember())
long_or_null_member_ = testing_dictionary.longOrNullMember();
// |longOrNullMemberWithDefault| has a default value but can be null, so
// we need to check availability.
if (testing_dictionary.hasLongOrNullMemberWithDefault())
long_or_null_member_with_default_ =
testing_dictionary.longOrNullMemberWithDefault();
if (testing_dictionary.hasBooleanMember())
boolean_member_ = testing_dictionary.booleanMember();
if (testing_dictionary.hasDoubleMember())
double_member_ = testing_dictionary.doubleMember();
if (testing_dictionary.hasUnrestrictedDoubleMember())
unrestricted_double_member_ = testing_dictionary.unrestrictedDoubleMember();
string_member_ = testing_dictionary.stringMember();
string_member_with_default_ = testing_dictionary.stringMemberWithDefault();
byte_string_member_ = testing_dictionary.byteStringMember();
usv_string_member_ = testing_dictionary.usvStringMember();
if (testing_dictionary.hasStringSequenceMember())
string_sequence_member_ = testing_dictionary.stringSequenceMember();
string_sequence_member_with_default_ =
testing_dictionary.stringSequenceMemberWithDefault();
if (testing_dictionary.hasStringSequenceOrNullMember())
string_sequence_or_null_member_ =
testing_dictionary.stringSequenceOrNullMember();
enum_member_ = testing_dictionary.enumMember();
enum_member_with_default_ = testing_dictionary.enumMemberWithDefault();
enum_or_null_member_ = testing_dictionary.enumOrNullMember();
if (testing_dictionary.hasElementMember())
element_member_ = testing_dictionary.elementMember();
if (testing_dictionary.hasElementOrNullMember())
element_or_null_member_ = testing_dictionary.elementOrNullMember();
object_member_ = testing_dictionary.objectMember();
object_or_null_member_with_default_ =
testing_dictionary.objectOrNullMemberWithDefault();
if (testing_dictionary.hasDoubleOrStringMember())
double_or_string_member_ = testing_dictionary.doubleOrStringMember();
if (testing_dictionary.hasDoubleOrStringSequenceMember())
double_or_string_sequence_member_ =
testing_dictionary.doubleOrStringSequenceMember();
event_target_or_null_member_ = testing_dictionary.eventTargetOrNullMember();
if (testing_dictionary.hasDictionaryMember()) {
NonThrowableExceptionState exception_state;
dictionary_member_properties_ =
testing_dictionary.dictionaryMember().GetOwnPropertiesAsStringHashMap(
exception_state);
}
if (testing_dictionary.hasInternalEnumOrInternalEnumSequenceMember()) {
internal_enum_or_internal_enum_sequence_ =
testing_dictionary.internalEnumOrInternalEnumSequenceMember();
}
any_member_ = testing_dictionary.anyMember();
}
void DictionaryTest::get(InternalDictionary& result) {
if (long_member_)
result.setLongMember(long_member_.value());
if (long_member_with_clamp_)
result.setLongMemberWithClamp(long_member_with_clamp_.value());
if (long_member_with_enforce_range_) {
result.setLongMemberWithEnforceRange(
long_member_with_enforce_range_.value());
}
result.setLongMemberWithDefault(long_member_with_default_);
if (long_or_null_member_)
result.setLongOrNullMember(long_or_null_member_.value());
if (long_or_null_member_with_default_) {
result.setLongOrNullMemberWithDefault(
long_or_null_member_with_default_.value());
}
if (boolean_member_)
result.setBooleanMember(boolean_member_.value());
if (double_member_)
result.setDoubleMember(double_member_.value());
if (unrestricted_double_member_)
result.setUnrestrictedDoubleMember(unrestricted_double_member_.value());
result.setStringMember(string_member_);
result.setStringMemberWithDefault(string_member_with_default_);
result.setByteStringMember(byte_string_member_);
result.setUsvStringMember(usv_string_member_);
if (string_sequence_member_)
result.setStringSequenceMember(string_sequence_member_.value());
result.setStringSequenceMemberWithDefault(
string_sequence_member_with_default_);
if (string_sequence_or_null_member_) {
result.setStringSequenceOrNullMember(
string_sequence_or_null_member_.value());
}
result.setEnumMember(enum_member_);
result.setEnumMemberWithDefault(enum_member_with_default_);
result.setEnumOrNullMember(enum_or_null_member_);
if (element_member_)
result.setElementMember(element_member_);
if (element_or_null_member_.has_value())
result.setElementOrNullMember(element_or_null_member_.value());
result.setObjectMember(object_member_);
result.setObjectOrNullMemberWithDefault(object_or_null_member_with_default_);
if (!double_or_string_member_.IsNull())
result.setDoubleOrStringMember(double_or_string_member_);
if (double_or_string_sequence_member_) {
result.setDoubleOrStringSequenceMember(
double_or_string_sequence_member_.value());
}
result.setEventTargetOrNullMember(event_target_or_null_member_);
result.setInternalEnumOrInternalEnumSequenceMember(
internal_enum_or_internal_enum_sequence_);
result.setAnyMember(any_member_);
}
ScriptValue DictionaryTest::getDictionaryMemberProperties(
ScriptState* script_state) {
if (!dictionary_member_properties_)
return ScriptValue();
V8ObjectBuilder builder(script_state);
HashMap<String, String> properties = dictionary_member_properties_.value();
for (HashMap<String, String>::iterator it = properties.begin();
it != properties.end(); ++it)
builder.AddString(it->key, it->value);
return builder.GetScriptValue();
}
void DictionaryTest::setDerived(const InternalDictionaryDerived& derived) {
DCHECK(derived.hasRequiredBooleanMember());
set(derived);
if (derived.hasDerivedStringMember())
derived_string_member_ = derived.derivedStringMember();
derived_string_member_with_default_ =
derived.derivedStringMemberWithDefault();
required_boolean_member_ = derived.requiredBooleanMember();
}
void DictionaryTest::getDerived(InternalDictionaryDerived& result) {
get(result);
result.setDerivedStringMember(derived_string_member_);
result.setDerivedStringMemberWithDefault(derived_string_member_with_default_);
result.setRequiredBooleanMember(required_boolean_member_);
}
void DictionaryTest::setDerivedDerived(
const InternalDictionaryDerivedDerived& derived) {
setDerived(derived);
if (derived.hasDerivedDerivedStringMember())
derived_derived_string_member_ = derived.derivedDerivedStringMember();
}
void DictionaryTest::getDerivedDerived(
InternalDictionaryDerivedDerived& result) {
getDerived(result);
result.setDerivedDerivedStringMember(derived_derived_string_member_);
}
String DictionaryTest::stringFromIterable(
ScriptState* script_state,
Dictionary iterable,
ExceptionState& exception_state) const {
StringBuilder result;
ExecutionContext* execution_context = ExecutionContext::From(script_state);
ScriptIterator iterator = GetIterator(iterable, execution_context);
if (iterator.IsNull())
return g_empty_string;
bool first_loop = true;
while (iterator.Next(execution_context, exception_state)) {
if (exception_state.HadException())
return g_empty_string;
if (first_loop)
first_loop = false;
else
result.Append(',');
v8::Local<v8::Value> value;
if (iterator.GetValue().ToLocal(&value))
result.Append(ToCoreString(value->ToString()));
}
return result.ToString();
}
void DictionaryTest::Reset() {
long_member_ = base::nullopt;
long_member_with_clamp_ = base::nullopt;
long_member_with_enforce_range_ = base::nullopt;
long_member_with_default_ = -1; // This value should not be returned.
long_or_null_member_ = base::nullopt;
long_or_null_member_with_default_ = base::nullopt;
boolean_member_ = base::nullopt;
double_member_ = base::nullopt;
unrestricted_double_member_ = base::nullopt;
string_member_ = String();
string_member_with_default_ = String("Should not be returned");
string_sequence_member_ = base::nullopt;
string_sequence_member_with_default_.Fill("Should not be returned", 1);
string_sequence_or_null_member_ = base::nullopt;
enum_member_ = String();
enum_member_with_default_ = String();
enum_or_null_member_ = String();
element_member_ = nullptr;
element_or_null_member_.reset();
object_member_ = ScriptValue();
object_or_null_member_with_default_ = ScriptValue();
double_or_string_member_ = DoubleOrString();
event_target_or_null_member_ = nullptr;
derived_string_member_ = String();
derived_string_member_with_default_ = String();
required_boolean_member_ = false;
dictionary_member_properties_ = base::nullopt;
internal_enum_or_internal_enum_sequence_ =
InternalEnumOrInternalEnumSequence();
any_member_ = ScriptValue();
}
void DictionaryTest::Trace(blink::Visitor* visitor) {
visitor->Trace(element_member_);
visitor->Trace(element_or_null_member_);
visitor->Trace(double_or_string_sequence_member_);
visitor->Trace(event_target_or_null_member_);
ScriptWrappable::Trace(visitor);
}
} // namespace blink