From f55e0bf547c85f4262cc0ac29d2b112a394f9323 Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Wed, 15 Aug 2007 06:38:41 +0000 Subject: [PATCH] Added PHPUnit unit testing framework git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@40129 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- core/model/DatabaseAdmin.php | 31 ++++----- core/model/ErrorPage.php | 2 +- core/model/SiteTree.php | 2 - tests/SapphireTest.php | 127 +++++++++++++++++++++++++++++++++++ tests/SiteTreeTest.php | 30 +++++++++ tests/SiteTreeTest.yml | 30 +++++++++ tests/TestRunner.php | 27 ++++++++ 7 files changed, 229 insertions(+), 20 deletions(-) create mode 100644 tests/SapphireTest.php create mode 100644 tests/SiteTreeTest.php create mode 100644 tests/SiteTreeTest.yml create mode 100644 tests/TestRunner.php diff --git a/core/model/DatabaseAdmin.php b/core/model/DatabaseAdmin.php index cdfc4bb11..84b2050c4 100644 --- a/core/model/DatabaseAdmin.php +++ b/core/model/DatabaseAdmin.php @@ -119,11 +119,11 @@ class DatabaseAdmin extends Controller { * Updates the database schema, creating tables & fields as necessary. * * @param boolean $quiet Don't show messages + * @param boolean $populate Populate the database, as well as setting up its schema */ - function doBuild($quiet = false) { + function doBuild($quiet = false, $populate = true) { $conn = DB::getConn(); - Profiler::mark('doBuild'); if($quiet) { DB::quiet(); } else { @@ -158,30 +158,28 @@ class DatabaseAdmin extends Controller { if(!$quiet) { echo "
  • $dataClass"; } - Profiler::mark("requireTable $dataClass"); singleton($dataClass)->requireTable(); - Profiler::unmark("requireTable $dataClass"); } } $conn->endSchemaUpdate(); ManifestBuilder::update_db_tables(); + + if($populate) { + if(!$quiet) { + echo '

    Creating database records

    '; + } - if(!$quiet) { - echo '

    Creating database records

    '; - } + foreach($dataClasses as $dataClass) { + // Test_ indicates that it's the data class is part of testing system - foreach($dataClasses as $dataClass) { - // Test_ indicates that it's the data class is part of testing system + if(strpos($dataClass,'Test_') === false) { + if(!$quiet) { + echo "
  • $dataClass"; + } - if(strpos($dataClass,'Test_') === false) { - if(!$quiet) { - echo "
  • $dataClass"; + singleton($dataClass)->requireDefaultRecords(); } - - Profiler::mark("requireDefaultRecords $dataClass"); - singleton($dataClass)->requireDefaultRecords(); - Profiler::unmark("requireDefaultRecords $dataClass"); } } @@ -190,7 +188,6 @@ class DatabaseAdmin extends Controller { if(isset($_REQUEST['from_installer'])) { echo "OK"; } - Profiler::unmark('doBuild'); } diff --git a/core/model/ErrorPage.php b/core/model/ErrorPage.php index 31f935419..3e117edca 100755 --- a/core/model/ErrorPage.php +++ b/core/model/ErrorPage.php @@ -21,7 +21,7 @@ class ErrorPage extends Page { */ function requireDefaultRecords() { parent::requireDefaultRecords(); - + if(!DataObject::get_one("ErrorPage", "ErrorCode = '404'")) { $errorpage = new ErrorPage(); $errorpage->ErrorCode = 404; diff --git a/core/model/SiteTree.php b/core/model/SiteTree.php index 94341c9f7..4b3f69e17 100644 --- a/core/model/SiteTree.php +++ b/core/model/SiteTree.php @@ -398,14 +398,12 @@ class SiteTree extends DataObject { if($this->class == 'SiteTree') { if(!DataObject::get_one("SiteTree", "URLSegment = 'home'")) { $homepage = new Page(); - echo 'Running with the homepage: ' . $homepage->ID; $homepage->Title = "Home"; $homepage->Content = "

    Welcome to SilverStripe! This is the default homepage. You can edit this page by opening the CMS.

    "; $homepage->URLSegment = "home"; $homepage->Status = "Published"; $homepage->write(); - echo 'Created the homepage: ' . $homepage->ID; $homepage->publish("Stage", "Live"); $homepage->flushCache(); diff --git a/tests/SapphireTest.php b/tests/SapphireTest.php new file mode 100644 index 000000000..954853f23 --- /dev/null +++ b/tests/SapphireTest.php @@ -0,0 +1,127 @@ +databaseExists($dbname)) { + $dbname = 'tmpdb' . rand(1000000,9999999); + } + $dbConn->selectDatabase($dbname); + + // This code is a bit misplaced; we want some way of the whole session being reinitialised... + Versioned::reading_stage(null); + + $dbConn->createDatabase(); + singleton('DataObject')->flushCache(); + + $dbadmin = new DatabaseAdmin(); + $dbadmin->doBuild(true, false); + + // Load the fixture into the database + $className = get_class($this); + $fixtureFile = eval("return {$className}::\$fixture_file;"); + $this->loadFixture($fixtureFile); + } + + /** + * Array of + */ + protected $fixtureDictionary; + + + /** + * 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 + * @param $identifier The identifier string, as provided in your fixture file + */ + protected function idFromFixture($className, $identifier) { + return $this->fixtureDictionary["$className.$identifier"]; + } + + /** + * Get an object from the fixture. + * @param $className The data class, as specified in your fixture file. Parent classes won't work + * @param $identifier The identifier string, as provided in your fixture file + */ + protected function objFromFixture($className, $identifier) { + return DataObject::get_by_id($className, $this->idFromFixture($className, $identifier)); + } + + /** + * Load a YAML fixture file into the database. + * Once loaded, you can use idFromFixture() and objFromFixture() to get items from the fixture + * @param $fixtureFile The location of the .yml fixture file, relative to the site base dir + */ + function loadFixture($fixtureFile) { + $parser = new Spyc(); + $fixtureContent = $parser->load(Director::baseFolder().'/'.$fixtureFile); + + $this->fixtureDictionary = array(); + + foreach($fixtureContent as $dataClass => $items) { + foreach($items as $identifier => $fields) { + $obj = new $dataClass(); + foreach($fields as $fieldName => $fieldVal) { + // Parse a dictionary reference - used to set foreign keys + if(substr($fieldVal,0,2) == '=>') { + $obj->$fieldName = $this->fixtureDicationary[ substr($fieldVal,2) ]; + + // Regular field value setting + } else { + $obj->$fieldName = $fieldVal; + } + } + $obj->write(); + + // Populate the dictionary with the ID + $this->fixtureDictionary[$dataClass.'.'.$identifier] = $obj->ID; + } + } + } + + function tearDown() { + // Delete our temporary database + $dbConn = DB::getConn(); + if(substr($dbConn->currentDatabase(),0,5) == 'tmpdb') { + // echo "Deleted temp database " . $dbConn->currentDatabase() . "\n"; + $dbConn->dropDatabase(); + } + } +} + +?> \ No newline at end of file diff --git a/tests/SiteTreeTest.php b/tests/SiteTreeTest.php new file mode 100644 index 000000000..9f8ab7d54 --- /dev/null +++ b/tests/SiteTreeTest.php @@ -0,0 +1,30 @@ + 'home', + 'staff' => 'my-staff', + 'about' => 'about-us', + 'staffduplicate' => 'my-staff-2', + 'product1' => '1-1-test-product', + 'product2' => 'another-product', + 'product3' => 'another-product-2', + 'product4' => 'another-product-3', + ); + + foreach($expectedURLs as $fixture => $urlSegment) { + $obj = $this->objFromFixture('Page', $fixture); + $this->assertEquals($urlSegment, $obj->URLSegment); + } + } +} \ No newline at end of file diff --git a/tests/SiteTreeTest.yml b/tests/SiteTreeTest.yml new file mode 100644 index 000000000..29f4caef2 --- /dev/null +++ b/tests/SiteTreeTest.yml @@ -0,0 +1,30 @@ +Page: + home: + Title: Home + about: + Title: About Us + staff: + Title: Staff + URLSegment: my-staff + Parent: =>Page.about + staffduplicate: + Title: Staff + URLSegment: my-staff + Parent: =>Page.about + products: + Title: Products + product1: + Title: 1.1 Test Product + product2: + Title: Another Product + product3: + Title: Another Product + product4: + Title: Another Product + contact: + Title: Contact Us + +ErrorPage: + 404: + Title: Page not Found + ErrorCode: 404 \ No newline at end of file diff --git a/tests/TestRunner.php b/tests/TestRunner.php new file mode 100644 index 000000000..0c4df8872 --- /dev/null +++ b/tests/TestRunner.php @@ -0,0 +1,27 @@ +Sapphire PHPUnit Test Runner"; + echo "

    Discovered the following subclasses of SapphireTest for testing: " . implode(", ", $tests) . "

    "; + + echo "
    ";
    +		$suite = new PHPUnit_Framework_TestSuite();
    +		foreach($tests as $test) {
    +			$suite->addTest(new PHPUnit_Framework_TestSuite($test));
    +		}
    +
    +		PHPUnit_TextUI_TestRunner::run($suite);
    +	}
    +}
    \ No newline at end of file