Files
qingjian/apps/linux/server/tests/protocol.rs
T
jacklaoz 0f17aa15d5 feat(linux): IBus 前端,安装脚本按机器上的框架装对应前端 (#628)
GNOME 默认的输入法框架是 IBus:加一个 IBus 前端(纯 Rust,与 Fcitx5 插件共用同一个 Server),安装脚本按机器上有哪个框架装对应的前端(--frontend auto/fcitx5/ibus/both),可选把 Server 装成随登录启动的 systemd 用户服务。

协议类型搬进 qingjian_platform::protocol::linux,两个前端共用。GNOME Wayland 上组句中按应用快捷键时先把拼音上屏到原来的框。

合并 main 时保留 #351 的 --fcitx4(单独一支,不与 --frontend 同用)。
2026-10-23 13:43:26 +08:00

88 lines
2.9 KiB
Rust

//! 共享长度前缀协议的内存回环。
use qingjian_platform::protocol::{
ClientMessage, KeyEvent, KeyModifiers, PROTOCOL_VERSION, ServerMessage, SessionId,
read_message, write_message,
};
use std::io::Cursor;
#[test]
fn client_key_round_trips_with_length_prefix() {
let message = ClientMessage::Key {
session: SessionId(42),
event: KeyEvent::new(u32::from(b'N'), Some('n'), KeyModifiers::default()),
};
let mut bytes = Vec::new();
write_message(&mut bytes, &message).unwrap();
assert_eq!(
u32::from_le_bytes(bytes[..4].try_into().unwrap()) as usize,
bytes.len() - 4
);
let decoded = read_message::<_, ClientMessage>(&mut Cursor::new(bytes)).unwrap();
assert_eq!(decoded, Some(message));
}
#[test]
fn open_session_carries_protocol_and_close_is_replyless() {
let open = ClientMessage::OpenSession {
session: SessionId(1),
app: Some("gedit".into()),
protocol: PROTOCOL_VERSION,
};
let close = ClientMessage::CloseSession {
session: SessionId(1),
};
let mut bytes = Vec::new();
write_message(&mut bytes, &open).unwrap();
write_message(&mut bytes, &close).unwrap();
let mut cursor = Cursor::new(bytes);
assert_eq!(
read_message::<_, ClientMessage>(&mut cursor).unwrap(),
Some(open)
);
assert_eq!(
read_message::<_, ClientMessage>(&mut cursor).unwrap(),
Some(close)
);
let response = ServerMessage::Committed {
session: SessionId(1),
text: Some("你好".into()),
};
let mut out = Vec::new();
write_message(&mut out, &response).unwrap();
assert_eq!(
read_message::<_, ServerMessage>(&mut Cursor::new(out)).unwrap(),
Some(response)
);
}
#[test]
fn linux_display_identity_round_trips_without_changing_shared_protocol() {
let identity = qingjian_platform::protocol::linux::DisplayIdentity {
generation: 7,
context: "001122".into(),
revision: 13,
};
let ack = qingjian_platform::protocol::linux::DisplayAcknowledged {
session: SessionId(2),
identity: identity.clone(),
senses: vec![(0, 1), (3, 0)],
};
let value = serde_json::to_value(&ack).unwrap();
let decoded: qingjian_platform::protocol::linux::DisplayAcknowledged =
serde_json::from_value(value).unwrap();
assert_eq!(decoded.identity, identity);
assert_eq!(decoded.senses, vec![(0, 1), (3, 0)]);
}
/// Fcitx5 插件的 OpenSession 把协议版本写死在 C++ 里;Server 要求完全一致,升版本时两边得一起改。
#[test]
fn fcitx5_plugin_opens_sessions_with_the_current_protocol() {
let plugin = concat!(env!("CARGO_MANIFEST_DIR"), "/../fcitx5/src/qingjian.cpp");
let source = std::fs::read_to_string(plugin).unwrap();
let expected = format!("{{\"protocol\", {PROTOCOL_VERSION}}}");
assert!(
source.contains(&expected),
"qingjian.cpp 的 OpenSession 应写 {expected}"
);
}