public static function gensuite($config = array(), $current_depth = 1) { $config = array_merge(array('befores' => 0, 'before_alls' => 0, 'afters' => 0, 'after_alls' => 0, 'tests' => 1, 'depth' => 0, 'describes' => array('L', 'R'), 'callbacks' => array('it' => function ($ctx) { expect(true)->to->eql(true); }, 'before' => function ($ctx) { $ctx->value = 3; }, 'before_all' => function ($ctx) { $ctx->value = 5; }, 'after' => function ($ctx) { $ctx->value = 7; }, 'after_all' => function ($ctx) { $ctx->value = 11; })), $config); if ($config['depth'] == 0) { return; } foreach ($config['describes'] as $side) { describe("Level {$side}{$current_depth}", function ($ctx) use($config, $current_depth) { for ($i = 1; $i <= $config['tests']; $i++) { it("nested {$i}", $config['callbacks']['it']); } for ($i = 1; $i <= $config['befores']; $i++) { before($config['callbacks']['before']); } for ($i = 1; $i <= $config['before_alls']; $i++) { before_all($config['callbacks']['before_all']); } for ($i = 1; $i <= $config['after_alls']; $i++) { after_all($config['callbacks']['after_all']); } for ($i = 1; $i <= $config['afters']; $i++) { after($config['callbacks']['after']); } $config['depth']--; Util::gensuite($config, $current_depth + 1); }); } }
use Matura\Test\User; use Matura\Test\Group; /** * Tests the construction of our test graph via our DSL. */ describe('Matura', function ($ctx) { before(function ($ctx) { // Officially, nesting suites in this manner is unsupported. // A Suite block is automatically created for every test file. $ctx->suite = suite('Suite', function () { describe('Fixture', function ($ctx) { it('TestMethod', function ($ctx) { }); before(function ($ctx) { }); before_all(function ($ctx) { }); }); }); }); describe('Suite', function ($ctx) { before(function ($ctx) { $ctx->describe = $ctx->suite->find('Suite:Fixture'); }); it('should be a Suite Block', function ($ctx) { expect($ctx->suite)->to->be->an('Matura\\Blocks\\Suite'); }); it('should have a name', function ($ctx) { expect($ctx->suite->getName())->to->eql('Suite'); }); it('should have a path', function ($ctx) { expect($ctx->suite->path())->to->eql('Suite');
// Level L1:Level R2:nested 1 expect($result->totalTests())->to->eql(2); }); }); }); describe('Error Capture and Reporting', function ($ctx) { before(function ($ctx) { $ctx->spy = $spy = Mockery::mock()->shouldIgnoreMissing(); $ctx->listener = Mockery::mock('Matura\\Events\\Listener')->shouldIgnoreMissing(); $ctx->suite = suite('Fixture', function ($inner_ctx) use($spy, $ctx) { $ctx->before_all = before_all(array($spy, 'before_all')); $ctx->after_all = after_all(array($spy, 'after_all')); $ctx->after = after(array($spy, 'after')); $ctx->before = before(array($spy, 'before')); $ctx->describe = describe('Inner', function ($inner_ctx) use($spy, $ctx) { $ctx->inner_before_all = before_all(array($spy, 'inner_before_all')); $ctx->inner_after_all = after_all(array($spy, 'inner_after_all')); $ctx->inner_after = after(array($spy, 'inner_after')); $ctx->inner_before = before(array($spy, 'inner_before')); $ctx->test = it('should have a test case', array($spy, 'it')); }); }); $ctx->suite_runner = new SuiteRunner($ctx->suite, new ResultSet()); $ctx->suite_runner->addListener($ctx->listener); }); describe('At the Suite Level', function ($ctx) { it('should capture before_all errors', function ($ctx) { $ctx->spy->shouldReceive('before_all')->once()->andThrow('\\Exception'); $ctx->suite_runner->run(); $failures = $ctx->suite_runner->getResultSet()->getFailures(); expect($failures)->to->have->length(1);
expect($ctx->before_scalar)->to->be(5); }); it('should have a scalar from the once before hook', function ($ctx) { expect($ctx->once_before_scalar)->to->be(10); }); it('should invoke methods', function ($ctx) { expect($ctx->func(5))->to->eql(5); }); describe('Nested, Undefined Values', function ($ctx) { it('should return null for an undefined value when nested deeper', function ($ctx) { expect($ctx->another_never_set)->to->be(null); }); }); describe('Sibling-Of `Isolation` Block', function ($ctx) { before_all(function ($ctx) { $ctx->once_before_scalar = 15; }); before(function ($ctx) { $ctx->before_scalar = 10; $ctx->group = new Group('staff'); }); it("should have the clobbered value of `once_before_scalar`", function ($ctx) { expect($ctx->once_before_scalar)->to->be(15); }); it("should have the clobbered value of `group`", function ($ctx) { expect($ctx->group->name)->to->be('staff'); }); }); describe('Isolation', function ($ctx) { it("should have the parent `once_before_scalar` and not a sibling's", function ($ctx) { expect($ctx->once_before_scalar)->to->be(10);
}); it('should set the admins group', function ($ctx) { expect($ctx->admins)->to->be->a('Matura\\Test\\Group'); }); it('should skip this test when invoked', function ($ctx) { skip(); }); it('should be strict about undefined variables', function ($ctx) { $arr = array(0); $result = $arr[0] + $arr[1]; }); // Nested blocks help organize tests and allow progressive augmentation of // test context. describe('Inner Block with Before All and Context Clobbering', function ($ctx) { before_all(function ($ctx) { // Do something costly like purge and re-seed a database. $ctx->purged_database = true; }); before(function ($ctx) { $ctx->admins = new Group('modified_admins'); }); it('should inherit context from outer before blocks', function ($ctx) { expect($ctx->bob)->to->be->a('Matura\\Test\\User'); }); it('should shadow context variables from outer contexts if assigned', function ($ctx) { expect($ctx->admins->name)->to->eql('modified_admins'); }); }); xdescribe('Skipped Block', function ($ctx) { it('should skip me because my block has been marked skipped', function ($ctx) { throw new Exception('I should not be invoked'); });