From 0a23bfbc23ec68ed229b78c8f9995928c133c4a6 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Tue, 5 Oct 2021 19:37:38 +0200 Subject: [PATCH] Add `assert` function --- src/library/mod.rs | 1 + src/library/utility.rs | 19 +++++++++++++++++-- tests/typ/utility/basics.typ | 16 ++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/library/mod.rs b/src/library/mod.rs index 13c8fd5c5..1fcd05814 100644 --- a/src/library/mod.rs +++ b/src/library/mod.rs @@ -57,6 +57,7 @@ pub fn new() -> Scope { std.def_func("circle", circle); // Utility. + std.def_func("assert", assert); std.def_func("type", type_); std.def_func("repr", repr); std.def_func("join", join); diff --git a/src/library/utility.rs b/src/library/utility.rs index e6d5476f6..5de674642 100644 --- a/src/library/utility.rs +++ b/src/library/utility.rs @@ -4,6 +4,17 @@ use std::str::FromStr; use super::*; use crate::color::{Color, RgbaColor}; +/// `assert`: Ensure that a condition is fulfilled. +pub fn assert(_: &mut EvalContext, args: &mut Args) -> TypResult { + let Spanned { v, span } = args.expect("condition")?; + match v { + Value::Bool(true) => {} + Value::Bool(false) => bail!(span, "assertion failed"), + v => bail!(span, "expected boolean, found {}", v.type_name()), + } + Ok(Value::None) +} + /// `type`: The name of a value's type. pub fn type_(_: &mut EvalContext, args: &mut Args) -> TypResult { Ok(args.expect::("value")?.type_name().into()) @@ -86,7 +97,7 @@ pub fn abs(_: &mut EvalContext, args: &mut Args) -> TypResult { Value::Relative(v) => Value::Relative(v.abs()), Value::Fractional(v) => Value::Fractional(v.abs()), Value::Linear(_) => bail!(span, "cannot take absolute value of a linear"), - _ => bail!(span, "expected numeric value"), + v => bail!(span, "expected numeric value, found {}", v.type_name()), }) } @@ -157,7 +168,11 @@ pub fn len(_: &mut EvalContext, args: &mut Args) -> TypResult { Value::Str(v) => v.len(), Value::Array(v) => v.len(), Value::Dict(v) => v.len(), - _ => bail!(span, "expected string, array or dictionary"), + v => bail!( + span, + "expected string, array or dictionary, found {}", + v.type_name(), + ), })) } diff --git a/tests/typ/utility/basics.typ b/tests/typ/utility/basics.typ index a2f6b220a..3cd4ffa96 100644 --- a/tests/typ/utility/basics.typ +++ b/tests/typ/utility/basics.typ @@ -1,6 +1,22 @@ // Test basic functions. // Ref: false +--- +// Test the `assert` function. +#assert(1 + 1 == 2) +#assert(2..5 == (2, 3, 4)) +#assert(not false) + +--- +// Test failing assertions. +// Error: 9-15 assertion failed +#assert(1 == 2) + +--- +// Test failing assertions. +// Error: 9-15 expected boolean, found string +#assert("true") + --- // Test the `type` function. #test(type(1), "integer")