📄 test-api.cc
字号:
size_t length() const { return length_; } private: uint16_t* data_; size_t length_;};int TestResource::dispose_count = 0;class TestAsciiResource: public String::ExternalAsciiStringResource { public: static int dispose_count; explicit TestAsciiResource(char* data) : data_(data), length_(strlen(data)) { } ~TestAsciiResource() { i::DeleteArray(data_); ++dispose_count; } const char* data() const { return data_; } size_t length() const { return length_; } private: char* data_; size_t length_;};int TestAsciiResource::dispose_count = 0;THREADED_TEST(ScriptUsingStringResource) { TestResource::dispose_count = 0; const char* c_source = "1 + 2 * 3"; uint16_t* two_byte_source = AsciiToTwoByteString(c_source); { v8::HandleScope scope; LocalContext env; TestResource* resource = new TestResource(two_byte_source); Local<String> source = String::NewExternal(resource); Local<Script> script = Script::Compile(source); Local<Value> value = script->Run(); CHECK(value->IsNumber()); CHECK_EQ(7, value->Int32Value()); CHECK(source->IsExternal()); CHECK_EQ(resource, static_cast<TestResource*>(source->GetExternalStringResource())); v8::internal::Heap::CollectAllGarbage(); CHECK_EQ(0, TestResource::dispose_count); } v8::internal::Heap::CollectAllGarbage(); CHECK_EQ(1, TestResource::dispose_count);}THREADED_TEST(ScriptUsingAsciiStringResource) { TestAsciiResource::dispose_count = 0; const char* c_source = "1 + 2 * 3"; { v8::HandleScope scope; LocalContext env; Local<String> source = String::NewExternal(new TestAsciiResource(i::StrDup(c_source))); Local<Script> script = Script::Compile(source); Local<Value> value = script->Run(); CHECK(value->IsNumber()); CHECK_EQ(7, value->Int32Value()); v8::internal::Heap::CollectAllGarbage(); CHECK_EQ(0, TestAsciiResource::dispose_count); } v8::internal::Heap::CollectAllGarbage(); CHECK_EQ(1, TestAsciiResource::dispose_count);}THREADED_TEST(GlobalProperties) { v8::HandleScope scope; LocalContext env; v8::Handle<v8::Object> global = env->Global(); global->Set(v8_str("pi"), v8_num(3.1415926)); Local<Value> pi = global->Get(v8_str("pi")); CHECK_EQ(3.1415926, pi->NumberValue());}static v8::Handle<Value> handle_call(const v8::Arguments& args) { ApiTestFuzzer::Fuzz(); return v8_num(102);}static v8::Handle<Value> construct_call(const v8::Arguments& args) { ApiTestFuzzer::Fuzz(); args.This()->Set(v8_str("x"), v8_num(1)); args.This()->Set(v8_str("y"), v8_num(2)); return args.This();}THREADED_TEST(FunctionTemplate) { v8::HandleScope scope; LocalContext env; { Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(handle_call); Local<Function> fun = fun_templ->GetFunction(); env->Global()->Set(v8_str("obj"), fun); Local<Script> script = v8_compile("obj()"); CHECK_EQ(102, script->Run()->Int32Value()); } // Use SetCallHandler to initialize a function template, should work like the // previous one. { Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); fun_templ->SetCallHandler(handle_call); Local<Function> fun = fun_templ->GetFunction(); env->Global()->Set(v8_str("obj"), fun); Local<Script> script = v8_compile("obj()"); CHECK_EQ(102, script->Run()->Int32Value()); } // Test constructor calls. { Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(construct_call); fun_templ->SetClassName(v8_str("funky")); Local<Function> fun = fun_templ->GetFunction(); env->Global()->Set(v8_str("obj"), fun); Local<Script> script = v8_compile("var s = new obj(); s.x"); CHECK_EQ(1, script->Run()->Int32Value()); Local<Value> result = v8_compile("(new obj()).toString()")->Run(); CHECK_EQ(v8_str("[object funky]"), result); }}static v8::Handle<Value> handle_property(Local<String> name, const AccessorInfo&) { ApiTestFuzzer::Fuzz(); return v8_num(900);}THREADED_TEST(PropertyHandler) { v8::HandleScope scope; Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); fun_templ->InstanceTemplate()->SetAccessor(v8_str("foo"), handle_property); LocalContext env; Local<Function> fun = fun_templ->GetFunction(); env->Global()->Set(v8_str("Fun"), fun); Local<Script> getter = v8_compile("var obj = new Fun(); obj.foo;"); CHECK_EQ(900, getter->Run()->Int32Value()); Local<Script> setter = v8_compile("obj.foo = 901;"); CHECK_EQ(901, setter->Run()->Int32Value());}THREADED_TEST(Number) { v8::HandleScope scope; LocalContext env; double PI = 3.1415926; Local<v8::Number> pi_obj = v8::Number::New(PI); CHECK_EQ(PI, pi_obj->NumberValue());}THREADED_TEST(ToNumber) { v8::HandleScope scope; LocalContext env; Local<String> str = v8_str("3.1415926"); CHECK_EQ(3.1415926, str->NumberValue()); v8::Handle<v8::Boolean> t = v8::True(); CHECK_EQ(1.0, t->NumberValue()); v8::Handle<v8::Boolean> f = v8::False(); CHECK_EQ(0.0, f->NumberValue());}THREADED_TEST(Date) { v8::HandleScope scope; LocalContext env; double PI = 3.1415926; Local<Value> date_obj = v8::Date::New(PI); CHECK_EQ(3.0, date_obj->NumberValue());}THREADED_TEST(Boolean) { v8::HandleScope scope; LocalContext env; v8::Handle<v8::Boolean> t = v8::True(); CHECK(t->Value()); v8::Handle<v8::Boolean> f = v8::False(); CHECK(!f->Value()); v8::Handle<v8::Primitive> u = v8::Undefined(); CHECK(!u->BooleanValue()); v8::Handle<v8::Primitive> n = v8::Null(); CHECK(!n->BooleanValue()); v8::Handle<String> str1 = v8_str(""); CHECK(!str1->BooleanValue()); v8::Handle<String> str2 = v8_str("x"); CHECK(str2->BooleanValue()); CHECK(!v8::Number::New(0)->BooleanValue()); CHECK(v8::Number::New(-1)->BooleanValue()); CHECK(v8::Number::New(1)->BooleanValue()); CHECK(v8::Number::New(42)->BooleanValue()); CHECK(!v8_compile("NaN")->Run()->BooleanValue());}static v8::Handle<Value> DummyCallHandler(const v8::Arguments& args) { ApiTestFuzzer::Fuzz(); return v8_num(13.4);}static v8::Handle<Value> GetM(Local<String> name, const AccessorInfo&) { ApiTestFuzzer::Fuzz(); return v8_num(876);}THREADED_TEST(GlobalPrototype) { v8::HandleScope scope; v8::Handle<v8::FunctionTemplate> func_templ = v8::FunctionTemplate::New(); func_templ->PrototypeTemplate()->Set( "dummy", v8::FunctionTemplate::New(DummyCallHandler)); v8::Handle<ObjectTemplate> templ = func_templ->InstanceTemplate(); templ->Set("x", v8_num(200)); templ->SetAccessor(v8_str("m"), GetM); LocalContext env(0, templ); v8::Handle<v8::Object> obj = env->Global(); v8::Handle<Script> script = v8_compile("dummy()"); v8::Handle<Value> result = script->Run(); CHECK_EQ(13.4, result->NumberValue()); CHECK_EQ(200, v8_compile("x")->Run()->Int32Value()); CHECK_EQ(876, v8_compile("m")->Run()->Int32Value());}static v8::Handle<Value> GetIntValue(Local<String> property, const AccessorInfo& info) { ApiTestFuzzer::Fuzz(); int* value = static_cast<int*>(v8::Handle<v8::External>::Cast(info.Data())->Value()); return v8_num(*value);}static void SetIntValue(Local<String> property, Local<Value> value, const AccessorInfo& info) { int* field = static_cast<int*>(v8::Handle<v8::External>::Cast(info.Data())->Value()); *field = value->Int32Value();}int foo, bar, baz;THREADED_TEST(GlobalVariableAccess) { foo = 0; bar = -4; baz = 10; v8::HandleScope scope; v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); templ->InstanceTemplate()->SetAccessor(v8_str("foo"), GetIntValue, SetIntValue, v8::External::New(&foo)); templ->InstanceTemplate()->SetAccessor(v8_str("bar"), GetIntValue, SetIntValue, v8::External::New(&bar)); templ->InstanceTemplate()->SetAccessor(v8_str("baz"), GetIntValue, SetIntValue, v8::External::New(&baz)); LocalContext env(0, templ->InstanceTemplate()); v8_compile("foo = (++bar) + baz")->Run(); CHECK_EQ(bar, -3); CHECK_EQ(foo, 7);}THREADED_TEST(ObjectTemplate) { v8::HandleScope scope; Local<ObjectTemplate> templ1 = ObjectTemplate::New(); templ1->Set("x", v8_num(10)); templ1->Set("y", v8_num(13)); LocalContext env; Local<v8::Object> instance1 = templ1->NewInstance(); env->Global()->Set(v8_str("p"), instance1); CHECK(v8_compile("(p.x == 10)")->Run()->BooleanValue()); CHECK(v8_compile("(p.y == 13)")->Run()->BooleanValue()); Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(); fun->PrototypeTemplate()->Set("nirk", v8_num(123)); Local<ObjectTemplate> templ2 = fun->InstanceTemplate(); templ2->Set("a", v8_num(12)); templ2->Set("b", templ1); Local<v8::Object> instance2 = templ2->NewInstance(); env->Global()->Set(v8_str("q"), instance2); CHECK(v8_compile("(q.nirk == 123)")->Run()->BooleanValue()); CHECK(v8_compile("(q.a == 12)")->Run()->BooleanValue()); CHECK(v8_compile("(q.b.x == 10)")->Run()->BooleanValue()); CHECK(v8_compile("(q.b.y == 13)")->Run()->BooleanValue());}static v8::Handle<Value> GetFlabby(const v8::Arguments& args) { ApiTestFuzzer::Fuzz(); return v8_num(17.2);}static v8::Handle<Value> GetKnurd(Local<String> property, const AccessorInfo&) { ApiTestFuzzer::Fuzz(); return v8_num(15.2);}THREADED_TEST(DescriptorInheritance) { v8::HandleScope scope; v8::Handle<v8::FunctionTemplate> super = v8::FunctionTemplate::New(); super->PrototypeTemplate()->Set("flabby", v8::FunctionTemplate::New(GetFlabby)); super->PrototypeTemplate()->Set("PI", v8_num(3.14)); super->InstanceTemplate()->SetAccessor(v8_str("knurd"), GetKnurd); v8::Handle<v8::FunctionTemplate> base1 = v8::FunctionTemplate::New(); base1->Inherit(super); base1->PrototypeTemplate()->Set("v1", v8_num(20.1)); v8::Handle<v8::FunctionTemplate> base2 = v8::FunctionTemplate::New(); base2->Inherit(super); base2->PrototypeTemplate()->Set("v2", v8_num(10.1)); LocalContext env; env->Global()->Set(v8_str("s"), super->GetFunction()); env->Global()->Set(v8_str("base1"), base1->GetFunction()); env->Global()->Set(v8_str("base2"), base2->GetFunction()); // Checks right __proto__ chain. CHECK(CompileRun("base1.prototype.__proto__ == s.prototype")->BooleanValue()); CHECK(CompileRun("base2.prototype.__proto__ == s.prototype")->BooleanValue()); CHECK(v8_compile("s.prototype.PI == 3.14")->Run()->BooleanValue()); // Instance accessor should not be visible on function object or its prototype CHECK(CompileRun("s.knurd == undefined")->BooleanValue()); CHECK(CompileRun("s.prototype.knurd == undefined")->BooleanValue()); CHECK(CompileRun("base1.prototype.knurd == undefined")->BooleanValue()); env->Global()->Set(v8_str("obj"), base1->GetFunction()->NewInstance()); CHECK_EQ(17.2, v8_compile("obj.flabby()")->Run()->NumberValue()); CHECK(v8_compile("'flabby' in obj")->Run()->BooleanValue()); CHECK_EQ(15.2, v8_compile("obj.knurd")->Run()->NumberValue()); CHECK(v8_compile("'knurd' in obj")->Run()->BooleanValue()); CHECK_EQ(20.1, v8_compile("obj.v1")->Run()->NumberValue()); env->Global()->Set(v8_str("obj2"), base2->GetFunction()->NewInstance()); CHECK_EQ(17.2, v8_compile("obj2.flabby()")->Run()->NumberValue()); CHECK(v8_compile("'flabby' in obj2")->Run()->BooleanValue()); CHECK_EQ(15.2, v8_compile("obj2.knurd")->Run()->NumberValue()); CHECK(v8_compile("'knurd' in obj2")->Run()->BooleanValue()); CHECK_EQ(10.1, v8_compile("obj2.v2")->Run()->NumberValue()); // base1 and base2 cannot cross reference to each's prototype CHECK(v8_compile("obj.v2")->Run()->IsUndefined()); CHECK(v8_compile("obj2.v1")->Run()->IsUndefined());}int echo_named_call_count;static v8::Handle<Value> EchoNamedProperty(Local<String> name, const AccessorInfo& info) { ApiTestFuzzer::Fuzz(); CHECK_EQ(v8_str("data"), info.Data()); echo_named_call_count++; return name;}THREADED_TEST(NamedPropertyHandlerGetter) { echo_named_call_count = 0; v8::HandleScope scope; v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); templ->InstanceTemplate()->SetNamedPropertyHandler(EchoNamedProperty, 0, 0, 0, 0, v8_str("data"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -