v8/test/cctest/test-intl.cc
Sathya Gunasekaran 294dbf49bc [intl] Add GetOption
This patch ports over the spec defined operation `GetOption` from
JavaScript to C++:
https://tc39.github.io/ecma402/#sec-getoption

The JS implementation will be deleted once all it's
users are migrated.

Refactors LocaleConstructor to use this method which fixes some test262
tests. The test262 test status file is updated to reflect this.

Bug: v8:5751, v8:7684
Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng
Change-Id: Ief5eae9b69dcea50062825163ca7658ed20bd0cf
Reviewed-on: https://chromium-review.googlesource.com/1094201
Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53652}
2018-06-11 22:19:22 +00:00

198 lines
7.5 KiB
C++

// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifdef V8_INTL_SUPPORT
#include "src/builtins/builtins-intl.h"
#include "src/lookup.h"
#include "src/objects-inl.h"
#include "test/cctest/cctest.h"
namespace v8 {
namespace internal {
// This operator overloading enables CHECK_EQ to be used with
// std::vector<NumberFormatSpan>
bool operator==(const NumberFormatSpan& lhs, const NumberFormatSpan& rhs) {
return memcmp(&lhs, &rhs, sizeof(lhs)) == 0;
}
template <typename _CharT, typename _Traits, typename T>
std::basic_ostream<_CharT, _Traits>& operator<<(
std::basic_ostream<_CharT, _Traits>& self, const std::vector<T>& v) {
self << "[";
for (auto it = v.begin(); it < v.end();) {
self << *it;
it++;
if (it < v.end()) self << ", ";
}
return self << "]";
}
template <typename _CharT, typename _Traits>
std::basic_ostream<_CharT, _Traits>& operator<<(
std::basic_ostream<_CharT, _Traits>& self, const NumberFormatSpan& part) {
return self << "{" << part.field_id << "," << part.begin_pos << ","
<< part.end_pos << "}";
}
void test_flatten_regions_to_parts(
const std::vector<NumberFormatSpan>& regions,
const std::vector<NumberFormatSpan>& expected_parts) {
std::vector<NumberFormatSpan> mutable_regions = regions;
std::vector<NumberFormatSpan> parts = FlattenRegionsToParts(&mutable_regions);
CHECK_EQ(expected_parts, parts);
}
TEST(FlattenRegionsToParts) {
test_flatten_regions_to_parts(
std::vector<NumberFormatSpan>{
NumberFormatSpan(-1, 0, 10), NumberFormatSpan(1, 2, 8),
NumberFormatSpan(2, 2, 4), NumberFormatSpan(3, 6, 8),
},
std::vector<NumberFormatSpan>{
NumberFormatSpan(-1, 0, 2), NumberFormatSpan(2, 2, 4),
NumberFormatSpan(1, 4, 6), NumberFormatSpan(3, 6, 8),
NumberFormatSpan(-1, 8, 10),
});
test_flatten_regions_to_parts(
std::vector<NumberFormatSpan>{
NumberFormatSpan(0, 0, 1),
},
std::vector<NumberFormatSpan>{
NumberFormatSpan(0, 0, 1),
});
test_flatten_regions_to_parts(
std::vector<NumberFormatSpan>{
NumberFormatSpan(-1, 0, 1), NumberFormatSpan(0, 0, 1),
},
std::vector<NumberFormatSpan>{
NumberFormatSpan(0, 0, 1),
});
test_flatten_regions_to_parts(
std::vector<NumberFormatSpan>{
NumberFormatSpan(0, 0, 1), NumberFormatSpan(-1, 0, 1),
},
std::vector<NumberFormatSpan>{
NumberFormatSpan(0, 0, 1),
});
test_flatten_regions_to_parts(
std::vector<NumberFormatSpan>{
NumberFormatSpan(-1, 0, 10), NumberFormatSpan(1, 0, 1),
NumberFormatSpan(2, 0, 2), NumberFormatSpan(3, 0, 3),
NumberFormatSpan(4, 0, 4), NumberFormatSpan(5, 0, 5),
NumberFormatSpan(15, 5, 10), NumberFormatSpan(16, 6, 10),
NumberFormatSpan(17, 7, 10), NumberFormatSpan(18, 8, 10),
NumberFormatSpan(19, 9, 10),
},
std::vector<NumberFormatSpan>{
NumberFormatSpan(1, 0, 1), NumberFormatSpan(2, 1, 2),
NumberFormatSpan(3, 2, 3), NumberFormatSpan(4, 3, 4),
NumberFormatSpan(5, 4, 5), NumberFormatSpan(15, 5, 6),
NumberFormatSpan(16, 6, 7), NumberFormatSpan(17, 7, 8),
NumberFormatSpan(18, 8, 9), NumberFormatSpan(19, 9, 10),
});
// : 4
// : 22 33 3
// : 11111 22
// input regions: 0000000 111
// : ------------
// output parts: 0221340--231
test_flatten_regions_to_parts(
std::vector<NumberFormatSpan>{
NumberFormatSpan(-1, 0, 12), NumberFormatSpan(0, 0, 7),
NumberFormatSpan(1, 9, 12), NumberFormatSpan(1, 1, 6),
NumberFormatSpan(2, 9, 11), NumberFormatSpan(2, 1, 3),
NumberFormatSpan(3, 10, 11), NumberFormatSpan(3, 4, 6),
NumberFormatSpan(4, 5, 6),
},
std::vector<NumberFormatSpan>{
NumberFormatSpan(0, 0, 1), NumberFormatSpan(2, 1, 3),
NumberFormatSpan(1, 3, 4), NumberFormatSpan(3, 4, 5),
NumberFormatSpan(4, 5, 6), NumberFormatSpan(0, 6, 7),
NumberFormatSpan(-1, 7, 9), NumberFormatSpan(2, 9, 10),
NumberFormatSpan(3, 10, 11), NumberFormatSpan(1, 11, 12),
});
}
TEST(GetOptions) {
LocalContext env;
Isolate* isolate = CcTest::i_isolate();
v8::Isolate* v8_isolate = env->GetIsolate();
v8::HandleScope handle_scope(v8_isolate);
Handle<JSObject> options = isolate->factory()->NewJSObjectWithNullProto();
Handle<String> key = isolate->factory()->NewStringFromAsciiChecked("foo");
Handle<String> service =
isolate->factory()->NewStringFromAsciiChecked("service");
Handle<Object> undefined = isolate->factory()->undefined_value();
Handle<FixedArray> empty_fixed_array =
isolate->factory()->empty_fixed_array();
// No value found
Handle<Object> result =
Object::GetOption(isolate, options, key, Object::OptionType::String,
empty_fixed_array, undefined, service)
.ToHandleChecked();
CHECK(result->IsUndefined(isolate));
// Value found
v8::internal::LookupIterator it(options, key);
CHECK(Object::SetProperty(&it, Handle<Smi>(Smi::FromInt(42), isolate),
LanguageMode::kStrict,
AllocationMemento::MAY_BE_STORE_FROM_KEYED)
.FromJust());
result = Object::GetOption(isolate, options, key, Object::OptionType::String,
empty_fixed_array, undefined, service)
.ToHandleChecked();
CHECK(result->IsString());
Handle<String> expected_str =
isolate->factory()->NewStringFromAsciiChecked("42");
CHECK(String::Equals(expected_str, Handle<String>::cast(result)));
result = Object::GetOption(isolate, options, key, Object::OptionType::Boolean,
empty_fixed_array, undefined, service)
.ToHandleChecked();
CHECK(result->IsBoolean());
CHECK(result->IsTrue(isolate));
// No expected value in values array
Handle<FixedArray> values = isolate->factory()->NewFixedArray(1);
{
CHECK(!Object::GetOption(isolate, options, key, Object::OptionType::String,
values, undefined, service)
.ToHandle(&result));
CHECK(isolate->has_pending_exception());
isolate->clear_pending_exception();
}
// Add expected value to values array
values->set(0, *expected_str);
result = Object::GetOption(isolate, options, key, Object::OptionType::String,
values, undefined, service)
.ToHandleChecked();
CHECK(result->IsString());
CHECK(String::Equals(expected_str, Handle<String>::cast(result)));
// Test boolean values
CHECK(Object::SetProperty(&it, isolate->factory()->ToBoolean(false),
LanguageMode::kStrict,
AllocationMemento::MAY_BE_STORE_FROM_KEYED)
.FromJust());
result = Object::GetOption(isolate, options, key, Object::OptionType::String,
empty_fixed_array, undefined, service)
.ToHandleChecked();
CHECK(result->IsString());
result = Object::GetOption(isolate, options, key, Object::OptionType::Boolean,
empty_fixed_array, undefined, service)
.ToHandleChecked();
CHECK(result->IsBoolean());
CHECK(result->IsFalse(isolate));
}
} // namespace internal
} // namespace v8
#endif // V8_INTL_SUPPORT