Merged from 2.3

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@76269 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Sean Harvey 2009-05-06 06:36:16 +00:00
parent 7a4320f339
commit b20b6e0f95
16 changed files with 176 additions and 14 deletions

View File

@ -161,6 +161,9 @@ abstract class Object {
* completely replace the default PHP static when you set $replace = true, and do not define extra data on any child * completely replace the default PHP static when you set $replace = true, and do not define extra data on any child
* classes * classes
* *
* Note that from SilverStripe 2.3.2, Object::get_static() can only be used to get public
* static variables, not protected ones.
*
* @param string $class * @param string $class
* @param string $name the property name * @param string $name the property name
* @param bool $uncached if set to TRUE, force a regeneration of the static cache * @param bool $uncached if set to TRUE, force a regeneration of the static cache
@ -238,6 +241,9 @@ abstract class Object {
/** /**
* Get an uninherited static variable - a variable that is explicity set in this class, and not in the parent class. * Get an uninherited static variable - a variable that is explicity set in this class, and not in the parent class.
* *
* Note that from SilverStripe 2.3.2, Object::uninherited_static() can only be used to get public
* static variables, not protected ones.
*
* @todo Recursively filter out parent statics, currently only inspects the parent class * @todo Recursively filter out parent statics, currently only inspects the parent class
* *
* @param string $class * @param string $class

View File

@ -617,13 +617,12 @@ class Requirements_Backend {
$jsRequirements = preg_replace('/>\n*/', '>', $jsRequirements); $jsRequirements = preg_replace('/>\n*/', '>', $jsRequirements);
// We put script tags into the body, for performance. // We put script tags into the body, for performance.
// If your template already has script tags in the body, then we put our script tags at the top of the body. // If your template already has script tags in the body, then we put our script
// Otherwise, we put it at the bottom. // tags just before those. Otherwise, we put it at the bottom.
$p1 = strripos($content, '<script'); $p1 = strripos($content, '<script');
$p2 = stripos($content, '<body'); $p2 = stripos($content, '<body');
if($p1 !== false && $p1 > $p2) { if($p1 !== false && $p1 > $p2) {
user_error("You have a script tag in the body, moving requirements to top of <body> for compatibilty. I recommend removing the script tag from your template's body.", E_USER_NOTICE); $content = substr($content,0,$p1) . $jsRequirements . substr($content,$p1);
$content = eregi_replace("(<body[^>]*>)", "\\1" . $jsRequirements, $content);
} else { } else {
$content = eregi_replace("(</body[^>]*>)", $jsRequirements . "\\1", $content); $content = eregi_replace("(</body[^>]*>)", $jsRequirements . "\\1", $content);
} }

View File

@ -725,9 +725,10 @@ class Translatable extends DataObjectDecorator {
* @return DataObject * @return DataObject
*/ */
function alternateGetByUrl($urlSegment, $extraFilter, $cache = null, $orderby = null) { function alternateGetByUrl($urlSegment, $extraFilter, $cache = null, $orderby = null) {
$SQL_URLSegment = Convert::raw2sql($urlSegment); $filter = sprintf("\"SiteTree\".\"URLSegment\" = '%s'", Convert::raw2sql($urlSegment));
if($extraFilter) $filter .= " AND $extraFilter";
self::$enable_lang_filter = false; self::$enable_lang_filter = false;
$record = DataObject::get_one('SiteTree', "\"URLSegment\" = '{$SQL_URLSegment}'", false); $record = DataObject::get_one('SiteTree', $filter);
self::$enable_lang_filter = true; self::$enable_lang_filter = true;
return $record; return $record;

View File

@ -26,7 +26,7 @@ abstract class DBField extends ViewableData {
* *
* @var string * @var string
*/ */
protected static $default_search_filter_class = 'PartialMatchFilter'; public static $default_search_filter_class = 'PartialMatchFilter';
/** /**
* @var $default mixed Default-value in the database. * @var $default mixed Default-value in the database.

View File

@ -19,7 +19,7 @@ class ForeignKey extends Int {
*/ */
protected $object; protected $object;
protected static $default_search_filter_class = 'ExactMatchMultiFilter'; public static $default_search_filter_class = 'ExactMatchMultiFilter';
function __construct($name, $object = null) { function __construct($name, $object = null) {
$this->object = $object; $this->object = $object;

View File

@ -13,7 +13,7 @@ class PrimaryKey extends Int {
*/ */
protected $object; protected $object;
protected static $default_search_filter_class = 'ExactMatchMultiFilter'; public static $default_search_filter_class = 'ExactMatchMultiFilter';
/** /**
* @param string $name * @param string $name

View File

@ -30,7 +30,10 @@ class CliTestReporter extends SapphireTestReporter {
echo SSCli::text(" AT LEAST ONE FAILURE ", "white", "red"); echo SSCli::text(" AT LEAST ONE FAILURE ", "white", "red");
} }
echo "\n\n$testCount tests run: " . SSCli::text("$passCount passes", null) . ", ". SSCli::text("$failCount fails", null) . ", and 0 exceptions\n"; echo "\n\n$testCount tests run: " . SSCli::text("$passCount passes", null) . ", ". SSCli::text("$failCount fails", null) . ", and 0 exceptions\n";
echo "Maximum memory usage: " . number_format(memory_get_peak_usage()/(1024*1024), 1) . "M\n\n";
if(function_exists('memory_get_peak_usage')) {
echo "Maximum memory usage: " . number_format(memory_get_peak_usage()/(1024*1024), 1) . "M\n\n";
}
$totalTime = array_sum($this->testSpeeds); $totalTime = array_sum($this->testSpeeds);
echo "Total time: " . round($totalTime,3) . " seconds\n"; echo "Total time: " . round($totalTime,3) . " seconds\n";

View File

@ -253,6 +253,18 @@ class FunctionalTest extends SapphireTest {
} }
} }
/**
* Log in as the given member
* @param $member The ID, fixture codename, or Member object of the member that you want to log in
*/
function logInAs($member) {
if(is_object($member)) $memberID = $member->ID;
elseif(is_numeric($member)) $memberID = $member;
else $memberID = $this->idFromFixture('Member', $member);
$this->session()->inst_set('loggedInAs', $memberID);
}
/** /**
* Use the draft (stage) site for testing. * 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. * This is helpful if you're not testing publication functionality and don't want "stage management" cluttering your test.

View File

@ -126,10 +126,10 @@ class TestRunner extends Controller {
* Run only a single test class or a comma-separated list of tests * Run only a single test class or a comma-separated list of tests
*/ */
function only($request) { function only($request) {
if ($request->param('TestCase') == 'all') { if($request->param('TestCase') == 'all') {
$this->all(); $this->all();
} else { } else {
$classNames = explode(',',$request->param('TestCase')); $classNames = explode(',', $request->param('TestCase'));
foreach($classNames as $className) { foreach($classNames as $className) {
if(!class_exists($className) || !(singleton($className) instanceof SapphireTest)) { if(!class_exists($className) || !(singleton($className) instanceof SapphireTest)) {
user_error("TestRunner::only(): Invalid TestCase '$className', cannot find matching class", E_USER_ERROR); user_error("TestRunner::only(): Invalid TestCase '$className', cannot find matching class", E_USER_ERROR);

View File

@ -335,6 +335,8 @@ class Email extends ViewableData {
* and it won't be plain email :) * and it won't be plain email :)
*/ */
protected function parseVariables($isPlain = false) { protected function parseVariables($isPlain = false) {
SSViewer::set_source_file_comments(false);
if(!$this->parseVariables_done) { if(!$this->parseVariables_done) {
$this->parseVariables_done = true; $this->parseVariables_done = true;

View File

@ -1023,6 +1023,7 @@ class ComplexTableField_Popup extends Form {
$this->dataObject = $dataObject; $this->dataObject = $dataObject;
Requirements::clear(); Requirements::clear();
Requirements::unblock_all();
$actions = new FieldSet(); $actions = new FieldSet();
if(!$readonly) { if(!$readonly) {

View File

@ -206,6 +206,19 @@ class SiteTreeTest extends SapphireTest {
$this->assertEquals('Page', $requeriedPage->class); $this->assertEquals('Page', $requeriedPage->class);
} }
/**
* Test SiteTree::get_by_url()
*/
function testGetByURL() {
// Test basic get by url
$this->assertEquals($this->idFromFixture('Page', 'home'), SiteTree::get_by_url("home")->ID);
// Test the extraFilter argument
// Note: One day, it would be more appropriate to return null instead of false for queries such as these
$this->assertFalse(SiteTree::get_by_url("home", "1 = 2"));
}
} }
// We make these extend page since that's what all page types are expected to do // We make these extend page since that's what all page types are expected to do

View File

@ -0,0 +1,57 @@
<?php
class HierarchyTest extends SapphireTest {
static $fixture_file = 'sapphire/tests/model/HierarchyTest.yml';
/**
* Test Hierarchy::AllHistoricalChildren().
*/
function testAllHistoricalChildren() {
// Delete some pages
$this->objFromFixture('Page', 'page2b')->delete();
$this->objFromFixture('Page', 'page3a')->delete();
$this->objFromFixture('Page', 'page3')->delete();
// Check that page1-3 appear at the top level of the AllHistoricalChildren tree
$this->assertEquals(array("Page 1", "Page 2", "Page 3"),
singleton('Page')->AllHistoricalChildren()->column('Title'));
// Check that both page 2 children are returned
$page2 = $this->objFromFixture('Page', 'page2');
$this->assertEquals(array("Page 2a", "Page 2b"),
$page2->AllHistoricalChildren()->column('Title'));
// Page 3 has been deleted; let's bring it back from the grave
$page3 = Versioned::get_including_deleted("SiteTree", "Title = 'Page 3'")->First();
// Check that both page 3 children are returned
$this->assertEquals(array("Page 3a", "Page 3b"),
$page3->AllHistoricalChildren()->column('Title'));
}
/**
* Test that you can call Hierarchy::markExpanded/Unexpanded/Open() on a page, and that
* calling Hierarchy::isMarked() on a different instance of that object will return true.
*/
function testItemMarkingIsntRestrictedToSpecificInstance() {
// Mark a few pages
$this->objFromFixture('Page', 'page2')->markExpanded();
$this->objFromFixture('Page', 'page2a')->markExpanded();
$this->objFromFixture('Page', 'page2b')->markExpanded();
$this->objFromFixture('Page', 'page3')->markUnexpanded();
// Query some pages in a different context and check their m
$pages = DataObject::get("Page");
$marked = $expanded = array();
foreach($pages as $page) {
if($page->isMarked()) $marked[] = $page->Title;
if($page->isExpanded()) $expanded[] = $page->Title;
}
$this->assertEquals(array('Page 2', 'Page 3', 'Page 2a', 'Page 2b'), $marked);
$this->assertEquals(array('Page 2', 'Page 2a', 'Page 2b'), $expanded);
}
}

View File

@ -0,0 +1,19 @@
Page:
page1:
Title: Page 1
page2:
Title: Page 2
page3:
Title: Page 3
page2a:
Parent: =>Page.page2
Title: Page 2a
page2b:
Parent: =>Page.page2
Title: Page 2b
page3a:
Parent: =>Page.page3
Title: Page 3a
page3b:
Parent: =>Page.page3
Title: Page 3b

View File

@ -0,0 +1,30 @@
<?php
class VersionedTest extends SapphireTest {
static $fixture_file = 'sapphire/tests/model/VersionedTest.yml';
/**
* Test Versioned::get_including_deleted()
*/
function testGetIncludingDeleted() {
// Delete a page
$this->objFromFixture('Page', 'page3')->delete();
// Get all items, ignoring deleted
$remainingPages = DataObject::get("SiteTree", "ParentID = 0");
// Check that page 3 has gone
$this->assertEquals(array("Page 1", "Page 2"), $remainingPages->column('Title'));
// Get all including deleted
$allPages = Versioned::get_including_deleted("SiteTree", "ParentID = 0");
// Check that page 3 is still there
$this->assertEquals(array("Page 1", "Page 2", "Page 3"), $allPages->column('Title'));
// Check that this still works if we switch to reading the other stage
Versioned::reading_stage("Live");
$allPages = Versioned::get_including_deleted("SiteTree", "ParentID = 0");
$this->assertEquals(array("Page 1", "Page 2", "Page 3"), $allPages->column('Title'));
}
}

View File

@ -0,0 +1,19 @@
Page:
page1:
Title: Page 1
page2:
Title: Page 2
page3:
Title: Page 3
page2a:
Parent: =>Page.page2
Title: Page 2a
page2b:
Parent: =>Page.page2
Title: Page 2b
page3a:
Parent: =>Page.page3
Title: Page 3a
page3b:
Parent: =>Page.page3
Title: Page 3b