diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 16e655f..f271d3e 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -6,7 +6,7 @@ on: workflow_dispatch: jobs: - test: + integration-tests: runs-on: ubuntu-latest steps: @@ -21,14 +21,6 @@ jobs: - name: Install dependencies run: composer install - - name: Set up Docker Compose - uses: docker/setup-compose-action@v1 - - - name: Prepare data directory with correct permissions - run: | - mkdir -p ./tests/.litebase - chmod 777 ./tests/.litebase - - name: Run integration tests run: vendor/bin/pest tests/Integration diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 84f03e1..2a52f3b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -21,4 +21,4 @@ jobs: run: composer install --no-interaction --prefer-dist --optimize-autoloader - name: Tests - run: ./vendor/bin/pest --ci + run: ./vendor/bin/pest tests/Unit --ci diff --git a/README.md b/README.md index 6b541b8..714a332 100644 --- a/README.md +++ b/README.md @@ -9,13 +9,45 @@ A PHP SDK for interacting with [Litebase](https://github.com/litebase/litebase), You can install the package via composer: ```bash -composer require ... +composer require litebase/litebase-php ``` ## Usage -``` php -// Usage description here +```php +use Litebase\Configuration; +use Litebase\LitebasePDO; + +$pdo = new LitebasePDO([ + 'host' => 'localhost', + 'port' => 8888, + 'token' => 'your_api_token', + 'database' => 'your_database_name/main', +]); + +$statement = $pdo->prepare('SELECT * FROM users WHERE id = ?'); +$statement->execute([1]); +$result = $statement->fetchAll(PDO::FETCH_ASSOC); + +foreach ($result as $row) { + print_r($row); +} + +// Use transactions +$pdo = $pdo->beginTransaction(); + +try { + $statement = $pdo->prepare('INSERT INTO users (name, email) VALUES (?, ?)'); + $statement->execute(['John Doe', 'john@example.com']); + + $statement = $pdo->prepare('INSERT INTO logs (user_id, action) VALUES (?, ?)'); + $statement->execute([$pdo->lastInsertId(), 'user_created']); + + $pdo->commit(); +} catch (\Exception $e) { + $pdo->rollBack(); + throw $e; +} ``` ## Contributing @@ -24,10 +56,17 @@ Please see [CONTRIBUTING](https://github.com/litebase/litebase-php?tab=contribut ### Testing +You can run the tests with: ``` bash composer test ``` +Integration test requires a running Litebase instance. You can start one using Docker: + +```bash +docker run -d -p 8888:8888 --name litebase litebase/litebase:latest +``` + ## Code of Conduct Please see [CODE OF CONDUCT](https://github.com/litebase/litebase-php?tab=coc-ov-file) for details. diff --git a/composer.json b/composer.json index 8969c1c..4a8652d 100644 --- a/composer.json +++ b/composer.json @@ -50,7 +50,8 @@ "generate_open_api": "openapi-generator-cli generate -c openapi_config.yaml", "phpstan": "vendor/bin/phpstan analyse -c phpstan.neon --memory-limit=512M src tests", "pint": "vendor/bin/pint --no-interaction", - "test": "vendor/bin/pest", + "test": "vendor/bin/pest tests/Unit", + "test-integration": "vendor/bin/pest tests/Integration", "test-coverage": "vendor/bin/pest --coverage-html coverage" } } diff --git a/phpunit.xml b/phpunit.xml index 57d0b5d..aa1f42e 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -9,6 +9,7 @@ > + tests/Integration tests/Unit diff --git a/tests/Integration/ApiClientTest.php b/tests/Integration/ApiClientTest.php index ef1eae0..adc918e 100644 --- a/tests/Integration/ApiClientTest.php +++ b/tests/Integration/ApiClientTest.php @@ -18,38 +18,21 @@ $client = new ApiClient($configuration); beforeAll(function () use ($client) { - exec('docker compose -f ./tests/docker-compose.test.yml up -d'); - - // Give the container a moment to initialize - sleep(2); + LitebaseContainer::start(); try { $response = $client->clusterStatus()->listClusterStatuses(); } catch (\Exception $e) { - $lines = []; - exec('docker ps -a'); - exec('docker compose -f ./tests/docker-compose.test.yml logs --tail=200 --no-color', $lines, $rc); - - $logs = implode("\n", $lines); - - throw new \RuntimeException('Failed to connect to Litebase server for integration tests: '.$e->getMessage()."\nContainer logs:\n{$logs}"); + throw new \RuntimeException('Failed to connect to Litebase server for integration tests: ' . $e->getMessage()); } if ($response->getStatus() !== 'success') { - $lines = []; - exec('docker ps -a'); - exec('docker compose -f ./tests/docker-compose.test.yml logs --tail=200 --no-color', $lines, $rc); - - $logs = implode("\n", $lines); - - throw new \RuntimeException('Failed to connect to Litebase server for integration tests.'."Container logs:\n{$logs}"); + throw new \RuntimeException('Failed to connect to Litebase server for integration tests.'); } }); afterAll(function () { - exec('docker compose -f ./tests/docker-compose.test.yml down -v'); - // Delete the .litebase directory to clean up any persisted data - exec('rm -rf ./tests/.litebase'); + LitebaseContainer::stop(); }); describe('ApiClient', function () use ($client) { diff --git a/tests/Integration/LitebaseContainer.php b/tests/Integration/LitebaseContainer.php new file mode 100644 index 0000000..d33a093 --- /dev/null +++ b/tests/Integration/LitebaseContainer.php @@ -0,0 +1,37 @@ +/dev/null || true"); + + $startCommand = "docker run -d --rm --name litebase-test -p 8888:8888 \\ + -e LITEBASE_CLUSTER_ID=cluster-1 \\ + -e LITEBASE_DATA_PATH=/tmp/data \\ + -e LITEBASE_ENCRYPTION_KEY=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \\ + -e LITEBASE_ENV=testing \\ + -e LITEBASE_PORT=8888 \\ + -e LITEBASE_ROOT_USERNAME=root \\ + -e LITEBASE_ROOT_PASSWORD=password \\ + -e LITEBASE_STORAGE_NETWORK_PATH=/tmp/data/_network \\ + -e LITEBASE_STORAGE_TMP_PATH=/tmp \\ + -e LITEBASE_STORAGE_OBJECT_MODE=local \\ + litebase/litebase start"; + + shell_exec($startCommand); + + sleep(2); + } + + public static function stop(): void + { + $stopCommand = "docker stop litebase-test"; + shell_exec($stopCommand); + } +} diff --git a/tests/Integration/LitebasePDOTest.php b/tests/Integration/LitebasePDOTest.php new file mode 100644 index 0000000..08081a3 --- /dev/null +++ b/tests/Integration/LitebasePDOTest.php @@ -0,0 +1,74 @@ +setHost('127.0.0.1') + ->setPort('8888') + ->setUsername('root') + ->setPassword('password'); + + $client = new ApiClient($configuration); + + try { + $client->database()->createDatabase(new DatabaseStoreRequest([ + 'name' => 'test', + ])); + } catch (\Exception $e) { + throw new \RuntimeException('Failed to connect to Litebase server for integration tests: ' . $e->getMessage()); + } +}); + +afterAll(function () { + LitebaseContainer::stop(); +}); + +describe('LitebasePDO', function () { + $pdo = new LitebasePDO([ + 'host' => 'localhost', + 'port' => '8888', + 'username' => 'root', + 'password' => 'password', + 'database' => 'test/main', + ]); + + test('can perform a transaction', function () use ($pdo) { + $result = $pdo->beginTransaction(); + expect($result)->toBeTrue(); + + $affectedRows = $pdo->exec('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, email TEXT)'); + + expect($affectedRows)->toBeGreaterThanOrEqual(0); + + $statement = $pdo->prepare('INSERT INTO users (name, email) VALUES (?, ?)'); + + $insertResult = $statement->execute(['Alice', 'alice@example.com']); + + expect($insertResult)->toBeTrue(); + + $result = $pdo->commit(); + expect($result)->toBeTrue(); + + $statement = $pdo->prepare('SELECT * FROM users WHERE email = ?'); + $statement->execute(['alice@example.com']); + + /** @var array $user */ + $user = $statement->fetch(PDO::FETCH_ASSOC); + + expect($user['name'])->toBe('Alice'); + expect($user['email'])->toBe('alice@example.com'); + }); +}); diff --git a/tests/docker-compose.test.yml b/tests/docker-compose.test.yml deleted file mode 100644 index a6361e9..0000000 --- a/tests/docker-compose.test.yml +++ /dev/null @@ -1,22 +0,0 @@ -services: - database: - image: litebase/litebase - ports: - - "8888:8888" - volumes: - - ./.litebase:/home/litebase/data - environment: - - LITEBASE_CLUSTER_ID=cluster-1 - - LITEBASE_DEBUG=true - - LITEBASE_ENV=development - - LITEBASE_DATA_PATH=/home/litebase/data - - LITEBASE_STORAGE_NETWORK_PATH=/home/litebase/data/_network - - LITEBASE_PORT=8888 - - LITEBASE_ROOT_PASSWORD=password - - LITEBASE_ROOT_USERNAME=root - - LITEBASE_ENCRYPTION_KEY=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - - LITEBASE_STORAGE_OBJECT_MODE=local - - LITEBASE_STORAGE_TMP_PATH=/tmp - -volumes: - litebase_data: