mirror of
https://github.com/denoland/deno.git
synced 2025-09-27 12:49:10 +00:00
Refactor libdeno ES module interface. (#1624)
Allows for future asynchronous module loading. Add support for import.meta.url Fixes #1496
This commit is contained in:
parent
7d278a0383
commit
00597ffde1
23 changed files with 884 additions and 467 deletions
|
@ -3,18 +3,18 @@
|
|||
|
||||
TEST(LibDenoTest, InitializesCorrectly) {
|
||||
EXPECT_NE(snapshot.data_ptr, nullptr);
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr, nullptr});
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr});
|
||||
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "1 + 2"));
|
||||
deno_delete(d);
|
||||
}
|
||||
|
||||
TEST(LibDenoTest, Snapshotter) {
|
||||
Deno* d1 = deno_new(deno_config{1, empty, empty, nullptr, nullptr});
|
||||
Deno* d1 = deno_new(deno_config{1, empty, empty, nullptr});
|
||||
EXPECT_TRUE(deno_execute(d1, nullptr, "a.js", "a = 1 + 2"));
|
||||
deno_buf test_snapshot = deno_get_snapshot(d1);
|
||||
deno_delete(d1);
|
||||
|
||||
Deno* d2 = deno_new(deno_config{0, test_snapshot, empty, nullptr, nullptr});
|
||||
Deno* d2 = deno_new(deno_config{0, test_snapshot, empty, nullptr});
|
||||
EXPECT_TRUE(
|
||||
deno_execute(d2, nullptr, "b.js", "if (a != 3) throw Error('x');"));
|
||||
deno_delete(d2);
|
||||
|
@ -23,14 +23,14 @@ TEST(LibDenoTest, Snapshotter) {
|
|||
}
|
||||
|
||||
TEST(LibDenoTest, CanCallFunction) {
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr, nullptr});
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr});
|
||||
EXPECT_TRUE(deno_execute(d, nullptr, "a.js",
|
||||
"if (CanCallFunction() != 'foo') throw Error();"));
|
||||
deno_delete(d);
|
||||
}
|
||||
|
||||
TEST(LibDenoTest, ErrorsCorrectly) {
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr, nullptr});
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr});
|
||||
EXPECT_FALSE(deno_execute(d, nullptr, "a.js", "throw Error()"));
|
||||
deno_delete(d);
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ TEST(LibDenoTest, RecvReturnEmpty) {
|
|||
EXPECT_EQ(buf.data_ptr[1], 'b');
|
||||
EXPECT_EQ(buf.data_ptr[2], 'c');
|
||||
};
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb, nullptr});
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb});
|
||||
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "RecvReturnEmpty()"));
|
||||
EXPECT_EQ(count, 2);
|
||||
deno_delete(d);
|
||||
|
@ -93,14 +93,14 @@ TEST(LibDenoTest, RecvReturnBar) {
|
|||
EXPECT_EQ(buf.data_ptr[2], 'c');
|
||||
deno_respond(d, user_data, req_id, strbuf("bar"));
|
||||
};
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb, nullptr});
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb});
|
||||
EXPECT_TRUE(deno_execute(d, d, "a.js", "RecvReturnBar()"));
|
||||
EXPECT_EQ(count, 1);
|
||||
deno_delete(d);
|
||||
}
|
||||
|
||||
TEST(LibDenoTest, DoubleRecvFails) {
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr, nullptr});
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr});
|
||||
EXPECT_FALSE(deno_execute(d, nullptr, "a.js", "DoubleRecvFails()"));
|
||||
deno_delete(d);
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ TEST(LibDenoTest, SendRecvSlice) {
|
|||
// Send back.
|
||||
deno_respond(d, user_data, req_id, buf2);
|
||||
};
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb, nullptr});
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb});
|
||||
EXPECT_TRUE(deno_execute(d, d, "a.js", "SendRecvSlice()"));
|
||||
EXPECT_EQ(count, 5);
|
||||
deno_delete(d);
|
||||
|
@ -151,26 +151,26 @@ TEST(LibDenoTest, JSSendArrayBufferViewTypes) {
|
|||
EXPECT_EQ(buf.alloc_len, 4321u);
|
||||
EXPECT_EQ(buf.data_ptr[0], count);
|
||||
};
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb, nullptr});
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb});
|
||||
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "JSSendArrayBufferViewTypes()"));
|
||||
EXPECT_EQ(count, 3);
|
||||
deno_delete(d);
|
||||
}
|
||||
|
||||
TEST(LibDenoTest, TypedArraySnapshots) {
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr, nullptr});
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr});
|
||||
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "TypedArraySnapshots()"));
|
||||
deno_delete(d);
|
||||
}
|
||||
|
||||
TEST(LibDenoTest, SnapshotBug) {
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr, nullptr});
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr});
|
||||
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "SnapshotBug()"));
|
||||
deno_delete(d);
|
||||
}
|
||||
|
||||
TEST(LibDenoTest, GlobalErrorHandling) {
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr, nullptr});
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr});
|
||||
EXPECT_FALSE(deno_execute(d, nullptr, "a.js", "GlobalErrorHandling()"));
|
||||
std::string expected =
|
||||
"{\"message\":\"Uncaught ReferenceError: notdefined is not defined\","
|
||||
|
@ -199,7 +199,7 @@ TEST(LibDenoTest, DataBuf) {
|
|||
EXPECT_EQ(buf.data_ptr[0], 1);
|
||||
EXPECT_EQ(buf.data_ptr[1], 2);
|
||||
};
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb, nullptr});
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb});
|
||||
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "DataBuf()"));
|
||||
EXPECT_EQ(count, 1);
|
||||
// data_buf was subsequently changed in JS, let's check that our copy reflects
|
||||
|
@ -212,7 +212,7 @@ TEST(LibDenoTest, DataBuf) {
|
|||
TEST(LibDenoTest, CheckPromiseErrors) {
|
||||
static int count = 0;
|
||||
auto recv_cb = [](auto _, int req_id, auto buf, auto data_buf) { count++; };
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb, nullptr});
|
||||
Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb});
|
||||
EXPECT_EQ(deno_last_exception(d), nullptr);
|
||||
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "CheckPromiseErrors()"));
|
||||
EXPECT_EQ(deno_last_exception(d), nullptr);
|
||||
|
@ -225,7 +225,7 @@ TEST(LibDenoTest, CheckPromiseErrors) {
|
|||
}
|
||||
|
||||
TEST(LibDenoTest, LastException) {
|
||||
Deno* d = deno_new(deno_config{0, empty, empty, nullptr, nullptr});
|
||||
Deno* d = deno_new(deno_config{0, empty, empty, nullptr});
|
||||
EXPECT_EQ(deno_last_exception(d), nullptr);
|
||||
EXPECT_FALSE(deno_execute(d, nullptr, "a.js", "\n\nthrow Error('boo');\n\n"));
|
||||
EXPECT_STREQ(deno_last_exception(d),
|
||||
|
@ -240,7 +240,7 @@ TEST(LibDenoTest, LastException) {
|
|||
}
|
||||
|
||||
TEST(LibDenoTest, EncodeErrorBug) {
|
||||
Deno* d = deno_new(deno_config{0, empty, empty, nullptr, nullptr});
|
||||
Deno* d = deno_new(deno_config{0, empty, empty, nullptr});
|
||||
EXPECT_EQ(deno_last_exception(d), nullptr);
|
||||
EXPECT_FALSE(deno_execute(d, nullptr, "a.js", "eval('a')"));
|
||||
EXPECT_STREQ(
|
||||
|
@ -259,117 +259,10 @@ TEST(LibDenoTest, EncodeErrorBug) {
|
|||
TEST(LibDenoTest, Shared) {
|
||||
uint8_t s[] = {0, 1, 2};
|
||||
deno_buf shared = {nullptr, 0, s, 3};
|
||||
Deno* d = deno_new(deno_config{0, snapshot, shared, nullptr, nullptr});
|
||||
Deno* d = deno_new(deno_config{0, snapshot, shared, nullptr});
|
||||
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "Shared()"));
|
||||
EXPECT_EQ(s[0], 42);
|
||||
EXPECT_EQ(s[1], 43);
|
||||
EXPECT_EQ(s[2], 44);
|
||||
deno_delete(d);
|
||||
}
|
||||
|
||||
static const char* mod_a =
|
||||
"import { retb } from 'b.js'\n"
|
||||
"if (retb() != 'b') throw Error();";
|
||||
|
||||
static const char* mod_b = "export function retb() { return 'b' }";
|
||||
|
||||
TEST(LibDenoTest, ModuleResolution) {
|
||||
static int count = 0;
|
||||
auto resolve_cb = [](void* user_data, const char* specifier,
|
||||
const char* referrer) {
|
||||
EXPECT_STREQ(specifier, "b.js");
|
||||
EXPECT_STREQ(referrer, "a.js");
|
||||
count++;
|
||||
auto d = reinterpret_cast<Deno*>(user_data);
|
||||
deno_resolve_ok(d, "b.js", mod_b);
|
||||
};
|
||||
Deno* d = deno_new(deno_config{0, empty, empty, nullptr, resolve_cb});
|
||||
EXPECT_TRUE(deno_execute_mod(d, d, "a.js", mod_a, false));
|
||||
EXPECT_EQ(count, 1);
|
||||
deno_delete(d);
|
||||
}
|
||||
|
||||
TEST(LibDenoTest, ModuleResolutionFail) {
|
||||
static int count = 0;
|
||||
auto resolve_cb = [](void* user_data, const char* specifier,
|
||||
const char* referrer) {
|
||||
EXPECT_STREQ(specifier, "b.js");
|
||||
EXPECT_STREQ(referrer, "a.js");
|
||||
count++;
|
||||
// Do not call deno_resolve_ok();
|
||||
};
|
||||
Deno* d = deno_new(deno_config{0, empty, empty, nullptr, resolve_cb});
|
||||
EXPECT_FALSE(deno_execute_mod(d, d, "a.js", mod_a, false));
|
||||
EXPECT_EQ(count, 1);
|
||||
deno_delete(d);
|
||||
}
|
||||
|
||||
TEST(LibDenoTest, ModuleSnapshot) {
|
||||
Deno* d1 = deno_new(deno_config{1, empty, empty, nullptr, nullptr});
|
||||
EXPECT_TRUE(deno_execute_mod(d1, nullptr, "x.js",
|
||||
"const globalEval = eval\n"
|
||||
"const global = globalEval('this')\n"
|
||||
"global.a = 1 + 2",
|
||||
0));
|
||||
deno_buf test_snapshot = deno_get_snapshot(d1);
|
||||
deno_delete(d1);
|
||||
|
||||
const char* y_src = "if (a != 3) throw Error('x');";
|
||||
|
||||
deno_config config{0, test_snapshot, empty, nullptr, nullptr};
|
||||
Deno* d2 = deno_new(config);
|
||||
EXPECT_TRUE(deno_execute(d2, nullptr, "y.js", y_src));
|
||||
deno_delete(d2);
|
||||
|
||||
Deno* d3 = deno_new(config);
|
||||
EXPECT_TRUE(deno_execute_mod(d3, nullptr, "y.js", y_src, false));
|
||||
deno_delete(d3);
|
||||
|
||||
delete[] test_snapshot.data_ptr;
|
||||
}
|
||||
|
||||
TEST(LibDenoTest, ModuleResolveOnly) {
|
||||
static int count = 0;
|
||||
auto resolve_cb = [](void* user_data, const char* specifier,
|
||||
const char* referrer) {
|
||||
EXPECT_STREQ(specifier, "b.js");
|
||||
EXPECT_STREQ(referrer, "a.js");
|
||||
count++;
|
||||
auto d = reinterpret_cast<Deno*>(user_data);
|
||||
deno_resolve_ok(d, "b.js", mod_b);
|
||||
};
|
||||
Deno* d = deno_new(deno_config{0, empty, empty, nullptr, resolve_cb});
|
||||
// Code should not execute. If executed, the error would be thrown
|
||||
EXPECT_TRUE(deno_execute_mod(d, d, "a.js",
|
||||
"import { retb } from 'b.js'\n"
|
||||
"throw Error('unreachable');",
|
||||
true));
|
||||
EXPECT_EQ(count, 1);
|
||||
deno_delete(d);
|
||||
}
|
||||
|
||||
TEST(LibDenoTest, BuiltinModules) {
|
||||
static int count = 0;
|
||||
auto resolve_cb = [](void* user_data, const char* specifier,
|
||||
const char* referrer) {
|
||||
EXPECT_STREQ(specifier, "b.js");
|
||||
EXPECT_STREQ(referrer, "c.js");
|
||||
count++;
|
||||
auto d = reinterpret_cast<Deno*>(user_data);
|
||||
deno_resolve_ok(d, "b.js", mod_b);
|
||||
};
|
||||
Deno* d = deno_new(deno_config{0, empty, empty, nullptr, resolve_cb});
|
||||
EXPECT_TRUE(deno_execute(
|
||||
d, d, "setup.js", "libdeno.builtinModules['deno'] = { foo: 'bar' }; \n"));
|
||||
EXPECT_EQ(count, 0);
|
||||
EXPECT_TRUE(
|
||||
deno_execute_mod(d, d, "c.js",
|
||||
"import { retb } from 'b.js'\n"
|
||||
"import * as deno from 'deno'\n"
|
||||
"if (retb() != 'b') throw Error('retb');\n"
|
||||
// " libdeno.print('deno ' + JSON.stringify(deno));\n"
|
||||
"if (deno.foo != 'bar') throw Error('foo');\n",
|
||||
false));
|
||||
EXPECT_EQ(count, 1);
|
||||
deno_delete(d);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue