From 14e1341df6a8e4151142b43677555c731a8a286f Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Wed, 30 Mar 2011 19:47:30 +1300 Subject: [PATCH] ENHANCEMENT Added support for SapphireTest::$fixture_file paths relative to current class location ('MyTest.yml' or '../otherfolder/MyTest.yml'). Added SapphireTest->getCurrentAbsolutePath() and getCurrentRelativePath() for easy access within unit tests --- dev/SapphireTest.php | 28 ++++++++++++++++++++++++++++ dev/YamlFixture.php | 23 +++++++++++++++++------ tests/testing/YamlFixtureTest.php | 23 ++++++++++++++++++++++- 3 files changed, 67 insertions(+), 7 deletions(-) diff --git a/dev/SapphireTest.php b/dev/SapphireTest.php index 88944194cca..f6fc4813ef5 100755 --- a/dev/SapphireTest.php +++ b/dev/SapphireTest.php @@ -166,10 +166,19 @@ function setUp() { } if($fixtureFile) { + $pathForClass = $this->getCurrentPath(); $fixtureFiles = (is_array($fixtureFile)) ? $fixtureFile : array($fixtureFile); $i = 0; foreach($fixtureFiles as $fixtureFilePath) { + // Support fixture paths relative to the test class, rather than relative to webroot + // String checking is faster than file_exists() calls. + $isRelativeToFile = (strpos('/', $fixtureFilePath) === false || preg_match('/^\.\./', $fixtureFilePath)); + if($isRelativeToFile) { + $resolvedPath = realpath($pathForClass . '/' . $fixtureFilePath); + if($resolvedPath) $fixtureFilePath = $resolvedPath; + } + $fixture = new YamlFixture($fixtureFilePath); $fixture->saveIntoDatabase(); $this->fixtures[] = $fixture; @@ -370,6 +379,25 @@ function clearFixtures() { $this->fixtures = array(); } + /** + * Useful for writing unit tests without hardcoding folder structures. + * + * @return String Absolute path to current class. + */ + protected function getCurrentAbsolutePath() { + return dirname(SS_ClassLoader::instance()->getManifest()->getItemPath(get_class($this))); + } + + /** + * @return String File path relative to webroot + */ + protected function getCurrentRelativePath() { + $base = Director::baseFolder(); + $path = $this->getCurrentAbsolutePath(); + if(substr($path,0,strlen($base)) == $base) $path = preg_replace('/^\/*/', '', substr($path,strlen($base))); + return $path; + } + function tearDown() { // Preserve memory settings ini_set('memory_limit', ($this->originalMemoryLimit) ? $this->originalMemoryLimit : -1); diff --git a/dev/YamlFixture.php b/dev/YamlFixture.php index bd67b707b73..0a969e56f35 100644 --- a/dev/YamlFixture.php +++ b/dev/YamlFixture.php @@ -68,13 +68,11 @@ * @see http://code.google.com/p/spyc/ * * @todo Write unit test for YamlFixture - * - * @param $fixtureFile The location of the .yml fixture file, relative to the site base dir */ class YamlFixture extends Object { /** - * The location of the .yml fixture file, relative to the site base dir + * Absolute path to the .yml fixture file * * @var string */ @@ -87,15 +85,28 @@ class YamlFixture extends Object { */ protected $fixtureDictionary; + /** + * @param String Absolute file path, or relative path to {@link Director::baseFolder()} + */ function __construct($fixtureFile) { - if(!file_exists(Director::baseFolder().'/'. $fixtureFile)) { - user_error('YamlFixture::__construct(): Fixture path "' . $fixtureFile . '" not found', E_USER_ERROR); + if(!Director::is_absolute($fixtureFile)) $fixtureFile = Director::baseFolder().'/'. $fixtureFile; + + if(!file_exists($fixtureFile)) { + throw new InvalidArgumentException('YamlFixture::__construct(): Fixture path "' . $fixtureFile . '" not found'); } $this->fixtureFile = $fixtureFile; + parent::__construct(); } + /** + * @return String Absolute file path + */ + function getFixtureFile() { + return $this->fixtureFile; + } + /** * Get the ID of an object from the fixture. * @param $className The data class, as specified in your fixture file. Parent classes won't work @@ -151,7 +162,7 @@ public function saveIntoDatabase() { DataObject::set_validation_enabled(false); $parser = new Spyc(); - $fixtureContent = $parser->loadFile(Director::baseFolder().'/'.$this->fixtureFile); + $fixtureContent = $parser->loadFile($this->fixtureFile); $this->fixtureDictionary = array(); foreach($fixtureContent as $dataClass => $items) { diff --git a/tests/testing/YamlFixtureTest.php b/tests/testing/YamlFixtureTest.php index f7570ac6105..d2da8ba7791 100644 --- a/tests/testing/YamlFixtureTest.php +++ b/tests/testing/YamlFixtureTest.php @@ -1,13 +1,34 @@ assertEquals($absPath, $obj->getFixtureFile()); + } + + function testRelativeFixturePath() { + $relPath = 'sapphire/tests/testing/YamlFixtureTest.yml'; + $obj = new YamlFixture($relPath); + $this->assertEquals(Director::baseFolder() . '/' . $relPath, $obj->getFixtureFile()); + } + + /** + * @expectedException InvalidArgumentException + */ + function testFailsWithInvalidFixturePath() { + $invalidPath = 'sapphire/tests/testing/invalid.yml'; + $obj = new YamlFixture($invalidPath); + } + function testSQLInsert() { $object1 = DataObject::get_by_id("YamlFixtureTest_DataObject", $this->idFromFixture("YamlFixtureTest_DataObject", "testobject1")); $this->assertTrue($object1->ManyMany()->Count() == 2, "Should be 2 items in this manymany relationship");