vegardit / haxe-doctest

A haxelib inspired by Python's doctest command that generates unit tests based on assertions specified within the source code.
http://vegardit.github.io/haxe-doctest/
Apache License 2.0
23 stars 2 forks source link

Deep value tests. #6

Closed nanjizal closed 5 years ago

nanjizal commented 5 years ago

Wanted to clarify the recommend deep value testing, and perhaps request more integration or maybe you would like me to attempt to add to documents? Perhaps there is an easier approach?

Found two libraries https://lib.haxe.org/t/deep%20equal/

Equal seems simpler to use outside of haxe-doctest. haxelib install equals

So at the moment I am doing:

// abstract Vec3( V3 ) from V3 to V3 { where V3 is typedef x,y,z.
    /**
     * <pre><code>
     * >>> Equal.equals( Vec3.zero(), { x: 0., y: 0., z: 0. } ) == true
     * >>> Equal.equals( Vec3.zero(), new Vec3({ x: 0., y: 0., z: 0. }) ) == true
     * </code></pre>
     */
    public static inline
    function zero(){
        return new Vec3({ x: 0.
                        , y: 0.
                        , z: 0. });
    }

Then setup of project.

package rayTriangle;
import utest.Runner;
import utest.Test;
import utest.ui.Report;
import equals.Equal;   // <- notice this line is needed here not in Vec3 class!
@:build(hx.doctest.DocTestGenerator.generateDocTests())
@:build(utest.utils.TestBuilder.build())
class RayTriangleTests extends utest.Test {
    public static function main() {
        var runner = new Runner();
        runner.addCase( new RayTriangleTests() );
        Report.create(runner);
        runner.run();
    }
    function new() {
        super();
    }
}

Gama11 suggested I try using utest.Assert.same but it returns a success or failure so is more complex ?

I wondered how might be best to move forward. I can use 'equals' initially but think it would be ideal that failures provide specific details.

sebthom commented 5 years ago

This works fine for me:

package example;

typedef V3 = {var x:Float; var y:Float; var z:Float; }

abstract Vec3(V3) from V3 to V3 {
    public inline function new (v3:V3) this = v3;
}

class Vec3Utils {
    /**
     * <pre><code>
     * >>> Vec3Utils.zero() == { x: 0., y: 0., z: 0. }
     * >>> new Vec3Utils.Vec3({x:0.,y: 0., z: 0.}) == new Vec3Utils.Vec3({x:0.,y: 0., z: 0.})
     * >>> Vec3Utils.zero() == new Vec3Utils.Vec3({x:0.,y: 0., z: 0.})
     * >>> Vec3Utils.zero() == Vec3Utils.zero()
     * </code></pre>
     */
    public static inline function zero()
        return new Vec3({x:0.,y: 0., z: 0.});
}
sebthom commented 5 years ago

Doctest uses the DocTestUtils#equals() method to perform equality tests which does deep equals for anonymous structures.

nanjizal commented 5 years ago

That looks pretty similar to my minimal test yet mine fails, am I missing something obvious? Are you running on recent haxe4 I can try upgrading to very latest?

( for trying out test setup I am using fairly small test library to get to grips.rayTriangle-test )

I was testing on javascript with Haxe 4.0.0-preview.5+83d9c11

package rayTriangle;
#if avoid_typedef
@:structInit
class V3 {
    public var x: Float;
    public var y: Float;
    public var z: Float; 
    //private
    function new( x: Float, y: Float, z: Float ){
        this.x = x;
        this.y = y;
        this.z = z;
    }
}
#else
typedef V3 = {
    public var x: Float;
    public var y: Float;
    public var z: Float;
}
#end
@:forward
abstract Vec3( V3 ) from V3 to V3 {
    public inline
    function new( v: V3 ){
        this = v;
    }
    /**
     * <pre><code>
     * >>> Vec3.zero() == { x: 0., y: 0., z: 0. }
     * </code></pre>
     */
    public static inline
    function zero(){
        return new Vec3({ x: 0.
                        , y: 0.
                        , z: 0. });
    }
    @:op(A - B)
    public static inline
    function subtract( a: Vec3, b: Vec3 ): Vec3 {
        return new Vec3({ x: a.x - b.x
                        , y: a.y - b.y
                        , z: a.z - b.z });
    }
    public inline
    function dot( v: Vec3 ): Float{
      return this.x * v.x + this.y * v.y + this.z * v.z;
    }
    @:op(A % B)
    public static inline
    function cross( a: Vec3, b: Vec3 ): Vec3 {
            return new Vec3({  x: a.y * b.z - a.z * b.y
                             , y: a.z * b.x - a.x * b.z
                             , z: a.x * b.y - a.y * b.x });
    }
    public inline
    function length(): Float {
        return Math.sqrt( this.x*this.x + this.y*this.y + this.z*this.z );
    }
    public inline
    function normalize(): Vec3 {
        var len = length();
        return new Vec3( { x: this.x/len
                         , y: this.y/len
                         , z: this.z/len } );
    }
    public inline
    function toString(): String {
        return "[" + this.x + ', ' + this.y + ', ' + this.z + "]";
    }
}
package rayTriangle;
import utest.Runner;
import utest.Test;
import utest.ui.Report;
import equals.Equal;
import utest.Assert;
@:build(hx.doctest.DocTestGenerator.generateDocTests())
@:build(utest.utils.TestBuilder.build())
class RayTriangleTests extends utest.Test {
    public static function main() {
        var runner = new Runner();
        runner.addCase( new RayTriangleTests() );
        Report.create(runner);
        runner.run();
    }
    function new() {
        super();
    }
}

my compile code...

#    Javascript test
-cp src
-lib utest
-lib haxe-doctest
-lib equals
#-lib munit
-main rayTriangle.RayTriangleTests
# switch between abstract and class and abstract and typedef
-D avoid_typedef
-js test.js
-cmd echo '<!DOCTYPE html><meta charset="UTF-8"><html><body><script src="test.js"></script></body></html>' >indexTest.html
-cmd open indexTest.html
rayTriangleFailTest

full generated js source

// Generated by Haxe 4.0.0-preview.5+83d9c11
(function ($global) { "use strict";
var $estr = function() { return js_Boot.__string_rec(this,''); },$hxEnums = $hxEnums || {},$_;
function $extend(from, fields) {
    var proto = Object.create(from);
    for (var name in fields) proto[name] = fields[name];
    if( fields.toString !== Object.prototype.toString ) proto.toString = fields.toString;
    return proto;
}
var EReg = function(r,opt) {
    this.r = new RegExp(r,opt.split("u").join(""));
};
EReg.__name__ = "EReg";
EReg.prototype = {
    r: null
    ,match: function(s) {
        if(this.r.global) {
            this.r.lastIndex = 0;
        }
        this.r.m = this.r.exec(s);
        this.r.s = s;
        return this.r.m != null;
    }
    ,matched: function(n) {
        if(this.r.m != null && n >= 0 && n < this.r.m.length) {
            return this.r.m[n];
        } else {
            throw new js__$Boot_HaxeError("EReg::matched");
        }
    }
    ,__class__: EReg
};
var HxOverrides = function() { };
HxOverrides.__name__ = "HxOverrides";
HxOverrides.cca = function(s,index) {
    var x = s.charCodeAt(index);
    if(x != x) {
        return undefined;
    }
    return x;
};
HxOverrides.substr = function(s,pos,len) {
    if(len == null) {
        len = s.length;
    } else if(len < 0) {
        if(pos == 0) {
            len = s.length + len;
        } else {
            return "";
        }
    }
    return s.substr(pos,len);
};
HxOverrides.remove = function(a,obj) {
    var i = a.indexOf(obj);
    if(i == -1) {
        return false;
    }
    a.splice(i,1);
    return true;
};
HxOverrides.iter = function(a) {
    return { cur : 0, arr : a, hasNext : function() {
        return this.cur < this.arr.length;
    }, next : function() {
        return this.arr[this.cur++];
    }};
};
var IntIterator = function(min,max) {
    this.min = min;
    this.max = max;
};
IntIterator.__name__ = "IntIterator";
IntIterator.prototype = {
    min: null
    ,max: null
    ,hasNext: function() {
        return this.min < this.max;
    }
    ,next: function() {
        return this.min++;
    }
    ,__class__: IntIterator
};
var Lambda = function() { };
Lambda.__name__ = "Lambda";
Lambda.array = function(it) {
    var a = [];
    var i = $getIterator(it);
    while(i.hasNext()) {
        var i1 = i.next();
        a.push(i1);
    }
    return a;
};
Lambda.has = function(it,elt) {
    var x = $getIterator(it);
    while(x.hasNext()) {
        var x1 = x.next();
        if(x1 == elt) {
            return true;
        }
    }
    return false;
};
Math.__name__ = "Math";
var Reflect = function() { };
Reflect.__name__ = "Reflect";
Reflect.field = function(o,field) {
    try {
        return o[field];
    } catch( e ) {
        haxe_CallStack.lastException = e;
        var e1 = ((e) instanceof js__$Boot_HaxeError) ? e.val : e;
        return null;
    }
};
Reflect.getProperty = function(o,field) {
    var tmp;
    if(o == null) {
        return null;
    } else {
        var tmp1;
        if(o.__properties__) {
            tmp = o.__properties__["get_" + field];
            tmp1 = tmp;
        } else {
            tmp1 = false;
        }
        if(tmp1) {
            return o[tmp]();
        } else {
            return o[field];
        }
    }
};
Reflect.fields = function(o) {
    var a = [];
    if(o != null) {
        var hasOwnProperty = Object.prototype.hasOwnProperty;
        for( var f in o ) {
        if(f != "__id__" && f != "hx__closures__" && hasOwnProperty.call(o,f)) {
            a.push(f);
        }
        }
    }
    return a;
};
Reflect.isFunction = function(f) {
    if(typeof(f) == "function") {
        return !(f.__name__ || f.__ename__);
    } else {
        return false;
    }
};
Reflect.compare = function(a,b) {
    if(a == b) {
        return 0;
    } else if(a > b) {
        return 1;
    } else {
        return -1;
    }
};
Reflect.compareMethods = function(f1,f2) {
    if(f1 == f2) {
        return true;
    }
    if(!Reflect.isFunction(f1) || !Reflect.isFunction(f2)) {
        return false;
    }
    if(f1.scope == f2.scope && f1.method == f2.method) {
        return f1.method != null;
    } else {
        return false;
    }
};
Reflect.isObject = function(v) {
    if(v == null) {
        return false;
    }
    var t = typeof(v);
    if(!(t == "string" || t == "object" && v.__enum__ == null)) {
        if(t == "function") {
            return (v.__name__ || v.__ename__) != null;
        } else {
            return false;
        }
    } else {
        return true;
    }
};
Reflect.isEnumValue = function(v) {
    if(v != null) {
        return v.__enum__ != null;
    } else {
        return false;
    }
};
var Std = function() { };
Std.__name__ = "Std";
Std.string = function(s) {
    return js_Boot.__string_rec(s,"");
};
Std.parseInt = function(x) {
    var v = parseInt(x, x && x[0]=="0" && (x[1]=="x" || x[1]=="X") ? 16 : 10);
    if(isNaN(v)) {
        return null;
    }
    return v;
};
var StringBuf = function() {
    this.b = "";
};
StringBuf.__name__ = "StringBuf";
StringBuf.prototype = {
    b: null
    ,__class__: StringBuf
};
var StringTools = function() { };
StringTools.__name__ = "StringTools";
StringTools.htmlEscape = function(s,quotes) {
    var buf_b = "";
    var _g_offset = 0;
    var _g_s = s;
    while(_g_offset < _g_s.length) {
        var c = _g_s.charCodeAt(_g_offset++);
        if(c >= 55296 && c < 56319) {
            c = c - 55232 << 10 | _g_s.charCodeAt(_g_offset++) & 1023;
        }
        var code = c;
        switch(code) {
        case 34:
            if(quotes) {
                buf_b += "&quot;";
            } else {
                buf_b += String.fromCodePoint(code);
            }
            break;
        case 38:
            buf_b += "&amp;";
            break;
        case 39:
            if(quotes) {
                buf_b += "&#039;";
            } else {
                buf_b += String.fromCodePoint(code);
            }
            break;
        case 60:
            buf_b += "&lt;";
            break;
        case 62:
            buf_b += "&gt;";
            break;
        default:
            buf_b += String.fromCodePoint(code);
        }
    }
    return buf_b;
};
StringTools.startsWith = function(s,start) {
    if(s.length >= start.length) {
        return HxOverrides.substr(s,0,start.length) == start;
    } else {
        return false;
    }
};
StringTools.isSpace = function(s,pos) {
    var c = HxOverrides.cca(s,pos);
    if(!(c > 8 && c < 14)) {
        return c == 32;
    } else {
        return true;
    }
};
StringTools.ltrim = function(s) {
    var l = s.length;
    var r = 0;
    while(r < l && StringTools.isSpace(s,r)) ++r;
    if(r > 0) {
        return HxOverrides.substr(s,r,l - r);
    } else {
        return s;
    }
};
StringTools.rtrim = function(s) {
    var l = s.length;
    var r = 0;
    while(r < l && StringTools.isSpace(s,l - r - 1)) ++r;
    if(r > 0) {
        return HxOverrides.substr(s,0,l - r);
    } else {
        return s;
    }
};
StringTools.trim = function(s) {
    return StringTools.ltrim(StringTools.rtrim(s));
};
StringTools.replace = function(s,sub,by) {
    return s.split(sub).join(by);
};
var ValueType = $hxEnums["ValueType"] = { __ename__ : "ValueType", __constructs__ : ["TNull","TInt","TFloat","TBool","TObject","TFunction","TClass","TEnum","TUnknown"]
    ,TNull: {_hx_index:0,__enum__:"ValueType",toString:$estr}
    ,TInt: {_hx_index:1,__enum__:"ValueType",toString:$estr}
    ,TFloat: {_hx_index:2,__enum__:"ValueType",toString:$estr}
    ,TBool: {_hx_index:3,__enum__:"ValueType",toString:$estr}
    ,TObject: {_hx_index:4,__enum__:"ValueType",toString:$estr}
    ,TFunction: {_hx_index:5,__enum__:"ValueType",toString:$estr}
    ,TClass: ($_=function(c) { return {_hx_index:6,c:c,__enum__:"ValueType",toString:$estr}; },$_.__params__ = ["c"],$_)
    ,TEnum: ($_=function(e) { return {_hx_index:7,e:e,__enum__:"ValueType",toString:$estr}; },$_.__params__ = ["e"],$_)
    ,TUnknown: {_hx_index:8,__enum__:"ValueType",toString:$estr}
};
var Type = function() { };
Type.__name__ = "Type";
Type.getEnum = function(o) {
    if(o == null) {
        return null;
    }
    return $hxEnums[o.__enum__];
};
Type.getInstanceFields = function(c) {
    var a = [];
    for(var i in c.prototype) a.push(i);
    HxOverrides.remove(a,"__class__");
    HxOverrides.remove(a,"__properties__");
    return a;
};
Type["typeof"] = function(v) {
    switch(typeof(v)) {
    case "boolean":
        return ValueType.TBool;
    case "function":
        if(v.__name__ || v.__ename__) {
            return ValueType.TObject;
        }
        return ValueType.TFunction;
    case "number":
        if(Math.ceil(v) == v % 2147483648.0) {
            return ValueType.TInt;
        }
        return ValueType.TFloat;
    case "object":
        if(v == null) {
            return ValueType.TNull;
        }
        var e = v.__enum__;
        if(e != null) {
            return ValueType.TEnum($hxEnums[e]);
        }
        var c = js_Boot.getClass(v);
        if(c != null) {
            return ValueType.TClass(c);
        }
        return ValueType.TObject;
    case "string":
        return ValueType.TClass(String);
    case "undefined":
        return ValueType.TNull;
    default:
        return ValueType.TUnknown;
    }
};
Type.enumEq = function(a,b) {
    if(a == b) {
        return true;
    }
    try {
        var e = a.__enum__;
        if(e == null || e != b.__enum__) {
            return false;
        }
        if(a._hx_index != b._hx_index) {
            return false;
        }
        var enm = $hxEnums[e];
        var ctorName = enm.__constructs__[a._hx_index];
        var params = enm[ctorName].__params__;
        var _g = 0;
        while(_g < params.length) {
            var f = params[_g];
            ++_g;
            if(!Type.enumEq(a[f],b[f])) {
                return false;
            }
        }
    } catch( e1 ) {
        haxe_CallStack.lastException = e1;
        var e2 = ((e1) instanceof js__$Boot_HaxeError) ? e1.val : e1;
        return false;
    }
    return true;
};
Type.enumParameters = function(e) {
    var enm = $hxEnums[e.__enum__];
    var ctorName = enm.__constructs__[e._hx_index];
    var params = enm[ctorName].__params__;
    if(params != null) {
        var _g = [];
        var _g1 = 0;
        while(_g1 < params.length) {
            var p = params[_g1];
            ++_g1;
            _g.push(e[p]);
        }
        return _g;
    } else {
        return [];
    }
};
var equals_Equal = function() { };
equals_Equal.__name__ = "equals.Equal";
equals_Equal.isNull = function(a) {
    if(Type["typeof"](a)._hx_index == 0) {
        return true;
    } else {
        return false;
    }
};
equals_Equal.isFunction = function(a) {
    if(Type["typeof"](a)._hx_index == 5) {
        return true;
    } else {
        return false;
    }
};
equals_Equal.equals = function(a,b) {
    if(a == b) {
        return true;
    }
    if(equals_Equal.isNull(a) || equals_Equal.isNull(b)) {
        return false;
    }
    switch(Type["typeof"](a)._hx_index) {
    case 2:
        if(isNaN(a)) {
            return isNaN(b);
        } else {
            return false;
        }
        break;
    case 0:case 1:case 3:case 8:
        return a == b;
    case 4:
        break;
    case 5:
        return Reflect.compareMethods(a,b);
    case 6:
        if(((a) instanceof Array) && a.__enum__ == null) {
            var a1 = js_Boot.__cast(a , Array);
            var b1 = js_Boot.__cast(b , Array);
            if(a1.length != b1.length) {
                return false;
            }
            var _g = 0;
            var _g1 = a1.length;
            while(_g < _g1) {
                var i = _g++;
                if(!equals_Equal.equals(a1[i],b1[i])) {
                    return false;
                }
            }
            return true;
        }
        if(js_Boot.__instanceof(a,haxe_IMap)) {
            var a2 = js_Boot.__cast(a , haxe_IMap);
            var b2 = js_Boot.__cast(b , haxe_IMap);
            var _g2 = [];
            var key = a2.keys();
            while(key.hasNext()) {
                var key1 = key.next();
                _g2.push(key1);
            }
            var a_keys = _g2;
            var _g11 = [];
            var key2 = b2.keys();
            while(key2.hasNext()) {
                var key3 = key2.next();
                _g11.push(key3);
            }
            var b_keys = _g11;
            if(!equals_Equal.equals(a_keys,b_keys)) {
                return false;
            }
            var _g21 = 0;
            while(_g21 < a_keys.length) {
                var key4 = a_keys[_g21];
                ++_g21;
                if(!equals_Equal.equals(a2.get(key4),b2.get(key4))) {
                    return false;
                }
            }
            return true;
        }
        if(((a) instanceof Date)) {
            return (js_Boot.__cast(a , Date)).getTime() == (js_Boot.__cast(b , Date)).getTime();
        }
        if(((a) instanceof haxe_io_Bytes)) {
            return equals_Equal.equals((js_Boot.__cast(a , haxe_io_Bytes)).b.bufferValue,(js_Boot.__cast(b , haxe_io_Bytes)).b.bufferValue);
        }
        break;
    case 7:
        if(a._hx_index != b._hx_index) {
            return false;
        }
        var a_args = Type.enumParameters(a);
        var b_args = Type.enumParameters(b);
        return equals_Equal.equals(a_args,b_args);
    }
    var _g12 = 0;
    var _g22 = Reflect.fields(a);
    while(_g12 < _g22.length) {
        var field = _g22[_g12];
        ++_g12;
        var pa = Reflect.field(a,field);
        var pb = Reflect.field(b,field);
        if(equals_Equal.isFunction(pa)) {
            if(equals_Equal.isNull(pa) != equals_Equal.isNull(pb)) {
                return false;
            }
            continue;
        }
        if(!equals_Equal.equals(pa,pb)) {
            return false;
        }
    }
    return true;
};
var haxe_StackItem = $hxEnums["haxe.StackItem"] = { __ename__ : "haxe.StackItem", __constructs__ : ["CFunction","Module","FilePos","Method","LocalFunction"]
    ,CFunction: {_hx_index:0,__enum__:"haxe.StackItem",toString:$estr}
    ,Module: ($_=function(m) { return {_hx_index:1,m:m,__enum__:"haxe.StackItem",toString:$estr}; },$_.__params__ = ["m"],$_)
    ,FilePos: ($_=function(s,file,line,column) { return {_hx_index:2,s:s,file:file,line:line,column:column,__enum__:"haxe.StackItem",toString:$estr}; },$_.__params__ = ["s","file","line","column"],$_)
    ,Method: ($_=function(classname,method) { return {_hx_index:3,classname:classname,method:method,__enum__:"haxe.StackItem",toString:$estr}; },$_.__params__ = ["classname","method"],$_)
    ,LocalFunction: ($_=function(v) { return {_hx_index:4,v:v,__enum__:"haxe.StackItem",toString:$estr}; },$_.__params__ = ["v"],$_)
};
var haxe_CallStack = function() { };
haxe_CallStack.__name__ = "haxe.CallStack";
haxe_CallStack.getStack = function(e) {
    if(e == null) {
        return [];
    }
    var oldValue = Error.prepareStackTrace;
    Error.prepareStackTrace = function(error,callsites) {
        var stack = [];
        var _g = 0;
        while(_g < callsites.length) {
            var site = callsites[_g];
            ++_g;
            if(haxe_CallStack.wrapCallSite != null) {
                site = haxe_CallStack.wrapCallSite(site);
            }
            var method = null;
            var fullName = site.getFunctionName();
            if(fullName != null) {
                var idx = fullName.lastIndexOf(".");
                if(idx >= 0) {
                    var className = HxOverrides.substr(fullName,0,idx);
                    var methodName = HxOverrides.substr(fullName,idx + 1,null);
                    method = haxe_StackItem.Method(className,methodName);
                }
            }
            var fileName = site.getFileName();
            var fileAddr = fileName == null ? -1 : fileName.indexOf("file:");
            if(haxe_CallStack.wrapCallSite != null && fileAddr > 0) {
                fileName = HxOverrides.substr(fileName,fileAddr + 6,null);
            }
            stack.push(haxe_StackItem.FilePos(method,fileName,site.getLineNumber(),site.getColumnNumber()));
        }
        return stack;
    };
    var a = haxe_CallStack.makeStack(e.stack);
    Error.prepareStackTrace = oldValue;
    return a;
};
haxe_CallStack.callStack = function() {
    try {
        throw new Error();
    } catch( e ) {
        haxe_CallStack.lastException = e;
        var e1 = ((e) instanceof js__$Boot_HaxeError) ? e.val : e;
        var a = haxe_CallStack.getStack(e);
        a.shift();
        return a;
    }
};
haxe_CallStack.exceptionStack = function() {
    return haxe_CallStack.getStack(haxe_CallStack.lastException);
};
haxe_CallStack.toString = function(stack) {
    var b = new StringBuf();
    var _g = 0;
    while(_g < stack.length) {
        var s = stack[_g];
        ++_g;
        b.b += "\nCalled from ";
        haxe_CallStack.itemToString(b,s);
    }
    return b.b;
};
haxe_CallStack.itemToString = function(b,s) {
    switch(s._hx_index) {
    case 0:
        b.b += "a C function";
        break;
    case 1:
        var m = s.m;
        b.b += "module ";
        b.b += m == null ? "null" : "" + m;
        break;
    case 2:
        var col = s.column;
        var line = s.line;
        var file = s.file;
        var s1 = s.s;
        if(s1 != null) {
            haxe_CallStack.itemToString(b,s1);
            b.b += " (";
        }
        b.b += file == null ? "null" : "" + file;
        b.b += " line ";
        b.b += line == null ? "null" : "" + line;
        if(col != null) {
            b.b += " column ";
            b.b += col == null ? "null" : "" + col;
        }
        if(s1 != null) {
            b.b += ")";
        }
        break;
    case 3:
        var meth = s.method;
        var cname = s.classname;
        b.b += cname == null ? "null" : "" + cname;
        b.b += ".";
        b.b += meth == null ? "null" : "" + meth;
        break;
    case 4:
        var n = s.v;
        b.b += "local function #";
        b.b += n == null ? "null" : "" + n;
        break;
    }
};
haxe_CallStack.makeStack = function(s) {
    if(s == null) {
        return [];
    } else if(typeof(s) == "string") {
        var stack = s.split("\n");
        if(stack[0] == "Error") {
            stack.shift();
        }
        var m = [];
        var rie10 = new EReg("^   at ([A-Za-z0-9_. ]+) \\(([^)]+):([0-9]+):([0-9]+)\\)$","");
        var _g = 0;
        while(_g < stack.length) {
            var line = stack[_g];
            ++_g;
            if(rie10.match(line)) {
                var path = rie10.matched(1).split(".");
                var meth = path.pop();
                var file = rie10.matched(2);
                var line1 = Std.parseInt(rie10.matched(3));
                var column = Std.parseInt(rie10.matched(4));
                m.push(haxe_StackItem.FilePos(meth == "Anonymous function" ? haxe_StackItem.LocalFunction() : meth == "Global code" ? null : haxe_StackItem.Method(path.join("."),meth),file,line1,column));
            } else {
                m.push(haxe_StackItem.Module(StringTools.trim(line)));
            }
        }
        return m;
    } else {
        return s;
    }
};
var haxe_IMap = function() { };
haxe_IMap.__name__ = "haxe.IMap";
haxe_IMap.prototype = {
    get: null
    ,keys: null
    ,__class__: haxe_IMap
};
var haxe_Log = function() { };
haxe_Log.__name__ = "haxe.Log";
haxe_Log.formatOutput = function(v,infos) {
    var str = Std.string(v);
    if(infos == null) {
        return str;
    }
    var pstr = infos.fileName + ":" + infos.lineNumber;
    if(infos != null && infos.customParams != null) {
        var _g = 0;
        var _g1 = infos.customParams;
        while(_g < _g1.length) {
            var v1 = _g1[_g];
            ++_g;
            str += ", " + Std.string(v1);
        }
    }
    return pstr + ": " + str;
};
haxe_Log.trace = function(v,infos) {
    var str = haxe_Log.formatOutput(v,infos);
    if(typeof(console) != "undefined" && console.log != null) {
        console.log(str);
    }
};
var haxe_Timer = function(time_ms) {
    var me = this;
    this.id = setInterval(function() {
        me.run();
    },time_ms);
};
haxe_Timer.__name__ = "haxe.Timer";
haxe_Timer.delay = function(f,time_ms) {
    var t = new haxe_Timer(time_ms);
    t.run = function() {
        t.stop();
        f();
    };
    return t;
};
haxe_Timer.prototype = {
    id: null
    ,stop: function() {
        if(this.id == null) {
            return;
        }
        clearInterval(this.id);
        this.id = null;
    }
    ,run: function() {
    }
    ,__class__: haxe_Timer
};
var haxe_ds_List = function() {
    this.length = 0;
};
haxe_ds_List.__name__ = "haxe.ds.List";
haxe_ds_List.prototype = {
    h: null
    ,q: null
    ,length: null
    ,add: function(item) {
        var x = new haxe_ds__$List_ListNode(item,null);
        if(this.h == null) {
            this.h = x;
        } else {
            this.q.next = x;
        }
        this.q = x;
        this.length++;
    }
    ,remove: function(v) {
        var prev = null;
        var l = this.h;
        while(l != null) {
            if(l.item == v) {
                if(prev == null) {
                    this.h = l.next;
                } else {
                    prev.next = l.next;
                }
                if(this.q == l) {
                    this.q = prev;
                }
                this.length--;
                return true;
            }
            prev = l;
            l = l.next;
        }
        return false;
    }
    ,iterator: function() {
        return new haxe_ds__$List_ListIterator(this.h);
    }
    ,__class__: haxe_ds_List
};
var haxe_ds__$List_ListNode = function(item,next) {
    this.item = item;
    this.next = next;
};
haxe_ds__$List_ListNode.__name__ = "haxe.ds._List.ListNode";
haxe_ds__$List_ListNode.prototype = {
    item: null
    ,next: null
    ,__class__: haxe_ds__$List_ListNode
};
var haxe_ds__$List_ListIterator = function(head) {
    this.head = head;
};
haxe_ds__$List_ListIterator.__name__ = "haxe.ds._List.ListIterator";
haxe_ds__$List_ListIterator.prototype = {
    head: null
    ,hasNext: function() {
        return this.head != null;
    }
    ,next: function() {
        var val = this.head.item;
        this.head = this.head.next;
        return val;
    }
    ,__class__: haxe_ds__$List_ListIterator
};
var haxe_ds_ObjectMap = function() {
    this.h = { __keys__ : { }};
};
haxe_ds_ObjectMap.__name__ = "haxe.ds.ObjectMap";
haxe_ds_ObjectMap.__interfaces__ = [haxe_IMap];
haxe_ds_ObjectMap.prototype = {
    h: null
    ,set: function(key,value) {
        var id = key.__id__ || (key.__id__ = ++haxe_ds_ObjectMap.count);
        this.h[id] = value;
        this.h.__keys__[id] = key;
    }
    ,get: function(key) {
        return this.h[key.__id__];
    }
    ,keys: function() {
        var a = [];
        for( var key in this.h.__keys__ ) {
        if(this.h.hasOwnProperty(key)) {
            a.push(this.h.__keys__[key]);
        }
        }
        return HxOverrides.iter(a);
    }
    ,__class__: haxe_ds_ObjectMap
};
var haxe_ds_StringMap = function() {
    this.h = { };
};
haxe_ds_StringMap.__name__ = "haxe.ds.StringMap";
haxe_ds_StringMap.__interfaces__ = [haxe_IMap];
haxe_ds_StringMap.prototype = {
    h: null
    ,rh: null
    ,get: function(key) {
        if(__map_reserved[key] != null) {
            return this.getReserved(key);
        }
        return this.h[key];
    }
    ,setReserved: function(key,value) {
        if(this.rh == null) {
            this.rh = { };
        }
        this.rh["$" + key] = value;
    }
    ,getReserved: function(key) {
        if(this.rh == null) {
            return null;
        } else {
            return this.rh["$" + key];
        }
    }
    ,existsReserved: function(key) {
        if(this.rh == null) {
            return false;
        }
        return this.rh.hasOwnProperty("$" + key);
    }
    ,keys: function() {
        return HxOverrides.iter(this.arrayKeys());
    }
    ,arrayKeys: function() {
        var out = [];
        for( var key in this.h ) {
        if(this.h.hasOwnProperty(key)) {
            out.push(key);
        }
        }
        if(this.rh != null) {
            for( var key in this.rh ) {
            if(key.charCodeAt(0) == 36) {
                out.push(key.substr(1));
            }
            }
        }
        return out;
    }
    ,__class__: haxe_ds_StringMap
};
var haxe_io_Bytes = function(data) {
    this.length = data.byteLength;
    this.b = new Uint8Array(data);
    this.b.bufferValue = data;
    data.hxBytes = this;
    data.bytes = this.b;
};
haxe_io_Bytes.__name__ = "haxe.io.Bytes";
haxe_io_Bytes.prototype = {
    length: null
    ,b: null
    ,__class__: haxe_io_Bytes
};
var haxe_rtti_Meta = function() { };
haxe_rtti_Meta.__name__ = "haxe.rtti.Meta";
haxe_rtti_Meta.getMeta = function(t) {
    return t.__meta__;
};
haxe_rtti_Meta.getFields = function(t) {
    var meta = haxe_rtti_Meta.getMeta(t);
    if(meta == null || meta.fields == null) {
        return { };
    } else {
        return meta.fields;
    }
};
var hx_doctest_internal_DocTestUtils = function() { };
hx_doctest_internal_DocTestUtils.__name__ = "hx.doctest.internal.DocTestUtils";
hx_doctest_internal_DocTestUtils.exceptionStackAsString = function() {
    var stack = haxe_CallStack.exceptionStack();
    var i = -1;
    var _g = 0;
    _hx_loop1: while(_g < stack.length) {
        var elem = stack[_g];
        ++_g;
        ++i;
        switch(elem._hx_index) {
        case 2:
            var line = elem.line;
            var file = elem.file;
            var elem2 = elem.s;
            if(StringTools.startsWith(file,"hx/doctest")) {
                stack = stack.slice(0,i);
                break _hx_loop1;
            }
            if(elem2 != null) {
                if(elem2 != null) {
                    if(elem2._hx_index == 3) {
                        var method = elem2.method;
                        var classname = elem2.classname;
                        if(StringTools.startsWith(classname,"hx.doctest.")) {
                            stack = stack.slice(0,i);
                            break _hx_loop1;
                        }
                    }
                }
            }
            break;
        case 3:
            var method1 = elem.method;
            var classname1 = elem.classname;
            if(StringTools.startsWith(classname1,"hx.doctest.")) {
                stack = stack.slice(0,i);
                break _hx_loop1;
            }
            break;
        default:
        }
    }
    return "  " + haxe_CallStack.toString(stack).split("\n").join("\n  ") + "\n";
};
hx_doctest_internal_DocTestUtils.equals = function(left,right) {
    if(((left) instanceof Array) && left.__enum__ == null && (((right) instanceof Array) && right.__enum__ == null)) {
        if(left.length == right.length) {
            var _g = 0;
            var _g1 = left.length;
            while(_g < _g1) {
                var i = _g++;
                if(!hx_doctest_internal_DocTestUtils.equals(left[i],right[i])) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }
    if(((right) instanceof EReg)) {
        return (js_Boot.__cast(right , EReg)).match(Std.string(left));
    }
    if(Reflect.isEnumValue(left) && Reflect.isEnumValue(right)) {
        var leftEnum = left;
        var rightEnum = right;
        return Type.enumEq(leftEnum,rightEnum);
    }
    if(Reflect.isObject(left) && Reflect.isObject(right)) {
        var o = left;
        var clsLeft = o == null ? null : js_Boot.getClass(o);
        var clsNameLeft = clsLeft == null ? null : clsLeft.__name__;
        var o1 = right;
        var clsRight = o1 == null ? null : js_Boot.getClass(o1);
        var clsRightName = clsRight == null ? null : clsRight.__name__;
        if(clsNameLeft == null && clsRightName == null) {
            var clsLeftFields = Reflect.fields(left);
            clsLeftFields.sort(function(x,y) {
                if(x > y) {
                    return 1;
                } else if(x == y) {
                    return 0;
                } else {
                    return -1;
                }
            });
            var clsRightFields = Reflect.fields(left);
            clsRightFields.sort(function(x1,y1) {
                if(x1 > y1) {
                    return 1;
                } else if(x1 == y1) {
                    return 0;
                } else {
                    return -1;
                }
            });
            if(hx_doctest_internal_DocTestUtils.equals(clsLeftFields,clsRightFields)) {
                var _g2 = 0;
                while(_g2 < clsLeftFields.length) {
                    var f = clsLeftFields[_g2];
                    ++_g2;
                    if(!hx_doctest_internal_DocTestUtils.equals(Reflect.field(clsLeft,f),Reflect.field(clsRight,f))) {
                        return false;
                    }
                }
                return true;
            }
        }
    }
    return left == right;
};
hx_doctest_internal_DocTestUtils.substringAfter = function(str,sep) {
    var foundAt = str.indexOf(sep);
    if(foundAt == -1) {
        return "";
    }
    return str.substring(foundAt + sep.length);
};
hx_doctest_internal_DocTestUtils.substringAfterLast = function(str,sep) {
    var foundAt = str.lastIndexOf(sep);
    if(foundAt == -1) {
        return "";
    }
    return str.substring(foundAt + sep.length);
};
hx_doctest_internal_DocTestUtils.substringBefore = function(str,sep) {
    var foundAt = str.indexOf(sep);
    if(foundAt == -1) {
        return "";
    }
    return str.substring(0,foundAt);
};
hx_doctest_internal_DocTestUtils.substringBeforeLast = function(str,sep) {
    var foundAt = str.lastIndexOf(sep);
    if(foundAt == -1) {
        return "";
    }
    return str.substring(0,foundAt);
};
var js__$Boot_HaxeError = function(val) {
    Error.call(this);
    this.val = val;
    if(Error.captureStackTrace) {
        Error.captureStackTrace(this,js__$Boot_HaxeError);
    }
};
js__$Boot_HaxeError.__name__ = "js._Boot.HaxeError";
js__$Boot_HaxeError.__super__ = Error;
js__$Boot_HaxeError.prototype = $extend(Error.prototype,{
    val: null
    ,__class__: js__$Boot_HaxeError
});
var js_Boot = function() { };
js_Boot.__name__ = "js.Boot";
js_Boot.getClass = function(o) {
    if(((o) instanceof Array) && o.__enum__ == null) {
        return Array;
    } else {
        var cl = o.__class__;
        if(cl != null) {
            return cl;
        }
        var name = js_Boot.__nativeClassName(o);
        if(name != null) {
            return js_Boot.__resolveNativeClass(name);
        }
        return null;
    }
};
js_Boot.__string_rec = function(o,s) {
    if(o == null) {
        return "null";
    }
    if(s.length >= 5) {
        return "<...>";
    }
    var t = typeof(o);
    if(t == "function" && (o.__name__ || o.__ename__)) {
        t = "object";
    }
    switch(t) {
    case "function":
        return "<function>";
    case "object":
        if(o.__enum__) {
            var e = $hxEnums[o.__enum__];
            var n = e.__constructs__[o._hx_index];
            var con = e[n];
            if(con.__params__) {
                s += "\t";
                var tmp = n + "(";
                var _g = [];
                var _g1 = 0;
                var _g2 = con.__params__;
                while(_g1 < _g2.length) {
                    var p = _g2[_g1];
                    ++_g1;
                    _g.push(js_Boot.__string_rec(o[p],s));
                }
                return tmp + _g.join(",") + ")";
            } else {
                return n;
            }
        }
        if(((o) instanceof Array)) {
            var l = o.length;
            var i;
            var str = "[";
            s += "\t";
            var _g3 = 0;
            var _g11 = l;
            while(_g3 < _g11) {
                var i1 = _g3++;
                str += (i1 > 0 ? "," : "") + js_Boot.__string_rec(o[i1],s);
            }
            str += "]";
            return str;
        }
        var tostr;
        try {
            tostr = o.toString;
        } catch( e1 ) {
            haxe_CallStack.lastException = e1;
            var e2 = ((e1) instanceof js__$Boot_HaxeError) ? e1.val : e1;
            return "???";
        }
        if(tostr != null && tostr != Object.toString && typeof(tostr) == "function") {
            var s2 = o.toString();
            if(s2 != "[object Object]") {
                return s2;
            }
        }
        var k = null;
        var str1 = "{\n";
        s += "\t";
        var hasp = o.hasOwnProperty != null;
        for( var k in o ) {
        if(hasp && !o.hasOwnProperty(k)) {
            continue;
        }
        if(k == "prototype" || k == "__class__" || k == "__super__" || k == "__interfaces__" || k == "__properties__") {
            continue;
        }
        if(str1.length != 2) {
            str1 += ", \n";
        }
        str1 += s + k + " : " + js_Boot.__string_rec(o[k],s);
        }
        s = s.substring(1);
        str1 += "\n" + s + "}";
        return str1;
    case "string":
        return o;
    default:
        return String(o);
    }
};
js_Boot.__interfLoop = function(cc,cl) {
    if(cc == null) {
        return false;
    }
    if(cc == cl) {
        return true;
    }
    var intf = cc.__interfaces__;
    if(intf != null) {
        var _g = 0;
        var _g1 = intf.length;
        while(_g < _g1) {
            var i = _g++;
            var i1 = intf[i];
            if(i1 == cl || js_Boot.__interfLoop(i1,cl)) {
                return true;
            }
        }
    }
    return js_Boot.__interfLoop(cc.__super__,cl);
};
js_Boot.__instanceof = function(o,cl) {
    if(cl == null) {
        return false;
    }
    switch(cl) {
    case Array:
        if(((o) instanceof Array)) {
            return o.__enum__ == null;
        } else {
            return false;
        }
        break;
    case Bool:
        return typeof(o) == "boolean";
    case Dynamic:
        return o != null;
    case Float:
        return typeof(o) == "number";
    case Int:
        if(typeof(o) == "number") {
            return ((o | 0) === o);
        } else {
            return false;
        }
        break;
    case String:
        return typeof(o) == "string";
    default:
        if(o != null) {
            if(typeof(cl) == "function") {
                if(((o) instanceof cl)) {
                    return true;
                }
                if(js_Boot.__interfLoop(js_Boot.getClass(o),cl)) {
                    return true;
                }
            } else if(typeof(cl) == "object" && js_Boot.__isNativeObj(cl)) {
                if(((o) instanceof cl)) {
                    return true;
                }
            }
        } else {
            return false;
        }
        if(cl == Class ? o.__name__ != null : false) {
            return true;
        }
        if(cl == Enum ? o.__ename__ != null : false) {
            return true;
        }
        return $hxEnums[o.__enum__] == cl;
    }
};
js_Boot.__cast = function(o,t) {
    if(o == null || js_Boot.__instanceof(o,t)) {
        return o;
    } else {
        throw new js__$Boot_HaxeError("Cannot cast " + Std.string(o) + " to " + Std.string(t));
    }
};
js_Boot.__nativeClassName = function(o) {
    var name = js_Boot.__toStr.call(o).slice(8,-1);
    if(name == "Object" || name == "Function" || name == "Math" || name == "JSON") {
        return null;
    }
    return name;
};
js_Boot.__isNativeObj = function(o) {
    return js_Boot.__nativeClassName(o) != null;
};
js_Boot.__resolveNativeClass = function(name) {
    return $global[name];
};
var utest_ITest = function() { };
utest_ITest.__name__ = "utest.ITest";
var utest_Test = function() {
};
utest_Test.__name__ = "utest.Test";
utest_Test.__interfaces__ = [utest_ITest];
utest_Test.prototype = {
    __initializeUtest__: function() {
        var init = { tests : [], accessories : { }};
        return init;
    }
    ,__class__: utest_Test
};
var rayTriangle_RayTriangleTests = function() {
    utest_Test.call(this);
};
rayTriangle_RayTriangleTests.__name__ = "rayTriangle.RayTriangleTests";
rayTriangle_RayTriangleTests.main = function() {
    var runner = new utest_Runner();
    runner.addCase(new rayTriangle_RayTriangleTests());
    utest_ui_Report.create(runner);
    runner.run();
};
rayTriangle_RayTriangleTests.__super__ = utest_Test;
rayTriangle_RayTriangleTests.prototype = $extend(utest_Test.prototype,{
    testVec3_1: function() {
        var left;
        try {
            var this1 = new rayTriangle_V3(0.,0.,0.);
            left = this1;
        } catch( ex ) {
            haxe_CallStack.lastException = ex;
            left = "exception: " + Std.string(((ex) instanceof js__$Boot_HaxeError) ? ex.val : ex) + hx_doctest_internal_DocTestUtils.exceptionStackAsString();
        }
        var right;
        try {
            right = { x : 0., y : 0., z : 0.};
        } catch( ex1 ) {
            haxe_CallStack.lastException = ex1;
            right = "exception: " + Std.string(((ex1) instanceof js__$Boot_HaxeError) ? ex1.val : ex1) + hx_doctest_internal_DocTestUtils.exceptionStackAsString();
        }
        if(hx_doctest_internal_DocTestUtils.equals(left,right)) {
            utest_Assert.pass("Vec3.hx:30 [OK] Vec3.zero() == { x: 0., y: 0., z: 0. }",{ lineNumber : 30, fileName : "src/rayTriangle/Vec3.hx", className : "", methodName : ""});
        } else {
            utest_Assert.fail("Vec3.zero() == { x: 0., y: 0., z: 0. } --> Left side '" + Std.string(left) + "' does not equal '" + Std.string(right) + "'.",{ lineNumber : 30, fileName : "src/rayTriangle/Vec3.hx", className : "", methodName : ""});
        }
    }
    ,__initializeUtest__: function() {
        var _gthis = this;
        var init = utest_Test.prototype.__initializeUtest__.call(this);
        init.tests.push({ name : "testVec3_1", execute : function() {
            _gthis.testVec3_1();
            return utest_Async.getResolved();
        }});
        return init;
    }
    ,__class__: rayTriangle_RayTriangleTests
});
var rayTriangle_V3 = function(x,y,z) {
    this.x = x;
    this.y = y;
    this.z = z;
};
rayTriangle_V3.__name__ = "rayTriangle.V3";
rayTriangle_V3.prototype = {
    x: null
    ,y: null
    ,z: null
    ,__class__: rayTriangle_V3
};
var rayTriangle__$Vec3_Vec3_$Impl_$ = {};
rayTriangle__$Vec3_Vec3_$Impl_$.__name__ = "rayTriangle._Vec3.Vec3_Impl_";
rayTriangle__$Vec3_Vec3_$Impl_$._new = function(v) {
    var this1 = v;
    return this1;
};
rayTriangle__$Vec3_Vec3_$Impl_$.zero = function() {
    var this1 = new rayTriangle_V3(0.,0.,0.);
    return this1;
};
rayTriangle__$Vec3_Vec3_$Impl_$.subtract = function(a,b) {
    var this1 = new rayTriangle_V3(a.x - b.x,a.y - b.y,a.z - b.z);
    return this1;
};
rayTriangle__$Vec3_Vec3_$Impl_$.dot = function(this1,v) {
    return this1.x * v.x + this1.y * v.y + this1.z * v.z;
};
rayTriangle__$Vec3_Vec3_$Impl_$.cross = function(a,b) {
    var this1 = new rayTriangle_V3(a.y * b.z - a.z * b.y,a.z * b.x - a.x * b.z,a.x * b.y - a.y * b.x);
    return this1;
};
rayTriangle__$Vec3_Vec3_$Impl_$.$length = function(this1) {
    return Math.sqrt(this1.x * this1.x + this1.y * this1.y + this1.z * this1.z);
};
rayTriangle__$Vec3_Vec3_$Impl_$.normalize = function(this1) {
    var len = Math.sqrt(this1.x * this1.x + this1.y * this1.y + this1.z * this1.z);
    var this2 = new rayTriangle_V3(this1.x / len,this1.y / len,this1.z / len);
    return this2;
};
rayTriangle__$Vec3_Vec3_$Impl_$.toString = function(this1) {
    return "[" + this1.x + ", " + this1.y + ", " + this1.z + "]";
};
var utest_Assert = function() { };
utest_Assert.__name__ = "utest.Assert";
utest_Assert.processResult = function(cond,getMessage,pos) {
    if(utest_Assert.results == null) {
        throw new js__$Boot_HaxeError("Assert at " + pos.fileName + ":" + pos.lineNumber + " out of context. Most likely you are trying to assert after a test timeout.");
    }
    if(cond) {
        utest_Assert.results.add(utest_Assertation.Success(pos));
    } else {
        utest_Assert.results.add(utest_Assertation.Failure(getMessage(),pos));
    }
};
utest_Assert.isTrue = function(cond,msg,pos) {
    if(utest_Assert.results == null) {
        throw new js__$Boot_HaxeError("Assert at " + pos.fileName + ":" + pos.lineNumber + " out of context. Most likely you are trying to assert after a test timeout.");
    }
    if(cond) {
        utest_Assert.results.add(utest_Assertation.Success(pos));
    } else {
        utest_Assert.results.add(utest_Assertation.Failure(msg != null ? msg : "expected true",pos));
    }
};
utest_Assert.isFalse = function(value,msg,pos) {
    if(utest_Assert.results == null) {
        throw new js__$Boot_HaxeError("Assert at " + pos.fileName + ":" + pos.lineNumber + " out of context. Most likely you are trying to assert after a test timeout.");
    }
    if(value == false) {
        utest_Assert.results.add(utest_Assertation.Success(pos));
    } else {
        utest_Assert.results.add(utest_Assertation.Failure(msg != null ? msg : "expected false",pos));
    }
};
utest_Assert.isNull = function(value,msg,pos) {
    if(utest_Assert.results == null) {
        throw new js__$Boot_HaxeError("Assert at " + pos.fileName + ":" + pos.lineNumber + " out of context. Most likely you are trying to assert after a test timeout.");
    }
    if(value == null) {
        utest_Assert.results.add(utest_Assertation.Success(pos));
    } else {
        utest_Assert.results.add(utest_Assertation.Failure(msg != null ? msg : "expected null but it is " + utest_Assert.q(value),pos));
    }
};
utest_Assert.notNull = function(value,msg,pos) {
    if(utest_Assert.results == null) {
        throw new js__$Boot_HaxeError("Assert at " + pos.fileName + ":" + pos.lineNumber + " out of context. Most likely you are trying to assert after a test timeout.");
    }
    if(value != null) {
        utest_Assert.results.add(utest_Assertation.Success(pos));
    } else {
        utest_Assert.results.add(utest_Assertation.Failure(msg != null ? msg : "expected not null",pos));
    }
};
utest_Assert.is = function(value,type,msg,pos) {
    if(utest_Assert.results == null) {
        throw new js__$Boot_HaxeError("Assert at " + pos.fileName + ":" + pos.lineNumber + " out of context. Most likely you are trying to assert after a test timeout.");
    }
    if(js_Boot.__instanceof(value,type)) {
        utest_Assert.results.add(utest_Assertation.Success(pos));
    } else {
        utest_Assert.results.add(utest_Assertation.Failure(msg != null ? msg : "expected type " + utest_Assert.typeToString(type) + " but it is " + utest_Assert.typeToString(value),pos));
    }
};
utest_Assert.notEquals = function(expected,value,msg,pos) {
    if(utest_Assert.results == null) {
        throw new js__$Boot_HaxeError("Assert at " + pos.fileName + ":" + pos.lineNumber + " out of context. Most likely you are trying to assert after a test timeout.");
    }
    if(expected != value) {
        utest_Assert.results.add(utest_Assertation.Success(pos));
    } else {
        utest_Assert.results.add(utest_Assertation.Failure(msg != null ? msg : "expected " + utest_Assert.q(expected) + " and test value " + utest_Assert.q(value) + " should be different",pos));
    }
};
utest_Assert.equals = function(expected,value,msg,pos) {
    if(utest_Assert.results == null) {
        throw new js__$Boot_HaxeError("Assert at " + pos.fileName + ":" + pos.lineNumber + " out of context. Most likely you are trying to assert after a test timeout.");
    }
    if(expected == value) {
        utest_Assert.results.add(utest_Assertation.Success(pos));
    } else {
        utest_Assert.results.add(utest_Assertation.Failure(msg != null ? msg : "expected " + utest_Assert.q(expected) + " but it is " + utest_Assert.q(value),pos));
    }
};
utest_Assert.match = function(pattern,value,msg,pos) {
    var cond = pattern.match(value);
    if(utest_Assert.results == null) {
        throw new js__$Boot_HaxeError("Assert at " + pos.fileName + ":" + pos.lineNumber + " out of context. Most likely you are trying to assert after a test timeout.");
    }
    if(cond) {
        utest_Assert.results.add(utest_Assertation.Success(pos));
    } else {
        utest_Assert.results.add(utest_Assertation.Failure(msg != null ? msg : "the value " + utest_Assert.q(value) + " does not match the provided pattern",pos));
    }
};
utest_Assert.floatEquals = function(expected,value,approx,msg,pos) {
    var cond = utest_Assert._floatEquals(expected,value,approx);
    if(utest_Assert.results == null) {
        throw new js__$Boot_HaxeError("Assert at " + pos.fileName + ":" + pos.lineNumber + " out of context. Most likely you are trying to assert after a test timeout.");
    }
    if(cond) {
        utest_Assert.results.add(utest_Assertation.Success(pos));
    } else {
        utest_Assert.results.add(utest_Assertation.Failure(msg != null ? msg : "expected " + utest_Assert.q(expected) + " but it is " + utest_Assert.q(value),pos));
    }
};
utest_Assert._floatEquals = function(expected,value,approx) {
    if(isNaN(expected)) {
        return isNaN(value);
    } else if(isNaN(value)) {
        return false;
    } else if(!isFinite(expected) && !isFinite(value)) {
        return expected > 0 == value > 0;
    }
    if(null == approx) {
        approx = 1e-5;
    }
    return Math.abs(value - expected) <= approx;
};
utest_Assert.getTypeName = function(v) {
    var _g = Type["typeof"](v);
    switch(_g._hx_index) {
    case 0:
        return "`null`";
    case 1:
        return "Int";
    case 2:
        return "Float";
    case 3:
        return "Bool";
    case 4:
        return "Object";
    case 5:
        return "function";
    case 6:
        var c = _g.c;
        return c.__name__;
    case 7:
        var e = _g.e;
        return e.__ename__;
    case 8:
        return "`Unknown`";
    }
};
utest_Assert.isIterable = function(v,isAnonym) {
    var fields;
    if(isAnonym) {
        fields = Reflect.fields(v);
    } else {
        var o = v;
        fields = Type.getInstanceFields(o == null ? null : js_Boot.getClass(o));
    }
    if(!Lambda.has(fields,"iterator")) {
        return false;
    }
    return Reflect.isFunction(Reflect.field(v,"iterator"));
};
utest_Assert.isIterator = function(v,isAnonym) {
    var fields;
    if(isAnonym) {
        fields = Reflect.fields(v);
    } else {
        var o = v;
        fields = Type.getInstanceFields(o == null ? null : js_Boot.getClass(o));
    }
    if(!Lambda.has(fields,"next") || !Lambda.has(fields,"hasNext")) {
        return false;
    }
    if(Reflect.isFunction(Reflect.field(v,"next"))) {
        return Reflect.isFunction(Reflect.field(v,"hasNext"));
    } else {
        return false;
    }
};
utest_Assert.sameAs = function(expected,value,status,approx) {
    var texpected = utest_Assert.getTypeName(expected);
    var tvalue = utest_Assert.getTypeName(value);
    status.expectedValue = expected;
    status.actualValue = value;
    if(texpected != tvalue && !(texpected == "Int" && tvalue == "Float" || texpected == "Float" && tvalue == "Int")) {
        status.error = "expected type " + texpected + " but it is " + tvalue + (status.path == "" ? "" : " for field " + status.path);
        return false;
    }
    var _g = Type["typeof"](expected);
    switch(_g._hx_index) {
    case 1:case 2:
        if(!utest_Assert._floatEquals(expected,value,approx)) {
            status.error = "expected " + utest_Assert.q(expected) + " but it is " + utest_Assert.q(value) + (status.path == "" ? "" : " for field " + status.path);
            return false;
        }
        return true;
    case 0:case 3:
        if(expected != value) {
            status.error = "expected " + utest_Assert.q(expected) + " but it is " + utest_Assert.q(value) + (status.path == "" ? "" : " for field " + status.path);
            return false;
        }
        return true;
    case 4:
        if(status.recursive || status.path == "") {
            var tfields = Reflect.fields(value);
            var fields = Reflect.fields(expected);
            var path = status.path;
            var _g1 = 0;
            while(_g1 < fields.length) {
                var field = fields[_g1];
                ++_g1;
                HxOverrides.remove(tfields,field);
                status.path = path == "" ? field : path + "." + field;
                if(!Object.prototype.hasOwnProperty.call(value,field)) {
                    status.error = "expected field " + status.path + " does not exist in " + utest_Assert.q(value);
                    return false;
                }
                var e = Reflect.field(expected,field);
                if(Reflect.isFunction(e)) {
                    continue;
                }
                var v = Reflect.field(value,field);
                if(!utest_Assert.sameAs(e,v,status,approx)) {
                    return false;
                }
            }
            if(tfields.length > 0) {
                status.error = "the tested object has extra field(s) (" + tfields.join(", ") + ") not included in the expected ones";
                return false;
            }
        }
        if(utest_Assert.isIterator(expected,true)) {
            if(!utest_Assert.isIterator(value,true)) {
                status.error = "expected Iterable but it is not " + (status.path == "" ? "" : " for field " + status.path);
                return false;
            }
            if(status.recursive || status.path == "") {
                var evalues = Lambda.array({ iterator : function() {
                    return expected;
                }});
                var vvalues = Lambda.array({ iterator : function() {
                    return value;
                }});
                if(evalues.length != vvalues.length) {
                    status.error = "expected " + evalues.length + " values in Iterator but they are " + vvalues.length + (status.path == "" ? "" : " for field " + status.path);
                    return false;
                }
                var path1 = status.path;
                var _g2 = 0;
                var _g11 = evalues.length;
                while(_g2 < _g11) {
                    var i = _g2++;
                    status.path = path1 == "" ? "iterator[" + i + "]" : path1 + "[" + i + "]";
                    if(!utest_Assert.sameAs(evalues[i],vvalues[i],status,approx)) {
                        status.error = "expected " + utest_Assert.q(status.expectedValue) + " but it is " + utest_Assert.q(status.actualValue) + (status.path == "" ? "" : " for field " + status.path);
                        return false;
                    }
                }
            }
            return true;
        }
        if(utest_Assert.isIterable(expected,true)) {
            if(!utest_Assert.isIterable(value,true)) {
                status.error = "expected Iterator but it is not " + (status.path == "" ? "" : " for field " + status.path);
                return false;
            }
            if(status.recursive || status.path == "") {
                var evalues1 = Lambda.array(expected);
                var vvalues1 = Lambda.array(value);
                if(evalues1.length != vvalues1.length) {
                    status.error = "expected " + evalues1.length + " values in Iterable but they are " + vvalues1.length + (status.path == "" ? "" : " for field " + status.path);
                    return false;
                }
                var path2 = status.path;
                var _g3 = 0;
                var _g12 = evalues1.length;
                while(_g3 < _g12) {
                    var i1 = _g3++;
                    status.path = path2 == "" ? "iterable[" + i1 + "]" : path2 + "[" + i1 + "]";
                    if(!utest_Assert.sameAs(evalues1[i1],vvalues1[i1],status,approx)) {
                        return false;
                    }
                }
            }
            return true;
        }
        return true;
    case 5:
        if(!Reflect.compareMethods(expected,value)) {
            status.error = "expected same function reference" + (status.path == "" ? "" : " for field " + status.path);
            return false;
        }
        return true;
    case 6:
        var c = _g.c;
        var cexpected = c.__name__;
        var o = value;
        var c1 = o == null ? null : js_Boot.getClass(o);
        var cvalue = c1.__name__;
        if(cexpected != cvalue) {
            status.error = "expected instance of " + utest_Assert.q(cexpected) + " but it is " + utest_Assert.q(cvalue) + (status.path == "" ? "" : " for field " + status.path);
            return false;
        }
        if(typeof(expected) == "string") {
            if(expected == value) {
                return true;
            } else {
                status.error = "expected string '" + Std.string(expected) + "' but it is '" + Std.string(value) + "'";
                return false;
            }
        }
        if(((expected) instanceof Array) && expected.__enum__ == null) {
            if(status.recursive || status.path == "") {
                if(expected.length != value.length) {
                    status.error = "expected " + Std.string(expected.length) + " elements but they are " + Std.string(value.length) + (status.path == "" ? "" : " for field " + status.path);
                    return false;
                }
                var path3 = status.path;
                var _g4 = 0;
                var _g13 = expected.length;
                while(_g4 < _g13) {
                    var i2 = _g4++;
                    status.path = path3 == "" ? "array[" + i2 + "]" : path3 + "[" + i2 + "]";
                    if(!utest_Assert.sameAs(expected[i2],value[i2],status,approx)) {
                        status.error = "expected array element at [" + i2 + "] to have " + utest_Assert.q(status.expectedValue) + " but it is " + utest_Assert.q(status.actualValue) + (status.path == "" ? "" : " for field " + status.path);
                        return false;
                    }
                }
            }
            return true;
        }
        if(((expected) instanceof Date)) {
            if(expected.getTime() != value.getTime()) {
                status.error = "expected " + utest_Assert.q(expected) + " but it is " + utest_Assert.q(value) + (status.path == "" ? "" : " for field " + status.path);
                return false;
            }
            return true;
        }
        if(((expected) instanceof haxe_io_Bytes)) {
            if(status.recursive || status.path == "") {
                var ebytes = expected;
                var vbytes = value;
                if(ebytes.length != vbytes.length) {
                    return false;
                }
                var _g5 = 0;
                var _g14 = ebytes.length;
                while(_g5 < _g14) {
                    var i3 = _g5++;
                    if(ebytes.b[i3] != vbytes.b[i3]) {
                        status.error = "expected byte " + ebytes.b[i3] + " but it is " + vbytes.b[i3] + (status.path == "" ? "" : " for field " + status.path);
                        return false;
                    }
                }
            }
            return true;
        }
        if(js_Boot.__instanceof(expected,haxe_IMap)) {
            if(status.recursive || status.path == "") {
                var map = js_Boot.__cast(expected , haxe_IMap);
                var vmap = js_Boot.__cast(value , haxe_IMap);
                var _g6 = [];
                var k = map.keys();
                while(k.hasNext()) {
                    var k1 = k.next();
                    _g6.push(k1);
                }
                var keys = _g6;
                var _g15 = [];
                var k2 = vmap.keys();
                while(k2.hasNext()) {
                    var k3 = k2.next();
                    _g15.push(k3);
                }
                var vkeys = _g15;
                if(keys.length != vkeys.length) {
                    status.error = "expected " + keys.length + " keys but they are " + vkeys.length + (status.path == "" ? "" : " for field " + status.path);
                    return false;
                }
                var path4 = status.path;
                var _g21 = 0;
                while(_g21 < keys.length) {
                    var key = keys[_g21];
                    ++_g21;
                    status.path = path4 == "" ? "hash[" + Std.string(key) + "]" : path4 + "[" + Std.string(key) + "]";
                    if(!utest_Assert.sameAs(map.get(key),vmap.get(key),status,approx)) {
                        status.error = "expected " + utest_Assert.q(status.expectedValue) + " but it is " + utest_Assert.q(status.actualValue) + (status.path == "" ? "" : " for field " + status.path);
                        return false;
                    }
                }
            }
            return true;
        }
        if(utest_Assert.isIterator(expected,false)) {
            if(status.recursive || status.path == "") {
                var evalues2 = Lambda.array({ iterator : function() {
                    return expected;
                }});
                var vvalues2 = Lambda.array({ iterator : function() {
                    return value;
                }});
                if(evalues2.length != vvalues2.length) {
                    status.error = "expected " + evalues2.length + " values in Iterator but they are " + vvalues2.length + (status.path == "" ? "" : " for field " + status.path);
                    return false;
                }
                var path5 = status.path;
                var _g7 = 0;
                var _g16 = evalues2.length;
                while(_g7 < _g16) {
                    var i4 = _g7++;
                    status.path = path5 == "" ? "iterator[" + i4 + "]" : path5 + "[" + i4 + "]";
                    if(!utest_Assert.sameAs(evalues2[i4],vvalues2[i4],status,approx)) {
                        status.error = "expected " + utest_Assert.q(status.expectedValue) + " but it is " + utest_Assert.q(status.actualValue) + (status.path == "" ? "" : " for field " + status.path);
                        return false;
                    }
                }
            }
            return true;
        }
        if(utest_Assert.isIterable(expected,false)) {
            if(status.recursive || status.path == "") {
                var evalues3 = Lambda.array(expected);
                var vvalues3 = Lambda.array(value);
                if(evalues3.length != vvalues3.length) {
                    status.error = "expected " + evalues3.length + " values in Iterable but they are " + vvalues3.length + (status.path == "" ? "" : " for field " + status.path);
                    return false;
                }
                var path6 = status.path;
                var _g8 = 0;
                var _g17 = evalues3.length;
                while(_g8 < _g17) {
                    var i5 = _g8++;
                    status.path = path6 == "" ? "iterable[" + i5 + "]" : path6 + "[" + i5 + "]";
                    if(!utest_Assert.sameAs(evalues3[i5],vvalues3[i5],status,approx)) {
                        return false;
                    }
                }
            }
            return true;
        }
        if(status.recursive || status.path == "") {
            var o1 = expected;
            var fields1 = Type.getInstanceFields(o1 == null ? null : js_Boot.getClass(o1));
            var path7 = status.path;
            var _g9 = 0;
            while(_g9 < fields1.length) {
                var field1 = fields1[_g9];
                ++_g9;
                status.path = path7 == "" ? field1 : path7 + "." + field1;
                var e1 = Reflect.field(expected,field1);
                if(Reflect.isFunction(e1)) {
                    continue;
                }
                var v1 = Reflect.field(value,field1);
                if(!utest_Assert.sameAs(e1,v1,status,approx)) {
                    return false;
                }
            }
        }
        return true;
    case 7:
        var e2 = _g.e;
        var eexpected = e2.__ename__;
        var e3 = Type.getEnum(value);
        var evalue = e3.__ename__;
        if(eexpected != evalue) {
            status.error = "expected enumeration of " + utest_Assert.q(eexpected) + " but it is " + utest_Assert.q(evalue) + (status.path == "" ? "" : " for field " + status.path);
            return false;
        }
        if(status.recursive || status.path == "") {
            if(expected._hx_index != value._hx_index) {
                var e4 = expected;
                var tmp = "expected enum constructor " + utest_Assert.q($hxEnums[e4.__enum__].__constructs__[e4._hx_index]) + " but it is ";
                var e5 = value;
                status.error = tmp + utest_Assert.q($hxEnums[e5.__enum__].__constructs__[e5._hx_index]) + (status.path == "" ? "" : " for field " + status.path);
                return false;
            }
            var eparams = Type.enumParameters(expected);
            var vparams = Type.enumParameters(value);
            var path8 = status.path;
            var _g10 = 0;
            var _g18 = eparams.length;
            while(_g10 < _g18) {
                var i6 = _g10++;
                status.path = path8 == "" ? "enum[" + i6 + "]" : path8 + "[" + i6 + "]";
                if(!utest_Assert.sameAs(eparams[i6],vparams[i6],status,approx)) {
                    status.error = "expected enum param " + utest_Assert.q(expected) + " but it is " + utest_Assert.q(value) + (status.path == "" ? "" : " for field " + status.path) + " with " + status.error;
                    return false;
                }
            }
        }
        return true;
    case 8:
        throw new js__$Boot_HaxeError("Unable to compare two unknown types");
    }
};
utest_Assert.q = function(v) {
    if(typeof(v) == "string") {
        return "\"" + StringTools.replace(v,"\"","\\\"") + "\"";
    } else {
        return Std.string(v);
    }
};
utest_Assert.same = function(expected,value,recursive,msg,approx,pos) {
    if(null == approx) {
        approx = 1e-5;
    }
    var status = { recursive : null == recursive ? true : recursive, path : "", error : null, expectedValue : expected, actualValue : value};
    if(utest_Assert.sameAs(expected,value,status,approx)) {
        utest_Assert.pass(msg,pos);
    } else {
        utest_Assert.fail(msg == null ? status.error : msg,pos);
    }
};
utest_Assert.raises = function(method,type,msgNotThrown,msgWrongType,pos) {
    var name = type != null ? type.__name__ : "Dynamic";
    try {
        method();
        if(null == msgNotThrown) {
            msgNotThrown = "exception of type " + name + " not raised";
        }
        utest_Assert.fail(msgNotThrown,pos);
    } catch( ex ) {
        haxe_CallStack.lastException = ex;
        var ex1 = ((ex) instanceof js__$Boot_HaxeError) ? ex.val : ex;
        if(null == type) {
            utest_Assert.pass(null,pos);
        } else {
            if(null == msgWrongType) {
                msgWrongType = "expected throw of type " + name + " but it is " + Std.string(ex1);
            }
            utest_Assert.isTrue(js_Boot.__instanceof(ex1,type),msgWrongType,pos);
        }
    }
};
utest_Assert.allows = function(possibilities,value,msg,pos) {
    if(Lambda.has(possibilities,value)) {
        utest_Assert.isTrue(true,msg,pos);
    } else {
        utest_Assert.fail(msg == null ? "value " + utest_Assert.q(value) + " not found in the expected possibilities " + Std.string(possibilities) : msg,pos);
    }
};
utest_Assert.contains = function(match,values,msg,pos) {
    if(Lambda.has(values,match)) {
        utest_Assert.isTrue(true,msg,pos);
    } else {
        utest_Assert.fail(msg == null ? "values " + utest_Assert.q(values) + " do not contain " + Std.string(match) : msg,pos);
    }
};
utest_Assert.notContains = function(match,values,msg,pos) {
    if(!Lambda.has(values,match)) {
        utest_Assert.isTrue(true,msg,pos);
    } else {
        utest_Assert.fail(msg == null ? "values " + utest_Assert.q(values) + " do contain " + Std.string(match) : msg,pos);
    }
};
utest_Assert.stringContains = function(match,value,msg,pos) {
    if(value != null && value.indexOf(match) >= 0) {
        utest_Assert.isTrue(true,msg,pos);
    } else {
        utest_Assert.fail(msg == null ? "value " + utest_Assert.q(value) + " does not contain " + utest_Assert.q(match) : msg,pos);
    }
};
utest_Assert.stringSequence = function(sequence,value,msg,pos) {
    if(null == value) {
        utest_Assert.fail(msg == null ? "null argument value" : msg,pos);
        return;
    }
    var p = 0;
    var _g = 0;
    while(_g < sequence.length) {
        var s = sequence[_g];
        ++_g;
        var p2 = value.indexOf(s,p);
        if(p2 < 0) {
            if(msg == null) {
                msg = "expected '" + s + "' after ";
                if(p > 0) {
                    var cut = HxOverrides.substr(value,0,p);
                    if(cut.length > 30) {
                        cut = "..." + HxOverrides.substr(cut,-27,null);
                    }
                    msg += " '" + cut + "'";
                } else {
                    msg += " begin";
                }
            }
            utest_Assert.fail(msg,pos);
            return;
        }
        p = p2 + s.length;
    }
    utest_Assert.isTrue(true,msg,pos);
};
utest_Assert.pass = function(msg,pos) {
    if(msg == null) {
        msg = "pass expected";
    }
    utest_Assert.isTrue(true,msg,pos);
};
utest_Assert.fail = function(msg,pos) {
    if(msg == null) {
        msg = "failure expected";
    }
    utest_Assert.isTrue(false,msg,pos);
};
utest_Assert.warn = function(msg) {
    utest_Assert.results.add(utest_Assertation.Warning(msg));
};
utest_Assert.createAsync = function(f,timeout) {
    return function() {
    };
};
utest_Assert.createEvent = function(f,timeout) {
    return function(e) {
    };
};
utest_Assert.typeToString = function(t) {
    try {
        var o = t;
        var _t = o == null ? null : js_Boot.getClass(o);
        if(_t != null) {
            t = _t;
        }
    } catch( e ) {
        haxe_CallStack.lastException = e;
        var e1 = ((e) instanceof js__$Boot_HaxeError) ? e.val : e;
    }
    try {
        return t.__name__;
    } catch( e2 ) {
        haxe_CallStack.lastException = e2;
        var e3 = ((e2) instanceof js__$Boot_HaxeError) ? e2.val : e2;
    }
    try {
        var _t1 = Type.getEnum(t);
        if(_t1 != null) {
            t = _t1;
        }
    } catch( e4 ) {
        haxe_CallStack.lastException = e4;
        var e5 = ((e4) instanceof js__$Boot_HaxeError) ? e4.val : e4;
    }
    try {
        return t.__ename__;
    } catch( e6 ) {
        haxe_CallStack.lastException = e6;
        var e7 = ((e6) instanceof js__$Boot_HaxeError) ? e6.val : e6;
    }
    try {
        return Std.string(Type["typeof"](t));
    } catch( e8 ) {
        haxe_CallStack.lastException = e8;
        var e9 = ((e8) instanceof js__$Boot_HaxeError) ? e8.val : e8;
    }
    try {
        return Std.string(t);
    } catch( e10 ) {
        haxe_CallStack.lastException = e10;
        var e11 = ((e10) instanceof js__$Boot_HaxeError) ? e10.val : e10;
    }
    return "<unable to retrieve type name>";
};
var utest_Assertation = $hxEnums["utest.Assertation"] = { __ename__ : "utest.Assertation", __constructs__ : ["Success","Failure","Error","SetupError","TeardownError","TimeoutError","AsyncError","Warning","Ignore"]
    ,Success: ($_=function(pos) { return {_hx_index:0,pos:pos,__enum__:"utest.Assertation",toString:$estr}; },$_.__params__ = ["pos"],$_)
    ,Failure: ($_=function(msg,pos) { return {_hx_index:1,msg:msg,pos:pos,__enum__:"utest.Assertation",toString:$estr}; },$_.__params__ = ["msg","pos"],$_)
    ,Error: ($_=function(e,stack) { return {_hx_index:2,e:e,stack:stack,__enum__:"utest.Assertation",toString:$estr}; },$_.__params__ = ["e","stack"],$_)
    ,SetupError: ($_=function(e,stack) { return {_hx_index:3,e:e,stack:stack,__enum__:"utest.Assertation",toString:$estr}; },$_.__params__ = ["e","stack"],$_)
    ,TeardownError: ($_=function(e,stack) { return {_hx_index:4,e:e,stack:stack,__enum__:"utest.Assertation",toString:$estr}; },$_.__params__ = ["e","stack"],$_)
    ,TimeoutError: ($_=function(missedAsyncs,stack) { return {_hx_index:5,missedAsyncs:missedAsyncs,stack:stack,__enum__:"utest.Assertation",toString:$estr}; },$_.__params__ = ["missedAsyncs","stack"],$_)
    ,AsyncError: ($_=function(e,stack) { return {_hx_index:6,e:e,stack:stack,__enum__:"utest.Assertation",toString:$estr}; },$_.__params__ = ["e","stack"],$_)
    ,Warning: ($_=function(msg) { return {_hx_index:7,msg:msg,__enum__:"utest.Assertation",toString:$estr}; },$_.__params__ = ["msg"],$_)
    ,Ignore: ($_=function(reason) { return {_hx_index:8,reason:reason,__enum__:"utest.Assertation",toString:$estr}; },$_.__params__ = ["reason"],$_)
};
var utest_Async = function(timeoutMs) {
    if(timeoutMs == null) {
        timeoutMs = 250;
    }
    this.callbacks = [];
    this.timedOut = false;
    this.resolved = false;
    this.startTime = Date.now() / 1000;
    this.timer = haxe_Timer.delay($bind(this,this.setTimedOutState),timeoutMs);
};
utest_Async.__name__ = "utest.Async";
utest_Async.getResolved = function() {
    if(utest_Async.resolvedInstance == null) {
        utest_Async.resolvedInstance = new utest_Async();
        utest_Async.resolvedInstance.done({ fileName : "utest/Async.hx", lineNumber : 28, className : "utest.Async", methodName : "getResolved"});
    }
    return utest_Async.resolvedInstance;
};
utest_Async.prototype = {
    resolved: null
    ,timedOut: null
    ,callbacks: null
    ,startTime: null
    ,timer: null
    ,done: function(pos) {
        if(this.resolved) {
            if(this.timedOut) {
                throw new js__$Boot_HaxeError("Cannot done() at " + pos.fileName + ":" + pos.lineNumber + " because async is timed out.");
            } else {
                throw new js__$Boot_HaxeError("Cannot done() at " + pos.fileName + ":" + pos.lineNumber + " because async is done already.");
            }
        }
        this.resolved = true;
        var _g = 0;
        var _g1 = this.callbacks;
        while(_g < _g1.length) {
            var cb = _g1[_g];
            ++_g;
            cb();
        }
    }
    ,setTimeout: function(timeoutMs,pos) {
        if(this.resolved) {
            throw new js__$Boot_HaxeError("Cannot setTimeout(" + timeoutMs + ") at " + pos.fileName + ":" + pos.lineNumber + " because async is done.");
        }
        if(this.timedOut) {
            throw new js__$Boot_HaxeError("Cannot setTimeout(" + timeoutMs + ") at " + pos.fileName + ":" + pos.lineNumber + " because async is timed out.");
        }
        this.timer.stop();
        var delay = timeoutMs - Math.round(1000 * (Date.now() / 1000 - this.startTime));
        this.timer = haxe_Timer.delay($bind(this,this.setTimedOutState),delay);
    }
    ,then: function(cb) {
        if(this.resolved) {
            cb();
        } else {
            this.callbacks.push(cb);
        }
    }
    ,setTimedOutState: function() {
        if(this.resolved) {
            return;
        }
        this.timedOut = true;
        this.done({ fileName : "utest/Async.hx", lineNumber : 78, className : "utest.Async", methodName : "setTimedOutState"});
    }
    ,__class__: utest_Async
};
var utest__$Dispatcher_EventException = $hxEnums["utest._Dispatcher.EventException"] = { __ename__ : "utest._Dispatcher.EventException", __constructs__ : ["StopPropagation"]
    ,StopPropagation: {_hx_index:0,__enum__:"utest._Dispatcher.EventException",toString:$estr}
};
var utest_Dispatcher = function() {
    this.handlers = [];
};
utest_Dispatcher.__name__ = "utest.Dispatcher";
utest_Dispatcher.stop = function() {
    throw new js__$Boot_HaxeError(utest__$Dispatcher_EventException.StopPropagation);
};
utest_Dispatcher.prototype = {
    handlers: null
    ,add: function(h) {
        this.handlers.push(h);
        return h;
    }
    ,remove: function(h) {
        var _g = 0;
        var _g1 = this.handlers.length;
        while(_g < _g1) {
            var i = _g++;
            if(Reflect.compareMethods(this.handlers[i],h)) {
                return this.handlers.splice(i,1)[0];
            }
        }
        return null;
    }
    ,clear: function() {
        this.handlers = [];
    }
    ,dispatch: function(e) {
        try {
            var list = this.handlers.slice();
            var _g = 0;
            while(_g < list.length) {
                var l = list[_g];
                ++_g;
                l(e);
            }
            return true;
        } catch( exc ) {
            haxe_CallStack.lastException = exc;
            var exc1 = ((exc) instanceof js__$Boot_HaxeError) ? exc.val : exc;
            if(js_Boot.__instanceof(exc1,utest__$Dispatcher_EventException)) {
                var exc2 = exc1;
                return false;
            } else {
                throw exc;
            }
        }
    }
    ,has: function() {
        return this.handlers.length > 0;
    }
    ,__class__: utest_Dispatcher
};
var utest_Notifier = function() {
    this.handlers = [];
};
utest_Notifier.__name__ = "utest.Notifier";
utest_Notifier.stop = function() {
    throw new js__$Boot_HaxeError(utest__$Dispatcher_EventException.StopPropagation);
};
utest_Notifier.prototype = {
    handlers: null
    ,add: function(h) {
        this.handlers.push(h);
        return h;
    }
    ,remove: function(h) {
        var _g = 0;
        var _g1 = this.handlers.length;
        while(_g < _g1) {
            var i = _g++;
            if(Reflect.compareMethods(this.handlers[i],h)) {
                return this.handlers.splice(i,1)[0];
            }
        }
        return null;
    }
    ,clear: function() {
        this.handlers = [];
    }
    ,dispatch: function() {
        try {
            var list = this.handlers.slice();
            var _g = 0;
            while(_g < list.length) {
                var l = list[_g];
                ++_g;
                l();
            }
            return true;
        } catch( exc ) {
            haxe_CallStack.lastException = exc;
            var exc1 = ((exc) instanceof js__$Boot_HaxeError) ? exc.val : exc;
            if(js_Boot.__instanceof(exc1,utest__$Dispatcher_EventException)) {
                var exc2 = exc1;
                return false;
            } else {
                throw exc;
            }
        }
    }
    ,has: function() {
        return this.handlers.length > 0;
    }
    ,__class__: utest_Notifier
};
var utest_TestHandler = function(fixture) {
    this.wasBound = false;
    this.finished = false;
    if(fixture == null) {
        throw new js__$Boot_HaxeError("fixture argument is null");
    }
    this.fixture = fixture;
    this.results = new haxe_ds_List();
    this.asyncStack = new haxe_ds_List();
    this.onTested = new utest_Dispatcher();
    this.onTimeout = new utest_Dispatcher();
    this.onComplete = new utest_Dispatcher();
    this.onPrecheck = new utest_Dispatcher();
    if(fixture.ignoringInfo != null) {
        this.results.add(utest_Assertation.Ignore(fixture.ignoringInfo));
    }
};
utest_TestHandler.__name__ = "utest.TestHandler";
utest_TestHandler.exceptionStack = function(pops) {
    if(pops == null) {
        pops = 2;
    }
    var stack = haxe_CallStack.exceptionStack();
    while(pops-- > 0) stack.pop();
    return stack;
};
utest_TestHandler.prototype = {
    results: null
    ,fixture: null
    ,finished: null
    ,asyncStack: null
    ,onTested: null
    ,onTimeout: null
    ,onComplete: null
    ,onPrecheck: null
    ,precheck: null
    ,wasBound: null
    ,execute: function() {
        var _gthis = this;
        if(this.fixture.ignoringInfo != null) {
            this.executeFinally();
            return;
        }
        var isSync = true;
        var expectingAsync = true;
        var run = function() {
            if(isSync) {
                expectingAsync = false;
                return;
            }
            _gthis.executeFixtureMethod();
            _gthis.executeFinally();
        };
        try {
            this.executeMethod(this.fixture.setup);
            this.executeAsyncMethod(this.fixture.setupAsync,run);
            if(!expectingAsync) {
                this.executeFixtureMethod();
            }
        } catch( e ) {
            haxe_CallStack.lastException = e;
            this.results.add(utest_Assertation.SetupError(((e) instanceof js__$Boot_HaxeError) ? e.val : e,utest_TestHandler.exceptionStack()));
        }
        isSync = false;
        if(!expectingAsync) {
            this.executeFinally();
        }
    }
    ,executeFixtureMethod: function() {
        try {
            this.executeMethod(this.fixture.method);
        } catch( e ) {
            haxe_CallStack.lastException = e;
            this.results.add(utest_Assertation.Error(((e) instanceof js__$Boot_HaxeError) ? e.val : e,utest_TestHandler.exceptionStack()));
        }
    }
    ,executeFinally: function() {
        this.onPrecheck.dispatch(this);
        this.checkTested();
    }
    ,checkTested: function() {
        if(this.expiration == null || this.asyncStack.length == 0) {
            this.tested();
        } else if(Date.now() / 1000 > this.expiration) {
            this.timeout();
        } else {
            haxe_Timer.delay($bind(this,this.checkTested),10);
        }
    }
    ,expiration: null
    ,setTimeout: function(timeout) {
        var newExpire = Date.now() / 1000 + timeout / 1000;
        this.expiration = this.expiration == null ? newExpire : newExpire > this.expiration ? newExpire : this.expiration;
    }
    ,bindHandler: function() {
        if(this.wasBound) {
            return;
        }
        utest_Assert.results = this.results;
        utest_Assert.createAsync = $bind(this,this.addAsync);
        utest_Assert.createEvent = $bind(this,this.addEvent);
        this.wasBound = true;
    }
    ,unbindHandler: function() {
        if(!this.wasBound) {
            return;
        }
        utest_Assert.results = null;
        utest_Assert.createAsync = function(f,t) {
            return function() {
            };
        };
        utest_Assert.createEvent = function(f1,t1) {
            return function(e) {
            };
        };
        this.wasBound = false;
    }
    ,addAsync: function(f,timeout) {
        if(timeout == null) {
            timeout = 250;
        }
        if(null == f) {
            f = function() {
            };
        }
        this.asyncStack.add(f);
        var handler = this;
        this.setTimeout(timeout);
        return function() {
            if(!handler.asyncStack.remove(f)) {
                handler.results.add(utest_Assertation.AsyncError("async function already executed",[]));
                return;
            }
            try {
                handler.bindHandler();
                f();
            } catch( e ) {
                haxe_CallStack.lastException = e;
                handler.results.add(utest_Assertation.AsyncError(((e) instanceof js__$Boot_HaxeError) ? e.val : e,utest_TestHandler.exceptionStack(0)));
            }
        };
    }
    ,addEvent: function(f,timeout) {
        if(timeout == null) {
            timeout = 250;
        }
        this.asyncStack.add(f);
        var handler = this;
        this.setTimeout(timeout);
        return function(e) {
            if(!handler.asyncStack.remove(f)) {
                handler.results.add(utest_Assertation.AsyncError("event already executed",[]));
                return;
            }
            try {
                handler.bindHandler();
                f(e);
            } catch( e1 ) {
                haxe_CallStack.lastException = e1;
                handler.results.add(utest_Assertation.AsyncError(((e1) instanceof js__$Boot_HaxeError) ? e1.val : e1,utest_TestHandler.exceptionStack(0)));
            }
        };
    }
    ,executeMethod: function(name) {
        if(name == null) {
            return;
        }
        this.bindHandler();
        Reflect.field(this.fixture.target,name).apply(this.fixture.target,[]);
    }
    ,executeAsyncMethod: function(name,done) {
        if(name == null) {
            done();
            return;
        }
        this.bindHandler();
        Reflect.field(this.fixture.target,name).apply(this.fixture.target,[done]);
    }
    ,tested: function() {
        if(this.results.length == 0) {
            this.results.add(utest_Assertation.Warning("no assertions"));
        }
        this.onTested.dispatch(this);
        this.completed();
    }
    ,timeout: function() {
        this.results.add(utest_Assertation.TimeoutError(this.asyncStack.length,[]));
        this.onTimeout.dispatch(this);
        this.completed();
    }
    ,completed: function() {
        var _gthis = this;
        if(this.fixture.ignoringInfo != null) {
            this.completedFinally();
            return;
        }
        var isSync = true;
        var expectingAsync = true;
        var complete = function() {
            if(isSync) {
                expectingAsync = false;
                return;
            }
            _gthis.completedFinally();
        };
        try {
            this.executeMethod(this.fixture.teardown);
            this.executeAsyncMethod(this.fixture.teardownAsync,complete);
        } catch( e ) {
            haxe_CallStack.lastException = e;
            this.results.add(utest_Assertation.TeardownError(((e) instanceof js__$Boot_HaxeError) ? e.val : e,utest_TestHandler.exceptionStack(2)));
        }
        isSync = false;
        if(!expectingAsync) {
            this.completedFinally();
        }
    }
    ,completedFinally: function() {
        this.finished = true;
        this.unbindHandler();
        this.onComplete.dispatch(this);
    }
    ,__class__: utest_TestHandler
};
var utest_ITestHandler = function(fixture) {
    utest_TestHandler.call(this,fixture);
    if(!fixture.isITest) {
        throw new js__$Boot_HaxeError("Invalid fixture type for utest.ITestHandler");
    }
    this.testCase = js_Boot.__cast(fixture.target , utest_ITest);
    this.test = fixture.test;
    if(this.test == null) {
        throw new js__$Boot_HaxeError("Fixture is missing test data");
    }
};
utest_ITestHandler.__name__ = "utest.ITestHandler";
utest_ITestHandler.__super__ = utest_TestHandler;
utest_ITestHandler.prototype = $extend(utest_TestHandler.prototype,{
    testCase: null
    ,test: null
    ,setupAsync: null
    ,testAsync: null
    ,teardownAsync: null
    ,execute: function() {
        if(this.fixture.ignoringInfo != null) {
            this.executeFinally();
            return;
        }
        this.bindHandler();
        this.runSetup();
    }
    ,runSetup: function() {
        try {
            this.setupAsync = this.fixture.setupMethod();
        } catch( e ) {
            haxe_CallStack.lastException = e;
            this.results.add(utest_Assertation.SetupError(((e) instanceof js__$Boot_HaxeError) ? e.val : e,haxe_CallStack.exceptionStack()));
            this.completedFinally();
            return;
        }
        this.setupAsync.then($bind(this,this.checkSetup));
    }
    ,checkSetup: function() {
        if(this.setupAsync.timedOut) {
            this.results.add(utest_Assertation.SetupError("Setup timeout",[]));
            this.completedFinally();
        } else {
            this.runTest();
        }
    }
    ,runTest: function() {
        try {
            this.testAsync = this.test.execute();
        } catch( e ) {
            haxe_CallStack.lastException = e;
            this.results.add(utest_Assertation.Error(((e) instanceof js__$Boot_HaxeError) ? e.val : e,haxe_CallStack.exceptionStack()));
            this.runTeardown();
            return;
        }
        this.testAsync.then($bind(this,this.checkTest));
    }
    ,checkTest: function() {
        this.onPrecheck.dispatch(this);
        if(this.testAsync.timedOut) {
            this.results.add(utest_Assertation.TimeoutError(1,[]));
            this.onTimeout.dispatch(this);
        } else if(this.testAsync.resolved) {
            if(this.results.length == 0) {
                this.results.add(utest_Assertation.Warning("no assertions"));
            }
            this.onTested.dispatch(this);
        } else {
            throw new js__$Boot_HaxeError("Unexpected test state");
        }
        this.runTeardown();
    }
    ,runTeardown: function() {
        try {
            this.teardownAsync = this.fixture.teardownMethod();
        } catch( e ) {
            haxe_CallStack.lastException = e;
            this.results.add(utest_Assertation.TeardownError(((e) instanceof js__$Boot_HaxeError) ? e.val : e,haxe_CallStack.exceptionStack()));
            this.completedFinally();
            return;
        }
        this.teardownAsync.then($bind(this,this.checkTeardown));
    }
    ,checkTeardown: function() {
        if(this.teardownAsync.timedOut) {
            this.results.add(utest_Assertation.TeardownError("Teardown timeout",[]));
        }
        this.completedFinally();
    }
    ,bindHandler: function() {
        if(this.wasBound) {
            return;
        }
        utest_Assert.results = this.results;
        var msg = " is not allowed in tests extending utest.ITest. Add `async:utest.Async` argument to the test method instead.";
        utest_Assert.createAsync = function(f,t) {
            throw new js__$Boot_HaxeError("Assert.createAsync() " + msg);
        };
        utest_Assert.createEvent = function(f1,t1) {
            throw new js__$Boot_HaxeError("Assert.createEvent() " + msg);
        };
        this.wasBound = true;
    }
    ,__class__: utest_ITestHandler
});
var utest__$IgnoredFixture_IgnoredFixture_$Impl_$ = {};
utest__$IgnoredFixture_IgnoredFixture_$Impl_$.__name__ = "utest._IgnoredFixture.IgnoredFixture_Impl_";
utest__$IgnoredFixture_IgnoredFixture_$Impl_$.__properties__ = {get_ignoreReason:"get_ignoreReason",get_isIgnored:"get_isIgnored"};
utest__$IgnoredFixture_IgnoredFixture_$Impl_$.NotIgnored = function() {
    var this1 = null;
    return this1;
};
utest__$IgnoredFixture_IgnoredFixture_$Impl_$.Ignored = function(reason) {
    var this1 = reason != null ? reason : "";
    return this1;
};
utest__$IgnoredFixture_IgnoredFixture_$Impl_$._new = function(reason) {
    var this1 = reason;
    return this1;
};
utest__$IgnoredFixture_IgnoredFixture_$Impl_$.get_isIgnored = function(this1) {
    return this1 != null;
};
utest__$IgnoredFixture_IgnoredFixture_$Impl_$.get_ignoreReason = function(this1) {
    return this1;
};
var utest_Runner = function() {
    this.executedFixtures = 0;
    this.pos = 0;
    this.complete = false;
    this.globalPattern = null;
    this.iTestFixtures = new haxe_ds_ObjectMap();
    this.fixtures = [];
    this.onProgress = new utest_Dispatcher();
    this.onStart = new utest_Dispatcher();
    this.onComplete = new utest_Dispatcher();
    this.onPrecheck = new utest_Dispatcher();
    this.onTestStart = new utest_Dispatcher();
    this.onTestComplete = new utest_Dispatcher();
    this.length = 0;
    var envPattern = null;
    if(envPattern != null) {
        this.globalPattern = new EReg(envPattern,"");
    }
};
utest_Runner.__name__ = "utest.Runner";
utest_Runner.prototype = {
    fixtures: null
    ,iTestFixtures: null
    ,onProgress: null
    ,onStart: null
    ,onComplete: null
    ,onPrecheck: null
    ,onTestStart: null
    ,onTestComplete: null
    ,length: null
    ,globalPattern: null
    ,complete: null
    ,addCase: function(test,setup,teardown,prefix,pattern,setupAsync,teardownAsync) {
        if(teardownAsync == null) {
            teardownAsync = "teardownAsync";
        }
        if(setupAsync == null) {
            setupAsync = "setupAsync";
        }
        if(prefix == null) {
            prefix = "test";
        }
        if(teardown == null) {
            teardown = "teardown";
        }
        if(setup == null) {
            setup = "setup";
        }
        if(js_Boot.__instanceof(test,utest_ITest)) {
            this.addITest(test,pattern);
        } else {
            this.addCaseOld(test,setup,teardown,prefix,pattern,setupAsync,teardownAsync);
        }
    }
    ,addITest: function(testCase,pattern) {
        if(this.iTestFixtures.h.__keys__[testCase.__id__] != null) {
            throw new js__$Boot_HaxeError("Cannot add the same test twice.");
        }
        var fixtures = [];
        var init = testCase.__initializeUtest__();
        var _g = 0;
        var _g1 = init.tests;
        while(_g < _g1.length) {
            var test = _g1[_g];
            ++_g;
            if(!this.isTestFixtureName(test.name,["test","spec"],pattern,this.globalPattern)) {
                continue;
            }
            var fixture = utest_TestFixture.ofData(testCase,test,init.accessories);
            this.addFixture(fixture);
            fixtures.push(fixture);
        }
        this.iTestFixtures.set(testCase,{ setupClass : utest_utils_AccessoriesUtils.getSetupClass(init.accessories), fixtures : fixtures, teardownClass : utest_utils_AccessoriesUtils.getTeardownClass(init.accessories)});
    }
    ,addCaseOld: function(test,setup,teardown,prefix,pattern,setupAsync,teardownAsync) {
        if(teardownAsync == null) {
            teardownAsync = "teardownAsync";
        }
        if(setupAsync == null) {
            setupAsync = "setupAsync";
        }
        if(prefix == null) {
            prefix = "test";
        }
        if(teardown == null) {
            teardown = "teardown";
        }
        if(setup == null) {
            setup = "setup";
        }
        if(!Reflect.isObject(test)) {
            throw new js__$Boot_HaxeError("can't add a null object as a test case");
        }
        if(!this.isMethod(test,setup)) {
            setup = null;
        }
        if(!this.isMethod(test,setupAsync)) {
            setupAsync = null;
        }
        if(!this.isMethod(test,teardown)) {
            teardown = null;
        }
        if(!this.isMethod(test,teardownAsync)) {
            teardownAsync = null;
        }
        var o = test;
        var fields = Type.getInstanceFields(o == null ? null : js_Boot.getClass(o));
        var _g = 0;
        while(_g < fields.length) {
            var field = fields[_g];
            ++_g;
            if(!this.isMethod(test,field)) {
                continue;
            }
            if(!this.isTestFixtureName(field,[prefix],pattern,this.globalPattern)) {
                continue;
            }
            this.addFixture(new utest_TestFixture(test,field,setup,teardown,setupAsync,teardownAsync));
        }
    }
    ,isTestFixtureName: function(name,prefixes,pattern,globalPattern) {
        if(pattern == null && globalPattern == null) {
            var _g = 0;
            while(_g < prefixes.length) {
                var prefix = prefixes[_g];
                ++_g;
                if(StringTools.startsWith(name,prefix)) {
                    return true;
                }
            }
            return false;
        }
        if(pattern == null) {
            pattern = globalPattern;
        }
        return pattern.match(name);
    }
    ,addFixture: function(fixture) {
        this.fixtures.push(fixture);
        this.length++;
    }
    ,getFixture: function(index) {
        return this.fixtures[index];
    }
    ,isMethod: function(test,name) {
        try {
            return Reflect.isFunction(Reflect.field(test,name));
        } catch( e ) {
            haxe_CallStack.lastException = e;
            var e1 = ((e) instanceof js__$Boot_HaxeError) ? e.val : e;
            return false;
        }
    }
    ,run: function() {
        this.onStart.dispatch(this);
        var iTestRunner = new utest__$Runner_ITestRunner(this);
        iTestRunner.run();
        this.waitForCompletion();
    }
    ,waitForCompletion: function() {
        if(!this.complete) {
            haxe_Timer.delay($bind(this,this.waitForCompletion),100);
        }
    }
    ,pos: null
    ,executedFixtures: null
    ,runNext: function(finishedHandler) {
        var _g = this.pos;
        var _g1 = this.fixtures.length;
        while(_g < _g1) {
            var i = _g++;
            var fixture = this.fixtures[this.pos++];
            if(fixture.isITest) {
                continue;
            }
            var handler = this.runFixture(fixture);
            if(!handler.finished) {
                handler.onComplete.add($bind(this,this.runNext));
                return;
            }
        }
        this.complete = true;
        this.onComplete.dispatch(this);
    }
    ,runFixture: function(fixture) {
        var handler = fixture.isITest ? new utest_ITestHandler(fixture) : new utest_TestHandler(fixture);
        handler.onComplete.add($bind(this,this.testComplete));
        handler.onPrecheck.add(($_=this.onPrecheck,$bind($_,$_.dispatch)));
        this.onTestStart.dispatch(handler);
        handler.execute();
        return handler;
    }
    ,testComplete: function(h) {
        ++this.executedFixtures;
        this.onTestComplete.dispatch(h);
        this.onProgress.dispatch({ result : utest_TestResult.ofHandler(h), done : this.executedFixtures, totals : this.length});
    }
    ,__class__: utest_Runner
};
var utest__$Runner_ITestRunner = function(runner) {
    this.runner = runner;
};
utest__$Runner_ITestRunner.__name__ = "utest._Runner.ITestRunner";
utest__$Runner_ITestRunner.prototype = {
    runner: null
    ,cases: null
    ,currentCase: null
    ,currentCaseFixtures: null
    ,teardownClass: null
    ,setupAsync: null
    ,teardownAsync: null
    ,run: function() {
        this.cases = this.runner.iTestFixtures.keys();
        this.runCases();
    }
    ,runCases: function() {
        while(this.cases.hasNext()) {
            this.currentCase = this.cases.next();
            var data = this.runner.iTestFixtures.h[this.currentCase.__id__];
            this.currentCaseFixtures = data.fixtures;
            this.teardownClass = data.teardownClass;
            try {
                this.setupAsync = data.setupClass();
            } catch( e ) {
                haxe_CallStack.lastException = e;
                this.setupFailed(utest_Assertation.SetupError("setupClass failed: " + Std.string(((e) instanceof js__$Boot_HaxeError) ? e.val : e),haxe_CallStack.exceptionStack()));
                return;
            }
            if(this.setupAsync.resolved) {
                if(!this.runFixtures()) {
                    return;
                }
            } else {
                this.setupAsync.then($bind(this,this.checkSetup));
                return;
            }
        }
        this.runner.runNext();
    }
    ,checkSetup: function() {
        if(this.setupAsync.timedOut) {
            this.setupFailed(utest_Assertation.SetupError("setupClass timeout",[]));
        } else {
            this.runFixtures();
        }
    }
    ,setupFailed: function(assertation) {
        this.runner.executedFixtures += this.currentCaseFixtures.length;
        this.runner.onProgress.dispatch({ totals : this.runner.length, result : utest_TestResult.ofFailedSetupClass(this.currentCase,assertation), done : this.runner.executedFixtures});
        this.runCases();
    }
    ,runFixtures: function(finishedHandler) {
        while(this.currentCaseFixtures.length > 0) {
            var handler = this.runner.runFixture(this.currentCaseFixtures.pop());
            if(!handler.finished) {
                handler.onComplete.add($bind(this,this.runFixtures));
                return false;
            }
        }
        try {
            this.teardownAsync = this.teardownClass();
        } catch( e ) {
            haxe_CallStack.lastException = e;
            this.teardownFailed(utest_Assertation.TeardownError("tearDownClass failed: " + Std.string(((e) instanceof js__$Boot_HaxeError) ? e.val : e),haxe_CallStack.exceptionStack()));
        }
        if(this.teardownAsync.resolved && finishedHandler == null) {
            return true;
        }
        this.teardownAsync.then($bind(this,this.checkTeardown));
        return false;
    }
    ,checkTeardown: function() {
        if(this.teardownAsync.timedOut) {
            this.teardownFailed(utest_Assertation.TeardownError("teardownClass timeout",[]));
        }
        this.runCases();
    }
    ,teardownFailed: function(assertation) {
        this.runner.onProgress.dispatch({ totals : this.runner.length, result : utest_TestResult.ofFailedTeardownClass(this.currentCase,assertation), done : this.runner.executedFixtures});
    }
    ,__class__: utest__$Runner_ITestRunner
};
var utest_AccessoryName = function() { };
utest_AccessoryName.__name__ = "utest.AccessoryName";
var utest_TestFixture = function(target,method,setup,teardown,setupAsync,teardownAsync) {
    this.isITest = false;
    this.target = target;
    this.method = method;
    this.setup = setup;
    this.setupAsync = setupAsync;
    this.teardown = teardown;
    this.teardownAsync = teardownAsync;
    this.ignoringInfo = this.getIgnored();
};
utest_TestFixture.__name__ = "utest.TestFixture";
utest_TestFixture.ofData = function(target,test,accessories) {
    var fixture = new utest_TestFixture(target,test.name);
    fixture.isITest = true;
    fixture.test = test;
    fixture.setupMethod = utest_utils_AccessoriesUtils.getSetup(accessories);
    fixture.teardownMethod = utest_utils_AccessoriesUtils.getTeardown(accessories);
    return fixture;
};
utest_TestFixture.prototype = {
    target: null
    ,method: null
    ,setup: null
    ,setupAsync: null
    ,teardown: null
    ,teardownAsync: null
    ,ignoringInfo: null
    ,isITest: null
    ,test: null
    ,setupMethod: null
    ,teardownMethod: null
    ,checkMethod: function(name,arg) {
        var field = Reflect.field(this.target,name);
        if(field == null) {
            throw new js__$Boot_HaxeError(arg + " function " + name + " is not a field of target");
        }
        if(!Reflect.isFunction(field)) {
            throw new js__$Boot_HaxeError(arg + " function " + name + " is not a function");
        }
    }
    ,getIgnored: function() {
        var o = this.target;
        var metas = haxe_rtti_Meta.getFields(o == null ? null : js_Boot.getClass(o));
        var metasForTestMetas = Reflect.getProperty(metas,this.method);
        if(metasForTestMetas == null || !Object.prototype.hasOwnProperty.call(metasForTestMetas,"Ignored")) {
            return utest__$IgnoredFixture_IgnoredFixture_$Impl_$.NotIgnored();
        }
        var ignoredArgs = Reflect.getProperty(metasForTestMetas,"Ignored");
        if(ignoredArgs == null || ignoredArgs.length == 0 || ignoredArgs[0] == null) {
            return utest__$IgnoredFixture_IgnoredFixture_$Impl_$.Ignored();
        }
        var ignoredReason = Std.string(ignoredArgs[0]);
        return utest__$IgnoredFixture_IgnoredFixture_$Impl_$.Ignored(ignoredReason);
    }
    ,__class__: utest_TestFixture
};
var utest_TestResult = function() {
};
utest_TestResult.__name__ = "utest.TestResult";
utest_TestResult.ofHandler = function(handler) {
    var r = new utest_TestResult();
    var o = handler.fixture.target;
    var c = o == null ? null : js_Boot.getClass(o);
    var path = c.__name__.split(".");
    r.cls = path.pop();
    r.pack = path.join(".");
    r.method = handler.fixture.method;
    r.setup = handler.fixture.setup;
    r.setupAsync = handler.fixture.setupAsync;
    r.teardown = handler.fixture.teardown;
    r.teardownAsync = handler.fixture.teardownAsync;
    r.assertations = handler.results;
    return r;
};
utest_TestResult.ofFailedSetupClass = function(testCase,assertation) {
    var r = new utest_TestResult();
    var c = testCase == null ? null : js_Boot.getClass(testCase);
    var path = c.__name__.split(".");
    r.cls = path.pop();
    r.pack = path.join(".");
    r.method = "setup";
    r.assertations = new haxe_ds_List();
    r.assertations.add(assertation);
    return r;
};
utest_TestResult.ofFailedTeardownClass = function(testCase,assertation) {
    var r = new utest_TestResult();
    var c = testCase == null ? null : js_Boot.getClass(testCase);
    var path = c.__name__.split(".");
    r.cls = path.pop();
    r.pack = path.join(".");
    r.method = "setup";
    r.assertations = new haxe_ds_List();
    r.assertations.add(assertation);
    return r;
};
utest_TestResult.prototype = {
    pack: null
    ,cls: null
    ,method: null
    ,setup: null
    ,setupAsync: null
    ,teardown: null
    ,teardownAsync: null
    ,assertations: null
    ,allOk: function() {
        var _g_head = this.assertations.h;
        while(_g_head != null) {
            var val = _g_head.item;
            _g_head = _g_head.next;
            var l = val;
            if(l._hx_index == 0) {
                break;
            } else {
                return false;
            }
        }
        return true;
    }
    ,__class__: utest_TestResult
};
var utest_ui_Report = function() { };
utest_ui_Report.__name__ = "utest.ui.Report";
utest_ui_Report.create = function(runner,displaySuccessResults,headerDisplayMode) {
    var report;
    if(typeof window != 'undefined') {
        report = new utest_ui_text_HtmlReport(runner,null,true);
    } else {
        report = new utest_ui_text_PrintReport(runner);
    }
    if(null == displaySuccessResults) {
        report.displaySuccessResults = utest_ui_common_SuccessResultsDisplayMode.ShowSuccessResultsWithNoErrors;
    } else {
        report.displaySuccessResults = displaySuccessResults;
    }
    if(null == headerDisplayMode) {
        report.displayHeader = utest_ui_common_HeaderDisplayMode.ShowHeaderWithResults;
    } else {
        report.displayHeader = headerDisplayMode;
    }
    return report;
};
var utest_ui_common_ClassResult = function(className,setupName,teardownName) {
    this.fixtures = new haxe_ds_StringMap();
    this.className = className;
    this.setupName = setupName;
    this.hasSetup = setupName != null;
    this.teardownName = teardownName;
    this.hasTeardown = teardownName != null;
    this.methods = 0;
    this.stats = new utest_ui_common_ResultStats();
};
utest_ui_common_ClassResult.__name__ = "utest.ui.common.ClassResult";
utest_ui_common_ClassResult.prototype = {
    fixtures: null
    ,className: null
    ,setupName: null
    ,teardownName: null
    ,hasSetup: null
    ,hasTeardown: null
    ,methods: null
    ,stats: null
    ,add: function(result) {
        var key = result.methodName;
        var _this = this.fixtures;
        if(__map_reserved[key] != null ? _this.existsReserved(key) : _this.h.hasOwnProperty(key)) {
            throw new js__$Boot_HaxeError("invalid duplicated fixture: " + this.className + "." + result.methodName);
        }
        this.stats.wire(result.stats);
        this.methods++;
        var key1 = result.methodName;
        var _this1 = this.fixtures;
        if(__map_reserved[key1] != null) {
            _this1.setReserved(key1,result);
        } else {
            _this1.h[key1] = result;
        }
    }
    ,get: function(method) {
        var _this = this.fixtures;
        if(__map_reserved[method] != null) {
            return _this.getReserved(method);
        } else {
            return _this.h[method];
        }
    }
    ,exists: function(method) {
        var _this = this.fixtures;
        if(__map_reserved[method] != null) {
            return _this.existsReserved(method);
        } else {
            return _this.h.hasOwnProperty(method);
        }
    }
    ,methodNames: function(errorsHavePriority) {
        if(errorsHavePriority == null) {
            errorsHavePriority = true;
        }
        var names = [];
        var name = this.fixtures.keys();
        while(name.hasNext()) {
            var name1 = name.next();
            names.push(name1);
        }
        if(errorsHavePriority) {
            var me = this;
            names.sort(function(a,b) {
                var as = me.get(a).stats;
                var bs = me.get(b).stats;
                if(as.hasErrors) {
                    if(!bs.hasErrors) {
                        return -1;
                    } else if(as.errors == bs.errors) {
                        return Reflect.compare(a,b);
                    } else {
                        return Reflect.compare(as.errors,bs.errors);
                    }
                } else if(bs.hasErrors) {
                    return 1;
                } else if(as.hasFailures) {
                    if(!bs.hasFailures) {
                        return -1;
                    } else if(as.failures == bs.failures) {
                        return Reflect.compare(a,b);
                    } else {
                        return Reflect.compare(as.failures,bs.failures);
                    }
                } else if(bs.hasFailures) {
                    return 1;
                } else if(as.hasWarnings) {
                    if(!bs.hasWarnings) {
                        return -1;
                    } else if(as.warnings == bs.warnings) {
                        return Reflect.compare(a,b);
                    } else {
                        return Reflect.compare(as.warnings,bs.warnings);
                    }
                } else if(bs.hasWarnings) {
                    return 1;
                } else {
                    return Reflect.compare(a,b);
                }
            });
        } else {
            names.sort(function(a1,b1) {
                return Reflect.compare(a1,b1);
            });
        }
        return names;
    }
    ,__class__: utest_ui_common_ClassResult
};
var utest_ui_common_FixtureResult = function(methodName) {
    this.methodName = methodName;
    this.list = new haxe_ds_List();
    this.hasTestError = false;
    this.hasSetupError = false;
    this.hasTeardownError = false;
    this.hasTimeoutError = false;
    this.hasAsyncError = false;
    this.stats = new utest_ui_common_ResultStats();
};
utest_ui_common_FixtureResult.__name__ = "utest.ui.common.FixtureResult";
utest_ui_common_FixtureResult.prototype = {
    methodName: null
    ,hasTestError: null
    ,hasSetupError: null
    ,hasTeardownError: null
    ,hasTimeoutError: null
    ,hasAsyncError: null
    ,stats: null
    ,list: null
    ,iterator: function() {
        return new haxe_ds__$List_ListIterator(this.list.h);
    }
    ,add: function(assertation) {
        this.list.add(assertation);
        switch(assertation._hx_index) {
        case 0:
            this.stats.addSuccesses(1);
            break;
        case 1:
            this.stats.addFailures(1);
            break;
        case 2:
            this.stats.addErrors(1);
            break;
        case 3:
            this.stats.addErrors(1);
            this.hasSetupError = true;
            break;
        case 4:
            this.stats.addErrors(1);
            this.hasTeardownError = true;
            break;
        case 5:
            this.stats.addErrors(1);
            this.hasTimeoutError = true;
            break;
        case 6:
            this.stats.addErrors(1);
            this.hasAsyncError = true;
            break;
        case 7:
            this.stats.addWarnings(1);
            break;
        case 8:
            this.stats.addIgnores(1);
            break;
        }
    }
    ,__class__: utest_ui_common_FixtureResult
};
var utest_ui_common_HeaderDisplayMode = $hxEnums["utest.ui.common.HeaderDisplayMode"] = { __ename__ : "utest.ui.common.HeaderDisplayMode", __constructs__ : ["AlwaysShowHeader","NeverShowHeader","ShowHeaderWithResults"]
    ,AlwaysShowHeader: {_hx_index:0,__enum__:"utest.ui.common.HeaderDisplayMode",toString:$estr}
    ,NeverShowHeader: {_hx_index:1,__enum__:"utest.ui.common.HeaderDisplayMode",toString:$estr}
    ,ShowHeaderWithResults: {_hx_index:2,__enum__:"utest.ui.common.HeaderDisplayMode",toString:$estr}
};
var utest_ui_common_SuccessResultsDisplayMode = $hxEnums["utest.ui.common.SuccessResultsDisplayMode"] = { __ename__ : "utest.ui.common.SuccessResultsDisplayMode", __constructs__ : ["AlwaysShowSuccessResults","NeverShowSuccessResults","ShowSuccessResultsWithNoErrors"]
    ,AlwaysShowSuccessResults: {_hx_index:0,__enum__:"utest.ui.common.SuccessResultsDisplayMode",toString:$estr}
    ,NeverShowSuccessResults: {_hx_index:1,__enum__:"utest.ui.common.SuccessResultsDisplayMode",toString:$estr}
    ,ShowSuccessResultsWithNoErrors: {_hx_index:2,__enum__:"utest.ui.common.SuccessResultsDisplayMode",toString:$estr}
};
var utest_ui_common_IReport = function() { };
utest_ui_common_IReport.__name__ = "utest.ui.common.IReport";
utest_ui_common_IReport.prototype = {
    displaySuccessResults: null
    ,displayHeader: null
    ,setHandler: null
    ,__class__: utest_ui_common_IReport
};
var utest_ui_common_PackageResult = function(packageName) {
    this.isEmpty = true;
    this.packageName = packageName;
    this.classes = new haxe_ds_StringMap();
    this.packages = new haxe_ds_StringMap();
    this.stats = new utest_ui_common_ResultStats();
};
utest_ui_common_PackageResult.__name__ = "utest.ui.common.PackageResult";
utest_ui_common_PackageResult.prototype = {
    packageName: null
    ,isEmpty: null
    ,classes: null
    ,packages: null
    ,stats: null
    ,addResult: function(result,flattenPackage) {
        this.isEmpty = false;
        var pack = this.getOrCreatePackage(result.pack,flattenPackage,this);
        var cls = this.getOrCreateClass(pack,result.cls,result.setup,result.teardown);
        var fix = this.createFixture(result.method,result.assertations);
        cls.add(fix);
    }
    ,addClass: function(result) {
        this.isEmpty = false;
        var key = result.className;
        var _this = this.classes;
        if(__map_reserved[key] != null) {
            _this.setReserved(key,result);
        } else {
            _this.h[key] = result;
        }
        this.stats.wire(result.stats);
    }
    ,addPackage: function(result) {
        this.isEmpty = false;
        var key = result.packageName;
        var _this = this.packages;
        if(__map_reserved[key] != null) {
            _this.setReserved(key,result);
        } else {
            _this.h[key] = result;
        }
        this.stats.wire(result.stats);
    }
    ,existsPackage: function(name) {
        var _this = this.packages;
        if(__map_reserved[name] != null) {
            return _this.existsReserved(name);
        } else {
            return _this.h.hasOwnProperty(name);
        }
    }
    ,existsClass: function(name) {
        var _this = this.classes;
        if(__map_reserved[name] != null) {
            return _this.existsReserved(name);
        } else {
            return _this.h.hasOwnProperty(name);
        }
    }
    ,getPackage: function(name) {
        if(this.packageName == null && name == "") {
            return this;
        }
        var _this = this.packages;
        if(__map_reserved[name] != null) {
            return _this.getReserved(name);
        } else {
            return _this.h[name];
        }
    }
    ,getClass: function(name) {
        var _this = this.classes;
        if(__map_reserved[name] != null) {
            return _this.getReserved(name);
        } else {
            return _this.h[name];
        }
    }
    ,classNames: function(errorsHavePriority) {
        if(errorsHavePriority == null) {
            errorsHavePriority = true;
        }
        var names = [];
        var name = this.classes.keys();
        while(name.hasNext()) {
            var name1 = name.next();
            names.push(name1);
        }
        if(errorsHavePriority) {
            var me = this;
            names.sort(function(a,b) {
                var as = me.getClass(a).stats;
                var bs = me.getClass(b).stats;
                if(as.hasErrors) {
                    if(!bs.hasErrors) {
                        return -1;
                    } else if(as.errors == bs.errors) {
                        return Reflect.compare(a,b);
                    } else {
                        return Reflect.compare(as.errors,bs.errors);
                    }
                } else if(bs.hasErrors) {
                    return 1;
                } else if(as.hasFailures) {
                    if(!bs.hasFailures) {
                        return -1;
                    } else if(as.failures == bs.failures) {
                        return Reflect.compare(a,b);
                    } else {
                        return Reflect.compare(as.failures,bs.failures);
                    }
                } else if(bs.hasFailures) {
                    return 1;
                } else if(as.hasWarnings) {
                    if(!bs.hasWarnings) {
                        return -1;
                    } else if(as.warnings == bs.warnings) {
                        return Reflect.compare(a,b);
                    } else {
                        return Reflect.compare(as.warnings,bs.warnings);
                    }
                } else if(bs.hasWarnings) {
                    return 1;
                } else {
                    return Reflect.compare(a,b);
                }
            });
        } else {
            names.sort(function(a1,b1) {
                return Reflect.compare(a1,b1);
            });
        }
        return names;
    }
    ,packageNames: function(errorsHavePriority) {
        if(errorsHavePriority == null) {
            errorsHavePriority = true;
        }
        var names = [];
        if(this.packageName == null) {
            names.push("");
        }
        var name = this.packages.keys();
        while(name.hasNext()) {
            var name1 = name.next();
            names.push(name1);
        }
        if(errorsHavePriority) {
            var me = this;
            names.sort(function(a,b) {
                var as = me.getPackage(a).stats;
                var bs = me.getPackage(b).stats;
                if(as.hasErrors) {
                    if(!bs.hasErrors) {
                        return -1;
                    } else if(as.errors == bs.errors) {
                        return Reflect.compare(a,b);
                    } else {
                        return Reflect.compare(as.errors,bs.errors);
                    }
                } else if(bs.hasErrors) {
                    return 1;
                } else if(as.hasFailures) {
                    if(!bs.hasFailures) {
                        return -1;
                    } else if(as.failures == bs.failures) {
                        return Reflect.compare(a,b);
                    } else {
                        return Reflect.compare(as.failures,bs.failures);
                    }
                } else if(bs.hasFailures) {
                    return 1;
                } else if(as.hasWarnings) {
                    if(!bs.hasWarnings) {
                        return -1;
                    } else if(as.warnings == bs.warnings) {
                        return Reflect.compare(a,b);
                    } else {
                        return Reflect.compare(as.warnings,bs.warnings);
                    }
                } else if(bs.hasWarnings) {
                    return 1;
                } else {
                    return Reflect.compare(a,b);
                }
            });
        } else {
            names.sort(function(a1,b1) {
                return Reflect.compare(a1,b1);
            });
        }
        return names;
    }
    ,createFixture: function(method,assertations) {
        var f = new utest_ui_common_FixtureResult(method);
        var assertation = $getIterator(assertations);
        while(assertation.hasNext()) {
            var assertation1 = assertation.next();
            f.add(assertation1);
        }
        return f;
    }
    ,getOrCreateClass: function(pack,cls,setup,teardown) {
        if(pack.existsClass(cls)) {
            return pack.getClass(cls);
        }
        var c = new utest_ui_common_ClassResult(cls,setup,teardown);
        pack.addClass(c);
        return c;
    }
    ,getOrCreatePackage: function(pack,flat,ref) {
        if(pack == null || pack == "") {
            return ref;
        }
        if(flat) {
            if(ref.existsPackage(pack)) {
                return ref.getPackage(pack);
            }
            var p = new utest_ui_common_PackageResult(pack);
            ref.addPackage(p);
            return p;
        } else {
            var parts = pack.split(".");
            var _g = 0;
            while(_g < parts.length) {
                var part = parts[_g];
                ++_g;
                ref = this.getOrCreatePackage(part,true,ref);
            }
            return ref;
        }
    }
    ,__class__: utest_ui_common_PackageResult
};
var utest_ui_common_ReportTools = function() { };
utest_ui_common_ReportTools.__name__ = "utest.ui.common.ReportTools";
utest_ui_common_ReportTools.hasHeader = function(report,stats) {
    switch(report.displayHeader._hx_index) {
    case 0:
        return true;
    case 1:
        return false;
    case 2:
        if(!stats.isOk) {
            return true;
        }
        switch(report.displaySuccessResults._hx_index) {
        case 1:
            return false;
        case 0:case 2:
            return true;
        }
        break;
    }
};
utest_ui_common_ReportTools.skipResult = function(report,stats,isOk) {
    if(!stats.isOk) {
        return false;
    }
    switch(report.displaySuccessResults._hx_index) {
    case 0:
        return false;
    case 1:
        return true;
    case 2:
        return !isOk;
    }
};
utest_ui_common_ReportTools.hasOutput = function(report,stats) {
    if(!stats.isOk) {
        return true;
    }
    return utest_ui_common_ReportTools.hasHeader(report,stats);
};
var utest_ui_common_ResultAggregator = function(runner,flattenPackage) {
    if(flattenPackage == null) {
        flattenPackage = false;
    }
    if(runner == null) {
        throw new js__$Boot_HaxeError("runner argument is null");
    }
    this.flattenPackage = flattenPackage;
    this.runner = runner;
    runner.onStart.add($bind(this,this.start));
    runner.onProgress.add($bind(this,this.progress));
    runner.onComplete.add($bind(this,this.complete));
    this.onStart = new utest_Notifier();
    this.onComplete = new utest_Dispatcher();
    this.onProgress = new utest_Dispatcher();
};
utest_ui_common_ResultAggregator.__name__ = "utest.ui.common.ResultAggregator";
utest_ui_common_ResultAggregator.prototype = {
    runner: null
    ,flattenPackage: null
    ,root: null
    ,onStart: null
    ,onComplete: null
    ,onProgress: null
    ,start: function(runner) {
        this.checkNonITest();
        this.root = new utest_ui_common_PackageResult(null);
        this.onStart.dispatch();
    }
    ,checkNonITest: function() {
        var first = null;
        var total = 0;
        var _g = 0;
        var _g1 = this.runner.length;
        while(_g < _g1) {
            var i = _g++;
            var fixture = this.runner.getFixture(i);
            if(!fixture.isITest) {
                ++total;
                if(first == null) {
                    var o = fixture.target;
                    var c = o == null ? null : js_Boot.getClass(o);
                    first = c.__name__;
                }
            }
        }
        if(total > 0) {
            var baseMsg = "implement utest.ITest. Non-ITest tests are deprecated. Implement utest.ITest or extend utest.Test.";
            var msg;
            switch(total) {
            case 1:
                msg = "" + first + " doesn't " + baseMsg;
                break;
            case 2:
                msg = "" + first + " and 1 other don't " + baseMsg;
                break;
            default:
                msg = "" + first + " and " + total + " others don't " + baseMsg;
            }
            haxe_Log.trace(msg,{ fileName : "utest/ui/common/ResultAggregator.hx", lineNumber : 54, className : "utest.ui.common.ResultAggregator", methodName : "checkNonITest"});
        }
    }
    ,getOrCreatePackage: function(pack,flat,ref) {
        if(ref == null) {
            ref = this.root;
        }
        if(pack == null || pack == "") {
            return ref;
        }
        if(flat) {
            if(ref.existsPackage(pack)) {
                return ref.getPackage(pack);
            }
            var p = new utest_ui_common_PackageResult(pack);
            ref.addPackage(p);
            return p;
        } else {
            var parts = pack.split(".");
            var _g = 0;
            while(_g < parts.length) {
                var part = parts[_g];
                ++_g;
                ref = this.getOrCreatePackage(part,true,ref);
            }
            return ref;
        }
    }
    ,getOrCreateClass: function(pack,cls,setup,teardown) {
        if(pack.existsClass(cls)) {
            return pack.getClass(cls);
        }
        var c = new utest_ui_common_ClassResult(cls,setup,teardown);
        pack.addClass(c);
        return c;
    }
    ,createFixture: function(result) {
        var f = new utest_ui_common_FixtureResult(result.method);
        var _g_head = result.assertations.h;
        while(_g_head != null) {
            var val = _g_head.item;
            _g_head = _g_head.next;
            var assertation = val;
            f.add(assertation);
        }
        return f;
    }
    ,progress: function(e) {
        this.root.addResult(e.result,this.flattenPackage);
        this.onProgress.dispatch(e);
    }
    ,complete: function(runner) {
        if(this.root.isEmpty) {
            this.root.addResult(this.createNoTestsResult(),false);
        }
        this.onComplete.dispatch(this.root);
    }
    ,createNoTestsResult: function() {
        var result = new utest_TestResult();
        result.pack = "";
        result.cls = "";
        result.method = "";
        result.assertations = new haxe_ds_List();
        var pos = { fileName : "", lineNumber : 1, className : "utest.Runner", methodName : "run"};
        result.assertations.add(utest_Assertation.Failure("No tests executed.",pos));
        return result;
    }
    ,__class__: utest_ui_common_ResultAggregator
};
var utest_ui_common_ResultStats = function() {
    this.assertations = 0;
    this.successes = 0;
    this.failures = 0;
    this.errors = 0;
    this.warnings = 0;
    this.ignores = 0;
    this.isOk = true;
    this.hasFailures = false;
    this.hasErrors = false;
    this.hasWarnings = false;
    this.hasIgnores = false;
    this.onAddSuccesses = new utest_Dispatcher();
    this.onAddFailures = new utest_Dispatcher();
    this.onAddErrors = new utest_Dispatcher();
    this.onAddWarnings = new utest_Dispatcher();
    this.onAddIgnores = new utest_Dispatcher();
};
utest_ui_common_ResultStats.__name__ = "utest.ui.common.ResultStats";
utest_ui_common_ResultStats.prototype = {
    assertations: null
    ,successes: null
    ,failures: null
    ,errors: null
    ,warnings: null
    ,ignores: null
    ,onAddSuccesses: null
    ,onAddFailures: null
    ,onAddErrors: null
    ,onAddWarnings: null
    ,onAddIgnores: null
    ,isOk: null
    ,hasFailures: null
    ,hasErrors: null
    ,hasWarnings: null
    ,hasIgnores: null
    ,addSuccesses: function(v) {
        if(v == 0) {
            return;
        }
        this.assertations += v;
        this.successes += v;
        this.onAddSuccesses.dispatch(v);
    }
    ,addFailures: function(v) {
        if(v == 0) {
            return;
        }
        this.assertations += v;
        this.failures += v;
        this.hasFailures = this.failures > 0;
        this.isOk = !(this.hasFailures || this.hasErrors || this.hasWarnings);
        this.onAddFailures.dispatch(v);
    }
    ,addErrors: function(v) {
        if(v == 0) {
            return;
        }
        this.assertations += v;
        this.errors += v;
        this.hasErrors = this.errors > 0;
        this.isOk = !(this.hasFailures || this.hasErrors || this.hasWarnings);
        this.onAddErrors.dispatch(v);
    }
    ,addIgnores: function(v) {
        if(v == 0) {
            return;
        }
        this.assertations += v;
        this.ignores += v;
        this.hasIgnores = this.ignores > 0;
        this.onAddIgnores.dispatch(v);
    }
    ,addWarnings: function(v) {
        if(v == 0) {
            return;
        }
        this.assertations += v;
        this.warnings += v;
        this.hasWarnings = this.warnings > 0;
        this.isOk = !(this.hasFailures || this.hasErrors || this.hasWarnings);
        this.onAddWarnings.dispatch(v);
    }
    ,sum: function(other) {
        this.addSuccesses(other.successes);
        this.addFailures(other.failures);
        this.addErrors(other.errors);
        this.addWarnings(other.warnings);
        this.addIgnores(other.ignores);
    }
    ,subtract: function(other) {
        this.addSuccesses(-other.successes);
        this.addFailures(-other.failures);
        this.addErrors(-other.errors);
        this.addWarnings(-other.warnings);
        this.addIgnores(-other.ignores);
    }
    ,wire: function(dependant) {
        dependant.onAddSuccesses.add($bind(this,this.addSuccesses));
        dependant.onAddFailures.add($bind(this,this.addFailures));
        dependant.onAddErrors.add($bind(this,this.addErrors));
        dependant.onAddWarnings.add($bind(this,this.addWarnings));
        dependant.onAddIgnores.add($bind(this,this.addIgnores));
        this.sum(dependant);
    }
    ,unwire: function(dependant) {
        dependant.onAddSuccesses.remove($bind(this,this.addSuccesses));
        dependant.onAddFailures.remove($bind(this,this.addFailures));
        dependant.onAddErrors.remove($bind(this,this.addErrors));
        dependant.onAddWarnings.remove($bind(this,this.addWarnings));
        dependant.onAddIgnores.remove($bind(this,this.addIgnores));
        this.subtract(dependant);
    }
    ,__class__: utest_ui_common_ResultStats
};
var utest_ui_text_HtmlReport = function(runner,outputHandler,traceRedirected) {
    if(traceRedirected == null) {
        traceRedirected = true;
    }
    this.aggregator = new utest_ui_common_ResultAggregator(runner,true);
    runner.onStart.add($bind(this,this.start));
    this.aggregator.onComplete.add($bind(this,this.complete));
    if(null == outputHandler) {
        this.setHandler($bind(this,this._handler));
    } else {
        this.setHandler(outputHandler);
    }
    if(traceRedirected) {
        this.redirectTrace();
    }
    this.displaySuccessResults = utest_ui_common_SuccessResultsDisplayMode.AlwaysShowSuccessResults;
    this.displayHeader = utest_ui_common_HeaderDisplayMode.AlwaysShowHeader;
};
utest_ui_text_HtmlReport.__name__ = "utest.ui.text.HtmlReport";
utest_ui_text_HtmlReport.__interfaces__ = [utest_ui_common_IReport];
utest_ui_text_HtmlReport.prototype = {
    traceRedirected: null
    ,displaySuccessResults: null
    ,displayHeader: null
    ,handler: null
    ,aggregator: null
    ,oldTrace: null
    ,_traces: null
    ,setHandler: function(handler) {
        this.handler = handler;
    }
    ,redirectTrace: function() {
        if(this.traceRedirected) {
            return;
        }
        this._traces = [];
        this.oldTrace = haxe_Log.trace;
        haxe_Log.trace = $bind(this,this._trace);
    }
    ,restoreTrace: function() {
        if(!this.traceRedirected) {
            return;
        }
        haxe_Log.trace = this.oldTrace;
    }
    ,_traceTime: null
    ,_trace: function(v,infos) {
        var time = Date.now() / 1000;
        var delta = this._traceTime == null ? 0 : time - this._traceTime;
        this._traces.push({ msg : StringTools.htmlEscape(Std.string(v)), infos : infos, time : time - this.startTime, delta : delta, stack : haxe_CallStack.callStack()});
        this._traceTime = Date.now() / 1000;
    }
    ,startTime: null
    ,start: function(e) {
        this.startTime = Date.now() / 1000;
    }
    ,cls: function(stats) {
        if(stats.hasErrors) {
            return "error";
        } else if(stats.hasFailures) {
            return "failure";
        } else if(stats.hasWarnings) {
            return "warn";
        } else {
            return "ok";
        }
    }
    ,resultNumbers: function(buf,stats) {
        var numbers = [];
        if(stats.assertations == 1) {
            numbers.push("<strong>1</strong> test");
        } else {
            numbers.push("<strong>" + stats.assertations + "</strong> tests");
        }
        if(stats.successes != stats.assertations) {
            if(stats.successes == 1) {
                numbers.push("<strong>1</strong> pass");
            } else if(stats.successes > 0) {
                numbers.push("<strong>" + stats.successes + "</strong> passes");
            }
        }
        if(stats.errors == 1) {
            numbers.push("<strong>1</strong> error");
        } else if(stats.errors > 0) {
            numbers.push("<strong>" + stats.errors + "</strong> errors");
        }
        if(stats.failures == 1) {
            numbers.push("<strong>1</strong> failure");
        } else if(stats.failures > 0) {
            numbers.push("<strong>" + stats.failures + "</strong> failures");
        }
        if(stats.warnings == 1) {
            numbers.push("<strong>1</strong> warning");
        } else if(stats.warnings > 0) {
            numbers.push("<strong>" + stats.warnings + "</strong> warnings");
        }
        var x = numbers.join(", ");
        buf.b += Std.string(x);
    }
    ,blockNumbers: function(buf,stats) {
        var x = "<div class=\"" + this.cls(stats) + "bg statnumbers\">";
        buf.b += Std.string(x);
        this.resultNumbers(buf,stats);
        buf.b += "</div>";
    }
    ,formatStack: function(stack,addNL) {
        if(addNL == null) {
            addNL = true;
        }
        var parts = [];
        var nl = addNL ? "\n" : "";
        var last = null;
        var count = 1;
        var _g = 0;
        var _g1 = haxe_CallStack.toString(stack).split("\n");
        while(_g < _g1.length) {
            var part = _g1[_g];
            ++_g;
            if(StringTools.trim(part) == "") {
                continue;
            }
            if(-1 < part.indexOf("Called from utest.")) {
                continue;
            }
            if(part == last) {
                parts[parts.length - 1] = part + " (#" + ++count + ")";
            } else {
                count = 1;
                last = part;
                parts.push(last);
            }
        }
        var s = "<ul><li>" + parts.join("</li>" + nl + "<li>") + "</li></ul>" + nl;
        return "<div>" + s + "</div>" + nl;
    }
    ,addFixture: function(buf,result,name,isOk) {
        if(utest_ui_common_ReportTools.skipResult(this,result.stats,isOk)) {
            return;
        }
        buf.b += "<li class=\"fixture\"><div class=\"li\">";
        var x = "<span class=\"" + this.cls(result.stats) + "bg fixtureresult\">";
        buf.b += Std.string(x);
        if(result.stats.isOk) {
            buf.b += "OK ";
        } else if(result.stats.hasErrors) {
            buf.b += "ERROR ";
        } else if(result.stats.hasFailures) {
            buf.b += "FAILURE ";
        } else if(result.stats.hasWarnings) {
            buf.b += "WARNING ";
        }
        buf.b += "</span>";
        buf.b += "<div class=\"fixturedetails\">";
        buf.b += Std.string("<strong>" + name + "</strong>");
        buf.b += ": ";
        this.resultNumbers(buf,result.stats);
        var messages = [];
        var _g = result.iterator();
        while(_g.head != null) {
            var val = _g.head.item;
            _g.head = _g.head.next;
            var assertation = val;
            switch(assertation._hx_index) {
            case 0:
                break;
            case 1:
                var pos = assertation.pos;
                var msg = assertation.msg;
                messages.push("<strong>line " + pos.lineNumber + "</strong>: <em>" + StringTools.htmlEscape(msg) + "</em>");
                break;
            case 2:
                var s = assertation.stack;
                var e = assertation.e;
                messages.push("<strong>error</strong>: <em>" + this.getErrorDescription(e) + "</em>\n<br/><strong>stack</strong>:" + this.getErrorStack(s,e));
                break;
            case 3:
                var s1 = assertation.stack;
                var e1 = assertation.e;
                messages.push("<strong>setup error</strong>: " + this.getErrorDescription(e1) + "\n<br/><strong>stack</strong>:" + this.getErrorStack(s1,e1));
                break;
            case 4:
                var s2 = assertation.stack;
                var e2 = assertation.e;
                messages.push("<strong>tear-down error</strong>: " + this.getErrorDescription(e2) + "\n<br/><strong>stack</strong>:" + this.getErrorStack(s2,e2));
                break;
            case 5:
                var missedAsyncs = assertation.missedAsyncs;
                messages.push("<strong>missed async call(s)</strong>: " + missedAsyncs);
                break;
            case 6:
                var s3 = assertation.stack;
                var e3 = assertation.e;
                messages.push("<strong>async error</strong>: " + this.getErrorDescription(e3) + "\n<br/><strong>stack</strong>:" + this.getErrorStack(s3,e3));
                break;
            case 7:
                var msg1 = assertation.msg;
                messages.push(StringTools.htmlEscape(msg1));
                break;
            case 8:
                var reason = assertation.reason;
                messages.push(StringTools.htmlEscape(reason));
                break;
            }
        }
        if(messages.length > 0) {
            buf.b += "<div class=\"testoutput\">";
            var x1 = messages.join("<br/>");
            buf.b += Std.string(x1);
            buf.b += "</div>\n";
        }
        buf.b += "</div>\n";
        buf.b += "</div></li>\n";
    }
    ,getErrorDescription: function(e) {
        return Std.string(e);
    }
    ,getErrorStack: function(s,e) {
        return this.formatStack(s);
    }
    ,addClass: function(buf,result,name,isOk) {
        if(utest_ui_common_ReportTools.skipResult(this,result.stats,isOk)) {
            return;
        }
        buf.b += "<li>";
        buf.b += Std.string("<h2 class=\"classname\">" + name + "</h2>");
        this.blockNumbers(buf,result.stats);
        buf.b += "<ul>\n";
        var _g = 0;
        var _g1 = result.methodNames();
        while(_g < _g1.length) {
            var mname = _g1[_g];
            ++_g;
            this.addFixture(buf,result.get(mname),mname,isOk);
        }
        buf.b += "</ul>\n";
        buf.b += "</li>\n";
    }
    ,addPackages: function(buf,result,isOk) {
        if(utest_ui_common_ReportTools.skipResult(this,result.stats,isOk)) {
            return;
        }
        buf.b += "<ul id=\"utest-results-packages\">\n";
        var _g = 0;
        var _g1 = result.packageNames(false);
        while(_g < _g1.length) {
            var name = _g1[_g];
            ++_g;
            this.addPackage(buf,result.getPackage(name),name,isOk);
        }
        buf.b += "</ul>\n";
    }
    ,addPackage: function(buf,result,name,isOk) {
        if(utest_ui_common_ReportTools.skipResult(this,result.stats,isOk)) {
            return;
        }
        if(name == "" && result.classNames().length == 0) {
            return;
        }
        buf.b += "<li>";
        buf.b += Std.string("<h2>" + name + "</h2>");
        this.blockNumbers(buf,result.stats);
        buf.b += "<ul>\n";
        var _g = 0;
        var _g1 = result.classNames();
        while(_g < _g1.length) {
            var cname = _g1[_g];
            ++_g;
            this.addClass(buf,result.getClass(cname),cname,isOk);
        }
        buf.b += "</ul>\n";
        buf.b += "</li>\n";
    }
    ,getTextResults: function() {
        var newline = "\n";
        var indents = function(count) {
            var _g = [];
            var _g1 = 0;
            var _g2 = count;
            while(_g1 < _g2) {
                var i = _g1++;
                _g.push("  ");
            }
            return _g.join("");
        };
        var dumpStack = function(stack) {
            if(stack.length == 0) {
                return "";
            }
            var parts = haxe_CallStack.toString(stack).split("\n");
            var r = [];
            var _g3 = 0;
            while(_g3 < parts.length) {
                var part = parts[_g3];
                ++_g3;
                if(part.indexOf(" utest.") >= 0) {
                    continue;
                }
                r.push(part);
            }
            return r.join(newline);
        };
        var buf_b = "";
        var _g4 = 0;
        var _g11 = this.result.packageNames();
        while(_g4 < _g11.length) {
            var pname = _g11[_g4];
            ++_g4;
            var pack = this.result.getPackage(pname);
            if(utest_ui_common_ReportTools.skipResult(this,pack.stats,this.result.stats.isOk)) {
                continue;
            }
            var _g5 = 0;
            var _g12 = pack.classNames();
            while(_g5 < _g12.length) {
                var cname = _g12[_g5];
                ++_g5;
                var cls = pack.getClass(cname);
                if(utest_ui_common_ReportTools.skipResult(this,cls.stats,this.result.stats.isOk)) {
                    continue;
                }
                buf_b += Std.string((pname == "" ? "" : pname + ".") + cname + newline);
                var _g6 = 0;
                var _g13 = cls.methodNames();
                while(_g6 < _g13.length) {
                    var mname = _g13[_g6];
                    ++_g6;
                    var fix = cls.get(mname);
                    if(utest_ui_common_ReportTools.skipResult(this,fix.stats,this.result.stats.isOk)) {
                        continue;
                    }
                    buf_b += Std.string(indents(1) + mname + ": ");
                    if(fix.stats.isOk) {
                        buf_b += "OK ";
                    } else if(fix.stats.hasErrors) {
                        buf_b += "ERROR ";
                    } else if(fix.stats.hasFailures) {
                        buf_b += "FAILURE ";
                    } else if(fix.stats.hasWarnings) {
                        buf_b += "WARNING ";
                    }
                    var messages = "";
                    var _g7 = fix.iterator();
                    while(_g7.head != null) {
                        var val = _g7.head.item;
                        _g7.head = _g7.head.next;
                        var assertation = val;
                        switch(assertation._hx_index) {
                        case 0:
                            buf_b += ".";
                            break;
                        case 1:
                            var pos = assertation.pos;
                            var msg = assertation.msg;
                            buf_b += "F";
                            messages += indents(2) + "line: " + pos.lineNumber + ", " + msg + newline;
                            break;
                        case 2:
                            var s = assertation.stack;
                            var e = assertation.e;
                            buf_b += "E";
                            messages += indents(2) + Std.string(e) + dumpStack(s) + newline;
                            break;
                        case 3:
                            var s1 = assertation.stack;
                            var e1 = assertation.e;
                            buf_b += "S";
                            messages += indents(2) + Std.string(e1) + dumpStack(s1) + newline;
                            break;
                        case 4:
                            var s2 = assertation.stack;
                            var e2 = assertation.e;
                            buf_b += "T";
                            messages += indents(2) + Std.string(e2) + dumpStack(s2) + newline;
                            break;
                        case 5:
                            var s3 = assertation.stack;
                            var missedAsyncs = assertation.missedAsyncs;
                            buf_b += "O";
                            messages += indents(2) + "missed async calls: " + missedAsyncs + dumpStack(s3) + newline;
                            break;
                        case 6:
                            var s4 = assertation.stack;
                            var e3 = assertation.e;
                            buf_b += "A";
                            messages += indents(2) + Std.string(e3) + dumpStack(s4) + newline;
                            break;
                        case 7:
                            var msg1 = assertation.msg;
                            buf_b += "W";
                            messages += indents(2) + msg1 + newline;
                            break;
                        case 8:
                            var reason = assertation.reason;
                            buf_b += "I";
                            if(reason != null && reason != "") {
                                messages += indents(2) + ("With reason: " + reason) + newline;
                            }
                            break;
                        }
                    }
                    buf_b += newline == null ? "null" : "" + newline;
                    buf_b += messages == null ? "null" : "" + messages;
                }
            }
        }
        return buf_b;
    }
    ,getHeader: function() {
        var buf = new StringBuf();
        if(!utest_ui_common_ReportTools.hasHeader(this,this.result.stats)) {
            return "";
        }
        var end = Date.now() / 1000;
        var time = ((end - this.startTime) * 1000 | 0) / 1000;
        var msg = "TEST OK";
        if(this.result.stats.hasErrors) {
            msg = "TEST ERRORS";
        } else if(this.result.stats.hasFailures) {
            msg = "TEST FAILED";
        } else if(this.result.stats.hasWarnings) {
            msg = "WARNING REPORTED";
        }
        var x = "<h1 class=\"" + this.cls(this.result.stats) + "bg header\">" + msg + "</h1>\n";
        buf.b += Std.string(x);
        buf.b += "<div class=\"headerinfo\">";
        this.resultNumbers(buf,this.result.stats);
        buf.b += Std.string(" performed on <strong>" + utest_ui_text_HtmlReport.platform + "</strong>, executed in <strong> " + time + " sec. </strong></div >\n ");
        return buf.b;
    }
    ,getTrace: function() {
        var buf_b = "";
        if(this._traces == null || this._traces.length == 0) {
            return "";
        }
        buf_b += "<div class=\"trace\"><h2>traces</h2><ol>";
        var _g = 0;
        var _g1 = this._traces;
        while(_g < _g1.length) {
            var t = _g1[_g];
            ++_g;
            buf_b += "<li><div class=\"li\">";
            var stack = StringTools.replace(this.formatStack(t.stack,false),"'","\\'");
            var method = "<span class=\"tracepackage\">" + t.infos.className + "</span><br/>" + t.infos.methodName + "(" + t.infos.lineNumber + ")";
            buf_b += Std.string("<span class=\"tracepos\" onmouseover=\"utestTooltip(this.parentNode, '" + stack + "')\" onmouseout=\"utestRemoveTooltip()\">");
            buf_b += method == null ? "null" : "" + method;
            buf_b += "</span><span class=\"tracetime\">";
            buf_b += Std.string("@ " + this.formatTime(t.time));
            if(Math.round(t.delta * 1000) > 0) {
                buf_b += Std.string(", ~" + this.formatTime(t.delta));
            }
            buf_b += "</span><span class=\"tracemsg\">";
            buf_b += Std.string(StringTools.replace(StringTools.trim(t.msg),"\n","<br/>\n"));
            buf_b += "</span><div class=\"clr\"></div></div></li>";
        }
        buf_b += "</ol></div>";
        return buf_b;
    }
    ,getResults: function() {
        var buf = new StringBuf();
        this.addPackages(buf,this.result,this.result.stats.isOk);
        return buf.b;
    }
    ,getAll: function() {
        if(!utest_ui_common_ReportTools.hasOutput(this,this.result.stats)) {
            return "";
        } else {
            return this.getHeader() + this.getTrace() + this.getResults();
        }
    }
    ,getHtml: function(title) {
        if(null == title) {
            title = "utest: " + utest_ui_text_HtmlReport.platform;
        }
        var s = this.getAll();
        if("" == s) {
            return "";
        } else {
            return this.wrapHtml(title,s);
        }
    }
    ,result: null
    ,complete: function(result) {
        this.result = result;
        this.handler(this);
        this.restoreTrace();
        var exposedResult = { isOk : result.stats.isOk, message : this.getTextResults()};
        if('undefined' != typeof window) {
            window.utest_result = exposedResult;
        }
    }
    ,formatTime: function(t) {
        return Math.round(t * 1000) + " ms";
    }
    ,cssStyle: function() {
        return "body, dd, dt {\n  font-family: Verdana, Arial, Sans-serif;\n  font-size: 12px;\n}\ndl {\n  width: 180px;\n}\ndd, dt {\n  margin : 0;\n  padding : 2px 5px;\n  border-top: 1px solid #f0f0f0;\n  border-left: 1px solid #f0f0f0;\n  border-right: 1px solid #CCCCCC;\n  border-bottom: 1px solid #CCCCCC;\n}\ndd.value {\n  text-align: center;\n  background-color: #eeeeee;\n}\ndt {\n  text-align: left;\n  background-color: #e6e6e6;\n  float: left;\n  width: 100px;\n}\n\nh1, h2, h3, h4, h5, h6 {\n  margin: 0;\n  padding: 0;\n}\n\nh1 {\n  text-align: center;\n  font-weight: bold;\n  padding: 5px 0 4px 0;\n  font-family: Arial, Sans-serif;\n  font-size: 18px;\n  border-top: 1px solid #f0f0f0;\n  border-left: 1px solid #f0f0f0;\n  border-right: 1px solid #CCCCCC;\n  border-bottom: 1px solid #CCCCCC;\n  margin: 0 2px 0px 2px;\n}\n\nh2 {\n  font-weight: bold;\n  padding: 2px 0 2px 8px;\n  font-family: Arial, Sans-serif;\n  font-size: 13px;\n  border-top: 1px solid #f0f0f0;\n  border-left: 1px solid #f0f0f0;\n  border-right: 1px solid #CCCCCC;\n  border-bottom: 1px solid #CCCCCC;\n  margin: 0 0 0px 0;\n  background-color: #FFFFFF;\n  color: #777777;\n}\n\nh2.classname {\n  color: #000000;\n}\n\n.okbg {\n  background-color: #66FF55;\n}\n.errorbg {\n  background-color: #CC1100;\n}\n.failurebg {\n  background-color: #EE3322;\n}\n.warnbg {\n  background-color: #FFCC99;\n}\n.headerinfo {\n  text-align: right;\n  font-size: 11px;\n  font - color: 0xCCCCCC;\n  margin: 0 2px 5px 2px;\n  border-left: 1px solid #f0f0f0;\n  border-right: 1px solid #CCCCCC;\n  border-bottom: 1px solid #CCCCCC;\n  padding: 2px;\n}\n\nli {\n  padding: 4px;\n  margin: 2px;\n  border-top: 1px solid #f0f0f0;\n  border-left: 1px solid #f0f0f0;\n  border-right: 1px solid #CCCCCC;\n  border-bottom: 1px solid #CCCCCC;\n  background-color: #e6e6e6;\n}\n\nli.fixture {\n  background-color: #f6f6f6;\n  padding-bottom: 6px;\n}\n\ndiv.fixturedetails {\n  padding-left: 108px;\n}\n\nul {\n  padding: 0;\n  margin: 6px 0 0 0;\n  list-style-type: none;\n}\n\nol {\n  padding: 0 0 0 28px;\n  margin: 0px 0 0 0;\n}\n\n.statnumbers {\n  padding: 2px 8px;\n}\n\n.fixtureresult {\n  width: 100px;\n  text-align: center;\n  display: block;\n  float: left;\n  font-weight: bold;\n  padding: 1px;\n  margin: 0 0 0 0;\n}\n\n.testoutput {\n  border: 1px dashed #CCCCCC;\n  margin: 4px 0 0 0;\n  padding: 4px 8px;\n  background-color: #eeeeee;\n}\n\nspan.tracepos, span.traceposempty {\n  display: block;\n  float: left;\n  font-weight: bold;\n  font-size: 9px;\n  width: 170px;\n  margin: 2px 0 0 2px;\n}\n\nspan.tracepos:hover {\n  cursor : pointer;\n  background-color: #ffff99;\n}\n\nspan.tracemsg {\n  display: block;\n  margin-left: 180px;\n  background-color: #eeeeee;\n  padding: 7px;\n}\n\nspan.tracetime {\n  display: block;\n  float: right;\n  margin: 2px;\n  font-size: 9px;\n  color: #777777;\n}\n\n\ndiv.trace ol {\n  padding: 0 0 0 40px;\n  color: #777777;\n}\n\ndiv.trace li {\n  padding: 0;\n}\n\ndiv.trace li div.li {\n  color: #000000;\n}\n\ndiv.trace h2 {\n  margin: 0 2px 0px 2px;\n  padding-left: 4px;\n}\n\n.tracepackage {\n  color: #777777;\n  font-weight: normal;\n}\n\n.clr {\n  clear: both;\n}\n\n#utesttip {\n  margin-top: -3px;\n  margin-left: 170px;\n  font-size: 9px;\n}\n\n#utesttip li {\n  margin: 0;\n  background-color: #ffff99;\n  padding: 2px 4px;\n  border: 0;\n  border-bottom: 1px dashed #ffff33;\n}";
    }
    ,jsScript: function() {
        return "function utestTooltip(ref, text) {\n  var el = document.getElementById(\"utesttip\");\n  if(!el) {\n    var el = document.createElement(\"div\")\n    el.id = \"utesttip\";\n    el.style.position = \"absolute\";\n    document.body.appendChild(el)\n  }\n  var p = utestFindPos(ref);\n  el.style.left = (4 + p[0]) + \"px\";\n  el.style.top = (p[1] - 1) + \"px\";\n  el.innerHTML =  text;\n}\n\nfunction utestFindPos(el) {\n  var left = 0;\n  var top = 0;\n  do {\n    left += el.offsetLeft;\n    top += el.offsetTop;\n  } while(el = el.offsetParent)\n  return [left, top];\n}\n\nfunction utestRemoveTooltip() {\n  var el = document.getElementById(\"utesttip\")\n  if(el)\n    document.body.removeChild(el)\n}";
    }
    ,wrapHtml: function(title,s) {
        return "<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<title>" + title + "</title>\n      <style type=\"text/css\">" + this.cssStyle() + "</style>\n      <script type=\"text/javascript\">\n" + this.jsScript() + "\n</" + "script>\n</head>\n      <body>\n" + s + "\n</body>\n</html>";
    }
    ,_handler: function(report) {
        var _gthis = this;
        if(window.document.readyState == "loading") {
            var onReadyStateChange = null;
            onReadyStateChange = function() {
                if(window.document.readyState != "loading") {
                    window.document.removeEventListener("readystatechange",onReadyStateChange);
                    _gthis._handler(report);
                }
            };
            window.document.addEventListener("readystatechange",onReadyStateChange);
            return;
        }
        var isDef = function(v) {
            return typeof v != 'undefined';
        };
        var hasProcess = typeof process != 'undefined';
        if(hasProcess) {
            process.stdout.write(report.getHtml());
            return;
        }
        var head = window.document.getElementsByTagName("head")[0];
        var script = window.document.createElement("script");
        script.type = "text/javascript";
        var sjs = report.jsScript();
        if(isDef(script.text)) {
            script.text = sjs;
        } else {
            script.innerHTML = sjs;
        }
        head.appendChild(script);
        var style = window.document.createElement("style");
        style.type = "text/css";
        var scss = report.cssStyle();
        if(isDef(style.styleSheet)) {
            style.styleSheet.cssText = scss;
        } else if(isDef(style.cssText)) {
            style.cssText = scss;
        } else if(isDef(style.innerText)) {
            style.innerText = scss;
        } else {
            style.innerHTML = scss;
        }
        head.appendChild(style);
        var el = window.document.getElementById("utest-results");
        if(null == el) {
            el = window.document.createElement("div");
            el.id = "utest-results";
            window.document.body.appendChild(el);
        }
        el.innerHTML = report.getAll();
    }
    ,__class__: utest_ui_text_HtmlReport
};
var utest_ui_text_PlainTextReport = function(runner,outputHandler) {
    this.aggregator = new utest_ui_common_ResultAggregator(runner,true);
    runner.onStart.add($bind(this,this.start));
    this.aggregator.onComplete.add($bind(this,this.complete));
    if(null != outputHandler) {
        this.setHandler(outputHandler);
    }
    this.displaySuccessResults = utest_ui_common_SuccessResultsDisplayMode.AlwaysShowSuccessResults;
    this.displayHeader = utest_ui_common_HeaderDisplayMode.AlwaysShowHeader;
};
utest_ui_text_PlainTextReport.__name__ = "utest.ui.text.PlainTextReport";
utest_ui_text_PlainTextReport.__interfaces__ = [utest_ui_common_IReport];
utest_ui_text_PlainTextReport.prototype = {
    displaySuccessResults: null
    ,displayHeader: null
    ,handler: null
    ,aggregator: null
    ,newline: null
    ,indent: null
    ,setHandler: function(handler) {
        this.handler = handler;
    }
    ,startTime: null
    ,start: function(e) {
        this.startTime = this.getTime();
    }
    ,getTime: function() {
        return Date.now() / 1000;
    }
    ,indents: function(c) {
        var s = "";
        while(--c >= 0) s += this.indent;
        return s;
    }
    ,dumpStack: function(stack) {
        if(stack.length == 0) {
            return "";
        }
        var parts = haxe_CallStack.toString(stack).split("\n");
        var r = [];
        var _g = 0;
        while(_g < parts.length) {
            var part = parts[_g];
            ++_g;
            if(part.indexOf(" utest.") >= 0) {
                continue;
            }
            r.push(part);
        }
        return r.join(this.newline);
    }
    ,addHeader: function(buf,result) {
        if(!utest_ui_common_ReportTools.hasHeader(this,result.stats)) {
            return;
        }
        var end = this.getTime();
        var time = ((end - this.startTime) * 1000 | 0) / 1000;
        buf.b += Std.string("\nassertations: " + result.stats.assertations + this.newline);
        buf.b += Std.string("successes: " + result.stats.successes + this.newline);
        buf.b += Std.string("errors: " + result.stats.errors + this.newline);
        buf.b += Std.string("failures: " + result.stats.failures + this.newline);
        buf.b += Std.string("warnings: " + result.stats.warnings + this.newline);
        buf.b += Std.string("execution time: " + time + this.newline);
        buf.b += Std.string(this.newline);
        buf.b += Std.string("results: " + (result.stats.isOk ? "ALL TESTS OK (success: true)" : "SOME TESTS FAILURES (success: false)"));
        buf.b += Std.string(this.newline);
    }
    ,result: null
    ,getResults: function() {
        var buf = new StringBuf();
        this.addHeader(buf,this.result);
        var _g = 0;
        var _g1 = this.result.packageNames();
        while(_g < _g1.length) {
            var pname = _g1[_g];
            ++_g;
            var pack = this.result.getPackage(pname);
            if(utest_ui_common_ReportTools.skipResult(this,pack.stats,this.result.stats.isOk)) {
                continue;
            }
            var _g2 = 0;
            var _g11 = pack.classNames();
            while(_g2 < _g11.length) {
                var cname = _g11[_g2];
                ++_g2;
                var cls = pack.getClass(cname);
                if(utest_ui_common_ReportTools.skipResult(this,cls.stats,this.result.stats.isOk)) {
                    continue;
                }
                buf.b += Std.string((pname == "" ? "" : pname + ".") + cname + this.newline);
                var _g3 = 0;
                var _g12 = cls.methodNames();
                while(_g3 < _g12.length) {
                    var mname = _g12[_g3];
                    ++_g3;
                    var fix = cls.get(mname);
                    if(utest_ui_common_ReportTools.skipResult(this,fix.stats,this.result.stats.isOk)) {
                        continue;
                    }
                    var x = this.indents(1) + mname + ": ";
                    buf.b += Std.string(x);
                    if(fix.stats.isOk) {
                        buf.b += "OK ";
                    } else if(fix.stats.hasErrors) {
                        buf.b += "ERROR ";
                    } else if(fix.stats.hasFailures) {
                        buf.b += "FAILURE ";
                    } else if(fix.stats.hasWarnings) {
                        buf.b += "WARNING ";
                    }
                    var messages = "";
                    var _g4 = fix.iterator();
                    while(_g4.head != null) {
                        var val = _g4.head.item;
                        _g4.head = _g4.head.next;
                        var assertation = val;
                        switch(assertation._hx_index) {
                        case 0:
                            buf.b += ".";
                            break;
                        case 1:
                            var pos = assertation.pos;
                            var msg = assertation.msg;
                            buf.b += "F";
                            messages += this.indents(2) + "line: " + pos.lineNumber + ", " + msg + this.newline;
                            break;
                        case 2:
                            var s = assertation.stack;
                            var e = assertation.e;
                            buf.b += "E";
                            messages += this.indents(2) + Std.string(e) + this.dumpStack(s) + this.newline;
                            break;
                        case 3:
                            var s1 = assertation.stack;
                            var e1 = assertation.e;
                            buf.b += "S";
                            messages += this.indents(2) + Std.string(e1) + this.dumpStack(s1) + this.newline;
                            break;
                        case 4:
                            var s2 = assertation.stack;
                            var e2 = assertation.e;
                            buf.b += "T";
                            messages += this.indents(2) + Std.string(e2) + this.dumpStack(s2) + this.newline;
                            break;
                        case 5:
                            var s3 = assertation.stack;
                            var missedAsyncs = assertation.missedAsyncs;
                            buf.b += "O";
                            messages += this.indents(2) + "missed async calls: " + missedAsyncs + this.dumpStack(s3) + this.newline;
                            break;
                        case 6:
                            var s4 = assertation.stack;
                            var e3 = assertation.e;
                            buf.b += "A";
                            messages += this.indents(2) + Std.string(e3) + this.dumpStack(s4) + this.newline;
                            break;
                        case 7:
                            var msg1 = assertation.msg;
                            buf.b += "W";
                            messages += this.indents(2) + msg1 + this.newline;
                            break;
                        case 8:
                            var reason = assertation.reason;
                            buf.b += "I";
                            if(reason != null && reason != "") {
                                messages += this.indents(2) + ("With reason: " + reason) + this.newline;
                            }
                            break;
                        }
                    }
                    buf.b += Std.string(this.newline);
                    buf.b += messages == null ? "null" : "" + messages;
                }
            }
        }
        return buf.b;
    }
    ,complete: function(result) {
        this.result = result;
        if(this.handler != null) {
            this.handler(this);
        }
        if(typeof phantom != "undefined") {
            phantom.exit(result.stats.isOk ? 0 : 1);
        }
        if(typeof process != "undefined") {
            process.exit(result.stats.isOk ? 0 : 1);
        }
    }
    ,__class__: utest_ui_text_PlainTextReport
};
var utest_ui_text_PrintReport = function(runner) {
    utest_ui_text_PlainTextReport.call(this,runner,$bind(this,this._handler));
    this.newline = "\n";
    this.indent = "  ";
};
utest_ui_text_PrintReport.__name__ = "utest.ui.text.PrintReport";
utest_ui_text_PrintReport.__super__ = utest_ui_text_PlainTextReport;
utest_ui_text_PrintReport.prototype = $extend(utest_ui_text_PlainTextReport.prototype,{
    _handler: function(report) {
        this._trace(report.getResults());
    }
    ,_trace: function(s) {
        s = StringTools.replace(s,"  ",this.indent);
        s = StringTools.replace(s,"\n",this.newline);
        haxe_Log.trace(s,{ fileName : "utest/ui/text/PrintReport.hx", lineNumber : 52, className : "utest.ui.text.PrintReport", methodName : "_trace"});
    }
    ,__class__: utest_ui_text_PrintReport
});
var utest_utils_AccessoriesUtils = function() { };
utest_utils_AccessoriesUtils.__name__ = "utest.utils.AccessoriesUtils";
utest_utils_AccessoriesUtils.getSetupClass = function(accessories) {
    if(accessories.setupClass == null) {
        return utest_Async.getResolved;
    } else {
        return accessories.setupClass;
    }
};
utest_utils_AccessoriesUtils.getSetup = function(accessories) {
    if(accessories.setup == null) {
        return utest_Async.getResolved;
    } else {
        return accessories.setup;
    }
};
utest_utils_AccessoriesUtils.getTeardown = function(accessories) {
    if(accessories.teardown == null) {
        return utest_Async.getResolved;
    } else {
        return accessories.teardown;
    }
};
utest_utils_AccessoriesUtils.getTeardownClass = function(accessories) {
    if(accessories.teardownClass == null) {
        return utest_Async.getResolved;
    } else {
        return accessories.teardownClass;
    }
};
var utest_utils_AsyncUtils = function() { };
utest_utils_AsyncUtils.__name__ = "utest.utils.AsyncUtils";
utest_utils_AsyncUtils.orResolved = function(async) {
    if(async == null) {
        return utest_Async.getResolved();
    } else {
        return async;
    }
};
function $getIterator(o) { if( o instanceof Array ) return HxOverrides.iter(o); else return o.iterator(); }
var $fid = 0;
function $bind(o,m) { if( m == null ) return null; if( m.__id__ == null ) m.__id__ = $fid++; var f; if( o.hx__closures__ == null ) o.hx__closures__ = {}; else f = o.hx__closures__[m.__id__]; if( f == null ) { f = m.bind(o); o.hx__closures__[m.__id__] = f; } return f; }
if( String.fromCodePoint == null ) String.fromCodePoint = function(c) { return c < 0x10000 ? String.fromCharCode(c) : String.fromCharCode((c>>10)+0xD7C0)+String.fromCharCode((c&0x3FF)+0xDC00); }
String.prototype.__class__ = String;
String.__name__ = "String";
Array.__name__ = "Array";
Date.prototype.__class__ = Date;
Date.__name__ = "Date";
var Int = { };
var Dynamic = { };
var Float = Number;
var Bool = Boolean;
var Class = { };
var Enum = { };
haxe_ds_ObjectMap.count = 0;
var __map_reserved = {};
Object.defineProperty(js__$Boot_HaxeError.prototype,"message",{ get : function() {
    return String(this.val);
}});
js_Boot.__toStr = ({ }).toString;
utest_TestHandler.POLLING_TIME = 10;
utest_AccessoryName.SETUP_NAME = "setup";
utest_AccessoryName.SETUP_CLASS_NAME = "setupClass";
utest_AccessoryName.TEARDOWN_NAME = "teardown";
utest_AccessoryName.TEARDOWN_CLASS_NAME = "teardownClass";
utest_ui_text_HtmlReport.platform = "javascript";
rayTriangle_RayTriangleTests.main();
})(typeof window != "undefined" ? window : typeof global != "undefined" ? global : typeof self != "undefined" ? self : this);
nanjizal commented 5 years ago

Do I need to switch analyzer off or something.

sebthom commented 5 years ago

I tried a newer Haxe 4 release (RC2) and used HashLink as target but that should not matter. This test also works with Haxe 3.4: https://github.com/vegardit/haxe-doctest/blob/master/test/hx/doctest/example/ExampleTools.hx#L39

nanjizal commented 5 years ago

I don't have HL setup but I can test for cpp, did you test on js?

sebthom commented 5 years ago

I just tested with nodejs and phantomjs both succeed.

However when I change typedef V3 to @:structInit class V3 { then the comparison fails - which is expected because then we do not compare anonymous structures but objects for which reference equality is used.

nanjizal commented 5 years ago

when I use @:structInit I get:

line 30: Vec3.zero() == new Vec3({ x: 0., y: 0., z: 0. } ) --> Left side '{ x : 0, y : 0, z : 0 }' does not equal '{ x : 0, y : 0, z : 0 }'.

You saying this should fail, but

equals.Equal.equals(  Vec3.zero(),  new Vec3({ x: 0., y: 0., z: 0. } ) )== true

succeeds

sebthom commented 5 years ago

I am not using a third party library for testing equality. I checked how doctest behaves when using == between the statements to compare. Deep equals with doctest is only used for arrays and anonymous structures automatically.

nanjizal commented 5 years ago

thank you for taking a look so quickly, good so know some deep tests are supported, found typedef's even on js to be slower, but @:structInit I don't think adds any overhead so it's likely to be my preferred option going forward and probably for geom not use typedef at all. As you can see the signatures in code so it's much clearer to read more like the Luxe approach.

Could it be setup so we can assign our own static method for comparisom or do you think that might be too complicated, have not checked if Assert.same works yet but 'equals' does.

nanjizal commented 5 years ago

anyway thanks for taking a look so quickly :)

nanjizal commented 5 years ago

Think maybe nice solution is to just add a toTypeDef method, it's more verbose but should allow checking other methods easier.

    public inline
    function toTypedef(): { x: Float, y: Float, z: Float }{
        return { x: this.x, y: this.y, z: this.z };
    }

eg:

    /**
     * <pre><code>
     * >>> Vec3.zero().toTypedef() == new Vec3({ x: 0., y: 0., z: 0. } ).toTypedef()
     * </code></pre>
     */
    public static inline
    function zero(){
        return new Vec3({ x: 0.
                        , y: 0.
                        , z: 0. });
    }

overkill for this case but on 3x4 matrix will be worth the extra method.

sebthom commented 5 years ago

We could change the default behaviour of the == operator in test assertions to always perform structural comparisons and not identity comparison of objects and introduce a second operator === that always checks for identity/reference equality - similar to what JS does.

nanjizal commented 5 years ago

Ok this seems to be checking structure not the actual values when I do it this way which is not going to check that 'zero' is setup correctly.

Ideally a solution should allow, but its hard to say what grammar would be suitable.

Deep equality

nanjizal commented 5 years ago

Equals seems to work for 'zero' fine where I need to check values.

sebthom commented 5 years ago

I changed the behavior of the == comparison operator between the left and the right side expression. It now always performs a deep equals comparison. If one needs to check for reference equality === and !== can be used. See: https://github.com/vegardit/haxe-doctest/blob/970fdb414443babf8d96eab57ceb345603c7f1bd/test/hx/doctest/example/ExampleEntity.hx#L21-L30

I am closing the issue for now. You can reopen if required.

nanjizal commented 5 years ago

The deep equals is really useful, really nice to use, noticed not working for arrays, had to resort to Equal, not vital leaving here for future ref.

   /**
     * <pre><code>
     * >>> ({ 
     * ... var a = Matrix1x4.unit();
     * ... var b: Array<Float> = a;
     * ... trace( 'b '+ b );
     * ... Equal.equals( b, [ 1., 1., 1., 1. ] ); }) == true
     * </code></pre>
     */
    @:to
    public inline function toArray():Array<Float> {
        return [ this.x, this.y, this.z, this.w ];
    }
sebthom commented 5 years ago

@nanjizal arrays should actually work. there is also a unit test for it: https://github.com/vegardit/haxe-doctest/blob/master/test/hx/doctest/example/ExampleTools.hx#L27

You can try to debug the deepEquals method at https://github.com/vegardit/haxe-doctest/blob/master/src/hx/doctest/internal/DocTestUtils.hx#L48 to see why it doesn't work in your case.

nanjizal commented 5 years ago

Have any recent changes effected Cppia, it no longer seems to trace any test info. Probably something I have done wrong my end.