python-plugin: RAII (PyOwned/PyBorrowed) + autodecode enum; crate: ny-llvmc --emit exe with NyRT link; tools: build_llvm.sh crate-exe path + crate_exe_smoke; CURRENT_TASK update
This commit is contained in:
@ -3,18 +3,88 @@ mod tests {
|
||||
use crate::box_trait::{IntegerBox, NyashBox, StringBox};
|
||||
use crate::boxes::array::ArrayBox;
|
||||
use crate::boxes::math_box::FloatBox;
|
||||
use crate::runtime::plugin_loader_unified::PluginHost;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
|
||||
// RAII: environment variable guard (restores on drop)
|
||||
struct EnvGuard {
|
||||
key: &'static str,
|
||||
prev: Option<String>,
|
||||
}
|
||||
|
||||
impl EnvGuard {
|
||||
fn set(key: &'static str, val: &str) -> Self {
|
||||
let prev = env::var(key).ok();
|
||||
env::set_var(key, val);
|
||||
EnvGuard { key, prev }
|
||||
}
|
||||
|
||||
fn remove(key: &'static str) -> Self {
|
||||
let prev = env::var(key).ok();
|
||||
env::remove_var(key);
|
||||
EnvGuard { key, prev }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for EnvGuard {
|
||||
fn drop(&mut self) {
|
||||
match &self.prev {
|
||||
Some(v) => env::set_var(self.key, v),
|
||||
None => env::remove_var(self.key),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper: read-lock the global plugin host and pass immutable ref to closure
|
||||
fn with_host<R>(f: impl FnOnce(&PluginHost) -> R) -> R {
|
||||
let host = crate::runtime::get_global_plugin_host();
|
||||
let guard = host.read().expect("plugin host RwLock poisoned");
|
||||
f(&*guard)
|
||||
}
|
||||
|
||||
// ---- Test helpers (invoke wrappers) ----
|
||||
fn inv_ok(
|
||||
h: &PluginHost,
|
||||
box_ty: &str,
|
||||
method: &str,
|
||||
id: u32,
|
||||
args: &[Box<dyn NyashBox>],
|
||||
) -> Option<Box<dyn NyashBox>> {
|
||||
h.invoke_instance_method(box_ty, method, id, args)
|
||||
.expect(&format!("invoke {}::{}", box_ty, method))
|
||||
}
|
||||
|
||||
fn inv_some(
|
||||
h: &PluginHost,
|
||||
box_ty: &str,
|
||||
method: &str,
|
||||
id: u32,
|
||||
args: &[Box<dyn NyashBox>],
|
||||
) -> Box<dyn NyashBox> {
|
||||
inv_ok(h, box_ty, method, id, args)
|
||||
.unwrap_or_else(|| panic!("{}::{} returned None", box_ty, method))
|
||||
}
|
||||
|
||||
fn inv_void(
|
||||
h: &PluginHost,
|
||||
box_ty: &str,
|
||||
method: &str,
|
||||
id: u32,
|
||||
args: &[Box<dyn NyashBox>],
|
||||
) {
|
||||
let _ = h
|
||||
.invoke_instance_method(box_ty, method, id, args)
|
||||
.expect(&format!("invoke {}::{}", box_ty, method));
|
||||
}
|
||||
|
||||
fn ensure_host() {
|
||||
let _ = crate::runtime::init_global_plugin_host("nyash.toml");
|
||||
}
|
||||
|
||||
fn create_plugin_instance(box_type: &str) -> (String, u32, Box<dyn NyashBox>) {
|
||||
let host = crate::runtime::get_global_plugin_host();
|
||||
let host = host.read().unwrap();
|
||||
let bx = host.create_box(box_type, &[]).expect("create_box");
|
||||
let bx = with_host(|h| h.create_box(box_type, &[]).expect("create_box"));
|
||||
// Downcast to PluginBoxV2 to get instance_id
|
||||
if let Some(p) = bx
|
||||
.as_any()
|
||||
@ -30,58 +100,25 @@ mod tests {
|
||||
#[ignore = "MIR13 parity: MapBox TLV vs TypeBox under unified BoxCall/TypeOp pending"]
|
||||
fn mapbox_get_set_size_tlv_vs_typebox() {
|
||||
ensure_host();
|
||||
let host = crate::runtime::get_global_plugin_host();
|
||||
|
||||
// TLV path: disable typebox
|
||||
env::set_var("NYASH_DISABLE_TYPEBOX", "1");
|
||||
// TLV path: disable typebox (restored automatically)
|
||||
let _g = EnvGuard::set("NYASH_DISABLE_TYPEBOX", "1");
|
||||
let (bt1, id1, _hold1) = create_plugin_instance("MapBox");
|
||||
let out_tlv = {
|
||||
let h = host.read().unwrap();
|
||||
// set("k", 42)
|
||||
let _ = h
|
||||
.invoke_instance_method(
|
||||
&bt1,
|
||||
"set",
|
||||
id1,
|
||||
&[Box::new(StringBox::new("k")), Box::new(IntegerBox::new(42))],
|
||||
)
|
||||
.expect("set tlv");
|
||||
// size()
|
||||
let sz = h
|
||||
.invoke_instance_method(&bt1, "size", id1, &[])
|
||||
.expect("size tlv")
|
||||
.unwrap();
|
||||
// get("k")
|
||||
let gv = h
|
||||
.invoke_instance_method(&bt1, "get", id1, &[Box::new(StringBox::new("k"))])
|
||||
.expect("get tlv")
|
||||
.unwrap();
|
||||
let out_tlv = with_host(|h| {
|
||||
inv_void(h, &bt1, "set", id1, &[Box::new(StringBox::new("k")), Box::new(IntegerBox::new(42))]);
|
||||
let sz = inv_some(h, &bt1, "size", id1, &[]);
|
||||
let gv = inv_some(h, &bt1, "get", id1, &[Box::new(StringBox::new("k"))]);
|
||||
(sz.to_string_box().value, gv.to_string_box().value)
|
||||
};
|
||||
});
|
||||
|
||||
// TypeBox path: enable typebox
|
||||
env::remove_var("NYASH_DISABLE_TYPEBOX");
|
||||
let _g2 = EnvGuard::remove("NYASH_DISABLE_TYPEBOX");
|
||||
let (bt2, id2, _hold2) = create_plugin_instance("MapBox");
|
||||
let out_tb = {
|
||||
let h = host.read().unwrap();
|
||||
let _ = h
|
||||
.invoke_instance_method(
|
||||
&bt2,
|
||||
"set",
|
||||
id2,
|
||||
&[Box::new(StringBox::new("k")), Box::new(IntegerBox::new(42))],
|
||||
)
|
||||
.expect("set tb");
|
||||
let sz = h
|
||||
.invoke_instance_method(&bt2, "size", id2, &[])
|
||||
.expect("size tb")
|
||||
.unwrap();
|
||||
let gv = h
|
||||
.invoke_instance_method(&bt2, "get", id2, &[Box::new(StringBox::new("k"))])
|
||||
.expect("get tb")
|
||||
.unwrap();
|
||||
let out_tb = with_host(|h| {
|
||||
inv_void(h, &bt2, "set", id2, &[Box::new(StringBox::new("k")), Box::new(IntegerBox::new(42))]);
|
||||
let sz = inv_some(h, &bt2, "size", id2, &[]);
|
||||
let gv = inv_some(h, &bt2, "get", id2, &[Box::new(StringBox::new("k"))]);
|
||||
(sz.to_string_box().value, gv.to_string_box().value)
|
||||
};
|
||||
});
|
||||
|
||||
assert_eq!(out_tlv, out_tb, "TLV vs TypeBox results should match");
|
||||
}
|
||||
@ -90,53 +127,24 @@ mod tests {
|
||||
#[ignore = "MIR13 parity: ArrayBox len/get under unified ops pending"]
|
||||
fn arraybox_set_get_len_tlv_vs_typebox() {
|
||||
ensure_host();
|
||||
let host = crate::runtime::get_global_plugin_host();
|
||||
// TLV path
|
||||
env::set_var("NYASH_DISABLE_TYPEBOX", "1");
|
||||
// TLV path (guarded)
|
||||
let _g = EnvGuard::set("NYASH_DISABLE_TYPEBOX", "1");
|
||||
let (bt1, id1, _hold1) = create_plugin_instance("ArrayBox");
|
||||
let out_tlv = {
|
||||
let h = host.read().unwrap();
|
||||
let _ = h
|
||||
.invoke_instance_method(
|
||||
&bt1,
|
||||
"set",
|
||||
id1,
|
||||
&[Box::new(IntegerBox::new(0)), Box::new(IntegerBox::new(7))],
|
||||
)
|
||||
.expect("set tlv");
|
||||
let ln = h
|
||||
.invoke_instance_method(&bt1, "len", id1, &[])
|
||||
.expect("len tlv")
|
||||
.unwrap();
|
||||
let gv = h
|
||||
.invoke_instance_method(&bt1, "get", id1, &[Box::new(IntegerBox::new(0))])
|
||||
.expect("get tlv")
|
||||
.unwrap();
|
||||
let out_tlv = with_host(|h| {
|
||||
inv_void(h, &bt1, "set", id1, &[Box::new(IntegerBox::new(0)), Box::new(IntegerBox::new(7))]);
|
||||
let ln = inv_some(h, &bt1, "len", id1, &[]);
|
||||
let gv = inv_some(h, &bt1, "get", id1, &[Box::new(IntegerBox::new(0))]);
|
||||
(ln.to_string_box().value, gv.to_string_box().value)
|
||||
};
|
||||
// TypeBox path
|
||||
env::remove_var("NYASH_DISABLE_TYPEBOX");
|
||||
});
|
||||
// TypeBox path (guarded)
|
||||
let _g2 = EnvGuard::remove("NYASH_DISABLE_TYPEBOX");
|
||||
let (bt2, id2, _hold2) = create_plugin_instance("ArrayBox");
|
||||
let out_tb = {
|
||||
let h = host.read().unwrap();
|
||||
let _ = h
|
||||
.invoke_instance_method(
|
||||
&bt2,
|
||||
"set",
|
||||
id2,
|
||||
&[Box::new(IntegerBox::new(0)), Box::new(IntegerBox::new(7))],
|
||||
)
|
||||
.expect("set tb");
|
||||
let ln = h
|
||||
.invoke_instance_method(&bt2, "length", id2, &[])
|
||||
.expect("len tb")
|
||||
.unwrap();
|
||||
let gv = h
|
||||
.invoke_instance_method(&bt2, "get", id2, &[Box::new(IntegerBox::new(0))])
|
||||
.expect("get tb")
|
||||
.unwrap();
|
||||
let out_tb = with_host(|h| {
|
||||
inv_void(h, &bt2, "set", id2, &[Box::new(IntegerBox::new(0)), Box::new(IntegerBox::new(7))]);
|
||||
let ln = inv_some(h, &bt2, "length", id2, &[]);
|
||||
let gv = inv_some(h, &bt2, "get", id2, &[Box::new(IntegerBox::new(0))]);
|
||||
(ln.to_string_box().value, gv.to_string_box().value)
|
||||
};
|
||||
});
|
||||
assert_eq!(
|
||||
out_tlv, out_tb,
|
||||
"TLV vs TypeBox results should match (ArrayBox)"
|
||||
@ -149,36 +157,22 @@ mod tests {
|
||||
ensure_host();
|
||||
let host = crate::runtime::get_global_plugin_host();
|
||||
// TLV path
|
||||
env::set_var("NYASH_DISABLE_TYPEBOX", "1");
|
||||
let _g = EnvGuard::set("NYASH_DISABLE_TYPEBOX", "1");
|
||||
let (bt1, id1, _hold1) = create_plugin_instance("StringBox");
|
||||
let out_tlv = {
|
||||
let h = host.read().unwrap();
|
||||
let out_tlv = with_host(|h| {
|
||||
// birth with init string: use fromUtf8 via set of arg in create? Current loader birth() no-arg, so concat
|
||||
let _ = h
|
||||
.invoke_instance_method(&bt1, "concat", id1, &[Box::new(StringBox::new("ab"))])
|
||||
.expect("concat tlv")
|
||||
.unwrap();
|
||||
let ln = h
|
||||
.invoke_instance_method(&bt1, "length", id1, &[])
|
||||
.expect("len tlv")
|
||||
.unwrap();
|
||||
inv_void(h, &bt1, "concat", id1, &[Box::new(StringBox::new("ab"))]);
|
||||
let ln = inv_some(h, &bt1, "length", id1, &[]);
|
||||
(ln.to_string_box().value)
|
||||
};
|
||||
});
|
||||
// TypeBox path
|
||||
env::remove_var("NYASH_DISABLE_TYPEBOX");
|
||||
let _g2 = EnvGuard::remove("NYASH_DISABLE_TYPEBOX");
|
||||
let (bt2, id2, _hold2) = create_plugin_instance("StringBox");
|
||||
let out_tb = {
|
||||
let h = host.read().unwrap();
|
||||
let _ = h
|
||||
.invoke_instance_method(&bt2, "concat", id2, &[Box::new(StringBox::new("ab"))])
|
||||
.expect("concat tb")
|
||||
.unwrap();
|
||||
let ln = h
|
||||
.invoke_instance_method(&bt2, "length", id2, &[])
|
||||
.expect("len tb")
|
||||
.unwrap();
|
||||
let out_tb = with_host(|h| {
|
||||
inv_void(h, &bt2, "concat", id2, &[Box::new(StringBox::new("ab"))]);
|
||||
let ln = inv_some(h, &bt2, "length", id2, &[]);
|
||||
(ln.to_string_box().value)
|
||||
};
|
||||
});
|
||||
assert_eq!(
|
||||
out_tlv, out_tb,
|
||||
"TLV vs TypeBox results should match (StringBox)"
|
||||
@ -191,35 +185,21 @@ mod tests {
|
||||
ensure_host();
|
||||
let host = crate::runtime::get_global_plugin_host();
|
||||
// TLV path
|
||||
env::set_var("NYASH_DISABLE_TYPEBOX", "1");
|
||||
let _g = EnvGuard::set("NYASH_DISABLE_TYPEBOX", "1");
|
||||
let (bt1, id1, _hold1) = create_plugin_instance("IntegerBox");
|
||||
let out_tlv = {
|
||||
let h = host.read().unwrap();
|
||||
let _ = h
|
||||
.invoke_instance_method(&bt1, "set", id1, &[Box::new(IntegerBox::new(123))])
|
||||
.expect("set tlv")
|
||||
.unwrap();
|
||||
let gv = h
|
||||
.invoke_instance_method(&bt1, "get", id1, &[])
|
||||
.expect("get tlv")
|
||||
.unwrap();
|
||||
let out_tlv = with_host(|h| {
|
||||
inv_void(h, &bt1, "set", id1, &[Box::new(IntegerBox::new(123))]);
|
||||
let gv = inv_some(h, &bt1, "get", id1, &[]);
|
||||
gv.to_string_box().value
|
||||
};
|
||||
});
|
||||
// TypeBox path
|
||||
env::remove_var("NYASH_DISABLE_TYPEBOX");
|
||||
let _g2 = EnvGuard::remove("NYASH_DISABLE_TYPEBOX");
|
||||
let (bt2, id2, _hold2) = create_plugin_instance("IntegerBox");
|
||||
let out_tb = {
|
||||
let h = host.read().unwrap();
|
||||
let _ = h
|
||||
.invoke_instance_method(&bt2, "set", id2, &[Box::new(IntegerBox::new(123))])
|
||||
.expect("set tb")
|
||||
.unwrap();
|
||||
let gv = h
|
||||
.invoke_instance_method(&bt2, "get", id2, &[])
|
||||
.expect("get tb")
|
||||
.unwrap();
|
||||
let out_tb = with_host(|h| {
|
||||
inv_void(h, &bt2, "set", id2, &[Box::new(IntegerBox::new(123))]);
|
||||
let gv = inv_some(h, &bt2, "get", id2, &[]);
|
||||
gv.to_string_box().value
|
||||
};
|
||||
});
|
||||
assert_eq!(
|
||||
out_tlv, out_tb,
|
||||
"TLV vs TypeBox results should match (IntegerBox)"
|
||||
@ -232,25 +212,23 @@ mod tests {
|
||||
ensure_host();
|
||||
let host = crate::runtime::get_global_plugin_host();
|
||||
// TLV path
|
||||
env::set_var("NYASH_DISABLE_TYPEBOX", "1");
|
||||
let _g = EnvGuard::set("NYASH_DISABLE_TYPEBOX", "1");
|
||||
let (bt1, id1, _hold1) = create_plugin_instance("ConsoleBox");
|
||||
let out_tlv_is_none = {
|
||||
let h = host.read().unwrap();
|
||||
let out_tlv_is_none = with_host(|h| {
|
||||
let rv = h
|
||||
.invoke_instance_method(&bt1, "println", id1, &[Box::new(StringBox::new("hello"))])
|
||||
.expect("println tlv");
|
||||
rv.is_none()
|
||||
};
|
||||
});
|
||||
// TypeBox path
|
||||
env::remove_var("NYASH_DISABLE_TYPEBOX");
|
||||
let _g2 = EnvGuard::remove("NYASH_DISABLE_TYPEBOX");
|
||||
let (bt2, id2, _hold2) = create_plugin_instance("ConsoleBox");
|
||||
let out_tb_is_none = {
|
||||
let h = host.read().unwrap();
|
||||
let out_tb_is_none = with_host(|h| {
|
||||
let rv = h
|
||||
.invoke_instance_method(&bt2, "println", id2, &[Box::new(StringBox::new("hello"))])
|
||||
.expect("println tb");
|
||||
rv.is_none()
|
||||
};
|
||||
});
|
||||
assert!(
|
||||
out_tlv_is_none && out_tb_is_none,
|
||||
"println should return void/None in both modes"
|
||||
@ -264,62 +242,36 @@ mod tests {
|
||||
let host = crate::runtime::get_global_plugin_host();
|
||||
|
||||
// TLV path
|
||||
env::set_var("NYASH_DISABLE_TYPEBOX", "1");
|
||||
let _g = EnvGuard::set("NYASH_DISABLE_TYPEBOX", "1");
|
||||
let (bt1, id1, _hold1) = create_plugin_instance("MathBox");
|
||||
let out_tlv = {
|
||||
let h = host.read().unwrap();
|
||||
let s1 = h
|
||||
.invoke_instance_method(&bt1, "sqrt", id1, &[Box::new(IntegerBox::new(9))])
|
||||
.expect("sqrt tlv")
|
||||
.unwrap();
|
||||
let s2 = h
|
||||
.invoke_instance_method(&bt1, "sin", id1, &[Box::new(IntegerBox::new(0))])
|
||||
.expect("sin tlv")
|
||||
.unwrap();
|
||||
let s3 = h
|
||||
.invoke_instance_method(&bt1, "cos", id1, &[Box::new(IntegerBox::new(0))])
|
||||
.expect("cos tlv")
|
||||
.unwrap();
|
||||
let s4 = h
|
||||
.invoke_instance_method(&bt1, "round", id1, &[Box::new(IntegerBox::new(26))])
|
||||
.expect("round tlv")
|
||||
.unwrap();
|
||||
let out_tlv = with_host(|h| {
|
||||
let s1 = inv_some(h, &bt1, "sqrt", id1, &[Box::new(IntegerBox::new(9))]);
|
||||
let s2 = inv_some(h, &bt1, "sin", id1, &[Box::new(IntegerBox::new(0))]);
|
||||
let s3 = inv_some(h, &bt1, "cos", id1, &[Box::new(IntegerBox::new(0))]);
|
||||
let s4 = inv_some(h, &bt1, "round", id1, &[Box::new(IntegerBox::new(26))]);
|
||||
(
|
||||
s1.to_string_box().value,
|
||||
s2.to_string_box().value,
|
||||
s3.to_string_box().value,
|
||||
s4.to_string_box().value,
|
||||
)
|
||||
};
|
||||
});
|
||||
|
||||
// TypeBox path
|
||||
env::remove_var("NYASH_DISABLE_TYPEBOX");
|
||||
let _g2 = EnvGuard::remove("NYASH_DISABLE_TYPEBOX");
|
||||
let (bt2, id2, _hold2) = create_plugin_instance("MathBox");
|
||||
let out_tb = {
|
||||
let h = host.read().unwrap();
|
||||
let s1 = h
|
||||
.invoke_instance_method(&bt2, "sqrt", id2, &[Box::new(IntegerBox::new(9))])
|
||||
.expect("sqrt tb")
|
||||
.unwrap();
|
||||
let s2 = h
|
||||
.invoke_instance_method(&bt2, "sin", id2, &[Box::new(IntegerBox::new(0))])
|
||||
.expect("sin tb")
|
||||
.unwrap();
|
||||
let s3 = h
|
||||
.invoke_instance_method(&bt2, "cos", id2, &[Box::new(IntegerBox::new(0))])
|
||||
.expect("cos tb")
|
||||
.unwrap();
|
||||
let s4 = h
|
||||
.invoke_instance_method(&bt2, "round", id2, &[Box::new(IntegerBox::new(26))])
|
||||
.expect("round tb")
|
||||
.unwrap();
|
||||
let out_tb = with_host(|h| {
|
||||
let s1 = inv_some(h, &bt2, "sqrt", id2, &[Box::new(IntegerBox::new(9))]);
|
||||
let s2 = inv_some(h, &bt2, "sin", id2, &[Box::new(IntegerBox::new(0))]);
|
||||
let s3 = inv_some(h, &bt2, "cos", id2, &[Box::new(IntegerBox::new(0))]);
|
||||
let s4 = inv_some(h, &bt2, "round", id2, &[Box::new(IntegerBox::new(26))]);
|
||||
(
|
||||
s1.to_string_box().value,
|
||||
s2.to_string_box().value,
|
||||
s3.to_string_box().value,
|
||||
s4.to_string_box().value,
|
||||
)
|
||||
};
|
||||
});
|
||||
assert_eq!(
|
||||
out_tlv, out_tb,
|
||||
"TLV vs TypeBox results should match (MathBox)"
|
||||
@ -341,46 +293,34 @@ mod tests {
|
||||
};
|
||||
|
||||
// TLV path
|
||||
env::set_var("NYASH_DISABLE_TYPEBOX", "1");
|
||||
let _g = EnvGuard::set("NYASH_DISABLE_TYPEBOX", "1");
|
||||
let (bt1, id1, _hold1) = create_plugin_instance("EncodingBox");
|
||||
let out_tlv = {
|
||||
let h = host.read().unwrap();
|
||||
let b64 = h
|
||||
.invoke_instance_method(
|
||||
&bt1,
|
||||
"base64Encode",
|
||||
id1,
|
||||
&[Box::new(StringBox::new("hi"))],
|
||||
)
|
||||
.expect("b64 tlv")
|
||||
.unwrap();
|
||||
let hex = h
|
||||
.invoke_instance_method(&bt1, "hexEncode", id1, &[Box::new(StringBox::new("hi"))])
|
||||
.expect("hex tlv")
|
||||
.unwrap();
|
||||
let out_tlv = with_host(|h| {
|
||||
let b64 = inv_some(
|
||||
h,
|
||||
&bt1,
|
||||
"base64Encode",
|
||||
id1,
|
||||
&[Box::new(StringBox::new("hi"))],
|
||||
);
|
||||
let hex = inv_some(h, &bt1, "hexEncode", id1, &[Box::new(StringBox::new("hi"))]);
|
||||
(b64.to_string_box().value, hex.to_string_box().value)
|
||||
};
|
||||
});
|
||||
|
||||
// TypeBox path
|
||||
env::remove_var("NYASH_DISABLE_TYPEBOX");
|
||||
let _g2 = EnvGuard::remove("NYASH_DISABLE_TYPEBOX");
|
||||
let (bt2, id2, _hold2) = create_plugin_instance("EncodingBox");
|
||||
let out_tb = {
|
||||
let h = host.read().unwrap();
|
||||
let b64 = h
|
||||
.invoke_instance_method(
|
||||
&bt2,
|
||||
"base64Encode",
|
||||
id2,
|
||||
&[Box::new(StringBox::new("hi"))],
|
||||
)
|
||||
.expect("b64 tb")
|
||||
.unwrap();
|
||||
let hex = h
|
||||
.invoke_instance_method(&bt2, "hexEncode", id2, &[Box::new(StringBox::new("hi"))])
|
||||
.expect("hex tb")
|
||||
.unwrap();
|
||||
let out_tb = with_host(|h| {
|
||||
let b64 = inv_some(
|
||||
h,
|
||||
&bt2,
|
||||
"base64Encode",
|
||||
id2,
|
||||
&[Box::new(StringBox::new("hi"))],
|
||||
);
|
||||
let hex = inv_some(h, &bt2, "hexEncode", id2, &[Box::new(StringBox::new("hi"))]);
|
||||
(b64.to_string_box().value, hex.to_string_box().value)
|
||||
};
|
||||
});
|
||||
assert_eq!(
|
||||
out_tlv, out_tb,
|
||||
"TLV vs TypeBox results should match (EncodingBox)"
|
||||
@ -394,42 +334,24 @@ mod tests {
|
||||
let host = crate::runtime::get_global_plugin_host();
|
||||
|
||||
// TLV path
|
||||
env::set_var("NYASH_DISABLE_TYPEBOX", "1");
|
||||
let _g = EnvGuard::set("NYASH_DISABLE_TYPEBOX", "1");
|
||||
let (bt1, id1, _hold1) = create_plugin_instance("RegexBox");
|
||||
let out_tlv = {
|
||||
let h = host.read().unwrap();
|
||||
let _ = h
|
||||
.invoke_instance_method(&bt1, "compile", id1, &[Box::new(StringBox::new("h.+o"))])
|
||||
.expect("compile tlv");
|
||||
let m = h
|
||||
.invoke_instance_method(&bt1, "isMatch", id1, &[Box::new(StringBox::new("hello"))])
|
||||
.expect("isMatch tlv")
|
||||
.unwrap();
|
||||
let f = h
|
||||
.invoke_instance_method(&bt1, "find", id1, &[Box::new(StringBox::new("hello"))])
|
||||
.expect("find tlv")
|
||||
.unwrap();
|
||||
let out_tlv = with_host(|h| {
|
||||
inv_void(h, &bt1, "compile", id1, &[Box::new(StringBox::new("h.+o"))]);
|
||||
let m = inv_some(h, &bt1, "isMatch", id1, &[Box::new(StringBox::new("hello"))]);
|
||||
let f = inv_some(h, &bt1, "find", id1, &[Box::new(StringBox::new("hello"))]);
|
||||
(m.to_string_box().value, f.to_string_box().value)
|
||||
};
|
||||
});
|
||||
|
||||
// TypeBox path
|
||||
env::remove_var("NYASH_DISABLE_TYPEBOX");
|
||||
let _g2 = EnvGuard::remove("NYASH_DISABLE_TYPEBOX");
|
||||
let (bt2, id2, _hold2) = create_plugin_instance("RegexBox");
|
||||
let out_tb = {
|
||||
let h = host.read().unwrap();
|
||||
let _ = h
|
||||
.invoke_instance_method(&bt2, "compile", id2, &[Box::new(StringBox::new("h.+o"))])
|
||||
.expect("compile tb");
|
||||
let m = h
|
||||
.invoke_instance_method(&bt2, "isMatch", id2, &[Box::new(StringBox::new("hello"))])
|
||||
.expect("isMatch tb")
|
||||
.unwrap();
|
||||
let f = h
|
||||
.invoke_instance_method(&bt2, "find", id2, &[Box::new(StringBox::new("hello"))])
|
||||
.expect("find tb")
|
||||
.unwrap();
|
||||
let out_tb = with_host(|h| {
|
||||
inv_void(h, &bt2, "compile", id2, &[Box::new(StringBox::new("h.+o"))]);
|
||||
let m = inv_some(h, &bt2, "isMatch", id2, &[Box::new(StringBox::new("hello"))]);
|
||||
let f = inv_some(h, &bt2, "find", id2, &[Box::new(StringBox::new("hello"))]);
|
||||
(m.to_string_box().value, f.to_string_box().value)
|
||||
};
|
||||
});
|
||||
assert_eq!(
|
||||
out_tlv, out_tb,
|
||||
"TLV vs TypeBox results should match (RegexBox)"
|
||||
@ -443,108 +365,66 @@ mod tests {
|
||||
let host = crate::runtime::get_global_plugin_host();
|
||||
|
||||
// TLV path
|
||||
env::set_var("NYASH_DISABLE_TYPEBOX", "1");
|
||||
let _g = EnvGuard::set("NYASH_DISABLE_TYPEBOX", "1");
|
||||
let (bt1, id1, _hold1) = create_plugin_instance("PathBox");
|
||||
let out_tlv = {
|
||||
let h = host.read().unwrap();
|
||||
let j = h
|
||||
.invoke_instance_method(
|
||||
&bt1,
|
||||
"join",
|
||||
id1,
|
||||
&[
|
||||
Box::new(StringBox::new("/a/b")),
|
||||
Box::new(StringBox::new("c.txt")),
|
||||
],
|
||||
)
|
||||
.expect("join tlv")
|
||||
.unwrap();
|
||||
let d = h
|
||||
.invoke_instance_method(
|
||||
&bt1,
|
||||
"dirname",
|
||||
id1,
|
||||
&[Box::new(StringBox::new("/a/b/c.txt"))],
|
||||
)
|
||||
.expect("dirname tlv")
|
||||
.unwrap();
|
||||
let b = h
|
||||
.invoke_instance_method(
|
||||
&bt1,
|
||||
"basename",
|
||||
id1,
|
||||
&[Box::new(StringBox::new("/a/b/c.txt"))],
|
||||
)
|
||||
.expect("basename tlv")
|
||||
.unwrap();
|
||||
let n = h
|
||||
.invoke_instance_method(
|
||||
&bt1,
|
||||
"normalize",
|
||||
id1,
|
||||
&[Box::new(StringBox::new("/a/./b/../b/c"))],
|
||||
)
|
||||
.expect("normalize tlv")
|
||||
.unwrap();
|
||||
let out_tlv = with_host(|h| {
|
||||
let j = inv_some(
|
||||
h,
|
||||
&bt1,
|
||||
"join",
|
||||
id1,
|
||||
&[
|
||||
Box::new(StringBox::new("/a/b")),
|
||||
Box::new(StringBox::new("c.txt")),
|
||||
],
|
||||
);
|
||||
let d = inv_some(h, &bt1, "dirname", id1, &[Box::new(StringBox::new("/a/b/c.txt"))]);
|
||||
let b = inv_some(h, &bt1, "basename", id1, &[Box::new(StringBox::new("/a/b/c.txt"))]);
|
||||
let n = inv_some(
|
||||
h,
|
||||
&bt1,
|
||||
"normalize",
|
||||
id1,
|
||||
&[Box::new(StringBox::new("/a/./b/../b/c"))],
|
||||
);
|
||||
(
|
||||
j.to_string_box().value,
|
||||
d.to_string_box().value,
|
||||
b.to_string_box().value,
|
||||
n.to_string_box().value,
|
||||
)
|
||||
};
|
||||
});
|
||||
|
||||
// TypeBox path
|
||||
env::remove_var("NYASH_DISABLE_TYPEBOX");
|
||||
let _g2 = EnvGuard::remove("NYASH_DISABLE_TYPEBOX");
|
||||
let (bt2, id2, _hold2) = create_plugin_instance("PathBox");
|
||||
let out_tb = {
|
||||
let h = host.read().unwrap();
|
||||
let j = h
|
||||
.invoke_instance_method(
|
||||
&bt2,
|
||||
"join",
|
||||
id2,
|
||||
&[
|
||||
Box::new(StringBox::new("/a/b")),
|
||||
Box::new(StringBox::new("c.txt")),
|
||||
],
|
||||
)
|
||||
.expect("join tb")
|
||||
.unwrap();
|
||||
let d = h
|
||||
.invoke_instance_method(
|
||||
&bt2,
|
||||
"dirname",
|
||||
id2,
|
||||
&[Box::new(StringBox::new("/a/b/c.txt"))],
|
||||
)
|
||||
.expect("dirname tb")
|
||||
.unwrap();
|
||||
let b = h
|
||||
.invoke_instance_method(
|
||||
&bt2,
|
||||
"basename",
|
||||
id2,
|
||||
&[Box::new(StringBox::new("/a/b/c.txt"))],
|
||||
)
|
||||
.expect("basename tb")
|
||||
.unwrap();
|
||||
let n = h
|
||||
.invoke_instance_method(
|
||||
&bt2,
|
||||
"normalize",
|
||||
id2,
|
||||
&[Box::new(StringBox::new("/a/./b/../b/c"))],
|
||||
)
|
||||
.expect("normalize tb")
|
||||
.unwrap();
|
||||
let out_tb = with_host(|h| {
|
||||
let j = inv_some(
|
||||
h,
|
||||
&bt2,
|
||||
"join",
|
||||
id2,
|
||||
&[
|
||||
Box::new(StringBox::new("/a/b")),
|
||||
Box::new(StringBox::new("c.txt")),
|
||||
],
|
||||
);
|
||||
let d = inv_some(h, &bt2, "dirname", id2, &[Box::new(StringBox::new("/a/b/c.txt"))]);
|
||||
let b = inv_some(h, &bt2, "basename", id2, &[Box::new(StringBox::new("/a/b/c.txt"))]);
|
||||
let n = inv_some(
|
||||
h,
|
||||
&bt2,
|
||||
"normalize",
|
||||
id2,
|
||||
&[Box::new(StringBox::new("/a/./b/../b/c"))],
|
||||
);
|
||||
(
|
||||
j.to_string_box().value,
|
||||
d.to_string_box().value,
|
||||
b.to_string_box().value,
|
||||
n.to_string_box().value,
|
||||
)
|
||||
};
|
||||
});
|
||||
assert_eq!(
|
||||
out_tlv, out_tb,
|
||||
"TLV vs TypeBox results should match (PathBox)"
|
||||
@ -559,54 +439,48 @@ mod tests {
|
||||
let toml_text = "[package]\nname=\"nyash\"\n[deps]\nregex=\"1\"\n";
|
||||
|
||||
// TLV path
|
||||
env::set_var("NYASH_DISABLE_TYPEBOX", "1");
|
||||
let _g = EnvGuard::set("NYASH_DISABLE_TYPEBOX", "1");
|
||||
let (bt1, id1, _hold1) = create_plugin_instance("TOMLBox");
|
||||
let out_tlv = {
|
||||
let h = host.read().unwrap();
|
||||
let _ = h
|
||||
.invoke_instance_method(&bt1, "parse", id1, &[Box::new(StringBox::new(toml_text))])
|
||||
.expect("parse tlv")
|
||||
.unwrap();
|
||||
let name = h
|
||||
.invoke_instance_method(
|
||||
&bt1,
|
||||
"get",
|
||||
id1,
|
||||
&[Box::new(StringBox::new("package.name"))],
|
||||
)
|
||||
.expect("get tlv")
|
||||
.unwrap();
|
||||
let json = h
|
||||
.invoke_instance_method(&bt1, "toJson", id1, &[])
|
||||
.expect("toJson tlv")
|
||||
.unwrap();
|
||||
let out_tlv = with_host(|h| {
|
||||
inv_void(
|
||||
h,
|
||||
&bt1,
|
||||
"parse",
|
||||
id1,
|
||||
&[Box::new(StringBox::new(toml_text))],
|
||||
);
|
||||
let name = inv_some(
|
||||
h,
|
||||
&bt1,
|
||||
"get",
|
||||
id1,
|
||||
&[Box::new(StringBox::new("package.name"))],
|
||||
);
|
||||
let json = inv_some(h, &bt1, "toJson", id1, &[]);
|
||||
(name.to_string_box().value, json.to_string_box().value)
|
||||
};
|
||||
});
|
||||
|
||||
// TypeBox path
|
||||
env::remove_var("NYASH_DISABLE_TYPEBOX");
|
||||
let _g2 = EnvGuard::remove("NYASH_DISABLE_TYPEBOX");
|
||||
let (bt2, id2, _hold2) = create_plugin_instance("TOMLBox");
|
||||
let out_tb = {
|
||||
let h = host.read().unwrap();
|
||||
let _ = h
|
||||
.invoke_instance_method(&bt2, "parse", id2, &[Box::new(StringBox::new(toml_text))])
|
||||
.expect("parse tb")
|
||||
.unwrap();
|
||||
let name = h
|
||||
.invoke_instance_method(
|
||||
&bt2,
|
||||
"get",
|
||||
id2,
|
||||
&[Box::new(StringBox::new("package.name"))],
|
||||
)
|
||||
.expect("get tb")
|
||||
.unwrap();
|
||||
let json = h
|
||||
.invoke_instance_method(&bt2, "toJson", id2, &[])
|
||||
.expect("toJson tb")
|
||||
.unwrap();
|
||||
let out_tb = with_host(|h| {
|
||||
inv_void(
|
||||
h,
|
||||
&bt2,
|
||||
"parse",
|
||||
id2,
|
||||
&[Box::new(StringBox::new(toml_text))],
|
||||
);
|
||||
let name = inv_some(
|
||||
h,
|
||||
&bt2,
|
||||
"get",
|
||||
id2,
|
||||
&[Box::new(StringBox::new("package.name"))],
|
||||
);
|
||||
let json = inv_some(h, &bt2, "toJson", id2, &[]);
|
||||
(name.to_string_box().value, json.to_string_box().value)
|
||||
};
|
||||
});
|
||||
assert_eq!(
|
||||
out_tlv, out_tb,
|
||||
"TLV vs TypeBox results should match (TOMLBox)"
|
||||
@ -620,28 +494,20 @@ mod tests {
|
||||
let host = crate::runtime::get_global_plugin_host();
|
||||
|
||||
// TLV path
|
||||
env::set_var("NYASH_DISABLE_TYPEBOX", "1");
|
||||
let _g = EnvGuard::set("NYASH_DISABLE_TYPEBOX", "1");
|
||||
let (bt1, id1, _hold1) = create_plugin_instance("TimeBox");
|
||||
let t_tlv = {
|
||||
let h = host.read().unwrap();
|
||||
let v = h
|
||||
.invoke_instance_method(&bt1, "now", id1, &[])
|
||||
.expect("now tlv")
|
||||
.unwrap();
|
||||
let t_tlv = with_host(|h| {
|
||||
let v = inv_some(h, &bt1, "now", id1, &[]);
|
||||
v.to_string_box().value.parse::<i64>().unwrap_or(0)
|
||||
};
|
||||
});
|
||||
|
||||
// TypeBox path
|
||||
env::remove_var("NYASH_DISABLE_TYPEBOX");
|
||||
let _g2 = EnvGuard::remove("NYASH_DISABLE_TYPEBOX");
|
||||
let (bt2, id2, _hold2) = create_plugin_instance("TimeBox");
|
||||
let t_tb = {
|
||||
let h = host.read().unwrap();
|
||||
let v = h
|
||||
.invoke_instance_method(&bt2, "now", id2, &[])
|
||||
.expect("now tb")
|
||||
.unwrap();
|
||||
let t_tb = with_host(|h| {
|
||||
let v = inv_some(h, &bt2, "now", id2, &[]);
|
||||
v.to_string_box().value.parse::<i64>().unwrap_or(0)
|
||||
};
|
||||
});
|
||||
|
||||
let diff = (t_tb - t_tlv).abs();
|
||||
assert!(diff < 5_000, "TimeBox.now difference too large: {}ms", diff);
|
||||
@ -654,49 +520,31 @@ mod tests {
|
||||
let host = crate::runtime::get_global_plugin_host();
|
||||
|
||||
// TLV path: verify get->inc->get increases by 1
|
||||
env::set_var("NYASH_DISABLE_TYPEBOX", "1");
|
||||
let _g = EnvGuard::set("NYASH_DISABLE_TYPEBOX", "1");
|
||||
let (bt1, id1, _hold1) = create_plugin_instance("CounterBox");
|
||||
let (a1, b1) = {
|
||||
let h = host.read().unwrap();
|
||||
let a = h
|
||||
.invoke_instance_method(&bt1, "get", id1, &[])
|
||||
.expect("get tlv")
|
||||
.unwrap();
|
||||
let _ = h
|
||||
.invoke_instance_method(&bt1, "inc", id1, &[])
|
||||
.expect("inc tlv");
|
||||
let b = h
|
||||
.invoke_instance_method(&bt1, "get", id1, &[])
|
||||
.expect("get2 tlv")
|
||||
.unwrap();
|
||||
let (a1, b1) = with_host(|h| {
|
||||
let a = inv_some(h, &bt1, "get", id1, &[]);
|
||||
inv_void(h, &bt1, "inc", id1, &[]);
|
||||
let b = inv_some(h, &bt1, "get", id1, &[]);
|
||||
(
|
||||
a.to_string_box().value.parse::<i64>().unwrap_or(0),
|
||||
b.to_string_box().value.parse::<i64>().unwrap_or(0),
|
||||
)
|
||||
};
|
||||
});
|
||||
assert_eq!(b1 - a1, 1, "CounterBox TLV should increment by 1");
|
||||
|
||||
// TypeBox path: verify same delta behavior (not comparing absolute values due to singleton)
|
||||
env::remove_var("NYASH_DISABLE_TYPEBOX");
|
||||
let _g2 = EnvGuard::remove("NYASH_DISABLE_TYPEBOX");
|
||||
let (bt2, id2, _hold2) = create_plugin_instance("CounterBox");
|
||||
let (a2, b2) = {
|
||||
let h = host.read().unwrap();
|
||||
let a = h
|
||||
.invoke_instance_method(&bt2, "get", id2, &[])
|
||||
.expect("get tb")
|
||||
.unwrap();
|
||||
let _ = h
|
||||
.invoke_instance_method(&bt2, "inc", id2, &[])
|
||||
.expect("inc tb");
|
||||
let b = h
|
||||
.invoke_instance_method(&bt2, "get", id2, &[])
|
||||
.expect("get2 tb")
|
||||
.unwrap();
|
||||
let (a2, b2) = with_host(|h| {
|
||||
let a = inv_some(h, &bt2, "get", id2, &[]);
|
||||
inv_void(h, &bt2, "inc", id2, &[]);
|
||||
let b = inv_some(h, &bt2, "get", id2, &[]);
|
||||
(
|
||||
a.to_string_box().value.parse::<i64>().unwrap_or(0),
|
||||
b.to_string_box().value.parse::<i64>().unwrap_or(0),
|
||||
)
|
||||
};
|
||||
});
|
||||
assert_eq!(b2 - a2, 1, "CounterBox TypeBox should increment by 1");
|
||||
}
|
||||
|
||||
@ -718,8 +566,7 @@ mod tests {
|
||||
// TLV path
|
||||
env::set_var("NYASH_DISABLE_TYPEBOX", "1");
|
||||
let (bt1, id1, _hold1) = create_plugin_instance("FileBox");
|
||||
let out_tlv = {
|
||||
let h = host.read().unwrap();
|
||||
let out_tlv = with_host(|h| {
|
||||
let _ = h
|
||||
.invoke_instance_method(
|
||||
&bt1,
|
||||
@ -749,21 +596,17 @@ mod tests {
|
||||
],
|
||||
)
|
||||
.expect("open2 tlv");
|
||||
let rd = h
|
||||
.invoke_instance_method(&bt1, "read", id1, &[])
|
||||
.expect("read tlv")
|
||||
.unwrap();
|
||||
let rd = inv_some(h, &bt1, "read", id1, &[]);
|
||||
let _ = h
|
||||
.invoke_instance_method(&bt1, "close", id1, &[])
|
||||
.expect("close2 tlv");
|
||||
rd.to_string_box().value
|
||||
};
|
||||
});
|
||||
|
||||
// TypeBox path
|
||||
env::remove_var("NYASH_DISABLE_TYPEBOX");
|
||||
let _g2 = EnvGuard::remove("NYASH_DISABLE_TYPEBOX");
|
||||
let (bt2, id2, _hold2) = create_plugin_instance("FileBox");
|
||||
let out_tb = {
|
||||
let h = host.read().unwrap();
|
||||
let out_tb = with_host(|h| {
|
||||
let _ = h
|
||||
.invoke_instance_method(
|
||||
&bt2,
|
||||
@ -792,15 +635,12 @@ mod tests {
|
||||
],
|
||||
)
|
||||
.expect("open2 tb");
|
||||
let rd = h
|
||||
.invoke_instance_method(&bt2, "read", id2, &[])
|
||||
.expect("read tb")
|
||||
.unwrap();
|
||||
let rd = inv_some(h, &bt2, "read", id2, &[]);
|
||||
let _ = h
|
||||
.invoke_instance_method(&bt2, "close", id2, &[])
|
||||
.expect("close2 tb");
|
||||
rd.to_string_box().value
|
||||
};
|
||||
});
|
||||
|
||||
// Cleanup best-effort
|
||||
let _ = fs::remove_file(&path_str);
|
||||
@ -813,7 +653,9 @@ mod tests {
|
||||
|
||||
fn rand_id() -> u64 {
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
|
||||
let now = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("SystemTime before UNIX_EPOCH");
|
||||
now.as_micros() as u64
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user