implement JS password scoring, td_stock approve logicc

This commit is contained in:
Thanakorn S
2026-04-30 15:14:42 +07:00
parent db5c47b6ca
commit ac4fd9a5ad
3147 changed files with 1298 additions and 343 deletions
@@ -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);
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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());
}
}
@@ -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());
}
}
@@ -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();
}
}
@@ -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;
}
}
@@ -0,0 +1 @@
coverage_clover: build/logs/clover.xml
@@ -0,0 +1,3 @@
coverage_clover:
- build/logs/clover-part1.xml
- build/logs/clover-part2.xml
@@ -0,0 +1 @@
coverage_clover: build/logs/clover-*.xml
@@ -0,0 +1 @@
coverage_clover: build/logs/clover.dummy.xml
@@ -0,0 +1 @@
entry_point: http://foo.bar/
@@ -0,0 +1 @@
json_path: build/logs/coveralls-upload.json
@@ -0,0 +1 @@
json_path: build/logs.dummy/coveralls-upload.json
@@ -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());
}
}
@@ -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);
}
}
@@ -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();
}
}
@@ -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)
;
}
}
@@ -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();
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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()
;
}
}
@@ -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;
}
}
@@ -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();
}
}
@@ -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);
}
}
@@ -0,0 +1 @@
# empty config
@@ -0,0 +1,6 @@
<?php
abstract class AbstractClass
{
abstract public function hello();
}
@@ -0,0 +1,10 @@
<?php
namespace CoverallsTest;
class Coverage0
{
public function doSomething()
{
$var = '';
}
}
@@ -0,0 +1,10 @@
<?php
namespace CoverallsTest;
class Coverage10
{
public function doSomething()
{
$var = '';
}
}
@@ -0,0 +1,10 @@
<?php
namespace CoverallsTest;
class Coverage100
{
public function doSomething()
{
$var = '';
}
}
@@ -0,0 +1,10 @@
<?php
namespace CoverallsTest;
class Coverage70
{
public function doSomething()
{
$var = '';
}
}
@@ -0,0 +1,10 @@
<?php
namespace CoverallsTest;
class Coverage80
{
public function doSomething()
{
$var = '';
}
}
@@ -0,0 +1,10 @@
<?php
namespace CoverallsTest;
class Coverage90
{
public function doSomething()
{
$var = '';
}
}
@@ -0,0 +1,6 @@
<?php
interface TestInterface
{
public function hello();
}
@@ -0,0 +1,9 @@
<?php
class TestFile
{
public function __construct()
{
$this->message = 'hoge';
}
}
@@ -0,0 +1,10 @@
<?php
namespace Hoge;
class TestFile
{
public function __construct()
{
$this->message = 'hoge';
}
}
@@ -0,0 +1,10 @@
<?php
namespace Hoge;
class TestFileBis
{
public function __construct()
{
$this->message = 'hoge';
}
}
@@ -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);
}
}
}