From abdf23f87fe37c72c6e1819536a620b31f11d297 Mon Sep 17 00:00:00 2001
From: ARCJ137442 <61109168+ARCJ137442@users.noreply.github.com>
Date: Thu, 12 Sep 2024 17:37:51 +0800
Subject: [PATCH] =?UTF-8?q?refactor:=20:white=5Fcheck=5Fmark:=20=E6=95=B4?=
=?UTF-8?q?=E7=90=86=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/bin/ws_server_test/main.rs | 174 +++++++++++++++++
src/main.rs | 341 +-------------------------------
src/tests/config_paths.rs | 54 +++++
src/tests/mod.rs | 347 +++++++++++++++++++++++++++++++++
4 files changed, 577 insertions(+), 339 deletions(-)
create mode 100644 src/bin/ws_server_test/main.rs
create mode 100644 src/tests/config_paths.rs
create mode 100644 src/tests/mod.rs
diff --git a/src/bin/ws_server_test/main.rs b/src/bin/ws_server_test/main.rs
new file mode 100644
index 0000000..864e780
--- /dev/null
+++ b/src/bin/ws_server_test/main.rs
@@ -0,0 +1,174 @@
+//! 基于Websocket的远程NAVM虚拟机测试
+//! * ⚠️【2024-09-12 17:06:00】此处代码仅作研究用,不推荐用于实际使用
+
+use std::{
+ cell::RefCell,
+ thread::{self, sleep},
+ time::Duration,
+};
+extern crate ws;
+
+fn main() {
+ /// 单次训练过程
+ fn train(sender: ws::Sender) -> impl Fn(ws::Message) -> Result<(), ws::Error> {
+ // 尝试注册操作
+ let _ = sender.send("REG left".to_string());
+ let _ = sender.send("REG right".to_string());
+
+ // 预先经验
+ for _ in 0..5 {
+ // 背景事件
+ let _ = sender.send("NSE b>. :|:".to_string());
+ // 自身操作
+ let _ = sender.send("NSE <(*, {SELF}) --> ^left>. :|:".to_string());
+ let _ = sender.send("NSE <(*, {SELF}) --> ^right>. :|:".to_string());
+ // 一定间隔
+ let _ = sender.send("CYC 10".to_string());
+ // 自身状态
+ let _ = sender.send("NSE <{SELF} --> [good]>. :|:".to_string());
+ }
+ // 再间隔一段时间,开始训练
+ let _ = sender.send("CYC 100".to_string());
+
+ let sender2 = sender.clone();
+ // 生成一个不断发送消息的线程
+ thread::spawn(move || loop {
+ let _ = sender2.send("NSE b>. :|:".to_string());
+ let _ = sender2.send("CYC 10".to_string());
+ let _ = sender2.send("NSE <{SELF} --> [good]>! :|:".to_string());
+ // let _ = sender2.send("NSE 1 =/> <{SELF} --> [good]>>? :|:".to_string());
+ thread::sleep(Duration::from_secs_f64(0.03));
+ });
+
+ // * 📝Websocket Handler不能可变,就用RefCell实现内部可变性
+ let right_side = RefCell::new(false);
+ let num_good = RefCell::new(0_usize);
+ let output_steps = RefCell::new(0_usize);
+ let minimum_fitness_period = RefCell::new(usize::MAX);
+ const MAX_GOOD: usize = 20;
+ move |msg: ws::Message| {
+ // println!("Got message: {}", msg);
+ let msg = msg.to_string();
+ // 记录步数
+ let output_steps = &mut *output_steps.borrow_mut();
+ *output_steps += 1;
+ // 操作
+ if msg.contains("EXE") {
+ // 左右操作状态
+ let left = msg.contains(r#"["left","{SELF}"]"#);
+ let right = msg.contains(r#"["right","{SELF}"]"#);
+ if !left && !right {
+ return Ok(());
+ }
+ let minimum_fitness_period = &mut *minimum_fitness_period.borrow_mut();
+ // * 🔬可以尝试「左右颠倒」以观察NARS的适应能力
+ let num_good = &mut *num_good.borrow_mut();
+ let right_side = &mut *right_side.borrow_mut();
+ let lr = if *right_side { "right" } else { "left" };
+ // 奖励
+ if left && !*right_side || right && *right_side {
+ let _ = sender.send("NSE <{SELF} --> [good]>. :|: %1.0; 0.5%".to_string());
+ println!("good\t{lr}\tfor {num_good}!\t{minimum_fitness_period}");
+ *num_good += 1;
+ // 改变模式
+ if *num_good > MAX_GOOD {
+ let b = *right_side;
+ *right_side = !b;
+ *num_good = 0;
+ // 一个轮回⇒以「轮回数」记录「适应性」
+ if b {
+ *minimum_fitness_period = *minimum_fitness_period.min(output_steps);
+ *output_steps = 0;
+ }
+ }
+ }
+ // 惩罚
+ else {
+ let _ = sender.send("NSE <{SELF} --> [good]>. :|: %0.0; 0.5%".to_string());
+ println!("bad\t{lr}\tfor {num_good}!\t{minimum_fitness_period}");
+ }
+ }
+ // out.close(CloseCode::Normal)
+ Ok(())
+ }
+ }
+
+ // 循环
+ loop {
+ let _ = ws::connect("ws://127.0.0.1:8765", train);
+ // 连接失败则延迟等待
+ sleep(Duration::from_secs(1));
+ }
+}
+
+/// 压力测试
+/// * 🚩发送大量NSE消息,测试服务器端响应快慢
+#[test]
+#[ignore = "【2024-04-14 20:38:45】仅作为其它Websocket服务端的压力测试,不应在库测试中出现"]
+fn test_overwhelming_nse() {
+ loop {
+ let _ = ws::connect("ws://127.0.0.1:8765", |sender| {
+ // 生成一个不断发送消息的线程
+ thread::spawn(move || loop {
+ let _ = sender.send("NSE A.".to_string());
+ let _ = sender.send("NSE B.".to_string());
+ let _ = sender.send("NSE A?".to_string());
+ });
+
+ // handle received message
+ move |msg| {
+ println!("Got message: {}", msg);
+ // out.close(CloseCode::Normal)
+ Ok(())
+ }
+ });
+ sleep(Duration::from_secs(1));
+ }
+}
+
+/// debug测试
+/// * 🔗GitHub issue:
+#[test]
+#[ignore = "【2024-04-14 20:38:45】仅作为其它Websocket服务端的测试,不应在库测试中出现"]
+fn main_debug() {
+ // A client that sends tons of messages to the server
+ thread::spawn(move || {
+ let _ = ws::connect("ws://127.0.0.1:3012", |sender| {
+ let mut num_send = 0_usize;
+ // Generate a thread that constantly sends messages for testing
+ thread::spawn(move || loop {
+ num_send += 1;
+ // The content is just for example, the actual situation has more variety
+ let _ = sender.send(format!("overwhelming message #{num_send}!"));
+ });
+
+ // Handle nothing
+ move |_| Ok(())
+ });
+ });
+
+ // A server that echoes messages back to the client
+ ws::Builder::new()
+ .with_settings(ws::Settings {
+ max_connections: 0x40,
+ // * ↓Change this setting to `usize::MAX` actually can't be allowed: It might run out of memory
+ queue_size: 0x300,
+ // ! ↓Even enabled it, it still can't stop the blocking
+ panic_on_queue: true,
+ ..Default::default()
+ })
+ .build(|sender: ws::Sender| {
+ // handle received message
+ move |msg| {
+ println!("Got message: {msg}");
+ println!("from {sender:?}");
+ // ! It will block on ↓this line when the `SyncSender` is full
+ let _ = sender.send(msg);
+ // * ↑If uncomment this line of code, the server will not be blocked
+ Ok(())
+ }
+ })
+ .unwrap()
+ .listen("127.0.0.1:3012")
+ .unwrap();
+}
diff --git a/src/main.rs b/src/main.rs
index 880f424..54448a1 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -98,343 +98,6 @@ pub fn main_args(cwd: IoResult, args: impl Iterator- ) ->
result
}
-/// 单元测试
+// 单元测试
#[cfg(test)]
-#[allow(unused_attributes)]
-mod tests {
- use super::*;
- use babel_nar::tests::config_paths::*;
- use nar_dev_utils::list;
-
- /// 测试入口/ONA
- /// * 🎯通用、可复用的启动代码
- /// * 🎯跨不同CIN通用
- /// * 🎯跨同CIN不同测试通用
- pub fn main(cin_config_path: &str, other_args: &[&str]) -> Result<()> {
- babel_nar::exists_or_exit!("./executables");
- // 以默认参数启动
- main_args(
- env::current_dir(),
- [
- &["BabelNAR-cli.exe", "-d", "-c", cin_config_path],
- other_args,
- ]
- .concat()
- .into_iter()
- .map(str::to_string),
- )
- }
-
- /// 测试入口/多配置加载
- /// * 🎯多「虚拟机启动配置」合并
- /// * 🎯预引入NAL
- pub fn main_configs(cin_config_path: &str, other_config_paths: &[&str]) -> Result<()> {
- let args = list![
- [
- // 第二个文件,搭建测试环境
- "-c",
- config_path,
- // 第三个文件,指示预加载
- "-c",
- config_path,
- ]
- for config_path in (other_config_paths)
- ]
- .concat();
- main(cin_config_path, &args)
- }
-
- /// 批量生成「预引入NAL」
- macro_rules! cin_tests {
- (
- $(#[$attr_root:meta])*
- $cin_path:ident; // ! ❌若为`expr`,则会和上边的修饰符导致「本地歧义」
- $(
- $(#[$attr:meta])*
- $name:ident => $config_path:expr $(;)?
- )*
- ) => {
- /// 主Shell
- /// * 🎯正常BabelNAR CLI shell启动
- /// * 🎯正常用户命令行交互体验
- $(#[$attr_root])*
- #[test]
- #[ignore = "仅作试运行用,不用于自动化测试"]
- pub fn main_shell() -> Result<()> {
- main($cin_path, &[])
- }
-
-
- /// Matriangle服务器
- /// * 🎯复现先前基于Matriangle环境的NARS实验
- $(#[$attr_root])*
- #[test]
- #[ignore = "仅作试运行用,不用于自动化测试"]
- pub fn main_matriangle_server() -> Result<()> {
- // 以默认参数启动
- main_configs($cin_path, &[MATRIANGLE_SERVER])
- }
-
- $(
- $(#[$attr])*
- #[test]
- #[ignore = "【2024-06-12 23:52:35】不用于自动化测试:会自动清屏影响测试结果呈现"]
- pub fn $name() -> Result<()> {
- main_configs($cin_path, &[PRELUDE_TEST, $config_path])
- }
- )*
- };
- }
-
- /// 测试/ONA
- mod ona {
- use super::*;
-
- cin_tests! {
- ONA;
-
- /// 真值通配
- /// * 📝✅【2024-06-15 20:31:10】成功
- nal_tw => NAL_TRUTH_WILDCARD
-
- /// 简单演绎
- /// * 📝✅【2024-04-19 22:49:51】成功
- nal_de => NAL_SIMPLE_DEDUCTION
-
- /// 高阶演绎
- /// * 📝✅【2024-04-19 22:50:04】成功
- nal_hi => NAL_HIGHER_DEDUCTION
-
- /// 自变量消除
- /// * 📝✅【2024-04-19 22:50:53】成功
- nal_ie => NAL_I_VAR_ELIMINATION
-
- /// 时间归纳
- /// * 📝✅【2024-04-19 22:52:45】成功
- nal_te => NAL_TEMPORAL_INDUCTION
-
- /// 简单操作
- /// * 📝❌【2024-04-19 22:55:35】失败:推理不出任何内容
- nal_so => NAL_SIMPLE_OPERATION
-
- /// 操作
- /// * 📝✅【2024-04-19 23:01:52】成功,但少许问题
- /// * 📝【2024-04-07 14:17:21】目前ONA面对其中的「经验问句」没有回答
- /// * ⚠️在启用`REG left`注册操作后,反而从成功变为失败
- nal_op => NAL_OPERATION
- }
- }
-
- /// 测试/OpenNARS (3.x)
- mod opennars {
- use super::*;
-
- cin_tests! {
- #[ignore = "【2024-04-14 20:24:52】会导致残留子进程"]
- OPENNARS;
-
- /// 真值通配
- /// * 📝✅【2024-06-15 20:31:10】成功
- nal_tw => NAL_TRUTH_WILDCARD
-
- /// 简单演绎
- /// * 📝✅【2024-04-19 22:49:02】成功(步数性能上不佳)
- nal_de => NAL_SIMPLE_DEDUCTION
-
- /// 高阶演绎
- /// * 📝✅【2024-04-19 22:48:56】成功
- nal_hi => NAL_HIGHER_DEDUCTION
-
- /// 自变量消除
- /// * 📝✅【2024-04-07 16:01:15】成功
- nal_ie => NAL_I_VAR_ELIMINATION
-
- /// 时间归纳
- /// * 📝✅【2024-04-19 22:52:35】成功(步数性能上不佳)
- nal_te => NAL_TEMPORAL_INDUCTION
-
- /// 简单操作
- /// * 📝✅【2024-04-07 16:13:39】成功
- nal_so => NAL_SIMPLE_OPERATION
-
- /// 操作
- /// * 📝✅【2024-04-07 14:59:53】成功
- nal_op => NAL_OPERATION
- }
- }
-
- /// 测试/OpenNARS (1.5.8)
- mod opennars158 {
- use super::*;
-
- cin_tests! {
- #[ignore = "【2024-04-14 20:24:52】会导致残留子进程"]
- OPENNARS_158;
-
- /// 真值通配
- /// * 📝✅【2024-06-15 20:31:10】成功
- nal_tw => NAL_TRUTH_WILDCARD
-
- /// 简单演绎
- /// * 📝✅【2024-04-19 23:02:59】成功
- nal_de => NAL_SIMPLE_DEDUCTION
-
- /// 高阶演绎
- /// * 📝✅【2024-04-19 23:03:06】成功
- nal_hi => NAL_HIGHER_DEDUCTION
-
- /// 自变量消除
- /// * 📝✅【2024-04-19 23:03:15】成功
- nal_ie => NAL_I_VAR_ELIMINATION
-
- /// 时间归纳
- /// * 📝❌【2024-04-19 23:03:20】失败:语法层面就不支持
- nal_te => NAL_TEMPORAL_INDUCTION
-
- /// 简单操作
- /// * 📝❌【2024-04-19 23:03:37】失败:语法层面就不支持
- nal_so => NAL_SIMPLE_OPERATION
-
- /// 操作
- /// * 📝❌【2024-04-19 23:03:48】失败:语法层面就不支持
- nal_op => NAL_OPERATION
- }
- }
-
- /// 测试/PyNARS
- mod pynars {
- use super::*;
-
- cin_tests! {
- PYNARS;
-
- /// 真值通配
- /// * 📝❌【2024-06-15 20:39:59】失败:原因不明
- nal_tw => NAL_TRUTH_WILDCARD
-
- /// 简单演绎
- /// * 📝✅【2024-04-19 23:04:24】成功
- nal_de => NAL_SIMPLE_DEDUCTION
-
- /// 高阶演绎
- /// * 📝✅【2024-04-19 23:04:33】成功
- nal_hi => NAL_HIGHER_DEDUCTION
-
- /// 自变量消除
- /// * 📝❌【2024-04-19 23:05:32】失败:啥推理都没有
- nal_ie => NAL_I_VAR_ELIMINATION
-
- /// 时间归纳
- /// * 📝❌【2024-04-19 23:06:43】失败:只会回答`D>. :\: %1.000;0.900%`
- nal_te => NAL_TEMPORAL_INDUCTION
-
- /// 简单操作
- /// * 📝❌【2024-04-19 23:06:48】失败:没有任何回答
- nal_so => NAL_SIMPLE_OPERATION
-
- /// 操作
- /// * 📝❌【2024-04-19 23:07:11】目前仍测试失败
- /// * 📄【2024-04-19 23:07:27】只会回答`ANSWER:<{SELF}-->(/, ^left, _)>. :\: %1.000;0.900%`
- /// * 📌PyNARS自身对NAL-7、NAL-8支持尚不完善
- /// * 📌PyNARS中操作`left`并非默认已注册
- /// * ❌【2024-04-07 14:41:54】补充:追加了也不行
- nal_op => NAL_OPERATION
- }
- }
-
- /// 测试/CXinJS
- /// * 📝【2024-04-19 23:10:28】用来试探「自动测试脚本」的下限
- mod cxin_js {
- use super::*;
-
- cin_tests! {
- CXIN_JS;
-
- /// 真值通配
- /// * 📝❌【2024-06-15 20:41:37】失败:没有ANSWER
- nal_tw => NAL_TRUTH_WILDCARD
-
- /// 简单演绎
- /// * 📝❌【2024-04-07 14:37:49】失败:导出了结论,但没法回答
- /// * 📄只能导出`C>. %1;0.9%`
- nal_de => NAL_SIMPLE_DEDUCTION
-
- /// 高阶演绎
- /// * 📝❌【2024-04-19 23:08:44】失败:只能导出到`B>?`
- /// * 📌即便是五百步,也推不出来
- nal_hi => NAL_HIGHER_DEDUCTION
-
- /// 自变量消除
- /// * 📝❌【2024-04-19 23:09:21】失败:仅推理到`C>?`,并且遇到「XXX is not a function」错误
- nal_ie => NAL_I_VAR_ELIMINATION
-
- /// 时间归纳
- /// * 📝❌【2024-04-19 23:09:34】失败:解析即报错——不支持`=/>`
- nal_te => NAL_TEMPORAL_INDUCTION
-
- /// 简单操作
- /// * 📝❌【2024-04-19 23:09:47】失败:推理不出任何内容
- /// * 💭还会把「目标」解析成「判断」……
- nal_so => NAL_SIMPLE_OPERATION
-
- /// 操作
- /// * 📝❌【2024-04-19 23:10:21】失败:自身就不支持
- nal_op => NAL_OPERATION
- }
- }
-
- /// 测试/原生IL-1
- mod native_il_1 {
- use super::*;
-
- cin_tests! {
- NATIVE_IL_1;
-
- /// 真值通配
- /// * 📝❌【2024-06-15 20:42:18】失败:尚不支持
- nal_tw => NAL_TRUTH_WILDCARD
-
- /// 简单演绎
- /// * 📝✅【2024-04-09 21:12:10】成功
- nal_de => NAL_SIMPLE_DEDUCTION
-
- /// 高阶演绎
- /// * 📝❌【2024-04-09 21:12:32】失败:尚不支持
- nal_hi => NAL_HIGHER_DEDUCTION
-
- /// 自变量消除
- /// * 📝❌【2024-04-09 21:12:32】失败:尚不支持
- nal_ie => NAL_I_VAR_ELIMINATION
-
- /// 时间归纳
- /// * 📝❌【2024-04-09 21:12:32】失败:尚不支持
- nal_te => NAL_TEMPORAL_INDUCTION
-
- /// 简单操作
- /// * 📝❌【2024-04-09 21:12:32】失败:尚不支持
- nal_so => NAL_SIMPLE_OPERATION
-
- /// 操作
- /// * 📝❌【2024-04-09 21:12:32】失败:尚不支持
- nal_op => NAL_OPERATION
- }
- }
-
- // ! ❌【2024-04-07 14:39:20】接口完成度不高的NARS-Python、OpenJunars暂不进行测试
-
- /// 测试入口/带Websocket Shell
- /// * 🎯正常BabelNAR CLI shell启动
- /// * 🎯用户命令行交互体验(并存)
- /// * 🎯Websocket通信
- #[test]
- #[ignore = "仅作试运行用,不用于自动化测试"]
- pub fn main_websocket() -> Result<()> {
- // 以默认参数启动
- main_args(
- env::current_dir(),
- ["test.exe", "-d", "-c", ONA, "-c", WEBSOCKET]
- .into_iter()
- .map(str::to_string),
- )
- }
-}
+mod tests;
diff --git a/src/tests/config_paths.rs b/src/tests/config_paths.rs
new file mode 100644
index 0000000..d443358
--- /dev/null
+++ b/src/tests/config_paths.rs
@@ -0,0 +1,54 @@
+#![allow(unused_variables)]
+#![allow(dead_code)]
+
+nar_dev_utils::macro_once! {
+ /// 实用宏/简化字符串常量
+ macro str_const($(
+ $(#[$m:meta])*
+ $name:ident = $value:literal $(;)?
+ )*) {
+ $(
+ $(#[$m])*
+ pub const $name: &str = $value;
+ )*
+ }
+
+ /// 用于「启动参数解析」的测试环境
+ ARG_PARSE_TEST =
+ "./src/tests/cli/config/_arg_parse_test.opennars.hjson"
+
+ /// OpenNARS
+ OPENNARS = "./src/tests/cli/config/cin_opennars.hjson"
+ /// OpenNARS
+ OPENNARS_158 = "./src/tests/cli/config/cin_opennars_158.hjson"
+ /// ONA
+ ONA = "./src/tests/cli/config/cin_ona.hjson"
+ /// PyNARS
+ PYNARS = "./src/tests/cli/config/cin_pynars.hjson"
+ /// CXinJS
+ CXIN_JS = "./src/tests/cli/config/cin_cxin_js.hjson"
+ /// 原生IL-1
+ NATIVE_IL_1 = "./src/tests/cli/config/cin_native_il_1.hjson"
+
+ /// 预引入/NAL测试环境
+ PRELUDE_TEST = "./src/tests/cli/config/prelude_test.hjson"
+ /// NAL/简单演绎
+ NAL_SIMPLE_DEDUCTION = "./src/tests/cli/config/nal_simple_deduction.hjson"
+ /// NAL/高阶演绎
+ NAL_HIGHER_DEDUCTION = "./src/tests/cli/config/nal_higher_deduction.hjson"
+ /// NAL/自变量消除
+ NAL_I_VAR_ELIMINATION = "./src/tests/cli/config/nal_i_var_elimination.hjson"
+ /// NAL/时间归纳
+ NAL_TEMPORAL_INDUCTION = "./src/tests/cli/config/nal_temporal_induction.hjson"
+ /// NAL/操作
+ NAL_OPERATION = "./src/tests/cli/config/nal_operation.hjson"
+ /// NAL/简单操作
+ NAL_SIMPLE_OPERATION = "./src/tests/cli/config/nal_simple_operation.hjson"
+ /// NAL/真值通配
+ NAL_TRUTH_WILDCARD = "./src/tests/cli/config/nal_truth_wildcard.hjson"
+
+ /// Websocket
+ WEBSOCKET = "./src/tests/cli/config/websocket.hjson"
+ /// Matriangle服务器
+ MATRIANGLE_SERVER = "./src/tests/cli/config/matriangle_server.hjson"
+}
diff --git a/src/tests/mod.rs b/src/tests/mod.rs
new file mode 100644
index 0000000..94d9e2d
--- /dev/null
+++ b/src/tests/mod.rs
@@ -0,0 +1,347 @@
+//! 单元测试
+#![allow(unused_attributes)]
+
+use super::*;
+use nar_dev_utils::list;
+
+/// 测试用配置文件路径
+/// * 🎯后续其它地方统一使用该处路径
+/// * 📌相对路径の根目录:项目根目录(`Cargo.toml`所在目录)
+/// * ⚠️只与配置文件路径有关,不与CIN位置有关
+/// * 💭后续若在不同工作环境中,需要调整配置文件中有关「CIN位置」的信息
+/// * ⚠️此处所涉及的CIN不附带于源码中,而是**另行发布**
+/// * ❗部分CIN涉及c
+pub mod config_paths;
+use config_paths::*;
+
+/// 通用测试入口
+/// * 🎯通用、可复用的启动代码
+/// * 🎯跨不同CIN通用
+/// * 🎯跨同CIN不同测试通用
+pub fn main(cin_config_path: &str, other_args: &[&str]) -> Result<()> {
+ babel_nar::exists_or_exit!("./executables");
+ // 以默认参数启动
+ main_args(
+ env::current_dir(),
+ [
+ &["BabelNAR-cli.exe", "-d", "-c", cin_config_path],
+ other_args,
+ ]
+ .concat()
+ .into_iter()
+ .map(str::to_string),
+ )
+}
+
+/// 测试入口/多配置加载
+/// * 🎯多「虚拟机启动配置」合并
+/// * 🎯预引入NAL
+pub fn main_configs(cin_config_path: &str, other_config_paths: &[&str]) -> Result<()> {
+ let args = list![
+ [
+ // 第二个文件,搭建测试环境
+ "-c",
+ config_path,
+ // 第三个文件,指示预加载
+ "-c",
+ config_path,
+ ]
+ for config_path in (other_config_paths)
+ ]
+ .concat();
+ main(cin_config_path, &args)
+}
+
+/// 批量生成「预引入NAL」
+macro_rules! cin_tests {
+ (
+ $(#[$attr_root:meta])*
+ $cin_path:ident; // ! ❌若为`expr`,则会和上边的修饰符导致「本地歧义」
+ $(
+ $(#[$attr:meta])*
+ $name:ident => $config_path:expr $(;)?
+ )*
+ ) => {
+ /// 主Shell
+ /// * 🎯正常BabelNAR CLI shell启动
+ /// * 🎯正常用户命令行交互体验
+ $(#[$attr_root])*
+ #[test]
+ #[ignore = "仅作试运行用,不用于自动化测试"]
+ pub fn main_shell() -> Result<()> {
+ main($cin_path, &[])
+ }
+
+
+ /// Matriangle服务器
+ /// * 🎯复现先前基于Matriangle环境的NARS实验
+ $(#[$attr_root])*
+ #[test]
+ #[ignore = "仅作试运行用,不用于自动化测试"]
+ pub fn main_matriangle_server() -> Result<()> {
+ // 以默认参数启动
+ main_configs($cin_path, &[MATRIANGLE_SERVER])
+ }
+
+ $(
+ $(#[$attr])*
+ #[test]
+ #[ignore = "【2024-06-12 23:52:35】不用于自动化测试:会自动清屏影响测试结果呈现"]
+ pub fn $name() -> Result<()> {
+ main_configs($cin_path, &[PRELUDE_TEST, $config_path])
+ }
+ )*
+ };
+}
+
+/// 测试/ONA
+mod ona {
+ use super::*;
+
+ cin_tests! {
+ ONA;
+
+ /// 真值通配
+ /// * 📝✅【2024-06-15 20:31:10】成功
+ nal_tw => NAL_TRUTH_WILDCARD
+
+ /// 简单演绎
+ /// * 📝✅【2024-04-19 22:49:51】成功
+ nal_de => NAL_SIMPLE_DEDUCTION
+
+ /// 高阶演绎
+ /// * 📝✅【2024-04-19 22:50:04】成功
+ nal_hi => NAL_HIGHER_DEDUCTION
+
+ /// 自变量消除
+ /// * 📝✅【2024-04-19 22:50:53】成功
+ nal_ie => NAL_I_VAR_ELIMINATION
+
+ /// 时间归纳
+ /// * 📝✅【2024-04-19 22:52:45】成功
+ nal_te => NAL_TEMPORAL_INDUCTION
+
+ /// 简单操作
+ /// * 📝❌【2024-04-19 22:55:35】失败:推理不出任何内容
+ nal_so => NAL_SIMPLE_OPERATION
+
+ /// 操作
+ /// * 📝✅【2024-04-19 23:01:52】成功,但少许问题
+ /// * 📝【2024-04-07 14:17:21】目前ONA面对其中的「经验问句」没有回答
+ /// * ⚠️在启用`REG left`注册操作后,反而从成功变为失败
+ nal_op => NAL_OPERATION
+ }
+}
+
+/// 测试/OpenNARS (3.x)
+mod opennars {
+ use super::*;
+
+ cin_tests! {
+ #[ignore = "【2024-04-14 20:24:52】会导致残留子进程"]
+ OPENNARS;
+
+ /// 真值通配
+ /// * 📝✅【2024-06-15 20:31:10】成功
+ nal_tw => NAL_TRUTH_WILDCARD
+
+ /// 简单演绎
+ /// * 📝✅【2024-04-19 22:49:02】成功(步数性能上不佳)
+ nal_de => NAL_SIMPLE_DEDUCTION
+
+ /// 高阶演绎
+ /// * 📝✅【2024-04-19 22:48:56】成功
+ nal_hi => NAL_HIGHER_DEDUCTION
+
+ /// 自变量消除
+ /// * 📝✅【2024-04-07 16:01:15】成功
+ nal_ie => NAL_I_VAR_ELIMINATION
+
+ /// 时间归纳
+ /// * 📝✅【2024-04-19 22:52:35】成功(步数性能上不佳)
+ nal_te => NAL_TEMPORAL_INDUCTION
+
+ /// 简单操作
+ /// * 📝✅【2024-04-07 16:13:39】成功
+ nal_so => NAL_SIMPLE_OPERATION
+
+ /// 操作
+ /// * 📝✅【2024-04-07 14:59:53】成功
+ nal_op => NAL_OPERATION
+ }
+}
+
+/// 测试/OpenNARS (1.5.8)
+mod opennars158 {
+ use super::*;
+
+ cin_tests! {
+ #[ignore = "【2024-04-14 20:24:52】会导致残留子进程"]
+ OPENNARS_158;
+
+ /// 真值通配
+ /// * 📝✅【2024-06-15 20:31:10】成功
+ nal_tw => NAL_TRUTH_WILDCARD
+
+ /// 简单演绎
+ /// * 📝✅【2024-04-19 23:02:59】成功
+ nal_de => NAL_SIMPLE_DEDUCTION
+
+ /// 高阶演绎
+ /// * 📝✅【2024-04-19 23:03:06】成功
+ nal_hi => NAL_HIGHER_DEDUCTION
+
+ /// 自变量消除
+ /// * 📝✅【2024-04-19 23:03:15】成功
+ nal_ie => NAL_I_VAR_ELIMINATION
+
+ /// 时间归纳
+ /// * 📝❌【2024-04-19 23:03:20】失败:语法层面就不支持
+ nal_te => NAL_TEMPORAL_INDUCTION
+
+ /// 简单操作
+ /// * 📝❌【2024-04-19 23:03:37】失败:语法层面就不支持
+ nal_so => NAL_SIMPLE_OPERATION
+
+ /// 操作
+ /// * 📝❌【2024-04-19 23:03:48】失败:语法层面就不支持
+ nal_op => NAL_OPERATION
+ }
+}
+
+/// 测试/PyNARS
+mod pynars {
+ use super::*;
+
+ cin_tests! {
+ PYNARS;
+
+ /// 真值通配
+ /// * 📝❌【2024-06-15 20:39:59】失败:原因不明
+ nal_tw => NAL_TRUTH_WILDCARD
+
+ /// 简单演绎
+ /// * 📝✅【2024-04-19 23:04:24】成功
+ nal_de => NAL_SIMPLE_DEDUCTION
+
+ /// 高阶演绎
+ /// * 📝✅【2024-04-19 23:04:33】成功
+ nal_hi => NAL_HIGHER_DEDUCTION
+
+ /// 自变量消除
+ /// * 📝❌【2024-04-19 23:05:32】失败:啥推理都没有
+ nal_ie => NAL_I_VAR_ELIMINATION
+
+ /// 时间归纳
+ /// * 📝❌【2024-04-19 23:06:43】失败:只会回答`D>. :\: %1.000;0.900%`
+ nal_te => NAL_TEMPORAL_INDUCTION
+
+ /// 简单操作
+ /// * 📝❌【2024-04-19 23:06:48】失败:没有任何回答
+ nal_so => NAL_SIMPLE_OPERATION
+
+ /// 操作
+ /// * 📝❌【2024-04-19 23:07:11】目前仍测试失败
+ /// * 📄【2024-04-19 23:07:27】只会回答`ANSWER:<{SELF}-->(/, ^left, _)>. :\: %1.000;0.900%`
+ /// * 📌PyNARS自身对NAL-7、NAL-8支持尚不完善
+ /// * 📌PyNARS中操作`left`并非默认已注册
+ /// * ❌【2024-04-07 14:41:54】补充:追加了也不行
+ nal_op => NAL_OPERATION
+ }
+}
+
+/// 测试/CXinJS
+/// * 📝【2024-04-19 23:10:28】用来试探「自动测试脚本」的下限
+mod cxin_js {
+ use super::*;
+
+ cin_tests! {
+ CXIN_JS;
+
+ /// 真值通配
+ /// * 📝❌【2024-06-15 20:41:37】失败:没有ANSWER
+ nal_tw => NAL_TRUTH_WILDCARD
+
+ /// 简单演绎
+ /// * 📝❌【2024-04-07 14:37:49】失败:导出了结论,但没法回答
+ /// * 📄只能导出`C>. %1;0.9%`
+ nal_de => NAL_SIMPLE_DEDUCTION
+
+ /// 高阶演绎
+ /// * 📝❌【2024-04-19 23:08:44】失败:只能导出到`B>?`
+ /// * 📌即便是五百步,也推不出来
+ nal_hi => NAL_HIGHER_DEDUCTION
+
+ /// 自变量消除
+ /// * 📝❌【2024-04-19 23:09:21】失败:仅推理到`C>?`,并且遇到「XXX is not a function」错误
+ nal_ie => NAL_I_VAR_ELIMINATION
+
+ /// 时间归纳
+ /// * 📝❌【2024-04-19 23:09:34】失败:解析即报错——不支持`=/>`
+ nal_te => NAL_TEMPORAL_INDUCTION
+
+ /// 简单操作
+ /// * 📝❌【2024-04-19 23:09:47】失败:推理不出任何内容
+ /// * 💭还会把「目标」解析成「判断」……
+ nal_so => NAL_SIMPLE_OPERATION
+
+ /// 操作
+ /// * 📝❌【2024-04-19 23:10:21】失败:自身就不支持
+ nal_op => NAL_OPERATION
+ }
+}
+
+/// 测试/原生IL-1
+mod native_il_1 {
+ use super::*;
+
+ cin_tests! {
+ NATIVE_IL_1;
+
+ /// 真值通配
+ /// * 📝❌【2024-06-15 20:42:18】失败:尚不支持
+ nal_tw => NAL_TRUTH_WILDCARD
+
+ /// 简单演绎
+ /// * 📝✅【2024-04-09 21:12:10】成功
+ nal_de => NAL_SIMPLE_DEDUCTION
+
+ /// 高阶演绎
+ /// * 📝❌【2024-04-09 21:12:32】失败:尚不支持
+ nal_hi => NAL_HIGHER_DEDUCTION
+
+ /// 自变量消除
+ /// * 📝❌【2024-04-09 21:12:32】失败:尚不支持
+ nal_ie => NAL_I_VAR_ELIMINATION
+
+ /// 时间归纳
+ /// * 📝❌【2024-04-09 21:12:32】失败:尚不支持
+ nal_te => NAL_TEMPORAL_INDUCTION
+
+ /// 简单操作
+ /// * 📝❌【2024-04-09 21:12:32】失败:尚不支持
+ nal_so => NAL_SIMPLE_OPERATION
+
+ /// 操作
+ /// * 📝❌【2024-04-09 21:12:32】失败:尚不支持
+ nal_op => NAL_OPERATION
+ }
+}
+
+// ! ❌【2024-04-07 14:39:20】接口完成度不高的NARS-Python、OpenJunars暂不进行测试
+
+/// 测试入口/带Websocket Shell
+/// * 🎯正常BabelNAR CLI shell启动
+/// * 🎯用户命令行交互体验(并存)
+/// * 🎯Websocket通信
+#[test]
+#[ignore = "仅作试运行用,不用于自动化测试"]
+pub fn main_websocket() -> Result<()> {
+ // 以默认参数启动
+ main_args(
+ env::current_dir(),
+ ["test.exe", "-d", "-c", ONA, "-c", WEBSOCKET]
+ .into_iter()
+ .map(str::to_string),
+ )
+}