From 47be453399d2a400dc78d34e54dc99b70f5c8ecd Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Sat, 19 Feb 2022 15:51:44 +0200 Subject: [PATCH 01/22] Fix phpunit config --- phpunit.xml.dist | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index a4f58fa..19b71ae 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,26 +1,28 @@ - ./tests - - + + + ./src - - + + From 6a9bd2887b2ca875bd16d057f71218963f401eb1 Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Sat, 12 Mar 2022 17:51:02 +0200 Subject: [PATCH 02/22] Type hints and return types --- src/Asserts/ArtisanAsserts.php | 73 +++------------- src/Asserts/CollectionAsserts.php | 18 +--- src/Asserts/DatabaseAsserts.php | 26 ++---- src/Asserts/EloquentAsserts.php | 84 ++++--------------- src/Asserts/ExceptionAsserts.php | 7 +- src/Asserts/FilesystemAsserts.php | 22 +---- src/Asserts/LogFileAsserts.php | 32 ++----- src/Asserts/ReflectionAsserts.php | 36 ++------ src/Asserts/ScheduleAsserts.php | 33 ++------ src/Asserts/ServiceProviderAsserts.php | 20 +---- src/Helpers/ApplicationHelpers.php | 17 +--- src/Helpers/ArtisanHelpers.php | 14 +--- tests/Asserts/LogFileAssertsTest.php | 8 +- tests/Asserts/ScheduleAssertsTest.php | 4 +- tests/TestCase.php | 18 +--- tests/fixture/app/Comment.php | 5 +- tests/fixture/app/Commentable.php | 4 +- .../Commands/ConfirmableTraitCommand.php | 4 +- .../Console/Commands/ConfirmationCommand.php | 4 +- .../app/Console/Commands/GenericCommand.php | 8 +- .../Console/Commands/RegisteredCommand.php | 4 +- .../Console/Commands/TableOutputCommand.php | 8 +- .../app/Http/Controllers/HomeController.php | 2 - tests/fixture/app/Post.php | 26 ++---- .../app/Providers/FixtureServiceProvider.php | 12 +-- .../database/factories/CommentFactory.php | 4 +- .../database/factories/PostFactory.php | 4 +- .../2016_11_01_131415_create_posts_table.php | 12 +-- ...016_11_01_131425_create_comments_table.php | 12 +-- 29 files changed, 107 insertions(+), 414 deletions(-) diff --git a/src/Asserts/ArtisanAsserts.php b/src/Asserts/ArtisanAsserts.php index eb2d81b..1ff7e75 100644 --- a/src/Asserts/ArtisanAsserts.php +++ b/src/Asserts/ArtisanAsserts.php @@ -10,13 +10,8 @@ trait ArtisanAsserts { /** * Add expectation that the given confirmation question would be shown. - * - * @param string $question - * @param string $command - * @param array $parameters - * @return void */ - protected function willSeeConfirmation(string $question, string $command, array $parameters = []) + protected function willSeeConfirmation(string $question, string $command, array $parameters = []): void { $mock = Mockery::mock("{$command}[confirm]"); $mock->shouldReceive('confirm')->once()->with($question); @@ -26,13 +21,8 @@ protected function willSeeConfirmation(string $question, string $command, array /** * Add expectation that the given confirmation question would not be shown. - * - * @param string $question - * @param string $command - * @param array $parameters - * @return void */ - protected function willNotSeeConfirmation(string $question, string $command, array $parameters = []) + protected function willNotSeeConfirmation(string $question, string $command, array $parameters = []): void { $mock = Mockery::mock("{$command}[confirm]"); $mock->shouldNotReceive('confirm')->with($question); @@ -42,13 +32,8 @@ protected function willNotSeeConfirmation(string $question, string $command, arr /** * Add expectation that the given confirmation question would be shown, and accept it. - * - * @param string $question - * @param string $command - * @param array $parameters - * @return void */ - protected function willGiveConfirmation(string $question, string $command, array $parameters = []) + protected function willGiveConfirmation(string $question, string $command, array $parameters = []): void { $mock = Mockery::mock("{$command}[confirm]"); $mock->shouldReceive('confirm')->once()->with($question)->andReturn(true); @@ -58,13 +43,8 @@ protected function willGiveConfirmation(string $question, string $command, array /** * Add expectation that the given confirmation question would be shown, and do not accept it. - * - * @param string $question - * @param string $command - * @param array $parameters - * @return void */ - protected function willNotGiveConfirmation(string $question, string $command, array $parameters = []) + protected function willNotGiveConfirmation(string $question, string $command, array $parameters = []): void { $mock = Mockery::mock("{$command}[confirm]"); $mock->shouldReceive('confirm')->once()->with($question)->andReturn(false); @@ -74,11 +54,8 @@ protected function willNotGiveConfirmation(string $question, string $command, ar /** * Assert that the given artisan output is seen. - * - * @param string $output - * @return void */ - protected function seeArtisanOutput(string $output) + protected function seeArtisanOutput(string $output): void { if (File::exists($output)) { $output = File::get($output); @@ -91,11 +68,8 @@ protected function seeArtisanOutput(string $output) /** * Assert that the given artisan output is not seen. - * - * @param string $output - * @return void */ - protected function dontSeeArtisanOutput(string $output) + protected function dontSeeArtisanOutput(string $output): void { if (File::exists($output)) { $output = File::get($output); @@ -108,11 +82,8 @@ protected function dontSeeArtisanOutput(string $output) /** * Assert that the given string is seen in the artisan output. - * - * @param string $needle - * @return void */ - protected function seeInArtisanOutput(string $needle) + protected function seeInArtisanOutput(string $needle): void { if (File::exists($needle)) { $needle = File::get($needle); @@ -125,11 +96,8 @@ protected function seeInArtisanOutput(string $needle) /** * Assert that the given string is not seen in the artisan output. - * - * @param string $needle - * @return void */ - protected function dontSeeInArtisanOutput(string $needle) + protected function dontSeeInArtisanOutput(string $needle): void { if (File::exists($needle)) { $needle = File::get($needle); @@ -142,11 +110,8 @@ protected function dontSeeInArtisanOutput(string $needle) /** * Assert that the given data is seen in the artisan table output. - * - * @param array $data - * @return void */ - protected function seeArtisanTableOutput(array $data) + protected function seeArtisanTableOutput(array $data): void { $message = 'Failed asserting that artisan table output consists of expected data.'; $this->assertEquals($data, $this->parseArtisanTableOutput($this->getArtisanOutput()), $message); @@ -154,11 +119,8 @@ protected function seeArtisanTableOutput(array $data) /** * Assert that the given data is not seen in the artisan table output. - * - * @param array $data - * @return void */ - protected function dontSeeArtisanTableOutput(array $data) + protected function dontSeeArtisanTableOutput(array $data): void { $message = 'Failed asserting that artisan table output not consists of expected data.'; $this->assertNotEquals($data, $this->parseArtisanTableOutput($this->getArtisanOutput()), $message); @@ -166,11 +128,8 @@ protected function dontSeeArtisanTableOutput(array $data) /** * Assert that the artisan table output has the given number of data rows. - * - * @param int $count - * @return void */ - protected function seeArtisanTableRowsCount(int $count) + protected function seeArtisanTableRowsCount(int $count): void { $message = "Failed asserting that artisan table rows count equals to `{$count}`."; $this->assertCount($count, $this->parseArtisanTableOutput($this->getArtisanOutput()), $message); @@ -178,11 +137,8 @@ protected function seeArtisanTableRowsCount(int $count) /** * Assert that the artisan table output doesn't have the given number of data rows. - * - * @param int $count - * @return void */ - protected function dontSeeArtisanTableRowsCount(int $count) + protected function dontSeeArtisanTableRowsCount(int $count): void { $message = "Failed asserting that artisan table rows count not equals to `{$count}`."; $this->assertNotCount($count, $this->parseArtisanTableOutput($this->getArtisanOutput()), $message); @@ -192,11 +148,8 @@ protected function dontSeeArtisanTableRowsCount(int $count) * Parse the artisan table output. * * Return data rows with headers as keys. - * - * @param string $output - * @return array */ - private function parseArtisanTableOutput(string $output) + private function parseArtisanTableOutput(string $output): array { $output = explode("\n", trim($output)); diff --git a/src/Asserts/CollectionAsserts.php b/src/Asserts/CollectionAsserts.php index 9ecae07..d262001 100644 --- a/src/Asserts/CollectionAsserts.php +++ b/src/Asserts/CollectionAsserts.php @@ -8,35 +8,25 @@ trait CollectionAsserts { /** * Assert that the given collections are equal based on the specified key. - * - * @param \Illuminate\Support\Collection $collection1 - * @param \Illuminate\Support\Collection $collection2 - * @param string $key - * @return void */ - protected function assertCollectionsEqual(Collection $collection1, Collection $collection2, string $key) + protected function assertCollectionsEqual(Collection $collection1, Collection $collection2, string $key): void { $this->assertEquals( $collection1->pluck($key)->sort()->values(), $collection2->pluck($key)->sort()->values(), - 'Failed asserting that collections are equal.' + 'Failed asserting that collections are equal.', ); } /** * Assert that the given collections are not equal based on the specified key. - * - * @param \Illuminate\Support\Collection $collection1 - * @param \Illuminate\Support\Collection $collection2 - * @param string $key - * @return void */ - protected function assertCollectionsNotEqual(Collection $collection1, Collection $collection2, string $key) + protected function assertCollectionsNotEqual(Collection $collection1, Collection $collection2, string $key): void { $this->assertNotEquals( $collection1->pluck($key)->sort()->values(), $collection2->pluck($key)->sort()->values(), - 'Failed asserting that collections are not equal.' + 'Failed asserting that collections are not equal.', ); } } diff --git a/src/Asserts/DatabaseAsserts.php b/src/Asserts/DatabaseAsserts.php index 55774a1..6aae3d3 100644 --- a/src/Asserts/DatabaseAsserts.php +++ b/src/Asserts/DatabaseAsserts.php @@ -8,40 +8,30 @@ trait DatabaseAsserts { /** * Assert that the database has the given table. - * - * @param string $table - * @return void */ - protected function assertDatabaseHasTable(string $table) + protected function assertDatabaseHasTable(string $table): void { $this->assertTrue( Schema::hasTable($table), - "Failed asserting that database has table `{$table}`." + "Failed asserting that database has table `{$table}`.", ); } /** * Assert that the database doesn't have the given table. - * - * @param string $table - * @return void */ - protected function assertDatabaseMissingTable(string $table) + protected function assertDatabaseMissingTable(string $table): void { $this->assertFalse( Schema::hasTable($table), - "Failed asserting that database missing table `{$table}`." + "Failed asserting that database missing table `{$table}`.", ); } /** * Assert that the database has all the given rows. - * - * @param string $table - * @param array $rows - * @return $this */ - protected function assertDatabaseHasMany(string $table, array $rows) + protected function assertDatabaseHasMany(string $table, array $rows): self { foreach ($rows as $row) { $this->assertDatabaseHas($table, $row); @@ -52,12 +42,8 @@ protected function assertDatabaseHasMany(string $table, array $rows) /** * Assert that the database doesn't have all the given rows. - * - * @param string $table - * @param array $rows - * @return $this */ - protected function assertDatabaseMissingMany(string $table, array $rows) + protected function assertDatabaseMissingMany(string $table, array $rows): self { foreach ($rows as $row) { $this->assertDatabaseMissing($table, $row); diff --git a/src/Asserts/EloquentAsserts.php b/src/Asserts/EloquentAsserts.php index 38e71f0..f4adf8d 100644 --- a/src/Asserts/EloquentAsserts.php +++ b/src/Asserts/EloquentAsserts.php @@ -11,12 +11,8 @@ trait EloquentAsserts { /** * Assert that the model's table name equals to the given value. - * - * @param string $class - * @param string $table - * @return void */ - protected function assertEloquentTableEquals(string $class, string $table) + protected function assertEloquentTableEquals(string $class, string $table): void { /** @var \Illuminate\Database\Eloquent\Model $model */ $model = new $class; @@ -27,12 +23,8 @@ protected function assertEloquentTableEquals(string $class, string $table) /** * Assert that the model's table name doesn't equal to the given value. - * - * @param string $class - * @param string $table - * @return void */ - protected function assertEloquentTableNotEquals(string $class, string $table) + protected function assertEloquentTableNotEquals(string $class, string $table): void { /** @var \Illuminate\Database\Eloquent\Model $model */ $model = new $class; @@ -43,11 +35,8 @@ protected function assertEloquentTableNotEquals(string $class, string $table) /** * Assert that the model's primary key is incrementing. - * - * @param string $class - * @return void */ - protected function assertEloquentIsIncrementing(string $class) + protected function assertEloquentIsIncrementing(string $class): void { /** @var \Illuminate\Database\Eloquent\Model $model */ $model = new $class; @@ -58,11 +47,8 @@ protected function assertEloquentIsIncrementing(string $class) /** * Assert that the model's primary key is not incrementing. - * - * @param string $class - * @return void */ - protected function assertEloquentIsNotIncrementing(string $class) + protected function assertEloquentIsNotIncrementing(string $class): void { /** @var \Illuminate\Database\Eloquent\Model $model */ $model = new $class; @@ -73,12 +59,8 @@ protected function assertEloquentIsNotIncrementing(string $class) /** * Assert that the model's `fillable` field equals to the given value. - * - * @param string $class - * @param array $fillable - * @return void */ - protected function assertEloquentFillableEquals(string $class, array $fillable) + protected function assertEloquentFillableEquals(string $class, array $fillable): void { /** @var \Illuminate\Database\Eloquent\Model $model */ $model = new $class; @@ -89,12 +71,8 @@ protected function assertEloquentFillableEquals(string $class, array $fillable) /** * Assert that the model's `fillable` field doesn't equal to the given value. - * - * @param string $class - * @param array $fillable - * @return void */ - protected function assertEloquentFillableNotEquals(string $class, array $fillable) + protected function assertEloquentFillableNotEquals(string $class, array $fillable): void { /** @var \Illuminate\Database\Eloquent\Model $model */ $model = new $class; @@ -105,12 +83,8 @@ protected function assertEloquentFillableNotEquals(string $class, array $fillabl /** * Assert that the model's `dates` field equals to the given value. - * - * @param string $class - * @param array $dates - * @return void */ - protected function assertEloquentDatesEquals(string $class, array $dates) + protected function assertEloquentDatesEquals(string $class, array $dates): void { /** @var \Illuminate\Database\Eloquent\Model $model */ $model = new $class; @@ -121,12 +95,8 @@ protected function assertEloquentDatesEquals(string $class, array $dates) /** * Assert that the model's `dates` field doesn't equal to the given value. - * - * @param string $class - * @param array $dates - * @return void */ - protected function assertEloquentDatesNotEquals(string $class, array $dates) + protected function assertEloquentDatesNotEquals(string $class, array $dates): void { /** @var \Illuminate\Database\Eloquent\Model $model */ $model = new $class; @@ -137,12 +107,8 @@ protected function assertEloquentDatesNotEquals(string $class, array $dates) /** * Assert that the model's `touches` field equals to the given value. - * - * @param string $class - * @param array $touches - * @return void */ - protected function assertEloquentTouchesEquals(string $class, array $touches) + protected function assertEloquentTouchesEquals(string $class, array $touches): void { /** @var \Illuminate\Database\Eloquent\Model $model */ $model = new $class; @@ -153,12 +119,8 @@ protected function assertEloquentTouchesEquals(string $class, array $touches) /** * Assert that the model's `touches` field doesn't equal to the given value. - * - * @param string $class - * @param array $touches - * @return void */ - protected function assertEloquentTouchesNotEquals(string $class, array $touches) + protected function assertEloquentTouchesNotEquals(string $class, array $touches): void { /** @var \Illuminate\Database\Eloquent\Model $model */ $model = new $class; @@ -169,12 +131,8 @@ protected function assertEloquentTouchesNotEquals(string $class, array $touches) /** * Assert that the model has the given `HasMany` relation. - * - * @param string $class - * @param string $relation - * @return void */ - protected function assertEloquentHasMany(string $class, string $relation) + protected function assertEloquentHasMany(string $class, string $relation): void { $this->assertMethodExists($class, $relation); @@ -197,13 +155,8 @@ protected function assertEloquentHasMany(string $class, string $relation) /** * Assert that the model has `create` method for the given `HasMany` relation. - * - * @param string $class - * @param string $relation - * @param string $createMethod - * @return void */ - protected function assertEloquentHasCreateFor(string $class, string $relation, string $createMethod = '') + protected function assertEloquentHasCreateFor(string $class, string $relation, string $createMethod = ''): void { $this->assertMethodExists($class, $relation); @@ -227,13 +180,8 @@ protected function assertEloquentHasCreateFor(string $class, string $relation, s /** * Assert that the model has `createMany` method for the given `HasMany` relation. - * - * @param string $class - * @param string $relation - * @param string $createManyMethod - * @return void */ - protected function assertEloquentHasCreateManyFor(string $class, string $relation, string $createManyMethod = '') + protected function assertEloquentHasCreateManyFor(string $class, string $relation, string $createManyMethod = ''): void { $this->assertMethodExists($class, $relation); @@ -260,12 +208,8 @@ protected function assertEloquentHasCreateManyFor(string $class, string $relatio /** * Assert that the model has the given `BelongsTo` relation. - * - * @param string $class - * @param string $relation - * @return void */ - protected function assertEloquentBelongsTo(string $class, string $relation) + protected function assertEloquentBelongsTo(string $class, string $relation): void { $this->assertMethodExists($class, $relation); diff --git a/src/Asserts/ExceptionAsserts.php b/src/Asserts/ExceptionAsserts.php index e6d0fe6..ca57a15 100644 --- a/src/Asserts/ExceptionAsserts.php +++ b/src/Asserts/ExceptionAsserts.php @@ -6,13 +6,8 @@ trait ExceptionAsserts { /** * Add expectation that the given exception would be thrown. - * - * @param string $class - * @param string $message - * @param int $code - * @return void */ - protected function willSeeException(string $class, string $message = '', int $code = 0) + protected function willSeeException(string $class, string $message = '', int $code = 0): void { $this->expectException($class); diff --git a/src/Asserts/FilesystemAsserts.php b/src/Asserts/FilesystemAsserts.php index 9ac2c1e..13809e9 100644 --- a/src/Asserts/FilesystemAsserts.php +++ b/src/Asserts/FilesystemAsserts.php @@ -9,11 +9,8 @@ trait FilesystemAsserts { /** * Assert that the given directory is empty. - * - * @param string $path - * @return void */ - protected function assertDirectoryEmpty(string $path) + protected function assertDirectoryEmpty(string $path): void { $glob = Str::finish($path, '/') . '*'; $this->assertEmpty(File::glob($glob), "Failed asserting that directory `{$path}` is empty."); @@ -21,11 +18,8 @@ protected function assertDirectoryEmpty(string $path) /** * Assert that the given directory is not empty. - * - * @param string $path - * @return void */ - protected function assertDirectoryNotEmpty(string $path) + protected function assertDirectoryNotEmpty(string $path): void { $glob = Str::finish($path, '/') . '*'; $this->assertNotEmpty(File::glob($glob), "Failed asserting that directory `{$path}` is not empty."); @@ -33,12 +27,8 @@ protected function assertDirectoryNotEmpty(string $path) /** * Assert that directory has the given number of files. - * - * @param string $path - * @param int $count - * @return void */ - protected function assertFilesCount(string $path, int $count) + protected function assertFilesCount(string $path, int $count): void { $message = "Failed asserting that directory `{$path}` has `{$count}` files."; $this->assertCount($count, File::files($path), $message); @@ -46,12 +36,8 @@ protected function assertFilesCount(string $path, int $count) /** * Assert that directory doesn't have the given number of files. - * - * @param string $path - * @param int $count - * @return void */ - protected function assertNotFilesCount(string $path, int $count) + protected function assertNotFilesCount(string $path, int $count): void { $message = "Failed asserting that directory `{$path}` not has `{$count}` files."; $this->assertNotCount($count, File::files($path), $message); diff --git a/src/Asserts/LogFileAsserts.php b/src/Asserts/LogFileAsserts.php index da35877..f17d39e 100644 --- a/src/Asserts/LogFileAsserts.php +++ b/src/Asserts/LogFileAsserts.php @@ -11,11 +11,8 @@ trait LogFileAsserts * Assert that the given log file exists. * * The path is relative to the `storage/logs` folder. - * - * @param string $path - * @return void */ - protected function seeLogFile(string $path) + protected function seeLogFile(string $path): void { $message = "Failed asserting that log file `{$path}` exists."; $this->assertFileExists($this->composeLogFilePath($path), $message); @@ -25,11 +22,8 @@ protected function seeLogFile(string $path) * Assert that the given log file doesn't exist. * * The path is relative to the `storage/logs` folder. - * - * @param string $path - * @return void */ - protected function dontSeeLogFile(string $path) + protected function dontSeeLogFile(string $path): void { $message = "Failed asserting that log file `{$path}` not exists."; $this->assertFileDoesNotExist($this->composeLogFilePath($path), $message); @@ -39,12 +33,8 @@ protected function dontSeeLogFile(string $path) * Assert that the log file contains the given message. * * The path is relative to the `storage/logs` folder. - * - * @param string $path - * @param string|array $message - * @return void */ - protected function seeInLogFile(string $path, $message) + protected function seeInLogFile(string $path, array|string $message): void { $messages = !is_array($message) ? [$message] : $message; @@ -59,12 +49,8 @@ protected function seeInLogFile(string $path, $message) * Assert that the log file doesn't contain the given message. * * The path is relative to the `storage/logs` folder. - * - * @param string $path - * @param string|array $message - * @return void */ - protected function dontSeeInLogFile(string $path, $message) + protected function dontSeeInLogFile(string $path, array|string $message): void { $messages = !is_array($message) ? [$message] : $message; @@ -77,22 +63,16 @@ protected function dontSeeInLogFile(string $path, $message) /** * Compose the log file path. - * - * @param string $path - * @return string */ - private function composeLogFilePath(string $path) + private function composeLogFilePath(string $path): string { return storage_path("logs/{$path}"); } /** * Compose regex pattern for the given log message. - * - * @param string $message - * @return string */ - private function composeRegexPattern(string $message) + private function composeRegexPattern(string $message): string { $pattern = '/' . preg_quote($message, '/') diff --git a/src/Asserts/ReflectionAsserts.php b/src/Asserts/ReflectionAsserts.php index c1fc079..8705524 100644 --- a/src/Asserts/ReflectionAsserts.php +++ b/src/Asserts/ReflectionAsserts.php @@ -6,12 +6,8 @@ trait ReflectionAsserts { /** * Assert that class is a subclass of the given parent. - * - * @param string $class - * @param string $parent - * @return void */ - protected function assertSubclassOf(string $class, string $parent) + protected function assertSubclassOf(string $class, string $parent): void { $message = "Failed asserting that class `{$class}` is subclass of `{$parent}`."; $this->assertTrue(is_subclass_of($class, $parent), $message); @@ -19,12 +15,8 @@ protected function assertSubclassOf(string $class, string $parent) /** * Assert that class is not a subclass of the given parent. - * - * @param string $class - * @param string $parent - * @return void */ - protected function assertNotSubclassOf(string $class, string $parent) + protected function assertNotSubclassOf(string $class, string $parent): void { $message = "Failed asserting that class `{$class}` is not subclass of `{$parent}`."; $this->assertFalse(is_subclass_of($class, $parent), $message); @@ -32,12 +24,8 @@ protected function assertNotSubclassOf(string $class, string $parent) /** * Assert that class uses the given trait. - * - * @param string $class - * @param string $trait - * @return void */ - protected function assertTraitUsed(string $class, string $trait) + protected function assertTraitUsed(string $class, string $trait): void { $message = "Failed asserting that class `{$class}` is using trait `{$trait}`."; $this->assertContains($trait, class_uses($class), $message); @@ -45,12 +33,8 @@ protected function assertTraitUsed(string $class, string $trait) /** * Assert that class doesn't use the given trait. - * - * @param string $class - * @param string $trait - * @return void */ - protected function assertTraitNotUsed(string $class, string $trait) + protected function assertTraitNotUsed(string $class, string $trait): void { $message = "Failed asserting that class `{$class}` is not using trait `{$trait}`."; $this->assertNotContains($trait, class_uses($class), $message); @@ -58,12 +42,8 @@ protected function assertTraitNotUsed(string $class, string $trait) /** * Assert that object has the given method. - * - * @param object|string $object - * @param string $method - * @return void */ - protected function assertMethodExists($object, string $method) + protected function assertMethodExists(object|string $object, string $method): void { $message = "Failed asserting that `{$method}` method exists on specified object."; $this->assertTrue(method_exists($object, $method), $message); @@ -71,12 +51,8 @@ protected function assertMethodExists($object, string $method) /** * Assert that object doesn't have the given method. - * - * @param object|string $object - * @param string $method - * @return void */ - protected function assertMethodNotExists($object, string $method) + protected function assertMethodNotExists(object|string $object, string $method): void { $message = "Failed asserting that `{$method}` method not exists on specified object."; $this->assertFalse(method_exists($object, $method), $message); diff --git a/src/Asserts/ScheduleAsserts.php b/src/Asserts/ScheduleAsserts.php index 86e57e5..f76cbc0 100644 --- a/src/Asserts/ScheduleAsserts.php +++ b/src/Asserts/ScheduleAsserts.php @@ -10,11 +10,8 @@ trait ScheduleAsserts { /** * Assert that schedule count equals to the given value. - * - * @param int $count - * @return void */ - protected function seeScheduleCount(int $count) + protected function seeScheduleCount(int $count): void { $message = "Failed asserting that schedule events count is {$count}."; $this->assertCount($count, app(Schedule::class)->events(), $message); @@ -22,11 +19,8 @@ protected function seeScheduleCount(int $count) /** * Assert that schedule count doesn't equal to the given value. - * - * @param int $count - * @return void */ - protected function dontSeeScheduleCount(int $count) + protected function dontSeeScheduleCount(int $count): void { $message = "Failed asserting that schedule events count is not {$count}."; $this->assertNotCount($count, app(Schedule::class)->events(), $message); @@ -34,13 +28,8 @@ protected function dontSeeScheduleCount(int $count) /** * Assert that the given command is scheduled. - * - * @param string $command - * @param string $expression - * @param bool $runInBackground - * @return void */ - protected function seeInSchedule(string $command, string $expression, bool $runInBackground = false) + protected function seeInSchedule(string $command, string $expression, bool $runInBackground = false): void { $event = $this->getScheduleEvent($command); @@ -58,11 +47,8 @@ protected function seeInSchedule(string $command, string $expression, bool $runI /** * Assert that the given command is not scheduled. - * - * @param string $command - * @return void */ - protected function dontSeeInSchedule(string $command) + protected function dontSeeInSchedule(string $command): void { $message = "Failed asserting that command `{$command}` is not in schedule."; $this->assertEmpty($this->getScheduleEvent($command), $message); @@ -70,11 +56,8 @@ protected function dontSeeInSchedule(string $command) /** * Get schedule event by the given command. - * - * @param string $command - * @return \Illuminate\Console\Scheduling\Event|null */ - private function getScheduleEvent(string $command) + private function getScheduleEvent(string $command): Event|null { $schedule = app(Schedule::class); @@ -86,12 +69,8 @@ private function getScheduleEvent(string $command) /** * Normalize the given schedule expression. - * - * @param \Illuminate\Console\Scheduling\Event $event - * @param string $expression - * @return string */ - private function normalizeScheduleExpression(Event $event, string $expression) + private function normalizeScheduleExpression(Event $event, string $expression): string { if (method_exists($event, $expression)) { $event->$expression(); diff --git a/src/Asserts/ServiceProviderAsserts.php b/src/Asserts/ServiceProviderAsserts.php index a24fe0f..6ba4af8 100644 --- a/src/Asserts/ServiceProviderAsserts.php +++ b/src/Asserts/ServiceProviderAsserts.php @@ -9,11 +9,8 @@ trait ServiceProviderAsserts { /** * Assert that the given alias is registered. - * - * @param string $alias - * @return void */ - protected function seeRegisteredAlias(string $alias) + protected function seeRegisteredAlias(string $alias): void { $message = "Failed asserting that alias `{$alias}` is registered."; $this->assertNotEmpty(AliasLoader::getInstance()->load($alias), $message); @@ -21,11 +18,8 @@ protected function seeRegisteredAlias(string $alias) /** * Assert that the given alias is not registered. - * - * @param string $alias - * @return void */ - protected function dontSeeRegisteredAlias(string $alias) + protected function dontSeeRegisteredAlias(string $alias): void { $message = "Failed asserting that alias `{$alias}` is not registered."; $this->assertEmpty(AliasLoader::getInstance()->load($alias), $message); @@ -33,11 +27,8 @@ protected function dontSeeRegisteredAlias(string $alias) /** * Assert that the given command is registered. - * - * @param string $name - * @return void */ - protected function seeRegisteredCommand(string $name) + protected function seeRegisteredCommand(string $name): void { $message = "Failed asserting that command `{$name}` is registered."; $this->assertArrayHasKey($name, Artisan::all(), $message); @@ -45,11 +36,8 @@ protected function seeRegisteredCommand(string $name) /** * Assert that the given command is not registered. - * - * @param string $name - * @return void */ - protected function dontSeeRegisteredCommand(string $name) + protected function dontSeeRegisteredCommand(string $name): void { $message = "Failed asserting that command `{$name}` is not registered."; $this->assertArrayNotHasKey($name, Artisan::all(), $message); diff --git a/src/Helpers/ApplicationHelpers.php b/src/Helpers/ApplicationHelpers.php index 86de24e..6da50b4 100644 --- a/src/Helpers/ApplicationHelpers.php +++ b/src/Helpers/ApplicationHelpers.php @@ -8,31 +8,24 @@ trait ApplicationHelpers { /** * Emulate that application is running on the `local` environment. - * - * @return void */ - protected function emulateLocal() + protected function emulateLocal(): void { $this->emulateEnvironment('local'); } /** * Emulate that application is running on the `production` environment. - * - * @return void */ - protected function emulateProduction() + protected function emulateProduction(): void { $this->emulateEnvironment('production'); } /** * Emulate that application is running on the given environment. - * - * @param string $environment - * @return void */ - protected function emulateEnvironment(string $environment) + protected function emulateEnvironment(string $environment): void { App::detectEnvironment(function () use ($environment) { return $environment; @@ -41,10 +34,8 @@ protected function emulateEnvironment(string $environment) /** * Check whether the application is running on Travis or not. - * - * @return bool */ - protected function isTravis() + protected function isTravis(): bool { return (bool) getenv('TRAVIS'); } diff --git a/src/Helpers/ArtisanHelpers.php b/src/Helpers/ArtisanHelpers.php index 669f738..c5027bc 100644 --- a/src/Helpers/ArtisanHelpers.php +++ b/src/Helpers/ArtisanHelpers.php @@ -11,19 +11,13 @@ trait ArtisanHelpers { /** * The artisan output. - * - * @var \Symfony\Component\Console\Output\BufferedOutput */ - protected static $artisanOutput; + protected static BufferedOutput|string $artisanOutput; /** * Run the given artisan console command. - * - * @param \Illuminate\Console\Command|string $command - * @param array $parameters - * @return \Illuminate\Console\Command */ - protected function runArtisan($command, array $parameters = []) + protected function runArtisan(Command|string $command, array $parameters = []): Command { $command = $command instanceof Command ? $command : new $command; @@ -37,10 +31,8 @@ protected function runArtisan($command, array $parameters = []) /** * Get artisan output. - * - * @return string */ - protected function getArtisanOutput() + protected function getArtisanOutput(): string { $output = Artisan::output(); if (!empty($output)) { diff --git a/tests/Asserts/LogFileAssertsTest.php b/tests/Asserts/LogFileAssertsTest.php index 548deb4..6fcb2a6 100644 --- a/tests/Asserts/LogFileAssertsTest.php +++ b/tests/Asserts/LogFileAssertsTest.php @@ -10,8 +10,6 @@ class LogFileAssertsTest extends TestCase { /** * Setup the test environment. - * - * @return void */ protected function setUp(): void { @@ -22,10 +20,8 @@ protected function setUp(): void /** * Create a sample log file. - * - * @return void */ - private function createSampleLogFile() + private function createSampleLogFile(): void { $date = Carbon::now(); $path = storage_path('logs/example.log'); @@ -93,8 +89,6 @@ public function which_also_supports_array_of_contents() /** * Clean up the testing environment before the next test. - * - * @return void */ protected function tearDown(): void { diff --git a/tests/Asserts/ScheduleAssertsTest.php b/tests/Asserts/ScheduleAssertsTest.php index b123f89..b56a857 100644 --- a/tests/Asserts/ScheduleAssertsTest.php +++ b/tests/Asserts/ScheduleAssertsTest.php @@ -22,10 +22,8 @@ protected function resolveApplicationConsoleKernel($app) /** * Create a sample schedule. - * - * @return void */ - private function createSampleSchedule() + private function createSampleSchedule(): void { app()->booted(function () { $schedule = app(Schedule::class); diff --git a/tests/TestCase.php b/tests/TestCase.php index b497370..8f7f7ed 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -21,8 +21,6 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase /** * Setup the test environment. - * - * @return void */ protected function setUp(): void { @@ -47,10 +45,8 @@ protected function getPackageProviders($app) /** * Setup the database. - * - * @return void */ - protected function setUpDatabase() + protected function setUpDatabase(): void { config(['database.default' => 'testing']); config(['database.connections.testing.foreign_key_constraints' => true]); @@ -65,30 +61,24 @@ protected function setUpDatabase() /** * Setup factories. - * - * @return void */ - private function setUpFactories() + private function setUpFactories(): void { Factory::useNamespace('Illuminated\\Testing\\Tests\\Database\\Factories\\'); } /** * Setup views. - * - * @return void */ - private function setUpViews() + private function setUpViews(): void { app('view')->addLocation(__DIR__ . '/fixture/resources/views'); } /** * Setup storage. - * - * @return void */ - private function setUpStorage() + private function setUpStorage(): void { $this->app->useStoragePath(__DIR__ . '/fixture/storage'); } diff --git a/tests/fixture/app/Comment.php b/tests/fixture/app/Comment.php index efed434..35ddc66 100644 --- a/tests/fixture/app/Comment.php +++ b/tests/fixture/app/Comment.php @@ -4,6 +4,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; class Comment extends Model { @@ -25,10 +26,8 @@ class Comment extends Model /** * Get the post. - * - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ - public function post() + public function post(): BelongsTo { return $this->belongsTo(Post::class); } diff --git a/tests/fixture/app/Commentable.php b/tests/fixture/app/Commentable.php index 362dd29..746a567 100644 --- a/tests/fixture/app/Commentable.php +++ b/tests/fixture/app/Commentable.php @@ -6,8 +6,6 @@ trait Commentable { /** * Just a random trait property for tests. - * - * @var bool */ - protected $something = true; + protected bool $something = true; } diff --git a/tests/fixture/app/Console/Commands/ConfirmableTraitCommand.php b/tests/fixture/app/Console/Commands/ConfirmableTraitCommand.php index d57bd4b..abdf399 100644 --- a/tests/fixture/app/Console/Commands/ConfirmableTraitCommand.php +++ b/tests/fixture/app/Console/Commands/ConfirmableTraitCommand.php @@ -18,10 +18,8 @@ class ConfirmableTraitCommand extends Command /** * Handle the command. - * - * @return void */ - public function handle() + public function handle(): void { if (!$this->confirmToProceed('Attention, please!', true)) { return; diff --git a/tests/fixture/app/Console/Commands/ConfirmationCommand.php b/tests/fixture/app/Console/Commands/ConfirmationCommand.php index cab9ebc..ebe837c 100644 --- a/tests/fixture/app/Console/Commands/ConfirmationCommand.php +++ b/tests/fixture/app/Console/Commands/ConfirmationCommand.php @@ -15,10 +15,8 @@ class ConfirmationCommand extends Command /** * Handle the command. - * - * @return void */ - public function handle() + public function handle(): void { if (!$this->confirm('Are you sure?')) { return; diff --git a/tests/fixture/app/Console/Commands/GenericCommand.php b/tests/fixture/app/Console/Commands/GenericCommand.php index 90e7c61..7ec4598 100644 --- a/tests/fixture/app/Console/Commands/GenericCommand.php +++ b/tests/fixture/app/Console/Commands/GenericCommand.php @@ -15,20 +15,16 @@ class GenericCommand extends Command /** * Handle the command. - * - * @return void */ - public function handle() + public function handle(): void { $this->info('Hello, World!'); } /** * Get the greeting message. - * - * @return string */ - public function getGreetingMessage() + public function getGreetingMessage(): string { $name = $this->option('name') ?: 'Dude'; diff --git a/tests/fixture/app/Console/Commands/RegisteredCommand.php b/tests/fixture/app/Console/Commands/RegisteredCommand.php index 6be643d..3ae90cc 100644 --- a/tests/fixture/app/Console/Commands/RegisteredCommand.php +++ b/tests/fixture/app/Console/Commands/RegisteredCommand.php @@ -15,10 +15,8 @@ class RegisteredCommand extends Command /** * Handle the command. - * - * @return void */ - public function handle() + public function handle(): void { $this->info('Done!'); } diff --git a/tests/fixture/app/Console/Commands/TableOutputCommand.php b/tests/fixture/app/Console/Commands/TableOutputCommand.php index 9202c68..65730e3 100644 --- a/tests/fixture/app/Console/Commands/TableOutputCommand.php +++ b/tests/fixture/app/Console/Commands/TableOutputCommand.php @@ -15,10 +15,8 @@ class TableOutputCommand extends Command /** * Handle the command. - * - * @return void */ - public function handle() + public function handle(): void { $rows = $this->getRows(); $headers = array_keys($rows[0]); @@ -27,10 +25,8 @@ public function handle() /** * Get the rows. - * - * @return array */ - private function getRows() + private function getRows(): array { return [ ['System' => 'Node-1', 'Status' => 'Enabled'], diff --git a/tests/fixture/app/Http/Controllers/HomeController.php b/tests/fixture/app/Http/Controllers/HomeController.php index 49b94b4..5c5265d 100644 --- a/tests/fixture/app/Http/Controllers/HomeController.php +++ b/tests/fixture/app/Http/Controllers/HomeController.php @@ -8,8 +8,6 @@ class HomeController extends Controller { /** * The index action. - * - * @return \Illuminate\View\View */ public function index() { diff --git a/tests/fixture/app/Post.php b/tests/fixture/app/Post.php index 0c23b5b..448d711 100644 --- a/tests/fixture/app/Post.php +++ b/tests/fixture/app/Post.php @@ -2,8 +2,10 @@ namespace Illuminated\Testing\Tests\App; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\HasMany; class Post extends Model { @@ -33,32 +35,24 @@ class Post extends Model /** * Get the comments. - * - * @return \Illuminate\Database\Eloquent\Relations\HasMany */ - public function comments() + public function comments(): HasMany { return $this->hasMany(Comment::class); } /** * Create a comment. - * - * @param array $attributes - * @return \Illuminate\Database\Eloquent\Model */ - public function createComment(array $attributes) + public function createComment(array $attributes): Comment { return $this->comments()->create($attributes); } /** * Create many comments. - * - * @param array $comments - * @return \Illuminate\Database\Eloquent\Collection */ - public function createManyComments(array $comments) + public function createManyComments(array $comments): Collection { return $this->comments()->createMany($comments); } @@ -66,12 +60,9 @@ public function createManyComments(array $comments) /** * Attach a comment. * - * @param array $attributes - * @return \Illuminate\Database\Eloquent\Model - * * @noinspection PhpUnused */ - public function attachComment(array $attributes) + public function attachComment(array $attributes): Comment { return $this->createComment($attributes); } @@ -79,12 +70,9 @@ public function attachComment(array $attributes) /** * Attach many comments. * - * @param array $comments - * @return \Illuminate\Database\Eloquent\Collection - * * @noinspection PhpUnused */ - public function attachManyComments(array $comments) + public function attachManyComments(array $comments): Collection { return $this->createManyComments($comments); } diff --git a/tests/fixture/app/Providers/FixtureServiceProvider.php b/tests/fixture/app/Providers/FixtureServiceProvider.php index da38f60..716ea1b 100644 --- a/tests/fixture/app/Providers/FixtureServiceProvider.php +++ b/tests/fixture/app/Providers/FixtureServiceProvider.php @@ -11,10 +11,8 @@ class FixtureServiceProvider extends ServiceProvider { /** * Register any application services. - * - * @return void */ - public function register() + public function register(): void { $this->registerAliases(); $this->registerCommands(); @@ -22,10 +20,8 @@ public function register() /** * Register aliases. - * - * @return void */ - private function registerAliases() + private function registerAliases(): void { $this->app->booting(function () { $loader = AliasLoader::getInstance(); @@ -35,10 +31,8 @@ private function registerAliases() /** * Register commands. - * - * @return void */ - private function registerCommands() + private function registerCommands(): void { $this->app->singleton('command.fixture.registered', RegisteredCommand::class); diff --git a/tests/fixture/database/factories/CommentFactory.php b/tests/fixture/database/factories/CommentFactory.php index 6e19129..3c810b1 100644 --- a/tests/fixture/database/factories/CommentFactory.php +++ b/tests/fixture/database/factories/CommentFactory.php @@ -16,10 +16,8 @@ class CommentFactory extends Factory /** * Define the model's default state. - * - * @return array */ - public function definition() + public function definition(): array { return [ 'body' => $this->faker->sentence, diff --git a/tests/fixture/database/factories/PostFactory.php b/tests/fixture/database/factories/PostFactory.php index 7acdcdc..f2672cc 100644 --- a/tests/fixture/database/factories/PostFactory.php +++ b/tests/fixture/database/factories/PostFactory.php @@ -16,10 +16,8 @@ class PostFactory extends Factory /** * Define the model's default state. - * - * @return array */ - public function definition() + public function definition(): array { return [ 'title' => $this->faker->sentence, diff --git a/tests/fixture/database/migrations/2016_11_01_131415_create_posts_table.php b/tests/fixture/database/migrations/2016_11_01_131415_create_posts_table.php index a66b640..291c01c 100644 --- a/tests/fixture/database/migrations/2016_11_01_131415_create_posts_table.php +++ b/tests/fixture/database/migrations/2016_11_01_131415_create_posts_table.php @@ -4,14 +4,12 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreatePostsTable extends Migration +return new class extends Migration { /** * Run the migration. - * - * @return void */ - public function up() + public function up(): void { Schema::create('posts', function (Blueprint $table) { $table->increments('id'); @@ -23,11 +21,9 @@ public function up() /** * Rollback the migration. - * - * @return void */ - public function down() + public function down(): void { Schema::drop('posts'); } -} +}; diff --git a/tests/fixture/database/migrations/2016_11_01_131425_create_comments_table.php b/tests/fixture/database/migrations/2016_11_01_131425_create_comments_table.php index 218734e..f5d21fb 100644 --- a/tests/fixture/database/migrations/2016_11_01_131425_create_comments_table.php +++ b/tests/fixture/database/migrations/2016_11_01_131425_create_comments_table.php @@ -4,14 +4,12 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreateCommentsTable extends Migration +return new class extends Migration { /** * Run the migration. - * - * @return void */ - public function up() + public function up(): void { Schema::create('comments', function (Blueprint $table) { $table->increments('id'); @@ -24,11 +22,9 @@ public function up() /** * Rollback the migration. - * - * @return void */ - public function down() + public function down(): void { Schema::drop('comments'); } -} +}; From f104ea4ea3789f5e3ed16bef555811567fbe74d2 Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Wed, 16 Mar 2022 18:39:54 +0200 Subject: [PATCH 03/22] Material Theme (sponsor) --- README.md | 1 + art/sponsor-material-theme.png | Bin 0 -> 2584 bytes 2 files changed, 1 insertion(+) create mode 100644 art/sponsor-material-theme.png diff --git a/README.md b/README.md index 386a10b..5c957a1 100644 --- a/README.md +++ b/README.md @@ -817,6 +817,7 @@ $this->dontSeeRegisteredCommand('foobarbaz'); ## Sponsors [![Laravel Idea](art/sponsor-laravel-idea.png)](https://laravel-idea.com) +[![Material Theme UI Plugin](art/sponsor-material-theme.png)](https://material-theme.com) ## License diff --git a/art/sponsor-material-theme.png b/art/sponsor-material-theme.png new file mode 100644 index 0000000000000000000000000000000000000000..70bca40a359a18ec20c87e05d1f4352eb2f51aed GIT binary patch literal 2584 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-#^NA%Cx&(BWL^R}$5JCa(|mmy zw18|51~x_^24;{FAY@>aVqgWc85qJCrQz&2Mh&PMCZHNa1|Z2G3dCvcnG7sY^))~m z#MA*1FghT!A~h#Bu_V7pA)qK$ul3|ji{LH2VNctjR6Fz6|RFk{71`!WUw=1rL)5hW46 zK32*3xq68y`AMmI6}bfz9|8>y;bpKhp88yV>WRp=I1=9MH?=;jqGLkxkLMfuL^+7WFhI$72*tC^ors2>AlEJAB7)Ee!p;%UtSOC!k4h)DJ zZ9p!t0!Mg+OJ;6rUNO)=cBTe4V5eb7AUubpF%p+XBnc#qAjexp1f>?|=ahm%&(7EY z4D<~_l#M=yJi6XU0(z0<(e?TlWu^k-6Kt;`)GlN(boB_ULh~|9?2MpV(1ek60Yl%) zxhNHsc|!8@bL_C?B^!NoRoDzjbxABqwFBiJT?1oXL$eTA{?Rr7<|tr5!3}|^L^Hz| zm?2UUOA@h}Vs2$%j%*5wTBtcT`k+*el*%Dl2rLTBLv~z12f*^99haZ3ydwhxtFEVu zV@L+;+o4%>J_KE>=8S5x}!o@sj-sb?*CWZ9&!8AcrNx#ihQyC)`u6n z*$d{`n@XwpKkZyIzw$&m%+r0EZ!+WfhY2wy^XeV++CDm$<}%O zY{#wNy}OnVZcH`xxLf6XUUm=T+G5FDS+#CwIh$iUeOq+4%{ZKN*-d%U&d+7heWhofTs~o; z70`QC+;UZ#SSinp4#`6*LVfzp^@=YnV%GMSiyik{_3>8q?Fp6X-C2eDW+~4#yCn`4 ze*4?+$ufDtY?BjWmQs9oclCa|nj`h$#-YjEg4+F@OGCSJH*8Nd6U@53wOWFYEv0Ji zjoI-#<0|Wp$efN=U+3aw08X7mi_(4`w|CB z(cJ|%k0$;jnu%>49-kKO{UW7X@$m=eU6b&iKdv)7NH1#Yyr}7UUZ8W` ze(Ifn?|(&XY24<*YN!+z zrL&bIP+;c~AKn$L##}p_4Oe8!zc-(^;Pd{O$r;gmHvURI|Lu^j%bhY7^TSye=iHu} ze*D6^{>6`%`EQ^8-?nL8R$S)uDD@)~WLJB-#JfDYoOMIqVYSli8y;zPGnKWzt-P`7 zRD+r8(S4edE=<4nIy3QDzCU<(Sy6>e@ws2mpWA+#CT$?aGm}4$$Gy5=cgDvvZD#H* zJ!UEr7W{m2$#SzNn%&=f*#1dGOx5Njmm{-390`mS608pwUtB3UvAgp8qc{Vlt{uD5 zO-1GFQXfZFG#!}G%x^C$bmjXRsiF_z-9MlISShfx`OasZATa~q-_Hu_-?RUf7yGd{ zSZV6rqw8}{>^GmBBJ-O+O6Rcn<#zdbe_fP5T26A9uFvRSaE) Date: Wed, 16 Mar 2022 19:07:15 +0200 Subject: [PATCH 04/22] Material Theme (sponsor) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5c957a1..9f60b2e 100644 --- a/README.md +++ b/README.md @@ -816,8 +816,8 @@ $this->dontSeeRegisteredCommand('foobarbaz'); ## Sponsors -[![Laravel Idea](art/sponsor-laravel-idea.png)](https://laravel-idea.com) [![Material Theme UI Plugin](art/sponsor-material-theme.png)](https://material-theme.com) +[![Laravel Idea](art/sponsor-laravel-idea.png)](https://laravel-idea.com) ## License From 50bbd460e7824e58e0d0ec0f5bf8fa4221d4a9ff Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Wed, 16 Mar 2022 19:09:25 +0200 Subject: [PATCH 05/22] Material Theme (sponsor) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9f60b2e..5c957a1 100644 --- a/README.md +++ b/README.md @@ -816,8 +816,8 @@ $this->dontSeeRegisteredCommand('foobarbaz'); ## Sponsors -[![Material Theme UI Plugin](art/sponsor-material-theme.png)](https://material-theme.com) [![Laravel Idea](art/sponsor-laravel-idea.png)](https://laravel-idea.com) +[![Material Theme UI Plugin](art/sponsor-material-theme.png)](https://material-theme.com) ## License From 8fa9e207521c2ac647f453459e55acf3c2837c90 Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Wed, 16 Mar 2022 19:14:19 +0200 Subject: [PATCH 06/22] Material Theme (sponsor) --- README.md | 4 ++-- art/sponsor-material-theme.png | Bin 2584 -> 7123 bytes .../QuickLook/Icon.tiff | Bin 0 -> 4870 bytes .../QuickLook/Thumbnail.tiff | Bin 0 -> 15074 bytes .../data/0D6D801E-30F3-46BF-815B-DC27D2EB5BE0 | Bin 0 -> 4844 bytes .../data/originalImportedContentDocumentInfo | Bin 0 -> 708 bytes art/sponsor-material-theme.pxd/metadata.info | Bin 0 -> 143360 bytes 7 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 art/sponsor-material-theme.pxd/QuickLook/Icon.tiff create mode 100644 art/sponsor-material-theme.pxd/QuickLook/Thumbnail.tiff create mode 100644 art/sponsor-material-theme.pxd/data/0D6D801E-30F3-46BF-815B-DC27D2EB5BE0 create mode 100644 art/sponsor-material-theme.pxd/data/originalImportedContentDocumentInfo create mode 100644 art/sponsor-material-theme.pxd/metadata.info diff --git a/README.md b/README.md index 5c957a1..88ce578 100644 --- a/README.md +++ b/README.md @@ -816,8 +816,8 @@ $this->dontSeeRegisteredCommand('foobarbaz'); ## Sponsors -[![Laravel Idea](art/sponsor-laravel-idea.png)](https://laravel-idea.com) -[![Material Theme UI Plugin](art/sponsor-material-theme.png)](https://material-theme.com) +[![Laravel Idea](art/sponsor-laravel-idea.png)](https://laravel-idea.com)
+[![Material Theme UI Plugin](art/sponsor-material-theme.png)](https://material-theme.com)
## License diff --git a/art/sponsor-material-theme.png b/art/sponsor-material-theme.png index 70bca40a359a18ec20c87e05d1f4352eb2f51aed..f65752906f94a7a1539ceb5ea361b06b59cb3c20 100644 GIT binary patch delta 6020 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 delta 1447 zcmV;Y1z7siH<%P5iBL{Q4GJ0x0000DNk~Le0000o0000o2nGNE03JVxv5_IQ0su0R z*dzohFYg4B0T=3_>w4g+&HyORaAx2P)Lvvt%QUG?T_FEi8mg2MZj-B;*~y^zd;`m zk%)w-%jxXKnA!u6Jj~MT%A^N7`gAXU_S)Ju`D=l9ga0n>%+u z)}+yw5=eJQ)5?Fe-J`!14YWN;^L=}`|H~u9=*J(MJMVuD5e<7DdycWjGhv!u=QiB^ z>=W<>^g{*JV=d;N`~kZU9$Fh2HQ}ihTv~+Tpa&pH#v_rk{aJ{FVe_L8TwT6-|3e5Y zE`ZPPXFlN90DX#zFp+3#4U|$*$ZqECTRK6za%edQiPz1D+WU>Vra`?_0`w^=!bD;l zYtT{@=%{}UuIS`B*bHrI9}u?q3m(uQ7|tQ%b5JW+qk73j8_h8peLXmluWiAa7QM6RqF zLp8Dx49%?X2D ziA{fmEVh`#V$((=lDYGCTaIq zLv>Y)ZLqgtHW6yuwR;#224s4j*qdLuUU`3h#2m|8C$2<7%TWl1*?;0vCK;HCK(Mo3 zWhYw1f|%UIl}MBmN;KG1&H?kvf0b^d3B4{q$+9rH65)js!4JA!kWZ`$>{UpWpB({t zBix}ZOpZkGTohVy4C;H^S_y6Xj{Co`eo1d!YxGHb_6%W zYSEnAm1oD$u8*VRrcbw*|2=}PYF=sQS|`Mi9ji%1Uqs^5YStFvKNS+x_pDPIa`0D+`RDkl5V?cg^DI&pFirdBaDVRy{T~+iy;CBU z-NmnL$iFv}WE}esS}emC(}y3P{X`=1Ig&t^F9A<*)&aOJ?Lq(m002ovPDHLkV1k>^ BpPm2! diff --git a/art/sponsor-material-theme.pxd/QuickLook/Icon.tiff b/art/sponsor-material-theme.pxd/QuickLook/Icon.tiff new file mode 100644 index 0000000000000000000000000000000000000000..2d86ba46da2a4f60b2054a8d414db3d0c4047941 GIT binary patch literal 4870 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

^5!Ke&He0%YH6mJ=5s&<1fZu$De(k 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 literal 0 HcmV?d00001 diff --git a/art/sponsor-material-theme.pxd/data/0D6D801E-30F3-46BF-815B-DC27D2EB5BE0 b/art/sponsor-material-theme.pxd/data/0D6D801E-30F3-46BF-815B-DC27D2EB5BE0 new file mode 100644 index 0000000000000000000000000000000000000000..854b02ebd195da067d1701eea11901c187bd5c0f GIT binary patch literal 4844 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 J`!jQ%_y$c%TB`s6 literal 0 HcmV?d00001 diff --git a/art/sponsor-material-theme.pxd/metadata.info b/art/sponsor-material-theme.pxd/metadata.info new file mode 100644 index 0000000000000000000000000000000000000000..d20690879f7596153d5554873a1c301e746e5c3e GIT binary patch literal 143360 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 literal 0 HcmV?d00001 From 8fb9f41d69da2e1892a1484d7e0d70b39962dfab Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Thu, 17 Mar 2022 17:36:06 +0200 Subject: [PATCH 07/22] Material Theme (sponsor) --- .../QuickLook/Icon.tiff | Bin 5024 -> 5038 bytes .../QuickLook/Thumbnail.tiff | Bin 34892 -> 22858 bytes art/sponsor-laravel-idea.pxd/metadata.info | Bin 110592 -> 118784 bytes art/sponsor-material-theme.png | Bin 7123 -> 7123 bytes .../QuickLook/Icon.tiff | Bin 4870 -> 4876 bytes .../QuickLook/Thumbnail.tiff | Bin 15074 -> 15010 bytes .../data/0D6D801E-30F3-46BF-815B-DC27D2EB5BE0 | Bin 4844 -> 4844 bytes art/sponsor-material-theme.pxd/metadata.info | Bin 143360 -> 143360 bytes 8 files changed, 0 insertions(+), 0 deletions(-) diff --git a/art/sponsor-laravel-idea.pxd/QuickLook/Icon.tiff b/art/sponsor-laravel-idea.pxd/QuickLook/Icon.tiff index 7b6bbdb9c423e1e1cfa5c64369307bb2c6b9b30b..ae4a01a193d7cd2fa4b331e8ada32d341ee0a83c 100644 GIT binary patch delta 1694 zcmV;P24VT2C$1+fO-%qQ000JrfB+y+I3yGR0)YUZ@F-ji0|EfQpikj=APg@b0>K01 zo3-SVkt`m6K(ILJ;QfC*882tcCTmBeQfXAWWj0SCki;S26S!0!cb$SqPx|Bi{ak+q zz<@Bj(!XYjzTxk-GtutGLb{$PT7-^EPP|@kSGsIG00D->U_ej^1PU7hfWu*|NN6kr z0fm|mhtoiE3ImQs0B|Uwy83=MSky){&VciDzaOrDo94FjQNdufx9Bd*T>}*71v&i- z>bUxX1At%A2m-m@@Jo#0 zAZeYd`F*uSoY5r?ir4rx#vqU|#6SXofdO859>sW$27w|wnCBWNx%6n6aB-G?E0CfX zrK)a!+iLEj02=<2EC_%E!msM<(1W0HI--+Ak23z80N^kR0|V#WY;zyS@%nhLU1PYud z(fV+Npg0H;n@@qX&9kRFRCAXnneJS$FDgub0WtuH76t*LS>|}21tZeF0DvG04g#RS zG(*Ve;pTOn2PoAifQsq(f=S>&9ti@2Tz&xobgQg*9mLwYeSu(T9w`A-7>7(8qg%ih zMj>QIgPw88=HY+<7%@hJ07D7{E9&${?Vac8`ghEr7%J(7J8(bhwYzG10h@g6&hnb3c9!G&x3DP7Sa(^C9*a8L~*P(O<)yo z*h&GwfFv?ur)e+)fdEKg$XdtNJZ%CXpe#2Y=c(poQ1nO=1p$Hu<)D! zU`{GeA7|0>Y@lk2?i>LiIB<5T2Wj^6A7S7W1P7K0{CS>A0p&3OK#9P8pN9ZB00WFe z6#E$_k??(*P@(@%pwA`75dy%tHcT9+8NMV`3@8m)f#Ogm3j+i>(sG)t$o?3w!V0o+^pgvX{9~dcm2=wFW#BUoRSCR#X zz-}Te=0_O8C!tWSz=kIY$S@6qcf&PfO&*a7JL2b^FoINTuP9K-B>j$pi?g7K*z z!=z9S@#rW4fffb;sLleR;*Lj%vOt2#KB00TxK|h?bpUWoy1~2<&I=L@#0-BZFd7hB z;PDo3M0yM-P6k9<;R|nU9kQ?%5K?&hG5`<{u~9O=0KkMbL-2EtA>KQGM7S9PfP7dE z(bPHv%KsjXJXyW4e!KvPUmZi7at0=B`JwyhN8ma+0s&zJ#_&Q?AZ$u6LFO&m!0ct= zg+_p2JU(8C$bm!LXEssvIA4%iY{TSd0QMvtA}~Q!B$6_&8Pg z0v*KwcK~w=0o-u<8bQo|3IO2d7p7=l9to&;1QEPB<&-{~ONB;&Kr{w`=pq*Eczlf3 zj6FttL46=TlVX3?TAvDRTTgd@H@N^DA!W7Er`6S^X1O$Q9 zYKKu~ALG#ZfIvuo2iVsIXv7ta;qNO4F{&KGGz@_u8XSP&6AnXYc#mtFHou`DUR}_&&!a9t8z-d@Ur9zsIv2 z0!uV|*zxQ^5ts)A%7)92p}qjra2G450Q1;!%LU9316*K&&J{2WjjeOU0KkBPMzPgt zt$+jq*9Z`_QSLJ>fCB=Nj0xJ&#=pm`OeJ89=7KqP0l}C?6HLHNW)ETXGX{y28X)|h z1MvC=0Em48>H*CFV-!7y=>HzWX&Viph&>0u#18|YceU~oU6fsZTqP~FV3JOG304g+ ogangz1|8- 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%0AB8hw1jA|i+Jj4h{*`x08-$|SZEUCtQp%VecX{q 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 WfZ2WLV{rK*2<$I^6MWYVPX9k9IsXd) diff --git a/art/sponsor-material-theme.png b/art/sponsor-material-theme.png index f65752906f94a7a1539ceb5ea361b06b59cb3c20..203c6909487103994407578bce2c9e066d974199 100644 GIT binary patch delta 6000 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 NNB{r^#IvdfTnr+mS2zFw delta 1418 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 delta 11087 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 BIamMy delta 969 zcma)*O-~a+7{@yeC`LSpQ6tDpJc)E=-@3HM#B96MZEJT+xBDIscDKN`OiO{bEF6G% z@?zAB8@<8Ncp%}hi3iRe`~Z4E;=zMgzkov_24gf%GI=tY=lMPV=RcY4qk-+CfjxN8 zKl%3l`u=|Y;KfA$otL|%?*5lUl>ym+9Rf6)p*SYNurx743u%HCQY4XrDTYXL8-v<$_=%^_}rX6v~%sh(>~g4C8& zTa(m9PO591tZFNgkmImxSe(~(g_dlaif3cdR`_ljyc*f+E(mG9fD$E0##N<}>{Oxc zS+t(2W)(bP9zT^n4^whcBkiu!RMd*uLM2ln-3F>*%aQ5xrix@ihrN5vZDd;2to*n7 zqGeEL>g66l#{kixwEl$|=jdW$`CVmgaLj=QiuK*R=T6C3}i5 zSbQgVPymzHAL=d!!ipjH-o`TX@ulTbHMm#+qgQll))n=2>|58ZrDWW-8*UZAqbTK; zXA~(5eNvSbDFI1MRq@=A;#JL)HAq>i?;39uLbSOOCOe~{qn zGI$dG_$hq73~qz-oLF1pD$Vf23Md2632(LmyL%xL8Qbgwb2;z8$SUh C>@=tV From afb17c4419eb7d37a6b028ea7f40854ba04b1ced Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Tue, 26 Jul 2022 21:44:36 +0300 Subject: [PATCH 08/22] Buy me a coffee --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 88ce578..9661129 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # Laravel Testing Tools -[Become a Patron](https://patreon.com/dmitryivanov) +[Buy me a coffee](https://buymeacoffee.com/dmitry.ivanov) [![StyleCI](https://github.styleci.io/repos/75414626/shield?branch=master&style=flat)](https://github.styleci.io/repos/75414626?branch=master) [![Build Status](https://img.shields.io/github/workflow/status/dmitry-ivanov/laravel-testing-tools/tests/master)](https://github.com/dmitry-ivanov/laravel-testing-tools/actions?query=workflow%3Atests+branch%3Amaster) From cdf318915b95d1e7f619ab463a67469cac570368 Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Tue, 26 Jul 2022 22:57:12 +0300 Subject: [PATCH 09/22] Drop obsolete assertions (became part of Laravel core) --- README.md | 181 +----------------- src/Asserts/ArtisanAsserts.php | 175 ----------------- src/Helpers/ArtisanHelpers.php | 48 ----- src/TestingTools.php | 5 +- tests/Asserts/ArtisanAssertsTest.php | 160 ---------------- .../confirmable.accepted.output.txt | 5 - .../generic.correct.output.txt | 1 - .../generic.incorrect.output.txt | 1 - .../table.needle.output.txt | 1 - .../table.wrong-needle.output.txt | 1 - tests/Helpers/ArtisanHelpersTest.php | 49 ----- tests/TestCase.php | 10 +- tests/TestingToolsTest.php | 4 - .../Commands/ConfirmableTraitCommand.php | 30 --- .../Console/Commands/ConfirmationCommand.php | 27 --- .../app/Console/Commands/GenericCommand.php | 33 ---- .../Console/Commands/TableOutputCommand.php | 37 ---- tests/fixture/app/Console/Kernel.php | 16 -- 18 files changed, 7 insertions(+), 777 deletions(-) delete mode 100644 src/Asserts/ArtisanAsserts.php delete mode 100644 src/Helpers/ArtisanHelpers.php delete mode 100644 tests/Asserts/ArtisanAssertsTest.php delete mode 100644 tests/Asserts/ArtisanAssertsTest/confirmable.accepted.output.txt delete mode 100644 tests/Asserts/ArtisanAssertsTest/generic.correct.output.txt delete mode 100644 tests/Asserts/ArtisanAssertsTest/generic.incorrect.output.txt delete mode 100644 tests/Asserts/ArtisanAssertsTest/table.needle.output.txt delete mode 100644 tests/Asserts/ArtisanAssertsTest/table.wrong-needle.output.txt delete mode 100644 tests/Helpers/ArtisanHelpersTest.php delete mode 100644 tests/fixture/app/Console/Commands/ConfirmableTraitCommand.php delete mode 100644 tests/fixture/app/Console/Commands/ConfirmationCommand.php delete mode 100644 tests/fixture/app/Console/Commands/GenericCommand.php delete mode 100644 tests/fixture/app/Console/Commands/TableOutputCommand.php diff --git a/README.md b/README.md index 9661129..1803ab6 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Laravel-specific Testing Helpers and Assertions. composer require --dev illuminated/testing-tools ``` -2. Use `Illuminated\Testing\TestingTools` and disable `$mockConsoleOutput`: +2. Use `Illuminated\Testing\TestingTools` trait: ```php use Illuminated\Testing\TestingTools; @@ -47,8 +47,6 @@ Laravel-specific Testing Helpers and Assertions. { use TestingTools; - public $mockConsoleOutput = false; - // ... } ``` @@ -56,14 +54,14 @@ Laravel-specific Testing Helpers and Assertions. 3. Use any of the provided helpers and assertions in your tests: ```php - class HelloCommandTest extends TestCase + class ExampleCommandTest extends TestCase { /** @test */ - public function it_outputs_hello_world() + public function it_logs_hello_world() { - $this->artisan('hello'); + $this->artisan('example'); - $this->seeArtisanOutput('Hello, World!'); + $this->seeInLogFile('example.log', 'Hello World!'); } } ``` @@ -77,26 +75,11 @@ Laravel-specific Testing Helpers and Assertions. - [emulateProduction](#emulateproduction) - [emulateEnvironment](#emulateenvironment) - [isTravis](#istravis) -- [ArtisanHelpers](#artisanhelpers) - - [runArtisan](#runartisan) ## Available assertions > Feel free to contribute. -- [ArtisanAsserts](#artisanasserts) - - [willSeeConfirmation](#willseeconfirmation) - - [willNotSeeConfirmation](#willnotseeconfirmation) - - [willGiveConfirmation](#willgiveconfirmation) - - [willNotGiveConfirmation](#willnotgiveconfirmation) - - [seeArtisanOutput](#seeartisanoutput) - - [dontSeeArtisanOutput](#dontseeartisanoutput) - - [seeInArtisanOutput](#seeinartisanoutput) - - [dontSeeInArtisanOutput](#dontseeinartisanoutput) - - [seeArtisanTableOutput](#seeartisantableoutput) - - [dontSeeArtisanTableOutput](#dontseeartisantableoutput) - - [seeArtisanTableRowsCount](#seeartisantablerowscount) - - [dontSeeArtisanTableRowsCount](#dontseeartisantablerowscount) - [CollectionAsserts](#collectionasserts) - [assertCollectionsEqual](#assertcollectionsequal) - [assertCollectionsNotEqual](#assertcollectionsnotequal) @@ -188,162 +171,8 @@ $this->isTravis(); // true ``` -### ArtisanHelpers - -#### `runArtisan()` - -Run the given artisan console command: - -```php -$command = $this->runArtisan(MyCommand::class, ['--name' => 'John']); - -// \Illuminate\Console\Command -``` - -Also, you can pass the command instance as a first argument: - -```php -$command = $this->runArtisan(new MyCommand, ['--name' => 'Jane']); - -// \Illuminate\Console\Command -``` - ## Assertions -### ArtisanAsserts - -#### `willSeeConfirmation()` - -Add expectation that the given confirmation question would be shown: - -```php -$this->willSeeConfirmation('Are you sure?', MyCommand::class); -``` - -#### `willNotSeeConfirmation()` - -Add expectation that the given confirmation question would not be shown: - -```php -$this->willNotSeeConfirmation('Are you sure?', MyCommand::class); -``` - -#### `willGiveConfirmation()` - -Add expectation that the given confirmation question would be shown, and accept it: - -```php -$this->willGiveConfirmation('Are you sure?', MyCommand::class); - -$this->seeArtisanOutput('Done!'); -``` - -#### `willNotGiveConfirmation()` - -Add expectation that the given confirmation question would be shown, and do not accept it: - -```php -$this->willNotGiveConfirmation('Are you sure?', MyCommand::class); - -$this->dontSeeArtisanOutput('Done!'); -``` - -#### `seeArtisanOutput()` - -Assert that the given artisan output is seen: - -```php -$this->seeArtisanOutput('Hello, World!'); -``` - -Also, you can specify a path to the file containing output: - -```php -$this->seeArtisanOutput('correct.output.txt'); -``` - -#### `dontSeeArtisanOutput()` - -Assert that the given artisan output is not seen: - -```php -$this->dontSeeArtisanOutput('Hello, Universe!'); -``` - -Also, you can specify a path to the file containing output: - -```php -$this->dontSeeArtisanOutput('incorrect.output.txt'); -``` - -#### `seeInArtisanOutput()` - -Assert that the given string is seen in the artisan output: - -```php -$this->seeInArtisanOutput('Hello'); -``` - -Also, you can specify a path to the file containing the string: - -```php -$this->seeInArtisanOutput('needle.txt'); -``` - -#### `dontSeeInArtisanOutput()` - -Assert that the given string is not seen in the artisan output: - -```php -$this->dontSeeInArtisanOutput('FooBar'); -``` - -Also, you can specify a path to the file containing the string: - -```php -$this->dontSeeInArtisanOutput('wrong-needle.txt'); -``` - -#### `seeArtisanTableOutput()` - -Assert that the given data is seen in the artisan table output: - -```php -$this->seeArtisanTableOutput([ - ['System' => 'Node-1', 'Status' => 'Enabled'], - ['System' => 'Node-2', 'Status' => 'Enabled'], - ['System' => 'Node-3', 'Status' => 'Enabled'], -]); -``` - -#### `dontSeeArtisanTableOutput()` - -Assert that the given data is not seen in the artisan table output: - -```php -$this->dontSeeArtisanTableOutput([ - ['System' => 'Node-1', 'Status' => 'Disabled'], - ['System' => 'Node-2', 'Status' => 'Disabled'], - ['System' => 'Node-3', 'Status' => 'Disabled'], -]); -``` - -#### `seeArtisanTableRowsCount()` - -Assert that the artisan table output has the given number of data rows: - -```php -$this->seeArtisanTableRowsCount(3); -``` - -#### `dontSeeArtisanTableRowsCount()` - -Assert that the artisan table output doesn't have the given number of data rows: - -```php -$this->dontSeeArtisanTableRowsCount(5); -``` - ### CollectionAsserts #### `assertCollectionsEqual()` diff --git a/src/Asserts/ArtisanAsserts.php b/src/Asserts/ArtisanAsserts.php deleted file mode 100644 index 1ff7e75..0000000 --- a/src/Asserts/ArtisanAsserts.php +++ /dev/null @@ -1,175 +0,0 @@ -shouldReceive('confirm')->once()->with($question); - - $this->runArtisan($mock, $parameters); - } - - /** - * Add expectation that the given confirmation question would not be shown. - */ - protected function willNotSeeConfirmation(string $question, string $command, array $parameters = []): void - { - $mock = Mockery::mock("{$command}[confirm]"); - $mock->shouldNotReceive('confirm')->with($question); - - $this->runArtisan($mock, $parameters); - } - - /** - * Add expectation that the given confirmation question would be shown, and accept it. - */ - protected function willGiveConfirmation(string $question, string $command, array $parameters = []): void - { - $mock = Mockery::mock("{$command}[confirm]"); - $mock->shouldReceive('confirm')->once()->with($question)->andReturn(true); - - $this->runArtisan($mock, $parameters); - } - - /** - * Add expectation that the given confirmation question would be shown, and do not accept it. - */ - protected function willNotGiveConfirmation(string $question, string $command, array $parameters = []): void - { - $mock = Mockery::mock("{$command}[confirm]"); - $mock->shouldReceive('confirm')->once()->with($question)->andReturn(false); - - $this->runArtisan($mock, $parameters); - } - - /** - * Assert that the given artisan output is seen. - */ - protected function seeArtisanOutput(string $output): void - { - if (File::exists($output)) { - $output = File::get($output); - } - - $expected = trim($output); - $actual = trim($this->getArtisanOutput()); - $this->assertEquals($expected, $actual, "Failed asserting that artisan output is `{$expected}`."); - } - - /** - * Assert that the given artisan output is not seen. - */ - protected function dontSeeArtisanOutput(string $output): void - { - if (File::exists($output)) { - $output = File::get($output); - } - - $expected = trim($output); - $actual = trim($this->getArtisanOutput()); - $this->assertNotEquals($expected, $actual, "Failed asserting that artisan output is not `{$expected}`."); - } - - /** - * Assert that the given string is seen in the artisan output. - */ - protected function seeInArtisanOutput(string $needle): void - { - if (File::exists($needle)) { - $needle = File::get($needle); - } - - $output = $this->getArtisanOutput(); - $message = "Failed asserting that artisan output contains `{$needle}`."; - $this->assertStringContainsString($needle, $output, $message); - } - - /** - * Assert that the given string is not seen in the artisan output. - */ - protected function dontSeeInArtisanOutput(string $needle): void - { - if (File::exists($needle)) { - $needle = File::get($needle); - } - - $output = $this->getArtisanOutput(); - $message = "Failed asserting that artisan output not contains `{$needle}`."; - $this->assertStringNotContainsString($needle, $output, $message); - } - - /** - * Assert that the given data is seen in the artisan table output. - */ - protected function seeArtisanTableOutput(array $data): void - { - $message = 'Failed asserting that artisan table output consists of expected data.'; - $this->assertEquals($data, $this->parseArtisanTableOutput($this->getArtisanOutput()), $message); - } - - /** - * Assert that the given data is not seen in the artisan table output. - */ - protected function dontSeeArtisanTableOutput(array $data): void - { - $message = 'Failed asserting that artisan table output not consists of expected data.'; - $this->assertNotEquals($data, $this->parseArtisanTableOutput($this->getArtisanOutput()), $message); - } - - /** - * Assert that the artisan table output has the given number of data rows. - */ - protected function seeArtisanTableRowsCount(int $count): void - { - $message = "Failed asserting that artisan table rows count equals to `{$count}`."; - $this->assertCount($count, $this->parseArtisanTableOutput($this->getArtisanOutput()), $message); - } - - /** - * Assert that the artisan table output doesn't have the given number of data rows. - */ - protected function dontSeeArtisanTableRowsCount(int $count): void - { - $message = "Failed asserting that artisan table rows count not equals to `{$count}`."; - $this->assertNotCount($count, $this->parseArtisanTableOutput($this->getArtisanOutput()), $message); - } - - /** - * Parse the artisan table output. - * - * Return data rows with headers as keys. - */ - private function parseArtisanTableOutput(string $output): array - { - $output = explode("\n", trim($output)); - - // Filter and normalize the output - $output = collect($output) - ->reject(function (string $line) { - return !Str::contains($line, '|'); - }) - ->map(function (string $line) { - $line = explode('|', $line); - $line = array_filter($line); - return array_map('trim', $line); - }); - - // The first item is headers - $headers = $output->shift(); - - // Combine headers with the line values - return $output->map(function (array $values) use ($headers) { - return array_combine($headers, $values); - })->toArray(); - } -} diff --git a/src/Helpers/ArtisanHelpers.php b/src/Helpers/ArtisanHelpers.php deleted file mode 100644 index c5027bc..0000000 --- a/src/Helpers/ArtisanHelpers.php +++ /dev/null @@ -1,48 +0,0 @@ -setLaravel($this->app); - - self::$artisanOutput = new BufferedOutput; - $command->run(new ArrayInput($parameters), self::$artisanOutput); - - return $command; - } - - /** - * Get artisan output. - */ - protected function getArtisanOutput(): string - { - $output = Artisan::output(); - if (!empty($output)) { - self::$artisanOutput = $output; - } - - if (self::$artisanOutput instanceof BufferedOutput) { - self::$artisanOutput = self::$artisanOutput->fetch(); - } - - return self::$artisanOutput; - } -} diff --git a/src/TestingTools.php b/src/TestingTools.php index 32212df..8c5ca10 100644 --- a/src/TestingTools.php +++ b/src/TestingTools.php @@ -2,7 +2,6 @@ namespace Illuminated\Testing; -use Illuminated\Testing\Asserts\ArtisanAsserts; use Illuminated\Testing\Asserts\CollectionAsserts; use Illuminated\Testing\Asserts\DatabaseAsserts; use Illuminated\Testing\Asserts\EloquentAsserts; @@ -13,15 +12,13 @@ use Illuminated\Testing\Asserts\ScheduleAsserts; use Illuminated\Testing\Asserts\ServiceProviderAsserts; use Illuminated\Testing\Helpers\ApplicationHelpers; -use Illuminated\Testing\Helpers\ArtisanHelpers; trait TestingTools { /** Helpers */ use ApplicationHelpers; - use ArtisanHelpers; + /** Asserts */ - use ArtisanAsserts; use CollectionAsserts; use DatabaseAsserts; use EloquentAsserts; diff --git a/tests/Asserts/ArtisanAssertsTest.php b/tests/Asserts/ArtisanAssertsTest.php deleted file mode 100644 index a953c71..0000000 --- a/tests/Asserts/ArtisanAssertsTest.php +++ /dev/null @@ -1,160 +0,0 @@ -willSeeConfirmation('Are you sure?', ConfirmationCommand::class); - } - - /** @test */ - public function which_also_works_with_confirmable_trait() - { - $this->willSeeConfirmation('Do you really wish to run this command?', ConfirmableTraitCommand::class); - } - - /** @test */ - public function it_has_will_not_see_confirmation_assertion() - { - $this->willNotSeeConfirmation('Are you sure?', GenericCommand::class); - } - - /** @test */ - public function it_has_will_give_confirmation_assertion() - { - $this->willGiveConfirmation('Are you sure?', ConfirmationCommand::class); - - $this->seeArtisanOutput('Done!'); - } - - /** @test */ - public function which_is_also_works_with_confirmable_trait() - { - $this->willGiveConfirmation('Do you really wish to run this command?', ConfirmableTraitCommand::class); - - $this->seeArtisanOutput(__DIR__ . '/ArtisanAssertsTest/confirmable.accepted.output.txt'); - } - - /** @test */ - public function it_has_will_not_give_confirmation_assertion() - { - $this->willNotGiveConfirmation('Are you sure?', ConfirmationCommand::class); - - $this->dontSeeArtisanOutput(__DIR__ . '/ArtisanAssertsTest/confirmable.accepted.output.txt'); - } - - /** @test */ - public function it_has_see_artisan_output_assertion() - { - $this->artisan('generic'); - - $this->seeArtisanOutput('Hello, World!'); - } - - /** @test */ - public function which_accepts_file_path_instead_of_string_output() - { - $this->artisan('generic'); - - $this->seeArtisanOutput(__DIR__ . '/ArtisanAssertsTest/generic.correct.output.txt'); - } - - /** @test */ - public function it_has_dont_see_artisan_output_assertion() - { - $this->artisan('generic'); - - $this->dontSeeArtisanOutput('Hello, Universe!'); - } - - /** @test */ - public function which_also_accepts_file_path_instead_of_string_output() - { - $this->artisan('generic'); - - $this->dontSeeArtisanOutput(__DIR__ . '/ArtisanAssertsTest/generic.incorrect.output.txt'); - } - - /** @test */ - public function it_has_see_in_artisan_output_assertion() - { - $this->artisan('table-output'); - - $this->seeInArtisanOutput('Node-2'); - } - - /** @test */ - public function which_accepts_file_path_instead_of_string_needle() - { - $this->artisan('table-output'); - - $this->seeInArtisanOutput(__DIR__ . '/ArtisanAssertsTest/table.needle.output.txt'); - } - - /** @test */ - public function it_has_dont_see_in_artisan_output_assertion() - { - $this->artisan('table-output'); - - $this->dontSeeInArtisanOutput('Hello'); - } - - /** @test */ - public function which_also_accepts_file_path_instead_of_string_needle() - { - $this->artisan('table-output'); - - $this->dontSeeInArtisanOutput(__DIR__ . '/ArtisanAssertsTest/table.wrong-needle.output.txt'); - } - - /** @test */ - public function it_has_see_artisan_table_output_assertion() - { - $this->artisan('table-output'); - - $this->seeArtisanTableOutput([ - ['System' => 'Node-1', 'Status' => 'Enabled'], - ['System' => 'Node-2', 'Status' => 'Enabled'], - ['System' => 'Node-3', 'Status' => 'Enabled'], - ]); - } - - /** @test */ - public function it_has_dont_see_artisan_table_output_assertion() - { - $this->artisan('table-output'); - - $this->dontSeeArtisanTableOutput([ - ['System' => 'Node-1', 'Status' => 'Disabled'], - ['System' => 'Node-2', 'Status' => 'Disabled'], - ['System' => 'Node-3', 'Status' => 'Disabled'], - ]); - } - - /** @test */ - public function it_has_see_artisan_table_rows_count_assertion() - { - $this->artisan('table-output'); - - $this->seeArtisanTableRowsCount(3); - } - - /** @test */ - public function it_has_dont_see_artisan_table_rows_count_assertion() - { - $this->artisan('table-output'); - - $this->dontSeeArtisanTableRowsCount(1); - $this->dontSeeArtisanTableRowsCount(2); - $this->dontSeeArtisanTableRowsCount(4); - $this->dontSeeArtisanTableRowsCount(5); - } -} diff --git a/tests/Asserts/ArtisanAssertsTest/confirmable.accepted.output.txt b/tests/Asserts/ArtisanAssertsTest/confirmable.accepted.output.txt deleted file mode 100644 index 0bf295f..0000000 --- a/tests/Asserts/ArtisanAssertsTest/confirmable.accepted.output.txt +++ /dev/null @@ -1,5 +0,0 @@ -****************************** -* Attention, please! * -****************************** - -Done! diff --git a/tests/Asserts/ArtisanAssertsTest/generic.correct.output.txt b/tests/Asserts/ArtisanAssertsTest/generic.correct.output.txt deleted file mode 100644 index 8ab686e..0000000 --- a/tests/Asserts/ArtisanAssertsTest/generic.correct.output.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, World! diff --git a/tests/Asserts/ArtisanAssertsTest/generic.incorrect.output.txt b/tests/Asserts/ArtisanAssertsTest/generic.incorrect.output.txt deleted file mode 100644 index c643077..0000000 --- a/tests/Asserts/ArtisanAssertsTest/generic.incorrect.output.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, Universe! diff --git a/tests/Asserts/ArtisanAssertsTest/table.needle.output.txt b/tests/Asserts/ArtisanAssertsTest/table.needle.output.txt deleted file mode 100644 index 4c10f7c..0000000 --- a/tests/Asserts/ArtisanAssertsTest/table.needle.output.txt +++ /dev/null @@ -1 +0,0 @@ -Node-2 \ No newline at end of file diff --git a/tests/Asserts/ArtisanAssertsTest/table.wrong-needle.output.txt b/tests/Asserts/ArtisanAssertsTest/table.wrong-needle.output.txt deleted file mode 100644 index 5ab2f8a..0000000 --- a/tests/Asserts/ArtisanAssertsTest/table.wrong-needle.output.txt +++ /dev/null @@ -1 +0,0 @@ -Hello \ No newline at end of file diff --git a/tests/Helpers/ArtisanHelpersTest.php b/tests/Helpers/ArtisanHelpersTest.php deleted file mode 100644 index 54a158e..0000000 --- a/tests/Helpers/ArtisanHelpersTest.php +++ /dev/null @@ -1,49 +0,0 @@ -runArtisan(GenericCommand::class); - - $this->assertInstanceOf(GenericCommand::class, $command); - $this->assertEquals('Hello, Dude!', $command->getGreetingMessage()); - } - - /** @test */ - public function it_can_run_artisan_command_by_class_name_and_parameters() - { - /** @var GenericCommand $command */ - $command = $this->runArtisan(GenericCommand::class, ['--name' => 'John']); - - $this->assertInstanceOf(GenericCommand::class, $command); - $this->assertEquals('Hello, John!', $command->getGreetingMessage()); - } - - /** @test */ - public function it_can_run_artisan_command_by_object() - { - /** @var GenericCommand $command */ - $command = $this->runArtisan(new GenericCommand); - - $this->assertInstanceOf(GenericCommand::class, $command); - $this->assertEquals('Hello, Dude!', $command->getGreetingMessage()); - } - - /** @test */ - public function it_can_run_artisan_command_by_object_and_parameters() - { - /** @var GenericCommand $command */ - $command = $this->runArtisan(new GenericCommand, ['--name' => 'Jane']); - - $this->assertInstanceOf(GenericCommand::class, $command); - $this->assertEquals('Hello, Jane!', $command->getGreetingMessage()); - } -} diff --git a/tests/TestCase.php b/tests/TestCase.php index 8f7f7ed..0c2f189 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -12,13 +12,6 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase { use TestingTools; - /** - * Indicates if the console output should be mocked. - * - * @var bool - */ - public $mockConsoleOutput = false; - /** * Setup the test environment. */ @@ -55,8 +48,7 @@ protected function setUpDatabase(): void '--database' => 'testing', '--realpath' => true, '--path' => __DIR__ . '/fixture/database/migrations/', - ]); - $this->seeInArtisanOutput('Migrated'); + ])->expectsOutputToContain('DONE'); } /** diff --git a/tests/TestingToolsTest.php b/tests/TestingToolsTest.php index d86baae..7f807e6 100644 --- a/tests/TestingToolsTest.php +++ b/tests/TestingToolsTest.php @@ -2,7 +2,6 @@ namespace Illuminated\Testing\Tests; -use Illuminated\Testing\Asserts\ArtisanAsserts; use Illuminated\Testing\Asserts\CollectionAsserts; use Illuminated\Testing\Asserts\DatabaseAsserts; use Illuminated\Testing\Asserts\EloquentAsserts; @@ -13,7 +12,6 @@ use Illuminated\Testing\Asserts\ScheduleAsserts; use Illuminated\Testing\Asserts\ServiceProviderAsserts; use Illuminated\Testing\Helpers\ApplicationHelpers; -use Illuminated\Testing\Helpers\ArtisanHelpers; use Illuminated\Testing\TestingTools; class TestingToolsTest extends TestCase @@ -22,13 +20,11 @@ class TestingToolsTest extends TestCase public function it_is_using_all_testing_tools_helpers() { $this->assertTraitUsed(TestingTools::class, ApplicationHelpers::class); - $this->assertTraitUsed(TestingTools::class, ArtisanHelpers::class); } /** @test */ public function it_is_using_all_testing_tools_asserts() { - $this->assertTraitUsed(TestingTools::class, ArtisanAsserts::class); $this->assertTraitUsed(TestingTools::class, CollectionAsserts::class); $this->assertTraitUsed(TestingTools::class, DatabaseAsserts::class); $this->assertTraitUsed(TestingTools::class, EloquentAsserts::class); diff --git a/tests/fixture/app/Console/Commands/ConfirmableTraitCommand.php b/tests/fixture/app/Console/Commands/ConfirmableTraitCommand.php deleted file mode 100644 index abdf399..0000000 --- a/tests/fixture/app/Console/Commands/ConfirmableTraitCommand.php +++ /dev/null @@ -1,30 +0,0 @@ -confirmToProceed('Attention, please!', true)) { - return; - } - - $this->info('Done!'); - } -} diff --git a/tests/fixture/app/Console/Commands/ConfirmationCommand.php b/tests/fixture/app/Console/Commands/ConfirmationCommand.php deleted file mode 100644 index ebe837c..0000000 --- a/tests/fixture/app/Console/Commands/ConfirmationCommand.php +++ /dev/null @@ -1,27 +0,0 @@ -confirm('Are you sure?')) { - return; - } - - $this->info('Done!'); - } -} diff --git a/tests/fixture/app/Console/Commands/GenericCommand.php b/tests/fixture/app/Console/Commands/GenericCommand.php deleted file mode 100644 index 7ec4598..0000000 --- a/tests/fixture/app/Console/Commands/GenericCommand.php +++ /dev/null @@ -1,33 +0,0 @@ -info('Hello, World!'); - } - - /** - * Get the greeting message. - */ - public function getGreetingMessage(): string - { - $name = $this->option('name') ?: 'Dude'; - - return "Hello, {$name}!"; - } -} diff --git a/tests/fixture/app/Console/Commands/TableOutputCommand.php b/tests/fixture/app/Console/Commands/TableOutputCommand.php deleted file mode 100644 index 65730e3..0000000 --- a/tests/fixture/app/Console/Commands/TableOutputCommand.php +++ /dev/null @@ -1,37 +0,0 @@ -getRows(); - $headers = array_keys($rows[0]); - $this->table($headers, $rows); - } - - /** - * Get the rows. - */ - private function getRows(): array - { - return [ - ['System' => 'Node-1', 'Status' => 'Enabled'], - ['System' => 'Node-2', 'Status' => 'Enabled'], - ['System' => 'Node-3', 'Status' => 'Enabled'], - ]; - } -} diff --git a/tests/fixture/app/Console/Kernel.php b/tests/fixture/app/Console/Kernel.php index 4807e39..04211c1 100644 --- a/tests/fixture/app/Console/Kernel.php +++ b/tests/fixture/app/Console/Kernel.php @@ -2,22 +2,6 @@ namespace Illuminated\Testing\Tests\App\Console; -use Illuminated\Testing\Tests\App\Console\Commands\ConfirmableTraitCommand; -use Illuminated\Testing\Tests\App\Console\Commands\ConfirmationCommand; -use Illuminated\Testing\Tests\App\Console\Commands\GenericCommand; -use Illuminated\Testing\Tests\App\Console\Commands\TableOutputCommand; - class Kernel extends \Orchestra\Testbench\Foundation\Console\Kernel { - /** - * The Artisan commands provided by the application. - * - * @var array - */ - protected $commands = [ - GenericCommand::class, - TableOutputCommand::class, - ConfirmationCommand::class, - ConfirmableTraitCommand::class, - ]; } From 839ec5d62c61ce7a7308dac341482ed120b38d5e Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Wed, 27 Jul 2022 22:55:32 +0300 Subject: [PATCH 10/22] Fix tests --- tests/TestCase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/TestCase.php b/tests/TestCase.php index 0c2f189..8b708c3 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -48,7 +48,7 @@ protected function setUpDatabase(): void '--database' => 'testing', '--realpath' => true, '--path' => __DIR__ . '/fixture/database/migrations/', - ])->expectsOutputToContain('DONE'); + ])->assertSuccessful(); } /** From cc2fd727ddbc7e2785c150a123e14aeaa9d7f8a9 Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Mon, 1 Aug 2022 21:57:06 +0300 Subject: [PATCH 11/22] Remove the `isTravis()` helper method --- README.md | 11 ----------- src/Helpers/ApplicationHelpers.php | 8 -------- tests/Helpers/ApplicationHelpersTest.php | 7 ------- 3 files changed, 26 deletions(-) diff --git a/README.md b/README.md index 1803ab6..65728af 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,6 @@ Laravel-specific Testing Helpers and Assertions. - [emulateLocal](#emulatelocal) - [emulateProduction](#emulateproduction) - [emulateEnvironment](#emulateenvironment) - - [isTravis](#istravis) ## Available assertions @@ -161,16 +160,6 @@ Emulate that application is running on the given environment: $this->emulateEnvironment('demo'); ``` -#### `isTravis()` - -Check whether the application is running on Travis or not: - -```php -$this->isTravis(); - -// true -``` - ## Assertions ### CollectionAsserts diff --git a/src/Helpers/ApplicationHelpers.php b/src/Helpers/ApplicationHelpers.php index 6da50b4..7c00854 100644 --- a/src/Helpers/ApplicationHelpers.php +++ b/src/Helpers/ApplicationHelpers.php @@ -31,12 +31,4 @@ protected function emulateEnvironment(string $environment): void return $environment; }); } - - /** - * Check whether the application is running on Travis or not. - */ - protected function isTravis(): bool - { - return (bool) getenv('TRAVIS'); - } } diff --git a/tests/Helpers/ApplicationHelpersTest.php b/tests/Helpers/ApplicationHelpersTest.php index 97002b8..5d67c32 100644 --- a/tests/Helpers/ApplicationHelpersTest.php +++ b/tests/Helpers/ApplicationHelpersTest.php @@ -29,11 +29,4 @@ public function it_can_emulate_any_environment() $this->assertEquals('demo', $this->app->environment()); } - - /** @test */ - public function it_can_check_if_tests_are_running_on_travis() - { - $expected = (bool) getenv('TRAVIS'); - $this->assertEquals($expected, $this->isTravis()); - } } From 41ea4b1863176f7a033a649b2015c52e80c74620 Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Mon, 1 Aug 2022 22:47:15 +0300 Subject: [PATCH 12/22] Simplified a bit --- src/Asserts/CollectionAsserts.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Asserts/CollectionAsserts.php b/src/Asserts/CollectionAsserts.php index d262001..21aa47c 100644 --- a/src/Asserts/CollectionAsserts.php +++ b/src/Asserts/CollectionAsserts.php @@ -11,9 +11,9 @@ trait CollectionAsserts */ protected function assertCollectionsEqual(Collection $collection1, Collection $collection2, string $key): void { - $this->assertEquals( - $collection1->pluck($key)->sort()->values(), - $collection2->pluck($key)->sort()->values(), + $this->assertEqualsCanonicalizing( + $collection1->pluck($key), + $collection2->pluck($key), 'Failed asserting that collections are equal.', ); } @@ -23,9 +23,9 @@ protected function assertCollectionsEqual(Collection $collection1, Collection $c */ protected function assertCollectionsNotEqual(Collection $collection1, Collection $collection2, string $key): void { - $this->assertNotEquals( - $collection1->pluck($key)->sort()->values(), - $collection2->pluck($key)->sort()->values(), + $this->assertNotEqualsCanonicalizing( + $collection1->pluck($key), + $collection2->pluck($key), 'Failed asserting that collections are not equal.', ); } From 3a25ad3c1339315acddd9f3d5afa4ccc047401dd Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Sun, 21 Aug 2022 14:01:25 +0300 Subject: [PATCH 13/22] Remove Eloquent assertions --- README.md | 185 -------------- src/Asserts/EloquentAsserts.php | 229 ------------------ src/TestingTools.php | 2 - tests/Asserts/EloquentAssertsTest.php | 107 -------- tests/TestCase.php | 9 - tests/TestingToolsTest.php | 2 - tests/fixture/app/Category.php | 29 --- tests/fixture/app/Comment.php | 34 --- .../app/Http/Controllers/HomeController.php | 16 -- tests/fixture/app/Post.php | 60 ----- .../database/factories/CommentFactory.php | 26 -- ...016_11_01_131425_create_comments_table.php | 30 --- .../resources/views/home/index.blade.php | 13 - .../resources/views/layout/app.blade.php | 12 - 14 files changed, 754 deletions(-) delete mode 100644 src/Asserts/EloquentAsserts.php delete mode 100644 tests/Asserts/EloquentAssertsTest.php delete mode 100644 tests/fixture/app/Category.php delete mode 100644 tests/fixture/app/Comment.php delete mode 100644 tests/fixture/app/Http/Controllers/HomeController.php delete mode 100644 tests/fixture/database/factories/CommentFactory.php delete mode 100644 tests/fixture/database/migrations/2016_11_01_131425_create_comments_table.php delete mode 100644 tests/fixture/resources/views/home/index.blade.php delete mode 100644 tests/fixture/resources/views/layout/app.blade.php diff --git a/README.md b/README.md index 65728af..35832f9 100644 --- a/README.md +++ b/README.md @@ -87,21 +87,6 @@ Laravel-specific Testing Helpers and Assertions. - [assertDatabaseMissingTable](#assertdatabasemissingtable) - [assertDatabaseHasMany](#assertdatabasehasmany) - [assertDatabaseMissingMany](#assertdatabasemissingmany) -- [EloquentAsserts](#eloquentasserts) - - [assertEloquentTableEquals](#asserteloquenttableequals) - - [assertEloquentTableNotEquals](#asserteloquenttablenotequals) - - [assertEloquentIsIncrementing](#asserteloquentisincrementing) - - [assertEloquentIsNotIncrementing](#asserteloquentisnotincrementing) - - [assertEloquentFillableEquals](#asserteloquentfillableequals) - - [assertEloquentFillableNotEquals](#asserteloquentfillablenotequals) - - [assertEloquentDatesEquals](#asserteloquentdatesequals) - - [assertEloquentDatesNotEquals](#asserteloquentdatesnotequals) - - [assertEloquentTouchesEquals](#asserteloquenttouchesequals) - - [assertEloquentTouchesNotEquals](#asserteloquenttouchesnotequals) - - [assertEloquentHasMany](#asserteloquenthasmany) - - [assertEloquentHasCreateFor](#asserteloquenthascreatefor) - - [assertEloquentHasCreateManyFor](#asserteloquenthascreatemanyfor) - - [assertEloquentBelongsTo](#asserteloquentbelongsto) - [ExceptionAsserts](#exceptionasserts) - [willSeeException](#willseeexception) - [FilesystemAsserts](#filesystemasserts) @@ -221,176 +206,6 @@ $this->assertDatabaseMissingMany('posts', [ ]); ``` -### EloquentAsserts - -#### `assertEloquentTableEquals()` - -Assert that the model's table name equals to the given value: - -```php -$this->assertEloquentTableEquals(User::class, 'users'); -``` - -#### `assertEloquentTableNotEquals()` - -Assert that the model's table name doesn't equal to the given value: - -```php -$this->assertEloquentTableNotEquals(User::class, 'posts'); -``` - -#### `assertEloquentIsIncrementing()` - -Assert that the model's primary key is incrementing: - -```php -$this->assertEloquentIsIncrementing(Post::class); -``` - -#### `assertEloquentIsNotIncrementing()` - -Assert that the model's primary key is not incrementing: - -```php -$this->assertEloquentIsNotIncrementing(Category::class); -``` - -#### `assertEloquentFillableEquals()` - -Assert that the model's `fillable` field equals to the given value: - -```php -$this->assertEloquentFillableEquals(Post::class, ['title', 'publish_at']); -``` - -#### `assertEloquentFillableNotEquals()` - -Assert that the model's `fillable` field doesn't equal to the given value: - -```php -$this->assertEloquentFillableNotEquals(Post::class, ['title', 'body', 'publish_at']); -``` - -#### `assertEloquentDatesEquals()` - -Assert that the model's `dates` field equals to the given value: - -```php -$this->assertEloquentDatesEquals(Post::class, ['publish_at', 'created_at', 'updated_at']); -``` - -#### `assertEloquentDatesNotEquals()` - -Assert that the model's `dates` field doesn't equal to the given value: - -```php -$this->assertEloquentDatesNotEquals(Post::class, ['publish_at']); -``` - -#### `assertEloquentTouchesEquals()` - -Assert that the model's `touches` field equals to the given value: - -```php -$this->assertEloquentTouchesEquals(Comment::class, ['post']); -``` - -#### `assertEloquentTouchesNotEquals()` - -Assert that the model's `touches` field doesn't equal to the given value: - -```php -$this->assertEloquentTouchesNotEquals(Comment::class, ['user']); -``` - -#### `assertEloquentHasMany()` - -> NOTE: To use this assertion, you have to create model factories for both classes. - -Assert that the model has the given `HasMany` relation: - -```php -$this->assertEloquentHasMany(Post::class, 'comments'); -``` - -Assuming that `Post` class has `comments` relation: - -```php -class Post extends Model -{ - public function comments() - { - return $this->hasMany(Comment::class); - } -} -``` - -#### `assertEloquentHasCreateFor()` - -> NOTE: To use this assertion, you have to create model factories for both classes. - -Assert that the model has `create` method for the given `HasMany` relation: - -```php -$this->assertEloquentHasCreateFor(Post::class, 'comments'); -``` - -Assuming that `Post` class has `createComment()` method: - -```php -class Post extends Model -{ - public function createComment(array $attributes) - { - return $this->comments()->create($attributes); - } -} -``` - -#### `assertEloquentHasCreateManyFor()` - -> NOTE: To use this assertion, you have to create model factories for both classes. - -Assert that the model has `createMany` method for the given `HasMany` relation: - -```php -$this->assertEloquentHasCreateManyFor(Post::class, 'comments'); -``` - -Assuming that `Post` class has `createManyComments()` method: - -```php -class Post extends Model -{ - public function createManyComments(array $comments) - { - return $this->comments()->createMany($comments); - } -} -``` - -#### `assertEloquentBelongsTo()` - -> NOTE: To use this assertion, you have to create model factories for both classes. - -Assert that the model has the given `BelongsTo` relation: - -```php -$this->assertEloquentBelongsTo(Comment::class, 'post'); -``` - -Assuming that `Comment` class has `post` relation: - -```php -class Comment extends Model -{ - public function post() - { - return $this->belongsTo(Post::class); - } -} -``` - ### ExceptionAsserts #### `willSeeException()` diff --git a/src/Asserts/EloquentAsserts.php b/src/Asserts/EloquentAsserts.php deleted file mode 100644 index f4adf8d..0000000 --- a/src/Asserts/EloquentAsserts.php +++ /dev/null @@ -1,229 +0,0 @@ -assertEquals($table, $model->getTable(), $message); - } - - /** - * Assert that the model's table name doesn't equal to the given value. - */ - protected function assertEloquentTableNotEquals(string $class, string $table): void - { - /** @var \Illuminate\Database\Eloquent\Model $model */ - $model = new $class; - - $message = "Failed asserting that Eloquent table not equals to `{$table}`."; - $this->assertNotEquals($table, $model->getTable(), $message); - } - - /** - * Assert that the model's primary key is incrementing. - */ - protected function assertEloquentIsIncrementing(string $class): void - { - /** @var \Illuminate\Database\Eloquent\Model $model */ - $model = new $class; - - $message = 'Failed asserting that Eloquent model has incrementing primary key.'; - $this->assertTrue($model->getIncrementing(), $message); - } - - /** - * Assert that the model's primary key is not incrementing. - */ - protected function assertEloquentIsNotIncrementing(string $class): void - { - /** @var \Illuminate\Database\Eloquent\Model $model */ - $model = new $class; - - $message = 'Failed asserting that Eloquent model has not incrementing primary key.'; - $this->assertFalse($model->getIncrementing(), $message); - } - - /** - * Assert that the model's `fillable` field equals to the given value. - */ - protected function assertEloquentFillableEquals(string $class, array $fillable): void - { - /** @var \Illuminate\Database\Eloquent\Model $model */ - $model = new $class; - - $message = 'Failed asserting that Eloquent fillable equals to specified value.'; - $this->assertEquals($fillable, $model->getFillable(), $message); - } - - /** - * Assert that the model's `fillable` field doesn't equal to the given value. - */ - protected function assertEloquentFillableNotEquals(string $class, array $fillable): void - { - /** @var \Illuminate\Database\Eloquent\Model $model */ - $model = new $class; - - $message = 'Failed asserting that Eloquent fillable not equals to specified value.'; - $this->assertNotEquals($fillable, $model->getFillable(), $message); - } - - /** - * Assert that the model's `dates` field equals to the given value. - */ - protected function assertEloquentDatesEquals(string $class, array $dates): void - { - /** @var \Illuminate\Database\Eloquent\Model $model */ - $model = new $class; - - $message = 'Failed asserting that Eloquent dates equals to specified value.'; - $this->assertEquals($dates, $model->getDates(), $message); - } - - /** - * Assert that the model's `dates` field doesn't equal to the given value. - */ - protected function assertEloquentDatesNotEquals(string $class, array $dates): void - { - /** @var \Illuminate\Database\Eloquent\Model $model */ - $model = new $class; - - $message = 'Failed asserting that Eloquent dates not equals to specified value.'; - $this->assertNotEquals($dates, $model->getDates(), $message); - } - - /** - * Assert that the model's `touches` field equals to the given value. - */ - protected function assertEloquentTouchesEquals(string $class, array $touches): void - { - /** @var \Illuminate\Database\Eloquent\Model $model */ - $model = new $class; - - $message = 'Failed asserting that Eloquent touches equals to specified value.'; - $this->assertEquals($touches, $model->getTouchedRelations(), $message); - } - - /** - * Assert that the model's `touches` field doesn't equal to the given value. - */ - protected function assertEloquentTouchesNotEquals(string $class, array $touches): void - { - /** @var \Illuminate\Database\Eloquent\Model $model */ - $model = new $class; - - $message = 'Failed asserting that Eloquent touches not equals to specified value.'; - $this->assertNotEquals($touches, $model->getTouchedRelations(), $message); - } - - /** - * Assert that the model has the given `HasMany` relation. - */ - protected function assertEloquentHasMany(string $class, string $relation): void - { - $this->assertMethodExists($class, $relation); - - /** @var \Illuminate\Database\Eloquent\Relations\HasMany $hasManyRelation */ - $hasManyRelation = (new $class)->{$relation}(); - $this->assertInstanceOf(HasMany::class, $hasManyRelation); - - $parentKey = $hasManyRelation->getParent()->getKeyName(); - $childModel = $hasManyRelation->getRelated(); - $childKey = $childModel->getKeyName(); - $childForeignKey = $hasManyRelation->getForeignKeyName(); - - $parent = Factory::factoryForModel($class)->create(); - $children = Factory::factoryForModel(get_class($childModel)) - ->count(3) - ->create([$childForeignKey => $parent->{$parentKey}]); - - $this->assertCollectionsEqual($children, $parent->{$relation}, $childKey); - } - - /** - * Assert that the model has `create` method for the given `HasMany` relation. - */ - protected function assertEloquentHasCreateFor(string $class, string $relation, string $createMethod = ''): void - { - $this->assertMethodExists($class, $relation); - - /** @var \Illuminate\Database\Eloquent\Relations\HasMany $hasManyRelation */ - $hasManyRelation = (new $class)->{$relation}(); - $this->assertInstanceOf(HasMany::class, $hasManyRelation); - - $createMethod = !empty($createMethod) ? $createMethod : 'create' . Str::title(Str::singular($relation)); - $this->assertMethodExists($class, $createMethod); - - /** @var \Illuminate\Database\Eloquent\Model $child */ - $parent = Factory::factoryForModel($class)->create(); - $child = $parent->{$createMethod}( - Factory::factoryForModel(get_class($hasManyRelation->getRelated())) - ->make() - ->toArray() - ); - - $this->assertEquals($child->fresh()->toArray(), $parent->{$relation}->first()->toArray()); - } - - /** - * Assert that the model has `createMany` method for the given `HasMany` relation. - */ - protected function assertEloquentHasCreateManyFor(string $class, string $relation, string $createManyMethod = ''): void - { - $this->assertMethodExists($class, $relation); - - /** @var \Illuminate\Database\Eloquent\Relations\HasMany $hasManyRelation */ - $hasManyRelation = (new $class)->{$relation}(); - $this->assertInstanceOf(HasMany::class, $hasManyRelation); - - $createManyMethod = !empty($createManyMethod) ? $createManyMethod : 'createMany' . Str::title($relation); - $this->assertMethodExists($class, $createManyMethod); - - $childModel = $hasManyRelation->getRelated(); - $childKey = $childModel->getKeyName(); - - $parent = Factory::factoryForModel($class)->create(); - $children = $parent->{$createManyMethod}( - Factory::factoryForModel(get_class($childModel)) - ->count(3) - ->make() - ->toArray() - ); - - $this->assertCollectionsEqual($children, $parent->{$relation}, $childKey); - } - - /** - * Assert that the model has the given `BelongsTo` relation. - */ - protected function assertEloquentBelongsTo(string $class, string $relation): void - { - $this->assertMethodExists($class, $relation); - - /** @var \Illuminate\Database\Eloquent\Relations\BelongsTo $belongsToRelation */ - $belongsToRelation = (new $class)->{$relation}(); - $this->assertInstanceOf(BelongsTo::class, $belongsToRelation); - - $parentModel = $belongsToRelation->getRelated(); - $parentKey = $parentModel->getKeyName(); - $childForeignKey = $belongsToRelation->getForeignKeyName(); - - $parent = Factory::factoryForModel(get_class($parentModel))->create(); - $child = Factory::factoryForModel($class)->create([$childForeignKey => $parent->{$parentKey}]); - - $this->assertEquals($parent->fresh()->toArray(), $child->{$relation}->toArray()); - } -} diff --git a/src/TestingTools.php b/src/TestingTools.php index 8c5ca10..34d254b 100644 --- a/src/TestingTools.php +++ b/src/TestingTools.php @@ -4,7 +4,6 @@ use Illuminated\Testing\Asserts\CollectionAsserts; use Illuminated\Testing\Asserts\DatabaseAsserts; -use Illuminated\Testing\Asserts\EloquentAsserts; use Illuminated\Testing\Asserts\ExceptionAsserts; use Illuminated\Testing\Asserts\FilesystemAsserts; use Illuminated\Testing\Asserts\LogFileAsserts; @@ -21,7 +20,6 @@ trait TestingTools /** Asserts */ use CollectionAsserts; use DatabaseAsserts; - use EloquentAsserts; use ExceptionAsserts; use FilesystemAsserts; use LogFileAsserts; diff --git a/tests/Asserts/EloquentAssertsTest.php b/tests/Asserts/EloquentAssertsTest.php deleted file mode 100644 index be1881b..0000000 --- a/tests/Asserts/EloquentAssertsTest.php +++ /dev/null @@ -1,107 +0,0 @@ -assertEloquentTableEquals(Post::class, 'posts'); - } - - /** @test */ - public function it_has_eloquent_table_not_equals_assertion() - { - $this->assertEloquentTableNotEquals(Post::class, 'users'); - } - - /** @test */ - public function it_has_eloquent_is_incrementing_assertion() - { - $this->assertEloquentIsIncrementing(Post::class); - } - - /** @test */ - public function it_has_eloquent_is_not_incrementing_assertion() - { - $this->assertEloquentIsNotIncrementing(Category::class); - } - - /** @test */ - public function it_has_eloquent_fillable_equals_assertion() - { - $this->assertEloquentFillableEquals(Post::class, ['title', 'publish_at']); - } - - /** @test */ - public function it_has_eloquent_fillable_not_equals_assertion() - { - $this->assertEloquentFillableNotEquals(Post::class, ['title', 'body', 'publish_at']); - } - - /** @test */ - public function it_has_eloquent_dates_equals_assertion() - { - $this->assertEloquentDatesEquals(Post::class, ['publish_at', 'created_at', 'updated_at']); - } - - /** @test */ - public function it_has_eloquent_dates_not_equals_assertion() - { - $this->assertEloquentDatesNotEquals(Post::class, ['publish_at']); - } - - /** @test */ - public function it_has_eloquent_touches_equals_assertion() - { - $this->assertEloquentTouchesEquals(Post::class, []); - } - - /** @test */ - public function it_has_eloquent_touches_not_equals_assertion() - { - $this->assertEloquentTouchesNotEquals(Post::class, ['user']); - } - - /** @test */ - public function it_has_eloquent_has_many_assertion() - { - $this->assertEloquentHasMany(Post::class, 'comments'); - } - - /** @test */ - public function it_has_eloquent_has_create_for_assertion() - { - $this->assertEloquentHasCreateFor(Post::class, 'comments'); - } - - /** @test */ - public function which_supports_optional_parameter_for_specifying_custom_create_method_name() - { - $this->assertEloquentHasCreateFor(Post::class, 'comments', 'attachComment'); - } - - /** @test */ - public function it_has_eloquent_has_create_many_for_assertion() - { - $this->assertEloquentHasCreateManyFor(Post::class, 'comments'); - } - - /** @test */ - public function which_also_supports_optional_parameter_for_specifying_custom_create_many_method_name() - { - $this->assertEloquentHasCreateManyFor(Post::class, 'comments', 'attachManyComments'); - } - - /** @test */ - public function it_has_eloquent_belongs_to_assertion() - { - $this->assertEloquentBelongsTo(Comment::class, 'post'); - } -} diff --git a/tests/TestCase.php b/tests/TestCase.php index 8b708c3..2ae708b 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -21,7 +21,6 @@ protected function setUp(): void $this->setUpDatabase(); $this->setUpFactories(); - $this->setUpViews(); $this->setUpStorage(); } @@ -59,14 +58,6 @@ private function setUpFactories(): void Factory::useNamespace('Illuminated\\Testing\\Tests\\Database\\Factories\\'); } - /** - * Setup views. - */ - private function setUpViews(): void - { - app('view')->addLocation(__DIR__ . '/fixture/resources/views'); - } - /** * Setup storage. */ diff --git a/tests/TestingToolsTest.php b/tests/TestingToolsTest.php index 7f807e6..818fc4d 100644 --- a/tests/TestingToolsTest.php +++ b/tests/TestingToolsTest.php @@ -4,7 +4,6 @@ use Illuminated\Testing\Asserts\CollectionAsserts; use Illuminated\Testing\Asserts\DatabaseAsserts; -use Illuminated\Testing\Asserts\EloquentAsserts; use Illuminated\Testing\Asserts\ExceptionAsserts; use Illuminated\Testing\Asserts\FilesystemAsserts; use Illuminated\Testing\Asserts\LogFileAsserts; @@ -27,7 +26,6 @@ public function it_is_using_all_testing_tools_asserts() { $this->assertTraitUsed(TestingTools::class, CollectionAsserts::class); $this->assertTraitUsed(TestingTools::class, DatabaseAsserts::class); - $this->assertTraitUsed(TestingTools::class, EloquentAsserts::class); $this->assertTraitUsed(TestingTools::class, ExceptionAsserts::class); $this->assertTraitUsed(TestingTools::class, FilesystemAsserts::class); $this->assertTraitUsed(TestingTools::class, LogFileAsserts::class); diff --git a/tests/fixture/app/Category.php b/tests/fixture/app/Category.php deleted file mode 100644 index 3b8de76..0000000 --- a/tests/fixture/app/Category.php +++ /dev/null @@ -1,29 +0,0 @@ -belongsTo(Post::class); - } -} diff --git a/tests/fixture/app/Http/Controllers/HomeController.php b/tests/fixture/app/Http/Controllers/HomeController.php deleted file mode 100644 index 5c5265d..0000000 --- a/tests/fixture/app/Http/Controllers/HomeController.php +++ /dev/null @@ -1,16 +0,0 @@ -hasMany(Comment::class); - } - - /** - * Create a comment. - */ - public function createComment(array $attributes): Comment - { - return $this->comments()->create($attributes); - } - - /** - * Create many comments. - */ - public function createManyComments(array $comments): Collection - { - return $this->comments()->createMany($comments); - } - - /** - * Attach a comment. - * - * @noinspection PhpUnused - */ - public function attachComment(array $attributes): Comment - { - return $this->createComment($attributes); - } - - /** - * Attach many comments. - * - * @noinspection PhpUnused - */ - public function attachManyComments(array $comments): Collection - { - return $this->createManyComments($comments); - } } diff --git a/tests/fixture/database/factories/CommentFactory.php b/tests/fixture/database/factories/CommentFactory.php deleted file mode 100644 index 3c810b1..0000000 --- a/tests/fixture/database/factories/CommentFactory.php +++ /dev/null @@ -1,26 +0,0 @@ - $this->faker->sentence, - ]; - } -} diff --git a/tests/fixture/database/migrations/2016_11_01_131425_create_comments_table.php b/tests/fixture/database/migrations/2016_11_01_131425_create_comments_table.php deleted file mode 100644 index f5d21fb..0000000 --- a/tests/fixture/database/migrations/2016_11_01_131425_create_comments_table.php +++ /dev/null @@ -1,30 +0,0 @@ -increments('id'); - $table->integer('post_id')->index(); - $table->string('body'); - $table->timestamps(); - $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade'); - }); - } - - /** - * Rollback the migration. - */ - public function down(): void - { - Schema::drop('comments'); - } -}; diff --git a/tests/fixture/resources/views/home/index.blade.php b/tests/fixture/resources/views/home/index.blade.php deleted file mode 100644 index 65954a3..0000000 --- a/tests/fixture/resources/views/home/index.blade.php +++ /dev/null @@ -1,13 +0,0 @@ -@extends('layout.app') - -@section('content') -

-
Welcome
-
- This is Laravel Testing Tools! -
Some test item 1
-
Some test item 2
-
Some test item 3
-
-
-@endsection diff --git a/tests/fixture/resources/views/layout/app.blade.php b/tests/fixture/resources/views/layout/app.blade.php deleted file mode 100644 index 80dce28..0000000 --- a/tests/fixture/resources/views/layout/app.blade.php +++ /dev/null @@ -1,12 +0,0 @@ - - - - - Laravel Testing Tools - - -
- @yield('content') -
- - From bcccd30bb6892e7975ea43b41f7c523e824260ea Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Sun, 21 Aug 2022 15:16:11 +0300 Subject: [PATCH 14/22] Remove exception assertions --- README.md | 12 ------------ src/Asserts/ExceptionAsserts.php | 20 -------------------- src/TestingTools.php | 2 -- tests/Asserts/ExceptionAssertsTest.php | 17 ----------------- tests/TestingToolsTest.php | 2 -- 5 files changed, 53 deletions(-) delete mode 100644 src/Asserts/ExceptionAsserts.php delete mode 100644 tests/Asserts/ExceptionAssertsTest.php diff --git a/README.md b/README.md index 35832f9..217b949 100644 --- a/README.md +++ b/README.md @@ -87,8 +87,6 @@ Laravel-specific Testing Helpers and Assertions. - [assertDatabaseMissingTable](#assertdatabasemissingtable) - [assertDatabaseHasMany](#assertdatabasehasmany) - [assertDatabaseMissingMany](#assertdatabasemissingmany) -- [ExceptionAsserts](#exceptionasserts) - - [willSeeException](#willseeexception) - [FilesystemAsserts](#filesystemasserts) - [assertDirectoryEmpty](#assertdirectoryempty) - [assertDirectoryNotEmpty](#assertdirectorynotempty) @@ -206,16 +204,6 @@ $this->assertDatabaseMissingMany('posts', [ ]); ``` -### ExceptionAsserts - -#### `willSeeException()` - -Add expectation that the given exception would be thrown: - -```php -$this->willSeeException(RuntimeException::class, 'Oops! Houston, we have a problem!'); -``` - ### FilesystemAsserts #### `assertDirectoryEmpty()` diff --git a/src/Asserts/ExceptionAsserts.php b/src/Asserts/ExceptionAsserts.php deleted file mode 100644 index ca57a15..0000000 --- a/src/Asserts/ExceptionAsserts.php +++ /dev/null @@ -1,20 +0,0 @@ -expectException($class); - - if ($message) { - $this->expectExceptionMessage($message); - } - - $this->expectExceptionCode($code); - } -} diff --git a/src/TestingTools.php b/src/TestingTools.php index 34d254b..8575941 100644 --- a/src/TestingTools.php +++ b/src/TestingTools.php @@ -4,7 +4,6 @@ use Illuminated\Testing\Asserts\CollectionAsserts; use Illuminated\Testing\Asserts\DatabaseAsserts; -use Illuminated\Testing\Asserts\ExceptionAsserts; use Illuminated\Testing\Asserts\FilesystemAsserts; use Illuminated\Testing\Asserts\LogFileAsserts; use Illuminated\Testing\Asserts\ReflectionAsserts; @@ -20,7 +19,6 @@ trait TestingTools /** Asserts */ use CollectionAsserts; use DatabaseAsserts; - use ExceptionAsserts; use FilesystemAsserts; use LogFileAsserts; use ReflectionAsserts; diff --git a/tests/Asserts/ExceptionAssertsTest.php b/tests/Asserts/ExceptionAssertsTest.php deleted file mode 100644 index b430ac9..0000000 --- a/tests/Asserts/ExceptionAssertsTest.php +++ /dev/null @@ -1,17 +0,0 @@ -willSeeException(RuntimeException::class, 'Oops! Houston, we have a problem!'); - - throw new RuntimeException('Oops! Houston, we have a problem!'); - } -} diff --git a/tests/TestingToolsTest.php b/tests/TestingToolsTest.php index 818fc4d..efbd665 100644 --- a/tests/TestingToolsTest.php +++ b/tests/TestingToolsTest.php @@ -4,7 +4,6 @@ use Illuminated\Testing\Asserts\CollectionAsserts; use Illuminated\Testing\Asserts\DatabaseAsserts; -use Illuminated\Testing\Asserts\ExceptionAsserts; use Illuminated\Testing\Asserts\FilesystemAsserts; use Illuminated\Testing\Asserts\LogFileAsserts; use Illuminated\Testing\Asserts\ReflectionAsserts; @@ -26,7 +25,6 @@ public function it_is_using_all_testing_tools_asserts() { $this->assertTraitUsed(TestingTools::class, CollectionAsserts::class); $this->assertTraitUsed(TestingTools::class, DatabaseAsserts::class); - $this->assertTraitUsed(TestingTools::class, ExceptionAsserts::class); $this->assertTraitUsed(TestingTools::class, FilesystemAsserts::class); $this->assertTraitUsed(TestingTools::class, LogFileAsserts::class); $this->assertTraitUsed(TestingTools::class, ReflectionAsserts::class); From a6c6b301d2735f5981346e02ded8b490e94f710c Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Sun, 21 Aug 2022 16:18:02 +0300 Subject: [PATCH 15/22] Remove reflection asserts --- README.md | 57 ------------------ src/Asserts/ReflectionAsserts.php | 60 ------------------- src/TestingTools.php | 2 - tests/Asserts/ReflectionAssertsTest.php | 48 --------------- tests/TestCase.php | 9 +++ tests/TestingToolsTest.php | 2 - tests/fixture/app/Commentable.php | 11 ---- tests/fixture/app/Post.php | 3 - .../database/factories/PostFactory.php | 3 - .../2016_11_01_131415_create_posts_table.php | 9 --- 10 files changed, 9 insertions(+), 195 deletions(-) delete mode 100644 src/Asserts/ReflectionAsserts.php delete mode 100644 tests/Asserts/ReflectionAssertsTest.php delete mode 100644 tests/fixture/app/Commentable.php diff --git a/README.md b/README.md index 217b949..4f7191f 100644 --- a/README.md +++ b/README.md @@ -97,13 +97,6 @@ Laravel-specific Testing Helpers and Assertions. - [dontSeeLogFile](#dontseelogfile) - [seeInLogFile](#seeinlogfile) - [dontSeeInLogFile](#dontseeinlogfile) -- [ReflectionAsserts](#reflectionasserts) - - [assertSubclassOf](#assertsubclassof) - - [assertNotSubclassOf](#assertnotsubclassof) - - [assertTraitUsed](#asserttraitused) - - [assertTraitNotUsed](#asserttraitnotused) - - [assertMethodExists](#assertmethodexists) - - [assertMethodNotExists](#assertmethodnotexists) - [ScheduleAsserts](#scheduleasserts) - [seeScheduleCount](#seeschedulecount) - [dontSeeScheduleCount](#dontseeschedulecount) @@ -307,56 +300,6 @@ $this->dontSeeInLogFile('example.log', [ ]); ``` -### ReflectionAsserts - -#### `assertSubclassOf()` - -Assert that class is a subclass of the given parent: - -```php -$this->assertSubclassOf(Post::class, Model::class); -``` - -#### `assertNotSubclassOf()` - -Assert that class is not a subclass of the given parent: - -```php -$this->assertNotSubclassOf(Post::class, Command::class); -``` - -#### `assertTraitUsed()` - -Assert that class uses the given trait: - -```php -$this->assertTraitUsed(User::class, Notifiable::class); -``` - -#### `assertTraitNotUsed()` - -Assert that class doesn't use the given trait: - -```php -$this->assertTraitNotUsed(Post::class, Notifiable::class); -``` - -#### `assertMethodExists()` - -Assert that object has the given method: - -```php -$this->assertMethodExists(Post::class, 'save'); -``` - -#### `assertMethodNotExists()` - -Assert that object doesn't have the given method: - -```php -$this->assertMethodNotExists(Post::class, 'fly'); -``` - ### ScheduleAsserts #### `seeScheduleCount()` diff --git a/src/Asserts/ReflectionAsserts.php b/src/Asserts/ReflectionAsserts.php deleted file mode 100644 index 8705524..0000000 --- a/src/Asserts/ReflectionAsserts.php +++ /dev/null @@ -1,60 +0,0 @@ -assertTrue(is_subclass_of($class, $parent), $message); - } - - /** - * Assert that class is not a subclass of the given parent. - */ - protected function assertNotSubclassOf(string $class, string $parent): void - { - $message = "Failed asserting that class `{$class}` is not subclass of `{$parent}`."; - $this->assertFalse(is_subclass_of($class, $parent), $message); - } - - /** - * Assert that class uses the given trait. - */ - protected function assertTraitUsed(string $class, string $trait): void - { - $message = "Failed asserting that class `{$class}` is using trait `{$trait}`."; - $this->assertContains($trait, class_uses($class), $message); - } - - /** - * Assert that class doesn't use the given trait. - */ - protected function assertTraitNotUsed(string $class, string $trait): void - { - $message = "Failed asserting that class `{$class}` is not using trait `{$trait}`."; - $this->assertNotContains($trait, class_uses($class), $message); - } - - /** - * Assert that object has the given method. - */ - protected function assertMethodExists(object|string $object, string $method): void - { - $message = "Failed asserting that `{$method}` method exists on specified object."; - $this->assertTrue(method_exists($object, $method), $message); - } - - /** - * Assert that object doesn't have the given method. - */ - protected function assertMethodNotExists(object|string $object, string $method): void - { - $message = "Failed asserting that `{$method}` method not exists on specified object."; - $this->assertFalse(method_exists($object, $method), $message); - } -} diff --git a/src/TestingTools.php b/src/TestingTools.php index 8575941..3060f45 100644 --- a/src/TestingTools.php +++ b/src/TestingTools.php @@ -6,7 +6,6 @@ use Illuminated\Testing\Asserts\DatabaseAsserts; use Illuminated\Testing\Asserts\FilesystemAsserts; use Illuminated\Testing\Asserts\LogFileAsserts; -use Illuminated\Testing\Asserts\ReflectionAsserts; use Illuminated\Testing\Asserts\ScheduleAsserts; use Illuminated\Testing\Asserts\ServiceProviderAsserts; use Illuminated\Testing\Helpers\ApplicationHelpers; @@ -21,7 +20,6 @@ trait TestingTools use DatabaseAsserts; use FilesystemAsserts; use LogFileAsserts; - use ReflectionAsserts; use ScheduleAsserts; use ServiceProviderAsserts; } diff --git a/tests/Asserts/ReflectionAssertsTest.php b/tests/Asserts/ReflectionAssertsTest.php deleted file mode 100644 index b38ff7e..0000000 --- a/tests/Asserts/ReflectionAssertsTest.php +++ /dev/null @@ -1,48 +0,0 @@ -assertSubclassOf(Post::class, Model::class); - } - - /** @test */ - public function it_has_not_subclass_of_assertion() - { - $this->assertNotSubclassOf(Post::class, Command::class); - } - - /** @test */ - public function it_has_trait_used_assertion() - { - $this->assertTraitUsed(Post::class, Commentable::class); - } - - /** @test */ - public function it_has_trait_not_used_assertion() - { - $this->assertTraitNotUsed(Post::class, 'Acme\Trait\Fake'); - } - - /** @test */ - public function it_has_method_exists_assertion() - { - $this->assertMethodExists(Post::class, 'save'); - } - - /** @test */ - public function it_has_method_not_exists_assertion() - { - $this->assertMethodNotExists(Post::class, 'fake'); - } -} diff --git a/tests/TestCase.php b/tests/TestCase.php index 2ae708b..affa95a 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -78,4 +78,13 @@ protected function resolveApplicationConsoleKernel($app) app(KernelContract::class); } + + /** + * Assert that class uses the given trait. + */ + protected function assertTraitUsed(string $class, string $trait): void + { + $message = "Failed asserting that class `{$class}` is using trait `{$trait}`."; + $this->assertContains($trait, class_uses($class), $message); + } } diff --git a/tests/TestingToolsTest.php b/tests/TestingToolsTest.php index efbd665..a8ffba3 100644 --- a/tests/TestingToolsTest.php +++ b/tests/TestingToolsTest.php @@ -6,7 +6,6 @@ use Illuminated\Testing\Asserts\DatabaseAsserts; use Illuminated\Testing\Asserts\FilesystemAsserts; use Illuminated\Testing\Asserts\LogFileAsserts; -use Illuminated\Testing\Asserts\ReflectionAsserts; use Illuminated\Testing\Asserts\ScheduleAsserts; use Illuminated\Testing\Asserts\ServiceProviderAsserts; use Illuminated\Testing\Helpers\ApplicationHelpers; @@ -27,7 +26,6 @@ public function it_is_using_all_testing_tools_asserts() $this->assertTraitUsed(TestingTools::class, DatabaseAsserts::class); $this->assertTraitUsed(TestingTools::class, FilesystemAsserts::class); $this->assertTraitUsed(TestingTools::class, LogFileAsserts::class); - $this->assertTraitUsed(TestingTools::class, ReflectionAsserts::class); $this->assertTraitUsed(TestingTools::class, ScheduleAsserts::class); $this->assertTraitUsed(TestingTools::class, ServiceProviderAsserts::class); } diff --git a/tests/fixture/app/Commentable.php b/tests/fixture/app/Commentable.php deleted file mode 100644 index 746a567..0000000 --- a/tests/fixture/app/Commentable.php +++ /dev/null @@ -1,11 +0,0 @@ - $this->faker->sentence, - 'publish_at' => $this->faker->dateTimeThisYear, ]; } } diff --git a/tests/fixture/database/migrations/2016_11_01_131415_create_posts_table.php b/tests/fixture/database/migrations/2016_11_01_131415_create_posts_table.php index 291c01c..25100b8 100644 --- a/tests/fixture/database/migrations/2016_11_01_131415_create_posts_table.php +++ b/tests/fixture/database/migrations/2016_11_01_131415_create_posts_table.php @@ -14,16 +14,7 @@ public function up(): void Schema::create('posts', function (Blueprint $table) { $table->increments('id'); $table->string('title'); - $table->dateTime('publish_at'); $table->timestamps(); }); } - - /** - * Rollback the migration. - */ - public function down(): void - { - Schema::drop('posts'); - } }; From d198bd6d1ab515e64eb8aee13c0deef07271cdde Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Sun, 21 Aug 2022 17:07:07 +0300 Subject: [PATCH 16/22] Remove service provider asserts --- README.md | 39 ---------------- src/Asserts/ServiceProviderAsserts.php | 45 ------------------- src/TestingTools.php | 2 - tests/Asserts/ServiceProviderAssertsTest.php | 32 ------------- tests/TestCase.php | 15 +------ tests/TestingToolsTest.php | 2 - .../Console/Commands/RegisteredCommand.php | 23 ---------- tests/fixture/app/Console/Kernel.php | 7 --- .../app/Providers/FixtureServiceProvider.php | 41 ----------------- 9 files changed, 1 insertion(+), 205 deletions(-) delete mode 100644 src/Asserts/ServiceProviderAsserts.php delete mode 100644 tests/Asserts/ServiceProviderAssertsTest.php delete mode 100644 tests/fixture/app/Console/Commands/RegisteredCommand.php delete mode 100644 tests/fixture/app/Console/Kernel.php delete mode 100644 tests/fixture/app/Providers/FixtureServiceProvider.php diff --git a/README.md b/README.md index 4f7191f..0236791 100644 --- a/README.md +++ b/README.md @@ -102,11 +102,6 @@ Laravel-specific Testing Helpers and Assertions. - [dontSeeScheduleCount](#dontseeschedulecount) - [seeInSchedule](#seeinschedule) - [dontSeeInSchedule](#dontseeinschedule) -- [ServiceProviderAsserts](#serviceproviderasserts) - - [seeRegisteredAlias](#seeregisteredalias) - - [dontSeeRegisteredAlias](#dontseeregisteredalias) - - [seeRegisteredCommand](#seeregisteredcommand) - - [dontSeeRegisteredCommand](#dontseeregisteredcommand) ## Helpers @@ -344,40 +339,6 @@ Assert that the given command is not scheduled: $this->dontSeeInSchedule('foobarbaz'); ``` -### ServiceProviderAsserts - -#### `seeRegisteredAlias()` - -Assert that the given alias is registered: - -```php -$this->seeRegisteredAlias('Twitter'); -``` - -#### `dontSeeRegisteredAlias()` - -Assert that the given alias is not registered: - -```php -$this->dontSeeRegisteredAlias('FooBarBaz'); -``` - -#### `seeRegisteredCommand()` - -Assert that the given command is registered: - -```php -$this->seeRegisteredCommand('my-command'); -``` - -#### `dontSeeRegisteredCommand()` - -Assert that the given command is not registered: - -```php -$this->dontSeeRegisteredCommand('foobarbaz'); -``` - ## Sponsors [![Laravel Idea](art/sponsor-laravel-idea.png)](https://laravel-idea.com)
diff --git a/src/Asserts/ServiceProviderAsserts.php b/src/Asserts/ServiceProviderAsserts.php deleted file mode 100644 index 6ba4af8..0000000 --- a/src/Asserts/ServiceProviderAsserts.php +++ /dev/null @@ -1,45 +0,0 @@ -assertNotEmpty(AliasLoader::getInstance()->load($alias), $message); - } - - /** - * Assert that the given alias is not registered. - */ - protected function dontSeeRegisteredAlias(string $alias): void - { - $message = "Failed asserting that alias `{$alias}` is not registered."; - $this->assertEmpty(AliasLoader::getInstance()->load($alias), $message); - } - - /** - * Assert that the given command is registered. - */ - protected function seeRegisteredCommand(string $name): void - { - $message = "Failed asserting that command `{$name}` is registered."; - $this->assertArrayHasKey($name, Artisan::all(), $message); - } - - /** - * Assert that the given command is not registered. - */ - protected function dontSeeRegisteredCommand(string $name): void - { - $message = "Failed asserting that command `{$name}` is not registered."; - $this->assertArrayNotHasKey($name, Artisan::all(), $message); - } -} diff --git a/src/TestingTools.php b/src/TestingTools.php index 3060f45..ba43518 100644 --- a/src/TestingTools.php +++ b/src/TestingTools.php @@ -7,7 +7,6 @@ use Illuminated\Testing\Asserts\FilesystemAsserts; use Illuminated\Testing\Asserts\LogFileAsserts; use Illuminated\Testing\Asserts\ScheduleAsserts; -use Illuminated\Testing\Asserts\ServiceProviderAsserts; use Illuminated\Testing\Helpers\ApplicationHelpers; trait TestingTools @@ -21,5 +20,4 @@ trait TestingTools use FilesystemAsserts; use LogFileAsserts; use ScheduleAsserts; - use ServiceProviderAsserts; } diff --git a/tests/Asserts/ServiceProviderAssertsTest.php b/tests/Asserts/ServiceProviderAssertsTest.php deleted file mode 100644 index 5c56bf1..0000000 --- a/tests/Asserts/ServiceProviderAssertsTest.php +++ /dev/null @@ -1,32 +0,0 @@ -seeRegisteredAlias('Acme\Alias\Post'); - } - - /** @test */ - public function it_has_dont_see_registered_alias_assertion() - { - $this->dontSeeRegisteredAlias('Acme\Alias\Fake'); - } - - /** @test */ - public function it_has_see_registered_command_assertion() - { - $this->seeRegisteredCommand('registered'); - } - - /** @test */ - public function it_has_dont_see_registered_command_assertion() - { - $this->dontSeeRegisteredCommand('fake'); - } -} diff --git a/tests/TestCase.php b/tests/TestCase.php index affa95a..8a2bf5e 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -5,8 +5,6 @@ use Illuminate\Contracts\Console\Kernel as KernelContract; use Illuminate\Database\Eloquent\Factories\Factory; use Illuminated\Testing\TestingTools; -use Illuminated\Testing\Tests\App\Console\Kernel; -use Illuminated\Testing\Tests\App\Providers\FixtureServiceProvider; abstract class TestCase extends \Orchestra\Testbench\TestCase { @@ -24,17 +22,6 @@ protected function setUp(): void $this->setUpStorage(); } - /** - * Get package providers. - * - * @param \Illuminate\Foundation\Application $app - * @return array - */ - protected function getPackageProviders($app) - { - return [FixtureServiceProvider::class]; - } - /** * Setup the database. */ @@ -74,7 +61,7 @@ private function setUpStorage(): void */ protected function resolveApplicationConsoleKernel($app) { - $app->singleton(KernelContract::class, Kernel::class); + parent::resolveApplicationConsoleKernel($app); app(KernelContract::class); } diff --git a/tests/TestingToolsTest.php b/tests/TestingToolsTest.php index a8ffba3..1c9df23 100644 --- a/tests/TestingToolsTest.php +++ b/tests/TestingToolsTest.php @@ -7,7 +7,6 @@ use Illuminated\Testing\Asserts\FilesystemAsserts; use Illuminated\Testing\Asserts\LogFileAsserts; use Illuminated\Testing\Asserts\ScheduleAsserts; -use Illuminated\Testing\Asserts\ServiceProviderAsserts; use Illuminated\Testing\Helpers\ApplicationHelpers; use Illuminated\Testing\TestingTools; @@ -27,6 +26,5 @@ public function it_is_using_all_testing_tools_asserts() $this->assertTraitUsed(TestingTools::class, FilesystemAsserts::class); $this->assertTraitUsed(TestingTools::class, LogFileAsserts::class); $this->assertTraitUsed(TestingTools::class, ScheduleAsserts::class); - $this->assertTraitUsed(TestingTools::class, ServiceProviderAsserts::class); } } diff --git a/tests/fixture/app/Console/Commands/RegisteredCommand.php b/tests/fixture/app/Console/Commands/RegisteredCommand.php deleted file mode 100644 index 3ae90cc..0000000 --- a/tests/fixture/app/Console/Commands/RegisteredCommand.php +++ /dev/null @@ -1,23 +0,0 @@ -info('Done!'); - } -} diff --git a/tests/fixture/app/Console/Kernel.php b/tests/fixture/app/Console/Kernel.php deleted file mode 100644 index 04211c1..0000000 --- a/tests/fixture/app/Console/Kernel.php +++ /dev/null @@ -1,7 +0,0 @@ -registerAliases(); - $this->registerCommands(); - } - - /** - * Register aliases. - */ - private function registerAliases(): void - { - $this->app->booting(function () { - $loader = AliasLoader::getInstance(); - $loader->alias('Acme\Alias\Post', Post::class); - }); - } - - /** - * Register commands. - */ - private function registerCommands(): void - { - $this->app->singleton('command.fixture.registered', RegisteredCommand::class); - - $this->commands(['command.fixture.registered']); - } -} From 6b8c784350b964f7a227b04af2f685b8e3ce0124 Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Sun, 21 Aug 2022 17:40:42 +0300 Subject: [PATCH 17/22] Change the main example --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 0236791..2333213 100644 --- a/README.md +++ b/README.md @@ -54,14 +54,16 @@ Laravel-specific Testing Helpers and Assertions. 3. Use any of the provided helpers and assertions in your tests: ```php - class ExampleCommandTest extends TestCase + class ExampleTest extends TestCase { /** @test */ - public function it_logs_hello_world() + public function it_has_lots_of_useful_assertions() { - $this->artisan('example'); - - $this->seeInLogFile('example.log', 'Hello World!'); + $this->assertDatabaseHasMany('posts', [ + ['title' => 'Awesome!'], + ['title' => 'Multiple rows check'], + ['title' => 'Can be done in one assertion'], + ]); } } ``` From 43cde41b6692d2f05daab5f3dbdf766a2d12bff7 Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Sun, 21 Aug 2022 18:05:36 +0300 Subject: [PATCH 18/22] Fix readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2333213..0080e6e 100644 --- a/README.md +++ b/README.md @@ -61,8 +61,8 @@ Laravel-specific Testing Helpers and Assertions. { $this->assertDatabaseHasMany('posts', [ ['title' => 'Awesome!'], - ['title' => 'Multiple rows check'], - ['title' => 'Can be done in one assertion'], + ['title' => 'Check multiple rows'], + ['title' => 'In one simple assertion 🤟'], ]); } } From 0592567611c2853d05f59afe76f016fafc315255 Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Sun, 21 Aug 2022 18:39:09 +0300 Subject: [PATCH 19/22] Fix readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 0080e6e..cce4b63 100644 --- a/README.md +++ b/README.md @@ -351,3 +351,5 @@ $this->dontSeeInSchedule('foobarbaz'); Laravel Testing Tools is open-sourced software licensed under the [MIT license](LICENSE.md). [Support on Patreon](https://patreon.com/dmitryivanov) + +[Buy me a coffee](https://buymeacoffee.com/dmitry.ivanov) From f3dc2ee58a53ca50f3491fc455d9d87a9549fc9f Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Sun, 21 Aug 2022 18:43:52 +0300 Subject: [PATCH 20/22] Fix readme --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cce4b63..a1a05ab 100644 --- a/README.md +++ b/README.md @@ -350,6 +350,5 @@ $this->dontSeeInSchedule('foobarbaz'); Laravel Testing Tools is open-sourced software licensed under the [MIT license](LICENSE.md). -[Support on Patreon](https://patreon.com/dmitryivanov) - -[Buy me a coffee](https://buymeacoffee.com/dmitry.ivanov) +[Support on Patreon](https://patreon.com/dmitryivanov)
+[Buy me a coffee](https://buymeacoffee.com/dmitry.ivanov)
From 7d0a1334783ecf016e986802b7737c953e705ad9 Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Sun, 21 Aug 2022 18:51:21 +0300 Subject: [PATCH 21/22] Fix readme --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a1a05ab..b7da757 100644 --- a/README.md +++ b/README.md @@ -350,5 +350,6 @@ $this->dontSeeInSchedule('foobarbaz'); Laravel Testing Tools is open-sourced software licensed under the [MIT license](LICENSE.md). -[Support on Patreon](https://patreon.com/dmitryivanov)
-[Buy me a coffee](https://buymeacoffee.com/dmitry.ivanov)
+[Support on Patreon](https://patreon.com/dmitryivanov) +  +[Buy me a coffee](https://buymeacoffee.com/dmitry.ivanov) From 800a08df8c50be91f6bbab98ca95da936a75436d Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Sun, 21 Aug 2022 18:52:59 +0300 Subject: [PATCH 22/22] Fix readme --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b7da757..4763e10 100644 --- a/README.md +++ b/README.md @@ -350,6 +350,5 @@ $this->dontSeeInSchedule('foobarbaz'); Laravel Testing Tools is open-sourced software licensed under the [MIT license](LICENSE.md). -[Support on Patreon](https://patreon.com/dmitryivanov) -  -[Buy me a coffee](https://buymeacoffee.com/dmitry.ivanov) +[Support on Patreon](https://patreon.com/dmitryivanov)  +[Buy me a coffee](https://buymeacoffee.com/dmitry.ivanov)