Refactored ManifestBuilder for better testability

Added initial ManifestBuilderTest

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@51682 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Sam Minnee 2008-03-26 09:23:51 +00:00
parent 7eea3c091f
commit df474f0467
2 changed files with 169 additions and 24 deletions

View File

@ -60,8 +60,7 @@ class ManifestBuilder {
'shortstat',
'HTML',
);
/**
* Returns true if the manifest file should be regenerated
*
@ -85,11 +84,41 @@ class ManifestBuilder {
* Generates a new manifest file and saves it to {@link MANIFEST_FILE}
*/
static function compileManifest() {
// Config manifest
$baseDir = dirname($_SERVER['SCRIPT_FILENAME']) . "/..";
$baseDir = ereg_replace("/[^/]+/\\.\\.", "", $baseDir);
$manifest = self::generate_php_file(self::get_manifest_info($baseDir));
if($fh = fopen(MANIFEST_FILE, "w")) {
fwrite($fh, $manifest);
fclose($fh);
} else {
die("Cannot write manifest file! Check permissions of " .
MANIFEST_FILE);
}
}
/**
* Turn an array produced by get_manifest_info() into the content of the manifest PHP include
*/
static function generate_php_file($manifestInfo) {
$output = "<?php\n";
foreach($manifestInfo['globals'] as $globalName => $globalVal) {
$output .= "\$$globalName = " . var_export($globalVal, true) . ";\n\n";
}
foreach($manifestInfo['require_once'] as $requireItem) {
$output .= "require_once(\"$requireItem\");\n";
}
return $output;
}
/**
* Return an array containing information for the manifest
*/
static function get_manifest_info($baseDir) {
// locate and include the exclude files
$topLevel = scandir($baseDir);
foreach($topLevel as $file) {
@ -125,15 +154,12 @@ class ManifestBuilder {
}
}
$manifest = "\$_CLASS_MANIFEST = " . var_export($classManifest, true) .
";\n";
$manifestInfo["globals"]["_CLASS_MANIFEST"] = $classManifest;
// Load the manifest in, so that the autoloader works
global $_CLASS_MANIFEST;
$_CLASS_MANIFEST = $classManifest;
// _config.php manifest
global $databaseConfig;
$topLevel = scandir($baseDir);
@ -142,7 +168,7 @@ class ManifestBuilder {
if(@is_dir("$baseDir/$filename/") &&
file_exists("$baseDir/$filename/_config.php") &&
!file_exists("$baseDir/$filename/_manifest_exclude")) {
$manifest .= "require_once(\"$baseDir/$filename/_config.php\");\n";
$manifestInfo["require_once"][] = "$baseDir/$filename/_config.php";
// Include this so that we're set up for connecting to the database
// in the rest of the manifest builder
require_once("$baseDir/$filename/_config.php");
@ -179,28 +205,20 @@ class ManifestBuilder {
// Ensure that any custom templates get favoured
ManifestBuilder::getTemplateManifest($baseDir, project(), $templateManifest, $cssManifest);
$manifest .= "\$_TEMPLATE_MANIFEST = " . var_export($templateManifest, true) . ";\n";
$manifest .= "\$_CSS_MANIFEST = " . var_export($cssManifest, true) . ";\n";
$manifestInfo["globals"]["_TEMPLATE_MANIFEST"] = $templateManifest;
$manifestInfo["globals"]["_CSS_MANIFEST"] = $cssManifest;
DB::connect($databaseConfig);
// Database manifest
$allClasses = ManifestBuilder::allClasses($classManifest);
$manifest .= "\$_ALL_CLASSES = " . var_export($allClasses, true) . ";\n";
$manifestInfo["globals"]["_ALL_CLASSES"] = $allClasses;
global $_ALL_CLASSES;
$_ALL_CLASSES = $allClasses;
// Write manifest to disk
$manifest = "<?php\n$manifest\n?>";
if($fh = fopen(MANIFEST_FILE, "w")) {
fwrite($fh, $manifest);
fclose($fh);
} else {
die("Cannot write manifest file! Check permissions of " .
MANIFEST_FILE);
}
return $manifestInfo;
}
@ -309,7 +327,10 @@ class ManifestBuilder {
* information.
*/
private static function allClasses($classManifest) {
self::$classArray = array();
self::$extendsArray = array();
self::$implementsArray = array();
// Include everything, so we actually have *all* classes
foreach($classManifest as $file) {
$b = basename($file);
@ -339,7 +360,7 @@ class ManifestBuilder {
if(is_subclass_of($subclass, $class)) $allClasses['children'][$class][$subclass] = $subclass;
}
}
return $allClasses;
}

View File

@ -0,0 +1,124 @@
<?php
class ManifestBuilderTest extends SapphireTest {
function testManifest() {
$baseFolder = TEMP_FOLDER . '/manifest-test';
global $_CLASS_MANIFEST, $project;
$originalClassManifest = $_CLASS_MANIFEST;
$originalProject = $project;
$manifestInfo = ManifestBuilder::get_manifest_info($baseFolder);
Debug::show($manifestInfo);
$this->assertEquals("$baseFolder/sapphire/MyClass.php", $manifestInfo['globals']['_CLASS_MANIFEST']['MyClass']);
$this->assertEquals("$baseFolder/sapphire/subdir/SubDirClass.php", $manifestInfo['globals']['_CLASS_MANIFEST']['SubDirClass']);
$this->assertNotContains('OtherFile', array_keys($manifestInfo['globals']['_CLASS_MANIFEST']));
global $_CLASS_MANIFEST, $project;
$project = $originalProject;
$_CLASS_MANIFEST = $originalClassManifest;
// Check aspects of PHP file
$manifest = ManifestBuilder::generate_php_file($manifestInfo);
// Debug::message($manifest);
$this->assertEquals(1, preg_match('/^<\?php/', $manifest), "Starts with <?php");
$this->assertEquals(1, preg_match('/\$_CLASS_MANIFEST\s*=\s*array/m', $manifest), "\$_CLASS_MANIFEST exists");
$this->assertEquals(1, preg_match('/\$_TEMPLATE_MANIFEST\s*=\s*array/m', $manifest), "\$_TEMPLATE_MANIFEST exists");
$this->assertEquals(1, preg_match('/\$_CSS_MANIFEST\s*=\s*array/m', $manifest), "\$_CSS_MANIFEST exists");
$this->assertEquals(1, preg_match('/\$_ALL_CLASSES\s*=\s*array/m', $manifest), "\$_ALL_CLASSES exists");
$this->assertEquals(1, preg_match('/require_once\("[^"]+rahbeast\/_config.php"\);/i', $manifest), "rahbeast/_config.php included");
$this->assertEquals(1, preg_match('/require_once\("[^"]+sapphire\/_config.php"\);/i', $manifest), "sapphire/_config.php included");
}
function setUp() {
$filesystemFixture = array(
'rahbeast/',
'rahbeast/_config.php' => <<<PHP
<?php
global \$project;
\$project = 'rahbeast';
PHP
,
'sapphire/',
'sapphire/_config.php',
'sapphire/MyClass.php' => <<<PHP
<?php
class MyClass extends Object {
}
class MyClass_Other extends DataObject implements Something {
}
class MyClass_Final extends DataObject implements Something, Else {
}
?>
PHP
,
'sapphire/subdir/',
'sapphire/subdir/SubDirClass.php' => <<<PHP
<?php
class SubDirClass extends Something implements Else, Other {
}
PHP
,
'sapphire/subdir/SubDirClass.php',
'otherdir/',
'otherdir/OtherFile.php' => <<<PHP
<?php
class OtherFile extends Object {
}
PHP
,
);
// Build the fixture specified above
$baseFolder = TEMP_FOLDER . '/manifest-test/';
if(file_exists($baseFolder)) Filesystem::removeFolder($baseFolder);
mkdir($baseFolder);
foreach($filesystemFixture as $i => $item) {
if(is_numeric($i)) {
$itemContent = null;
} else {
$itemContent = $item;
$item = $i;
}
// Directory
if(substr($item,-1) == '/') {
mkdir($baseFolder . $item);
} else {
touch($baseFolder . $item);
if($itemContent) {
$fh = fopen($baseFolder . $item, 'w');
fwrite($fh, $itemContent);
fclose($fh);
}
}
}
}
function tearDown() {
// Kill the folder after we're done
$baseFolder = TEMP_FOLDER . '/manifest-test/';
Filesystem::removeFolder($baseFolder);
}
}
?>