From ecc77edd3e8fd47a0bb80e5d7dbf86d45d7bae6b Mon Sep 17 00:00:00 2001 From: Andrey Helldar Date: Fri, 15 Mar 2024 21:32:39 +0300 Subject: [PATCH] Tests added --- .github/workflows/tests.yml | 131 +++++++++++++++--- .gitignore | 7 +- composer.json | 10 +- phpunit.xml | 8 +- ...{DataDumpListener.php => DumpListener.php} | 2 +- src/Service/Tables.php | 15 +- src/ServiceProvider.php | 4 +- tests/Fixtures/Database/Migration.php | 61 ++++++++ .../Providers/TestServiceProvider.php | 20 +++ .../migrations/2024_03_15_000001_foo.php | 9 ++ .../migrations/2024_03_15_000002_bar.php | 9 ++ .../migrations/2024_03_15_000003_baz.php | 9 ++ tests/Helpers/circle.php | 10 ++ tests/Helpers/data.php | 22 +++ tests/Helpers/filling.php | 15 ++ tests/Helpers/names.php | 23 +++ tests/Helpers/path.php | 31 +++++ tests/Helpers/tables.php | 28 ++++ tests/Pest.php | 8 ++ tests/TestCase.php | 64 ++++++++- tests/Unit/DumpTest.php | 21 +++ 21 files changed, 455 insertions(+), 52 deletions(-) rename src/Listeners/{DataDumpListener.php => DumpListener.php} (96%) create mode 100644 tests/Fixtures/Database/Migration.php create mode 100644 tests/Fixtures/Providers/TestServiceProvider.php create mode 100644 tests/Fixtures/migrations/2024_03_15_000001_foo.php create mode 100644 tests/Fixtures/migrations/2024_03_15_000002_bar.php create mode 100644 tests/Fixtures/migrations/2024_03_15_000003_baz.php create mode 100644 tests/Helpers/circle.php create mode 100644 tests/Helpers/data.php create mode 100644 tests/Helpers/filling.php create mode 100644 tests/Helpers/names.php create mode 100644 tests/Helpers/path.php create mode 100644 tests/Helpers/tables.php create mode 100644 tests/Pest.php create mode 100644 tests/Unit/DumpTest.php diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index cd1ceae..db150b9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -3,30 +3,115 @@ name: Tests on: [ push, pull_request ] jobs: - build: - runs-on: ubuntu-latest + + sqlite: + runs-on: ubuntu-latest + + strategy: + fail-fast: true + matrix: + php: [ "8.2", "8.3" ] + laravel: [ "10.0", "11.0" ] + + name: PHP ${{ matrix.php }}, Laravel ${{ matrix.laravel }}, SQLite 3 - strategy: - fail-fast: true - matrix: - php: [ "8.2", "8.3" ] - laravel: [ "10.0", "11.0" ] + steps: + - name: Checkout code + uses: actions/checkout@v4 - name: PHP ${{ matrix.php }}, Laravel ${{ matrix.laravel }} + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, gd, redis, pdo_mysql, pdo_pgsql + coverage: xdebug - steps: - - name: Checkout code - uses: actions/checkout@v4 + - name: Install dependencies + run: composer require laravel/framework:^${{ matrix.laravel }} - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: curl, mbstring, zip, pcntl, pdo, pdo_sqlite, iconv - coverage: xdebug - - - name: Install dependencies - run: composer require laravel/framework:^${{ matrix.laravel }} - - - name: Execute tests - run: sudo vendor/bin/phpunit + - name: Execute tests + run: sudo vendor/bin/phpunit + +# mysql: +# runs-on: ubuntu-latest +# +# strategy: +# fail-fast: true +# matrix: +# php: [ "8.2", "8.3" ] +# laravel: [ "10.0", "11.0" ] +# mysql: [ "5.7", "8" ] +# +# name: PHP ${{ matrix.php }}, Laravel ${{ matrix.laravel }}, PostgreSQL ${{ matrix.psql }} +# +# services: +# mysql: +# image: mysql:${{ matrix.mysql }} +# env: +# MYSQL_ROOT_PASSWORD: root +# MYSQL_DATABASE: default +# ports: +# - 3306:3306 +# options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 +# +# steps: +# - name: Checkout code +# uses: actions/checkout@v4 +# +# - name: Setup PHP +# uses: shivammathur/setup-php@v2 +# with: +# php-version: ${{ matrix.php }} +# extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, gd, redis, pdo_mysql, pdo_pgsql +# coverage: xdebug +# +# - name: Install dependencies +# run: composer require laravel/framework:^${{ matrix.laravel }} +# +# - name: Execute tests +# run: sudo vendor/bin/phpunit +# env: +# DB_CONNECTION: mysql +# MYSQL_HOST: 127.0.0.1 +# +# postgres: +# runs-on: ubuntu-latest +# +# strategy: +# fail-fast: true +# matrix: +# php: [ "8.2", "8.3" ] +# laravel: [ "10.0", "11.0" ] +# psql: [ "12", "13", "14", "15", "16" ] +# +# name: PHP ${{ matrix.php }}, Laravel ${{ matrix.laravel }}, PostgreSQL ${{ matrix.psql }} +# +# services: +# postgres: +# image: postgres:${{ matrix.psql }}-alpine +# ports: +# - 5432:5432 +# env: +# POSTGRES_DB: default +# POSTGRES_USER: root +# POSTGRES_PASSWORD: root +# +# steps: +# - name: Checkout code +# uses: actions/checkout@v4 +# +# - name: Setup PHP +# uses: shivammathur/setup-php@v2 +# with: +# php-version: ${{ matrix.php }} +# extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, gd, redis, pdo_mysql, pdo_pgsql +# coverage: xdebug +# +# - name: Install dependencies +# run: composer require laravel/framework:^${{ matrix.laravel }} +# +# - name: Execute tests +# run: sudo vendor/bin/phpunit +# env: +# DB_CONNECTION: pgsql +# PGSQL_HOST: 127.0.0.1 diff --git a/.gitignore b/.gitignore index 227cca8..738d71e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,11 @@ .idea/ -_site/ build/ -node_modules/ -tmp/ +tests/tmp/ vendor/ .cache .DS_Store .env -.php_cs.cache -.phpintel .temp *.bak @@ -18,4 +14,3 @@ vendor/ *.orig composer.lock -package-lock.json diff --git a/composer.json b/composer.json index 37f2e61..49e2a87 100644 --- a/composer.json +++ b/composer.json @@ -49,7 +49,9 @@ "require-dev": { "mockery/mockery": "^1.3.1", "orchestra/testbench": "^8.0 || ^9.0", - "phpunit/phpunit": "^10.0" + "pestphp/pest": "^2.34", + "pestphp/pest-plugin-laravel": "^2.3", + "ext-pdo": "*" }, "minimum-stability": "stable", "prefer-stable": true, @@ -68,6 +70,7 @@ "dragon-code/codestyler": true, "ergebnis/composer-normalize": true, "friendsofphp/php-cs-fixer": true, + "pestphp/pest-plugin": true, "symfony/thanks": true }, "preferred-install": "dist", @@ -79,5 +82,10 @@ "DragonCode\\LaravelDataDumper\\ServiceProvider" ] } + }, + "scripts": { + "test": [ + "vendor/bin/pest --parallel" + ] } } diff --git a/phpunit.xml b/phpunit.xml index de92e84..ad56879 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -12,9 +12,6 @@ - - - ./tests @@ -25,4 +22,9 @@ ./src + + + + + diff --git a/src/Listeners/DataDumpListener.php b/src/Listeners/DumpListener.php similarity index 96% rename from src/Listeners/DataDumpListener.php rename to src/Listeners/DumpListener.php index 619d674..0e7e460 100644 --- a/src/Listeners/DataDumpListener.php +++ b/src/Listeners/DumpListener.php @@ -8,7 +8,7 @@ use DragonCode\LaravelDataDumper\Service\Tables; use Illuminate\Database\Events\SchemaDumped; -class DataDumpListener +class DumpListener { public function __construct( protected readonly Tables $tables, diff --git a/src/Service/Tables.php b/src/Service/Tables.php index d734709..ea10000 100644 --- a/src/Service/Tables.php +++ b/src/Service/Tables.php @@ -4,7 +4,7 @@ namespace DragonCode\LaravelDataDumper\Service; -use stdClass; +use Illuminate\Support\Facades\Schema; class Tables { @@ -20,20 +20,11 @@ protected function toDump(): array protected function flatten(): array { - return array_map(function (array | stdClass $item) { - return is_array($item) ? $item['name'] : $item->name; - }, $this->getTables()); + return array_column($this->getTables(), 'name'); } protected function getTables(): array { - return method_exists($this->schema(), 'getAllTables') - ? $this->schema()->getAllTables() - : $this->schema()->getTables(); - } - - protected function schema() - { - return app('db.schema'); + return Schema::getTables(); } } diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php index 527e71e..a331eb8 100644 --- a/src/ServiceProvider.php +++ b/src/ServiceProvider.php @@ -5,7 +5,7 @@ namespace DragonCode\LaravelDataDumper; use DragonCode\LaravelDataDumper\Concerns\About; -use DragonCode\LaravelDataDumper\Listeners\DataDumpListener; +use DragonCode\LaravelDataDumper\Listeners\DumpListener; use Illuminate\Database\Events\SchemaDumped; use Illuminate\Support\Facades\Event; use Illuminate\Support\ServiceProvider as BaseServiceProvider; @@ -29,7 +29,7 @@ public function register(): void protected function bootListener(): void { - Event::listen(SchemaDumped::class, DataDumpListener::class); + Event::listen(SchemaDumped::class, DumpListener::class); } protected function registerConfig(): void diff --git a/tests/Fixtures/Database/Migration.php b/tests/Fixtures/Database/Migration.php new file mode 100644 index 0000000..200d87d --- /dev/null +++ b/tests/Fixtures/Database/Migration.php @@ -0,0 +1,61 @@ +createTable(); + $this->fillTable(); + } + + protected function createTable(): void + { + Schema::create($this->tableName(), function (Blueprint $table) { + $table->id(); + + $table->string($this->column()); + + $table->timestamp('created_at')->useCurrent(); + $table->timestamp('updated_at')->useCurrent(); + }); + } + + protected function fillTable(): void + { + circleProcess(fn (int $i) => $this->table()->insert([ + $this->column() => $this->value($i), + ])); + } + + protected function column(): string + { + return columnName($this->tableName); + } + + protected function value(int $index): string + { + return valueName($this->tableName, $index); + } + + protected function tableName(): string + { + return tableName($this->tableName); + } + + protected function table(): Builder + { + return DB::table($this->tableName()); + } +} diff --git a/tests/Fixtures/Providers/TestServiceProvider.php b/tests/Fixtures/Providers/TestServiceProvider.php new file mode 100644 index 0000000..0db2af3 --- /dev/null +++ b/tests/Fixtures/Providers/TestServiceProvider.php @@ -0,0 +1,20 @@ +bootMigrations(); + } + + protected function bootMigrations(): void + { + $this->loadMigrationsFrom(__DIR__ . '/../migrations'); + } +} diff --git a/tests/Fixtures/migrations/2024_03_15_000001_foo.php b/tests/Fixtures/migrations/2024_03_15_000001_foo.php new file mode 100644 index 0000000..200f9af --- /dev/null +++ b/tests/Fixtures/migrations/2024_03_15_000001_foo.php @@ -0,0 +1,9 @@ +extend('toBeDataContains', function () { + foreach (allTableNames() as $table) { + expect($this->value) + ->toContain(tableName($table)) + ->toContain(columnName($table)); + + circleProcess( + fn (int $i) => expect($this->value)->toContain(valueName($table, $i)) + ); + } +}); + +expect()->extend('toBeContainsMigrations', function () { + expect($this->value) + ->toContain('2024_03_15_000001_foo') + ->toContain('2024_03_15_000002_bar') + ->toContain('2024_03_15_000003_baz'); +}); diff --git a/tests/Helpers/filling.php b/tests/Helpers/filling.php new file mode 100644 index 0000000..db37573 --- /dev/null +++ b/tests/Helpers/filling.php @@ -0,0 +1,15 @@ +extend('toBeFilledTables', function () { + foreach (names() as $name) { + expect( + DB::table(tableName($name))->count() + )->toBe(10); + } + + return $this; +}); diff --git a/tests/Helpers/names.php b/tests/Helpers/names.php new file mode 100644 index 0000000..b1d9362 --- /dev/null +++ b/tests/Helpers/names.php @@ -0,0 +1,23 @@ +extend('toBeHasTables', function () { + $actual = array_column(Schema::getTables(), 'name'); + + sort($actual); + + expect(array_values($actual))->toBe( + array_values(allTableNames()) + ); + + return $this; +}); + +function allTableNames(): array +{ + $tables = array_map(fn (string $name) => tableName($name), names()); + + $names = array_merge($tables, ['migrations']); + + sort($names); + + return $names; +} diff --git a/tests/Pest.php b/tests/Pest.php new file mode 100644 index 0000000..597d522 --- /dev/null +++ b/tests/Pest.php @@ -0,0 +1,8 @@ +compact() + ->in('Unit'); diff --git a/tests/TestCase.php b/tests/TestCase.php index 1021ad8..5957865 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -3,15 +3,71 @@ namespace Tests; use DragonCode\LaravelDataDumper\ServiceProvider; -use Illuminate\Foundation\Testing\RefreshDatabase; +use Illuminate\Config\Repository; use Orchestra\Testbench\TestCase as BaseTestCase; +use PDO; +use Tests\Fixtures\Providers\TestServiceProvider; abstract class TestCase extends BaseTestCase { - use RefreshDatabase; - protected function getPackageProviders($app): array { - return [ServiceProvider::class]; + return [ + ServiceProvider::class, + TestServiceProvider::class, + ]; + } + + protected function getEnvironmentSetUp($app): void + { + /** @var Repository $config */ + $config = $app['config']; + + $config->set('database.schema.tables', [ + tableName('foo'), + tableName('bar'), + ]); + + $config->set('database.connections', [ + 'sqlite' => [ + 'driver' => 'sqlite', + 'database' => databasePath(), + 'prefix' => '', + 'foreign_key_constraints' => true, + ], + + 'mysql' => [ + 'driver' => 'mysql', + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '3306'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'unix_socket' => env('DB_SOCKET', ''), + 'charset' => env('DB_CHARSET', 'utf8mb4'), + 'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'), + 'prefix' => '', + 'prefix_indexes' => true, + 'strict' => true, + 'engine' => null, + 'options' => extension_loaded('pdo_mysql') ? array_filter([ + PDO::MYSQL_ATTR_SSL_CA => null, + ]) : [], + ], + + 'pgsql' => [ + 'driver' => 'pgsql', + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '5432'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => env('DB_CHARSET', 'utf8'), + 'prefix' => '', + 'prefix_indexes' => true, + 'search_path' => 'public', + 'sslmode' => 'prefer', + ], + ]); } } diff --git a/tests/Unit/DumpTest.php b/tests/Unit/DumpTest.php new file mode 100644 index 0000000..b3509d7 --- /dev/null +++ b/tests/Unit/DumpTest.php @@ -0,0 +1,21 @@ +toBeHasTables() + ->toBeFilledTables(); + + $path = dumpStoragePath(); + + artisan(DumpCommand::class, ['--path' => $path])->run(); + + $content = file_get_contents($path); + + expect($content) + ->toBeDataContains() + ->toBeContainsMigrations(); +});