1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
use lang.bs;
use core.lang;
optional delimiter = lang.bs.SDelimiter;
required delimiter = lang.bs.SRequiredDelimiter;
// Operators that makes sense to use for tests. We give them very low priority to avoid suprises.
OpInfo SCheckOp() #fnName; // Mark it so that it is clearly visible.
SCheckOp => compareLt(op, 0) : "<"@ op;
SCheckOp => compareGt(op, 0) : ">"@ op;
SCheckOp => compareLte(op, 0) : "<="@ op;
SCheckOp => compareGte(op, 0) : ">="@ op;
SCheckOp => compareEq(op, 0) : "=="@ op;
SCheckOp => compareNeq(op, 0) : "!="@ op;
SCheckOp => IsOperator(op, 0, false) : "is"@ op;
SCheckOp => IsOperator(op, 0, true) : "!is"@ op;
// Use 'startsWith', 'endsWith', and 'contains' as operators to get nicer outputs!
SCheckOp => lOperator(op, 0) : "startsWith"@ op;
SCheckOp => lOperator(op, 0) : "endsWith"@ op;
SCheckOp => lOperator(op, 0) : "contains"@ op;
// An expression together with its captured source text.
ExprText SExprText(Block block);
SExprText => ExprText(expr, text) : (SExpr(block) expr) text;
// Main test logic, the check-statement.
STestBody..SStmt[10] => checkExpr(pos, block, lhs, op, rhs) : "check" #keyword ~ SExprText(block) lhs, SCheckOp op, SExprText(block) rhs, ";";
STestBody..SStmt[05] => checkExpr(pos, block, cond, text) : "check" #keyword ~ (SCondition(block) cond) text, ";";
STestBody..SStmt[00] => checkExpr(pos, block, expr) : "check" #keyword ~ SExprText(block) expr ~ "no" #keyword ~ "throw" #keyword, ";";
STestBody..SStmt[00] => checkExpr(pos, block, expr, exception) : "check" #keyword ~ SExprText(block) expr ~ "throws" #keyword ~ SType exception;
// Abort the entire test run.
STestBody..SStmt[100] => abortExpr(pos, block) : "abort" #keyword, ";";
// Allow creating test functions.
SPlainFileItem => TestDecl(env, name, options, body) : "test" #keyword ~ SName name #fnName, SFreeOptions@ options, "{" [, STestBody@ body, ]+ "}" = STestDecl;
// Extra rule for the body, so that we can allow special syntax only inside test functions.
void STestBody(ExprBlock block);
STestBody => block : (SStmt(block) -> add, )*;
|