mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
API CHANGE Added FunctionalTest::
API CHANGE Added ->session() API CHANGE Added FunctionalTest:: API CHANGE Improved FunctionalTest's match by selector commands to produce less brittle output (rationalises whitespace) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@55134 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
5562885c69
commit
5dff780a5d
@ -582,6 +582,11 @@ class ManifestBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
static function includeEverything() {
|
||||
global $_CLASS_MANIFEST;
|
||||
foreach($_CLASS_MANIFEST as $classFile) require_once($classFile);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -107,7 +107,7 @@ class ContentController extends Controller {
|
||||
}
|
||||
|
||||
// Draft/Archive security check - only CMS users should be able to look at stage/archived content
|
||||
if($this->URLSegment != 'Security' && (Versioned::current_archived_date() || (Versioned::current_stage() && Versioned::current_stage() != 'Live'))) {
|
||||
if($this->URLSegment != 'Security' && !Session::get('unsecuredDraftSite') && (Versioned::current_archived_date() || (Versioned::current_stage() && Versioned::current_stage() != 'Live'))) {
|
||||
if(!Permission::check('CMS_ACCESS_CMSMain')) {
|
||||
$link = $this->Link();
|
||||
$message = _t("ContentController.DRAFT_SITE_ACCESS_RESTRICTION", "You must log in with your CMS password in order to view the draft or archived content. <a href=\"%s\">Click here to go back to the published site.</a>");
|
||||
|
@ -413,12 +413,15 @@ class Director {
|
||||
static function makeRelative($url) {
|
||||
$base1 = self::absoluteBaseURL();
|
||||
$base2 = self::baseFolder();
|
||||
$base3 = self::baseURL();
|
||||
|
||||
// Allow for the accidental inclusion of a // in the URL
|
||||
$url = ereg_replace('([^:])//','\\1/',$url);
|
||||
|
||||
if(substr($url,0,strlen($base1)) == $base1) return substr($url,strlen($base1));
|
||||
if(substr($url,0,strlen($base2)) == $base2) return substr($url,strlen($base2));
|
||||
else if(substr($url,0,strlen($base2)) == $base2) return substr($url,strlen($base2));
|
||||
else if(substr($url,0,strlen($base3)) == $base3) return substr($url,strlen($base3));
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
|
@ -233,7 +233,7 @@ class PDODatabase extends Database {
|
||||
* @return boolean Returns true if successful
|
||||
* @todo This shouldn't take any arguments; it should take the information given in the constructor instead.
|
||||
*/
|
||||
public function createDatabase($connect, $username, $password, $database) {
|
||||
public function createDatabase() {
|
||||
try {
|
||||
$dbh = new PDO($connect, $username, $password);
|
||||
$stmt = $dbh->prepare("CREATE DATABASE $database");
|
||||
|
@ -20,6 +20,18 @@
|
||||
* </code>
|
||||
*/
|
||||
class FunctionalTest extends SapphireTest {
|
||||
/**
|
||||
* Set this to true on your sub-class to disable the use of themes in this test.
|
||||
* This can be handy for functional testing of modules without having to worry about whether a user has changed
|
||||
* behaviour by replacing the theme.
|
||||
*/
|
||||
static $disable_themes = false;
|
||||
|
||||
/**
|
||||
* Set this to true on your sub-class to use the draft site by default for every test in this class.
|
||||
*/
|
||||
static $use_draft_site = false;
|
||||
|
||||
protected $mainSession = null;
|
||||
|
||||
/**
|
||||
@ -27,14 +39,39 @@ class FunctionalTest extends SapphireTest {
|
||||
*/
|
||||
protected $cssParser = null;
|
||||
|
||||
private $originalTheme = null;
|
||||
|
||||
/**
|
||||
* Returns the {@link Session} object for this test
|
||||
*/
|
||||
function session() {
|
||||
return $this->mainSession->session();
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
$this->mainSession = new TestSession();
|
||||
|
||||
// Disable theme, if necessary
|
||||
if($this->stat('disable_themes')) {
|
||||
$this->originalTheme = SSViewer::current_theme();
|
||||
SSViewer::set_theme(null);
|
||||
}
|
||||
|
||||
// Switch to draft site, if necessary
|
||||
if($this->stat('use_draft_site')) {
|
||||
$this->useDraftSite();
|
||||
}
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
parent::tearDown();
|
||||
$this->mainSession = null;
|
||||
|
||||
// Re-enable theme, if previously disabled
|
||||
if($this->stat('disable_themes')) {
|
||||
SSViewer::set_theme($this->originalTheme);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -42,7 +79,9 @@ class FunctionalTest extends SapphireTest {
|
||||
*/
|
||||
function get($url) {
|
||||
$this->cssParser = null;
|
||||
return $this->mainSession->get($url);
|
||||
$response = $this->mainSession->get($url);
|
||||
if(is_object($response) && $response->getHeader('Location')) $response = $this->mainSession->followRedirection();
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -50,7 +89,9 @@ class FunctionalTest extends SapphireTest {
|
||||
*/
|
||||
function post($url, $data) {
|
||||
$this->cssParser = null;
|
||||
return $this->mainSession->post($url, $data);
|
||||
$response = $this->mainSession->post($url, $data);
|
||||
if(is_object($response) && $response->getHeader('Location')) $response = $this->mainSession->followRedirection();
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -59,7 +100,9 @@ class FunctionalTest extends SapphireTest {
|
||||
*/
|
||||
function submitForm($formID, $button = null, $data = array()) {
|
||||
$this->cssParser = null;
|
||||
return $this->mainSession->submitForm($formID, $button, $data);
|
||||
$response = $this->mainSession->submitForm($formID, $button, $data);
|
||||
if(is_object($response) && $response->getHeader('Location')) $response = $this->mainSession->followRedirection();
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -89,7 +132,7 @@ class FunctionalTest extends SapphireTest {
|
||||
*/
|
||||
function assertPartialMatchBySelector($selector, $expectedMatches) {
|
||||
$items = $this->cssParser()->getBySelector($selector);
|
||||
foreach($items as $item) $actuals[$item . ''] = true;
|
||||
foreach($items as $item) $actuals[] = trim(preg_replace("/[ \n\r\t]+/", " ", $item. ''));
|
||||
|
||||
foreach($expectedMatches as $match) {
|
||||
if(!isset($actuals[$match])) {
|
||||
@ -115,7 +158,7 @@ class FunctionalTest extends SapphireTest {
|
||||
*/
|
||||
function assertExactMatchBySelector($selector, $expectedMatches) {
|
||||
$items = $this->cssParser()->getBySelector($selector);
|
||||
foreach($items as $item) $actuals[] = $item . '';
|
||||
foreach($items as $item) $actuals[] = trim(preg_replace("/[ \n\r\t]+/", " ", $item. ''));
|
||||
|
||||
if($expectedMatches != $actuals) {
|
||||
throw new PHPUnit_Framework_AssertionFailedError(
|
||||
@ -172,4 +215,22 @@ class FunctionalTest extends SapphireTest {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the draft (stage) site for testing.
|
||||
* This is helpful if you're not testing publication functionality and don't want "stage management" cluttering your test.
|
||||
*/
|
||||
function useDraftSite() {
|
||||
$this->session()->inst_set('currentStage', 'Stage');
|
||||
$this->session()->inst_set('unsecuredDraftSite', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a static variable from this class.
|
||||
* Gets around PHP's lack of late static binding.
|
||||
*/
|
||||
function stat($varName) {
|
||||
$className = get_class($this);
|
||||
return eval("return {$className}::\$$varName;");
|
||||
}
|
||||
}
|
@ -61,6 +61,19 @@ class TestRunner extends Controller {
|
||||
}
|
||||
}
|
||||
|
||||
function coverage() {
|
||||
if(hasPhpUnit()) {
|
||||
ManifestBuilder::includeEverything();
|
||||
$tests = ClassInfo::subclassesFor('SapphireTest');
|
||||
array_shift($tests);
|
||||
unset($tests['FunctionalTest']);
|
||||
|
||||
$this->runTests($tests, true);
|
||||
} else {
|
||||
echo "Please install PHPUnit using pear";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run only a single test class
|
||||
*/
|
||||
@ -75,7 +88,7 @@ class TestRunner extends Controller {
|
||||
|
||||
}
|
||||
|
||||
function runTests($classList) {
|
||||
function runTests($classList, $coverage = false) {
|
||||
if(!Director::is_cli()) {
|
||||
self::$default_reporter->writeHeader();
|
||||
echo '<div class="info">';
|
||||
@ -100,7 +113,16 @@ class TestRunner extends Controller {
|
||||
}
|
||||
|
||||
/*, array("reportDirectory" => "/Users/sminnee/phpunit-report")*/
|
||||
if($coverage) {
|
||||
$testResult = PHPUnit_TextUI_TestRunner::run($suite, array("reportDirectory" => "../assets/coverage-report"));
|
||||
} else {
|
||||
$testResult = PHPUnit_TextUI_TestRunner::run($suite);
|
||||
}
|
||||
|
||||
if($coverage) {
|
||||
$coverageURL = Director::absoluteURL('assets/coverage-report');
|
||||
echo "<p><a href=\"$coverageURL\">Coverage report available here</a></p>";
|
||||
}
|
||||
|
||||
if(!Director::is_cli()) echo '</div>';
|
||||
|
||||
|
@ -80,7 +80,8 @@ class TestSession {
|
||||
* Get the most recent response's content
|
||||
*/
|
||||
function lastContent() {
|
||||
return $this->lastResponse->getBody();
|
||||
if(is_string($this->lastResponse)) return $this->lastResponse;
|
||||
else return $this->lastResponse->getBody();
|
||||
}
|
||||
|
||||
function cssParser() {
|
||||
|
Loading…
Reference in New Issue
Block a user