diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7f23762..f4533c9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -3,46 +3,78 @@ name: main on: [push, pull_request] jobs: - run: + + php-cs: runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + name: Checkout repository + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + tools: phpstan, php-cs-fixer:3 + + - name: Install + uses: "ramsey/composer-install@v2" + env: + COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.COMPOSER_AUTH }}"}}' + + - name: Run PHP CS Fixer + run: php-cs-fixer fix --diff --dry-run + + - name: Run PHPStan + run: phpstan analyse src tests example + + test: + runs-on: ${{ matrix.operating-system }} + timeout-minutes: 3 + needs: + - php-cs strategy: matrix: + operating-system: [ ubuntu-latest ] php-versions: ['8.0', '8.1', '8.2'] - dependency-versions: ['lowest', 'highest'] - name: PHP ${{ matrix.php-versions }} with ${{ matrix.dependency-versions }} versions of Composer dependencies + dependency-versions: ['lowest', 'locked'] + include: + - operating-system: windows-latest + php-versions: '8.0' + dependency-versions: 'locked' + - operating-system: macos-latest + php-versions: '8.0' + dependency-versions: 'locked' + name: PHP ${{ matrix.php-versions }} on ${{ matrix.operating-system }} with ${{ matrix.dependency-versions }} versions of Composer dependencies steps: - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-versions }} - tools: phpstan, phpcs, php-cs-fixer:3 - coverage: pcov - - - name: Checkout - uses: actions/checkout@v2 - - - name: Install - uses: "ramsey/composer-install@v2" - with: - dependency-versions: ${{ matrix.dependency-versions }} - env: - COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.COMPOSER_AUTH }}"}}' - - - name: Run PHP CS Fixer - run: php-cs-fixer fix --diff --dry-run - - - name: Run PHPStan - run: phpstan analyse src tests example - - - name: Test & Generate Code Coverage - run: ./vendor/bin/phpunit - env: - PACT_LOGLEVEL: ${{ vars.PACT_LOGLEVEL }} - - - name: Upload coverage results to Coveralls - env: - COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - composer global require php-coveralls/php-coveralls - php-coveralls --coverage_clover=clover.xml -v - if: matrix.php-versions == '8.0' + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + extensions: ffi + php-version: ${{ matrix.php-versions }} + coverage: pcov + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Checkout + uses: actions/checkout@v3 + + - name: Install + uses: "ramsey/composer-install@v2" + with: + dependency-versions: ${{ matrix.dependency-versions }} + env: + COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.COMPOSER_AUTH }}"}}' + + - name: Test & Generate Code Coverage + run: composer test + env: + PACT_LOGLEVEL: ${{ vars.PACT_LOGLEVEL }} + + - name: Upload coverage results to Coveralls + env: + COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + composer global require php-coveralls/php-coveralls + php-coveralls --coverage_clover=clover.xml -v + if: matrix.php-versions == '8.2' diff --git a/composer.json b/composer.json index 7e38a6b..ae8ac2c 100644 --- a/composer.json +++ b/composer.json @@ -47,6 +47,12 @@ "url": "https://github.com/tienvx/pact-php-plugin.git" } ], + "scripts": { + "test": [ + "php -r \"array_map('unlink', glob('./example/consumer/tests/Contract/pacts/*.json'));\"", + "phpunit" + ] + }, "extra": { "downloads": { "pact-csv-plugin-metadata": { diff --git a/example/broker/pacts/csvConsumer-csvProvider.json b/example/broker/pacts/csvConsumer-csvProvider.json index 15cd01e..ce787b9 100644 --- a/example/broker/pacts/csvConsumer-csvProvider.json +++ b/example/broker/pacts/csvConsumer-csvProvider.json @@ -4,12 +4,12 @@ }, "interactions": [ { - "description": "request for a report", + "description": "request for a report.csv", "interactionMarkup": { "markup": "# Data\n\n|Name|100|2000-01-01|\n", "markupType": "COMMON_MARK" }, - "key": "ad7b43bc4dd005f5", + "key": "a565e88863669aab", "pending": false, "pluginConfiguration": { "csv": { @@ -23,7 +23,7 @@ ], "request": { "headers": { - "Content-Type": [ + "Accept": [ "text/csv" ] }, @@ -72,8 +72,8 @@ "combine": "AND", "matchers": [ { - "match": "timestamp", - "timestamp": "yyyy-MM-dd" + "format": "yyyy-MM-dd", + "match": "datetime" } ] } @@ -81,15 +81,13 @@ }, "status": 200 }, - "transport": "http", "type": "Synchronous/HTTP" } ], "metadata": { "pactRust": { - "ffi": "0.3.14", - "mockserver": "0.9.5", - "models": "1.0.0" + "ffi": "0.4.1", + "models": "1.0.4" }, "pactSpecification": { "version": "4.0" diff --git a/example/consumer/tests/Contract/CsvHttpClientTest.php b/example/consumer/tests/Contract/CsvHttpClientTest.php index cf6c077..3721e1a 100644 --- a/example/consumer/tests/Contract/CsvHttpClientTest.php +++ b/example/consumer/tests/Contract/CsvHttpClientTest.php @@ -17,7 +17,8 @@ public function testGetCsvFile() $request ->setMethod('GET') ->setPath('/report.csv') - ->addHeader('Accept', 'text/csv'); + ->addHeader('Accept', 'text/csv') + ; $response = new ProviderResponse(); $response @@ -26,15 +27,16 @@ public function testGetCsvFile() 'csvHeaders' => false, 'column:1' => "matching(type,'Name')", 'column:2' => 'matching(number,100)', - 'column:3' => "matching(datetime, 'yyyy-MM-dd','2000-01-01')" + 'column:3' => "matching(datetime, 'yyyy-MM-dd','2000-01-01')", ]) - ->setContentType('text/csv'); + ->setContentType('text/csv') + ; $config = new MockServerConfig(); $config->setConsumer('csvConsumer'); $config->setProvider('csvProvider'); $config->setPactSpecificationVersion('4.0.0'); - $config->setPactDir(__DIR__ . '/pacts'); + $config->setPactDir(__DIR__.'/pacts'); if ($logLevel = \getenv('PACT_LOGLEVEL')) { $config->setLogLevel($logLevel); } @@ -43,7 +45,8 @@ public function testGetCsvFile() ->given('report.csv file exist') ->uponReceiving('request for a report.csv') ->with($request) - ->willRespondWith($response); + ->willRespondWith($response) + ; $service = new CsvHttpClient($config->getBaseUri()); $columns = $service->getCsvFile(); diff --git a/example/provider/public/index.php b/example/provider/public/index.php index de520d0..cec52ff 100644 --- a/example/provider/public/index.php +++ b/example/provider/public/index.php @@ -1,6 +1,6 @@ getBody()->write('Hello world!'); return $response - ->withHeader('Content-Type', 'text/plain'); + ->withHeader('Content-Type', 'text/plain') + ; }); $app->post('/change-state', function (Request $request, Response $response) { diff --git a/example/provider/tests/Contract/PactVerifyTest.php b/example/provider/tests/Contract/PactVerifyTest.php index dc4ff84..3902724 100644 --- a/example/provider/tests/Contract/PactVerifyTest.php +++ b/example/provider/tests/Contract/PactVerifyTest.php @@ -11,13 +11,21 @@ class PactVerifyTest extends TestCase { private Process $process; + private int $port; protected function setUp(): void { - $this->process = new Process(['php', '-S', 'localhost:8000', '-t', __DIR__.'/../../public/']); + $this->process = new Process(['php', '-S', 'localhost:0', '-t', __DIR__.'/../../public/']); $this->process->start(); - $this->process->waitUntil(fn () => is_resource(fsockopen('localhost', 8000))); + $this->process->waitUntil(function (string $type, string $output): bool { + $result = preg_match('/Development Server \(http:\/\/localhost:(\d+)\) started/', $output, $matches); + if ($result === 1) { + $this->port = (int)$matches[1]; + } + + return $result; + }); } protected function tearDown(): void @@ -33,15 +41,15 @@ public function testPactVerifyConsumer() ->setProviderVersion('1.0.0') ->setProviderBranch('main') ->setHost('localhost') - ->setPort(8000) - ->setStateChangeUrl(new Uri('http://localhost:8000/change-state')) + ->setPort($this->port) + ->setStateChangeUrl(new Uri("http://localhost:{$this->port}/change-state")) ->setStateChangeTeardown(true) ->setStateChangeAsBody(true) ->setPublishResults(false) ; $verifier = new Verifier($config); - $verifier->addDirectory(__DIR__ . '/../../../broker/pacts'); + $verifier->addDirectory(__DIR__.'/../../../broker/pacts'); $this->assertTrue($verifier->verify()); } diff --git a/src/CsvInteractionBuilder.php b/src/CsvInteractionBuilder.php index 6e9638b..c5633c8 100644 --- a/src/CsvInteractionBuilder.php +++ b/src/CsvInteractionBuilder.php @@ -19,7 +19,7 @@ public function __construct(MockServerConfigInterface $config) private function setPluginDir(): void { - $pluginDir = __DIR__ . '/../bin/pact-plugins'; - \putenv("PACT_PLUGIN_DIR=$pluginDir"); + $pluginDir = __DIR__.'/../bin/pact-plugins'; + \putenv("PACT_PLUGIN_DIR={$pluginDir}"); } } diff --git a/tests/CsvInteractionBuilderTest.php b/tests/CsvInteractionBuilderTest.php index 983d860..033256f 100644 --- a/tests/CsvInteractionBuilderTest.php +++ b/tests/CsvInteractionBuilderTest.php @@ -2,14 +2,8 @@ namespace Tienvx\PactPhpCsv\Tests; -use PhpPact\Consumer\InteractionBuilder; -use PhpPact\Consumer\Matcher\Matcher; -use PhpPact\Consumer\Model\ConsumerRequest; -use PhpPact\Consumer\Model\ProviderResponse; -use PhpPact\Standalone\Exception\MissingEnvVariableException; use PhpPact\Standalone\MockService\MockServerConfig; use PhpPact\Standalone\MockService\MockServerConfigInterface; -use PhpPact\Standalone\MockService\MockServerEnvConfig; use PHPUnit\Framework\TestCase; use Tienvx\PactPhpCsv\CsvInteractionBuilder; use Tienvx\PactPhpPlugin\Exception\PluginNotSupportedBySpecificationException; @@ -24,7 +18,8 @@ protected function setUp(): void $this->config ->setConsumer('consumer') ->setProvider('provider') - ->setLogLevel('debug'); + ->setLogLevel('debug') + ; } public function testPluginNotSupportedBySpecification(): void @@ -40,6 +35,6 @@ public function testPluginSupportedBySpecification(): void $this->config->setPactSpecificationVersion('4.0.0'); \putenv('PACT_PLUGIN_DIR=/home'); new CsvInteractionBuilder($this->config); - $this->assertSame(realpath(__DIR__ . '/../bin/pact-plugins'), realpath(\getenv('PACT_PLUGIN_DIR'))); + $this->assertSame(realpath(__DIR__.'/../bin/pact-plugins'), realpath(\getenv('PACT_PLUGIN_DIR'))); } }