From fab48e9d36d06b5fcde84dd4d44c44e432214a08 Mon Sep 17 00:00:00 2001 From: Volodymyr Stolyarchuk Date: Tue, 15 Jul 2025 16:20:56 +0300 Subject: [PATCH 01/16] fix: add badges --- .github/workflows/default.yaml | 28 +++++- README.md | 174 ++++++++++++++++++++++++++++++++- 2 files changed, 194 insertions(+), 8 deletions(-) diff --git a/.github/workflows/default.yaml b/.github/workflows/default.yaml index 430984c..9b474e8 100644 --- a/.github/workflows/default.yaml +++ b/.github/workflows/default.yaml @@ -16,7 +16,7 @@ jobs: php-versions: ['8.2', '8.3', '8.4'] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup PHP with PECL extension uses: shivammathur/setup-php@v2 @@ -26,7 +26,7 @@ jobs: - name: Cache Composer packages id: composer-cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: vendor key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} @@ -43,4 +43,26 @@ jobs: run: vendor/bin/phpstan analyse - name: Execute PHPUnit tests - run: vendor/bin/phpunit + run: | + if [ "${{ matrix.php-versions }}" = "8.3" ]; then + vendor/bin/phpunit --coverage-clover coverage.xml + else + vendor/bin/phpunit + fi + + - name: Generate coverage badge + if: matrix.php-versions == '8.3' + uses: timkrase/phpunit-coverage-badge@v1.2.1 + with: + coverage_badge_path: output/coverage.svg + push_badge: false + + - name: Git push to image-data branch + if: matrix.php-versions == '8.3' && (github.ref == 'refs/heads/main' || github.event_name == 'pull_request') + uses: peaceiris/actions-gh-pages@v3 + with: + publish_dir: ./output + publish_branch: image-data + github_token: ${{ secrets.GITHUB_TOKEN }} + user_name: 'github-actions[bot]' + user_email: 'github-actions[bot]@users.noreply.github.com' diff --git a/README.md b/README.md index 0b6575b..e58f4e0 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # PHP-VCR integration for PHPUnit +![Coverage](https://raw.githubusercontent.com/angelov/phpunit-php-vcr/image-data/coverage.svg) + A library that allows you to easily use the PHP-VCR library in your PHPUnit tests. ## Requirements @@ -24,8 +26,8 @@ Then, add the extension to your PHPUnit configuration file. - - + + @@ -34,7 +36,8 @@ Then, add the extension to your PHPUnit configuration file. ## Usage The library provides an `UseCassette` attribute that can be declared on test classes or specific test methods. The -attribute expects one string argument - the name of the cassette. +attribute accepts a cassette name and optional parameters for advanced functionality like separate cassettes per +data provider case. When running the tests, the library will automatically turn the recorder on and off, and insert the cassettes when needed. @@ -54,7 +57,7 @@ responses in the given cassette. { #[Test] public function example(): void { ... } - + #[Test] public function another(): void { ... } } @@ -102,4 +105,165 @@ used for that method. In this example, the responses from the requests made in t #[UseCassette("example_2.yml")] public function recorded(): void { ... } } - ``` \ No newline at end of file + ``` + +## DataProvider Support + +The library supports PHPUnit's `DataProvider` functionality with additional options for managing cassettes when using data providers. + +### Basic DataProvider Usage + +When using a data provider with the basic `UseCassette` attribute, all test cases from the data provider will share the same cassette file: + +```php +use Angelov\PHPUnitPHPVcr\UseCassette; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\TestCase; + +class ExampleTest extends TestCase +{ + #[Test] + #[UseCassette("shared_cassette.yml")] + #[DataProvider("urls")] + public function testWithDataProvider(string $url): void + { + $content = file_get_contents($url); + // All test cases will use the same cassette file + } + + public static function urls(): iterable + { + yield ["https://example.com"]; + yield ["https://example.org"]; + } +} +``` + +### Separate Cassettes Per DataProvider Case + +For more granular control, you can create separate cassette files for each data provider case using the `separateCassettePerCase` parameter: + +```php +use Angelov\PHPUnitPHPVcr\UseCassette; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\TestCase; + +class ExampleTest extends TestCase +{ + #[Test] + #[UseCassette(name: "separate_cassettes.yml", separateCassettePerCase: true)] + #[DataProvider("urls")] + public function testWithSeparateCassettes(string $url): void + { + $content = file_get_contents($url); + // Each test case will have its own cassette file: + // - separate_cassettes-0.yml + // - separate_cassettes-1.yml + } + + public static function urls(): iterable + { + yield ["https://example.com"]; + yield ["https://example.org"]; + } +} +``` + +### Named DataProvider Cases + +When using named data provider cases, the cassette files will use the case names: + +```php +use Angelov\PHPUnitPHPVcr\UseCassette; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\TestCase; + +class ExampleTest extends TestCase +{ + #[Test] + #[UseCassette(name: "named_cassettes.yml", separateCassettePerCase: true)] + #[DataProvider("namedUrls")] + public function testWithNamedCassettes(string $url): void + { + $content = file_get_contents($url); + // Each test case will have its own cassette file: + // - named_cassettes-example-com.yml + // - named_cassettes-example-org.yml + } + + public static function namedUrls(): iterable + { + yield 'example.com' => ["https://example.com"]; + yield 'example.org' => ["https://example.org"]; + } +} +``` + +### Grouping Cassettes in Directories + +To organize separate cassette files in directories, use the `groupCaseFilesInDirectory` parameter: + +```php +use Angelov\PHPUnitPHPVcr\UseCassette; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\TestCase; + +class ExampleTest extends TestCase +{ + #[Test] + #[UseCassette( + name: "organized_cassettes.yml", + separateCassettePerCase: true, + groupCaseFilesInDirectory: true + )] + #[DataProvider("urls")] + public function testWithOrganizedCassettes(string $url): void + { + $content = file_get_contents($url); + // Cassette files will be organized in a directory: + // - organized_cassettes/0.yml + // - organized_cassettes/1.yml + } + + public static function urls(): iterable + { + yield ["https://example.com"]; + yield ["https://example.org"]; + } +} +``` + +### Class-Level DataProvider Support + +The dataProvider functionality also works when the `UseCassette` attribute is declared at the class level: + +```php +use Angelov\PHPUnitPHPVcr\UseCassette; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\TestCase; + +#[UseCassette(name: "class_level.yml", separateCassettePerCase: true)] +class ExampleTest extends TestCase +{ + #[Test] + #[DataProvider("urls")] + public function testMethod(string $url): void + { + $content = file_get_contents($url); + // Each test case will have separate cassettes: + // - class_level-0.yml + // - class_level-1.yml + } + + public static function urls(): iterable + { + yield ["https://example.com"]; + yield ["https://example.org"]; + } +} +``` From 40f1640f1884ab94093d38e1b11cfeed25aa50c5 Mon Sep 17 00:00:00 2001 From: Volodymyr Stolyarchuk Date: Tue, 15 Jul 2025 16:31:25 +0300 Subject: [PATCH 02/16] feat: separate cassettes per dataProvider cases --- .github/workflows/default.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/default.yaml b/.github/workflows/default.yaml index 9b474e8..21ee122 100644 --- a/.github/workflows/default.yaml +++ b/.github/workflows/default.yaml @@ -50,12 +50,18 @@ jobs: vendor/bin/phpunit fi + - name: Update README badge URL for current repository + if: matrix.php-versions == '8.3' + run: | + sed -i 's|angelov/phpunit-php-vcr|${{ github.repository }}|g' README.md + - name: Generate coverage badge if: matrix.php-versions == '8.3' uses: timkrase/phpunit-coverage-badge@v1.2.1 with: coverage_badge_path: output/coverage.svg push_badge: false + report: coverage.xml - name: Git push to image-data branch if: matrix.php-versions == '8.3' && (github.ref == 'refs/heads/main' || github.event_name == 'pull_request') From 8410421a7084bdb114b5f0059a54496609f19d7f Mon Sep 17 00:00:00 2001 From: Volodymyr Stolyarchuk Date: Tue, 15 Jul 2025 16:36:19 +0300 Subject: [PATCH 03/16] feat: separate cassettes per dataProvider cases --- .github/workflows/default.yaml | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/.github/workflows/default.yaml b/.github/workflows/default.yaml index 21ee122..9781594 100644 --- a/.github/workflows/default.yaml +++ b/.github/workflows/default.yaml @@ -53,7 +53,13 @@ jobs: - name: Update README badge URL for current repository if: matrix.php-versions == '8.3' run: | - sed -i 's|angelov/phpunit-php-vcr|${{ github.repository }}|g' README.md + if [ "${{ github.event_name }}" = "pull_request" ]; then + # For PRs, badge will be in the current branch root + sed -i 's|https://raw.githubusercontent.com/angelov/phpunit-php-vcr/image-data/coverage.svg|https://raw.githubusercontent.com/${{ github.repository }}/${{ github.head_ref }}/coverage.svg|g' README.md + else + # For main branch, badge will be in image-data branch + sed -i 's|angelov/phpunit-php-vcr|${{ github.repository }}|g' README.md + fi - name: Generate coverage badge if: matrix.php-versions == '8.3' @@ -63,8 +69,8 @@ jobs: push_badge: false report: coverage.xml - - name: Git push to image-data branch - if: matrix.php-versions == '8.3' && (github.ref == 'refs/heads/main' || github.event_name == 'pull_request') + - name: Git push to image-data branch (main branch) + if: matrix.php-versions == '8.3' && github.ref == 'refs/heads/main' uses: peaceiris/actions-gh-pages@v3 with: publish_dir: ./output @@ -72,3 +78,14 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} user_name: 'github-actions[bot]' user_email: 'github-actions[bot]@users.noreply.github.com' + + - name: Commit coverage badge to current branch (PR) + if: matrix.php-versions == '8.3' && github.event_name == 'pull_request' + run: | + git config --local user.email "github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + # Move coverage badge to root for PR commits + mv output/coverage.svg coverage.svg + git add coverage.svg + git commit -m "ci: Update coverage badge" || exit 0 + git push From b0e8ab8c0b691d367a15d0e6d8e85515ba6c05b7 Mon Sep 17 00:00:00 2001 From: Volodymyr Stolyarchuk Date: Tue, 15 Jul 2025 16:38:49 +0300 Subject: [PATCH 04/16] feat: separate cassettes per dataProvider cases --- .github/workflows/default.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/default.yaml b/.github/workflows/default.yaml index 9781594..fcd861f 100644 --- a/.github/workflows/default.yaml +++ b/.github/workflows/default.yaml @@ -84,8 +84,8 @@ jobs: run: | git config --local user.email "github-actions[bot]@users.noreply.github.com" git config --local user.name "github-actions[bot]" - # Move coverage badge to root for PR commits - mv output/coverage.svg coverage.svg + # Copy coverage badge to root for PR commits + cp output/coverage.svg coverage.svg git add coverage.svg git commit -m "ci: Update coverage badge" || exit 0 git push From 28cecc1983daa75a30dba96a51ebfa4be8e061d7 Mon Sep 17 00:00:00 2001 From: Volodymyr Stolyarchuk Date: Tue, 15 Jul 2025 16:41:23 +0300 Subject: [PATCH 05/16] feat: separate cassettes per dataProvider cases --- .github/workflows/default.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/default.yaml b/.github/workflows/default.yaml index fcd861f..12b6cb3 100644 --- a/.github/workflows/default.yaml +++ b/.github/workflows/default.yaml @@ -17,6 +17,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} - name: Setup PHP with PECL extension uses: shivammathur/setup-php@v2 @@ -84,8 +86,10 @@ jobs: run: | git config --local user.email "github-actions[bot]@users.noreply.github.com" git config --local user.name "github-actions[bot]" + # Checkout the actual PR branch + git checkout ${{ github.head_ref }} # Copy coverage badge to root for PR commits cp output/coverage.svg coverage.svg git add coverage.svg git commit -m "ci: Update coverage badge" || exit 0 - git push + git push origin ${{ github.head_ref }} From 06b3e0e109895470004d74f0bd342c4967c51705 Mon Sep 17 00:00:00 2001 From: Volodymyr Stolyarchuk Date: Tue, 15 Jul 2025 16:42:37 +0300 Subject: [PATCH 06/16] feat: separate cassettes per dataProvider cases --- .github/workflows/default.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/default.yaml b/.github/workflows/default.yaml index 12b6cb3..6c1faba 100644 --- a/.github/workflows/default.yaml +++ b/.github/workflows/default.yaml @@ -19,6 +19,7 @@ jobs: - uses: actions/checkout@v4 with: token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: '0' # Fetch all history for accurate coverage reporting - name: Setup PHP with PECL extension uses: shivammathur/setup-php@v2 From bc0a649d3947e6390cc5b035dd54a833f183864a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 15 Jul 2025 13:43:08 +0000 Subject: [PATCH 07/16] ci: Update coverage badge --- coverage.svg | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 coverage.svg diff --git a/coverage.svg b/coverage.svg new file mode 100644 index 0000000..b8caba4 --- /dev/null +++ b/coverage.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + coverage + + 31 % + + \ No newline at end of file From 4ede5083e054c215328d67439bb4b5d9af5ee327 Mon Sep 17 00:00:00 2001 From: Volodymyr Stolyarchuk Date: Tue, 15 Jul 2025 16:50:52 +0300 Subject: [PATCH 08/16] feat: separate cassettes per dataProvider cases --- .github/workflows/default.yaml | 46 +++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/.github/workflows/default.yaml b/.github/workflows/default.yaml index 6c1faba..d8cc902 100644 --- a/.github/workflows/default.yaml +++ b/.github/workflows/default.yaml @@ -9,6 +9,8 @@ on: jobs: build: runs-on: ubuntu-latest + permissions: + contents: write strategy: fail-fast: false @@ -20,6 +22,7 @@ jobs: with: token: ${{ secrets.GITHUB_TOKEN }} fetch-depth: '0' # Fetch all history for accurate coverage reporting + ref: ${{ github.event_name == 'pull_request' && github.head_ref || github.ref }} - name: Setup PHP with PECL extension uses: shivammathur/setup-php@v2 @@ -53,17 +56,6 @@ jobs: vendor/bin/phpunit fi - - name: Update README badge URL for current repository - if: matrix.php-versions == '8.3' - run: | - if [ "${{ github.event_name }}" = "pull_request" ]; then - # For PRs, badge will be in the current branch root - sed -i 's|https://raw.githubusercontent.com/angelov/phpunit-php-vcr/image-data/coverage.svg|https://raw.githubusercontent.com/${{ github.repository }}/${{ github.head_ref }}/coverage.svg|g' README.md - else - # For main branch, badge will be in image-data branch - sed -i 's|angelov/phpunit-php-vcr|${{ github.repository }}|g' README.md - fi - - name: Generate coverage badge if: matrix.php-versions == '8.3' uses: timkrase/phpunit-coverage-badge@v1.2.1 @@ -72,8 +64,28 @@ jobs: push_badge: false report: coverage.xml - - name: Git push to image-data branch (main branch) + - name: Update README badge URL for current repository + if: matrix.php-versions == '8.3' + run: | + # Update the README with the correct badge URL + sed -i 's|angelov/phpunit-php-vcr|${{ github.repository }}|g' README.md + if [ "${{ github.event_name }}" = "pull_request" ]; then + sed -i 's|image-data/coverage.svg|${{ github.head_ref }}/coverage.svg|g' README.md + fi + + - name: Check badge file exists (main branch) if: matrix.php-versions == '8.3' && github.ref == 'refs/heads/main' + id: check_badge + run: | + if [ -f "output/coverage.svg" ]; then + echo "badge_exists=true" >> $GITHUB_OUTPUT + else + echo "badge_exists=false" >> $GITHUB_OUTPUT + echo "Coverage badge file not found, skipping push to image-data branch" + fi + + - name: Deploy badge to image-data branch + if: matrix.php-versions == '8.3' && github.ref == 'refs/heads/main' && steps.check_badge.outputs.badge_exists == 'true' uses: peaceiris/actions-gh-pages@v3 with: publish_dir: ./output @@ -85,12 +97,16 @@ jobs: - name: Commit coverage badge to current branch (PR) if: matrix.php-versions == '8.3' && github.event_name == 'pull_request' run: | + # Check if badge file exists + if [ ! -f "output/coverage.svg" ]; then + echo "Coverage badge file not found, skipping commit" + exit 0 + fi + git config --local user.email "github-actions[bot]@users.noreply.github.com" git config --local user.name "github-actions[bot]" - # Checkout the actual PR branch - git checkout ${{ github.head_ref }} # Copy coverage badge to root for PR commits cp output/coverage.svg coverage.svg git add coverage.svg git commit -m "ci: Update coverage badge" || exit 0 - git push origin ${{ github.head_ref }} + git push From 6290b6466021a978694c1d42d535c9fbdfc3a40a Mon Sep 17 00:00:00 2001 From: Volodymyr Stolyarchuk Date: Tue, 15 Jul 2025 16:55:21 +0300 Subject: [PATCH 09/16] feat: separate cassettes per dataProvider cases --- .github/workflows/default.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/default.yaml b/.github/workflows/default.yaml index d8cc902..1ba8858 100644 --- a/.github/workflows/default.yaml +++ b/.github/workflows/default.yaml @@ -95,8 +95,9 @@ jobs: user_email: 'github-actions[bot]@users.noreply.github.com' - name: Commit coverage badge to current branch (PR) - if: matrix.php-versions == '8.3' && github.event_name == 'pull_request' + if: matrix.php-versions == '8.3' run: | + echo "Event name: ${{ github.event_name }}" # Check if badge file exists if [ ! -f "output/coverage.svg" ]; then echo "Coverage badge file not found, skipping commit" From 5f07984cc010df2dd6f94f31afd5d3fc27ee0a49 Mon Sep 17 00:00:00 2001 From: Volodymyr Stolyarchuk Date: Tue, 15 Jul 2025 16:59:19 +0300 Subject: [PATCH 10/16] feat: separate cassettes per dataProvider cases --- .github/workflows/default.yaml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/default.yaml b/.github/workflows/default.yaml index 1ba8858..42bdda0 100644 --- a/.github/workflows/default.yaml +++ b/.github/workflows/default.yaml @@ -60,7 +60,7 @@ jobs: if: matrix.php-versions == '8.3' uses: timkrase/phpunit-coverage-badge@v1.2.1 with: - coverage_badge_path: output/coverage.svg + coverage_badge_path: coverage.svg push_badge: false report: coverage.xml @@ -77,7 +77,8 @@ jobs: if: matrix.php-versions == '8.3' && github.ref == 'refs/heads/main' id: check_badge run: | - if [ -f "output/coverage.svg" ]; then + if [ -f "coverage.svg" ]; then + echo "Coverage badge file found" echo "badge_exists=true" >> $GITHUB_OUTPUT else echo "badge_exists=false" >> $GITHUB_OUTPUT @@ -99,15 +100,13 @@ jobs: run: | echo "Event name: ${{ github.event_name }}" # Check if badge file exists - if [ ! -f "output/coverage.svg" ]; then + if [ ! -f "coverage.svg" ]; then echo "Coverage badge file not found, skipping commit" exit 0 fi git config --local user.email "github-actions[bot]@users.noreply.github.com" git config --local user.name "github-actions[bot]" - # Copy coverage badge to root for PR commits - cp output/coverage.svg coverage.svg git add coverage.svg git commit -m "ci: Update coverage badge" || exit 0 git push From a21798880f0efd30cf8e68b450802b834c7df13e Mon Sep 17 00:00:00 2001 From: Volodymyr Stolyarchuk Date: Tue, 15 Jul 2025 17:10:08 +0300 Subject: [PATCH 11/16] feat: separate cassettes per dataProvider cases --- .github/workflows/default.yaml | 43 ++++++++++++---------------------- 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/.github/workflows/default.yaml b/.github/workflows/default.yaml index 42bdda0..b156781 100644 --- a/.github/workflows/default.yaml +++ b/.github/workflows/default.yaml @@ -15,7 +15,7 @@ jobs: strategy: fail-fast: false matrix: - php-versions: ['8.2', '8.3', '8.4'] + php-versions: [ '8.2', '8.3', '8.4' ] steps: - uses: actions/checkout@v4 @@ -56,28 +56,31 @@ jobs: vendor/bin/phpunit fi + - name: Generate coverage badge + if: matrix.php-versions != '8.3' + run: | + echo "Coverage badge generation skipped for PHP version ${{ matrix.php-versions }}" + exit 0 + - name: Generate coverage badge if: matrix.php-versions == '8.3' uses: timkrase/phpunit-coverage-badge@v1.2.1 with: - coverage_badge_path: coverage.svg + coverage_badge_path: ./output/coverage.svg push_badge: false report: coverage.xml - name: Update README badge URL for current repository - if: matrix.php-versions == '8.3' + if: matrix.php-versions == '8.3' && github.repository != 'angelov/phpunit-php-vcr' run: | # Update the README with the correct badge URL sed -i 's|angelov/phpunit-php-vcr|${{ github.repository }}|g' README.md - if [ "${{ github.event_name }}" = "pull_request" ]; then - sed -i 's|image-data/coverage.svg|${{ github.head_ref }}/coverage.svg|g' README.md - fi - - name: Check badge file exists (main branch) - if: matrix.php-versions == '8.3' && github.ref == 'refs/heads/main' + - name: Check badge file exists + if: matrix.php-versions == '8.3' id: check_badge run: | - if [ -f "coverage.svg" ]; then + if [ -f "./output/coverage.svg" ]; then echo "Coverage badge file found" echo "badge_exists=true" >> $GITHUB_OUTPUT else @@ -86,27 +89,11 @@ jobs: fi - name: Deploy badge to image-data branch - if: matrix.php-versions == '8.3' && github.ref == 'refs/heads/main' && steps.check_badge.outputs.badge_exists == 'true' - uses: peaceiris/actions-gh-pages@v3 + if: matrix.php-versions == '8.3' && steps.check_badge.outputs.badge_exists == 'true' + uses: peaceiris/actions-gh-pages@v4 with: publish_dir: ./output publish_branch: image-data github_token: ${{ secrets.GITHUB_TOKEN }} user_name: 'github-actions[bot]' - user_email: 'github-actions[bot]@users.noreply.github.com' - - - name: Commit coverage badge to current branch (PR) - if: matrix.php-versions == '8.3' - run: | - echo "Event name: ${{ github.event_name }}" - # Check if badge file exists - if [ ! -f "coverage.svg" ]; then - echo "Coverage badge file not found, skipping commit" - exit 0 - fi - - git config --local user.email "github-actions[bot]@users.noreply.github.com" - git config --local user.name "github-actions[bot]" - git add coverage.svg - git commit -m "ci: Update coverage badge" || exit 0 - git push + user_email: 'github-actions[bot]@users.noreply.github.com' \ No newline at end of file From 83ae9dac59087d8710893d038227f88510a9798d Mon Sep 17 00:00:00 2001 From: Volodymyr Stolyarchuk Date: Tue, 15 Jul 2025 17:17:02 +0300 Subject: [PATCH 12/16] feat: separate cassettes per dataProvider cases --- .github/workflows/default.yaml | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/.github/workflows/default.yaml b/.github/workflows/default.yaml index b156781..fa926e1 100644 --- a/.github/workflows/default.yaml +++ b/.github/workflows/default.yaml @@ -19,10 +19,6 @@ jobs: steps: - uses: actions/checkout@v4 - with: - token: ${{ secrets.GITHUB_TOKEN }} - fetch-depth: '0' # Fetch all history for accurate coverage reporting - ref: ${{ github.event_name == 'pull_request' && github.head_ref || github.ref }} - name: Setup PHP with PECL extension uses: shivammathur/setup-php@v2 @@ -49,21 +45,23 @@ jobs: run: vendor/bin/phpstan analyse - name: Execute PHPUnit tests + id: phpunit run: | if [ "${{ matrix.php-versions }}" = "8.3" ]; then vendor/bin/phpunit --coverage-clover coverage.xml + echo "generate-coverage-badge=true" >> $GITHUB_OUTPUT else + echo "generate-coverage-badge=false" >> $GITHUB_OUTPUT vendor/bin/phpunit fi - - name: Generate coverage badge - if: matrix.php-versions != '8.3' + - name: Check for Coverage badge generation + if: steps.phpunit.outputs.generate-coverage-badge != 'true' run: | echo "Coverage badge generation skipped for PHP version ${{ matrix.php-versions }}" exit 0 - name: Generate coverage badge - if: matrix.php-versions == '8.3' uses: timkrase/phpunit-coverage-badge@v1.2.1 with: coverage_badge_path: ./output/coverage.svg @@ -71,13 +69,12 @@ jobs: report: coverage.xml - name: Update README badge URL for current repository - if: matrix.php-versions == '8.3' && github.repository != 'angelov/phpunit-php-vcr' + if: github.repository != 'angelov/phpunit-php-vcr' run: | # Update the README with the correct badge URL sed -i 's|angelov/phpunit-php-vcr|${{ github.repository }}|g' README.md - name: Check badge file exists - if: matrix.php-versions == '8.3' id: check_badge run: | if [ -f "./output/coverage.svg" ]; then @@ -89,7 +86,7 @@ jobs: fi - name: Deploy badge to image-data branch - if: matrix.php-versions == '8.3' && steps.check_badge.outputs.badge_exists == 'true' + if: steps.check_badge.outputs.badge_exists == 'true' uses: peaceiris/actions-gh-pages@v4 with: publish_dir: ./output From c97c86b41fec41f1950f5d2cc687d657b5b91042 Mon Sep 17 00:00:00 2001 From: Volodymyr Stolyarchuk Date: Tue, 15 Jul 2025 17:22:40 +0300 Subject: [PATCH 13/16] feat: separate cassettes per dataProvider cases --- .github/workflows/default.yaml | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/.github/workflows/default.yaml b/.github/workflows/default.yaml index fa926e1..4994567 100644 --- a/.github/workflows/default.yaml +++ b/.github/workflows/default.yaml @@ -55,26 +55,16 @@ jobs: vendor/bin/phpunit fi - - name: Check for Coverage badge generation - if: steps.phpunit.outputs.generate-coverage-badge != 'true' - run: | - echo "Coverage badge generation skipped for PHP version ${{ matrix.php-versions }}" - exit 0 - - name: Generate coverage badge uses: timkrase/phpunit-coverage-badge@v1.2.1 + if: steps.phpunit.outputs.generate-coverage-badge == 'true' with: coverage_badge_path: ./output/coverage.svg push_badge: false report: coverage.xml - - name: Update README badge URL for current repository - if: github.repository != 'angelov/phpunit-php-vcr' - run: | - # Update the README with the correct badge URL - sed -i 's|angelov/phpunit-php-vcr|${{ github.repository }}|g' README.md - - name: Check badge file exists + if: steps.phpunit.outputs.generate-coverage-badge == 'true' id: check_badge run: | if [ -f "./output/coverage.svg" ]; then @@ -86,7 +76,7 @@ jobs: fi - name: Deploy badge to image-data branch - if: steps.check_badge.outputs.badge_exists == 'true' + if: steps.phpunit.outputs.generate-coverage-badge == 'true' && steps.check_badge.outputs.badge_exists == 'true' uses: peaceiris/actions-gh-pages@v4 with: publish_dir: ./output From 58fc167d32f446c5ccd1f6865d107eb4bb502211 Mon Sep 17 00:00:00 2001 From: Volodymyr Stolyarchuk Date: Tue, 15 Jul 2025 17:25:56 +0300 Subject: [PATCH 14/16] feat: separate cassettes per dataProvider cases --- .github/workflows/default.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/default.yaml b/.github/workflows/default.yaml index 4994567..905fe4d 100644 --- a/.github/workflows/default.yaml +++ b/.github/workflows/default.yaml @@ -47,7 +47,7 @@ jobs: - name: Execute PHPUnit tests id: phpunit run: | - if [ "${{ matrix.php-versions }}" = "8.3" ]; then + if [ "${{ matrix.php-versions }}" = "8.3" && ${{github.ref}} == "refs/heads/main" && ${{github.event_name}} == "push" ]; then vendor/bin/phpunit --coverage-clover coverage.xml echo "generate-coverage-badge=true" >> $GITHUB_OUTPUT else From 2a998b964b5aa80a651cd6bfb4caf042dc5f5612 Mon Sep 17 00:00:00 2001 From: Volodymyr Stolyarchuk Date: Tue, 15 Jul 2025 17:27:41 +0300 Subject: [PATCH 15/16] feat: separate cassettes per dataProvider cases --- README.md | 172 ++---------------------------------------------------- 1 file changed, 5 insertions(+), 167 deletions(-) diff --git a/README.md b/README.md index e58f4e0..1daa771 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,8 @@ Then, add the extension to your PHPUnit configuration file. - - + + @@ -36,8 +36,7 @@ Then, add the extension to your PHPUnit configuration file. ## Usage The library provides an `UseCassette` attribute that can be declared on test classes or specific test methods. The -attribute accepts a cassette name and optional parameters for advanced functionality like separate cassettes per -data provider case. +attribute expects one string argument - the name of the cassette. When running the tests, the library will automatically turn the recorder on and off, and insert the cassettes when needed. @@ -57,7 +56,7 @@ responses in the given cassette. { #[Test] public function example(): void { ... } - + #[Test] public function another(): void { ... } } @@ -105,165 +104,4 @@ used for that method. In this example, the responses from the requests made in t #[UseCassette("example_2.yml")] public function recorded(): void { ... } } - ``` - -## DataProvider Support - -The library supports PHPUnit's `DataProvider` functionality with additional options for managing cassettes when using data providers. - -### Basic DataProvider Usage - -When using a data provider with the basic `UseCassette` attribute, all test cases from the data provider will share the same cassette file: - -```php -use Angelov\PHPUnitPHPVcr\UseCassette; -use PHPUnit\Framework\Attributes\DataProvider; -use PHPUnit\Framework\Attributes\Test; -use PHPUnit\Framework\TestCase; - -class ExampleTest extends TestCase -{ - #[Test] - #[UseCassette("shared_cassette.yml")] - #[DataProvider("urls")] - public function testWithDataProvider(string $url): void - { - $content = file_get_contents($url); - // All test cases will use the same cassette file - } - - public static function urls(): iterable - { - yield ["https://example.com"]; - yield ["https://example.org"]; - } -} -``` - -### Separate Cassettes Per DataProvider Case - -For more granular control, you can create separate cassette files for each data provider case using the `separateCassettePerCase` parameter: - -```php -use Angelov\PHPUnitPHPVcr\UseCassette; -use PHPUnit\Framework\Attributes\DataProvider; -use PHPUnit\Framework\Attributes\Test; -use PHPUnit\Framework\TestCase; - -class ExampleTest extends TestCase -{ - #[Test] - #[UseCassette(name: "separate_cassettes.yml", separateCassettePerCase: true)] - #[DataProvider("urls")] - public function testWithSeparateCassettes(string $url): void - { - $content = file_get_contents($url); - // Each test case will have its own cassette file: - // - separate_cassettes-0.yml - // - separate_cassettes-1.yml - } - - public static function urls(): iterable - { - yield ["https://example.com"]; - yield ["https://example.org"]; - } -} -``` - -### Named DataProvider Cases - -When using named data provider cases, the cassette files will use the case names: - -```php -use Angelov\PHPUnitPHPVcr\UseCassette; -use PHPUnit\Framework\Attributes\DataProvider; -use PHPUnit\Framework\Attributes\Test; -use PHPUnit\Framework\TestCase; - -class ExampleTest extends TestCase -{ - #[Test] - #[UseCassette(name: "named_cassettes.yml", separateCassettePerCase: true)] - #[DataProvider("namedUrls")] - public function testWithNamedCassettes(string $url): void - { - $content = file_get_contents($url); - // Each test case will have its own cassette file: - // - named_cassettes-example-com.yml - // - named_cassettes-example-org.yml - } - - public static function namedUrls(): iterable - { - yield 'example.com' => ["https://example.com"]; - yield 'example.org' => ["https://example.org"]; - } -} -``` - -### Grouping Cassettes in Directories - -To organize separate cassette files in directories, use the `groupCaseFilesInDirectory` parameter: - -```php -use Angelov\PHPUnitPHPVcr\UseCassette; -use PHPUnit\Framework\Attributes\DataProvider; -use PHPUnit\Framework\Attributes\Test; -use PHPUnit\Framework\TestCase; - -class ExampleTest extends TestCase -{ - #[Test] - #[UseCassette( - name: "organized_cassettes.yml", - separateCassettePerCase: true, - groupCaseFilesInDirectory: true - )] - #[DataProvider("urls")] - public function testWithOrganizedCassettes(string $url): void - { - $content = file_get_contents($url); - // Cassette files will be organized in a directory: - // - organized_cassettes/0.yml - // - organized_cassettes/1.yml - } - - public static function urls(): iterable - { - yield ["https://example.com"]; - yield ["https://example.org"]; - } -} -``` - -### Class-Level DataProvider Support - -The dataProvider functionality also works when the `UseCassette` attribute is declared at the class level: - -```php -use Angelov\PHPUnitPHPVcr\UseCassette; -use PHPUnit\Framework\Attributes\DataProvider; -use PHPUnit\Framework\Attributes\Test; -use PHPUnit\Framework\TestCase; - -#[UseCassette(name: "class_level.yml", separateCassettePerCase: true)] -class ExampleTest extends TestCase -{ - #[Test] - #[DataProvider("urls")] - public function testMethod(string $url): void - { - $content = file_get_contents($url); - // Each test case will have separate cassettes: - // - class_level-0.yml - // - class_level-1.yml - } - - public static function urls(): iterable - { - yield ["https://example.com"]; - yield ["https://example.org"]; - } -} -``` + ``` \ No newline at end of file From e95fe99971a06db55f8d51a0bad673b85d7f0133 Mon Sep 17 00:00:00 2001 From: Volodymyr Stolyarchuk Date: Tue, 15 Jul 2025 17:29:07 +0300 Subject: [PATCH 16/16] feat: separate cassettes per dataProvider cases --- coverage.svg | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 coverage.svg diff --git a/coverage.svg b/coverage.svg deleted file mode 100644 index b8caba4..0000000 --- a/coverage.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - coverage - - 31 % - - \ No newline at end of file