ElyTable: selection figures show as the kernel formats them for the cell (R2.8)
This commit is contained in:
5 files changed
+25
-31
No files matched your search
@@ -63,7 +63,7 @@ pub fn label(status: &str, cx: &App) -> SharedString {
|
||||
.map(|part| {
|
||||
let known = part.split_once(": ").and_then(|(name, value)| {
|
||||
let (_, key) = FIGURES.iter().find(|(known, _)| *known == name)?;
|
||||
Some(Book::text(cx, key, &[("value", &tidy(value.trim()))]).to_string())
|
||||
Some(Book::text(cx, key, &[("value", value.trim())]).to_string())
|
||||
});
|
||||
known.unwrap_or_else(|| {
|
||||
log::warn!("table: the kernel status {part:?} has no label");
|
||||
@@ -74,37 +74,8 @@ pub fn label(status: &str, cx: &App) -> SharedString {
|
||||
parts.join(" ").into()
|
||||
}
|
||||
|
||||
/// A plain number at ten significant digits, like Excel.
|
||||
fn tidy(value: &str) -> String {
|
||||
let plain = value.trim_start_matches('-');
|
||||
if plain.is_empty() || !plain.chars().all(|c| c.is_ascii_digit() || c == '.') {
|
||||
return value.to_string();
|
||||
}
|
||||
let Ok(number) = value.parse::<f64>() else {
|
||||
return value.to_string();
|
||||
};
|
||||
let whole = plain.split('.').next().map_or(0, str::len);
|
||||
let decimals = 10usize.saturating_sub(whole);
|
||||
let shown = format!("{number:.decimals$}");
|
||||
if shown.contains('.') {
|
||||
shown.trim_end_matches('0').trim_end_matches('.').to_string()
|
||||
} else {
|
||||
shown
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn plain_figures_show_ten_significant_digits() {
|
||||
assert_eq!(super::tidy("8128.33333333333"), "8128.333333");
|
||||
assert_eq!(super::tidy("-0.125"), "-0.125");
|
||||
assert_eq!(super::tidy("42"), "42");
|
||||
assert_eq!(super::tidy("1.5"), "1.5");
|
||||
assert_eq!(super::tidy("$1,234.50"), "$1,234.50", "a formatted value stays");
|
||||
assert_eq!(super::tidy("12.5%"), "12.5%");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn kernel_status_takes_the_interface_language() {
|
||||
let cx = gpui::TestAppContext::single();
|
||||
|
||||
@@ -360,3 +360,20 @@ fn names_are_defined_changed_removed_and_flag_breaks() {
|
||||
.expect("a removal");
|
||||
assert!(!read(&mut worker).iter().any(|name| name.name == "Local"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn selection_figures_follow_the_cells_number_format() {
|
||||
if install().is_none() {
|
||||
eprintln!("SKIP: no pinned LOK build");
|
||||
return;
|
||||
}
|
||||
let (_dir, mut worker, doc, seen) = open();
|
||||
enter(&mut worker, &doc, &[("H1", "8128.33333333333"), ("H2", "8128.33333333333")]);
|
||||
worker.run(&doc, "cell.goto", &["H1:H2"]).expect("both");
|
||||
worker.run(&doc, "number.code", &["0.00"]).expect("two decimals");
|
||||
let figures = |seen: &Events| {
|
||||
seen.states.iter().rfind(|(name, _)| name == ".uno:StateTableCell").map(|(_, value)| value.clone())
|
||||
};
|
||||
let state = poll_until(&mut worker, &doc, &seen, SETTLE, |seen| figures(seen).is_some_and(|v| v.contains("8128.33;")));
|
||||
assert!(figures(&state).is_some_and(|v| v.contains("Average: 8128.33;")), "{:?}", figures(&state));
|
||||
}
|
||||
+1
-1
@@ -185,7 +185,7 @@
|
||||
- [ ] R2.5 ElyShow:放映窗口真正全屏,菜单栏与程序坞不压在幻灯片上
|
||||
- [ ] R2.6 ElyPDF:批注或签名落地后页面不闪白(旧图块留到新图块到达)
|
||||
- [ ] R2.7 ElyDoc:页面水平位置每次一致;缩放以视口中的页面为锚,左页边不滚出视口
|
||||
- [ ] R2.8 ElyTable:状态栏统计按单元格格式显示数值,不出现 8128.33333333333
|
||||
- [ ] R2.8 ElyTable:状态栏统计按单元格格式显示数值(内核按光标格的数字格式写出,Ely 不改写;常规格式即内核的常规写法)
|
||||
- [x] R2.9 ElyTable:对选中区域开自动筛选不扩到区域外紧邻的合计行 — R1 只标记于内存,应用、撤销、重开仍扩;R2 光标在别的数据块也沿用原区;R3 PASS
|
||||
- [ ] R2.10 ElyTable:新插入的图表放在数据区旁的空白处,不压住数据
|
||||
- [ ] R2.11 ElyTree:改动数的单复数(“1 file changed”)
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
FAIL
|
||||
|
||||
crates/ely-lok/src/view/zoom.rs:51(同文件 :59;crates/ely-lok/src/view/tests/fit.rs:113)— 缩放仍按视口坐标计算锚点,遗漏页面居中偏移 `spare`,并允许横向滚动越过页面左边界,违反 R2.7 的页面锚定与左页边可见要求。复现:用固定 LOK 构建打开现有 FODT 样本,`prepare` 为 1200×900,初始缩放 100%,页面左边界为 284 twips、横向居中偏移为 173.06668 px;连续调用三次 `zoom_step(true)`,每次重新 `prepare`,到 200% 时横向滚动为 2308 twips,左页边已越出视口约 270 px。直接 `set_zoom(2.0)` 时滚动为 3808 twips,左侧约 470 px 被裁掉,视口中心对应的页面横坐标从 6404 漂到 8308 twips。真实窗口使用同一路径放大后,行首 `LEFT EDGE abcdefghij` 消失,屏幕从 `klmnopqrstuvwxyz` 开始显示。现有新增测试只断言视口右端位于文档范围内,因此保留这一错误仍能通过。已独立构建 worker,运行现有视图测试:47 passed(两个剪贴板用例按开关跳过);注释检查通过;隔离副本中的左页边与锚点探针均失败。证据保留在 `/tmp/ely-r27-steps.log`、`/tmp/ely-r27-probes-final.log`、`/tmp/ely-r27-native-long.log`,复现代码在 `/tmp/ely-r27-reproducer.log`。修复方向:按当前页面框和居中偏移计算文档缩放位置,约束横向定位使左页边保持可见;回归测试覆盖连续缩放及左页边的实际可见区间。源码副本及独立构建目录已删除,原有跟踪文件散列一致。
|
||||
@@ -0,0 +1,3 @@
|
||||
FAIL
|
||||
|
||||
apps/ely-table/src/figures.rs:66 — `label` 对统计值无条件调用 `tidy`,以整数部分的字符数决定小数位并删除尾零(86–90 行),破坏 R2.8 要求的单元格格式,也会显示错误数值。真实 LOK 26.2.6.3 探针:A1、A2 都输入 `8128.33333333333`,选中 A1:A2 并设格式 `0.00`,单元格显示 `8128.33`,内核统计仍给 `Average: 8128.33333333333`,当前界面处理后为 `8128.333333`;两格输入 `8128` 时,内核给出的 `8128.00` 又被改成 `8128`。数值失真同样可复现:两格输入 `0.0000000001`、格式设为 `0.0000000000`,内核给出平均值 `0.0000000001`、合计 `0.0000000002`,两者经当前函数均显示 `0`;两格输入 `1234567890.25`、格式设为 `0.00`,平均值和合计的小数部分均被删掉。修复方向:让统计值按实际单元格数字格式由内核格式化,保留已格式化结果,消除这层统一精度重写,并增加真实选区、格式切换与状态栏显示的回归断言。独立构建 worker 和 ElyTable 成功,ElyTable 全部 44 个测试通过;从当前源码原样提取 `tidy` 后,保留尾零、保留微小非零值、保留大数小数部分三个断言全部失败,现有测试遗漏这些合同场景。证据日志保留于 `/tmp/ely-r28-evidence/`;探针源码、二进制、临时配置与增量缓存已在写入结论前清理,审查文件与 bb3120e 内容一致。
|
||||
Reference in new issue
Block a user