app settings
This commit is contained in:
+40
@@ -0,0 +1,40 @@
|
||||
build: false
|
||||
version: dev-{build}
|
||||
shallow_clone: false
|
||||
clone_folder: C:\projects\php-coveralls
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- php_ver: 7.1.2
|
||||
|
||||
cache:
|
||||
- '%APPDATA%\Composer'
|
||||
- '%LOCALAPPDATA%\Composer'
|
||||
- C:\tools\php -> .appveyor.yml
|
||||
- C:\tools\composer.phar -> .appveyor.yml
|
||||
|
||||
init:
|
||||
- SET PATH=C:\tools\php;%PATH%
|
||||
|
||||
install:
|
||||
- ps: Set-Service wuauserv -StartupType Manual
|
||||
- IF NOT EXIST C:\tools\php (choco install --yes --allow-empty-checksums php --version %php_ver% --params '/InstallDir:C:\tools\php')
|
||||
- appveyor DownloadFile http://curl.haxx.se/ca/cacert.pem -FileName C:\cacert.pem
|
||||
- cd C:\tools\php
|
||||
- copy php.ini-production php.ini
|
||||
- echo date.timezone=UTC >> php.ini
|
||||
- echo memory_limit=512M >> php.ini
|
||||
- echo extension_dir=ext >> php.ini
|
||||
- echo extension=php_curl.dll >> php.ini
|
||||
- echo extension=php_openssl.dll >> php.ini
|
||||
- echo curl.cainfo=C:\cacert.pem >> php.ini
|
||||
- IF NOT EXIST C:\tools\composer.phar (cd C:\tools && appveyor DownloadFile https://getcomposer.org/download/1.4.1/composer.phar)
|
||||
- php C:\tools\composer.phar global show -ND 2>1 | findstr "hirak/prestissimo" || php C:\tools\composer.phar global require hirak/prestissimo
|
||||
|
||||
before_test:
|
||||
- cd C:\projects\php-coveralls
|
||||
- php C:\tools\composer.phar update --no-interaction --no-progress --prefer-stable --no-ansi
|
||||
|
||||
test_script:
|
||||
- cd C:\projects\php-coveralls
|
||||
- phpdbg -qrr vendor\phpunit\phpunit\phpunit --verbose
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
name: "${{matrix.os}} | PHP${{matrix.php}} Symfony@${{matrix.symfony || '*'}} ${{ matrix.composer-flags}}"
|
||||
runs-on: ${{matrix.os}}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- php: '5.5'
|
||||
os: ubuntu-latest
|
||||
composer-flags: '--prefer-lowest'
|
||||
coverage: 'xdebug'
|
||||
- php: '5.5'
|
||||
os: ubuntu-latest
|
||||
symfony: '^3.0'
|
||||
- php: '5.5'
|
||||
os: windows-latest
|
||||
coverage: 'xdebug'
|
||||
- php: '5.6'
|
||||
os: ubuntu-latest
|
||||
- php: '7.0'
|
||||
os: ubuntu-latest
|
||||
- php: '7.1'
|
||||
os: ubuntu-latest
|
||||
symfony: '^4.0'
|
||||
- php: '7.2'
|
||||
os: ubuntu-latest
|
||||
symfony: '^5.0'
|
||||
- php: '7.3'
|
||||
os: ubuntu-latest
|
||||
- php: '7.4'
|
||||
os: ubuntu-latest
|
||||
- php: '8.0'
|
||||
os: ubuntu-latest
|
||||
symfony: '^6.0'
|
||||
- php: '8.1'
|
||||
os: ubuntu-latest
|
||||
symfony: '^6.0'
|
||||
- php: '8.2'
|
||||
os: ubuntu-latest
|
||||
symfony: '^6.0'
|
||||
coverage: 'pcov'
|
||||
- php: '8.2'
|
||||
os: ubuntu-latest
|
||||
symfony: '^6.0'
|
||||
coverage: 'xdebug'
|
||||
- php: '8.2'
|
||||
os: windows-latest
|
||||
symfony: '^6.0'
|
||||
coverage: 'pcov'
|
||||
- php: '8.3'
|
||||
os: ubuntu-latest
|
||||
symfony: '^6.0'
|
||||
|
||||
continue-on-error: ${{ matrix.php == '8.3' }}
|
||||
|
||||
steps:
|
||||
- name: Checkout source
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Get symfony flex version
|
||||
uses: actions/github-script@v3.1
|
||||
id: flex-version
|
||||
with:
|
||||
script: 'return "${{ matrix.php }}" == "7.0" ? "~1.6.0" : "^1.11"'
|
||||
result-encoding: string
|
||||
|
||||
- name: PHP setup
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
ini-values: zend.assertions=1, error_reporting=-1, display_errors=On, log_errors_max_len=0
|
||||
coverage: ${{ matrix.coverage || 'none' }}
|
||||
|
||||
- name: Downgrade composer for old Symfony Flex
|
||||
if: steps.flex-version.outputs.result == '~1.6.0'
|
||||
run: composer self-update --1
|
||||
|
||||
- name: "Disallow Symfony Flex to run as a Composer plugin (global)"
|
||||
if: startsWith(matrix.php, '5') == false && steps.flex-version.outputs.result != '~1.6.0'
|
||||
run: composer -g config allow-plugins.symfony/flex false
|
||||
|
||||
- name: "Install Symfony Flex"
|
||||
if: startsWith(matrix.php, '5') == false
|
||||
run: composer global require -o --no-interaction symfony/flex:${{ steps.flex-version.outputs.result }} --no-plugins
|
||||
|
||||
- name: Require Symfony version
|
||||
if: matrix.symfony
|
||||
run: composer config extra.symfony.require ${{ matrix.symfony }}
|
||||
|
||||
- name: Update composer dependencies
|
||||
if: matrix.php != '8.3'
|
||||
run: composer update -o --no-interaction --no-progress ${{ matrix.composer-flags }}
|
||||
|
||||
- name: "Update composer dependencies (PHP 8.2, ignore platform)"
|
||||
if: matrix.php == '8.3'
|
||||
run: composer update -o --no-interaction --no-progress ${{ matrix.composer-flags }} --ignore-platform-req=php+
|
||||
|
||||
- name: Run test suite
|
||||
run: php vendor/bin/phpunit -v
|
||||
|
||||
- name: Upload coverage results to Coveralls
|
||||
if: matrix.coverage
|
||||
env:
|
||||
COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
COVERALLS_PARALLEL: true
|
||||
COVERALLS_FLAG_NAME: "${{matrix.os}} | PHP${{matrix.php}} Symfony@${{matrix.symfony || '*'}}"
|
||||
run: php bin/php-coveralls -v --exclude-no-stmt
|
||||
|
||||
coveralls-finish:
|
||||
needs: tests
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Notify Coveralls when build is finished
|
||||
run: |
|
||||
curl -k https://coveralls.io/webhook?repo_token=${{ secrets.GITHUB_TOKEN }} \
|
||||
-d "repo_name=$GITHUB_REPOSITORY&payload[build_num]=$GITHUB_RUN_ID&payload[status]=done"
|
||||
|
||||
build-phar:
|
||||
needs: tests
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 8.1
|
||||
extensions: phar, openssl, sodium
|
||||
coverage: none
|
||||
ini-values: phar.readonly=Off, error_reporting=-1, display_errors=On, zend.assertions=1
|
||||
# Autoload files generated with Composer 2.3+ are not compatible with PHP < 7.0.
|
||||
tools: composer:2.2
|
||||
|
||||
- name: Set Composer platform
|
||||
run: composer config platform.php 5.5.0
|
||||
|
||||
- name: Install Composer dependencies
|
||||
uses: ramsey/composer-install@v2
|
||||
with:
|
||||
composer-options: "--no-dev --optimize-autoloader"
|
||||
|
||||
# Note: do NOT turn on the requirement checker in the box config as it is no longer
|
||||
# compatible with PHP < 7.2.
|
||||
- name: Install Box
|
||||
run: wget https://github.com/humbug/box/releases/latest/download/box.phar -O box.phar && chmod 0755 box.phar
|
||||
|
||||
- name: Validate configuration
|
||||
run: php box.phar validate -i box.json
|
||||
|
||||
- name: Building binary...
|
||||
run: php box.phar compile -v --config=box.json
|
||||
|
||||
- name: Show info about the build phar
|
||||
run: php box.phar info -l ./build/artifacts/php-coveralls.phar
|
||||
|
||||
- name: Upload the Phar artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: php-coveralls-phar
|
||||
path: ./build/artifacts/php-coveralls.phar
|
||||
retention-days: 30
|
||||
|
||||
test-phar:
|
||||
needs: build-phar
|
||||
name: "Test Phar PHP ${{ matrix.php }}"
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- php: '5.5'
|
||||
- php: '7.2'
|
||||
- php: '8.0'
|
||||
- php: '8.3'
|
||||
|
||||
continue-on-error: ${{ matrix.php == '8.3' }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Download the Phar artifact
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: php-coveralls-phar
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
ini-values: error_reporting=-1, display_errors=On, zend.assertions=1
|
||||
coverage: none
|
||||
|
||||
- name: Test the Phar is functional
|
||||
run: php php-coveralls.phar --version
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
name: Static Code Analysis
|
||||
|
||||
on:
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
jobs:
|
||||
static-code-analysis:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 8.1
|
||||
coverage: none
|
||||
|
||||
- name: Validate composer.json
|
||||
run: composer validate
|
||||
|
||||
- name: Run all checks
|
||||
run: |
|
||||
composer install-dev-tools
|
||||
composer sca
|
||||
@@ -0,0 +1,30 @@
|
||||
# phpstorm
|
||||
.idea
|
||||
|
||||
# eclipse
|
||||
.buildpath
|
||||
.project
|
||||
.settings/
|
||||
|
||||
# PHP prj
|
||||
build/
|
||||
cache.properties
|
||||
|
||||
# composer
|
||||
vendor/
|
||||
composer.lock
|
||||
|
||||
# travis
|
||||
travis/
|
||||
|
||||
# bin
|
||||
composer.phar
|
||||
php-cs-fixer.phar
|
||||
|
||||
.coveralls.yml
|
||||
.php-cs-fixer.php
|
||||
.php-cs-fixer.cache
|
||||
.phpunit.result.cache
|
||||
phpunit.xml
|
||||
|
||||
box.phar
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
$finder = PhpCsFixer\Finder::create()
|
||||
->ignoreDotFiles(false)
|
||||
->ignoreVCSIgnored(true)
|
||||
->exclude('tests/Fixture')
|
||||
->in(__DIR__)
|
||||
;
|
||||
|
||||
$config = new PhpCsFixer\Config();
|
||||
$config
|
||||
->setRiskyAllowed(true)
|
||||
->setRules([
|
||||
'@PhpCsFixer' => true,
|
||||
'@PhpCsFixer:risky' => true,
|
||||
'yoda_style' => [
|
||||
'equal' => false,
|
||||
'identical' => false,
|
||||
'less_and_greater' => false,
|
||||
],
|
||||
'concat_space' => ['spacing' => 'one'],
|
||||
'explicit_indirect_variable' => false,
|
||||
'explicit_string_variable' => false,
|
||||
'method_chaining_indentation' => false,
|
||||
'php_unit_test_annotation' => false,
|
||||
'single_line_comment_style' => false,
|
||||
'ternary_to_elvis_operator' => false,
|
||||
'visibility_required' => ['elements' => ['method', 'property']],
|
||||
])
|
||||
->setFinder($finder)
|
||||
;
|
||||
|
||||
return $config;
|
||||
+308
@@ -0,0 +1,308 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
## 2.6.0
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* Add windows-os to github action (#335)
|
||||
* DX: Update PHP CS Fixer to ^3.13.2 (#355)
|
||||
* DX: update dev-tools, especially PHP CS Fixer (#366)
|
||||
* Fix PHP 8.1 compatibility (#361)
|
||||
* GH Actions/CI: run the test suite against PHP 8.1, 8.2 and 8.3 (#363)
|
||||
* README: fix broken badge and mention GH Actions (#362)
|
||||
* Replace Travis CI with the GitHub action badge (#364)
|
||||
* Upgrade PHAR generation to Box 4.x (#351)
|
||||
|
||||
## 2.5.3
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
- GH Actions: various updates (#346)
|
||||
- MetricsTest: fix tests failing on imprecise floats (#344)
|
||||
- PHP 8.1 | Fix "passing null to non-nullable" deprecations (tests only) (#345)
|
||||
- PHP 8.2 | Fix deprecated embedded variables in text strings (#343)
|
||||
- Fix minor typo in GitHub Action step's name (#349)
|
||||
|
||||
## 2.5.2
|
||||
|
||||
### Bug fix
|
||||
|
||||
- [#330](https://github.com/php-coveralls/php-coveralls/pull/330) Changed `CIRCLE_BUILD_NUM` to `CIRCLE_WORKFLOW_ID`
|
||||
- [#328](https://github.com/php-coveralls/php-coveralls/pull/328)
|
||||
Added compatibility with Symfony 6
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
- [#325](https://github.com/php-coveralls/php-coveralls/pull/325) CI: Migrate to GitHub Actions
|
||||
|
||||
## 2.5.1
|
||||
|
||||
### Bug fix
|
||||
|
||||
- [#324](https://github.com/php-coveralls/php-coveralls/pull/324) Fix PHP 5.5 compatibility
|
||||
|
||||
## 2.5.0
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
- [#322](https://github.com/php-coveralls/php-coveralls/pull/322) Allow for Symfony:^6
|
||||
- [#321](https://github.com/php-coveralls/php-coveralls/pull/321) Disallow `psr/log` v3
|
||||
- [#319](https://github.com/php-coveralls/php-coveralls/pull/319) Added fallback to show where is problem with non-UTF8 char
|
||||
- [#317](https://github.com/php-coveralls/php-coveralls/pull/317) Allow `psr/log` v2 and v3
|
||||
- [#316](https://github.com/php-coveralls/php-coveralls/pull/316) Update README with Travis CI configuration detail
|
||||
- [#311](https://github.com/php-coveralls/php-coveralls/pull/311) Update version in master to latest release
|
||||
|
||||
## 2.4.3
|
||||
|
||||
### Bug fix
|
||||
|
||||
- [#308](https://github.com/php-coveralls/php-coveralls/pull/308) Add file missing for PHP 8
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
- [#303](https://github.com/php-coveralls/php-coveralls/pull/303) Update README.md
|
||||
|
||||
## 2.4.2
|
||||
|
||||
### Bug fix
|
||||
|
||||
- [#302](https://github.com/php-coveralls/php-coveralls/pull/302) Add COVERALLS_REPO_TOKEN to error message when run on Github Action
|
||||
- [#299](https://github.com/php-coveralls/php-coveralls/pull/299) Correct spelling error in Github
|
||||
|
||||
## 2.4.1
|
||||
|
||||
### Bug fix
|
||||
|
||||
- [#298](https://github.com/php-coveralls/php-coveralls/pull/298) Fix support of branch name with hyphen and "(no branch)"
|
||||
|
||||
## 2.4.0
|
||||
|
||||
### Enhancement
|
||||
|
||||
- [#296](https://github.com/php-coveralls/php-coveralls/pull/296) Add Github Actions and COVERALLS_FLAG_NAME support
|
||||
- [#295](https://github.com/php-coveralls/php-coveralls/pull/295) Add support for PHP 8 + PHPUnit 9
|
||||
- [#289](https://github.com/php-coveralls/php-coveralls/pull/289) Add insecure option
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
- [#297](https://github.com/php-coveralls/php-coveralls/pull/297) DX: .gitignore cache PHPUnit
|
||||
|
||||
## 2.3.0
|
||||
|
||||
### Enhancement
|
||||
|
||||
- [#290](https://github.com/php-coveralls/php-coveralls/pull/290) Allow to specify endpoint in arguments
|
||||
- [#288](https://github.com/php-coveralls/php-coveralls/pull/288) Add Guzzle 7 support
|
||||
- [#279](https://github.com/php-coveralls/php-coveralls/pull/279) Added COVERALLS_PARALLEL support and Configured CI_BUILD_NUMBER for Travis CI
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
- [#294](https://github.com/php-coveralls/php-coveralls/pull/294) DX: Allow PHPUnit 7
|
||||
- [#292](https://github.com/php-coveralls/php-coveralls/pull/292) CI: reduce amount of jobs
|
||||
- [#291](https://github.com/php-coveralls/php-coveralls/pull/291) DX: Configurator - reduce cyclomatic complexity
|
||||
- [#286](https://github.com/php-coveralls/php-coveralls/pull/286) Fix incorrect version in README
|
||||
- [#283](https://github.com/php-coveralls/php-coveralls/pull/283) Update .travis.yml to include PHP 7.4
|
||||
|
||||
## 2.2.0
|
||||
|
||||
### Enhancement
|
||||
|
||||
- [#269](https://github.com/php-coveralls/php-coveralls/pull/269) Add possibility to change entry point
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
- [#277](https://github.com/php-coveralls/php-coveralls/pull/277) DX: Update PHP CS Fixer
|
||||
- [#276](https://github.com/php-coveralls/php-coveralls/pull/276) DX: Fix PHPMd config, allowing build to pass
|
||||
- [#274](https://github.com/php-coveralls/php-coveralls/pull/274) Allow Symfony 5
|
||||
- [#268](https://github.com/php-coveralls/php-coveralls/pull/268) Update minimum version of symfony/yaml to 2.0.5
|
||||
- [#267](https://github.com/php-coveralls/php-coveralls/pull/267) Add --dev to install step
|
||||
|
||||
## 2.1.0
|
||||
|
||||
### Enhancement
|
||||
|
||||
- [#263](https://github.com/php-coveralls/php-coveralls/pull/263) JsonFile - detect json_encode failure
|
||||
- [#262](https://github.com/php-coveralls/php-coveralls/pull/262) DX: Improve error messages
|
||||
- [#261](https://github.com/php-coveralls/php-coveralls/pull/261) Return non-0 status on command errors
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
- [#265](https://github.com/php-coveralls/php-coveralls/pull/265) Remove obsolete apigen and versioneye
|
||||
- [#264](https://github.com/php-coveralls/php-coveralls/pull/264) Drop HHVM support
|
||||
- [#256](https://github.com/php-coveralls/php-coveralls/pull/256) Update references to renamed binary
|
||||
|
||||
## 2.0.0
|
||||
|
||||
### Bug fix
|
||||
|
||||
- [#232](https://github.com/php-coveralls/php-coveralls/pull/232) phar building - set up platform.php for composer before building phar file
|
||||
|
||||
### Enhancement
|
||||
|
||||
- [#223](https://github.com/php-coveralls/php-coveralls/pull/223) Make project works on Windows
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
- Binary and phar renamed to match tool name: php-coveralls and php-coveralls.phar
|
||||
- [#228](https://github.com/php-coveralls/php-coveralls/pull/228) Rename vendor
|
||||
- [#227](https://github.com/php-coveralls/php-coveralls/pull/227) Drop V1 from namespaces and class names
|
||||
- Upgrade to Guzzle 6
|
||||
|
||||
## 1.1.0
|
||||
|
||||
### Enhancement
|
||||
|
||||
- [#192](https://github.com/php-coveralls/php-coveralls/pull/192) let output json path be configurable
|
||||
|
||||
## 1.0.2
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
- Update github repo link
|
||||
- [#250](https://github.com/php-coveralls/php-coveralls/pull/250) GitCommand - drop useless tests
|
||||
- [#248](https://github.com/php-coveralls/php-coveralls/pull/248) Allow Symfony 4
|
||||
- [#249](https://github.com/php-coveralls/php-coveralls/pull/249) Allow PHPUnit 6
|
||||
- [#224](https://github.com/php-coveralls/php-coveralls/pull/224) Travis - update used ubuntu dist
|
||||
- [#212](https://github.com/php-coveralls/php-coveralls/pull/212) update PHP CS Fixer
|
||||
- Use stable and semantic version constrains
|
||||
- Start v1.0.2 development
|
||||
- Phpdoc
|
||||
|
||||
## 1.0.1
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
- [#183](https://github.com/php-coveralls/php-coveralls/pull/183) Lower required version of symfony/*
|
||||
|
||||
## 1.0.0
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
- [#136](https://github.com/php-coveralls/php-coveralls/pull/136) Removed src_dir from CoverallsConfiguration
|
||||
- [#154](https://github.com/php-coveralls/php-coveralls/issues/154) Show a deprecation notice when src_dir is set in the config
|
||||
|
||||
## 0.7.0
|
||||
|
||||
### Bug fix
|
||||
|
||||
- [#30](https://github.com/php-coveralls/php-coveralls/issues/30) Fix bug: Guzzle\Common\Exception\RuntimeException occur without response body
|
||||
- [#41](https://github.com/php-coveralls/php-coveralls/issues/41) CloverXmlCoverageCollector could not handle root directory
|
||||
- [#114](https://github.com/php-coveralls/php-coveralls/pull/114) Fix PHP 5.3.3, Fix HHVM on Travis, boost Travis configuration, enhance PHP CS Fixer usage
|
||||
|
||||
### Enhancement
|
||||
|
||||
- [#15](https://github.com/php-coveralls/php-coveralls/issues/15) Support environment prop in json_file
|
||||
- [#24](https://github.com/php-coveralls/php-coveralls/issues/24) Show helpful message if the requirements are not satisfied
|
||||
- [#53](https://github.com/php-coveralls/php-coveralls/issues/53) Setting configuration options through command line flags
|
||||
- Added --root_dir and --coverage_clover flags
|
||||
- [#64](https://github.com/php-coveralls/php-coveralls/issues/64) file names need to be relative to the git repo root
|
||||
- [#114](https://github.com/php-coveralls/php-coveralls/pull/114) Fix PHP 5.3.3, Fix HHVM on Travis, boost Travis configuration, enhance PHP CS Fixer usage
|
||||
- [#124](https://github.com/php-coveralls/php-coveralls/pull/124) Create a .phar file
|
||||
- [#149](https://github.com/php-coveralls/php-coveralls/pull/149) Build phar file on travis
|
||||
- [#127](https://github.com/php-coveralls/php-coveralls/issues/126) Remove src_dir entirely
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
- [#17](https://github.com/php-coveralls/php-coveralls/issues/17) Refactor test cases
|
||||
- [#32](https://github.com/php-coveralls/php-coveralls/issues/32) Refactor CoverallsV1JobsCommand
|
||||
- [#35](https://github.com/php-coveralls/php-coveralls/issues/35) Remove ext-curl dependency
|
||||
- [#38](https://github.com/php-coveralls/php-coveralls/issues/38) Change namespace
|
||||
- [#114](https://github.com/php-coveralls/php-coveralls/pull/114) PHP 7.0.0 is now officially supported
|
||||
|
||||
## 0.6.1 (2013-05-04)
|
||||
|
||||
### Bug fix
|
||||
|
||||
- [#27](https://github.com/php-coveralls/php-coveralls/issues/27) Fix bug: Response message is not shown if exception occurred
|
||||
|
||||
### Enhancement
|
||||
|
||||
- [#23](https://github.com/php-coveralls/php-coveralls/issues/23) Add CLI option: `--exclude-no-stmt`
|
||||
- [#23](https://github.com/php-coveralls/php-coveralls/issues/23) Add .coveralls.yml configuration: `exclude_no_stmt`
|
||||
|
||||
|
||||
## 0.6.0 (2013-05-03)
|
||||
|
||||
### Bug fix
|
||||
|
||||
- Fix bug: Show exception log at sending a request instead of exception backtrace
|
||||
- [#12](https://github.com/php-coveralls/php-coveralls/issues/12) Fix bug: end of file should not be included in code coverage
|
||||
- [#21](https://github.com/php-coveralls/php-coveralls/issues/21) Fix bug: add connection error handling
|
||||
|
||||
### Enhancement
|
||||
|
||||
- [#11](https://github.com/php-coveralls/php-coveralls/issues/11) Support configuration for multiple clover.xml
|
||||
- [#14](https://github.com/php-coveralls/php-coveralls/issues/14) Log enhancement
|
||||
- show file size of `json_file`
|
||||
- show number of included source files
|
||||
- show elapsed time and memory usage
|
||||
- show coverage
|
||||
- show response message
|
||||
- [#18](https://github.com/php-coveralls/php-coveralls/issues/18) Relax dependent libs version
|
||||
|
||||
## 0.5.0 (2013-04-29)
|
||||
|
||||
### Bug fix
|
||||
|
||||
- Fix bug: only existing file lines should be included in coverage data
|
||||
|
||||
### Enhancement
|
||||
|
||||
- `--verbose (-v)` CLI option enables logging
|
||||
- Support standardized env vars ([Codeship](https://www.codeship.io) supported these env vars)
|
||||
- CI_NAME
|
||||
- CI_BUILD_NUMBER
|
||||
- CI_BUILD_URL
|
||||
- CI_BRANCH
|
||||
- CI_PULL_REQUEST
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
- Refactor console logging (PSR-3 compliant)
|
||||
- Change composer's minimal stability from dev to stable
|
||||
|
||||
## 0.4.0 (2013-04-21)
|
||||
|
||||
### Bug fix
|
||||
|
||||
- Fix bug: `repo_token` is required on CircleCI, Jenkins
|
||||
|
||||
### Enhancement
|
||||
|
||||
- Replace REST client implementation by [guzzle/guzzle](https://github.com/guzzle/guzzle)
|
||||
|
||||
## 0.3.2 (2013-04-20)
|
||||
|
||||
### Bug fix
|
||||
|
||||
- Fix bug: API reqest from local environment should be with repo_token
|
||||
- Fix bug: service_name in .coveralls.yml will not reflect to json_file
|
||||
|
||||
## 0.3.1 (2013-04-19)
|
||||
|
||||
### Bug fix
|
||||
|
||||
- [#1](Installing with composer issue) Fix bug: wrong bin path of composer.json ([@zomble](https://github.com/zomble)).
|
||||
|
||||
## 0.3.0 (2013-04-19)
|
||||
|
||||
### Enhancement
|
||||
|
||||
- Better CLI implementation by using [symfony/Console](https://github.com/symfony/Console) component
|
||||
- Support `--dry-run`, `--config (-c)` CLI option
|
||||
|
||||
## 0.2.0 (2013-04-18)
|
||||
|
||||
### Enhancement
|
||||
|
||||
- Support .coveralls.yml
|
||||
|
||||
## 0.1.0 (2013-04-15)
|
||||
|
||||
First release.
|
||||
|
||||
- Support Travis CI (tested)
|
||||
- Implement CircleCI, Jenkins, local environment (but not tested on these CI environments)
|
||||
- Collect coverage information from clover.xml
|
||||
- Collect git repository information
|
||||
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Kitamura Satoshi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -0,0 +1,379 @@
|
||||
php-coveralls
|
||||
=============
|
||||
|
||||
[](https://github.com/php-coveralls/php-coveralls/actions/workflows/static-code-analysis.yml)
|
||||
[](https://github.com/php-coveralls/php-coveralls/actions/workflows/ci.yml)
|
||||
[](https://coveralls.io/r/php-coveralls/php-coveralls)
|
||||
|
||||
[](https://packagist.org/packages/php-coveralls/php-coveralls)
|
||||
[](https://packagist.org/packages/php-coveralls/php-coveralls)
|
||||
|
||||
PHP client library for [Coveralls](https://coveralls.io).
|
||||
|
||||
# Prerequisites
|
||||
|
||||
- PHP 5.5+ for 2.x or 5.3+ for 1.x
|
||||
- On [GitHub](https://github.com/)
|
||||
- Building on [Travis CI](http://travis-ci.org/), [CircleCI](https://circleci.com/), [Jenkins](http://jenkins-ci.org/), [Codeship](https://www.codeship.io/) or [GitHub Actions](https://github.com/features/actions)
|
||||
- Testing by [PHPUnit](https://github.com/sebastianbergmann/phpunit/) or other testing framework that can generate clover style coverage report
|
||||
|
||||
# Installation
|
||||
|
||||
## Download phar file
|
||||
|
||||
We started to create a phar file, starting from the version 0.7.0
|
||||
release. It is available at the URLs like:
|
||||
|
||||
```
|
||||
https://github.com/php-coveralls/php-coveralls/releases/download/v2.6.0/php-coveralls.phar
|
||||
```
|
||||
|
||||
Download the file and add exec permissions:
|
||||
|
||||
```sh
|
||||
$ wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.6.0/php-coveralls.phar
|
||||
$ chmod +x php-coveralls.phar
|
||||
```
|
||||
|
||||
## Install by composer
|
||||
|
||||
To install php-coveralls with Composer, run the following command:
|
||||
|
||||
```sh
|
||||
$ composer require --dev php-coveralls/php-coveralls
|
||||
```
|
||||
|
||||
If you need support for PHP versions older than 5.5, you will need to use a 1.x version:
|
||||
|
||||
```sh
|
||||
$ composer require --dev 'php-coveralls/php-coveralls:^1.1'
|
||||
```
|
||||
|
||||
You can see this library on [Packagist](https://packagist.org/packages/php-coveralls/php-coveralls).
|
||||
|
||||
Composer installs autoloader at `./vendor/autoloader.php`. If you use
|
||||
php-coveralls in your php script, add:
|
||||
|
||||
```php
|
||||
require_once 'vendor/autoload.php';
|
||||
```
|
||||
|
||||
If you use Symfony2, autoloader has to be detected automatically.
|
||||
|
||||
|
||||
## Use it from your git clone
|
||||
|
||||
Or you can use git clone command:
|
||||
|
||||
```sh
|
||||
# HTTP
|
||||
$ git clone https://github.com/php-coveralls/php-coveralls.git
|
||||
# SSH
|
||||
$ git clone git@github.com:php-coveralls/php-coveralls.git
|
||||
```
|
||||
|
||||
# Configuration
|
||||
|
||||
Currently php-coveralls supports clover style coverage report and collects coverage information from `clover.xml`.
|
||||
|
||||
## PHPUnit
|
||||
|
||||
Make sure that `phpunit.xml.dist` is configured to generate "coverage-clover" type log named `clover.xml` like the following configuration:
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit ...>
|
||||
<logging>
|
||||
...
|
||||
<log type="coverage-clover" target="build/logs/clover.xml"/>
|
||||
...
|
||||
</logging>
|
||||
</phpunit>
|
||||
```
|
||||
|
||||
You can also use `--coverage-clover` CLI option.
|
||||
|
||||
```sh
|
||||
phpunit --coverage-clover build/logs/clover.xml
|
||||
```
|
||||
|
||||
### phpcov
|
||||
|
||||
Above settings are good for most projects if your test suite is executed once a build and is not divided into several parts. But if your test suite is configured as parallel tasks or generates multiple coverage reports through a build, you can use either `coverage_clover` configuration in `.coveralls.yml` ([see below coverage clover configuration section](#coverage-clover-configuration)) to specify multiple `clover.xml` files or `phpcov` for processing coverage reports.
|
||||
|
||||
#### composer.json
|
||||
|
||||
```json
|
||||
"require-dev": {
|
||||
"php-coveralls/php-coveralls": "^2.6",
|
||||
"phpunit/phpcov": "^2.0"
|
||||
},
|
||||
```
|
||||
|
||||
#### phpunit configuration
|
||||
|
||||
Make sure that `phpunit.xml.dist` is configured to generate "coverage-php" type log:
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit ...>
|
||||
<logging>
|
||||
...
|
||||
<log type="coverage-php" target="build/cov/coverage.cov"/>
|
||||
...
|
||||
</logging>
|
||||
</phpunit>
|
||||
```
|
||||
|
||||
You can also use `--coverage-php` CLI option.
|
||||
|
||||
```sh
|
||||
# use --coverage-php option instead of --coverage-clover
|
||||
phpunit --coverage-php build/cov/coverage-${component_name}.cov
|
||||
```
|
||||
|
||||
#### phpcov configuration
|
||||
|
||||
And then, execute `phpcov.php` to merge `coverage.cov` logs.
|
||||
|
||||
```sh
|
||||
# get information
|
||||
php vendor/bin/phpcov.php --help
|
||||
|
||||
# merge coverage.cov logs under build/cov
|
||||
php vendor/bin/phpcov.php merge --clover build/logs/clover.xml build/cov
|
||||
|
||||
# in case of memory exhausting error
|
||||
php -d memory_limit=-1 vendor/bin/phpcov.php ...
|
||||
```
|
||||
|
||||
### clover.xml
|
||||
|
||||
php-coveralls collects `count` attribute in a `line` tag from `clover.xml` if its `type` attribute equals to `stmt`. When `type` attribute equals to `method`, php-coveralls excludes its `count` attribute from coverage collection because abstract method in an abstract class is never counted though subclasses implement that method which is executed in test cases.
|
||||
|
||||
```xml
|
||||
<!-- this one is counted as code coverage -->
|
||||
<line num="37" type="stmt" count="1"/>
|
||||
<!-- this one is not counted -->
|
||||
<line num="43" type="method" name="getCommandName" crap="1" count="1"/>
|
||||
```
|
||||
|
||||
## Travis CI
|
||||
|
||||
Add `php php-coveralls.phar` or `php vendor/bin/php-coveralls` to your `.travis.yml` at `after_success`.
|
||||
|
||||
```yml
|
||||
# .travis.yml
|
||||
language: php
|
||||
php:
|
||||
- 5.5
|
||||
- 5.4
|
||||
- 5.3
|
||||
|
||||
env:
|
||||
global:
|
||||
- XDEBUG_MODE=coverage
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- php: 5.5
|
||||
|
||||
install:
|
||||
- curl -s http://getcomposer.org/installer | php
|
||||
- php composer.phar install --dev --no-interaction
|
||||
|
||||
script:
|
||||
- mkdir -p build/logs
|
||||
- php vendor/bin/phpunit -c phpunit.xml.dist
|
||||
|
||||
after_success:
|
||||
- travis_retry php vendor/bin/php-coveralls
|
||||
# or enable logging
|
||||
- travis_retry php vendor/bin/php-coveralls -v
|
||||
```
|
||||
|
||||
## CircleCI
|
||||
|
||||
Enable Xdebug in your `circle.yml` at `dependencies` section since currently Xdebug extension is not pre-enabled. `composer` and `phpunit` are pre-installed but you can install them manually in this dependencies section. The following sample uses default ones.
|
||||
|
||||
```yml
|
||||
machine:
|
||||
php:
|
||||
version: 5.4.10
|
||||
|
||||
## Customize dependencies
|
||||
dependencies:
|
||||
override:
|
||||
- mkdir -p build/logs
|
||||
- composer install --dev --no-interaction
|
||||
- sed -i 's/^;//' ~/.phpenv/versions/$(phpenv global)/etc/conf.d/xdebug.ini
|
||||
|
||||
## Customize test commands
|
||||
test:
|
||||
override:
|
||||
- phpunit -c phpunit.xml.dist
|
||||
```
|
||||
|
||||
Add `COVERALLS_REPO_TOKEN` environment variable with your coveralls repo token on Web UI (Tweaks -> Environment Variable).
|
||||
|
||||
## Codeship
|
||||
|
||||
You can configure CI process for Coveralls by adding the following commands to the textarea on Web UI (Project settings > Test tab).
|
||||
|
||||
In the "Modify your Setup Commands" section:
|
||||
|
||||
```sh
|
||||
curl -s http://getcomposer.org/installer | php
|
||||
php composer.phar install --dev --no-interaction
|
||||
mkdir -p build/logs
|
||||
```
|
||||
|
||||
In the "Modify your Test Commands" section:
|
||||
|
||||
```sh
|
||||
php vendor/bin/phpunit -c phpunit.xml.dist
|
||||
php vendor/bin/php-coveralls
|
||||
```
|
||||
|
||||
Next, open Project settings > Environment tab, you can set `COVERALLS_REPO_TOKEN` environment variable.
|
||||
|
||||
In the "Configure your environment variables" section:
|
||||
|
||||
```sh
|
||||
COVERALLS_REPO_TOKEN=your_token
|
||||
```
|
||||
|
||||
## GitHub Actions
|
||||
|
||||
Add a new step after phpunit generate coverage report.
|
||||
|
||||
```yaml
|
||||
- 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=build/logs/clover.xml -v
|
||||
```
|
||||
|
||||
## From local environment
|
||||
|
||||
If you would like to call Coveralls API from your local environment, you can set `COVERALLS_RUN_LOCALLY` environment variable. This configuration requires `repo_token` to specify which project on Coveralls your project maps to. This can be done by configuring `.coveralls.yml` or `COVERALLS_REPO_TOKEN` environment variable.
|
||||
|
||||
```sh
|
||||
$ export COVERALLS_RUN_LOCALLY=1
|
||||
|
||||
# either env var
|
||||
$ export COVERALLS_REPO_TOKEN=your_token
|
||||
|
||||
# or .coveralls.yml configuration
|
||||
$ vi .coveralls.yml
|
||||
repo_token: your_token # should be kept secret!
|
||||
```
|
||||
|
||||
php-coveralls set the following properties to `json_file` which is sent to Coveralls API (same behaviour as the Ruby library will do except for the service name).
|
||||
|
||||
- service_name: php-coveralls
|
||||
- service_event_type: manual
|
||||
|
||||
## Parallel Builds
|
||||
|
||||
Coveralls provides the ability to combine coverage result from multiple parallel builds into one. To enable the feature you can set the following in your environment variable.
|
||||
|
||||
```sh
|
||||
COVERALLS_PARALLEL=true
|
||||
```
|
||||
|
||||
To distinguish your job name, please set the `COVERALLS_FLAG_NAME` environment variable.
|
||||
|
||||
```sh
|
||||
COVERALLS_FLAG_NAME=$YOUR_PHP_VERSION
|
||||
```
|
||||
|
||||
Bear in mind that you will need to configure your build to send a webhook after all the parallel builds are done in order for Coveralls to merge the results.
|
||||
|
||||
Refer to [Parallel Builds Webhook](https://docs.coveralls.io/parallel-build-webhook) for more information for setup on your environment.
|
||||
|
||||
|
||||
## CLI options
|
||||
|
||||
You can get help information for `coveralls` with the `--help (-h)` option.
|
||||
|
||||
```sh
|
||||
php vendor/bin/php-coveralls --help
|
||||
```
|
||||
|
||||
- `--config (-c)`: Used to specify the path to `.coveralls.yml`. Default is `.coveralls.yml`
|
||||
- `--verbose (-v)`: Used to show logs.
|
||||
- `--dry-run`: Used not to send json_file to Coveralls Jobs API.
|
||||
- `--exclude-no-stmt`: Used to exclude source files that have no executable statements.
|
||||
- `--env (-e)`: Runtime environment name: test, dev, prod (default: "prod")
|
||||
- `--coverage_clover (-x)`: Coverage clover xml files(allowing multiple values)
|
||||
- `--json_path` (-o): Used to specify where to output json_file that will be
|
||||
uploaded to Coveralls API. (default: `build/logs/coveralls-upload.json`)
|
||||
- `--root_dir (-r)`: Root directory of the project. (default: ".")
|
||||
|
||||
## .coveralls.yml
|
||||
|
||||
php-coveralls can use optional `.coveralls.yml` file to configure options. This configuration file is usually at the root level of your repository, but you can specify other path by `--config (or -c)` CLI option. Following options are the same as Ruby library ([see reference on coveralls.io](https://coveralls.io/docs/ruby)).
|
||||
|
||||
- `repo_token`: Used to specify which project on Coveralls your project maps to. This is only needed for repos not using CI and should be kept secret
|
||||
- `service_name`: Allows you to specify where Coveralls should look to find additional information about your builds. This can be any string, but using `travis-ci` or `travis-pro` will allow Coveralls to fetch branch data, comment on pull requests, and more.
|
||||
|
||||
Following options can be used for php-coveralls.
|
||||
|
||||
- `entry_point`: Used to specify API endpoint for sending reports. Useful when using self-hosted coveralls or other other, similar service (eg opencov). Default is `https://coveralls.io`.
|
||||
- `coverage_clover`: Used to specify the path to `clover.xml`. Default is `build/logs/clover.xml`
|
||||
- `json_path`: Used to specify where to output `json_file` that will be uploaded to Coveralls API. Default is `build/logs/coveralls-upload.json`.
|
||||
|
||||
```yml
|
||||
# .coveralls.yml example configuration
|
||||
|
||||
# same as Ruby lib
|
||||
repo_token: your_token # should be kept secret!
|
||||
service_name: travis-pro # travis-ci or travis-pro
|
||||
|
||||
# for php-coveralls
|
||||
coverage_clover: build/logs/clover.xml
|
||||
json_path: build/logs/coveralls-upload.json
|
||||
```
|
||||
|
||||
### coverage clover configuration
|
||||
|
||||
You can specify multiple `clover.xml` logs at `coverage_clover`. This is useful for a project that has more than two test suites if all of the test results should be merged into one `json_file`.
|
||||
|
||||
```yml
|
||||
#.coveralls.yml
|
||||
|
||||
# single file
|
||||
coverage_clover: build/logs/clover.xml
|
||||
|
||||
# glob
|
||||
coverage_clover: build/logs/clover-*.xml
|
||||
|
||||
# array
|
||||
# specify files
|
||||
coverage_clover:
|
||||
- build/logs/clover-Auth.xml
|
||||
- build/logs/clover-Db.xml
|
||||
- build/logs/clover-Validator.xml
|
||||
```
|
||||
|
||||
You can also use `--coverage_clover` (or `-x`) command line option as follows:
|
||||
|
||||
```
|
||||
coveralls --coverage_clover=build/logs/my-clover.xml
|
||||
```
|
||||
|
||||
### root_dir detection and override
|
||||
|
||||
This tool assume the current directory is the project root directory by default. You can override it with `--root_dir` command line option.
|
||||
|
||||
|
||||
# Change log
|
||||
|
||||
[See changelog](CHANGELOG.md)
|
||||
|
||||
# Wiki
|
||||
|
||||
[See wiki](https://github.com/php-coveralls/php-coveralls/wiki)
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
if (\file_exists(__DIR__ . '/../vendor/autoload.php')) {
|
||||
// Called from local git clone.
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
} elseif (\file_exists(__DIR__ . '/../../../autoload.php')) {
|
||||
// Called from your project's vendor dir.
|
||||
require __DIR__ . '/../../../autoload.php';
|
||||
} else {
|
||||
die(
|
||||
'You need to set up the project dependencies using the following commands:' . PHP_EOL .
|
||||
'curl -s http://getcomposer.org/installer | php' . PHP_EOL .
|
||||
'php composer.phar install' . PHP_EOL
|
||||
);
|
||||
}
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Console\ApplicationFactory;
|
||||
|
||||
$app = ApplicationFactory::create(\getcwd());
|
||||
$app->run();
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"alias": "php-coveralls.phar",
|
||||
"base-path": null,
|
||||
"chmod": "0755",
|
||||
"directories": [
|
||||
"bin",
|
||||
"src"
|
||||
],
|
||||
"check-requirements": false,
|
||||
"compactors": [
|
||||
"KevinGH\\Box\\Compactor\\Php"
|
||||
],
|
||||
"files": [
|
||||
"LICENSE"
|
||||
],
|
||||
"finder": [
|
||||
{
|
||||
"name": ["*.php", "*.php8", "*.pem"],
|
||||
"exclude": ["tests"],
|
||||
"in": ["vendor"]
|
||||
}
|
||||
],
|
||||
"git-version": "package_version",
|
||||
"main": "bin/php-coveralls",
|
||||
"output": "build/artifacts/php-coveralls.phar",
|
||||
"stub": true
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
machine:
|
||||
php:
|
||||
version:
|
||||
7.1.0
|
||||
|
||||
dependencies:
|
||||
override:
|
||||
- mkdir -p build/logs
|
||||
- echo "date.timezone = America/Los_Angeles" > /opt/circleci/php/$(phpenv global)/etc/conf.d/date.ini
|
||||
- composer update --prefer-stable --prefer-lowest --no-interaction
|
||||
|
||||
test:
|
||||
override:
|
||||
- phpunit
|
||||
post:
|
||||
- bin/php-coveralls -v --exclude-no-stmt
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"name": "php-coveralls/php-coveralls",
|
||||
"description": "PHP client library for Coveralls API",
|
||||
"keywords": ["coverage", "github", "test", "ci"],
|
||||
"homepage": "https://github.com/php-coveralls/php-coveralls",
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kitamura Satoshi",
|
||||
"email": "with.no.parachute@gmail.com",
|
||||
"homepage": "https://www.facebook.com/satooshi.jp",
|
||||
"role": "Original creator"
|
||||
},
|
||||
{
|
||||
"name": "Takashi Matsuo",
|
||||
"email": "tmatsuo@google.com"
|
||||
},
|
||||
{
|
||||
"name": "Google Inc"
|
||||
},
|
||||
{
|
||||
"name": "Dariusz Ruminski",
|
||||
"email": "dariusz.ruminski@gmail.com",
|
||||
"homepage": "https://github.com/keradus"
|
||||
},
|
||||
{
|
||||
"name": "Contributors",
|
||||
"homepage": "https://github.com/php-coveralls/php-coveralls/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^5.5 || ^7.0 || ^8.0",
|
||||
"ext-json": "*",
|
||||
"ext-simplexml": "*",
|
||||
"guzzlehttp/guzzle": "^6.0 || ^7.0",
|
||||
"psr/log": "^1.0 || ^2.0",
|
||||
"symfony/config": "^2.1 || ^3.0 || ^4.0 || ^5.0 || ^6.0",
|
||||
"symfony/console": "^2.1 || ^3.0 || ^4.0 || ^5.0 || ^6.0",
|
||||
"symfony/stopwatch": "^2.0 || ^3.0 || ^4.0 || ^5.0 || ^6.0",
|
||||
"symfony/yaml": "^2.0.5 || ^3.0 || ^4.0 || ^5.0 || ^6.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.35 || ^5.4.3 || ^6.0 || ^7.0 || >=8.0 <8.5.29 || >=9.0 <9.5.23",
|
||||
"sanmai/phpunit-legacy-adapter": "^6.1 || ^8.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/http-kernel": "Allows Symfony integration"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PhpCoveralls\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"PhpCoveralls\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"bin": [
|
||||
"bin/php-coveralls"
|
||||
],
|
||||
"scripts": {
|
||||
"install-dev-tools": [
|
||||
"cd dev-tools && composer install --no-interaction"
|
||||
],
|
||||
"sca": [
|
||||
"php dev-tools/vendor/bin/php-cs-fixer fix --dry-run -vv",
|
||||
"php dev-tools/vendor/bin/phpmd src text build/config/phpmd.xml"
|
||||
]
|
||||
},
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
"process-timeout": 0,
|
||||
"sort-packages": true
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"require": {
|
||||
"php": "^8.1",
|
||||
"ext-json": "*",
|
||||
"ext-simplexml": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.21.1",
|
||||
"pdepend/pdepend": "^2.2",
|
||||
"phpmd/phpmd": "^2.3",
|
||||
"sebastian/finder-facade": "^1.1",
|
||||
"sebastian/phpcpd": "^1.4",
|
||||
"theseer/fdomdocument": "^1.6"
|
||||
},
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
"sort-packages": true
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
|
||||
backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
beStrictAboutChangesToGlobalState="true"
|
||||
beStrictAboutOutputDuringTests="true"
|
||||
beStrictAboutTestsThatDoNotTestAnything="true"
|
||||
bootstrap="vendor/autoload.php"
|
||||
colors="true"
|
||||
columns="max"
|
||||
convertDeprecationsToExceptions="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnError="false"
|
||||
stopOnFailure="false"
|
||||
stopOnRisky="false"
|
||||
verbose="true"
|
||||
>
|
||||
<php>
|
||||
<ini name="error_reporting" value="E_ALL" />
|
||||
</php>
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="PHP Coveralls component test suite">
|
||||
<directory>./tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>./src</directory>
|
||||
<exclude>
|
||||
<directory>./build</directory>
|
||||
<directory>./composer</directory>
|
||||
<directory>./tests</directory>
|
||||
<directory>./vendor</directory>
|
||||
</exclude>
|
||||
</whitelist>
|
||||
</filter>
|
||||
|
||||
<logging>
|
||||
<log type="coverage-clover" target="build/logs/clover.xml"/>
|
||||
<log type="junit" target="build/logs/junit.xml" logIncompleteSkipped="false"/>
|
||||
</logging>
|
||||
</phpunit>
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Bundle\CoverallsBundle\Api;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Config\Configuration;
|
||||
|
||||
/**
|
||||
* Coveralls API client.
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*/
|
||||
abstract class CoverallsApi
|
||||
{
|
||||
/**
|
||||
* Configuration.
|
||||
*
|
||||
* @var Configuration
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* HTTP client.
|
||||
*
|
||||
* @var \GuzzleHttp\Client
|
||||
*/
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Configuration $config configuration
|
||||
* @param \GuzzleHttp\Client $client hTTP client
|
||||
*/
|
||||
public function __construct(Configuration $config, Client $client = null)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->client = $client;
|
||||
}
|
||||
|
||||
// accessor
|
||||
|
||||
/**
|
||||
* Return configuration.
|
||||
*
|
||||
* @return Configuration
|
||||
*/
|
||||
public function getConfiguration()
|
||||
{
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set HTTP client.
|
||||
*
|
||||
* @param \GuzzleHttp\Client $client hTTP client
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setHttpClient(Client $client)
|
||||
{
|
||||
$this->client = $client;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return HTTP client.
|
||||
*
|
||||
* @return \GuzzleHttp\Client
|
||||
*/
|
||||
public function getHttpClient()
|
||||
{
|
||||
return $this->client;
|
||||
}
|
||||
}
|
||||
+190
@@ -0,0 +1,190 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Bundle\CoverallsBundle\Api;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Collector\CiEnvVarsCollector;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Collector\CloverXmlCoverageCollector;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Collector\GitInfoCollector;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\JsonFile;
|
||||
use PhpCoveralls\Component\System\Git\GitCommand;
|
||||
|
||||
/**
|
||||
* Jobs API.
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*/
|
||||
class Jobs extends CoverallsApi
|
||||
{
|
||||
/**
|
||||
* URL for jobs API.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const URL = '/api/v1/jobs';
|
||||
|
||||
/**
|
||||
* Filename as a POST parameter.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FILENAME = 'json_file';
|
||||
|
||||
/**
|
||||
* JsonFile.
|
||||
*
|
||||
* @var JsonFile
|
||||
*/
|
||||
protected $jsonFile;
|
||||
|
||||
// API
|
||||
|
||||
/**
|
||||
* Collect clover XML into json_file.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function collectCloverXml()
|
||||
{
|
||||
$rootDir = $this->config->getRootDir();
|
||||
$cloverXmlPaths = $this->config->getCloverXmlPaths();
|
||||
$xmlCollector = new CloverXmlCoverageCollector();
|
||||
|
||||
foreach ($cloverXmlPaths as $cloverXmlPath) {
|
||||
$xml = simplexml_load_file($cloverXmlPath);
|
||||
|
||||
$xmlCollector->collect($xml, $rootDir);
|
||||
}
|
||||
|
||||
$this->jsonFile = $xmlCollector->getJsonFile();
|
||||
|
||||
if ($this->config->isExcludeNoStatements()) {
|
||||
$this->jsonFile->excludeNoStatementsFiles();
|
||||
}
|
||||
|
||||
$this->jsonFile->sortSourceFiles();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect git repository info into json_file.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function collectGitInfo()
|
||||
{
|
||||
$command = new GitCommand();
|
||||
$gitCollector = new GitInfoCollector($command);
|
||||
|
||||
$this->jsonFile->setGit($gitCollector->collect());
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect environment variables.
|
||||
*
|
||||
* @param array $env $_SERVER environment
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws \PhpCoveralls\Bundle\CoverallsBundle\Entity\Exception\RequirementsNotSatisfiedException
|
||||
*/
|
||||
public function collectEnvVars(array $env)
|
||||
{
|
||||
$envCollector = new CiEnvVarsCollector($this->config);
|
||||
|
||||
try {
|
||||
$this->jsonFile->fillJobs($envCollector->collect($env));
|
||||
} catch (\PhpCoveralls\Bundle\CoverallsBundle\Entity\Exception\RequirementsNotSatisfiedException $e) {
|
||||
$e->setReadEnv($envCollector->getReadEnv());
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump uploading json file.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function dumpJsonFile()
|
||||
{
|
||||
$jsonPath = $this->config->getJsonPath();
|
||||
|
||||
file_put_contents($jsonPath, $this->jsonFile);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send json_file to jobs API.
|
||||
*
|
||||
* @return null|\GuzzleHttp\Psr7\Response
|
||||
*/
|
||||
public function send()
|
||||
{
|
||||
if ($this->config->isDryRun()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$url = $this->config->getEntryPoint() . static::URL;
|
||||
$jsonPath = $this->config->getJsonPath();
|
||||
|
||||
return $this->upload($url, $jsonPath, static::FILENAME);
|
||||
}
|
||||
|
||||
// accessor
|
||||
|
||||
/**
|
||||
* Set JsonFile.
|
||||
*
|
||||
* @param JsonFile $jsonFile json_file content
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setJsonFile(JsonFile $jsonFile)
|
||||
{
|
||||
$this->jsonFile = $jsonFile;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return JsonFile.
|
||||
*
|
||||
* @return null|JsonFile
|
||||
*/
|
||||
public function getJsonFile()
|
||||
{
|
||||
return $this->jsonFile;
|
||||
}
|
||||
|
||||
// internal method
|
||||
|
||||
/**
|
||||
* Upload a file.
|
||||
*
|
||||
* @param string $url uRL to upload
|
||||
* @param string $path file path
|
||||
* @param string $filename filename
|
||||
*
|
||||
* @return \GuzzleHttp\Psr7\Response
|
||||
*/
|
||||
protected function upload($url, $path, $filename)
|
||||
{
|
||||
$options = [
|
||||
'multipart' => [
|
||||
[
|
||||
'name' => $filename,
|
||||
'contents' => file_get_contents($path),
|
||||
'filename' => basename($path),
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
return $this->client->post($url, $options);
|
||||
}
|
||||
}
|
||||
+292
@@ -0,0 +1,292 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Bundle\CoverallsBundle\Collector;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Config\Configuration;
|
||||
|
||||
/**
|
||||
* Environment variables collector for CI envrionment.
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*/
|
||||
class CiEnvVarsCollector
|
||||
{
|
||||
/**
|
||||
* Configuration.
|
||||
*
|
||||
* @var Configuration
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* Environment variables.
|
||||
*
|
||||
* Overwritten through collection process.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $env;
|
||||
|
||||
/**
|
||||
* Read environment variables.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $readEnv;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Configuration $config configuration
|
||||
*/
|
||||
public function __construct(Configuration $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
/**
|
||||
* Collect environment variables.
|
||||
*
|
||||
* @param array $env $_SERVER environment
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function collect(array $env)
|
||||
{
|
||||
$this->env = $env;
|
||||
$this->readEnv = [];
|
||||
|
||||
$this
|
||||
->fillTravisCi()
|
||||
->fillCircleCi()
|
||||
->fillAppVeyor()
|
||||
->fillJenkins()
|
||||
->fillGithubActions()
|
||||
->fillLocal()
|
||||
->fillRepoToken()
|
||||
->fillParallel()
|
||||
;
|
||||
|
||||
return $this->env;
|
||||
}
|
||||
|
||||
// accessor
|
||||
|
||||
/**
|
||||
* Return read environment variables.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getReadEnv()
|
||||
{
|
||||
return $this->readEnv;
|
||||
}
|
||||
|
||||
// internal method
|
||||
|
||||
/**
|
||||
* Fill Travis CI environment variables.
|
||||
*
|
||||
* "TRAVIS", "TRAVIS_BUILD_NUMBER", TRAVIS_JOB_ID" must be set.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function fillTravisCi()
|
||||
{
|
||||
if (isset($this->env['TRAVIS']) && $this->env['TRAVIS'] && isset($this->env['TRAVIS_JOB_ID'], $this->env['TRAVIS_BUILD_NUMBER'])) {
|
||||
$this->env['CI_JOB_ID'] = $this->env['TRAVIS_JOB_ID'];
|
||||
$this->env['CI_BUILD_NUMBER'] = $this->env['TRAVIS_BUILD_NUMBER'];
|
||||
|
||||
if ($this->config->hasServiceName()) {
|
||||
$this->env['CI_NAME'] = $this->config->getServiceName();
|
||||
} else {
|
||||
$this->env['CI_NAME'] = 'travis-ci';
|
||||
}
|
||||
|
||||
// backup
|
||||
$this->readEnv['TRAVIS'] = $this->env['TRAVIS'];
|
||||
$this->readEnv['TRAVIS_JOB_ID'] = $this->env['TRAVIS_JOB_ID'];
|
||||
$this->readEnv['CI_NAME'] = $this->env['CI_NAME'];
|
||||
$this->readEnv['CI_BUILD_NUMBER'] = $this->env['CI_BUILD_NUMBER'];
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill Github Actions environment variables.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function fillGithubActions()
|
||||
{
|
||||
if (!isset($this->env['GITHUB_ACTIONS'])) {
|
||||
return $this;
|
||||
}
|
||||
$this->env['CI_NAME'] = 'github';
|
||||
|
||||
$githubEventName = $this->env['GITHUB_EVENT_NAME'];
|
||||
$githubRef = $this->env['GITHUB_REF'];
|
||||
|
||||
if (strpos($githubRef, 'refs/heads/') !== false) {
|
||||
$githubRef = str_replace('refs/heads/', '', $githubRef);
|
||||
} elseif ($githubEventName === 'pull_request') {
|
||||
$refParts = explode('/', $githubRef);
|
||||
$prNumber = $refParts[2];
|
||||
$this->env['CI_PULL_REQUEST'] = $prNumber;
|
||||
$this->readEnv['CI_PULL_REQUEST'] = $this->env['CI_PULL_REQUEST'];
|
||||
} elseif (strpos($githubRef, 'refs/tags/') !== false) {
|
||||
$githubRef = str_replace('refs/tags/', '', $githubRef);
|
||||
}
|
||||
|
||||
// Same as coverallsapp/github-action
|
||||
// @link https://github.com/coverallsapp/github-action/blob/5984097c6e76d873ef1d8e8e1836b0914d307c3c/src/run.ts#L47
|
||||
$this->env['CI_JOB_ID'] = $this->env['GITHUB_RUN_ID'];
|
||||
$this->env['CI_BRANCH'] = $githubRef;
|
||||
|
||||
$this->readEnv['GITHUB_ACTIONS'] = $this->env['GITHUB_ACTIONS'];
|
||||
$this->readEnv['GITHUB_REF'] = $this->env['GITHUB_REF'];
|
||||
$this->readEnv['CI_NAME'] = $this->env['CI_NAME'];
|
||||
$this->readEnv['CI_JOB_ID'] = $this->env['CI_JOB_ID'];
|
||||
$this->readEnv['CI_BRANCH'] = $this->env['CI_BRANCH'];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill CircleCI environment variables.
|
||||
*
|
||||
* "CIRCLECI", "CIRCLE_WORKFLOW_ID" must be set.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function fillCircleCi()
|
||||
{
|
||||
if (isset($this->env['CIRCLECI']) && $this->env['CIRCLECI'] && isset($this->env['CIRCLE_WORKFLOW_ID'])) {
|
||||
$this->env['CI_BUILD_NUMBER'] = $this->env['CIRCLE_WORKFLOW_ID'];
|
||||
$this->env['CI_NAME'] = 'circleci';
|
||||
|
||||
// backup
|
||||
$this->readEnv['CIRCLECI'] = $this->env['CIRCLECI'];
|
||||
$this->readEnv['CIRCLE_WORKFLOW_ID'] = $this->env['CIRCLE_WORKFLOW_ID'];
|
||||
$this->readEnv['CI_NAME'] = $this->env['CI_NAME'];
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill AppVeyor environment variables.
|
||||
*
|
||||
* "APPVEYOR", "APPVEYOR_BUILD_NUMBER" must be set.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function fillAppVeyor()
|
||||
{
|
||||
if (isset($this->env['APPVEYOR']) && $this->env['APPVEYOR'] && isset($this->env['APPVEYOR_BUILD_NUMBER'])) {
|
||||
$this->env['CI_BUILD_NUMBER'] = $this->env['APPVEYOR_BUILD_NUMBER'];
|
||||
$this->env['CI_JOB_ID'] = $this->env['APPVEYOR_JOB_NUMBER'];
|
||||
$this->env['CI_BRANCH'] = $this->env['APPVEYOR_REPO_BRANCH'];
|
||||
$this->env['CI_PULL_REQUEST'] = $this->env['APPVEYOR_PULL_REQUEST_NUMBER'];
|
||||
$this->env['CI_NAME'] = 'AppVeyor';
|
||||
|
||||
// backup
|
||||
$this->readEnv['APPVEYOR'] = $this->env['APPVEYOR'];
|
||||
$this->readEnv['APPVEYOR_BUILD_NUMBER'] = $this->env['APPVEYOR_BUILD_NUMBER'];
|
||||
$this->readEnv['APPVEYOR_JOB_NUMBER'] = $this->env['APPVEYOR_JOB_NUMBER'];
|
||||
$this->readEnv['APPVEYOR_REPO_BRANCH'] = $this->env['APPVEYOR_REPO_BRANCH'];
|
||||
$this->readEnv['APPVEYOR_PULL_REQUEST_NUMBER'] = $this->env['APPVEYOR_PULL_REQUEST_NUMBER'];
|
||||
$this->readEnv['CI_NAME'] = $this->env['CI_NAME'];
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill Jenkins environment variables.
|
||||
*
|
||||
* "JENKINS_URL", "BUILD_NUMBER" must be set.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function fillJenkins()
|
||||
{
|
||||
if (isset($this->env['JENKINS_URL'], $this->env['BUILD_NUMBER'])) {
|
||||
$this->env['CI_BUILD_NUMBER'] = $this->env['BUILD_NUMBER'];
|
||||
$this->env['CI_BUILD_URL'] = $this->env['JENKINS_URL'];
|
||||
$this->env['CI_NAME'] = 'jenkins';
|
||||
|
||||
// backup
|
||||
$this->readEnv['BUILD_NUMBER'] = $this->env['BUILD_NUMBER'];
|
||||
$this->readEnv['JENKINS_URL'] = $this->env['JENKINS_URL'];
|
||||
$this->readEnv['CI_NAME'] = $this->env['CI_NAME'];
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill local environment variables.
|
||||
*
|
||||
* "COVERALLS_RUN_LOCALLY" must be set.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function fillLocal()
|
||||
{
|
||||
if (isset($this->env['COVERALLS_RUN_LOCALLY']) && $this->env['COVERALLS_RUN_LOCALLY']) {
|
||||
$this->env['CI_JOB_ID'] = null;
|
||||
$this->env['CI_NAME'] = 'php-coveralls';
|
||||
$this->env['COVERALLS_EVENT_TYPE'] = 'manual';
|
||||
|
||||
// backup
|
||||
$this->readEnv['COVERALLS_RUN_LOCALLY'] = $this->env['COVERALLS_RUN_LOCALLY'];
|
||||
$this->readEnv['COVERALLS_EVENT_TYPE'] = $this->env['COVERALLS_EVENT_TYPE'];
|
||||
$this->readEnv['CI_NAME'] = $this->env['CI_NAME'];
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill repo_token for unsupported CI service.
|
||||
*
|
||||
* "COVERALLS_REPO_TOKEN" must be set.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function fillRepoToken()
|
||||
{
|
||||
if ($this->config->hasRepoToken()) {
|
||||
$this->env['COVERALLS_REPO_TOKEN'] = $this->config->getRepoToken();
|
||||
}
|
||||
|
||||
// backup
|
||||
if (isset($this->env['COVERALLS_REPO_TOKEN'])) {
|
||||
$this->readEnv['COVERALLS_REPO_TOKEN'] = $this->env['COVERALLS_REPO_TOKEN'];
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill parallel for parallel jobs.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function fillParallel()
|
||||
{
|
||||
if (isset($this->env['COVERALLS_PARALLEL'])) {
|
||||
$this->readEnv['COVERALLS_PARALLEL'] = $this->env['COVERALLS_PARALLEL'];
|
||||
}
|
||||
|
||||
if (isset($this->env['COVERALLS_FLAG_NAME'])) {
|
||||
$this->readEnv['COVERALLS_FLAG_NAME'] = $this->env['COVERALLS_FLAG_NAME'];
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Bundle\CoverallsBundle\Collector;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\JsonFile;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\SourceFile;
|
||||
|
||||
/**
|
||||
* Coverage collector for clover.xml.
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*/
|
||||
class CloverXmlCoverageCollector
|
||||
{
|
||||
/**
|
||||
* JsonFile.
|
||||
*
|
||||
* @var \PhpCoveralls\Bundle\CoverallsBundle\Entity\JsonFile
|
||||
*/
|
||||
protected $jsonFile;
|
||||
|
||||
// API
|
||||
|
||||
/**
|
||||
* Collect coverage from XML object.
|
||||
*
|
||||
* @param \SimpleXMLElement $xml clover XML object
|
||||
* @param string $rootDir path to repository root directory
|
||||
*
|
||||
* @return \PhpCoveralls\Bundle\CoverallsBundle\Entity\JsonFile
|
||||
*/
|
||||
public function collect(\SimpleXMLElement $xml, $rootDir)
|
||||
{
|
||||
$root = rtrim($rootDir, \DIRECTORY_SEPARATOR) . \DIRECTORY_SEPARATOR;
|
||||
|
||||
if ($this->jsonFile === null) {
|
||||
$this->jsonFile = new JsonFile();
|
||||
}
|
||||
|
||||
// overwrite if run_at has already been set
|
||||
$runAt = $this->collectRunAt($xml);
|
||||
$this->jsonFile->setRunAt($runAt);
|
||||
|
||||
$xpaths = [
|
||||
'/coverage/project/file',
|
||||
'/coverage/project/package/file',
|
||||
];
|
||||
|
||||
foreach ($xpaths as $xpath) {
|
||||
foreach ($xml->xpath($xpath) as $file) {
|
||||
$srcFile = $this->collectFileCoverage($file, $root);
|
||||
|
||||
if ($srcFile !== null) {
|
||||
$this->jsonFile->addSourceFile($srcFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->jsonFile;
|
||||
}
|
||||
|
||||
// accessor
|
||||
|
||||
/**
|
||||
* Return json file.
|
||||
*
|
||||
* @return \PhpCoveralls\Bundle\CoverallsBundle\Entity\JsonFile
|
||||
*/
|
||||
public function getJsonFile()
|
||||
{
|
||||
return $this->jsonFile;
|
||||
}
|
||||
|
||||
// Internal method
|
||||
|
||||
/**
|
||||
* Collect timestamp when the job ran.
|
||||
*
|
||||
* @param \SimpleXMLElement $xml clover XML object of a file
|
||||
* @param string $format dateTime format
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function collectRunAt(\SimpleXMLElement $xml, $format = 'Y-m-d H:i:s O')
|
||||
{
|
||||
$timestamp = $xml->project['timestamp'];
|
||||
$runAt = new \DateTime('@' . $timestamp);
|
||||
|
||||
return $runAt->format($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect coverage data of a file.
|
||||
*
|
||||
* @param \SimpleXMLElement $file clover XML object of a file
|
||||
* @param string $root path to src directory
|
||||
*
|
||||
* @return null|\PhpCoveralls\Bundle\CoverallsBundle\Entity\SourceFile
|
||||
*/
|
||||
protected function collectFileCoverage(\SimpleXMLElement $file, $root)
|
||||
{
|
||||
$absolutePath = realpath((string) ($file['path'] ?: $file['name']));
|
||||
|
||||
if (strpos($absolutePath, $root) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
$filename = $absolutePath;
|
||||
|
||||
if ($root !== \DIRECTORY_SEPARATOR) {
|
||||
$filename = str_replace($root, '', $absolutePath);
|
||||
}
|
||||
|
||||
return $this->collectCoverage($file, $absolutePath, $filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect coverage data.
|
||||
*
|
||||
* @param \SimpleXMLElement $file clover XML object of a file
|
||||
* @param string $path path to source file
|
||||
* @param string $filename filename
|
||||
*
|
||||
* @return \PhpCoveralls\Bundle\CoverallsBundle\Entity\SourceFile
|
||||
*/
|
||||
protected function collectCoverage(\SimpleXMLElement $file, $path, $filename)
|
||||
{
|
||||
if ($this->jsonFile->hasSourceFile($path)) {
|
||||
$srcFile = $this->jsonFile->getSourceFile($path);
|
||||
} else {
|
||||
$srcFile = new SourceFile($path, $filename);
|
||||
}
|
||||
|
||||
foreach ($file->line as $line) {
|
||||
if ((string) $line['type'] === 'stmt') {
|
||||
$lineNum = (int) $line['num'];
|
||||
|
||||
if ($lineNum > 0) {
|
||||
$srcFile->addCoverage($lineNum - 1, (int) $line['count']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $srcFile;
|
||||
}
|
||||
}
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Bundle\CoverallsBundle\Collector;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Commit;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Git;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Remote;
|
||||
use PhpCoveralls\Component\System\Git\GitCommand;
|
||||
|
||||
/**
|
||||
* Git repository info collector.
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*/
|
||||
class GitInfoCollector
|
||||
{
|
||||
/**
|
||||
* Git command.
|
||||
*
|
||||
* @var GitCommand
|
||||
*/
|
||||
protected $command;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param GitCommand $command Git command
|
||||
*/
|
||||
public function __construct(GitCommand $command)
|
||||
{
|
||||
$this->command = $command;
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
/**
|
||||
* Collect git repository info.
|
||||
*
|
||||
* @return \PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Git
|
||||
*/
|
||||
public function collect()
|
||||
{
|
||||
$branch = $this->collectBranch();
|
||||
$commit = $this->collectCommit();
|
||||
$remotes = $this->collectRemotes();
|
||||
|
||||
return new Git($branch, $commit, $remotes);
|
||||
}
|
||||
|
||||
// accessor
|
||||
|
||||
/**
|
||||
* Return git command.
|
||||
*
|
||||
* @return \PhpCoveralls\Component\System\Git\GitCommand
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
return $this->command;
|
||||
}
|
||||
|
||||
// internal method
|
||||
|
||||
/**
|
||||
* Collect branch name.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function collectBranch()
|
||||
{
|
||||
$branchesResult = $this->command->getBranches();
|
||||
|
||||
foreach ($branchesResult as $result) {
|
||||
if ($result === '* (no branch)') {
|
||||
// Case detected on Travis PUSH hook for tags, can be reporduced by following command:
|
||||
// $ git clone --depth=1 --branch=v2.4.0 https://github.com/php-coveralls/php-coveralls.git php-coveralls && cd php-coveralls && git branch
|
||||
// * (no branch)
|
||||
return '(no branch)';
|
||||
}
|
||||
|
||||
if (strpos($result, '* ') === 0) {
|
||||
preg_match('/^\* (?:\(HEAD detached at )?([\w\/\-]+)\)?/', $result, $matches);
|
||||
|
||||
return $matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
throw new \RuntimeException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect commit info.
|
||||
*
|
||||
* @return \PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Commit
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function collectCommit()
|
||||
{
|
||||
$commitResult = $this->command->getHeadCommit();
|
||||
|
||||
if (\count($commitResult) !== 6 || array_keys($commitResult) !== range(0, 5)) {
|
||||
throw new \RuntimeException();
|
||||
}
|
||||
|
||||
$commit = new Commit();
|
||||
|
||||
return $commit
|
||||
->setId($commitResult[0])
|
||||
->setAuthorName($commitResult[1])
|
||||
->setAuthorEmail($commitResult[2])
|
||||
->setCommitterName($commitResult[3])
|
||||
->setCommitterEmail($commitResult[4])
|
||||
->setMessage($commitResult[5])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect remotes info.
|
||||
*
|
||||
* @return \PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Remote[]
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function collectRemotes()
|
||||
{
|
||||
$remotesResult = $this->command->getRemotes();
|
||||
|
||||
if (\count($remotesResult) === 0) {
|
||||
throw new \RuntimeException();
|
||||
}
|
||||
|
||||
// parse command result
|
||||
$results = [];
|
||||
|
||||
foreach ($remotesResult as $result) {
|
||||
if (strpos($result, ' ') !== false) {
|
||||
list($remote) = explode(' ', $result, 2);
|
||||
|
||||
$results[] = $remote;
|
||||
}
|
||||
}
|
||||
|
||||
// filter
|
||||
$results = array_unique($results);
|
||||
|
||||
// create Remote instances
|
||||
$remotes = [];
|
||||
|
||||
foreach ($results as $result) {
|
||||
if (strpos($result, "\t") !== false) {
|
||||
list($name, $url) = explode("\t", $result, 2);
|
||||
|
||||
$remote = new Remote();
|
||||
$remotes[] = $remote->setName($name)->setUrl($url);
|
||||
}
|
||||
}
|
||||
|
||||
return $remotes;
|
||||
}
|
||||
}
|
||||
+209
@@ -0,0 +1,209 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Bundle\CoverallsBundle\Command;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Api\Jobs;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Config\Configuration;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Config\Configurator;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Repository\JobsRepository;
|
||||
use PhpCoveralls\Component\File\Path;
|
||||
use PhpCoveralls\Component\Log\ConsoleLogger;
|
||||
use Psr\Log\NullLogger;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Stopwatch\Stopwatch;
|
||||
|
||||
/**
|
||||
* Coveralls Jobs API v1 command.
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*/
|
||||
class CoverallsJobsCommand extends Command
|
||||
{
|
||||
/**
|
||||
* Skip SSL verification while sending a report if true.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $allowInsecure;
|
||||
|
||||
/**
|
||||
* Path to project root directory.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $rootDir;
|
||||
|
||||
/**
|
||||
* Logger.
|
||||
*
|
||||
* @var \Psr\Log\LoggerInterface
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
// accessor
|
||||
|
||||
/**
|
||||
* Set root directory.
|
||||
*
|
||||
* @param string $rootDir path to project root directory
|
||||
*/
|
||||
public function setRootDir($rootDir)
|
||||
{
|
||||
$this->rootDir = $rootDir;
|
||||
}
|
||||
|
||||
// internal method
|
||||
|
||||
/**
|
||||
* @see \Symfony\Component\Console\Command\Command::configure()
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('coveralls:v1:jobs')
|
||||
->setDescription('Coveralls Jobs API v1')
|
||||
->addOption(
|
||||
'config',
|
||||
'-c',
|
||||
InputOption::VALUE_OPTIONAL,
|
||||
'.coveralls.yml path',
|
||||
'.coveralls.yml'
|
||||
)
|
||||
->addOption(
|
||||
'dry-run',
|
||||
null,
|
||||
InputOption::VALUE_NONE,
|
||||
'Do not send json_file to Jobs API'
|
||||
)
|
||||
->addOption(
|
||||
'exclude-no-stmt',
|
||||
null,
|
||||
InputOption::VALUE_NONE,
|
||||
'Exclude source files that have no executable statements'
|
||||
)
|
||||
->addOption(
|
||||
'env',
|
||||
'-e',
|
||||
InputOption::VALUE_OPTIONAL,
|
||||
'Runtime environment name: test, dev, prod',
|
||||
'prod'
|
||||
)
|
||||
->addOption(
|
||||
'coverage_clover',
|
||||
'-x',
|
||||
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
|
||||
'Coverage clover xml files (allowing multiple values).',
|
||||
[]
|
||||
)
|
||||
->addOption(
|
||||
'json_path',
|
||||
'-o',
|
||||
InputOption::VALUE_REQUIRED,
|
||||
'Coveralls output json file',
|
||||
[]
|
||||
)
|
||||
->addOption(
|
||||
'entry_point',
|
||||
null,
|
||||
InputOption::VALUE_REQUIRED,
|
||||
'Coveralls entrypoint',
|
||||
'https://coveralls.io'
|
||||
)
|
||||
->addOption(
|
||||
'root_dir',
|
||||
'-r',
|
||||
InputOption::VALUE_OPTIONAL,
|
||||
'Root directory of the project.',
|
||||
'.'
|
||||
)
|
||||
->addOption(
|
||||
'insecure',
|
||||
'-k',
|
||||
InputOption::VALUE_NONE,
|
||||
'Skip SSL certificate check.'
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \Symfony\Component\Console\Command\Command::execute()
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$stopwatch = new Stopwatch();
|
||||
$stopwatch->start(__CLASS__);
|
||||
$file = new Path();
|
||||
if ($input->getOption('root_dir') !== '.') {
|
||||
$this->rootDir = $file->toAbsolutePath(
|
||||
$input->getOption('root_dir'),
|
||||
$this->rootDir
|
||||
);
|
||||
}
|
||||
|
||||
$config = $this->loadConfiguration($input, $this->rootDir);
|
||||
$this->logger = $config->isVerbose() && !$config->isTestEnv() ? new ConsoleLogger($output) : new NullLogger();
|
||||
$this->allowInsecure = (bool) $input->getOption('insecure');
|
||||
|
||||
$executionStatus = $this->executeApi($config);
|
||||
|
||||
$event = $stopwatch->stop(__CLASS__);
|
||||
$time = number_format($event->getDuration() / 1000, 3); // sec
|
||||
$mem = number_format($event->getMemory() / (1024 * 1024), 2); // MB
|
||||
$this->logger->info(sprintf('elapsed time: <info>%s</info> sec memory: <info>%s</info> MB', $time, $mem));
|
||||
|
||||
return $executionStatus ? 0 : 1;
|
||||
}
|
||||
|
||||
// for Jobs API
|
||||
|
||||
/**
|
||||
* Load configuration.
|
||||
*
|
||||
* @param InputInterface $input input arguments
|
||||
* @param string $rootDir path to project root directory
|
||||
*
|
||||
* @return \PhpCoveralls\Bundle\CoverallsBundle\Config\Configuration
|
||||
*/
|
||||
protected function loadConfiguration(InputInterface $input, $rootDir)
|
||||
{
|
||||
$coverallsYmlPath = $input->getOption('config');
|
||||
|
||||
$ymlPath = $this->rootDir . \DIRECTORY_SEPARATOR . $coverallsYmlPath;
|
||||
$configurator = new Configurator();
|
||||
|
||||
return $configurator
|
||||
->load($ymlPath, $rootDir, $input)
|
||||
->setDryRun($input->getOption('dry-run'))
|
||||
->setExcludeNoStatementsUnlessFalse($input->getOption('exclude-no-stmt'))
|
||||
->setVerbose($input->getOption('verbose'))
|
||||
->setEnv($input->getOption('env'))
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute Jobs API.
|
||||
*
|
||||
* @param Configuration $config configuration
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function executeApi(Configuration $config)
|
||||
{
|
||||
$params = [];
|
||||
if ($this->allowInsecure) {
|
||||
$params['verify'] = false;
|
||||
}
|
||||
|
||||
$client = new Client($params);
|
||||
$api = new Jobs($config, $client);
|
||||
$repository = new JobsRepository($api, $config);
|
||||
|
||||
$repository->setLogger($this->logger);
|
||||
|
||||
return $repository->persist();
|
||||
}
|
||||
}
|
||||
+397
@@ -0,0 +1,397 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Bundle\CoverallsBundle\Config;
|
||||
|
||||
/**
|
||||
* Coveralls API configuration.
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*/
|
||||
class Configuration
|
||||
{
|
||||
/**
|
||||
* Entry point which is used for api calls.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $entryPoint;
|
||||
|
||||
// same as ruby lib
|
||||
|
||||
/**
|
||||
* repo_token.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $repoToken;
|
||||
|
||||
/**
|
||||
* service_name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $serviceName;
|
||||
|
||||
// only for php lib
|
||||
|
||||
/**
|
||||
* Absolute path to repository root directory.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $rootDir;
|
||||
|
||||
/**
|
||||
* Absolute paths to clover.xml.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $cloverXmlPaths = [];
|
||||
|
||||
/**
|
||||
* Absolute path to output json_file.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $jsonPath;
|
||||
|
||||
// from command option
|
||||
|
||||
/**
|
||||
* Whether to send json_file to jobs API.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $dryRun = true;
|
||||
|
||||
/**
|
||||
* Whether to exclude source files that have no executable statements.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $excludeNoStatements = false;
|
||||
|
||||
/**
|
||||
* Whether to show log.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $verbose = false;
|
||||
|
||||
/**
|
||||
* Runtime environment name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $env = 'prod';
|
||||
|
||||
// accessor
|
||||
|
||||
/**
|
||||
* Set api entry point.
|
||||
*
|
||||
* @param string $entryPoint
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setEntryPoint($entryPoint)
|
||||
{
|
||||
$this->entryPoint = rtrim($entryPoint, '/');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return api entry point.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEntryPoint()
|
||||
{
|
||||
return $this->entryPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set repository token.
|
||||
*
|
||||
* @param string $repoToken
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setRepoToken($repoToken)
|
||||
{
|
||||
$this->repoToken = $repoToken;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether repository token is configured.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRepoToken()
|
||||
{
|
||||
return $this->repoToken !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return repository token.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getRepoToken()
|
||||
{
|
||||
return $this->repoToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set service name.
|
||||
*
|
||||
* @param string $serviceName
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setServiceName($serviceName)
|
||||
{
|
||||
$this->serviceName = $serviceName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the service name is configured.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasServiceName()
|
||||
{
|
||||
return $this->serviceName !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return service name.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getServiceName()
|
||||
{
|
||||
return $this->serviceName;
|
||||
}
|
||||
|
||||
public function setRootDir($rootDir)
|
||||
{
|
||||
$this->rootDir = $rootDir;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRootDir()
|
||||
{
|
||||
return $this->rootDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set absolute paths to clover.xml.
|
||||
*
|
||||
* @param string[] $cloverXmlPaths
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setCloverXmlPaths(array $cloverXmlPaths)
|
||||
{
|
||||
$this->cloverXmlPaths = $cloverXmlPaths;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add absolute path to clover.xml.
|
||||
*
|
||||
* @param string $cloverXmlPath
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addCloverXmlPath($cloverXmlPath)
|
||||
{
|
||||
$this->cloverXmlPaths[] = $cloverXmlPath;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return absolute path to clover.xml.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getCloverXmlPaths()
|
||||
{
|
||||
return $this->cloverXmlPaths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set absolute path to output json_file.
|
||||
*
|
||||
* @param string $jsonPath
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setJsonPath($jsonPath)
|
||||
{
|
||||
$this->jsonPath = $jsonPath;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return absolute path to output json_file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getJsonPath()
|
||||
{
|
||||
return $this->jsonPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to send json_file to jobs API.
|
||||
*
|
||||
* @param bool $dryRun
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setDryRun($dryRun)
|
||||
{
|
||||
$this->dryRun = $dryRun;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether to send json_file to jobs API.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDryRun()
|
||||
{
|
||||
return $this->dryRun;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to exclude source files that have no executable statements.
|
||||
*
|
||||
* @param bool $excludeNoStatements
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setExcludeNoStatements($excludeNoStatements)
|
||||
{
|
||||
$this->excludeNoStatements = $excludeNoStatements;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to exclude source files that have no executable statements unless false.
|
||||
*
|
||||
* @param bool $excludeNoStatements
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setExcludeNoStatementsUnlessFalse($excludeNoStatements)
|
||||
{
|
||||
if ($excludeNoStatements) {
|
||||
$this->excludeNoStatements = true;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether to exclude source files that have no executable statements.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isExcludeNoStatements()
|
||||
{
|
||||
return $this->excludeNoStatements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to show log.
|
||||
*
|
||||
* @param bool $verbose
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setVerbose($verbose)
|
||||
{
|
||||
$this->verbose = $verbose;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether to show log.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isVerbose()
|
||||
{
|
||||
return $this->verbose;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set runtime environment name.
|
||||
*
|
||||
* @param string $env runtime environment name
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setEnv($env)
|
||||
{
|
||||
$this->env = $env;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return runtime environment name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEnv()
|
||||
{
|
||||
return $this->env;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the runtime environment is test.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isTestEnv()
|
||||
{
|
||||
return $this->env === 'test';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the runtime environment is dev.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDevEnv()
|
||||
{
|
||||
return $this->env === 'dev';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the runtime environment is prod.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isProdEnv()
|
||||
{
|
||||
return $this->env === 'prod';
|
||||
}
|
||||
}
|
||||
+255
@@ -0,0 +1,255 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Bundle\CoverallsBundle\Config;
|
||||
|
||||
use PhpCoveralls\Component\File\Path;
|
||||
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
|
||||
use Symfony\Component\Config\Definition\Processor;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Yaml\Parser;
|
||||
|
||||
/**
|
||||
* Coveralls API configurator.
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*/
|
||||
class Configurator
|
||||
{
|
||||
// API
|
||||
|
||||
/**
|
||||
* Load configuration.
|
||||
*
|
||||
* @param string $coverallsYmlPath Path to .coveralls.yml.
|
||||
* @param string $rootDir path to project root directory
|
||||
*
|
||||
* @return \PhpCoveralls\Bundle\CoverallsBundle\Config\Configuration
|
||||
*
|
||||
* @throws \Symfony\Component\Yaml\Exception\ParseException If the YAML is not valid
|
||||
*/
|
||||
public function load($coverallsYmlPath, $rootDir, InputInterface $input = null)
|
||||
{
|
||||
$yml = $this->parse($coverallsYmlPath);
|
||||
$options = $this->process($yml);
|
||||
|
||||
return $this->createConfiguration($options, $rootDir, $input);
|
||||
}
|
||||
|
||||
// Internal method
|
||||
|
||||
/**
|
||||
* Parse .coveralls.yml.
|
||||
*
|
||||
* @param string $coverallsYmlPath Path to .coveralls.yml.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \Symfony\Component\Yaml\Exception\ParseException If the YAML is not valid
|
||||
*/
|
||||
protected function parse($coverallsYmlPath)
|
||||
{
|
||||
$file = new Path();
|
||||
$path = realpath($coverallsYmlPath);
|
||||
|
||||
if ($file->isRealFileReadable($path)) {
|
||||
$parser = new Parser();
|
||||
$yml = $parser->parse(file_get_contents($path));
|
||||
|
||||
return empty($yml) ? [] : $yml;
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Process parsed configuration according to the configuration definition.
|
||||
*
|
||||
* @param array $yml parsed configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function process(array $yml)
|
||||
{
|
||||
$processor = new Processor();
|
||||
$configuration = new CoverallsConfiguration();
|
||||
|
||||
return $processor->processConfiguration($configuration, ['coveralls' => $yml]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create coveralls configuration.
|
||||
*
|
||||
* @param array $options processed configuration
|
||||
* @param string $rootDir path to project root directory
|
||||
*
|
||||
* @return \PhpCoveralls\Bundle\CoverallsBundle\Config\Configuration
|
||||
*/
|
||||
protected function createConfiguration(array $options, $rootDir, InputInterface $input = null)
|
||||
{
|
||||
$configuration = new Configuration();
|
||||
$file = new Path();
|
||||
|
||||
$repoToken = $options['repo_token'];
|
||||
$repoSecretToken = $options['repo_secret_token'];
|
||||
|
||||
$coverage_clover = $this->getPotentiallyOverriddenOptionValue('coverage_clover', $options, $input);
|
||||
$json_path = $this->getPotentiallyOverriddenOptionValue('json_path', $options, $input);
|
||||
$entry_point = $this->getPotentiallyOverriddenOptionValue('entry_point', $options, $input);
|
||||
|
||||
return $configuration
|
||||
->setEntrypoint($entry_point)
|
||||
->setRepoToken($repoToken !== null ? $repoToken : $repoSecretToken)
|
||||
->setServiceName($options['service_name'])
|
||||
->setRootDir($rootDir)
|
||||
->setCloverXmlPaths($this->ensureCloverXmlPaths($coverage_clover, $rootDir, $file))
|
||||
->setJsonPath($this->ensureJsonPath($json_path, $rootDir, $file))
|
||||
->setExcludeNoStatements($options['exclude_no_stmt'])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure coverage_clover is valid.
|
||||
*
|
||||
* @param string $option coverage_clover option
|
||||
* @param string $rootDir path to project root directory
|
||||
* @param Path $file path object
|
||||
*
|
||||
* @return string[] valid Absolute paths of coverage_clover
|
||||
*
|
||||
* @throws \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
|
||||
*/
|
||||
protected function ensureCloverXmlPaths($option, $rootDir, Path $file)
|
||||
{
|
||||
if (\is_array($option)) {
|
||||
return $this->getGlobPathsFromArrayOption($option, $rootDir, $file);
|
||||
}
|
||||
|
||||
return $this->getGlobPathsFromStringOption($option, $rootDir, $file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return absolute paths from glob path.
|
||||
*
|
||||
* @param string $path absolute path
|
||||
*
|
||||
* @return string[] absolute paths
|
||||
*
|
||||
* @throws \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
|
||||
*/
|
||||
protected function getGlobPaths($path)
|
||||
{
|
||||
$paths = [];
|
||||
$iterator = new \GlobIterator($path);
|
||||
|
||||
foreach ($iterator as $fileInfo) {
|
||||
/* @var $fileInfo \SplFileInfo */
|
||||
$paths[] = $fileInfo->getPathname();
|
||||
}
|
||||
|
||||
// validate
|
||||
if (\count($paths) === 0) {
|
||||
throw new InvalidConfigurationException("coverage_clover XML file is not readable: {$path}");
|
||||
}
|
||||
|
||||
return $paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return absolute paths from string option value.
|
||||
*
|
||||
* @param string $option coverage_clover option value
|
||||
* @param string $rootDir path to project root directory
|
||||
* @param Path $file path object
|
||||
*
|
||||
* @return string[] absolute paths
|
||||
*
|
||||
* @throws \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
|
||||
*/
|
||||
protected function getGlobPathsFromStringOption($option, $rootDir, Path $file)
|
||||
{
|
||||
if (!\is_string($option)) {
|
||||
throw new InvalidConfigurationException('coverage_clover XML file option must be a string');
|
||||
}
|
||||
|
||||
// normalize
|
||||
$path = $file->toAbsolutePath($option, $rootDir);
|
||||
|
||||
return $this->getGlobPaths($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return absolute paths from array option values.
|
||||
*
|
||||
* @param array $options coverage_clover option values
|
||||
* @param string $rootDir path to project root directory
|
||||
* @param Path $file path object
|
||||
*
|
||||
* @return string[] absolute paths
|
||||
*
|
||||
* @throws \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
|
||||
*/
|
||||
protected function getGlobPathsFromArrayOption(array $options, $rootDir, Path $file)
|
||||
{
|
||||
$paths = [];
|
||||
|
||||
foreach ($options as $option) {
|
||||
$paths = array_merge($paths, $this->getGlobPathsFromStringOption($option, $rootDir, $file));
|
||||
}
|
||||
|
||||
return $paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure json_path is valid.
|
||||
*
|
||||
* @param string $option json_path option
|
||||
* @param string $rootDir path to project root directory
|
||||
* @param Path $file path object
|
||||
*
|
||||
* @return string valid json_path
|
||||
*
|
||||
* @throws \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
|
||||
*/
|
||||
protected function ensureJsonPath($option, $rootDir, Path $file)
|
||||
{
|
||||
// normalize
|
||||
$realpath = $file->getRealWritingFilePath($option, $rootDir);
|
||||
|
||||
// validate file
|
||||
$realFilePath = $file->getRealPath($realpath, $rootDir);
|
||||
|
||||
if ($realFilePath !== false && !$file->isRealFileWritable($realFilePath)) {
|
||||
throw new InvalidConfigurationException("json_path is not writable: {$realFilePath}");
|
||||
}
|
||||
|
||||
// validate parent dir
|
||||
$realDir = $file->getRealDir($realpath, $rootDir);
|
||||
|
||||
if (!$file->isRealDirWritable($realDir)) {
|
||||
throw new InvalidConfigurationException("json_path is not writable: {$realFilePath}");
|
||||
}
|
||||
|
||||
return $realpath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get option from YAML config, potentially overridden via input params.
|
||||
*
|
||||
* @param string $optionName option name
|
||||
* @param array $options processed configuration
|
||||
*
|
||||
* @return \PhpCoveralls\Bundle\CoverallsBundle\Config\Configuration
|
||||
*/
|
||||
private function getPotentiallyOverriddenOptionValue($optionName, array $options, InputInterface $input = null)
|
||||
{
|
||||
$value = $options[$optionName];
|
||||
if ($input !== null && $input->hasOption($optionName)) {
|
||||
$inputOverride = $input->getOption($optionName);
|
||||
if (!empty($inputOverride)) {
|
||||
$value = $inputOverride;
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Bundle\CoverallsBundle\Config;
|
||||
|
||||
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
|
||||
use Symfony\Component\Config\Definition\ConfigurationInterface;
|
||||
|
||||
/**
|
||||
* Definition of .coveralls.yml configuration.
|
||||
*
|
||||
* # same as ruby
|
||||
* repo_token: your-token
|
||||
* repo_secret_token: your-token
|
||||
* service_name: travis-pro
|
||||
*
|
||||
* coverage_clover: build/logs/clover.xml
|
||||
* json_path: build/logs/coveralls-upload.json
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*/
|
||||
class CoverallsConfiguration implements ConfigurationInterface
|
||||
{
|
||||
// ConfigurationInterface
|
||||
|
||||
/**
|
||||
* @see \Symfony\Component\Config\Definition\ConfigurationInterface::getConfigTreeBuilder()
|
||||
*/
|
||||
public function getConfigTreeBuilder()
|
||||
{
|
||||
// define configuration
|
||||
|
||||
if (method_exists(TreeBuilder::class, 'getRootNode')) {
|
||||
$treeBuilder = new TreeBuilder('coveralls');
|
||||
$rootNode = $treeBuilder->getRootNode();
|
||||
} else {
|
||||
$treeBuilder = new TreeBuilder();
|
||||
$rootNode = $treeBuilder->root('coveralls');
|
||||
}
|
||||
|
||||
$rootNode
|
||||
->children()
|
||||
// same as ruby lib
|
||||
->scalarNode('entry_point')
|
||||
->defaultValue('https://coveralls.io')
|
||||
->end()
|
||||
->scalarNode('repo_token')
|
||||
->defaultNull()
|
||||
->end()
|
||||
->scalarNode('repo_secret_token')
|
||||
->defaultNull()
|
||||
->end()
|
||||
->scalarNode('service_name')
|
||||
->defaultNull()
|
||||
->end()
|
||||
->variableNode('coverage_clover')
|
||||
->defaultValue('build/logs/clover.xml')
|
||||
->end()
|
||||
->scalarNode('json_path')
|
||||
->defaultValue('build/logs/coveralls-upload.json')
|
||||
->end()
|
||||
->booleanNode('exclude_no_stmt')
|
||||
->defaultFalse()
|
||||
->end()
|
||||
->end()
|
||||
;
|
||||
|
||||
return $treeBuilder;
|
||||
}
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Bundle\CoverallsBundle\Console;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Command\CoverallsJobsCommand;
|
||||
use Symfony\Component\Console\Application as BaseApplication;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
|
||||
/**
|
||||
* Coveralls API application.
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*/
|
||||
class Application extends BaseApplication
|
||||
{
|
||||
/**
|
||||
* Path to project root directory.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $rootDir;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $rootDir path to project root directory
|
||||
* @param string $name The name of the application
|
||||
* @param string $version The version of the application
|
||||
*/
|
||||
public function __construct($rootDir, $name = 'UNKNOWN', $version = 'UNKNOWN')
|
||||
{
|
||||
$this->rootDir = $rootDir;
|
||||
|
||||
parent::__construct($name, $version);
|
||||
}
|
||||
|
||||
// accessor
|
||||
|
||||
/**
|
||||
* @see \Symfony\Component\Console\Application::getDefinition()
|
||||
*/
|
||||
public function getDefinition()
|
||||
{
|
||||
$inputDefinition = parent::getDefinition();
|
||||
// clear out the normal first argument, which is the command name
|
||||
$inputDefinition->setArguments();
|
||||
|
||||
return $inputDefinition;
|
||||
}
|
||||
|
||||
// internal method
|
||||
|
||||
/**
|
||||
* @see \Symfony\Component\Console\Application::getCommandName()
|
||||
*/
|
||||
protected function getCommandName(InputInterface $input)
|
||||
{
|
||||
unset($input);
|
||||
|
||||
return 'coveralls:v1:jobs';
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \Symfony\Component\Console\Application::getDefaultCommands()
|
||||
*/
|
||||
protected function getDefaultCommands()
|
||||
{
|
||||
// Keep the core default commands to have the HelpCommand
|
||||
// which is used when using the --help option
|
||||
$defaultCommands = parent::getDefaultCommands();
|
||||
|
||||
$defaultCommands[] = $this->createCoverallsJobsCommand();
|
||||
|
||||
return $defaultCommands;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create CoverallsJobsCommand.
|
||||
*
|
||||
* @return \PhpCoveralls\Bundle\CoverallsBundle\Console\CoverallsJobsCommand
|
||||
*/
|
||||
protected function createCoverallsJobsCommand()
|
||||
{
|
||||
$command = new CoverallsJobsCommand();
|
||||
$command->setRootDir($this->rootDir);
|
||||
|
||||
return $command;
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Bundle\CoverallsBundle\Console;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Command\CoverallsJobsCommand;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Console\Application as CoverallsApplication;
|
||||
use Symfony\Component\Console\Application;
|
||||
use Symfony\Component\Console\SingleCommandApplication;
|
||||
|
||||
/**
|
||||
* In symfony/console 3.1 and lower provides only one way to realize single command application.
|
||||
* It is possible by extending the {@see Application}
|
||||
* Since symfony/console 6 applied strict typing which makes impossible to extending.
|
||||
* Since symfony/console 3.1 added public method setDefaultCommand()
|
||||
* Since symfony/console 3.2 method setDefaultCommand() accepts a boolean as second parameter, so we can build
|
||||
* single command application without extending.
|
||||
* But we can't rely on condition is method setDefaultCommand exists to apply new way without extending
|
||||
* Since symfony/console 5.1 introduced new class {@see SingleCommandApplication}. But we can't use that without
|
||||
* huge code duplication from the {@see CoverallsJobsCommand}.
|
||||
* Nevertheless, when SingleCommandApplication exists we can be sure - setDefaultCommand can be applied.
|
||||
*
|
||||
* @see https://symfony.com/doc/3.1/components/console/single_command_tool.html
|
||||
* @see https://symfony.com/doc/3.2/components/console/single_command_tool.html
|
||||
* @see https://symfony.com/doc/5.1/components/console/single_command_tool.html
|
||||
*
|
||||
* @author Viktor Linkin <adrenalinkin@gmail.com>
|
||||
*/
|
||||
class ApplicationFactory
|
||||
{
|
||||
const APP_NAME = 'PHP client library for Coveralls API';
|
||||
const APP_VERSION = '@package_version@';
|
||||
|
||||
/**
|
||||
* @param string $rootDir
|
||||
*
|
||||
* @return Application
|
||||
*/
|
||||
public static function create($rootDir)
|
||||
{
|
||||
$command = new CoverallsJobsCommand();
|
||||
$command->setRootDir($rootDir);
|
||||
|
||||
if (class_exists(SingleCommandApplication::class) === false) {
|
||||
$application = new CoverallsApplication(self::APP_NAME, self::APP_VERSION);
|
||||
$application->add($command);
|
||||
|
||||
return $application;
|
||||
}
|
||||
|
||||
$application = new Application(self::APP_NAME, self::APP_VERSION);
|
||||
$application->add($command);
|
||||
$application->setDefaultCommand($command->getName(), true);
|
||||
|
||||
return $application;
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Bundle\CoverallsBundle;
|
||||
|
||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
|
||||
/**
|
||||
* Coveralls bundle.
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*/
|
||||
class CoverallsBundle extends Bundle
|
||||
{
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Bundle\CoverallsBundle\Entity;
|
||||
|
||||
/**
|
||||
* Array convertable entity.
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*/
|
||||
interface ArrayConvertable
|
||||
{
|
||||
/**
|
||||
* Convert to an array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray();
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Bundle\CoverallsBundle\Entity;
|
||||
|
||||
/**
|
||||
* Data for Coveralls API.
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*/
|
||||
abstract class Coveralls implements ArrayConvertable
|
||||
{
|
||||
/**
|
||||
* String expression (convert to json).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$result = json_encode($this->toArray());
|
||||
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
$this->onJsonError();
|
||||
}
|
||||
|
||||
return (string) $result;
|
||||
}
|
||||
|
||||
protected function onJsonError()
|
||||
{
|
||||
throw new \UnexpectedValueException(sprintf(
|
||||
'Can not encode to JSON, error: "%s". If you have non-UTF8 chars, consider migration to UTF8.',
|
||||
json_last_error_msg()
|
||||
));
|
||||
}
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Bundle\CoverallsBundle\Entity\Exception;
|
||||
|
||||
/**
|
||||
* Requirements of json_file are not satisfied.
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*/
|
||||
class RequirementsNotSatisfiedException extends \RuntimeException
|
||||
{
|
||||
/**
|
||||
* Error message.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $message = 'Requirements are not satisfied.';
|
||||
|
||||
/**
|
||||
* Read environment variables.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $readEnv;
|
||||
|
||||
/**
|
||||
* Array of secret env vars.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
private static $secretEnvVars = [
|
||||
'COVERALLS_REPO_TOKEN',
|
||||
];
|
||||
|
||||
/**
|
||||
* Return help message.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getHelpMessage()
|
||||
{
|
||||
$message = $this->message . "\n";
|
||||
|
||||
if (\is_array($this->readEnv)) {
|
||||
foreach ($this->readEnv as $envVarName => $value) {
|
||||
$message .= $this->format($envVarName, $value);
|
||||
}
|
||||
}
|
||||
|
||||
$message .= <<< 'EOL'
|
||||
|
||||
Set environment variables properly like the following.
|
||||
For Travis users:
|
||||
|
||||
- TRAVIS
|
||||
- TRAVIS_BUILD_NUMBER
|
||||
- TRAVIS_JOB_ID
|
||||
|
||||
For CircleCI users:
|
||||
|
||||
- CIRCLECI
|
||||
- CIRCLE_WORKFLOW_ID
|
||||
- COVERALLS_REPO_TOKEN
|
||||
|
||||
For Jenkins users:
|
||||
|
||||
- JENKINS_URL
|
||||
- BUILD_NUMBER
|
||||
- COVERALLS_REPO_TOKEN
|
||||
|
||||
For AppVeyor users:
|
||||
|
||||
- APPVEYOR
|
||||
- APPVEYOR_BUILD_NUMBER
|
||||
|
||||
For Github Actions users:
|
||||
- GITHUB_REF
|
||||
- GITHUB_ACTIONS
|
||||
- GITHUB_RUN_ID
|
||||
- GITHUB_EVENT_NAME
|
||||
- COVERALLS_REPO_TOKEN
|
||||
|
||||
From local environment:
|
||||
|
||||
- COVERALLS_RUN_LOCALLY
|
||||
- COVERALLS_REPO_TOKEN
|
||||
|
||||
EOL;
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set read environment variables.
|
||||
*
|
||||
* @param array $readEnv read environment variables
|
||||
*/
|
||||
public function setReadEnv(array $readEnv)
|
||||
{
|
||||
$this->readEnv = $readEnv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return read environment variables.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getReadEnv()
|
||||
{
|
||||
return $this->readEnv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a pair of the envVarName and the value.
|
||||
*
|
||||
* @param string $key the env var name
|
||||
* @param string $value the value of the env var
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function format($key, $value)
|
||||
{
|
||||
if (\in_array($key, self::$secretEnvVars, true)
|
||||
&& \is_string($value)
|
||||
&& $value !== '') {
|
||||
$value = '********(HIDDEN)';
|
||||
}
|
||||
|
||||
return sprintf(" - %s=%s\n", $key, var_export($value, true));
|
||||
}
|
||||
}
|
||||
+218
@@ -0,0 +1,218 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Bundle\CoverallsBundle\Entity\Git;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\Coveralls;
|
||||
|
||||
/**
|
||||
* Commit info.
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*/
|
||||
class Commit extends Coveralls
|
||||
{
|
||||
/**
|
||||
* Commit ID.
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* Author name.
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $authorName;
|
||||
|
||||
/**
|
||||
* Author email.
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $authorEmail;
|
||||
|
||||
/**
|
||||
* Committer name.
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $committerName;
|
||||
|
||||
/**
|
||||
* Committer email.
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $committerEmail;
|
||||
|
||||
/**
|
||||
* Commit message.
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $message;
|
||||
|
||||
// API
|
||||
|
||||
/**
|
||||
* @see \PhpCoveralls\Bundle\CoverallsBundle\Entity\ArrayConvertable::toArray()
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'author_name' => $this->authorName,
|
||||
'author_email' => $this->authorEmail,
|
||||
'committer_name' => $this->committerName,
|
||||
'committer_email' => $this->committerEmail,
|
||||
'message' => $this->message,
|
||||
];
|
||||
}
|
||||
|
||||
// accessor
|
||||
|
||||
/**
|
||||
* Set commit ID.
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return \PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Commit
|
||||
*/
|
||||
public function setId($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return commit ID.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set author name.
|
||||
*
|
||||
* @param string $authorName
|
||||
*
|
||||
* @return \PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Commit
|
||||
*/
|
||||
public function setAuthorName($authorName)
|
||||
{
|
||||
$this->authorName = $authorName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return author name.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getAuthorName()
|
||||
{
|
||||
return $this->authorName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set author email.
|
||||
*
|
||||
* @param string $authorEmail
|
||||
*
|
||||
* @return \PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Commit
|
||||
*/
|
||||
public function setAuthorEmail($authorEmail)
|
||||
{
|
||||
$this->authorEmail = $authorEmail;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return author email.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getAuthorEmail()
|
||||
{
|
||||
return $this->authorEmail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set committer name.
|
||||
*
|
||||
* @param string $committerName
|
||||
*
|
||||
* @return \PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Commit
|
||||
*/
|
||||
public function setCommitterName($committerName)
|
||||
{
|
||||
$this->committerName = $committerName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return committer name.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getCommitterName()
|
||||
{
|
||||
return $this->committerName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set committer email.
|
||||
*
|
||||
* @param string $committerEmail
|
||||
*
|
||||
* @return \PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Commit
|
||||
*/
|
||||
public function setCommitterEmail($committerEmail)
|
||||
{
|
||||
$this->committerEmail = $committerEmail;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return committer email.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getCommitterEmail()
|
||||
{
|
||||
return $this->committerEmail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set commit message.
|
||||
*
|
||||
* @param string $message
|
||||
*
|
||||
* @return \PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Commit
|
||||
*/
|
||||
public function setMessage($message)
|
||||
{
|
||||
$this->message = $message;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return commit message.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getMessage()
|
||||
{
|
||||
return $this->message;
|
||||
}
|
||||
}
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Bundle\CoverallsBundle\Entity\Git;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\Coveralls;
|
||||
|
||||
/**
|
||||
* Data represents "git" of Coveralls API.
|
||||
*
|
||||
* "git": {
|
||||
* "head": {
|
||||
* "id": "b31f08d07ae564b08237e5a336e478b24ccc4a65",
|
||||
* "author_name": "Nick Merwin",
|
||||
* "author_email": "...",
|
||||
* "committer_name": "Nick Merwin",
|
||||
* "committer_email": "...",
|
||||
* "message": "version bump"
|
||||
* },
|
||||
* "branch": "master",
|
||||
* "remotes": [
|
||||
* {
|
||||
* "name": "origin",
|
||||
* "url": "git@github.com:lemurheavy/coveralls-ruby.git"
|
||||
* }
|
||||
* ]
|
||||
* }
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*/
|
||||
class Git extends Coveralls
|
||||
{
|
||||
/**
|
||||
* Branch name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $branch;
|
||||
|
||||
/**
|
||||
* Head.
|
||||
*
|
||||
* @var Commit
|
||||
*/
|
||||
protected $head;
|
||||
|
||||
/**
|
||||
* Remote.
|
||||
*
|
||||
* @var Remote[]
|
||||
*/
|
||||
protected $remotes;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $branch branch name
|
||||
* @param Commit $head hEAD commit
|
||||
* @param array $remotes remote repositories
|
||||
*/
|
||||
public function __construct($branch, Commit $head, array $remotes)
|
||||
{
|
||||
$this->branch = $branch;
|
||||
$this->head = $head;
|
||||
$this->remotes = $remotes;
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
/**
|
||||
* @see \PhpCoveralls\Bundle\CoverallsBundle\Entity\ArrayConvertable::toArray()
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
$remotes = [];
|
||||
|
||||
foreach ($this->remotes as $remote) {
|
||||
$remotes[] = $remote->toArray();
|
||||
}
|
||||
|
||||
return [
|
||||
'branch' => $this->branch,
|
||||
'head' => $this->head->toArray(),
|
||||
'remotes' => $remotes,
|
||||
];
|
||||
}
|
||||
|
||||
// accessor
|
||||
|
||||
/**
|
||||
* Return branch name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBranch()
|
||||
{
|
||||
return $this->branch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return HEAD commit.
|
||||
*
|
||||
* @return \PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Commit
|
||||
*/
|
||||
public function getHead()
|
||||
{
|
||||
return $this->head;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return remote repositories.
|
||||
*
|
||||
* @return \PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Remote[]
|
||||
*/
|
||||
public function getRemotes()
|
||||
{
|
||||
return $this->remotes;
|
||||
}
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Bundle\CoverallsBundle\Entity\Git;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\Coveralls;
|
||||
|
||||
/**
|
||||
* Remote info.
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*/
|
||||
class Remote extends Coveralls
|
||||
{
|
||||
/**
|
||||
* Remote name.
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* Remote URL.
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $url;
|
||||
|
||||
// API
|
||||
|
||||
/**
|
||||
* @see \PhpCoveralls\Bundle\CoverallsBundle\Entity\ArrayConvertable::toArray()
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return [
|
||||
'name' => $this->name,
|
||||
'url' => $this->url,
|
||||
];
|
||||
}
|
||||
|
||||
// accessor
|
||||
|
||||
/**
|
||||
* Set remote name.
|
||||
*
|
||||
* @param string $name remote name
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return remote name.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set remote URL.
|
||||
*
|
||||
* @param string $url remote URL
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setUrl($url)
|
||||
{
|
||||
$this->url = $url;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return remote URL.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
}
|
||||
+725
@@ -0,0 +1,725 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Bundle\CoverallsBundle\Entity;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\Exception\RequirementsNotSatisfiedException;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Git;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Version;
|
||||
|
||||
/**
|
||||
* Data represents "json_file" of Coveralls API.
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
|
||||
*/
|
||||
class JsonFile extends Coveralls
|
||||
{
|
||||
/**
|
||||
* Service name.
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $serviceName;
|
||||
|
||||
/**
|
||||
* Service job id.
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $serviceJobId;
|
||||
|
||||
/**
|
||||
* Service number (not documented).
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $serviceNumber;
|
||||
|
||||
/**
|
||||
* Service event type (not documented).
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $serviceEventType;
|
||||
|
||||
/**
|
||||
* Build URL of the project (not documented).
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $serviceBuildUrl;
|
||||
|
||||
/**
|
||||
* Branch name (not documented).
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $serviceBranch;
|
||||
|
||||
/**
|
||||
* Pull request info (not documented).
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $servicePullRequest;
|
||||
|
||||
/**
|
||||
* Repository token.
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $repoToken;
|
||||
|
||||
/**
|
||||
* Source files.
|
||||
*
|
||||
* @var \PhpCoveralls\Bundle\CoverallsBundle\Entity\SourceFile[]
|
||||
*/
|
||||
protected $sourceFiles = [];
|
||||
|
||||
/**
|
||||
* Git data.
|
||||
*
|
||||
* @var null|Git
|
||||
*/
|
||||
protected $git;
|
||||
|
||||
/**
|
||||
* A timestamp when the job ran. Must be parsable by Ruby.
|
||||
*
|
||||
* "2013-02-18 00:52:48 -0800"
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $runAt;
|
||||
|
||||
/**
|
||||
* Metrics.
|
||||
*
|
||||
* @var Metrics
|
||||
*/
|
||||
protected $metrics;
|
||||
|
||||
/**
|
||||
* If this is set, the build will not be considered done until a webhook has
|
||||
* been sent to https://coveralls.io/webhook?repo_token=….
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $parallel;
|
||||
|
||||
/**
|
||||
* If this is set, the job being reported will be named in the view and have
|
||||
* it’s own independent status reported to your VCS provider.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $flagName;
|
||||
|
||||
// API
|
||||
|
||||
/**
|
||||
* @see \PhpCoveralls\Bundle\CoverallsBundle\Entity\ArrayConvertable::toArray()
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
$array = [];
|
||||
|
||||
$arrayMap = [
|
||||
// json key => property name
|
||||
'service_name' => 'serviceName',
|
||||
'service_job_id' => 'serviceJobId',
|
||||
'service_number' => 'serviceNumber',
|
||||
'service_build_url' => 'serviceBuildUrl',
|
||||
'service_branch' => 'serviceBranch',
|
||||
'service_pull_request' => 'servicePullRequest',
|
||||
'service_event_type' => 'serviceEventType',
|
||||
'repo_token' => 'repoToken',
|
||||
'parallel' => 'parallel',
|
||||
'flag_name' => 'flagName',
|
||||
'git' => 'git',
|
||||
'run_at' => 'runAt',
|
||||
'source_files' => 'sourceFiles',
|
||||
];
|
||||
|
||||
foreach ($arrayMap as $jsonKey => $propName) {
|
||||
if (isset($this->$propName)) {
|
||||
$array[$jsonKey] = $this->toJsonProperty($this->$propName);
|
||||
}
|
||||
}
|
||||
|
||||
$array['environment'] = [
|
||||
'packagist_version' => Version::VERSION,
|
||||
];
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill environment variables.
|
||||
*
|
||||
* @param array $env $_SERVER environment
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function fillJobs(array $env)
|
||||
{
|
||||
return $this
|
||||
->fillStandardizedEnvVars($env)
|
||||
->ensureJobs()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exclude source files that have no executable statements.
|
||||
*/
|
||||
public function excludeNoStatementsFiles()
|
||||
{
|
||||
$this->sourceFiles = array_filter(
|
||||
$this->sourceFiles,
|
||||
function (SourceFile $sourceFile) {
|
||||
return $sourceFile->getMetrics()->hasStatements();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort source files by path.
|
||||
*/
|
||||
public function sortSourceFiles()
|
||||
{
|
||||
ksort($this->sourceFiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return line coverage.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function reportLineCoverage()
|
||||
{
|
||||
$metrics = $this->getMetrics();
|
||||
|
||||
foreach ($this->sourceFiles as $sourceFile) {
|
||||
/* @var $sourceFile \PhpCoveralls\Bundle\CoverallsBundle\Entity\SourceFile */
|
||||
$metrics->merge($sourceFile->getMetrics());
|
||||
}
|
||||
|
||||
return $metrics->getLineCoverage();
|
||||
}
|
||||
|
||||
// accessor
|
||||
|
||||
/**
|
||||
* Return whether the json file has source file.
|
||||
*
|
||||
* @param string $path absolute path to source file
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasSourceFile($path)
|
||||
{
|
||||
return isset($this->sourceFiles[$path]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return source file.
|
||||
*
|
||||
* @param string $path absolute path to source file
|
||||
*
|
||||
* @return null|\PhpCoveralls\Bundle\CoverallsBundle\Entity\SourceFile
|
||||
*/
|
||||
public function getSourceFile($path)
|
||||
{
|
||||
if ($this->hasSourceFile($path)) {
|
||||
return $this->sourceFiles[$path];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add source file.
|
||||
*/
|
||||
public function addSourceFile(SourceFile $sourceFile)
|
||||
{
|
||||
$this->sourceFiles[$sourceFile->getPath()] = $sourceFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the json file has a source file.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasSourceFiles()
|
||||
{
|
||||
return \count($this->sourceFiles) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return source files.
|
||||
*
|
||||
* @return \PhpCoveralls\Bundle\CoverallsBundle\Entity\SourceFile[]
|
||||
*/
|
||||
public function getSourceFiles()
|
||||
{
|
||||
return $this->sourceFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set service name.
|
||||
*
|
||||
* @param string $serviceName service name
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setServiceName($serviceName)
|
||||
{
|
||||
$this->serviceName = $serviceName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return service name.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getServiceName()
|
||||
{
|
||||
return $this->serviceName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set repository token.
|
||||
*
|
||||
* @param string $repoToken repository token
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setRepoToken($repoToken)
|
||||
{
|
||||
$this->repoToken = $repoToken;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return repository token.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getRepoToken()
|
||||
{
|
||||
return $this->repoToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set parallel.
|
||||
*
|
||||
* @param string $parallel parallel
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setParallel($parallel)
|
||||
{
|
||||
$this->parallel = $parallel;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return parallel.
|
||||
*
|
||||
* @return null|bool
|
||||
*/
|
||||
public function getParallel()
|
||||
{
|
||||
return $this->parallel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set flag name.
|
||||
*
|
||||
* @param string $flagName flag name
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFlagName($flagName)
|
||||
{
|
||||
$this->flagName = $flagName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return flag name.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getFlagName()
|
||||
{
|
||||
return $this->flagName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set service job id.
|
||||
*
|
||||
* @param string $serviceJobId service job id
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setServiceJobId($serviceJobId)
|
||||
{
|
||||
$this->serviceJobId = $serviceJobId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return service job id.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getServiceJobId()
|
||||
{
|
||||
return $this->serviceJobId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return service number.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServiceNumber()
|
||||
{
|
||||
return $this->serviceNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return service event type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServiceEventType()
|
||||
{
|
||||
return $this->serviceEventType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return build URL of the project.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServiceBuildUrl()
|
||||
{
|
||||
return $this->serviceBuildUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return branch name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServiceBranch()
|
||||
{
|
||||
return $this->serviceBranch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return pull request info.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServicePullRequest()
|
||||
{
|
||||
return $this->servicePullRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set git data.
|
||||
*
|
||||
* @param Git $git git data
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setGit(Git $git)
|
||||
{
|
||||
$this->git = $git;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return git data.
|
||||
*
|
||||
* @return null|Git
|
||||
*/
|
||||
public function getGit()
|
||||
{
|
||||
return $this->git;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set timestamp when the job ran.
|
||||
*
|
||||
* @param string $runAt timestamp
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setRunAt($runAt)
|
||||
{
|
||||
$this->runAt = $runAt;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return timestamp when the job ran.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getRunAt()
|
||||
{
|
||||
return $this->runAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return metrics.
|
||||
*
|
||||
* @return \PhpCoveralls\Bundle\CoverallsBundle\Entity\Metrics
|
||||
*/
|
||||
public function getMetrics()
|
||||
{
|
||||
if ($this->metrics === null) {
|
||||
$this->metrics = new Metrics();
|
||||
}
|
||||
|
||||
return $this->metrics;
|
||||
}
|
||||
|
||||
// internal method
|
||||
|
||||
/**
|
||||
* Convert to json property.
|
||||
*
|
||||
* @param mixed $prop
|
||||
*/
|
||||
protected function toJsonProperty($prop)
|
||||
{
|
||||
if ($prop instanceof Coveralls) {
|
||||
return $prop->toArray();
|
||||
}
|
||||
|
||||
if (\is_array($prop)) {
|
||||
return $this->toJsonPropertyArray($prop);
|
||||
}
|
||||
|
||||
return $prop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to array as json property.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function toJsonPropertyArray(array $propArray)
|
||||
{
|
||||
$array = [];
|
||||
|
||||
foreach ($propArray as $prop) {
|
||||
$array[] = $this->toJsonProperty($prop);
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill standardized environment variables.
|
||||
*
|
||||
* "CI_NAME", "CI_BUILD_NUMBER" must be set.
|
||||
*
|
||||
* Env vars are:
|
||||
*
|
||||
* * CI_NAME
|
||||
* * CI_BUILD_NUMBER
|
||||
* * CI_BUILD_URL
|
||||
* * CI_BRANCH
|
||||
* * CI_PULL_REQUEST
|
||||
*
|
||||
* These vars are supported by Codeship.
|
||||
*
|
||||
* @param array $env $_SERVER environment
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function fillStandardizedEnvVars(array $env)
|
||||
{
|
||||
$map = [
|
||||
// defined in Ruby lib
|
||||
'serviceName' => 'CI_NAME',
|
||||
'serviceNumber' => 'CI_BUILD_NUMBER',
|
||||
'serviceBuildUrl' => 'CI_BUILD_URL',
|
||||
'serviceBranch' => 'CI_BRANCH',
|
||||
'servicePullRequest' => 'CI_PULL_REQUEST',
|
||||
|
||||
// extends by php-coveralls
|
||||
'serviceJobId' => 'CI_JOB_ID',
|
||||
'serviceEventType' => 'COVERALLS_EVENT_TYPE',
|
||||
'repoToken' => 'COVERALLS_REPO_TOKEN',
|
||||
'parallel' => 'COVERALLS_PARALLEL',
|
||||
'flagName' => 'COVERALLS_FLAG_NAME',
|
||||
];
|
||||
|
||||
foreach ($map as $propName => $envName) {
|
||||
if (isset($env[$envName])) {
|
||||
$this->$propName = $env[$envName];
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure data consistency for jobs API.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function ensureJobs()
|
||||
{
|
||||
if (!$this->hasSourceFiles()) {
|
||||
throw new \RuntimeException('source_files must be set');
|
||||
}
|
||||
|
||||
if ($this->requireServiceJobId()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($this->requireServiceNumber()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($this->requireServiceEventType()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($this->requireRepoToken()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($this->requireGithubActions()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($this->isUnsupportedServiceJob()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
throw new RequirementsNotSatisfiedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the job requires "service_job_id" (for Travis CI).
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function requireServiceJobId()
|
||||
{
|
||||
return $this->serviceName !== null
|
||||
&& $this->serviceNumber !== null
|
||||
&& $this->serviceJobId !== null
|
||||
&& $this->repoToken === null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the job requires "service_number" (for CircleCI, Jenkins, Codeship or other CIs).
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function requireServiceNumber()
|
||||
{
|
||||
return $this->serviceName !== null
|
||||
&& $this->serviceNumber !== null
|
||||
&& $this->repoToken !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the job requires "service_event_type" (for local environment).
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function requireServiceEventType()
|
||||
{
|
||||
return $this->serviceName !== null
|
||||
&& $this->serviceEventType !== null
|
||||
&& $this->repoToken !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the job requires "repo_token" (for Travis PRO).
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function requireRepoToken()
|
||||
{
|
||||
return $this->serviceName === 'travis-pro'
|
||||
&& $this->repoToken !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the job requires "service_number", "service_job_id" and "repo_token" (for GithubActions).
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function requireGithubActions()
|
||||
{
|
||||
return $this->serviceName === 'github' && $this->serviceJobId !== null && $this->repoToken !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the job is running on unsupported service.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isUnsupportedServiceJob()
|
||||
{
|
||||
return $this->serviceJobId === null
|
||||
&& $this->serviceNumber === null
|
||||
&& $this->serviceEventType === null
|
||||
&& $this->repoToken !== null;
|
||||
}
|
||||
|
||||
protected function onJsonError()
|
||||
{
|
||||
$array = $this->toArray();
|
||||
|
||||
if (!empty($array['git'])) {
|
||||
$this->throwWhenInvalidJson($array['git'], '[git]');
|
||||
}
|
||||
|
||||
$sourceFiles = empty($array['source_files']) ? [] : $array['source_files'];
|
||||
|
||||
foreach ($sourceFiles as $item) {
|
||||
$this->throwWhenInvalidJson($item, '[source_files]: ' . $item['name']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $source
|
||||
*/
|
||||
private function throwWhenInvalidJson(array $item, $source)
|
||||
{
|
||||
json_encode($item);
|
||||
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
throw new \UnexpectedValueException(sprintf(
|
||||
'Can not encode to JSON, error: "%s" in "%s".',
|
||||
json_last_error_msg(),
|
||||
$source
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Bundle\CoverallsBundle\Entity;
|
||||
|
||||
/**
|
||||
* Metrics.
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*/
|
||||
class Metrics
|
||||
{
|
||||
/**
|
||||
* Number of statements.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $statements = 0;
|
||||
|
||||
/**
|
||||
* Number of covered statements.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $coveredStatements = 0;
|
||||
|
||||
/**
|
||||
* Line coverage.
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
protected $lineCoverage;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $coverage coverage data
|
||||
*/
|
||||
public function __construct(array $coverage = [])
|
||||
{
|
||||
// statements
|
||||
// not null
|
||||
$statementsArray = array_filter(
|
||||
$coverage,
|
||||
function ($line) {
|
||||
return $line !== null;
|
||||
}
|
||||
);
|
||||
$this->statements = \count($statementsArray);
|
||||
|
||||
// covered statements
|
||||
// gt 0
|
||||
$coveredArray = array_filter(
|
||||
$statementsArray,
|
||||
function ($line) {
|
||||
return $line > 0;
|
||||
}
|
||||
);
|
||||
$this->coveredStatements = \count($coveredArray);
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
/**
|
||||
* Merge other metrics.
|
||||
*/
|
||||
public function merge(self $that)
|
||||
{
|
||||
$this->statements += $that->statements;
|
||||
$this->coveredStatements += $that->coveredStatements;
|
||||
$this->lineCoverage = null; // clear previous data
|
||||
}
|
||||
|
||||
// accessor
|
||||
|
||||
/**
|
||||
* Return whether the source file has executable statements.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasStatements()
|
||||
{
|
||||
return $this->statements !== 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return number of statements.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getStatements()
|
||||
{
|
||||
return $this->statements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return number of covered statements.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getCoveredStatements()
|
||||
{
|
||||
return $this->coveredStatements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return line coverage.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getLineCoverage()
|
||||
{
|
||||
if ($this->lineCoverage === null) {
|
||||
$this->lineCoverage = $this->calculateLineCoverage($this->statements, $this->coveredStatements);
|
||||
}
|
||||
|
||||
return $this->lineCoverage;
|
||||
}
|
||||
|
||||
// internal method
|
||||
|
||||
/**
|
||||
* Calculate line coverage.
|
||||
*
|
||||
* @param int $statements number of statements
|
||||
* @param int $coveredStatements number of covered statements
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
protected function calculateLineCoverage($statements, $coveredStatements)
|
||||
{
|
||||
if ($statements === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ($coveredStatements / $statements) * 100;
|
||||
}
|
||||
}
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Bundle\CoverallsBundle\Entity;
|
||||
|
||||
/**
|
||||
* Data represents "source_files" element of Coveralls' "json_file".
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*/
|
||||
class SourceFile extends Coveralls
|
||||
{
|
||||
/**
|
||||
* Source filename.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* Source content.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $source;
|
||||
|
||||
/**
|
||||
* Coverage data of the source file.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $coverage;
|
||||
|
||||
/**
|
||||
* Absolute path.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* Line number of the source file.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $fileLines;
|
||||
|
||||
/**
|
||||
* Metrics.
|
||||
*
|
||||
* @var Metrics
|
||||
*/
|
||||
protected $metrics;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $path absolute path
|
||||
* @param string $name source filename
|
||||
* @param string $eol end of line
|
||||
*/
|
||||
public function __construct($path, $name, $eol = "\n")
|
||||
{
|
||||
$this->path = $path;
|
||||
$this->name = $name;
|
||||
$this->source = trim(file_get_contents($path));
|
||||
|
||||
$lines = explode($eol, $this->source);
|
||||
$this->fileLines = \count($lines);
|
||||
$this->coverage = array_fill(0, $this->fileLines, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \PhpCoveralls\Bundle\CoverallsBundle\Entity\ArrayConvertable::toArray()
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return [
|
||||
'name' => $this->name,
|
||||
'source' => $this->source,
|
||||
'coverage' => $this->coverage,
|
||||
];
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
/**
|
||||
* Add coverage.
|
||||
*
|
||||
* @param int $lineNum line number
|
||||
* @param int $count number of covered
|
||||
*/
|
||||
public function addCoverage($lineNum, $count)
|
||||
{
|
||||
if (\array_key_exists($lineNum, $this->coverage)) {
|
||||
$this->coverage[$lineNum] += $count;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return line coverage.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function reportLineCoverage()
|
||||
{
|
||||
return $this->getMetrics()->getLineCoverage();
|
||||
}
|
||||
|
||||
// accessor
|
||||
|
||||
/**
|
||||
* Return source filename.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return source content.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSource()
|
||||
{
|
||||
return $this->source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return coverage data of the source file.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCoverage()
|
||||
{
|
||||
return $this->coverage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return absolute path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return line number of the source file.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getFileLines()
|
||||
{
|
||||
return $this->fileLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return metrics.
|
||||
*
|
||||
* @return Metrics
|
||||
*/
|
||||
public function getMetrics()
|
||||
{
|
||||
if ($this->metrics === null) {
|
||||
$this->metrics = new Metrics($this->coverage);
|
||||
}
|
||||
|
||||
return $this->metrics;
|
||||
}
|
||||
}
|
||||
+290
@@ -0,0 +1,290 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Bundle\CoverallsBundle\Repository;
|
||||
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Api\Jobs;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Config\Configuration;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\JsonFile;
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Jobs API client.
|
||||
*
|
||||
* Just wrap for logging.
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*/
|
||||
class JobsRepository implements LoggerAwareInterface
|
||||
{
|
||||
/**
|
||||
* Jobs API.
|
||||
*
|
||||
* @var \PhpCoveralls\Bundle\CoverallsBundle\Api\Jobs
|
||||
*/
|
||||
protected $api;
|
||||
|
||||
/**
|
||||
* Configuration.
|
||||
*
|
||||
* @var \PhpCoveralls\Bundle\CoverallsBundle\Config\Configuration
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* Logger.
|
||||
*
|
||||
* @var \Psr\Log\LoggerInterface
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Jobs $api aPI
|
||||
* @param Configuration $config configuration
|
||||
*/
|
||||
public function __construct(Jobs $api, Configuration $config)
|
||||
{
|
||||
$this->api = $api;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
/**
|
||||
* Persist coverage data to Coveralls.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function persist()
|
||||
{
|
||||
try {
|
||||
return $this
|
||||
->collectCloverXml()
|
||||
->collectGitInfo()
|
||||
->collectEnvVars()
|
||||
->dumpJsonFile()
|
||||
->send()
|
||||
;
|
||||
} catch (\PhpCoveralls\Bundle\CoverallsBundle\Entity\Exception\RequirementsNotSatisfiedException $e) {
|
||||
$this->logger->error(sprintf('%s', $e->getHelpMessage()));
|
||||
|
||||
return false;
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error(sprintf("%s\n\n%s", $e->getMessage(), $e->getTraceAsString()));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// LoggerAwareInterface
|
||||
|
||||
/**
|
||||
* @see \Psr\Log\LoggerAwareInterface::setLogger()
|
||||
*/
|
||||
public function setLogger(LoggerInterface $logger)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
// internal method
|
||||
|
||||
/**
|
||||
* Collect clover XML into json_file.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function collectCloverXml()
|
||||
{
|
||||
$this->logger->info('Load coverage clover log:');
|
||||
|
||||
foreach ($this->config->getCloverXmlPaths() as $path) {
|
||||
$this->logger->info(sprintf(' - %s', $path));
|
||||
}
|
||||
|
||||
$jsonFile = $this->api->collectCloverXml()->getJsonFile();
|
||||
|
||||
if ($jsonFile->hasSourceFiles()) {
|
||||
$this->logCollectedSourceFiles($jsonFile);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect git repository info into json_file.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function collectGitInfo()
|
||||
{
|
||||
$this->logger->info('Collect git info');
|
||||
|
||||
$this->api->collectGitInfo();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect environment variables.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function collectEnvVars()
|
||||
{
|
||||
$this->logger->info('Read environment variables');
|
||||
|
||||
$this->api->collectEnvVars($_SERVER);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump submitting json file.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function dumpJsonFile()
|
||||
{
|
||||
$jsonPath = $this->config->getJsonPath();
|
||||
$this->logger->info(sprintf('Dump submitting json file: %s', $jsonPath));
|
||||
|
||||
$this->api->dumpJsonFile();
|
||||
|
||||
$filesize = 0;
|
||||
if (\is_string($jsonPath) && file_exists($jsonPath)) {
|
||||
$filesize = number_format(filesize($jsonPath) / 1024, 2); // kB
|
||||
}
|
||||
$this->logger->info(sprintf('File size: <info>%s</info> kB', $filesize));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send json_file to Jobs API.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function send()
|
||||
{
|
||||
$this->logger->info(sprintf('Submitting to %s', $this->config->getEntryPoint() . Jobs::URL));
|
||||
|
||||
try {
|
||||
$response = $this->api->send();
|
||||
$message = $response
|
||||
? sprintf('Finish submitting. status: %s %s', $response->getStatusCode(), $response->getReasonPhrase())
|
||||
: 'Finish dry run';
|
||||
|
||||
$this->logger->info($message);
|
||||
|
||||
if ($response instanceof Response) {
|
||||
$this->logResponse($response);
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (\GuzzleHttp\Exception\ConnectException $e) {
|
||||
// connection error
|
||||
$message = sprintf("Connection error occurred. %s\n\n%s", $e->getMessage(), $e->getTraceAsString());
|
||||
} catch (\GuzzleHttp\Exception\ClientException $e) {
|
||||
// 422 Unprocessable Entity
|
||||
$response = $e->getResponse();
|
||||
$message = sprintf('Client error occurred. status: %s %s', $response->getStatusCode(), $response->getReasonPhrase());
|
||||
} catch (\GuzzleHttp\Exception\ServerException $e) {
|
||||
// 500 Internal Server Error
|
||||
// 503 Service Unavailable
|
||||
$response = $e->getResponse();
|
||||
$message = sprintf('Server error occurred. status: %s %s', $response->getStatusCode(), $response->getReasonPhrase());
|
||||
}
|
||||
|
||||
$this->logger->error($message);
|
||||
|
||||
if (isset($response)) {
|
||||
$this->logResponse($response);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// logging
|
||||
|
||||
/**
|
||||
* Colorize coverage.
|
||||
*
|
||||
* * green 90% - 100% <info>
|
||||
* * yellow 80% - 90% <comment>
|
||||
* * red 0% - 80% <fg=red>
|
||||
*
|
||||
* @param float $coverage coverage
|
||||
* @param string $format format string to colorize
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function colorizeCoverage($coverage, $format)
|
||||
{
|
||||
if ($coverage >= 90) {
|
||||
return sprintf('<info>%s</info>', $format);
|
||||
}
|
||||
|
||||
if ($coverage >= 80) {
|
||||
return sprintf('<comment>%s</comment>', $format);
|
||||
}
|
||||
|
||||
return sprintf('<fg=red>%s</fg=red>', $format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log collected source files.
|
||||
*
|
||||
* @param JsonFile $jsonFile json file
|
||||
*/
|
||||
protected function logCollectedSourceFiles(JsonFile $jsonFile)
|
||||
{
|
||||
$sourceFiles = $jsonFile->getSourceFiles();
|
||||
$numFiles = \count($sourceFiles);
|
||||
|
||||
$this->logger->info(sprintf('Found <info>%s</info> source file%s:', number_format($numFiles), $numFiles > 1 ? 's' : ''));
|
||||
|
||||
foreach ($sourceFiles as $sourceFile) {
|
||||
/** @var \PhpCoveralls\Bundle\CoverallsBundle\Entity\SourceFile $sourceFile */
|
||||
$coverage = $sourceFile->reportLineCoverage();
|
||||
$template = ' - ' . $this->colorizeCoverage($coverage, '%6.2f%%') . ' %s';
|
||||
|
||||
$this->logger->info(sprintf($template, $coverage, $sourceFile->getName()));
|
||||
}
|
||||
|
||||
$coverage = $jsonFile->reportLineCoverage();
|
||||
$template = 'Coverage: ' . $this->colorizeCoverage($coverage, '%6.2f%% (%d/%d)');
|
||||
$metrics = $jsonFile->getMetrics();
|
||||
|
||||
$this->logger->info(sprintf($template, $coverage, $metrics->getCoveredStatements(), $metrics->getStatements()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Log response.
|
||||
*
|
||||
* @param Response $response aPI response
|
||||
*/
|
||||
protected function logResponse(Response $response)
|
||||
{
|
||||
$raw_body = (string) $response->getBody();
|
||||
$body = json_decode($raw_body, true);
|
||||
if ($body === null) {
|
||||
// the response body is not in JSON format
|
||||
$this->logger->error($raw_body);
|
||||
} elseif (isset($body['error'])) {
|
||||
if (isset($body['message'])) {
|
||||
$this->logger->error($body['message']);
|
||||
}
|
||||
} else {
|
||||
if (isset($body['message'])) {
|
||||
$this->logger->info(sprintf('Accepted %s', $body['message']));
|
||||
}
|
||||
|
||||
if (isset($body['url'])) {
|
||||
$this->logger->info(sprintf('You can see the build on %s', $body['url']));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Bundle\CoverallsBundle;
|
||||
|
||||
/**
|
||||
* CoverallsBundle version.
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*/
|
||||
final class Version
|
||||
{
|
||||
/**
|
||||
* CoverallsBundle version.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const VERSION = '2.6.0';
|
||||
}
|
||||
Vendored
+185
@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Component\File;
|
||||
|
||||
/**
|
||||
* Path utils.
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*/
|
||||
class Path
|
||||
{
|
||||
/**
|
||||
* Return whether the path is relative path.
|
||||
*
|
||||
* @param string $path path
|
||||
*
|
||||
* @return bool true if the path is relative path, false otherwise
|
||||
*/
|
||||
public function isRelativePath($path)
|
||||
{
|
||||
if ($path === '') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
||||
return !preg_match('/^[a-z]+\:\\\\/i', $path);
|
||||
}
|
||||
|
||||
return strpos($path, \DIRECTORY_SEPARATOR) !== 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cat file path.
|
||||
*
|
||||
* @param string $path file path
|
||||
* @param string $rootDir absolute path to project root directory
|
||||
*
|
||||
* @return false|string absolute path
|
||||
*/
|
||||
public function toAbsolutePath($path, $rootDir)
|
||||
{
|
||||
if (!\is_string($path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->isRelativePath($path)) {
|
||||
return $rootDir . \DIRECTORY_SEPARATOR . $path;
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return real file path.
|
||||
*
|
||||
* @param string $path file path
|
||||
* @param string $rootDir absolute path to project root directory
|
||||
*
|
||||
* @return false|string real path string if the path string is passed and real path exists, false otherwise
|
||||
*/
|
||||
public function getRealPath($path, $rootDir)
|
||||
{
|
||||
if (!\is_string($path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->isRelativePath($path)) {
|
||||
return realpath($rootDir . \DIRECTORY_SEPARATOR . $path);
|
||||
}
|
||||
|
||||
return realpath($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return real directory path.
|
||||
*
|
||||
* @param string $path path
|
||||
* @param string $rootDir absolute path to project root directory
|
||||
*
|
||||
* @return false|string real directory path string if the path string is passed and real directory exists, false otherwise
|
||||
*/
|
||||
public function getRealDir($path, $rootDir)
|
||||
{
|
||||
if (!\is_string($path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->isRelativePath($path)) {
|
||||
return realpath($rootDir . \DIRECTORY_SEPARATOR . \dirname($path));
|
||||
}
|
||||
|
||||
return realpath(\dirname($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return real file path to write.
|
||||
*
|
||||
* @param string $path file path
|
||||
* @param string $rootDir absolute path to project root directory
|
||||
*
|
||||
* @return false|string real file path string if the parent directory exists, false otherwise
|
||||
*/
|
||||
public function getRealWritingFilePath($path, $rootDir)
|
||||
{
|
||||
$realDir = $this->getRealDir($path, $rootDir);
|
||||
|
||||
if (!\is_string($realDir)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $realDir . \DIRECTORY_SEPARATOR . basename($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the real path exists.
|
||||
*
|
||||
* @param bool|string $realpath real path
|
||||
*
|
||||
* @return bool true if the real path exists, false otherwise
|
||||
*/
|
||||
public function isRealPathExist($realpath)
|
||||
{
|
||||
return $realpath !== false && file_exists($realpath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the real file path exists.
|
||||
*
|
||||
* @param bool|string $realpath real file path
|
||||
*
|
||||
* @return bool true if the real file path exists, false otherwise
|
||||
*/
|
||||
public function isRealFileExist($realpath)
|
||||
{
|
||||
return $this->isRealPathExist($realpath) && is_file($realpath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the real file path is readable.
|
||||
*
|
||||
* @param bool|string $realpath real file path
|
||||
*
|
||||
* @return bool true if the real file path is readable, false otherwise
|
||||
*/
|
||||
public function isRealFileReadable($realpath)
|
||||
{
|
||||
return $this->isRealFileExist($realpath) && is_readable($realpath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the real file path is writable.
|
||||
*
|
||||
* @param bool|string $realpath real file path
|
||||
*
|
||||
* @return bool true if the real file path is writable, false otherwise
|
||||
*/
|
||||
public function isRealFileWritable($realpath)
|
||||
{
|
||||
return $this->isRealFileExist($realpath) && is_writable($realpath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the real directory exists.
|
||||
*
|
||||
* @param bool|string $realpath real directory path
|
||||
*
|
||||
* @return bool true if the real directory exists, false otherwise
|
||||
*/
|
||||
public function isRealDirExist($realpath)
|
||||
{
|
||||
return $this->isRealPathExist($realpath) && is_dir($realpath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the real directory is writable.
|
||||
*
|
||||
* @param bool|string $realpath real directory path
|
||||
*
|
||||
* @return bool true if the real directory is writable, false otherwise
|
||||
*/
|
||||
public function isRealDirWritable($realpath)
|
||||
{
|
||||
return $this->isRealDirExist($realpath) && is_writable($realpath);
|
||||
}
|
||||
}
|
||||
Vendored
+42
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Component\Log;
|
||||
|
||||
use Psr\Log\AbstractLogger;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Console logger for php-coveralls command.
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*/
|
||||
class ConsoleLogger extends AbstractLogger
|
||||
{
|
||||
/**
|
||||
* Output.
|
||||
*
|
||||
* @var \Symfony\Component\Console\Output\OutputInterface
|
||||
*/
|
||||
protected $output;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct(OutputInterface $output)
|
||||
{
|
||||
$this->output = $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \Psr\Log\LoggerInterface::log()
|
||||
*
|
||||
* @param mixed $level
|
||||
* @param mixed $message
|
||||
*/
|
||||
public function log($level, $message, array $context = [])
|
||||
{
|
||||
unset($level, $context);
|
||||
|
||||
$this->output->writeln($message);
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Component\System\Git;
|
||||
|
||||
use PhpCoveralls\Component\System\SystemCommandExecutor;
|
||||
use PhpCoveralls\Component\System\SystemCommandExecutorInterface;
|
||||
|
||||
/**
|
||||
* Git command.
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*/
|
||||
class GitCommand
|
||||
{
|
||||
/**
|
||||
* @var SystemCommandExecutorInterface
|
||||
*/
|
||||
private $executor;
|
||||
|
||||
public function __construct(SystemCommandExecutorInterface $executor = null)
|
||||
{
|
||||
$this->executor = $executor ? $executor : new SystemCommandExecutor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return branch names.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getBranches()
|
||||
{
|
||||
return $this->executor->execute('git branch');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return HEAD commit.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getHeadCommit()
|
||||
{
|
||||
return $this->executor->execute("git log -1 --pretty=format:'%H%n%aN%n%ae%n%cN%n%ce%n%s'");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return remote repositories.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getRemotes()
|
||||
{
|
||||
return $this->executor->execute('git remote -v');
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Component\System;
|
||||
|
||||
/**
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
* @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class SystemCommandExecutor implements SystemCommandExecutorInterface
|
||||
{
|
||||
/**
|
||||
* Execute command.
|
||||
*
|
||||
* @param string $command
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function execute($command)
|
||||
{
|
||||
exec($command, $result, $returnValue);
|
||||
|
||||
if ($returnValue === 0) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
throw new \RuntimeException(sprintf('Failed to execute command: %s', $command), $returnValue);
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Component\System;
|
||||
|
||||
/**
|
||||
* @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
interface SystemCommandExecutorInterface
|
||||
{
|
||||
/**
|
||||
* Execute command.
|
||||
*
|
||||
* @param string $command
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function execute($command);
|
||||
}
|
||||
+736
@@ -0,0 +1,736 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Tests\Bundle\CoverallsBundle\Api;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Psr7;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Api\Jobs;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Collector\CiEnvVarsCollector;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Collector\CloverXmlCoverageCollector;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Config\Configuration;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\JsonFile;
|
||||
use PhpCoveralls\Tests\ProjectTestCase;
|
||||
|
||||
/**
|
||||
* @covers \PhpCoveralls\Bundle\CoverallsBundle\Api\CoverallsApi
|
||||
* @covers \PhpCoveralls\Bundle\CoverallsBundle\Api\Jobs
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class JobsTest extends ProjectTestCase
|
||||
{
|
||||
// getJsonFile()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveJsonFileOnConstruction()
|
||||
{
|
||||
$object = $this->createJobsNeverSendOnDryRun();
|
||||
|
||||
self::assertNull($object->getJsonFile());
|
||||
}
|
||||
|
||||
// setJsonFile()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetJsonFile()
|
||||
{
|
||||
$jsonFile = $this->collectJsonFile();
|
||||
|
||||
$object = $this->createJobsNeverSendOnDryRun()->setJsonFile($jsonFile);
|
||||
|
||||
self::assertSame($jsonFile, $object->getJsonFile());
|
||||
}
|
||||
|
||||
// getConfiguration()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldReturnConfiguration()
|
||||
{
|
||||
$config = $this->createConfiguration();
|
||||
|
||||
$object = new Jobs($config);
|
||||
|
||||
self::assertSame($config, $object->getConfiguration());
|
||||
}
|
||||
|
||||
// getHttpClient()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveHttpClientOnConstructionWithoutHttpClient()
|
||||
{
|
||||
$config = $this->createConfiguration();
|
||||
|
||||
$object = new Jobs($config);
|
||||
|
||||
self::assertNull($object->getHttpClient());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldHaveHttpClientOnConstructionWithHttpClient()
|
||||
{
|
||||
$config = $this->createConfiguration();
|
||||
$client = $this->createAdapterMockNeverCalled();
|
||||
|
||||
$object = new Jobs($config, $client);
|
||||
|
||||
self::assertSame($client, $object->getHttpClient());
|
||||
}
|
||||
|
||||
// setHttpClient()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetHttpClient()
|
||||
{
|
||||
$config = $this->createConfiguration();
|
||||
$client = $this->createAdapterMockNeverCalled();
|
||||
|
||||
$object = new Jobs($config);
|
||||
$object->setHttpClient($client);
|
||||
|
||||
self::assertSame($client, $object->getHttpClient());
|
||||
}
|
||||
|
||||
// collectCloverXml()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldCollectCloverXml()
|
||||
{
|
||||
$this->makeProjectDir(null, $this->logsDir);
|
||||
$xml = $this->getCloverXml();
|
||||
|
||||
file_put_contents($this->cloverXmlPath, $xml);
|
||||
|
||||
$config = $this->createConfiguration();
|
||||
|
||||
$object = new Jobs($config);
|
||||
|
||||
$same = $object->collectCloverXml();
|
||||
|
||||
// return $this
|
||||
self::assertSame($same, $object);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldCollectCloverXml
|
||||
*
|
||||
* @return JsonFile
|
||||
*/
|
||||
public function shouldHaveJsonFileAfterCollectCloverXml(Jobs $object)
|
||||
{
|
||||
$jsonFile = $object->getJsonFile();
|
||||
|
||||
self::assertNotNull($jsonFile);
|
||||
$sourceFiles = $jsonFile->getSourceFiles();
|
||||
self::assertCount(4, $sourceFiles);
|
||||
|
||||
return $jsonFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldHaveJsonFileAfterCollectCloverXml
|
||||
*/
|
||||
public function shouldNotHaveGitAfterCollectCloverXml(JsonFile $jsonFile)
|
||||
{
|
||||
$git = $jsonFile->getGit();
|
||||
|
||||
self::assertNull($git);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldCollectCloverXmlExcludingNoStatementsFiles()
|
||||
{
|
||||
$this->makeProjectDir(null, $this->logsDir);
|
||||
$xml = $this->getCloverXml();
|
||||
|
||||
file_put_contents($this->cloverXmlPath, $xml);
|
||||
|
||||
$config = $this->createConfiguration()->setExcludeNoStatements(true);
|
||||
|
||||
$object = new Jobs($config);
|
||||
|
||||
$same = $object->collectCloverXml();
|
||||
|
||||
// return $this
|
||||
self::assertSame($same, $object);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldCollectCloverXmlExcludingNoStatementsFiles
|
||||
*
|
||||
* @return JsonFile
|
||||
*/
|
||||
public function shouldHaveJsonFileAfterCollectCloverXmlExcludingNoStatementsFiles(Jobs $object)
|
||||
{
|
||||
$jsonFile = $object->getJsonFile();
|
||||
|
||||
self::assertNotNull($jsonFile);
|
||||
$sourceFiles = $jsonFile->getSourceFiles();
|
||||
self::assertCount(2, $sourceFiles);
|
||||
|
||||
return $jsonFile;
|
||||
}
|
||||
|
||||
// collectGitInfo()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldCollectCloverXml
|
||||
*
|
||||
* @return Jobs
|
||||
*/
|
||||
public function shouldCollectGitInfo(Jobs $object)
|
||||
{
|
||||
$same = $object->collectGitInfo();
|
||||
|
||||
// return $this
|
||||
self::assertSame($same, $object);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldCollectGitInfo
|
||||
*
|
||||
* @return JsonFile
|
||||
*/
|
||||
public function shouldHaveJsonFileAfterCollectGitInfo(Jobs $object)
|
||||
{
|
||||
$jsonFile = $object->getJsonFile();
|
||||
|
||||
self::assertNotNull($jsonFile);
|
||||
|
||||
return $jsonFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldHaveJsonFileAfterCollectGitInfo
|
||||
*/
|
||||
public function shouldHaveGitAfterCollectGitInfo(JsonFile $jsonFile)
|
||||
{
|
||||
$git = $jsonFile->getGit();
|
||||
|
||||
self::assertNotNull($git);
|
||||
}
|
||||
|
||||
// send()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSendTravisCiJob()
|
||||
{
|
||||
$this->makeProjectDir(null, $this->logsDir);
|
||||
|
||||
$serviceJobId = '1.1';
|
||||
|
||||
$server = [];
|
||||
$server['TRAVIS'] = true;
|
||||
$server['TRAVIS_BUILD_NUMBER'] = '654321';
|
||||
$server['TRAVIS_JOB_ID'] = $serviceJobId;
|
||||
|
||||
$object = $this->createJobsWith();
|
||||
$jsonFile = $this->collectJsonFile();
|
||||
|
||||
$object
|
||||
->setJsonFile($jsonFile)
|
||||
->collectEnvVars($server)
|
||||
->dumpJsonFile()
|
||||
->send()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSendTravisProJob()
|
||||
{
|
||||
$this->makeProjectDir(null, $this->logsDir);
|
||||
|
||||
$serviceName = 'travis-pro';
|
||||
$serviceJobId = '1.1';
|
||||
$repoToken = 'your_token';
|
||||
|
||||
$server = [];
|
||||
$server['TRAVIS'] = true;
|
||||
$server['TRAVIS_BUILD_NUMBER'] = '8888';
|
||||
$server['TRAVIS_JOB_ID'] = $serviceJobId;
|
||||
$server['COVERALLS_REPO_TOKEN'] = $repoToken;
|
||||
|
||||
$object = $this->createJobsWith();
|
||||
$object->getConfiguration()->setServiceName($serviceName);
|
||||
$jsonFile = $this->collectJsonFile();
|
||||
|
||||
$object
|
||||
->setJsonFile($jsonFile)
|
||||
->collectEnvVars($server)
|
||||
->dumpJsonFile()
|
||||
->send()
|
||||
;
|
||||
|
||||
self::assertSame($serviceName, $jsonFile->getServiceName());
|
||||
self::assertSame($serviceJobId, $jsonFile->getServiceJobId());
|
||||
self::assertSame($repoToken, $jsonFile->getRepoToken());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSendCircleCiJob()
|
||||
{
|
||||
$this->makeProjectDir(null, $this->logsDir);
|
||||
|
||||
$serviceNumber = '123';
|
||||
$repoToken = 'token';
|
||||
|
||||
$server = [];
|
||||
$server['COVERALLS_REPO_TOKEN'] = $repoToken;
|
||||
$server['CIRCLECI'] = 'true';
|
||||
$server['CIRCLE_WORKFLOW_ID'] = $serviceNumber;
|
||||
|
||||
$object = $this->createJobsWith();
|
||||
$jsonFile = $this->collectJsonFile();
|
||||
|
||||
$object
|
||||
->setJsonFile($jsonFile)
|
||||
->collectEnvVars($server)
|
||||
->dumpJsonFile()
|
||||
->send()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSendJenkinsJob()
|
||||
{
|
||||
$this->makeProjectDir(null, $this->logsDir);
|
||||
|
||||
$serviceNumber = '123';
|
||||
$repoToken = 'token';
|
||||
|
||||
$server = [];
|
||||
$server['COVERALLS_REPO_TOKEN'] = $repoToken;
|
||||
$server['JENKINS_URL'] = 'http://localhost:8080';
|
||||
$server['BUILD_NUMBER'] = $serviceNumber;
|
||||
|
||||
$object = $this->createJobsWith();
|
||||
$jsonFile = $this->collectJsonFile();
|
||||
|
||||
$object
|
||||
->setJsonFile($jsonFile)
|
||||
->collectEnvVars($server)
|
||||
->dumpJsonFile()
|
||||
->send()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSendLocalJob()
|
||||
{
|
||||
$this->makeProjectDir(null, $this->logsDir);
|
||||
|
||||
$server = [];
|
||||
$server['COVERALLS_RUN_LOCALLY'] = '1';
|
||||
|
||||
$object = $this->createJobsWith();
|
||||
$object->getConfiguration()->setRepoToken('token');
|
||||
$jsonFile = $this->collectJsonFile();
|
||||
|
||||
$object
|
||||
->setJsonFile($jsonFile)
|
||||
->collectEnvVars($server)
|
||||
->dumpJsonFile()
|
||||
->send()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSendUnsupportedJob()
|
||||
{
|
||||
$this->makeProjectDir(null, $this->logsDir);
|
||||
|
||||
$server = [];
|
||||
$server['COVERALLS_REPO_TOKEN'] = 'token';
|
||||
|
||||
$object = $this->createJobsWith();
|
||||
$jsonFile = $this->collectJsonFile();
|
||||
|
||||
$object
|
||||
->setJsonFile($jsonFile)
|
||||
->collectEnvVars($server)
|
||||
->dumpJsonFile()
|
||||
->send()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSendUnsupportedGitJob()
|
||||
{
|
||||
$this->makeProjectDir(null, $this->logsDir);
|
||||
|
||||
$server = [];
|
||||
$server['COVERALLS_REPO_TOKEN'] = 'token';
|
||||
$server['GIT_COMMIT'] = 'abc123';
|
||||
|
||||
$object = $this->createJobsWith();
|
||||
$jsonFile = $this->collectJsonFile();
|
||||
|
||||
$object
|
||||
->setJsonFile($jsonFile)
|
||||
->collectEnvVars($server)
|
||||
->dumpJsonFile()
|
||||
->send()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotSendJobIfTestEnv()
|
||||
{
|
||||
$this->makeProjectDir(null, $this->logsDir);
|
||||
|
||||
$server = [];
|
||||
$server['TRAVIS'] = true;
|
||||
$server['TRAVIS_BUILD_NUMBER'] = '198765';
|
||||
$server['TRAVIS_JOB_ID'] = '1.1';
|
||||
|
||||
$object = $this->createJobsNeverSendOnDryRun();
|
||||
$object->getConfiguration()->setEnv('test');
|
||||
$jsonFile = $this->collectJsonFile();
|
||||
|
||||
$object
|
||||
->setJsonFile($jsonFile)
|
||||
->collectEnvVars($server)
|
||||
->dumpJsonFile()
|
||||
->send()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function throwRuntimeExceptionIfInvalidEnv()
|
||||
{
|
||||
$this->expectException(\RuntimeException::class);
|
||||
|
||||
$server = [];
|
||||
|
||||
$object = $this->createJobsNeverSend();
|
||||
$jsonFile = $this->collectJsonFile();
|
||||
|
||||
$object
|
||||
->setJsonFile($jsonFile)
|
||||
->collectEnvVars($server)
|
||||
->dumpJsonFile()
|
||||
->send()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function throwRuntimeExceptionIfNoSourceFiles()
|
||||
{
|
||||
$this->expectException(\RuntimeException::class);
|
||||
|
||||
$server = [];
|
||||
$server['TRAVIS'] = true;
|
||||
$server['TRAVIS_BUILD_NUMBER'] = '12345';
|
||||
$server['TRAVIS_JOB_ID'] = '1.1';
|
||||
$server['GIT_COMMIT'] = 'abc123';
|
||||
|
||||
$object = $this->createJobsNeverSend();
|
||||
$jsonFile = $this->collectJsonFileWithoutSourceFiles();
|
||||
|
||||
$object
|
||||
->setJsonFile($jsonFile)
|
||||
->collectEnvVars($server)
|
||||
->dumpJsonFile()
|
||||
->send()
|
||||
;
|
||||
}
|
||||
|
||||
protected function legacySetUp()
|
||||
{
|
||||
$this->setUpDir(realpath(__DIR__ . '/../../..'));
|
||||
}
|
||||
|
||||
protected function legacyTearDown()
|
||||
{
|
||||
$this->rmFile($this->jsonPath);
|
||||
$this->rmFile($this->cloverXmlPath);
|
||||
$this->rmDir($this->logsDir);
|
||||
$this->rmDir($this->buildDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Jobs
|
||||
*/
|
||||
protected function createJobsWith()
|
||||
{
|
||||
$config = new Configuration();
|
||||
|
||||
$config
|
||||
->setEntryPoint('https://coveralls.io')
|
||||
->setJsonPath($this->jsonPath)
|
||||
->setDryRun(false)
|
||||
;
|
||||
|
||||
$client = $this->createAdapterMockWith($this->url, $this->filename);
|
||||
|
||||
return new Jobs($config, $client);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Jobs
|
||||
*/
|
||||
protected function createJobsNeverSend()
|
||||
{
|
||||
$config = new Configuration();
|
||||
$config
|
||||
->setEntryPoint('https://coveralls.io')
|
||||
->setJsonPath($this->jsonPath)
|
||||
->setDryRun(false)
|
||||
;
|
||||
|
||||
$client = $this->createAdapterMockNeverCalled();
|
||||
|
||||
return new Jobs($config, $client);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Jobs
|
||||
*/
|
||||
protected function createJobsNeverSendOnDryRun()
|
||||
{
|
||||
$config = new Configuration();
|
||||
$config
|
||||
->setEntryPoint('https://coveralls.io')
|
||||
->setJsonPath($this->jsonPath)
|
||||
->setDryRun(true)
|
||||
;
|
||||
|
||||
$client = $this->createAdapterMockNeverCalled();
|
||||
|
||||
return new Jobs($config, $client);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Client
|
||||
*/
|
||||
protected function createAdapterMockNeverCalled()
|
||||
{
|
||||
$client = $this->prophesize(Client::class);
|
||||
$client
|
||||
->send()
|
||||
->shouldNotBeCalled()
|
||||
;
|
||||
|
||||
return $client->reveal();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param string $filename
|
||||
*
|
||||
* @return Client
|
||||
*/
|
||||
protected function createAdapterMockWith($url, $filename)
|
||||
{
|
||||
$response = $this->prophesize(Psr7\Response::class);
|
||||
$response->reveal();
|
||||
|
||||
$client = $this->prophesize(Client::class);
|
||||
$client
|
||||
->post($url, \Prophecy\Argument::that(function ($options) use ($filename) {
|
||||
return !empty($options['multipart'][0]['name'])
|
||||
&& !empty($options['multipart'][0]['contents'])
|
||||
&& $filename === $options['multipart'][0]['name']
|
||||
&& \is_string($options['multipart'][0]['contents']);
|
||||
}))
|
||||
->willReturn($response)
|
||||
->shouldBeCalled()
|
||||
;
|
||||
|
||||
return $client->reveal();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Configuration
|
||||
*/
|
||||
protected function createConfiguration()
|
||||
{
|
||||
$config = new Configuration();
|
||||
$config->setRootDir('');
|
||||
|
||||
return $config->addCloverXmlPath($this->cloverXmlPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getCloverXml()
|
||||
{
|
||||
$xml = <<<'XML'
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<coverage generated="1365848893">
|
||||
<project timestamp="1365848893">
|
||||
<file name="%s/test.php">
|
||||
<class name="TestFile" namespace="global">
|
||||
<metrics methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="1" coveredstatements="0" elements="2" coveredelements="0"/>
|
||||
</class>
|
||||
<line num="5" type="method" name="__construct" crap="1" count="0"/>
|
||||
<line num="7" type="stmt" count="0"/>
|
||||
</file>
|
||||
<file name="%s/TestInterface.php">
|
||||
<class name="TestInterface" namespace="global">
|
||||
<metrics methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="0" coveredstatements="0" elements="1" coveredelements="0"/>
|
||||
</class>
|
||||
<line num="5" type="method" name="hello" crap="1" count="0"/>
|
||||
</file>
|
||||
<file name="%s/AbstractClass.php">
|
||||
<class name="AbstractClass" namespace="global">
|
||||
<metrics methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="0" coveredstatements="0" elements="1" coveredelements="0"/>
|
||||
</class>
|
||||
<line num="5" type="method" name="hello" crap="1" count="0"/>
|
||||
</file>
|
||||
<file name="dummy.php">
|
||||
<class name="TestFile" namespace="global">
|
||||
<metrics methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="1" coveredstatements="0" elements="2" coveredelements="0"/>
|
||||
</class>
|
||||
<line num="5" type="method" name="__construct" crap="1" count="0"/>
|
||||
<line num="7" type="stmt" count="0"/>
|
||||
</file>
|
||||
<package name="Hoge">
|
||||
<file name="%s/test2.php">
|
||||
<class name="TestFile" namespace="Hoge">
|
||||
<metrics methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="1" coveredstatements="0" elements="2" coveredelements="0"/>
|
||||
</class>
|
||||
<line num="6" type="method" name="__construct" crap="1" count="0"/>
|
||||
<line num="8" type="stmt" count="0"/>
|
||||
</file>
|
||||
</package>
|
||||
</project>
|
||||
</coverage>
|
||||
XML;
|
||||
|
||||
return sprintf($xml, $this->srcDir, $this->srcDir, $this->srcDir, $this->srcDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \SimpleXMLElement
|
||||
*/
|
||||
protected function createCloverXml()
|
||||
{
|
||||
$xml = $this->getCloverXml();
|
||||
|
||||
return simplexml_load_string($xml);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getNoSourceCloverXml()
|
||||
{
|
||||
return <<<'XML'
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<coverage generated="1365848893">
|
||||
<project timestamp="1365848893">
|
||||
<file name="dummy.php">
|
||||
<class name="TestFile" namespace="global">
|
||||
<metrics methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="1" coveredstatements="0" elements="2" coveredelements="0"/>
|
||||
</class>
|
||||
<line num="5" type="method" name="__construct" crap="1" count="0"/>
|
||||
<line num="7" type="stmt" count="0"/>
|
||||
</file>
|
||||
</project>
|
||||
</coverage>
|
||||
XML;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \SimpleXMLElement
|
||||
*/
|
||||
protected function createNoSourceCloverXml()
|
||||
{
|
||||
$xml = $this->getNoSourceCloverXml();
|
||||
|
||||
return simplexml_load_string($xml);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JsonFile
|
||||
*/
|
||||
protected function collectJsonFile()
|
||||
{
|
||||
$xml = $this->createCloverXml();
|
||||
$collector = new CloverXmlCoverageCollector();
|
||||
|
||||
return $collector->collect($xml, $this->srcDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JsonFile
|
||||
*/
|
||||
protected function collectJsonFileWithoutSourceFiles()
|
||||
{
|
||||
$xml = $this->createNoSourceCloverXml();
|
||||
$collector = new CloverXmlCoverageCollector();
|
||||
|
||||
return $collector->collect($xml, $this->srcDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Configuration $config
|
||||
*
|
||||
* @return CiEnvVarsCollector
|
||||
*/
|
||||
protected function createCiEnvVarsCollector($config = null)
|
||||
{
|
||||
if ($config === null) {
|
||||
$config = $this->createConfiguration();
|
||||
}
|
||||
|
||||
return new CiEnvVarsCollector($config);
|
||||
}
|
||||
}
|
||||
+497
@@ -0,0 +1,497 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Tests\Bundle\CoverallsBundle\Collector;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Collector\CiEnvVarsCollector;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Config\Configuration;
|
||||
use PhpCoveralls\Tests\ProjectTestCase;
|
||||
|
||||
/**
|
||||
* @covers \PhpCoveralls\Bundle\CoverallsBundle\Collector\CiEnvVarsCollector
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class CiEnvVarsCollectorTest extends ProjectTestCase
|
||||
{
|
||||
// collect()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldCollectTravisCiEnvVars()
|
||||
{
|
||||
$serviceName = 'travis-ci';
|
||||
$serviceJobId = '1.1';
|
||||
$serviceBuildNumber = '123456';
|
||||
|
||||
$env = [];
|
||||
$env['TRAVIS'] = true;
|
||||
$env['TRAVIS_JOB_ID'] = $serviceJobId;
|
||||
$env['TRAVIS_BUILD_NUMBER'] = $serviceBuildNumber;
|
||||
|
||||
$object = $this->createCiEnvVarsCollector();
|
||||
|
||||
$actual = $object->collect($env);
|
||||
|
||||
self::assertArrayHasKey('CI_NAME', $actual);
|
||||
self::assertSame($serviceName, $actual['CI_NAME']);
|
||||
|
||||
self::assertArrayHasKey('CI_JOB_ID', $actual);
|
||||
self::assertSame($serviceJobId, $actual['CI_JOB_ID']);
|
||||
|
||||
self::assertArrayHasKey('CI_BUILD_NUMBER', $actual);
|
||||
self::assertSame($serviceBuildNumber, $actual['CI_BUILD_NUMBER']);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldCollectTravisProEnvVars()
|
||||
{
|
||||
$serviceName = 'travis-pro';
|
||||
$serviceJobId = '1.2';
|
||||
$serviceBuildNumber = '12345';
|
||||
$repoToken = 'your_token';
|
||||
|
||||
$env = [];
|
||||
$env['TRAVIS'] = true;
|
||||
$env['TRAVIS_JOB_ID'] = $serviceJobId;
|
||||
$env['TRAVIS_BUILD_NUMBER'] = $serviceBuildNumber;
|
||||
$env['COVERALLS_REPO_TOKEN'] = $repoToken;
|
||||
|
||||
$config = $this->createConfiguration();
|
||||
$config->setServiceName($serviceName);
|
||||
|
||||
$object = $this->createCiEnvVarsCollector($config);
|
||||
|
||||
$actual = $object->collect($env);
|
||||
|
||||
self::assertArrayHasKey('CI_NAME', $actual);
|
||||
self::assertSame($serviceName, $actual['CI_NAME']);
|
||||
|
||||
self::assertArrayHasKey('CI_JOB_ID', $actual);
|
||||
self::assertSame($serviceJobId, $actual['CI_JOB_ID']);
|
||||
|
||||
self::assertArrayHasKey('CI_BUILD_NUMBER', $actual);
|
||||
self::assertSame($serviceBuildNumber, $actual['CI_BUILD_NUMBER']);
|
||||
|
||||
self::assertArrayHasKey('COVERALLS_REPO_TOKEN', $actual);
|
||||
self::assertSame($repoToken, $actual['COVERALLS_REPO_TOKEN']);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldCollectCircleCiEnvVars()
|
||||
{
|
||||
$serviceName = 'circleci';
|
||||
$serviceNumber = '123';
|
||||
|
||||
$env = [];
|
||||
$env['COVERALLS_REPO_TOKEN'] = 'token';
|
||||
$env['CIRCLECI'] = 'true';
|
||||
$env['CIRCLE_WORKFLOW_ID'] = $serviceNumber;
|
||||
|
||||
$object = $this->createCiEnvVarsCollector();
|
||||
|
||||
$actual = $object->collect($env);
|
||||
|
||||
self::assertArrayHasKey('CI_NAME', $actual);
|
||||
self::assertSame($serviceName, $actual['CI_NAME']);
|
||||
|
||||
self::assertArrayHasKey('CI_BUILD_NUMBER', $actual);
|
||||
self::assertSame($serviceNumber, $actual['CI_BUILD_NUMBER']);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldCollectJenkinsEnvVars()
|
||||
{
|
||||
$serviceName = 'jenkins';
|
||||
$serviceNumber = '123';
|
||||
$buildUrl = 'http://localhost:8080';
|
||||
|
||||
$env = [];
|
||||
$env['COVERALLS_REPO_TOKEN'] = 'token';
|
||||
$env['JENKINS_URL'] = $buildUrl;
|
||||
$env['BUILD_NUMBER'] = $serviceNumber;
|
||||
|
||||
$object = $this->createCiEnvVarsCollector();
|
||||
|
||||
$actual = $object->collect($env);
|
||||
|
||||
self::assertArrayHasKey('CI_NAME', $actual);
|
||||
self::assertSame($serviceName, $actual['CI_NAME']);
|
||||
|
||||
self::assertArrayHasKey('CI_BUILD_NUMBER', $actual);
|
||||
self::assertSame($serviceNumber, $actual['CI_BUILD_NUMBER']);
|
||||
|
||||
self::assertArrayHasKey('CI_BUILD_URL', $actual);
|
||||
self::assertSame($buildUrl, $actual['CI_BUILD_URL']);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldCollectGithubActionsEnvVars()
|
||||
{
|
||||
$serviceName = 'github';
|
||||
$jobId = '275038505';
|
||||
|
||||
$env = [];
|
||||
$env['COVERALLS_REPO_TOKEN'] = 'token';
|
||||
$env['GITHUB_ACTIONS'] = true;
|
||||
$env['GITHUB_EVENT_NAME'] = 'push';
|
||||
$env['GITHUB_REF'] = 'refs/heads/master';
|
||||
$env['GITHUB_RUN_ID'] = '275038505';
|
||||
|
||||
$object = $this->createCiEnvVarsCollector();
|
||||
|
||||
$actual = $object->collect($env);
|
||||
|
||||
self::assertArrayHasKey('CI_NAME', $actual);
|
||||
self::assertSame($serviceName, $actual['CI_NAME']);
|
||||
|
||||
self::assertArrayHasKey('CI_JOB_ID', $actual);
|
||||
self::assertSame($jobId, $actual['CI_JOB_ID']);
|
||||
|
||||
self::assertArrayHasKey('CI_BRANCH', $actual);
|
||||
self::assertSame('master', $actual['CI_BRANCH']);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldCollectGithubActionsEnvVarsForPullRequest()
|
||||
{
|
||||
$serviceName = 'github';
|
||||
|
||||
$env = [];
|
||||
$env['COVERALLS_REPO_TOKEN'] = 'token';
|
||||
$env['GITHUB_ACTIONS'] = true;
|
||||
$env['GITHUB_EVENT_NAME'] = 'pull_request';
|
||||
$env['GITHUB_REF'] = 'refs/pull/1/merge';
|
||||
$env['GITHUB_RUN_ID'] = '275038505';
|
||||
|
||||
$object = $this->createCiEnvVarsCollector();
|
||||
|
||||
$actual = $object->collect($env);
|
||||
|
||||
self::assertArrayHasKey('CI_NAME', $actual);
|
||||
self::assertSame($serviceName, $actual['CI_NAME']);
|
||||
|
||||
self::assertArrayHasKey('CI_JOB_ID', $actual);
|
||||
self::assertSame('275038505', $actual['CI_JOB_ID']);
|
||||
|
||||
self::assertArrayHasKey('CI_BRANCH', $actual);
|
||||
self::assertSame('refs/pull/1/merge', $actual['CI_BRANCH']);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldCollectGithubActionsEnvVarsForTag()
|
||||
{
|
||||
$serviceName = 'github';
|
||||
|
||||
$env = [];
|
||||
$env['COVERALLS_REPO_TOKEN'] = 'token';
|
||||
$env['GITHUB_ACTIONS'] = true;
|
||||
$env['GITHUB_EVENT_NAME'] = 'push';
|
||||
$env['GITHUB_REF'] = 'refs/tags/v123.456.789';
|
||||
$env['GITHUB_RUN_ID'] = '275038505';
|
||||
|
||||
$object = $this->createCiEnvVarsCollector();
|
||||
|
||||
$actual = $object->collect($env);
|
||||
|
||||
self::assertArrayHasKey('CI_NAME', $actual);
|
||||
self::assertSame($serviceName, $actual['CI_NAME']);
|
||||
|
||||
self::assertArrayHasKey('CI_JOB_ID', $actual);
|
||||
self::assertSame('275038505', $actual['CI_JOB_ID']);
|
||||
|
||||
self::assertArrayHasKey('CI_BRANCH', $actual);
|
||||
self::assertSame('v123.456.789', $actual['CI_BRANCH']);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldCollectLocalEnvVars()
|
||||
{
|
||||
$serviceName = 'php-coveralls';
|
||||
$serviceEventType = 'manual';
|
||||
|
||||
$env = [];
|
||||
$env['COVERALLS_REPO_TOKEN'] = 'token';
|
||||
$env['COVERALLS_RUN_LOCALLY'] = '1';
|
||||
|
||||
$object = $this->createCiEnvVarsCollector();
|
||||
|
||||
$actual = $object->collect($env);
|
||||
|
||||
self::assertArrayHasKey('CI_NAME', $actual);
|
||||
self::assertSame($serviceName, $actual['CI_NAME']);
|
||||
|
||||
self::assertArrayHasKey('COVERALLS_EVENT_TYPE', $actual);
|
||||
self::assertSame($serviceEventType, $actual['COVERALLS_EVENT_TYPE']);
|
||||
|
||||
self::assertArrayHasKey('CI_JOB_ID', $actual);
|
||||
self::assertNull($actual['CI_JOB_ID']);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldCollectUnsupportedConfig()
|
||||
{
|
||||
$repoToken = 'token';
|
||||
|
||||
$env = [];
|
||||
|
||||
$config = $this->createConfiguration();
|
||||
$config->setRepoToken($repoToken);
|
||||
|
||||
$object = $this->createCiEnvVarsCollector($config);
|
||||
|
||||
$actual = $object->collect($env);
|
||||
|
||||
self::assertArrayHasKey('COVERALLS_REPO_TOKEN', $actual);
|
||||
self::assertSame($repoToken, $actual['COVERALLS_REPO_TOKEN']);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldCollectUnsupportedEnvVars()
|
||||
{
|
||||
$repoToken = 'token';
|
||||
|
||||
$env = [];
|
||||
$env['COVERALLS_REPO_TOKEN'] = $repoToken;
|
||||
|
||||
$object = $this->createCiEnvVarsCollector();
|
||||
|
||||
$actual = $object->collect($env);
|
||||
|
||||
self::assertArrayHasKey('COVERALLS_REPO_TOKEN', $actual);
|
||||
self::assertSame($repoToken, $actual['COVERALLS_REPO_TOKEN']);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldCollectParallel()
|
||||
{
|
||||
$parallel = true;
|
||||
$flagName = 'php-7.4';
|
||||
|
||||
$env = [];
|
||||
$env['COVERALLS_PARALLEL'] = $parallel;
|
||||
$env['COVERALLS_FLAG_NAME'] = $flagName;
|
||||
|
||||
$object = $this->createCiEnvVarsCollector();
|
||||
|
||||
$actual = $object->collect($env);
|
||||
|
||||
self::assertArrayHasKey('COVERALLS_PARALLEL', $actual);
|
||||
self::assertSame($parallel, $actual['COVERALLS_PARALLEL']);
|
||||
|
||||
self::assertArrayHasKey('COVERALLS_FLAG_NAME', $actual);
|
||||
self::assertSame($flagName, $actual['COVERALLS_FLAG_NAME']);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
// getReadEnv()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveReadEnvOnConstruction()
|
||||
{
|
||||
$object = $this->createCiEnvVarsCollector();
|
||||
|
||||
self::assertNull($object->getReadEnv());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldCollectTravisCiEnvVars
|
||||
*/
|
||||
public function shouldHaveReadEnvAfterCollectTravisCiEnvVars(CiEnvVarsCollector $object)
|
||||
{
|
||||
$readEnv = $object->getReadEnv();
|
||||
|
||||
self::assertCount(4, $readEnv);
|
||||
self::assertArrayHasKey('TRAVIS', $readEnv);
|
||||
self::assertArrayHasKey('TRAVIS_JOB_ID', $readEnv);
|
||||
self::assertArrayHasKey('CI_NAME', $readEnv);
|
||||
self::assertArrayHasKey('CI_BUILD_NUMBER', $readEnv);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldCollectGithubActionsEnvVars
|
||||
*/
|
||||
public function shouldHaveReadEnvAfterCollectGithubActionsEnvVars(CiEnvVarsCollector $object)
|
||||
{
|
||||
$readEnv = $object->getReadEnv();
|
||||
|
||||
self::assertCount(6, $readEnv);
|
||||
self::assertArrayHasKey('GITHUB_REF', $readEnv);
|
||||
self::assertArrayHasKey('CI_NAME', $readEnv);
|
||||
self::assertArrayHasKey('CI_JOB_ID', $readEnv);
|
||||
self::assertArrayHasKey('GITHUB_ACTIONS', $readEnv);
|
||||
self::assertArrayHasKey('CI_BRANCH', $readEnv);
|
||||
self::assertArrayHasKey('COVERALLS_REPO_TOKEN', $readEnv);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldCollectTravisProEnvVars
|
||||
*/
|
||||
public function shouldHaveReadEnvAfterCollectTravisProEnvVars(CiEnvVarsCollector $object)
|
||||
{
|
||||
$readEnv = $object->getReadEnv();
|
||||
|
||||
self::assertCount(5, $readEnv);
|
||||
self::assertArrayHasKey('TRAVIS', $readEnv);
|
||||
self::assertArrayHasKey('TRAVIS_JOB_ID', $readEnv);
|
||||
self::assertArrayHasKey('CI_NAME', $readEnv);
|
||||
self::assertArrayHasKey('CI_BUILD_NUMBER', $readEnv);
|
||||
self::assertArrayHasKey('COVERALLS_REPO_TOKEN', $readEnv);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldCollectCircleCiEnvVars
|
||||
*/
|
||||
public function shouldHaveReadEnvAfterCollectCircleCiEnvVars(CiEnvVarsCollector $object)
|
||||
{
|
||||
$readEnv = $object->getReadEnv();
|
||||
|
||||
self::assertCount(4, $readEnv);
|
||||
self::assertArrayHasKey('COVERALLS_REPO_TOKEN', $readEnv);
|
||||
self::assertArrayHasKey('CIRCLECI', $readEnv);
|
||||
self::assertArrayHasKey('CIRCLE_WORKFLOW_ID', $readEnv);
|
||||
self::assertArrayHasKey('CI_NAME', $readEnv);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldCollectJenkinsEnvVars
|
||||
*/
|
||||
public function shouldHaveReadEnvAfterCollectJenkinsEnvVars(CiEnvVarsCollector $object)
|
||||
{
|
||||
$readEnv = $object->getReadEnv();
|
||||
|
||||
self::assertCount(4, $readEnv);
|
||||
self::assertArrayHasKey('COVERALLS_REPO_TOKEN', $readEnv);
|
||||
self::assertArrayHasKey('JENKINS_URL', $readEnv);
|
||||
self::assertArrayHasKey('BUILD_NUMBER', $readEnv);
|
||||
self::assertArrayHasKey('CI_NAME', $readEnv);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldCollectLocalEnvVars
|
||||
*/
|
||||
public function shouldHaveReadEnvAfterCollectLocalEnvVars(CiEnvVarsCollector $object)
|
||||
{
|
||||
$readEnv = $object->getReadEnv();
|
||||
|
||||
self::assertCount(4, $readEnv);
|
||||
self::assertArrayHasKey('COVERALLS_REPO_TOKEN', $readEnv);
|
||||
self::assertArrayHasKey('COVERALLS_RUN_LOCALLY', $readEnv);
|
||||
self::assertArrayHasKey('COVERALLS_EVENT_TYPE', $readEnv);
|
||||
self::assertArrayHasKey('CI_NAME', $readEnv);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldCollectUnsupportedConfig
|
||||
*/
|
||||
public function shouldHaveReadEnvAfterCollectUnsupportedConfig(CiEnvVarsCollector $object)
|
||||
{
|
||||
$readEnv = $object->getReadEnv();
|
||||
|
||||
self::assertCount(1, $readEnv);
|
||||
self::assertArrayHasKey('COVERALLS_REPO_TOKEN', $readEnv);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldCollectUnsupportedEnvVars
|
||||
*/
|
||||
public function shouldHaveReadEnvAfterCollectUnsupportedEnvVars(CiEnvVarsCollector $object)
|
||||
{
|
||||
$readEnv = $object->getReadEnv();
|
||||
|
||||
self::assertCount(1, $readEnv);
|
||||
self::assertArrayHasKey('COVERALLS_REPO_TOKEN', $readEnv);
|
||||
}
|
||||
|
||||
protected function legacySetUp()
|
||||
{
|
||||
$this->setUpDir(realpath(__DIR__ . '/../../..'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Configuration
|
||||
*/
|
||||
protected function createConfiguration()
|
||||
{
|
||||
$config = new Configuration();
|
||||
|
||||
return $config
|
||||
->addCloverXmlPath($this->cloverXmlPath)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|Configuration $config
|
||||
*
|
||||
* @return CiEnvVarsCollector
|
||||
*/
|
||||
protected function createCiEnvVarsCollector($config = null)
|
||||
{
|
||||
if ($config === null) {
|
||||
$config = $this->createConfiguration();
|
||||
}
|
||||
|
||||
return new CiEnvVarsCollector($config);
|
||||
}
|
||||
}
|
||||
+304
@@ -0,0 +1,304 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Tests\Bundle\CoverallsBundle\Collector;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Collector\CloverXmlCoverageCollector;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Git;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\JsonFile;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\SourceFile;
|
||||
use PhpCoveralls\Tests\ProjectTestCase;
|
||||
|
||||
/**
|
||||
* @covers \PhpCoveralls\Bundle\CoverallsBundle\Collector\CloverXmlCoverageCollector
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class CloverXmlCoverageCollectorTest extends ProjectTestCase
|
||||
{
|
||||
/**
|
||||
* @var CloverXmlCoverageCollector
|
||||
*/
|
||||
private $object;
|
||||
|
||||
// getJsonFile()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveJsonFileOnConstruction()
|
||||
{
|
||||
self::assertNull($this->object->getJsonFile());
|
||||
}
|
||||
|
||||
// collect() under srcDir
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldCollect()
|
||||
{
|
||||
$xml = $this->createCloverXml();
|
||||
$jsonFile = $this->object->collect($xml, $this->srcDir);
|
||||
|
||||
self::assertSame($jsonFile, $this->object->getJsonFile());
|
||||
$this->assertJsonFile($jsonFile, null, null, null, null, '2013-04-13 10:28:13 +0000');
|
||||
|
||||
return $jsonFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldCollect
|
||||
*
|
||||
* @return JsonFile
|
||||
*/
|
||||
public function shouldCollectSourceFiles(JsonFile $jsonFile)
|
||||
{
|
||||
$sourceFiles = $jsonFile->getSourceFiles();
|
||||
|
||||
self::assertCount(3, $sourceFiles);
|
||||
|
||||
return $jsonFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldCollectSourceFiles
|
||||
*/
|
||||
public function shouldCollectSourceFileTest1(JsonFile $jsonFile)
|
||||
{
|
||||
$sourceFiles = $jsonFile->getSourceFiles();
|
||||
|
||||
$name1 = 'test.php';
|
||||
$path1 = $this->srcDir . \DIRECTORY_SEPARATOR . $name1;
|
||||
|
||||
self::assertArrayHasKey($path1, $sourceFiles);
|
||||
$this->assertSourceFileTest1($sourceFiles[$path1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldCollectSourceFiles
|
||||
*/
|
||||
public function shouldCollectSourceFileTest2(JsonFile $jsonFile)
|
||||
{
|
||||
$sourceFiles = $jsonFile->getSourceFiles();
|
||||
|
||||
$name2 = 'test2.php';
|
||||
$path2 = $this->srcDir . \DIRECTORY_SEPARATOR . $name2;
|
||||
|
||||
self::assertArrayHasKey($path2, $sourceFiles);
|
||||
$this->assertSourceFileTest2($sourceFiles[$path2]);
|
||||
}
|
||||
|
||||
// collect() under /
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldCollectUnderRootDir()
|
||||
{
|
||||
$xml = $this->createCloverXml();
|
||||
$jsonFile = $this->object->collect($xml, \DIRECTORY_SEPARATOR);
|
||||
|
||||
self::assertSame($jsonFile, $this->object->getJsonFile());
|
||||
$this->assertJsonFile($jsonFile, null, null, null, null, '2013-04-13 10:28:13 +0000');
|
||||
|
||||
return $jsonFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldCollectUnderRootDir
|
||||
*
|
||||
* @return JsonFile
|
||||
*/
|
||||
public function shouldCollectSourceFilesUnderRootDir(JsonFile $jsonFile)
|
||||
{
|
||||
$sourceFiles = $jsonFile->getSourceFiles();
|
||||
|
||||
self::assertCount(3, $sourceFiles);
|
||||
|
||||
return $jsonFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldCollectSourceFilesUnderRootDir
|
||||
*/
|
||||
public function shouldCollectSourceFileTest1UnderRootDir(JsonFile $jsonFile)
|
||||
{
|
||||
$sourceFiles = $jsonFile->getSourceFiles();
|
||||
|
||||
$name1 = 'test.php';
|
||||
$path1 = $this->srcDir . \DIRECTORY_SEPARATOR . $name1;
|
||||
|
||||
self::assertArrayHasKey($path1, $sourceFiles);
|
||||
$this->assertSourceFileTest1UnderRootDir($sourceFiles[$path1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldCollectSourceFilesUnderRootDir
|
||||
*/
|
||||
public function shouldCollectSourceFileTest2UnderRootDir(JsonFile $jsonFile)
|
||||
{
|
||||
$sourceFiles = $jsonFile->getSourceFiles();
|
||||
|
||||
$name2 = 'test2.php';
|
||||
$path2 = $this->srcDir . \DIRECTORY_SEPARATOR . $name2;
|
||||
|
||||
self::assertArrayHasKey($path2, $sourceFiles);
|
||||
$this->assertSourceFileTest2UnderRootDir($sourceFiles[$path2]);
|
||||
}
|
||||
|
||||
protected function legacySetUp()
|
||||
{
|
||||
$this->setUpDir(realpath(__DIR__ . '/../../..'));
|
||||
|
||||
$this->object = new CloverXmlCoverageCollector();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \SimpleXMLElement
|
||||
*/
|
||||
protected function createCloverXml()
|
||||
{
|
||||
$xml = <<<'XML'
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<coverage generated="1365848893">
|
||||
<project timestamp="1365848893">
|
||||
<file name="%s/test.php">
|
||||
<class name="TestFile" namespace="global">
|
||||
<metrics methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="1" coveredstatements="0" elements="2" coveredelements="0"/>
|
||||
</class>
|
||||
<line num="5" type="method" name="__construct" crap="1" count="0"/>
|
||||
<line num="7" type="stmt" count="2"/>
|
||||
</file>
|
||||
<file name="%s/test.php">
|
||||
<class name="TestFile" namespace="global">
|
||||
<metrics methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="1" coveredstatements="0" elements="2" coveredelements="0"/>
|
||||
</class>
|
||||
<line num="5" type="method" name="__construct" crap="1" count="0"/>
|
||||
<line num="7" type="stmt" count="1"/>
|
||||
</file>
|
||||
<file name="dummy.php">
|
||||
<class name="TestFile" namespace="global">
|
||||
<metrics methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="1" coveredstatements="0" elements="2" coveredelements="0"/>
|
||||
</class>
|
||||
<line num="5" type="method" name="__construct" crap="1" count="0"/>
|
||||
<line num="7" type="stmt" count="0"/>
|
||||
</file>
|
||||
<package name="Hoge">
|
||||
<file name="%s/test2.php">
|
||||
<class name="TestFile" namespace="Hoge">
|
||||
<metrics methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="1" coveredstatements="0" elements="2" coveredelements="0"/>
|
||||
</class>
|
||||
<line num="6" type="method" name="__construct" crap="1" count="0"/>
|
||||
<line num="8" type="stmt" count="0"/>
|
||||
</file>
|
||||
<file path="%s/test3.php" name="test3.php">
|
||||
<class name="TestFileBis" namespace="Hoge">
|
||||
<metrics methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="1" coveredstatements="0" elements="2" coveredelements="0"/>
|
||||
</class>
|
||||
<line num="6" type="method" name="__construct" crap="1" count="0"/>
|
||||
<line num="8" type="stmt" count="0"/>
|
||||
</file>
|
||||
</package>
|
||||
</project>
|
||||
</coverage>
|
||||
XML;
|
||||
|
||||
return simplexml_load_string(sprintf($xml, $this->srcDir, $this->srcDir, $this->srcDir, $this->srcDir));
|
||||
}
|
||||
|
||||
// custom assert
|
||||
|
||||
/**
|
||||
* @param JsonFile $jsonFile
|
||||
* @param string $serviceName
|
||||
* @param string $serviceJobId
|
||||
* @param string $repoToken
|
||||
* @param Git $git
|
||||
* @param string $runAt
|
||||
*/
|
||||
protected function assertJsonFile($jsonFile, $serviceName, $serviceJobId, $repoToken, $git, $runAt)
|
||||
{
|
||||
self::assertSame($serviceName, $jsonFile->getServiceName());
|
||||
self::assertSame($serviceJobId, $jsonFile->getServiceJobId());
|
||||
self::assertSame($repoToken, $jsonFile->getRepoToken());
|
||||
self::assertSame($git, $jsonFile->getGit());
|
||||
self::assertSame($runAt, $jsonFile->getRunAt());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $path
|
||||
* @param int $fileLines
|
||||
* @param string $source
|
||||
*/
|
||||
protected function assertSourceFile(SourceFile $sourceFile, $name, $path, $fileLines, array $coverage, $source)
|
||||
{
|
||||
self::assertSame($name, $sourceFile->getName());
|
||||
$this->assertSamePath($path, $sourceFile->getPath());
|
||||
self::assertSame($fileLines, $sourceFile->getFileLines());
|
||||
self::assertSame($coverage, $sourceFile->getCoverage());
|
||||
self::assertSame($source, $sourceFile->getSource());
|
||||
}
|
||||
|
||||
protected function assertSourceFileTest1(SourceFile $sourceFile)
|
||||
{
|
||||
$name1 = 'test.php';
|
||||
$path1 = $this->srcDir . \DIRECTORY_SEPARATOR . $name1;
|
||||
$fileLines1 = 9;
|
||||
$coverage1 = array_fill(0, $fileLines1, null);
|
||||
$coverage1[6] = 3;
|
||||
$source1 = trim(file_get_contents($path1));
|
||||
|
||||
$this->assertSourceFile($sourceFile, $name1, $path1, $fileLines1, $coverage1, $source1);
|
||||
}
|
||||
|
||||
protected function assertSourceFileTest2(SourceFile $sourceFile)
|
||||
{
|
||||
$name2 = 'test2.php';
|
||||
$path2 = $this->srcDir . \DIRECTORY_SEPARATOR . $name2;
|
||||
$fileLines2 = 10;
|
||||
$coverage2 = array_fill(0, $fileLines2, null);
|
||||
$coverage2[7] = 0;
|
||||
$source2 = trim(file_get_contents($path2));
|
||||
|
||||
$this->assertSourceFile($sourceFile, $name2, $path2, $fileLines2, $coverage2, $source2);
|
||||
}
|
||||
|
||||
protected function assertSourceFileTest1UnderRootDir(SourceFile $sourceFile)
|
||||
{
|
||||
$name1 = 'test.php';
|
||||
$path1 = $this->srcDir . \DIRECTORY_SEPARATOR . $name1;
|
||||
$fileLines1 = 9;
|
||||
$coverage1 = array_fill(0, $fileLines1, null);
|
||||
$coverage1[6] = 3;
|
||||
$source1 = trim(file_get_contents($path1));
|
||||
|
||||
$this->assertSourceFile($sourceFile, $path1, $path1, $fileLines1, $coverage1, $source1);
|
||||
}
|
||||
|
||||
protected function assertSourceFileTest2UnderRootDir(SourceFile $sourceFile)
|
||||
{
|
||||
$name2 = 'test2.php';
|
||||
$path2 = $this->srcDir . \DIRECTORY_SEPARATOR . $name2;
|
||||
$fileLines2 = 10;
|
||||
$coverage2 = array_fill(0, $fileLines2, null);
|
||||
$coverage2[7] = 0;
|
||||
$source2 = trim(file_get_contents($path2));
|
||||
|
||||
$this->assertSourceFile($sourceFile, $path2, $path2, $fileLines2, $coverage2, $source2);
|
||||
}
|
||||
}
|
||||
+309
@@ -0,0 +1,309 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Tests\Bundle\CoverallsBundle\Collector;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Collector\GitInfoCollector;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Commit;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Git;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Remote;
|
||||
use PhpCoveralls\Component\System\Git\GitCommand;
|
||||
use PhpCoveralls\Tests\ProjectTestCase;
|
||||
|
||||
/**
|
||||
* @covers \PhpCoveralls\Bundle\CoverallsBundle\Collector\GitInfoCollector
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class GitInfoCollectorTest extends ProjectTestCase
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $getBranchesValue = [
|
||||
' master',
|
||||
'* branch-1',
|
||||
' branch-2',
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $getHeadCommitValue = [
|
||||
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
|
||||
'Author Name',
|
||||
'author@satooshi.jp',
|
||||
'Committer Name',
|
||||
'committer@satooshi.jp',
|
||||
'commit message',
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $getRemotesValue = [
|
||||
"origin\tgit@github.com:php-coveralls/php-coveralls.git (fetch)",
|
||||
"origin\tgit@github.com:php-coveralls/php-coveralls.git (push)",
|
||||
];
|
||||
|
||||
// getCommand()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldHaveGitCommandOnConstruction()
|
||||
{
|
||||
$command = new GitCommand();
|
||||
$object = new GitInfoCollector($command);
|
||||
|
||||
self::assertSame($command, $object->getCommand());
|
||||
}
|
||||
|
||||
// collect()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldCollect()
|
||||
{
|
||||
$gitCommand = $this->createGitCommandStubWith($this->getBranchesValue, $this->getHeadCommitValue, $this->getRemotesValue);
|
||||
$object = new GitInfoCollector($gitCommand);
|
||||
|
||||
$git = $object->collect();
|
||||
|
||||
self::assertInstanceOf(Git::class, $git);
|
||||
$this->assertGit($git);
|
||||
self::assertSame('branch-1', $git->getBranch());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldCollectDetachedRef()
|
||||
{
|
||||
$gitCommand = $this->createGitCommandStubWith(
|
||||
['* (HEAD detached at pull/1/merge)'],
|
||||
$this->getHeadCommitValue,
|
||||
$this->getRemotesValue
|
||||
);
|
||||
$object = new GitInfoCollector($gitCommand);
|
||||
|
||||
$git = $object->collect();
|
||||
|
||||
self::assertInstanceOf(Git::class, $git);
|
||||
$this->assertGit($git);
|
||||
self::assertSame('pull/1/merge', $git->getBranch());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldCollectNoBranch()
|
||||
{
|
||||
$gitCommand = $this->createGitCommandStubWith(
|
||||
['* (no branch)'],
|
||||
$this->getHeadCommitValue,
|
||||
$this->getRemotesValue
|
||||
);
|
||||
$object = new GitInfoCollector($gitCommand);
|
||||
|
||||
$git = $object->collect();
|
||||
|
||||
self::assertInstanceOf(Git::class, $git);
|
||||
$this->assertGit($git);
|
||||
self::assertSame('(no branch)', $git->getBranch());
|
||||
}
|
||||
|
||||
// collectBranch() exception
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function throwRuntimeExceptionIfCurrentBranchNotFound()
|
||||
{
|
||||
$getBranchesValue = [
|
||||
' master',
|
||||
];
|
||||
$gitCommand = $this->createGitCommandStubCalledBranches($getBranchesValue);
|
||||
|
||||
$object = new GitInfoCollector($gitCommand);
|
||||
|
||||
$this->expectException(\RuntimeException::class);
|
||||
$object->collect();
|
||||
}
|
||||
|
||||
// collectCommit() exception
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function throwRuntimeExceptionIfHeadCommitIsInvalid()
|
||||
{
|
||||
$getHeadCommitValue = [];
|
||||
$gitCommand = $this->createGitCommandStubCalledHeadCommit($this->getBranchesValue, $getHeadCommitValue);
|
||||
|
||||
$object = new GitInfoCollector($gitCommand);
|
||||
|
||||
$this->expectException(\RuntimeException::class);
|
||||
$object->collect();
|
||||
}
|
||||
|
||||
// collectRemotes() exception
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function throwRuntimeExceptionIfRemoteIsInvalid()
|
||||
{
|
||||
$getRemotesValue = [];
|
||||
$gitCommand = $this->createGitCommandStubWith($this->getBranchesValue, $this->getHeadCommitValue, $getRemotesValue);
|
||||
|
||||
$object = new GitInfoCollector($gitCommand);
|
||||
|
||||
$this->expectException(\RuntimeException::class);
|
||||
$object->collect();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $getBranchesValue
|
||||
* @param mixed $getHeadCommitValue
|
||||
* @param mixed $getRemotesValue
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
protected function createGitCommandStubWith($getBranchesValue, $getHeadCommitValue, $getRemotesValue)
|
||||
{
|
||||
$stub = $this->prophesize(GitCommand::class);
|
||||
|
||||
$this->setUpGitCommandStubWithGetBranchesOnce($stub, $getBranchesValue);
|
||||
$this->setUpGitCommandStubWithGetHeadCommitOnce($stub, $getHeadCommitValue);
|
||||
$this->setUpGitCommandStubWithGetRemotesOnce($stub, $getRemotesValue);
|
||||
|
||||
return $stub->reveal();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $getBranchesValue
|
||||
*
|
||||
* @return GitCommand
|
||||
*/
|
||||
protected function createGitCommandStubCalledBranches($getBranchesValue)
|
||||
{
|
||||
$stub = $this->prophesize(GitCommand::class);
|
||||
|
||||
$this->setUpGitCommandStubWithGetBranchesOnce($stub, $getBranchesValue);
|
||||
$this->setUpGitCommandStubWithGetHeadCommitNeverCalled($stub);
|
||||
$this->setUpGitCommandStubWithGetRemotesNeverCalled($stub);
|
||||
|
||||
return $stub->reveal();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $getBranchesValue
|
||||
* @param array $getHeadCommitValue
|
||||
*
|
||||
* @return GitCommand
|
||||
*/
|
||||
protected function createGitCommandStubCalledHeadCommit($getBranchesValue, $getHeadCommitValue)
|
||||
{
|
||||
$stub = $this->prophesize(GitCommand::class);
|
||||
|
||||
$this->setUpGitCommandStubWithGetBranchesOnce($stub, $getBranchesValue);
|
||||
$this->setUpGitCommandStubWithGetHeadCommitOnce($stub, $getHeadCommitValue);
|
||||
$this->setUpGitCommandStubWithGetRemotesNeverCalled($stub);
|
||||
|
||||
return $stub->reveal();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param GitCommand $stub
|
||||
* @param mixed $getBranchesValue
|
||||
*/
|
||||
protected function setUpGitCommandStubWithGetBranchesOnce($stub, $getBranchesValue)
|
||||
{
|
||||
$stub
|
||||
->getBranches()
|
||||
->willReturn($getBranchesValue)
|
||||
->shouldBeCalled()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param GitCommand $stub
|
||||
* @param array $getHeadCommitValue
|
||||
*/
|
||||
protected function setUpGitCommandStubWithGetHeadCommitOnce($stub, $getHeadCommitValue)
|
||||
{
|
||||
$stub
|
||||
->getHeadCommit()
|
||||
->willReturn($getHeadCommitValue)
|
||||
->shouldBeCalled()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param GitCommand $stub
|
||||
*/
|
||||
protected function setUpGitCommandStubWithGetHeadCommitNeverCalled($stub)
|
||||
{
|
||||
$stub
|
||||
->getHeadCommit()
|
||||
->shouldNotBeCalled()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param GitCommand $stub
|
||||
* @param array $getRemotesValue
|
||||
*/
|
||||
protected function setUpGitCommandStubWithGetRemotesOnce($stub, $getRemotesValue)
|
||||
{
|
||||
$stub
|
||||
->getRemotes()
|
||||
->willReturn($getRemotesValue)
|
||||
->shouldBeCalled()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param GitCommand $stub
|
||||
*/
|
||||
protected function setUpGitCommandStubWithGetRemotesNeverCalled($stub)
|
||||
{
|
||||
$stub
|
||||
->getRemotes()
|
||||
->shouldNotBeCalled()
|
||||
;
|
||||
}
|
||||
|
||||
protected function assertGit(Git $git)
|
||||
{
|
||||
$commit = $git->getHead();
|
||||
|
||||
self::assertInstanceOf(Commit::class, $commit);
|
||||
$this->assertCommit($commit);
|
||||
|
||||
$remotes = $git->getRemotes();
|
||||
self::assertCount(1, $remotes);
|
||||
|
||||
self::assertInstanceOf(Remote::class, $remotes[0]);
|
||||
$this->assertRemote($remotes[0]);
|
||||
}
|
||||
|
||||
protected function assertCommit(Commit $commit)
|
||||
{
|
||||
self::assertSame('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', $commit->getId());
|
||||
self::assertSame('Author Name', $commit->getAuthorName());
|
||||
self::assertSame('author@satooshi.jp', $commit->getAuthorEmail());
|
||||
self::assertSame('Committer Name', $commit->getCommitterName());
|
||||
self::assertSame('committer@satooshi.jp', $commit->getCommitterEmail());
|
||||
self::assertSame('commit message', $commit->getMessage());
|
||||
}
|
||||
|
||||
protected function assertRemote(Remote $remote)
|
||||
{
|
||||
self::assertSame('origin', $remote->getName());
|
||||
self::assertSame('git@github.com:php-coveralls/php-coveralls.git', $remote->getUrl());
|
||||
}
|
||||
}
|
||||
+248
@@ -0,0 +1,248 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Tests\Bundle\CoverallsBundle\Command;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Command\CoverallsJobsCommand;
|
||||
use PhpCoveralls\Tests\ProjectTestCase;
|
||||
use Symfony\Component\Console\Application;
|
||||
use Symfony\Component\Console\Tester\CommandTester;
|
||||
|
||||
/**
|
||||
* @covers \PhpCoveralls\Bundle\CoverallsBundle\Command\CoverallsJobsCommand
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class CoverallsJobsCommandTest extends ProjectTestCase
|
||||
{
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldExecuteCoverallsJobsCommand()
|
||||
{
|
||||
$this->makeProjectDir(null, $this->logsDir);
|
||||
$this->dumpCloverXml();
|
||||
|
||||
$command = new CoverallsJobsCommand();
|
||||
$command->setRootDir($this->rootDir);
|
||||
|
||||
$app = new Application();
|
||||
$app->add($command);
|
||||
|
||||
$command = $app->find('coveralls:v1:jobs');
|
||||
$commandTester = new CommandTester($command);
|
||||
|
||||
$_SERVER['TRAVIS'] = true;
|
||||
$_SERVER['TRAVIS_BUILD_NUMBER'] = '12345';
|
||||
$_SERVER['TRAVIS_JOB_ID'] = 'command_test';
|
||||
|
||||
$actual = $commandTester->execute(
|
||||
[
|
||||
'command' => $command->getName(),
|
||||
'--dry-run' => true,
|
||||
'--config' => 'coveralls.yml',
|
||||
'--env' => 'test',
|
||||
]
|
||||
);
|
||||
|
||||
self::assertSame(0, $actual);
|
||||
|
||||
// It should succeed too with a correct coverage_clover option.
|
||||
$actual = $commandTester->execute(
|
||||
[
|
||||
'command' => $command->getName(),
|
||||
'--dry-run' => true,
|
||||
'--config' => 'coveralls.yml',
|
||||
'--env' => 'test',
|
||||
'--coverage_clover' => 'build/logs/clover.xml',
|
||||
]
|
||||
);
|
||||
|
||||
self::assertSame(0, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldExecuteCoverallsJobsCommandWithWrongRootDir()
|
||||
{
|
||||
$this->expectException(\Symfony\Component\Config\Definition\Exception\InvalidConfigurationException::class);
|
||||
|
||||
$this->makeProjectDir(null, $this->logsDir);
|
||||
$this->dumpCloverXml();
|
||||
|
||||
$command = new CoverallsJobsCommand();
|
||||
$command->setRootDir($this->logsDir); // Wrong rootDir.
|
||||
|
||||
$app = new Application();
|
||||
$app->add($command);
|
||||
|
||||
$command = $app->find('coveralls:v1:jobs');
|
||||
$commandTester = new CommandTester($command);
|
||||
|
||||
$_SERVER['TRAVIS'] = true;
|
||||
$_SERVER['TRAVIS_JOB_ID'] = 'command_test';
|
||||
|
||||
$actual = $commandTester->execute(
|
||||
[
|
||||
'command' => $command->getName(),
|
||||
'--dry-run' => true,
|
||||
'--config' => 'coveralls.yml',
|
||||
'--env' => 'test',
|
||||
]
|
||||
);
|
||||
|
||||
self::assertSame(0, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldExecuteCoverallsJobsCommandWithRootDirOverride()
|
||||
{
|
||||
$this->makeProjectDir(null, $this->logsDir);
|
||||
$this->dumpCloverXml();
|
||||
|
||||
$command = new CoverallsJobsCommand();
|
||||
$command->setRootDir($this->logsDir); // Wrong rootDir.
|
||||
|
||||
$app = new Application();
|
||||
$app->add($command);
|
||||
|
||||
$command = $app->find('coveralls:v1:jobs');
|
||||
$commandTester = new CommandTester($command);
|
||||
|
||||
$_SERVER['TRAVIS'] = true;
|
||||
$_SERVER['TRAVIS_JOB_ID'] = 'command_test';
|
||||
|
||||
$actual = $commandTester->execute(
|
||||
[
|
||||
'command' => $command->getName(),
|
||||
'--dry-run' => true,
|
||||
'--config' => 'coveralls.yml',
|
||||
'--env' => 'test',
|
||||
// Overriding with a correct one.
|
||||
'--root_dir' => $this->rootDir,
|
||||
]
|
||||
);
|
||||
|
||||
self::assertSame(0, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldExecuteCoverallsJobsCommandThrowInvalidConfigurationException()
|
||||
{
|
||||
$this->expectException(\Symfony\Component\Config\Definition\Exception\InvalidConfigurationException::class);
|
||||
|
||||
$this->makeProjectDir(null, $this->logsDir);
|
||||
$this->dumpCloverXml();
|
||||
|
||||
$command = new CoverallsJobsCommand();
|
||||
$command->setRootDir($this->rootDir);
|
||||
|
||||
$app = new Application();
|
||||
$app->add($command);
|
||||
|
||||
$command = $app->find('coveralls:v1:jobs');
|
||||
$commandTester = new CommandTester($command);
|
||||
|
||||
$_SERVER['TRAVIS'] = true;
|
||||
$_SERVER['TRAVIS_JOB_ID'] = 'command_test';
|
||||
|
||||
$commandTester->execute(
|
||||
[
|
||||
'command' => $command->getName(),
|
||||
'--dry-run' => true,
|
||||
'--config' => 'coveralls.yml',
|
||||
'--env' => 'test',
|
||||
'--coverage_clover' => 'nonexistent.xml',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldExecuteCoverallsJobsCommandWithInsecureOption()
|
||||
{
|
||||
$this->makeProjectDir(null, $this->logsDir);
|
||||
$this->dumpCloverXml();
|
||||
|
||||
$command = new CoverallsJobsCommand();
|
||||
$command->setRootDir($this->rootDir);
|
||||
|
||||
$app = new Application();
|
||||
$app->add($command);
|
||||
|
||||
$command = $app->find('coveralls:v1:jobs');
|
||||
$commandTester = new CommandTester($command);
|
||||
|
||||
$_SERVER['TRAVIS'] = true;
|
||||
$_SERVER['TRAVIS_JOB_ID'] = 'command_test';
|
||||
|
||||
$actual = $commandTester->execute(
|
||||
[
|
||||
'command' => $command->getName(),
|
||||
'--dry-run' => true,
|
||||
'--config' => 'coveralls.yml',
|
||||
'--env' => 'test',
|
||||
'--insecure' => true,
|
||||
]
|
||||
);
|
||||
|
||||
self::assertSame(0, $actual);
|
||||
}
|
||||
|
||||
protected function legacySetUp()
|
||||
{
|
||||
$this->setUpDir(realpath(__DIR__ . '/../../..'));
|
||||
}
|
||||
|
||||
protected function legacyTearDown()
|
||||
{
|
||||
$this->rmFile($this->cloverXmlPath);
|
||||
$this->rmFile($this->jsonPath);
|
||||
$this->rmDir($this->logsDir);
|
||||
$this->rmDir($this->buildDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getCloverXml()
|
||||
{
|
||||
$xml = <<<'XML'
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<coverage generated="1365848893">
|
||||
<project timestamp="1365848893">
|
||||
<file name="%s/test.php">
|
||||
<class name="TestFile" namespace="global">
|
||||
<metrics methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="1" coveredstatements="0" elements="2" coveredelements="0"/>
|
||||
</class>
|
||||
<line num="5" type="method" name="__construct" crap="1" count="0"/>
|
||||
<line num="7" type="stmt" count="0"/>
|
||||
</file>
|
||||
<package name="Hoge">
|
||||
<file name="%s/test2.php">
|
||||
<class name="TestFile" namespace="Hoge">
|
||||
<metrics methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="1" coveredstatements="0" elements="2" coveredelements="0"/>
|
||||
</class>
|
||||
<line num="6" type="method" name="__construct" crap="1" count="0"/>
|
||||
<line num="8" type="stmt" count="0"/>
|
||||
</file>
|
||||
</package>
|
||||
</project>
|
||||
</coverage>
|
||||
XML;
|
||||
|
||||
return sprintf($xml, $this->srcDir, $this->srcDir);
|
||||
}
|
||||
|
||||
protected function dumpCloverXml()
|
||||
{
|
||||
file_put_contents($this->cloverXmlPath, $this->getCloverXml());
|
||||
}
|
||||
}
|
||||
+431
@@ -0,0 +1,431 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Tests\Bundle\CoverallsBundle\Config;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Config\Configuration;
|
||||
use PhpCoveralls\Tests\ProjectTestCase;
|
||||
|
||||
/**
|
||||
* @covers \PhpCoveralls\Bundle\CoverallsBundle\Config\Configuration
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class ConfigurationTest extends ProjectTestCase
|
||||
{
|
||||
/**
|
||||
* @var Configuration
|
||||
*/
|
||||
private $object;
|
||||
|
||||
// hasRepoToken()
|
||||
// getRepoToken()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveRepoTokenOnConstruction()
|
||||
{
|
||||
self::assertFalse($this->object->hasRepoToken());
|
||||
self::assertNull($this->object->getRepoToken());
|
||||
}
|
||||
|
||||
// hasServiceName()
|
||||
// getServiceName()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveServiceNameOnConstruction()
|
||||
{
|
||||
self::assertFalse($this->object->hasServiceName());
|
||||
self::assertNull($this->object->getServiceName());
|
||||
}
|
||||
|
||||
// getCloverXmlPaths()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldHaveEmptyCloverXmlPathsOnConstruction()
|
||||
{
|
||||
self::assertEmpty($this->object->getCloverXmlPaths());
|
||||
}
|
||||
|
||||
// getRootDir()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotRootDirOnConstruction()
|
||||
{
|
||||
self::assertNull($this->object->getRootDir());
|
||||
}
|
||||
|
||||
// getJsonPath()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveJsonPathOnConstruction()
|
||||
{
|
||||
self::assertNull($this->object->getJsonPath());
|
||||
}
|
||||
|
||||
// isDryRun()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldBeDryRunOnConstruction()
|
||||
{
|
||||
self::assertTrue($this->object->isDryRun());
|
||||
}
|
||||
|
||||
// isExcludeNoStatements()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotBeExcludeNotStatementsOnConstruction()
|
||||
{
|
||||
self::assertFalse($this->object->isExcludeNoStatements());
|
||||
}
|
||||
|
||||
// isVerbose
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotBeVerboseOnConstruction()
|
||||
{
|
||||
self::assertFalse($this->object->isVerbose());
|
||||
}
|
||||
|
||||
// getEnv()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldBeProdEnvOnConstruction()
|
||||
{
|
||||
self::assertSame('prod', $this->object->getEnv());
|
||||
}
|
||||
|
||||
// isTestEnv()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldBeTestEnv()
|
||||
{
|
||||
$expected = 'test';
|
||||
|
||||
$this->object->setEnv($expected);
|
||||
|
||||
self::assertSame($expected, $this->object->getEnv());
|
||||
self::assertTrue($this->object->isTestEnv());
|
||||
self::assertFalse($this->object->isDevEnv());
|
||||
self::assertFalse($this->object->isProdEnv());
|
||||
}
|
||||
|
||||
// isDevEnv()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldBeDevEnv()
|
||||
{
|
||||
$expected = 'dev';
|
||||
|
||||
$this->object->setEnv($expected);
|
||||
|
||||
self::assertSame($expected, $this->object->getEnv());
|
||||
self::assertFalse($this->object->isTestEnv());
|
||||
self::assertTrue($this->object->isDevEnv());
|
||||
self::assertFalse($this->object->isProdEnv());
|
||||
}
|
||||
|
||||
// isProdEnv()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldBeProdEnv()
|
||||
{
|
||||
$expected = 'prod';
|
||||
|
||||
$this->object->setEnv($expected);
|
||||
|
||||
self::assertSame($expected, $this->object->getEnv());
|
||||
self::assertFalse($this->object->isTestEnv());
|
||||
self::assertFalse($this->object->isDevEnv());
|
||||
self::assertTrue($this->object->isProdEnv());
|
||||
}
|
||||
|
||||
// setEntryPoint
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetEntryPoint()
|
||||
{
|
||||
$expected = 'http://entry_point';
|
||||
|
||||
$same = $this->object->setEntryPoint($expected);
|
||||
|
||||
self::assertSame($same, $this->object);
|
||||
self::assertSame($expected, $this->object->getEntryPoint());
|
||||
}
|
||||
|
||||
// setRootDir()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetRootDir()
|
||||
{
|
||||
$expected = '/root';
|
||||
|
||||
$same = $this->object->setRootDir($expected);
|
||||
|
||||
self::assertSame($same, $this->object);
|
||||
self::assertSame($expected, $this->object->getRootDir());
|
||||
}
|
||||
|
||||
// setRepoToken()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetRepoToken()
|
||||
{
|
||||
$expected = 'token';
|
||||
|
||||
$same = $this->object->setRepoToken($expected);
|
||||
|
||||
self::assertSame($same, $this->object);
|
||||
self::assertSame($expected, $this->object->getRepoToken());
|
||||
}
|
||||
|
||||
// setServiceName()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetServiceName()
|
||||
{
|
||||
$expected = 'travis-ci';
|
||||
|
||||
$same = $this->object->setServiceName($expected);
|
||||
|
||||
self::assertSame($same, $this->object);
|
||||
self::assertSame($expected, $this->object->getServiceName());
|
||||
}
|
||||
|
||||
// setCloverXmlPaths()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetCloverXmlPaths()
|
||||
{
|
||||
$expected = ['/path/to/clover.xml'];
|
||||
|
||||
$same = $this->object->setCloverXmlPaths($expected);
|
||||
|
||||
self::assertSame($same, $this->object);
|
||||
self::assertSame($expected, $this->object->getCloverXmlPaths());
|
||||
}
|
||||
|
||||
// addCloverXmlPath()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldAddCloverXmlPath()
|
||||
{
|
||||
$expected = '/path/to/clover.xml';
|
||||
|
||||
$same = $this->object->addCloverXmlPath($expected);
|
||||
|
||||
self::assertSame($same, $this->object);
|
||||
self::assertSame([$expected], $this->object->getCloverXmlPaths());
|
||||
}
|
||||
|
||||
// setJsonPath()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetJsonPath()
|
||||
{
|
||||
$expected = '/path/to/coveralls-upload.json';
|
||||
|
||||
$same = $this->object->setJsonPath($expected);
|
||||
|
||||
self::assertSame($same, $this->object);
|
||||
self::assertSame($expected, $this->object->getJsonPath());
|
||||
}
|
||||
|
||||
// setDryRun()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetDryRunFalse()
|
||||
{
|
||||
$expected = false;
|
||||
|
||||
$same = $this->object->setDryRun($expected);
|
||||
|
||||
self::assertSame($same, $this->object);
|
||||
self::assertFalse($this->object->isDryRun());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetDryRunTrue()
|
||||
{
|
||||
$expected = true;
|
||||
|
||||
$same = $this->object->setDryRun($expected);
|
||||
|
||||
self::assertSame($same, $this->object);
|
||||
self::assertTrue($this->object->isDryRun());
|
||||
}
|
||||
|
||||
// setExcludeNoStatements()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetExcludeNoStatementsFalse()
|
||||
{
|
||||
$expected = false;
|
||||
|
||||
$same = $this->object->setExcludeNoStatements($expected);
|
||||
|
||||
self::assertSame($same, $this->object);
|
||||
self::assertFalse($this->object->isExcludeNoStatements());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetExcludeNoStatementsTrue()
|
||||
{
|
||||
$expected = true;
|
||||
|
||||
$same = $this->object->setExcludeNoStatements($expected);
|
||||
|
||||
self::assertSame($same, $this->object);
|
||||
self::assertTrue($this->object->isExcludeNoStatements());
|
||||
}
|
||||
|
||||
// setExcludeNoStatementsUnlessFalse()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetExcludeNoStatementsFalseUnlessFalse()
|
||||
{
|
||||
$expected = false;
|
||||
|
||||
$same = $this->object->setExcludeNoStatementsUnlessFalse($expected);
|
||||
|
||||
self::assertSame($same, $this->object);
|
||||
self::assertFalse($this->object->isExcludeNoStatements());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetExcludeNoStatementsTrueUnlessFalse()
|
||||
{
|
||||
$expected = true;
|
||||
|
||||
$same = $this->object->setExcludeNoStatementsUnlessFalse($expected);
|
||||
|
||||
self::assertSame($same, $this->object);
|
||||
self::assertTrue($this->object->isExcludeNoStatements());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetExcludeNoStatementsTrueIfFalsePassedAndIfTrueWasSet()
|
||||
{
|
||||
$expected = false;
|
||||
|
||||
$same = $this->object->setExcludeNoStatements(true);
|
||||
$same = $this->object->setExcludeNoStatementsUnlessFalse($expected);
|
||||
|
||||
self::assertSame($same, $this->object);
|
||||
self::assertTrue($this->object->isExcludeNoStatements());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetExcludeNoStatementsTrueIfTruePassedAndIfTrueWasSet()
|
||||
{
|
||||
$expected = true;
|
||||
|
||||
$same = $this->object->setExcludeNoStatements(true);
|
||||
$same = $this->object->setExcludeNoStatementsUnlessFalse($expected);
|
||||
|
||||
self::assertSame($same, $this->object);
|
||||
self::assertTrue($this->object->isExcludeNoStatements());
|
||||
}
|
||||
|
||||
// setVerbose()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetVerboseFalse()
|
||||
{
|
||||
$expected = false;
|
||||
|
||||
$same = $this->object->setVerbose($expected);
|
||||
|
||||
self::assertSame($same, $this->object);
|
||||
self::assertFalse($this->object->isVerbose());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetVerboseTrue()
|
||||
{
|
||||
$expected = true;
|
||||
|
||||
$same = $this->object->setVerbose($expected);
|
||||
|
||||
self::assertSame($same, $this->object);
|
||||
self::assertTrue($this->object->isVerbose());
|
||||
}
|
||||
|
||||
// setEnv()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetEnv()
|
||||
{
|
||||
$expected = 'myenv';
|
||||
|
||||
$same = $this->object->setEnv($expected);
|
||||
|
||||
self::assertSame($same, $this->object);
|
||||
self::assertSame($expected, $this->object->getEnv());
|
||||
}
|
||||
|
||||
protected function legacySetUp()
|
||||
{
|
||||
$this->object = new Configuration();
|
||||
}
|
||||
}
|
||||
+426
@@ -0,0 +1,426 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Tests\Bundle\CoverallsBundle\Config;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Config\Configuration;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Config\Configurator;
|
||||
use PhpCoveralls\Tests\ProjectTestCase;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Input\InputDefinition;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
||||
/**
|
||||
* @covers \PhpCoveralls\Bundle\CoverallsBundle\Config\Configurator
|
||||
* @covers \PhpCoveralls\Bundle\CoverallsBundle\Config\CoverallsConfiguration
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class ConfiguratorTest extends ProjectTestCase
|
||||
{
|
||||
/**
|
||||
* @var Configurator
|
||||
*/
|
||||
private $object;
|
||||
|
||||
// load()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldLoadNonExistingYml()
|
||||
{
|
||||
$this->makeProjectDir($this->srcDir, $this->logsDir, $this->cloverXmlPath);
|
||||
|
||||
$path = realpath(__DIR__ . '/yaml/dummy.yml');
|
||||
|
||||
$config = $this->object->load($path, $this->rootDir);
|
||||
|
||||
$this->assertConfiguration($config, [$this->cloverXmlPath], $this->jsonPath);
|
||||
}
|
||||
|
||||
// default src_dir not found, it doesn't throw anything now, as src_dir is not required for configuration
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function loadConfigurationOnLoadEmptyYmlWhenSrcDirNotFound()
|
||||
{
|
||||
$this->makeProjectDir(null, $this->logsDir, $this->cloverXmlPath);
|
||||
|
||||
$path = realpath(__DIR__ . '/yaml/dummy.yml');
|
||||
|
||||
$config = $this->object->load($path, $this->rootDir);
|
||||
|
||||
self::assertInstanceOf('PhpCoveralls\Bundle\CoverallsBundle\Config\Configuration', $config);
|
||||
}
|
||||
|
||||
// default coverage_clover not found
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function throwInvalidConfigurationExceptionOnLoadEmptyYmlIfCoverageCloverNotFound()
|
||||
{
|
||||
$this->expectException(\Symfony\Component\Config\Definition\Exception\InvalidConfigurationException::class);
|
||||
|
||||
$this->makeProjectDir($this->srcDir, $this->logsDir, null);
|
||||
|
||||
$path = realpath(__DIR__ . '/yaml/dummy.yml');
|
||||
|
||||
$this->object->load($path, $this->rootDir);
|
||||
}
|
||||
|
||||
// default json_path not writable
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function throwInvalidConfigurationExceptionOnLoadEmptyYmlIfJsonPathDirNotWritable()
|
||||
{
|
||||
$this->expectException(\Symfony\Component\Config\Definition\Exception\InvalidConfigurationException::class);
|
||||
|
||||
if ($this->isWindowsOS()) {
|
||||
// On Windows read-only attribute on dir applies to files in dir, but not the dir itself.
|
||||
self::markTestSkipped('Unable to run on Windows');
|
||||
}
|
||||
|
||||
$this->makeProjectDir($this->srcDir, $this->logsDir, $this->cloverXmlPath, true);
|
||||
|
||||
$path = realpath(__DIR__ . '/yaml/dummy.yml');
|
||||
|
||||
$this->object->load($path, $this->rootDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function throwInvalidConfigurationExceptionOnLoadEmptyYmlIfJsonPathNotWritable()
|
||||
{
|
||||
$this->expectException(\Symfony\Component\Config\Definition\Exception\InvalidConfigurationException::class);
|
||||
|
||||
$this->makeProjectDir($this->srcDir, $this->logsDir, $this->cloverXmlPath, false, true);
|
||||
|
||||
$path = realpath(__DIR__ . '/yaml/dummy.yml');
|
||||
|
||||
$this->object->load($path, $this->rootDir);
|
||||
}
|
||||
|
||||
// no configuration
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldLoadEmptyYml()
|
||||
{
|
||||
$this->makeProjectDir($this->srcDir, $this->logsDir, $this->cloverXmlPath);
|
||||
|
||||
$path = realpath(__DIR__ . '/yaml/empty.yml');
|
||||
|
||||
$config = $this->object->load($path, $this->rootDir);
|
||||
|
||||
$this->assertConfiguration($config, [$this->cloverXmlPath], $this->jsonPath);
|
||||
}
|
||||
|
||||
// load default value yml
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldThrowInvalidConfigurationExceptionUponLoadingSrcDirYml()
|
||||
{
|
||||
$this->expectException(\Symfony\Component\Config\Definition\Exception\InvalidConfigurationException::class);
|
||||
|
||||
$this->makeProjectDir($this->srcDir, $this->logsDir, $this->cloverXmlPath);
|
||||
|
||||
$path = realpath(__DIR__ . '/yaml/src_dir.yml');
|
||||
|
||||
$this->object->load($path, $this->rootDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldLoadCoverageCloverYmlContainingDefaultValue()
|
||||
{
|
||||
$this->makeProjectDir($this->srcDir, $this->logsDir, $this->cloverXmlPath);
|
||||
|
||||
$path = realpath(__DIR__ . '/yaml/coverage_clover.yml');
|
||||
|
||||
$config = $this->object->load($path, $this->rootDir);
|
||||
|
||||
$this->assertConfiguration($config, [$this->cloverXmlPath], $this->jsonPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldLoadCoverageCloverOverriddenByInput()
|
||||
{
|
||||
$this->makeProjectDir($this->srcDir, $this->logsDir, [$this->cloverXmlPath1, $this->cloverXmlPath2]);
|
||||
|
||||
$path = realpath(__DIR__ . '/yaml/coverage_clover.yml');
|
||||
|
||||
// Mocking command line options.
|
||||
$defs = new InputDefinition(
|
||||
[
|
||||
new InputOption(
|
||||
'coverage_clover',
|
||||
'x',
|
||||
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY
|
||||
),
|
||||
]
|
||||
);
|
||||
$inputArray = [
|
||||
'--coverage_clover' => [
|
||||
'build/logs/clover-part1.xml',
|
||||
'build/logs/clover-part2.xml',
|
||||
],
|
||||
];
|
||||
$input = new ArrayInput($inputArray, $defs);
|
||||
$config = $this->object->load($path, $this->rootDir, $input);
|
||||
$this->assertConfiguration($config, [$this->cloverXmlPath1, $this->cloverXmlPath2], $this->jsonPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldLoadCoverageCloverYmlContainingGlobValue()
|
||||
{
|
||||
$this->makeProjectDir($this->srcDir, $this->logsDir, [$this->cloverXmlPath1, $this->cloverXmlPath2]);
|
||||
|
||||
$path = realpath(__DIR__ . '/yaml/coverage_clover_glob.yml');
|
||||
|
||||
$config = $this->object->load($path, $this->rootDir);
|
||||
|
||||
$this->assertConfiguration($config, [$this->cloverXmlPath1, $this->cloverXmlPath2], $this->jsonPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldLoadCoverageCloverYmlContainingArrayValue()
|
||||
{
|
||||
$this->makeProjectDir($this->srcDir, $this->logsDir, [$this->cloverXmlPath1, $this->cloverXmlPath2]);
|
||||
|
||||
$path = realpath(__DIR__ . '/yaml/coverage_clover_array.yml');
|
||||
|
||||
$config = $this->object->load($path, $this->rootDir);
|
||||
|
||||
$this->assertConfiguration($config, [$this->cloverXmlPath1, $this->cloverXmlPath2], $this->jsonPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldLoadJsonPathYmlContainingDefaultValue()
|
||||
{
|
||||
$this->makeProjectDir($this->srcDir, $this->logsDir, $this->cloverXmlPath);
|
||||
|
||||
$path = realpath(__DIR__ . '/yaml/json_path.yml');
|
||||
|
||||
$config = $this->object->load($path, $this->rootDir);
|
||||
|
||||
$this->assertConfiguration($config, [$this->cloverXmlPath], $this->jsonPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldLoadJsonPathOverriddenByInput()
|
||||
{
|
||||
$this->makeProjectDir($this->srcDir, $this->logsDir, $this->cloverXmlPath);
|
||||
|
||||
$path = realpath(__DIR__ . '/yaml/json_path.yml');
|
||||
|
||||
// Mocking command line options.
|
||||
$defs = new InputDefinition(
|
||||
[
|
||||
new InputOption(
|
||||
'json_path',
|
||||
'o',
|
||||
InputOption::VALUE_REQUIRED
|
||||
),
|
||||
]
|
||||
);
|
||||
|
||||
$inputArray = [
|
||||
'--json_path' => 'build/logs/coveralls-upload-custom.json',
|
||||
];
|
||||
$expectedJsonPath = substr($this->jsonPath, 0, \strlen($this->jsonPath) - 5) . '-custom.json';
|
||||
|
||||
$input = new ArrayInput($inputArray, $defs);
|
||||
$config = $this->object->load($path, $this->rootDir, $input);
|
||||
$this->assertConfiguration($config, [$this->cloverXmlPath], $expectedJsonPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldLoadExcludeNoStmtYmlContainingTrue()
|
||||
{
|
||||
$this->makeProjectDir($this->srcDir, $this->logsDir, $this->cloverXmlPath);
|
||||
|
||||
$path = realpath(__DIR__ . '/yaml/exclude_no_stmt_true.yml');
|
||||
|
||||
$config = $this->object->load($path, $this->rootDir);
|
||||
|
||||
$this->assertConfiguration($config, [$this->cloverXmlPath], $this->jsonPath, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldLoadExcludeNoStmtYmlContainingFalse()
|
||||
{
|
||||
$this->makeProjectDir($this->srcDir, $this->logsDir, $this->cloverXmlPath);
|
||||
|
||||
$path = realpath(__DIR__ . '/yaml/exclude_no_stmt_false.yml');
|
||||
|
||||
$config = $this->object->load($path, $this->rootDir);
|
||||
|
||||
$this->assertConfiguration($config, [$this->cloverXmlPath], $this->jsonPath, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldLoadEntryPoint()
|
||||
{
|
||||
$this->makeProjectDir($this->srcDir, $this->logsDir, $this->cloverXmlPath);
|
||||
|
||||
$path = realpath(__DIR__ . '/yaml/entry_point.yml');
|
||||
|
||||
$config = $this->object->load($path, $this->rootDir);
|
||||
|
||||
self::assertSame('http://foo.bar', $config->getEntryPoint());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldLoadUseDefaultEntryPointIfNotSet()
|
||||
{
|
||||
$this->makeProjectDir($this->srcDir, $this->logsDir, $this->cloverXmlPath);
|
||||
|
||||
$path = realpath(__DIR__ . '/yaml/empty.yml');
|
||||
|
||||
$config = $this->object->load($path, $this->rootDir);
|
||||
|
||||
self::assertSame('https://coveralls.io', $config->getEntryPoint());
|
||||
}
|
||||
|
||||
// configured coverage_clover not found
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function throwInvalidConfigurationExceptionOnLoadCoverageCloverYmlIfCoverageCloverNotFound()
|
||||
{
|
||||
$this->expectException(\Symfony\Component\Config\Definition\Exception\InvalidConfigurationException::class);
|
||||
|
||||
$this->makeProjectDir($this->srcDir, $this->logsDir, $this->cloverXmlPath);
|
||||
|
||||
$path = realpath(__DIR__ . '/yaml/coverage_clover_not_found.yml');
|
||||
|
||||
$this->object->load($path, $this->rootDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function throwInvalidConfigurationExceptionOnLoadCoverageCloverYmlIfCoverageCloverIsNotString()
|
||||
{
|
||||
$this->expectException(\Symfony\Component\Config\Definition\Exception\InvalidConfigurationException::class);
|
||||
|
||||
$this->makeProjectDir($this->srcDir, $this->logsDir, $this->cloverXmlPath);
|
||||
|
||||
$path = realpath(__DIR__ . '/yaml/coverage_clover_invalid.yml');
|
||||
|
||||
$this->object->load($path, $this->rootDir);
|
||||
}
|
||||
|
||||
// configured json_path not found
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function throwInvalidConfigurationExceptionOnLoadJsonPathYmlIfJsonPathNotFound()
|
||||
{
|
||||
$this->expectException(\Symfony\Component\Config\Definition\Exception\InvalidConfigurationException::class);
|
||||
|
||||
$this->makeProjectDir($this->srcDir, $this->logsDir, $this->cloverXmlPath);
|
||||
|
||||
$path = realpath(__DIR__ . '/yaml/json_path_not_found.yml');
|
||||
|
||||
$this->object->load($path, $this->rootDir);
|
||||
}
|
||||
|
||||
// configured exclude_no_stmt invalid
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function throwInvalidConfigurationExceptionOnLoadExcludeNoStmtYmlIfInvalid()
|
||||
{
|
||||
if (\PHP_VERSION_ID >= 80000 && !\function_exists('get_debug_type')) {
|
||||
self::markTestIncomplete('get_debug_type() is not available yet');
|
||||
}
|
||||
|
||||
$this->expectException(\Symfony\Component\Config\Definition\Exception\InvalidConfigurationException::class);
|
||||
|
||||
$this->makeProjectDir($this->srcDir, $this->logsDir, $this->cloverXmlPath);
|
||||
|
||||
$path = realpath(__DIR__ . '/yaml/exclude_no_stmt_invalid.yml');
|
||||
|
||||
$this->object->load($path, $this->rootDir);
|
||||
}
|
||||
|
||||
protected function legacySetUp()
|
||||
{
|
||||
$this->setUpDir(realpath(__DIR__ . '/../../..'));
|
||||
|
||||
$this->srcDir = $this->rootDir . '/src';
|
||||
|
||||
$this->object = new Configurator();
|
||||
}
|
||||
|
||||
protected function legacyTearDown()
|
||||
{
|
||||
$this->rmFile($this->cloverXmlPath);
|
||||
$this->rmFile($this->cloverXmlPath1);
|
||||
$this->rmFile($this->cloverXmlPath2);
|
||||
$this->rmFile($this->jsonPath);
|
||||
$this->rmDir($this->srcDir);
|
||||
$this->rmDir($this->logsDir);
|
||||
$this->rmDir($this->buildDir);
|
||||
}
|
||||
|
||||
// custom assertion
|
||||
|
||||
/**
|
||||
* @param string $jsonPath
|
||||
* @param bool $excludeNoStatements
|
||||
*/
|
||||
protected function assertConfiguration(Configuration $config, array $cloverXml, $jsonPath, $excludeNoStatements = false)
|
||||
{
|
||||
$this->assertSamePaths($cloverXml, $config->getCloverXmlPaths());
|
||||
$this->assertSamePath($jsonPath, $config->getJsonPath());
|
||||
self::assertSame($excludeNoStatements, $config->isExcludeNoStatements());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function isWindowsOS()
|
||||
{
|
||||
static $isWindows;
|
||||
|
||||
if ($isWindows === null) {
|
||||
$isWindows = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
|
||||
}
|
||||
|
||||
return $isWindows;
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
coverage_clover: build/logs/clover.xml
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
coverage_clover:
|
||||
- build/logs/clover-part1.xml
|
||||
- build/logs/clover-part2.xml
|
||||
+1
@@ -0,0 +1 @@
|
||||
coverage_clover: build/logs/clover-*.xml
|
||||
+1
@@ -0,0 +1 @@
|
||||
coverage_clover: false
|
||||
+1
@@ -0,0 +1 @@
|
||||
coverage_clover: build/logs/clover.dummy.xml
|
||||
+1
@@ -0,0 +1 @@
|
||||
entry_point: http://foo.bar/
|
||||
+1
@@ -0,0 +1 @@
|
||||
exclude_no_stmt: false
|
||||
+1
@@ -0,0 +1 @@
|
||||
exclude_no_stmt: 1
|
||||
+1
@@ -0,0 +1 @@
|
||||
exclude_no_stmt: true
|
||||
+1
@@ -0,0 +1 @@
|
||||
json_path: build/logs/coveralls-upload.json
|
||||
+1
@@ -0,0 +1 @@
|
||||
json_path: build/logs.dummy/coveralls-upload.json
|
||||
+1
@@ -0,0 +1 @@
|
||||
src_dir: src
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Tests\Bundle\CoverallsBundle\Console;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Console\ApplicationFactory;
|
||||
use PhpCoveralls\Tests\ProjectTestCase;
|
||||
use Symfony\Component\Console\Tester\ApplicationTester;
|
||||
|
||||
/**
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @info This test is also covering \PhpCoveralls\Bundle\CoverallsBundle\Console\Application, but we cannot declare it as if so, PCOV will autoload it and it will fail on non-compat Sf/PHP combination, as we cannot declare partial loading anymore
|
||||
*
|
||||
* @covers \PhpCoveralls\Bundle\CoverallsBundle\Console\ApplicationFactory
|
||||
*/
|
||||
final class ApplicationTest extends ProjectTestCase
|
||||
{
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldExecuteCoverallsJobsCommand()
|
||||
{
|
||||
$this->makeProjectDir(null, $this->logsDir);
|
||||
$this->dumpCloverXml();
|
||||
|
||||
$app = ApplicationFactory::create($this->rootDir);
|
||||
$app->setAutoExit(false); // avoid to call exit() in Application
|
||||
|
||||
// run
|
||||
$_SERVER['TRAVIS'] = true;
|
||||
$_SERVER['TRAVIS_BUILD_NUMBER'] = 'application_build';
|
||||
$_SERVER['TRAVIS_JOB_ID'] = 'application_test';
|
||||
|
||||
$tester = new ApplicationTester($app);
|
||||
$actual = $tester->run(
|
||||
[
|
||||
'--dry-run' => true,
|
||||
'--config' => 'coveralls.yml',
|
||||
]
|
||||
);
|
||||
|
||||
self::assertSame(0, $actual);
|
||||
}
|
||||
|
||||
protected function legacySetUp()
|
||||
{
|
||||
$this->setUpDir(realpath(__DIR__ . '/../../..'));
|
||||
}
|
||||
|
||||
protected function legacyTearDown()
|
||||
{
|
||||
$this->rmFile($this->cloverXmlPath);
|
||||
$this->rmFile($this->jsonPath);
|
||||
$this->rmDir($this->logsDir);
|
||||
$this->rmDir($this->buildDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getCloverXml()
|
||||
{
|
||||
$xml = <<<'XML'
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<coverage generated="1365848893">
|
||||
<project timestamp="1365848893">
|
||||
<file name="%s/test.php">
|
||||
<class name="TestFile" namespace="global">
|
||||
<metrics methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="1" coveredstatements="0" elements="2" coveredelements="0"/>
|
||||
</class>
|
||||
<line num="5" type="method" name="__construct" crap="1" count="0"/>
|
||||
<line num="7" type="stmt" count="0"/>
|
||||
</file>
|
||||
<package name="Hoge">
|
||||
<file name="%s/test2.php">
|
||||
<class name="TestFile" namespace="Hoge">
|
||||
<metrics methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="1" coveredstatements="0" elements="2" coveredelements="0"/>
|
||||
</class>
|
||||
<line num="6" type="method" name="__construct" crap="1" count="0"/>
|
||||
<line num="8" type="stmt" count="0"/>
|
||||
</file>
|
||||
</package>
|
||||
</project>
|
||||
</coverage>
|
||||
XML;
|
||||
|
||||
return sprintf($xml, $this->srcDir, $this->srcDir);
|
||||
}
|
||||
|
||||
protected function dumpCloverXml()
|
||||
{
|
||||
file_put_contents($this->cloverXmlPath, $this->getCloverXml());
|
||||
}
|
||||
}
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Tests\Bundle\CoverallsBundle\Entity\Exception;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\Exception\RequirementsNotSatisfiedException;
|
||||
use PhpCoveralls\Tests\ProjectTestCase;
|
||||
|
||||
/**
|
||||
* @covers \PhpCoveralls\Bundle\CoverallsBundle\Entity\Exception\RequirementsNotSatisfiedException
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class RequirementsNotSatisfiedExceptionTest extends ProjectTestCase
|
||||
{
|
||||
// getReadEnv()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveReadEnvOnConstruction()
|
||||
{
|
||||
$object = new RequirementsNotSatisfiedException();
|
||||
|
||||
self::assertNull($object->getReadEnv());
|
||||
}
|
||||
|
||||
// setReadEnv()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetReadEnv()
|
||||
{
|
||||
$expected = [
|
||||
'ENV_NAME' => 'value',
|
||||
];
|
||||
|
||||
$object = new RequirementsNotSatisfiedException();
|
||||
$object->setReadEnv($expected);
|
||||
|
||||
self::assertSame($expected, $object->getReadEnv());
|
||||
}
|
||||
|
||||
// getHelpMessage()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldGetHelpMessageWithStringEnvVar()
|
||||
{
|
||||
$expected = [
|
||||
'ENV_NAME' => 'value',
|
||||
];
|
||||
|
||||
$object = new RequirementsNotSatisfiedException();
|
||||
$object->setReadEnv($expected);
|
||||
|
||||
$message = $object->getHelpMessage();
|
||||
|
||||
self::assertStringContainsString(" - ENV_NAME='value'", $message);
|
||||
}
|
||||
|
||||
// getHelpMessage()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldGetHelpMessageWithSecretStringEnvVarHidden()
|
||||
{
|
||||
// Make sure the secret repo token is HIDDEN.
|
||||
$env = [
|
||||
'COVERALLS_REPO_TOKEN' => 'secret',
|
||||
];
|
||||
$expected = " - COVERALLS_REPO_TOKEN='********(HIDDEN)'";
|
||||
|
||||
$object = new RequirementsNotSatisfiedException();
|
||||
$object->setReadEnv($env);
|
||||
|
||||
$message = $object->getHelpMessage();
|
||||
|
||||
self::assertStringContainsString($expected, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldGetHelpMessageWithSecretEmptyStringEnvVarShown()
|
||||
{
|
||||
// Make sure the secret repo token is shown when it's empty.
|
||||
$env = [
|
||||
'COVERALLS_REPO_TOKEN' => '',
|
||||
];
|
||||
$expected = " - COVERALLS_REPO_TOKEN=''";
|
||||
|
||||
$object = new RequirementsNotSatisfiedException();
|
||||
$object->setReadEnv($env);
|
||||
|
||||
$message = $object->getHelpMessage();
|
||||
|
||||
self::assertStringContainsString($expected, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldGetHelpMessageWithIntegerEnvVar()
|
||||
{
|
||||
$expected = [
|
||||
'ENV_NAME' => 123,
|
||||
];
|
||||
|
||||
$object = new RequirementsNotSatisfiedException();
|
||||
$object->setReadEnv($expected);
|
||||
|
||||
$message = $object->getHelpMessage();
|
||||
|
||||
self::assertStringContainsString(' - ENV_NAME=123', $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldGetHelpMessageWithBooleanEnvVar()
|
||||
{
|
||||
$expected = [
|
||||
'ENV_NAME' => true,
|
||||
];
|
||||
|
||||
$object = new RequirementsNotSatisfiedException();
|
||||
$object->setReadEnv($expected);
|
||||
|
||||
$message = $object->getHelpMessage();
|
||||
|
||||
self::assertStringContainsString(' - ENV_NAME=true', $message);
|
||||
}
|
||||
}
|
||||
+231
@@ -0,0 +1,231 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Tests\Bundle\CoverallsBundle\Entity\Git;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Commit;
|
||||
use PhpCoveralls\Tests\ProjectTestCase;
|
||||
|
||||
/**
|
||||
* @covers \PhpCoveralls\Bundle\CoverallsBundle\Entity\Coveralls
|
||||
* @covers \PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Commit
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class CommitTest extends ProjectTestCase
|
||||
{
|
||||
/**
|
||||
* @var Commit
|
||||
*/
|
||||
private $object;
|
||||
|
||||
// getId()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveIdOnConstruction()
|
||||
{
|
||||
self::assertNull($this->object->getId());
|
||||
}
|
||||
|
||||
// getAuthorName()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHoveAuthorNameOnConstruction()
|
||||
{
|
||||
self::assertNull($this->object->getAuthorName());
|
||||
}
|
||||
|
||||
// getAuthorEmail()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHoveAuthorEmailOnConstruction()
|
||||
{
|
||||
self::assertNull($this->object->getAuthorEmail());
|
||||
}
|
||||
|
||||
// getCommitterName()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHoveCommitterNameOnConstruction()
|
||||
{
|
||||
self::assertNull($this->object->getCommitterName());
|
||||
}
|
||||
|
||||
// getCommitterEmail()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHoveCommitterEmailOnConstruction()
|
||||
{
|
||||
self::assertNull($this->object->getCommitterEmail());
|
||||
}
|
||||
|
||||
// getMessage()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHoveMessageOnConstruction()
|
||||
{
|
||||
self::assertNull($this->object->getMessage());
|
||||
}
|
||||
|
||||
// setId()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetId()
|
||||
{
|
||||
$expected = 'id';
|
||||
|
||||
$obj = $this->object->setId($expected);
|
||||
|
||||
self::assertSame($expected, $this->object->getId());
|
||||
self::assertSame($obj, $this->object);
|
||||
}
|
||||
|
||||
// setAuthorName()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetAuthorName()
|
||||
{
|
||||
$expected = 'author_name';
|
||||
|
||||
$obj = $this->object->setAuthorName($expected);
|
||||
|
||||
self::assertSame($expected, $this->object->getAuthorName());
|
||||
self::assertSame($obj, $this->object);
|
||||
}
|
||||
|
||||
// setAuthorEmail()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetAuthorEmail()
|
||||
{
|
||||
$expected = 'author_email';
|
||||
|
||||
$obj = $this->object->setAuthorEmail($expected);
|
||||
|
||||
self::assertSame($expected, $this->object->getAuthorEmail());
|
||||
self::assertSame($obj, $this->object);
|
||||
}
|
||||
|
||||
// setCommitterName()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetCommitterName()
|
||||
{
|
||||
$expected = 'committer_name';
|
||||
|
||||
$obj = $this->object->setCommitterName($expected);
|
||||
|
||||
self::assertSame($expected, $this->object->getCommitterName());
|
||||
self::assertSame($obj, $this->object);
|
||||
}
|
||||
|
||||
// setCommitterEmail()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetCommitterEmail()
|
||||
{
|
||||
$expected = 'committer_email';
|
||||
|
||||
$obj = $this->object->setCommitterEmail($expected);
|
||||
|
||||
self::assertSame($expected, $this->object->getCommitterEmail());
|
||||
self::assertSame($obj, $this->object);
|
||||
}
|
||||
|
||||
// setMessage()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetMessage()
|
||||
{
|
||||
$expected = 'message';
|
||||
|
||||
$obj = $this->object->setMessage($expected);
|
||||
|
||||
self::assertSame($expected, $this->object->getMessage());
|
||||
self::assertSame($obj, $this->object);
|
||||
}
|
||||
|
||||
// toArray()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldConvertToArray()
|
||||
{
|
||||
$expected = [
|
||||
'id' => null,
|
||||
'author_name' => null,
|
||||
'author_email' => null,
|
||||
'committer_name' => null,
|
||||
'committer_email' => null,
|
||||
'message' => null,
|
||||
];
|
||||
|
||||
self::assertSame($expected, $this->object->toArray());
|
||||
self::assertSame(json_encode($expected), (string) $this->object);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldConvertToFilledArray()
|
||||
{
|
||||
$id = 'id';
|
||||
$authorName = 'author_name';
|
||||
$authorEmail = 'author_email';
|
||||
$committerName = 'committer_name';
|
||||
$committerEmail = 'committer_email';
|
||||
$message = 'message';
|
||||
|
||||
$this->object
|
||||
->setId($id)
|
||||
->setAuthorName($authorName)
|
||||
->setAuthorEmail($authorEmail)
|
||||
->setCommitterName($committerName)
|
||||
->setCommitterEmail($committerEmail)
|
||||
->setMessage($message)
|
||||
;
|
||||
|
||||
$expected = [
|
||||
'id' => $id,
|
||||
'author_name' => $authorName,
|
||||
'author_email' => $authorEmail,
|
||||
'committer_name' => $committerName,
|
||||
'committer_email' => $committerEmail,
|
||||
'message' => $message,
|
||||
];
|
||||
|
||||
self::assertSame($expected, $this->object->toArray());
|
||||
self::assertSame(json_encode($expected), (string) $this->object);
|
||||
}
|
||||
|
||||
protected function legacySetUp()
|
||||
{
|
||||
$this->object = new Commit();
|
||||
}
|
||||
}
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Tests\Bundle\CoverallsBundle\Entity\Git;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Commit;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Git;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Remote;
|
||||
use PhpCoveralls\Tests\ProjectTestCase;
|
||||
|
||||
/**
|
||||
* @covers \PhpCoveralls\Bundle\CoverallsBundle\Entity\Coveralls
|
||||
* @covers \PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Git
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class GitTest extends ProjectTestCase
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $branchName;
|
||||
|
||||
/**
|
||||
* @var Commit
|
||||
*/
|
||||
private $commit;
|
||||
|
||||
/**
|
||||
* @var Remote
|
||||
*/
|
||||
private $remote;
|
||||
|
||||
/**
|
||||
* @var Git
|
||||
*/
|
||||
private $object;
|
||||
|
||||
// getBranch()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldHaveBranchNameOnConstruction()
|
||||
{
|
||||
self::assertSame($this->branchName, $this->object->getBranch());
|
||||
}
|
||||
|
||||
// getHead()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldHaveHeadCommitOnConstruction()
|
||||
{
|
||||
self::assertSame($this->commit, $this->object->getHead());
|
||||
}
|
||||
|
||||
// getRemotes()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldHaveRemotesOnConstruction()
|
||||
{
|
||||
self::assertSame([$this->remote], $this->object->getRemotes());
|
||||
}
|
||||
|
||||
// toArray()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldConvertToArray()
|
||||
{
|
||||
$expected = [
|
||||
'branch' => $this->branchName,
|
||||
'head' => $this->commit->toArray(),
|
||||
'remotes' => [$this->remote->toArray()],
|
||||
];
|
||||
|
||||
self::assertSame($expected, $this->object->toArray());
|
||||
self::assertSame(json_encode($expected), (string) $this->object);
|
||||
}
|
||||
|
||||
protected function legacySetUp()
|
||||
{
|
||||
$this->branchName = 'branch_name';
|
||||
$this->commit = $this->createCommit();
|
||||
$this->remote = $this->createRemote();
|
||||
|
||||
$this->object = new Git($this->branchName, $this->commit, [$this->remote]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $url
|
||||
*
|
||||
* @return Remote
|
||||
*/
|
||||
protected function createRemote($name = 'name', $url = 'url')
|
||||
{
|
||||
$remote = new Remote();
|
||||
|
||||
return $remote
|
||||
->setName($name)
|
||||
->setUrl($url)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @param string $authorName
|
||||
* @param string $authorEmail
|
||||
* @param string $committerName
|
||||
* @param string $committerEmail
|
||||
* @param string $message
|
||||
*
|
||||
* @return Commit
|
||||
*/
|
||||
protected function createCommit($id = 'id', $authorName = 'author_name', $authorEmail = 'author_email', $committerName = 'committer_name', $committerEmail = 'committer_email', $message = 'message')
|
||||
{
|
||||
$commit = new Commit();
|
||||
|
||||
return $commit
|
||||
->setId($id)
|
||||
->setAuthorName($authorName)
|
||||
->setAuthorEmail($authorEmail)
|
||||
->setCommitterName($committerName)
|
||||
->setCommitterEmail($committerEmail)
|
||||
->setMessage($message)
|
||||
;
|
||||
}
|
||||
}
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Tests\Bundle\CoverallsBundle\Entity\Git;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Remote;
|
||||
use PhpCoveralls\Tests\ProjectTestCase;
|
||||
|
||||
/**
|
||||
* @covers \PhpCoveralls\Bundle\CoverallsBundle\Entity\Coveralls
|
||||
* @covers \PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Remote
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class RemoteTest extends ProjectTestCase
|
||||
{
|
||||
/**
|
||||
* @var Remote
|
||||
*/
|
||||
private $object;
|
||||
|
||||
// getName()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveRemoteNameOnConstruction()
|
||||
{
|
||||
self::assertNull($this->object->getName());
|
||||
}
|
||||
|
||||
// getUrl()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveUrlOnConstruction()
|
||||
{
|
||||
self::assertNull($this->object->getUrl());
|
||||
}
|
||||
|
||||
// setName()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetRemoteName()
|
||||
{
|
||||
$expected = 'remote_name';
|
||||
|
||||
$obj = $this->object->setName($expected);
|
||||
|
||||
self::assertSame($expected, $this->object->getName());
|
||||
self::assertSame($obj, $this->object);
|
||||
}
|
||||
|
||||
// setUrl()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetRemoteUrl()
|
||||
{
|
||||
$expected = 'git@github.com:php-coveralls/php-coveralls.git';
|
||||
|
||||
$obj = $this->object->setUrl($expected);
|
||||
|
||||
self::assertSame($expected, $this->object->getUrl());
|
||||
self::assertSame($obj, $this->object);
|
||||
}
|
||||
|
||||
// toArray()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldConvertToArray()
|
||||
{
|
||||
$expected = [
|
||||
'name' => null,
|
||||
'url' => null,
|
||||
];
|
||||
|
||||
self::assertSame($expected, $this->object->toArray());
|
||||
self::assertSame(json_encode($expected), (string) $this->object);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldConvertToFilledArray()
|
||||
{
|
||||
$name = 'name';
|
||||
$url = 'url';
|
||||
|
||||
$this->object
|
||||
->setName($name)
|
||||
->setUrl($url)
|
||||
;
|
||||
|
||||
$expected = [
|
||||
'name' => $name,
|
||||
'url' => $url,
|
||||
];
|
||||
|
||||
self::assertSame($expected, $this->object->toArray());
|
||||
self::assertSame(json_encode($expected), (string) $this->object);
|
||||
}
|
||||
|
||||
protected function legacySetUp()
|
||||
{
|
||||
$this->object = new Remote();
|
||||
}
|
||||
}
|
||||
+866
@@ -0,0 +1,866 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Tests\Bundle\CoverallsBundle\Entity;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Collector\CloverXmlCoverageCollector;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Commit;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Git;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\Git\Remote;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\JsonFile;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\SourceFile;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Version;
|
||||
use PhpCoveralls\Tests\ProjectTestCase;
|
||||
|
||||
/**
|
||||
* @covers \PhpCoveralls\Bundle\CoverallsBundle\Entity\Coveralls
|
||||
* @covers \PhpCoveralls\Bundle\CoverallsBundle\Entity\JsonFile
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class JsonFileTest extends ProjectTestCase
|
||||
{
|
||||
/**
|
||||
* @var JsonFile
|
||||
*/
|
||||
private $object;
|
||||
|
||||
// hasSourceFile()
|
||||
// getSourceFile()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveSourceFileOnConstruction()
|
||||
{
|
||||
$path = 'test.php';
|
||||
|
||||
self::assertFalse($this->object->hasSourceFile($path));
|
||||
self::assertNull($this->object->getSourceFile($path));
|
||||
}
|
||||
|
||||
// hasSourceFiles()
|
||||
// getSourceFiles()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldCountZeroSourceFilesOnConstruction()
|
||||
{
|
||||
self::assertFalse($this->object->hasSourceFiles());
|
||||
self::assertEmpty($this->object->getSourceFiles());
|
||||
}
|
||||
|
||||
// getServiceName()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveServiceNameOnConstruction()
|
||||
{
|
||||
self::assertNull($this->object->getServiceName());
|
||||
}
|
||||
|
||||
// getRepoToken()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveRepoTokenOnConstruction()
|
||||
{
|
||||
self::assertNull($this->object->getRepoToken());
|
||||
}
|
||||
|
||||
// getServiceJobId()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveServiceJobIdOnConstruction()
|
||||
{
|
||||
self::assertNull($this->object->getServiceJobId());
|
||||
}
|
||||
|
||||
// getServiceNumber()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveServiceNumberOnConstruction()
|
||||
{
|
||||
self::assertNull($this->object->getServiceNumber());
|
||||
}
|
||||
|
||||
// getServiceEventType()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveServiceEventTypeOnConstruction()
|
||||
{
|
||||
self::assertNull($this->object->getServiceEventType());
|
||||
}
|
||||
|
||||
// getServiceBuildUrl()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveServiceBuildUrlOnConstruction()
|
||||
{
|
||||
self::assertNull($this->object->getServiceBuildUrl());
|
||||
}
|
||||
|
||||
// getServiceBranch()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveServiceBranchOnConstruction()
|
||||
{
|
||||
self::assertNull($this->object->getServiceBranch());
|
||||
}
|
||||
|
||||
// getServicePullRequest()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveServicePullRequestOnConstruction()
|
||||
{
|
||||
self::assertNull($this->object->getServicePullRequest());
|
||||
}
|
||||
|
||||
// getGit()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveGitOnConstruction()
|
||||
{
|
||||
self::assertNull($this->object->getGit());
|
||||
}
|
||||
|
||||
// getRunAt()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveRunAtOnConstruction()
|
||||
{
|
||||
self::assertNull($this->object->getRunAt());
|
||||
}
|
||||
|
||||
// getMetrics()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldHaveEmptyMetrics()
|
||||
{
|
||||
$metrics = $this->object->getMetrics();
|
||||
|
||||
self::assertSame(0, $metrics->getStatements());
|
||||
self::assertSame(0, $metrics->getCoveredStatements());
|
||||
self::assertSame(0, $metrics->getLineCoverage());
|
||||
}
|
||||
|
||||
// setServiceName()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetServiceName()
|
||||
{
|
||||
$expected = 'travis-ci';
|
||||
|
||||
$obj = $this->object->setServiceName($expected);
|
||||
|
||||
self::assertSame($expected, $this->object->getServiceName());
|
||||
self::assertSame($obj, $this->object);
|
||||
|
||||
return $this->object;
|
||||
}
|
||||
|
||||
// setRepoToken()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetRepoToken()
|
||||
{
|
||||
$expected = 'token';
|
||||
|
||||
$obj = $this->object->setRepoToken($expected);
|
||||
|
||||
self::assertSame($expected, $this->object->getRepoToken());
|
||||
self::assertSame($obj, $this->object);
|
||||
|
||||
return $this->object;
|
||||
}
|
||||
|
||||
// setParallel()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetParallel()
|
||||
{
|
||||
$expected = true;
|
||||
|
||||
$obj = $this->object->setParallel($expected);
|
||||
|
||||
self::assertSame($expected, $this->object->getParallel());
|
||||
self::assertSame($obj, $this->object);
|
||||
|
||||
return $this->object;
|
||||
}
|
||||
|
||||
// setFlagName()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetFlagName()
|
||||
{
|
||||
$expected = 'php-7.4';
|
||||
|
||||
$obj = $this->object->setFlagName($expected);
|
||||
|
||||
self::assertSame($expected, $this->object->getFlagName());
|
||||
self::assertSame($obj, $this->object);
|
||||
|
||||
return $this->object;
|
||||
}
|
||||
|
||||
// setServiceJobId()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetServiceJobId()
|
||||
{
|
||||
$expected = 'job_id';
|
||||
|
||||
$obj = $this->object->setServiceJobId($expected);
|
||||
|
||||
self::assertSame($expected, $this->object->getServiceJobId());
|
||||
self::assertSame($obj, $this->object);
|
||||
|
||||
return $this->object;
|
||||
}
|
||||
|
||||
// setGit()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetGit()
|
||||
{
|
||||
$remotes = [new Remote()];
|
||||
$head = new Commit();
|
||||
$git = new Git('master', $head, $remotes);
|
||||
|
||||
$obj = $this->object->setGit($git);
|
||||
|
||||
self::assertSame($git, $this->object->getGit());
|
||||
self::assertSame($obj, $this->object);
|
||||
|
||||
return $this->object;
|
||||
}
|
||||
|
||||
// setRunAt()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldSetRunAt()
|
||||
{
|
||||
$expected = '2013-04-04 11:22:33 +0900';
|
||||
|
||||
$obj = $this->object->setRunAt($expected);
|
||||
|
||||
self::assertSame($expected, $this->object->getRunAt());
|
||||
self::assertSame($obj, $this->object);
|
||||
|
||||
return $this->object;
|
||||
}
|
||||
|
||||
// addSourceFile()
|
||||
// sortSourceFiles()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldAddSourceFile()
|
||||
{
|
||||
$sourceFile = $this->createSourceFile();
|
||||
|
||||
$this->object->addSourceFile($sourceFile);
|
||||
$this->object->sortSourceFiles();
|
||||
|
||||
$path = $sourceFile->getPath();
|
||||
|
||||
self::assertTrue($this->object->hasSourceFiles());
|
||||
self::assertSame([$path => $sourceFile], $this->object->getSourceFiles());
|
||||
self::assertTrue($this->object->hasSourceFile($path));
|
||||
self::assertSame($sourceFile, $this->object->getSourceFile($path));
|
||||
}
|
||||
|
||||
// toArray()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldConvertToArray()
|
||||
{
|
||||
$expected = [
|
||||
'source_files' => [],
|
||||
'environment' => ['packagist_version' => Version::VERSION],
|
||||
];
|
||||
|
||||
self::assertSame($expected, $this->object->toArray());
|
||||
self::assertSame(json_encode($expected), (string) $this->object);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldConvertToArrayWithSourceFiles()
|
||||
{
|
||||
$sourceFile = $this->createSourceFile();
|
||||
|
||||
$this->object->addSourceFile($sourceFile);
|
||||
|
||||
$expected = [
|
||||
'source_files' => [$sourceFile->toArray()],
|
||||
'environment' => ['packagist_version' => Version::VERSION],
|
||||
];
|
||||
|
||||
self::assertSame($expected, $this->object->toArray());
|
||||
self::assertSame(json_encode($expected), (string) $this->object);
|
||||
}
|
||||
|
||||
// service_name
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldSetServiceName
|
||||
*
|
||||
* @param mixed $object
|
||||
*/
|
||||
public function shouldConvertToArrayWithServiceName($object)
|
||||
{
|
||||
$item = 'travis-ci';
|
||||
|
||||
$expected = [
|
||||
'service_name' => $item,
|
||||
'source_files' => [],
|
||||
'environment' => ['packagist_version' => Version::VERSION],
|
||||
];
|
||||
|
||||
self::assertSame($expected, $object->toArray());
|
||||
self::assertSame(json_encode($expected), (string) $object);
|
||||
}
|
||||
|
||||
// service_job_id
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldSetServiceJobId
|
||||
*
|
||||
* @param mixed $object
|
||||
*/
|
||||
public function shouldConvertToArrayWithServiceJobId($object)
|
||||
{
|
||||
$item = 'job_id';
|
||||
|
||||
$expected = [
|
||||
'service_job_id' => $item,
|
||||
'source_files' => [],
|
||||
'environment' => ['packagist_version' => Version::VERSION],
|
||||
];
|
||||
|
||||
self::assertSame($expected, $object->toArray());
|
||||
self::assertSame(json_encode($expected), (string) $object);
|
||||
}
|
||||
|
||||
// repo_token
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldSetRepoToken
|
||||
*
|
||||
* @param mixed $object
|
||||
*/
|
||||
public function shouldConvertToArrayWithRepoToken($object)
|
||||
{
|
||||
$item = 'token';
|
||||
|
||||
$expected = [
|
||||
'repo_token' => $item,
|
||||
'source_files' => [],
|
||||
'environment' => ['packagist_version' => Version::VERSION],
|
||||
];
|
||||
|
||||
self::assertSame($expected, $object->toArray());
|
||||
self::assertSame(json_encode($expected), (string) $object);
|
||||
}
|
||||
|
||||
// parallel
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldSetParallel
|
||||
*
|
||||
* @param mixed $object
|
||||
*/
|
||||
public function shouldConvertToArrayWithParallel($object)
|
||||
{
|
||||
$item = true;
|
||||
|
||||
$expected = [
|
||||
'parallel' => $item,
|
||||
'source_files' => [],
|
||||
'environment' => ['packagist_version' => Version::VERSION],
|
||||
];
|
||||
|
||||
self::assertSame($expected, $object->toArray());
|
||||
self::assertSame(json_encode($expected), (string) $object);
|
||||
}
|
||||
|
||||
// git
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldSetGit
|
||||
*
|
||||
* @param mixed $object
|
||||
*/
|
||||
public function shouldConvertToArrayWithGit($object)
|
||||
{
|
||||
$remotes = [new Remote()];
|
||||
$head = new Commit();
|
||||
$git = new Git('master', $head, $remotes);
|
||||
|
||||
$expected = [
|
||||
'git' => $git->toArray(),
|
||||
'source_files' => [],
|
||||
'environment' => ['packagist_version' => Version::VERSION],
|
||||
];
|
||||
|
||||
self::assertSame($expected, $object->toArray());
|
||||
self::assertSame(json_encode($expected), (string) $object);
|
||||
}
|
||||
|
||||
// run_at
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @depends shouldSetRunAt
|
||||
*
|
||||
* @param mixed $object
|
||||
*/
|
||||
public function shouldConvertToArrayWithRunAt($object)
|
||||
{
|
||||
$item = '2013-04-04 11:22:33 +0900';
|
||||
|
||||
$expected = [
|
||||
'run_at' => $item,
|
||||
'source_files' => [],
|
||||
'environment' => ['packagist_version' => Version::VERSION],
|
||||
];
|
||||
|
||||
self::assertSame($expected, $object->toArray());
|
||||
self::assertSame(json_encode($expected), (string) $object);
|
||||
}
|
||||
|
||||
// fillJobs()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldFillJobsForServiceJobId()
|
||||
{
|
||||
$serviceName = 'travis-ci';
|
||||
$serviceJobId = '1.1';
|
||||
$serviceBuild = 123;
|
||||
|
||||
$env = [];
|
||||
$env['CI_NAME'] = $serviceName;
|
||||
$env['CI_JOB_ID'] = $serviceJobId;
|
||||
$env['CI_BUILD_NUMBER'] = $serviceBuild;
|
||||
|
||||
$object = $this->collectJsonFile();
|
||||
|
||||
$same = $object->fillJobs($env);
|
||||
|
||||
self::assertSame($same, $object);
|
||||
self::assertSame($serviceName, $object->getServiceName());
|
||||
self::assertSame($serviceJobId, $object->getServiceJobId());
|
||||
self::assertSame($serviceBuild, $object->getServiceNumber());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldFillJobsForServiceNumber()
|
||||
{
|
||||
$repoToken = 'token';
|
||||
$serviceName = 'circleci';
|
||||
$serviceNumber = '123';
|
||||
|
||||
$env = [];
|
||||
$env['COVERALLS_REPO_TOKEN'] = $repoToken;
|
||||
$env['CI_NAME'] = $serviceName;
|
||||
$env['CI_BUILD_NUMBER'] = $serviceNumber;
|
||||
|
||||
$object = $this->collectJsonFile();
|
||||
|
||||
$same = $object->fillJobs($env);
|
||||
|
||||
self::assertSame($same, $object);
|
||||
self::assertSame($repoToken, $object->getRepoToken());
|
||||
self::assertSame($serviceName, $object->getServiceName());
|
||||
self::assertSame($serviceNumber, $object->getServiceNumber());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldFillJobsForStandardizedEnvVars()
|
||||
{
|
||||
/*
|
||||
* CI_NAME=codeship
|
||||
* CI_BUILD_NUMBER=108821
|
||||
* CI_BUILD_URL=https://www.codeship.io/projects/2777/builds/108821
|
||||
* CI_BRANCH=master
|
||||
* CI_PULL_REQUEST=false
|
||||
*/
|
||||
|
||||
$repoToken = 'token';
|
||||
$parallel = true;
|
||||
$serviceName = 'codeship';
|
||||
$serviceNumber = '108821';
|
||||
$serviceBuildUrl = 'https://www.codeship.io/projects/2777/builds/108821';
|
||||
$serviceBranch = 'master';
|
||||
$servicePullRequest = 'false';
|
||||
|
||||
$env = [];
|
||||
$env['COVERALLS_REPO_TOKEN'] = $repoToken;
|
||||
$env['COVERALLS_PARALLEL'] = $parallel;
|
||||
$env['CI_NAME'] = $serviceName;
|
||||
$env['CI_BUILD_NUMBER'] = $serviceNumber;
|
||||
$env['CI_BUILD_URL'] = $serviceBuildUrl;
|
||||
$env['CI_BRANCH'] = $serviceBranch;
|
||||
$env['CI_PULL_REQUEST'] = $servicePullRequest;
|
||||
|
||||
$object = $this->collectJsonFile();
|
||||
|
||||
$same = $object->fillJobs($env);
|
||||
|
||||
self::assertSame($same, $object);
|
||||
self::assertSame($repoToken, $object->getRepoToken());
|
||||
self::assertSame($parallel, $object->getParallel());
|
||||
self::assertSame($serviceName, $object->getServiceName());
|
||||
self::assertSame($serviceNumber, $object->getServiceNumber());
|
||||
self::assertSame($serviceBuildUrl, $object->getServiceBuildUrl());
|
||||
self::assertSame($serviceBranch, $object->getServiceBranch());
|
||||
self::assertSame($servicePullRequest, $object->getServicePullRequest());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldFillJobsForServiceEventType()
|
||||
{
|
||||
$repoToken = 'token';
|
||||
$serviceName = 'php-coveralls';
|
||||
$serviceEventType = 'manual';
|
||||
|
||||
$env = [];
|
||||
$env['COVERALLS_REPO_TOKEN'] = $repoToken;
|
||||
$env['COVERALLS_RUN_LOCALLY'] = '1';
|
||||
$env['COVERALLS_EVENT_TYPE'] = $serviceEventType;
|
||||
$env['CI_NAME'] = $serviceName;
|
||||
|
||||
$object = $this->collectJsonFile();
|
||||
|
||||
$same = $object->fillJobs($env);
|
||||
|
||||
self::assertSame($same, $object);
|
||||
self::assertSame($repoToken, $object->getRepoToken());
|
||||
self::assertSame($serviceName, $object->getServiceName());
|
||||
self::assertNull($object->getServiceJobId());
|
||||
self::assertSame($serviceEventType, $object->getServiceEventType());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldFillJobsForGithubActions()
|
||||
{
|
||||
$repoToken = 'token';
|
||||
$serviceName = 'github';
|
||||
$serviceJobId = '1.1';
|
||||
|
||||
$env = [];
|
||||
$env['CI_NAME'] = $serviceName;
|
||||
$env['CI_JOB_ID'] = $serviceJobId;
|
||||
$env['COVERALLS_REPO_TOKEN'] = $repoToken;
|
||||
|
||||
$object = $this->collectJsonFile();
|
||||
|
||||
$same = $object->fillJobs($env);
|
||||
|
||||
self::assertSame($same, $object);
|
||||
self::assertSame($serviceName, $object->getServiceName());
|
||||
self::assertSame($serviceJobId, $object->getServiceJobId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldFillJobsForUnsupportedJob()
|
||||
{
|
||||
$repoToken = 'token';
|
||||
|
||||
$env = [];
|
||||
$env['COVERALLS_REPO_TOKEN'] = $repoToken;
|
||||
|
||||
$object = $this->collectJsonFile();
|
||||
|
||||
$same = $object->fillJobs($env);
|
||||
|
||||
self::assertSame($same, $object);
|
||||
self::assertSame($repoToken, $object->getRepoToken());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function throwRuntimeExceptionOnFillingJobsIfInvalidEnv()
|
||||
{
|
||||
$this->expectException(\PhpCoveralls\Bundle\CoverallsBundle\Entity\Exception\RequirementsNotSatisfiedException::class);
|
||||
|
||||
$env = [];
|
||||
|
||||
$object = $this->collectJsonFile();
|
||||
|
||||
$object->fillJobs($env);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function throwRuntimeExceptionOnFillingJobsWithoutSourceFiles()
|
||||
{
|
||||
$this->expectException(\RuntimeException::class);
|
||||
|
||||
$env = [];
|
||||
$env['TRAVIS'] = true;
|
||||
$env['TRAVIS_BUILD_NUMBER'] = '123';
|
||||
$env['TRAVIS_JOB_ID'] = '1.1';
|
||||
|
||||
$object = $this->collectJsonFileWithoutSourceFiles();
|
||||
|
||||
$object->fillJobs($env);
|
||||
}
|
||||
|
||||
// reportLineCoverage()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldReportLineCoverage()
|
||||
{
|
||||
$object = $this->collectJsonFile();
|
||||
|
||||
self::assertSame(50.0, $object->reportLineCoverage());
|
||||
|
||||
$metrics = $object->getMetrics();
|
||||
|
||||
self::assertSame(2, $metrics->getStatements());
|
||||
self::assertSame(1, $metrics->getCoveredStatements());
|
||||
self::assertSame(50.0, $metrics->getLineCoverage());
|
||||
}
|
||||
|
||||
// excludeNoStatementsFiles()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldExcludeNoStatementsFiles()
|
||||
{
|
||||
$srcDir = $this->srcDir . \DIRECTORY_SEPARATOR;
|
||||
|
||||
$object = $this->collectJsonFile();
|
||||
|
||||
// before excluding
|
||||
$sourceFiles = $object->getSourceFiles();
|
||||
self::assertCount(4, $sourceFiles);
|
||||
|
||||
// filenames
|
||||
$paths = array_keys($sourceFiles);
|
||||
$filenames = array_map(function ($path) use ($srcDir) {return str_replace($srcDir, '', $path); }, $paths);
|
||||
|
||||
self::assertContains('test.php', $filenames);
|
||||
self::assertContains('test2.php', $filenames);
|
||||
self::assertContains('TestInterface.php', $filenames);
|
||||
self::assertContains('AbstractClass.php', $filenames);
|
||||
|
||||
// after excluding
|
||||
$object->excludeNoStatementsFiles();
|
||||
|
||||
$sourceFiles = $object->getSourceFiles();
|
||||
self::assertCount(2, $sourceFiles);
|
||||
|
||||
// filenames
|
||||
$paths = array_keys($sourceFiles);
|
||||
$filenames = array_map(function ($path) use ($srcDir) {return str_replace($srcDir, '', $path); }, $paths);
|
||||
|
||||
self::assertContains('test.php', $filenames);
|
||||
self::assertContains('test2.php', $filenames);
|
||||
self::assertNotContains('TestInterface.php', $filenames);
|
||||
self::assertNotContains('AbstractClass.php', $filenames);
|
||||
}
|
||||
|
||||
protected function legacySetUp()
|
||||
{
|
||||
$this->setUpDir(realpath(__DIR__ . '/../../..'));
|
||||
|
||||
$this->object = new JsonFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SourceFile
|
||||
*/
|
||||
protected function createSourceFile()
|
||||
{
|
||||
$filename = 'test.php';
|
||||
$path = $this->srcDir . \DIRECTORY_SEPARATOR . $filename;
|
||||
|
||||
return new SourceFile($path, $filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getCloverXml()
|
||||
{
|
||||
$xml = <<<'XML'
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<coverage generated="1365848893">
|
||||
<project timestamp="1365848893">
|
||||
<file name="%s/test.php">
|
||||
<class name="TestFile" namespace="global">
|
||||
<metrics methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="1" coveredstatements="0" elements="2" coveredelements="0"/>
|
||||
</class>
|
||||
<line num="5" type="method" name="__construct" crap="1" count="0"/>
|
||||
<line num="7" type="stmt" count="1"/>
|
||||
</file>
|
||||
<file name="%s/TestInterface.php">
|
||||
<class name="TestInterface" namespace="global">
|
||||
<metrics methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="0" coveredstatements="0" elements="1" coveredelements="0"/>
|
||||
</class>
|
||||
<line num="5" type="method" name="hello" crap="1" count="0"/>
|
||||
</file>
|
||||
<file name="%s/AbstractClass.php">
|
||||
<class name="AbstractClass" namespace="global">
|
||||
<metrics methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="0" coveredstatements="0" elements="1" coveredelements="0"/>
|
||||
</class>
|
||||
<line num="5" type="method" name="hello" crap="1" count="0"/>
|
||||
</file>
|
||||
<file name="dummy.php">
|
||||
<class name="TestFile" namespace="global">
|
||||
<metrics methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="1" coveredstatements="0" elements="2" coveredelements="0"/>
|
||||
</class>
|
||||
<line num="5" type="method" name="__construct" crap="1" count="0"/>
|
||||
<line num="7" type="stmt" count="0"/>
|
||||
</file>
|
||||
<package name="Hoge">
|
||||
<file name="%s/test2.php">
|
||||
<class name="TestFile" namespace="Hoge">
|
||||
<metrics methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="1" coveredstatements="0" elements="2" coveredelements="0"/>
|
||||
</class>
|
||||
<line num="6" type="method" name="__construct" crap="1" count="0"/>
|
||||
<line num="8" type="stmt" count="0"/>
|
||||
</file>
|
||||
</package>
|
||||
</project>
|
||||
</coverage>
|
||||
XML;
|
||||
|
||||
return sprintf($xml, $this->srcDir, $this->srcDir, $this->srcDir, $this->srcDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \SimpleXMLElement
|
||||
*/
|
||||
protected function createCloverXml()
|
||||
{
|
||||
$xml = $this->getCloverXml();
|
||||
|
||||
return simplexml_load_string($xml);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JsonFile
|
||||
*/
|
||||
protected function collectJsonFile()
|
||||
{
|
||||
$xml = $this->createCloverXml();
|
||||
$collector = new CloverXmlCoverageCollector();
|
||||
|
||||
return $collector->collect($xml, $this->srcDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getNoSourceCloverXml()
|
||||
{
|
||||
return <<<'XML'
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<coverage generated="1365848893">
|
||||
<project timestamp="1365848893">
|
||||
<file name="dummy.php">
|
||||
<class name="TestFile" namespace="global">
|
||||
<metrics methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="1" coveredstatements="0" elements="2" coveredelements="0"/>
|
||||
</class>
|
||||
<line num="5" type="method" name="__construct" crap="1" count="0"/>
|
||||
<line num="7" type="stmt" count="0"/>
|
||||
</file>
|
||||
</project>
|
||||
</coverage>
|
||||
XML;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \SimpleXMLElement
|
||||
*/
|
||||
protected function createNoSourceCloverXml()
|
||||
{
|
||||
$xml = $this->getNoSourceCloverXml();
|
||||
|
||||
return simplexml_load_string($xml);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JsonFile
|
||||
*/
|
||||
protected function collectJsonFileWithoutSourceFiles()
|
||||
{
|
||||
$xml = $this->createNoSourceCloverXml();
|
||||
$collector = new CloverXmlCoverageCollector();
|
||||
|
||||
return $collector->collect($xml, $this->srcDir);
|
||||
}
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Tests\Bundle\CoverallsBundle\Entity;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\Metrics;
|
||||
use PhpCoveralls\Tests\ProjectTestCase;
|
||||
|
||||
/**
|
||||
* @covers \PhpCoveralls\Bundle\CoverallsBundle\Entity\Metrics
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class MetricsTest extends ProjectTestCase
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $coverage;
|
||||
|
||||
// hasStatements()
|
||||
// getStatements()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveStatementsOnConstructionWithoutCoverage()
|
||||
{
|
||||
$object = new Metrics();
|
||||
|
||||
self::assertFalse($object->hasStatements());
|
||||
self::assertSame(0, $object->getStatements());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldHaveStatementsOnConstructionWithCoverage()
|
||||
{
|
||||
$object = new Metrics($this->coverage);
|
||||
|
||||
self::assertTrue($object->hasStatements());
|
||||
self::assertSame(3, $object->getStatements());
|
||||
}
|
||||
|
||||
// getCoveredStatements()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveCoveredStatementsOnConstructionWithoutCoverage()
|
||||
{
|
||||
$object = new Metrics();
|
||||
|
||||
self::assertSame(0, $object->getCoveredStatements());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldHaveCoveredStatementsOnConstructionWithCoverage()
|
||||
{
|
||||
$object = new Metrics($this->coverage);
|
||||
|
||||
self::assertSame(2, $object->getCoveredStatements());
|
||||
}
|
||||
|
||||
// getLineCoverage()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotHaveLineCoverageOnConstructionWithoutCoverage()
|
||||
{
|
||||
$object = new Metrics();
|
||||
|
||||
self::assertSame(0, $object->getLineCoverage());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldHaveLineCoverageOnConstructionWithCoverage()
|
||||
{
|
||||
$object = new Metrics($this->coverage);
|
||||
|
||||
$this->assertWithDelta(200 / 3, $object->getLineCoverage(), 0.0000000000001);
|
||||
}
|
||||
|
||||
// merge()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldMergeThatWithEmptyMetrics()
|
||||
{
|
||||
$object = new Metrics();
|
||||
$that = new Metrics($this->coverage);
|
||||
$object->merge($that);
|
||||
|
||||
self::assertSame(3, $object->getStatements());
|
||||
self::assertSame(2, $object->getCoveredStatements());
|
||||
$this->assertWithDelta(200 / 3, $object->getLineCoverage(), 0.0000000000001);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldMergeThat()
|
||||
{
|
||||
$object = new Metrics($this->coverage);
|
||||
$that = new Metrics($this->coverage);
|
||||
$object->merge($that);
|
||||
|
||||
self::assertSame(6, $object->getStatements());
|
||||
self::assertSame(4, $object->getCoveredStatements());
|
||||
$this->assertWithDelta(400 / 6, $object->getLineCoverage(), 0.0000000000001);
|
||||
}
|
||||
|
||||
protected function legacySetUp()
|
||||
{
|
||||
$this->coverage = array_fill(0, 5, null);
|
||||
$this->coverage[1] = 1;
|
||||
$this->coverage[3] = 1;
|
||||
$this->coverage[4] = 0;
|
||||
}
|
||||
|
||||
private function assertWithDelta($expected, $actual, $delta, $message = '')
|
||||
{
|
||||
if (method_exists(ProjectTestCase::class, 'assertEqualsWithDelta')) {
|
||||
parent::assertEqualsWithDelta($expected, $actual, $delta, $message);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
self::assertEquals($expected, $actual, $message, $delta);
|
||||
}
|
||||
}
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Tests\Bundle\CoverallsBundle\Entity;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\SourceFile;
|
||||
use PhpCoveralls\Tests\ProjectTestCase;
|
||||
|
||||
/**
|
||||
* @covers \PhpCoveralls\Bundle\CoverallsBundle\Entity\Coveralls
|
||||
* @covers \PhpCoveralls\Bundle\CoverallsBundle\Entity\SourceFile
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class SourceFileTest extends ProjectTestCase
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $path;
|
||||
|
||||
/**
|
||||
* @var SourceFile
|
||||
*/
|
||||
private $object;
|
||||
|
||||
// getName()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldHaveNameOnConstruction()
|
||||
{
|
||||
self::assertSame($this->filename, $this->object->getName());
|
||||
}
|
||||
|
||||
// getSource()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldHaveSourceOnConstruction()
|
||||
{
|
||||
$expected = trim(file_get_contents($this->path));
|
||||
|
||||
self::assertSame($expected, $this->object->getSource());
|
||||
}
|
||||
|
||||
// getCoverage()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldHaveNullCoverageOnConstruction()
|
||||
{
|
||||
$expected = array_fill(0, 9, null);
|
||||
|
||||
self::assertSame($expected, $this->object->getCoverage());
|
||||
}
|
||||
|
||||
// getPath()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldHavePathOnConstruction()
|
||||
{
|
||||
$this->assertSamePath($this->path, $this->object->getPath());
|
||||
}
|
||||
|
||||
// getFileLines()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldHaveFileLinesOnConstruction()
|
||||
{
|
||||
self::assertSame(9, $this->object->getFileLines());
|
||||
}
|
||||
|
||||
// toArray()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldConvertToArray()
|
||||
{
|
||||
$expected = [
|
||||
'name' => $this->filename,
|
||||
'source' => trim(file_get_contents($this->path)),
|
||||
'coverage' => array_fill(0, 9, null),
|
||||
];
|
||||
|
||||
self::assertSame($expected, $this->object->toArray());
|
||||
self::assertSame(json_encode($expected), (string) $this->object);
|
||||
}
|
||||
|
||||
// addCoverage()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldAddCoverage()
|
||||
{
|
||||
$this->object->addCoverage(5, 1);
|
||||
|
||||
$expected = array_fill(0, 9, null);
|
||||
$expected[5] = 1;
|
||||
|
||||
self::assertSame($expected, $this->object->getCoverage());
|
||||
}
|
||||
|
||||
// getMetrics()
|
||||
// reportLineCoverage()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldReportLineCoverage0PercentWithoutAddingCoverage()
|
||||
{
|
||||
$metrics = $this->object->getMetrics();
|
||||
|
||||
self::assertSame(0, $metrics->getStatements());
|
||||
self::assertSame(0, $metrics->getCoveredStatements());
|
||||
self::assertSame(0, $metrics->getLineCoverage());
|
||||
self::assertSame(0, $this->object->reportLineCoverage());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldReportLineCoverage100PercentAfterAddingCoverage()
|
||||
{
|
||||
$this->object->addCoverage(6, 1);
|
||||
|
||||
$metrics = $this->object->getMetrics();
|
||||
|
||||
self::assertSame(1, $metrics->getStatements());
|
||||
self::assertSame(1, $metrics->getCoveredStatements());
|
||||
self::assertSame(100, $metrics->getLineCoverage());
|
||||
self::assertSame(100, $this->object->reportLineCoverage());
|
||||
}
|
||||
|
||||
protected function legacySetUp()
|
||||
{
|
||||
$this->setUpDir(realpath(__DIR__ . '/../../..'));
|
||||
|
||||
$this->filename = 'test.php';
|
||||
$this->path = $this->srcDir . \DIRECTORY_SEPARATOR . $this->filename;
|
||||
|
||||
$this->object = new SourceFile($this->path, $this->filename);
|
||||
}
|
||||
}
|
||||
+459
@@ -0,0 +1,459 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Tests\Bundle\CoverallsBundle\Repository;
|
||||
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Api\Jobs;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Config\Configuration;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\Exception\RequirementsNotSatisfiedException;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\JsonFile;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\Metrics;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Entity\SourceFile;
|
||||
use PhpCoveralls\Bundle\CoverallsBundle\Repository\JobsRepository;
|
||||
use PhpCoveralls\Tests\ProjectTestCase;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\NullLogger;
|
||||
|
||||
/**
|
||||
* @covers \PhpCoveralls\Bundle\CoverallsBundle\Repository\JobsRepository
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class JobsRepositoryTest extends ProjectTestCase
|
||||
{
|
||||
// persist()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldPersist()
|
||||
{
|
||||
$statusCode = 200;
|
||||
$url = 'https://coveralls.io/jobs/67528';
|
||||
$response = new \GuzzleHttp\Psr7\Response(
|
||||
$statusCode,
|
||||
[],
|
||||
json_encode([
|
||||
'message' => 'Job #115.3',
|
||||
'url' => $url,
|
||||
]),
|
||||
'1.1',
|
||||
'OK'
|
||||
);
|
||||
$api = $this->createApiMock($response, $statusCode, $url);
|
||||
$config = $this->createConfiguration();
|
||||
$logger = $this->createLoggerMock();
|
||||
|
||||
$object = new JobsRepository($api, $config);
|
||||
|
||||
$object->setLogger($logger);
|
||||
self::assertTrue($object->persist());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldPersistDryRun()
|
||||
{
|
||||
$api = $this->createApiMock(null, 200); // params means API won't crash, but it will return null, as it does for dry-run
|
||||
$config = $this->createConfiguration();
|
||||
$logger = $this->createLoggerMock();
|
||||
|
||||
$object = new JobsRepository($api, $config);
|
||||
|
||||
$object->setLogger($logger);
|
||||
self::assertTrue($object->persist());
|
||||
}
|
||||
|
||||
// unexpected Exception
|
||||
// source files not found
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function unexpectedException()
|
||||
{
|
||||
$api = $this->createApiMockWithException();
|
||||
$config = $this->createConfiguration();
|
||||
$logger = $this->createLoggerMock();
|
||||
|
||||
$object = new JobsRepository($api, $config);
|
||||
|
||||
$object->setLogger($logger);
|
||||
self::assertFalse($object->persist());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function requirementsNotSatisfiedException()
|
||||
{
|
||||
$api = $this->createApiMockWithRequirementsNotSatisfiedException();
|
||||
$config = $this->createConfiguration();
|
||||
$logger = $this->createLoggerMock();
|
||||
|
||||
$object = new JobsRepository($api, $config);
|
||||
|
||||
$object->setLogger($logger);
|
||||
self::assertFalse($object->persist());
|
||||
}
|
||||
|
||||
// curl error
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function networkDisconnected()
|
||||
{
|
||||
$api = $this->createApiMock(null, null);
|
||||
$config = $this->createConfiguration();
|
||||
$logger = $this->createLoggerMock();
|
||||
|
||||
$object = new JobsRepository($api, $config);
|
||||
|
||||
$object->setLogger($logger);
|
||||
self::assertFalse($object->persist());
|
||||
}
|
||||
|
||||
// response 422
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function response422()
|
||||
{
|
||||
$statusCode = 422;
|
||||
$response = new \GuzzleHttp\Psr7\Response(
|
||||
$statusCode,
|
||||
[],
|
||||
json_encode([
|
||||
'message' => 'Build processing error.',
|
||||
'url' => '',
|
||||
'error' => true,
|
||||
]),
|
||||
'1.1',
|
||||
'Unprocessable Entity'
|
||||
);
|
||||
$api = $this->createApiMock($response, $statusCode);
|
||||
$config = $this->createConfiguration();
|
||||
$logger = $this->createLoggerMock();
|
||||
|
||||
$object = new JobsRepository($api, $config);
|
||||
|
||||
$object->setLogger($logger);
|
||||
self::assertFalse($object->persist());
|
||||
}
|
||||
|
||||
// response 500
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function response500()
|
||||
{
|
||||
$statusCode = 500;
|
||||
$response = new \GuzzleHttp\Psr7\Response($statusCode, [], null, '1.1', 'Internal Server Error');
|
||||
$api = $this->createApiMock($response, $statusCode);
|
||||
$config = $this->createConfiguration();
|
||||
$logger = $this->createLoggerMock();
|
||||
|
||||
$object = new JobsRepository($api, $config);
|
||||
|
||||
$object->setLogger($logger);
|
||||
self::assertFalse($object->persist());
|
||||
}
|
||||
|
||||
protected function legacySetUp()
|
||||
{
|
||||
$this->setUpDir(realpath(__DIR__ . '/../../..'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Jobs
|
||||
*/
|
||||
protected function createApiMockWithRequirementsNotSatisfiedException()
|
||||
{
|
||||
$api = $this->prophesize(Jobs::class);
|
||||
$this->setUpJobsApiWithCollectCloverXmlThrow($api, new RequirementsNotSatisfiedException());
|
||||
$this->setUpJobsApiWithGetJsonFileNotCalled($api);
|
||||
$this->setUpJobsApiWithCollectGitInfoNotCalled($api);
|
||||
$this->setUpJobsApiWithCollectEnvVarsNotCalled($api);
|
||||
$this->setUpJobsApiWithDumpJsonFileNotCalled($api);
|
||||
$this->setUpJobsApiWithSendNotCalled($api);
|
||||
|
||||
return $api->reveal();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Jobs
|
||||
*/
|
||||
protected function createApiMockWithException()
|
||||
{
|
||||
$api = $this->prophesize(Jobs::class);
|
||||
$this->setUpJobsApiWithCollectCloverXmlThrow($api, new \Exception('unexpected exception'));
|
||||
$this->setUpJobsApiWithGetJsonFileNotCalled($api);
|
||||
$this->setUpJobsApiWithCollectGitInfoNotCalled($api);
|
||||
$this->setUpJobsApiWithCollectEnvVarsNotCalled($api);
|
||||
$this->setUpJobsApiWithDumpJsonFileNotCalled($api);
|
||||
$this->setUpJobsApiWithSendNotCalled($api);
|
||||
|
||||
return $api->reveal();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|ResponseInterface $response
|
||||
* @param null|int $statusCode
|
||||
* @param string $uri
|
||||
*
|
||||
* @return Jobs
|
||||
*/
|
||||
protected function createApiMock($response, $statusCode = null, $uri = '/')
|
||||
{
|
||||
$api = $this->prophesize(Jobs::class);
|
||||
$this->setUpJobsApiWithCollectCloverXmlCalled($api);
|
||||
$this->setUpJobsApiWithGetJsonFileCalled($api, $this->createJsonFile());
|
||||
$this->setUpJobsApiWithCollectGitInfoCalled($api);
|
||||
$this->setUpJobsApiWithCollectEnvVarsCalled($api);
|
||||
$this->setUpJobsApiWithDumpJsonFileCalled($api);
|
||||
$this->setUpJobsApiWithSendCalled($api, $statusCode, new \GuzzleHttp\Psr7\Request('POST', $uri), $response);
|
||||
|
||||
return $api->reveal();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LoggerInterface
|
||||
*/
|
||||
protected function createLoggerMock()
|
||||
{
|
||||
$logger = $this->prophesize(NullLogger::class);
|
||||
$logger->info();
|
||||
$logger->error();
|
||||
|
||||
return $logger->reveal();
|
||||
}
|
||||
|
||||
// dependent object
|
||||
|
||||
/**
|
||||
* @param int $percent
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function createCoverage($percent)
|
||||
{
|
||||
// percent = (covered / stmt) * 100;
|
||||
// (percent * stmt) / 100 = covered
|
||||
$stmt = 100;
|
||||
$covered = ($percent * $stmt) / 100;
|
||||
$coverage = array_fill(0, 100, 0);
|
||||
|
||||
for ($i = 0; $i < $covered; ++$i) {
|
||||
$coverage[$i] = 1;
|
||||
}
|
||||
|
||||
return $coverage;
|
||||
}
|
||||
|
||||
protected function createJsonFile()
|
||||
{
|
||||
$jsonFile = new JsonFile();
|
||||
|
||||
$repositoryTestDir = $this->srcDir . '/RepositoryTest';
|
||||
|
||||
$sourceFiles = [
|
||||
0 => new SourceFile($repositoryTestDir . '/Coverage0.php', 'Coverage0.php'),
|
||||
10 => new SourceFile($repositoryTestDir . '/Coverage10.php', 'Coverage10.php'),
|
||||
70 => new SourceFile($repositoryTestDir . '/Coverage70.php', 'Coverage70.php'),
|
||||
80 => new SourceFile($repositoryTestDir . '/Coverage80.php', 'Coverage80.php'),
|
||||
90 => new SourceFile($repositoryTestDir . '/Coverage90.php', 'Coverage90.php'),
|
||||
100 => new SourceFile($repositoryTestDir . '/Coverage100.php', 'Coverage100.php'),
|
||||
];
|
||||
|
||||
foreach ($sourceFiles as $percent => $sourceFile) {
|
||||
$sourceFile->getMetrics()->merge(new Metrics($this->createCoverage($percent)));
|
||||
$jsonFile->addSourceFile($sourceFile);
|
||||
}
|
||||
|
||||
return $jsonFile;
|
||||
}
|
||||
|
||||
protected function createConfiguration()
|
||||
{
|
||||
$config = new Configuration();
|
||||
|
||||
return $config->addCloverXmlPath($this->cloverXmlPath);
|
||||
}
|
||||
|
||||
// mock
|
||||
|
||||
/**
|
||||
* @param Jobs $api
|
||||
*/
|
||||
private function setUpJobsApiWithCollectCloverXmlCalled($api)
|
||||
{
|
||||
$api
|
||||
->collectCloverXml()
|
||||
->will(function () {
|
||||
return $this;
|
||||
})
|
||||
->shouldBeCalled()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Jobs $api
|
||||
* @param \Exception $exception
|
||||
*/
|
||||
private function setUpJobsApiWithCollectCloverXmlThrow($api, $exception)
|
||||
{
|
||||
$api
|
||||
->collectCloverXml()
|
||||
->willThrow($exception)
|
||||
->shouldBeCalled()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Jobs $api
|
||||
* @param JsonFile $jsonFile
|
||||
*/
|
||||
private function setUpJobsApiWithGetJsonFileCalled($api, $jsonFile)
|
||||
{
|
||||
$api
|
||||
->getJsonFile()
|
||||
->willReturn($jsonFile)
|
||||
->shouldBeCalled()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Jobs $api
|
||||
*/
|
||||
private function setUpJobsApiWithGetJsonFileNotCalled($api)
|
||||
{
|
||||
$api
|
||||
->getJsonFile()
|
||||
->shouldNotBeCalled()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Jobs $api
|
||||
*/
|
||||
private function setUpJobsApiWithCollectGitInfoCalled($api)
|
||||
{
|
||||
$api
|
||||
->collectGitInfo()
|
||||
->will(function () {
|
||||
return $this;
|
||||
})
|
||||
->shouldBeCalled()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Jobs $api
|
||||
*/
|
||||
private function setUpJobsApiWithCollectGitInfoNotCalled($api)
|
||||
{
|
||||
$api
|
||||
->collectGitInfo()
|
||||
->shouldNotBeCalled()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Jobs $api
|
||||
*/
|
||||
private function setUpJobsApiWithCollectEnvVarsCalled($api)
|
||||
{
|
||||
$api
|
||||
->collectEnvVars($_SERVER)
|
||||
->will(function () {
|
||||
return $this;
|
||||
})
|
||||
->shouldBeCalled()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Jobs $api
|
||||
*/
|
||||
private function setUpJobsApiWithCollectEnvVarsNotCalled($api)
|
||||
{
|
||||
$api
|
||||
->collectEnvVars()
|
||||
->shouldNotBeCalled()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Jobs $api
|
||||
*/
|
||||
private function setUpJobsApiWithDumpJsonFileCalled($api)
|
||||
{
|
||||
$api
|
||||
->dumpJsonFile()
|
||||
->will(function () {
|
||||
return $this;
|
||||
})
|
||||
->shouldBeCalled()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Jobs $api
|
||||
*/
|
||||
private function setUpJobsApiWithDumpJsonFileNotCalled($api)
|
||||
{
|
||||
$api
|
||||
->dumpJsonFile()
|
||||
->shouldNotBeCalled()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Jobs $api
|
||||
* @param null|int $statusCode
|
||||
* @param RequestInterface $request
|
||||
* @param null|ResponseInterface $response
|
||||
*/
|
||||
private function setUpJobsApiWithSendCalled($api, $statusCode, $request, $response)
|
||||
{
|
||||
if ($statusCode === 200) {
|
||||
$api
|
||||
->send()
|
||||
->willReturn($response)
|
||||
->shouldBeCalled()
|
||||
;
|
||||
} else {
|
||||
if ($statusCode === null) {
|
||||
$exception = new \GuzzleHttp\Exception\ConnectException('Connection refused', $request);
|
||||
} elseif ($statusCode === 422) {
|
||||
$exception = \GuzzleHttp\Exception\ClientException::create($request, $response);
|
||||
} else {
|
||||
$exception = \GuzzleHttp\Exception\ServerException::create($request, $response);
|
||||
}
|
||||
|
||||
$api
|
||||
->send()
|
||||
->willThrow($exception)
|
||||
->shouldBeCalled()
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Jobs $api
|
||||
*/
|
||||
private function setUpJobsApiWithSendNotCalled($api)
|
||||
{
|
||||
$api
|
||||
->send()
|
||||
->shouldNotBeCalled()
|
||||
;
|
||||
}
|
||||
}
|
||||
Vendored
+507
@@ -0,0 +1,507 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Tests\Component\File;
|
||||
|
||||
use PhpCoveralls\Component\File\Path;
|
||||
use PhpCoveralls\Tests\ProjectTestCase;
|
||||
|
||||
/**
|
||||
* @covers \PhpCoveralls\Component\File\Path
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class PathTest extends ProjectTestCase
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $existingFile;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $unreadablePath;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $unwritablePath;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $unwritableDir;
|
||||
|
||||
/**
|
||||
* @var Path
|
||||
*/
|
||||
private $object;
|
||||
|
||||
// provider
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function provideRelativePaths()
|
||||
{
|
||||
return [
|
||||
[''],
|
||||
['.'],
|
||||
['..'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function provideShouldNotBeRelativePathCases()
|
||||
{
|
||||
if ($this->isWindowsOS()) {
|
||||
return [
|
||||
['c:\\'],
|
||||
['z:\\path\\to\\somewhere'],
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
['/'],
|
||||
['/path/to/somewhere'],
|
||||
];
|
||||
}
|
||||
|
||||
// isRelativePath()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @dataProvider provideRelativePaths
|
||||
*
|
||||
* @param mixed $path
|
||||
*/
|
||||
public function shouldBeRelativePath($path)
|
||||
{
|
||||
self::assertTrue($this->object->isRelativePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @dataProvider provideShouldNotBeRelativePathCases
|
||||
*
|
||||
* @param mixed $path
|
||||
*/
|
||||
public function shouldNotBeRelativePath($path)
|
||||
{
|
||||
self::assertFalse($this->object->isRelativePath($path));
|
||||
}
|
||||
|
||||
// toAbsolutePath()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotConvertAbsolutePath()
|
||||
{
|
||||
$path = false;
|
||||
$rootDir = __DIR__;
|
||||
|
||||
self::assertFalse($this->object->toAbsolutePath($path, $rootDir));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @dataProvider provideRelativePaths
|
||||
*
|
||||
* @param mixed $path
|
||||
*/
|
||||
public function shouldConvertAbsolutePathIfRelativePathGiven($path)
|
||||
{
|
||||
$rootDir = '/path/to/dir';
|
||||
|
||||
$expected = $rootDir . \DIRECTORY_SEPARATOR . $path;
|
||||
|
||||
self::assertSame($expected, $this->object->toAbsolutePath($path, $rootDir));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldConvertAbsolutePathIfAbsolutePathGiven()
|
||||
{
|
||||
$rootDir = '/path/to/dir';
|
||||
$path = __DIR__;
|
||||
|
||||
$expected = $path;
|
||||
|
||||
self::assertSame($expected, $this->object->toAbsolutePath($path, $rootDir));
|
||||
}
|
||||
|
||||
// getRealPath()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotBeRealPath()
|
||||
{
|
||||
$path = false;
|
||||
$rootDir = __DIR__;
|
||||
|
||||
self::assertFalse($this->object->getRealPath($path, $rootDir));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @dataProvider provideRelativePaths
|
||||
*
|
||||
* @param mixed $path
|
||||
*/
|
||||
public function shouldGetRealPathIfRelativePathGiven($path)
|
||||
{
|
||||
$rootDir = __DIR__;
|
||||
|
||||
$expected = realpath($rootDir . \DIRECTORY_SEPARATOR . $path);
|
||||
|
||||
self::assertSame($expected, $this->object->getRealPath($path, $rootDir));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldGetRealPathIfAbsolutePathGiven()
|
||||
{
|
||||
$path = __DIR__;
|
||||
$rootDir = '';
|
||||
|
||||
$expected = realpath($path);
|
||||
|
||||
self::assertSame($expected, $this->object->getRealPath($path, $rootDir));
|
||||
}
|
||||
|
||||
// getRealDir()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotBeRealDir()
|
||||
{
|
||||
$path = false;
|
||||
$rootDir = __DIR__;
|
||||
|
||||
self::assertFalse($this->object->getRealDir($path, $rootDir));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldGetRealDirIfRelativePathGiven()
|
||||
{
|
||||
$path = '';
|
||||
$rootDir = __DIR__;
|
||||
|
||||
$expected = realpath($rootDir . \DIRECTORY_SEPARATOR . $path);
|
||||
|
||||
self::assertSame($expected, $this->object->getRealDir($path, $rootDir));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldGetRealDirIfAbsolutePathGiven()
|
||||
{
|
||||
$path = __DIR__;
|
||||
$rootDir = '';
|
||||
|
||||
$expected = realpath($path . '/..');
|
||||
|
||||
self::assertSame($expected, $this->object->getRealDir($path, $rootDir));
|
||||
}
|
||||
|
||||
// getRealWritingFilePath()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotBeRealWritingFilePath()
|
||||
{
|
||||
$path = false;
|
||||
$rootDir = __DIR__;
|
||||
|
||||
self::assertFalse($this->object->getRealWritingFilePath($path, $rootDir));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldGetRealWritingPathIfRelativePathGiven()
|
||||
{
|
||||
$path = 'test.txt';
|
||||
$rootDir = __DIR__;
|
||||
|
||||
$expected = $rootDir . \DIRECTORY_SEPARATOR . $path;
|
||||
|
||||
self::assertSame($expected, $this->object->getRealWritingFilePath($path, $rootDir));
|
||||
}
|
||||
|
||||
// isRealPathExist()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotExistRealPathIfFalseGiven()
|
||||
{
|
||||
$path = false;
|
||||
|
||||
self::assertFalse($this->object->isRealPathExist($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotExistRealPath()
|
||||
{
|
||||
$path = __DIR__ . '/dummy.dir';
|
||||
|
||||
self::assertFalse($this->object->isRealPathExist($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldExistRealPath()
|
||||
{
|
||||
touch($this->existingFile);
|
||||
|
||||
self::assertTrue($this->object->isRealPathExist($this->existingFile));
|
||||
}
|
||||
|
||||
// isRealFileExist()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotExistRealFile()
|
||||
{
|
||||
$path = __DIR__ . '/dummy.file';
|
||||
|
||||
self::assertFalse($this->object->isRealFileExist($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotExistRealFileIfDirGiven()
|
||||
{
|
||||
$path = __DIR__;
|
||||
|
||||
self::assertFalse($this->object->isRealFileExist($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldExistRealFile()
|
||||
{
|
||||
touch($this->existingFile);
|
||||
|
||||
self::assertTrue($this->object->isRealFileExist($this->existingFile));
|
||||
}
|
||||
|
||||
// isRealFileReadable()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotBeRealFileReadableIfFileNotFound()
|
||||
{
|
||||
$path = __DIR__ . '/dummy.file';
|
||||
|
||||
self::assertFalse($this->object->isRealFileReadable($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotBeRealFileReadableIfFileUnreadable()
|
||||
{
|
||||
if ($this->isWindowsOS()) {
|
||||
// On Windows there is no write-only attribute.
|
||||
self::markTestSkipped('Unable to run on Windows');
|
||||
}
|
||||
|
||||
$this->touchUnreadableFile();
|
||||
|
||||
self::assertFalse($this->object->isRealFileReadable($this->unreadablePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldBeRealFileReadable()
|
||||
{
|
||||
touch($this->existingFile);
|
||||
|
||||
self::assertTrue($this->object->isRealFileReadable($this->existingFile));
|
||||
}
|
||||
|
||||
// isRealFileWritable()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotBeRealFileWritableIfFileNotFound()
|
||||
{
|
||||
$path = __DIR__ . '/dummy.file';
|
||||
|
||||
self::assertFalse($this->object->isRealFileWritable($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotBeRealFileWritableIfFileUnwritable()
|
||||
{
|
||||
$this->touchUnwritableFile();
|
||||
|
||||
self::assertFalse($this->object->isRealFileWritable($this->unwritablePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldBeRealFileWritable()
|
||||
{
|
||||
touch($this->existingFile);
|
||||
|
||||
self::assertTrue($this->object->isRealFileWritable($this->existingFile));
|
||||
}
|
||||
|
||||
// isRealDirExist()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotExistRealDir()
|
||||
{
|
||||
$path = __DIR__ . '/dummy.dir';
|
||||
|
||||
self::assertFalse($this->object->isRealDirExist($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotExistRealDirIfFileGiven()
|
||||
{
|
||||
touch($this->existingFile);
|
||||
|
||||
self::assertFalse($this->object->isRealDirExist($this->existingFile));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldExistRealDir()
|
||||
{
|
||||
$path = __DIR__;
|
||||
|
||||
self::assertTrue($this->object->isRealDirExist($path));
|
||||
}
|
||||
|
||||
// isRealDirWritable()
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotBeRealDirWritableIfDirNotFound()
|
||||
{
|
||||
$path = __DIR__ . '/dummy.dir';
|
||||
|
||||
self::assertFalse($this->object->isRealDirWritable($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldNotBeRealDirWritableIfDirUnwritable()
|
||||
{
|
||||
if ($this->isWindowsOS()) {
|
||||
// On Windows read-only attribute on dir applies to files in dir, but not the dir itself.
|
||||
self::markTestSkipped('Unable to run on Windows');
|
||||
}
|
||||
|
||||
$this->mkdirUnwritableDir();
|
||||
|
||||
self::assertFalse($this->object->isRealDirWritable($this->unwritableDir));
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldBeRealDirWritable()
|
||||
{
|
||||
$path = __DIR__;
|
||||
|
||||
self::assertTrue($this->object->isRealDirWritable($path));
|
||||
}
|
||||
|
||||
protected function legacySetUp()
|
||||
{
|
||||
$this->existingFile = __DIR__ . '/existing.txt';
|
||||
$this->unreadablePath = __DIR__ . '/unreadable.txt';
|
||||
$this->unwritablePath = __DIR__ . '/unwritable.txt';
|
||||
$this->unwritableDir = __DIR__ . '/unwritable.dir';
|
||||
|
||||
$this->object = new Path();
|
||||
}
|
||||
|
||||
protected function legacyTearDown()
|
||||
{
|
||||
$this->rmFile($this->existingFile);
|
||||
$this->rmFile($this->unreadablePath);
|
||||
$this->rmFile($this->unwritablePath);
|
||||
|
||||
$this->rmDir($this->unwritableDir);
|
||||
}
|
||||
|
||||
protected function touchUnreadableFile()
|
||||
{
|
||||
$this->rmFile($this->unreadablePath);
|
||||
|
||||
touch($this->unreadablePath);
|
||||
chmod($this->unreadablePath, 0377);
|
||||
}
|
||||
|
||||
protected function touchUnwritableFile()
|
||||
{
|
||||
$this->rmFile($this->unwritablePath);
|
||||
|
||||
touch($this->unwritablePath);
|
||||
chmod($this->unwritablePath, 0577);
|
||||
}
|
||||
|
||||
protected function mkdirUnwritableDir()
|
||||
{
|
||||
$this->rmDir($this->unwritableDir);
|
||||
|
||||
mkdir($this->unwritableDir);
|
||||
chmod($this->unwritableDir, 0577);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function isWindowsOS()
|
||||
{
|
||||
static $isWindows;
|
||||
|
||||
if ($isWindows === null) {
|
||||
$isWindows = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
|
||||
}
|
||||
|
||||
return $isWindows;
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Tests\Component\Log;
|
||||
|
||||
use PhpCoveralls\Component\Log\ConsoleLogger;
|
||||
use PhpCoveralls\Tests\ProjectTestCase;
|
||||
use Symfony\Component\Console\Output\StreamOutput;
|
||||
|
||||
/**
|
||||
* @covers \PhpCoveralls\Component\Log\ConsoleLogger
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class ConsoleLoggerTest extends ProjectTestCase
|
||||
{
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldWritelnToOutput()
|
||||
{
|
||||
$message = 'log test message';
|
||||
$output = $this->createAdapterMockWith($message);
|
||||
|
||||
$object = new ConsoleLogger($output);
|
||||
|
||||
$object->log('info', $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
*
|
||||
* @return StreamOutput
|
||||
*/
|
||||
protected function createAdapterMockWith($message)
|
||||
{
|
||||
$mock = $this->prophesize(StreamOutput::class);
|
||||
$mock
|
||||
->writeln($message)
|
||||
->shouldBeCalled()
|
||||
;
|
||||
|
||||
return $mock->reveal();
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Tests\Component\System\Git;
|
||||
|
||||
use PhpCoveralls\Component\System\Git\GitCommand;
|
||||
use PhpCoveralls\Tests\ProjectTestCase;
|
||||
|
||||
/**
|
||||
* @covers \PhpCoveralls\Component\System\Git\GitCommand
|
||||
* @covers \PhpCoveralls\Component\System\SystemCommandExecutor
|
||||
*
|
||||
* @author Kitamura Satoshi <with.no.parachute@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class GitCommandTest extends ProjectTestCase
|
||||
{
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldReturnBranches()
|
||||
{
|
||||
$object = new GitCommand();
|
||||
$actual = $object->getBranches();
|
||||
|
||||
self::assertIsArray($actual);
|
||||
self::assertNotEmpty($actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldReturnHeadCommit()
|
||||
{
|
||||
$object = new GitCommand();
|
||||
$actual = $object->getHeadCommit();
|
||||
|
||||
self::assertIsArray($actual);
|
||||
self::assertNotEmpty($actual);
|
||||
self::assertCount(6, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldReturnRemotes()
|
||||
{
|
||||
$object = new GitCommand();
|
||||
$actual = $object->getRemotes();
|
||||
|
||||
self::assertIsArray($actual);
|
||||
self::assertNotEmpty($actual);
|
||||
}
|
||||
}
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
# empty config
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
abstract class AbstractClass
|
||||
{
|
||||
abstract public function hello();
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
namespace CoverallsTest;
|
||||
|
||||
class Coverage0
|
||||
{
|
||||
public function doSomething()
|
||||
{
|
||||
$var = '';
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
namespace CoverallsTest;
|
||||
|
||||
class Coverage10
|
||||
{
|
||||
public function doSomething()
|
||||
{
|
||||
$var = '';
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
namespace CoverallsTest;
|
||||
|
||||
class Coverage100
|
||||
{
|
||||
public function doSomething()
|
||||
{
|
||||
$var = '';
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
namespace CoverallsTest;
|
||||
|
||||
class Coverage70
|
||||
{
|
||||
public function doSomething()
|
||||
{
|
||||
$var = '';
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
namespace CoverallsTest;
|
||||
|
||||
class Coverage80
|
||||
{
|
||||
public function doSomething()
|
||||
{
|
||||
$var = '';
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
namespace CoverallsTest;
|
||||
|
||||
class Coverage90
|
||||
{
|
||||
public function doSomething()
|
||||
{
|
||||
$var = '';
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
interface TestInterface
|
||||
{
|
||||
public function hello();
|
||||
}
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
class TestFile
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->message = 'hoge';
|
||||
}
|
||||
}
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
namespace Hoge;
|
||||
|
||||
class TestFile
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->message = 'hoge';
|
||||
}
|
||||
}
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
namespace Hoge;
|
||||
|
||||
class TestFileBis
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->message = 'hoge';
|
||||
}
|
||||
}
|
||||
+212
@@ -0,0 +1,212 @@
|
||||
<?php
|
||||
|
||||
namespace PhpCoveralls\Tests;
|
||||
|
||||
use LegacyPHPUnit\TestCase;
|
||||
|
||||
abstract class ProjectTestCase extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $rootDir;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $srcDir;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $url;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $filename;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $buildDir;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $logsDir;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $cloverXmlPath;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $cloverXmlPath1;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $cloverXmlPath2;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $jsonPath;
|
||||
|
||||
public function __call($method, $args)
|
||||
{
|
||||
switch ($method) {
|
||||
case 'assertStringContainsString':
|
||||
\call_user_func_array([$this, 'assertContains'], $args);
|
||||
|
||||
break;
|
||||
|
||||
case 'assertIsArray':
|
||||
\call_user_func_array([$this, 'assertInternalType'], array_merge(['array'], $args));
|
||||
|
||||
break;
|
||||
|
||||
case 'expectException':
|
||||
\call_user_func_array([$this, 'setExpectedException'], $args);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
trigger_error("Call to undefined method ::$method", E_USER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $projectDir
|
||||
*/
|
||||
protected function setUpDir($projectDir)
|
||||
{
|
||||
$this->rootDir = realpath($projectDir . '/Fixture');
|
||||
$this->srcDir = realpath($this->rootDir . '/files');
|
||||
|
||||
$this->url = 'https://coveralls.io/api/v1/jobs';
|
||||
$this->filename = 'json_file';
|
||||
|
||||
// build
|
||||
$this->buildDir = $this->rootDir . '/build';
|
||||
$this->logsDir = $this->rootDir . '/build/logs';
|
||||
|
||||
// log
|
||||
$this->cloverXmlPath = $this->logsDir . '/clover.xml';
|
||||
$this->cloverXmlPath1 = $this->logsDir . '/clover-part1.xml';
|
||||
$this->cloverXmlPath2 = $this->logsDir . '/clover-part2.xml';
|
||||
$this->jsonPath = $this->logsDir . '/coveralls-upload.json';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $srcDir
|
||||
* @param string $logsDir
|
||||
* @param string|string[] $cloverXmlPaths
|
||||
* @param bool $logsDirUnwritable
|
||||
* @param bool $jsonPathUnwritable
|
||||
*/
|
||||
protected function makeProjectDir($srcDir = null, $logsDir = null, $cloverXmlPaths = null, $logsDirUnwritable = false, $jsonPathUnwritable = false)
|
||||
{
|
||||
if ($srcDir !== null && !is_dir($srcDir)) {
|
||||
mkdir($srcDir, 0777, true);
|
||||
}
|
||||
|
||||
if ($logsDir !== null && !is_dir($logsDir)) {
|
||||
mkdir($logsDir, 0777, true);
|
||||
}
|
||||
|
||||
if ($cloverXmlPaths !== null) {
|
||||
if (\is_array($cloverXmlPaths)) {
|
||||
foreach ($cloverXmlPaths as $cloverXmlPath) {
|
||||
touch($cloverXmlPath);
|
||||
}
|
||||
} else {
|
||||
touch($cloverXmlPaths);
|
||||
}
|
||||
}
|
||||
|
||||
if ($logsDirUnwritable && file_exists($logsDir)) {
|
||||
chmod($logsDir, 0577);
|
||||
}
|
||||
|
||||
if ($jsonPathUnwritable) {
|
||||
touch($this->jsonPath);
|
||||
chmod($this->jsonPath, 0577);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*/
|
||||
protected function rmFile($file)
|
||||
{
|
||||
if (is_file($file)) {
|
||||
// we try to unlock file, for that, we might need different permissions:
|
||||
chmod(\dirname($file), 0777); // on unix
|
||||
chmod($file, 0777); // on Windows
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $dir
|
||||
*/
|
||||
protected function rmDir($dir)
|
||||
{
|
||||
if (is_dir($dir)) {
|
||||
chmod($dir, 0777);
|
||||
rmdir($dir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function normalizePath($path)
|
||||
{
|
||||
return strtr(\DIRECTORY_SEPARATOR, '/', $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $expected
|
||||
* @param string $input
|
||||
* @param null|string $msg
|
||||
*/
|
||||
protected function assertSamePath($expected, $input, $msg = null)
|
||||
{
|
||||
if ($msg !== null) {
|
||||
self::assertSame(
|
||||
$this->normalizePath($expected),
|
||||
$this->normalizePath($input),
|
||||
$msg
|
||||
);
|
||||
} else {
|
||||
self::assertSame(
|
||||
$this->normalizePath($expected),
|
||||
$this->normalizePath($input)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $expected
|
||||
* @param string[] $input
|
||||
* @param null|string $msg
|
||||
*/
|
||||
protected function assertSamePaths(array $expected, array $input, $msg = null)
|
||||
{
|
||||
$expected = array_map(function ($path) { return $this->normalizePath($path); }, $expected);
|
||||
$input = array_map(function ($path) { return $this->normalizePath($path); }, $input);
|
||||
|
||||
if ($msg !== null) {
|
||||
self::assertSame($expected, $input, $msg);
|
||||
} else {
|
||||
self::assertSame($expected, $input);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user