openpencil/crates/op-host-web/tests/font_stack_resolution.rs
Kayshen-X 01820bf5ea fix(editor): improve import and generation reliability
Expand HTML/CSS import fidelity, preserve layered fills and accurate fonts across HTML, Figma, and OP files, and make missing-font resolution selectable and case-insensitive. Harden code generation recovery and preview rendering, make model selection immediate, and keep image decode/compositing consistent across native and web hosts. Add mobile dependency and widget-boundary guards so all supported targets retain the intended feature surface.
2026-07-21 06:34:53 +08:00

95 lines
3.4 KiB
Rust

//! CanvasKit named-font stack resolver coverage.
fn bridge_source() -> String {
std::fs::read_to_string(format!(
"{}/src/op_ck_bridge.js",
env!("CARGO_MANIFEST_DIR")
))
.expect("CanvasKit bridge source is readable")
}
#[test]
fn canvaskit_named_font_stack_resolution_runs_in_javascript() {
use std::io::Write;
use std::process::{Command, Stdio};
let mut source = bridge_source();
source.push_str(
r#"
const assert = (condition, message) => { if (!condition) throw new Error(message); };
const imported = new Map([
['inter', { tf: 'imported-inter' }],
['later face', { tf: 'imported-later' }],
['acme, sans', { tf: 'imported-comma' }],
]);
const system = new Map([
['inter', { tf: 'system-inter' }],
['system first', { tf: 'system-first' }],
]);
const parsed = opCkParseFontFamilyStack('"Acme, Sans", Missing, \'Later Face\'');
assert(JSON.stringify(parsed) === JSON.stringify(['Acme, Sans', 'Missing', 'Later Face']),
'quoted family commas must not split the CSS stack');
let resolved = opCkResolveRegisteredTypeface('SYSTEM FIRST, Later Face', imported, system);
assert(resolved && resolved.source === 'system' && resolved.tf === 'system-first',
'an earlier exact system family must beat a later imported family');
resolved = opCkResolveRegisteredTypeface('InTeR', imported, system);
assert(resolved && resolved.source === 'imported' && resolved.tf === 'imported-inter',
'matching must ignore ASCII case and imported must beat system for one candidate');
resolved = opCkResolveRegisteredTypeface('Missing, "ACME, SANS"', imported, system);
assert(resolved && resolved.familyKey === 'acme, sans' && resolved.tf === 'imported-comma',
'an unavailable candidate must fall through to the next quoted candidate');
resolved = opCkResolveRegisteredTypeface('Missing, UI-SANS-SERIF, Later Face', imported, system);
assert(resolved === null,
'a generic candidate must terminate named lookup and use browser fallback');
"#,
);
let mut child = match Command::new("node")
.args(["--input-type=module"])
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
{
Ok(child) => child,
Err(error) if error.kind() == std::io::ErrorKind::NotFound => return,
Err(error) => panic!("failed to start node for CanvasKit bridge test: {error}"),
};
child
.stdin
.take()
.expect("node stdin is available")
.write_all(source.as_bytes())
.expect("CanvasKit bridge test source is writable");
let output = child
.wait_with_output()
.expect("CanvasKit bridge JavaScript test completes");
assert!(
output.status.success(),
"CanvasKit font stack JavaScript assertions failed:\n{}",
String::from_utf8_lossy(&output.stderr)
);
}
#[test]
fn canvaskit_named_font_stack_resolver_is_wired_to_system_registry() {
let source = bridge_source();
for marker in [
"const systemTypefacesByFamily = new Map()",
"opCkResolveRegisteredTypeface(family, importedTypefaces, systemTypefacesByFamily)",
"systemTypefacesByFamily.set(key, entry)",
"registeredCoverageSegments(familyEntry.key, familyEntry.tf, sz, t)",
] {
assert!(
source.contains(marker),
"CanvasKit exact-family selection must preserve `{marker}`"
);
}
}