├── LICENSE.md ├── README.md ├── composer.json ├── phpunit.xml.dist └── src ├── Collections ├── TestCollectionMacros.php └── TestCollectionMixin.php ├── Constraints ├── ViewEquals.php ├── ViewExists.php ├── ViewNotEquals.php └── ViewNotExists.php ├── InteractsWithViews.php └── Responses ├── TestResponseMacros.php └── TestResponseMixin.php /LICENSE.md: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | 3 | Copyright (c) Sven Luijten 4 | 5 | > Permission is hereby granted, free of charge, to any person obtaining a copy 6 | > of this software and associated documentation files (the "Software"), to deal 7 | > in the Software without restriction, including without limitation the rights 8 | > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | > copies of the Software, and to permit persons to whom the Software is 10 | > furnished to do so, subject to the following conditions: 11 | > 12 | > The above copyright notice and this permission notice shall be included in 13 | > all copies or substantial portions of the Software. 14 | > 15 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | > THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![laravel-testing-utils](https://user-images.githubusercontent.com/11269635/46561515-4d5a2c80-c8f8-11e8-8f16-b0eb950c5102.jpg) 2 | 3 | # Laravel Testing Utils 4 | 5 | [![Latest Version on Packagist][ico-version]][link-packagist] 6 | [![Total Downloads][ico-downloads]][link-downloads] 7 | [![Software License][ico-license]](LICENSE.md) 8 | [![Build Status][ico-tests]][link-tests] 9 | [![StyleCI][ico-styleci]][link-styleci] 10 | [![PhpStan][ico-phpstan]][link-phpstan] 11 | 12 | This package adds various Laravel-related assertions so you won't have 13 | to write them yourself in every new application. 14 | 15 | ## Index 16 | - [Installation](#installation) 17 | - [Downloading](#downloading) 18 | - [Usage](#usage) 19 | - [`InteractsWithViews`](#interactswithviews) 20 | - [`TestCollectionMacros`](#testcollectionmacros) 21 | - [Contributing](#contributing) 22 | - [License](#license) 23 | 24 | ## Installation 25 | You will have to follow a couple of steps to install this package. 26 | 27 | ### Downloading 28 | Via [Composer](http://getcomposer.org): 29 | 30 | ```bash 31 | $ composer require sven/laravel-testing-utils:^1.0 --dev 32 | ``` 33 | 34 | Or add the package to your development dependencies in `composer.json` 35 | and run `composer update` on the command line to download the package: 36 | 37 | ```json 38 | { 39 | "require-dev": { 40 | "sven/laravel-testing-utils": "^1.0" 41 | } 42 | } 43 | ``` 44 | 45 | ## Usage 46 | You will now have access to several traits and macros to use in your test classes. 47 | 48 | ### `InteractsWithViews` 49 | This trait adds several view-related assertions. They are used as follows: 50 | 51 | ```php 52 | assertViewExists('some.view-file'); 67 | } 68 | 69 | /** @test */ 70 | public function it_does_not_create_a_view() 71 | { 72 | // ... 73 | 74 | $this->assertViewNotExists('some.view-file'); 75 | } 76 | 77 | /** @test */ 78 | public function the_view_equals() 79 | { 80 | // ... 81 | 82 | $this->assertViewEquals('The Expected Contents', 'index'); 83 | } 84 | 85 | /** @test */ 86 | public function the_view_does_not_equal() 87 | { 88 | // ... 89 | 90 | $this->assertViewNotEquals('This Is Not The Content You\'re Looking For', 'index'); 91 | } 92 | } 93 | ``` 94 | 95 | ### `TestCollectionMacros` 96 | This set of macros adds some assertions to Laravel collections: `assertContains` and `assertNotContains`. 97 | They are used as follows: 98 | 99 | ```php 100 | assertContains('some-item'); 119 | $collection->assertNotContains('some-other-item'); 120 | } 121 | } 122 | ``` 123 | 124 | ## Contributing 125 | All contributions (pull requests, issues and feature requests) are 126 | welcome. Make sure to read through the [CONTRIBUTING.md](CONTRIBUTING.md) first, 127 | though. See the [contributors page](../../graphs/contributors) for all contributors. 128 | 129 | ## License 130 | `sven/laravel-testing-utils` is licensed under the MIT License (MIT). Please see the 131 | [license file](LICENSE.md) for more information. 132 | 133 | [ico-version]: https://img.shields.io/packagist/v/sven/laravel-testing-utils.svg 134 | [ico-license]: https://img.shields.io/badge/license-MIT-brightgreen.svg 135 | [ico-downloads]: https://img.shields.io/packagist/dt/sven/laravel-testing-utils.svg 136 | [ico-tests]: https://github.com/svenluijten/laravel-testing-utils/workflows/Tests/badge.svg 137 | [ico-styleci]: https://styleci.io/repos/102160848/shield?style=flat 138 | [ico-phpstan]: https://img.shields.io/badge/phpstan-enabled-blue.svg 139 | 140 | [link-packagist]: https://packagist.org/packages/sven/laravel-testing-utils 141 | [link-downloads]: https://packagist.org/packages/sven/laravel-testing-utils 142 | [link-tests]: https://github.com/svenluijten/laravel-testing-utils/actions?query=workflow%3ATests 143 | [link-styleci]: https://styleci.io/repos/102160848 144 | [link-phpstan]: https://github.com/phpstan/phpstan 145 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sven/laravel-testing-utils", 3 | "description": "", 4 | "keywords": [ 5 | "testing", 6 | "assertions", 7 | "laravel", 8 | "phpunit", 9 | "view", 10 | "collection", 11 | "response" 12 | ], 13 | "license": "MIT", 14 | "authors": [ 15 | { 16 | "name": "Sven Luijten", 17 | "email": "svenluijten1995@gmail.com", 18 | "homepage": "https://svenluijten.com" 19 | } 20 | ], 21 | "require": { 22 | "php": "^7.1", 23 | "laravel/framework": "^5.7 || ^6.0", 24 | "phpunit/phpunit": "^7.0 || ^8.0" 25 | }, 26 | "require-dev": { 27 | "localheinz/composer-normalize": "^1.3", 28 | "orchestra/testbench": "^3.7", 29 | "phpstan/phpstan": "^0.12" 30 | }, 31 | "config": { 32 | "sort-packages": true 33 | }, 34 | "autoload": { 35 | "psr-4": { 36 | "Sven\\LaravelTestingUtils\\": "src/" 37 | } 38 | }, 39 | "autoload-dev": { 40 | "psr-4": { 41 | "Sven\\LaravelTestingUtils\\Tests\\": "tests/" 42 | } 43 | }, 44 | "scripts": { 45 | "analyse": "phpstan analyse --level=7 src/ tests/", 46 | "check": [ 47 | "@test", 48 | "@analyse" 49 | ], 50 | "test": "phpunit --ansi" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | ./tests/ 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/Collections/TestCollectionMacros.php: -------------------------------------------------------------------------------- 1 | contains(...func_get_args()), 20 | 'Failed asserting that the collection contains the specified value.' 21 | ); 22 | }; 23 | } 24 | 25 | /** 26 | * Assert that an item does not exist in the collection. 27 | * 28 | * @return \Closure 29 | */ 30 | public function assertNotContains(): callable 31 | { 32 | return function ($key, $operator = null, $value = null) { 33 | /* @var \Illuminate\Support\Collection $this */ 34 | PHPUnit::assertFalse( 35 | $this->contains(...func_get_args()), 36 | 'Failed asserting that the collection does not contain the specified value.' 37 | ); 38 | }; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Constraints/ViewEquals.php: -------------------------------------------------------------------------------- 1 | expected = $expected; 17 | } 18 | 19 | protected function matches($other): bool 20 | { 21 | /** @var \Illuminate\View\ViewFinderInterface $finder */ 22 | $finder = app('view.finder'); 23 | 24 | $contents = file_get_contents($finder->find($other)); 25 | 26 | if ($contents === false) { 27 | return false; 28 | } 29 | 30 | return $this->expected === $contents; 31 | } 32 | 33 | protected function failureDescription($other): string 34 | { 35 | return 'the content of the view '.parent::failureDescription($other); 36 | } 37 | 38 | public function toString(): string 39 | { 40 | return 'equals the specified value'; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Constraints/ViewExists.php: -------------------------------------------------------------------------------- 1 | find($other); 17 | 18 | return true; 19 | } catch (InvalidArgumentException $e) { 20 | return false; 21 | } 22 | } 23 | 24 | protected function failureDescription($other): string 25 | { 26 | return 'a view with the name '.parent::failureDescription($other); 27 | } 28 | 29 | public function toString(): string 30 | { 31 | return 'exists'; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Constraints/ViewNotEquals.php: -------------------------------------------------------------------------------- 1 | expected = $expected; 17 | } 18 | 19 | protected function matches($other): bool 20 | { 21 | /** @var \Illuminate\View\ViewFinderInterface $finder */ 22 | $finder = app('view.finder'); 23 | 24 | $contents = file_get_contents($finder->find($other)); 25 | 26 | if ($contents === false) { 27 | return false; 28 | } 29 | 30 | return $this->expected !== $contents; 31 | } 32 | 33 | protected function failureDescription($other): string 34 | { 35 | return 'the content of the view '.parent::failureDescription($other); 36 | } 37 | 38 | public function toString(): string 39 | { 40 | return 'does not equal the specified value'; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Constraints/ViewNotExists.php: -------------------------------------------------------------------------------- 1 | find($other); 17 | 18 | return false; 19 | } catch (InvalidArgumentException $e) { 20 | return true; 21 | } 22 | } 23 | 24 | protected function failureDescription($other): string 25 | { 26 | return 'a view with the name '.parent::failureDescription($other); 27 | } 28 | 29 | public function toString(): string 30 | { 31 | return 'does not exist'; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/InteractsWithViews.php: -------------------------------------------------------------------------------- 1 | ensureResponseHasView(); 24 | 25 | $data = $response->getOriginalContent()->getData(); 26 | $keys = explode('.', $keyInView); 27 | 28 | foreach ($keys as $key) { 29 | if (Arr::accessible($data)) { 30 | PHPUnit::assertTrue(Arr::exists($data, $key)); 31 | } elseif (is_object($data)) { 32 | PHPUnit::assertTrue(isset($data->{$key})); 33 | } else { 34 | PHPUnit::fail('Data is not an object or array.'); 35 | } 36 | 37 | $data = data_get($data, $key); 38 | } 39 | 40 | if ($value instanceof Closure) { 41 | PHPUnit::assertTrue($value($data)); 42 | } elseif ($value instanceof Model) { 43 | PHPUnit::assertTrue($value->is($data)); 44 | } else { 45 | PHPUnit::assertEquals($value, $data); 46 | } 47 | 48 | return $response; 49 | }; 50 | } 51 | } 52 | --------------------------------------------------------------------------------