mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-25 10:17:02 -06:00
Selecting other art drops Puppet Warp pins, ending Edit Text clears the flat view, and a font scan lays type out again. None of these makes an undo step or counts as an edit to save, but each one replaced the document. A background save that finished afterwards compared the document with the one it wrote by pointer, so the document stayed marked modified. Data Recovery also wrote a new copy of a document whose pins had been dropped. DocState now records the documents that these changes replaced, and DocState::same_content counts them as having the same content. The modified flag, the end of a background save and Data Recovery use it. After Edit Text ends, an undo state that was the saved one stays the saved one.
66 lines
3.0 KiB
Rust
66 lines
3.0 KiB
Rust
//! The fonts available (`text.fontList`), the installed ones listed without asking for them (#36),
|
|
//! and Refresh Font List (`text.rescanFonts`).
|
|
|
|
use serde_json::{Value, json};
|
|
use vectorcraft_text::{FontDb, system_font_dirs};
|
|
|
|
use super::*;
|
|
|
|
fn names(v: &Value) -> Vec<String> {
|
|
serde_json::from_value(v.clone()).unwrap()
|
|
}
|
|
|
|
#[test]
|
|
fn the_font_list_names_every_available_family_with_its_styles() {
|
|
let mut s = Session::new();
|
|
let fams = names(&s.execute("text.fontList", &json!({})).unwrap()["families"]);
|
|
assert_eq!(fams, *FontDb::global().menu_family_list());
|
|
for f in ["Source Sans 3", "Source Serif 4", "Inter", "JetBrains Mono"] {
|
|
assert!(fams.iter().any(|x| x == f), "{f}");
|
|
}
|
|
// Every installed family, though nothing asked for system fonts.
|
|
let installed = FontDb::with_font_dirs(system_font_dirs());
|
|
installed.load_system_fonts();
|
|
let missing: Vec<String> = installed.menu_family_list().iter().filter(|f| !fams.contains(f)).cloned().collect();
|
|
assert!(missing.is_empty(), "{missing:?}");
|
|
let r = s.execute("text.fontList", &json!({"family": "source sans 3"})).unwrap();
|
|
assert_eq!(r["family"], "Source Sans 3");
|
|
let styles = names(&r["styles"]);
|
|
assert!(["Regular", "Semibold", "Bold", "Italic"].iter().all(|x| styles.iter().any(|s| s == x)), "{styles:?}");
|
|
assert!(s.execute("text.fontList", &json!({"family": "No Such Font"})).is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn refreshing_the_font_list_redraws_type_without_editing_the_document() {
|
|
let mut s = Session::new();
|
|
s.execute("file.new", &json!({"width": 200, "height": 200})).unwrap();
|
|
s.execute("text.create", &json!({"x": 10, "y": 40, "text": "Type", "font": "No Such Font"})).unwrap();
|
|
s.doc_mut().unwrap().mark_saved();
|
|
let revision = s.doc().unwrap().revision;
|
|
let r = s.execute("text.rescanFonts", &json!({})).unwrap();
|
|
assert_eq!(r["families"], json!(FontDb::global().menu_family_list().len()));
|
|
assert!(r["faces"].is_u64());
|
|
let d = s.doc().unwrap();
|
|
assert!(d.revision > revision, "the canvas redraws");
|
|
assert!(!d.is_dirty(), "nothing to save");
|
|
}
|
|
|
|
/// Refreshing the font list while a background save writes the file leaves the document saved
|
|
/// once the file is written.
|
|
#[test]
|
|
fn refreshing_the_font_list_during_a_save_leaves_the_document_saved() {
|
|
use crate::cmd::fileio::{SaveMode, save_job, save_plan};
|
|
let mut s = Session::new();
|
|
s.execute("file.new", &json!({"width": 200, "height": 200})).unwrap();
|
|
s.execute("text.create", &json!({"x": 10, "y": 40, "text": "Type", "font": "No Such Font"})).unwrap();
|
|
let uid = s.doc().unwrap().uid;
|
|
let plan = save_plan(&s, SaveMode::SaveAs, &json!({"path": "/x/type.vectorcraft", "modified": 777})).unwrap();
|
|
let job = save_job(&mut s, plan).unwrap();
|
|
s.execute("text.rescanFonts", &json!({})).unwrap();
|
|
job.write(|_, _| Ok(())).unwrap();
|
|
job.complete(&mut s, uid);
|
|
let d = s.doc().unwrap();
|
|
assert_eq!(d.doc.metadata.modified, Some(777));
|
|
assert!(!d.is_dirty());
|
|
}
|