Files
cadcraft/crates/engine/tests/it/multiline_attributes.rs
aiongg 9cf115e808 CI: one test binary per crate, nextest, line tables only (#1989)
* Build: line tables only in dev, no debug info for dependencies

* Tests: one integration-test binary per crate

Each crate's tests/*.rs becomes a module of tests/it/main.rs. Files that
install process-wide state (the file io hooks, user aliases, SAVETIME and
SAVEFILEPATH, user linetype and pattern files, registered fonts) stay their
own test binaries.

* xtask ci: nextest, tests without examples, one wasm check call
2026-10-23 13:34:26 -04:00

95 lines
3.5 KiB
Rust

//! A block with a multiline attribute definition: its references get the multiline text placed
//! with them, it moves with them, and an attribute edit replaces it.
use std::sync::Arc;
use cadcraft_engine::Session;
use cadcraft_engine::doc::{Attrib, Block, Common, Entity, EntityKind, Handle, MText, MultilineAttrib, Text};
use cadcraft_engine::geom::Vec3;
use serde_json::json;
/// A session whose block TAG has a multiline definition LABEL ("SITE" / "NAME") at (10, 3).
fn session() -> Session {
let mut d = cadcraft_engine::doc::Drawing::new_imperial();
let text = Text {
insert: Vec3::new(2.0, 2.0, 0.0),
align_pt: None,
height: 2.0,
value: "SITE\nNAME".into(),
rotation: 0.0,
width_factor: 1.0,
oblique: 0.0,
style: "Standard".into(),
halign: Default::default(),
valign: Default::default(),
};
let mtext = MText {
insert: Vec3::new(10.0, 3.0, 0.0),
height: 2.0,
width: 0.0,
attach: 8,
rotation: 0.0,
style: "Standard".into(),
contents: "SITE\\PNAME".into(),
line_spacing: 1.0,
line_spacing_exact: false,
columns: None,
};
let def = Attrib {
tag: "LABEL".into(),
text,
invisible: false,
constant: false,
prompt: "Site".into(),
props: Default::default(),
multiline: Some(MultilineAttrib { mtext, read_as: "SITE\nNAME".into() }),
modes: Default::default(),
};
let mut b = Block::new("TAG");
let h = d.new_handle();
b.entities.push(Entity { handle: h, common: Common::default(), kind: EntityKind::AttDef(def) });
d.blocks.insert("TAG".into(), Arc::new(b));
let mut s = Session::empty();
s.open_drawing(d, "tags", None);
s
}
fn label(s: &Session, h: Handle) -> Attrib {
match s.doc().unwrap().entity(h).map(|e| &e.kind) {
Some(EntityKind::Insert(i)) => i.attribs[0].clone(),
other => panic!("{other:?}"),
}
}
#[test]
fn references_get_the_multiline_text_and_carry_it() {
let mut s = session();
let r = s.execute("insert", &json!({ "name": "TAG", "at": [10, 5] })).unwrap();
let h = Handle::parse_hex(r["handle"].as_str().unwrap()).unwrap();
let a = label(&s, h);
assert_eq!(a.text.value, "SITE\nNAME");
let m = a.multiline_text().expect("multiline");
assert_eq!((m.insert.x, m.insert.y, m.contents.as_str()), (20.0, 8.0, "SITE\\PNAME"));
// MOVE carries it.
s.execute("move", &json!({ "handles": [h.hex()], "delta": [5, 0] })).unwrap();
let m = label(&s, h).multiline_text().unwrap();
assert_eq!((m.insert.x, m.insert.y), (25.0, 8.0));
// An edited value replaces the multiline text; ATTSYNC keeps the value and the text.
s.execute("attedit", &json!({ "handle": h.hex(), "values": { "label": "WELL 7" } })).unwrap();
assert_eq!(label(&s, h).multiline_text().map(|m| m.contents), Some("WELL 7".to_string()));
s.execute("attsync", &json!({ "name": "TAG" })).unwrap();
let a = label(&s, h);
assert_eq!(a.text.value, "WELL 7");
assert_eq!(a.multiline_text().map(|m| (m.contents, m.insert.x)), Some(("WELL 7".to_string(), 25.0)));
}
#[test]
fn a_value_given_on_insert_replaces_the_definition_text() {
let mut s = session();
let r = s.execute("insert", &json!({ "name": "TAG", "at": [0, 0], "attribs": { "LABEL": "NORTH" } })).unwrap();
let h = Handle::parse_hex(r["handle"].as_str().unwrap()).unwrap();
assert_eq!(label(&s, h).multiline_text().map(|m| m.contents), Some("NORTH".to_string()));
}