1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-28 16:20:57 -05:00

Merge branch 'main' into auto-config

This commit is contained in:
Ryan Dahl 2022-01-10 18:22:07 -05:00
commit 67756b55f2
22 changed files with 547 additions and 72 deletions

View file

@ -870,7 +870,7 @@ declare namespace Deno {
*
* Returns the number of bytes written. This function is one of the lowest
* level APIs and most users should not work with this directly, but rather use
* Deno.writeAllSync() instead.
* `writeAllSync()` from https://deno.land/std/streams/conversion.ts instead.
*
* **It is not guaranteed that the full buffer will be written in a single
* call.**

View file

@ -121,13 +121,60 @@ declare namespace Deno {
| "pointer";
/** A foreign function as defined by its parameter and result types */
export interface ForeignFunction {
parameters: NativeType[];
result: NativeType;
export interface ForeignFunction<
Parameters extends readonly NativeType[] = readonly NativeType[],
Result extends NativeType = NativeType,
NonBlocking extends boolean = boolean,
> {
parameters: Parameters;
result: Result;
/** When true, function calls will run on a dedicated blocking thread and will return a Promise resolving to the `result`. */
nonblocking?: boolean;
nonblocking?: NonBlocking;
}
/** A foreign function interface descriptor */
export interface ForeignFunctionInterface {
[name: string]: ForeignFunction;
}
/** All possible number types interfacing with foreign functions */
type StaticNativeNumberType = Exclude<NativeType, "void" | "pointer">;
/** Infers a foreign function return type */
type StaticForeignFunctionResult<T extends NativeType> = T extends "void"
? void
: T extends StaticNativeNumberType ? number
: T extends "pointer" ? UnsafePointer
: never;
type StaticForeignFunctionParameter<T> = T extends "void" ? void
: T extends StaticNativeNumberType ? number
: T extends "pointer" ? Deno.UnsafePointer | Deno.TypedArray
: unknown;
/** Infers a foreign function parameter list. */
type StaticForeignFunctionParameters<T extends readonly NativeType[]> = [
...{
[K in keyof T]: StaticForeignFunctionParameter<T[K]>;
},
];
/** Infers a foreign function */
type StaticForeignFunction<T extends ForeignFunction> = (
...args: StaticForeignFunctionParameters<T["parameters"]>
) => ConditionalAsync<
T["nonblocking"],
StaticForeignFunctionResult<T["result"]>
>;
type ConditionalAsync<IsAsync extends boolean | undefined, T> =
IsAsync extends true ? Promise<T> : T;
/** Infers a foreign function interface */
type StaticForeignFunctionInterface<T extends ForeignFunctionInterface> = {
[K in keyof T]: StaticForeignFunction<T[K]>;
};
type TypedArray =
| Int8Array
| Uint8Array
@ -202,10 +249,9 @@ declare namespace Deno {
}
/** A dynamic library resource */
export interface DynamicLibrary<S extends Record<string, ForeignFunction>> {
export interface DynamicLibrary<S extends ForeignFunctionInterface> {
/** All of the registered symbols along with functions for calling them */
symbols: { [K in keyof S]: (...args: unknown[]) => unknown };
symbols: StaticForeignFunctionInterface<S>;
close(): void;
}
@ -213,7 +259,7 @@ declare namespace Deno {
*
* Opens a dynamic library and registers symbols
*/
export function dlopen<S extends Record<string, ForeignFunction>>(
export function dlopen<S extends ForeignFunctionInterface>(
filename: string | URL,
symbols: S,
): DynamicLibrary<S>;

View file

@ -328,7 +328,7 @@ impl FileFetcher {
/// Fetch cached remote file.
///
/// This is a recursive operation if source file has redirections.
fn fetch_cached(
pub(crate) fn fetch_cached(
&self,
specifier: &ModuleSpecifier,
redirect_limit: i64,

View file

@ -214,6 +214,7 @@ pub struct Flags {
pub argv: Vec<String>,
pub subcommand: DenoSubcommand,
pub allow_all: bool,
pub allow_env: Option<Vec<String>>,
pub allow_hrtime: bool,
pub allow_net: Option<Vec<String>>,
@ -269,6 +270,11 @@ impl Flags {
pub fn to_permission_args(&self) -> Vec<String> {
let mut args = vec![];
if self.allow_all {
args.push("--allow-all".to_string());
return args;
}
match &self.allow_read {
Some(read_allowlist) if read_allowlist.is_empty() => {
args.push("--allow-read".to_string());
@ -2274,6 +2280,7 @@ fn permission_args_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
flags.allow_hrtime = true;
}
if matches.is_present("allow-all") {
flags.allow_all = true;
flags.allow_read = Some(vec![]);
flags.allow_env = Some(vec![]);
flags.allow_net = Some(vec![]);
@ -2669,6 +2676,7 @@ mod tests {
subcommand: DenoSubcommand::Run(RunFlags {
script: "gist.ts".to_string(),
}),
allow_all: true,
allow_net: Some(vec![]),
allow_env: Some(vec![]),
allow_run: Some(vec![]),

View file

@ -20,9 +20,11 @@ fn final_blankline() {
}
fn run_coverage_text(test_name: &str, extension: &str) {
let deno_dir = TempDir::new().expect("tempdir fail");
let tempdir = TempDir::new().expect("tempdir fail");
let tempdir = tempdir.path().join("cov");
let status = util::deno_cmd()
let status = util::deno_cmd_with_deno_dir(deno_dir.path())
.current_dir(util::testdata_path())
.arg("test")
.arg("--quiet")
@ -36,17 +38,19 @@ fn run_coverage_text(test_name: &str, extension: &str) {
assert!(status.success());
let output = util::deno_cmd()
let output = util::deno_cmd_with_deno_dir(deno_dir.path())
.current_dir(util::testdata_path())
.arg("coverage")
.arg("--quiet")
.arg("--unstable")
.arg(format!("{}/", tempdir.to_str().unwrap()))
.stdout(std::process::Stdio::piped())
.stderr(std::process::Stdio::inherit())
.stderr(std::process::Stdio::piped())
.output()
.expect("failed to spawn coverage reporter");
// Verify there's no "Check" being printed
assert!(output.stderr.is_empty());
let actual =
util::strip_ansi_codes(std::str::from_utf8(&output.stdout).unwrap())
.to_string();
@ -64,7 +68,7 @@ fn run_coverage_text(test_name: &str, extension: &str) {
assert!(output.status.success());
let output = util::deno_cmd()
let output = util::deno_cmd_with_deno_dir(deno_dir.path())
.current_dir(util::testdata_path())
.arg("coverage")
.arg("--quiet")

View file

@ -13,6 +13,15 @@ use std::pin::Pin;
use test_util as util;
use tokio::net::TcpStream;
macro_rules! assert_starts_with {
($string:expr, $($test:expr),+) => {
let string = $string; // This might be a function call or something
if !($(string.starts_with($test))||+) {
panic!("{:?} does not start with {:?}", string, [$($test),+]);
}
}
}
fn inspect_flag_with_unique_port(flag_prefix: &str) -> String {
use std::sync::atomic::{AtomicU16, Ordering};
static PORT: AtomicU16 = AtomicU16::new(9229);
@ -23,8 +32,8 @@ fn inspect_flag_with_unique_port(flag_prefix: &str) -> String {
fn extract_ws_url_from_stderr(
stderr_lines: &mut impl std::iter::Iterator<Item = String>,
) -> url::Url {
let stderr_first_line = stderr_lines.next().unwrap();
assert!(stderr_first_line.starts_with("Debugger listening on "));
let stderr_first_line = skip_check_line(stderr_lines);
assert_starts_with!(&stderr_first_line, "Debugger listening on ");
let v: Vec<_> = stderr_first_line.match_indices("ws:").collect();
assert_eq!(v.len(), 1);
let ws_url_index = v[0].0;
@ -32,25 +41,57 @@ fn extract_ws_url_from_stderr(
url::Url::parse(ws_url).unwrap()
}
fn skip_check_line(
stderr_lines: &mut impl std::iter::Iterator<Item = String>,
) -> String {
loop {
let mut line = stderr_lines.next().unwrap();
line = util::strip_ansi_codes(&line).to_string();
if line.starts_with("Check") {
continue;
}
return line;
}
}
fn assert_stderr(
stderr_lines: &mut impl std::iter::Iterator<Item = String>,
expected_lines: &[&str],
) {
let mut expected_index = 0;
loop {
let line = skip_check_line(stderr_lines);
assert_eq!(line, expected_lines[expected_index]);
expected_index += 1;
if expected_index >= expected_lines.len() {
break;
}
}
}
fn assert_stderr_for_inspect(
stderr_lines: &mut impl std::iter::Iterator<Item = String>,
) {
assert_eq!(
&stderr_lines.next().unwrap(),
"Visit chrome://inspect to connect to the debugger."
assert_stderr(
stderr_lines,
&["Visit chrome://inspect to connect to the debugger."],
);
}
fn assert_stderr_for_inspect_brk(
stderr_lines: &mut impl std::iter::Iterator<Item = String>,
) {
assert_eq!(
&stderr_lines.next().unwrap(),
"Visit chrome://inspect to connect to the debugger."
);
assert_eq!(
&stderr_lines.next().unwrap(),
"Deno is waiting for debugger to connect."
assert_stderr(
stderr_lines,
&[
"Visit chrome://inspect to connect to the debugger.",
"Deno is waiting for debugger to connect.",
],
);
}
@ -99,7 +140,7 @@ async fn assert_inspector_messages(
#[tokio::test]
async fn inspector_connect() {
let script = util::testdata_path().join("inspector1.js");
let script = util::testdata_path().join("inspector/inspector1.js");
let mut child = util::deno_cmd()
.arg("run")
.arg(inspect_flag_with_unique_port("--inspect"))
@ -125,7 +166,7 @@ async fn inspector_connect() {
#[tokio::test]
async fn inspector_break_on_first_line() {
let script = util::testdata_path().join("inspector2.js");
let script = util::testdata_path().join("inspector/inspector2.js");
let mut child = util::deno_cmd()
.arg("run")
.arg(inspect_flag_with_unique_port("--inspect-brk"))
@ -216,7 +257,7 @@ async fn inspector_break_on_first_line() {
#[tokio::test]
async fn inspector_pause() {
let script = util::testdata_path().join("inspector1.js");
let script = util::testdata_path().join("inspector/inspector1.js");
let mut child = util::deno_cmd()
.arg("run")
.arg(inspect_flag_with_unique_port("--inspect"))
@ -263,7 +304,7 @@ async fn inspector_pause() {
let msg = ws_read_msg(&mut socket).await;
println!("response msg 1 {}", msg);
assert!(msg.starts_with(r#"{"id":6,"result":{"debuggerId":"#));
assert_starts_with!(msg, r#"{"id":6,"result":{"debuggerId":"#);
socket
.send(r#"{"id":31,"method":"Debugger.pause"}"#.into())
@ -286,7 +327,7 @@ async fn inspector_port_collision() {
return;
}
let script = util::testdata_path().join("inspector1.js");
let script = util::testdata_path().join("inspector/inspector1.js");
let inspect_flag = inspect_flag_with_unique_port("--inspect");
let mut child1 = util::deno_cmd()
@ -326,7 +367,7 @@ async fn inspector_port_collision() {
#[tokio::test]
async fn inspector_does_not_hang() {
let script = util::testdata_path().join("inspector3.js");
let script = util::testdata_path().join("inspector/inspector3.js");
let mut child = util::deno_cmd()
.arg("run")
.arg(inspect_flag_with_unique_port("--inspect-brk"))
@ -438,7 +479,7 @@ async fn inspector_does_not_hang() {
#[tokio::test]
async fn inspector_without_brk_runs_code() {
let script = util::testdata_path().join("inspector4.js");
let script = util::testdata_path().join("inspector/inspector4.js");
let mut child = util::deno_cmd()
.arg("run")
.arg(inspect_flag_with_unique_port("--inspect"))
@ -566,7 +607,7 @@ async fn inspector_runtime_evaluate_does_not_crash() {
#[tokio::test]
async fn inspector_json() {
let script = util::testdata_path().join("inspector1.js");
let script = util::testdata_path().join("inspector/inspector1.js");
let mut child = util::deno_cmd()
.arg("run")
.arg(inspect_flag_with_unique_port("--inspect"))
@ -595,7 +636,7 @@ async fn inspector_json() {
#[tokio::test]
async fn inspector_json_list() {
let script = util::testdata_path().join("inspector1.js");
let script = util::testdata_path().join("inspector/inspector1.js");
let mut child = util::deno_cmd()
.arg("run")
.arg(inspect_flag_with_unique_port("--inspect"))
@ -626,7 +667,7 @@ async fn inspector_json_list() {
async fn inspector_connect_non_ws() {
// https://github.com/denoland/deno/issues/11449
// Verify we don't panic if non-WS connection is being established
let script = util::testdata_path().join("inspector1.js");
let script = util::testdata_path().join("inspector/inspector1.js");
let mut child = util::deno_cmd()
.arg("run")
.arg(inspect_flag_with_unique_port("--inspect"))
@ -650,7 +691,7 @@ async fn inspector_connect_non_ws() {
#[tokio::test]
async fn inspector_break_on_first_line_in_test() {
let script = util::testdata_path().join("inspector_test.js");
let script = util::testdata_path().join("inspector/inspector_test.js");
let mut child = util::deno_cmd()
.arg("test")
.arg(inspect_flag_with_unique_port("--inspect-brk"))
@ -733,10 +774,7 @@ async fn inspector_break_on_first_line_in_test() {
)
.await;
assert!(&stdout_lines
.next()
.unwrap()
.starts_with("running 1 test from"));
assert_starts_with!(&stdout_lines.next().unwrap(), "running 1 test from");
assert!(&stdout_lines
.next()
.unwrap()
@ -745,3 +783,129 @@ async fn inspector_break_on_first_line_in_test() {
child.kill().unwrap();
child.wait().unwrap();
}
#[tokio::test]
async fn inspector_with_ts_files() {
let script = util::testdata_path().join("inspector/test.ts");
let mut child = util::deno_cmd()
.arg("run")
.arg(inspect_flag_with_unique_port("--inspect-brk"))
.arg(script)
.stdout(std::process::Stdio::piped())
.stderr(std::process::Stdio::piped())
.spawn()
.unwrap();
let stderr = child.stderr.as_mut().unwrap();
let mut stderr_lines =
std::io::BufReader::new(stderr).lines().map(|r| r.unwrap());
let ws_url = extract_ws_url_from_stderr(&mut stderr_lines);
let (socket, response) = tokio_tungstenite::connect_async(ws_url)
.await
.expect("Can't connect");
assert_eq!(response.status(), 101); // Switching protocols.
let (mut socket_tx, socket_rx) = socket.split();
let mut socket_rx = socket_rx
.map(|msg| msg.unwrap().to_string())
.filter(|msg| {
let pass = (msg.starts_with(r#"{"method":"Debugger.scriptParsed","#)
&& msg.contains("testdata/inspector"))
|| !msg.starts_with(r#"{"method":"Debugger.scriptParsed","#);
futures::future::ready(pass)
})
.boxed_local();
let stdout = child.stdout.as_mut().unwrap();
let mut stdout_lines =
std::io::BufReader::new(stdout).lines().map(|r| r.unwrap());
assert_stderr_for_inspect_brk(&mut stderr_lines);
assert_inspector_messages(
&mut socket_tx,
&[
r#"{"id":1,"method":"Runtime.enable"}"#,
r#"{"id":2,"method":"Debugger.enable"}"#,
],
&mut socket_rx,
&[
r#"{"id":1,"result":{}}"#,
],
&[
r#"{"method":"Runtime.executionContextCreated","params":{"context":{"id":1,"#,
],
)
.await;
// receive messages with sources from this test
let script1 = socket_rx.next().await.unwrap();
assert!(script1.contains("testdata/inspector/test.ts"));
let script1_id = {
let v: serde_json::Value = serde_json::from_str(&script1).unwrap();
v["params"]["scriptId"].as_str().unwrap().to_string()
};
let script2 = socket_rx.next().await.unwrap();
assert!(script2.contains("testdata/inspector/foo.ts"));
let script2_id = {
let v: serde_json::Value = serde_json::from_str(&script2).unwrap();
v["params"]["scriptId"].as_str().unwrap().to_string()
};
let script3 = socket_rx.next().await.unwrap();
assert!(script3.contains("testdata/inspector/bar.js"));
let script3_id = {
let v: serde_json::Value = serde_json::from_str(&script3).unwrap();
v["params"]["scriptId"].as_str().unwrap().to_string()
};
assert_inspector_messages(
&mut socket_tx,
&[],
&mut socket_rx,
&[r#"{"id":2,"result":{"debuggerId":"#],
&[],
)
.await;
assert_inspector_messages(
&mut socket_tx,
&[r#"{"id":3,"method":"Runtime.runIfWaitingForDebugger"}"#],
&mut socket_rx,
&[r#"{"id":3,"result":{}}"#],
&[r#"{"method":"Debugger.paused","#],
)
.await;
assert_inspector_messages(
&mut socket_tx,
&[
&format!(r#"{{"id":4,"method":"Debugger.getScriptSource","params":{{"scriptId":"{}"}}}}"#, script1_id),
&format!(r#"{{"id":5,"method":"Debugger.getScriptSource","params":{{"scriptId":"{}"}}}}"#, script2_id),
&format!(r#"{{"id":6,"method":"Debugger.getScriptSource","params":{{"scriptId":"{}"}}}}"#, script3_id),
],
&mut socket_rx,
&[
r#"{"id":4,"result":{"scriptSource":"import { foo } from \"./foo.ts\";\nimport { bar } from \"./bar.js\";\nconsole.log(foo());\nconsole.log(bar());\n//# sourceMappingURL=data:application/json;base64,"#,
r#"{"id":5,"result":{"scriptSource":"class Foo {\n hello() {\n return \"hello\";\n }\n}\nexport function foo() {\n const f = new Foo();\n return f.hello();\n}\n//# sourceMappingURL=data:application/json;base64,"#,
r#"{"id":6,"result":{"scriptSource":"export function bar() {\n return \"world\";\n}\n"#,
],
&[],
)
.await;
assert_inspector_messages(
&mut socket_tx,
&[r#"{"id":7,"method":"Debugger.resume"}"#],
&mut socket_rx,
&[r#"{"id":7,"result":{}}"#],
&[],
)
.await;
assert_eq!(&stdout_lines.next().unwrap(), "hello");
assert_eq!(&stdout_lines.next().unwrap(), "world");
child.kill().unwrap();
child.wait().unwrap();
}

3
cli/tests/testdata/inspector/bar.js vendored Normal file
View file

@ -0,0 +1,3 @@
export function bar() {
return "world";
}

10
cli/tests/testdata/inspector/foo.ts vendored Normal file
View file

@ -0,0 +1,10 @@
class Foo {
hello(): string {
return "hello";
}
}
export function foo(): string {
const f = new Foo();
return f.hello();
}

5
cli/tests/testdata/inspector/test.ts vendored Normal file
View file

@ -0,0 +1,5 @@
import { foo } from "./foo.ts";
import { bar } from "./bar.js";
console.log(foo());
console.log(bar());

View file

@ -798,3 +798,32 @@ Deno.test({
worker.terminate();
},
});
Deno.test({
name: "worker Deno.memoryUsage",
fn: async function () {
const w = new Worker(
/**
* Source code
* self.onmessage = function() {self.postMessage(Deno.memoryUsage())}
*/
"data:application/typescript;base64,c2VsZi5vbm1lc3NhZ2UgPSBmdW5jdGlvbigpIHtzZWxmLnBvc3RNZXNzYWdlKERlbm8ubWVtb3J5VXNhZ2UoKSl9",
{ type: "module", name: "tsWorker", deno: true },
);
w.postMessage(null);
const memoryUsagePromise = deferred();
w.onmessage = function (evt) {
memoryUsagePromise.resolve(evt.data);
};
assertEquals(
Object.keys(
await memoryUsagePromise as unknown as Record<string, number>,
),
["rss", "heapTotal", "heapUsed", "external"],
);
w.terminate();
},
});

View file

@ -1,7 +1,6 @@
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
use crate::colors;
use crate::emit;
use crate::flags::CoverageFlags;
use crate::flags::Flags;
use crate::fs_util::collect_files;
@ -11,11 +10,12 @@ use crate::tools::fmt::format_json;
use deno_ast::MediaType;
use deno_ast::ModuleSpecifier;
use deno_core::anyhow::anyhow;
use deno_core::anyhow::Context;
use deno_core::error::AnyError;
use deno_core::serde_json;
use deno_core::url::Url;
use deno_core::LocalInspectorSession;
use deno_runtime::permissions::Permissions;
use regex::Regex;
use serde::Deserialize;
use serde::Serialize;
@ -643,40 +643,69 @@ pub async fn cover_files(
for script_coverage in script_coverages {
let module_specifier =
deno_core::resolve_url_or_path(&script_coverage.url)?;
ps.prepare_module_load(
vec![module_specifier.clone()],
false,
emit::TypeLib::UnstableDenoWindow,
Permissions::allow_all(),
Permissions::allow_all(),
false,
let maybe_file = if module_specifier.scheme() == "file" {
ps.file_fetcher.get_source(&module_specifier)
} else {
ps.file_fetcher
.fetch_cached(&module_specifier, 10)
.with_context(|| {
format!("Failed to fetch \"{}\" from cache.", module_specifier)
})?
};
let file = maybe_file.ok_or_else(|| {
anyhow!("Failed to fetch \"{}\" from cache.
Before generating coverage report, run `deno test --coverage` to ensure consistent state.",
module_specifier
)
.await?;
})?;
let module_source = ps.load(module_specifier.clone(), None, false)?;
let script_source = &module_source.code;
// Check if file was transpiled
let transpiled_source = match file.media_type {
MediaType::JavaScript
| MediaType::Unknown
| MediaType::Cjs
| MediaType::Mjs
| MediaType::Json => file.source.as_ref().clone(),
MediaType::Dts | MediaType::Dmts | MediaType::Dcts => "".to_string(),
MediaType::TypeScript
| MediaType::Jsx
| MediaType::Mts
| MediaType::Cts
| MediaType::Tsx => {
let emit_path = ps
.dir
.gen_cache
.get_cache_filename_with_extension(&file.specifier, "js")
.unwrap_or_else(|| {
unreachable!("Unable to get cache filename: {}", &file.specifier)
});
match ps.dir.gen_cache.get(&emit_path) {
Ok(b) => String::from_utf8(b).unwrap(),
Err(_) => {
return Err(anyhow!(
"Missing transpiled source code for: \"{}\".
Before generating coverage report, run `deno test --coverage` to ensure consistent state.",
file.specifier,
))
}
}
}
MediaType::Wasm | MediaType::TsBuildInfo | MediaType::SourceMap => {
unreachable!()
}
};
let original_source = &file.source;
let maybe_source_map = ps.get_source_map(&script_coverage.url);
let maybe_cached_source = ps
.file_fetcher
.get_source(&module_specifier)
.map(|f| f.source);
let coverage_report = generate_coverage_report(
&script_coverage,
script_source,
&transpiled_source,
&maybe_source_map,
);
let file_text = if let Some(original_source) =
maybe_source_map.and(maybe_cached_source.as_ref())
{
original_source.as_str()
} else {
script_source
};
reporter.report(&coverage_report, file_text);
reporter.report(&coverage_report, original_source);
}
reporter.done();

View file

@ -729,6 +729,43 @@ mod tests {
}
}
#[test]
fn install_allow_all() {
let temp_dir = TempDir::new().expect("tempdir fail");
let bin_dir = temp_dir.path().join("bin");
std::fs::create_dir(&bin_dir).unwrap();
install(
Flags {
allow_all: true,
..Flags::default()
},
InstallFlags {
module_url: "http://localhost:4545/echo_server.ts".to_string(),
args: vec![],
name: Some("echo_test".to_string()),
root: Some(temp_dir.path().to_path_buf()),
force: false,
},
)
.unwrap();
let mut file_path = bin_dir.join("echo_test");
if cfg!(windows) {
file_path = file_path.with_extension("cmd");
}
let content = fs::read_to_string(file_path).unwrap();
if cfg!(windows) {
assert!(content.contains(
r#""run" "--allow-all" "http://localhost:4545/echo_server.ts""#
));
} else {
assert!(content
.contains(r#"run --allow-all 'http://localhost:4545/echo_server.ts'"#));
}
}
#[test]
fn install_local_module() {
let temp_dir = TempDir::new().expect("tempdir fail");

View file

@ -204,6 +204,7 @@ pub fn compile_to_runtime_flags(
subcommand: DenoSubcommand::Run(RunFlags {
script: "placeholder".to_string(),
}),
allow_all: flags.allow_all,
allow_env: flags.allow_env,
allow_hrtime: flags.allow_hrtime,
allow_net: flags.allow_net,

View file

@ -29,6 +29,7 @@
makeTempDir: __bootstrap.fs.makeTempDir,
makeTempFileSync: __bootstrap.fs.makeTempFileSync,
makeTempFile: __bootstrap.fs.makeTempFile,
memoryUsage: core.memoryUsage,
mkdirSync: __bootstrap.fs.mkdirSync,
mkdir: __bootstrap.fs.mkdir,
chdir: __bootstrap.fs.chdir,

View file

@ -588,7 +588,6 @@ delete Object.prototype.__proto__;
[internalSymbol]: internals,
resources: core.resources,
close: core.close,
memoryUsage: core.memoryUsage,
...denoNs,
};
ObjectDefineProperties(finalDenoNs, {

111
test_ffi/tests/ffi_types.ts Normal file
View file

@ -0,0 +1,111 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
// deno-lint-ignore-file
// Only for testing types. Invoke with `deno cache`
const remote = Deno.dlopen(
"dummy_lib.so",
{
method1: { parameters: ["usize", "usize"], result: "void" },
method2: { parameters: ["void"], result: "void" },
method3: { parameters: ["usize"], result: "void" },
method4: { parameters: ["isize"], result: "void" },
method5: { parameters: ["u8"], result: "void" },
method6: { parameters: ["u16"], result: "void" },
method7: { parameters: ["u32"], result: "void" },
method8: { parameters: ["u64"], result: "void" },
method9: { parameters: ["i8"], result: "void" },
method10: { parameters: ["i16"], result: "void" },
method11: { parameters: ["i32"], result: "void" },
method12: { parameters: ["i64"], result: "void" },
method13: { parameters: ["f32"], result: "void" },
method14: { parameters: ["f64"], result: "void" },
method15: { parameters: ["pointer"], result: "void" },
method16: { parameters: [], result: "usize" },
method17: { parameters: [], result: "usize", nonblocking: true },
method18: { parameters: [], result: "pointer" },
method19: { parameters: [], result: "pointer", nonblocking: true },
} as const,
);
// @ts-expect-error: Invalid argument
remote.symbols.method1(0);
// @ts-expect-error: Invalid return type
<number> remote.symbols.method1(0, 0);
<void> remote.symbols.method1(0, 0);
// @ts-expect-error: Invalid argument
remote.symbols.method2(null);
remote.symbols.method2(void 0);
// @ts-expect-error: Invalid argument
remote.symbols.method3(null);
remote.symbols.method3(0);
// @ts-expect-error: Invalid argument
remote.symbols.method4(null);
remote.symbols.method4(0);
// @ts-expect-error: Invalid argument
remote.symbols.method5(null);
remote.symbols.method5(0);
// @ts-expect-error: Invalid argument
remote.symbols.method6(null);
remote.symbols.method6(0);
// @ts-expect-error: Invalid argument
remote.symbols.method7(null);
remote.symbols.method7(0);
// @ts-expect-error: Invalid argument
remote.symbols.method8(null);
remote.symbols.method8(0);
// @ts-expect-error: Invalid argument
remote.symbols.method9(null);
remote.symbols.method9(0);
// @ts-expect-error: Invalid argument
remote.symbols.method10(null);
remote.symbols.method10(0);
// @ts-expect-error: Invalid argument
remote.symbols.method11(null);
remote.symbols.method11(0);
// @ts-expect-error: Invalid argument
remote.symbols.method12(null);
remote.symbols.method12(0);
// @ts-expect-error: Invalid argument
remote.symbols.method13(null);
remote.symbols.method13(0);
// @ts-expect-error: Invalid argument
remote.symbols.method14(null);
remote.symbols.method14(0);
// @ts-expect-error: Invalid argument
remote.symbols.method15(null);
remote.symbols.method15(new Uint16Array(1));
remote.symbols.method15({} as Deno.UnsafePointer);
const result = remote.symbols.method16();
// @ts-expect-error: Invalid argument
let r_0: string = result;
let r_1: number = result;
const result2 = remote.symbols.method17();
// @ts-expect-error: Invalid argument
result2.then((_0: string) => {});
result2.then((_1: number) => {});
const result3 = remote.symbols.method18();
// @ts-expect-error: Invalid argument
let r3_0: Deno.TypedArray = result3;
let r3_1: Deno.UnsafePointer = result3;
const result4 = remote.symbols.method19();
// @ts-expect-error: Invalid argument
result4.then((_0: Deno.TypedArray) => {});
result4.then((_1: Deno.UnsafePointer) => {});

View file

@ -9,8 +9,7 @@ const BUILD_VARIANT: &str = "debug";
#[cfg(not(debug_assertions))]
const BUILD_VARIANT: &str = "release";
#[test]
fn basic() {
fn build() {
let mut build_plugin_base = Command::new("cargo");
let mut build_plugin =
build_plugin_base.arg("build").arg("-p").arg("test_ffi");
@ -19,6 +18,12 @@ fn basic() {
}
let build_plugin_output = build_plugin.output().unwrap();
assert!(build_plugin_output.status.success());
}
#[test]
fn basic() {
build();
let output = deno_cmd()
.arg("run")
.arg("--allow-ffi")
@ -66,3 +71,26 @@ fn basic() {
assert_eq!(stdout, expected);
assert_eq!(stderr, "");
}
#[test]
fn symbol_types() {
build();
let output = deno_cmd()
.arg("cache")
.arg("--unstable")
.arg("--quiet")
.arg("tests/ffi_types.ts")
.env("NO_COLOR", "1")
.output()
.unwrap();
let stdout = std::str::from_utf8(&output.stdout).unwrap();
let stderr = std::str::from_utf8(&output.stderr).unwrap();
if !output.status.success() {
println!("stdout {}", stdout);
println!("stderr {}", stderr);
}
println!("{:?}", output.status);
assert!(output.status.success());
assert_eq!(stderr, "");
}