renderWith('TestSession_inprogress'); // Database if(!$request->getVar('database')) { // Create a new one with a randomized name $dbname = SapphireTest::create_temp_db(); DB::set_alternative_database_name($dbname); } $this->setState($request->getVars()); return $this->renderWith('TestSession_start'); } public function set($request) { if(!SapphireTest::using_temp_db()) { throw new LogicException( "This command can only be used with a temporary database. " . "Perhaps you should use dev/testsession/start first?" ); } $this->setState($request->getVars()); return $this->renderWith('TestSession_inprogress'); } public function clear($request) { if(!SapphireTest::using_temp_db()) { throw new LogicException( "This command can only be used with a temporary database. " . "Perhaps you should use dev/testsession/start first?" ); } SapphireTest::empty_temp_db(); return "Cleared database and test state"; } public function end() { if(!SapphireTest::using_temp_db()) { throw new LogicException( "This command can only be used with a temporary database. " . "Perhaps you should use dev/testsession/start first?" ); } SapphireTest::kill_temp_db(); DB::set_alternative_database_name(null); Session::clear('testsession'); return $this->renderWith('TestSession_end'); } protected function loadFixtureIntoDb($fixtureFile) { $realFile = realpath(BASE_PATH.'/'.$fixtureFile); $baseDir = realpath(Director::baseFolder()); if(!$realFile || !file_exists($realFile)) { throw new LogicException("Fixture file doesn't exist"); } else if(substr($realFile,0,strlen($baseDir)) != $baseDir) { throw new LogicException("Fixture file must be inside $baseDir"); } else if(substr($realFile,-4) != '.yml') { throw new LogicException("Fixture file must be a .yml file"); } else if(!preg_match('/^([^\/.][^\/]+)\/tests\//', $fixtureFile)) { throw new LogicException("Fixture file must be inside the tests subfolder of one of your modules."); } $fixture = Injector::inst()->create('YamlFixture', $fixtureFile); $fixture->saveIntoDatabase(); Session::add_to_array('testsession.fixtures', $fixtureFile); return $fixture; } /** * @return boolean */ public function isTesting() { return SapphireTest::using_temp_db(); } public function setState($data) { // Database $dbname = (isset($data['database'])) ? $data['database'] : null; if($dbname) { // Set existing one, assumes it already has been created $prefix = defined('SS_DATABASE_PREFIX') ? SS_DATABASE_PREFIX : 'ss_'; $pattern = strtolower(sprintf('#^%stmpdb\d{7}#', $prefix)); if(!preg_match($pattern, $dbname)) { throw new InvalidArgumentException("Invalid database name format"); } DB::set_alternative_database_name($dbname); } // Fixtures $fixtureFile = (isset($data['fixture'])) ? $data['fixture'] : null; if($fixtureFile) { $this->loadFixtureIntoDb($fixtureFile); } else { // If no fixture, then use defaults $dataClasses = ClassInfo::subclassesFor('DataObject'); array_shift($dataClasses); foreach($dataClasses as $dataClass) singleton($dataClass)->requireDefaultRecords(); } } /** * @return ArrayList */ public function getState() { $state = array(); if($dbname = DB::get_alternative_database_name()) { $state[] = new ArrayData(array( 'Name' => 'Database', 'Value' => $dbname, )); } if($fixtures = Session::get('testsession.fixtures')) { $state[] = new ArrayData(array( 'Name' => 'Fixture', 'Value' => implode(',', array_unique($fixtures)), )); } return new ArrayList($state); } }