diff --git a/op_hello/Cargo.toml b/op_hello/Cargo.toml new file mode 100644 index 00000000000000..61c6d2c0e22375 --- /dev/null +++ b/op_hello/Cargo.toml @@ -0,0 +1,19 @@ +# This is an imagined crate directory structure for Deno ops. + +[package] +name = "op_hello" +version = "0.1.0" +authors = ["Ryan Dahl "] +edition = "2018" + +# Note: I am explicitly attempting to not have a build.rs file. I think it might +# be unnecessary for each op crate to implement their own. Then again, it might +# be unavoidable... Let's try without first. + +[dependencies] +deno = "0.19.0" +# deno_std is needed because hello_test.ts depends on the "testing/mod.ts" file +# inside of deno_std. +# TODO deno_std is not yet published as crate +deno_std = "0.19.0" + diff --git a/op_hello/src/hello.ts b/op_hello/src/hello.ts new file mode 100644 index 00000000000000..ab4ca02f69a218 --- /dev/null +++ b/op_hello/src/hello.ts @@ -0,0 +1,12 @@ +const OP_HELLO: number = Deno.ops.add("hello"); + +// https://www.typescriptlang.org/docs/handbook/namespaces.html#splitting-across-files +namespace Deno { + /** + * The typedoc here ideally would be presevered automatically in + * lib.deno_runtime.d.ts + */ + export function hello() { + Deno.core.send(OP_HELLO); + } +} diff --git a/op_hello/src/hello_test.ts b/op_hello/src/hello_test.ts new file mode 100644 index 00000000000000..913568f73c6599 --- /dev/null +++ b/op_hello/src/hello_test.ts @@ -0,0 +1,34 @@ +// We need some way to import test modules. +// Attempt one: +// +// import { test } from "../../js/test_util.ts"; +// +// Here it is referencing files across crate boundaries, which will break +// 'cargo package' and means the crate is not useable outside the deno tree. +// This might be okay for a first pass, but it's not the best solution. +// +// Attempt two: +// we invent a new URL for referencing files in other crates. +// this is magic and not browser compatible.. Browser compatibility for +// ops is not so important. +// +// import { test } from "crate://deno_std@0.19.0/testing/mod.ts"; +// +// This is quite nice. But the version of deno_std already specified in +// Cargo.toml. I think we shouldn't repeat it. +import { test } from "crate://deno_std/testing/mod.ts"; + +// If we don't do the //src reorg that I've proposed in #3022, then we might be +// able to have a very elegant URL some day using the deno crate. +// +// import { test } from "crate://deno/std/testing/mod.ts"; + +import "./hello.ts"; + +test("hello test", () => { + Deno.hello(); +}); + +test("hello test2", () => { + Deno.hello(); +}); diff --git a/op_hello/src/lib.rs b/op_hello/src/lib.rs new file mode 100644 index 00000000000000..5d4ef2df8f9aeb --- /dev/null +++ b/op_hello/src/lib.rs @@ -0,0 +1,41 @@ +extern crate deno; +extern crate deno_std; +use deno::*; + +pub fn init(&mut isolate: Isolate) -> Result<(), ErrBox> { + isolate.register_op("hello", op_hello); // register_op defined by #3002 + + // Explicitly link the deno_std crate so it can be used in hello_test.ts + // Its usage looks like this: + // + // import { test } from "crate://deno_std/testing/mod.ts"; + // + // In the future it might make sense to automate this function away, but I think + // it would be prudent to make the crate URL resolution as obvious as + // possible. + isolate.register_crate_url("deno_std", deno_std::get_file); + + // TODO The ability to run typescript doesn't exist in deno core. + isolate.run("src/hello.ts") +} + +fn op_hello(_control_buf: &[u8], _zero_copy_buf: Option) -> CoreOp { + println!("Hello world"); + CoreOp::Sync(Box::new([])) +} + +#[test] +fn rust_test() { + match op_hello() { + CoreOp::Sync(buf) => { + assert_eq!(buf.len(), 0); + } + CoreOp::Async(_) => unreachable!(), + } +} + +#[test] +fn js_test() { + // This should execute src/hello_test.ts + deno_test(); +} diff --git a/op_hello_js/Cargo.toml b/op_hello_js/Cargo.toml new file mode 100644 index 00000000000000..5e6e44946ffa8b --- /dev/null +++ b/op_hello_js/Cargo.toml @@ -0,0 +1,14 @@ +# This is an imagined crate directory structure for Deno ops. +# Same as op_hello but done with JS and not TS. + +[package] +name = "op_hello_js" +version = "0.1.0" +authors = ["Ryan Dahl "] +edition = "2018" + +[lib] +path = "lib.rs" + +[dependencies] +deno = "0.19.0" diff --git a/op_hello_js/hello.js b/op_hello_js/hello.js new file mode 100644 index 00000000000000..7cfdaa82b871f3 --- /dev/null +++ b/op_hello_js/hello.js @@ -0,0 +1,6 @@ +// TODO In the future maybe we can extract the op id in the top-level and use a +// constant. But currently it's causing problems with snapshotting. + +export function hello() { + Deno.core.send(Deno.ops["hello"]); +} diff --git a/op_hello_js/hello_test.js b/op_hello_js/hello_test.js new file mode 100644 index 00000000000000..5fd5d0c050319e --- /dev/null +++ b/op_hello_js/hello_test.js @@ -0,0 +1,4 @@ +// As opposed to the TypeScript op_hello example, here we want to not rely on +// deno_std, as it uses TypeScript. So here don't use a test runner. +import { hello } from "./hello.js"; +hello(); diff --git a/op_hello_js/lib.rs b/op_hello_js/lib.rs new file mode 100644 index 00000000000000..ecd98b15a40694 --- /dev/null +++ b/op_hello_js/lib.rs @@ -0,0 +1,27 @@ +extern crate deno; +use deno::*; + +pub fn init(&mut isolate: Isolate) -> Result<(), ErrBox> { + isolate.register_op("hello", op_hello); // register_op defined by #3002 + isolate.execute("hello.js")?; + Ok(()) +} + +fn op_hello(_control_buf: &[u8], _zero_copy_buf: Option) -> CoreOp { + println!("Hello world"); + CoreOp::Sync(Box::new([])) +} + +#[test] +fn js_test() { + isolate.execute("hello_test.js") +} + +#[test] +fn rust_test() { + if let CoreOp::Sync(buf) = op_hello() { + assert_eq!(buf.len(), 0); + } else { + unreachable!(); + } +}