Skip to content

Commit

Permalink
Added last stable version badge
Browse files Browse the repository at this point in the history
  • Loading branch information
leopro committed May 29, 2013
1 parent 38796bf commit 8b2f201
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 10 deletions.
5 changes: 5 additions & 0 deletions app/config/routing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ pugx_badge_stat:
requirements:
type: total|daily|monthly

pugx_badge_last:
path: /{vendor}/{repository}/last_stable.png
defaults: { _controller: PUGXBadgeBundle:Badge:lastStable }
methods: [GET]

24 changes: 24 additions & 0 deletions src/PUGX/BadgeBundle/Controller/BadgeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,28 @@ public function downloadsAction($vendor, $repository, $type = 'total')

return $response;
}

public function lastStableAction($vendor, $repository)
{
$imageCreator = $this->get('image_creator');
$repository = $vendor . '/' . $repository;
$outputFilename = sprintf('%s.png', 'last_stable');
$httpCode = 200;

$last = $this->get('badger')->getLastStableVersion($repository);

// handles the image
$image = $imageCreator->createDownloadsImage($last);
//generating the streamed response
$response = new StreamedResponse(null, $httpCode);
$response->setCallback(function () use ($imageCreator, $image) {
$imageCreator->streamRawImageData($image);
});
$response->headers->set('Content-Type', 'image/png');
$response->headers->set('Content-Disposition', 'inline; filename="'.$outputFilename.'"');
$response->send();
$imageCreator->destroyImage($image);

return $response;
}
}
50 changes: 47 additions & 3 deletions src/PUGX/BadgeBundle/Service/Badger.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Packagist\Api\Client;
use PUGX\BadgeBundle\Event\PackageEvent;
use PUGX\BadgeBundle\Exception\UnexpectedValueException;
use Packagist\Api\Result\Package\Version;

class Badger
{
Expand Down Expand Up @@ -55,21 +56,64 @@ public function getPackageDownloads($repositoryName, $type)
/**
* Do the get number for that repository.
*
* @param $repositoryName
* @param string $repositoryName
*
* @return \Packagist\Api\Result\Package\Downloads
* @throws \PUGX\BadgeBundle\Exception
*/
private function doGetPackageDownloads($repositoryName)
{
$package = $this->client->get($repositoryName);
$package = $this->getPackage($repositoryName);
if ($package && ($download = $package->getDownloads()) && $download instanceof \Packagist\Api\Result\Package\Downloads) {

return $download;
}

throw new UnexpectedValueException(sprintf('Impossible to found repository "%s"', $repositoryName));

}

/**
* Returns package if found.
*
* @param string $repository
* @return \Packagist\Api\Result\Package|null
*/
protected function getPackage($repository)
{
$package = $this->client->get($repository);
if ($package && $package instanceof \Packagist\Api\Result\Package) {
return $package;
}

return null;
}

protected function filterStableVersions(Version $version)
{
$notStableKeys = array('dev', 'RC', 'BETA', 'ALPHA');
foreach ($notStableKeys as $notStableKey) {
if (stripos($version->getVersion(), $notStableKey) != false) {
return false;
}
}

return true;
}

public function getLastStableVersion($repository)
{
$last = null;

$package = $this->getPackage($repository);
if ($package && $versions = $package->getVersions()) {
$stableVersions = array_filter($versions, array($this, 'filterStableVersions'));
array_walk($stableVersions, function($version) use(&$last){
if ($version->getVersion() > $last) {
$last = $version->getVersion();
}
});
}

return $last;
}
}
22 changes: 21 additions & 1 deletion src/PUGX/BadgeBundle/Tests/Controller/BadgeControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

class BadgeControllerTest extends WebTestCase
{
public function testIndex()
public function testDownloadsAction()
{
// see the config_test.yml, there's a parameters in order to not stream the output using FakeImageCreator.
$data = '{"package":{"name":"pugx\/badge-poser","description":"add badges on your readme, such as downloads number or latest version.","time":"2013-05-24T14:45:06+00:00","maintainers":[{"name":"liuggio","email":"[email protected]"}],"versions":{"dev-master":{"name":"pugx\/badge-poser","description":"add badges on your readme, such as downloads number or latest version.","keywords":[],"homepage":"","version":"dev-master","version_normalized":"9999999-dev","license":[],"authors":[],"source":{"type":"git","url":"https:\/\/github.com\/PUGX\/badge-poser.git","reference":"024df1d420cd715aea3400bfea9b87ed0f3bb47e"},"dist":{"type":"zip","url":"https:\/\/api.github.com\/repos\/PUGX\/badge-poser\/zipball\/024df1d420cd715aea3400bfea9b87ed0f3bb47e","reference":"024df1d420cd715aea3400bfea9b87ed0f3bb47e","shasum":""},"type":"library","time":"2013-05-24T19:19:25+00:00","autoload":{"psr-0":{"":"src\/"}},"extra":{"symfony-app-dir":"app","symfony-web-dir":"web","branch-alias":{"dev-master":"0.1-dev"}},"require":{"php":">=5.3.3","symfony\/symfony":"2.2.*","doctrine\/orm":">=2.2,<3.0,>=2.2.3","doctrine\/doctrine-bundle":"1.2.*","twig\/extensions":"1.0.*","symfony\/assetic-bundle":"2.1.*","symfony\/swiftmailer-bundle":"2.2.*","symfony\/monolog-bundle":"2.2.*","sensio\/distribution-bundle":"2.2.*","sensio\/framework-extra-bundle":"2.2.*","sensio\/generator-bundle":"2.2.*","jms\/security-extra-bundle":"1.4.*","jms\/di-extra-bundle":"1.3.*","knplabs\/packagist-api":"dev-master"},"require-dev":{"guzzle\/plugin-mock":"*"}},"dev-develop":{"name":"pugx\/badge-poser","description":"add badges on your readme, such as downloads number or latest version.","keywords":[],"homepage":"","version":"dev-develop","version_normalized":"dev-develop","license":[],"authors":[],"source":{"type":"git","url":"https:\/\/github.com\/PUGX\/badge-poser.git","reference":"024df1d420cd715aea3400bfea9b87ed0f3bb47e"},"dist":{"type":"zip","url":"https:\/\/api.github.com\/repos\/PUGX\/badge-poser\/zipball\/024df1d420cd715aea3400bfea9b87ed0f3bb47e","reference":"024df1d420cd715aea3400bfea9b87ed0f3bb47e","shasum":""},"type":"library","time":"2013-05-24T19:19:25+00:00","autoload":{"psr-0":{"":"src\/"}},"extra":{"symfony-app-dir":"app","symfony-web-dir":"web","branch-alias":{"dev-master":"0.1-dev"}},"require":{"php":">=5.3.3","symfony\/symfony":"2.2.*","doctrine\/orm":">=2.2,<3.0,>=2.2.3","doctrine\/doctrine-bundle":"1.2.*","twig\/extensions":"1.0.*","symfony\/assetic-bundle":"2.1.*","symfony\/swiftmailer-bundle":"2.2.*","symfony\/monolog-bundle":"2.2.*","sensio\/distribution-bundle":"2.2.*","sensio\/framework-extra-bundle":"2.2.*","sensio\/generator-bundle":"2.2.*","jms\/security-extra-bundle":"1.4.*","jms\/di-extra-bundle":"1.3.*","knplabs\/packagist-api":"dev-master"},"require-dev":{"guzzle\/plugin-mock":"*"}}},"type":"library","repository":"https:\/\/github.com\/PUGX\/badge-poser","downloads":{"total":99,"monthly":12,"daily":9},"favers":9}}';
Expand All @@ -35,4 +35,24 @@ public function testIndex()
$crawler = $client->request('GET', '/pugx/badge-poser/d/total.png');
$this->assertTrue($client->getResponse()->isSuccessful());
}

public function testLastStableAction()
{
// see the config_test.yml, there's a parameters in order to not stream the output using FakeImageCreator.
$data = '{"package":{"name":"pugx\/badge-poser","description":"add badges on your readme, such as downloads number or latest version.","time":"2013-05-24T14:45:06+00:00","maintainers":[{"name":"liuggio","email":"[email protected]"}],"versions":{"1.0.0":{"name":"pugx\/badge-poser","description":"add badges on your readme, such as downloads number or latest version.","keywords":[],"homepage":"","version":"dev-master","version_normalized":"9999999-dev","license":[],"authors":[],"source":{"type":"git","url":"https:\/\/github.com\/PUGX\/badge-poser.git","reference":"024df1d420cd715aea3400bfea9b87ed0f3bb47e"},"dist":{"type":"zip","url":"https:\/\/api.github.com\/repos\/PUGX\/badge-poser\/zipball\/024df1d420cd715aea3400bfea9b87ed0f3bb47e","reference":"024df1d420cd715aea3400bfea9b87ed0f3bb47e","shasum":""},"type":"library","time":"2013-05-24T19:19:25+00:00","autoload":{"psr-0":{"":"src\/"}},"extra":{"symfony-app-dir":"app","symfony-web-dir":"web","branch-alias":{"dev-master":"0.1-dev"}},"require":{"php":">=5.3.3","symfony\/symfony":"2.2.*","doctrine\/orm":">=2.2,<3.0,>=2.2.3","doctrine\/doctrine-bundle":"1.2.*","twig\/extensions":"1.0.*","symfony\/assetic-bundle":"2.1.*","symfony\/swiftmailer-bundle":"2.2.*","symfony\/monolog-bundle":"2.2.*","sensio\/distribution-bundle":"2.2.*","sensio\/framework-extra-bundle":"2.2.*","sensio\/generator-bundle":"2.2.*","jms\/security-extra-bundle":"1.4.*","jms\/di-extra-bundle":"1.3.*","knplabs\/packagist-api":"dev-master"},"require-dev":{"guzzle\/plugin-mock":"*"}},"dev-develop":{"name":"pugx\/badge-poser","description":"add badges on your readme, such as downloads number or latest version.","keywords":[],"homepage":"","version":"dev-develop","version_normalized":"dev-develop","license":[],"authors":[],"source":{"type":"git","url":"https:\/\/github.com\/PUGX\/badge-poser.git","reference":"024df1d420cd715aea3400bfea9b87ed0f3bb47e"},"dist":{"type":"zip","url":"https:\/\/api.github.com\/repos\/PUGX\/badge-poser\/zipball\/024df1d420cd715aea3400bfea9b87ed0f3bb47e","reference":"024df1d420cd715aea3400bfea9b87ed0f3bb47e","shasum":""},"type":"library","time":"2013-05-24T19:19:25+00:00","autoload":{"psr-0":{"":"src\/"}},"extra":{"symfony-app-dir":"app","symfony-web-dir":"web","branch-alias":{"dev-master":"0.1-dev"}},"require":{"php":">=5.3.3","symfony\/symfony":"2.2.*","doctrine\/orm":">=2.2,<3.0,>=2.2.3","doctrine\/doctrine-bundle":"1.2.*","twig\/extensions":"1.0.*","symfony\/assetic-bundle":"2.1.*","symfony\/swiftmailer-bundle":"2.2.*","symfony\/monolog-bundle":"2.2.*","sensio\/distribution-bundle":"2.2.*","sensio\/framework-extra-bundle":"2.2.*","sensio\/generator-bundle":"2.2.*","jms\/security-extra-bundle":"1.4.*","jms\/di-extra-bundle":"1.3.*","knplabs\/packagist-api":"dev-master"},"require-dev":{"guzzle\/plugin-mock":"*"}}},"type":"library","repository":"https:\/\/github.com\/PUGX\/badge-poser","downloads":{"total":99,"monthly":12,"daily":9},"favers":9}}';
$packagistResponse = new \Guzzle\Http\Message\Response(200);
$packagistResponse->setBody($data);
$plugin = new \Guzzle\Plugin\Mock\MockPlugin();
$plugin->addResponse($packagistResponse);
$clientHttp = new \Guzzle\Http\Client();
$clientHttp->addSubscriber($plugin);

$packagistClient = new Client($clientHttp);
//We override the regular service
$client = static::createClient();
static::$kernel->getContainer()->set('packagist.client', $packagistClient);

$crawler = $client->request('GET', '/pugx/badge-poser/last_stable.png');
$this->assertTrue($client->getResponse()->isSuccessful());
}
}
73 changes: 67 additions & 6 deletions src/PUGX/BadgeBundle/Tests/Service/BadgerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
use Packagist\Api\Result\Package\Downloads;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use PUGX\BadgeBundle\Service\Badger;

use Packagist\Api\Result\Package\Version;

class BadgerTest extends WebTestCase
{
Expand All @@ -23,21 +23,22 @@ class BadgerTest extends WebTestCase
private $dispatcher;
private $packagistClient;

public function setUp() {
public function setUp()
{
$this->logger = $this->getMockBuilder('Symfony\Bridge\Monolog\Logger')
->disableOriginalConstructor()
->getMock();

$this->dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
$this->dispatcher->expects($this->once())
->method('dispatch');

$this->packagistClient = $this->getMock('Packagist\Api\Client');
}


public function testGetPackageDownloads()
{
$this->dispatcher->expects($this->once())
->method('dispatch');

$downloads = new Downloads();
$downloads->setTotal(90000);

Expand All @@ -55,14 +56,16 @@ public function testGetPackageDownloads()
$badger = new Badger($this->packagistClient, $this->dispatcher, $this->logger);

$this->assertEquals($badger->getPackageDownloads($input, 'total'), 90000);

}

/**
* @expectedException Exception
*/
public function testGetPackageDownloadsException()
{
$this->dispatcher->expects($this->once())
->method('dispatch');

$input = 'pugx/badge-poser';

$this->packagistClient->expects($this->once())
Expand All @@ -76,9 +79,67 @@ public function testGetPackageDownloadsException()
$badger = new Badger($this->packagistClient, $this->dispatcher, $this->logger);

$this->assertEquals($badger->getPackageDownloads($input, 'total'), null);
}

public function testVersionComparison()
{
$a = "2.1.10";
$b = "2.2.1";
$c = "2.2.2";
$d = "2.2.2-RC2";

$this->assertTrue(($b > $a));
$this->assertTrue(($c > $b));
$this->assertTrue(($d > $c));
}

public function testGetLastStableVersionReturnsLastVersion()
{
$branches = array('1.0.0', '1.1.0', '2.0.0', '3.0.x-dev', 'v3.0.0-RC1');
foreach ($branches as $branch) {
$version = new Version();
$version->fromArray(array('version' => $branch));
$versions[] = $version;
}

$input = 'pugx/badge-poser';
$output = $this->getMock('Packagist\Api\Result\Package');
$output->expects($this->once())
->method('getVersions')
->will($this->returnValue($versions));

$this->packagistClient->expects($this->once())
->method('get')
->with($this->equalTo($input))
->will($this->returnValue($output));

$badger = new Badger($this->packagistClient, $this->dispatcher, $this->logger);

$this->assertEquals('2.0.0', $badger->getLastStableVersion($input));
}

public function testGetLastStableVersionReturnsNull()
{
$branches = array('3.0.x-dev', 'v3.0.0-RC1');
foreach ($branches as $branch) {
$version = new Version();
$version->fromArray(array('version' => $branch));
$versions[] = $version;
}

$input = 'pugx/badge-poser';
$output = $this->getMock('Packagist\Api\Result\Package');
$output->expects($this->once())
->method('getVersions')
->will($this->returnValue($versions));

$this->packagistClient->expects($this->once())
->method('get')
->with($this->equalTo($input))
->will($this->returnValue($output));

$badger = new Badger($this->packagistClient, $this->dispatcher, $this->logger);

$this->assertEquals(null, $badger->getLastStableVersion($input));
}
}

0 comments on commit 8b2f201

Please sign in to comment.