mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
FEATURE: More ergonomic syntax for asserts.
This commit is contained in:
parent
b87d75c5c7
commit
a7a32d56b2
@ -16,15 +16,15 @@ let list = [1, 2, 3];
|
||||
let list2 = list;
|
||||
let list3 = [1, 2];
|
||||
|
||||
assert "one == one";
|
||||
assert "one == one";
|
||||
assert "one >= one";
|
||||
assert "two > one";
|
||||
assert "two >= two";
|
||||
assert "tpl1 == tpl2";
|
||||
assert "tpl1 != tpl3";
|
||||
assert "list == list2";
|
||||
assert "list != list3";
|
||||
assert |one == one|;
|
||||
assert |one == one|;
|
||||
assert |one >= one|;
|
||||
assert |two > one|;
|
||||
assert |two >= two|;
|
||||
assert |tpl1 == tpl2|;
|
||||
assert |tpl1 != tpl3|;
|
||||
assert |list == list2|;
|
||||
assert |list != list3|;
|
||||
|
||||
// Deep Comparisons
|
||||
let tpl4 = {
|
||||
@ -40,17 +40,17 @@ let less = {
|
||||
foo = "bar"
|
||||
};
|
||||
|
||||
assert "tpl4.inner == copy.inner";
|
||||
assert "tpl4.inner.fld == copy.inner.fld";
|
||||
assert "tpl4.lst == copy.lst";
|
||||
assert "tpl4.foo == copy.foo";
|
||||
assert "tpl4 == copy";
|
||||
assert "tpl4 != extra";
|
||||
assert "tpl4 != less";
|
||||
assert |tpl4.inner == copy.inner|;
|
||||
assert |tpl4.inner.fld == copy.inner.fld|;
|
||||
assert |tpl4.lst == copy.lst|;
|
||||
assert |tpl4.foo == copy.foo|;
|
||||
assert |tpl4 == copy|;
|
||||
assert |tpl4 != extra|;
|
||||
assert |tpl4 != less|;
|
||||
|
||||
// Expression comparisons
|
||||
assert "2 == 1+1";
|
||||
assert "(1+1) == 2";
|
||||
assert "(1+1) == (1+1)";
|
||||
assert |2 == 1+1|;
|
||||
assert |(1+1) == 2|;
|
||||
assert |(1+1) == (1+1)|;
|
||||
let want = "foo";
|
||||
assert "select want, 1, { foo=2, } == 2";
|
||||
assert |select want, 1, { foo=2, } == 2|;
|
@ -2,4 +2,4 @@ let empty = NULL;
|
||||
let tpl = {
|
||||
foo = NULL,
|
||||
};
|
||||
assert "tpl.foo == empty";
|
||||
assert |tpl.foo == empty|;
|
@ -13,10 +13,10 @@ let cplxmacro = macro(argint, argstr, argfloat) => {
|
||||
let simpleresult = simplemacro(1, 2, 3);
|
||||
let cplxresult = cplxmacro(1, "We", 3.0);
|
||||
|
||||
assert "simpleresult.field1 == 1";
|
||||
assert "simpleresult.field2 == 2";
|
||||
assert "simpleresult.field3 == 3";
|
||||
assert |simpleresult.field1 == 1|;
|
||||
assert |simpleresult.field2 == 2|;
|
||||
assert |simpleresult.field3 == 3|;
|
||||
|
||||
assert "cplxresult.field1 == 2";
|
||||
assert "cplxresult.field2 == \"We are here\"";
|
||||
assert "cplxresult.field3 == 2.0";
|
||||
assert |cplxresult.field1 == 2|;
|
||||
assert |cplxresult.field2 == "We are here"|;
|
||||
assert |cplxresult.field3 == 2.0|;
|
@ -1,7 +1,7 @@
|
||||
assert "2 * 2 + 1 == 5";
|
||||
assert "2 + 2 * 3 == 8";
|
||||
assert "2 * (2 + 1) == 6";
|
||||
assert "2 * 2 + 1 > 4";
|
||||
assert "2 * 2 + 1 > 6";
|
||||
assert "2 * 2 + 1 >= 5";
|
||||
assert "2 * 2 + 1 <= 5";
|
||||
assert |2 * 2 + 1 == 5|;
|
||||
assert |2 + 2 * 3 == 8|;
|
||||
assert |2 * (2 + 1) == 6|;
|
||||
assert |2 * 2 + 1 > 4|;
|
||||
assert |2 * 2 + 1 > 6|;
|
||||
assert |2 * 2 + 1 >= 5|;
|
||||
assert |2 * 2 + 1 <= 5|;
|
@ -10,10 +10,10 @@ let testmacro = macro(arg) => {
|
||||
output = arg,
|
||||
};
|
||||
|
||||
assert "list.0 == 1";
|
||||
assert "list.1 == 2";
|
||||
assert "list.3 == 4";
|
||||
assert "tuple.field1 == 1";
|
||||
assert "tuple.field2 == 3";
|
||||
assert "tuple.deeplist.0 == \"foo\"";
|
||||
assert "tuple.deeplist.1 == \"bar\"";
|
||||
assert |list.0 == 1|;
|
||||
assert |list.1 == 2|;
|
||||
assert |list.3 == 4|;
|
||||
assert |tuple.field1 == 1|;
|
||||
assert |tuple.field2 == 3|;
|
||||
assert |tuple.deeplist.0 == "foo"|;
|
||||
assert |tuple.deeplist.1 == "bar"|;
|
@ -71,6 +71,7 @@ pub enum TokenType {
|
||||
WS,
|
||||
COMMENT,
|
||||
QUOTED,
|
||||
PIPEQUOTE,
|
||||
DIGIT,
|
||||
BAREWORD,
|
||||
PUNCT,
|
||||
|
18
src/lib.rs
18
src/lib.rs
@ -409,23 +409,15 @@
|
||||
//!
|
||||
//! The assert statement defines an expression that must evaluate to either true or false. Assert statements are noops except
|
||||
//! during a validation compile. They give you a way to assert certains properties about your data and can be used as a form
|
||||
//! of unit testting for your configurations. It starts with the assert keyword followed by a quoted string that is
|
||||
//! itself a valid boolean ucg expression.
|
||||
//! of unit testing for your configurations. It starts with the assert keyword followed by a valid boolean ucg expression
|
||||
//! delimited by `|` characters.
|
||||
//!
|
||||
//! ```ucg
|
||||
//! assert "host == \"www.example.com\"";
|
||||
//! assert "select qa, 443, {
|
||||
//! assert host == "www.example.com";
|
||||
//! assert |select qa, 443, {
|
||||
//! qa = 80,
|
||||
//! prod = 443,
|
||||
//! } == 443";
|
||||
//! ```
|
||||
//!
|
||||
//! It is a little bit awkward for strings since you have to escape their quotes. But you can work around it by
|
||||
//! by storing the expectations in variables first and referencing them in the assert statement.
|
||||
//!
|
||||
//! ```ucg
|
||||
//! let expected_host = "www.example.com";
|
||||
//! assert "host == expected_host";
|
||||
//! } == 443|;
|
||||
//! ```
|
||||
//!
|
||||
//! When _test.ucg files are run in a validation run then ucg will output a log of all the assertions
|
||||
|
@ -838,7 +838,7 @@ named!(assert_statement<TokenIter, Statement, error::Error>,
|
||||
error::Error::new(
|
||||
"Invalid syntax for assert",
|
||||
error::ErrorType::ParseError, pos)),
|
||||
match_type!(STR)) >>
|
||||
match_type!(PIPEQUOTE)) >>
|
||||
punct!(";") >>
|
||||
(Statement::Assert(tok.clone()))
|
||||
)
|
||||
|
@ -309,6 +309,20 @@ fn test_out_statement_parse() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_assert_statement_parse() {
|
||||
assert_error!(out_statement("assert"));
|
||||
assert_error!(out_statement("assert |"));
|
||||
assert_error!(out_statement("assert |foo"));
|
||||
assert_parse!(
|
||||
assert_statement("assert |foo|;"),
|
||||
Statement::Assert(Token {
|
||||
pos: Position { line: 1, column: 8 },
|
||||
fragment: "foo".to_string(),
|
||||
typ: TokenType::PIPEQUOTE
|
||||
})
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn test_expression_statement_parse() {
|
||||
assert_error!(expression_statement("foo"));
|
||||
|
@ -73,6 +73,20 @@ named!(strtok( Span ) -> Token,
|
||||
)
|
||||
);
|
||||
|
||||
named!(pipequotetok( Span ) -> Token,
|
||||
do_parse!(
|
||||
span: position!() >>
|
||||
tag!("|") >>
|
||||
frag: take_until!("|") >>
|
||||
tag!("|") >>
|
||||
(Token{
|
||||
typ: TokenType::PIPEQUOTE,
|
||||
pos: Position::from(span),
|
||||
fragment: frag.fragment.to_string(),
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
named!(barewordtok( Span ) -> Token,
|
||||
do_parse!(
|
||||
span: position!() >>
|
||||
@ -336,6 +350,7 @@ named!(whitespace( Span ) -> Token,
|
||||
named!(token( Span ) -> Token,
|
||||
alt!(
|
||||
strtok |
|
||||
pipequotetok |
|
||||
emptytok | // This must come before the barewordtok
|
||||
digittok |
|
||||
commatok |
|
||||
@ -475,6 +490,14 @@ macro_rules! match_type {
|
||||
match_type!($i, STR => token_clone)
|
||||
};
|
||||
|
||||
($i:expr,PIPEQUOTE => $h:expr) => {
|
||||
match_type!($i, TokenType::PIPEQUOTE, "Not a Pipe Quoted String", $h)
|
||||
};
|
||||
|
||||
($i:expr,PIPEQUOTE) => {
|
||||
match_type!($i, PIPEQUOTE => token_clone)
|
||||
};
|
||||
|
||||
($i:expr,DIGIT => $h:expr) => {
|
||||
match_type!($i, TokenType::DIGIT, "Not a DIGIT", $h)
|
||||
};
|
||||
|
@ -42,6 +42,16 @@ fn test_escape_quoted() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pipe_quoted() {
|
||||
let result = pipequotetok(LocatedSpan::new("|foo|"));
|
||||
assert!(result.is_done(), format!("result {:?} is not ok", result));
|
||||
if let nom::IResult::Done(_, tok) = result {
|
||||
assert_eq!(tok.fragment, "foo".to_string());
|
||||
assert_eq!(tok.typ, TokenType::PIPEQUOTE);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_string_with_escaping() {
|
||||
let result = strtok(LocatedSpan::new("\"foo \\\\ \\\"bar\""));
|
||||
|
Loading…
x
Reference in New Issue
Block a user