use fonts::{CurrentTextStyle, UIFontFace, UIFontParser};
use std::collections::HashMap;
use std::fs;
use std::path::PathBuf;
fn font_path(rel: &str) -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("../../fixtures/fonts")
.join(rel)
}
#[test]
fn test_get_romans_no_current_style() {
let parser = UIFontParser::new();
let paths = vec![
font_path("Inter/Inter-VariableFont_opsz,wght.ttf"),
font_path("Inter/Inter-Italic-VariableFont_opsz,wght.ttf"),
];
if !paths.iter().all(|p| p.exists()) {
println!("Inter fonts not found, skipping test");
return;
}
let font_data: Vec<_> = paths.iter().map(|p| fs::read(p).unwrap()).collect();
let create_font_faces = || vec![
UIFontFace {
face_id: "Inter-VariableFont_opsz,wght.ttf".to_string(),
data: &font_data[0],
user_font_style_italic: Some(false), },
UIFontFace {
face_id: "Inter-Italic-VariableFont_opsz,wght.ttf".to_string(),
data: &font_data[1],
user_font_style_italic: Some(true), },
];
let roman_matches = parser
.get_romans(
Some("Inter".to_string()),
create_font_faces(),
None, None, )
.expect("Should analyze family successfully");
assert!(roman_matches.len() >= 1);
for mat in &roman_matches {
assert_eq!(mat.distance, 0.0);
assert!(mat.axis_diffs.is_none());
}
}
#[test]
fn test_get_romans_with_current_style() {
let parser = UIFontParser::new();
let paths = vec![
font_path("Inter/Inter-VariableFont_opsz,wght.ttf"),
font_path("Inter/Inter-Italic-VariableFont_opsz,wght.ttf"),
];
if !paths.iter().all(|p| p.exists()) {
println!("Inter fonts not found, skipping test");
return;
}
let font_data: Vec<_> = paths.iter().map(|p| fs::read(p).unwrap()).collect();
let create_font_faces = || vec![
UIFontFace {
face_id: "Inter-VariableFont_opsz,wght.ttf".to_string(),
data: &font_data[0],
user_font_style_italic: Some(false), },
UIFontFace {
face_id: "Inter-Italic-VariableFont_opsz,wght.ttf".to_string(),
data: &font_data[1],
user_font_style_italic: Some(true), },
];
let current_style = CurrentTextStyle {
weight: Some(500),
width: Some(100),
slant: None,
custom_axes: HashMap::new(),
};
let roman_matches = parser
.get_romans(
Some("Inter".to_string()),
create_font_faces(),
Some(current_style),
None, )
.expect("Should analyze family successfully");
assert!(roman_matches.len() >= 1);
for i in 1..roman_matches.len() {
assert!(
roman_matches[i - 1].distance <= roman_matches[i].distance,
"Results should be sorted by distance"
);
}
}
#[test]
fn test_get_romans_max_results() {
let parser = UIFontParser::new();
let paths = vec![
font_path("PT_Serif/PTSerif-Regular.ttf"),
font_path("PT_Serif/PTSerif-Bold.ttf"),
font_path("PT_Serif/PTSerif-Italic.ttf"),
font_path("PT_Serif/PTSerif-BoldItalic.ttf"),
];
let existing_paths: Vec<_> = paths.iter().filter(|p| p.exists()).collect();
if existing_paths.len() < 3 {
println!("PT Serif fonts not found, skipping test");
return;
}
let font_data: Vec<_> = existing_paths
.iter()
.map(|p| fs::read(*p).unwrap())
.collect();
let create_font_faces = || vec![
UIFontFace {
face_id: "PTSerif-Regular.ttf".to_string(),
data: &font_data[0],
user_font_style_italic: None, },
UIFontFace {
face_id: "PTSerif-Bold.ttf".to_string(),
data: &font_data[1],
user_font_style_italic: None, },
UIFontFace {
face_id: "PTSerif-Italic.ttf".to_string(),
data: &font_data[2],
user_font_style_italic: None, },
UIFontFace {
face_id: "PTSerif-BoldItalic.ttf".to_string(),
data: &font_data[3],
user_font_style_italic: None, },
];
let current_style = CurrentTextStyle {
weight: Some(400), width: Some(100),
slant: None,
custom_axes: HashMap::new(),
};
let roman_matches = parser
.get_romans(
Some("PT Serif".to_string()),
create_font_faces(),
Some(current_style),
Some(2), )
.expect("Should analyze family successfully");
assert!(roman_matches.len() >= 1);
assert!(roman_matches.len() <= 2);
if roman_matches.len() > 1 {
assert!(roman_matches[0].distance <= roman_matches[1].distance);
}
}
#[test]
fn test_get_romans_no_romans_available() {
let parser = UIFontParser::new();
let paths = vec![
font_path("PT_Serif/PTSerif-Italic.ttf"),
font_path("PT_Serif/PTSerif-BoldItalic.ttf"),
];
let existing_paths: Vec<_> = paths.iter().filter(|p| p.exists()).collect();
if existing_paths.len() < 2 {
println!("PT Serif italic fonts not found, skipping test");
return;
}
let font_data: Vec<_> = existing_paths
.iter()
.map(|p| fs::read(*p).unwrap())
.collect();
let create_font_faces = || vec![
UIFontFace {
face_id: "PTSerif-Italic.ttf".to_string(),
data: &font_data[0],
user_font_style_italic: None, },
UIFontFace {
face_id: "PTSerif-BoldItalic.ttf".to_string(),
data: &font_data[1],
user_font_style_italic: None, },
];
let current_style = CurrentTextStyle {
weight: Some(400),
width: Some(100),
slant: None,
custom_axes: HashMap::new(),
};
let roman_matches = parser
.get_romans(
Some("PT Serif".to_string()),
create_font_faces(),
Some(current_style),
None,
)
.expect("Should analyze family successfully");
assert_eq!(roman_matches.len(), 0);
}
#[test]
fn test_get_romans_variable_font() {
let parser = UIFontParser::new();
let path = font_path("Inter/Inter-VariableFont_opsz,wght.ttf");
if !path.exists() {
println!("Inter variable font not found, skipping test");
return;
}
let font_data = fs::read(&path).unwrap();
let create_font_faces = || vec![UIFontFace {
face_id: "Inter-VariableFont_opsz,wght.ttf".to_string(),
data: &font_data,
user_font_style_italic: None, }];
let current_style = CurrentTextStyle {
weight: Some(400),
width: Some(100),
slant: Some(15.0),
custom_axes: HashMap::new(),
};
let roman_matches = parser
.get_romans(
Some("Inter".to_string()),
create_font_faces(),
Some(current_style),
None,
)
.expect("Should analyze family successfully");
assert!(
roman_matches.len() > 0,
"Should have at least one roman variant"
);
}
#[test]
fn test_get_romans_custom_axes() {
let parser = UIFontParser::new();
let paths = vec![
font_path("PT_Serif/PTSerif-Regular.ttf"),
font_path("PT_Serif/PTSerif-Bold.ttf"),
];
let existing_paths: Vec<_> = paths.iter().filter(|p| p.exists()).collect();
if existing_paths.len() < 2 {
println!("PT Serif fonts not found, skipping test");
return;
}
let font_data: Vec<_> = existing_paths
.iter()
.map(|p| fs::read(*p).unwrap())
.collect();
let create_font_faces = || vec![
UIFontFace {
face_id: "PTSerif-Regular.ttf".to_string(),
data: &font_data[0],
user_font_style_italic: None, },
UIFontFace {
face_id: "PTSerif-Bold.ttf".to_string(),
data: &font_data[1],
user_font_style_italic: None, },
];
let mut custom_axes = HashMap::new();
custom_axes.insert("wght".to_string(), 500.0);
custom_axes.insert("wdth".to_string(), 120.0);
custom_axes.insert("opsz".to_string(), 14.0);
let current_style = CurrentTextStyle {
weight: Some(400), width: None, slant: None,
custom_axes,
};
let roman_matches = parser
.get_romans(
Some("PT Serif".to_string()),
create_font_faces(),
Some(current_style),
None,
)
.expect("Should analyze family successfully");
assert!(roman_matches.len() > 0);
for mat in &roman_matches {
assert!(mat.distance >= 0.0);
}
}
#[test]
fn test_get_romans_error_handling() {
let parser = UIFontParser::new();
let result = parser.get_romans(
Some("Inter".to_string()),
vec![], None,
None,
);
assert!(result.is_err());
}
#[test]
fn test_get_romans_round_trip_consistency() {
let parser = UIFontParser::new();
let paths = vec![
font_path("PT_Serif/PTSerif-Regular.ttf"),
font_path("PT_Serif/PTSerif-Bold.ttf"),
font_path("PT_Serif/PTSerif-Italic.ttf"),
font_path("PT_Serif/PTSerif-BoldItalic.ttf"),
];
let existing_paths: Vec<_> = paths.iter().filter(|p| p.exists()).collect();
if existing_paths.len() < 4 {
println!("PT Serif fonts not found, skipping test");
return;
}
let font_data: Vec<_> = existing_paths
.iter()
.map(|p| fs::read(*p).unwrap())
.collect();
let create_font_faces = || vec![
UIFontFace {
face_id: "PTSerif-Regular.ttf".to_string(),
data: &font_data[0],
user_font_style_italic: None, },
UIFontFace {
face_id: "PTSerif-Bold.ttf".to_string(),
data: &font_data[1],
user_font_style_italic: None, },
UIFontFace {
face_id: "PTSerif-Italic.ttf".to_string(),
data: &font_data[2],
user_font_style_italic: None, },
UIFontFace {
face_id: "PTSerif-BoldItalic.ttf".to_string(),
data: &font_data[3],
user_font_style_italic: None, },
];
let current_style = CurrentTextStyle {
weight: Some(400),
width: Some(100),
slant: None,
custom_axes: HashMap::new(),
};
let roman_matches = parser
.get_romans(
Some("PT Serif".to_string()),
create_font_faces(),
Some(current_style.clone()),
None,
)
.expect("Should get roman matches");
assert!(roman_matches.len() > 0);
let italic_matches = parser
.get_italics(
Some("PT Serif".to_string()),
create_font_faces(),
Some(current_style),
None,
)
.expect("Should get italic matches");
assert!(italic_matches.len() > 0);
}