Merge pull request #1295 from jshayes/nested-describe

Support for nested describe blocks
This commit is contained in:
Nuno Maduro
2024-10-22 13:41:38 +01:00
committed by GitHub
26 changed files with 847 additions and 33 deletions

View File

@ -15,7 +15,7 @@
↓ todo on describe → should not fail
↓ todo on describe → should run
TODO Tests\Features\Todo - 7 todos
TODO Tests\Features\Todo - 28 todos
↓ something todo later
↓ something todo later chained
↓ something todo later chained and with function body
@ -24,6 +24,52 @@
↓ it may have an associated PR #1
↓ it may have an associated note
// a note
↓ todo on describe → todo block → nested inside todo block → it should not execute
↓ todo on describe → todo block → nested inside todo block → it should set the note
// hi
↓ todo on describe → todo block → describe with note → it should apply the note to a test without a todo
// describe note
↓ todo on describe → todo block → describe with note → it should apply the note to a test with a todo
// describe note
↓ todo on describe → todo block → describe with note → it should apply the note as well as the note from the test
// describe note
// test note
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes to a test without a todo
// describe note
// nested describe note
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes to a test with a todo
// describe note
// nested describe note
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes as well as the note from the test
// describe note
// nested describe note
// test note
↓ todo on describe → todo block → it should not execute
↓ todo on test after describe block
↓ todo with note on test after describe block
// test note
↓ todo on beforeEach → todo block → nested inside todo block → it should not execute
↓ todo on beforeEach → todo block → describe with note → it should apply the note to a test without a todo
// describe note
↓ todo on beforeEach → todo block → describe with note → it should apply the note to a test with a todo
// describe note
↓ todo on beforeEach → todo block → describe with note → it should apply the note as well as the note from the test
// describe note
// test note
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes to a test without a todo
// describe note
// nested describe note
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes to a test with a todo
// describe note
// nested describe note
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes as well as the note from the test
// describe note
// nested describe note
// test note
↓ todo on beforeEach → todo block → it should not execute
↓ todo on test after describe block with beforeEach
↓ todo with note on test after describe block with beforeEach
// test note
PASS Tests\CustomTestCase\ChildTest
✓ override method
@ -34,6 +80,6 @@
PASS Tests\CustomTestCase\ParentTest
✓ override method
Tests: 17 todos, 3 passed (3 assertions)
Tests: 38 todos, 3 passed (20 assertions)
Duration: x.xxs

View File

@ -15,7 +15,7 @@
↓ todo on describe → should not fail
↓ todo on describe → should run
TODO Tests\Features\Todo - 7 todos
TODO Tests\Features\Todo - 28 todos
↓ something todo later
↓ something todo later chained
↓ something todo later chained and with function body
@ -24,6 +24,52 @@
↓ it may have an associated PR #1
↓ it may have an associated note
// a note
↓ todo on describe → todo block → nested inside todo block → it should not execute
↓ todo on describe → todo block → nested inside todo block → it should set the note
// hi
↓ todo on describe → todo block → describe with note → it should apply the note to a test without a todo
// describe note
↓ todo on describe → todo block → describe with note → it should apply the note to a test with a todo
// describe note
↓ todo on describe → todo block → describe with note → it should apply the note as well as the note from the test
// describe note
// test note
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes to a test without a todo
// describe note
// nested describe note
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes to a test with a todo
// describe note
// nested describe note
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes as well as the note from the test
// describe note
// nested describe note
// test note
↓ todo on describe → todo block → it should not execute
↓ todo on test after describe block
↓ todo with note on test after describe block
// test note
↓ todo on beforeEach → todo block → nested inside todo block → it should not execute
↓ todo on beforeEach → todo block → describe with note → it should apply the note to a test without a todo
// describe note
↓ todo on beforeEach → todo block → describe with note → it should apply the note to a test with a todo
// describe note
↓ todo on beforeEach → todo block → describe with note → it should apply the note as well as the note from the test
// describe note
// test note
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes to a test without a todo
// describe note
// nested describe note
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes to a test with a todo
// describe note
// nested describe note
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes as well as the note from the test
// describe note
// nested describe note
// test note
↓ todo on beforeEach → todo block → it should not execute
↓ todo on test after describe block with beforeEach
↓ todo with note on test after describe block with beforeEach
// test note
PASS Tests\CustomTestCase\ChildTest
✓ override method
@ -34,6 +80,6 @@
PASS Tests\CustomTestCase\ParentTest
✓ override method
Tests: 17 todos, 3 passed (3 assertions)
Tests: 38 todos, 3 passed (20 assertions)
Duration: x.xxs

View File

@ -15,7 +15,7 @@
↓ todo on describe → should not fail
↓ todo on describe → should run
TODO Tests\Features\Todo - 7 todos
TODO Tests\Features\Todo - 28 todos
↓ something todo later
↓ something todo later chained
↓ something todo later chained and with function body
@ -24,6 +24,52 @@
↓ it may have an associated PR #1
↓ it may have an associated note
// a note
↓ todo on describe → todo block → nested inside todo block → it should not execute
↓ todo on describe → todo block → nested inside todo block → it should set the note
// hi
↓ todo on describe → todo block → describe with note → it should apply the note to a test without a todo
// describe note
↓ todo on describe → todo block → describe with note → it should apply the note to a test with a todo
// describe note
↓ todo on describe → todo block → describe with note → it should apply the note as well as the note from the test
// describe note
// test note
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes to a test without a todo
// describe note
// nested describe note
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes to a test with a todo
// describe note
// nested describe note
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes as well as the note from the test
// describe note
// nested describe note
// test note
↓ todo on describe → todo block → it should not execute
↓ todo on test after describe block
↓ todo with note on test after describe block
// test note
↓ todo on beforeEach → todo block → nested inside todo block → it should not execute
↓ todo on beforeEach → todo block → describe with note → it should apply the note to a test without a todo
// describe note
↓ todo on beforeEach → todo block → describe with note → it should apply the note to a test with a todo
// describe note
↓ todo on beforeEach → todo block → describe with note → it should apply the note as well as the note from the test
// describe note
// test note
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes to a test without a todo
// describe note
// nested describe note
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes to a test with a todo
// describe note
// nested describe note
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes as well as the note from the test
// describe note
// nested describe note
// test note
↓ todo on beforeEach → todo block → it should not execute
↓ todo on test after describe block with beforeEach
↓ todo with note on test after describe block with beforeEach
// test note
PASS Tests\CustomTestCase\ChildTest
✓ override method
@ -34,6 +80,6 @@
PASS Tests\CustomTestCase\ParentTest
✓ override method
Tests: 17 todos, 3 passed (3 assertions)
Tests: 38 todos, 3 passed (20 assertions)
Duration: x.xxs

View File

@ -15,7 +15,7 @@
↓ todo on describe → should not fail
↓ todo on describe → should run
TODO Tests\Features\Todo - 7 todos
TODO Tests\Features\Todo - 28 todos
↓ something todo later
↓ something todo later chained
↓ something todo later chained and with function body
@ -24,6 +24,52 @@
↓ it may have an associated PR #1
↓ it may have an associated note
// a note
↓ todo on describe → todo block → nested inside todo block → it should not execute
↓ todo on describe → todo block → nested inside todo block → it should set the note
// hi
↓ todo on describe → todo block → describe with note → it should apply the note to a test without a todo
// describe note
↓ todo on describe → todo block → describe with note → it should apply the note to a test with a todo
// describe note
↓ todo on describe → todo block → describe with note → it should apply the note as well as the note from the test
// describe note
// test note
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes to a test without a todo
// describe note
// nested describe note
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes to a test with a todo
// describe note
// nested describe note
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes as well as the note from the test
// describe note
// nested describe note
// test note
↓ todo on describe → todo block → it should not execute
↓ todo on test after describe block
↓ todo with note on test after describe block
// test note
↓ todo on beforeEach → todo block → nested inside todo block → it should not execute
↓ todo on beforeEach → todo block → describe with note → it should apply the note to a test without a todo
// describe note
↓ todo on beforeEach → todo block → describe with note → it should apply the note to a test with a todo
// describe note
↓ todo on beforeEach → todo block → describe with note → it should apply the note as well as the note from the test
// describe note
// test note
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes to a test without a todo
// describe note
// nested describe note
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes to a test with a todo
// describe note
// nested describe note
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes as well as the note from the test
// describe note
// nested describe note
// test note
↓ todo on beforeEach → todo block → it should not execute
↓ todo on test after describe block with beforeEach
↓ todo with note on test after describe block with beforeEach
// test note
PASS Tests\CustomTestCase\ChildTest
✓ override method
@ -34,6 +80,6 @@
PASS Tests\CustomTestCase\ParentTest
✓ override method
Tests: 17 todos, 3 passed (3 assertions)
Tests: 38 todos, 3 passed (20 assertions)
Duration: x.xxs

View File

@ -27,6 +27,8 @@
PASS Tests\Features\AfterEach
✓ it does not get executed before the test
✓ it gets executed after the test
✓ outer → inner → it does not get executed before the test
✓ outer → inner → it should call all parent afterEach functions
PASS Tests\Features\Assignee
✓ it may be associated with an assignee [@nunomaduro, @taylorotwell]
@ -40,6 +42,9 @@
PASS Tests\Features\BeforeEach
✓ it gets executed before each test
✓ it gets executed before each test once again
✓ outer → inner → it should call all parent beforeEach functions
✓ with expectations → nested block → test
✓ with expectations → test
PASS Tests\Features\BeforeEachProxiesToTestCallWithExpectations
✓ runs 1
@ -178,6 +183,14 @@
✓ it may be used with high order with dataset "informal"
✓ it may be used with high order even when bound with dataset "formal"
✓ it may be used with high order even when bound with dataset "informal"
✓ with on nested describe → nested → before inner describe block with (1)
✓ with on nested describe → nested → describe → it should include the with value from all parent describe blocks with (1) / (2)
✓ with on nested describe → nested → describe → should include the with value from all parent describe blocks and the test with (1) / (2) / (3)
✓ with on nested describe → nested → after inner describe block with (1)
✓ after describe block with (5)
✓ it may be used with high order after describe block with dataset "formal"
✓ it may be used with high order after describe block with dataset "informal"
✓ after describe block with named dataset with ('after')
PASS Tests\Features\Depends
✓ first
@ -188,6 +201,13 @@
✓ depends run test only once
✓ it asserts true is true
✓ depends works with the correct test name
✓ describe block → first in describe
✓ describe block → second in describe
✓ describe block → third in describe
✓ describe block → nested describe → first in nested describe
✓ describe block → nested describe → second in nested describe
✓ describe block → nested describe → third in nested describe
✓ depends on test after describe block
PASS Tests\Features\DependsInheritance
✓ it is a test
@ -215,6 +235,7 @@
✓ depends on describe → bar
✓ depends on describe using with → foo with (3)
✓ depends on describe using with → bar with (3)
✓ with test after describe → it should run the before each
PASS Tests\Features\DescriptionLess
✓ get 'foo'
@ -1067,9 +1088,22 @@
✓ nested → it may have static note and runtime note
// This is before each static note
// This is describe static note
// This is before each describe static note
// This is a static note within describe
// This is before each runtime note
// This is before each describe runtime note
// This is a runtime note within describe
✓ nested → describe nested within describe → it may have a static note and runtime note
// This is before each static note
// This is describe static note
// This is before each describe static note
// This is a nested describe static note
// This is before each nested describe static note
// This is a static note within a nested describe
// This is before each runtime note
// This is before each describe runtime note
// This is before each nested describe runtime note
// This is a runtime note within a nested describe
✓ multiple notes
// This is before each static note
// This is before each runtime note
@ -1199,6 +1233,23 @@
✓ multiple times with repeat iterator with multiple dataset ('c') / ('d') @ repetition 2 of 2
✓ multiple times with repeat iterator with multiple dataset ('c') / ('e') @ repetition 2 of 2
✓ multiple times with repeat iterator with multiple dataset ('c') / ('f') @ repetition 2 of 2
✓ describe blocks → multiple times @ repetition 1 of 3
✓ describe blocks → multiple times @ repetition 2 of 3
✓ describe blocks → multiple times @ repetition 3 of 3
✓ describe blocks → describe with repeat → test with no repeat should repeat the number of times specified in the parent describe block @ repetition 1 of 3
✓ describe blocks → describe with repeat → test with no repeat should repeat the number of times specified in the parent describe block @ repetition 2 of 3
✓ describe blocks → describe with repeat → test with no repeat should repeat the number of times specified in the parent describe block @ repetition 3 of 3
✓ describe blocks → describe with repeat → test with repeat should repeat the number of times specified in the test @ repetition 1 of 2
✓ describe blocks → describe with repeat → test with repeat should repeat the number of times specified in the test @ repetition 2 of 2
✓ describe blocks → describe with repeat → nested describe without repeat → test with no repeat should repeat the number of times specified in the parent's parent describe block @ repetition 1 of 3
✓ describe blocks → describe with repeat → nested describe without repeat → test with no repeat should repeat the number of times specified in the parent's parent describe block @ repetition 2 of 3
✓ describe blocks → describe with repeat → nested describe without repeat → test with no repeat should repeat the number of times specified in the parent's parent describe block @ repetition 3 of 3
✓ describe blocks → describe with repeat → nested describe without repeat → test with repeat should repeat the number of times specified in the test @ repetition 1 of 2
✓ describe blocks → describe with repeat → nested describe without repeat → test with repeat should repeat the number of times specified in the test @ repetition 2 of 2
✓ describe blocks → describe with repeat → nested describe with repeat → test with no repeat should repeat the number of times specified in the parent describe block @ repetition 1 of 2
✓ describe blocks → describe with repeat → nested describe with repeat → test with no repeat should repeat the number of times specified in the parent describe block @ repetition 2 of 2
✓ describe blocks → describe with repeat → nested describe with repeat → test with repeat should repeat the number of times specified in the test @ repetition 1 of 2
✓ describe blocks → describe with repeat → nested describe with repeat → test with repeat should repeat the number of times specified in the test @ repetition 2 of 2
PASS Tests\Features\ScopedDatasets\Directory\NestedDirectory1\TestFileInNestedDirectoryWithDatasetsFile
✓ uses dataset with (1)
@ -1255,6 +1306,14 @@
- it skips when skip after assertion
- it can use something in the test case as a condition → This test was skipped
- it can user higher order callables and skip
- skip on describe → skipped tests → nested inside skipped block → it should not execute
- skip on describe → skipped tests → it should not execute
✓ skip on describe → it should execute
- skip on beforeEach → skipped tests → nested inside skipped block → it should not execute
- skip on beforeEach → skipped tests → it should not execute
✓ skip on beforeEach → it should execute
✓ it does not skip after the describe block
- it can skip after the describe block
WARN Tests\Features\SkipOnPhp
✓ it can run on php version
@ -1275,7 +1334,7 @@
✓ nested → it may be associated with an ticket #1, #4, #5, #6, #3
// an note between an the ticket
PASS Tests\Features\Todo - 7 todos
PASS Tests\Features\Todo - 28 todos
↓ something todo later
↓ something todo later chained
↓ something todo later chained and with function body
@ -1285,6 +1344,54 @@
↓ it may have an associated PR #1
↓ it may have an associated note
// a note
↓ todo on describe → todo block → nested inside todo block → it should not execute
↓ todo on describe → todo block → nested inside todo block → it should set the note
// hi
↓ todo on describe → todo block → describe with note → it should apply the note to a test without a todo
// describe note
↓ todo on describe → todo block → describe with note → it should apply the note to a test with a todo
// describe note
↓ todo on describe → todo block → describe with note → it should apply the note as well as the note from the test
// describe note
// test note
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes to a test without a todo
// describe note
// nested describe note
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes to a test with a todo
// describe note
// nested describe note
↓ todo on describe → todo block → describe with note → nested describe with note → it should apply all parent notes as well as the note from the test
// describe note
// nested describe note
// test note
↓ todo on describe → todo block → it should not execute
✓ todo on describe → it should execute
↓ todo on test after describe block
↓ todo with note on test after describe block
// test note
↓ todo on beforeEach → todo block → nested inside todo block → it should not execute
↓ todo on beforeEach → todo block → describe with note → it should apply the note to a test without a todo
// describe note
↓ todo on beforeEach → todo block → describe with note → it should apply the note to a test with a todo
// describe note
↓ todo on beforeEach → todo block → describe with note → it should apply the note as well as the note from the test
// describe note
// test note
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes to a test without a todo
// describe note
// nested describe note
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes to a test with a todo
// describe note
// nested describe note
↓ todo on beforeEach → todo block → describe with note → nested describe with note → it should apply all parent notes as well as the note from the test
// describe note
// nested describe note
// test note
↓ todo on beforeEach → todo block → it should not execute
✓ todo on beforeEach → it should execute
↓ todo on test after describe block with beforeEach
↓ todo with note on test after describe block with beforeEach
// test note
WARN Tests\Features\Warnings
! warning → Undefined property: P\Tests\Features\Warnings::$fooqwdfwqdfqw
@ -1433,6 +1540,13 @@
✓ preset invalid name
✓ preset → myFramework
PASS Tests\Unit\Support\Arr
✓ last → it should return false for an empty arary
✓ last → it should return the last element for an array with a single element
✓ last → it should return the last element for an array without changing the internal pointer
✓ last → it should return the last element for an associative array without changing the internal pointer
✓ last → it should return the last element for an mixed key array without changing the internal pointer
PASS Tests\Unit\Support\Backtrace
✓ it gets file name from called file
@ -1584,4 +1698,4 @@
WARN Tests\Visual\Version
- visual snapshot of help command output
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 17 todos, 28 skipped, 1095 passed (2648 assertions)
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 38 todos, 33 skipped, 1144 passed (2736 assertions)

View File

@ -26,3 +26,25 @@ it('gets executed after the test', function () {
afterEach(function () {
$this->state->bar = 2;
});
describe('outer', function () {
afterEach(function () {
$this->state->bar++;
});
describe('inner', function () {
afterEach(function () {
$this->state->bar++;
});
it('does not get executed before the test', function () {
expect($this->state)->toHaveProperty('bar');
expect($this->state->bar)->toBe(2);
});
it('should call all parent afterEach functions', function () {
expect($this->state)->toHaveProperty('bar');
expect($this->state->bar)->toBe(4);
});
});
});

View File

@ -25,3 +25,29 @@ it('gets executed before each test once again', function () {
beforeEach(function () {
$this->bar++;
});
describe('outer', function () {
beforeEach(function () {
$this->bar++;
});
describe('inner', function () {
beforeEach(function () {
$this->bar++;
});
it('should call all parent beforeEach functions', function () {
expect($this->bar)->toBe(3);
});
});
});
describe('with expectations', function () {
beforeEach()->expect(true)->toBeTrue();
describe('nested block', function () {
test('test', function () {});
});
test('test', function () {});
});

View File

@ -392,3 +392,40 @@ it('may be used with high order even when bound')
->with('greeting-bound')
->expect(fn (string $greeting) => $greeting)
->throws(InvalidArgumentException::class);
describe('with on nested describe', function () {
describe('nested', function () {
test('before inner describe block', function (...$args) {
expect($args)->toBe([1]);
});
describe('describe', function () {
it('should include the with value from all parent describe blocks', function (...$args) {
expect($args)->toBe([1, 2]);
});
test('should include the with value from all parent describe blocks and the test', function (...$args) {
expect($args)->toBe([1, 2, 3]);
})->with([3]);
})->with([2]);
test('after inner describe block', function (...$args) {
expect($args)->toBe([1]);
});
})->with([1]);
});
test('after describe block', function (...$args) {
expect($args)->toBe([5]);
})->with([5]);
it('may be used with high order after describe block')
->with('greeting-string')
->expect(fn (string $greeting) => $greeting)
->throwsNoExceptions();
dataset('after-describe', ['after']);
test('after describe block with named dataset', function (...$args) {
expect($args)->toBe(['after']);
})->with('after-describe');

View File

@ -36,3 +36,43 @@ test('depends run test only once', function () use (&$runCounter) {
// Regression tests. See https://github.com/pestphp/pest/pull/216
it('asserts true is true')->assertTrue(true);
test('depends works with the correct test name')->assertTrue(true)->depends('it asserts true is true');
describe('describe block', function () {
$runCounter = 0;
test('first in describe', function () use (&$runCounter) {
$runCounter++;
expect(true)->toBeTrue();
});
test('second in describe', function () use (&$runCounter) {
expect($runCounter)->toBe(1);
$runCounter++;
})->depends('first in describe');
test('third in describe', function () use (&$runCounter) {
expect($runCounter)->toBe(2);
})->depends('second in describe');
describe('nested describe', function () {
$runCounter = 0;
test('first in nested describe', function () use (&$runCounter) {
$runCounter++;
expect(true)->toBeTrue();
});
test('second in nested describe', function () use (&$runCounter) {
expect($runCounter)->toBe(1);
$runCounter++;
})->depends('first in nested describe');
test('third in nested describe', function () use (&$runCounter) {
expect($runCounter)->toBe(2);
})->depends('second in nested describe');
});
});
test('depends on test after describe block', function () use (&$runCounter) {
expect($runCounter)->toBe(2);
})->depends('first', 'second');

View File

@ -96,3 +96,15 @@ describe('depends on describe using with', function () {
expect($foo + $foo)->toBe(6);
})->depends('foo');
})->with([3]);
describe('with test after describe', function () {
beforeEach(function () {
$this->count++;
});
describe('foo', function () {});
it('should run the before each', function () {
expect($this->count)->toBe(2);
});
});

View File

@ -21,11 +21,27 @@ it('may have static note and runtime note', function () {
})->note('This is a static note');
describe('nested', function () {
beforeEach(function () {
$this->note('This is before each describe runtime note');
})->note('This is before each describe static note');
it('may have static note and runtime note', function () {
expect(true)->toBeTrue(true);
$this->note('This is a runtime note within describe');
})->note('This is a static note within describe');
describe('describe nested within describe', function () {
beforeEach(function () {
$this->note('This is before each nested describe runtime note');
})->note('This is before each nested describe static note');
it('may have a static note and runtime note', function () {
expect(true)->toBeTrue(true);
$this->note('This is a runtime note within a nested describe');
})->note('This is a static note within a nested describe');
})->note('This is a nested describe static note');
})->note('This is describe static note');
test('multiple notes', function () {

View File

@ -43,3 +43,39 @@ test('multiple times with repeat iterator with multiple dataset', function (stri
->toBeNumeric()
->toBeGreaterThan(0);
})->repeat(times: 2)->with(['a', 'b', 'c'], ['d', 'e', 'f']);
describe('describe blocks', function () {
test('multiple times', function () {
expect(true)->toBeTrue();
})->repeat(times: 3);
describe('describe with repeat', function () {
test('test with no repeat should repeat the number of times specified in the parent describe block', function () {
expect(true)->toBeTrue();
});
test('test with repeat should repeat the number of times specified in the test', function () {
expect(true)->toBeTrue();
})->repeat(times: 2);
describe('nested describe without repeat', function () {
test("test with no repeat should repeat the number of times specified in the parent's parent describe block", function () {
expect(true)->toBeTrue();
});
test('test with repeat should repeat the number of times specified in the test', function () {
expect(true)->toBeTrue();
})->repeat(times: 2);
});
describe('nested describe with repeat', function () {
test('test with no repeat should repeat the number of times specified in the parent describe block', function () {
expect(true)->toBeTrue();
});
test('test with repeat should repeat the number of times specified in the test', function () {
expect(true)->toBeTrue();
})->repeat(times: 2);
})->repeat(times: 2);
})->repeat(times: 3);
});

View File

@ -54,3 +54,81 @@ it('can user higher order callables and skip')
return $this->shouldSkip;
})
->toBeFalse();
describe('skip on describe', function () {
beforeEach(function () {
$this->ran = false;
});
afterEach(function () {
match ($this->name()) {
'__pest_evaluable__skip_on_describe__→__skipped_tests__→__nested_inside_skipped_block__→_it_should_not_execute' => expect($this->ran)->toBe(false),
'__pest_evaluable__skip_on_describe__→__skipped_tests__→_it_should_not_execute' => expect($this->ran)->toBe(false),
'__pest_evaluable__skip_on_describe__→_it_should_execute' => expect($this->ran)->toBe(true),
default => $this->fail('Unexpected test name: '.$this->name()),
};
});
describe('skipped tests', function () {
describe('nested inside skipped block', function () {
it('should not execute', function () {
$this->ran = true;
$this->fail();
});
});
it('should not execute', function () {
$this->ran = true;
$this->fail();
});
})->skip();
it('should execute', function () {
$this->ran = true;
expect($this->ran)->toBe(true);
});
});
describe('skip on beforeEach', function () {
beforeEach(function () {
$this->ran = false;
});
afterEach(function () {
match ($this->name()) {
'__pest_evaluable__skip_on_beforeEach__→__skipped_tests__→__nested_inside_skipped_block__→_it_should_not_execute' => expect($this->ran)->toBe(false),
'__pest_evaluable__skip_on_beforeEach__→__skipped_tests__→_it_should_not_execute' => expect($this->ran)->toBe(false),
'__pest_evaluable__skip_on_beforeEach__→_it_should_execute' => expect($this->ran)->toBe(true),
default => $this->fail('Unexpected test name: '.$this->name()),
};
});
describe('skipped tests', function () {
beforeEach()->skip();
describe('nested inside skipped block', function () {
it('should not execute', function () {
$this->ran = true;
$this->fail();
});
});
it('should not execute', function () {
$this->ran = true;
$this->fail();
});
});
it('should execute', function () {
$this->ran = true;
expect($this->ran)->toBe(true);
});
});
it('does not skip after the describe block', function () {
expect(true)->toBeTrue();
});
it('can skip after the describe block', function () {
expect(true)->toBeTrue();
})->skip();

View File

@ -27,3 +27,175 @@ it('may have an associated PR', function () {
it('may have an associated note', function () {
expect(true)->toBeTrue();
})->todo(note: 'a note');
describe('todo on describe', function () {
beforeEach(function () {
$this->ran = false;
});
afterEach(function () {
match ($this->name()) {
'__pest_evaluable__todo_on_describe__→__todo_block__→__nested_inside_todo_block__→_it_should_not_execute' => expect($this->ran)->toBe(false),
'__pest_evaluable__todo_on_describe__→__todo_block__→__nested_inside_todo_block__→_it_should_set_the_note' => expect($this->ran)->toBe(false),
'__pest_evaluable__todo_on_describe__→__todo_block__→__describe_with_note__→_it_should_apply_the_note_to_a_test_without_a_todo' => expect($this->ran)->toBe(false),
'__pest_evaluable__todo_on_describe__→__todo_block__→__describe_with_note__→_it_should_apply_the_note_to_a_test_with_a_todo' => expect($this->ran)->toBe(false),
'__pest_evaluable__todo_on_describe__→__todo_block__→__describe_with_note__→_it_should_apply_the_note_as_well_as_the_note_from_the_test' => expect($this->ran)->toBe(false),
'__pest_evaluable__todo_on_describe__→__todo_block__→__describe_with_note__→__nested_describe_with_note__→_it_should_apply_all_parent_notes_to_a_test_without_a_todo' => expect($this->ran)->toBe(false),
'__pest_evaluable__todo_on_describe__→__todo_block__→__describe_with_note__→__nested_describe_with_note__→_it_should_apply_all_parent_notes_to_a_test_with_a_todo' => expect($this->ran)->toBe(false),
'__pest_evaluable__todo_on_describe__→__todo_block__→__describe_with_note__→__nested_describe_with_note__→_it_should_apply_all_parent_notes_as_well_as_the_note_from_the_test' => expect($this->ran)->toBe(false),
'__pest_evaluable__todo_on_describe__→__todo_block__→_it_should_not_execute' => expect($this->ran)->toBe(false),
'__pest_evaluable__todo_on_describe__→_it_should_execute' => expect($this->ran)->toBe(true),
default => $this->fail('Unexpected test name: '.$this->name()),
};
});
describe('todo block', function () {
describe('nested inside todo block', function () {
it('should not execute', function () {
$this->ran = true;
$this->fail();
});
it('should set the note', function () {
$this->ran = true;
$this->fail();
})->todo(note: 'hi');
});
describe('describe with note', function () {
it('should apply the note to a test without a todo', function () {
$this->ran = true;
$this->fail();
});
it('should apply the note to a test with a todo', function () {
$this->ran = true;
$this->fail();
})->todo();
it('should apply the note as well as the note from the test', function () {
$this->ran = true;
$this->fail();
})->todo(note: 'test note');
describe('nested describe with note', function () {
it('should apply all parent notes to a test without a todo', function () {
$this->ran = true;
$this->fail();
});
it('should apply all parent notes to a test with a todo', function () {
$this->ran = true;
$this->fail();
})->todo();
it('should apply all parent notes as well as the note from the test', function () {
$this->ran = true;
$this->fail();
})->todo(note: 'test note');
})->todo(note: 'nested describe note');
})->todo(note: 'describe note');
it('should not execute', function () {
$this->ran = true;
$this->fail();
});
})->todo();
it('should execute', function () {
$this->ran = true;
expect($this->ran)->toBe(true);
});
});
test('todo on test after describe block', function () {
$this->fail();
})->todo();
test('todo with note on test after describe block', function () {
$this->fail();
})->todo(note: 'test note');
describe('todo on beforeEach', function () {
beforeEach(function () {
$this->ran = false;
});
afterEach(function () {
match ($this->name()) {
'__pest_evaluable__todo_on_beforeEach__→__todo_block__→__nested_inside_todo_block__→_it_should_not_execute' => expect($this->ran)->toBe(false),
'__pest_evaluable__todo_on_beforeEach__→__todo_block__→_it_should_not_execute' => expect($this->ran)->toBe(false),
'__pest_evaluable__todo_on_beforeEach__→__todo_block__→__describe_with_note__→_it_should_apply_the_note_to_a_test_without_a_todo' => expect($this->ran)->toBe(false),
'__pest_evaluable__todo_on_beforeEach__→__todo_block__→__describe_with_note__→_it_should_apply_the_note_to_a_test_with_a_todo' => expect($this->ran)->toBe(false),
'__pest_evaluable__todo_on_beforeEach__→__todo_block__→__describe_with_note__→_it_should_apply_the_note_as_well_as_the_note_from_the_test' => expect($this->ran)->toBe(false),
'__pest_evaluable__todo_on_beforeEach__→__todo_block__→__describe_with_note__→__nested_describe_with_note__→_it_should_apply_all_parent_notes_to_a_test_without_a_todo' => expect($this->ran)->toBe(false),
'__pest_evaluable__todo_on_beforeEach__→__todo_block__→__describe_with_note__→__nested_describe_with_note__→_it_should_apply_all_parent_notes_to_a_test_with_a_todo' => expect($this->ran)->toBe(false),
'__pest_evaluable__todo_on_beforeEach__→__todo_block__→__describe_with_note__→__nested_describe_with_note__→_it_should_apply_all_parent_notes_as_well_as_the_note_from_the_test' => expect($this->ran)->toBe(false),
'__pest_evaluable__todo_on_beforeEach__→_it_should_execute' => expect($this->ran)->toBe(true),
default => $this->fail('Unexpected test name: '.$this->name()),
};
});
describe('todo block', function () {
beforeEach()->todo();
describe('nested inside todo block', function () {
it('should not execute', function () {
$this->ran = true;
$this->fail();
});
});
describe('describe with note', function () {
it('should apply the note to a test without a todo', function () {
$this->ran = true;
$this->fail();
});
it('should apply the note to a test with a todo', function () {
$this->ran = true;
$this->fail();
})->todo();
it('should apply the note as well as the note from the test', function () {
$this->ran = true;
$this->fail();
})->todo(note: 'test note');
describe('nested describe with note', function () {
it('should apply all parent notes to a test without a todo', function () {
$this->ran = true;
$this->fail();
});
it('should apply all parent notes to a test with a todo', function () {
$this->ran = true;
$this->fail();
})->todo();
it('should apply all parent notes as well as the note from the test', function () {
$this->ran = true;
$this->fail();
})->todo(note: 'test note');
})->todo(note: 'nested describe note');
})->todo(note: 'describe note');
it('should not execute', function () {
$this->ran = true;
$this->fail();
});
});
it('should execute', function () {
$this->ran = true;
expect($this->ran)->toBe(true);
});
});
test('todo on test after describe block with beforeEach', function () {
$this->fail();
})->todo();
test('todo with note on test after describe block with beforeEach', function () {
$this->fail();
})->todo(note: 'test note');

View File

@ -0,0 +1,49 @@
<?php
use Pest\Support\Arr;
describe('last', function () {
it('should return false for an empty arary', function () {
expect(Arr::last([]))->toBeFalse();
});
it('should return the last element for an array with a single element', function () {
expect(Arr::last([1]))->toBe(1);
});
it('should return the last element for an array without changing the internal pointer', function () {
$array = [1, 2, 3];
expect(Arr::last($array))->toBe(3);
expect(current($array))->toBe(1);
next($array);
expect(current($array))->toBe(2);
expect(Arr::last($array))->toBe(3);
expect(current($array))->toBe(2);
});
it('should return the last element for an associative array without changing the internal pointer', function () {
$array = ['first' => 1, 'second' => 2, 'third' => 3];
expect(Arr::last($array))->toBe(3);
expect(current($array))->toBe(1);
next($array);
expect(current($array))->toBe(2);
expect(Arr::last($array))->toBe(3);
expect(current($array))->toBe(2);
});
it('should return the last element for an mixed key array without changing the internal pointer', function () {
$array = ['first' => 1, 2, 'third' => 3];
expect(Arr::last($array))->toBe(3);
expect(current($array))->toBe(1);
next($array);
expect(current($array))->toBe(2);
expect(Arr::last($array))->toBe(3);
expect(current($array))->toBe(2);
});
});

View File

@ -16,7 +16,7 @@ $run = function () {
test('parallel', function () use ($run) {
expect($run('--exclude-group=integration'))
->toContain('Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 17 todos, 19 skipped, 1085 passed (2624 assertions)')
->toContain('Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 38 todos, 24 skipped, 1134 passed (2712 assertions)')
->toContain('Parallel: 3 processes');
})->skipOnWindows();