diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..2cd720b --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,24 @@ +# file generated with AI assistance: Claude Code - 2026-06-13 23:14:54 UTC +name: Tests + +on: + push: + branches: [main, master, "feature/**"] + pull_request: + +jobs: + phpunit: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php: ["8.3", "8.4"] + name: PHPUnit (PHP ${{ matrix.php }}) + steps: + - uses: actions/checkout@v4 + - uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + coverage: none + - run: composer install --no-interaction --no-progress + - run: vendor/bin/phpunit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cff2af8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +# file generated with AI assistance: Claude Code - 2026-06-13 23:14:54 UTC +/vendor/ +/composer.lock +/.phpunit.cache/ diff --git a/composer.json b/composer.json index 85d7ee3..6376b61 100644 --- a/composer.json +++ b/composer.json @@ -18,6 +18,9 @@ "dmstr/api-platform-utils-bundle": "*", "dmstr/openapi-json-schema-bundle": "*" }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, "autoload": { "psr-4": { "Dmstr\\ApiConfiguration\\": "src/" diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..8086794 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,15 @@ +# file generated with AI assistance: Claude Code - 2026-06-13 23:14:54 UTC +# CLI-only test runner for this bundle — no MySQL/FPM required. +# Usage (on host): +# docker compose run --rm php +# Runs `composer install` then PHPUnit against tests/. +services: + php: + build: + dockerfile_inline: | + FROM php:8.4-cli-alpine + COPY --from=composer:2 /usr/bin/composer /usr/bin/composer + working_dir: /repo + volumes: + - .:/repo + command: sh -c "composer install --no-interaction --no-progress && vendor/bin/phpunit" diff --git a/phpunit.dist.xml b/phpunit.dist.xml new file mode 100644 index 0000000..9dc4142 --- /dev/null +++ b/phpunit.dist.xml @@ -0,0 +1,18 @@ + + + + + + tests + + + + + src + + + diff --git a/tests/Service/ApiExtensionRegistryTest.php b/tests/Service/ApiExtensionRegistryTest.php new file mode 100644 index 0000000..abdaa35 --- /dev/null +++ b/tests/Service/ApiExtensionRegistryTest.php @@ -0,0 +1,82 @@ +extension('github'); + + $registry->register($github); + + self::assertSame($github, $registry->get('github')); + } + + public function testGetUnknownReturnsNull(): void + { + self::assertNull((new ApiExtensionRegistry())->get('does-not-exist')); + } + + public function testHasReflectsRegistration(): void + { + $registry = new ApiExtensionRegistry(); + self::assertFalse($registry->has('gitlab')); + + $registry->register($this->extension('gitlab')); + self::assertTrue($registry->has('gitlab')); + } + + public function testAllReturnsNameKeyedMap(): void + { + $registry = new ApiExtensionRegistry(); + $github = $this->extension('github'); + $gitlab = $this->extension('gitlab'); + $registry->register($github); + $registry->register($gitlab); + + self::assertSame(['github' => $github, 'gitlab' => $gitlab], $registry->all()); + } + + public function testGetNamesListsRegisteredKeys(): void + { + $registry = new ApiExtensionRegistry(); + $registry->register($this->extension('github')); + $registry->register($this->extension('basecamp4')); + + self::assertSame(['github', 'basecamp4'], $registry->getNames()); + } + + public function testRegisteringSameNameOverwrites(): void + { + $registry = new ApiExtensionRegistry(); + $first = $this->extension('github'); + $second = $this->extension('github'); + + $registry->register($first); + $registry->register($second); + + self::assertSame($second, $registry->get('github')); + self::assertCount(1, $registry->all()); + } + + private function extension(string $name): ApiExtensionInterface + { + $extension = $this->createStub(ApiExtensionInterface::class); + $extension->method('getName')->willReturn($name); + + return $extension; + } +}