Add tests for FuncNameInferrer.
authormarja@chromium.org <marja@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 3 Jun 2014 15:02:16 +0000 (15:02 +0000)
committermarja@chromium.org <marja@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 3 Jun 2014 15:02:16 +0000 (15:02 +0000)
There were no explicit tests for FuncNameInferrer (though, some tests might
implicitly rely on it working properly in the common cases). Afaics, there were
no tests which would exercise inferring two byte function names or escaped
function names.

R=rossberg@chromium.org
BUG=

Review URL: https://codereview.chromium.org/310063002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21649 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

test/cctest/cctest.h
test/cctest/test-api.cc
test/cctest/test-parsing.cc

index edb1de9..a357be4 100644 (file)
@@ -311,6 +311,15 @@ class LocalContext {
   v8::Isolate* isolate_;
 };
 
+
+static inline uint16_t* AsciiToTwoByteString(const char* source) {
+  int array_length = i::StrLength(source) + 1;
+  uint16_t* converted = i::NewArray<uint16_t>(array_length);
+  for (int i = 0; i < array_length; i++) converted[i] = source[i];
+  return converted;
+}
+
+
 static inline v8::Local<v8::Value> v8_num(double x) {
   return v8::Number::New(v8::Isolate::GetCurrent(), x);
 }
@@ -403,6 +412,52 @@ static inline v8::Local<v8::Value> CompileRunWithOrigin(
 }
 
 
+
+static inline void ExpectString(const char* code, const char* expected) {
+  v8::Local<v8::Value> result = CompileRun(code);
+  CHECK(result->IsString());
+  v8::String::Utf8Value utf8(result);
+  CHECK_EQ(expected, *utf8);
+}
+
+
+static inline void ExpectInt32(const char* code, int expected) {
+  v8::Local<v8::Value> result = CompileRun(code);
+  CHECK(result->IsInt32());
+  CHECK_EQ(expected, result->Int32Value());
+}
+
+
+static inline void ExpectBoolean(const char* code, bool expected) {
+  v8::Local<v8::Value> result = CompileRun(code);
+  CHECK(result->IsBoolean());
+  CHECK_EQ(expected, result->BooleanValue());
+}
+
+
+static inline void ExpectTrue(const char* code) {
+  ExpectBoolean(code, true);
+}
+
+
+static inline void ExpectFalse(const char* code) {
+  ExpectBoolean(code, false);
+}
+
+
+static inline void ExpectObject(const char* code,
+                                v8::Local<v8::Value> expected) {
+  v8::Local<v8::Value> result = CompileRun(code);
+  CHECK(result->SameValue(expected));
+}
+
+
+static inline void ExpectUndefined(const char* code) {
+  v8::Local<v8::Value> result = CompileRun(code);
+  CHECK(result->IsUndefined());
+}
+
+
 // Helper function that simulates a full new-space in the heap.
 static inline void SimulateFullSpace(v8::internal::NewSpace* space) {
   int new_linear_size = static_cast<int>(
index 54a9932..2f39b3f 100644 (file)
@@ -99,50 +99,6 @@ void RunWithProfiler(void (*test)()) {
 }
 
 
-static void ExpectString(const char* code, const char* expected) {
-  Local<Value> result = CompileRun(code);
-  CHECK(result->IsString());
-  String::Utf8Value utf8(result);
-  CHECK_EQ(expected, *utf8);
-}
-
-
-static void ExpectInt32(const char* code, int expected) {
-  Local<Value> result = CompileRun(code);
-  CHECK(result->IsInt32());
-  CHECK_EQ(expected, result->Int32Value());
-}
-
-
-static void ExpectBoolean(const char* code, bool expected) {
-  Local<Value> result = CompileRun(code);
-  CHECK(result->IsBoolean());
-  CHECK_EQ(expected, result->BooleanValue());
-}
-
-
-static void ExpectTrue(const char* code) {
-  ExpectBoolean(code, true);
-}
-
-
-static void ExpectFalse(const char* code) {
-  ExpectBoolean(code, false);
-}
-
-
-static void ExpectObject(const char* code, Local<Value> expected) {
-  Local<Value> result = CompileRun(code);
-  CHECK(result->Equals(expected));
-}
-
-
-static void ExpectUndefined(const char* code) {
-  Local<Value> result = CompileRun(code);
-  CHECK(result->IsUndefined());
-}
-
-
 static int signature_callback_count;
 static Local<Value> signature_expected_receiver;
 static void IncrementingSignatureCallback(
@@ -451,14 +407,6 @@ THREADED_TEST(Script) {
 }
 
 
-static uint16_t* AsciiToTwoByteString(const char* source) {
-  int array_length = i::StrLength(source) + 1;
-  uint16_t* converted = i::NewArray<uint16_t>(array_length);
-  for (int i = 0; i < array_length; i++) converted[i] = source[i];
-  return converted;
-}
-
-
 class TestResource: public String::ExternalStringResource {
  public:
   TestResource(uint16_t* data, int* counter = NULL, bool owning_data = true)
index 15fdbdc..f6cf94e 100644 (file)
@@ -2457,3 +2457,89 @@ TEST(InvalidLeftHandSide) {
   RunParserSyncTest(postfix_context_data, good_statement_data, kSuccess);
   RunParserSyncTest(postfix_context_data, bad_statement_data_common, kError);
 }
+
+
+TEST(FuncNameInferrerBasic) {
+  // Tests that function names are inferred properly.
+  i::FLAG_allow_natives_syntax = true;
+  v8::Isolate* isolate = CcTest::isolate();
+  v8::HandleScope scope(isolate);
+  LocalContext env;
+  CompileRun("var foo1 = function() {}; "
+             "var foo2 = function foo3() {}; "
+             "function not_ctor() { "
+             "  var foo4 = function() {}; "
+             "  return %FunctionGetInferredName(foo4); "
+             "} "
+             "function Ctor() { "
+             "  var foo5 = function() {}; "
+             "  return %FunctionGetInferredName(foo5); "
+             "} "
+             "var obj1 = { foo6: function() {} }; "
+             "var obj2 = { 'foo7': function() {} }; "
+             "var obj3 = {}; "
+             "obj3[1] = function() {}; "
+             "var obj4 = {}; "
+             "obj4[1] = function foo8() {}; "
+             "var obj5 = {}; "
+             "obj5['foo9'] = function() {}; "
+             "var obj6 = { obj7 : { foo10: function() {} } };");
+  ExpectString("%FunctionGetInferredName(foo1)", "foo1");
+  // foo2 is not unnamed -> its name is not inferred.
+  ExpectString("%FunctionGetInferredName(foo2)", "");
+  ExpectString("not_ctor()", "foo4");
+  ExpectString("Ctor()", "Ctor.foo5");
+  ExpectString("%FunctionGetInferredName(obj1.foo6)", "obj1.foo6");
+  ExpectString("%FunctionGetInferredName(obj2.foo7)", "obj2.foo7");
+  ExpectString("%FunctionGetInferredName(obj3[1])",
+               "obj3.(anonymous function)");
+  ExpectString("%FunctionGetInferredName(obj4[1])", "");
+  ExpectString("%FunctionGetInferredName(obj5['foo9'])", "obj5.foo9");
+  ExpectString("%FunctionGetInferredName(obj6.obj7.foo10)", "obj6.obj7.foo10");
+}
+
+
+TEST(FuncNameInferrerTwoByte) {
+  // Tests function name inferring in cases where some parts of the inferred
+  // function name are two-byte strings.
+  i::FLAG_allow_natives_syntax = true;
+  v8::Isolate* isolate = CcTest::isolate();
+  v8::HandleScope scope(isolate);
+  LocalContext env;
+  uint16_t* two_byte_source = AsciiToTwoByteString(
+      "var obj1 = { oXj2 : { foo1: function() {} } }; "
+      "%FunctionGetInferredName(obj1.oXj2.foo1)");
+  uint16_t* two_byte_name = AsciiToTwoByteString("obj1.oXj2.foo1");
+  // Make it really non-ASCII (replace the Xs with a non-ASCII character).
+  two_byte_source[14] = two_byte_source[78] = two_byte_name[6] = 0x010d;
+  v8::Local<v8::String> source =
+      v8::String::NewFromTwoByte(isolate, two_byte_source);
+  v8::Local<v8::Value> result = CompileRun(source);
+  CHECK(result->IsString());
+  v8::Local<v8::String> expected_name =
+      v8::String::NewFromTwoByte(isolate, two_byte_name);
+  CHECK(result->Equals(expected_name));
+}
+
+
+TEST(FuncNameInferrerEscaped) {
+  // The same as FuncNameInferrerTwoByte, except that we express the two-byte
+  // character as a unicode escape.
+  i::FLAG_allow_natives_syntax = true;
+  v8::Isolate* isolate = CcTest::isolate();
+  v8::HandleScope scope(isolate);
+  LocalContext env;
+  uint16_t* two_byte_source = AsciiToTwoByteString(
+      "var obj1 = { o\\u010dj2 : { foo1: function() {} } }; "
+      "%FunctionGetInferredName(obj1.o\\u010dj2.foo1)");
+  uint16_t* two_byte_name = AsciiToTwoByteString("obj1.oXj2.foo1");
+  // Fix to correspond to the non-ASCII name in two_byte_source.
+  two_byte_name[6] = 0x010d;
+  v8::Local<v8::String> source =
+      v8::String::NewFromTwoByte(isolate, two_byte_source);
+  v8::Local<v8::Value> result = CompileRun(source);
+  CHECK(result->IsString());
+  v8::Local<v8::String> expected_name =
+      v8::String::NewFromTwoByte(isolate, two_byte_name);
+  CHECK(result->Equals(expected_name));
+}