Skip to content

Commit

Permalink
Add in a new test_suites function and supporting infrastructure. This…
Browse files Browse the repository at this point in the history
… new function allows the automatic construction of a test suite of multiple subsuites
  • Loading branch information
Whiteknight committed Feb 1, 2012
1 parent 1be7c35 commit d1aa335
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 23 deletions.
44 changes: 44 additions & 0 deletions src/test/Test.winxed
Expand Up @@ -40,6 +40,17 @@ namespace Rosella.Test
return result.was_successful();
}

function build_suite(var test_type)
{
var suitefactory = new Rosella.Test.SuiteFactory();
var test_factory = new Rosella.Test.TestFactory();

var class_obj = Rosella.get_type_class(test_type);
var test_methods = internal_get_test_methods(class_obj, "");

return suitefactory.create(test_factory, test_methods);
}

// Setup and run a single test function over a sequence of data
// objects.
function test_vector(var func, var tests, var options [slurpy,named])
Expand All @@ -55,6 +66,14 @@ namespace Rosella.Test
return result.was_successful();
}

function build_suite_vector(var func, var tests)
{
var suitefactory = new Rosella.Test.SuiteFactory.Vector();
var test_factory = new Rosella.Test.TestFactory();

return suitefactory.create(test_factory, tests, func);
}

// Tests in the form of a list. The first argument is a list of callback
// functions to execute as individual tests
function test_list(var list, var options [slurpy,named])
Expand All @@ -70,6 +89,31 @@ namespace Rosella.Test
return result.was_successful();
}

function build_suite_list(var list)
{
var suitefactory = new Rosella.Test.SuiteFactory.Vector();
var test_factory = new Rosella.Test.TestFactory();

return suitefactory.create(test_factory, list);
}

function test_suites(var suites, var options[slurpy,named])
{
test_vector(
function(var test, var suite) {
var parent_suite = test.status.suite();
var result = parent_suite.result.get_sub_result();
result = suite.run(result, parent_suite.context, parent_suite.asserter);
if (!result.was_successful()) {
string msg = sprintf("Failed %d of %d subtests", [result.num_failures, result.total_tests]);
parent_suite.asserter.fail(msg, 1, null);
}
},
suites,
options:[flat,named]
);
}

// Get the matcher factory
const string DEFAULT_MATCHER_FACTORY = "Rosella.Test.matcher_factory";
function matcher_factory()
Expand Down
23 changes: 9 additions & 14 deletions src/test/TestCase.winxed
Expand Up @@ -7,22 +7,20 @@

TestCase intercepts attribute accesses. Attributes on a TestCase are
read-only, and any attempt to modify them from within a running test
will cause an exception.

By default, TestCase provides two attributes, one for the currently
executing test method object, and one for the current TestContext data
object. Subclasses of TestCase can add additional attributes or
methods which can be used from inside tests.
will cause an exception. TestCase provides four attributes standard: The
currently executing method object, the TestContext object, the TestStatus
object and the Asserter object.

TestCase maps attribute names to private internal attributes. This is
done to make sure attributes are "natural" for use in both NQP and
Winxed. Also, the names need to be translated anyway to allow them to
be intercepted. Here's a basic mapping:
Winxed, and also that attributes are not modified directly by test code.
Also, the names need to be translated anyway to allow them to be
intercepted. Here's a basic mapping example:

"attr" -> "test_attr"
"$!attr" -> "test_attr"

The attributes "context" and "$!context" both map to the attribute
The attributes "context" and "$!context" both map to the private attribute
"test_context. "method" and "$!method" both map to "test_method".
Subclasses of TestCase can follow this pattern to provide access to
additional attributes, if needed.
Expand All @@ -47,17 +45,14 @@ class Rosella.Test.TestCase
// agnostic way.
function get_attr_str[vtable](string attr_raw)
{
var myclass = class Rosella.Test.TestCase;
var value = null;
string attr = attr_raw;
if (substr(attr, 0, 2) == '$!')
attr = substr(attr, 2);
attr = "test_" + attr;
try {
value = getattribute_private(self, myclass, attr);
return getattribute_private(self, class Rosella.Test.TestCase, "test_" + attr);
} catch(e) {
Rosella.Error.invalid(__FUNCTION__, "TestCase does not have an attribute '" + attr_raw + "'");
}
return value;
return null;
}
}
5 changes: 0 additions & 5 deletions src/test/TestContext.winxed
Expand Up @@ -20,11 +20,6 @@ class Rosella.Test.TestContext
for running tests. These are not required for normal running of
the Suite, and can be optionally disallowed or overridden in
custom Context objects.

Notice that if you don't provide some of these things, they won't
be available to running tests. For instance, this is the only
mechanism for marking a test as todo'd, so if you take that away
you won't be able to use that.
*/

// Get a named data value
Expand Down
6 changes: 4 additions & 2 deletions src/test/suitefactory/List.winxed
Expand Up @@ -8,9 +8,11 @@ class Rosella.Test.SuiteFactory.List : Rosella.Test.SuiteFactory
*/

// Constructor
function List(var suite_type)
function List(var suite_type [optional], int has_type [opt_flag])
{
self.SuiteFactory(suite_type);
if (has_type)
self.SuiteFactory(suite_type);
else self.SuiteFactory();
}

// Get a hash of test methods, one for each item in the data aggregate
Expand Down
6 changes: 4 additions & 2 deletions src/test/suitefactory/Vector.winxed
Expand Up @@ -10,9 +10,11 @@ class Rosella.Test.SuiteFactory.Vector : Rosella.Test.SuiteFactory
*/

// Constructor
function Vector(var suite_type)
function Vector(var suite_type [optional], int has_type [opt_flag])
{
self.SuiteFactory(suite_type);
if (has_type)
self.SuiteFactory(suite_type);
else self.SuiteFactory();
}

// Get a hash of test methods, one for each item in the data aggregate
Expand Down

0 comments on commit d1aa335

Please sign in to comment.