From e40a0d0f1ab3206170a00e9233cb97268d87a626 Mon Sep 17 00:00:00 2001 From: helpfulrobot Date: Fri, 18 Dec 2015 07:17:16 +1300 Subject: [PATCH] Converted to PSR-2 --- code/TestSessionController.php | 802 ++++++++++--------- code/TestSessionEnvironment.php | 668 +++++++-------- code/TestSessionRequestFilter.php | 98 ++- code/TestSessionStubCodeWriter.php | 120 +-- tests/unit/TestSessionStubCodeWriterTest.php | 80 +- 5 files changed, 916 insertions(+), 852 deletions(-) diff --git a/code/TestSessionController.php b/code/TestSessionController.php index 1031bd4..0655ff7 100644 --- a/code/TestSessionController.php +++ b/code/TestSessionController.php @@ -2,394 +2,416 @@ /** * Requires PHP's mycrypt extension in order to set the database name as an encrypted cookie. */ -class TestSessionController extends Controller { - - private static $allowed_actions = array( - 'index', - 'start', - 'set', - 'end', - 'clear', - 'browsersessionstate', - 'StartForm', - 'ProgressForm', - ); - - private static $alternative_database_name = -1; - - /** - * @var String Absolute path to a folder containing *.sql dumps. - */ - private static $database_templates_path; - - /** - * @var TestSessionEnvironment - */ - protected $environment; - - public function __construct() { - parent::__construct(); - - $this->environment = Injector::inst()->get('TestSessionEnvironment'); - } - - public function init() { - parent::init(); - - $this->extend('init'); - - $canAccess = ( - !Director::isLive() - && (Director::isDev() || Director::isTest() || Director::is_cli() || Permission::check("ADMIN")) - ); - if(!$canAccess) return Security::permissionFailure($this); - - Requirements::javascript('framework/thirdparty/jquery/jquery.js'); - Requirements::javascript('testsession/javascript/testsession.js'); - } - - public function Link($action = null) { - return Controller::join_links(Director::baseUrl(), 'dev/testsession', $action); - } - - public function index() { - if($this->environment->isRunningTests()) { - return $this->renderWith('TestSession_inprogress'); - } else { - return $this->renderWith('TestSession_start'); - } - } - - /** - * Start a test session. If you wish to extend how the test session is started (and add additional test state), - * then take a look at {@link TestSessionEnvironment::startTestSession()} and - * {@link TestSessionEnvironment::applyState()} to see the extension points. - */ - public function start() { - $params = $this->request->requestVars(); - - if(!empty($params['globalTestSession'])) { - $id = null; - } else { - $generator = Injector::inst()->get('RandomGenerator'); - $id = substr($generator->randomToken(), 0, 10); - Session::set('TestSessionId', $id); - } - - // Convert datetime from form object into a single string - $params = $this->fixDatetimeFormField($params); - - // Remove unnecessary items of form-specific data from being saved in the test session - $params = array_diff_key( - $params, - array( - 'action_set' => true, - 'action_start' => true, - 'SecurityID' => true, - 'url' => true, - 'flush' => true, - ) - ); - - $this->environment->startTestSession($params, $id); - - // Optionally import database - if(!empty($params['importDatabasePath']) || !empty($params['importDatabaseFilename'])) { - $absPath = ''; - - // by path - if(!empty($params['importDatabasePath'])) { - $absPath = $params['importDatabasePath']; - - // by filename - }else if(!empty($params['importDatabaseFilename'])) { - foreach($this->getDatabaseTemplates() as $tAbsPath => $tFilename){ - if($tFilename === $params['importDatabaseFilename']){ - $absPath = $tAbsPath; - break; - } - } - } - $this->environment->importDatabase( - $absPath, - !empty($params['requireDefaultRecords']) ? $params['requireDefaultRecords'] : false - ); - } else if(!empty($params['requireDefaultRecords']) && $params['requireDefaultRecords']) { - $this->environment->requireDefaultRecords(); - } - - // Fixtures - $fixtureFile = (!empty($params['fixture'])) ? $params['fixture'] : null; - if($fixtureFile) { - $this->environment->loadFixtureIntoDb($fixtureFile); - } - - return $this->renderWith('TestSession_inprogress'); - } - - /** - * Set $_SESSION state for the current browser session. - */ - public function browsersessionstate($request) { - if(!$this->environment->isRunningTests()) { - throw new LogicException("No test session in progress."); - } - - $newSessionStates = array_diff_key($request->getVars(), array('url' => true)); - if(!$newSessionStates) { - throw new LogicException('No query parameters detected'); - } - - $sessionStates = (array)Session::get('_TestSessionController.BrowserSessionState'); - - foreach($newSessionStates as $k => $v) { - Session::set($k, $v); - } - - // Track which state we're setting so we can unset later in end() - Session::set('_TestSessionController.BrowserSessionState', array_merge($sessionStates, $newSessionStates)); - } - - public function StartForm() { - $databaseTemplates = $this->getDatabaseTemplates(); - $fields = new FieldList( - new CheckboxField('createDatabase', 'Create temporary database?', 1) - ); - if($databaseTemplates) { - $fields->push( - $dropdown = new DropdownField('importDatabasePath', false) - ); - - $dropdown->setSource($databaseTemplates) - ->setEmptyString('Empty database'); - } - $fields->push(new CheckboxField('requireDefaultRecords', 'Create default data?')); - if(Director::isDev()) { - $fields->push( - CheckboxField::create('globalTestSession', 'Use global test session?') - ->setDescription('Caution: Will apply to all users across browsers') - ); - } - $fields->merge($this->getBaseFields()); - $form = new Form( - $this, - 'StartForm', - $fields, - new FieldList( - new FormAction('start', 'Start Session') - ) - ); - - $this->extend('updateStartForm', $form); - - return $form; - } - - /** - * Shows state which is allowed to be modified while a test session is in progress. - */ - public function ProgressForm() { - $fields = $this->getBaseFields(); - $form = new Form( - $this, - 'ProgressForm', - $fields, - new FieldList( - new FormAction('set', 'Set testing state') - ) - ); - - - $form->setFormAction($this->Link('set')); - - $this->extend('updateProgressForm', $form); - - return $form; - } - - protected function getBaseFields() { - $testState = $this->environment->getState(); - - $fields = new FieldList( - $textfield = new TextField('fixture', 'Fixture YAML file path'), - $datetimeField = new DatetimeField('datetime', 'Custom date'), - new HiddenField('flush', null, 1) - ); - $textfield->setAttribute('placeholder', 'Example: framework/tests/security/MemberTest.yml'); - $datetimeField->getDateField() - ->setConfig('dateformat', 'yyyy-MM-dd') - ->setConfig('showcalendar', true) - ->setAttribute('placeholder', 'Date (yyyy-MM-dd)'); - $datetimeField->getTimeField() - ->setConfig('timeformat', 'HH:mm:ss') - ->setAttribute('placeholder', 'Time (HH:mm:ss)'); - $datetimeField->setValue((isset($testState->datetime) ? $testState->datetime : null)); - - $this->extend('updateBaseFields', $fields); - - return $fields; - } - - public function DatabaseName() { - $db = DB::get_conn(); - return $db->getSelectedDatabase(); - } - - /** - * Updates an in-progress {@link TestSessionEnvironment} object with new details. This could be loading in new - * fixtures, setting the mocked date to another value etc. - * - * @return HTMLText Rendered Template - * @throws LogicException - */ - public function set() { - if(!$this->environment->isRunningTests()) { - throw new LogicException("No test session in progress."); - } - - $params = $this->request->requestVars(); - - // Convert datetime from form object into a single string - $params = $this->fixDatetimeFormField($params); - - // Remove unnecessary items of form-specific data from being saved in the test session - $params = array_diff_key( - $params, - array( - 'action_set' => true, - 'action_start' => true, - 'SecurityID' => true, - 'url' => true, - 'flush' => true, - ) - ); - - $this->environment->updateTestSession($params); - - return $this->renderWith('TestSession_inprogress'); - } - - public function clear() { - if(!$this->environment->isRunningTests()) { - throw new LogicException("No test session in progress."); - } - - $this->extend('onBeforeClear'); - - if(SapphireTest::using_temp_db()) { - SapphireTest::empty_temp_db(); - } - - if(isset($_SESSION['_testsession_codeblocks'])) { - unset($_SESSION['_testsession_codeblocks']); - } - - $this->extend('onAfterClear'); - - return "Cleared database and test state"; - } - - /** - * As with {@link self::start()}, if you want to extend the functionality of this, then look at - * {@link TestSessionEnvironent::endTestSession()} as the extension points have moved to there now that the logic - * is there. - */ - public function end() { - if(!$this->environment->isRunningTests()) { - throw new LogicException("No test session in progress."); - } - - $this->environment->endTestSession(); - Session::clear('TestSessionId'); - - // Clear out all PHP session states which have been set previously - if($sessionStates = Session::get('_TestSessionController.BrowserSessionState')) { - foreach($sessionStates as $k => $v) { - Session::clear($k); - } - Session::clear('_TestSessionController'); - } - - - return $this->renderWith('TestSession_end'); - } - - /** - * @return boolean - */ - public function isTesting() { - return SapphireTest::using_temp_db(); - } - - public function setState($data) { - Deprecation::notice('3.1', 'TestSessionController::setState() is no longer used, please use ' - . 'TestSessionEnvironment instead.'); - } - - /** - * @return ArrayList - */ - public function getState() { - $stateObj = $this->environment->getState(); - $state = array(); - - // Convert the stdObject of state into ArrayData - foreach($stateObj as $k => $v) { - $state[] = new ArrayData(array( - 'Name' => $k, - 'Value' => var_export($v, true) - )); - } - - return new ArrayList($state); - } - - /** - * Get all *.sql database files located in a specific path, - * keyed by their file name. - * - * @param String $path Absolute folder path - * @return array - */ - protected function getDatabaseTemplates($path = null) { - $templates = array(); - - if(!$path) { - $path = $this->config()->database_templates_path; - } - - // TODO Remove once we can set BASE_PATH through the config layer - if($path && !Director::is_absolute($path)) { - $path = BASE_PATH . '/' . $path; - } - - if($path && file_exists($path)) { - $it = new FilesystemIterator($path); - foreach($it as $fileinfo) { - if($fileinfo->getExtension() != 'sql') continue; - $templates[$fileinfo->getRealPath()] = $fileinfo->getFilename(); - } - } - - return $templates; - } - - /** - * @param $params array The form fields as passed through from ->start() or ->set() - * @return array The form fields, after fixing the datetime field if necessary - */ - private function fixDatetimeFormField($params) { - if(isset($params['datetime']) && is_array($params['datetime']) && !empty($params['datetime']['date'])) { - // Convert DatetimeField format from array into string - $datetime = $params['datetime']['date']; - $datetime .= ' '; - $datetime .= (@$params['datetime']['time']) ? $params['datetime']['time'] : '00:00:00'; - $params['datetime'] = $datetime; - } else if(isset($params['datetime']) && empty($params['datetime']['date'])) { - unset($params['datetime']); // No datetime, so remove the param entirely - } - - return $params; - } - +class TestSessionController extends Controller +{ + + private static $allowed_actions = array( + 'index', + 'start', + 'set', + 'end', + 'clear', + 'browsersessionstate', + 'StartForm', + 'ProgressForm', + ); + + private static $alternative_database_name = -1; + + /** + * @var String Absolute path to a folder containing *.sql dumps. + */ + private static $database_templates_path; + + /** + * @var TestSessionEnvironment + */ + protected $environment; + + public function __construct() + { + parent::__construct(); + + $this->environment = Injector::inst()->get('TestSessionEnvironment'); + } + + public function init() + { + parent::init(); + + $this->extend('init'); + + $canAccess = ( + !Director::isLive() + && (Director::isDev() || Director::isTest() || Director::is_cli() || Permission::check("ADMIN")) + ); + if (!$canAccess) { + return Security::permissionFailure($this); + } + + Requirements::javascript('framework/thirdparty/jquery/jquery.js'); + Requirements::javascript('testsession/javascript/testsession.js'); + } + + public function Link($action = null) + { + return Controller::join_links(Director::baseUrl(), 'dev/testsession', $action); + } + + public function index() + { + if ($this->environment->isRunningTests()) { + return $this->renderWith('TestSession_inprogress'); + } else { + return $this->renderWith('TestSession_start'); + } + } + + /** + * Start a test session. If you wish to extend how the test session is started (and add additional test state), + * then take a look at {@link TestSessionEnvironment::startTestSession()} and + * {@link TestSessionEnvironment::applyState()} to see the extension points. + */ + public function start() + { + $params = $this->request->requestVars(); + + if (!empty($params['globalTestSession'])) { + $id = null; + } else { + $generator = Injector::inst()->get('RandomGenerator'); + $id = substr($generator->randomToken(), 0, 10); + Session::set('TestSessionId', $id); + } + + // Convert datetime from form object into a single string + $params = $this->fixDatetimeFormField($params); + + // Remove unnecessary items of form-specific data from being saved in the test session + $params = array_diff_key( + $params, + array( + 'action_set' => true, + 'action_start' => true, + 'SecurityID' => true, + 'url' => true, + 'flush' => true, + ) + ); + + $this->environment->startTestSession($params, $id); + + // Optionally import database + if (!empty($params['importDatabasePath']) || !empty($params['importDatabaseFilename'])) { + $absPath = ''; + + // by path + if (!empty($params['importDatabasePath'])) { + $absPath = $params['importDatabasePath']; + + // by filename + } elseif (!empty($params['importDatabaseFilename'])) { + foreach ($this->getDatabaseTemplates() as $tAbsPath => $tFilename) { + if ($tFilename === $params['importDatabaseFilename']) { + $absPath = $tAbsPath; + break; + } + } + } + $this->environment->importDatabase( + $absPath, + !empty($params['requireDefaultRecords']) ? $params['requireDefaultRecords'] : false + ); + } elseif (!empty($params['requireDefaultRecords']) && $params['requireDefaultRecords']) { + $this->environment->requireDefaultRecords(); + } + + // Fixtures + $fixtureFile = (!empty($params['fixture'])) ? $params['fixture'] : null; + if ($fixtureFile) { + $this->environment->loadFixtureIntoDb($fixtureFile); + } + + return $this->renderWith('TestSession_inprogress'); + } + + /** + * Set $_SESSION state for the current browser session. + */ + public function browsersessionstate($request) + { + if (!$this->environment->isRunningTests()) { + throw new LogicException("No test session in progress."); + } + + $newSessionStates = array_diff_key($request->getVars(), array('url' => true)); + if (!$newSessionStates) { + throw new LogicException('No query parameters detected'); + } + + $sessionStates = (array)Session::get('_TestSessionController.BrowserSessionState'); + + foreach ($newSessionStates as $k => $v) { + Session::set($k, $v); + } + + // Track which state we're setting so we can unset later in end() + Session::set('_TestSessionController.BrowserSessionState', array_merge($sessionStates, $newSessionStates)); + } + + public function StartForm() + { + $databaseTemplates = $this->getDatabaseTemplates(); + $fields = new FieldList( + new CheckboxField('createDatabase', 'Create temporary database?', 1) + ); + if ($databaseTemplates) { + $fields->push( + $dropdown = new DropdownField('importDatabasePath', false) + ); + + $dropdown->setSource($databaseTemplates) + ->setEmptyString('Empty database'); + } + $fields->push(new CheckboxField('requireDefaultRecords', 'Create default data?')); + if (Director::isDev()) { + $fields->push( + CheckboxField::create('globalTestSession', 'Use global test session?') + ->setDescription('Caution: Will apply to all users across browsers') + ); + } + $fields->merge($this->getBaseFields()); + $form = new Form( + $this, + 'StartForm', + $fields, + new FieldList( + new FormAction('start', 'Start Session') + ) + ); + + $this->extend('updateStartForm', $form); + + return $form; + } + + /** + * Shows state which is allowed to be modified while a test session is in progress. + */ + public function ProgressForm() + { + $fields = $this->getBaseFields(); + $form = new Form( + $this, + 'ProgressForm', + $fields, + new FieldList( + new FormAction('set', 'Set testing state') + ) + ); + + + $form->setFormAction($this->Link('set')); + + $this->extend('updateProgressForm', $form); + + return $form; + } + + protected function getBaseFields() + { + $testState = $this->environment->getState(); + + $fields = new FieldList( + $textfield = new TextField('fixture', 'Fixture YAML file path'), + $datetimeField = new DatetimeField('datetime', 'Custom date'), + new HiddenField('flush', null, 1) + ); + $textfield->setAttribute('placeholder', 'Example: framework/tests/security/MemberTest.yml'); + $datetimeField->getDateField() + ->setConfig('dateformat', 'yyyy-MM-dd') + ->setConfig('showcalendar', true) + ->setAttribute('placeholder', 'Date (yyyy-MM-dd)'); + $datetimeField->getTimeField() + ->setConfig('timeformat', 'HH:mm:ss') + ->setAttribute('placeholder', 'Time (HH:mm:ss)'); + $datetimeField->setValue((isset($testState->datetime) ? $testState->datetime : null)); + + $this->extend('updateBaseFields', $fields); + + return $fields; + } + + public function DatabaseName() + { + $db = DB::get_conn(); + return $db->getSelectedDatabase(); + } + + /** + * Updates an in-progress {@link TestSessionEnvironment} object with new details. This could be loading in new + * fixtures, setting the mocked date to another value etc. + * + * @return HTMLText Rendered Template + * @throws LogicException + */ + public function set() + { + if (!$this->environment->isRunningTests()) { + throw new LogicException("No test session in progress."); + } + + $params = $this->request->requestVars(); + + // Convert datetime from form object into a single string + $params = $this->fixDatetimeFormField($params); + + // Remove unnecessary items of form-specific data from being saved in the test session + $params = array_diff_key( + $params, + array( + 'action_set' => true, + 'action_start' => true, + 'SecurityID' => true, + 'url' => true, + 'flush' => true, + ) + ); + + $this->environment->updateTestSession($params); + + return $this->renderWith('TestSession_inprogress'); + } + + public function clear() + { + if (!$this->environment->isRunningTests()) { + throw new LogicException("No test session in progress."); + } + + $this->extend('onBeforeClear'); + + if (SapphireTest::using_temp_db()) { + SapphireTest::empty_temp_db(); + } + + if (isset($_SESSION['_testsession_codeblocks'])) { + unset($_SESSION['_testsession_codeblocks']); + } + + $this->extend('onAfterClear'); + + return "Cleared database and test state"; + } + + /** + * As with {@link self::start()}, if you want to extend the functionality of this, then look at + * {@link TestSessionEnvironent::endTestSession()} as the extension points have moved to there now that the logic + * is there. + */ + public function end() + { + if (!$this->environment->isRunningTests()) { + throw new LogicException("No test session in progress."); + } + + $this->environment->endTestSession(); + Session::clear('TestSessionId'); + + // Clear out all PHP session states which have been set previously + if ($sessionStates = Session::get('_TestSessionController.BrowserSessionState')) { + foreach ($sessionStates as $k => $v) { + Session::clear($k); + } + Session::clear('_TestSessionController'); + } + + + return $this->renderWith('TestSession_end'); + } + + /** + * @return boolean + */ + public function isTesting() + { + return SapphireTest::using_temp_db(); + } + + public function setState($data) + { + Deprecation::notice('3.1', 'TestSessionController::setState() is no longer used, please use ' + . 'TestSessionEnvironment instead.'); + } + + /** + * @return ArrayList + */ + public function getState() + { + $stateObj = $this->environment->getState(); + $state = array(); + + // Convert the stdObject of state into ArrayData + foreach ($stateObj as $k => $v) { + $state[] = new ArrayData(array( + 'Name' => $k, + 'Value' => var_export($v, true) + )); + } + + return new ArrayList($state); + } + + /** + * Get all *.sql database files located in a specific path, + * keyed by their file name. + * + * @param String $path Absolute folder path + * @return array + */ + protected function getDatabaseTemplates($path = null) + { + $templates = array(); + + if (!$path) { + $path = $this->config()->database_templates_path; + } + + // TODO Remove once we can set BASE_PATH through the config layer + if ($path && !Director::is_absolute($path)) { + $path = BASE_PATH . '/' . $path; + } + + if ($path && file_exists($path)) { + $it = new FilesystemIterator($path); + foreach ($it as $fileinfo) { + if ($fileinfo->getExtension() != 'sql') { + continue; + } + $templates[$fileinfo->getRealPath()] = $fileinfo->getFilename(); + } + } + + return $templates; + } + + /** + * @param $params array The form fields as passed through from ->start() or ->set() + * @return array The form fields, after fixing the datetime field if necessary + */ + private function fixDatetimeFormField($params) + { + if (isset($params['datetime']) && is_array($params['datetime']) && !empty($params['datetime']['date'])) { + // Convert DatetimeField format from array into string + $datetime = $params['datetime']['date']; + $datetime .= ' '; + $datetime .= (@$params['datetime']['time']) ? $params['datetime']['time'] : '00:00:00'; + $params['datetime'] = $datetime; + } elseif (isset($params['datetime']) && empty($params['datetime']['date'])) { + unset($params['datetime']); // No datetime, so remove the param entirely + } + + return $params; + } } diff --git a/code/TestSessionEnvironment.php b/code/TestSessionEnvironment.php index 257d304..1262961 100644 --- a/code/TestSessionEnvironment.php +++ b/code/TestSessionEnvironment.php @@ -24,390 +24,410 @@ * * See {@link $state} for default information stored in the test session. */ -class TestSessionEnvironment extends Object { +class TestSessionEnvironment extends Object +{ - /** - * @var int Optional identifier for the session. - */ - protected $id; + /** + * @var int Optional identifier for the session. + */ + protected $id; - /** - * @var string The original database name, before we overrode it with our tmpdb. - * - * Used in {@link self::resetDatabaseName()} when we want to restore the normal DB connection. - */ - private $oldDatabaseName; + /** + * @var string The original database name, before we overrode it with our tmpdb. + * + * Used in {@link self::resetDatabaseName()} when we want to restore the normal DB connection. + */ + private $oldDatabaseName; - /** - * @config - * @var string Path (from web-root) to the test state file that indicates a testsession is in progress. - * Defaults to value stored in testsession/_config/_config.yml - */ - private static $test_state_file = 'TESTS_RUNNING.json'; + /** + * @config + * @var string Path (from web-root) to the test state file that indicates a testsession is in progress. + * Defaults to value stored in testsession/_config/_config.yml + */ + private static $test_state_file = 'TESTS_RUNNING.json'; - /** - * @config - * @var [type] - */ - private static $test_state_id_file = 'TESTS_RUNNING-%s.json'; + /** + * @config + * @var [type] + */ + private static $test_state_id_file = 'TESTS_RUNNING-%s.json'; - public function __construct($id = null) { - parent::__construct(); + public function __construct($id = null) + { + parent::__construct(); - if($id) { - $this->id = $id; - } else { - Session::start(); - // $_SESSION != Session::get() in some execution paths, suspect Controller->pushCurrent() - // as part of the issue, easiest resolution is to use session directly for now - $this->id = (isset($_SESSION['TestSessionId'])) ? $_SESSION['TestSessionId'] : null; - } - } + if ($id) { + $this->id = $id; + } else { + Session::start(); + // $_SESSION != Session::get() in some execution paths, suspect Controller->pushCurrent() + // as part of the issue, easiest resolution is to use session directly for now + $this->id = (isset($_SESSION['TestSessionId'])) ? $_SESSION['TestSessionId'] : null; + } + } - /** - * @return String Absolute path to the file persisting our state. - */ - public function getFilePath() { - if($this->id) { - $path = Director::getAbsFile(sprintf($this->config()->test_state_id_file, $this->id)); - } else { - $path = Director::getAbsFile($this->config()->test_state_file); - } + /** + * @return String Absolute path to the file persisting our state. + */ + public function getFilePath() + { + if ($this->id) { + $path = Director::getAbsFile(sprintf($this->config()->test_state_id_file, $this->id)); + } else { + $path = Director::getAbsFile($this->config()->test_state_file); + } - return $path; - } + return $path; + } - /** - * Tests for the existence of the file specified by $this->test_state_file - */ - public function isRunningTests() { - return(file_exists($this->getFilePath())); - } + /** + * Tests for the existence of the file specified by $this->test_state_file + */ + public function isRunningTests() + { + return(file_exists($this->getFilePath())); + } - /** - * @param String $id - */ - public function setId($id) { - $this->id = $id; - } + /** + * @param String $id + */ + public function setId($id) + { + $this->id = $id; + } - /** - * @return String - */ - public function getId() { - return $this->id; - } + /** + * @return String + */ + public function getId() + { + return $this->id; + } - /** - * Creates a temp database, sets up any extra requirements, and writes the state file. The database will be - * connected to as part of {@link self::applyState()}, so if you're continuing script execution after calling this - * method, be aware that the database will be different - so various things may break (e.g. administrator logins - * using the SS_DEFAULT_USERNAME / SS_DEFAULT_PASSWORD constants). - * - * If something isn't explicitly handled here, and needs special handling, then it should be taken care of by an - * extension to TestSessionEnvironment. You can either extend onBeforeStartTestSession() or - * onAfterStartTestSession(). Alternatively, for more fine-grained control, you can also extend - * onBeforeApplyState() and onAfterApplyState(). See the {@link self::applyState()} method for more. - * - * @param array $state An array of test state options to write. - */ - public function startTestSession($state = null, $id = null) { - if(!$state) $state = array(); - $this->removeStateFile(); - $this->id = $id; + /** + * Creates a temp database, sets up any extra requirements, and writes the state file. The database will be + * connected to as part of {@link self::applyState()}, so if you're continuing script execution after calling this + * method, be aware that the database will be different - so various things may break (e.g. administrator logins + * using the SS_DEFAULT_USERNAME / SS_DEFAULT_PASSWORD constants). + * + * If something isn't explicitly handled here, and needs special handling, then it should be taken care of by an + * extension to TestSessionEnvironment. You can either extend onBeforeStartTestSession() or + * onAfterStartTestSession(). Alternatively, for more fine-grained control, you can also extend + * onBeforeApplyState() and onAfterApplyState(). See the {@link self::applyState()} method for more. + * + * @param array $state An array of test state options to write. + */ + public function startTestSession($state = null, $id = null) + { + if (!$state) { + $state = array(); + } + $this->removeStateFile(); + $this->id = $id; - // Assumes state will be modified by reference - $this->extend('onBeforeStartTestSession', $state); + // Assumes state will be modified by reference + $this->extend('onBeforeStartTestSession', $state); - // Convert to JSON and back so we can share the applyState() code between this and ->loadFromFile() - $json = json_encode($state, JSON_FORCE_OBJECT); - $state = json_decode($json); + // Convert to JSON and back so we can share the applyState() code between this and ->loadFromFile() + $json = json_encode($state, JSON_FORCE_OBJECT); + $state = json_decode($json); - $this->applyState($state); + $this->applyState($state); - $this->extend('onAfterStartTestSession'); - } + $this->extend('onAfterStartTestSession'); + } - public function updateTestSession($state) { - $this->extend('onBeforeUpdateTestSession', $state); + public function updateTestSession($state) + { + $this->extend('onBeforeUpdateTestSession', $state); - // Convert to JSON and back so we can share the appleState() code between this and ->loadFromFile() - $json = json_encode($state, JSON_FORCE_OBJECT); - $state = json_decode($json); + // Convert to JSON and back so we can share the appleState() code between this and ->loadFromFile() + $json = json_encode($state, JSON_FORCE_OBJECT); + $state = json_decode($json); - $this->applyState($state); + $this->applyState($state); - $this->extend('onAfterUpdateTestSession'); - } + $this->extend('onAfterUpdateTestSession'); + } - /** - * Assumes the database has already been created in startTestSession(), as this method can be called from - * _config.php where we don't yet have a DB connection. - * - * Persists the state to the filesystem. - * - * You can extend this by creating an Extension object and implementing either onBeforeApplyState() or - * onAfterApplyState() to add your own test state handling in. - * - * @throws LogicException - * @throws InvalidArgumentException - */ - public function applyState($state) { - $this->extend('onBeforeApplyState', $state); + /** + * Assumes the database has already been created in startTestSession(), as this method can be called from + * _config.php where we don't yet have a DB connection. + * + * Persists the state to the filesystem. + * + * You can extend this by creating an Extension object and implementing either onBeforeApplyState() or + * onAfterApplyState() to add your own test state handling in. + * + * @throws LogicException + * @throws InvalidArgumentException + */ + public function applyState($state) + { + $this->extend('onBeforeApplyState', $state); - $database = (isset($state->database)) ? $state->database : null; + $database = (isset($state->database)) ? $state->database : null; - // back up source - global $databaseConfig; - $this->oldDatabaseName = $databaseConfig['database']; + // back up source + global $databaseConfig; + $this->oldDatabaseName = $databaseConfig['database']; - // Load existing state from $this->state into $state, if there is any - $oldState = $this->getState(); + // Load existing state from $this->state into $state, if there is any + $oldState = $this->getState(); - if($oldState) { - foreach($oldState as $k => $v) { - if(!isset($state->$k)) { - $state->$k = $v; // Don't overwrite stuff in $state, as that's the new state - } - } - } + if ($oldState) { + foreach ($oldState as $k => $v) { + if (!isset($state->$k)) { + $state->$k = $v; // Don't overwrite stuff in $state, as that's the new state + } + } + } - // ensure we have a connection to the database - if(isset($state->database) && $state->database) { - if(!DB::get_conn()) { - // No connection, so try and connect to tmpdb if it exists - if(isset($state->database)) { - $this->oldDatabaseName = $databaseConfig['database']; - $databaseConfig['database'] = $state->database; - } + // ensure we have a connection to the database + if (isset($state->database) && $state->database) { + if (!DB::get_conn()) { + // No connection, so try and connect to tmpdb if it exists + if (isset($state->database)) { + $this->oldDatabaseName = $databaseConfig['database']; + $databaseConfig['database'] = $state->database; + } - // Connect to database - DB::connect($databaseConfig); - } else { - // We've already connected to the database, do a fast check to see what database we're currently using - $db = DB::get_conn()->getSelectedDatabase(); - if(isset($state->database) && $db != $state->database) { - $this->oldDatabaseName = $databaseConfig['database']; - $databaseConfig['database'] = $state->database; - DB::connect($databaseConfig); - } - } - } + // Connect to database + DB::connect($databaseConfig); + } else { + // We've already connected to the database, do a fast check to see what database we're currently using + $db = DB::get_conn()->getSelectedDatabase(); + if (isset($state->database) && $db != $state->database) { + $this->oldDatabaseName = $databaseConfig['database']; + $databaseConfig['database'] = $state->database; + DB::connect($databaseConfig); + } + } + } - // Database - if(!$this->isRunningTests()) { - $dbName = (isset($state->database)) ? $state->database : null; + // Database + if (!$this->isRunningTests()) { + $dbName = (isset($state->database)) ? $state->database : null; - if($dbName) { - $dbExists = DB::get_conn()->databaseExists($dbName); - } else { - $dbExists = false; - } + if ($dbName) { + $dbExists = DB::get_conn()->databaseExists($dbName); + } else { + $dbExists = false; + } - if(!$dbExists) { - // Create a new one with a randomized name - $dbName = SapphireTest::create_temp_db(); + if (!$dbExists) { + // Create a new one with a randomized name + $dbName = SapphireTest::create_temp_db(); - $state->database = $dbName; // In case it's changed by the call to SapphireTest::create_temp_db(); + $state->database = $dbName; // In case it's changed by the call to SapphireTest::create_temp_db(); - // 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"); - } + // 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"); + } - $this->oldDatabaseName = $databaseConfig['database']; - $databaseConfig['database'] = $dbName; // Instead of calling DB::set_alternative_db_name(); + $this->oldDatabaseName = $databaseConfig['database']; + $databaseConfig['database'] = $dbName; // Instead of calling DB::set_alternative_db_name(); - // Connect to the new database, overwriting the old DB connection (if any) - DB::connect($databaseConfig); - } - } + // Connect to the new database, overwriting the old DB connection (if any) + DB::connect($databaseConfig); + } + } - // Mailer - $mailer = (isset($state->mailer)) ? $state->mailer : null; + // Mailer + $mailer = (isset($state->mailer)) ? $state->mailer : null; - if($mailer) { - if(!class_exists($mailer) || !is_subclass_of($mailer, 'Mailer')) { - throw new InvalidArgumentException(sprintf( - 'Class "%s" is not a valid class, or subclass of Mailer', - $mailer - )); - } - } + if ($mailer) { + if (!class_exists($mailer) || !is_subclass_of($mailer, 'Mailer')) { + throw new InvalidArgumentException(sprintf( + 'Class "%s" is not a valid class, or subclass of Mailer', + $mailer + )); + } + } - // Date and time - if(isset($state->datetime)) { - require_once 'Zend/Date.php'; - // Convert DatetimeField format - if(!Zend_Date::isDate($state->datetime, 'yyyy-MM-dd HH:mm:ss')) { - throw new LogicException(sprintf( - 'Invalid date format "%s", use yyyy-MM-dd HH:mm:ss', - $state->datetime - )); - } - } + // Date and time + if (isset($state->datetime)) { + require_once 'Zend/Date.php'; + // Convert DatetimeField format + if (!Zend_Date::isDate($state->datetime, 'yyyy-MM-dd HH:mm:ss')) { + throw new LogicException(sprintf( + 'Invalid date format "%s", use yyyy-MM-dd HH:mm:ss', + $state->datetime + )); + } + } - $this->saveState($state); - $this->extend('onAfterApplyState'); - } + $this->saveState($state); + $this->extend('onAfterApplyState'); + } - /** - * Import the database - * - * @param String $path Absolute path to a SQL dump (include DROP TABLE commands) - * @return void - */ - public function importDatabase($path, $requireDefaultRecords = false) { - $sql = file_get_contents($path); + /** + * Import the database + * + * @param String $path Absolute path to a SQL dump (include DROP TABLE commands) + * @return void + */ + public function importDatabase($path, $requireDefaultRecords = false) + { + $sql = file_get_contents($path); - // Split into individual query commands, removing comments - $sqlCmds = array_filter( - preg_split('/;\n/', - preg_replace(array('/^$\n/m', '/^(\/|#).*$\n/m'), '', $sql) - ) - ); + // Split into individual query commands, removing comments + $sqlCmds = array_filter( + preg_split('/;\n/', + preg_replace(array('/^$\n/m', '/^(\/|#).*$\n/m'), '', $sql) + ) + ); - // Execute each query - foreach($sqlCmds as $sqlCmd) { - DB::query($sqlCmd); - } + // Execute each query + foreach ($sqlCmds as $sqlCmd) { + DB::query($sqlCmd); + } - // In case the dump involved CREATE TABLE commands, we need to ensure the schema is still up to date - $dbAdmin = new DatabaseAdmin(); - Versioned::set_reading_mode(''); - $dbAdmin->doBuild(true, $requireDefaultRecords); - } + // In case the dump involved CREATE TABLE commands, we need to ensure the schema is still up to date + $dbAdmin = new DatabaseAdmin(); + Versioned::set_reading_mode(''); + $dbAdmin->doBuild(true, $requireDefaultRecords); + } - /** - * Build the database with default records, see {@link DataObject->requireDefaultRecords()}. - */ - public function requireDefaultRecords() { - $dbAdmin = new DatabaseAdmin(); - Versioned::set_reading_mode(''); - $dbAdmin->doBuild(true, true); - } + /** + * Build the database with default records, see {@link DataObject->requireDefaultRecords()}. + */ + public function requireDefaultRecords() + { + $dbAdmin = new DatabaseAdmin(); + Versioned::set_reading_mode(''); + $dbAdmin->doBuild(true, true); + } - /** - * Sliented as if the file already exists by another process, we don't want - * to modify. - */ - public function saveState($state) { - if (defined('JSON_PRETTY_PRINT')) { - $content = json_encode($state, JSON_PRETTY_PRINT); - } else { - $content = json_encode($state); - } - $old = umask(0); - file_put_contents($this->getFilePath(), $content, LOCK_EX); - umask($old); - } + /** + * Sliented as if the file already exists by another process, we don't want + * to modify. + */ + public function saveState($state) + { + if (defined('JSON_PRETTY_PRINT')) { + $content = json_encode($state, JSON_PRETTY_PRINT); + } else { + $content = json_encode($state); + } + $old = umask(0); + file_put_contents($this->getFilePath(), $content, LOCK_EX); + umask($old); + } - public function loadFromFile() { - if($this->isRunningTests()) { - try { - $contents = file_get_contents($this->getFilePath()); - $json = json_decode($contents); + public function loadFromFile() + { + if ($this->isRunningTests()) { + try { + $contents = file_get_contents($this->getFilePath()); + $json = json_decode($contents); - $this->applyState($json); - } catch(Exception $e) { - throw new \Exception("A test session appears to be in progress, but we can't retrieve the details. " - . "Try removing the " . $this->getFilePath() . " file. Inner " - . "error: " . $e->getMessage()); - } - } - } + $this->applyState($json); + } catch (Exception $e) { + throw new \Exception("A test session appears to be in progress, but we can't retrieve the details. " + . "Try removing the " . $this->getFilePath() . " file. Inner " + . "error: " . $e->getMessage()); + } + } + } - private function removeStateFile() { - $file = $this->getFilePath(); + private function removeStateFile() + { + $file = $this->getFilePath(); - if(file_exists($file)) { - if(!unlink($file)) { - throw new \Exception('Unable to remove the testsession state file, please remove it manually. File ' - . 'path: ' . $file); - } - } - } + if (file_exists($file)) { + if (!unlink($file)) { + throw new \Exception('Unable to remove the testsession state file, please remove it manually. File ' + . 'path: ' . $file); + } + } + } - /** - * Cleans up the test session state by restoring the normal database connect (for the rest of this request, if any) - * and removes the {@link self::$test_state_file} so that future requests don't use this test state. - * - * Can be extended by implementing either onBeforeEndTestSession() or onAfterEndTestSession(). - * - * This should implement itself cleanly in case it is called twice (e.g. don't throw errors when the state file - * doesn't exist anymore because it's already been cleaned up etc.) This is because during behat test runs where - * a queueing system (e.g. silverstripe-resque) is used, the behat module may call this first, and then the forked - * worker will call it as well - but there is only one state file that is created. - */ - public function endTestSession() { - $this->extend('onBeforeEndTestSession'); + /** + * Cleans up the test session state by restoring the normal database connect (for the rest of this request, if any) + * and removes the {@link self::$test_state_file} so that future requests don't use this test state. + * + * Can be extended by implementing either onBeforeEndTestSession() or onAfterEndTestSession(). + * + * This should implement itself cleanly in case it is called twice (e.g. don't throw errors when the state file + * doesn't exist anymore because it's already been cleaned up etc.) This is because during behat test runs where + * a queueing system (e.g. silverstripe-resque) is used, the behat module may call this first, and then the forked + * worker will call it as well - but there is only one state file that is created. + */ + public function endTestSession() + { + $this->extend('onBeforeEndTestSession'); - if(SapphireTest::using_temp_db()) { - $this->resetDatabaseName(); + if (SapphireTest::using_temp_db()) { + $this->resetDatabaseName(); - SapphireTest::set_is_running_test(false); - } + SapphireTest::set_is_running_test(false); + } - $this->removeStateFile(); + $this->removeStateFile(); - $this->extend('onAfterEndTestSession'); - } + $this->extend('onAfterEndTestSession'); + } - /** - * Loads a YAML fixture into the database as part of the {@link TestSessionController}. - * - * @param string $fixtureFile The .yml file to load - * @return FixtureFactory The loaded fixture - * @throws LogicException - */ - public 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."); - } + /** + * Loads a YAML fixture into the database as part of the {@link TestSessionController}. + * + * @param string $fixtureFile The .yml file to load + * @return FixtureFactory The loaded fixture + * @throws LogicException + */ + public 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"); + } elseif (substr($realFile, 0, strlen($baseDir)) != $baseDir) { + throw new LogicException("Fixture file must be inside $baseDir"); + } elseif (substr($realFile, -4) != '.yml') { + throw new LogicException("Fixture file must be a .yml file"); + } elseif (!preg_match('/^([^\/.][^\/]+)\/tests\//', $fixtureFile)) { + throw new LogicException("Fixture file must be inside the tests subfolder of one of your modules."); + } - $factory = Injector::inst()->create('FixtureFactory'); - $fixture = Injector::inst()->create('YamlFixture', $fixtureFile); - $fixture->writeInto($factory); + $factory = Injector::inst()->create('FixtureFactory'); + $fixture = Injector::inst()->create('YamlFixture', $fixtureFile); + $fixture->writeInto($factory); - $state = $this->getState(); - $state->fixtures[] = $fixtureFile; - $this->applyState($state); + $state = $this->getState(); + $state->fixtures[] = $fixtureFile; + $this->applyState($state); - return $fixture; - } + return $fixture; + } - /** - * Reset the database connection to use the original database. Called by {@link self::endTestSession()}. - */ - public function resetDatabaseName() { - if($this->oldDatabaseName) { - global $databaseConfig; + /** + * Reset the database connection to use the original database. Called by {@link self::endTestSession()}. + */ + public function resetDatabaseName() + { + if ($this->oldDatabaseName) { + global $databaseConfig; - $databaseConfig['database'] = $this->oldDatabaseName; + $databaseConfig['database'] = $this->oldDatabaseName; - $conn = DB::get_conn(); + $conn = DB::get_conn(); - if($conn) { - $conn->selectDatabase($this->oldDatabaseName, false, false); - } - } - } + if ($conn) { + $conn->selectDatabase($this->oldDatabaseName, false, false); + } + } + } - /** - * @return stdClass Data as taken from the JSON object in {@link self::loadFromFile()} - */ - public function getState() { - $path = Director::getAbsFile($this->getFilePath()); - return (file_exists($path)) ? json_decode(file_get_contents($path)) : new stdClass; - } + /** + * @return stdClass Data as taken from the JSON object in {@link self::loadFromFile()} + */ + public function getState() + { + $path = Director::getAbsFile($this->getFilePath()); + return (file_exists($path)) ? json_decode(file_get_contents($path)) : new stdClass; + } } diff --git a/code/TestSessionRequestFilter.php b/code/TestSessionRequestFilter.php index bf9b180..362bfb0 100644 --- a/code/TestSessionRequestFilter.php +++ b/code/TestSessionRequestFilter.php @@ -2,56 +2,66 @@ /** * Sets state previously initialized through {@link TestSessionController}. */ -class TestSessionRequestFilter implements RequestFilter { +class TestSessionRequestFilter implements RequestFilter +{ - /** - * @var TestSessionEnvironment - */ - protected $testSessionEnvironment; + /** + * @var TestSessionEnvironment + */ + protected $testSessionEnvironment; - public function __construct() { - $this->testSessionEnvironment = Injector::inst()->get('TestSessionEnvironment'); - } + public function __construct() + { + $this->testSessionEnvironment = Injector::inst()->get('TestSessionEnvironment'); + } - public function preRequest(SS_HTTPRequest $request, Session $session, DataModel $model) { - if(!$this->testSessionEnvironment->isRunningTests()) return; + public function preRequest(SS_HTTPRequest $request, Session $session, DataModel $model) + { + if (!$this->testSessionEnvironment->isRunningTests()) { + return; + } - $testState = $this->testSessionEnvironment->getState(); + $testState = $this->testSessionEnvironment->getState(); - // Date and time - if(isset($testState->datetime)) { - SS_Datetime::set_mock_now($testState->datetime); - } + // Date and time + if (isset($testState->datetime)) { + SS_Datetime::set_mock_now($testState->datetime); + } - // Register mailer - if(isset($testState->mailer)) { - $mailer = $testState->mailer; - Email::set_mailer(new $mailer()); - Config::inst()->update("Email","send_all_emails_to", null); - } + // Register mailer + if (isset($testState->mailer)) { + $mailer = $testState->mailer; + Email::set_mailer(new $mailer()); + Config::inst()->update("Email", "send_all_emails_to", null); + } - // Allows inclusion of a PHP file, usually with procedural commands - // to set up required test state. The file can be generated - // through {@link TestSessionStubCodeWriter}, and the session state - // set through {@link TestSessionController->set()} and the - // 'testsession.stubfile' state parameter. - if(isset($testState->stubfile)) { - $file = $testState->stubfile; - if(!Director::isLive() && $file && file_exists($file)) { - // Connect to the database so the included code can interact with it - global $databaseConfig; - if ($databaseConfig) DB::connect($databaseConfig); - include_once($file); - } - } - } + // Allows inclusion of a PHP file, usually with procedural commands + // to set up required test state. The file can be generated + // through {@link TestSessionStubCodeWriter}, and the session state + // set through {@link TestSessionController->set()} and the + // 'testsession.stubfile' state parameter. + if (isset($testState->stubfile)) { + $file = $testState->stubfile; + if (!Director::isLive() && $file && file_exists($file)) { + // Connect to the database so the included code can interact with it + global $databaseConfig; + if ($databaseConfig) { + DB::connect($databaseConfig); + } + include_once($file); + } + } + } - public function postRequest(SS_HTTPRequest $request, SS_HTTPResponse $response, DataModel $model) { - if(!$this->testSessionEnvironment->isRunningTests()) return; + public function postRequest(SS_HTTPRequest $request, SS_HTTPResponse $response, DataModel $model) + { + if (!$this->testSessionEnvironment->isRunningTests()) { + return; + } - // Store PHP session - $state = $this->testSessionEnvironment->getState(); - $state->session = Session::get_all(); - $this->testSessionEnvironment->applyState($state); - } -} \ No newline at end of file + // Store PHP session + $state = $this->testSessionEnvironment->getState(); + $state->session = Session::get_all(); + $this->testSessionEnvironment->applyState($state); + } +} diff --git a/code/TestSessionStubCodeWriter.php b/code/TestSessionStubCodeWriter.php index 823c6be..f442a6c 100644 --- a/code/TestSessionStubCodeWriter.php +++ b/code/TestSessionStubCodeWriter.php @@ -3,71 +3,77 @@ * Writes PHP to a file which can be included in SilverStripe runs on existence. * The generated file is included in page execution through {@link TestSessionRequestFilter}. */ -class TestSessionStubCodeWriter { +class TestSessionStubCodeWriter +{ - /** - * @var boolean Add debug statements to the generated PHP about - * the generator's origin code location. - */ - protected $debug = false; + /** + * @var boolean Add debug statements to the generated PHP about + * the generator's origin code location. + */ + protected $debug = false; - /** - * @var String Absolute path to a PHP file, essentially the "name" of the stub. - */ - protected $filePath; + /** + * @var String Absolute path to a PHP file, essentially the "name" of the stub. + */ + protected $filePath; - public function __construct($filePath = null) { - $this->filePath = $filePath ? $filePath : BASE_PATH . '/testSessionStubCode.php'; - } + public function __construct($filePath = null) + { + $this->filePath = $filePath ? $filePath : BASE_PATH . '/testSessionStubCode.php'; + } - /** - * Writes arbitrary PHP code to {@link $filePath} for later inclusion. - * Creates the file if it doesn't exist. - * Adds debug information about the origin of this code if {@link $debug} is set. - * - * @param String $php Block of PHP code (without preceding debug ? debug_backtrace() : null; - $path = $this->getFilePath(); - $header = ''; + /** + * Writes arbitrary PHP code to {@link $filePath} for later inclusion. + * Creates the file if it doesn't exist. + * Adds debug information about the origin of this code if {@link $debug} is set. + * + * @param String $php Block of PHP code (without preceding debug ? debug_backtrace() : null; + $path = $this->getFilePath(); + $header = ''; - // Create file incl. header if it doesn't exist - if(!file_exists($this->getFilePath())) { - touch($this->getFilePath()); - if($this->debug) { - $header .= "getFilePath())) { + touch($this->getFilePath()); + if ($this->debug) { + $header .= "debug) { - $header .= "// Added by " . $trace[1]['class'] . '::' . $trace[1]['function'] . "\n"; - } - file_put_contents($path, $header . $php . "\n", FILE_APPEND); - } + // Add content + if ($this->debug) { + $header .= "// Added by " . $trace[1]['class'] . '::' . $trace[1]['function'] . "\n"; + } + file_put_contents($path, $header . $php . "\n", FILE_APPEND); + } - public function reset() { - if(file_exists($this->getFilePath())) { - unlink($this->getFilePath()); - } - } + public function reset() + { + if (file_exists($this->getFilePath())) { + unlink($this->getFilePath()); + } + } - public function getFilePath() { - return $this->filePath; - } + public function getFilePath() + { + return $this->filePath; + } - public function getDebug() { - return $this->debug; - } + public function getDebug() + { + return $this->debug; + } - public function setDebug($debug) { - $this->debug = $debug; + public function setDebug($debug) + { + $this->debug = $debug; - return $this; - } - -} \ No newline at end of file + return $this; + } +} diff --git a/tests/unit/TestSessionStubCodeWriterTest.php b/tests/unit/TestSessionStubCodeWriterTest.php index eee52a1..727ff0a 100644 --- a/tests/unit/TestSessionStubCodeWriterTest.php +++ b/tests/unit/TestSessionStubCodeWriterTest.php @@ -1,43 +1,49 @@ write('foo();', false); - $this->assertFileExists($file); - $this->assertEquals( - file_get_contents($writer->getFilePath()), - "write('foo();', false); + $this->assertFileExists($file); + $this->assertEquals( + file_get_contents($writer->getFilePath()), + "write('foo();', false); - $writer->write('bar();', false); - $this->assertFileExists($file); - $this->assertEquals( - file_get_contents($writer->getFilePath()), - "write('foo();', false); + $writer->write('bar();', false); + $this->assertFileExists($file); + $this->assertEquals( + file_get_contents($writer->getFilePath()), + "write('foo();', false); - $this->assertFileExists($file); - $writer->reset(); - $this->assertFileNotExists($file); - } - -} \ No newline at end of file + public function testReset() + { + $file = TEMP_FOLDER . '/TestSessionStubCodeWriterTest-file.php'; + $writer = new TestSessionStubCodeWriter($file); + $writer->write('foo();', false); + $this->assertFileExists($file); + $writer->reset(); + $this->assertFileNotExists($file); + } +}