Index: test/cctest/test-api.cc |
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc |
index db0831c405c27ea65ae6525c9ad99af9cb18bb8b..a48daf6a981548845a19935b430e9e7eb05a8207 100644 |
--- a/test/cctest/test-api.cc |
+++ b/test/cctest/test-api.cc |
@@ -23000,3 +23000,77 @@ TEST(GetOwnPropertyDescriptor) { |
set->Call(x, 1, args); |
CHECK_EQ(v8_num(14), get->Call(x, 0, NULL)); |
} |
+ |
+class TestSourceStream : public v8::ScriptCompiler::ExternalSourceStream { |
+ public: |
+ explicit TestSourceStream(const char** chunks) : chunks_(chunks), index_(0) { |
+ SetEncoding(v8::ScriptCompiler::ExternalSourceStream::ONE_BYTE); |
+ } |
+ |
+ virtual unsigned GetMoreData(const char** src) { |
+ // Unlike in real use cases, this function will never block. |
+ if (chunks_[index_] == NULL) { |
+ return 0; |
+ } |
+ // Copy the data, since the caller takes ownership of it. |
+ unsigned len = strlen(chunks_[index_]); |
Sven Panne
2014/09/01 09:07:46
size_t
marja
2014/09/01 11:58:17
Done.
|
+ // snprintf will NULL-terminate, so reserve space for the NULL too. However, |
Sven Panne
2014/09/01 09:07:46
Nit: It zero-terminates, not NULL-terminates. :-)
marja
2014/09/01 11:58:17
Done.
|
+ // the caller is not interested in the NULL; we will return the real length |
+ // below. |
+ char* copy = new char[len + 1]; |
+ snprintf(copy, len + 1, "%s", chunks_[index_]); |
Sven Panne
2014/09/01 09:07:46
Wouldn't memcpy simplify things here and below?
marja
2014/09/01 11:58:17
Yes, but presubmit whines about it :(
jochen (gone - plz use gerrit)
2014/09/01 13:16:32
why not strncpy?
marja
2014/09/01 13:23:25
Argh, this discussion was confused.
So I original
|
+ *src = copy; |
+ ++index_; |
+ return len; |
+ } |
+ |
+ // Helper for constructing a string from chunks (the compilation needs it |
+ // too). |
+ static char* FullSourceString(const char** chunks) { |
+ size_t total_len = 0; |
+ for (size_t i = 0; chunks[i] != NULL; ++i) { |
+ total_len += strlen(chunks[i]); |
+ } |
+ char* full_string = new char[total_len + 1]; |
+ size_t offset = 0; |
+ for (size_t i = 0; chunks[i] != NULL; ++i) { |
+ size_t len = strlen(chunks[i]); |
+ snprintf(full_string + offset, len + 1, "%s", chunks[i]); |
+ offset += len; |
+ } |
+ return full_string; |
+ } |
+ |
+ private: |
+ const char** chunks_; |
+ unsigned index_; |
+}; |
+ |
+ |
+TEST(StreamingSimpleScript) { |
+ LocalContext env; |
+ v8::Isolate* isolate = env->GetIsolate(); |
+ v8::HandleScope scope(isolate); |
+ |
+ // This script is unrealistically small, since no one chunk is enough to fill |
+ // the backing buffer of Scanner, let alone overflow it. Other tests will |
+ // cover those cases. |
+ const char* chunks[] = {"function foo() { ret", "urn 3; } f", "oo(); ", NULL}; |
+ v8::ScriptCompiler::StreamedSource source(new TestSourceStream(chunks)); |
+ v8::ScriptCompiler::ScriptStreamingTask* task = |
+ v8::ScriptCompiler::StartStreamingScript(isolate, &source); |
+ |
+ // TestSourceStream::GetMoreData won't block, so it's okay to just run the |
+ // task here in the main thread. |
+ task->Run(); |
+ delete task; |
+ |
+ v8::ScriptOrigin origin(v8_str("http://foo.com")); |
+ char* full_source = TestSourceStream::FullSourceString(chunks); |
+ v8::Handle<Script> script = v8::ScriptCompiler::Compile( |
+ isolate, &source, v8_str(full_source), origin); |
+ CHECK(!script.IsEmpty()); |
+ v8::Handle<Value> result(script->Run()); |
+ CHECK_EQ(3, result->Int32Value()); |
+ delete[] full_source; |
+} |