Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@ cached-classes-null-IgnoreCover.txt
.haxelib
/haxelib.json
src/tmp/
*.hxproj
*.hxproj
13 changes: 13 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
## 2.3.3

- Flash cast fix
- Remove custom setter/getter functions (Haxe 4)

## 2.3.2

- Fixed invalid XML length

## 2.3.1

- js: Using `===` instead of `==` in `Assert.areEqual`

## 2.3.0

- Added support for `eval` target
Expand Down
2 changes: 1 addition & 1 deletion mdk/info.config
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: munit
version: 2.3.2
version: 2.3.3
dependencies:
mlib: ^2.0.0
mcover: ^2.0.0
Expand Down
4 changes: 2 additions & 2 deletions project.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"project":
{
"name": "MassiveUnit",
"version": "2.3.2",
"version": "2.3.3",
"id": "munit",
"haxelib":
{
Expand All @@ -19,4 +19,4 @@
"mcover": "2.x"
}
}
}
}
4 changes: 2 additions & 2 deletions src/haxelib.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
"massive"
],
"releasenote": "See https://github.com/massiveinteractive/MassiveUnit/blob/master/CHANGES.md",
"version": "2.3.2",
"version": "2.3.3",
"url": "http://github.com/massiveinteractive/MassiveUnit",
"dependencies": {
"mlib": "",
"mcover": ""
}
}
}
Binary file modified src/index.n
Binary file not shown.
11 changes: 10 additions & 1 deletion src/massive/munit/Assert.hx
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,15 @@ class Assert
static inline function equals(a:Dynamic, b:Dynamic) return switch(Type.typeof(a)) {
case TEnum(_): Type.enumEq(a, b);
case TFunction: Reflect.compareMethods(a, b);
default: a == b;
default:
#if(js)
#if(haxe_ver >= "4.0.0")
js.Syntax.strictEq(a, b);
#else
untyped __strict_eq__(a, b);
#end
#else
a == b;
#end
}
}
128 changes: 100 additions & 28 deletions src/massive/munit/TestClassHelper.hx
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,18 @@ class TestClassHelper
*/
public inline static var META_TAG_TEST_DEBUG:String = "TestDebug";

/**
* Meta tag marking a test as having an argument data provider
*/
public inline static var META_TAG_DATA_PROVIDER:String = "DataProvider";

/**
* Pseudo meta tag marking method inheritance depth. Auto generated
* by test parser, thus not in META_TAGS below as it is never expected
* to be in a test file.
**/
public inline static var META_TAG_INHERITANCE_DEPTH:String = "InheritanceDepth";

/**
* Array of all valid meta tags.
*/
Expand All @@ -116,24 +128,24 @@ class TestClassHelper
public var test(default, null):Dynamic;

/**
* The life cycle method to be called once, before tests in the class are executed.
* The life cycle methods to be called once, before tests in the class are executed.
*/
public var beforeClass(default, null):Function;
public var beforeClass(default, null):Array<Function>;

/**
* The life cycle method to be called once, after tests in the class are executed.
* The life cycle methods to be called once, after tests in the class are executed.
*/
public var afterClass(default, null):Function;
public var afterClass(default, null):Array<Function>;

/**
* The life cycle method to be called once, before each test in the class is executed.
* The life cycle methods to be called once, before each test in the class is executed.
*/
public var before(default, null):Function;
public var before(default, null):Array<Function>;

/**
* The life cycle method to be called once, after each test in the class is executed.
* The life cycle methods to be called once, after each test in the class is executed.
*/
public var after(default, null):Function;
public var after(default, null):Array<Function>;

public var className(default, null):String;
var tests:Array<TestCaseData> = [];
Expand All @@ -150,10 +162,10 @@ class TestClassHelper
this.type = type;
this.isDebug = isDebug;
className = Type.getClassName(type);
beforeClass = nullFunc;
afterClass = nullFunc;
before = nullFunc;
after = nullFunc;
beforeClass = new Array();
afterClass = new Array();
before = new Array();
after = new Array();
parse(type);
}

Expand Down Expand Up @@ -195,6 +207,9 @@ class TestClassHelper
var fieldMeta = collateFieldMeta(inherintanceChain);
scanForTests(fieldMeta);
tests.sort(sortTestsByName); // not pc as allows for possible test dependencies but useful for report consistency
// after methods should be called from subclass to base class order
after.reverse();
afterClass.reverse();
}

function getInheritanceChain(clazz:Class<Dynamic>):Array<Class<Dynamic>>
Expand All @@ -208,10 +223,18 @@ class TestClassHelper
function collateFieldMeta(inherintanceChain:Array<Class<Dynamic>>):Dynamic
{
var meta = {};
var depth = -1; // initially negative since incremented at top of loop
var i = inherintanceChain.length;
while (i-- > 0)
{
var clazz = inherintanceChain[i]; // start at root
// go to next inheritance depth
depth++;
// update lifecycle function arrays with new depth
beforeClass.push(nullFunc);
afterClass.push(nullFunc);
before.push(nullFunc);
after.push(nullFunc);
var newMeta = Meta.getFields(clazz);
var markedFieldNames = Reflect.fields(newMeta);

Expand All @@ -229,7 +252,9 @@ class TestClassHelper
var tagsCopy = {};
for (tagName in newTagNames)
Reflect.setField(tagsCopy, tagName, Reflect.field(newFieldTags, tagName));

// remember the inheritance depth of this field with a pseudo-tag
Reflect.setField(tagsCopy, META_TAG_INHERITANCE_DEPTH, [depth]);

Reflect.setField(meta, fieldName, tagsCopy);
}
else
Expand All @@ -251,6 +276,9 @@ class TestClassHelper
var tagValue = Reflect.field(newFieldTags, tagName);
Reflect.setField(recordedFieldTags, tagName, tagValue);
}
// update the inheritance depth of this field, as it overrides the
// earlier definition
Reflect.setField(recordedFieldTags, META_TAG_INHERITANCE_DEPTH, [depth]);
}
}
}
Expand All @@ -271,13 +299,16 @@ class TestClassHelper

function searchForMatchingTags(fieldName:String, func:Dynamic, funcMeta:Dynamic)
{
var depth = Reflect.field(funcMeta, META_TAG_INHERITANCE_DEPTH)[0];
for (tag in META_TAGS)
{
if (!Reflect.hasField(funcMeta, tag)) continue;
var args:Array<String> = Reflect.field(funcMeta, tag);
var description = (args != null) ? args[0] : "";
var isAsync = (args != null && description == META_PARAM_ASYNC_TEST); // deprecated support for @Test("Async")
var isIgnored = Reflect.hasField(funcMeta, META_TAG_IGNORE);
var hasDataProvider = Reflect.hasField(funcMeta, META_TAG_DATA_PROVIDER);
var dataProvider:String = null;

if (isAsync)
{
Expand All @@ -289,28 +320,69 @@ class TestClassHelper
description = (args != null) ? args[0] : "";
}

if (hasDataProvider)
{
args = Reflect.field(funcMeta, META_TAG_DATA_PROVIDER);
if (args != null)
{
dataProvider = args[0];
}
else
{
throw new MUnitException("Missing dataProvider source", null);
}
}

switch(tag)
{
case META_TAG_BEFORE_CLASS: beforeClass = func;
case META_TAG_AFTER_CLASS: afterClass = func;
case META_TAG_BEFORE: before = func;
case META_TAG_AFTER: after = func;
case META_TAG_ASYNC_TEST: if(!isDebug) addTest(fieldName, func, test, true, isIgnored, description);
case META_TAG_TEST: if(!isDebug) addTest(fieldName, func, test, isAsync, isIgnored, description);
case META_TAG_TEST_DEBUG: if(isDebug) addTest(fieldName, func, test, isAsync, isIgnored, description);
case META_TAG_BEFORE_CLASS: beforeClass[depth] = func;
case META_TAG_AFTER_CLASS: afterClass[depth] = func;
case META_TAG_BEFORE: before[depth] = func;
case META_TAG_AFTER: after[depth] = func;
case META_TAG_ASYNC_TEST: if(!isDebug) addTest(fieldName, func, test, true, isIgnored, description, dataProvider);
case META_TAG_TEST: if(!isDebug) addTest(fieldName, func, test, isAsync, isIgnored, description, dataProvider);
case META_TAG_TEST_DEBUG: if(isDebug) addTest(fieldName, func, test, isAsync, isIgnored, description, dataProvider);
}
}
}

function addTest(field:String, testFunction:Function, testInstance:Dynamic, isAsync:Bool, isIgnored:Bool, description:String)
function addTest(field:String, testFunction:Function, testInstance:Dynamic, isAsync:Bool, isIgnored:Bool, description:String, dataProvider:String)
{
var result:TestResult = new TestResult();
result.async = isAsync;
result.ignore = isIgnored;
result.className = className;
result.description = description;
result.name = field;
tests.push({scope:testInstance, test:testFunction, result:result});
var argsData:Array<Array<Dynamic>> = [[]];
if (dataProvider != null)
{
// look for object instance field
var provider:Dynamic = Reflect.field(testInstance, dataProvider);
if (null == provider) {
// look for static class field
provider = Reflect.field(Type.getClass(testInstance), dataProvider);
}
if (Reflect.isFunction(provider))
{
provider = Reflect.callMethod(testInstance, provider, []);
}
if (Std.is(provider, Array))
{
argsData = cast provider;
}
else
{
throw new MUnitException("dataProvider \'" + dataProvider +
"\' did not provide args array", null);
}
}
for (args in argsData)
{
var result:TestResult = new TestResult();
result.async = isAsync;
result.ignore = isIgnored;
result.className = className;
result.description = description;
result.name = field;
result.args = args;
var data:TestCaseData = { test:testFunction, scope:testInstance, result:result };
tests.push(data);
}
}

function sortTestsByName(x:TestCaseData, y:TestCaseData):Int
Expand Down
19 changes: 18 additions & 1 deletion src/massive/munit/TestResult.hx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ class TestResult
*/
public var ignore:Bool = false;

/**
* Arguments for the test, or null if no args
**/
public var args:Array<Dynamic>;

/**
* If this test failed, the assertion exception that was captured.
*/
Expand All @@ -97,7 +102,19 @@ class TestResult
/**
* Class constructor.
*/
public function new() {}
public function new()
{
passed = false;
executionTime = 0.0;
name = "";
className = "";
description = "";
async = false;
ignore = false;
args = null;
error = null;
failure = null;
}

function get_type():TestResultType
{
Expand Down
Loading