NEW: Allow SapphireTest::objFromFixture() to accept either table or class

Right now SapphireTest::objFromFixture() requires a class as the first
argument. This is fine when your fixture file uses classes as the keys,
but if populating a fixture via tables, objFromFixture() won’t work.

This patch lets you specify either the table name or the class name as
the key.

The benefit here is that you can build fixtures as raw inserts, which is
substantially quicker, and is likely to be a useful tool in building
more efficient test suites.
This commit is contained in:
Sam Minnee 2017-05-04 17:48:10 +12:00
parent dd7777321f
commit 1691e90fbd
3 changed files with 36 additions and 6 deletions

View File

@ -135,7 +135,7 @@ class FixtureFactory
/**
* Return all of the IDs in the fixture of a particular class name.
*
* @param string $class
* @param string $class The data class or table name
* @return array|false A map of fixture-identifier => object-id
*/
public function getIds($class)
@ -162,7 +162,7 @@ class FixtureFactory
/**
* Get an object from the fixture.
*
* @param string $class The data class, as specified in your fixture file. Parent classes won't work
* @param string $class The data class or table name, as specified in your fixture file. Parent classes won't work
* @param string $identifier The identifier string, as provided in your fixture file
* @return DataObject
*/
@ -172,6 +172,17 @@ class FixtureFactory
if (!$id) {
return null;
}
// If the class doesn't exist, look for a table instead
if (!class_exists($class)) {
$tableNames = DataObject::getSchema()->getTableNames();
$potential = array_search($class, $tableNames);
if (!$potential) {
throw new \LogicException("'$class' is neither a class nor a table name");
}
$class = $potential;
}
return DataObject::get_by_id($class, $id);
}
@ -240,7 +251,11 @@ class FixtureFactory
{
if (substr($value, 0, 2) == '=>') {
// Parse a dictionary reference - used to set foreign keys
list($class, $identifier) = explode('.', substr($value, 2), 2);
if (strpos($value, '.') !== false) {
list($class, $identifier) = explode('.', substr($value, 2), 2);
} else {
throw new \LogicException("Bad fixture lookup identifier: " . $value);
}
if ($this->fixtures && !isset($this->fixtures[$class][$identifier])) {
throw new InvalidArgumentException(sprintf(

View File

@ -475,7 +475,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase
/**
* Get the ID of an object from the fixture.
*
* @param string $className The data class, as specified in your fixture file. Parent classes won't work
* @param string $className The data class or table name, as specified in your fixture file. Parent classes won't work
* @param string $identifier The identifier string, as provided in your fixture file
* @return int
*/
@ -498,7 +498,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase
* Return all of the IDs in the fixture of a particular class name.
* Will collate all IDs form all fixtures if multiple fixtures are provided.
*
* @param string $className
* @param string $className The data class or table name, as specified in your fixture file
* @return array A map of fixture-identifier => object-id
*/
protected function allFixtureIDs($className)
@ -509,7 +509,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase
/**
* Get an object from the fixture.
*
* @param string $className The data class, as specified in your fixture file. Parent classes won't work
* @param string $className The data class or table name, as specified in your fixture file. Parent classes won't work
* @param string $identifier The identifier string, as provided in your fixture file
*
* @return DataObject

View File

@ -172,4 +172,19 @@ class FixtureFactoryTest extends SapphireTest
DataObjectRelation::get()->byID($relation1->ID)
);
}
public function testGetByClassOrTable()
{
$factory = new FixtureFactory();
$obj1 = $factory->createObject(TestDataObject::class, 'object-one', [ 'Name' => 'test one' ]);
$this->assertInstanceOf(TestDataObject::class, $factory->get(TestDataObject::class, 'object-one'));
$this->assertEquals('test one', $factory->get(TestDataObject::class, 'object-one')->Name);
$obj2 = $factory->createRaw('FixtureFactoryTest_TestDataObject', 'object-two', [ 'Name' => 'test two' ]);
$this->assertInstanceOf(
TestDataObject::class,
$factory->get('FixtureFactoryTest_TestDataObject', 'object-two')
);
$this->assertEquals('test two', $factory->get('FixtureFactoryTest_TestDataObject', 'object-two')->Name);
}
}