Use semver for Phraseanet version numbers

This commit is contained in:
Romain Neutron
2013-11-07 14:48:29 +01:00
parent 973e9f7907
commit 95b0c24d4b
49 changed files with 118 additions and 58 deletions

View File

@@ -39,6 +39,7 @@
"themattharris/tmhoauth" : "~0.7", "themattharris/tmhoauth" : "~0.7",
"twig/twig" : "~1.14, >=1.14.2", "twig/twig" : "~1.14, >=1.14.2",
"twig/extensions" : "~1.0", "twig/extensions" : "~1.0",
"vierbergenlars/php-semver" : "~2.1",
"zend/gdata" : "~1.12.1" "zend/gdata" : "~1.12.1"
}, },
"require-dev": { "require-dev": {

50
composer.lock generated
View File

@@ -3,7 +3,7 @@
"This file locks the dependencies of your project to a known state", "This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
], ],
"hash": "55c5aaf5173cac55c8869a159830a3d5", "hash": "f75434de6657af7daaf97fc6c9f16494",
"packages": [ "packages": [
{ {
"name": "alchemy-fr/tcpdf-clone", "name": "alchemy-fr/tcpdf-clone",
@@ -2915,6 +2915,54 @@
], ],
"time": "2013-10-30 08:20:53" "time": "2013-10-30 08:20:53"
}, },
{
"name": "vierbergenlars/php-semver",
"version": "v2.1.0",
"source": {
"type": "git",
"url": "https://github.com/vierbergenlars/php-semver.git",
"reference": "6b16f72b8c2d3aa00368f9fa612b2218a96245fc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/vierbergenlars/php-semver/zipball/6b16f72b8c2d3aa00368f9fa612b2218a96245fc",
"reference": "6b16f72b8c2d3aa00368f9fa612b2218a96245fc",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"vierbergenlars/simpletest": "1.1.*"
},
"bin": [
"bin/semver",
"bin/update-versions"
],
"type": "library",
"autoload": {
"psr-0": {
"vierbergenlars\\SemVer": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Lars Vierbergen",
"email": "vierbergenlars@gmail.com"
}
],
"description": "The Semantic Versioner for PHP",
"keywords": [
"semantic",
"semver",
"versioning"
],
"time": "2013-09-20 10:41:27"
},
{ {
"name": "zend/gdata", "name": "zend/gdata",
"version": "1.12.1", "version": "1.12.1",

View File

@@ -18,6 +18,7 @@ use Alchemy\Phrasea\Exception\RuntimeException;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputOption;
use vierbergenlars\SemVer\version;
class BowerInstall extends Command class BowerInstall extends Command
{ {
@@ -38,7 +39,7 @@ class BowerInstall extends Command
$version = trim($bower->command('-v')); $version = trim($bower->command('-v'));
if (!version_compare('1.0.0-alpha.1', $version, '<=')) { if (version::lt($version, '1.0.0-alpha.1')) {
throw new RuntimeException(sprintf( throw new RuntimeException(sprintf(
'Bower version 1.0.0-alpha.1 is required (version %s provided), please install bower-canary : `npm install -g bower-canary`', $version 'Bower version 1.0.0-alpha.1 is required (version %s provided), please install bower-canary : `npm install -g bower-canary`', $version
)); ));

View File

@@ -17,6 +17,7 @@ use Alchemy\Phrasea\Command\Upgrade\Step35;
use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
use vierbergenlars\SemVer\version;
/** /**
* *
@@ -69,7 +70,7 @@ EOF
if (null !== $input->getOption('from')) { if (null !== $input->getOption('from')) {
foreach ($versions as $classname => $version) { foreach ($versions as $classname => $version) {
if (version_compare($input->getOption('from'), $version) > 0) { if (version::lt($version, $input->getOption('from'))) {
continue; continue;
} }

View File

@@ -18,7 +18,7 @@ namespace Alchemy\Phrasea\Core;
*/ */
class Version class Version
{ {
protected static $number = '3.8.0'; protected static $number = '3.8.1-alpha.1';
protected static $name = 'Diplodocus'; protected static $name = 'Diplodocus';
public static function getNumber() public static function getNumber()

View File

@@ -15,7 +15,8 @@ use Alchemy\Phrasea\Application;
use JsonSchema\Validator as JsonValidator; use JsonSchema\Validator as JsonValidator;
use Alchemy\Phrasea\Exception\InvalidArgumentException; use Alchemy\Phrasea\Exception\InvalidArgumentException;
use Alchemy\Phrasea\Plugin\Exception\JsonValidationException; use Alchemy\Phrasea\Plugin\Exception\JsonValidationException;
use Alchemy\Phrasea\Core\Version; use Alchemy\Phrasea\Core\Version as PhraseaVersion;
use vierbergenlars\SemVer\version;
class ManifestValidator class ManifestValidator
{ {
@@ -23,7 +24,7 @@ class ManifestValidator
private $version; private $version;
private $schemaData; private $schemaData;
public function __construct(JsonValidator $validator, $schemaData, Version $version) public function __construct(JsonValidator $validator, $schemaData, PhraseaVersion $version)
{ {
if (!is_object($schemaData)) { if (!is_object($schemaData)) {
throw new InvalidArgumentException('Json Schema must be an object'); throw new InvalidArgumentException('Json Schema must be an object');
@@ -56,7 +57,7 @@ class ManifestValidator
} }
if (isset($data->{'minimum-phraseanet-version'})) { if (isset($data->{'minimum-phraseanet-version'})) {
if (true !== version_compare($this->version->getNumber(), $data->{'minimum-phraseanet-version'}, '>=')) { if (version::lt($this->version->getNumber(), $data->{'minimum-phraseanet-version'})) {
throw new JsonValidationException(sprintf( throw new JsonValidationException(sprintf(
'Version incomptibility : Minimum Phraseanet version required is %s, current version is %s', 'Version incomptibility : Minimum Phraseanet version required is %s, current version is %s',
$data->{'minimum-phraseanet-version'}, $data->{'minimum-phraseanet-version'},
@@ -66,7 +67,7 @@ class ManifestValidator
} }
if (isset($data->{'maximum-phraseanet-version'})) { if (isset($data->{'maximum-phraseanet-version'})) {
if (true !== version_compare($this->version->getNumber(), $data->{'maximum-phraseanet-version'}, '<')) { if (version::gte($this->version->getNumber(), $data->{'maximum-phraseanet-version'})) {
throw new JsonValidationException(sprintf( throw new JsonValidationException(sprintf(
'Version incomptibility : Maximum Phraseanet version required is %s, current version is %s', 'Version incomptibility : Maximum Phraseanet version required is %s, current version is %s',
$data->{'maximum-phraseanet-version'}, $data->{'maximum-phraseanet-version'},

View File

@@ -27,6 +27,7 @@ use Alchemy\Phrasea\Setup\Probe\PhraseaProbe;
use Alchemy\Phrasea\Setup\Probe\SearchEngineProbe; use Alchemy\Phrasea\Setup\Probe\SearchEngineProbe;
use Alchemy\Phrasea\Setup\Probe\SubdefsPathsProbe; use Alchemy\Phrasea\Setup\Probe\SubdefsPathsProbe;
use Alchemy\Phrasea\Setup\Probe\SystemProbe; use Alchemy\Phrasea\Setup\Probe\SystemProbe;
use vierbergenlars\SemVer\version;
class ConfigurationTester class ConfigurationTester
{ {
@@ -109,11 +110,11 @@ class ConfigurationTester
return false; return false;
} }
$upgradable = version_compare($this->app['phraseanet.appbox']->get_version(), $this->app['phraseanet.version']->getNumber(), ">"); $upgradable = version::lt($this->app['phraseanet.appbox']->get_version(), $this->app['phraseanet.version']->getNumber());
if (!$upgradable) { if (!$upgradable) {
foreach ($this->app['phraseanet.appbox']->get_databoxes() as $databox) { foreach ($this->app['phraseanet.appbox']->get_databoxes() as $databox) {
if (version_compare($databox->get_version(), $this->app['phraseanet.version']->getNumber(), "<")) { if (version::lt($databox->get_version(), $this->app['phraseanet.version']->getNumber())) {
$upgradable = true; $upgradable = true;
break; break;
} }

View File

@@ -16,6 +16,7 @@ use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\File\File as SymfoFile; use Symfony\Component\HttpFoundation\File\File as SymfoFile;
use Symfony\Component\Finder\Finder; use Symfony\Component\Finder\Finder;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use vierbergenlars\SemVer\version;
/** /**
* *
@@ -387,13 +388,13 @@ class appbox extends base
$upgrader->add_steps_complete(1); $upgrader->add_steps_complete(1);
if (version_compare($from_version, '3.1') < 0) { if (version::lt($from_version, '3.1')) {
$upgrader->addRecommendation(_('Your install requires data migration, please execute the following command'), 'bin/setup system:upgrade-datas --from=3.1'); $upgrader->addRecommendation(_('Your install requires data migration, please execute the following command'), 'bin/setup system:upgrade-datas --from=3.1');
} elseif (version_compare($from_version, '3.5') < 0) { } elseif (version::lt($from_version, '3.5')) {
$upgrader->addRecommendation(_('Your install requires data migration, please execute the following command'), 'bin/setup system:upgrade-datas --from=3.5'); $upgrader->addRecommendation(_('Your install requires data migration, please execute the following command'), 'bin/setup system:upgrade-datas --from=3.5');
} }
if (version_compare($from_version, '3.7') < 0) { if (version::lt($from_version, '3.7')) {
$upgrader->addRecommendation(_('Your install might need to re-read technical datas'), 'bin/console records:rescan-technical-datas'); $upgrader->addRecommendation(_('Your install might need to re-read technical datas'), 'bin/console records:rescan-technical-datas');
$upgrader->addRecommendation(_('Your install might need to build some sub-definitions'), 'bin/console records:build-missing-subdefs'); $upgrader->addRecommendation(_('Your install might need to build some sub-definitions'), 'bin/console records:build-missing-subdefs');
} }

View File

@@ -10,7 +10,8 @@
*/ */
use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Core\Version; use Alchemy\Phrasea\Core\Version as PhraseaVersion;
use vierbergenlars\SemVer\version;
abstract class base implements cache_cacheableInterface abstract class base implements cache_cacheableInterface
{ {
@@ -331,7 +332,7 @@ abstract class base implements cache_cacheableInterface
return $recommends; return $recommends;
} }
protected function setVersion(Version $version) protected function setVersion(PhraseaVersion $version)
{ {
try { try {
$sql = ''; $sql = '';
@@ -757,7 +758,7 @@ abstract class base implements cache_cacheableInterface
protected function apply_patches($from, $to, $post_process, Setup_Upgrade $upgrader, Application $app) protected function apply_patches($from, $to, $post_process, Setup_Upgrade $upgrader, Application $app)
{ {
if (version_compare($from, $to, '=')) { if (version::eq($from, $to)) {
return true; return true;
} }
@@ -783,7 +784,12 @@ abstract class base implements cache_cacheableInterface
if ( ! ! $post_process !== ! ! $patch->require_all_upgrades()) if ( ! ! $post_process !== ! ! $patch->require_all_upgrades())
continue; continue;
if ( ! version_compare($patch->get_release(), $from, '>') || ! version_compare($patch->get_release(), $to, '<=')) { // if patch is older than current install
if (version::lte($patch->get_release(), $from)) {
continue;
}
// if patch is new than current target
if (version::gt($patch->get_release(), $to)) {
continue; continue;
} }

View File

@@ -23,7 +23,7 @@ class patch_320 implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.2.0.0.a1'; private $release = '3.2.0-alpha.1';
/** /**
* *

View File

@@ -22,7 +22,7 @@ class patch_320a implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.2.0.0.a2'; private $release = '3.2.0-alpha.2';
/** /**
* *

View File

@@ -22,7 +22,7 @@ class patch_320ab implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.2.0.0.a1'; private $release = '3.2.0-alpha.1';
/** /**
* *

View File

@@ -22,7 +22,7 @@ class patch_320b implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.2.0.0.a3'; private $release = '3.2.0-alpha.3';
/** /**
* *

View File

@@ -22,7 +22,7 @@ class patch_320c implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.2.0.0.a4'; private $release = '3.2.0-alpha.4';
/** /**
* *

View File

@@ -22,7 +22,7 @@ class patch_320d implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.2.0.0.a5'; private $release = '3.2.0-alpha.5';
/** /**
* *

View File

@@ -22,7 +22,7 @@ class patch_320e implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.2.0.0.a6'; private $release = '3.2.0-alpha.6';
/** /**
* *

View File

@@ -23,7 +23,7 @@ class patch_320f implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.2.0.0.a4'; private $release = '3.2.0-alpha.4';
/** /**
* *

View File

@@ -22,7 +22,7 @@ class patch_320h implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.2.0.0.a8'; private $release = '3.2.0-alpha.8';
/** /**
* *

View File

@@ -22,7 +22,7 @@ class patch_360 implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.6.0.a1'; private $release = '3.6.0-alpha.1';
/** /**
* *

View File

@@ -22,7 +22,7 @@ class patch_3602 implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.6.0.a1'; private $release = '3.6.0-alpha.1';
/** /**
* *

View File

@@ -22,7 +22,7 @@ class patch_3603 implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.6.0.a2'; private $release = '3.6.0-alpha.2';
/** /**
* *

View File

@@ -22,7 +22,7 @@ class patch_3604 implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.6.0.a2'; private $release = '3.6.0-alpha.2';
/** /**
* *

View File

@@ -22,7 +22,7 @@ class patch_370 implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.7.0.a2'; private $release = '3.7.0-alpha.2';
/** /**
* *

View File

@@ -23,7 +23,7 @@ class patch_370a3 implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.7.0.a3'; private $release = '3.7.0-alpha.3';
/** /**
* *

View File

@@ -22,7 +22,7 @@ class patch_370a4 implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.7.0.a4'; private $release = '3.7.0-alpha.4';
/** /**
* *

View File

@@ -22,7 +22,7 @@ class patch_370a5 implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.7.0.a5'; private $release = '3.7.0-alpha.5';
/** /**
* *

View File

@@ -22,7 +22,7 @@ class patch_370a6 implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.7.0.a6'; private $release = '3.7.0-alpha.6';
/** /**
* *

View File

@@ -24,7 +24,7 @@ class patch_370a7 implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.7.0.a7'; private $release = '3.7.0-alpha.7';
/** /**
* *

View File

@@ -22,7 +22,7 @@ class patch_370a8 implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.7.0.a8'; private $release = '3.7.0-alpha.8';
/** /**
* *

View File

@@ -22,7 +22,7 @@ class patch_370a9 implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.7.0.a9'; private $release = '3.7.0-alpha.9';
/** /**
* *

View File

@@ -22,7 +22,7 @@ class patch_380 implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.8.0.a2'; private $release = '3.8.0-alpha.2';
/** /**
* *

View File

@@ -22,7 +22,7 @@ class patch_3802 implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.8.0.a2'; private $release = '3.8.0-alpha.2';
/** /**
* *

View File

@@ -23,7 +23,7 @@ class patch_3803 implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.8.0.a3'; private $release = '3.8.0-alpha.3';
/** /**
* *

View File

@@ -15,7 +15,7 @@ use Entities\AuthFailure;
class patch_3805 implements patchInterface class patch_3805 implements patchInterface
{ {
/** @var string */ /** @var string */
private $release = '3.8.0.a4'; private $release = '3.8.0-alpha.4';
/** @var array */ /** @var array */
private $concern = array(base::APPLICATION_BOX); private $concern = array(base::APPLICATION_BOX);

View File

@@ -14,7 +14,7 @@ use Alchemy\Phrasea\Application;
class patch_3806 implements patchInterface class patch_3806 implements patchInterface
{ {
/** @var string */ /** @var string */
private $release = '3.8.0.a6'; private $release = '3.8.0-alpha.6';
/** @var array */ /** @var array */
private $concern = array(base::APPLICATION_BOX); private $concern = array(base::APPLICATION_BOX);

View File

@@ -14,7 +14,7 @@ use Alchemy\Phrasea\Application;
class patch_3808 implements patchInterface class patch_3808 implements patchInterface
{ {
/** @var string */ /** @var string */
private $release = '3.8.0.a8'; private $release = '3.8.0-alpha.8';
/** @var array */ /** @var array */
private $concern = array(base::APPLICATION_BOX); private $concern = array(base::APPLICATION_BOX);

View File

@@ -14,7 +14,7 @@ use Alchemy\Phrasea\Application;
class patch_3809 implements patchInterface class patch_3809 implements patchInterface
{ {
/** @var string */ /** @var string */
private $release = '3.8.0.a9'; private $release = '3.8.0-alpha.9';
/** @var array */ /** @var array */
private $concern = array(base::DATA_BOX); private $concern = array(base::DATA_BOX);

View File

@@ -23,7 +23,7 @@ class patch_380a3 implements patchInterface
* *
* @var string * @var string
*/ */
private $release = '3.8.0.a3'; private $release = '3.8.0-alpha.3';
/** /**
* *

View File

@@ -14,7 +14,7 @@ use Alchemy\Phrasea\Application;
class patch_3810 implements patchInterface class patch_3810 implements patchInterface
{ {
/** @var string */ /** @var string */
private $release = '3.8.0.a10'; private $release = '3.8.0-alpha.10';
/** @var array */ /** @var array */
private $concern = array(base::APPLICATION_BOX); private $concern = array(base::APPLICATION_BOX);

View File

@@ -16,7 +16,7 @@ use Entities\SessionModule;
class patch_3811 implements patchInterface class patch_3811 implements patchInterface
{ {
/** @var string */ /** @var string */
private $release = '3.8.0.a11'; private $release = '3.8.0-alpha.11';
/** @var array */ /** @var array */
private $concern = array(base::APPLICATION_BOX); private $concern = array(base::APPLICATION_BOX);

View File

@@ -14,7 +14,7 @@ use Alchemy\Phrasea\Application;
class patch_3813 implements patchInterface class patch_3813 implements patchInterface
{ {
/** @var string */ /** @var string */
private $release = '3.8.0.a13'; private $release = '3.8.0-alpha.13';
/** @var array */ /** @var array */
private $concern = array(base::APPLICATION_BOX); private $concern = array(base::APPLICATION_BOX);

View File

@@ -14,7 +14,7 @@ use Alchemy\Phrasea\Application;
class patch_3814 implements patchInterface class patch_3814 implements patchInterface
{ {
/** @var string */ /** @var string */
private $release = '3.8.0.a14'; private $release = '3.8.0-alpha.14';
/** @var array */ /** @var array */
private $concern = array(base::APPLICATION_BOX); private $concern = array(base::APPLICATION_BOX);

View File

@@ -14,7 +14,7 @@ use Alchemy\Phrasea\Application;
class patch_3815 implements patchInterface class patch_3815 implements patchInterface
{ {
/** @var string */ /** @var string */
private $release = '3.8.0.a15'; private $release = '3.8.0-alpha.15';
/** @var array */ /** @var array */
private $concern = array(base::APPLICATION_BOX); private $concern = array(base::APPLICATION_BOX);

View File

@@ -14,7 +14,7 @@ use Alchemy\Phrasea\Application;
class patch_3816 implements patchInterface class patch_3816 implements patchInterface
{ {
/** @var string */ /** @var string */
private $release = '3.8.0.a16'; private $release = '3.8.0-alpha.16';
/** @var array */ /** @var array */
private $concern = array(base::APPLICATION_BOX); private $concern = array(base::APPLICATION_BOX);

View File

@@ -14,7 +14,7 @@ use Alchemy\Phrasea\Application;
class patch_3817 implements patchInterface class patch_3817 implements patchInterface
{ {
/** @var string */ /** @var string */
private $release = '3.8.0.a17'; private $release = '3.8.0-alpha.17';
/** @var array */ /** @var array */
private $concern = array(base::APPLICATION_BOX); private $concern = array(base::APPLICATION_BOX);

View File

@@ -15,7 +15,7 @@ use Symfony\Component\Process\ExecutableFinder;
class patch_3818 implements patchInterface class patch_3818 implements patchInterface
{ {
/** @var string */ /** @var string */
private $release = '3.8.0.a18'; private $release = '3.8.0-alpha.18';
/** @var array */ /** @var array */
private $concern = array(base::APPLICATION_BOX); private $concern = array(base::APPLICATION_BOX);

View File

@@ -14,7 +14,7 @@ use Alchemy\Phrasea\Application;
class patch_3819 implements patchInterface class patch_3819 implements patchInterface
{ {
/** @var string */ /** @var string */
private $release = '3.8.1'; private $release = '3.8.1-alpha.1';
/** @var array */ /** @var array */
private $concern = array(base::APPLICATION_BOX); private $concern = array(base::APPLICATION_BOX);

View File

@@ -14,7 +14,7 @@ use Alchemy\Phrasea\Application;
class patch_3820 implements patchInterface class patch_3820 implements patchInterface
{ {
/** @var string */ /** @var string */
private $release = '3.8.1'; private $release = '3.8.1-alpha.1';
/** @var array */ /** @var array */
private $concern = array(base::DATA_BOX); private $concern = array(base::DATA_BOX);

View File

@@ -93,7 +93,7 @@ class ConfigurationTesterTest extends AbstractSetupTester
/** /**
* Must return version + 1 * Must return version + 1
*/ */
$app['phraseanet.version']->expects($this->any()) $app['phraseanet.version']::staticExpects($this->any())
->method('getNumber') ->method('getNumber')
->will($this->returnValue('3.9')); ->will($this->returnValue('3.9'));
@@ -134,7 +134,7 @@ class ConfigurationTesterTest extends AbstractSetupTester
/** /**
* Must return version + 1 * Must return version + 1
*/ */
$app['phraseanet.version']->expects($this->any()) $app['phraseanet.version']::staticExpects($this->any())
->method('getNumber') ->method('getNumber')
->will($this->returnValue('3.9')); ->will($this->returnValue('3.9'));