我正在处理一些旧的php代码。在开发环境中,并且error_reporting
打开到E_ALL | E_STRICT
时,我得到了Notice: Undefined offset: 4 in /home/pgnetdev/www/PGNet/php-includes/base_classes.inc on line 545
令人反感的php类是
<?php
class CMap
{
var $m_aData;
var $m_aKeys;
var $m_iNumItems;
var $m_iCurrentDatumIndex;
function CMap()
{
$this->m_aData = array();
$this->m_aKeys = array();
$this->m_iNumItems = 0;
$this->m_iCurrentDatumIndex = 0;
}
function Add($strKey, & $clDatum)
{
if ($this->Contains($strKey))
return false;
$this->m_aKeys[$strKey] = $strKey;
$this->m_iNumItems++;
$this->m_aData[$strKey] = & $clDatum;
return true;
}
function &First()
{
if ($this->m_iNumItems <= 0)
return null;
sort($this->m_aKeys);
$this->m_iCurrentDatumIndex = 0;
return $this->m_aData[$this->m_aKeys[0]];
}
//line 545 in this method
function &Next()
{
fwrite(STDERR, "+[NEXT]: {$this->m_iCurrentDatumIndex} >= {$this->m_iNumItems}\n"); //not deployed
if ($this->m_iCurrentDatumIndex >= $this->m_iNumItems)
{
fwrite(STDERR, "-[NEXT]: returning null\n");// not deployed
return null;
}
fwrite(STDERR, "-[NEXT]: returning value\n"); //not deployed
return $this->m_aData[$this->m_aKeys[++$this->m_iCurrentDatumIndex]];// line 545
}
function &Find($strKey)
{
if (array_key_exists($strKey, $this->m_aData))
return $this->m_aData[$strKey];
return null;
}
function Contains($strKey)
{
return array_key_exists($strKey, $this->m_aData);
}
function Items()
{
return $this->m_iNumItems;
}
}
我对此的测试
<?php
error_reporting(E_ALL | E_STRICT);
require_once '../PGNet/php-includes/base_classes.inc';
class CMapTest extends PHPUnit_Framework_TestCase
{
public function testItemsReturnsNumberOfItemsAdded()
{
$map = new CMap();
$var = 1;
$this->assertEquals(0, $map->Items(), 'No Items, Zero Count expected');
$map->Add("KEY", $var);
$this->assertEquals(1, $map->Items(), 'Item just added, should have count 1');
}
public function testContainsReturnsTrueIfMapContainsKey()
{
$map = new CMap();
$var = 1;
$this->assertFalse($map->Contains("KEY"), 'No Items, No KEYS');
$map->Add("KEY", $var);
$this->assertTrue($map->Contains("KEY"), 'Item just added, should a key');
}
public function testFindReturnsNullIfMapDoesntContainsKey()
{
$map = new CMap();
$var = 1;
$map->Add("KEY", $var);
$actual = $map->Find("NO_KEY");
$this->assertEquals(null, $actual, 'no key no value... NULL is expected here');
}
public function testFindReturnsValueIfMapContainsKey()
{
$map = new CMap();
$var = 1;
$map->Add("KEY", $var);
$actual = $map->Find("KEY");
$this->assertEquals($var, $actual, 'has key finds value... var is expected here');
}
public function testAddReturnsFalseIfKeyIsAlreadyAdded()
{
$map = new CMap();
$var1 = 1;
$var2 = 2;
$willBeTrue = $map->Add("KEY", $var1);
$willBeFalse = $map->Add("KEY", $var2);
$this->assertTrue($willBeTrue, "first key added should always be true");
$this->assertFalse($willBeFalse, "key already exists so you cant replace it");
}
public function testFirstReturnsNullWhenNoItemsAdded()
{
$map = new CMap();
$actual = $map->First();
$this->assertEquals(null, $actual, 'no items added, returns false');
}
public function testFirstReturnsFirstSortedValue()
{
$map = new CMap();
$var1 = 1;
$var2 = 2;
$map->Add("B", $var2);
$map->Add("A", $var1);
$actual = $map->First();
$this->assertEquals($var1, $actual, 'keys are sorted then first one is grabbed');
}
public function testNextReturnsNullIfOnlySingleItemAdded()
{
$map = new CMap();
$var1 = 1;
$map->Add("A", $var1);
$actual = $map->First();
$this->assertEquals($var1, $actual, 'keys are sorted then first one is grabbed');
$this->assertEquals(null, $map->Next());
}
public function testNextReturnsNullAfterAllItemsAreIteratedThrough()
{
fwrite(STDERR, "+[testNextReturnsNullAfterAllItemsAreIteratedThrough]\n");
$map = new CMap();
$var1 = 1;
$var2 = 2;
$map->Add("B", $var2);
$map->Add("A", $var1);
$actual = $map->First();
$loopCount = 0;
try
{
for($actual = $map->First(); $actual != null; $actual = $map->Next())
{
$this->assertNotNull($actual);
$loopCount++;
}
}
catch (Throwable $th)
{
fwrite(STDERR, "-[testNextReturnsNullAfterAllItemsAreIteratedThrough]:WTH\n");
$this->assertFalse(true, $th->getMessage());
}
$this->assertEquals(2, $loopCount, "the for loop should work");
fwrite(STDERR, "-[testNextReturnsNullAfterAllItemsAreIteratedThrough]\n");
}
}
这里的最后一个测试是我真的很困惑,为什么它没有破裂或抛出任何东西。控制台输出是
$ phpunit ../PGNetTests/tests/unitTests/
PHPUnit @package_version@ by Sebastian Bergmann.
.......................................................+[NEXT]: 0 >= 1
-[NEXT]: returning value
.+[testNextReturnsNullAfterAllItemsAreIteratedThrough]
+[NEXT]: 0 >= 2
-[NEXT]: returning value
+[NEXT]: 1 >= 2
-[NEXT]: returning value
-[testNextReturnsNullAfterAllItemsAreIteratedThrough]
.... 60 / 88
..........................+[NEXT]: 0 >= 1
-[NEXT]: returning value
..
Time: 0 seconds, Memory: 4.25Mb
OK (88 tests, 326 assertions)
像我期望的那样,或者在输出中获得与生产中相同的消息,或者至少引发抛出的异常,甚至是-[NEXT] return null
,但是除了通过测试外我什么也没有,我不知道为什么。为什么?