use cooklang::{Converter, CooklangParser, Extensions};
#[test]
fn test_scale_updates_servings_metadata() {
let input = r#"---
servings: 4
---
@flour{200%g}
@eggs{2}
Mix and bake."#;
let parser = CooklangParser::new(Extensions::all(), Converter::default());
let mut recipe = parser.parse(input).unwrap_output();
assert_eq!(
recipe.metadata.servings().and_then(|s| s.as_number()),
Some(4)
);
let orig_servings_value = recipe
.metadata
.get(cooklang::metadata::StdKey::Servings)
.unwrap();
assert_eq!(orig_servings_value.as_u64(), Some(4));
recipe.scale_to_servings(8, &Converter::default()).unwrap();
let scaled_servings_value = recipe
.metadata
.get(cooklang::metadata::StdKey::Servings)
.unwrap();
assert_eq!(scaled_servings_value.as_u64(), Some(8));
}
#[test]
fn test_scale_by_factor_updates_servings_metadata() {
let input = r#">> servings: 2
@butter{100%g}
@sugar{50%g}"#;
let parser = CooklangParser::new(Extensions::all(), Converter::default());
let mut recipe = parser.parse(input).unwrap_output();
recipe.scale(3.0, &Converter::default());
let scaled_servings_value = recipe
.metadata
.get(cooklang::metadata::StdKey::Servings)
.unwrap();
match scaled_servings_value {
serde_yaml::Value::String(s) => assert_eq!(s, "6"),
serde_yaml::Value::Number(n) => assert_eq!(n.as_u64(), Some(6)),
_ => panic!("Unexpected servings value type"),
}
}
#[test]
fn test_scale_without_servings_metadata() {
let input = r#"@flour{200%g}
@eggs{2}"#;
let parser = CooklangParser::new(Extensions::all(), Converter::default());
let mut recipe = parser.parse(input).unwrap_output();
assert_eq!(recipe.metadata.servings(), None);
recipe.scale(2.0, &Converter::default());
assert!(recipe
.metadata
.get(cooklang::metadata::StdKey::Servings)
.is_none());
}
#[test]
fn test_scale_with_fractional_servings() {
let input = r#">> servings: 3
@milk{300%ml}"#;
let parser = CooklangParser::new(Extensions::all(), Converter::default());
let mut recipe = parser.parse(input).unwrap_output();
recipe.scale(1.5, &Converter::default());
let scaled_servings_value = recipe
.metadata
.get(cooklang::metadata::StdKey::Servings)
.unwrap();
match scaled_servings_value {
serde_yaml::Value::String(s) => assert_eq!(s, "5"),
serde_yaml::Value::Number(n) => assert_eq!(n.as_u64(), Some(5)),
_ => panic!("Unexpected servings value type"),
}
}
#[test]
fn test_scale_with_non_numeric_servings() {
let input = r#">> servings: two
@flour{200%g}
@butter{100%g}"#;
let parser = CooklangParser::new(Extensions::all(), Converter::default());
let mut recipe = parser.parse(input).unwrap_output();
let servings = recipe.metadata.servings();
assert!(servings.is_some());
assert_eq!(servings.as_ref().and_then(|s| s.as_number()), None);
assert_eq!(servings.as_ref().and_then(|s| s.as_text()), Some("two"));
recipe.scale(2.0, &Converter::default());
let servings_value = recipe
.metadata
.get(cooklang::metadata::StdKey::Servings)
.unwrap();
assert_eq!(servings_value.as_str(), Some("two"));
}
#[test]
fn test_scale_to_servings_with_parseable_string_servings() {
let input = r#"---
servings: "serves 4 people"
---
@rice{2%cups}"#;
let parser = CooklangParser::new(Extensions::all(), Converter::default());
let mut recipe = parser.parse(input).unwrap_output();
let servings = recipe.metadata.servings();
assert!(servings.is_some());
assert_eq!(servings.as_ref().and_then(|s| s.as_number()), None);
assert_eq!(
servings.as_ref().and_then(|s| s.as_text()),
Some("serves 4 people")
);
let result = recipe.scale_to_servings(8, &Converter::default());
assert!(result.is_err());
let ingredient_quantity = &recipe.ingredients[0].quantity.as_ref().unwrap();
match ingredient_quantity.value() {
cooklang::quantity::Value::Number(n) => {
assert_eq!(n.value(), 2.0); }
_ => panic!("Expected numeric value"),
}
}
#[test]
fn test_scale_to_servings_with_numeric_string() {
let input = r#"---
servings: "4"
---
@rice{2%cups}"#;
let parser = CooklangParser::new(Extensions::all(), Converter::default());
let mut recipe = parser.parse(input).unwrap_output();
let servings = recipe.metadata.servings();
assert!(servings.is_some());
assert_eq!(servings.as_ref().and_then(|s| s.as_number()), Some(4));
let result = recipe.scale_to_servings(8, &Converter::default());
assert!(result.is_ok());
let ingredient_quantity = &recipe.ingredients[0].quantity.as_ref().unwrap();
match ingredient_quantity.value() {
cooklang::quantity::Value::Number(n) => {
assert_eq!(n.value(), 4.0); }
_ => panic!("Expected numeric value"),
}
}
#[test]
fn test_scale_to_servings_with_non_numeric_servings() {
let input = r#"---
servings: "varies"
---
@rice{2%cups}"#;
let parser = CooklangParser::new(Extensions::all(), Converter::default());
let mut recipe = parser.parse(input).unwrap_output();
let servings = recipe.metadata.servings();
assert!(servings.is_some());
assert_eq!(servings.as_ref().and_then(|s| s.as_number()), None);
assert_eq!(servings.as_ref().and_then(|s| s.as_text()), Some("varies"));
let result = recipe.scale_to_servings(8, &Converter::default());
assert!(result.is_err());
match result.unwrap_err() {
cooklang::scale::ScaleError::InvalidServings => {
}
_ => panic!("Expected InvalidServings error, got a different error"),
}
let ingredient_quantity = &recipe.ingredients[0].quantity.as_ref().unwrap();
match ingredient_quantity.value() {
cooklang::quantity::Value::Number(n) => {
assert_eq!(n.value(), 2.0); }
_ => panic!("Expected numeric value"),
}
}