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

Side by Side Diff: test/cctest/test-api.cc

Issue 2244123005: [api] Add PropertyDescriptor and DefineProperty(). (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Minor fixes. Created 4 years, 3 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 unified diff | Download patch
« src/api.cc ('K') | « src/counters.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 15986 matching lines...) Expand 10 before | Expand all | Expand 10 after
15997 templ->NewInstance(env.local()).ToLocalChecked(); 15997 templ->NewInstance(env.local()).ToLocalChecked();
15998 { 15998 {
15999 v8::TryCatch try_catch(isolate); 15999 v8::TryCatch try_catch(isolate);
16000 CHECK(access_checked->DefineOwnProperty(env.local(), v8_str("foo"), 16000 CHECK(access_checked->DefineOwnProperty(env.local(), v8_str("foo"),
16001 v8::Integer::New(isolate, 42)) 16001 v8::Integer::New(isolate, 42))
16002 .IsNothing()); 16002 .IsNothing());
16003 CHECK(try_catch.HasCaught()); 16003 CHECK(try_catch.HasCaught());
16004 } 16004 }
16005 } 16005 }
16006 16006
16007 TEST(DefineProperty) {
16008 LocalContext env;
16009 v8::Isolate* isolate = env->GetIsolate();
16010 v8::HandleScope handle_scope(isolate);
16011
16012 v8::Local<v8::Name> p;
16013
16014 CompileRun(
16015 "var a = {};"
16016 "var b = [];"
16017 "Object.defineProperty(a, 'v1', {value: 23});"
16018 "Object.defineProperty(a, 'v2', {value: 23, configurable: true});");
16019
16020 v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(
16021 env->Global()->Get(env.local(), v8_str("a")).ToLocalChecked());
16022 v8::Local<v8::Array> arr = v8::Local<v8::Array>::Cast(
16023 env->Global()->Get(env.local(), v8_str("b")).ToLocalChecked());
16024
16025 const v8::PropertyDescriptor desc(v8_num(42));
16026 {
16027 // Use a data descriptor.
16028
16029 // Cannot change a non-configurable property.
16030 p = v8_str("v1");
16031 v8::TryCatch try_catch(isolate);
16032 CHECK(!obj->DefineProperty(env.local(), p, desc).FromJust());
16033 CHECK(!try_catch.HasCaught());
16034 v8::Local<v8::Value> val = obj->Get(env.local(), p).ToLocalChecked();
16035 CHECK(val->IsNumber());
16036 CHECK_EQ(23.0, val->NumberValue(env.local()).FromJust());
16037
16038 // Change a configurable property.
16039 p = v8_str("v2");
16040 CHECK(obj->DefineProperty(env.local(), p, desc).FromJust());
16041 CHECK(!try_catch.HasCaught());
16042 val = obj->Get(env.local(), p).ToLocalChecked();
16043 CHECK(val->IsNumber());
16044 CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
16045 }
16046
16047 {
16048 // Set a regular property.
16049 p = v8_str("v3");
16050 v8::TryCatch try_catch(isolate);
16051 CHECK(obj->DefineProperty(env.local(), p, desc).FromJust());
16052 CHECK(!try_catch.HasCaught());
16053 v8::Local<v8::Value> val = obj->Get(env.local(), p).ToLocalChecked();
16054 CHECK(val->IsNumber());
16055 CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
16056 }
16057
16058 {
16059 // Set an indexed property.
16060 v8::TryCatch try_catch(isolate);
16061 CHECK(obj->DefineProperty(env.local(), v8_str("1"), desc).FromJust());
16062 CHECK(!try_catch.HasCaught());
16063 v8::Local<v8::Value> val = obj->Get(env.local(), 1).ToLocalChecked();
16064 CHECK(val->IsNumber());
16065 CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
16066 }
16067
16068 {
16069 // No special case when changing array length.
16070 v8::TryCatch try_catch(isolate);
16071 CHECK(arr->DefineProperty(env.local(), v8_str("length"), desc).FromJust());
16072 CHECK(!try_catch.HasCaught());
16073 }
16074
16075 {
16076 // Special cases for arrays: index exceeds the array's length.
16077 v8::TryCatch try_catch(isolate);
16078 CHECK(arr->DefineProperty(env.local(), v8_str("100"), desc).FromJust());
16079 CHECK(!try_catch.HasCaught());
16080 CHECK_EQ(101U, arr->Length());
16081 v8::Local<v8::Value> val = arr->Get(env.local(), 100).ToLocalChecked();
16082 CHECK(val->IsNumber());
16083 CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
16084
16085 // Set an existing entry.
16086 CHECK(arr->DefineProperty(env.local(), v8_str("0"), desc).FromJust());
16087 CHECK(!try_catch.HasCaught());
16088 val = arr->Get(env.local(), 0).ToLocalChecked();
16089 CHECK(val->IsNumber());
16090 CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
16091 }
16092
16093 {
16094 // Use a generic descriptor.
16095 const v8::PropertyDescriptor desc_generic;
16096
16097 p = v8_str("v4");
16098 v8::TryCatch try_catch(isolate);
16099 CHECK(obj->DefineProperty(env.local(), p, desc_generic).FromJust());
16100 CHECK(!try_catch.HasCaught());
16101 v8::Local<v8::Value> val = obj->Get(env.local(), p).ToLocalChecked();
16102 CHECK(val->IsUndefined());
16103
16104 obj->Set(env.local(), p, v8_num(1)).FromJust();
16105 CHECK(!try_catch.HasCaught());
16106
16107 val = obj->Get(env.local(), p).ToLocalChecked();
16108 CHECK(val->IsUndefined());
16109 CHECK(!try_catch.HasCaught());
16110 }
16111
16112 {
16113 // Use a data descriptor with undefined value.
16114 const v8::PropertyDescriptor desc_empty(v8::Undefined(isolate));
16115
16116 v8::TryCatch try_catch(isolate);
16117 CHECK(obj->DefineProperty(env.local(), p, desc_empty).FromJust());
16118 CHECK(!try_catch.HasCaught());
16119 v8::Local<v8::Value> val = obj->Get(env.local(), p).ToLocalChecked();
16120 CHECK(val->IsUndefined());
16121 CHECK(!try_catch.HasCaught());
16122 }
16123
16124 {
16125 // Use a descriptor with attribute == v8::ReadOnly.
16126 v8::PropertyDescriptor desc_read_only(v8_num(42), false);
16127 desc_read_only.set_enumerable(true);
16128 desc_read_only.set_configurable(true);
16129
16130 p = v8_str("v5");
16131 v8::TryCatch try_catch(isolate);
16132 CHECK(obj->DefineProperty(env.local(), p, desc_read_only).FromJust());
16133 CHECK(!try_catch.HasCaught());
16134 v8::Local<v8::Value> val = obj->Get(env.local(), p).ToLocalChecked();
16135 CHECK(val->IsNumber());
16136 CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
16137 CHECK_EQ(v8::ReadOnly,
16138 obj->GetPropertyAttributes(env.local(), p).FromJust());
16139 CHECK(!try_catch.HasCaught());
16140 }
16141
16142 {
16143 // Use an accessor descriptor with empty handles.
16144 const v8::PropertyDescriptor desc_empty(v8::Undefined(isolate),
16145 v8::Undefined(isolate));
16146
16147 p = v8_str("v6");
16148 v8::TryCatch try_catch(isolate);
16149 CHECK(obj->DefineProperty(env.local(), p, desc_empty).FromJust());
16150 CHECK(!try_catch.HasCaught());
16151 v8::Local<v8::Value> val = obj->Get(env.local(), p).ToLocalChecked();
16152 CHECK(val->IsUndefined());
16153 CHECK(!try_catch.HasCaught());
16154 }
16155
16156 {
16157 // Use an accessor descriptor.
16158 CompileRun(
16159 "var set = function(x) {this.val = 2*x;};"
16160 "var get = function() {return this.val || 0;};");
16161
16162 v8::Local<v8::Function> get = v8::Local<v8::Function>::Cast(
16163 env->Global()->Get(env.local(), v8_str("get")).ToLocalChecked());
16164 v8::Local<v8::Function> set = v8::Local<v8::Function>::Cast(
16165 env->Global()->Get(env.local(), v8_str("set")).ToLocalChecked());
16166 const v8::PropertyDescriptor desc(get, set);
16167
16168 p = v8_str("v7");
16169 v8::TryCatch try_catch(isolate);
16170 CHECK(obj->DefineProperty(env.local(), p, desc).FromJust());
16171 CHECK(!try_catch.HasCaught());
16172
16173 v8::Local<v8::Value> val = obj->Get(env.local(), p).ToLocalChecked();
16174 CHECK(val->IsNumber());
16175 CHECK_EQ(0.0, val->NumberValue(env.local()).FromJust());
16176 CHECK(!try_catch.HasCaught());
16177
16178 obj->Set(env.local(), p, v8_num(7)).FromJust();
16179 CHECK(!try_catch.HasCaught());
16180
16181 val = obj->Get(env.local(), p).ToLocalChecked();
16182 CHECK(val->IsNumber());
16183 CHECK_EQ(14.0, val->NumberValue(env.local()).FromJust());
16184 CHECK(!try_catch.HasCaught());
16185 }
16186
16187 {
16188 // Redefine an existing property.
16189
16190 // desc = {value: 42, enumerable: true}
16191 v8::PropertyDescriptor desc(v8_num(42));
16192 desc.set_enumerable(true);
16193
16194 p = v8_str("v8");
16195 v8::TryCatch try_catch(isolate);
16196 CHECK(obj->DefineProperty(env.local(), p, desc).FromJust());
16197 CHECK(!try_catch.HasCaught());
16198
16199 // desc = {enumerable: true}
16200 v8::PropertyDescriptor desc_true((v8::Local<v8::Value>()));
16201 desc_true.set_enumerable(true);
16202
16203 // Successful redefinition because all present attributes have the same
16204 // value as the current descriptor.
16205 CHECK(obj->DefineProperty(env.local(), p, desc_true).FromJust());
16206 CHECK(!try_catch.HasCaught());
16207
16208 // desc = {}
16209 const v8::PropertyDescriptor desc_empty;
16210 // Successful redefinition because no attributes are overwritten in the
16211 // current descriptor.
16212 CHECK(obj->DefineProperty(env.local(), p, desc_empty).FromJust());
16213 CHECK(!try_catch.HasCaught());
16214
16215 // desc = {enumerable: false}
16216 v8::PropertyDescriptor desc_false((v8::Local<v8::Value>()));
16217 desc_false.set_enumerable(false);
16218 // Not successful because we cannot define a different value for enumerable.
16219 CHECK(!obj->DefineProperty(env.local(), p, desc_false).FromJust());
16220 CHECK(!try_catch.HasCaught());
16221 }
16222
16223 {
16224 // Redefine a property that has a getter.
16225 CompileRun("var get = function() {};");
16226 v8::Local<v8::Function> get = v8::Local<v8::Function>::Cast(
16227 env->Global()->Get(env.local(), v8_str("get")).ToLocalChecked());
16228
16229 // desc = {get: function() {}}
16230 const v8::PropertyDescriptor desc(get, v8::Local<v8::Function>());
16231 v8::TryCatch try_catch(isolate);
16232
16233 p = v8_str("v9");
16234 CHECK(obj->DefineProperty(env.local(), p, desc).FromJust());
16235 CHECK(!try_catch.HasCaught());
16236
16237 // desc_empty = {}
16238 // Successful because we are not redefining the current getter.
16239 const v8::PropertyDescriptor desc_empty;
16240 CHECK(obj->DefineProperty(env.local(), p, desc_empty).FromJust());
16241 CHECK(!try_catch.HasCaught());
16242
16243 // desc = {get: function() {}}
16244 // Successful because we redefine the getter with its current value.
16245 CHECK(obj->DefineProperty(env.local(), p, desc).FromJust());
16246 CHECK(!try_catch.HasCaught());
16247
16248 // desc = {get: undefined}
16249 const v8::PropertyDescriptor desc_undefined(v8::Undefined(isolate),
16250 v8::Local<v8::Function>());
16251 // Not successful because we cannot redefine with the current value of get
16252 // with undefined.
16253 CHECK(!obj->DefineProperty(env.local(), p, desc_undefined).FromJust());
16254 CHECK(!try_catch.HasCaught());
16255 }
16256
16257 CompileRun("Object.freeze(a);");
16258 {
16259 // We cannot change non-extensible objects.
16260 v8::TryCatch try_catch(isolate);
16261 CHECK(!obj->DefineProperty(env.local(), v8_str("v10"), desc).FromJust());
16262 CHECK(!try_catch.HasCaught());
16263 }
16264
16265 v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
16266 templ->SetAccessCheckCallback(AccessAlwaysBlocked);
16267 v8::Local<v8::Object> access_checked =
16268 templ->NewInstance(env.local()).ToLocalChecked();
16269 {
16270 v8::TryCatch try_catch(isolate);
16271 CHECK(access_checked->DefineProperty(env.local(), v8_str("v11"), desc)
16272 .IsNothing());
16273 CHECK(try_catch.HasCaught());
16274 }
16275 }
16007 16276
16008 THREADED_TEST(GetCurrentContextWhenNotInContext) { 16277 THREADED_TEST(GetCurrentContextWhenNotInContext) {
16009 i::Isolate* isolate = CcTest::i_isolate(); 16278 i::Isolate* isolate = CcTest::i_isolate();
16010 CHECK(isolate != NULL); 16279 CHECK(isolate != NULL);
16011 CHECK(isolate->context() == NULL); 16280 CHECK(isolate->context() == NULL);
16012 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); 16281 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
16013 v8::HandleScope scope(v8_isolate); 16282 v8::HandleScope scope(v8_isolate);
16014 // The following should not crash, but return an empty handle. 16283 // The following should not crash, but return an empty handle.
16015 v8::Local<v8::Context> current = v8_isolate->GetCurrentContext(); 16284 v8::Local<v8::Context> current = v8_isolate->GetCurrentContext();
16016 CHECK(current.IsEmpty()); 16285 CHECK(current.IsEmpty());
(...skipping 7315 matching lines...) Expand 10 before | Expand all | Expand 10 after
23332 "V8.Test", 0, 10000, v8::internal::HistogramTimer::MILLISECOND, 50, 23601 "V8.Test", 0, 10000, v8::internal::HistogramTimer::MILLISECOND, 50,
23333 reinterpret_cast<v8::internal::Isolate*>(isolate)); 23602 reinterpret_cast<v8::internal::Isolate*>(isolate));
23334 histogramTimer.Start(); 23603 histogramTimer.Start();
23335 CHECK_EQ(0, strcmp("V8.Test", last_event_message)); 23604 CHECK_EQ(0, strcmp("V8.Test", last_event_message));
23336 CHECK_EQ(0, last_event_status); 23605 CHECK_EQ(0, last_event_status);
23337 histogramTimer.Stop(); 23606 histogramTimer.Stop();
23338 CHECK_EQ(0, strcmp("V8.Test", last_event_message)); 23607 CHECK_EQ(0, strcmp("V8.Test", last_event_message));
23339 CHECK_EQ(1, last_event_status); 23608 CHECK_EQ(1, last_event_status);
23340 } 23609 }
23341 23610
23611 TEST(PropertyDescriptor) {
Jakob Kummerow 2016/08/31 14:15:13 I still think that unit tests for getters and sett
Franzi 2016/08/31 20:10:51 I like them. They catch some set/get typos or auto
23612 LocalContext context;
23613 v8::Isolate* isolate = context->GetIsolate();
23614 v8::HandleScope scope(isolate);
23615
23616 { // empty descriptor
23617 v8::PropertyDescriptor desc;
23618 CHECK(!desc.has_value());
23619 CHECK(!desc.has_set());
23620 CHECK(!desc.has_get());
23621 CHECK(!desc.has_enumerable());
23622 CHECK(!desc.has_configurable());
23623 CHECK(!desc.has_writable());
23624 }
23625 {
23626 // data descriptor
23627 v8::PropertyDescriptor desc(v8_num(42));
23628 desc.set_enumerable(false);
23629 CHECK(desc.value() == v8_num(42));
23630 CHECK(desc.has_value());
23631 CHECK(!desc.has_set());
23632 CHECK(!desc.has_get());
23633 CHECK(desc.has_enumerable());
23634 CHECK(!desc.enumerable());
23635 CHECK(!desc.has_configurable());
23636 CHECK(!desc.has_writable());
23637 }
23638 {
23639 // data descriptor
23640 v8::PropertyDescriptor desc(v8_num(42));
23641 desc.set_configurable(true);
23642 CHECK(desc.value() == v8_num(42));
23643 CHECK(desc.has_value());
23644 CHECK(!desc.has_set());
23645 CHECK(!desc.has_get());
23646 CHECK(desc.has_configurable());
23647 CHECK(desc.configurable());
23648 CHECK(!desc.has_enumerable());
23649 CHECK(!desc.has_writable());
23650 }
23651 {
23652 // data descriptor
23653 v8::PropertyDescriptor desc(v8_num(42));
23654 desc.set_configurable(false);
23655 CHECK(desc.value() == v8_num(42));
23656 CHECK(desc.has_value());
23657 CHECK(!desc.has_set());
23658 CHECK(!desc.has_get());
23659 CHECK(desc.has_configurable());
23660 CHECK(!desc.configurable());
23661 CHECK(!desc.has_enumerable());
23662 CHECK(!desc.has_writable());
23663 }
23664 {
23665 // data descriptor
23666 v8::PropertyDescriptor desc(v8_num(42), false);
23667 CHECK(desc.value() == v8_num(42));
23668 CHECK(desc.has_value());
23669 CHECK(!desc.has_set());
23670 CHECK(!desc.has_get());
23671 CHECK(!desc.has_enumerable());
23672 CHECK(!desc.has_configurable());
23673 CHECK(desc.has_writable());
23674 CHECK(!desc.writable());
23675 }
23676 {
23677 // data descriptor
23678 v8::PropertyDescriptor desc(v8::Local<v8::Value>(), true);
23679 CHECK(!desc.has_value());
23680 CHECK(!desc.has_set());
23681 CHECK(!desc.has_get());
23682 CHECK(!desc.has_enumerable());
23683 CHECK(!desc.has_configurable());
23684 CHECK(desc.has_writable());
23685 CHECK(desc.writable());
23686 }
23687 {
23688 // accessor descriptor
23689 CompileRun("var set = function() {return 43;};");
23690
23691 v8::Local<v8::Function> set =
23692 v8::Local<v8::Function>::Cast(context->Global()
23693 ->Get(context.local(), v8_str("set"))
23694 .ToLocalChecked());
23695 v8::PropertyDescriptor desc(v8::Undefined(isolate), set);
23696 desc.set_configurable(false);
23697 CHECK(!desc.has_value());
23698 CHECK(desc.has_get());
23699 CHECK(desc.get() == v8::Undefined(isolate));
23700 CHECK(desc.has_set());
23701 CHECK(desc.set() == set);
23702 CHECK(!desc.has_enumerable());
23703 CHECK(desc.has_configurable());
23704 CHECK(!desc.configurable());
23705 CHECK(!desc.has_writable());
23706 }
23707 {
23708 // accessor descriptor with Proxy
23709 CompileRun(
23710 "var set = new Proxy(function() {}, {});"
23711 "var get = undefined;");
23712
23713 v8::Local<v8::Value> get =
23714 v8::Local<v8::Value>::Cast(context->Global()
23715 ->Get(context.local(), v8_str("get"))
23716 .ToLocalChecked());
23717 v8::Local<v8::Function> set =
23718 v8::Local<v8::Function>::Cast(context->Global()
23719 ->Get(context.local(), v8_str("set"))
23720 .ToLocalChecked());
23721 v8::PropertyDescriptor desc(get, set);
23722 desc.set_configurable(false);
23723 CHECK(!desc.has_value());
23724 CHECK(desc.get() == v8::Undefined(isolate));
23725 CHECK(desc.has_get());
23726 CHECK(desc.set() == set);
23727 CHECK(desc.has_set());
23728 CHECK(!desc.has_enumerable());
23729 CHECK(desc.has_configurable());
23730 CHECK(!desc.configurable());
23731 CHECK(!desc.has_writable());
23732 }
23733 {
23734 // accessor descriptor with empty function handle
23735 v8::Local<v8::Function> get = v8::Local<v8::Function>();
23736 v8::PropertyDescriptor desc(get, get);
23737 CHECK(!desc.has_value());
23738 CHECK(!desc.has_get());
23739 CHECK(!desc.has_set());
23740 CHECK(!desc.has_enumerable());
23741 CHECK(!desc.has_configurable());
23742 CHECK(!desc.has_writable());
23743 }
23744 }
23342 23745
23343 TEST(Promises) { 23746 TEST(Promises) {
23344 LocalContext context; 23747 LocalContext context;
23345 v8::Isolate* isolate = context->GetIsolate(); 23748 v8::Isolate* isolate = context->GetIsolate();
23346 v8::HandleScope scope(isolate); 23749 v8::HandleScope scope(isolate);
23347 23750
23348 // Creation. 23751 // Creation.
23349 Local<v8::Promise::Resolver> pr = 23752 Local<v8::Promise::Resolver> pr =
23350 v8::Promise::Resolver::New(context.local()).ToLocalChecked(); 23753 v8::Promise::Resolver::New(context.local()).ToLocalChecked();
23351 Local<v8::Promise::Resolver> rr = 23754 Local<v8::Promise::Resolver> rr =
(...skipping 2172 matching lines...) Expand 10 before | Expand all | Expand 10 after
25524 25927
25525 // Put the function into context1 and call it. Since the access check 25928 // Put the function into context1 and call it. Since the access check
25526 // callback always returns true, the call succeeds even though the tokens 25929 // callback always returns true, the call succeeds even though the tokens
25527 // are different. 25930 // are different.
25528 context1->Enter(); 25931 context1->Enter();
25529 context1->Global()->Set(context1, v8_str("fun"), fun).FromJust(); 25932 context1->Global()->Set(context1, v8_str("fun"), fun).FromJust();
25530 v8::Local<v8::Value> x_value = CompileRun("fun('x')"); 25933 v8::Local<v8::Value> x_value = CompileRun("fun('x')");
25531 CHECK_EQ(42, x_value->Int32Value(context1).FromJust()); 25934 CHECK_EQ(42, x_value->Int32Value(context1).FromJust());
25532 context1->Exit(); 25935 context1->Exit();
25533 } 25936 }
OLDNEW
« src/api.cc ('K') | « src/counters.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698