Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(371)

Unified Diff: test/cctest/test-api.cc

Issue 88026: Added ForceSet on objects (Closed)
Patch Set: Added docs for ForceSet Created 11 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/objects.cc ('K') | « src/runtime.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/cctest/test-api.cc
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index ccbb262a1c1c8037d9d2195b45bf25cab30aab7c..eaba62749cc86434b4f2fca622840eb2d47080cf 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -6238,3 +6238,118 @@ TEST(ReadOnlyPropertyInGlobalProto) {
res = CompileRun("function f() { with (this) { y = 42 }; return y; }; f()");
CHECK_EQ(v8::Integer::New(42), res);
}
+
+static int force_set_set_count = 0;
+static int force_set_get_count = 0;
+bool pass_on_get = false;
+
+static v8::Handle<v8::Value> ForceSetGetter(v8::Local<v8::String> name,
+ const v8::AccessorInfo& info) {
+ force_set_get_count++;
+ if (pass_on_get) {
+ return v8::Handle<v8::Value>();
+ } else {
+ return v8::Int32::New(3);
+ }
+}
+
+static void ForceSetSetter(v8::Local<v8::String> name,
+ v8::Local<v8::Value> value,
+ const v8::AccessorInfo& info) {
+ force_set_set_count++;
+}
+
+static v8::Handle<v8::Value> ForceSetInterceptSetter(
+ v8::Local<v8::String> name,
+ v8::Local<v8::Value> value,
+ const v8::AccessorInfo& info) {
+ force_set_set_count++;
+ return v8::Undefined();
+}
+
+TEST(ForceSet) {
+ force_set_get_count = 0;
+ force_set_set_count = 0;
+ pass_on_get = false;
+
+ v8::HandleScope scope;
+ v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New();
+ v8::Handle<v8::String> access_property = v8::String::New("a");
+ templ->SetAccessor(access_property, ForceSetGetter, ForceSetSetter);
+ LocalContext context(NULL, templ);
+ v8::Handle<v8::Object> global = context->Global();
+
+ // Ordinary properties
+ v8::Handle<v8::String> simple_property = v8::String::New("p");
+ global->Set(simple_property, v8::Int32::New(4), v8::ReadOnly);
+ CHECK_EQ(4, global->Get(simple_property)->Int32Value());
+ // This should fail because the property is read-only
+ global->Set(simple_property, v8::Int32::New(5));
+ CHECK_EQ(4, global->Get(simple_property)->Int32Value());
+ // This should succeed even though the property is read-only
+ global->ForceSet(simple_property, v8::Int32::New(6));
+ CHECK_EQ(6, global->Get(simple_property)->Int32Value());
+
+ // Accessors
+ CHECK_EQ(0, force_set_set_count);
+ CHECK_EQ(0, force_set_get_count);
+ CHECK_EQ(3, global->Get(access_property)->Int32Value());
+ // CHECK_EQ the property shouldn't override it, just call the setter
+ // which in this case does nothing.
+ global->Set(access_property, v8::Int32::New(7));
+ CHECK_EQ(3, global->Get(access_property)->Int32Value());
+ CHECK_EQ(1, force_set_set_count);
+ CHECK_EQ(2, force_set_get_count);
+ // Forcing the property to be set should override the accessor without
+ // calling it
+ global->ForceSet(access_property, v8::Int32::New(8));
+ CHECK_EQ(8, global->Get(access_property)->Int32Value());
+ CHECK_EQ(1, force_set_set_count);
+ CHECK_EQ(2, force_set_get_count);
+}
+
+TEST(ForceSetWithInterceptor) {
+ force_set_get_count = 0;
+ force_set_set_count = 0;
+ pass_on_get = false;
+
+ v8::HandleScope scope;
+ v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New();
+ templ->SetNamedPropertyHandler(ForceSetGetter, ForceSetInterceptSetter);
+ LocalContext context(NULL, templ);
+ v8::Handle<v8::Object> global = context->Global();
+
+ v8::Handle<v8::String> some_property = v8::String::New("a");
+ CHECK_EQ(0, force_set_set_count);
+ CHECK_EQ(0, force_set_get_count);
+ CHECK_EQ(3, global->Get(some_property)->Int32Value());
+ // Setting the property shouldn't override it, just call the setter
+ // which in this case does nothing.
+ global->Set(some_property, v8::Int32::New(7));
+ CHECK_EQ(3, global->Get(some_property)->Int32Value());
+ CHECK_EQ(1, force_set_set_count);
+ CHECK_EQ(2, force_set_get_count);
+ // Getting the property when the interceptor returns an empty handle
+ // should yield undefined, since the property isn't present on the
+ // object itself yet.
+ pass_on_get = true;
+ CHECK(global->Get(some_property)->IsUndefined());
+ CHECK_EQ(1, force_set_set_count);
+ CHECK_EQ(3, force_set_get_count);
+ // Forcing the property to be set should cause the value to be
+ // set locally without calling the interceptor.
+ global->ForceSet(some_property, v8::Int32::New(8));
+ CHECK_EQ(8, global->Get(some_property)->Int32Value());
+ CHECK_EQ(1, force_set_set_count);
+ CHECK_EQ(4, force_set_get_count);
+ // Reenabling the interceptor should cause it to take precedence over
+ // the property
+ pass_on_get = false;
+ CHECK_EQ(3, global->Get(some_property)->Int32Value());
+ CHECK_EQ(1, force_set_set_count);
+ CHECK_EQ(5, force_set_get_count);
+ // The interceptor should also work for other properties
+ CHECK_EQ(3, global->Get(v8::String::New("b"))->Int32Value());
+ CHECK_EQ(1, force_set_set_count);
+ CHECK_EQ(6, force_set_get_count);
+}
« src/objects.cc ('K') | « src/runtime.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698