//! Testing saving files. use norad::{Codepoints, Font, FormatVersion, Glyph, Identifier, Plist}; use plist::Value; use tempfile::TempDir; #[test] fn save_default() { let my_ufo = Font::new(); let dir = TempDir::new().unwrap(); my_ufo.save(&dir).unwrap(); assert!(dir.path().join("metainfo.plist").exists()); assert!(dir.path().join("glyphs").exists()); assert!(dir.path().join("glyphs/contents.plist").exists()); let loaded = Font::load(dir).unwrap(); assert_eq!(loaded.meta.format_version, FormatVersion::V3); assert_eq!(loaded.meta.creator, Some("org.linebender.norad".into())); assert_eq!(loaded.layers.len(), 1); } #[test] fn save_new_file() { let mut my_ufo = Font::new(); let mut my_glyph = Glyph::new("A"); my_glyph.codepoints.set(['A']); my_glyph.note = Some("I did a glyph!".into()); let mut plist = Plist::new(); plist.insert("my-cool-key".into(), plist::Value::Integer(420_u32.into())); my_glyph.lib = plist; my_ufo.default_layer_mut().insert_glyph(my_glyph); let dir = TempDir::new().unwrap(); my_ufo.save(&dir).unwrap(); assert!(dir.path().join("metainfo.plist").exists()); assert!(dir.path().join("glyphs").exists()); assert!(dir.path().join("glyphs/contents.plist").exists()); assert!(dir.path().join("glyphs/A_.glif").exists()); let loaded = Font::load(dir).unwrap(); assert!(loaded.default_layer().get_glyph("A").is_some()); let glyph = loaded.default_layer().get_glyph("A").unwrap(); assert_eq!(glyph.codepoints, Codepoints::new(['A'])); let lib_val = glyph.lib.get("my-cool-key").and_then(|val| val.as_unsigned_integer()); assert_eq!(lib_val, Some(420)); } #[test] fn save_fancy() { let mut my_ufo = Font::new(); let other_ufo = Font::load("testdata/MutatorSansLightWide.ufo").unwrap(); *my_ufo.default_layer_mut() = other_ufo.layers.get("foreground").unwrap().clone(); let dir = TempDir::new().unwrap(); my_ufo.save(&dir).unwrap(); let loaded = Font::load(dir).unwrap(); let pre_layer = my_ufo.default_layer(); let post_layer = loaded.default_layer(); assert_eq!(pre_layer.iter().count(), post_layer.iter().count()); for glyph in pre_layer.iter() { let other = post_layer.get_glyph(glyph.name()); assert!(other.is_some(), "missing {}", glyph.name()); assert_eq!(glyph, other.unwrap()); } } #[test] fn roundtrip_object_libs() { let ufo = Font::load("testdata/identifiers.ufo").unwrap(); assert!(!ufo.lib.contains_key("public.objectLibs")); let glyph = ufo.get_glyph("test").unwrap(); assert!(!glyph.lib.contains_key("public.objectLibs")); let dir = TempDir::new().unwrap(); ufo.save(&dir).unwrap(); assert!(!glyph.lib.contains_key("public.objectLibs")); let ufo2 = Font::load(&dir).unwrap(); assert!(!ufo2.lib.contains_key("public.objectLibs")); let font_guideline_second = &ufo2.font_info.guidelines.as_ref().unwrap()[1]; assert_eq!( font_guideline_second.identifier(), Some(&Identifier::new("3f0f37d1-52d6-429c-aff4-3f81aed4abf0").unwrap()) ); assert_eq!( font_guideline_second .lib() .as_ref() .unwrap() .get("com.test.foo") .unwrap() .as_unsigned_integer() .unwrap(), 1234 ); let glyph2 = ufo2.get_glyph("test").unwrap(); assert!(!glyph2.lib.contains_key("public.objectLibs")); let anchor_second = &glyph2.anchors[1]; assert_eq!( anchor_second.identifier(), Some(&Identifier::new("90b7eb80-e21a-4a79-a8c0-7634c25ddc18").unwrap()) ); assert_eq!( anchor_second .lib() .as_ref() .and_then(|l| l.get("com.test.anchorTool").and_then(Value::as_boolean)), Some(true) ); assert_eq!( glyph2.guidelines[1].identifier(), Some(&Identifier::new("c76955c2-e9f2-4adf-8b51-1ae03da11dca").unwrap()) ); assert_eq!( glyph2.guidelines[1] .lib() .as_ref() .unwrap() .get("com.test.foo") .unwrap() .as_unsigned_integer() .unwrap(), 4321 ); assert_eq!( glyph.contours[0].identifier(), Some(&Identifier::new("9bf0591d-6281-4c76-8c13-9ff3d93eec4f").unwrap()) ); assert_eq!( glyph.contours[0].lib().as_ref().unwrap().get("com.test.foo").unwrap().as_string().unwrap(), "a" ); assert_eq!( glyph.contours[1].points[0].identifier(), Some(&Identifier::new("f32ac0e8-4ec8-45f6-88b1-0e49390b8f5b").unwrap()) ); assert_eq!( glyph.contours[1].points[0] .lib() .as_ref() .unwrap() .get("com.test.foo") .unwrap() .as_string() .unwrap(), "c" ); assert_eq!( glyph.contours[1].points[2].identifier(), Some(&Identifier::new("spare-id").unwrap()) ); assert!(glyph.contours[1].points[2].lib().is_none()); assert_eq!( glyph.components[0].identifier(), Some(&Identifier::new("a50e8ccd-2ba4-4279-a011-4c82a8075dd9").unwrap()) ); assert_eq!( glyph.components[0] .lib() .as_ref() .unwrap() .get("com.test.foo") .unwrap() .as_string() .unwrap(), "b" ); } #[test] fn object_libs_reject_existing_key() { let dir = TempDir::new().unwrap(); let mut ufo = Font::new(); let mut test_lib = plist::Dictionary::new(); test_lib.insert("public.objectLibs".into(), plist::Value::Dictionary(plist::Dictionary::new())); ufo.lib = test_lib.clone(); assert!(ufo.save(&dir).is_err()); ufo.lib.remove("public.objectLibs"); let mut glyph = Glyph::new("test"); glyph.lib = test_lib; ufo.default_layer_mut().insert_glyph(glyph); assert!(ufo.save(&dir).is_err()); }