vectorcraft/crates/engine/src/tests_textimport.rs

86 lines
4.4 KiB
Rust

//! File → Place of a text file: Text Import Options, and the text set as area type.
use serde_json::{Value, json};
use vectorcraft_doc::{NodeKind, TextKind};
use vectorcraft_geom::Rect;
use super::*;
fn session() -> Session {
let mut s = Session::new();
s.execute("file.new", &json!({"width": 400, "height": 300})).unwrap();
s
}
fn place_text(s: &mut Session, text: &[u8], extra: Value) -> Value {
let mut p = json!({"name": "notes.txt", "dataBase64": vectorcraft_format::base64_encode(text)});
if let (Some(o), Value::Object(e)) = (p.as_object_mut(), extra) {
o.extend(e);
}
s.execute("file.place", &p).unwrap()
}
/// The placed type's text and frame bounds.
fn placed(s: &Session, r: &Value) -> (String, Rect) {
let n = s.doc().unwrap().doc.node(NodeId(r["ids"][0].as_u64().unwrap())).unwrap().clone();
let NodeKind::Text(t) = &n.kind else { panic!("not type: {:?}", n.kind) };
assert!(matches!(t.kind, TextKind::Area { .. }), "area type");
(t.plain_text(), n.geometric_bounds().unwrap())
}
fn close(a: Rect, b: Rect) -> bool {
[a.x0 - b.x0, a.y0 - b.y0, a.x1 - b.x1, a.y1 - b.y1].iter().all(|d| d.abs() < 1e-6)
}
#[test]
fn crlf_with_returns_removed_places_one_paragraph_per_block_as_area_type() {
let mut s = session();
let text = b"Dear reader,\r\nthis is the first\r\nparagraph.\r\n\r\nAnd here\r\nthe second.\r\n";
let opts = json!({"text": {"removeLineReturns": true, "removeParagraphReturns": true, "replaceSpaces": 3}});
let r = place_text(&mut s, text, opts);
assert_eq!((r["format"].as_str(), r["name"].as_str(), r["linked"].as_bool()), (Some("txt"), Some("notes.txt"), Some(false)));
let (body, frame) = placed(&s, &r);
assert_eq!(body, "Dear reader, this is the first paragraph.\nAnd\there the second.");
assert!(close(frame, Rect::new(36.0, 36.0, 364.0, 264.0)), "the artboard less a 36 pt margin: {frame:?}");
let st = s.doc().unwrap();
assert_eq!((st.history.undo.len(), st.selection.objects.len()), (1, 1), "one undo step, selected");
// Without options each line is a paragraph; `rect` sets the frame.
let r = place_text(&mut s, text, json!({"rect": [10, 20, 100, 50]}));
let (body, frame) = placed(&s, &r);
assert_eq!(body, "Dear reader,\nthis is the first\nparagraph.\n\nAnd here\nthe second.");
assert!(close(frame, Rect::new(10.0, 20.0, 110.0, 70.0)), "{frame:?}");
}
#[test]
fn text_files_report_and_queue_with_their_options() {
let mut s = session();
let file = json!({"name": "a.txt", "dataBase64": vectorcraft_format::base64_encode(b"caf\xe9")});
let info = s.execute("file.place.info", &file).unwrap();
assert_eq!((info["format"].as_str(), info["width"].as_f64(), info["height"].as_f64()), (Some("txt"), Some(468.0), Some(648.0)));
// Not UTF-8: read as Windows-1252, or Mac Roman for a Mac file.
let r = place_text(&mut s, b"caf\x8e", json!({"text": {"characterSet": "ansi", "platform": "mac"}}));
assert_eq!(placed(&s, &r).0, "café");
let r = s.execute("file.place.queue", &json!({"files": [file], "text": {"characterSet": "ansi"}})).unwrap();
assert_eq!((r["count"].as_u64(), r["files"][0]["format"].as_str()), (Some(1), Some("txt")));
assert_eq!(s.tool_options()["name"], "a.txt");
let bad = json!({"name": "a.txt", "dataBase64": "YQ==", "text": {"platform": "beos"}});
assert!(s.execute("file.place", &bad).is_err());
let blank = json!({"name": "blank.txt", "dataBase64": vectorcraft_format::base64_encode(b" \r\n\t\r\n")});
assert!(s.execute("file.place", &blank).is_err(), "no text to place");
// Replace: the frame takes the replaced object's bounds.
s.execute("shape.rectangle", &json!({"x": 50, "y": 60, "width": 80, "height": 40})).unwrap();
let r = place_text(&mut s, b"Swap", json!({"replace": true}));
let (body, frame) = placed(&s, &r);
assert_eq!(body, "Swap");
assert!(close(frame, Rect::new(50.0, 60.0, 130.0, 100.0)), "{frame:?}");
}
#[test]
fn place_reads_what_open_reads_and_text_files() {
use cmd::fileio::{OPEN_EXTS, PLACE_EXTS, TEXT_EXTS};
assert_eq!(PLACE_EXTS, [OPEN_EXTS, TEXT_EXTS].concat());
let filters: Vec<_> = cmd::fileio::place_filters().collect();
assert_eq!((filters.first(), filters.last()), (Some(&("All placeable files", PLACE_EXTS)), Some(&("Text", TEXT_EXTS))));
assert!(!cmd::fileio::open_filters().any(|(_, exts)| exts.contains(&"txt")), "Open doesn't read text files");
}