Skip to content

Instantly share code, notes, and snippets.

@Simn
Created March 22, 2016 20:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Simn/9c60e152212c32d0dc43 to your computer and use it in GitHub Desktop.
Save Simn/9c60e152212c32d0dc43 to your computer and use it in GitHub Desktop.
Simple assert macro that shows sub-expressions
class Main {
static function main() {
var x = 7;
var y = 10;
tools.Assert.assert(x == 7 && y == 11);
}
}
src/Main.hx:5: characters 22-39 : Assertion failure: x == 7 && y == 11
src/Main.hx:5: characters 22-39 : x: 7
src/Main.hx:5: characters 22-39 : x == 7: true
src/Main.hx:5: characters 22-39 : y: 10
src/Main.hx:5: characters 22-39 : y == 11: false
src/Main.hx:5: characters 22-39 : x == 7 && y == 11: false
package tools;
import haxe.macro.Expr;
using haxe.macro.Tools;
class Assert {
static public macro function assert(e:Expr) {
var s = e.toString();
var p = e.pos;
var el = [];
var descs = [];
function add(e:Expr, s:String) {
var v = "_tmp" + el.length;
el.push(macro var $v = $e);
descs.push(s);
return v;
}
function map(e:Expr) {
return switch (e.expr) {
case EConst((CInt(_) | CFloat(_) | CString(_) | CRegexp(_) | CIdent("true" | "false" | "null"))):
e;
case _:
var s = e.toString();
e = e.map(map);
macro $i{add(e, s)};
}
}
var e = map(e);
var a = [for (i in 0...el.length) macro { expr: $v{descs[i]}, value: $i{"_tmp" + i} }];
el.push(macro if (!$e) @:pos(p) throw new tools.Assert.AssertionFailure($v{s}, $a{a}));
el.push(e);
return macro $b{el};
}
}
private typedef AssertionPart = {
expr: String,
value: Dynamic
}
class AssertionFailure {
public var message(default, null):String;
public var parts(default, null):Array<AssertionPart>;
public function new(message:String, parts:Array<AssertionPart>) {
this.message = message;
this.parts = parts;
}
public function toString() {
var buf = new StringBuf();
buf.add("Assertion failure: " + message);
for (part in parts) {
buf.add("\n\t" + part.expr + ": " + part.value);
}
return buf.toString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment