Empty commit

This commit is contained in:
Git 2014-01-24 08:00:47 +00:00
parent 2f6b91c588
commit 15b92f8e81
13 changed files with 480 additions and 5 deletions

150
classes/testing.class.php Normal file
View File

@ -0,0 +1,150 @@
<?
class Testing {
private static $ClassDirectories = array("classes");
private static $Classes = array();
/**
* Initialize the testasble classes into a map keyed by class name
*/
public static function init() {
self::load_classes();
}
/**
* Gets the class
*/
public static function get_classes() {
return self::$Classes;
}
/**
* Loads all the classes within given directories
*/
private static function load_classes() {
foreach (self::$ClassDirectories as $Directory) {
$Directory = SERVER_ROOT . "/" . $Directory . "/";
foreach (glob($Directory . "*.php") as $FileName) {
self::get_class_name($FileName);
}
}
}
/**
* Gets the class and adds into the map
*/
private static function get_class_name($FileName) {
$Tokens = token_get_all(file_get_contents($FileName));
$IsTestable = false;
$IsClass = false;
foreach ($Tokens as $Token) {
if (is_array($Token)) {
if (!$IsTestable && $Token[0] == T_DOC_COMMENT && strpos($Token[1], "@TestClass")) {
$IsTestable = true;
}
if ($IsTestable && $Token[0] == T_CLASS) {
$IsClass = true;
} else if ($IsClass && $Token[0] == T_STRING) {
$ReflectionClass = new ReflectionClass($Token[1]);
if (count(self::get_testable_methods($ReflectionClass))) {
self::$Classes[$Token[1]] = new ReflectionClass($Token[1]);
}
$IsTestable = false;
$IsClass = false;
}
}
}
}
/**
* Checks if class exists in the map
*/
public static function has_class($Class) {
return array_key_exists($Class, self::$Classes);
}
/**
* Checks if class has a given testable methood
*/
public static function has_testable_method($Class, $Method) {
$TestableMethods = self::get_testable_methods($Class);
foreach($TestableMethods as $TestMethod) {
if ($TestMethod->getName() === $Method) {
return true;
}
}
return false;
}
/**
* Get testable methods in a class, a testable method has a @Test
*/
public static function get_testable_methods($Class) {
if (is_string($Class)) {
$ReflectionClass = self::$Classes[$Class];
} else {
$ReflectionClass = $Class;
}
$ReflectionMethods = $ReflectionClass->getMethods();
$TestableMethods = array();
foreach($ReflectionMethods as $Method) {
if ($Method->isPublic() && $Method->isStatic() && strpos($Method->getDocComment(), "@Test")) {
$TestableMethods[] = $Method;
}
}
return $TestableMethods;
}
/**
* Get the class comment
*/
public static function get_class_comment($Class) {
$ReflectionClass = self::$Classes[$Class];
return trim(str_replace(array("@TestClass", "*", "/"), "", $ReflectionClass->getDocComment()));
}
/**
* Get the undocumented methods in a class
*/
public static function get_undocumented_methods($Class) {
$ReflectionClass = self::$Classes[$Class];
$Methods = array();
foreach($ReflectionClass->getMethods() as $Method) {
if (!$Method->getDocComment()) {
$Methods[] = $Method;
}
}
return $Methods;
}
/**
* Get the documented methods
*/
public static function get_documented_methods($Class) {
$ReflectionClass = self::$Classes[$Class];
$Methods = array();
foreach($ReflectionClass->getMethods() as $Method) {
if ($Method->getDocComment()) {
$Methods[] = $Method;
}
}
return $Methods;
}
/**
* Get all methods in a class
*/
public static function get_methods($Class) {
return self::$Classes[$Class]->getMethods();
}
/**
* Get a method comment
*/
public static function get_method_comment($Method) {
return trim(str_replace(array("*", "/"), "", $Method->getDocComment()));
}
}

View File

@ -0,0 +1,175 @@
<?
class TestingView {
/**
* Render the linkbox
*/
public static function render_linkbox($Page) { ?>
<div class="linkbox">
<? if ($Page != "classes") { ?>
<a href="testing.php" class="brackets">Classes</a>
<? }
if ($Page != "comments") { ?>
<a href="testing.php?action=comments" class="brackets">Comments</a>
<? } ?>
</div>
<? }
/**
* Render a list of classes
*/
public static function render_classes($Classes) { ?>
<table>
<tr class="colhead">
<td>
Class
</td>
<td>
Testable functions
</td>
</tr>
<? foreach($Classes as $Key => $Value) {
$Doc = Testing::get_class_comment($Key);
$Methods = count(Testing::get_testable_methods($Key));
?>
<tr>
<td>
<a href="testing.php?action=class&amp;name=<?=$Key?>" class="tooltip" title="<?=$Doc?>"><?=$Key?></a>
</td>
<td>
<?=$Methods?>
</td>
</tr>
<? } ?>
</table>
<? }
/**
* Render functions in a class
*/
public static function render_functions($Methods) {
foreach($Methods as $Index => $Method) {
$ClassName = $Method->getDeclaringClass()->getName();
$MethodName = $Method->getName();
?>
<div class="box box2">
<div class="head">
<span><?=self::render_method_definition($Method)?></span>
<span style="float: right;">
<a href="#" class="brackets" onclick="$('#method_params_<?=$Index?>').gtoggle(); return false;">Params</a>
<a href="#" class="brackets run" data-gazelle-id="<?=$Index?>" data-gazelle-class="<?=$ClassName?>" data-gazelle-method="<?=$MethodName?>">Run</a>
</span>
</div>
<div class="pad hidden" id="method_params_<?=$Index?>">
<?self::render_method_params($Method);?>
</div>
<div class="pad hidden" id="method_results_<?=$Index?>">
</div>
</div>
<? }
}
/**
* Render method parameters
*/
private static function render_method_params($Method) { ?>
<table>
<? foreach($Method->getParameters() as $Parameter) {
$DefaultValue = $Parameter->isDefaultValueAvailable() ? $Parameter->getDefaultValue() : "";
?>
<tr>
<td class="label">
<?=$Parameter->getName()?>
</td>
<td>
<input type="text" name="<?=$Parameter->getName()?>" value="<?=$DefaultValue?>"/>
</td>
</tr>
<? } ?>
</table>
<? }
/**
* Render the method definition
*/
private static function render_method_definition($Method) {
$Title = "<span class='tooltip' title='" . Testing::get_method_comment($Method) . "'>" . $Method->getName() . "</span> (";
foreach($Method->getParameters() as $Parameter) {
$Color = "red";
if ($Parameter->isDefaultValueAvailable()) {
$Color = "green";
}
$Title .= "<span style='color: $Color'>";
$Title .= "$" . $Parameter->getName();
if ($Parameter->isDefaultValueAvailable()) {
$Title .= " = " . $Parameter->getDefaultValue();
}
$Title .= "</span>";
$Title .= ", ";
}
$Title = rtrim($Title, ", ");
$Title .= ")";
return $Title;
}
/**
* Renders class documentation stats
*/
public static function render_missing_documentation($Classes) { ?>
<table>
<tr class="colhead">
<td>
Class
</td>
<td>
Class documented
</td>
<td>
Undocumented functions
</td>
<td>
Documented functions
</td>
</tr>
<? foreach($Classes as $Key => $Value) {
$ClassComment = Testing::get_class_comment($Key);
?>
<tr>
<td>
<?=$Key?>
</td>
<td>
<?=!empty($ClassComment) ? "Yes" : "No"?>
<td>
<?=count(Testing::get_undocumented_methods($Key))?>
</td>
<td>
<?=count(Testing::get_documented_methods($Key))?>
</td>
</tr>
<? } ?>
</table>
<? }
/**
* Pretty print any data
*/
public static function render_results($Data) {
$Results = '<pre><ul style="list-style-type: none">';
if (is_array($Data)) {
foreach ($Data as $Key => $Value){
if (is_array($Value)){
$Results .= '<li>' . $Key . ' => ' . self::render_results($Value) . '</li>';
} else{
$Results .= '<li>' . $Key . ' => ' . $Value . '</li>';
}
}
} else {
$Results .= '<li>' . $Data . '</li>';
}
$Results .= '</ul></pre>';
echo $Results;
}
}

View File

@ -6,7 +6,7 @@ public static function render_linkbox($Selected) {
?>
<div class="linkbox">
<a href="top10.php?type=torrents" class="brackets"><?=self::get_selected_link("Torrents", $Selected == "torrents")?></a>
<a href="top10.php?type=lastfm" class="brackets"><?=self::get_selected_link("Last.FM", $Selected == "lastfm")?></a>
<a href="top10.php?type=lastfm" class="brackets"><?=self::get_selected_link("Last.fm", $Selected == "lastfm")?></a>
<a href="top10.php?type=users" class="brackets"><?=self::get_selected_link("Users", $Selected == "users")?></a>
<a href="top10.php?type=tags" class="brackets"><?=self::get_selected_link("Tags", $Selected == "tags")?></a>
<a href="top10.php?type=votes" class="brackets"><?=self::get_selected_link("Favorites", $Selected == "votes")?></a>
@ -18,8 +18,8 @@ public static function render_linkbox($Selected) {
public static function render_artist_links($Selected, $View) {
?>
<div class="center">
<a href="top10.php?type=lastfm&amp;category=weekly&amp;view=<?=$View?>" class="brackets tooltip" title="These are the artists with the most Last.FM listeners this week"><?=self::get_selected_link("Weekly Artists", $Selected == "weekly")?></a>
<a href="top10.php?type=lastfm&amp;category=hyped&amp;view=<?=$View?>" class="brackets tooltip" title="These are the the fastest rising artists on Last.FM this week"><?=self::get_selected_link("Hyped Artists", $Selected == "hyped")?></a>
<a href="top10.php?type=lastfm&amp;category=weekly&amp;view=<?=$View?>" class="brackets tooltip" title="These are the artists with the most Last.fm listeners this week"><?=self::get_selected_link("Weekly Artists", $Selected == "weekly")?></a>
<a href="top10.php?type=lastfm&amp;category=hyped&amp;view=<?=$View?>" class="brackets tooltip" title="These are the the fastest rising artists on Last.fm this week"><?=self::get_selected_link("Hyped Artists", $Selected == "hyped")?></a>
</div>
<?

View File

@ -1,5 +1,8 @@
CHANGE LOG
2014-01-23 by Ajax
Introduced classes to test models. Classes with a @TestClass comment which include public static functions with a @Test comment will be made available to test via testing.php
2014-01-18 by alderaan
Fix grammar in pop-up notifications about new Staff PMs.

View File

@ -0,0 +1,18 @@
<?
authorize();
if (!check_perms('users_mod')) {
error(404);
}
$Class = $_POST['class'];
$Method = $_POST['method'];
$Params = json_decode($_POST['params'], true);
if (!empty($Class) && !empty($Method) && Testing::has_testable_method($Class, $Method)) {
if (count($Params)) {
$Results = call_user_func_array(array($Class, $Method), array_values($Params));
} else {
$Results = call_user_func(array($Class, $Method));
}
TestingView::render_results($Results);
}

View File

@ -0,0 +1,26 @@
<?
if (!check_perms('users_mod')) {
error(404);
}
$Class = $_GET['name'];
if (!empty($Class) && !Testing::has_class($Class)) {
error("Missing class");
}
View::show_header("Tests", "testing");
?>
<div class="header">
<h2><?=$Class?></h2>
<?=TestingView::render_linkbox("class"); ?>
</div>
<div class="thin">
<?=TestingView::render_functions(Testing::get_testable_methods($Class));?>
</div>
<?
View::show_footer();

View File

@ -0,0 +1,21 @@
<?
if (!check_perms('users_mod')) {
error(404);
}
View::show_header("Tests");
?>
<div class="header">
<h2>Tests</h2>
<? TestingView::render_linkbox("classes"); ?>
</div>
<div class="thin">
<? TestingView::render_classes(Testing::get_classes());?>
</div>
<?
View::show_footer();

View File

@ -0,0 +1,22 @@
<?
if (!check_perms('users_mod')) {
error(404);
}
View::show_header("Tests");
?>
<div class="header">
<h2>Documentation</h2>
<? TestingView::render_linkbox("comments"); ?>
</div>
<div class="thin">
<? TestingView::render_missing_documentation(Testing::get_classes());?>
</div>
<?
View::show_footer();

View File

@ -0,0 +1,26 @@
<?
enforce_login();
if (!check_perms('users_mod')) {
error(404);
} else {
Testing::init();
if (!empty($_REQUEST['action'])) {
switch ($_REQUEST['action']) {
case 'class':
include(SERVER_ROOT.'/sections/testing/class.php');
break;
case 'ajax_run_method':
include(SERVER_ROOT.'/sections/testing/ajax_run_method.php');
break;
case 'comments':
include(SERVER_ROOT.'/sections/testing/comments.php');
break;
default:
include(SERVER_ROOT.'/sections/testing/classes.php');
break;
}
} else {
include(SERVER_ROOT.'/sections/testing/classes.php');
}
}

View File

@ -159,6 +159,7 @@ function create_row($Title, $URL, $HasPermission = false, $Tooltip = false) {
create_row("BBCode sandbox", "tools.php?action=bbcode_sandbox", check_perms("users_mod"));
create_row("Public sandbox", "tools.php?action=public_sandbox", check_perms("users_mod"), "Do not click this!");
create_row("Mod-level sandbox", "tools.php?action=mod_sandbox", check_perms("users_mod"), "Do not click this!");
create_row("Testing", "testing.php", check_perms("users_mod"));
if ($ToolsHTML) {
?>

View File

@ -22,11 +22,11 @@
break;
}
View::show_header("Last.FM", "jquery.imagesloaded,jquery.wookmark,top10", "tiles");
View::show_header("Last.fm", "jquery.imagesloaded,jquery.wookmark,top10", "tiles");
?>
<div class="thin">
<div class="header">
<h2>Last.FM</h2>
<h2>Last.fm</h2>
<? Top10View::render_linkbox("lastfm"); ?>
</div>
<? Top10View::render_artist_links($Category, $View); ?>

View File

@ -0,0 +1,31 @@
$(document).ready(function() {
$(".run").click(function(e) {
e.preventDefault();
var id = $(this).data("gazelle-id");
var className = $(this).data("gazelle-class");
var methodName = $(this).data("gazelle-method");
var inputs = $("#method_params_" + id + " input");
var params = {};
$.each(inputs, function() {
params[this.name] = $(this).val();
});
$("#method_results_" + id).hide();
$.ajax({
type : "POST",
url : "testing.php?action=ajax_run_method",
data : {
"auth": authkey,
"class": className,
"method": methodName,
"params" : JSON.stringify(params)
}
}).done(function(response) {
$("#method_results_" + id).html(response);
$("#method_results_" + id).show();
});
});
});

2
testing.php Normal file
View File

@ -0,0 +1,2 @@
<?
require('classes/script_start.php');