Commit 69f2cef0 authored by alexpott's avatar alexpott

Issue #2003736 by dawehner, jhedstrom: Convert system module's Batch unit tests to phpunit.

parent 0e0d2f6b
......@@ -14,6 +14,7 @@
* @see batch_get()
*/
use Drupal\Core\Batch\Percentage;
use \Symfony\Component\HttpFoundation\JsonResponse;
/**
......@@ -329,27 +330,7 @@ function _batch_process() {
* @see _batch_process()
*/
function _batch_api_percentage($total, $current) {
if (!$total || $total == $current) {
// If $total doesn't evaluate as true or is equal to the current set, then
// we're finished, and we can return "100".
$percentage = "100";
}
else {
// We add a new digit at 200, 2000, etc. (since, for example, 199/200
// would round up to 100% if we didn't).
$decimal_places = max(0, floor(log10($total / 2.0)) - 1);
do {
// Calculate the percentage to the specified number of decimal places.
$percentage = sprintf('%01.' . $decimal_places . 'f', round($current / $total * 100, $decimal_places));
// When $current is an integer, the above calculation will always be
// correct. However, if $current is a floating point number (in the case
// of a multi-step batch operation that is not yet complete), $percentage
// may be erroneously rounded up to 100%. To prevent that, we add one
// more decimal place and try again.
$decimal_places++;
} while ($percentage == '100');
}
return $percentage;
return Percentage::format($total, $current);
}
/**
......
<?php
/**
* @file
* Contains \Drupal\Core\Batch\Percentage.
*/
namespace Drupal\Core\Batch;
/**
* Helper methods for the batch system.
*/
class Percentage {
/**
* Formats the percent completion for a batch set.
*
* @param int $total
* The total number of operations.
* @param int $current
* The number of the current operation. This may be a floating point number
* rather than an integer in the case of a multi-step operation that is not
* yet complete; in that case, the fractional part of $current represents the
* fraction of the operation that has been completed.
*
* @return string
* The properly formatted percentage, as a string. We output percentages
* using the correct number of decimal places so that we never print "100%"
* until we are finished, but we also never print more decimal places than
* are meaningful.
*
* @see _batch_process()
*/
public static function format($total, $current) {
if (!$total || $total == $current) {
// If $total doesn't evaluate as true or is equal to the current set, then
// we're finished, and we can return "100".
$percentage = '100';
}
else {
// We add a new digit at 200, 2000, etc. (since, for example, 199/200
// would round up to 100% if we didn't).
$decimal_places = max(0, floor(log10($total / 2.0)) - 1);
do {
// Calculate the percentage to the specified number of decimal places.
$percentage = sprintf('%01.' . $decimal_places . 'f', round($current / $total * 100, $decimal_places));
// When $current is an integer, the above calculation will always be
// correct. However, if $current is a floating point number (in the case
// of a multi-step batch operation that is not yet complete), $percentage
// may be erroneously rounded up to 100%. To prevent that, we add one
// more decimal place and try again.
$decimal_places++;
} while ($percentage == '100');
}
return $percentage;
}
}
......@@ -2,20 +2,23 @@
/**
* @file
* Definition of Drupal\system\Tests\Batch\PercentagesUnitTest.
* Contains \Drupal\system\Tests\Batch\PercentagesTest.
*/
namespace Drupal\system\Tests\Batch;
namespace Drupal\Tests\Core\Batch;
use Drupal\simpletest\UnitTestBase;
use Drupal\Core\Batch\Percentage;
use Drupal\Tests\UnitTestCase;
/**
* Unit tests of progress percentage rounding.
*
* Tests the function _batch_api_percentage() to make sure that the rounding
* works properly in all cases.
* Tests the Batch helper object to make sure that the rounding works properly
* in all cases.
*
* @see \Drupal\Component\Batch\Batch
*/
class PercentagesUnitTest extends UnitTestBase {
class BatchTest extends UnitTestCase {
protected $testCases = array();
public static function getInfo() {
......@@ -26,42 +29,58 @@ public static function getInfo() {
);
}
function setUp() {
// Set up an array of test cases, where the expected values are the keys,
// and the values are arrays with the keys 'total' and 'current',
// corresponding with the function parameters of _batch_api_percentage().
$this->testCases = array(
/**
* Tests the format() function.
*
* @dataProvider providerTestPercentages
*
* @see \Drupal\Core\Batch\Percentage::format()
*/
public function testPercentages($total, $current, $expected_result) {
$actual_result = Percentage::format($total, $current);
$this->assertEquals($actual_result, $expected_result, sprintf('The expected the batch api percentage at the state %s/%s is %s%% and got %s%%.', $current, $total, $expected_result, $actual_result));
}
/**
* Provide data for batch unit tests.
*
* @return array
* An array of data used by the test.
*/
public function providerTestPercentages() {
// Set up an array of test cases.
return array(
// array(total, current, expected).
// 1/2 is 50%.
'50' => array('total' => 2, 'current' => 1),
array(2, 1, '50'),
// Though we should never encounter a case where the current set is set
// 0, if we did, we should get 0%.
'0' => array('total' => 3, 'current' => 0),
array(3, 0, '0'),
// 1/3 is closer to 33% than to 34%.
'33' => array('total' => 3, 'current' => 1),
array(3, 1, '33'),
// 2/3 is closer to 67% than to 66%.
'67' => array('total' => 3, 'current' => 2),
array(3, 2, '67'),
// 1/199 should round up to 1%.
'1' => array('total' => 199, 'current' => 1),
array(199, 1, '1'),
// 198/199 should round down to 99%.
'99' => array('total' => 199, 'current' => 198),
array(199, 198, '99'),
// 199/200 would have rounded up to 100%, which would give the false
// impression of being finished, so we add another digit and should get
// 99.5%.
'99.5' => array('total' => 200, 'current' => 199),
array(200, 199, '99.5'),
// The same logic holds for 1/200: we should get 0.5%.
'0.5' => array('total' => 200, 'current' => 1),
array(200, 1, '0.5'),
// Numbers that come out evenly, such as 50/200, should be forced to have
// extra digits for consistancy.
'25.0' => array('total' => 200, 'current' => 50),
array(200, 50, '25.0'),
// Regardless of number of digits we're using, 100% should always just be
// 100%.
'100' => array('total' => 200, 'current' => 200),
array(200, 200, '100'),
// 1998/1999 should similarly round down to 99.9%.
'99.9' => array('total' => 1999, 'current' => 1998),
array(1999, 1998, '99.9'),
// 1999/2000 should add another digit and go to 99.95%.
'99.95' => array('total' => 2000, 'current' => 1999),
array(2000, 1999, '99.95'),
// 19999/20000 should add yet another digit and go to 99.995%.
'99.995' => array('total' => 20000, 'current' => 19999),
array(20000, 19999, '99.995'),
// The next five test cases simulate a batch with a single operation
// ('total' equals 1) that takes several steps to complete. Within the
// operation, we imagine that there are 501 items to process, and 100 are
......@@ -70,33 +89,12 @@ function setUp() {
// but for the last pass through, when 500 out of 501 items have been
// processed, we do not want to round up to 100%, since that would
// erroneously indicate that the processing is complete.
'20' => array('total' => 1, 'current' => 100/501),
'40' => array('total' => 1, 'current' => 200/501),
'60' => array('total' => 1, 'current' => 300/501),
'80' => array('total' => 1, 'current' => 400/501),
'99.8' => array('total' => 1, 'current' => 500/501),
array('total' => 1, 'current' => 100/501, '20'),
array('total' => 1, 'current' => 200/501, '40'),
array('total' => 1, 'current' => 300/501, '60'),
array('total' => 1, 'current' => 400/501, '80'),
array('total' => 1, 'current' => 500/501, '99.8'),
);
require_once DRUPAL_ROOT . '/core/includes/batch.inc';
parent::setUp();
}
/**
* Tests the _batch_api_percentage() function.
*/
function testBatchPercentages() {
foreach ($this->testCases as $expected_result => $arguments) {
// PHP sometimes casts numeric strings that are array keys to integers,
// cast them back here.
$expected_result = (string) $expected_result;
$total = $arguments['total'];
$current = $arguments['current'];
$actual_result = _batch_api_percentage($total, $current);
if ($actual_result === $expected_result) {
$this->pass(format_string('Expected the batch api percentage at the state @numerator/@denominator to be @expected%, and got @actual%.', array('@numerator' => $current, '@denominator' => $total, '@expected' => $expected_result, '@actual' => $actual_result)));
}
else {
$this->fail(format_string('Expected the batch api percentage at the state @numerator/@denominator to be @expected%, but got @actual%.', array('@numerator' => $current, '@denominator' => $total, '@expected' => $expected_result, '@actual' => $actual_result)));
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment