Index: test/cctest/test-api.cc |
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc |
index 283bcb8e0d66d869a7faf3751d761b5a3fb5a3c3..a2bb79a5b40617a84890ab3b7a5b87b33257b534 100644 |
--- a/test/cctest/test-api.cc |
+++ b/test/cctest/test-api.cc |
@@ -2021,6 +2021,22 @@ void SymbolAccessorSetter(Local<Name> name, Local<Value> value, |
SimpleAccessorSetter(Local<String>::Cast(sym->Name()), value, info); |
} |
+void SymbolAccessorGetterReturnsDefault(Local<Name> name, |
+ const v8::PropertyCallbackInfo<v8::Value>& info) { |
+ CHECK(name->IsSymbol()); |
+ Local<Symbol> sym = Local<Symbol>::Cast(name); |
+ if (sym->Name()->IsUndefined()) |
+ return; |
+ info.GetReturnValue().Set(info.Data()); |
+} |
+ |
+static void ThrowingSymbolAccessorGetter( |
+ Local<Name> name, |
+ const v8::PropertyCallbackInfo<v8::Value>& info) { |
+ ApiTestFuzzer::Fuzz(); |
Dmitry Lomov (no reviews)
2014/10/18 21:24:19
Why this line?
|
+ info.GetReturnValue().Set(info.GetIsolate()->ThrowException(name)); |
+} |
+ |
void EmptyInterceptorGetter(Local<String> name, |
const v8::PropertyCallbackInfo<v8::Value>& info) { |
} |
@@ -13489,6 +13505,52 @@ THREADED_TEST(ObjectProtoToString) { |
Local<Value> object = v8_compile("new Object()")->Run(); |
value = object.As<v8::Object>()->ObjectProtoToString(); |
CHECK(value->IsString() && value->Equals(v8_str("[object Object]"))); |
+ |
+ // Check that ES6 semantics using @@toStringTag work |
+ i::FLAG_harmony_tostring = true; |
+ Local<v8::Symbol> toStringTag = v8::Symbol::GetToStringTag(isolate); |
+ |
+#define TEST_TOSTRINGTAG(type, tag, expected) \ |
+ do { \ |
+ object = v8_compile("new " #type "()")->Run(); \ |
Dmitry Lomov (no reviews)
2014/10/18 21:24:19
Nit: use CompileRun here
|
+ object.As<v8::Object>()->Set(toStringTag, v8_str(#tag)); \ |
+ value = object.As<v8::Object>()->ObjectProtoToString(); \ |
+ CHECK(value->IsString() && value->Equals( \ |
+ v8_str("[object " #expected "]"))); \ |
+ } while (0) |
+ |
+ TEST_TOSTRINGTAG(Array, Object, Object); |
+ TEST_TOSTRINGTAG(Object, Arguments, ~Arguments); |
+ TEST_TOSTRINGTAG(Object, Array, ~Array); |
+ TEST_TOSTRINGTAG(Object, Boolean, ~Boolean); |
+ TEST_TOSTRINGTAG(Object, Date, ~Date); |
+ TEST_TOSTRINGTAG(Object, Error, ~Error); |
+ TEST_TOSTRINGTAG(Object, Function, ~Function); |
+ TEST_TOSTRINGTAG(Object, Number, ~Number); |
+ TEST_TOSTRINGTAG(Object, RegExp, ~RegExp); |
+ TEST_TOSTRINGTAG(Object, String, ~String); |
+ TEST_TOSTRINGTAG(Object, Foo, Foo); |
+ |
+#undef TEST_TOSTRINGTAG |
+ |
+ // @@toStringTag getter throws |
+ Local<v8::Object> obj = v8::Object::New(isolate); |
Dmitry Lomov (no reviews)
2014/10/18 21:24:19
Great test, add one more where the getter is actua
caitp (gmail)
2014/10/18 21:27:40
There's a problem with that --- the bootstrapper d
caitp (gmail)
2014/10/18 21:35:01
Er, I mean `Symbol.toStringTag` is not exposed ---
Dmitry Lomov (no reviews)
2014/10/18 21:45:00
Ah, I see. Extract the tests for toStringTag into
|
+ obj->SetAccessor(toStringTag, ThrowingSymbolAccessorGetter); |
+ { TryCatch try_catch; |
+ value = obj->ObjectProtoToString(); |
+ CHECK(value.IsEmpty()); |
+ CHECK(try_catch.HasCaught()); |
+ } |
+ |
+ // @@toStringTag getter does not throw |
+ obj = v8::Object::New(isolate); |
+ obj->SetAccessor(toStringTag, SymbolAccessorGetterReturnsDefault, |
+ 0, v8_str("Test")); |
+ { TryCatch try_catch; |
+ value = obj->ObjectProtoToString(); |
+ CHECK(value->IsString() && value->Equals(v8_str("[object Test]"))); |
+ CHECK(!try_catch.HasCaught()); |
+ } |
} |