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());
}