| Index: dart/runtime/vm/object_test.cc
|
| ===================================================================
|
| --- dart/runtime/vm/object_test.cc (revision 31530)
|
| +++ dart/runtime/vm/object_test.cc (working copy)
|
| @@ -332,6 +332,32 @@
|
| }
|
|
|
|
|
| +TEST_CASE(StringEncodeURI) {
|
| + const char* kInput =
|
| + "file:///usr/local/johnmccutchan/workspace/dart-repo/dart/test.dart";
|
| + const char* kOutput =
|
| + "file%3A%2F%2F%2Fusr%2Flocal%2Fjohnmccutchan%2Fworkspace%2F"
|
| + "dart-repo%2Fdart%2Ftest.dart";
|
| + const String& input = String::Handle(String::New(kInput));
|
| + const String& output = String::Handle(String::New(kOutput));
|
| + const String& encoded = String::Handle(String::EncodeURI(input));
|
| + EXPECT(output.Equals(encoded));
|
| +}
|
| +
|
| +
|
| +TEST_CASE(StringDecodeURI) {
|
| + const char* kOutput =
|
| + "file:///usr/local/johnmccutchan/workspace/dart-repo/dart/test.dart";
|
| + const char* kInput =
|
| + "file%3A%2F%2F%2Fusr%2Flocal%2Fjohnmccutchan%2Fworkspace%2F"
|
| + "dart-repo%2Fdart%2Ftest.dart";
|
| + const String& input = String::Handle(String::New(kInput));
|
| + const String& output = String::Handle(String::New(kOutput));
|
| + const String& decoded = String::Handle(String::DecodeURI(input));
|
| + EXPECT(output.Equals(decoded));
|
| +}
|
| +
|
| +
|
| TEST_CASE(Mint) {
|
| // On 64-bit architectures a Smi is stored in a 64 bit word. A Midint cannot
|
| // be allocated if it does fit into a Smi.
|
| @@ -2749,6 +2775,8 @@
|
| }
|
|
|
|
|
| +
|
| +
|
| // Expose helper function from object.cc for testing.
|
| bool EqualsIgnoringPrivate(const String& name, const String& private_name);
|
|
|
| @@ -3391,6 +3419,193 @@
|
| }
|
|
|
|
|
| +TEST_CASE(FindFieldIndex) {
|
| + const char* kScriptChars =
|
| + "class A {\n"
|
| + " var a;\n"
|
| + " var b;\n"
|
| + "}\n"
|
| + "class B {\n"
|
| + " var d;\n"
|
| + "}\n"
|
| + "test() {\n"
|
| + " new A();\n"
|
| + " new B();\n"
|
| + "}";
|
| + Dart_Handle h_lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
| + EXPECT_VALID(h_lib);
|
| + Dart_Handle result = Dart_Invoke(h_lib, NewString("test"), 0, NULL);
|
| + EXPECT_VALID(result);
|
| + Library& lib = Library::Handle();
|
| + lib ^= Api::UnwrapHandle(h_lib);
|
| + EXPECT(!lib.IsNull());
|
| + const Class& class_a = Class::Handle(GetClass(lib, "A"));
|
| + const Array& class_a_fields = Array::Handle(class_a.fields());
|
| + const Class& class_b = Class::Handle(GetClass(lib, "B"));
|
| + const Field& field_a = Field::Handle(GetField(class_a, "a"));
|
| + const Field& field_b = Field::Handle(GetField(class_a, "b"));
|
| + const Field& field_d = Field::Handle(GetField(class_b, "d"));
|
| + intptr_t field_a_index = class_a.FindFieldIndex(field_a);
|
| + intptr_t field_b_index = class_a.FindFieldIndex(field_b);
|
| + intptr_t field_d_index = class_a.FindFieldIndex(field_d);
|
| + // Valid index.
|
| + EXPECT_GE(field_a_index, 0);
|
| + // Valid index.
|
| + EXPECT_GE(field_b_index, 0);
|
| + // Invalid index.
|
| + EXPECT_EQ(field_d_index, -1);
|
| + Field& field_a_from_index = Field::Handle();
|
| + field_a_from_index ^= class_a_fields.At(field_a_index);
|
| + ASSERT(!field_a_from_index.IsNull());
|
| + // Same field.
|
| + EXPECT_EQ(field_a.raw(), field_a_from_index.raw());
|
| + Field& field_b_from_index = Field::Handle();
|
| + field_b_from_index ^= class_a_fields.At(field_b_index);
|
| + ASSERT(!field_b_from_index.IsNull());
|
| + // Same field.
|
| + EXPECT_EQ(field_b.raw(), field_b_from_index.raw());
|
| +}
|
| +
|
| +
|
| +TEST_CASE(FindFunctionIndex) {
|
| + // Tests both FindFunctionIndex and FindImplicitClosureFunctionIndex.
|
| + const char* kScriptChars =
|
| + "class A {\n"
|
| + " void a() {}\n"
|
| + " Function b() { return a; }\n"
|
| + "}\n"
|
| + "class B {\n"
|
| + " dynamic d() {}\n"
|
| + "}\n"
|
| + "var x;\n"
|
| + "test() {\n"
|
| + " x = new A().b();\n"
|
| + " x();\n"
|
| + " new B();\n"
|
| + " return x;\n"
|
| + "}";
|
| + Dart_Handle h_lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
| + EXPECT_VALID(h_lib);
|
| + Dart_Handle result = Dart_Invoke(h_lib, NewString("test"), 0, NULL);
|
| + EXPECT_VALID(result);
|
| + Library& lib = Library::Handle();
|
| + lib ^= Api::UnwrapHandle(h_lib);
|
| + EXPECT(!lib.IsNull());
|
| + const Class& class_a = Class::Handle(GetClass(lib, "A"));
|
| + const Class& class_b = Class::Handle(GetClass(lib, "B"));
|
| + const Function& func_a = Function::Handle(GetFunction(class_a, "a"));
|
| + const Function& func_b = Function::Handle(GetFunction(class_a, "b"));
|
| + const Function& func_d = Function::Handle(GetFunction(class_b, "d"));
|
| + EXPECT(func_a.HasImplicitClosureFunction());
|
| + const Function& func_x = Function::Handle(func_a.ImplicitClosureFunction());
|
| + intptr_t func_a_index = class_a.FindFunctionIndex(func_a);
|
| + intptr_t func_b_index = class_a.FindFunctionIndex(func_b);
|
| + intptr_t func_d_index = class_a.FindFunctionIndex(func_d);
|
| + intptr_t func_x_index = class_a.FindImplicitClosureFunctionIndex(func_x);
|
| + // Valid index.
|
| + EXPECT_GE(func_a_index, 0);
|
| + // Valid index.
|
| + EXPECT_GE(func_b_index, 0);
|
| + // Invalid index.
|
| + EXPECT_EQ(func_d_index, -1);
|
| + // Valid index.
|
| + EXPECT_GE(func_x_index, 0);
|
| + Function& func_a_from_index = Function::Handle();
|
| + func_a_from_index ^= class_a.FunctionFromIndex(func_a_index);
|
| + EXPECT(!func_a_from_index.IsNull());
|
| + // Same function.
|
| + EXPECT_EQ(func_a.raw(), func_a_from_index.raw());
|
| + Function& func_b_from_index = Function::Handle();
|
| + func_b_from_index ^= class_a.FunctionFromIndex(func_b_index);
|
| + EXPECT(!func_b_from_index.IsNull());
|
| + // Same function.
|
| + EXPECT_EQ(func_b.raw(), func_b_from_index.raw());
|
| + // Retrieve implicit closure function.
|
| + Function& func_x_from_index = Function::Handle();
|
| + func_x_from_index ^= class_a.ImplicitClosureFunctionFromIndex(func_x_index);
|
| + EXPECT_EQ(func_x.raw(), func_x_from_index.raw());
|
| +}
|
| +
|
| +
|
| +TEST_CASE(FindClosureIndex) {
|
| + // Allocate the class first.
|
| + const String& class_name = String::Handle(Symbols::New("MyClass"));
|
| + const Script& script = Script::Handle();
|
| + const Class& cls = Class::Handle(CreateDummyClass(class_name, script));
|
| + const Array& functions = Array::Handle(Array::New(1));
|
| +
|
| + Function& parent = Function::Handle();
|
| + const String& parent_name = String::Handle(Symbols::New("foo_papa"));
|
| + parent = Function::New(parent_name, RawFunction::kRegularFunction,
|
| + false, false, false, false, false, cls, 0);
|
| + functions.SetAt(0, parent);
|
| + cls.SetFunctions(functions);
|
| +
|
| + Function& function = Function::Handle();
|
| + const String& function_name = String::Handle(Symbols::New("foo"));
|
| + function = Function::NewClosureFunction(function_name, parent, 0);
|
| + // Add closure function to class.
|
| + cls.AddClosureFunction(function);
|
| +
|
| + // The closure should return a valid index.
|
| + intptr_t good_closure_index = cls.FindClosureIndex(function);
|
| + EXPECT_GE(good_closure_index, 0);
|
| + // The parent function should return an invalid index.
|
| + intptr_t bad_closure_index = cls.FindClosureIndex(parent);
|
| + EXPECT_EQ(bad_closure_index, -1);
|
| +
|
| + // Retrieve closure function via index.
|
| + Function& func_from_index = Function::Handle();
|
| + func_from_index ^= cls.ClosureFunctionFromIndex(good_closure_index);
|
| + // Same closure function.
|
| + EXPECT_EQ(func_from_index.raw(), function.raw());
|
| +}
|
| +
|
| +
|
| +TEST_CASE(FindInvocationDispatcherFunctionIndex) {
|
| + const String& class_name = String::Handle(Symbols::New("MyClass"));
|
| + const Script& script = Script::Handle();
|
| + const Class& cls = Class::Handle(CreateDummyClass(class_name, script));
|
| + ClassFinalizer::FinalizeTypesInClass(cls);
|
| +
|
| + const Array& functions = Array::Handle(Array::New(1));
|
| + Function& parent = Function::Handle();
|
| + const String& parent_name = String::Handle(Symbols::New("foo_papa"));
|
| + parent = Function::New(parent_name, RawFunction::kRegularFunction,
|
| + false, false, false, false, false, cls, 0);
|
| + functions.SetAt(0, parent);
|
| + cls.SetFunctions(functions);
|
| + cls.Finalize();
|
| +
|
| + // Add invocation dispatcher.
|
| + const String& invocation_dispatcher_name =
|
| + String::Handle(Symbols::New("myMethod"));
|
| + const Array& args_desc = Array::Handle(ArgumentsDescriptor::New(1));
|
| + Function& invocation_dispatcher = Function::Handle();
|
| + invocation_dispatcher ^=
|
| + cls.GetInvocationDispatcher(invocation_dispatcher_name, args_desc,
|
| + RawFunction::kNoSuchMethodDispatcher);
|
| + EXPECT(!invocation_dispatcher.IsNull());
|
| + // Get index to function.
|
| + intptr_t invocation_dispatcher_index =
|
| + cls.FindInvocationDispatcherFunctionIndex(invocation_dispatcher);
|
| + // Expect a valid index.
|
| + EXPECT_GE(invocation_dispatcher_index, 0);
|
| + // Retrieve function through index.
|
| + Function& invocation_dispatcher_from_index = Function::Handle();
|
| + invocation_dispatcher_from_index ^=
|
| + cls.InvocationDispatcherFunctionFromIndex(invocation_dispatcher_index);
|
| + // Same function.
|
| + EXPECT_EQ(invocation_dispatcher.raw(),
|
| + invocation_dispatcher_from_index.raw());
|
| + // Test function not found case.
|
| + const Function& bad_function = Function::Handle(Function::null());
|
| + intptr_t bad_invocation_dispatcher_index =
|
| + cls.FindInvocationDispatcherFunctionIndex(bad_function);
|
| + EXPECT_EQ(bad_invocation_dispatcher_index, -1);
|
| +}
|
| +
|
| +
|
| static void PrintMetadata(const char* name, const Object& data) {
|
| if (data.IsError()) {
|
| OS::Print("Error in metadata evaluation for %s: '%s'\n",
|
|
|