BUGFIX: Fixing tests

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@66508 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Sam Minnee 2008-11-24 19:28:46 +00:00
parent 96c5be8252
commit 2e955b498e
14 changed files with 119 additions and 116 deletions

View File

@ -96,9 +96,7 @@ class ComponentSet extends DataObjectSet {
$item = DataObject::get_by_id($this->childClass, $item);
if(!isset($item)) {
return;
}
if(!$item) return;
}
// If we've already got a database object, then update the database

View File

@ -122,11 +122,6 @@ abstract class Database extends Object {
*/
abstract function enumValuesForField($tableName, $fieldName);
/**
* Convert a SQLQuery object into a SQL statement
*/
abstract function sqlQueryToString(SQLQuery $sqlQuery);
/**
* The table list, generated by the tableList() function.
* Used by the requireTable() function.
@ -420,12 +415,15 @@ abstract class Database extends Object {
switch($writeInfo['command']) {
case "update":
$fieldList = implode(", ", $fieldList);
$sql = "update \"$table\" SET $fieldList where $writeInfo[where]";
$this->query($sql);
// Test to see if this update query shouldn't, in fact, be an insert
if($this->query("SELECT \"ID\" FROM \"$table\" WHERE $writeInfo[where]")->value()) {
$fieldList = implode(", ", $fieldList);
$sql = "update \"$table\" SET $fieldList where $writeInfo[where]";
$this->query($sql);
break;
}
// If affectedRows = 0, then don't break, meaning the insert query below gets called
if($this->affectedRows()) break;
// ...if not, we'll skip on to the insert code
case "insert":
if(!isset($writeInfo['fields']['ID']) && isset($writeInfo['id'])) {
@ -483,32 +481,73 @@ abstract class Database extends Object {
}
static function alteration_message($message,$type=""){
if(!Database::$supressOutput) {
$color = "";
switch ($type){
case "created":
$color = "green";
break;
case "obsolete":
$color = "red";
break;
case "error":
$color = "red";
break;
case "deleted":
$color = "red";
break;
case "changed":
$color = "blue";
break;
case "repaired":
$color = "blue";
break;
default:
$color="";
}
echo "<li style=\"color: $color\">$message</li>";
if(!Database::$supressOutput) {
$color = "";
switch ($type){
case "created":
$color = "green";
break;
case "obsolete":
$color = "red";
break;
case "error":
$color = "red";
break;
case "deleted":
$color = "red";
break;
case "changed":
$color = "blue";
break;
case "repaired":
$color = "blue";
break;
default:
$color="";
}
echo "<li style=\"color: $color\">$message</li>";
}
}
/**
* Convert a SQLQuery object into a SQL statement
*/
public function sqlQueryToString(SQLQuery $sqlQuery) {
if (!$sqlQuery->from) return '';
$distinct = $sqlQuery->distinct ? "DISTINCT " : "";
if($sqlQuery->delete) {
$text = "DELETE ";
} else if($sqlQuery->select) {
$text = "SELECT $distinct" . implode(", ", $sqlQuery->select);
}
$text .= " FROM " . implode(" ", $sqlQuery->from);
if($sqlQuery->where) $text .= " WHERE (" . $sqlQuery->getFilter(). ")";
if($sqlQuery->groupby) $text .= " GROUP BY " . implode(", ", $sqlQuery->groupby);
if($sqlQuery->having) $text .= " HAVING ( " . implode(" ) AND ( ", $sqlQuery->having) . " )";
if($sqlQuery->orderby) $text .= " ORDER BY " . $sqlQuery->orderby;
if($sqlQuery->limit) {
$limit = $sqlQuery->limit;
// Pass limit as array or SQL string value
if(is_array($limit)) {
if(!array_key_exists('limit',$limit)) user_error('SQLQuery::limit(): Wrong format for $limit', E_USER_ERROR);
if(isset($limit['start']) && is_numeric($limit['start']) && isset($limit['limit']) && is_numeric($limit['limit'])) {
$combinedLimit = "$limit[limit] OFFSET $limit[start]";
} elseif(isset($limit['limit']) && is_numeric($limit['limit'])) {
$combinedLimit = (int)$limit['limit'];
} else {
$combinedLimit = false;
}
if(!empty($combinedLimit)) $text .= " LIMIT " . $combinedLimit;
} else {
$text .= " LIMIT " . $sqlQuery->limit;
}
}
return $text;
}
}

View File

@ -552,7 +552,7 @@ class Hierarchy extends DataObjectDecorator {
if(!$afterNode || $afterNode->ParentID != $this->owner->ID) {
$children = $this->AllChildren();
} else {
$children = DataObject::get(ClassInfo::baseDataClass($this->owner->class), "\"$baseClass\".\"ParentID\"={$this->owner->ID}" . ( ( $afterNode ) ? " AND \"Sort\" > " . sprintf( '%d', $afterNode->Sort ) : "" ), '\"Sort\" ASC');
$children = DataObject::get(ClassInfo::baseDataClass($this->owner->class), "\"$baseClass\".\"ParentID\"={$this->owner->ID}" . ( ( $afterNode ) ? " AND \"Sort\" > " . sprintf( '%d', $afterNode->Sort ) : "" ), '"Sort" ASC');
}
// Try all the siblings of this node after the given node

View File

@ -563,49 +563,6 @@ class MySQLDatabase extends Database {
}
return $classes;
}
/**
* Convert a SQLQuery object into a SQL statement
*/
public function sqlQueryToString(SQLQuery $sqlQuery) {
if (!$sqlQuery->from) return '';
$distinct = $sqlQuery->distinct ? "DISTINCT " : "";
if($sqlQuery->delete) {
$text = "DELETE ";
} else if($sqlQuery->select) {
$text = "SELECT $distinct" . implode(", ", $sqlQuery->select);
}
$text .= " FROM " . implode(" ", $sqlQuery->from);
if($sqlQuery->where) $text .= " WHERE (" . $sqlQuery->getFilter(). ")";
if($sqlQuery->groupby) $text .= " GROUP BY " . implode(", ", $sqlQuery->groupby);
if($sqlQuery->having) $text .= " HAVING ( " . implode(" ) AND ( ", $sqlQuery->having) . " )";
if($sqlQuery->orderby) $text .= " ORDER BY " . $sqlQuery->orderby;
if($sqlQuery->limit) {
$limit = $sqlQuery->limit;
// Pass limit as array or SQL string value
if(is_array($limit)) {
if(!array_key_exists('limit',$limit)) user_error('SQLQuery::limit(): Wrong format for $limit', E_USER_ERROR);
if(isset($limit['start']) && is_numeric($limit['start']) && isset($limit['limit']) && is_numeric($limit['limit'])) {
// @todo MySQL specific LIMIT syntax
$combinedLimit = "$limit[limit] OFFSET $limit[start]";
} elseif(isset($limit['limit']) && is_numeric($limit['limit'])) {
$combinedLimit = (int)$limit['limit'];
} else {
$combinedLimit = false;
}
if(!empty($combinedLimit)) $this->limit = $combinedLimit;
} else {
$text .= " LIMIT " . $sqlQuery->limit;
}
}
return $text;
}
}
/**

View File

@ -1376,12 +1376,22 @@ class SiteTree extends DataObject {
GoogleSitemap::ping();
// Fix the sort order for this page's siblings
DB::query("UPDATE \"SiteTree_Live\"
SET \"Sort\" = \"SiteTree\".\"Sort\"
FROM \"SiteTree\"
WHERE \"SiteTree_Live\".\"ID\" = \"SiteTree\".\"ID\"
AND \"SiteTree_Live\".\"ParentID\" = " . sprintf('%d', $this->ParentID) );
if(DB::getConn() instanceof MySQLDatabase) {
// Special syntax for MySQL (grr!)
// More ANSI-compliant syntax
DB::query("UPDATE \"SiteTree_Live\", \"SiteTree\"
SET \"SiteTree_Live\".\"Sort\" = \"SiteTree\".\"Sort\"
WHERE \"SiteTree_Live\".\"ID\" = \"SiteTree\".\"ID\"
AND \"SiteTree_Live\".\"ParentID\" = " . sprintf('%d', $this->ParentID) );
} else {
// More ANSI-compliant syntax
DB::query("UPDATE \"SiteTree_Live\"
FROM \"SiteTree\"
SET \"Sort\" = \"SiteTree\".\"Sort\"
WHERE \"SiteTree_Live\".\"ID\" = \"SiteTree\".\"ID\"
AND \"SiteTree_Live\".\"ParentID\" = " . sprintf('%d', $this->ParentID) );
}
// Handle activities undertaken by decorators
$this->extend('onAfterPublish', $original);

View File

@ -381,7 +381,7 @@ class Translatable extends DataObjectDecorator {
* that is not a translatable field)
*/
$clauseparts = explode('.',$innerparts[1]);
$originalTable = str_replace('\"','',str_replace('_lang','',$clauseparts[0]));
$originalTable = str_replace('"','',str_replace('_lang','',$clauseparts[0]));
$parts[$j] = ($this->isInAugmentedTable($clauseparts[1], $originalTable) ? "\"{$originalTable}_lang\"" : "\"$originalTable\"")
. ".{$clauseparts[1]}{$innerparts[2]}";
}
@ -407,7 +407,7 @@ class Translatable extends DataObjectDecorator {
/* if we are selecting fields (not doing counts for example) we need to select everything from
* the original table (was renamed to _lang) since some fields that we require may be there
*/
if ($query->select[0][0] == '\"') $query->select = array_merge(array("\"$table\".*"),$query->select);
if ($query->select[0][0] == '"') $query->select = array_merge(array("\"$table\".*"),$query->select);
} else unset($query->from[$table]);
} else {
$query->from[$table] = str_replace("\"{$table}\".OriginalLangID","\"{$table}\".ID",$query->from[$table]);

View File

@ -452,7 +452,7 @@ class Versioned extends DataObjectDecorator {
$query = $this->owner->extendedSQL($filter,"");
foreach($query->from as $table => $join) {
if($join[0] == '\"') $baseTable = str_replace('\"','',$join);
if($join[0] == '"') $baseTable = str_replace('"','',$join);
else if (substr($join,0,5) != 'INNER') $query->from[$table] = "LEFT JOIN \"$table\" ON \"$table\".RecordID = \"{$baseTable}_versions\".RecordID AND \"$table\".Version = \"{$baseTable}_versions\".Version";
$query->renameTable($table, $table . '_versions');
}
@ -635,7 +635,7 @@ class Versioned extends DataObjectDecorator {
function buildVersionSQL($filter = "", $sort = "") {
$query = $this->owner->extendedSQL($filter,$sort);
foreach($query->from as $table => $join) {
if($join[0] == '\"') $baseTable = str_replace('\"','',$join);
if($join[0] == '"') $baseTable = str_replace('"','',$join);
else $query->from[$table] = "LEFT JOIN \"$table\" ON \"$table\".RecordID = \"{$baseTable}_versions\".RecordID AND \"$table\".Version = \"{$baseTable}_versions\".Version";
$query->renameTable($table, $table . '_versions');
}
@ -646,7 +646,7 @@ class Versioned extends DataObjectDecorator {
static function build_version_sql($className, $filter = "", $sort = "") {
$query = singleton($className)->extendedSQL($filter,$sort);
foreach($query->from as $table => $join) {
if($join[0] == '\"') $baseTable = str_replace('"','',$join);
if($join[0] == '"') $baseTable = str_replace('"','',$join);
else $query->from[$table] = "LEFT JOIN \"$table\" ON \"$table\".RecordID = \"{$baseTable}_versions\".RecordID AND \"$table\".Version = \"{$baseTable}_versions\".Version";
$query->renameTable($table, $table . '_versions');
}
@ -765,4 +765,4 @@ class Versioned_Version extends ViewableData {
}
}
?>
?>

View File

@ -47,7 +47,7 @@ class Boolean extends DBField {
* If necessary, this should include quotes.
*/
function prepValueForDB($value) {
if($value === true || $value === 1) {
if($value === true || $value === 1 || $value === '1') {
return "'1'";
} if(!$value || !is_numeric($value)) {
return "'0'";

View File

@ -176,17 +176,17 @@ class SearchForm extends Form {
$baseClass = reset($queryContent->from);
// There's no need to do all that joining
$queryContent->from = array(str_replace(array('`','"'),'',$baseClass) => $baseClass);
$queryContent->select = array("\"ClassName\"","\"$baseClass\".\"ID\"","\"ParentID\"","\"Title\"",
"\"URLSegment\"","\"Content\"","\"LastEdited\"","\"Created\"","_utf8'' AS \"Filename\"",
"_utf8'' AS \"Name\"", "$relevanceContent AS \"Relevance\"", "\"CanViewType\"");
$queryContent->select = array("\"ClassName\"","$baseClass.\"ID\"","\"ParentID\"","\"Title\"",
"\"URLSegment\"","\"Content\"","\"LastEdited\"","\"Created\"","'' AS \"Filename\"",
"'' AS \"Name\"", "$relevanceContent AS \"Relevance\"", "\"CanViewType\"");
$queryContent->orderby = null;
$queryFiles = singleton('File')->extendedSQL($notMatch . $matchFile . $fileFilter, "");
$baseClass = reset($queryFiles->from);
// There's no need to do all that joining
$queryFiles->from = array(str_replace(array('`','"'),'',$baseClass) => $baseClass);
$queryFiles->select = array("\"ClassName\"","\"$baseClass\".\"ID\"","_utf8'' AS \"ParentID\"","\"Title\"",
"_utf8'' AS \"URLSegment\"","\"Content\"","\"LastEdited\"","\"Created\"","\"Filename\"","\"Name\"",
$queryFiles->select = array("\"ClassName\"","$baseClass.\"ID\"","'' AS \"ParentID\"","\"Title\"",
"'' AS \"URLSegment\"","\"Content\"","\"LastEdited\"","\"Created\"","\"Filename\"","\"Name\"",
"$relevanceFile AS \"Relevance\"","NULL AS \"CanViewType\"");
$queryFiles->orderby = null;

View File

@ -6,24 +6,24 @@ class ControllerTest extends SapphireTest {
function testDefaultAction() {
/* For a controller with a template, the default action will simple run that template. */
$response = Director::test("ControllerTest_Controller/");
$this->assertEquals("This is the main template. Content is 'default content'.", $response->getBody());
$this->assertRegExp("/This is the main template. Content is 'default content'/", $response->getBody());
}
function testMethodActions() {
/* The Action can refer to a method that is called on the object. If a method returns an array, then it will be
used to customise the template data */
$response = Director::test("ControllerTest_Controller/methodaction");
$this->assertEquals("This is the main template. Content is 'methodaction content'.", $response->getBody());
$this->assertRegExp("/This is the main template. Content is 'methodaction content'./", $response->getBody());
/* If the method just returns a string, then that will be used as the response */
$response = Director::test("ControllerTest_Controller/stringaction");
$this->assertEquals("stringaction was called.", $response->getBody());
$this->assertRegExp("/stringaction was called./", $response->getBody());
}
function testTemplateActions() {
/* If there is no method, it can be used to point to an alternative template. */
$response = Director::test("ControllerTest_Controller/templateaction");
$this->assertEquals("This is the template for templateaction. Content is 'default content'.", $response->getBody());
$this->assertRegExp("/This is the template for templateaction. Content is 'default content'./", $response->getBody());
}
function testAllowedActions() {

View File

@ -85,7 +85,7 @@ class SQLQueryTest extends SapphireTest {
$query = new SQLQuery();
$query->from[] = "MyTable";
$query->limit(array('limit'=>99, 'start'=>97));
$this->assertEquals("SELECT * FROM MyTable LIMIT 97,99", $query->sql());
$this->assertEquals("SELECT * FROM MyTable LIMIT 99 OFFSET 97", $query->sql());
}
function testSelectWithOrderbyClause() {

View File

@ -10,7 +10,7 @@ class SSViewerTest extends SapphireTest {
));
$result = $data->renderWith("SSViewerTestPartialTemplate");
$this->assertEquals('Test partial template: var value', $result);
$this->assertEquals('Test partial template: var value', trim(preg_replace("/<!--.*-->/U",'',$result)));
}
function testRequirements() {
@ -41,6 +41,6 @@ SS
);
$output = $viewer->process(new ArrayData(array()));
$this->assertEquals("This is my templateThis is some contentThis is the final content", $output);
$this->assertEquals("This is my templateThis is some contentThis is the final content", preg_replace("/\n?<!--.*-->\n?/U",'',$output));
}
}

View File

@ -32,16 +32,16 @@ class DBFieldTest extends SapphireTest {
$this->assertEquals('1', singleton('Decimal')->prepValueForDB('1'));
/* Boolean behaviour, asserting we have 0 */
$this->assertEquals('0', singleton('Boolean')->prepValueForDB(0));
$this->assertEquals('0', singleton('Boolean')->prepValueForDB(null));
$this->assertEquals('0', singleton('Boolean')->prepValueForDB(false));
$this->assertEquals('0', singleton('Boolean')->prepValueForDB(''));
$this->assertEquals('0', singleton('Boolean')->prepValueForDB('0'));
$this->assertEquals("'0'", singleton('Boolean')->prepValueForDB(0));
$this->assertEquals("'0'", singleton('Boolean')->prepValueForDB(null));
$this->assertEquals("'0'", singleton('Boolean')->prepValueForDB(false));
$this->assertEquals("'0'", singleton('Boolean')->prepValueForDB(''));
$this->assertEquals("'0'", singleton('Boolean')->prepValueForDB('0'));
/* Boolean behaviour, asserting we have 1 */
$this->assertEquals('1', singleton('Boolean')->prepValueForDB(true));
$this->assertEquals('1', singleton('Boolean')->prepValueForDB(1));
$this->assertEquals('1', singleton('Boolean')->prepValueForDB('1'));
$this->assertEquals("'1'", singleton('Boolean')->prepValueForDB(true));
$this->assertEquals("'1'", singleton('Boolean')->prepValueForDB(1));
$this->assertEquals("'1'", singleton('Boolean')->prepValueForDB('1'));
/* Varchar behaviour */
$this->assertEquals("'0'", singleton('Varchar')->prepValueForDB(0));

View File

@ -44,7 +44,6 @@ class RequirementsTest extends SapphireTest {
$html = Requirements::includeInHTML(false, self::$html_template);
/* COMBINED JAVASCRIPT FILE IS INCLUDED IN HTML HEADER */
Debug::message($html);
$this->assertTrue((bool)preg_match('/src=".*\/RequirementsTest_bc\.js/', $html), 'combined javascript file is included in html header');
/* COMBINED JAVASCRIPT FILE EXISTS */