| Index: test/cctest/test-api.cc
|
| diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
|
| index ea9e6e122a24e811ea71874e1fb138c3b03a714e..54dc656f8bebb95938d4d30824b4b7d12c2a9b8d 100644
|
| --- a/test/cctest/test-api.cc
|
| +++ b/test/cctest/test-api.cc
|
| @@ -76,6 +76,11 @@ static void ExpectBoolean(const char* code, bool expected) {
|
| }
|
|
|
|
|
| +static void ExpectTrue(const char* code) {
|
| + ExpectBoolean(code, true);
|
| +}
|
| +
|
| +
|
| static void ExpectObject(const char* code, Local<Value> expected) {
|
| Local<Value> result = CompileRun(code);
|
| CHECK(result->Equals(expected));
|
| @@ -2506,7 +2511,7 @@ THREADED_TEST(DefinePropertyOnAPIAccessor) {
|
|
|
| // Uses getOwnPropertyDescriptor to check the configurable status
|
| Local<Script> script_desc
|
| - = Script::Compile(v8_str("var prop =Object.getOwnPropertyDescriptor( "
|
| + = Script::Compile(v8_str("var prop = Object.getOwnPropertyDescriptor( "
|
| "obj, 'x');"
|
| "prop.configurable;"));
|
| Local<Value> result = script_desc->Run();
|
| @@ -2592,7 +2597,166 @@ THREADED_TEST(DefinePropertyOnDefineGetterSetter) {
|
| }
|
|
|
|
|
| +static v8::Handle<v8::Object> GetGlobalProperty(LocalContext* context,
|
| + char const* name) {
|
| + return v8::Handle<v8::Object>::Cast((*context)->Global()->Get(v8_str(name)));
|
| +}
|
| +
|
| +
|
| +THREADED_TEST(DefineAPIAccessorOnObject) {
|
| + v8::HandleScope scope;
|
| + Local<ObjectTemplate> templ = ObjectTemplate::New();
|
| + LocalContext context;
|
| +
|
| + context->Global()->Set(v8_str("obj1"), templ->NewInstance());
|
| + CompileRun("var obj2 = {};");
|
| +
|
| + CHECK(CompileRun("obj1.x")->IsUndefined());
|
| + CHECK(CompileRun("obj2.x")->IsUndefined());
|
| +
|
| + CHECK(GetGlobalProperty(&context, "obj1")->
|
| + SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")));
|
| +
|
| + ExpectString("obj1.x", "x");
|
| + CHECK(CompileRun("obj2.x")->IsUndefined());
|
| +
|
| + CHECK(GetGlobalProperty(&context, "obj2")->
|
| + SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")));
|
| +
|
| + ExpectString("obj1.x", "x");
|
| + ExpectString("obj2.x", "x");
|
| +
|
| + ExpectTrue("Object.getOwnPropertyDescriptor(obj1, 'x').configurable");
|
| + ExpectTrue("Object.getOwnPropertyDescriptor(obj2, 'x').configurable");
|
| +
|
| + CompileRun("Object.defineProperty(obj1, 'x',"
|
| + "{ get: function() { return 'y'; }, configurable: true })");
|
|
|
| + ExpectString("obj1.x", "y");
|
| + ExpectString("obj2.x", "x");
|
| +
|
| + CompileRun("Object.defineProperty(obj2, 'x',"
|
| + "{ get: function() { return 'y'; }, configurable: true })");
|
| +
|
| + ExpectString("obj1.x", "y");
|
| + ExpectString("obj2.x", "y");
|
| +
|
| + ExpectTrue("Object.getOwnPropertyDescriptor(obj1, 'x').configurable");
|
| + ExpectTrue("Object.getOwnPropertyDescriptor(obj2, 'x').configurable");
|
| +
|
| + CHECK(GetGlobalProperty(&context, "obj1")->
|
| + SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")));
|
| + CHECK(GetGlobalProperty(&context, "obj2")->
|
| + SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")));
|
| +
|
| + ExpectString("obj1.x", "x");
|
| + ExpectString("obj2.x", "x");
|
| +
|
| + ExpectTrue("Object.getOwnPropertyDescriptor(obj1, 'x').configurable");
|
| + ExpectTrue("Object.getOwnPropertyDescriptor(obj2, 'x').configurable");
|
| +
|
| + // Define getters/setters, but now make them not configurable.
|
| + CompileRun("Object.defineProperty(obj1, 'x',"
|
| + "{ get: function() { return 'z'; }, configurable: false })");
|
| + CompileRun("Object.defineProperty(obj2, 'x',"
|
| + "{ get: function() { return 'z'; }, configurable: false })");
|
| +
|
| + ExpectTrue("!Object.getOwnPropertyDescriptor(obj1, 'x').configurable");
|
| + ExpectTrue("!Object.getOwnPropertyDescriptor(obj2, 'x').configurable");
|
| +
|
| + ExpectString("obj1.x", "z");
|
| + ExpectString("obj2.x", "z");
|
| +
|
| + CHECK(!GetGlobalProperty(&context, "obj1")->
|
| + SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")));
|
| + CHECK(!GetGlobalProperty(&context, "obj2")->
|
| + SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")));
|
| +
|
| + ExpectString("obj1.x", "z");
|
| + ExpectString("obj2.x", "z");
|
| +}
|
| +
|
| +
|
| +THREADED_TEST(DontDeleteAPIAccessorsCannotBeOverriden) {
|
| + v8::HandleScope scope;
|
| + Local<ObjectTemplate> templ = ObjectTemplate::New();
|
| + LocalContext context;
|
| +
|
| + context->Global()->Set(v8_str("obj1"), templ->NewInstance());
|
| + CompileRun("var obj2 = {};");
|
| +
|
| + CHECK(GetGlobalProperty(&context, "obj1")->SetAccessor(
|
| + v8_str("x"),
|
| + GetXValue, NULL,
|
| + v8_str("donut"), v8::DEFAULT, v8::DontDelete));
|
| + CHECK(GetGlobalProperty(&context, "obj2")->SetAccessor(
|
| + v8_str("x"),
|
| + GetXValue, NULL,
|
| + v8_str("donut"), v8::DEFAULT, v8::DontDelete));
|
| +
|
| + ExpectString("obj1.x", "x");
|
| + ExpectString("obj2.x", "x");
|
| +
|
| + ExpectTrue("!Object.getOwnPropertyDescriptor(obj1, 'x').configurable");
|
| + ExpectTrue("!Object.getOwnPropertyDescriptor(obj2, 'x').configurable");
|
| +
|
| + CHECK(!GetGlobalProperty(&context, "obj1")->
|
| + SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")));
|
| + CHECK(!GetGlobalProperty(&context, "obj2")->
|
| + SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")));
|
| +
|
| + {
|
| + v8::TryCatch try_catch;
|
| + CompileRun("Object.defineProperty(obj1, 'x',"
|
| + "{get: function() { return 'func'; }})");
|
| + CHECK(try_catch.HasCaught());
|
| + String::AsciiValue exception_value(try_catch.Exception());
|
| + CHECK_EQ(*exception_value,
|
| + "TypeError: Cannot redefine property: defineProperty");
|
| + }
|
| + {
|
| + v8::TryCatch try_catch;
|
| + CompileRun("Object.defineProperty(obj2, 'x',"
|
| + "{get: function() { return 'func'; }})");
|
| + CHECK(try_catch.HasCaught());
|
| + String::AsciiValue exception_value(try_catch.Exception());
|
| + CHECK_EQ(*exception_value,
|
| + "TypeError: Cannot redefine property: defineProperty");
|
| + }
|
| +}
|
| +
|
| +
|
| +static v8::Handle<Value> Get239Value(Local<String> name,
|
| + const AccessorInfo& info) {
|
| + ApiTestFuzzer::Fuzz();
|
| + CHECK_EQ(info.Data(), v8_str("donut"));
|
| + CHECK_EQ(name, v8_str("239"));
|
| + return name;
|
| +}
|
| +
|
| +
|
| +THREADED_TEST(ElementAPIAccessor) {
|
| + v8::HandleScope scope;
|
| + Local<ObjectTemplate> templ = ObjectTemplate::New();
|
| + LocalContext context;
|
| +
|
| + context->Global()->Set(v8_str("obj1"), templ->NewInstance());
|
| + CompileRun("var obj2 = {};");
|
| +
|
| + CHECK(GetGlobalProperty(&context, "obj1")->SetAccessor(
|
| + v8_str("239"),
|
| + Get239Value, NULL,
|
| + v8_str("donut")));
|
| + CHECK(GetGlobalProperty(&context, "obj2")->SetAccessor(
|
| + v8_str("239"),
|
| + Get239Value, NULL,
|
| + v8_str("donut")));
|
| +
|
| + ExpectString("obj1[239]", "239");
|
| + ExpectString("obj2[239]", "239");
|
| + ExpectString("obj1['239']", "239");
|
| + ExpectString("obj2['239']", "239");
|
| +}
|
|
|
|
|
| v8::Persistent<Value> xValue;
|
|
|