Index: test/cctest/test-api.cc |
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc |
index 896115d7403f6a2c72c43e49e5258da71c4696b4..eb5f9a7e5eb490b3f3f7384eee28f22242185cf1 100644 |
--- a/test/cctest/test-api.cc |
+++ b/test/cctest/test-api.cc |
@@ -13429,6 +13429,125 @@ TEST(CreateDataProperty) { |
} |
+TEST(DefineOwnProperty) { |
+ LocalContext env; |
+ v8::Isolate* isolate = env->GetIsolate(); |
+ v8::HandleScope handle_scope(isolate); |
+ |
+ CompileRun( |
+ "var a = {};" |
+ "var b = [];" |
+ "Object.defineProperty(a, 'foo', {value: 23});" |
+ "Object.defineProperty(a, 'bar', {value: 23, configurable: true});"); |
+ |
+ v8::Local<v8::Object> obj = |
+ v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("a"))); |
+ v8::Local<v8::Array> arr = |
+ v8::Local<v8::Array>::Cast(env->Global()->Get(v8_str("b"))); |
+ { |
+ // Can't change a non-configurable properties. |
+ v8::TryCatch try_catch(isolate); |
+ CHECK(!obj->DefineOwnProperty(env.local(), v8_str("foo"), |
+ v8::Integer::New(isolate, 42)).FromJust()); |
+ CHECK(!try_catch.HasCaught()); |
+ CHECK(obj->DefineOwnProperty(env.local(), v8_str("bar"), |
+ v8::Integer::New(isolate, 42)).FromJust()); |
+ CHECK(!try_catch.HasCaught()); |
+ v8::Local<v8::Value> val = |
+ obj->Get(env.local(), v8_str("bar")).ToLocalChecked(); |
+ CHECK(val->IsNumber()); |
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust()); |
+ } |
+ |
+ { |
+ // Set a regular property. |
+ v8::TryCatch try_catch(isolate); |
+ CHECK(obj->DefineOwnProperty(env.local(), v8_str("blub"), |
+ v8::Integer::New(isolate, 42)).FromJust()); |
+ CHECK(!try_catch.HasCaught()); |
+ v8::Local<v8::Value> val = |
+ obj->Get(env.local(), v8_str("blub")).ToLocalChecked(); |
+ CHECK(val->IsNumber()); |
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust()); |
+ } |
+ |
+ { |
+ // Set an indexed property. |
+ v8::TryCatch try_catch(isolate); |
+ CHECK(obj->DefineOwnProperty(env.local(), v8_str("1"), |
+ v8::Integer::New(isolate, 42)).FromJust()); |
+ CHECK(!try_catch.HasCaught()); |
+ v8::Local<v8::Value> val = obj->Get(env.local(), 1).ToLocalChecked(); |
+ CHECK(val->IsNumber()); |
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust()); |
+ } |
+ |
+ { |
+ // Special cases for arrays. |
+ v8::TryCatch try_catch(isolate); |
+ CHECK(!arr->DefineOwnProperty(env.local(), v8_str("length"), |
+ v8::Integer::New(isolate, 1)).FromJust()); |
+ CHECK(!try_catch.HasCaught()); |
+ } |
+ { |
+ // Special cases for arrays: index exceeds the array's length |
+ v8::TryCatch try_catch(isolate); |
+ CHECK(arr->DefineOwnProperty(env.local(), v8_str("1"), |
+ v8::Integer::New(isolate, 23)).FromJust()); |
+ CHECK(!try_catch.HasCaught()); |
+ CHECK_EQ(2, arr->Length()); |
+ v8::Local<v8::Value> val = arr->Get(env.local(), 1).ToLocalChecked(); |
+ CHECK(val->IsNumber()); |
+ CHECK_EQ(23.0, val->NumberValue(env.local()).FromJust()); |
+ |
+ // Set an existing entry. |
+ CHECK(arr->DefineOwnProperty(env.local(), v8_str("0"), |
+ v8::Integer::New(isolate, 42)).FromJust()); |
+ CHECK(!try_catch.HasCaught()); |
+ val = arr->Get(env.local(), 0).ToLocalChecked(); |
+ CHECK(val->IsNumber()); |
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust()); |
+ } |
+ |
+ { |
+ // Set a non-writable property. |
+ v8::TryCatch try_catch(isolate); |
+ CHECK(obj->DefineOwnProperty(env.local(), v8_str("lala"), |
+ v8::Integer::New(isolate, 42), |
+ v8::ReadOnly).FromJust()); |
+ CHECK(!try_catch.HasCaught()); |
+ v8::Local<v8::Value> val = |
+ obj->Get(env.local(), v8_str("lala")).ToLocalChecked(); |
+ CHECK(val->IsNumber()); |
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust()); |
+ CHECK_EQ(v8::ReadOnly, obj->GetPropertyAttributes( |
+ env.local(), v8_str("lala")).FromJust()); |
+ CHECK(!try_catch.HasCaught()); |
+ } |
+ |
+ CompileRun("Object.freeze(a);"); |
+ { |
+ // Can't change non-extensible objects. |
+ v8::TryCatch try_catch(isolate); |
+ CHECK(!obj->DefineOwnProperty(env.local(), v8_str("baz"), |
+ v8::Integer::New(isolate, 42)).FromJust()); |
+ CHECK(!try_catch.HasCaught()); |
+ } |
+ |
+ v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate); |
+ templ->SetAccessCheckCallbacks(AccessAlwaysBlocked, NULL); |
+ v8::Local<v8::Object> access_checked = |
+ templ->NewInstance(env.local()).ToLocalChecked(); |
+ { |
+ v8::TryCatch try_catch(isolate); |
+ CHECK(access_checked->DefineOwnProperty(env.local(), v8_str("foo"), |
+ v8::Integer::New(isolate, 42)) |
+ .IsNothing()); |
+ CHECK(try_catch.HasCaught()); |
+ } |
+} |
+ |
+ |
static v8::Local<Context> calling_context0; |
static v8::Local<Context> calling_context1; |
static v8::Local<Context> calling_context2; |