Skip to content

Commit

Permalink
enhancement(remap): Add assert_eq! function (#7866)
Browse files Browse the repository at this point in the history
* enhancement(remap): Add assert_eq! function

This PR adds an `assert_eq!` function with the goal of making writing
unit tests easier.

The output may change with
#6261 to make it easier to see
the condition that failed.

Closes #7833

Signed-off-by: Jesse Szwedko <jesse@szwedko.me>
  • Loading branch information
jszwedko committed Jun 16, 2021
1 parent 024f758 commit 0a34989
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/vrl/stdlib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ default = [
"append",
"array",
"assert",
"assert_eq",
"boolean",
"ceil",
"compact",
Expand Down Expand Up @@ -144,6 +145,7 @@ default = [
append = []
array = []
assert = []
assert_eq = []
boolean = []
ceil = []
compact = []
Expand Down
10 changes: 10 additions & 0 deletions lib/vrl/stdlib/benches/benches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ criterion_group!(
// https://github.com/timberio/vector/pull/6408
config = Criterion::default().noise_threshold(0.05);
targets = assert,
assert_eq,
ceil,
compact,
contains,
Expand Down Expand Up @@ -122,6 +123,15 @@ bench_function! {
}
}

bench_function! {
assert_eq=> vrl_stdlib::AssertEq;

literal {
args: func_args![left: value!(true), right: value!(true), message: "must be true"],
want: Ok(value!(true)),
}
}

bench_function! {
ceil => vrl_stdlib::Ceil;

Expand Down
124 changes: 124 additions & 0 deletions lib/vrl/stdlib/src/assert_eq.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
use vrl::prelude::*;

#[derive(Clone, Copy, Debug)]
pub struct AssertEq;

impl Function for AssertEq {
fn identifier(&self) -> &'static str {
"assert_eq"
}

fn parameters(&self) -> &'static [Parameter] {
&[
Parameter {
keyword: "left",
kind: kind::ANY,
required: true,
},
Parameter {
keyword: "right",
kind: kind::ANY,
required: true,
},
Parameter {
keyword: "message",
kind: kind::BYTES,
required: false,
},
]
}

fn examples(&self) -> &'static [Example] {
&[
Example {
title: "success",
source: "assert_eq!(true, true)",
result: Ok("true"),
},
Example {
title: "failure",
source: "assert_eq!(true, false)",
result: Err(
r#"function call error for "assert_eq" at (0:23): assertion failed: true == false"#,
),
},
Example {
title: "custom message",
source: "assert_eq!(true, false, s'custom error')",
result: Err(r#"function call error for "assert_eq" at (0:40): custom error"#),
},
]
}

fn compile(&self, mut arguments: ArgumentList) -> Compiled {
let left = arguments.required("left");
let right = arguments.required("right");
let message = arguments.optional("message");

Ok(Box::new(AssertEqFn {
left,
right,
message,
}))
}
}

#[derive(Debug, Clone)]
struct AssertEqFn {
left: Box<dyn Expression>,
right: Box<dyn Expression>,
message: Option<Box<dyn Expression>>,
}

impl Expression for AssertEqFn {
fn resolve(&self, ctx: &mut Context) -> Resolved {
let left = self.left.resolve(ctx)?;
let right = self.right.resolve(ctx)?;

if left == right {
Ok(true.into())
} else {
Err(self
.message
.as_ref()
.map(|m| {
m.resolve(ctx)
.and_then(|v| Ok(v.try_bytes_utf8_lossy()?.into_owned()))
})
.transpose()?
.unwrap_or_else(|| format!("assertion failed: {} == {}", left, right))
.into())
}
}

fn type_def(&self, _state: &state::Compiler) -> TypeDef {
TypeDef::new().fallible().boolean()
}
}

#[cfg(test)]
mod tests {
use super::*;

test_function![
assert_eq => AssertEq;

pass {
args: func_args![left: "foo", right: "foo"],
want: Ok(true),
tdef: TypeDef::new().fallible().boolean(),
}

fail {
args: func_args![left: "foo", right: "bar"],
want: Err(r#"assertion failed: "foo" == "bar""#),
tdef: TypeDef::new().fallible().boolean(),
}

message {
args: func_args![left: "foo", right: "bar", message: "failure!"],
want: Err("failure!"),
tdef: TypeDef::new().fallible().boolean(),
}
];
}
6 changes: 6 additions & 0 deletions lib/vrl/stdlib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ mod append;
mod array;
#[cfg(feature = "assert")]
mod assert;
#[cfg(feature = "assert_eq")]
mod assert_eq;
#[cfg(feature = "boolean")]
mod boolean;
#[cfg(feature = "ceil")]
Expand Down Expand Up @@ -219,6 +221,8 @@ pub use crate::sha1::Sha1;
pub use append::Append;
#[cfg(feature = "assert")]
pub use assert::Assert;
#[cfg(feature = "assert_eq")]
pub use assert_eq::AssertEq;
#[cfg(feature = "boolean")]
pub use boolean::Boolean;
#[cfg(feature = "ceil")]
Expand Down Expand Up @@ -418,6 +422,8 @@ pub fn all() -> Vec<Box<dyn vrl::Function>> {
Box::new(Append),
#[cfg(feature = "assert")]
Box::new(Assert),
#[cfg(feature = "assert_eq")]
Box::new(AssertEq),
#[cfg(feature = "boolean")]
Box::new(Boolean),
#[cfg(feature = "ceil")]
Expand Down

0 comments on commit 0a34989

Please sign in to comment.