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", |