merged 1.5.0 branch into 1.5.0-DB

git-svn-id: http://xe-core.googlecode.com/svn/branches/1.5.0-DB@8547 201d5d3c-b55e-5fd7-737f-ddc643e51545
This commit is contained in:
ucorina 2011-06-29 15:36:09 +00:00
parent 4973c78fbc
commit 01d0925dd5
145 changed files with 990 additions and 31147 deletions

View file

@ -243,7 +243,7 @@
$obj->content = str_replace($uploaded_target_path,sprintf('/files/attach/images/%s/%s%s', $this->module_srl, getNumberingPath($document_srl,3), $filename), $obj->content); $obj->content = str_replace($uploaded_target_path,sprintf('/files/attach/images/%s/%s%s', $this->module_srl, getNumberingPath($document_srl,3), $filename), $obj->content);
$oDocumentController = &getController('document'); $oDocumentController = &getController('document');
$obj->allow_comment = 'Y'; $obj->commentStatus = 'ALLOW';
$obj->allow_trackback = 'Y'; $obj->allow_trackback = 'Y';
$output = $oDocumentController->insertDocument($obj); $output = $oDocumentController->insertDocument($obj);
@ -403,7 +403,7 @@
$post->publish = 1; $post->publish = 1;
$post->userid = $oDocument->get('user_id'); $post->userid = $oDocument->get('user_id');
$post->mt_allow_pings = 0; $post->mt_allow_pings = 0;
$post->mt_allow_comments = $oDocument->allowComment()=='Y'?1:0; $post->mt_allow_comments = $oDocument->allowComment()?1:0;
$posts[] = $post; $posts[] = $post;
} }
$content = getXmlRpcResponse($posts); $content = getXmlRpcResponse($posts);

View file

@ -32,7 +32,7 @@
if($image_name_file) $nick_name = sprintf('<img src="%s%s" border="0" alt="id: %s" title="id: %s" style="vertical-align:middle;margin-right:3px" />', Context::getRequestUri(),$image_name_file, strip_tags($nick_name), strip_tags($nick_name)); if($image_name_file) $nick_name = sprintf('<img src="%s%s" border="0" alt="id: %s" title="id: %s" style="vertical-align:middle;margin-right:3px" />', Context::getRequestUri(),$image_name_file, strip_tags($nick_name), strip_tags($nick_name));
if($image_mark_file) $nick_name = sprintf('<img src="%s%s" border="0" alt="id: %s" title="id : %s" style="vertical-align:middle;margin-right:3px"/>%s', Context::getRequestUri(),$image_mark_file, strip_tags($nick_name), strip_tags($nick_name), $nick_name); if($image_mark_file) $nick_name = sprintf('<img src="%s%s" border="0" alt="id: %s" title="id : %s" style="vertical-align:middle;margin-right:3px"/>%s', Context::getRequestUri(),$image_mark_file, strip_tags($nick_name), strip_tags($nick_name), $nick_name);
if($group_image) $nick_name = sprintf('<img src="%s" border="0" style="vertical-align:middle;margin-right:3px"/>%s', $group_image->src, $nick_name); if($group_image) $nick_name = sprintf('<img src="%s" border="0" style="vertical-align:middle;margin-right:3px" alt="%s" title="%s" />%s', $group_image->src, $group_image->title, $group_image->description, $nick_name);
$orig_text = preg_replace('/'.preg_quote($matches[5],'/').'<\/'.$matches[6].'>$/', '', $matches[0]); $orig_text = preg_replace('/'.preg_quote($matches[5],'/').'<\/'.$matches[6].'>$/', '', $matches[0]);

View file

@ -6,6 +6,12 @@
$member_srl = $matches[3]; $member_srl = $matches[3];
if($member_srl<1) return $matches[0]; if($member_srl<1) return $matches[0];
$orig_text = preg_replace('/'.preg_quote($matches[5],'/').'<\/'.$matches[6].'>$/', '', $matches[0]);
// Check Group Image Mark
$oMemberModel = &getModel('member');
if($oMemberModel->getGroupImageMark($member_srl)) return $orig_text.$matches[5].'</'.$matches[6].'>';
if(!isset($GLOBALS['_pointLevelIcon'][$member_srl])) { if(!isset($GLOBALS['_pointLevelIcon'][$member_srl])) {
// Get point configuration // Get point configuration
if(!$GLOBALS['_pointConfig']) { if(!$GLOBALS['_pointConfig']) {
@ -40,7 +46,6 @@
} }
$text = $GLOBALS['_pointLevelIcon'][$member_srl]; $text = $GLOBALS['_pointLevelIcon'][$member_srl];
$orig_text = preg_replace('/'.preg_quote($matches[5],'/').'<\/'.$matches[6].'>$/', '', $matches[0]);
return $orig_text.$text.$matches[5].'</'.$matches[6].'>'; return $orig_text.$text.$matches[5].'</'.$matches[6].'>';
} }
?> ?>

View file

@ -158,6 +158,7 @@
require(_XE_PATH_.'classes/mail/Mail.class.php'); require(_XE_PATH_.'classes/mail/Mail.class.php');
require(_XE_PATH_.'classes/page/PageHandler.class.php'); require(_XE_PATH_.'classes/page/PageHandler.class.php');
require(_XE_PATH_.'classes/mobile/Mobile.class.php'); require(_XE_PATH_.'classes/mobile/Mobile.class.php');
require(_XE_PATH_.'classes/validator/Validator.class.php');
if(__DEBUG__) $GLOBALS['__elapsed_class_load__'] = getMicroTime() - __ClassLoadStartTime__; if(__DEBUG__) $GLOBALS['__elapsed_class_load__'] = getMicroTime() - __ClassLoadStartTime__;
} }
?> ?>

View file

@ -820,6 +820,14 @@
return $url; return $url;
} }
/**
* return the requested script path
**/
function getRequestUriByServerEnviroment()
{
return $_SERVER['REQUEST_URI'];
}
/** /**
* php unescape function of javascript's escape * php unescape function of javascript's escape
* Function converts an Javascript escaped string back into a string with specified charset (default is UTF-8). * Function converts an Javascript escaped string back into a string with specified charset (default is UTF-8).
@ -972,4 +980,21 @@
} }
} }
function alertScript($msg)
{
if(!$msg) return;
echo '<script type="text/javascript">alert("'.$msg.'");</script>';
}
function closePopupScript()
{
echo '<script type="text/javascript">window.close();</script>';
}
function reload($isOpener = false)
{
$reloadScript = $isOpener ? 'window.opener.location.reload()' : 'document.location.reload()';
echo '<script type="text/javascript">'.$reloadScript.'</script>';
}
?> ?>

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<layout version="0.2">
<title xml:lang="ko">사용자 정의 레이아웃</title>
<title xml:lang="en">User defined layout</title>
<title xml:lang="jp">ユーザー定義のレイアウト</title>
<description xml:lang="ko">사용자 정의 레이아웃에 관한 설명 입니다.</description>
<description xml:lang="en">Description for user defined layout.</description>
<description xml:lang="jp">ユーザー定義のレイアウトについての説明です。</description>
<version>1.0</version>
<date>2010-12-24</date>
<author email_address="user@user.com" link="http://user-define.com/">
<name xml:lang="ko">User Name</name>
</author>
<menus>
<menu name="main_menu" maxdepth="2" default="true">
<title xml:lang="ko">메뉴</title>
</menu>
</menus>
</layout>

View file

@ -0,0 +1,47 @@
<load target="user_layout.css" />
<div class="user_layout">
<div class="header">
<h1>Site Logo</h1>
<form action="{getUrl()}" method="get" class="search">
<input type="hidden" name="vid" value="{$vid}" />
<input type="hidden" name="mid" value="{$mid}" />
<input type="hidden" name="act" value="IS" />
<input type="text" name="is_keyword" value="{$is_keyword}" title="{$lang->cmd_search}" />
<input type="submit" value="{$lang->cmd_search}" />
</form>
<hr />
<div class="gnb">
.gnb
<ul>
<li loop="$main_menu->list=>$key1,$val1" class="active"|cond="$val1['selected']"><a href="{$val1['href']}" target="_blank"|cond="$val1['open_window']=='Y'">{$val1['link']}</a>
<ul cond="$val1['list']">
<li loop="$val1['list']=>$key2,$val2" class="active"|cond="$val2['selected']"><a href="{$val2['href']}" target="_blank"|cond="$val2['open_window']=='Y'">{$val2['link']}</a></li>
</ul>
</li>
</ul>
</div>
</div>
<hr />
<div class="body">
<div class="lnb">
<div class="account">
<img widget="login_info" skin="xe_official" />
</div>
<hr />
.lnb
<h2 loop="$main_menu->list=>$key1,$val1" cond="$val1['selected']"><a href="{$val1['href']}" target="_blank"|cond="$val1['open_window']=='Y'">{$val1['link']}</a></h2>
<ul loop="$main_menu->list=>$key1,$val1" cond="$val1['selected'] && $val1['list']">
<li loop="$val1['list']=>$key2,$val2" class="active"|cond="$val2['selected']"><a href="{$val2['href']}" target="_blank"|cond="$val2['open_window']=='Y'">{$val2['link']}</a>
<ul cond="$val2['list']">
<li loop="$val2['list']=>$key3,$val3" class="active"|cond="$val3['selected']"><a href="{$val3['href']}" target="_blank"|cond="$val3['open_window']=='Y'">{$val3['link']}</a>
</li>
</ul>
</li>
</ul>
</div>
<hr />
<div class="content">.content{$content}</div>
</div>
<hr />
<div class="footer">.footer</div>
</div>

View file

@ -0,0 +1,15 @@
@charset "utf-8";
/* Layout */
hr{ display:none;}
form, fieldset{ border:0; margin:0; padding:0;}
.user_layout{ width:960px; margin:0 auto;}
.header{ zoom:1; background:#ddd;}
.header:after{ content:""; display:block; clear:both;}
.header .search{ float:right;}
.gnb{ float:left;}
.body{ margin:20px 0; zoom:1; background:#eee;}
.body:after{ content:""; display:block; clear:both;}
.lnb{ float:left; width:200px; background:#ddd;}
.account{}
.content{ float:right; width:740px; background:#ddd;}
.footer{ background:#ddd;}

View file

@ -0,0 +1,5 @@
// <![CDATA[
jQuery(function($){
//
});
// ]]>

View file

@ -6,7 +6,7 @@
<script type="text/javascript"> <script type="text/javascript">
function moveDate() { function moveDate() {
xGetElementById('fo_calendar').submit(); document.forms['calendar'].submit();
return true; return true;
} }
</script> </script>
@ -16,7 +16,7 @@
<div class="header4 gap1"> <div class="header4 gap1">
<form action="./index.php" method="get" id="fo_calendar"> <form action="./index.php" method="get" name="calendar" id="fo_calendar">
<input type="hidden" name="module" value="{$module}" /> <input type="hidden" name="module" value="{$module}" />
<input type="hidden" name="act" value="{$act}" /> <input type="hidden" name="act" value="{$act}" />
<input type="hidden" name="selected_date" id="selected_date" value="{zDate('Ymd',$selected_date)}" /> <input type="hidden" name="selected_date" id="selected_date" value="{zDate('Ymd',$selected_date)}" />

View file

@ -11,8 +11,8 @@
<action name="procFileImageResize" type="controller" standalone="true" /> <action name="procFileImageResize" type="controller" standalone="true" />
<action name="procFileDelete" type="controller" standalone="true" /> <action name="procFileDelete" type="controller" standalone="true" />
<action name="procFileDownload" type="controller" standalone="true" /> <action name="procFileDownload" type="controller" standalone="true" />
<action name="procFileAdminDeleteChecked" type="controller" standalone="true" /> <action name="procFileAdminDeleteChecked" type="controller" standalone="true" ruleset="deleteChecked" />
<action name="procFileAdminInsertConfig" type="controller" standalone="true" /> <action name="procFileAdminInsertConfig" type="controller" standalone="true" ruleset="insertConfig" />
<action name="procFileAdminInsertModuleConfig" type="controller" standalone="true" /> <action name="procFileAdminInsertModuleConfig" type="controller" standalone="true" ruleset="fileModuleConfig" />
</actions> </actions>
</module> </module>

View file

@ -53,7 +53,8 @@
// An error appears if no document is selected // An error appears if no document is selected
$cart = Context::get('cart'); $cart = Context::get('cart');
if(!$cart) return $this->stop('msg_cart_is_null'); if(!$cart) return $this->stop('msg_cart_is_null');
$file_srl_list= explode('|@|', $cart); if(!is_array($cart)) $file_srl_list= explode('|@|', $cart);
else $file_srl_list = $cart;
$file_count = count($file_srl_list); $file_count = count($file_srl_list);
if(!$file_count) return $this->stop('msg_cart_is_null'); if(!$file_count) return $this->stop('msg_cart_is_null');
@ -67,6 +68,11 @@
} }
$this->setMessage( sprintf(Context::getLang('msg_checked_file_is_deleted'), $file_count) ); $this->setMessage( sprintf(Context::getLang('msg_checked_file_is_deleted'), $file_count) );
if(!in_array(Context::getRequestMethod(),array('XMLRPC','JSON'))) {
$returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'module', 'admin', 'act', 'dispFileAdminList');
header('location:'.$returnUrl);
return;
}
} }
/** /**
@ -76,13 +82,18 @@
// Get configurations (using module model object) // Get configurations (using module model object)
$config->allowed_filesize = Context::get('allowed_filesize'); $config->allowed_filesize = Context::get('allowed_filesize');
$config->allowed_attach_size = Context::get('allowed_attach_size'); $config->allowed_attach_size = Context::get('allowed_attach_size');
$config->allowed_filetypes = Context::get('allowed_filetypes'); $config->allowed_filetypes = str_replace(' ', '', Context::get('allowed_filetypes'));
$config->allow_outlink = Context::get('allow_outlink'); $config->allow_outlink = Context::get('allow_outlink');
$config->allow_outlink_format = Context::get('allow_outlink_format'); $config->allow_outlink_format = Context::get('allow_outlink_format');
$config->allow_outlink_site = Context::get('allow_outlink_site'); $config->allow_outlink_site = Context::get('allow_outlink_site');
// Create module Controller object // Create module Controller object
$oModuleController = &getController('module'); $oModuleController = &getController('module');
$output = $oModuleController->insertModuleConfig('file',$config); $output = $oModuleController->insertModuleConfig('file',$config);
if($output->toBool() && !in_array(Context::getRequestMethod(),array('XMLRPC','JSON'))) {
$returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'module', 'admin', 'act', 'dispFileAdminConfig');
header('location:'.$returnUrl);
return;
}
return $output; return $output;
} }
@ -96,16 +107,17 @@
if(preg_match('/^([0-9,]+)$/',$module_srl)) $module_srl = explode(',',$module_srl); if(preg_match('/^([0-9,]+)$/',$module_srl)) $module_srl = explode(',',$module_srl);
else $module_srl = array($module_srl); else $module_srl = array($module_srl);
$download_grant = trim(Context::get('download_grant')); $download_grant = Context::get('download_grant');
$file_config->allow_outlink = Context::get('allow_outlink'); $file_config->allow_outlink = Context::get('allow_outlink');
$file_config->allow_outlink_format = Context::get('allow_outlink_format'); $file_config->allow_outlink_format = Context::get('allow_outlink_format');
$file_config->allow_outlink_site = Context::get('allow_outlink_site'); $file_config->allow_outlink_site = Context::get('allow_outlink_site');
$file_config->allowed_filesize = Context::get('allowed_filesize'); $file_config->allowed_filesize = Context::get('allowed_filesize');
$file_config->allowed_attach_size = Context::get('allowed_attach_size'); $file_config->allowed_attach_size = Context::get('allowed_attach_size');
$file_config->allowed_filetypes = Context::get('allowed_filetypes'); $file_config->allowed_filetypes = str_replace(' ', '', Context::get('allowed_filetypes'));
if($download_grant) $file_config->download_grant = explode('|@|',$download_grant);
else $file_config->download_grant = array(); if(!is_array($download_grant)) $file_config->download_grant = explode('|@|',$download_grant);
else $file_config->download_grant = $download_grant;
//관리자가 허용한 첨부파일의 사이즈가 php.ini의 값보다 큰지 확인하기 - by ovclas //관리자가 허용한 첨부파일의 사이즈가 php.ini의 값보다 큰지 확인하기 - by ovclas
$userFileAllowSize = $this->_changeBytes($file_config->allowed_filesize.'M'); $userFileAllowSize = $this->_changeBytes($file_config->allowed_filesize.'M');
@ -126,6 +138,11 @@
$this->setError(-1); $this->setError(-1);
$this->setMessage('success_updated'); $this->setMessage('success_updated');
if(!in_array(Context::getRequestMethod(),array('XMLRPC','JSON'))) {
$returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'module', 'admin', 'act', 'dispBoardAdminContent');
header('location:'.$returnUrl);
return;
}
} }
/** /**

View file

@ -129,9 +129,12 @@
$doc_srls_count = count($doc_srls); $doc_srls_count = count($doc_srls);
if($doc_srls_count) { if($doc_srls_count) {
$document_output = $oDocumentModel->getDocuments($doc_srls); $document_output = $oDocumentModel->getDocuments($doc_srls);
foreach($document_output as $document) { if(is_array($document_output))
$document_list[$document->document_srl] = $document; {
} foreach($document_output as $document) {
$document_list[$document->document_srl] = $document;
}
}
} }
// Module List // Module List
$mod_srls_count = count($mod_srls); $mod_srls_count = count($mod_srls);

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<ruleset version="1.5.0">
<customrules>
</customrules>
<fields>
<field name="cart" required="true"/>
</fields>
</ruleset>

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<ruleset version="1.5.0">
<customrules>
<rule name="extension" type="regex" test="/^(?:\*\.\*|(\*\.\w+;\s*)*\*\.\w+;?)$/i" />
</customrules>
<fields>
<field name="allowed_filesize" required="true" rule="number" default="2" />
<field name="allowed_attach_size" required="true" rule="number" default="2" />
<field name="allowed_filetypes" required="true" rule="extension" />
<field name="download_grant" required="true" />
</fields>
</ruleset>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<ruleset version="1.5.0">
<customrules>
<rule name="extension" type="regex" test="/^(?:\*\.\*|(\*\.\w+;\s*)*\*\.\w+;?)$/i" />
</customrules>
<fields>
<field name="allowed_filesize" required="true" rule="number" default="2" />
<field name="allowed_attach_size" required="true" rule="number" default="2" />
<field name="allowed_filetypes" required="true" rule="extension" />
</fields>
</ruleset>

View file

@ -1,7 +1,9 @@
<!--#include("header.html")--> <!--#include("header.html")-->
<!--%import("filter/insert_config.xml")--> <!--%import("filter/insert_config.xml")-->
<form action="./" method="get" onsubmit="return procFilter(this, insert_config)"> <p class="xe_validator_error">{$XE_VALIDATOR_ERROR}</p>
<form ruleset="insertConfig" action="./" method="post">
<input type="hidden" name="act" value="procFileAdminInsertConfig" />
<table cellspacing="0" class="rowTable"> <table cellspacing="0" class="rowTable">
<tr class="row2"> <tr class="row2">
<th scope="col"><div>{$lang->allow_outlink}</div></th> <th scope="col"><div>{$lang->allow_outlink}</div></th>
@ -55,4 +57,4 @@
</th> </th>
</tr> </tr>
</table> </table>
</form> </form>

View file

@ -1,10 +1,10 @@
<!--%import("filter/delete_checked.xml")-->
<!--%import("css/file_list.css")--> <!--%import("css/file_list.css")-->
<!--#include("header.html")--> <!--#include("header.html")-->
<!-- 검색 --> <!-- 검색 -->
<div class="fl"> <div class="fl">
<form action="./" method="get" class="adminSearch"> <p class="xe_validator_error">{$XE_VALIDATOR_ERROR}</p>
<form ruleset="deleteChecked" action="./" method="get" class="adminSearch">
<input type="hidden" name="module" value="{$module}" /> <input type="hidden" name="module" value="{$module}" />
<input type="hidden" name="act" value="{$act}" /> <input type="hidden" name="act" value="{$act}" />
<input type="hidden" name="module_srl" value="{$module_srl}" /> <input type="hidden" name="module_srl" value="{$module_srl}" />
@ -29,7 +29,8 @@
</form> </form>
</div> </div>
<form id="fo_list" action="./" method="get" onsubmit="return procFilter(this, delete_checked)"> <form id="fo_list" action="./" method="post">
<input type="hidden" name="act" value="procFileAdminDeleteChecked" />
<input type="hidden" name="page" value="{$page}" /> <input type="hidden" name="page" value="{$page}" />
<!-- 모듈 선택 --> <!-- 모듈 선택 -->
@ -91,7 +92,7 @@
<tr> <tr>
<td class="tCenter number">{$no}</td> <td class="tCenter number">{$no}</td>
<td class="tCenter"><input type="checkbox" name="cart" value="{$val->file_srl}" /></td> <td class="tCenter"><input type="checkbox" name="cart[]" value="{$val->file_srl}" /></td>
<td class="wide"><a href="{$val->download_url}" class="red">{htmlspecialchars($val->source_filename)}</a></td> <td class="wide"><a href="{$val->download_url}" class="red">{htmlspecialchars($val->source_filename)}</a></td>
<td class="number tRight">{FileHandler::filesize($val->file_size)}</td> <td class="number tRight">{FileHandler::filesize($val->file_size)}</td>
<td class="tCenter"> <td class="tCenter">

View file

@ -1,5 +1,6 @@
<!--%import("filter/insert_file_module_config.xml")--> <form ruleset="fileModuleConfig" action="./" method="post">
<form action="./" method="get" onsubmit="return procFilter(this, insert_file_module_config)"> <input type="hidden" name="act" value="procFileAdminInsertModuleConfig" />
<input type="hidden" name="success_return_url" value="{getUrl('', 'module', $module, 'act', $act, 'module_srl', $module_srl)}" />
<input type="hidden" name="target_module_srl" value="{$module_info->module_srl?$module_info->module_srl:$module_srls}" /> <input type="hidden" name="target_module_srl" value="{$module_info->module_srl?$module_info->module_srl:$module_srls}" />
<h4 class="xeAdmin">{$lang->file}</h4> <h4 class="xeAdmin">{$lang->file}</h4>
@ -30,7 +31,7 @@
<th scope="col"><div>{$lang->enable_download_group}</div></th> <th scope="col"><div>{$lang->enable_download_group}</div></th>
<td> <td>
<!--@foreach($group_list as $k => $v)--> <!--@foreach($group_list as $k => $v)-->
<input type="checkbox" class="checkbox" name="download_grant" value="{$v->group_srl}" id="grant_{$key}_{$v->group_srl}" <!--@if(in_array($v->group_srl, $file_config->download_grant))-->checked="checked"<!--@end-->/> <input type="checkbox" class="checkbox" name="download_grant[]" value="{$v->group_srl}" id="grant_{$key}_{$v->group_srl}" <!--@if(in_array($v->group_srl, $file_config->download_grant))-->checked="checked"<!--@end-->/>
<label for="grant_{$key}_{$v->group_srl}">{$v->title}</label> <label for="grant_{$key}_{$v->group_srl}">{$v->title}</label>
&nbsp; &nbsp;
<!--@end--> <!--@end-->

View file

@ -37,8 +37,7 @@
Context::set('system_message', nl2br($this->getMessage())); Context::set('system_message', nl2br($this->getMessage()));
$this->setTemplatePath($template_path); $this->setTemplatePath($template_path);
$this->setTemplateFile('system_message'); $this->setTemplateFile('system_message');
} }
} }
?> ?>

View file

@ -1,8 +1,8 @@
<!--%import("filter/insert_config.xml")-->
<h3 class="xeAdmin">{$lang->message} <span class="gray">{$lang->cmd_management}</span></h3> <h3 class="xeAdmin">{$lang->message} <span class="gray">{$lang->cmd_management}</span></h3>
<form action="./" method="get" onsubmit="return procFilter(this, insert_config)"> <p class="xe_validator_error">{$XE_VALIDATOR_ERROR}</p>
<form action="./" method="post">
<input type="hidden" name="act" value="procMessageAdminInsertConfig" />
<p class="summary">{$lang->about_skin}</p> <p class="summary">{$lang->about_skin}</p>
<table cellspacing="0" class="rowTable"> <table cellspacing="0" class="rowTable">
<tr> <tr>

View file

@ -16,7 +16,7 @@
<condition operation="equal" column="doc.module_srl" var="module_srl" filter="number" /> <condition operation="equal" column="doc.module_srl" var="module_srl" filter="number" />
<condition operation="notin" column="doc.module_srl" var="except_module_srls" pipe="and" /> <condition operation="notin" column="doc.module_srl" var="except_module_srls" pipe="and" />
<condition operation="null" column="except_modules.module_srl" default="1" pipe="and" /> <condition operation="null" column="except_modules.module_srl" default="1" pipe="and" />
<condition operation="equal" column="doc.is_secret" default="N" pipe="and" /> <condition operation="equal" column="doc.status" default="PUBLIC" pipe="and" />
<condition operation="equal" column="modules.module_srl" default="doc.module_srl" filter="number" pipe="and" /> <condition operation="equal" column="modules.module_srl" default="doc.module_srl" filter="number" pipe="and" />
<condition operation="notin" column="modules.module_srl" var="except_modules" filter="numbers" pipe="and" /> <condition operation="notin" column="modules.module_srl" var="except_modules" filter="numbers" pipe="and" />
<condition operation="more" column="doc.last_update" var="start_date" filter="number" pipe="and" /> <condition operation="more" column="doc.last_update" var="start_date" filter="number" pipe="and" />

View file

@ -1,5 +1,5 @@
function insertSelectedModules(id, module_srl, mid, browser_title) { function insertSelectedModules(id, module_srl, mid, browser_title) {
var sel_obj = xGetElementById('_'+id); var sel_obj = get_by_id('_'+id);
for(var i=0;i<sel_obj.options.length;i++) if(sel_obj.options[i].value==module_srl) return; for(var i=0;i<sel_obj.options.length;i++) if(sel_obj.options[i].value==module_srl) return;
var opt = new Option(browser_title+' ('+mid+')', module_srl, false, false); var opt = new Option(browser_title+' ('+mid+')', module_srl, false, false);
sel_obj.options[sel_obj.options.length] = opt; sel_obj.options[sel_obj.options.length] = opt;
@ -9,7 +9,7 @@ function insertSelectedModules(id, module_srl, mid, browser_title) {
} }
function removeExceptModule(id) { function removeExceptModule(id) {
var sel_obj = xGetElementById('_'+id); var sel_obj = get_by_id('_'+id);
sel_obj.remove(sel_obj.selectedIndex); sel_obj.remove(sel_obj.selectedIndex);
if(sel_obj.options.length) sel_obj.selectedIndex = sel_obj.options.length-1; if(sel_obj.options.length) sel_obj.selectedIndex = sel_obj.options.length-1;
doSyncExceptModules(id); doSyncExceptModules(id);
@ -17,11 +17,11 @@ function removeExceptModule(id) {
function doSyncExceptModules(id) { function doSyncExceptModules(id) {
var selected_module_srls = new Array(); var selected_module_srls = new Array();
var sel_obj = xGetElementById('_'+id); var sel_obj = get_by_id('_'+id);
for(var i=0;i<sel_obj.options.length;i++) { for(var i=0;i<sel_obj.options.length;i++) {
selected_module_srls.push(sel_obj.options[i].value); selected_module_srls.push(sel_obj.options[i].value);
} }
xGetElementById(id).value = selected_module_srls.join(','); get_by_id(id).value = selected_module_srls.join(',');
} }

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="0.2">
<title xml:lang="ko">휴지통</title>
<title xml:lang="en">trash</title>
<description xml:lang="ko">문서, 댓글 등을 완전히 삭제하지 않고 복구 가능한 상태로 만들어 관리하는 모듈입니다. </description>
<version>0.1</version>
<date>2011-05-12</date>
<category>content</category>
<author email_address="developers@xpressengine.com" link="http://xpressengine.com/">
<name xml:lang="ko">NHN</name>
<name xml:lang="en">NHN</name>
<name xml:lang="vi">NHN</name>
<name xml:lang="es">NHN</name>
<name xml:lang="zh-CN">NHN</name>
<name xml:lang="jp">NHN</name>
<name xml:lang="ru">NHN</name>
<name xml:lang="zh-TW">NHN</name>
<name xml:lang="tr">NHN</name>
</author>
</module>

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<module>
<grants />
<permissions>
<permission action="dispTrashAdminList" target="manager" />
<permission action="procTrashAdminEmptyTrash" target="manager" />
<permission action="procTrashAdminRestore" target="manager" />
</permissions>
<actions>
<action name="dispTrashAdminList" type="view" standalone="true" admin_index="true" />
<action name="procTrashAdminEmptyTrash" type="controller" standalone="true" />
<action name="procTrashAdminRestore" type="controller" standalone="true" />
</actions>
</module>

View file

@ -0,0 +1,23 @@
<?php
/**
* @file modules/document/lang/ko.lang.php
* @author NHN (developers@xpressengine.com)
* @brief Document (document) of the basic language modules
**/
$lang->cmd_trash = '휴지통';
$lang->cmd_restore = '복원';
$lang->cmd_restore_all = '모두 복원';
$lang->in_trash = '휴지통';
$lang->trash_nick_name = '삭제자 닉네임';
$lang->trash_date = '삭제 날짜';
$lang->trash_description = '설명';
$lang->trash_type = '원본 종류';
$lang->success_trashed = '휴지통으로 이동되었습니다.';
$lang->empty_trash_selected = '선택 비우기';
$lang->empty_trash_all = '휴지통 비우기';
$lang->confirm_restore = '복원하시겠습니까?';
$lang->success_empty = '성공적으로 비웠습니다.';
$lang->fail_empty = '휴지통 비우기에 실패하였습니다.';
$lang->success_restore = '성공적으로 복원하였습니다.';
$lang->fail_restore = '복원에 실패하였습니다.';
?>

View file

@ -0,0 +1,103 @@
<?php
class TrashVO
{
var $trashSrl;
var $title;
var $originModule;
var $serializedObject;
var $description;
var $ipaddress;
var $removerSrl;
var $userId;
var $nickName;
var $regdate;
function getTrashSrl()
{
return $this->trashSrl;
}
function setTrashSrl($trashSrl)
{
$this->trashSrl = $trashSrl;
}
function getTitle()
{
if(empty($this->title)) return $lang->untitle;
return $this->title;
}
function setTitle($title)
{
$this->title = $title;
}
function getOriginModule()
{
if(empty($this->originModule)) return 'document';
return $this->originModule;
}
function setOriginModule($originModule)
{
$this->originModule = $originModule;
}
function getSerializedObject()
{
return $this->serializedObject;
}
function setSerializedObject($serializedObject)
{
$this->serializedObject = $serializedObject;
}
function getDescription()
{
return $this->description;
}
function setDescription($description)
{
$this->description = $description;
}
function getIpaddress()
{
return $this->ipaddress;
}
function setIpaddress($ipaddress)
{
$this->ipaddress = $ipaddress;
}
function getRemoverSrl()
{
return $this->removerSrl;
}
function setRemoverSrl($removerSrl)
{
$this->removerSrl = $removerSrl;
}
function getUserId()
{
return $this->userId;
}
function setUserId($userId)
{
$this->userId = $userId;
}
function getNickName()
{
return $this->nickName;
}
function setNickName($nickName)
{
$this->nickName = $nickName;
}
function getRegdate()
{
if(empty($this->regdate)) return date('YmdHis');
return $this->regdate;
}
function setRegdate($regdate)
{
$this->regdate = $regdate;
}
}
/* End of file Trash.php */
/* Location: ./modules/trash/model/Trash.php */

View file

@ -0,0 +1,9 @@
<query id="deleteTrash" action="delete">
<tables>
<table name="trash" />
</tables>
<conditions>
<condition operation="equal" column="trash_srl" var="trashSrl" filter="number" />
<condition operation="in" column="trash_srl" var="trashSrls" filter="number" />
</conditions>
</query>

View file

@ -0,0 +1,11 @@
<query id="getTrash" action="select">
<tables>
<table name="trash" />
</tables>
<columns>
<column name="*" />
</columns>
<conditions>
<condition operation="equal" column="trash_srl" var="trashSrl" filter="number" notnull="notnull" />
</conditions>
</query>

View file

@ -0,0 +1,21 @@
<query id="getTrashList" action="select">
<tables>
<table name="trash" alias="T" />
<table name="member" alias="M" />
</tables>
<columns>
<column name="T.*" />
<column name="M.user_id" />
<column name="M.nick_name" />
</columns>
<conditions>
<condition operation="equal" column="T.remover_srl" default="M.member_srl" notnull="notnull" />
<condition operation="equal" column="trash_srl" var="trashSrl" filter="number" />
</conditions>
<navigation>
<index var="sort_index" default="trash_srl" order="desc" />
<list_count var="list_count" default="20" />
<page_count var="page_count" default="10" />
<page var="page" default="1" />
</navigation>
</query>

View file

@ -0,0 +1,15 @@
<query id="insertTrash" action="insert">
<tables>
<table name="trash" />
</tables>
<columns>
<column name="trash_srl" var="trashSrl" filter="number" notnull="notnull" />
<column name="title" var="title" notnull="notnull" />
<column name="origin_module" var="originModule" notnull="notnull" default="document" />
<column name="serialized_object" var="serializedObject" />
<column name="description" var="description" />
<column name="ipaddress" var="ipaddress" default="ipaddress()" />
<column name="remover_srl" var="removerSrl" default="0" filter="number" />
<column name="regdate" var="regdate" default="curdate()" />
</columns>
</query>

View file

@ -0,0 +1,10 @@
<table name="trash">
<column name="trash_srl" type="number" size="11" notnull="notnull" primary_key="primary_key" />
<column name="title" type="varchar" size="250" />
<column name="origin_module" type="varchar" size="250" default="document" notnull="notnull" />
<column name="serialized_object" type="bigtext" notnull="notnull" />
<column name="description" type="text" />
<column name="ipaddress" type="varchar" size="128" notnull="notnull" />
<column name="remover_srl" type="number" size="11" notnull="notnull" />
<column name="regdate" type="date" index="idx_regdate" />
</table>

View file

@ -0,0 +1,12 @@
<filter name="emptyTrash" module="trash" act="procTrashAdminEmptyTrash" confirm_msg_code="confirm_delete">
<form>
<node target="trash_srl" />
</form>
<parameter>
<param name="trash_srl" target="trash_srl" />
</parameter>
<response callback_func="completeEmptyTrash">
<tag name="error" />
<tag name="message" />
</response>
</filter>

View file

@ -0,0 +1,2 @@
<!--%import("js/trash_admin.js")-->
<h3 class="xeAdmin">{$lang->cmd_trash} <span class="gray">{$lang->cmd_management}</span></h3>

View file

@ -0,0 +1,33 @@
/**
* @file modules/trash/js/trash_admin.js
* @author NHN (developers@xpressengine.com)
* @brief trash 모듈의 관리자용 javascript
**/
/* 휴지통 비우기 후 */
function completeEmptyTrash(ret_obj) {
var error = ret_obj['error'];
var message = ret_obj['message'];
alert(message);
if(error == '0') window.location.reload();
}
function goRestore(trash_srl)
{
if(confirm(confirm_restore_msg))
{
var params = {'trash_srl':trash_srl};
exec_xml('admin', 'procTrashAdminRestore', params, completeRestore);
}
}
function completeRestore(ret_obj)
{
var error = ret_obj['error'];
var message = ret_obj['message'];
alert(message);
if(error == '0') window.location.reload();
}

View file

@ -0,0 +1,69 @@
<script>
var confirm_restore_msg = '{$lang->confirm_restore}';
</script>
<!--%import("filter/emptyTrash.xml")-->
<!--#include("header.html")-->
<form id="fo_list" action="./" method="get" onsubmit="return procFilter(this, emptyTrash)">
<input type="hidden" name="page" value="{$page}" />
<input type="hidden" name="is_all" value="false" />
<!-- 목록 -->
<table cellspacing="0" class="rowTable clear">
<caption>Total {number_format($total_count)}, Page {number_format($page)}/{number_format($total_page)}</caption>
<thead>
<tr>
<th scope="col"><div>{$lang->no}</div></th>
<th scope="col"><div><input type="checkbox" onclick="XE.checkboxToggleAll('trash_srls[]');" /></div></th>
<th scope="col" class="wide"><div>{$lang->document} ({$lang->trash_type})</div></th>
<th scope="col"><div>{$lang->trash_nick_name}</div></th>
<th scope="col"><div>{$lang->trash_date}</div></th>
<th scope="col"><div>{$lang->ipaddress}</div></th>
<th scope="col"><dib>{$lang->trash_description}</div></th>
<th scope="col"><div>{$lang->cmd_restore}</div></th>
</tr>
</thead>
<tbody>
<!--@foreach($trash_list as $no => $oTrashVO)-->
<tr>
<td class="number center">{$no}</td>
<td><div><input type="checkbox" name="trash_srls[]" value="{$oTrashVO->getTrashSrl()}" /></div></t>
<td class="left subject">
{$oTrashVO->getTitle()} (
<!--@if($oTrashVO->getOriginModule() == 'document')-->
{$lang->document}
<!--@else if($oTrashVO->getOriginModule() == 'comment')-->
{$lang->replies}
<!--@else-->
{$lang->etc}
<!--@end-->
)
</td>
<td class="nowrap"><span class="member_{$oTrashVO->getMemberSrl()">{htmlspecialchars($oTrashVO->getNickName())}</span></td>
<td class="date center nowrap">{zdate($oTrashVO->getRegdate(), "Y-m-d H:i:s")}</td>
<td class="number center nowrap">{$oTrashVO->getIpaddress()}</td>
<td class="left">{$oTrashVO->getDescription()}</td>
<td class="center"><a href="#" onclick="goRestore({$oTrashVO->getTrashSrl()})">{$lang->cmd_restore}</a></td>
</tr>
<!--@end-->
</tbody>
</table>
<div class="fr">
<span class="button green"><input type="submit" value="{$lang->empty_trash_selected}" onclick="this.form.is_all.value=false" /></span>
<span class="button blue"><input type="submit" value="{$lang->empty_trash_all}" onclick="this.form.is_all.value=true" /></span>
</div>
</form>
<!-- 페이지 네비게이션 -->
<div class="pagination a1">
<a href="{getUrl('page','','module_srl',$module_srl)}" class="prevEnd">{$lang->first_page}</a>
<!--@while($page_no = $page_navigation->getNextPage())-->
<!--@if($page == $page_no)-->
<strong>{$page_no}</strong>
<!--@else-->
<a href="{getUrl('page',$page_no,'module_srl',$module_srl)}">{$page_no}</a>
<!--@end-->
<!--@end-->
<a href="{getUrl('page',$page_navigation->last_page,'module_srl',$module_srl)}" class="nextEnd">{$lang->last_page}</a>
</div>

View file

@ -0,0 +1,140 @@
<?php
/**
* @class documentController
* @author NHN (developers@xpressengine.com)
* @brief document the module's controller class
**/
class trashAdminController extends trash
{
/**
* @brief object insert to trash
**/
function insertTrash($obj)
{
if(Context::get('is_logged'))
{
$logged_info = Context::get('logged_info');
$oTrashVO = new TrashVO();
$oTrashVO->setTrashSrl(getNextSequence());
$oTrashVO->setTitle($obj->title);
$oTrashVO->setOriginModule($obj->trashType);
$oTrashVO->setSerializedObject(serialize($obj->originObject));
$oTrashVO->setDescription($obj->description);
$oTrashVO->setIpaddress($_SERVER['REMOTE_ADDR']);
$oTrashVO->setRemoverSrl($logged_info->member_srl);
$oTrashVO->setRegdate(date('YmdHis'));
$output = executeQuery('trash.insertTrash', $oTrashVO);
return $output;
}
return new Object(-1, 'msg_not_permitted');
}
/**
* @brief empty trash
* @param trashSrls : trash_srl in array
**/
function procTrashAdminEmptyTrash()
{
global $lang;
$isAll = Context::get('is_all');
$trashSrls = explode('|@|', Context::get('trash_srls'));
$oTrashModel = &getModel('trash');
if($isAll == 'true')
{
$trashSrls = array();
//module relation data delete...
$output = $oTrashModel->getTrashList($args);
if(!$output->toBool()) return new Object(-1, $output->message);
if(is_array($output->data))
{
foreach($output->data AS $key=>$oTrashVO)
{
//class file check
$classPath = ModuleHandler::getModulePath($oTrashVO->getOriginModule());
if(!is_dir(FileHandler::getRealPath($classPath))) return new Object(-1, 'not exist restore module directory');
$classFile = sprintf('%s%s.admin.controller.php', $classPath, $oTrashVO->getOriginModule());
$classFile = FileHandler::getRealPath($classFile);
if(!file_exists($classFile)) return new Object(-1, 'not exist restore module class file');
$oAdminController = &getAdminController($oTrashVO->getOriginModule());
if(!method_exists($oAdminController, 'emptyTrash')) return new Object(-1, 'not exist restore method in module class file');
$output = $oAdminController->emptyTrash($oTrashVO->getSerializedObject());
}
}
}
if(!$this->_emptyTrash($trashSrls))
return new Object(-1, $lang->fail_empty);
return new Object(0, $lang->success_empty);
}
function procTrashAdminRestore()
{
global $lang;
$trashSrl = Context::get('trash_srl');
$oTrashModel = &getModel('trash');
$output = $oTrashModel->getTrash($trashSrl);
if(!$output->toBool()) return new Object(-1, $output->message);
//class file check
$classPath = ModuleHandler::getModulePath($output->data->getOriginModule());
if(!is_dir(FileHandler::getRealPath($classPath))) return new Object(-1, 'not exist restore module directory');
$classFile = sprintf('%s%s.admin.controller.php', $classPath, $output->data->getOriginModule());
$classFile = FileHandler::getRealPath($classFile);
if(!file_exists($classFile)) return new Object(-1, 'not exist restore module class file');
$oAdminController = &getAdminController($output->data->getOriginModule());
if(!method_exists($oAdminController, 'restoreTrash')) return new Object(-1, 'not exist restore method in module class file');
// begin transaction
$oDB = &DB::getInstance();
$oDB->begin();
$originObject = unserialize($output->data->getSerializedObject());
$output = $oAdminController->restoreTrash($originObject);
if(!$output->toBool()) {
$oDB->rollback();
return new Object(-1, $output->message);
}
else
{
Context::set('is_all', 'false');
Context::set('trash_srls', $trashSrl);
$output = $this->procTrashAdminEmptyTrash();
if(!$output->toBool()) {
$oDB->rollback();
return new Object(-1, $output->message);
}
}
$oDB->commit();
return new Object(0, $lang->success_restore);
}
/**
* @brief empty trash
* @param trashSrls : trash_srl in array
**/
function _emptyTrash($trashSrls)
{
if(!is_array($trashSrls)) return false;
$args->trashSrls = $trashSrls;
$output = executeQuery('trash.deleteTrash', $args);
if(!$output->toBool()) return false;
return true;
}
}
/* End of file trash.controller.php */
/* Location: ./modules/trash/trash.controller.php */

View file

@ -0,0 +1,36 @@
<?php
/**
* @class trashView
* @author NHN (developers@xpressengine.com)
* @brief View class of the module trash
**/
class trashAdminView extends trash {
/**
* @brief Initialization
**/
function init() {
// 템플릿 경로 지정 (board의 경우 tpl에 관리자용 템플릿 모아놓음)
$template_path = sprintf("%stpl/",$this->module_path);
$this->setTemplatePath($template_path);
}
/**
* @brief trash list
**/
function dispTrashAdminList() {
$oTrashModel = getModel('trash');
$output = $oTrashModel->getTrashList($args);
Context::set('trash_list', $output->data);
Context::set('total_count', $output->total_count);
Context::set('total_page', $output->total_page);
Context::set('page', $output->page);
Context::set('page_navigation', $output->page_navigation);
// 템플릿 파일 지정
$this->setTemplateFile('trash_list');
}
}
?>

View file

@ -0,0 +1,39 @@
<?php
/**
* @class document
* @author NHN (developers@xpressengine.com)
* @brief document the module's high class
**/
require_once(_XE_PATH_.'modules/trash/model/TrashVO.php');
class trash extends ModuleObject {
/**
* @brief Implement if additional tasks are necessary when installing
**/
function moduleInstall() {
return new Object();
}
/**
* @brief a method to check if successfully installed
**/
function checkUpdate() {
//$oDB = &DB::getInstance();
//$oModuleModel = &getModel('module');
return false;
}
/**
* @brief Execute update
**/
function moduleUpdate() {
//$oDB = &DB::getInstance();
//$oModuleModel = &getModel('module');
return new Object(0,'success_updated');
}
}
?>

View file

@ -0,0 +1,12 @@
<?php
/**
* @class documentController
* @author NHN (developers@xpressengine.com)
* @brief document the module's controller class
**/
class trashController extends trash
{
}
/* End of file trash.controller.php */
/* Location: ./modules/trash/trash.controller.php */

View file

@ -0,0 +1,58 @@
<?php
class trashModel extends trash
{
/**
* @brief get one trash object
**/
function getTrash($trashSrl, $columnList = array())
{
$oTrashVO = new TrashVO();
if(!$trashSrl) return $oTrashVO;
$args->trashSrl = $trashSrl;
$output = executeQuery('trash.getTrash', $args, $columnList);
$this->_setTrashObject(&$oTrashVO, $output->data);
$output->data = $oTrashVO;
return $output;
}
/**
* @brief get trash object list
**/
function getTrashList($args, $columnList = array())
{
$output = executeQueryArray('trash.getTrashList', $args, $columnList);
if(is_array($output->data))
{
foreach($output->data AS $key=>$value)
{
$oTrashVO = new TrashVO();
$this->_setTrashObject(&$oTrashVO, $value);
$output->data[$key] = $oTrashVO;
}
}
return $output;
}
/**
* @brief set trash object from std object
**/
function _setTrashObject(&$oTrashVO, $stdObject)
{
$oTrashVO->setTrashSrl($stdObject->trash_srl);
$oTrashVO->setTitle($stdObject->title);
$oTrashVO->setOriginModule($stdObject->origin_module);
$oTrashVO->setSerializedObject($stdObject->serialized_object);
$oTrashVO->setDescription($stdObject->description);
$oTrashVO->setIpaddress($stdObject->ipaddress);
$oTrashVO->setRemoverSrl($stdObject->remover_srl);
$oTrashVO->setUserId($stdObject->user_id);
$oTrashVO->setNickName($stdObject->nick_name);
$oTrashVO->setRegdate($stdObject->regdate);
}
}

View file

@ -0,0 +1,16 @@
<?php
/**
* @class trashView
* @author NHN (developers@xpressengine.com)
* @brief View class of the module trash
**/
class trashView extends trash {
/**
* @brief Initialization
**/
function init() {
}
}
?>

View file

@ -1,7 +0,0 @@
<?php
class TestOfContext extends UnitTestCase {
function testOK() {
$this->assertTrue(true);
}
}
?>

View file

@ -0,0 +1,117 @@
<?php
define('__DEBUG__', 1);
$xe_path = realpath(dirname(__FILE__).'/../../../');
require "{$xe_path}/classes/xml/XmlParser.class.php";
require "{$xe_path}/classes/handler/Handler.class.php";
require "{$xe_path}/classes/file/FileHandler.class.php";
require "{$xe_path}/classes/validator/Validator.class.php";
error_reporting(E_ALL & ~E_NOTICE);
class ValidatorTest extends PHPUnit_Framework_TestCase
{
public function _testRequired() {
$vd = new Validator();
$vd->addFilter('userid', array('required'=>'true'));
// given data
$this->assertFalse( $vd->validate(array('no-userid'=>'hello')) );
$this->assertTrue( $vd->validate(array('userid'=>'myuserid')) );
$this->assertFalse( $vd->validate(array('userid'=>'')) );
// context data
$this->assertFalse( $vd->validate() );
Context::set('userid', '');
$this->assertFalse( $vd->validate() );
Context::set('userid', 'myuserid');
$this->assertTrue( $vd->validate() );
$vd->removeFilter('userid');
$this->assertTrue( $vd->validate() );
}
public function testDefault() {
global $mock_vars;
$vd = new Validator();
$vd->addFilter('userid', array('default'=>'ididid'));
// given data
$arr = array('no-userid'=>'');
$vd->validate($arr);
$this->assertEquals( $arr, array('no-userid'=>'') );
$arr = array('userid'=>'');
$vd->validate(&$arr); // pass-by-reference
$this->assertEquals( $arr, array('userid'=>'ididid') );
$arr = array('userid'=>'ownid');
$vd->validate(&$arr);
$this->assertEquals( $arr, array('userid'=>'ownid') );
// context data
$mock_vars = array(); // empty context variables
$vd->validate();
$this->assertEquals( 'ididid', Context::get('userid') );
$vd->load(dirname(__FILE__).'/login.xml');
Context::set('userid', '');
$vd->validate();
$this->assertEquals( 'idididid', Context::get('userid') );
}
public function testLength() {
$vd = new Validator();
$vd->addFilter('field1', array('length'=>'3:'));
$this->assertFalse( $vd->validate(array('field1'=>'ab')) );
$this->assertTrue( $vd->validate(array('field1'=>'abc')) );
$this->assertTrue( $vd->validate(array('field1'=>'abcd')) );
}
public function testCustomRule() {
}
public function testJSCompile() {
}
}
$mock_vars = array();
class Context
{
public function gets() {
global $mock_vars;
$args = func_get_args();
$output = new stdClass;
foreach($args as $name) {
$output->{$name} = $mock_vars[$name];
}
return $output;
}
public function getRequestVars() {
global $mock_vars;
return $mock_vars;
}
public function get($name) {
global $mock_vars;
return array_key_exists($name, $mock_vars)?$mock_vars[$name]:'';
}
public function set($name, $value) {
global $mock_vars;
$mock_vars[$name] = $value;
}
public function getLangType() {
return 'en';
}
}

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<ruleset version="1.5.0">
<customrules>
</customrules>
<fields>
<field name="nick_name" length="1:20"/>
<field name="password" length="1:20"/>
<field name="email_address" rule="email" length=":250" />
<field name="homepage" rule="url" length=":250" />
<field name="title" required="true" length="1:250"/>
<field name="content" required="true"/>
<field name="category_srl" required="true" rule="number" default="0" />
</fields>
</ruleset>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<ruleset>
<fields>
<field name="userid" required="true" length="5:10" rule="userid" default="idididid" />
<field name="password" required="true" />
</fields>
</ruleset>

View file

@ -1,23 +0,0 @@
<?php
define('__ZBXE__', true);
require_once('../config/config.inc.php');
if(__ENABLE_PHPUNIT_TEST__!=1) exit();
require_once('simpletest/autorun.php');
class AllTests extends TestSuite {
function AllTests() {
$oContext = &Context::getInstance();
$oContext->init();
$this->TestSuite('Classes Test');
$this->addFile(dirname(__FILE__).'/classes/context/Context.test.php');
$this->TestSuite('Module Test');
$this->addFile(dirname(__FILE__).'/modules/module/module.test.php');
$this->addFile(dirname(__FILE__).'/modules/module/opage.test.php');
}
}
?>

View file

@ -1,19 +0,0 @@
<?php
class LockTest extends UnitTestCase {
function testLock() {
$oController = &getController('module');
$this->assertNotNull($oController);
$output = $oController->lock('lockTest', 60);
$this->assertTrue($output->toBool());
$deadline = $output->get('deadline');
$output2 = $oController->lock('lockTest', 60);
$this->assertFalse($output2->toBool());
$output2 = $oController->unlock('lockTest', $deadline);
$this->assertTrue($output2->toBool());
$output2 = $oController->lock('lockTest', 60);
$this->assertTrue($output2->toBool());
$output2 = $oController->unlock('lockTest', $output2->get('deadline'));
$this->assertTrue($output2->toBool());
}
}
?>

View file

@ -1,63 +0,0 @@
<?php
class opageTest extends UnitTestCase {
function testReplaceSrc() {
$oController = &getController('opage');
$this->assertNotNull($oController);
$path = 'http://domain.com/test_path/opage.php';
$content = 'src="images/foo.jpg"';
$expected_result = 'src="http://domain.com/test_path/images/foo.jpg"';
$result = $oController->replaceSrc($content, $path);
$this->assertEqual($expected_result, $result);
$content = 'src="/images/foo.jpg"';
$expected_result = 'src="http://domain.com/images/foo.jpg"';
$result = $oController->replaceSrc($content, $path);
$this->assertEqual($expected_result, $result);
$content = 'src="./images/foo.jpg"';
$expected_result = 'src="http://domain.com/test_path/images/foo.jpg"';
$result = $oController->replaceSrc($content, $path);
$this->assertEqual($expected_result, $result);
$content = 'src="../images/foo.jpg"';
$expected_result = 'src="http://domain.com/test_path/../images/foo.jpg"';
$result = $oController->replaceSrc($content, $path);
$this->assertEqual($expected_result, $result);
$content = 'url("./images/foo.jpg")';
$expected_result = 'url("http://domain.com/test_path/images/foo.jpg")';
$result = $oController->replaceSrc($content, $path);
$this->assertEqual($expected_result, $result);
/*
* 프로토콜
* http, https, ftp, telnet, mailto, mms
*/
$content = 'href="https://domail.com/"';
$expected_result = $content;
$result = $oController->replaceSrc($content, $path);
$this->assertEqual($expected_result, $result);
$content = 'href="mailto:foo@domain.com"';
$expected_result = $content;
$result = $oController->replaceSrc($content, $path);
$this->assertEqual($expected_result, $result);
$content = 'href="mms://domain.com/bar.wmv"';
$expected_result = $content;
$result = $oController->replaceSrc($content, $path);
$this->assertEqual($expected_result, $result);
// + 포트번호
$path = 'http://domain.com:123/test_path/opage.php';
$content = 'src="./images/foo.jpg"';
$expected_result = 'src="http://domain.com:123/test_path/images/foo.jpg"';
$result = $oController->replaceSrc($content, $path);
$this->assertEqual($expected_result, $result);
}
}
?>

View file

@ -1,348 +0,0 @@
Simple Test interface changes
=============================
Because the SimpleTest tool set is still evolving it is likely that tests
written with earlier versions will fail with the newest ones. The most
dramatic changes are in the alpha releases. Here is a list of possible
problems and their fixes...
No method getRelativeUrls() or getAbsoluteUrls()
------------------------------------------------
These methods were always a bit weird anyway, and
the new parsing of the base tag makes them more so.
They have been replaced with getUrls() instead. If
you want the old functionality then simply chop
off the current domain from getUrl().
Method setWildcard() removed in mocks
-------------------------------------
Even setWildcard() has been removed in 1.0.1beta now.
If you want to test explicitely for a '*' string, then
simply pass in new IdenticalExpectation('*') instead.
No method _getTest() on mocks
-----------------------------
This has finally been removed. It was a pretty esoteric
flex point anyway. It was there to allow the mocks to
work with other test tools, but no one does this.
No method assertError(), assertNoErrors(), swallowErrors()
----------------------------------------------------------
These have been deprecated in 1.0.1beta in favour of
expectError() and expectException(). assertNoErrors() is
redundant if you use expectError() as failures are now reported
immediately.
No method TestCase::signal()
----------------------------
This has been deprecated in favour of triggering an error or
throwing an exception. Deprecated as of 1.0.1beta.
No method TestCase::sendMessage()
---------------------------------
This has been deprecated as of 1.0.1beta.
Failure to connect now emits failures
-------------------------------------
It used to be that you would have to use the
getTransferError() call on the web tester to see if
there was a socket level error in a fetch. This check
is now always carried out by the WebTestCase unless
the fetch is prefaced with WebTestCase::ignoreErrors().
The ignore directive only lasts for test case fetching
action such as get() and click().
No method SimpleTestOptions::ignore()
-------------------------------------
This is deprecated in version 1.0.1beta and has been moved
to SimpleTest::ignore() as that is more readable. In
addition, parent classes are also ignored automatically.
If you are using PHP5 you can skip this directive simply
by marking your test case as abstract.
No method assertCopy()
----------------------
This is deprecated in 1.0.1 in favour of assertClone().
The assertClone() method is slightly different in that
the objects must be identical, but without being a
reference. It is thus not a strict inversion of
assertReference().
Constructor wildcard override has no effect in mocks
----------------------------------------------------
As of 1.0.1beta this is now set with setWildcard() instead
of in the constructor.
No methods setStubBaseClass()/getStubBaseClass()
------------------------------------------------
As mocks are now used instead of stubs, these methods
stopped working and are now removed as of the 1.0.1beta
release. The mock objects may be freely used instead.
No method addPartialMockCode()
------------------------------
The ability to insert arbitrary partial mock code
has been removed. This was a low value feature
causing needless complications. It was removed
in the 1.0.1beta release.
No method setMockBaseClass()
----------------------------
The ability to change the mock base class has been
scheduled for removal and is deprecated since the
1.0.1beta version. This was a rarely used feature
except as a workaround for PHP5 limitations. As
these limitations are being resolved it's hoped
that the bundled mocks can be used directly.
No class Stub
-------------
Server stubs are deprecated from 1.0.1 as the mocks now
have exactly the same interface. Just use mock objects
instead.
No class SimpleTestOptions
--------------------------
This was replced by the shorter SimpleTest in 1.0.1beta1
and is since deprecated.
No file simple_test.php
-----------------------
This was renamed test_case.php in 1.0.1beta to more accurately
reflect it's purpose. This file should never be directly
included in test suites though, as it's part of the
underlying mechanics and has a tendency to be refactored.
No class WantedPatternExpectation
---------------------------------
This was deprecated in 1.0.1alpha in favour of the simpler
name PatternExpectation.
No class NoUnwantedPatternExpectation
-------------------------------------
This was deprecated in 1.0.1alpha in favour of the simpler
name NoPatternExpectation.
No method assertNoUnwantedPattern()
-----------------------------------
This has been renamed to assertNoPattern() in 1.0.1alpha and
the old form is deprecated.
No method assertWantedPattern()
-------------------------------
This has been renamed to assertPattern() in 1.0.1alpha and
the old form is deprecated.
No method assertExpectation()
-----------------------------
This was renamed as assert() in 1.0.1alpha and the old form
has been deprecated.
No class WildcardExpectation
----------------------------
This was a mostly internal class for the mock objects. It was
renamed AnythingExpectation to bring it closer to JMock and
NMock in version 1.0.1alpha.
Missing UnitTestCase::assertErrorPattern()
------------------------------------------
This method is deprecated for version 1.0.1 onwards.
This method has been subsumed by assertError() that can now
take an expectation. Simply pass a PatternExpectation
into assertError() to simulate the old behaviour.
No HTML when matching page elements
-----------------------------------
This behaviour has been switched to using plain text as if it
were seen by the user of the browser. This means that HTML tags
are suppressed, entities are converted and whitespace is
normalised. This should make it easier to match items in forms.
Also images are replaced with their "alt" text so that they
can be matched as well.
No method SimpleRunner::_getTestCase()
--------------------------------------
This was made public as getTestCase() in 1.0RC2.
No method restartSession()
--------------------------
This was renamed to restart() in the WebTestCase, SimpleBrowser
and the underlying SimpleUserAgent in 1.0RC2. Because it was
undocumented anyway, no attempt was made at backward
compatibility.
My custom test case ignored by tally()
--------------------------------------
The _assertTrue method has had it's signature changed due to a bug
in the PHP 5.0.1 release. You must now use getTest() from within
that method to get the test case. Mock compatibility with other
unit testers is now deprecated as of 1.0.1alpha as PEAR::PHPUnit2
should soon have mock support of it's own.
Broken code extending SimpleRunner
----------------------------------
This was replaced with SimpleScorer so that I could use the runner
name in another class. This happened in RC1 development and there
is no easy backward compatibility fix. The solution is simply to
extend SimpleScorer instead.
Missing method getBaseCookieValue()
-----------------------------------
This was renamed getCurrentCookieValue() in RC1.
Missing files from the SimpleTest suite
---------------------------------------
Versions of SimpleTest prior to Beta6 required a SIMPLE_TEST constant
to point at the SimpleTest folder location before any of the toolset
was loaded. This is no longer documented as it is now unnecessary
for later versions. If you are using an earlier version you may
need this constant. Consult the documentation that was bundled with
the release that you are using or upgrade to Beta6 or later.
No method SimpleBrowser::getCurrentUrl()
--------------------------------------
This is replaced with the more versatile showRequest() for
debugging. It only existed in this context for version Beta5.
Later versions will have SimpleBrowser::getHistory() for tracking
paths through pages. It is renamed as getUrl() since 1.0RC1.
No method Stub::setStubBaseClass()
----------------------------------
This method has finally been removed in 1.0RC1. Use
SimpleTestOptions::setStubBaseClass() instead.
No class CommandLineReporter
----------------------------
This was renamed to TextReporter in Beta3 and the deprecated version
was removed in 1.0RC1.
No method requireReturn()
-------------------------
This was deprecated in Beta3 and is now removed.
No method expectCookie()
------------------------
This method was abruptly removed in Beta4 so as to simplify the internals
until another mechanism can replace it. As a workaround it is necessary
to assert that the cookie has changed by setting it before the page
fetch and then assert the desired value.
No method clickSubmitByFormId()
-------------------------------
This method had an incorrect name as no button was involved. It was
renamed to submitByFormId() in Beta4 and the old version deprecated.
Now removed.
No method paintStart() or paintEnd()
------------------------------------
You should only get this error if you have subclassed the lower level
reporting and test runner machinery. These methods have been broken
down into events for test methods, events for test cases and events
for group tests. The new methods are...
paintStart() --> paintMethodStart(), paintCaseStart(), paintGroupStart()
paintEnd() --> paintMethodEnd(), paintCaseEnd(), paintGroupEnd()
This change was made in Beta3, ironically to make it easier to subclass
the inner machinery. Simply duplicating the code you had in the previous
methods should provide a temporary fix.
No class TestDisplay
--------------------
This has been folded into SimpleReporter in Beta3 and is now deprecated.
It was removed in RC1.
No method WebTestCase::fetch()
------------------------------
This was renamed get() in Alpha8. It is removed in Beta3.
No method submit()
------------------
This has been renamed clickSubmit() in Beta1. The old method was
removed in Beta2.
No method clearHistory()
------------------------
This method is deprecated in Beta2 and removed in RC1.
No method getCallCount()
------------------------
This method has been deprecated since Beta1 and has now been
removed. There are now more ways to set expectations on counts
and so this method should be unecessery. Removed in RC1.
Cannot find file *
------------------
The following public name changes have occoured...
simple_html_test.php --> reporter.php
simple_mock.php --> mock_objects.php
simple_unit.php --> unit_tester.php
simple_web.php --> web_tester.php
The old names were deprecated in Alpha8 and removed in Beta1.
No method attachObserver()
--------------------------
Prior to the Alpha8 release the old internal observer pattern was
gutted and replaced with a visitor. This is to trade flexibility of
test case expansion against the ease of writing user interfaces.
Code such as...
$test = &new MyTestCase();
$test->attachObserver(new TestHtmlDisplay());
$test->run();
...should be rewritten as...
$test = &new MyTestCase();
$test->run(new HtmlReporter());
If you previously attached multiple observers then the workaround
is to run the tests twice, once with each, until they can be combined.
For one observer the old method is simulated in Alpha 8, but is
removed in Beta1.
No class TestHtmlDisplay
------------------------
This class has been renamed to HtmlReporter in Alpha8. It is supported,
but deprecated in Beta1 and removed in Beta2. If you have subclassed
the display for your own design, then you will have to extend this
class (HtmlReporter) instead.
If you have accessed the event queue by overriding the notify() method
then I am afraid you are in big trouble :(. The reporter is now
carried around the test suite by the runner classes and the methods
called directly. In the unlikely event that this is a problem and
you don't want to upgrade the test tool then simplest is to write your
own runner class and invoke the tests with...
$test->accept(new MyRunner(new MyReporter()));
...rather than the run method. This should be easier to extend
anyway and gives much more control. Even this method is overhauled
in Beta3 where the runner class can be set within the test case. Really
the best thing to do is to upgrade to this version as whatever you were
trying to achieve before should now be very much easier.
Missing set options method
--------------------------
All test suite options are now in one class called SimpleTestOptions.
This means that options are set differently...
GroupTest::ignore() --> SimpleTestOptions::ignore()
Mock::setMockBaseClass() --> SimpleTestOptions::setMockBaseClass()
These changed in Alpha8 and the old versions are now removed in RC1.
No method setExpected*()
------------------------
The mock expectations changed their names in Alpha4 and the old names
ceased to be supported in Alpha8. The changes are...
setExpectedArguments() --> expectArguments()
setExpectedArgumentsSequence() --> expectArgumentsAt()
setExpectedCallCount() --> expectCallCount()
setMaximumCallCount() --> expectMaximumCallCount()
The parameters remained the same.

View file

@ -1,502 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View file

@ -1,108 +0,0 @@
SimpleTest
==========
You probably got this package from...
http://simpletest.sourceforge.net/projects/simpletest/
If there is no licence agreement with this package please download
a version from the location above. You must read and accept that
licence to use this software. The file is titled simply LICENSE.
What is it? It's a framework for unit testing, web site testing and
mock objects for PHP 4.2.0+ (and PHP 5.0 to 5.3 without E_STRICT).
If you have used JUnit, you will find this PHP unit testing version very
similar. Also included is a mock objects and server stubs generator.
The stubs can have return values set for different arguments, can have
sequences set also by arguments and can return items by reference.
The mocks inherit all of this functionality and can also have
expectations set, again in sequences and for different arguments.
A web tester similar in concept to JWebUnit is also included. There is no
JavaScript or tables support, but forms, authentication, cookies and
frames are handled.
You can see a release schedule at http://www.lastcraft.com/overview.php
which is also copied to the documentation folder with this release.
A full PHPDocumenter API documentation exists at
http://simpletest.sourceforge.net/.
The user interface is minimal
in the extreme, but a lot of information flows from the test suite.
After version 1.0 we will release a better web UI, but we are leaving XUL
and GTk versions to volunteers as everybody has their own opinion
on a good GUI, and we don't want to discourage development by shipping
one with the toolkit. YOucan download an Eclipse plug-in separately.
You are looking at a second full release. The unit tests for SimpleTest
itself can be run here...
simpletest/test/unit_tests.php
And tests involving live network connections as well are here...
simpletest/test/all_tests.php
The full tests will typically overrun the 8Mb limit often allowed
to a PHP process. A workaround is to run the tests on the command
with a custom php.ini file if you do not have access to your server
version.
You will have to edit the all_tests.php file if you are accesssing
the internet through a proxy server. See the comments in all_tests.php
for instructions.
The full tests read some test data from the LastCraft site. If the site
is down or has been modified for a later version then you will get
spurious errors. A unit_tests.php failure on the other hand would be
very serious. As far as we know we haven't yet managed to check in any
unit test failures, so please correct us if you find one.
Even if all of the tests run please verify that your existing test suites
also function as expected. If they don't see the file...
HELP_MY_TESTS_DONT_WORK_ANYMORE
This contains information on interface changes. It also points out
deprecated interfaces, so you should read this even if all of
your current tests appear to run.
There is a documentation folder which contains the core reference information
in English and French, although this information is fairly basic.
You can find a tutorial on...
http://www.lastcraft.com/first_test_tutorial.php
...to get you started and this material will eventually become included
with the project documentation. A French translation exists at...
http://www.onpk.net/index.php/2005/01/12/254-tutoriel-simpletest-decouvrir-les-tests-unitaires.
If you download and use, and possibly even extend this tool, please let us
know. Any feedback, even bad, is always welcome and we will work to get
your suggestions into the next release. Ideally please send your
comments to...
simpletest-support@lists.sourceforge.net
...so that others can read them too. We usually try to respond within 48
hours.
There is no change log except at Sourceforge. You can visit the
release notes to see the completed TODO list after each cycle and also the
status of any bugs, but if the bug is recent then it will be fixed in SVN only.
The SVN check-ins always have all the tests passing and so SVN snapshots should
be pretty usable, although the code may not look so good internally.
Oh, yes. It is called "Simple" because it should be simple to
use. We intend to add a complete set of tools for a test first
and "test as you code" type of development. "Simple" does not
mean "Lite" in this context.
Thanks to everyone who has sent comments and offered suggestions. They
really are invaluable, but sadly you are too many to mention in full.
Thanks to all on the advanced PHP forum on SitePoint, especially Harry
Feucks. Early adopters are always an inspiration.
Marcus Baker, Jason Sweat, Travis Swicegood, Perrick Penet and Edward Z. Yang.
--
marcus@lastcraft.com

View file

@ -1 +0,0 @@
1.0.1

View file

@ -1,238 +0,0 @@
<?php
/**
* Base include file for SimpleTest
* @package SimpleTest
* @subpackage WebTester
* @version $Id: authentication.php 1720 2008-04-07 02:32:43Z lastcraft $
*/
/**
* include http class
*/
require_once(dirname(__FILE__) . '/http.php');
/**
* Represents a single security realm's identity.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleRealm {
var $_type;
var $_root;
var $_username;
var $_password;
/**
* Starts with the initial entry directory.
* @param string $type Authentication type for this
* realm. Only Basic authentication
* is currently supported.
* @param SimpleUrl $url Somewhere in realm.
* @access public
*/
function SimpleRealm($type, $url) {
$this->_type = $type;
$this->_root = $url->getBasePath();
$this->_username = false;
$this->_password = false;
}
/**
* Adds another location to the realm.
* @param SimpleUrl $url Somewhere in realm.
* @access public
*/
function stretch($url) {
$this->_root = $this->_getCommonPath($this->_root, $url->getPath());
}
/**
* Finds the common starting path.
* @param string $first Path to compare.
* @param string $second Path to compare.
* @return string Common directories.
* @access private
*/
function _getCommonPath($first, $second) {
$first = explode('/', $first);
$second = explode('/', $second);
for ($i = 0; $i < min(count($first), count($second)); $i++) {
if ($first[$i] != $second[$i]) {
return implode('/', array_slice($first, 0, $i)) . '/';
}
}
return implode('/', $first) . '/';
}
/**
* Sets the identity to try within this realm.
* @param string $username Username in authentication dialog.
* @param string $username Password in authentication dialog.
* @access public
*/
function setIdentity($username, $password) {
$this->_username = $username;
$this->_password = $password;
}
/**
* Accessor for current identity.
* @return string Last succesful username.
* @access public
*/
function getUsername() {
return $this->_username;
}
/**
* Accessor for current identity.
* @return string Last succesful password.
* @access public
*/
function getPassword() {
return $this->_password;
}
/**
* Test to see if the URL is within the directory
* tree of the realm.
* @param SimpleUrl $url URL to test.
* @return boolean True if subpath.
* @access public
*/
function isWithin($url) {
if ($this->_isIn($this->_root, $url->getBasePath())) {
return true;
}
if ($this->_isIn($this->_root, $url->getBasePath() . $url->getPage() . '/')) {
return true;
}
return false;
}
/**
* Tests to see if one string is a substring of
* another.
* @param string $part Small bit.
* @param string $whole Big bit.
* @return boolean True if the small bit is
* in the big bit.
* @access private
*/
function _isIn($part, $whole) {
return strpos($whole, $part) === 0;
}
}
/**
* Manages security realms.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleAuthenticator {
var $_realms;
/**
* Clears the realms.
* @access public
*/
function SimpleAuthenticator() {
$this->restartSession();
}
/**
* Starts with no realms set up.
* @access public
*/
function restartSession() {
$this->_realms = array();
}
/**
* Adds a new realm centered the current URL.
* Browsers vary wildly on their behaviour in this
* regard. Mozilla ignores the realm and presents
* only when challenged, wasting bandwidth. IE
* just carries on presenting until a new challenge
* occours. SimpleTest tries to follow the spirit of
* the original standards committee and treats the
* base URL as the root of a file tree shaped realm.
* @param SimpleUrl $url Base of realm.
* @param string $type Authentication type for this
* realm. Only Basic authentication
* is currently supported.
* @param string $realm Name of realm.
* @access public
*/
function addRealm($url, $type, $realm) {
$this->_realms[$url->getHost()][$realm] = new SimpleRealm($type, $url);
}
/**
* Sets the current identity to be presented
* against that realm.
* @param string $host Server hosting realm.
* @param string $realm Name of realm.
* @param string $username Username for realm.
* @param string $password Password for realm.
* @access public
*/
function setIdentityForRealm($host, $realm, $username, $password) {
if (isset($this->_realms[$host][$realm])) {
$this->_realms[$host][$realm]->setIdentity($username, $password);
}
}
/**
* Finds the name of the realm by comparing URLs.
* @param SimpleUrl $url URL to test.
* @return SimpleRealm Name of realm.
* @access private
*/
function _findRealmFromUrl($url) {
if (! isset($this->_realms[$url->getHost()])) {
return false;
}
foreach ($this->_realms[$url->getHost()] as $name => $realm) {
if ($realm->isWithin($url)) {
return $realm;
}
}
return false;
}
/**
* Presents the appropriate headers for this location.
* @param SimpleHttpRequest $request Request to modify.
* @param SimpleUrl $url Base of realm.
* @access public
*/
function addHeaders(&$request, $url) {
if ($url->getUsername() && $url->getPassword()) {
$username = $url->getUsername();
$password = $url->getPassword();
} elseif ($realm = $this->_findRealmFromUrl($url)) {
$username = $realm->getUsername();
$password = $realm->getPassword();
} else {
return;
}
$this->addBasicHeaders($request, $username, $password);
}
/**
* Presents the appropriate headers for this
* location for basic authentication.
* @param SimpleHttpRequest $request Request to modify.
* @param string $username Username for realm.
* @param string $password Password for realm.
* @access public
* @static
*/
function addBasicHeaders(&$request, $username, $password) {
if ($username && $password) {
$request->addHeaderLine(
'Authorization: Basic ' . base64_encode("$username:$password"));
}
}
}
?>

View file

@ -1,87 +0,0 @@
<?php
/**
* Autorunner which runs all tests cases found in a file
* that includes this module.
* @package SimpleTest
* @version $Id: autorun.php 1721 2008-04-07 19:27:10Z lastcraft $
*/
require_once dirname(__FILE__) . '/unit_tester.php';
require_once dirname(__FILE__) . '/mock_objects.php';
require_once dirname(__FILE__) . '/collector.php';
require_once dirname(__FILE__) . '/default_reporter.php';
$GLOBALS['SIMPLETEST_AUTORUNNER_INITIAL_CLASSES'] = get_declared_classes();
register_shutdown_function('simpletest_autorun');
/**
* Exit handler to run all recent test cases if no test has
* so far been run. Uses the DefaultReporter which can have
* it's output controlled with SimpleTest::prefer().
*/
function simpletest_autorun() {
if (tests_have_run()) {
return;
}
$candidates = array_intersect(
capture_new_classes(),
classes_defined_in_initial_file());
$loader = new SimpleFileLoader();
$suite = $loader->createSuiteFromClasses(
basename(initial_file()),
$loader->selectRunnableTests($candidates));
$result = $suite->run(new DefaultReporter());
if (SimpleReporter::inCli()) {
exit($result ? 0 : 1);
}
}
/**
* Checks the current test context to see if a test has
* ever been run.
* @return boolean True if tests have run.
*/
function tests_have_run() {
if ($context = SimpleTest::getContext()) {
return (boolean)$context->getTest();
}
return false;
}
/**
* The first autorun file.
* @return string Filename of first autorun script.
*/
function initial_file() {
static $file = false;
if (! $file) {
$file = reset(get_included_files());
}
return $file;
}
/**
* Just the classes from the first autorun script. May
* get a few false positives, as it just does a regex based
* on following the word "class".
* @return array List of all possible classes in first
* autorun script.
*/
function classes_defined_in_initial_file() {
if (preg_match_all('/\bclass\s+(\w+)/i', file_get_contents(initial_file()), $matches)) {
return array_map('strtolower', $matches[1]);
}
return array();
}
/**
* Every class since the first autorun include. This
* is safe enough if require_once() is alwyas used.
* @return array Class names.
*/
function capture_new_classes() {
global $SIMPLETEST_AUTORUNNER_INITIAL_CLASSES;
return array_map('strtolower', array_diff(get_declared_classes(),
$SIMPLETEST_AUTORUNNER_INITIAL_CLASSES ?
$SIMPLETEST_AUTORUNNER_INITIAL_CLASSES : array()));
}
?>

File diff suppressed because it is too large Load diff

View file

@ -1,122 +0,0 @@
<?php
/**
* This file contains the following classes: {@link SimpleCollector},
* {@link SimplePatternCollector}.
*
* @author Travis Swicegood <development@domain51.com>
* @package SimpleTest
* @subpackage UnitTester
* @version $Id: collector.php 1723 2008-04-08 00:34:10Z lastcraft $
*/
/**
* The basic collector for {@link GroupTest}
*
* @see collect(), GroupTest::collect()
* @package SimpleTest
* @subpackage UnitTester
*/
class SimpleCollector {
/**
* Strips off any kind of slash at the end so as to normalise the path.
* @param string $path Path to normalise.
* @return string Path without trailing slash.
*/
function _removeTrailingSlash($path) {
if (substr($path, -1) == DIRECTORY_SEPARATOR) {
return substr($path, 0, -1);
} elseif (substr($path, -1) == '/') {
return substr($path, 0, -1);
} else {
return $path;
}
}
/**
* Scans the directory and adds what it can.
* @param object $test Group test with {@link GroupTest::addTestFile()} method.
* @param string $path Directory to scan.
* @see _attemptToAdd()
*/
function collect(&$test, $path) {
$path = $this->_removeTrailingSlash($path);
if ($handle = opendir($path)) {
while (($entry = readdir($handle)) !== false) {
if ($this->_isHidden($entry)) {
continue;
}
$this->_handle($test, $path . DIRECTORY_SEPARATOR . $entry);
}
closedir($handle);
}
}
/**
* This method determines what should be done with a given file and adds
* it via {@link GroupTest::addTestFile()} if necessary.
*
* This method should be overriden to provide custom matching criteria,
* such as pattern matching, recursive matching, etc. For an example, see
* {@link SimplePatternCollector::_handle()}.
*
* @param object $test Group test with {@link GroupTest::addTestFile()} method.
* @param string $filename A filename as generated by {@link collect()}
* @see collect()
* @access protected
*/
function _handle(&$test, $file) {
if (is_dir($file)) {
return;
}
$test->addTestFile($file);
}
/**
* Tests for hidden files so as to skip them. Currently
* only tests for Unix hidden files.
* @param string $filename Plain filename.
* @return boolean True if hidden file.
* @access private
*/
function _isHidden($filename) {
return strncmp($filename, '.', 1) == 0;
}
}
/**
* An extension to {@link SimpleCollector} that only adds files matching a
* given pattern.
*
* @package SimpleTest
* @subpackage UnitTester
* @see SimpleCollector
*/
class SimplePatternCollector extends SimpleCollector {
var $_pattern;
/**
*
* @param string $pattern Perl compatible regex to test name against
* See {@link http://us4.php.net/manual/en/reference.pcre.pattern.syntax.php PHP's PCRE}
* for full documentation of valid pattern.s
*/
function SimplePatternCollector($pattern = '/php$/i') {
$this->_pattern = $pattern;
}
/**
* Attempts to add files that match a given pattern.
*
* @see SimpleCollector::_handle()
* @param object $test Group test with {@link GroupTest::addTestFile()} method.
* @param string $path Directory to scan.
* @access protected
*/
function _handle(&$test, $filename) {
if (preg_match($this->_pattern, $filename)) {
parent::_handle($test, $filename);
}
}
}
?>

View file

@ -1,173 +0,0 @@
<?php
/**
* base include file for SimpleTest
* @package SimpleTest
* @version $Id: compatibility.php 1723 2008-04-08 00:34:10Z lastcraft $
*/
/**
* Static methods for compatibility between different
* PHP versions.
* @package SimpleTest
*/
class SimpleTestCompatibility {
/**
* Creates a copy whether in PHP5 or PHP4.
* @param object $object Thing to copy.
* @return object A copy.
* @access public
* @static
*/
function copy($object) {
if (version_compare(phpversion(), '5') >= 0) {
eval('$copy = clone $object;');
return $copy;
}
return $object;
}
/**
* Identity test. Drops back to equality + types for PHP5
* objects as the === operator counts as the
* stronger reference constraint.
* @param mixed $first Test subject.
* @param mixed $second Comparison object.
* @return boolean True if identical.
* @access public
* @static
*/
function isIdentical($first, $second) {
if (version_compare(phpversion(), '5') >= 0) {
return SimpleTestCompatibility::_isIdenticalType($first, $second);
}
if ($first != $second) {
return false;
}
return ($first === $second);
}
/**
* Recursive type test.
* @param mixed $first Test subject.
* @param mixed $second Comparison object.
* @return boolean True if same type.
* @access private
* @static
*/
function _isIdenticalType($first, $second) {
if (gettype($first) != gettype($second)) {
return false;
}
if (is_object($first) && is_object($second)) {
if (get_class($first) != get_class($second)) {
return false;
}
return SimpleTestCompatibility::_isArrayOfIdenticalTypes(
get_object_vars($first),
get_object_vars($second));
}
if (is_array($first) && is_array($second)) {
return SimpleTestCompatibility::_isArrayOfIdenticalTypes($first, $second);
}
if ($first !== $second) {
return false;
}
return true;
}
/**
* Recursive type test for each element of an array.
* @param mixed $first Test subject.
* @param mixed $second Comparison object.
* @return boolean True if identical.
* @access private
* @static
*/
function _isArrayOfIdenticalTypes($first, $second) {
if (array_keys($first) != array_keys($second)) {
return false;
}
foreach (array_keys($first) as $key) {
$is_identical = SimpleTestCompatibility::_isIdenticalType(
$first[$key],
$second[$key]);
if (! $is_identical) {
return false;
}
}
return true;
}
/**
* Test for two variables being aliases.
* @param mixed $first Test subject.
* @param mixed $second Comparison object.
* @return boolean True if same.
* @access public
* @static
*/
function isReference(&$first, &$second) {
if (version_compare(phpversion(), '5', '>=') && is_object($first)) {
return ($first === $second);
}
if (is_object($first) && is_object($second)) {
$id = uniqid("test");
$first->$id = true;
$is_ref = isset($second->$id);
unset($first->$id);
return $is_ref;
}
$temp = $first;
$first = uniqid("test");
$is_ref = ($first === $second);
$first = $temp;
return $is_ref;
}
/**
* Test to see if an object is a member of a
* class hiearchy.
* @param object $object Object to test.
* @param string $class Root name of hiearchy.
* @return boolean True if class in hiearchy.
* @access public
* @static
*/
function isA($object, $class) {
if (version_compare(phpversion(), '5') >= 0) {
if (! class_exists($class, false)) {
if (function_exists('interface_exists')) {
if (! interface_exists($class, false)) {
return false;
}
}
}
eval("\$is_a = \$object instanceof $class;");
return $is_a;
}
if (function_exists('is_a')) {
return is_a($object, $class);
}
return ((strtolower($class) == get_class($object))
or (is_subclass_of($object, $class)));
}
/**
* Sets a socket timeout for each chunk.
* @param resource $handle Socket handle.
* @param integer $timeout Limit in seconds.
* @access public
* @static
*/
function setTimeout($handle, $timeout) {
if (function_exists('stream_set_timeout')) {
stream_set_timeout($handle, $timeout, 0);
} elseif (function_exists('socket_set_timeout')) {
socket_set_timeout($handle, $timeout, 0);
} elseif (function_exists('set_socket_timeout')) {
set_socket_timeout($handle, $timeout, 0);
}
}
}
?>

View file

@ -1,380 +0,0 @@
<?php
/**
* Base include file for SimpleTest
* @package SimpleTest
* @subpackage WebTester
* @version $Id: cookies.php 1723 2008-04-08 00:34:10Z lastcraft $
*/
/**#@+
* include other SimpleTest class files
*/
require_once(dirname(__FILE__) . '/url.php');
/**#@-*/
/**
* Cookie data holder. Cookie rules are full of pretty
* arbitary stuff. I have used...
* http://wp.netscape.com/newsref/std/cookie_spec.html
* http://www.cookiecentral.com/faq/
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleCookie {
var $_host;
var $_name;
var $_value;
var $_path;
var $_expiry;
var $_is_secure;
/**
* Constructor. Sets the stored values.
* @param string $name Cookie key.
* @param string $value Value of cookie.
* @param string $path Cookie path if not host wide.
* @param string $expiry Expiry date as string.
* @param boolean $is_secure Currently ignored.
*/
function SimpleCookie($name, $value = false, $path = false, $expiry = false, $is_secure = false) {
$this->_host = false;
$this->_name = $name;
$this->_value = $value;
$this->_path = ($path ? $this->_fixPath($path) : "/");
$this->_expiry = false;
if (is_string($expiry)) {
$this->_expiry = strtotime($expiry);
} elseif (is_integer($expiry)) {
$this->_expiry = $expiry;
}
$this->_is_secure = $is_secure;
}
/**
* Sets the host. The cookie rules determine
* that the first two parts are taken for
* certain TLDs and three for others. If the
* new host does not match these rules then the
* call will fail.
* @param string $host New hostname.
* @return boolean True if hostname is valid.
* @access public
*/
function setHost($host) {
if ($host = $this->_truncateHost($host)) {
$this->_host = $host;
return true;
}
return false;
}
/**
* Accessor for the truncated host to which this
* cookie applies.
* @return string Truncated hostname.
* @access public
*/
function getHost() {
return $this->_host;
}
/**
* Test for a cookie being valid for a host name.
* @param string $host Host to test against.
* @return boolean True if the cookie would be valid
* here.
*/
function isValidHost($host) {
return ($this->_truncateHost($host) === $this->getHost());
}
/**
* Extracts just the domain part that determines a
* cookie's host validity.
* @param string $host Host name to truncate.
* @return string Domain or false on a bad host.
* @access private
*/
function _truncateHost($host) {
$tlds = SimpleUrl::getAllTopLevelDomains();
if (preg_match('/[a-z\-]+\.(' . $tlds . ')$/i', $host, $matches)) {
return $matches[0];
} elseif (preg_match('/[a-z\-]+\.[a-z\-]+\.[a-z\-]+$/i', $host, $matches)) {
return $matches[0];
}
return false;
}
/**
* Accessor for name.
* @return string Cookie key.
* @access public
*/
function getName() {
return $this->_name;
}
/**
* Accessor for value. A deleted cookie will
* have an empty string for this.
* @return string Cookie value.
* @access public
*/
function getValue() {
return $this->_value;
}
/**
* Accessor for path.
* @return string Valid cookie path.
* @access public
*/
function getPath() {
return $this->_path;
}
/**
* Tests a path to see if the cookie applies
* there. The test path must be longer or
* equal to the cookie path.
* @param string $path Path to test against.
* @return boolean True if cookie valid here.
* @access public
*/
function isValidPath($path) {
return (strncmp(
$this->_fixPath($path),
$this->getPath(),
strlen($this->getPath())) == 0);
}
/**
* Accessor for expiry.
* @return string Expiry string.
* @access public
*/
function getExpiry() {
if (! $this->_expiry) {
return false;
}
return gmdate("D, d M Y H:i:s", $this->_expiry) . " GMT";
}
/**
* Test to see if cookie is expired against
* the cookie format time or timestamp.
* Will give true for a session cookie.
* @param integer/string $now Time to test against. Result
* will be false if this time
* is later than the cookie expiry.
* Can be either a timestamp integer
* or a cookie format date.
* @access public
*/
function isExpired($now) {
if (! $this->_expiry) {
return true;
}
if (is_string($now)) {
$now = strtotime($now);
}
return ($this->_expiry < $now);
}
/**
* Ages the cookie by the specified number of
* seconds.
* @param integer $interval In seconds.
* @public
*/
function agePrematurely($interval) {
if ($this->_expiry) {
$this->_expiry -= $interval;
}
}
/**
* Accessor for the secure flag.
* @return boolean True if cookie needs SSL.
* @access public
*/
function isSecure() {
return $this->_is_secure;
}
/**
* Adds a trailing and leading slash to the path
* if missing.
* @param string $path Path to fix.
* @access private
*/
function _fixPath($path) {
if (substr($path, 0, 1) != '/') {
$path = '/' . $path;
}
if (substr($path, -1, 1) != '/') {
$path .= '/';
}
return $path;
}
}
/**
* Repository for cookies. This stuff is a
* tiny bit browser dependent.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleCookieJar {
var $_cookies;
/**
* Constructor. Jar starts empty.
* @access public
*/
function SimpleCookieJar() {
$this->_cookies = array();
}
/**
* Removes expired and temporary cookies as if
* the browser was closed and re-opened.
* @param string/integer $now Time to test expiry against.
* @access public
*/
function restartSession($date = false) {
$surviving_cookies = array();
for ($i = 0; $i < count($this->_cookies); $i++) {
if (! $this->_cookies[$i]->getValue()) {
continue;
}
if (! $this->_cookies[$i]->getExpiry()) {
continue;
}
if ($date && $this->_cookies[$i]->isExpired($date)) {
continue;
}
$surviving_cookies[] = $this->_cookies[$i];
}
$this->_cookies = $surviving_cookies;
}
/**
* Ages all cookies in the cookie jar.
* @param integer $interval The old session is moved
* into the past by this number
* of seconds. Cookies now over
* age will be removed.
* @access public
*/
function agePrematurely($interval) {
for ($i = 0; $i < count($this->_cookies); $i++) {
$this->_cookies[$i]->agePrematurely($interval);
}
}
/**
* Sets an additional cookie. If a cookie has
* the same name and path it is replaced.
* @param string $name Cookie key.
* @param string $value Value of cookie.
* @param string $host Host upon which the cookie is valid.
* @param string $path Cookie path if not host wide.
* @param string $expiry Expiry date.
* @access public
*/
function setCookie($name, $value, $host = false, $path = '/', $expiry = false) {
$cookie = new SimpleCookie($name, $value, $path, $expiry);
if ($host) {
$cookie->setHost($host);
}
$this->_cookies[$this->_findFirstMatch($cookie)] = $cookie;
}
/**
* Finds a matching cookie to write over or the
* first empty slot if none.
* @param SimpleCookie $cookie Cookie to write into jar.
* @return integer Available slot.
* @access private
*/
function _findFirstMatch($cookie) {
for ($i = 0; $i < count($this->_cookies); $i++) {
$is_match = $this->_isMatch(
$cookie,
$this->_cookies[$i]->getHost(),
$this->_cookies[$i]->getPath(),
$this->_cookies[$i]->getName());
if ($is_match) {
return $i;
}
}
return count($this->_cookies);
}
/**
* Reads the most specific cookie value from the
* browser cookies. Looks for the longest path that
* matches.
* @param string $host Host to search.
* @param string $path Applicable path.
* @param string $name Name of cookie to read.
* @return string False if not present, else the
* value as a string.
* @access public
*/
function getCookieValue($host, $path, $name) {
$longest_path = '';
foreach ($this->_cookies as $cookie) {
if ($this->_isMatch($cookie, $host, $path, $name)) {
if (strlen($cookie->getPath()) > strlen($longest_path)) {
$value = $cookie->getValue();
$longest_path = $cookie->getPath();
}
}
}
return (isset($value) ? $value : false);
}
/**
* Tests cookie for matching against search
* criteria.
* @param SimpleTest $cookie Cookie to test.
* @param string $host Host must match.
* @param string $path Cookie path must be shorter than
* this path.
* @param string $name Name must match.
* @return boolean True if matched.
* @access private
*/
function _isMatch($cookie, $host, $path, $name) {
if ($cookie->getName() != $name) {
return false;
}
if ($host && $cookie->getHost() && ! $cookie->isValidHost($host)) {
return false;
}
if (! $cookie->isValidPath($path)) {
return false;
}
return true;
}
/**
* Uses a URL to sift relevant cookies by host and
* path. Results are list of strings of form "name=value".
* @param SimpleUrl $url Url to select by.
* @return array Valid name and value pairs.
* @access public
*/
function selectAsPairs($url) {
$pairs = array();
foreach ($this->_cookies as $cookie) {
if ($this->_isMatch($cookie, $url->getHost(), $url->getPath(), $cookie->getName())) {
$pairs[] = $cookie->getName() . '=' . $cookie->getValue();
}
}
return $pairs;
}
}
?>

View file

@ -1,133 +0,0 @@
<?php
/**
* Optional include file for SimpleTest
* @package SimpleTest
* @subpackage UnitTester
* @version $Id: default_reporter.php 1704 2008-03-25 00:47:04Z lastcraft $
*/
/**#@+
* include other SimpleTest class files
*/
require_once(dirname(__FILE__) . '/simpletest.php');
require_once(dirname(__FILE__) . '/scorer.php');
require_once(dirname(__FILE__) . '/reporter.php');
require_once(dirname(__FILE__) . '/xml.php');
/**#@-*/
/**
* Parser for command line arguments. Extracts
* the a specific test to run and engages XML
* reporting when necessary.
* @package SimpleTest
* @subpackage UnitTester
*/
class SimpleCommandLineParser {
var $_to_property = array(
'case' => '_case', 'c' => '_case',
'test' => '_test', 't' => '_test',
'xml' => '_xml', 'x' => '_xml');
var $_case = '';
var $_test = '';
var $_xml = false;
var $_no_skips = false;
/**
* Parses raw command line arguments into object properties.
* @param string $arguments Raw commend line arguments.
*/
function SimpleCommandLineParser($arguments) {
if (! is_array($arguments)) {
return;
}
foreach ($arguments as $i => $argument) {
if (preg_match('/^--?(test|case|t|c)=(.+)$/', $argument, $matches)) {
$property = $this->_to_property[$matches[1]];
$this->$property = $matches[2];
} elseif (preg_match('/^--?(test|case|t|c)$/', $argument, $matches)) {
$property = $this->_to_property[$matches[1]];
if (isset($arguments[$i + 1])) {
$this->$property = $arguments[$i + 1];
}
} elseif (preg_match('/^--?(xml|x)$/', $argument)) {
$this->_xml = true;
} elseif (preg_match('/^--?(no-skip|no-skips|s)$/', $argument)) {
$this->_no_skips = true;
}
}
}
/**
* Run only this test.
* @return string Test name to run.
* @access public
*/
function getTest() {
return $this->_test;
}
/**
* Run only this test suite.
* @return string Test class name to run.
* @access public
*/
function getTestCase() {
return $this->_case;
}
/**
* Output should be XML or not.
* @return boolean True if XML desired.
* @access public
*/
function isXml() {
return $this->_xml;
}
/**
* Output should suppress skip messages.
* @return boolean True for no skips.
* @access public
*/
function noSkips() {
return $this->_no_skips;
}
}
/**
* The default reporter used by SimpleTest's autorun
* feature. The actual reporters used are dependency
* injected and can be overridden.
* @package SimpleTest
* @subpackage UnitTester
*/
class DefaultReporter extends SimpleReporterDecorator {
/**
* Assembles the appopriate reporter for the environment.
*/
function DefaultReporter() {
if (SimpleReporter::inCli()) {
global $argv;
$parser = new SimpleCommandLineParser($argv);
$interfaces = $parser->isXml() ? array('XmlReporter') : array('TextReporter');
$reporter = &new SelectiveReporter(
SimpleTest::preferred($interfaces),
$parser->getTestCase(),
$parser->getTest());
if ($parser->noSkips()) {
$reporter = &new NoSkipsReporter($reporter);
}
} else {
$reporter = &new SelectiveReporter(
SimpleTest::preferred('HtmlReporter'),
@$_GET['c'],
@$_GET['t']);
if (@$_GET['skips'] == 'no' || @$_GET['show-skips'] == 'no') {
$reporter = &new NoSkipsReporter($reporter);
}
}
$this->SimpleReporterDecorator($reporter);
}
}
?>

View file

@ -1,96 +0,0 @@
<?php
/**
* base include file for SimpleTest
* @package SimpleTest
* @subpackage UnitTester
* @version $Id: detached.php 1723 2008-04-08 00:34:10Z lastcraft $
*/
/**#@+
* include other SimpleTest class files
*/
require_once(dirname(__FILE__) . '/xml.php');
require_once(dirname(__FILE__) . '/shell_tester.php');
/**#@-*/
/**
* Runs an XML formated test in a separate process.
* @package SimpleTest
* @subpackage UnitTester
*/
class DetachedTestCase {
var $_command;
var $_dry_command;
var $_size;
/**
* Sets the location of the remote test.
* @param string $command Test script.
* @param string $dry_command Script for dry run.
* @access public
*/
function DetachedTestCase($command, $dry_command = false) {
$this->_command = $command;
$this->_dry_command = $dry_command ? $dry_command : $command;
$this->_size = false;
}
/**
* Accessor for the test name for subclasses.
* @return string Name of the test.
* @access public
*/
function getLabel() {
return $this->_command;
}
/**
* Runs the top level test for this class. Currently
* reads the data as a single chunk. I'll fix this
* once I have added iteration to the browser.
* @param SimpleReporter $reporter Target of test results.
* @returns boolean True if no failures.
* @access public
*/
function run(&$reporter) {
$shell = &new SimpleShell();
$shell->execute($this->_command);
$parser = &$this->_createParser($reporter);
if (! $parser->parse($shell->getOutput())) {
trigger_error('Cannot parse incoming XML from [' . $this->_command . ']');
return false;
}
return true;
}
/**
* Accessor for the number of subtests.
* @return integer Number of test cases.
* @access public
*/
function getSize() {
if ($this->_size === false) {
$shell = &new SimpleShell();
$shell->execute($this->_dry_command);
$reporter = &new SimpleReporter();
$parser = &$this->_createParser($reporter);
if (! $parser->parse($shell->getOutput())) {
trigger_error('Cannot parse incoming XML from [' . $this->_dry_command . ']');
return false;
}
$this->_size = $reporter->getTestCaseCount();
}
return $this->_size;
}
/**
* Creates the XML parser.
* @param SimpleReporter $reporter Target of test results.
* @return SimpleTestXmlListener XML reader.
* @access protected
*/
function &_createParser(&$reporter) {
return new SimpleTestXmlParser($reporter);
}
}
?>

View file

@ -1,360 +0,0 @@
<?php
/**
* base include file for SimpleTest
* @package SimpleTest
* @subpackage UnitTester
* @version $Id: dumper.php 1723 2008-04-08 00:34:10Z lastcraft $
*/
/**
* does type matter
*/
if (! defined('TYPE_MATTERS')) {
define('TYPE_MATTERS', true);
}
/**
* Displays variables as text and does diffs.
* @package SimpleTest
* @subpackage UnitTester
*/
class SimpleDumper {
/**
* Renders a variable in a shorter form than print_r().
* @param mixed $value Variable to render as a string.
* @return string Human readable string form.
* @access public
*/
function describeValue($value) {
$type = $this->getType($value);
switch($type) {
case "Null":
return "NULL";
case "Boolean":
return "Boolean: " . ($value ? "true" : "false");
case "Array":
return "Array: " . count($value) . " items";
case "Object":
return "Object: of " . get_class($value);
case "String":
return "String: " . $this->clipString($value, 200);
default:
return "$type: $value";
}
return "Unknown";
}
/**
* Gets the string representation of a type.
* @param mixed $value Variable to check against.
* @return string Type.
* @access public
*/
function getType($value) {
if (! isset($value)) {
return "Null";
} elseif (is_bool($value)) {
return "Boolean";
} elseif (is_string($value)) {
return "String";
} elseif (is_integer($value)) {
return "Integer";
} elseif (is_float($value)) {
return "Float";
} elseif (is_array($value)) {
return "Array";
} elseif (is_resource($value)) {
return "Resource";
} elseif (is_object($value)) {
return "Object";
}
return "Unknown";
}
/**
* Creates a human readable description of the
* difference between two variables. Uses a
* dynamic call.
* @param mixed $first First variable.
* @param mixed $second Value to compare with.
* @param boolean $identical If true then type anomolies count.
* @return string Description of difference.
* @access public
*/
function describeDifference($first, $second, $identical = false) {
if ($identical) {
if (! $this->_isTypeMatch($first, $second)) {
return "with type mismatch as [" . $this->describeValue($first) .
"] does not match [" . $this->describeValue($second) . "]";
}
}
$type = $this->getType($first);
if ($type == "Unknown") {
return "with unknown type";
}
$method = '_describe' . $type . 'Difference';
return $this->$method($first, $second, $identical);
}
/**
* Tests to see if types match.
* @param mixed $first First variable.
* @param mixed $second Value to compare with.
* @return boolean True if matches.
* @access private
*/
function _isTypeMatch($first, $second) {
return ($this->getType($first) == $this->getType($second));
}
/**
* Clips a string to a maximum length.
* @param string $value String to truncate.
* @param integer $size Minimum string size to show.
* @param integer $position Centre of string section.
* @return string Shortened version.
* @access public
*/
function clipString($value, $size, $position = 0) {
$length = strlen($value);
if ($length <= $size) {
return $value;
}
$position = min($position, $length);
$start = ($size/2 > $position ? 0 : $position - $size/2);
if ($start + $size > $length) {
$start = $length - $size;
}
$value = substr($value, $start, $size);
return ($start > 0 ? "..." : "") . $value . ($start + $size < $length ? "..." : "");
}
/**
* Creates a human readable description of the
* difference between two variables. The minimal
* version.
* @param null $first First value.
* @param mixed $second Value to compare with.
* @return string Human readable description.
* @access private
*/
function _describeGenericDifference($first, $second) {
return "as [" . $this->describeValue($first) .
"] does not match [" .
$this->describeValue($second) . "]";
}
/**
* Creates a human readable description of the
* difference between a null and another variable.
* @param null $first First null.
* @param mixed $second Null to compare with.
* @param boolean $identical If true then type anomolies count.
* @return string Human readable description.
* @access private
*/
function _describeNullDifference($first, $second, $identical) {
return $this->_describeGenericDifference($first, $second);
}
/**
* Creates a human readable description of the
* difference between a boolean and another variable.
* @param boolean $first First boolean.
* @param mixed $second Boolean to compare with.
* @param boolean $identical If true then type anomolies count.
* @return string Human readable description.
* @access private
*/
function _describeBooleanDifference($first, $second, $identical) {
return $this->_describeGenericDifference($first, $second);
}
/**
* Creates a human readable description of the
* difference between a string and another variable.
* @param string $first First string.
* @param mixed $second String to compare with.
* @param boolean $identical If true then type anomolies count.
* @return string Human readable description.
* @access private
*/
function _describeStringDifference($first, $second, $identical) {
if (is_object($second) || is_array($second)) {
return $this->_describeGenericDifference($first, $second);
}
$position = $this->_stringDiffersAt($first, $second);
$message = "at character $position";
$message .= " with [" .
$this->clipString($first, 200, $position) . "] and [" .
$this->clipString($second, 200, $position) . "]";
return $message;
}
/**
* Creates a human readable description of the
* difference between an integer and another variable.
* @param integer $first First number.
* @param mixed $second Number to compare with.
* @param boolean $identical If true then type anomolies count.
* @return string Human readable description.
* @access private
*/
function _describeIntegerDifference($first, $second, $identical) {
if (is_object($second) || is_array($second)) {
return $this->_describeGenericDifference($first, $second);
}
return "because [" . $this->describeValue($first) .
"] differs from [" .
$this->describeValue($second) . "] by " .
abs($first - $second);
}
/**
* Creates a human readable description of the
* difference between two floating point numbers.
* @param float $first First float.
* @param mixed $second Float to compare with.
* @param boolean $identical If true then type anomolies count.
* @return string Human readable description.
* @access private
*/
function _describeFloatDifference($first, $second, $identical) {
if (is_object($second) || is_array($second)) {
return $this->_describeGenericDifference($first, $second);
}
return "because [" . $this->describeValue($first) .
"] differs from [" .
$this->describeValue($second) . "] by " .
abs($first - $second);
}
/**
* Creates a human readable description of the
* difference between two arrays.
* @param array $first First array.
* @param mixed $second Array to compare with.
* @param boolean $identical If true then type anomolies count.
* @return string Human readable description.
* @access private
*/
function _describeArrayDifference($first, $second, $identical) {
if (! is_array($second)) {
return $this->_describeGenericDifference($first, $second);
}
if (! $this->_isMatchingKeys($first, $second, $identical)) {
return "as key list [" .
implode(", ", array_keys($first)) . "] does not match key list [" .
implode(", ", array_keys($second)) . "]";
}
foreach (array_keys($first) as $key) {
if ($identical && ($first[$key] === $second[$key])) {
continue;
}
if (! $identical && ($first[$key] == $second[$key])) {
continue;
}
return "with member [$key] " . $this->describeDifference(
$first[$key],
$second[$key],
$identical);
}
return "";
}
/**
* Compares two arrays to see if their key lists match.
* For an identical match, the ordering and types of the keys
* is significant.
* @param array $first First array.
* @param array $second Array to compare with.
* @param boolean $identical If true then type anomolies count.
* @return boolean True if matching.
* @access private
*/
function _isMatchingKeys($first, $second, $identical) {
$first_keys = array_keys($first);
$second_keys = array_keys($second);
if ($identical) {
return ($first_keys === $second_keys);
}
sort($first_keys);
sort($second_keys);
return ($first_keys == $second_keys);
}
/**
* Creates a human readable description of the
* difference between a resource and another variable.
* @param resource $first First resource.
* @param mixed $second Resource to compare with.
* @param boolean $identical If true then type anomolies count.
* @return string Human readable description.
* @access private
*/
function _describeResourceDifference($first, $second, $identical) {
return $this->_describeGenericDifference($first, $second);
}
/**
* Creates a human readable description of the
* difference between two objects.
* @param object $first First object.
* @param mixed $second Object to compare with.
* @param boolean $identical If true then type anomolies count.
* @return string Human readable description.
* @access private
*/
function _describeObjectDifference($first, $second, $identical) {
if (! is_object($second)) {
return $this->_describeGenericDifference($first, $second);
}
return $this->_describeArrayDifference(
get_object_vars($first),
get_object_vars($second),
$identical);
}
/**
* Find the first character position that differs
* in two strings by binary chop.
* @param string $first First string.
* @param string $second String to compare with.
* @return integer Position of first differing
* character.
* @access private
*/
function _stringDiffersAt($first, $second) {
if (! $first || ! $second) {
return 0;
}
if (strlen($first) < strlen($second)) {
list($first, $second) = array($second, $first);
}
$position = 0;
$step = strlen($first);
while ($step > 1) {
$step = (integer)(($step + 1) / 2);
if (strncmp($first, $second, $position + $step) == 0) {
$position += $step;
}
}
return $position;
}
/**
* Sends a formatted dump of a variable to a string.
* @param mixed $variable Variable to display.
* @return string Output from print_r().
* @access public
* @static
*/
function dump($variable) {
ob_start();
print_r($variable);
$formatted = ob_get_contents();
ob_end_clean();
return $formatted;
}
}
?>

View file

@ -1,307 +0,0 @@
<?php
/**
* base include file for eclipse plugin
* @package SimpleTest
* @subpackage Eclipse
* @version $Id: eclipse.php 1723 2008-04-08 00:34:10Z lastcraft $
*/
/**#@+
* simpletest include files
*/
include_once 'unit_tester.php';
include_once 'test_case.php';
include_once 'invoker.php';
include_once 'socket.php';
include_once 'mock_objects.php';
/**#@-*/
/**
* base reported class for eclipse plugin
* @package SimpleTest
* @subpackage Eclipse
*/
class EclipseReporter extends SimpleScorer {
/**
* Reporter to be run inside of Eclipse interface.
* @param object $listener Eclipse listener (?).
* @param boolean $cc Whether to include test coverage.
*/
function EclipseReporter(&$listener, $cc=false){
$this->_listener = &$listener;
$this->SimpleScorer();
$this->_case = "";
$this->_group = "";
$this->_method = "";
$this->_cc = $cc;
$this->_error = false;
$this->_fail = false;
}
/**
* Means to display human readable object comparisons.
* @return SimpleDumper Visual comparer.
*/
function getDumper() {
return new SimpleDumper();
}
/**
* Localhost connection from Eclipse.
* @param integer $port Port to connect to Eclipse.
* @param string $host Normally localhost.
* @return SimpleSocket Connection to Eclipse.
*/
function &createListener($port, $host="127.0.0.1"){
$tmplistener = &new SimpleSocket($host, $port, 5);
return $tmplistener;
}
/**
* Wraps the test in an output buffer.
* @param SimpleInvoker $invoker Current test runner.
* @return EclipseInvoker Decorator with output buffering.
* @access public
*/
function &createInvoker(&$invoker){
$eclinvoker = &new EclipseInvoker($invoker, $this->_listener);
return $eclinvoker;
}
/**
* C style escaping.
* @param string $raw String with backslashes, quotes and whitespace.
* @return string Replaced with C backslashed tokens.
*/
function escapeVal($raw){
$needle = array("\\","\"","/","\b","\f","\n","\r","\t");
$replace = array('\\\\','\"','\/','\b','\f','\n','\r','\t');
return str_replace($needle, $replace, $raw);
}
/**
* Stash the first passing item. Clicking the test
* item goes to first pass.
* @param string $message Test message, but we only wnat the first.
* @access public
*/
function paintPass($message){
if (! $this->_pass){
$this->_message = $this->escapeVal($message);
}
$this->_pass = true;
}
/**
* Stash the first failing item. Clicking the test
* item goes to first fail.
* @param string $message Test message, but we only wnat the first.
* @access public
*/
function paintFail($message){
//only get the first failure or error
if (! $this->_fail && ! $this->_error){
$this->_fail = true;
$this->_message = $this->escapeVal($message);
$this->_listener->write('{status:"fail",message:"'.$this->_message.'",group:"'.$this->_group.'",case:"'.$this->_case.'",method:"'.$this->_method.'"}');
}
}
/**
* Stash the first error. Clicking the test
* item goes to first error.
* @param string $message Test message, but we only wnat the first.
* @access public
*/
function paintError($message){
if (! $this->_fail && ! $this->_error){
$this->_error = true;
$this->_message = $this->escapeVal($message);
$this->_listener->write('{status:"error",message:"'.$this->_message.'",group:"'.$this->_group.'",case:"'.$this->_case.'",method:"'.$this->_method.'"}');
}
}
/**
* Stash the first exception. Clicking the test
* item goes to first message.
* @param string $message Test message, but we only wnat the first.
* @access public
*/
function paintException($exception){
if (! $this->_fail && ! $this->_error){
$this->_error = true;
$message = 'Unexpected exception of type[' . get_class($exception) .
'] with message [' . $exception->getMessage() . '] in [' .
$exception->getFile() .' line '. $exception->getLine() . ']';
$this->_message = $this->escapeVal($message);
$this->_listener->write(
'{status:"error",message:"' . $this->_message . '",group:"' .
$this->_group . '",case:"' . $this->_case . '",method:"' . $this->_method
. '"}');
}
}
/**
* We don't display any special header.
* @param string $test_name First test top level
* to start.
* @access public
*/
function paintHeader($test_name) {
}
/**
* We don't display any special footer.
* @param string $test_name The top level test.
* @access public
*/
function paintFooter($test_name) {
}
/**
* Paints nothing at the start of a test method, but stash
* the method name for later.
* @param string $test_name Name of test that is starting.
* @access public
*/
function paintMethodStart($method) {
$this->_pass = false;
$this->_fail = false;
$this->_error = false;
$this->_method = $this->escapeVal($method);
}
/**
* Only send one message if the test passes, after that
* suppress the message.
* @param string $test_name Name of test that is ending.
* @access public
*/
function paintMethodEnd($method){
if ($this->_fail || $this->_error || ! $this->_pass){
} else {
$this->_listener->write(
'{status:"pass",message:"' . $this->_message . '",group:"' .
$this->_group . '",case:"' . $this->_case . '",method:"' .
$this->_method . '"}');
}
}
/**
* Stashes the test case name for the later failure message.
* @param string $test_name Name of test or other label.
* @access public
*/
function paintCaseStart($case){
$this->_case = $this->escapeVal($case);
}
/**
* Drops the name.
* @param string $test_name Name of test or other label.
* @access public
*/
function paintCaseEnd($case){
$this->_case = "";
}
/**
* Stashes the name of the test suite. Starts test coverage
* if enabled.
* @param string $group Name of test or other label.
* @param integer $size Number of test cases starting.
* @access public
*/
function paintGroupStart($group, $size){
$this->_group = $this->escapeVal($group);
if ($this->_cc){
if (extension_loaded('xdebug')){
xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);
}
}
}
/**
* Paints coverage report if enabled.
* @param string $group Name of test or other label.
* @access public
*/
function paintGroupEnd($group){
$this->_group = "";
$cc = "";
if ($this->_cc){
if (extension_loaded('xdebug')){
$arrfiles = xdebug_get_code_coverage();
xdebug_stop_code_coverage();
$thisdir = dirname(__FILE__);
$thisdirlen = strlen($thisdir);
foreach ($arrfiles as $index=>$file){
if (substr($index, 0, $thisdirlen)===$thisdir){
continue;
}
$lcnt = 0;
$ccnt = 0;
foreach ($file as $line){
if ($line == -2){
continue;
}
$lcnt++;
if ($line==1){
$ccnt++;
}
}
if ($lcnt > 0){
$cc .= round(($ccnt/$lcnt) * 100, 2) . '%';
}else{
$cc .= "0.00%";
}
$cc.= "\t". $index . "\n";
}
}
}
$this->_listener->write('{status:"coverage",message:"' .
EclipseReporter::escapeVal($cc) . '"}');
}
}
/**
* Invoker decorator for Eclipse. Captures output until
* the end of the test.
* @package SimpleTest
* @subpackage Eclipse
*/
class EclipseInvoker extends SimpleInvokerDecorator{
function EclipseInvoker(&$invoker, &$listener) {
$this->_listener = &$listener;
$this->SimpleInvokerDecorator($invoker);
}
/**
* Starts output buffering.
* @param string $method Test method to call.
* @access public
*/
function before($method){
ob_start();
$this->_invoker->before($method);
}
/**
* Stops output buffering and send the captured output
* to the listener.
* @param string $method Test method to call.
* @access public
*/
function after($method) {
$this->_invoker->after($method);
$output = ob_get_contents();
ob_end_clean();
if ($output !== ""){
$result = $this->_listener->write('{status:"info",message:"' .
EclipseReporter::escapeVal($output) . '"}');
}
}
}
?>

View file

@ -1,552 +0,0 @@
<?php
/**
* base include file for SimpleTest
* @package SimpleTest
* @subpackage WebTester
* @version $Id: encoding.php 1723 2008-04-08 00:34:10Z lastcraft $
*/
/**#@+
* include other SimpleTest class files
*/
require_once(dirname(__FILE__) . '/socket.php');
/**#@-*/
/**
* Single post parameter.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleEncodedPair {
var $_key;
var $_value;
/**
* Stashes the data for rendering later.
* @param string $key Form element name.
* @param string $value Data to send.
*/
function SimpleEncodedPair($key, $value) {
$this->_key = $key;
$this->_value = $value;
}
/**
* The pair as a single string.
* @return string Encoded pair.
* @access public
*/
function asRequest() {
return urlencode($this->_key) . '=' . urlencode($this->_value);
}
/**
* The MIME part as a string.
* @return string MIME part encoding.
* @access public
*/
function asMime() {
$part = 'Content-Disposition: form-data; ';
$part .= "name=\"" . $this->_key . "\"\r\n";
$part .= "\r\n" . $this->_value;
return $part;
}
/**
* Is this the value we are looking for?
* @param string $key Identifier.
* @return boolean True if matched.
* @access public
*/
function isKey($key) {
return $key == $this->_key;
}
/**
* Is this the value we are looking for?
* @return string Identifier.
* @access public
*/
function getKey() {
return $this->_key;
}
/**
* Is this the value we are looking for?
* @return string Content.
* @access public
*/
function getValue() {
return $this->_value;
}
}
/**
* Single post parameter.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleAttachment {
var $_key;
var $_content;
var $_filename;
/**
* Stashes the data for rendering later.
* @param string $key Key to add value to.
* @param string $content Raw data.
* @param hash $filename Original filename.
*/
function SimpleAttachment($key, $content, $filename) {
$this->_key = $key;
$this->_content = $content;
$this->_filename = $filename;
}
/**
* The pair as a single string.
* @return string Encoded pair.
* @access public
*/
function asRequest() {
return '';
}
/**
* The MIME part as a string.
* @return string MIME part encoding.
* @access public
*/
function asMime() {
$part = 'Content-Disposition: form-data; ';
$part .= 'name="' . $this->_key . '"; ';
$part .= 'filename="' . $this->_filename . '"';
$part .= "\r\nContent-Type: " . $this->_deduceMimeType();
$part .= "\r\n\r\n" . $this->_content;
return $part;
}
/**
* Attempts to figure out the MIME type from the
* file extension and the content.
* @return string MIME type.
* @access private
*/
function _deduceMimeType() {
if ($this->_isOnlyAscii($this->_content)) {
return 'text/plain';
}
return 'application/octet-stream';
}
/**
* Tests each character is in the range 0-127.
* @param string $ascii String to test.
* @access private
*/
function _isOnlyAscii($ascii) {
for ($i = 0, $length = strlen($ascii); $i < $length; $i++) {
if (ord($ascii[$i]) > 127) {
return false;
}
}
return true;
}
/**
* Is this the value we are looking for?
* @param string $key Identifier.
* @return boolean True if matched.
* @access public
*/
function isKey($key) {
return $key == $this->_key;
}
/**
* Is this the value we are looking for?
* @return string Identifier.
* @access public
*/
function getKey() {
return $this->_key;
}
/**
* Is this the value we are looking for?
* @return string Content.
* @access public
*/
function getValue() {
return $this->_filename;
}
}
/**
* Bundle of GET/POST parameters. Can include
* repeated parameters.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleEncoding {
var $_request;
/**
* Starts empty.
* @param array $query Hash of parameters.
* Multiple values are
* as lists on a single key.
* @access public
*/
function SimpleEncoding($query = false) {
if (! $query) {
$query = array();
}
$this->clear();
$this->merge($query);
}
/**
* Empties the request of parameters.
* @access public
*/
function clear() {
$this->_request = array();
}
/**
* Adds a parameter to the query.
* @param string $key Key to add value to.
* @param string/array $value New data.
* @access public
*/
function add($key, $value) {
if ($value === false) {
return;
}
if (is_array($value)) {
foreach ($value as $item) {
$this->_addPair($key, $item);
}
} else {
$this->_addPair($key, $value);
}
}
/**
* Adds a new value into the request.
* @param string $key Key to add value to.
* @param string/array $value New data.
* @access private
*/
function _addPair($key, $value) {
$this->_request[] = new SimpleEncodedPair($key, $value);
}
/**
* Adds a MIME part to the query. Does nothing for a
* form encoded packet.
* @param string $key Key to add value to.
* @param string $content Raw data.
* @param hash $filename Original filename.
* @access public
*/
function attach($key, $content, $filename) {
$this->_request[] = new SimpleAttachment($key, $content, $filename);
}
/**
* Adds a set of parameters to this query.
* @param array/SimpleQueryString $query Multiple values are
* as lists on a single key.
* @access public
*/
function merge($query) {
if (is_object($query)) {
$this->_request = array_merge($this->_request, $query->getAll());
} elseif (is_array($query)) {
foreach ($query as $key => $value) {
$this->add($key, $value);
}
}
}
/**
* Accessor for single value.
* @return string/array False if missing, string
* if present and array if
* multiple entries.
* @access public
*/
function getValue($key) {
$values = array();
foreach ($this->_request as $pair) {
if ($pair->isKey($key)) {
$values[] = $pair->getValue();
}
}
if (count($values) == 0) {
return false;
} elseif (count($values) == 1) {
return $values[0];
} else {
return $values;
}
}
/**
* Accessor for listing of pairs.
* @return array All pair objects.
* @access public
*/
function getAll() {
return $this->_request;
}
/**
* Renders the query string as a URL encoded
* request part.
* @return string Part of URL.
* @access protected
*/
function _encode() {
$statements = array();
foreach ($this->_request as $pair) {
if ($statement = $pair->asRequest()) {
$statements[] = $statement;
}
}
return implode('&', $statements);
}
}
/**
* Bundle of GET parameters. Can include
* repeated parameters.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleGetEncoding extends SimpleEncoding {
/**
* Starts empty.
* @param array $query Hash of parameters.
* Multiple values are
* as lists on a single key.
* @access public
*/
function SimpleGetEncoding($query = false) {
$this->SimpleEncoding($query);
}
/**
* HTTP request method.
* @return string Always GET.
* @access public
*/
function getMethod() {
return 'GET';
}
/**
* Writes no extra headers.
* @param SimpleSocket $socket Socket to write to.
* @access public
*/
function writeHeadersTo(&$socket) {
}
/**
* No data is sent to the socket as the data is encoded into
* the URL.
* @param SimpleSocket $socket Socket to write to.
* @access public
*/
function writeTo(&$socket) {
}
/**
* Renders the query string as a URL encoded
* request part for attaching to a URL.
* @return string Part of URL.
* @access public
*/
function asUrlRequest() {
return $this->_encode();
}
}
/**
* Bundle of URL parameters for a HEAD request.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleHeadEncoding extends SimpleGetEncoding {
/**
* Starts empty.
* @param array $query Hash of parameters.
* Multiple values are
* as lists on a single key.
* @access public
*/
function SimpleHeadEncoding($query = false) {
$this->SimpleGetEncoding($query);
}
/**
* HTTP request method.
* @return string Always HEAD.
* @access public
*/
function getMethod() {
return 'HEAD';
}
}
/**
* Bundle of POST parameters. Can include
* repeated parameters.
* @package SimpleTest
* @subpackage WebTester
*/
class SimplePostEncoding extends SimpleEncoding {
/**
* Starts empty.
* @param array $query Hash of parameters.
* Multiple values are
* as lists on a single key.
* @access public
*/
function SimplePostEncoding($query = false) {
if (is_array($query) and $this->hasMoreThanOneLevel($query)) {
$query = $this->rewriteArrayWithMultipleLevels($query);
}
$this->SimpleEncoding($query);
}
function hasMoreThanOneLevel($query) {
foreach ($query as $key => $value) {
if (is_array($value)) {
return true;
}
}
return false;
}
function rewriteArrayWithMultipleLevels($query) {
$query_ = array();
foreach ($query as $key => $value) {
if (is_array($value)) {
foreach ($value as $sub_key => $sub_value) {
$query_[$key."[".$sub_key."]"] = $sub_value;
}
} else {
$query_[$key] = $value;
}
}
if ($this->hasMoreThanOneLevel($query_)) {
$query_ = $this->rewriteArrayWithMultipleLevels($query_);
}
return $query_;
}
/**
* HTTP request method.
* @return string Always POST.
* @access public
*/
function getMethod() {
return 'POST';
}
/**
* Dispatches the form headers down the socket.
* @param SimpleSocket $socket Socket to write to.
* @access public
*/
function writeHeadersTo(&$socket) {
$socket->write("Content-Length: " . (integer)strlen($this->_encode()) . "\r\n");
$socket->write("Content-Type: application/x-www-form-urlencoded\r\n");
}
/**
* Dispatches the form data down the socket.
* @param SimpleSocket $socket Socket to write to.
* @access public
*/
function writeTo(&$socket) {
$socket->write($this->_encode());
}
/**
* Renders the query string as a URL encoded
* request part for attaching to a URL.
* @return string Part of URL.
* @access public
*/
function asUrlRequest() {
return '';
}
}
/**
* Bundle of POST parameters in the multipart
* format. Can include file uploads.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleMultipartEncoding extends SimplePostEncoding {
var $_boundary;
/**
* Starts empty.
* @param array $query Hash of parameters.
* Multiple values are
* as lists on a single key.
* @access public
*/
function SimpleMultipartEncoding($query = false, $boundary = false) {
$this->SimplePostEncoding($query);
$this->_boundary = ($boundary === false ? uniqid('st') : $boundary);
}
/**
* Dispatches the form headers down the socket.
* @param SimpleSocket $socket Socket to write to.
* @access public
*/
function writeHeadersTo(&$socket) {
$socket->write("Content-Length: " . (integer)strlen($this->_encode()) . "\r\n");
$socket->write("Content-Type: multipart/form-data, boundary=" . $this->_boundary . "\r\n");
}
/**
* Dispatches the form data down the socket.
* @param SimpleSocket $socket Socket to write to.
* @access public
*/
function writeTo(&$socket) {
$socket->write($this->_encode());
}
/**
* Renders the query string as a URL encoded
* request part.
* @return string Part of URL.
* @access public
*/
function _encode() {
$stream = '';
foreach ($this->_request as $pair) {
$stream .= "--" . $this->_boundary . "\r\n";
$stream .= $pair->asMime() . "\r\n";
}
$stream .= "--" . $this->_boundary . "--\r\n";
return $stream;
}
}
?>

View file

@ -1,288 +0,0 @@
<?php
/**
* base include file for SimpleTest
* @package SimpleTest
* @subpackage UnitTester
* @version $Id: errors.php 1672 2008-03-02 04:47:34Z edwardzyang $
*/
/**
* @ignore - PHP5 compatibility fix.
*/
if (! defined('E_STRICT')) {
define('E_STRICT', 2048);
}
/**#@+
* Includes SimpleTest files.
*/
require_once dirname(__FILE__) . '/invoker.php';
require_once dirname(__FILE__) . '/test_case.php';
require_once dirname(__FILE__) . '/expectation.php';
/**#@-*/
/**
* Extension that traps errors into an error queue.
* @package SimpleTest
* @subpackage UnitTester
*/
class SimpleErrorTrappingInvoker extends SimpleInvokerDecorator {
/**
* Stores the invoker to wrap.
* @param SimpleInvoker $invoker Test method runner.
*/
function SimpleErrorTrappingInvoker(&$invoker) {
$this->SimpleInvokerDecorator($invoker);
}
/**
* Invokes a test method and dispatches any
* untrapped errors. Called back from
* the visiting runner.
* @param string $method Test method to call.
* @access public
*/
function invoke($method) {
$queue = &$this->_createErrorQueue();
set_error_handler('SimpleTestErrorHandler');
parent::invoke($method);
restore_error_handler();
$queue->tally();
}
/**
* Wires up the error queue for a single test.
* @return SimpleErrorQueue Queue connected to the test.
* @access private
*/
function &_createErrorQueue() {
$context = &SimpleTest::getContext();
$test = &$this->getTestCase();
$queue = &$context->get('SimpleErrorQueue');
$queue->setTestCase($test);
return $queue;
}
}
/**
* Error queue used to record trapped
* errors.
* @package SimpleTest
* @subpackage UnitTester
*/
class SimpleErrorQueue {
var $_queue;
var $_expectation_queue;
var $_test;
var $_using_expect_style = false;
/**
* Starts with an empty queue.
*/
function SimpleErrorQueue() {
$this->clear();
}
/**
* Discards the contents of the error queue.
* @access public
*/
function clear() {
$this->_queue = array();
$this->_expectation_queue = array();
}
/**
* Sets the currently running test case.
* @param SimpleTestCase $test Test case to send messages to.
* @access public
*/
function setTestCase(&$test) {
$this->_test = &$test;
}
/**
* Sets up an expectation of an error. If this is
* not fulfilled at the end of the test, a failure
* will occour. If the error does happen, then this
* will cancel it out and send a pass message.
* @param SimpleExpectation $expected Expected error match.
* @param string $message Message to display.
* @access public
*/
function expectError($expected, $message) {
$this->_using_expect_style = true;
array_push($this->_expectation_queue, array($expected, $message));
}
/**
* Adds an error to the front of the queue.
* @param integer $severity PHP error code.
* @param string $content Text of error.
* @param string $filename File error occoured in.
* @param integer $line Line number of error.
* @access public
*/
function add($severity, $content, $filename, $line) {
$content = str_replace('%', '%%', $content);
if ($this->_using_expect_style) {
$this->_testLatestError($severity, $content, $filename, $line);
} else {
array_push(
$this->_queue,
array($severity, $content, $filename, $line));
}
}
/**
* Any errors still in the queue are sent to the test
* case. Any unfulfilled expectations trigger failures.
* @access public
*/
function tally() {
while (list($severity, $message, $file, $line) = $this->extract()) {
$severity = $this->getSeverityAsString($severity);
$this->_test->error($severity, $message, $file, $line);
}
while (list($expected, $message) = $this->_extractExpectation()) {
$this->_test->assert($expected, false, "%s -> Expected error not caught");
}
}
/**
* Tests the error against the most recent expected
* error.
* @param integer $severity PHP error code.
* @param string $content Text of error.
* @param string $filename File error occoured in.
* @param integer $line Line number of error.
* @access private
*/
function _testLatestError($severity, $content, $filename, $line) {
if ($expectation = $this->_extractExpectation()) {
list($expected, $message) = $expectation;
$this->_test->assert($expected, $content, sprintf(
$message,
"%s -> PHP error [$content] severity [" .
$this->getSeverityAsString($severity) .
"] in [$filename] line [$line]"));
} else {
$this->_test->error($severity, $content, $filename, $line);
}
}
/**
* Pulls the earliest error from the queue.
* @return mixed False if none, or a list of error
* information. Elements are: severity
* as the PHP error code, the error message,
* the file with the error, the line number
* and a list of PHP super global arrays.
* @access public
*/
function extract() {
if (count($this->_queue)) {
return array_shift($this->_queue);
}
return false;
}
/**
* Pulls the earliest expectation from the queue.
* @return SimpleExpectation False if none.
* @access private
*/
function _extractExpectation() {
if (count($this->_expectation_queue)) {
return array_shift($this->_expectation_queue);
}
return false;
}
/**
* @deprecated
*/
function assertNoErrors($message) {
return $this->_test->assert(
new TrueExpectation(),
count($this->_queue) == 0,
sprintf($message, 'Should be no errors'));
}
/**
* @deprecated
*/
function assertError($expected, $message) {
if (count($this->_queue) == 0) {
$this->_test->fail(sprintf($message, 'Expected error not found'));
return false;
}
list($severity, $content, $file, $line) = $this->extract();
$severity = $this->getSeverityAsString($severity);
return $this->_test->assert(
$expected,
$content,
sprintf($message, "Expected PHP error [$content] severity [$severity] in [$file] line [$line]"));
}
/**
* Converts an error code into it's string
* representation.
* @param $severity PHP integer error code.
* @return String version of error code.
* @access public
* @static
*/
function getSeverityAsString($severity) {
static $map = array(
E_STRICT => 'E_STRICT',
E_ERROR => 'E_ERROR',
E_WARNING => 'E_WARNING',
E_PARSE => 'E_PARSE',
E_NOTICE => 'E_NOTICE',
E_CORE_ERROR => 'E_CORE_ERROR',
E_CORE_WARNING => 'E_CORE_WARNING',
E_COMPILE_ERROR => 'E_COMPILE_ERROR',
E_COMPILE_WARNING => 'E_COMPILE_WARNING',
E_USER_ERROR => 'E_USER_ERROR',
E_USER_WARNING => 'E_USER_WARNING',
E_USER_NOTICE => 'E_USER_NOTICE');
if (defined('E_RECOVERABLE_ERROR')) {
$map[E_RECOVERABLE_ERROR] = 'E_RECOVERABLE_ERROR';
}
if (defined('E_DEPRECATED')) {
$map[E_DEPRECATED] = 'E_DEPRECATED';
}
return $map[$severity];
}
}
/**
* Error handler that simply stashes any errors into the global
* error queue. Simulates the existing behaviour with respect to
* logging errors, but this feature may be removed in future.
* @param $severity PHP error code.
* @param $message Text of error.
* @param $filename File error occoured in.
* @param $line Line number of error.
* @param $super_globals Hash of PHP super global arrays.
* @static
* @access public
*/
function SimpleTestErrorHandler($severity, $message, $filename = null, $line = null, $super_globals = null, $mask = null) {
$severity = $severity & error_reporting();
if ($severity) {
restore_error_handler();
if (ini_get('log_errors')) {
$label = SimpleErrorQueue::getSeverityAsString($severity);
error_log("$label: $message in $filename on line $line");
}
$context = &SimpleTest::getContext();
$queue = &$context->get('SimpleErrorQueue');
$queue->add($severity, $message, $filename, $line);
set_error_handler('SimpleTestErrorHandler');
}
return true;
}
?>

View file

@ -1,198 +0,0 @@
<?php
/**
* base include file for SimpleTest
* @package SimpleTest
* @subpackage UnitTester
* @version $Id: exceptions.php 1672 2008-03-02 04:47:34Z edwardzyang $
*/
/**#@+
* Include required SimpleTest files
*/
require_once dirname(__FILE__) . '/invoker.php';
require_once dirname(__FILE__) . '/expectation.php';
/**#@-*/
/**
* Extension that traps exceptions and turns them into
* an error message. PHP5 only.
* @package SimpleTest
* @subpackage UnitTester
*/
class SimpleExceptionTrappingInvoker extends SimpleInvokerDecorator {
/**
* Stores the invoker to be wrapped.
* @param SimpleInvoker $invoker Test method runner.
*/
function SimpleExceptionTrappingInvoker($invoker) {
$this->SimpleInvokerDecorator($invoker);
}
/**
* Invokes a test method whilst trapping expected
* exceptions. Any left over unthrown exceptions
* are then reported as failures.
* @param string $method Test method to call.
*/
function invoke($method) {
$trap = SimpleTest::getContext()->get('SimpleExceptionTrap');
$trap->clear();
try {
$has_thrown = false;
parent::invoke($method);
} catch (Exception $exception) {
$has_thrown = true;
if (! $trap->isExpected($this->getTestCase(), $exception)) {
$this->getTestCase()->exception($exception);
}
$trap->clear();
}
if ($message = $trap->getOutstanding()) {
$this->getTestCase()->fail($message);
}
if ($has_thrown) {
try {
parent::getTestCase()->tearDown();
} catch (Exception $e) { }
}
}
}
/**
* Tests exceptions either by type or the exact
* exception. This could be improved to accept
* a pattern expectation to test the error
* message, but that will have to come later.
* @package SimpleTest
* @subpackage UnitTester
*/
class ExceptionExpectation extends SimpleExpectation {
private $expected;
/**
* Sets up the conditions to test against.
* If the expected value is a string, then
* it will act as a test of the class name.
* An exception as the comparison will
* trigger an identical match. Writing this
* down now makes it look doubly dumb. I hope
* come up with a better scheme later.
* @param mixed $expected A class name or an actual
* exception to compare with.
* @param string $message Message to display.
*/
function __construct($expected, $message = '%s') {
$this->expected = $expected;
parent::__construct($message);
}
/**
* Carry out the test.
* @param Exception $compare Value to check.
* @return boolean True if matched.
*/
function test($compare) {
if (is_string($this->expected)) {
return ($compare instanceof $this->expected);
}
if (get_class($compare) != get_class($this->expected)) {
return false;
}
return $compare->getMessage() == $this->expected->getMessage();
}
/**
* Create the message to display describing the test.
* @param Exception $compare Exception to match.
* @return string Final message.
*/
function testMessage($compare) {
if (is_string($this->expected)) {
return "Exception [" . $this->describeException($compare) .
"] should be type [" . $this->expected . "]";
}
return "Exception [" . $this->describeException($compare) .
"] should match [" .
$this->describeException($this->expected) . "]";
}
/**
* Summary of an Exception object.
* @param Exception $compare Exception to describe.
* @return string Text description.
*/
protected function describeException($exception) {
return get_class($exception) . ": " . $exception->getMessage();
}
}
/**
* Stores expected exceptions for when they
* get thrown. Saves the irritating try...catch
* block.
* @package SimpleTest
* @subpackage UnitTester
*/
class SimpleExceptionTrap {
private $expected;
private $message;
/**
* Clears down the queue ready for action.
*/
function __construct() {
$this->clear();
}
/**
* Sets up an expectation of an exception.
* This has the effect of intercepting an
* exception that matches.
* @param SimpleExpectation $expected Expected exception to match.
* @param string $message Message to display.
* @access public
*/
function expectException($expected = false, $message = '%s') {
if ($expected === false) {
$expected = new AnythingExpectation();
}
if (! SimpleExpectation::isExpectation($expected)) {
$expected = new ExceptionExpectation($expected);
}
$this->expected = $expected;
$this->message = $message;
}
/**
* Compares the expected exception with any
* in the queue. Issues a pass or fail and
* returns the state of the test.
* @param SimpleTestCase $test Test case to send messages to.
* @param Exception $exception Exception to compare.
* @return boolean False on no match.
*/
function isExpected($test, $exception) {
if ($this->expected) {
return $test->assert($this->expected, $exception, $this->message);
}
return false;
}
/**
* Tests for any left over exception.
* @return string/false The failure message or false if none.
*/
function getOutstanding() {
return sprintf($this->message, 'Failed to trap exception');
}
/**
* Discards the contents of the error queue.
*/
function clear() {
$this->expected = false;
$this->message = false;
}
}
?>

View file

@ -1,895 +0,0 @@
<?php
/**
* base include file for SimpleTest
* @package SimpleTest
* @subpackage UnitTester
* @version $Id: expectation.php 1723 2008-04-08 00:34:10Z lastcraft $
*/
/**#@+
* include other SimpleTest class files
*/
require_once(dirname(__FILE__) . '/dumper.php');
require_once(dirname(__FILE__) . '/compatibility.php');
/**#@-*/
/**
* Assertion that can display failure information.
* Also includes various helper methods.
* @package SimpleTest
* @subpackage UnitTester
* @abstract
*/
class SimpleExpectation {
var $_dumper = false;
var $_message;
/**
* Creates a dumper for displaying values and sets
* the test message.
* @param string $message Customised message on failure.
*/
function SimpleExpectation($message = '%s') {
$this->_message = $message;
}
/**
* Tests the expectation. True if correct.
* @param mixed $compare Comparison value.
* @return boolean True if correct.
* @access public
* @abstract
*/
function test($compare) {
}
/**
* Returns a human readable test message.
* @param mixed $compare Comparison value.
* @return string Description of success
* or failure.
* @access public
* @abstract
*/
function testMessage($compare) {
}
/**
* Overlays the generated message onto the stored user
* message. An additional message can be interjected.
* @param mixed $compare Comparison value.
* @param SimpleDumper $dumper For formatting the results.
* @return string Description of success
* or failure.
* @access public
*/
function overlayMessage($compare, $dumper) {
$this->_dumper = $dumper;
return sprintf($this->_message, $this->testMessage($compare));
}
/**
* Accessor for the dumper.
* @return SimpleDumper Current value dumper.
* @access protected
*/
function &_getDumper() {
if (! $this->_dumper) {
$dumper = &new SimpleDumper();
return $dumper;
}
return $this->_dumper;
}
/**
* Test to see if a value is an expectation object.
* A useful utility method.
* @param mixed $expectation Hopefully an Epectation
* class.
* @return boolean True if descended from
* this class.
* @access public
* @static
*/
function isExpectation($expectation) {
return is_object($expectation) &&
SimpleTestCompatibility::isA($expectation, 'SimpleExpectation');
}
}
/**
* A wildcard expectation always matches.
* @package SimpleTest
* @subpackage MockObjects
*/
class AnythingExpectation extends SimpleExpectation {
/**
* Tests the expectation. Always true.
* @param mixed $compare Ignored.
* @return boolean True.
* @access public
*/
function test($compare) {
return true;
}
/**
* Returns a human readable test message.
* @param mixed $compare Comparison value.
* @return string Description of success
* or failure.
* @access public
*/
function testMessage($compare) {
$dumper = &$this->_getDumper();
return 'Anything always matches [' . $dumper->describeValue($compare) . ']';
}
}
/**
* An expectation that never matches.
* @package SimpleTest
* @subpackage MockObjects
*/
class FailedExpectation extends SimpleExpectation {
/**
* Tests the expectation. Always false.
* @param mixed $compare Ignored.
* @return boolean True.
* @access public
*/
function test($compare) {
return false;
}
/**
* Returns a human readable test message.
* @param mixed $compare Comparison value.
* @return string Description of failure.
* @access public
*/
function testMessage($compare) {
$dumper = &$this->_getDumper();
return 'Failed expectation never matches [' . $dumper->describeValue($compare) . ']';
}
}
/**
* An expectation that passes on boolean true.
* @package SimpleTest
* @subpackage MockObjects
*/
class TrueExpectation extends SimpleExpectation {
/**
* Tests the expectation.
* @param mixed $compare Should be true.
* @return boolean True on match.
* @access public
*/
function test($compare) {
return (boolean)$compare;
}
/**
* Returns a human readable test message.
* @param mixed $compare Comparison value.
* @return string Description of success
* or failure.
* @access public
*/
function testMessage($compare) {
$dumper = &$this->_getDumper();
return 'Expected true, got [' . $dumper->describeValue($compare) . ']';
}
}
/**
* An expectation that passes on boolean false.
* @package SimpleTest
* @subpackage MockObjects
*/
class FalseExpectation extends SimpleExpectation {
/**
* Tests the expectation.
* @param mixed $compare Should be false.
* @return boolean True on match.
* @access public
*/
function test($compare) {
return ! (boolean)$compare;
}
/**
* Returns a human readable test message.
* @param mixed $compare Comparison value.
* @return string Description of success
* or failure.
* @access public
*/
function testMessage($compare) {
$dumper = &$this->_getDumper();
return 'Expected false, got [' . $dumper->describeValue($compare) . ']';
}
}
/**
* Test for equality.
* @package SimpleTest
* @subpackage UnitTester
*/
class EqualExpectation extends SimpleExpectation {
var $_value;
/**
* Sets the value to compare against.
* @param mixed $value Test value to match.
* @param string $message Customised message on failure.
* @access public
*/
function EqualExpectation($value, $message = '%s') {
$this->SimpleExpectation($message);
$this->_value = $value;
}
/**
* Tests the expectation. True if it matches the
* held value.
* @param mixed $compare Comparison value.
* @return boolean True if correct.
* @access public
*/
function test($compare) {
return (($this->_value == $compare) && ($compare == $this->_value));
}
/**
* Returns a human readable test message.
* @param mixed $compare Comparison value.
* @return string Description of success
* or failure.
* @access public
*/
function testMessage($compare) {
if ($this->test($compare)) {
return "Equal expectation [" . $this->_dumper->describeValue($this->_value) . "]";
} else {
return "Equal expectation fails " .
$this->_dumper->describeDifference($this->_value, $compare);
}
}
/**
* Accessor for comparison value.
* @return mixed Held value to compare with.
* @access protected
*/
function _getValue() {
return $this->_value;
}
}
/**
* Test for inequality.
* @package SimpleTest
* @subpackage UnitTester
*/
class NotEqualExpectation extends EqualExpectation {
/**
* Sets the value to compare against.
* @param mixed $value Test value to match.
* @param string $message Customised message on failure.
* @access public
*/
function NotEqualExpectation($value, $message = '%s') {
$this->EqualExpectation($value, $message);
}
/**
* Tests the expectation. True if it differs from the
* held value.
* @param mixed $compare Comparison value.
* @return boolean True if correct.
* @access public
*/
function test($compare) {
return ! parent::test($compare);
}
/**
* Returns a human readable test message.
* @param mixed $compare Comparison value.
* @return string Description of success
* or failure.
* @access public
*/
function testMessage($compare) {
$dumper = &$this->_getDumper();
if ($this->test($compare)) {
return "Not equal expectation passes " .
$dumper->describeDifference($this->_getValue(), $compare);
} else {
return "Not equal expectation fails [" .
$dumper->describeValue($this->_getValue()) .
"] matches";
}
}
}
/**
* Test for being within a range.
* @package SimpleTest
* @subpackage UnitTester
*/
class WithinMarginExpectation extends SimpleExpectation {
var $_upper;
var $_lower;
/**
* Sets the value to compare against and the fuzziness of
* the match. Used for comparing floating point values.
* @param mixed $value Test value to match.
* @param mixed $margin Fuzziness of match.
* @param string $message Customised message on failure.
* @access public
*/
function WithinMarginExpectation($value, $margin, $message = '%s') {
$this->SimpleExpectation($message);
$this->_upper = $value + $margin;
$this->_lower = $value - $margin;
}
/**
* Tests the expectation. True if it matches the
* held value.
* @param mixed $compare Comparison value.
* @return boolean True if correct.
* @access public
*/
function test($compare) {
return (($compare <= $this->_upper) && ($compare >= $this->_lower));
}
/**
* Returns a human readable test message.
* @param mixed $compare Comparison value.
* @return string Description of success
* or failure.
* @access public
*/
function testMessage($compare) {
if ($this->test($compare)) {
return $this->_withinMessage($compare);
} else {
return $this->_outsideMessage($compare);
}
}
/**
* Creates a the message for being within the range.
* @param mixed $compare Value being tested.
* @access private
*/
function _withinMessage($compare) {
return "Within expectation [" . $this->_dumper->describeValue($this->_lower) . "] and [" .
$this->_dumper->describeValue($this->_upper) . "]";
}
/**
* Creates a the message for being within the range.
* @param mixed $compare Value being tested.
* @access private
*/
function _outsideMessage($compare) {
if ($compare > $this->_upper) {
return "Outside expectation " .
$this->_dumper->describeDifference($compare, $this->_upper);
} else {
return "Outside expectation " .
$this->_dumper->describeDifference($compare, $this->_lower);
}
}
}
/**
* Test for being outside of a range.
* @package SimpleTest
* @subpackage UnitTester
*/
class OutsideMarginExpectation extends WithinMarginExpectation {
/**
* Sets the value to compare against and the fuzziness of
* the match. Used for comparing floating point values.
* @param mixed $value Test value to not match.
* @param mixed $margin Fuzziness of match.
* @param string $message Customised message on failure.
* @access public
*/
function OutsideMarginExpectation($value, $margin, $message = '%s') {
$this->WithinMarginExpectation($value, $margin, $message);
}
/**
* Tests the expectation. True if it matches the
* held value.
* @param mixed $compare Comparison value.
* @return boolean True if correct.
* @access public
*/
function test($compare) {
return ! parent::test($compare);
}
/**
* Returns a human readable test message.
* @param mixed $compare Comparison value.
* @return string Description of success
* or failure.
* @access public
*/
function testMessage($compare) {
if (! $this->test($compare)) {
return $this->_withinMessage($compare);
} else {
return $this->_outsideMessage($compare);
}
}
}
/**
* Test for reference.
* @package SimpleTest
* @subpackage UnitTester
*/
class ReferenceExpectation extends SimpleExpectation {
var $_value;
/**
* Sets the reference value to compare against.
* @param mixed $value Test reference to match.
* @param string $message Customised message on failure.
* @access public
*/
function ReferenceExpectation(&$value, $message = '%s') {
$this->SimpleExpectation($message);
$this->_value =& $value;
}
/**
* Tests the expectation. True if it exactly
* references the held value.
* @param mixed $compare Comparison reference.
* @return boolean True if correct.
* @access public
*/
function test(&$compare) {
return SimpleTestCompatibility::isReference($this->_value, $compare);
}
/**
* Returns a human readable test message.
* @param mixed $compare Comparison value.
* @return string Description of success
* or failure.
* @access public
*/
function testMessage($compare) {
if ($this->test($compare)) {
return "Reference expectation [" . $this->_dumper->describeValue($this->_value) . "]";
} else {
return "Reference expectation fails " .
$this->_dumper->describeDifference($this->_value, $compare);
}
}
function _getValue() {
return $this->_value;
}
}
/**
* Test for identity.
* @package SimpleTest
* @subpackage UnitTester
*/
class IdenticalExpectation extends EqualExpectation {
/**
* Sets the value to compare against.
* @param mixed $value Test value to match.
* @param string $message Customised message on failure.
* @access public
*/
function IdenticalExpectation($value, $message = '%s') {
$this->EqualExpectation($value, $message);
}
/**
* Tests the expectation. True if it exactly
* matches the held value.
* @param mixed $compare Comparison value.
* @return boolean True if correct.
* @access public
*/
function test($compare) {
return SimpleTestCompatibility::isIdentical($this->_getValue(), $compare);
}
/**
* Returns a human readable test message.
* @param mixed $compare Comparison value.
* @return string Description of success
* or failure.
* @access public
*/
function testMessage($compare) {
$dumper = &$this->_getDumper();
if ($this->test($compare)) {
return "Identical expectation [" . $dumper->describeValue($this->_getValue()) . "]";
} else {
return "Identical expectation [" . $dumper->describeValue($this->_getValue()) .
"] fails with [" .
$dumper->describeValue($compare) . "] " .
$dumper->describeDifference($this->_getValue(), $compare, TYPE_MATTERS);
}
}
}
/**
* Test for non-identity.
* @package SimpleTest
* @subpackage UnitTester
*/
class NotIdenticalExpectation extends IdenticalExpectation {
/**
* Sets the value to compare against.
* @param mixed $value Test value to match.
* @param string $message Customised message on failure.
* @access public
*/
function NotIdenticalExpectation($value, $message = '%s') {
$this->IdenticalExpectation($value, $message);
}
/**
* Tests the expectation. True if it differs from the
* held value.
* @param mixed $compare Comparison value.
* @return boolean True if correct.
* @access public
*/
function test($compare) {
return ! parent::test($compare);
}
/**
* Returns a human readable test message.
* @param mixed $compare Comparison value.
* @return string Description of success
* or failure.
* @access public
*/
function testMessage($compare) {
$dumper = &$this->_getDumper();
if ($this->test($compare)) {
return "Not identical expectation passes " .
$dumper->describeDifference($this->_getValue(), $compare, TYPE_MATTERS);
} else {
return "Not identical expectation [" . $dumper->describeValue($this->_getValue()) . "] matches";
}
}
}
/**
* Test for a pattern using Perl regex rules.
* @package SimpleTest
* @subpackage UnitTester
*/
class PatternExpectation extends SimpleExpectation {
var $_pattern;
/**
* Sets the value to compare against.
* @param string $pattern Pattern to search for.
* @param string $message Customised message on failure.
* @access public
*/
function PatternExpectation($pattern, $message = '%s') {
$this->SimpleExpectation($message);
$this->_pattern = $pattern;
}
/**
* Accessor for the pattern.
* @return string Perl regex as string.
* @access protected
*/
function _getPattern() {
return $this->_pattern;
}
/**
* Tests the expectation. True if the Perl regex
* matches the comparison value.
* @param string $compare Comparison value.
* @return boolean True if correct.
* @access public
*/
function test($compare) {
return (boolean)preg_match($this->_getPattern(), $compare);
}
/**
* Returns a human readable test message.
* @param mixed $compare Comparison value.
* @return string Description of success
* or failure.
* @access public
*/
function testMessage($compare) {
if ($this->test($compare)) {
return $this->_describePatternMatch($this->_getPattern(), $compare);
} else {
$dumper = &$this->_getDumper();
return "Pattern [" . $this->_getPattern() .
"] not detected in [" .
$dumper->describeValue($compare) . "]";
}
}
/**
* Describes a pattern match including the string
* found and it's position.
* @param string $pattern Regex to match against.
* @param string $subject Subject to search.
* @access protected
*/
function _describePatternMatch($pattern, $subject) {
preg_match($pattern, $subject, $matches);
$position = strpos($subject, $matches[0]);
$dumper = $this->_getDumper();
return "Pattern [$pattern] detected at character [$position] in [" .
$dumper->describeValue($subject) . "] as [" .
$matches[0] . "] in region [" .
$dumper->clipString($subject, 100, $position) . "]";
}
}
/**
* @package SimpleTest
* @subpackage UnitTester
* @deprecated
*/
class WantedPatternExpectation extends PatternExpectation {
}
/**
* Fail if a pattern is detected within the
* comparison.
* @package SimpleTest
* @subpackage UnitTester
*/
class NoPatternExpectation extends PatternExpectation {
/**
* Sets the reject pattern
* @param string $pattern Pattern to search for.
* @param string $message Customised message on failure.
* @access public
*/
function NoPatternExpectation($pattern, $message = '%s') {
$this->PatternExpectation($pattern, $message);
}
/**
* Tests the expectation. False if the Perl regex
* matches the comparison value.
* @param string $compare Comparison value.
* @return boolean True if correct.
* @access public
*/
function test($compare) {
return ! parent::test($compare);
}
/**
* Returns a human readable test message.
* @param string $compare Comparison value.
* @return string Description of success
* or failure.
* @access public
*/
function testMessage($compare) {
if ($this->test($compare)) {
$dumper = &$this->_getDumper();
return "Pattern [" . $this->_getPattern() .
"] not detected in [" .
$dumper->describeValue($compare) . "]";
} else {
return $this->_describePatternMatch($this->_getPattern(), $compare);
}
}
}
/**
* @package SimpleTest
* @subpackage UnitTester
* @deprecated
*/
class UnwantedPatternExpectation extends NoPatternExpectation {
}
/**
* Tests either type or class name if it's an object.
* @package SimpleTest
* @subpackage UnitTester
*/
class IsAExpectation extends SimpleExpectation {
var $_type;
/**
* Sets the type to compare with.
* @param string $type Type or class name.
* @param string $message Customised message on failure.
* @access public
*/
function IsAExpectation($type, $message = '%s') {
$this->SimpleExpectation($message);
$this->_type = $type;
}
/**
* Accessor for type to check against.
* @return string Type or class name.
* @access protected
*/
function _getType() {
return $this->_type;
}
/**
* Tests the expectation. True if the type or
* class matches the string value.
* @param string $compare Comparison value.
* @return boolean True if correct.
* @access public
*/
function test($compare) {
if (is_object($compare)) {
return SimpleTestCompatibility::isA($compare, $this->_type);
} else {
return (strtolower(gettype($compare)) == $this->_canonicalType($this->_type));
}
}
/**
* Coerces type name into a gettype() match.
* @param string $type User type.
* @return string Simpler type.
* @access private
*/
function _canonicalType($type) {
$type = strtolower($type);
$map = array(
'bool' => 'boolean',
'float' => 'double',
'real' => 'double',
'int' => 'integer');
if (isset($map[$type])) {
$type = $map[$type];
}
return $type;
}
/**
* Returns a human readable test message.
* @param mixed $compare Comparison value.
* @return string Description of success
* or failure.
* @access public
*/
function testMessage($compare) {
$dumper = &$this->_getDumper();
return "Value [" . $dumper->describeValue($compare) .
"] should be type [" . $this->_type . "]";
}
}
/**
* Tests either type or class name if it's an object.
* Will succeed if the type does not match.
* @package SimpleTest
* @subpackage UnitTester
*/
class NotAExpectation extends IsAExpectation {
var $_type;
/**
* Sets the type to compare with.
* @param string $type Type or class name.
* @param string $message Customised message on failure.
* @access public
*/
function NotAExpectation($type, $message = '%s') {
$this->IsAExpectation($type, $message);
}
/**
* Tests the expectation. False if the type or
* class matches the string value.
* @param string $compare Comparison value.
* @return boolean True if different.
* @access public
*/
function test($compare) {
return ! parent::test($compare);
}
/**
* Returns a human readable test message.
* @param mixed $compare Comparison value.
* @return string Description of success
* or failure.
* @access public
*/
function testMessage($compare) {
$dumper = &$this->_getDumper();
return "Value [" . $dumper->describeValue($compare) .
"] should not be type [" . $this->_getType() . "]";
}
}
/**
* Tests for existance of a method in an object
* @package SimpleTest
* @subpackage UnitTester
*/
class MethodExistsExpectation extends SimpleExpectation {
var $_method;
/**
* Sets the value to compare against.
* @param string $method Method to check.
* @param string $message Customised message on failure.
* @access public
* @return void
*/
function MethodExistsExpectation($method, $message = '%s') {
$this->SimpleExpectation($message);
$this->_method = &$method;
}
/**
* Tests the expectation. True if the method exists in the test object.
* @param string $compare Comparison method name.
* @return boolean True if correct.
* @access public
*/
function test($compare) {
return (boolean)(is_object($compare) && method_exists($compare, $this->_method));
}
/**
* Returns a human readable test message.
* @param mixed $compare Comparison value.
* @return string Description of success
* or failure.
* @access public
*/
function testMessage($compare) {
$dumper = &$this->_getDumper();
if (! is_object($compare)) {
return 'No method on non-object [' . $dumper->describeValue($compare) . ']';
}
$method = $this->_method;
return "Object [" . $dumper->describeValue($compare) .
"] should contain method [$method]";
}
}
?>

View file

@ -1,198 +0,0 @@
<?php
/**
* adapter for SimpleTest to use PEAR PHPUnit test cases
* @package SimpleTest
* @subpackage Extensions
* @version $Id: pear_test_case.php 1388 2006-11-10 20:59:59Z lastcraft $
*/
/**#@+
* include SimpleTest files
*/
require_once(dirname(__FILE__) . '/../dumper.php');
require_once(dirname(__FILE__) . '/../compatibility.php');
require_once(dirname(__FILE__) . '/../test_case.php');
require_once(dirname(__FILE__) . '/../expectation.php');
/**#@-*/
/**
* Adapter for PEAR PHPUnit test case to allow
* legacy PEAR test cases to be used with SimpleTest.
* @package SimpleTest
* @subpackage Extensions
*/
class PHPUnit_TestCase extends SimpleTestCase {
var $_loosely_typed;
/**
* Constructor. Sets the test name.
* @param $label Test name to display.
* @public
*/
function PHPUnit_TestCase($label = false) {
$this->SimpleTestCase($label);
$this->_loosely_typed = false;
}
/**
* Will test straight equality if set to loose
* typing, or identity if not.
* @param $first First value.
* @param $second Comparison value.
* @param $message Message to display.
* @public
*/
function assertEquals($first, $second, $message = "%s", $delta = 0) {
if ($this->_loosely_typed) {
$expectation = &new EqualExpectation($first);
} else {
$expectation = &new IdenticalExpectation($first);
}
$this->assert($expectation, $second, $message);
}
/**
* Passes if the value tested is not null.
* @param $value Value to test against.
* @param $message Message to display.
* @public
*/
function assertNotNull($value, $message = "%s") {
parent::assert(new TrueExpectation(), isset($value), $message);
}
/**
* Passes if the value tested is null.
* @param $value Value to test against.
* @param $message Message to display.
* @public
*/
function assertNull($value, $message = "%s") {
parent::assert(new TrueExpectation(), !isset($value), $message);
}
/**
* In PHP5 the identity test tests for the same
* object. This is a reference test in PHP4.
* @param $first First object handle.
* @param $second Hopefully the same handle.
* @param $message Message to display.
* @public
*/
function assertSame(&$first, &$second, $message = "%s") {
$dumper = &new SimpleDumper();
$message = sprintf(
$message,
"[" . $dumper->describeValue($first) .
"] and [" . $dumper->describeValue($second) .
"] should reference the same object");
return $this->assert(
new TrueExpectation(),
SimpleTestCompatibility::isReference($first, $second),
$message);
}
/**
* In PHP5 the identity test tests for the same
* object. This is a reference test in PHP4.
* @param $first First object handle.
* @param $second Hopefully a different handle.
* @param $message Message to display.
* @public
*/
function assertNotSame(&$first, &$second, $message = "%s") {
$dumper = &new SimpleDumper();
$message = sprintf(
$message,
"[" . $dumper->describeValue($first) .
"] and [" . $dumper->describeValue($second) .
"] should not be the same object");
return $this->assert(
new falseExpectation(),
SimpleTestCompatibility::isReference($first, $second),
$message);
}
/**
* Sends pass if the test condition resolves true,
* a fail otherwise.
* @param $condition Condition to test true.
* @param $message Message to display.
* @public
*/
function assertTrue($condition, $message = "%s") {
parent::assert(new TrueExpectation(), $condition, $message);
}
/**
* Sends pass if the test condition resolves false,
* a fail otherwise.
* @param $condition Condition to test false.
* @param $message Message to display.
* @public
*/
function assertFalse($condition, $message = "%s") {
parent::assert(new FalseExpectation(), $condition, $message);
}
/**
* Tests a regex match. Needs refactoring.
* @param $pattern Regex to match.
* @param $subject String to search in.
* @param $message Message to display.
* @public
*/
function assertRegExp($pattern, $subject, $message = "%s") {
$this->assert(new PatternExpectation($pattern), $subject, $message);
}
/**
* Tests the type of a value.
* @param $value Value to take type of.
* @param $type Hoped for type.
* @param $message Message to display.
* @public
*/
function assertType($value, $type, $message = "%s") {
parent::assert(new TrueExpectation(), gettype($value) == strtolower($type), $message);
}
/**
* Sets equality operation to act as a simple equal
* comparison only, allowing a broader range of
* matches.
* @param $loosely_typed True for broader comparison.
* @public
*/
function setLooselyTyped($loosely_typed) {
$this->_loosely_typed = $loosely_typed;
}
/**
* For progress indication during
* a test amongst other things.
* @return Usually one.
* @public
*/
function countTestCases() {
return $this->getSize();
}
/**
* Accessor for name, normally just the class
* name.
* @public
*/
function getName() {
return $this->getLabel();
}
/**
* Does nothing. For compatibility only.
* @param $name Dummy
* @public
*/
function setName($name) {
}
}
?>

View file

@ -1,96 +0,0 @@
<?php
/**
* adapter for SimpleTest to use PHPUnit test cases
* @package SimpleTest
* @subpackage Extensions
* @version $Id: phpunit_test_case.php 1530 2007-06-04 23:35:45Z lastcraft $
*/
/**#@+
* include SimpleTest files
*/
require_once(dirname(__FILE__) . '/../unit_tester.php');
require_once(dirname(__FILE__) . '/../expectation.php');
/**#@-*/
/**
* Adapter for sourceforge PHPUnit test case to allow
* legacy test cases to be used with SimpleTest.
* @package SimpleTest
* @subpackage Extensions
*/
class TestCase extends SimpleTestCase {
/**
* Constructor. Sets the test name.
* @param $label Test name to display.
* @public
*/
function TestCase($label = false) {
$this->SimpleTestCase($label);
}
/**
* Sends pass if the test condition resolves true,
* a fail otherwise.
* @param $condition Condition to test true.
* @param $message Message to display.
* @public
*/
function assert($condition, $message = false) {
parent::assert(new TrueExpectation(), $condition, $message);
}
/**
* Will test straight equality if set to loose
* typing, or identity if not.
* @param $first First value.
* @param $second Comparison value.
* @param $message Message to display.
* @public
*/
function assertEquals($first, $second, $message = false) {
parent::assert(new EqualExpectation($first), $second, $message);
}
/**
* Simple string equality.
* @param $first First value.
* @param $second Comparison value.
* @param $message Message to display.
* @public
*/
function assertEqualsMultilineStrings($first, $second, $message = false) {
parent::assert(new EqualExpectation($first), $second, $message);
}
/**
* Tests a regex match.
* @param $pattern Regex to match.
* @param $subject String to search in.
* @param $message Message to display.
* @public
*/
function assertRegexp($pattern, $subject, $message = false) {
parent::assert(new PatternExpectation($pattern), $subject, $message);
}
/**
* Sends an error which we interpret as a fail
* with a different message for compatibility.
* @param $message Message to display.
* @public
*/
function error($message) {
parent::fail("Error triggered [$message]");
}
/**
* Accessor for name.
* @public
*/
function name() {
return $this->getLabel();
}
}
?>

View file

@ -1,42 +0,0 @@
<?php
class TestDoxReporter extends SimpleReporter
{
var $_test_case_pattern = '/^TestOf(.*)$/';
function TestDoxReporter($test_case_pattern = '/^TestOf(.*)$/') {
parent::SimpleScorer();
$this->_test_case_pattern = empty($test_case_pattern) ? '/^(.*)$/' : $test_case_pattern;
}
function paintCaseStart($test_name) {
preg_match($this->_test_case_pattern, $test_name, $matches);
if (!empty($matches[1])) {
echo $matches[1] . "\n";
} else {
echo $test_name . "\n";
}
}
function paintCaseEnd() {
echo "\n";
}
function paintMethodStart($test_name) {
if (!preg_match('/^test(.*)$/i', $test_name, $matches)) {
return;
}
$test_name = $matches[1];
$test_name = preg_replace('/([A-Z])([A-Z])/', '$1 $2', $test_name);
echo '- ' . strtolower(preg_replace('/([a-zA-Z])([A-Z0-9])/', '$1 $2', $test_name));
}
function paintMethodEnd() {
echo "\n";
}
function paintFail() {
echo " [FAILED]";
}
}

View file

@ -1,108 +0,0 @@
<?php
// $Id: test.php 1641 2008-01-22 20:13:52Z pp11 $
require_once dirname(__FILE__) . '/../../autorun.php';
require_once dirname(__FILE__) . '/../testdox.php';
// uncomment to see test dox in action
//SimpleTest::prefer(new TestDoxReporter());
class TestOfTestDoxReporter extends UnitTestCase
{
function testIsAnInstanceOfSimpleScorerAndReporter() {
$dox = new TestDoxReporter();
$this->assertIsA($dox, 'SimpleScorer');
$this->assertIsA($dox, 'SimpleReporter');
}
function testOutputsNameOfTestCase() {
$dox = new TestDoxReporter();
ob_start();
$dox->paintCaseStart('TestOfTestDoxReporter');
$buffer = ob_get_clean();
$this->assertWantedPattern('/^TestDoxReporter/', $buffer);
}
function testOutputOfTestCaseNameFilteredByConstructParameter() {
$dox = new TestDoxReporter('/^(.*)Test$/');
ob_start();
$dox->paintCaseStart('SomeGreatWidgetTest');
$buffer = ob_get_clean();
$this->assertWantedPattern('/^SomeGreatWidget/', $buffer);
}
function testIfTest_case_patternIsEmptyAssumeEverythingMatches() {
$dox = new TestDoxReporter('');
ob_start();
$dox->paintCaseStart('TestOfTestDoxReporter');
$buffer = ob_get_clean();
$this->assertWantedPattern('/^TestOfTestDoxReporter/', $buffer);
}
function testEmptyLineInsertedWhenCaseEnds() {
$dox = new TestDoxReporter();
ob_start();
$dox->paintCaseEnd('TestOfTestDoxReporter');
$buffer = ob_get_clean();
$this->assertEqual("\n", $buffer);
}
function testPaintsTestMethodInTestDoxFormat() {
$dox = new TestDoxReporter();
ob_start();
$dox->paintMethodStart('testSomeGreatTestCase');
$buffer = ob_get_clean();
$this->assertEqual("- some great test case", $buffer);
unset($buffer);
$random = rand(100, 200);
ob_start();
$dox->paintMethodStart("testRandomNumberIs{$random}");
$buffer = ob_get_clean();
$this->assertEqual("- random number is {$random}", $buffer);
}
function testDoesNotOutputAnythingOnNoneTestMethods() {
$dox = new TestDoxReporter();
ob_start();
$dox->paintMethodStart('nonMatchingMethod');
$buffer = ob_get_clean();
$this->assertEqual('', $buffer);
}
function testPaintMethodAddLineBreak() {
$dox = new TestDoxReporter();
ob_start();
$dox->paintMethodEnd('someMethod');
$buffer = ob_get_clean();
$this->assertEqual("\n", $buffer);
$this->assertNoErrors();
}
function testProperlySpacesSingleLettersInMethodName() {
$dox = new TestDoxReporter();
ob_start();
$dox->paintMethodStart('testAVerySimpleAgainAVerySimpleMethod');
$buffer = ob_get_clean();
$this->assertEqual('- a very simple again a very simple method', $buffer);
}
function testOnFailureThisPrintsFailureNotice() {
$dox = new TestDoxReporter();
ob_start();
$dox->paintFail();
$buffer = ob_get_clean();
$this->assertEqual(' [FAILED]', $buffer);
}
function testWhenMatchingMethodNamesTestPrefixIsCaseInsensitive() {
$dox = new TestDoxReporter();
ob_start();
$dox->paintMethodStart('TESTSupportsAllUppercaseTestPrefixEvenThoughIDoNotKnowWhyYouWouldDoThat');
$buffer = ob_get_clean();
$this->assertEqual(
'- supports all uppercase test prefix even though i do not know why you would do that',
$buffer
);
}
}

View file

@ -1,355 +0,0 @@
<?php
/**
* Base include file for SimpleTest.
* @package SimpleTest
* @subpackage WebTester
* @version $Id: form.php 1672 2008-03-02 04:47:34Z edwardzyang $
*/
/**#@+
* include SimpleTest files
*/
require_once(dirname(__FILE__) . '/tag.php');
require_once(dirname(__FILE__) . '/encoding.php');
require_once(dirname(__FILE__) . '/selector.php');
/**#@-*/
/**
* Form tag class to hold widget values.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleForm {
var $_method;
var $_action;
var $_encoding;
var $_default_target;
var $_id;
var $_buttons;
var $_images;
var $_widgets;
var $_radios;
var $_checkboxes;
/**
* Starts with no held controls/widgets.
* @param SimpleTag $tag Form tag to read.
* @param SimplePage $page Holding page.
*/
function SimpleForm($tag, &$page) {
$this->_method = $tag->getAttribute('method');
$this->_action = $this->_createAction($tag->getAttribute('action'), $page);
$this->_encoding = $this->_setEncodingClass($tag);
$this->_default_target = false;
$this->_id = $tag->getAttribute('id');
$this->_buttons = array();
$this->_images = array();
$this->_widgets = array();
$this->_radios = array();
$this->_checkboxes = array();
}
/**
* Creates the request packet to be sent by the form.
* @param SimpleTag $tag Form tag to read.
* @return string Packet class.
* @access private
*/
function _setEncodingClass($tag) {
if (strtolower($tag->getAttribute('method')) == 'post') {
if (strtolower($tag->getAttribute('enctype')) == 'multipart/form-data') {
return 'SimpleMultipartEncoding';
}
return 'SimplePostEncoding';
}
return 'SimpleGetEncoding';
}
/**
* Sets the frame target within a frameset.
* @param string $frame Name of frame.
* @access public
*/
function setDefaultTarget($frame) {
$this->_default_target = $frame;
}
/**
* Accessor for method of form submission.
* @return string Either get or post.
* @access public
*/
function getMethod() {
return ($this->_method ? strtolower($this->_method) : 'get');
}
/**
* Combined action attribute with current location
* to get an absolute form target.
* @param string $action Action attribute from form tag.
* @param SimpleUrl $base Page location.
* @return SimpleUrl Absolute form target.
*/
function _createAction($action, &$page) {
if (($action === '') || ($action === false)) {
return $page->expandUrl($page->getUrl());
}
return $page->expandUrl(new SimpleUrl($action));;
}
/**
* Absolute URL of the target.
* @return SimpleUrl URL target.
* @access public
*/
function getAction() {
$url = $this->_action;
if ($this->_default_target && ! $url->getTarget()) {
$url->setTarget($this->_default_target);
}
return $url;
}
/**
* Creates the encoding for the current values in the
* form.
* @return SimpleFormEncoding Request to submit.
* @access private
*/
function _encode() {
$class = $this->_encoding;
$encoding = new $class();
for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
$this->_widgets[$i]->write($encoding);
}
return $encoding;
}
/**
* ID field of form for unique identification.
* @return string Unique tag ID.
* @access public
*/
function getId() {
return $this->_id;
}
/**
* Adds a tag contents to the form.
* @param SimpleWidget $tag Input tag to add.
* @access public
*/
function addWidget(&$tag) {
if (strtolower($tag->getAttribute('type')) == 'submit') {
$this->_buttons[] = &$tag;
} elseif (strtolower($tag->getAttribute('type')) == 'image') {
$this->_images[] = &$tag;
} elseif ($tag->getName()) {
$this->_setWidget($tag);
}
}
/**
* Sets the widget into the form, grouping radio
* buttons if any.
* @param SimpleWidget $tag Incoming form control.
* @access private
*/
function _setWidget(&$tag) {
if (strtolower($tag->getAttribute('type')) == 'radio') {
$this->_addRadioButton($tag);
} elseif (strtolower($tag->getAttribute('type')) == 'checkbox') {
$this->_addCheckbox($tag);
} else {
$this->_widgets[] = &$tag;
}
}
/**
* Adds a radio button, building a group if necessary.
* @param SimpleRadioButtonTag $tag Incoming form control.
* @access private
*/
function _addRadioButton(&$tag) {
if (! isset($this->_radios[$tag->getName()])) {
$this->_widgets[] = &new SimpleRadioGroup();
$this->_radios[$tag->getName()] = count($this->_widgets) - 1;
}
$this->_widgets[$this->_radios[$tag->getName()]]->addWidget($tag);
}
/**
* Adds a checkbox, making it a group on a repeated name.
* @param SimpleCheckboxTag $tag Incoming form control.
* @access private
*/
function _addCheckbox(&$tag) {
if (! isset($this->_checkboxes[$tag->getName()])) {
$this->_widgets[] = &$tag;
$this->_checkboxes[$tag->getName()] = count($this->_widgets) - 1;
} else {
$index = $this->_checkboxes[$tag->getName()];
if (! SimpleTestCompatibility::isA($this->_widgets[$index], 'SimpleCheckboxGroup')) {
$previous = &$this->_widgets[$index];
$this->_widgets[$index] = &new SimpleCheckboxGroup();
$this->_widgets[$index]->addWidget($previous);
}
$this->_widgets[$index]->addWidget($tag);
}
}
/**
* Extracts current value from form.
* @param SimpleSelector $selector Criteria to apply.
* @return string/array Value(s) as string or null
* if not set.
* @access public
*/
function getValue($selector) {
for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
if ($selector->isMatch($this->_widgets[$i])) {
return $this->_widgets[$i]->getValue();
}
}
foreach ($this->_buttons as $button) {
if ($selector->isMatch($button)) {
return $button->getValue();
}
}
return null;
}
/**
* Sets a widget value within the form.
* @param SimpleSelector $selector Criteria to apply.
* @param string $value Value to input into the widget.
* @return boolean True if value is legal, false
* otherwise. If the field is not
* present, nothing will be set.
* @access public
*/
function setField($selector, $value, $position=false) {
$success = false;
$_position = 0;
for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
if ($selector->isMatch($this->_widgets[$i])) {
$_position++;
if ($position === false or $_position === (int)$position) {
if ($this->_widgets[$i]->setValue($value)) {
$success = true;
}
}
}
}
return $success;
}
/**
* Used by the page object to set widgets labels to
* external label tags.
* @param SimpleSelector $selector Criteria to apply.
* @access public
*/
function attachLabelBySelector($selector, $label) {
for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
if ($selector->isMatch($this->_widgets[$i])) {
if (method_exists($this->_widgets[$i], 'setLabel')) {
$this->_widgets[$i]->setLabel($label);
return;
}
}
}
}
/**
* Test to see if a form has a submit button.
* @param SimpleSelector $selector Criteria to apply.
* @return boolean True if present.
* @access public
*/
function hasSubmit($selector) {
foreach ($this->_buttons as $button) {
if ($selector->isMatch($button)) {
return true;
}
}
return false;
}
/**
* Test to see if a form has an image control.
* @param SimpleSelector $selector Criteria to apply.
* @return boolean True if present.
* @access public
*/
function hasImage($selector) {
foreach ($this->_images as $image) {
if ($selector->isMatch($image)) {
return true;
}
}
return false;
}
/**
* Gets the submit values for a selected button.
* @param SimpleSelector $selector Criteria to apply.
* @param hash $additional Additional data for the form.
* @return SimpleEncoding Submitted values or false
* if there is no such button
* in the form.
* @access public
*/
function submitButton($selector, $additional = false) {
$additional = $additional ? $additional : array();
foreach ($this->_buttons as $button) {
if ($selector->isMatch($button)) {
$encoding = $this->_encode();
$button->write($encoding);
if ($additional) {
$encoding->merge($additional);
}
return $encoding;
}
}
return false;
}
/**
* Gets the submit values for an image.
* @param SimpleSelector $selector Criteria to apply.
* @param integer $x X-coordinate of click.
* @param integer $y Y-coordinate of click.
* @param hash $additional Additional data for the form.
* @return SimpleEncoding Submitted values or false
* if there is no such button in the
* form.
* @access public
*/
function submitImage($selector, $x, $y, $additional = false) {
$additional = $additional ? $additional : array();
foreach ($this->_images as $image) {
if ($selector->isMatch($image)) {
$encoding = $this->_encode();
$image->write($encoding, $x, $y);
if ($additional) {
$encoding->merge($additional);
}
return $encoding;
}
}
return false;
}
/**
* Simply submits the form without the submit button
* value. Used when there is only one button or it
* is unimportant.
* @return hash Submitted values.
* @access public
*/
function submit() {
return $this->_encode();
}
}
?>

View file

@ -1,596 +0,0 @@
<?php
/**
* Base include file for SimpleTest
* @package SimpleTest
* @subpackage WebTester
* @version $Id: frames.php 1672 2008-03-02 04:47:34Z edwardzyang $
*/
/**#@+
* include other SimpleTest class files
*/
require_once(dirname(__FILE__) . '/page.php');
require_once(dirname(__FILE__) . '/user_agent.php');
/**#@-*/
/**
* A composite page. Wraps a frameset page and
* adds subframes. The original page will be
* mostly ignored. Implements the SimplePage
* interface so as to be interchangeable.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleFrameset {
var $_frameset;
var $_frames;
var $_focus;
var $_names;
/**
* Stashes the frameset page. Will make use of the
* browser to fetch the sub frames recursively.
* @param SimplePage $page Frameset page.
*/
function SimpleFrameset(&$page) {
$this->_frameset = &$page;
$this->_frames = array();
$this->_focus = false;
$this->_names = array();
}
/**
* Adds a parsed page to the frameset.
* @param SimplePage $page Frame page.
* @param string $name Name of frame in frameset.
* @access public
*/
function addFrame(&$page, $name = false) {
$this->_frames[] = &$page;
if ($name) {
$this->_names[$name] = count($this->_frames) - 1;
}
}
/**
* Replaces existing frame with another. If the
* frame is nested, then the call is passed down
* one level.
* @param array $path Path of frame in frameset.
* @param SimplePage $page Frame source.
* @access public
*/
function setFrame($path, &$page) {
$name = array_shift($path);
if (isset($this->_names[$name])) {
$index = $this->_names[$name];
} else {
$index = $name - 1;
}
if (count($path) == 0) {
$this->_frames[$index] = &$page;
return;
}
$this->_frames[$index]->setFrame($path, $page);
}
/**
* Accessor for current frame focus. Will be
* false if no frame has focus. Will have the nested
* frame focus if any.
* @return array Labels or indexes of nested frames.
* @access public
*/
function getFrameFocus() {
if ($this->_focus === false) {
return array();
}
return array_merge(
array($this->_getPublicNameFromIndex($this->_focus)),
$this->_frames[$this->_focus]->getFrameFocus());
}
/**
* Turns an internal array index into the frames list
* into a public name, or if none, then a one offset
* index.
* @param integer $subject Internal index.
* @return integer/string Public name.
* @access private
*/
function _getPublicNameFromIndex($subject) {
foreach ($this->_names as $name => $index) {
if ($subject == $index) {
return $name;
}
}
return $subject + 1;
}
/**
* Sets the focus by index. The integer index starts from 1.
* If already focused and the target frame also has frames,
* then the nested frame will be focused.
* @param integer $choice Chosen frame.
* @return boolean True if frame exists.
* @access public
*/
function setFrameFocusByIndex($choice) {
if (is_integer($this->_focus)) {
if ($this->_frames[$this->_focus]->hasFrames()) {
return $this->_frames[$this->_focus]->setFrameFocusByIndex($choice);
}
}
if (($choice < 1) || ($choice > count($this->_frames))) {
return false;
}
$this->_focus = $choice - 1;
return true;
}
/**
* Sets the focus by name. If already focused and the
* target frame also has frames, then the nested frame
* will be focused.
* @param string $name Chosen frame.
* @return boolean True if frame exists.
* @access public
*/
function setFrameFocus($name) {
if (is_integer($this->_focus)) {
if ($this->_frames[$this->_focus]->hasFrames()) {
return $this->_frames[$this->_focus]->setFrameFocus($name);
}
}
if (in_array($name, array_keys($this->_names))) {
$this->_focus = $this->_names[$name];
return true;
}
return false;
}
/**
* Clears the frame focus.
* @access public
*/
function clearFrameFocus() {
$this->_focus = false;
$this->_clearNestedFramesFocus();
}
/**
* Clears the frame focus for any nested frames.
* @access private
*/
function _clearNestedFramesFocus() {
for ($i = 0; $i < count($this->_frames); $i++) {
$this->_frames[$i]->clearFrameFocus();
}
}
/**
* Test for the presence of a frameset.
* @return boolean Always true.
* @access public
*/
function hasFrames() {
return true;
}
/**
* Accessor for frames information.
* @return array/string Recursive hash of frame URL strings.
* The key is either a numerical
* index or the name attribute.
* @access public
*/
function getFrames() {
$report = array();
for ($i = 0; $i < count($this->_frames); $i++) {
$report[$this->_getPublicNameFromIndex($i)] =
$this->_frames[$i]->getFrames();
}
return $report;
}
/**
* Accessor for raw text of either all the pages or
* the frame in focus.
* @return string Raw unparsed content.
* @access public
*/
function getRaw() {
if (is_integer($this->_focus)) {
return $this->_frames[$this->_focus]->getRaw();
}
$raw = '';
for ($i = 0; $i < count($this->_frames); $i++) {
$raw .= $this->_frames[$i]->getRaw();
}
return $raw;
}
/**
* Accessor for plain text of either all the pages or
* the frame in focus.
* @return string Plain text content.
* @access public
*/
function getText() {
if (is_integer($this->_focus)) {
return $this->_frames[$this->_focus]->getText();
}
$raw = '';
for ($i = 0; $i < count($this->_frames); $i++) {
$raw .= ' ' . $this->_frames[$i]->getText();
}
return trim($raw);
}
/**
* Accessor for last error.
* @return string Error from last response.
* @access public
*/
function getTransportError() {
if (is_integer($this->_focus)) {
return $this->_frames[$this->_focus]->getTransportError();
}
return $this->_frameset->getTransportError();
}
/**
* Request method used to fetch this frame.
* @return string GET, POST or HEAD.
* @access public
*/
function getMethod() {
if (is_integer($this->_focus)) {
return $this->_frames[$this->_focus]->getMethod();
}
return $this->_frameset->getMethod();
}
/**
* Original resource name.
* @return SimpleUrl Current url.
* @access public
*/
function getUrl() {
if (is_integer($this->_focus)) {
$url = $this->_frames[$this->_focus]->getUrl();
$url->setTarget($this->_getPublicNameFromIndex($this->_focus));
} else {
$url = $this->_frameset->getUrl();
}
return $url;
}
/**
* Page base URL.
* @return SimpleUrl Current url.
* @access public
*/
function getBaseUrl() {
if (is_integer($this->_focus)) {
$url = $this->_frames[$this->_focus]->getBaseUrl();
} else {
$url = $this->_frameset->getBaseUrl();
}
return $url;
}
/**
* Expands expandomatic URLs into fully qualified
* URLs for the frameset page.
* @param SimpleUrl $url Relative URL.
* @return SimpleUrl Absolute URL.
* @access public
*/
function expandUrl($url) {
return $this->_frameset->expandUrl($url);
}
/**
* Original request data.
* @return mixed Sent content.
* @access public
*/
function getRequestData() {
if (is_integer($this->_focus)) {
return $this->_frames[$this->_focus]->getRequestData();
}
return $this->_frameset->getRequestData();
}
/**
* Accessor for current MIME type.
* @return string MIME type as string; e.g. 'text/html'
* @access public
*/
function getMimeType() {
if (is_integer($this->_focus)) {
return $this->_frames[$this->_focus]->getMimeType();
}
return $this->_frameset->getMimeType();
}
/**
* Accessor for last response code.
* @return integer Last HTTP response code received.
* @access public
*/
function getResponseCode() {
if (is_integer($this->_focus)) {
return $this->_frames[$this->_focus]->getResponseCode();
}
return $this->_frameset->getResponseCode();
}
/**
* Accessor for last Authentication type. Only valid
* straight after a challenge (401).
* @return string Description of challenge type.
* @access public
*/
function getAuthentication() {
if (is_integer($this->_focus)) {
return $this->_frames[$this->_focus]->getAuthentication();
}
return $this->_frameset->getAuthentication();
}
/**
* Accessor for last Authentication realm. Only valid
* straight after a challenge (401).
* @return string Name of security realm.
* @access public
*/
function getRealm() {
if (is_integer($this->_focus)) {
return $this->_frames[$this->_focus]->getRealm();
}
return $this->_frameset->getRealm();
}
/**
* Accessor for outgoing header information.
* @return string Header block.
* @access public
*/
function getRequest() {
if (is_integer($this->_focus)) {
return $this->_frames[$this->_focus]->getRequest();
}
return $this->_frameset->getRequest();
}
/**
* Accessor for raw header information.
* @return string Header block.
* @access public
*/
function getHeaders() {
if (is_integer($this->_focus)) {
return $this->_frames[$this->_focus]->getHeaders();
}
return $this->_frameset->getHeaders();
}
/**
* Accessor for parsed title.
* @return string Title or false if no title is present.
* @access public
*/
function getTitle() {
return $this->_frameset->getTitle();
}
/**
* Accessor for a list of all fixed links.
* @return array List of urls as strings.
* @access public
*/
function getUrls() {
if (is_integer($this->_focus)) {
return $this->_frames[$this->_focus]->getUrls();
}
$urls = array();
foreach ($this->_frames as $frame) {
$urls = array_merge($urls, $frame->getUrls());
}
return array_values(array_unique($urls));
}
/**
* Accessor for URLs by the link label. Label will match
* regardess of whitespace issues and case.
* @param string $label Text of link.
* @return array List of links with that label.
* @access public
*/
function getUrlsByLabel($label) {
if (is_integer($this->_focus)) {
return $this->_tagUrlsWithFrame(
$this->_frames[$this->_focus]->getUrlsByLabel($label),
$this->_focus);
}
$urls = array();
foreach ($this->_frames as $index => $frame) {
$urls = array_merge(
$urls,
$this->_tagUrlsWithFrame(
$frame->getUrlsByLabel($label),
$index));
}
return $urls;
}
/**
* Accessor for a URL by the id attribute. If in a frameset
* then the first link found with that ID attribute is
* returned only. Focus on a frame if you want one from
* a specific part of the frameset.
* @param string $id Id attribute of link.
* @return string URL with that id.
* @access public
*/
function getUrlById($id) {
foreach ($this->_frames as $index => $frame) {
if ($url = $frame->getUrlById($id)) {
if (! $url->gettarget()) {
$url->setTarget($this->_getPublicNameFromIndex($index));
}
return $url;
}
}
return false;
}
/**
* Attaches the intended frame index to a list of URLs.
* @param array $urls List of SimpleUrls.
* @param string $frame Name of frame or index.
* @return array List of tagged URLs.
* @access private
*/
function _tagUrlsWithFrame($urls, $frame) {
$tagged = array();
foreach ($urls as $url) {
if (! $url->getTarget()) {
$url->setTarget($this->_getPublicNameFromIndex($frame));
}
$tagged[] = $url;
}
return $tagged;
}
/**
* Finds a held form by button label. Will only
* search correctly built forms.
* @param SimpleSelector $selector Button finder.
* @return SimpleForm Form object containing
* the button.
* @access public
*/
function &getFormBySubmit($selector) {
$form = &$this->_findForm('getFormBySubmit', $selector);
return $form;
}
/**
* Finds a held form by image using a selector.
* Will only search correctly built forms. The first
* form found either within the focused frame, or
* across frames, will be the one returned.
* @param SimpleSelector $selector Image finder.
* @return SimpleForm Form object containing
* the image.
* @access public
*/
function &getFormByImage($selector) {
$form = &$this->_findForm('getFormByImage', $selector);
return $form;
}
/**
* Finds a held form by the form ID. A way of
* identifying a specific form when we have control
* of the HTML code. The first form found
* either within the focused frame, or across frames,
* will be the one returned.
* @param string $id Form label.
* @return SimpleForm Form object containing the matching ID.
* @access public
*/
function &getFormById($id) {
$form = &$this->_findForm('getFormById', $id);
return $form;
}
/**
* General form finder. Will search all the frames or
* just the one in focus.
* @param string $method Method to use to find in a page.
* @param string $attribute Label, name or ID.
* @return SimpleForm Form object containing the matching ID.
* @access private
*/
function &_findForm($method, $attribute) {
if (is_integer($this->_focus)) {
$form = &$this->_findFormInFrame(
$this->_frames[$this->_focus],
$this->_focus,
$method,
$attribute);
return $form;
}
for ($i = 0; $i < count($this->_frames); $i++) {
$form = &$this->_findFormInFrame(
$this->_frames[$i],
$i,
$method,
$attribute);
if ($form) {
return $form;
}
}
$null = null;
return $null;
}
/**
* Finds a form in a page using a form finding method. Will
* also tag the form with the frame name it belongs in.
* @param SimplePage $page Page content of frame.
* @param integer $index Internal frame representation.
* @param string $method Method to use to find in a page.
* @param string $attribute Label, name or ID.
* @return SimpleForm Form object containing the matching ID.
* @access private
*/
function &_findFormInFrame(&$page, $index, $method, $attribute) {
$form = &$this->_frames[$index]->$method($attribute);
if (isset($form)) {
$form->setDefaultTarget($this->_getPublicNameFromIndex($index));
}
return $form;
}
/**
* Sets a field on each form in which the field is
* available.
* @param SimpleSelector $selector Field finder.
* @param string $value Value to set field to.
* @return boolean True if value is valid.
* @access public
*/
function setField($selector, $value) {
if (is_integer($this->_focus)) {
$this->_frames[$this->_focus]->setField($selector, $value);
} else {
for ($i = 0; $i < count($this->_frames); $i++) {
$this->_frames[$i]->setField($selector, $value);
}
}
}
/**
* Accessor for a form element value within a page.
* @param SimpleSelector $selector Field finder.
* @return string/boolean A string if the field is
* present, false if unchecked
* and null if missing.
* @access public
*/
function getField($selector) {
for ($i = 0; $i < count($this->_frames); $i++) {
$value = $this->_frames[$i]->getField($selector);
if (isset($value)) {
return $value;
}
}
return null;
}
}
?>

View file

@ -1,624 +0,0 @@
<?php
/**
* base include file for SimpleTest
* @package SimpleTest
* @subpackage WebTester
* @version $Id: http.php 1722 2008-04-07 19:30:56Z lastcraft $
*/
/**#@+
* include other SimpleTest class files
*/
require_once(dirname(__FILE__) . '/socket.php');
require_once(dirname(__FILE__) . '/cookies.php');
require_once(dirname(__FILE__) . '/url.php');
/**#@-*/
/**
* Creates HTTP headers for the end point of
* a HTTP request.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleRoute {
var $_url;
/**
* Sets the target URL.
* @param SimpleUrl $url URL as object.
* @access public
*/
function SimpleRoute($url) {
$this->_url = $url;
}
/**
* Resource name.
* @return SimpleUrl Current url.
* @access protected
*/
function getUrl() {
return $this->_url;
}
/**
* Creates the first line which is the actual request.
* @param string $method HTTP request method, usually GET.
* @return string Request line content.
* @access protected
*/
function _getRequestLine($method) {
return $method . ' ' . $this->_url->getPath() .
$this->_url->getEncodedRequest() . ' HTTP/1.0';
}
/**
* Creates the host part of the request.
* @return string Host line content.
* @access protected
*/
function _getHostLine() {
$line = 'Host: ' . $this->_url->getHost();
if ($this->_url->getPort()) {
$line .= ':' . $this->_url->getPort();
}
return $line;
}
/**
* Opens a socket to the route.
* @param string $method HTTP request method, usually GET.
* @param integer $timeout Connection timeout.
* @return SimpleSocket New socket.
* @access public
*/
function &createConnection($method, $timeout) {
$default_port = ('https' == $this->_url->getScheme()) ? 443 : 80;
$socket = &$this->_createSocket(
$this->_url->getScheme() ? $this->_url->getScheme() : 'http',
$this->_url->getHost(),
$this->_url->getPort() ? $this->_url->getPort() : $default_port,
$timeout);
if (! $socket->isError()) {
$socket->write($this->_getRequestLine($method) . "\r\n");
$socket->write($this->_getHostLine() . "\r\n");
$socket->write("Connection: close\r\n");
}
return $socket;
}
/**
* Factory for socket.
* @param string $scheme Protocol to use.
* @param string $host Hostname to connect to.
* @param integer $port Remote port.
* @param integer $timeout Connection timeout.
* @return SimpleSocket/SimpleSecureSocket New socket.
* @access protected
*/
function &_createSocket($scheme, $host, $port, $timeout) {
if (in_array($scheme, array('https'))) {
$socket = &new SimpleSecureSocket($host, $port, $timeout);
} else {
$socket = &new SimpleSocket($host, $port, $timeout);
}
return $socket;
}
}
/**
* Creates HTTP headers for the end point of
* a HTTP request via a proxy server.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleProxyRoute extends SimpleRoute {
var $_proxy;
var $_username;
var $_password;
/**
* Stashes the proxy address.
* @param SimpleUrl $url URL as object.
* @param string $proxy Proxy URL.
* @param string $username Username for autentication.
* @param string $password Password for autentication.
* @access public
*/
function SimpleProxyRoute($url, $proxy, $username = false, $password = false) {
$this->SimpleRoute($url);
$this->_proxy = $proxy;
$this->_username = $username;
$this->_password = $password;
}
/**
* Creates the first line which is the actual request.
* @param string $method HTTP request method, usually GET.
* @param SimpleUrl $url URL as object.
* @return string Request line content.
* @access protected
*/
function _getRequestLine($method) {
$url = $this->getUrl();
$scheme = $url->getScheme() ? $url->getScheme() : 'http';
$port = $url->getPort() ? ':' . $url->getPort() : '';
return $method . ' ' . $scheme . '://' . $url->getHost() . $port .
$url->getPath() . $url->getEncodedRequest() . ' HTTP/1.0';
}
/**
* Creates the host part of the request.
* @param SimpleUrl $url URL as object.
* @return string Host line content.
* @access protected
*/
function _getHostLine() {
$host = 'Host: ' . $this->_proxy->getHost();
$port = $this->_proxy->getPort() ? $this->_proxy->getPort() : 8080;
return "$host:$port";
}
/**
* Opens a socket to the route.
* @param string $method HTTP request method, usually GET.
* @param integer $timeout Connection timeout.
* @return SimpleSocket New socket.
* @access public
*/
function &createConnection($method, $timeout) {
$socket = &$this->_createSocket(
$this->_proxy->getScheme() ? $this->_proxy->getScheme() : 'http',
$this->_proxy->getHost(),
$this->_proxy->getPort() ? $this->_proxy->getPort() : 8080,
$timeout);
if ($socket->isError()) {
return $socket;
}
$socket->write($this->_getRequestLine($method) . "\r\n");
$socket->write($this->_getHostLine() . "\r\n");
if ($this->_username && $this->_password) {
$socket->write('Proxy-Authorization: Basic ' .
base64_encode($this->_username . ':' . $this->_password) .
"\r\n");
}
$socket->write("Connection: close\r\n");
return $socket;
}
}
/**
* HTTP request for a web page. Factory for
* HttpResponse object.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleHttpRequest {
var $_route;
var $_encoding;
var $_headers;
var $_cookies;
/**
* Builds the socket request from the different pieces.
* These include proxy information, URL, cookies, headers,
* request method and choice of encoding.
* @param SimpleRoute $route Request route.
* @param SimpleFormEncoding $encoding Content to send with
* request.
* @access public
*/
function SimpleHttpRequest(&$route, $encoding) {
$this->_route = &$route;
$this->_encoding = $encoding;
$this->_headers = array();
$this->_cookies = array();
}
/**
* Dispatches the content to the route's socket.
* @param integer $timeout Connection timeout.
* @return SimpleHttpResponse A response which may only have
* an error, but hopefully has a
* complete web page.
* @access public
*/
function &fetch($timeout) {
$socket = &$this->_route->createConnection($this->_encoding->getMethod(), $timeout);
if (! $socket->isError()) {
$this->_dispatchRequest($socket, $this->_encoding);
}
$response = &$this->_createResponse($socket);
return $response;
}
/**
* Sends the headers.
* @param SimpleSocket $socket Open socket.
* @param string $method HTTP request method,
* usually GET.
* @param SimpleFormEncoding $encoding Content to send with request.
* @access private
*/
function _dispatchRequest(&$socket, $encoding) {
foreach ($this->_headers as $header_line) {
$socket->write($header_line . "\r\n");
}
if (count($this->_cookies) > 0) {
$socket->write("Cookie: " . implode(";", $this->_cookies) . "\r\n");
}
$encoding->writeHeadersTo($socket);
$socket->write("\r\n");
$encoding->writeTo($socket);
}
/**
* Adds a header line to the request.
* @param string $header_line Text of full header line.
* @access public
*/
function addHeaderLine($header_line) {
$this->_headers[] = $header_line;
}
/**
* Reads all the relevant cookies from the
* cookie jar.
* @param SimpleCookieJar $jar Jar to read
* @param SimpleUrl $url Url to use for scope.
* @access public
*/
function readCookiesFromJar($jar, $url) {
$this->_cookies = $jar->selectAsPairs($url);
}
/**
* Wraps the socket in a response parser.
* @param SimpleSocket $socket Responding socket.
* @return SimpleHttpResponse Parsed response object.
* @access protected
*/
function &_createResponse(&$socket) {
$response = &new SimpleHttpResponse(
$socket,
$this->_route->getUrl(),
$this->_encoding);
return $response;
}
}
/**
* Collection of header lines in the response.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleHttpHeaders {
var $_raw_headers;
var $_response_code;
var $_http_version;
var $_mime_type;
var $_location;
var $_cookies;
var $_authentication;
var $_realm;
/**
* Parses the incoming header block.
* @param string $headers Header block.
* @access public
*/
function SimpleHttpHeaders($headers) {
$this->_raw_headers = $headers;
$this->_response_code = false;
$this->_http_version = false;
$this->_mime_type = '';
$this->_location = false;
$this->_cookies = array();
$this->_authentication = false;
$this->_realm = false;
foreach (split("\r\n", $headers) as $header_line) {
$this->_parseHeaderLine($header_line);
}
}
/**
* Accessor for parsed HTTP protocol version.
* @return integer HTTP error code.
* @access public
*/
function getHttpVersion() {
return $this->_http_version;
}
/**
* Accessor for raw header block.
* @return string All headers as raw string.
* @access public
*/
function getRaw() {
return $this->_raw_headers;
}
/**
* Accessor for parsed HTTP error code.
* @return integer HTTP error code.
* @access public
*/
function getResponseCode() {
return (integer)$this->_response_code;
}
/**
* Returns the redirected URL or false if
* no redirection.
* @return string URL or false for none.
* @access public
*/
function getLocation() {
return $this->_location;
}
/**
* Test to see if the response is a valid redirect.
* @return boolean True if valid redirect.
* @access public
*/
function isRedirect() {
return in_array($this->_response_code, array(301, 302, 303, 307)) &&
(boolean)$this->getLocation();
}
/**
* Test to see if the response is an authentication
* challenge.
* @return boolean True if challenge.
* @access public
*/
function isChallenge() {
return ($this->_response_code == 401) &&
(boolean)$this->_authentication &&
(boolean)$this->_realm;
}
/**
* Accessor for MIME type header information.
* @return string MIME type.
* @access public
*/
function getMimeType() {
return $this->_mime_type;
}
/**
* Accessor for authentication type.
* @return string Type.
* @access public
*/
function getAuthentication() {
return $this->_authentication;
}
/**
* Accessor for security realm.
* @return string Realm.
* @access public
*/
function getRealm() {
return $this->_realm;
}
/**
* Writes new cookies to the cookie jar.
* @param SimpleCookieJar $jar Jar to write to.
* @param SimpleUrl $url Host and path to write under.
* @access public
*/
function writeCookiesToJar(&$jar, $url) {
foreach ($this->_cookies as $cookie) {
$jar->setCookie(
$cookie->getName(),
$cookie->getValue(),
$url->getHost(),
$cookie->getPath(),
$cookie->getExpiry());
}
}
/**
* Called on each header line to accumulate the held
* data within the class.
* @param string $header_line One line of header.
* @access protected
*/
function _parseHeaderLine($header_line) {
if (preg_match('/HTTP\/(\d+\.\d+)\s+(\d+)/i', $header_line, $matches)) {
$this->_http_version = $matches[1];
$this->_response_code = $matches[2];
}
if (preg_match('/Content-type:\s*(.*)/i', $header_line, $matches)) {
$this->_mime_type = trim($matches[1]);
}
if (preg_match('/Location:\s*(.*)/i', $header_line, $matches)) {
$this->_location = trim($matches[1]);
}
if (preg_match('/Set-cookie:(.*)/i', $header_line, $matches)) {
$this->_cookies[] = $this->_parseCookie($matches[1]);
}
if (preg_match('/WWW-Authenticate:\s+(\S+)\s+realm=\"(.*?)\"/i', $header_line, $matches)) {
$this->_authentication = $matches[1];
$this->_realm = trim($matches[2]);
}
}
/**
* Parse the Set-cookie content.
* @param string $cookie_line Text after "Set-cookie:"
* @return SimpleCookie New cookie object.
* @access private
*/
function _parseCookie($cookie_line) {
$parts = split(";", $cookie_line);
$cookie = array();
preg_match('/\s*(.*?)\s*=(.*)/', array_shift($parts), $cookie);
foreach ($parts as $part) {
if (preg_match('/\s*(.*?)\s*=(.*)/', $part, $matches)) {
$cookie[$matches[1]] = trim($matches[2]);
}
}
return new SimpleCookie(
$cookie[1],
trim($cookie[2]),
isset($cookie["path"]) ? $cookie["path"] : "",
isset($cookie["expires"]) ? $cookie["expires"] : false);
}
}
/**
* Basic HTTP response.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleHttpResponse extends SimpleStickyError {
var $_url;
var $_encoding;
var $_sent;
var $_content;
var $_headers;
/**
* Constructor. Reads and parses the incoming
* content and headers.
* @param SimpleSocket $socket Network connection to fetch
* response text from.
* @param SimpleUrl $url Resource name.
* @param mixed $encoding Record of content sent.
* @access public
*/
function SimpleHttpResponse(&$socket, $url, $encoding) {
$this->SimpleStickyError();
$this->_url = $url;
$this->_encoding = $encoding;
$this->_sent = $socket->getSent();
$this->_content = false;
$raw = $this->_readAll($socket);
if ($socket->isError()) {
$this->_setError('Error reading socket [' . $socket->getError() . ']');
return;
}
$this->_parse($raw);
}
/**
* Splits up the headers and the rest of the content.
* @param string $raw Content to parse.
* @access private
*/
function _parse($raw) {
if (! $raw) {
$this->_setError('Nothing fetched');
$this->_headers = &new SimpleHttpHeaders('');
} elseif (! strstr($raw, "\r\n\r\n")) {
$this->_setError('Could not split headers from content');
$this->_headers = &new SimpleHttpHeaders($raw);
} else {
list($headers, $this->_content) = split("\r\n\r\n", $raw, 2);
$this->_headers = &new SimpleHttpHeaders($headers);
}
}
/**
* Original request method.
* @return string GET, POST or HEAD.
* @access public
*/
function getMethod() {
return $this->_encoding->getMethod();
}
/**
* Resource name.
* @return SimpleUrl Current url.
* @access public
*/
function getUrl() {
return $this->_url;
}
/**
* Original request data.
* @return mixed Sent content.
* @access public
*/
function getRequestData() {
return $this->_encoding;
}
/**
* Raw request that was sent down the wire.
* @return string Bytes actually sent.
* @access public
*/
function getSent() {
return $this->_sent;
}
/**
* Accessor for the content after the last
* header line.
* @return string All content.
* @access public
*/
function getContent() {
return $this->_content;
}
/**
* Accessor for header block. The response is the
* combination of this and the content.
* @return SimpleHeaders Wrapped header block.
* @access public
*/
function getHeaders() {
return $this->_headers;
}
/**
* Accessor for any new cookies.
* @return array List of new cookies.
* @access public
*/
function getNewCookies() {
return $this->_headers->getNewCookies();
}
/**
* Reads the whole of the socket output into a
* single string.
* @param SimpleSocket $socket Unread socket.
* @return string Raw output if successful
* else false.
* @access private
*/
function _readAll(&$socket) {
$all = '';
while (! $this->_isLastPacket($next = $socket->read())) {
$all .= $next;
}
return $all;
}
/**
* Test to see if the packet from the socket is the
* last one.
* @param string $packet Chunk to interpret.
* @return boolean True if empty or EOF.
* @access private
*/
function _isLastPacket($packet) {
if (is_string($packet)) {
return $packet === '';
}
return ! $packet;
}
}
?>

View file

@ -1,139 +0,0 @@
<?php
/**
* Base include file for SimpleTest
* @package SimpleTest
* @subpackage UnitTester
* @version $Id: invoker.php 1722 2008-04-07 19:30:56Z lastcraft $
*/
/**#@+
* Includes SimpleTest files and defined the root constant
* for dependent libraries.
*/
require_once(dirname(__FILE__) . '/errors.php');
require_once(dirname(__FILE__) . '/compatibility.php');
require_once(dirname(__FILE__) . '/scorer.php');
require_once(dirname(__FILE__) . '/expectation.php');
require_once(dirname(__FILE__) . '/dumper.php');
if (! defined('SIMPLE_TEST')) {
define('SIMPLE_TEST', dirname(__FILE__) . '/');
}
/**#@-*/
/**
* This is called by the class runner to run a
* single test method. Will also run the setUp()
* and tearDown() methods.
* @package SimpleTest
* @subpackage UnitTester
*/
class SimpleInvoker {
var $_test_case;
/**
* Stashes the test case for later.
* @param SimpleTestCase $test_case Test case to run.
*/
function SimpleInvoker(&$test_case) {
$this->_test_case = &$test_case;
}
/**
* Accessor for test case being run.
* @return SimpleTestCase Test case.
* @access public
*/
function &getTestCase() {
return $this->_test_case;
}
/**
* Runs test level set up. Used for changing
* the mechanics of base test cases.
* @param string $method Test method to call.
* @access public
*/
function before($method) {
$this->_test_case->before($method);
}
/**
* Invokes a test method and buffered with setUp()
* and tearDown() calls.
* @param string $method Test method to call.
* @access public
*/
function invoke($method) {
$this->_test_case->setUp();
$this->_test_case->$method();
$this->_test_case->tearDown();
}
/**
* Runs test level clean up. Used for changing
* the mechanics of base test cases.
* @param string $method Test method to call.
* @access public
*/
function after($method) {
$this->_test_case->after($method);
}
}
/**
* Do nothing decorator. Just passes the invocation
* straight through.
* @package SimpleTest
* @subpackage UnitTester
*/
class SimpleInvokerDecorator {
var $_invoker;
/**
* Stores the invoker to wrap.
* @param SimpleInvoker $invoker Test method runner.
*/
function SimpleInvokerDecorator(&$invoker) {
$this->_invoker = &$invoker;
}
/**
* Accessor for test case being run.
* @return SimpleTestCase Test case.
* @access public
*/
function &getTestCase() {
return $this->_invoker->getTestCase();
}
/**
* Runs test level set up. Used for changing
* the mechanics of base test cases.
* @param string $method Test method to call.
* @access public
*/
function before($method) {
$this->_invoker->before($method);
}
/**
* Invokes a test method and buffered with setUp()
* and tearDown() calls.
* @param string $method Test method to call.
* @access public
*/
function invoke($method) {
$this->_invoker->invoke($method);
}
/**
* Runs test level clean up. Used for changing
* the mechanics of base test cases.
* @param string $method Test method to call.
* @access public
*/
function after($method) {
$this->_invoker->after($method);
}
}
?>

File diff suppressed because it is too large Load diff

View file

@ -1,983 +0,0 @@
<?php
/**
* Base include file for SimpleTest
* @package SimpleTest
* @subpackage WebTester
* @version $Id: page.php 1672 2008-03-02 04:47:34Z edwardzyang $
*/
/**#@+
* include other SimpleTest class files
*/
require_once(dirname(__FILE__) . '/http.php');
require_once(dirname(__FILE__) . '/parser.php');
require_once(dirname(__FILE__) . '/tag.php');
require_once(dirname(__FILE__) . '/form.php');
require_once(dirname(__FILE__) . '/selector.php');
/**#@-*/
/**
* Creates tags and widgets given HTML tag
* attributes.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleTagBuilder {
/**
* Factory for the tag objects. Creates the
* appropriate tag object for the incoming tag name
* and attributes.
* @param string $name HTML tag name.
* @param hash $attributes Element attributes.
* @return SimpleTag Tag object.
* @access public
*/
function createTag($name, $attributes) {
static $map = array(
'a' => 'SimpleAnchorTag',
'title' => 'SimpleTitleTag',
'base' => 'SimpleBaseTag',
'button' => 'SimpleButtonTag',
'textarea' => 'SimpleTextAreaTag',
'option' => 'SimpleOptionTag',
'label' => 'SimpleLabelTag',
'form' => 'SimpleFormTag',
'frame' => 'SimpleFrameTag');
$attributes = $this->_keysToLowerCase($attributes);
if (array_key_exists($name, $map)) {
$tag_class = $map[$name];
return new $tag_class($attributes);
} elseif ($name == 'select') {
return $this->_createSelectionTag($attributes);
} elseif ($name == 'input') {
return $this->_createInputTag($attributes);
}
return new SimpleTag($name, $attributes);
}
/**
* Factory for selection fields.
* @param hash $attributes Element attributes.
* @return SimpleTag Tag object.
* @access protected
*/
function _createSelectionTag($attributes) {
if (isset($attributes['multiple'])) {
return new MultipleSelectionTag($attributes);
}
return new SimpleSelectionTag($attributes);
}
/**
* Factory for input tags.
* @param hash $attributes Element attributes.
* @return SimpleTag Tag object.
* @access protected
*/
function _createInputTag($attributes) {
if (! isset($attributes['type'])) {
return new SimpleTextTag($attributes);
}
$type = strtolower(trim($attributes['type']));
$map = array(
'submit' => 'SimpleSubmitTag',
'image' => 'SimpleImageSubmitTag',
'checkbox' => 'SimpleCheckboxTag',
'radio' => 'SimpleRadioButtonTag',
'text' => 'SimpleTextTag',
'hidden' => 'SimpleTextTag',
'password' => 'SimpleTextTag',
'file' => 'SimpleUploadTag');
if (array_key_exists($type, $map)) {
$tag_class = $map[$type];
return new $tag_class($attributes);
}
return false;
}
/**
* Make the keys lower case for case insensitive look-ups.
* @param hash $map Hash to convert.
* @return hash Unchanged values, but keys lower case.
* @access private
*/
function _keysToLowerCase($map) {
$lower = array();
foreach ($map as $key => $value) {
$lower[strtolower($key)] = $value;
}
return $lower;
}
}
/**
* SAX event handler. Maintains a list of
* open tags and dispatches them as they close.
* @package SimpleTest
* @subpackage WebTester
*/
class SimplePageBuilder extends SimpleSaxListener {
var $_tags;
var $_page;
var $_private_content_tag;
/**
* Sets the builder up empty.
* @access public
*/
function SimplePageBuilder() {
$this->SimpleSaxListener();
}
/**
* Frees up any references so as to allow the PHP garbage
* collection from unset() to work.
* @access public
*/
function free() {
unset($this->_tags);
unset($this->_page);
unset($this->_private_content_tags);
}
/**
* Reads the raw content and send events
* into the page to be built.
* @param $response SimpleHttpResponse Fetched response.
* @return SimplePage Newly parsed page.
* @access public
*/
function &parse($response) {
$this->_tags = array();
$this->_page = &$this->_createPage($response);
$parser = &$this->_createParser($this);
$parser->parse($response->getContent());
$this->_page->acceptPageEnd();
return $this->_page;
}
/**
* Creates an empty page.
* @return SimplePage New unparsed page.
* @access protected
*/
function &_createPage($response) {
$page = &new SimplePage($response);
return $page;
}
/**
* Creates the parser used with the builder.
* @param $listener SimpleSaxListener Target of parser.
* @return SimpleSaxParser Parser to generate
* events for the builder.
* @access protected
*/
function &_createParser(&$listener) {
$parser = &new SimpleHtmlSaxParser($listener);
return $parser;
}
/**
* Start of element event. Opens a new tag.
* @param string $name Element name.
* @param hash $attributes Attributes without content
* are marked as true.
* @return boolean False on parse error.
* @access public
*/
function startElement($name, $attributes) {
$factory = &new SimpleTagBuilder();
$tag = $factory->createTag($name, $attributes);
if (! $tag) {
return true;
}
if ($tag->getTagName() == 'label') {
$this->_page->acceptLabelStart($tag);
$this->_openTag($tag);
return true;
}
if ($tag->getTagName() == 'form') {
$this->_page->acceptFormStart($tag);
return true;
}
if ($tag->getTagName() == 'frameset') {
$this->_page->acceptFramesetStart($tag);
return true;
}
if ($tag->getTagName() == 'frame') {
$this->_page->acceptFrame($tag);
return true;
}
if ($tag->isPrivateContent() && ! isset($this->_private_content_tag)) {
$this->_private_content_tag = &$tag;
}
if ($tag->expectEndTag()) {
$this->_openTag($tag);
return true;
}
$this->_page->acceptTag($tag);
return true;
}
/**
* End of element event.
* @param string $name Element name.
* @return boolean False on parse error.
* @access public
*/
function endElement($name) {
if ($name == 'label') {
$this->_page->acceptLabelEnd();
return true;
}
if ($name == 'form') {
$this->_page->acceptFormEnd();
return true;
}
if ($name == 'frameset') {
$this->_page->acceptFramesetEnd();
return true;
}
if ($this->_hasNamedTagOnOpenTagStack($name)) {
$tag = array_pop($this->_tags[$name]);
if ($tag->isPrivateContent() && $this->_private_content_tag->getTagName() == $name) {
unset($this->_private_content_tag);
}
$this->_addContentTagToOpenTags($tag);
$this->_page->acceptTag($tag);
return true;
}
return true;
}
/**
* Test to see if there are any open tags awaiting
* closure that match the tag name.
* @param string $name Element name.
* @return boolean True if any are still open.
* @access private
*/
function _hasNamedTagOnOpenTagStack($name) {
return isset($this->_tags[$name]) && (count($this->_tags[$name]) > 0);
}
/**
* Unparsed, but relevant data. The data is added
* to every open tag.
* @param string $text May include unparsed tags.
* @return boolean False on parse error.
* @access public
*/
function addContent($text) {
if (isset($this->_private_content_tag)) {
$this->_private_content_tag->addContent($text);
} else {
$this->_addContentToAllOpenTags($text);
}
return true;
}
/**
* Any content fills all currently open tags unless it
* is part of an option tag.
* @param string $text May include unparsed tags.
* @access private
*/
function _addContentToAllOpenTags($text) {
foreach (array_keys($this->_tags) as $name) {
for ($i = 0, $count = count($this->_tags[$name]); $i < $count; $i++) {
$this->_tags[$name][$i]->addContent($text);
}
}
}
/**
* Parsed data in tag form. The parsed tag is added
* to every open tag. Used for adding options to select
* fields only.
* @param SimpleTag $tag Option tags only.
* @access private
*/
function _addContentTagToOpenTags(&$tag) {
if ($tag->getTagName() != 'option') {
return;
}
foreach (array_keys($this->_tags) as $name) {
for ($i = 0, $count = count($this->_tags[$name]); $i < $count; $i++) {
$this->_tags[$name][$i]->addTag($tag);
}
}
}
/**
* Opens a tag for receiving content. Multiple tags
* will be receiving input at the same time.
* @param SimpleTag $tag New content tag.
* @access private
*/
function _openTag(&$tag) {
$name = $tag->getTagName();
if (! in_array($name, array_keys($this->_tags))) {
$this->_tags[$name] = array();
}
$this->_tags[$name][] = &$tag;
}
}
/**
* A wrapper for a web page.
* @package SimpleTest
* @subpackage WebTester
*/
class SimplePage {
var $_links;
var $_title;
var $_last_widget;
var $_label;
var $_left_over_labels;
var $_open_forms;
var $_complete_forms;
var $_frameset;
var $_frames;
var $_frameset_nesting_level;
var $_transport_error;
var $_raw;
var $_text;
var $_sent;
var $_headers;
var $_method;
var $_url;
var $_base = false;
var $_request_data;
/**
* Parses a page ready to access it's contents.
* @param SimpleHttpResponse $response Result of HTTP fetch.
* @access public
*/
function SimplePage($response = false) {
$this->_links = array();
$this->_title = false;
$this->_left_over_labels = array();
$this->_open_forms = array();
$this->_complete_forms = array();
$this->_frameset = false;
$this->_frames = array();
$this->_frameset_nesting_level = 0;
$this->_text = false;
if ($response) {
$this->_extractResponse($response);
} else {
$this->_noResponse();
}
}
/**
* Extracts all of the response information.
* @param SimpleHttpResponse $response Response being parsed.
* @access private
*/
function _extractResponse($response) {
$this->_transport_error = $response->getError();
$this->_raw = $response->getContent();
$this->_sent = $response->getSent();
$this->_headers = $response->getHeaders();
$this->_method = $response->getMethod();
$this->_url = $response->getUrl();
$this->_request_data = $response->getRequestData();
}
/**
* Sets up a missing response.
* @access private
*/
function _noResponse() {
$this->_transport_error = 'No page fetched yet';
$this->_raw = false;
$this->_sent = false;
$this->_headers = false;
$this->_method = 'GET';
$this->_url = false;
$this->_request_data = false;
}
/**
* Original request as bytes sent down the wire.
* @return mixed Sent content.
* @access public
*/
function getRequest() {
return $this->_sent;
}
/**
* Accessor for raw text of page.
* @return string Raw unparsed content.
* @access public
*/
function getRaw() {
return $this->_raw;
}
/**
* Accessor for plain text of page as a text browser
* would see it.
* @return string Plain text of page.
* @access public
*/
function getText() {
if (! $this->_text) {
$this->_text = SimpleHtmlSaxParser::normalise($this->_raw);
}
return $this->_text;
}
/**
* Accessor for raw headers of page.
* @return string Header block as text.
* @access public
*/
function getHeaders() {
if ($this->_headers) {
return $this->_headers->getRaw();
}
return false;
}
/**
* Original request method.
* @return string GET, POST or HEAD.
* @access public
*/
function getMethod() {
return $this->_method;
}
/**
* Original resource name.
* @return SimpleUrl Current url.
* @access public
*/
function getUrl() {
return $this->_url;
}
/**
* Base URL if set via BASE tag page url otherwise
* @return SimpleUrl Base url.
* @access public
*/
function getBaseUrl() {
return $this->_base;
}
/**
* Original request data.
* @return mixed Sent content.
* @access public
*/
function getRequestData() {
return $this->_request_data;
}
/**
* Accessor for last error.
* @return string Error from last response.
* @access public
*/
function getTransportError() {
return $this->_transport_error;
}
/**
* Accessor for current MIME type.
* @return string MIME type as string; e.g. 'text/html'
* @access public
*/
function getMimeType() {
if ($this->_headers) {
return $this->_headers->getMimeType();
}
return false;
}
/**
* Accessor for HTTP response code.
* @return integer HTTP response code received.
* @access public
*/
function getResponseCode() {
if ($this->_headers) {
return $this->_headers->getResponseCode();
}
return false;
}
/**
* Accessor for last Authentication type. Only valid
* straight after a challenge (401).
* @return string Description of challenge type.
* @access public
*/
function getAuthentication() {
if ($this->_headers) {
return $this->_headers->getAuthentication();
}
return false;
}
/**
* Accessor for last Authentication realm. Only valid
* straight after a challenge (401).
* @return string Name of security realm.
* @access public
*/
function getRealm() {
if ($this->_headers) {
return $this->_headers->getRealm();
}
return false;
}
/**
* Accessor for current frame focus. Will be
* false as no frames.
* @return array Always empty.
* @access public
*/
function getFrameFocus() {
return array();
}
/**
* Sets the focus by index. The integer index starts from 1.
* @param integer $choice Chosen frame.
* @return boolean Always false.
* @access public
*/
function setFrameFocusByIndex($choice) {
return false;
}
/**
* Sets the focus by name. Always fails for a leaf page.
* @param string $name Chosen frame.
* @return boolean False as no frames.
* @access public
*/
function setFrameFocus($name) {
return false;
}
/**
* Clears the frame focus. Does nothing for a leaf page.
* @access public
*/
function clearFrameFocus() {
}
/**
* Adds a tag to the page.
* @param SimpleTag $tag Tag to accept.
* @access public
*/
function acceptTag(&$tag) {
if ($tag->getTagName() == "a") {
$this->_addLink($tag);
} elseif ($tag->getTagName() == "base") {
$this->_setBase($tag);
} elseif ($tag->getTagName() == "title") {
$this->_setTitle($tag);
} elseif ($this->_isFormElement($tag->getTagName())) {
for ($i = 0; $i < count($this->_open_forms); $i++) {
$this->_open_forms[$i]->addWidget($tag);
}
$this->_last_widget = &$tag;
}
}
/**
* Opens a label for a described widget.
* @param SimpleFormTag $tag Tag to accept.
* @access public
*/
function acceptLabelStart(&$tag) {
$this->_label = &$tag;
unset($this->_last_widget);
}
/**
* Closes the most recently opened label.
* @access public
*/
function acceptLabelEnd() {
if (isset($this->_label)) {
if (isset($this->_last_widget)) {
$this->_last_widget->setLabel($this->_label->getText());
unset($this->_last_widget);
} else {
$this->_left_over_labels[] = SimpleTestCompatibility::copy($this->_label);
}
unset($this->_label);
}
}
/**
* Tests to see if a tag is a possible form
* element.
* @param string $name HTML element name.
* @return boolean True if form element.
* @access private
*/
function _isFormElement($name) {
return in_array($name, array('input', 'button', 'textarea', 'select'));
}
/**
* Opens a form. New widgets go here.
* @param SimpleFormTag $tag Tag to accept.
* @access public
*/
function acceptFormStart(&$tag) {
$this->_open_forms[] = &new SimpleForm($tag, $this);
}
/**
* Closes the most recently opened form.
* @access public
*/
function acceptFormEnd() {
if (count($this->_open_forms)) {
$this->_complete_forms[] = array_pop($this->_open_forms);
}
}
/**
* Opens a frameset. A frameset may contain nested
* frameset tags.
* @param SimpleFramesetTag $tag Tag to accept.
* @access public
*/
function acceptFramesetStart(&$tag) {
if (! $this->_isLoadingFrames()) {
$this->_frameset = &$tag;
}
$this->_frameset_nesting_level++;
}
/**
* Closes the most recently opened frameset.
* @access public
*/
function acceptFramesetEnd() {
if ($this->_isLoadingFrames()) {
$this->_frameset_nesting_level--;
}
}
/**
* Takes a single frame tag and stashes it in
* the current frame set.
* @param SimpleFrameTag $tag Tag to accept.
* @access public
*/
function acceptFrame(&$tag) {
if ($this->_isLoadingFrames()) {
if ($tag->getAttribute('src')) {
$this->_frames[] = &$tag;
}
}
}
/**
* Test to see if in the middle of reading
* a frameset.
* @return boolean True if inframeset.
* @access private
*/
function _isLoadingFrames() {
if (! $this->_frameset) {
return false;
}
return ($this->_frameset_nesting_level > 0);
}
/**
* Test to see if link is an absolute one.
* @param string $url Url to test.
* @return boolean True if absolute.
* @access protected
*/
function _linkIsAbsolute($url) {
$parsed = new SimpleUrl($url);
return (boolean)($parsed->getScheme() && $parsed->getHost());
}
/**
* Adds a link to the page.
* @param SimpleAnchorTag $tag Link to accept.
* @access protected
*/
function _addLink($tag) {
$this->_links[] = $tag;
}
/**
* Marker for end of complete page. Any work in
* progress can now be closed.
* @access public
*/
function acceptPageEnd() {
while (count($this->_open_forms)) {
$this->_complete_forms[] = array_pop($this->_open_forms);
}
foreach ($this->_left_over_labels as $label) {
for ($i = 0, $count = count($this->_complete_forms); $i < $count; $i++) {
$this->_complete_forms[$i]->attachLabelBySelector(
new SimpleById($label->getFor()),
$label->getText());
}
}
}
/**
* Test for the presence of a frameset.
* @return boolean True if frameset.
* @access public
*/
function hasFrames() {
return (boolean)$this->_frameset;
}
/**
* Accessor for frame name and source URL for every frame that
* will need to be loaded. Immediate children only.
* @return boolean/array False if no frameset or
* otherwise a hash of frame URLs.
* The key is either a numerical
* base one index or the name attribute.
* @access public
*/
function getFrameset() {
if (! $this->_frameset) {
return false;
}
$urls = array();
for ($i = 0; $i < count($this->_frames); $i++) {
$name = $this->_frames[$i]->getAttribute('name');
$url = new SimpleUrl($this->_frames[$i]->getAttribute('src'));
$urls[$name ? $name : $i + 1] = $this->expandUrl($url);
}
return $urls;
}
/**
* Fetches a list of loaded frames.
* @return array/string Just the URL for a single page.
* @access public
*/
function getFrames() {
$url = $this->expandUrl($this->getUrl());
return $url->asString();
}
/**
* Accessor for a list of all links.
* @return array List of urls with scheme of
* http or https and hostname.
* @access public
*/
function getUrls() {
$all = array();
foreach ($this->_links as $link) {
$url = $this->_getUrlFromLink($link);
$all[] = $url->asString();
}
return $all;
}
/**
* Accessor for URLs by the link label. Label will match
* regardess of whitespace issues and case.
* @param string $label Text of link.
* @return array List of links with that label.
* @access public
*/
function getUrlsByLabel($label) {
$matches = array();
foreach ($this->_links as $link) {
if ($link->getText() == $label) {
$matches[] = $this->_getUrlFromLink($link);
}
}
return $matches;
}
/**
* Accessor for a URL by the id attribute.
* @param string $id Id attribute of link.
* @return SimpleUrl URL with that id of false if none.
* @access public
*/
function getUrlById($id) {
foreach ($this->_links as $link) {
if ($link->getAttribute('id') === (string)$id) {
return $this->_getUrlFromLink($link);
}
}
return false;
}
/**
* Converts a link tag into a target URL.
* @param SimpleAnchor $link Parsed link.
* @return SimpleUrl URL with frame target if any.
* @access private
*/
function _getUrlFromLink($link) {
$url = $this->expandUrl($link->getHref());
if ($link->getAttribute('target')) {
$url->setTarget($link->getAttribute('target'));
}
return $url;
}
/**
* Expands expandomatic URLs into fully qualified
* URLs.
* @param SimpleUrl $url Relative URL.
* @return SimpleUrl Absolute URL.
* @access public
*/
function expandUrl($url) {
if (! is_object($url)) {
$url = new SimpleUrl($url);
}
$location = $this->getBaseUrl() ? $this->getBaseUrl() : new SimpleUrl();
return $url->makeAbsolute($location->makeAbsolute($this->getUrl()));
}
/**
* Sets the base url for the page.
* @param SimpleTag $tag Base URL for page.
* @access protected
*/
function _setBase(&$tag) {
$url = $tag->getAttribute('href');
$this->_base = new SimpleUrl($url);
}
/**
* Sets the title tag contents.
* @param SimpleTitleTag $tag Title of page.
* @access protected
*/
function _setTitle(&$tag) {
$this->_title = &$tag;
}
/**
* Accessor for parsed title.
* @return string Title or false if no title is present.
* @access public
*/
function getTitle() {
if ($this->_title) {
return $this->_title->getText();
}
return false;
}
/**
* Finds a held form by button label. Will only
* search correctly built forms.
* @param SimpleSelector $selector Button finder.
* @return SimpleForm Form object containing
* the button.
* @access public
*/
function &getFormBySubmit($selector) {
for ($i = 0; $i < count($this->_complete_forms); $i++) {
if ($this->_complete_forms[$i]->hasSubmit($selector)) {
return $this->_complete_forms[$i];
}
}
$null = null;
return $null;
}
/**
* Finds a held form by image using a selector.
* Will only search correctly built forms.
* @param SimpleSelector $selector Image finder.
* @return SimpleForm Form object containing
* the image.
* @access public
*/
function &getFormByImage($selector) {
for ($i = 0; $i < count($this->_complete_forms); $i++) {
if ($this->_complete_forms[$i]->hasImage($selector)) {
return $this->_complete_forms[$i];
}
}
$null = null;
return $null;
}
/**
* Finds a held form by the form ID. A way of
* identifying a specific form when we have control
* of the HTML code.
* @param string $id Form label.
* @return SimpleForm Form object containing the matching ID.
* @access public
*/
function &getFormById($id) {
for ($i = 0; $i < count($this->_complete_forms); $i++) {
if ($this->_complete_forms[$i]->getId() == $id) {
return $this->_complete_forms[$i];
}
}
$null = null;
return $null;
}
/**
* Sets a field on each form in which the field is
* available.
* @param SimpleSelector $selector Field finder.
* @param string $value Value to set field to.
* @return boolean True if value is valid.
* @access public
*/
function setField($selector, $value, $position=false) {
$is_set = false;
for ($i = 0; $i < count($this->_complete_forms); $i++) {
if ($this->_complete_forms[$i]->setField($selector, $value, $position)) {
$is_set = true;
}
}
return $is_set;
}
/**
* Accessor for a form element value within a page.
* @param SimpleSelector $selector Field finder.
* @return string/boolean A string if the field is
* present, false if unchecked
* and null if missing.
* @access public
*/
function getField($selector) {
for ($i = 0; $i < count($this->_complete_forms); $i++) {
$value = $this->_complete_forms[$i]->getValue($selector);
if (isset($value)) {
return $value;
}
}
return null;
}
}
?>

View file

@ -1,764 +0,0 @@
<?php
/**
* base include file for SimpleTest
* @package SimpleTest
* @subpackage MockObjects
* @version $Id: parser.php 1723 2008-04-08 00:34:10Z lastcraft $
*/
/**#@+
* Lexer mode stack constants
*/
foreach (array('LEXER_ENTER', 'LEXER_MATCHED',
'LEXER_UNMATCHED', 'LEXER_EXIT',
'LEXER_SPECIAL') as $i => $constant) {
if (! defined($constant)) {
define($constant, $i + 1);
}
}
/**#@-*/
/**
* Compounded regular expression. Any of
* the contained patterns could match and
* when one does, it's label is returned.
* @package SimpleTest
* @subpackage WebTester
*/
class ParallelRegex {
var $_patterns;
var $_labels;
var $_regex;
var $_case;
/**
* Constructor. Starts with no patterns.
* @param boolean $case True for case sensitive, false
* for insensitive.
* @access public
*/
function ParallelRegex($case) {
$this->_case = $case;
$this->_patterns = array();
$this->_labels = array();
$this->_regex = null;
}
/**
* Adds a pattern with an optional label.
* @param string $pattern Perl style regex, but ( and )
* lose the usual meaning.
* @param string $label Label of regex to be returned
* on a match.
* @access public
*/
function addPattern($pattern, $label = true) {
$count = count($this->_patterns);
$this->_patterns[$count] = $pattern;
$this->_labels[$count] = $label;
$this->_regex = null;
}
/**
* Attempts to match all patterns at once against
* a string.
* @param string $subject String to match against.
* @param string $match First matched portion of
* subject.
* @return boolean True on success.
* @access public
*/
function match($subject, &$match) {
if (count($this->_patterns) == 0) {
return false;
}
if (! preg_match($this->_getCompoundedRegex(), $subject, $matches)) {
$match = '';
return false;
}
$match = $matches[0];
for ($i = 1; $i < count($matches); $i++) {
if ($matches[$i]) {
return $this->_labels[$i - 1];
}
}
return true;
}
/**
* Compounds the patterns into a single
* regular expression separated with the
* "or" operator. Caches the regex.
* Will automatically escape (, ) and / tokens.
* @param array $patterns List of patterns in order.
* @access private
*/
function _getCompoundedRegex() {
if ($this->_regex == null) {
for ($i = 0, $count = count($this->_patterns); $i < $count; $i++) {
$this->_patterns[$i] = '(' . str_replace(
array('/', '(', ')'),
array('\/', '\(', '\)'),
$this->_patterns[$i]) . ')';
}
$this->_regex = "/" . implode("|", $this->_patterns) . "/" . $this->_getPerlMatchingFlags();
}
return $this->_regex;
}
/**
* Accessor for perl regex mode flags to use.
* @return string Perl regex flags.
* @access private
*/
function _getPerlMatchingFlags() {
return ($this->_case ? "msS" : "msSi");
}
}
/**
* States for a stack machine.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleStateStack {
var $_stack;
/**
* Constructor. Starts in named state.
* @param string $start Starting state name.
* @access public
*/
function SimpleStateStack($start) {
$this->_stack = array($start);
}
/**
* Accessor for current state.
* @return string State.
* @access public
*/
function getCurrent() {
return $this->_stack[count($this->_stack) - 1];
}
/**
* Adds a state to the stack and sets it
* to be the current state.
* @param string $state New state.
* @access public
*/
function enter($state) {
array_push($this->_stack, $state);
}
/**
* Leaves the current state and reverts
* to the previous one.
* @return boolean False if we drop off
* the bottom of the list.
* @access public
*/
function leave() {
if (count($this->_stack) == 1) {
return false;
}
array_pop($this->_stack);
return true;
}
}
/**
* Accepts text and breaks it into tokens.
* Some optimisation to make the sure the
* content is only scanned by the PHP regex
* parser once. Lexer modes must not start
* with leading underscores.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleLexer {
var $_regexes;
var $_parser;
var $_mode;
var $_mode_handlers;
var $_case;
/**
* Sets up the lexer in case insensitive matching
* by default.
* @param SimpleSaxParser $parser Handling strategy by
* reference.
* @param string $start Starting handler.
* @param boolean $case True for case sensitive.
* @access public
*/
function SimpleLexer(&$parser, $start = "accept", $case = false) {
$this->_case = $case;
$this->_regexes = array();
$this->_parser = &$parser;
$this->_mode = &new SimpleStateStack($start);
$this->_mode_handlers = array($start => $start);
}
/**
* Adds a token search pattern for a particular
* parsing mode. The pattern does not change the
* current mode.
* @param string $pattern Perl style regex, but ( and )
* lose the usual meaning.
* @param string $mode Should only apply this
* pattern when dealing with
* this type of input.
* @access public
*/
function addPattern($pattern, $mode = "accept") {
if (! isset($this->_regexes[$mode])) {
$this->_regexes[$mode] = new ParallelRegex($this->_case);
}
$this->_regexes[$mode]->addPattern($pattern);
if (! isset($this->_mode_handlers[$mode])) {
$this->_mode_handlers[$mode] = $mode;
}
}
/**
* Adds a pattern that will enter a new parsing
* mode. Useful for entering parenthesis, strings,
* tags, etc.
* @param string $pattern Perl style regex, but ( and )
* lose the usual meaning.
* @param string $mode Should only apply this
* pattern when dealing with
* this type of input.
* @param string $new_mode Change parsing to this new
* nested mode.
* @access public
*/
function addEntryPattern($pattern, $mode, $new_mode) {
if (! isset($this->_regexes[$mode])) {
$this->_regexes[$mode] = new ParallelRegex($this->_case);
}
$this->_regexes[$mode]->addPattern($pattern, $new_mode);
if (! isset($this->_mode_handlers[$new_mode])) {
$this->_mode_handlers[$new_mode] = $new_mode;
}
}
/**
* Adds a pattern that will exit the current mode
* and re-enter the previous one.
* @param string $pattern Perl style regex, but ( and )
* lose the usual meaning.
* @param string $mode Mode to leave.
* @access public
*/
function addExitPattern($pattern, $mode) {
if (! isset($this->_regexes[$mode])) {
$this->_regexes[$mode] = new ParallelRegex($this->_case);
}
$this->_regexes[$mode]->addPattern($pattern, "__exit");
if (! isset($this->_mode_handlers[$mode])) {
$this->_mode_handlers[$mode] = $mode;
}
}
/**
* Adds a pattern that has a special mode. Acts as an entry
* and exit pattern in one go, effectively calling a special
* parser handler for this token only.
* @param string $pattern Perl style regex, but ( and )
* lose the usual meaning.
* @param string $mode Should only apply this
* pattern when dealing with
* this type of input.
* @param string $special Use this mode for this one token.
* @access public
*/
function addSpecialPattern($pattern, $mode, $special) {
if (! isset($this->_regexes[$mode])) {
$this->_regexes[$mode] = new ParallelRegex($this->_case);
}
$this->_regexes[$mode]->addPattern($pattern, "_$special");
if (! isset($this->_mode_handlers[$special])) {
$this->_mode_handlers[$special] = $special;
}
}
/**
* Adds a mapping from a mode to another handler.
* @param string $mode Mode to be remapped.
* @param string $handler New target handler.
* @access public
*/
function mapHandler($mode, $handler) {
$this->_mode_handlers[$mode] = $handler;
}
/**
* Splits the page text into tokens. Will fail
* if the handlers report an error or if no
* content is consumed. If successful then each
* unparsed and parsed token invokes a call to the
* held listener.
* @param string $raw Raw HTML text.
* @return boolean True on success, else false.
* @access public
*/
function parse($raw) {
if (! isset($this->_parser)) {
return false;
}
$length = strlen($raw);
while (is_array($parsed = $this->_reduce($raw))) {
list($raw, $unmatched, $matched, $mode) = $parsed;
if (! $this->_dispatchTokens($unmatched, $matched, $mode)) {
return false;
}
if ($raw === '') {
return true;
}
if (strlen($raw) == $length) {
return false;
}
$length = strlen($raw);
}
if (! $parsed) {
return false;
}
return $this->_invokeParser($raw, LEXER_UNMATCHED);
}
/**
* Sends the matched token and any leading unmatched
* text to the parser changing the lexer to a new
* mode if one is listed.
* @param string $unmatched Unmatched leading portion.
* @param string $matched Actual token match.
* @param string $mode Mode after match. A boolean
* false mode causes no change.
* @return boolean False if there was any error
* from the parser.
* @access private
*/
function _dispatchTokens($unmatched, $matched, $mode = false) {
if (! $this->_invokeParser($unmatched, LEXER_UNMATCHED)) {
return false;
}
if (is_bool($mode)) {
return $this->_invokeParser($matched, LEXER_MATCHED);
}
if ($this->_isModeEnd($mode)) {
if (! $this->_invokeParser($matched, LEXER_EXIT)) {
return false;
}
return $this->_mode->leave();
}
if ($this->_isSpecialMode($mode)) {
$this->_mode->enter($this->_decodeSpecial($mode));
if (! $this->_invokeParser($matched, LEXER_SPECIAL)) {
return false;
}
return $this->_mode->leave();
}
$this->_mode->enter($mode);
return $this->_invokeParser($matched, LEXER_ENTER);
}
/**
* Tests to see if the new mode is actually to leave
* the current mode and pop an item from the matching
* mode stack.
* @param string $mode Mode to test.
* @return boolean True if this is the exit mode.
* @access private
*/
function _isModeEnd($mode) {
return ($mode === "__exit");
}
/**
* Test to see if the mode is one where this mode
* is entered for this token only and automatically
* leaves immediately afterwoods.
* @param string $mode Mode to test.
* @return boolean True if this is the exit mode.
* @access private
*/
function _isSpecialMode($mode) {
return (strncmp($mode, "_", 1) == 0);
}
/**
* Strips the magic underscore marking single token
* modes.
* @param string $mode Mode to decode.
* @return string Underlying mode name.
* @access private
*/
function _decodeSpecial($mode) {
return substr($mode, 1);
}
/**
* Calls the parser method named after the current
* mode. Empty content will be ignored. The lexer
* has a parser handler for each mode in the lexer.
* @param string $content Text parsed.
* @param boolean $is_match Token is recognised rather
* than unparsed data.
* @access private
*/
function _invokeParser($content, $is_match) {
if (($content === '') || ($content === false)) {
return true;
}
$handler = $this->_mode_handlers[$this->_mode->getCurrent()];
return $this->_parser->$handler($content, $is_match);
}
/**
* Tries to match a chunk of text and if successful
* removes the recognised chunk and any leading
* unparsed data. Empty strings will not be matched.
* @param string $raw The subject to parse. This is the
* content that will be eaten.
* @return array/boolean Three item list of unparsed
* content followed by the
* recognised token and finally the
* action the parser is to take.
* True if no match, false if there
* is a parsing error.
* @access private
*/
function _reduce($raw) {
if ($action = $this->_regexes[$this->_mode->getCurrent()]->match($raw, $match)) {
$unparsed_character_count = strpos($raw, $match);
$unparsed = substr($raw, 0, $unparsed_character_count);
$raw = substr($raw, $unparsed_character_count + strlen($match));
return array($raw, $unparsed, $match, $action);
}
return true;
}
}
/**
* Breaks HTML into SAX events.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleHtmlLexer extends SimpleLexer {
/**
* Sets up the lexer with case insensitive matching
* and adds the HTML handlers.
* @param SimpleSaxParser $parser Handling strategy by
* reference.
* @access public
*/
function SimpleHtmlLexer(&$parser) {
$this->SimpleLexer($parser, 'text');
$this->mapHandler('text', 'acceptTextToken');
$this->_addSkipping();
foreach ($this->_getParsedTags() as $tag) {
$this->_addTag($tag);
}
$this->_addInTagTokens();
}
/**
* List of parsed tags. Others are ignored.
* @return array List of searched for tags.
* @access private
*/
function _getParsedTags() {
return array('a', 'base', 'title', 'form', 'input', 'button', 'textarea', 'select',
'option', 'frameset', 'frame', 'label');
}
/**
* The lexer has to skip certain sections such
* as server code, client code and styles.
* @access private
*/
function _addSkipping() {
$this->mapHandler('css', 'ignore');
$this->addEntryPattern('<style', 'text', 'css');
$this->addExitPattern('</style>', 'css');
$this->mapHandler('js', 'ignore');
$this->addEntryPattern('<script', 'text', 'js');
$this->addExitPattern('</script>', 'js');
$this->mapHandler('comment', 'ignore');
$this->addEntryPattern('<!--', 'text', 'comment');
$this->addExitPattern('-->', 'comment');
}
/**
* Pattern matches to start and end a tag.
* @param string $tag Name of tag to scan for.
* @access private
*/
function _addTag($tag) {
$this->addSpecialPattern("</$tag>", 'text', 'acceptEndToken');
$this->addEntryPattern("<$tag", 'text', 'tag');
}
/**
* Pattern matches to parse the inside of a tag
* including the attributes and their quoting.
* @access private
*/
function _addInTagTokens() {
$this->mapHandler('tag', 'acceptStartToken');
$this->addSpecialPattern('\s+', 'tag', 'ignore');
$this->_addAttributeTokens();
$this->addExitPattern('/>', 'tag');
$this->addExitPattern('>', 'tag');
}
/**
* Matches attributes that are either single quoted,
* double quoted or unquoted.
* @access private
*/
function _addAttributeTokens() {
$this->mapHandler('dq_attribute', 'acceptAttributeToken');
$this->addEntryPattern('=\s*"', 'tag', 'dq_attribute');
$this->addPattern("\\\\\"", 'dq_attribute');
$this->addExitPattern('"', 'dq_attribute');
$this->mapHandler('sq_attribute', 'acceptAttributeToken');
$this->addEntryPattern("=\s*'", 'tag', 'sq_attribute');
$this->addPattern("\\\\'", 'sq_attribute');
$this->addExitPattern("'", 'sq_attribute');
$this->mapHandler('uq_attribute', 'acceptAttributeToken');
$this->addSpecialPattern('=\s*[^>\s]*', 'tag', 'uq_attribute');
}
}
/**
* Converts HTML tokens into selected SAX events.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleHtmlSaxParser {
var $_lexer;
var $_listener;
var $_tag;
var $_attributes;
var $_current_attribute;
/**
* Sets the listener.
* @param SimpleSaxListener $listener SAX event handler.
* @access public
*/
function SimpleHtmlSaxParser(&$listener) {
$this->_listener = &$listener;
$this->_lexer = &$this->createLexer($this);
$this->_tag = '';
$this->_attributes = array();
$this->_current_attribute = '';
}
/**
* Runs the content through the lexer which
* should call back to the acceptors.
* @param string $raw Page text to parse.
* @return boolean False if parse error.
* @access public
*/
function parse($raw) {
return $this->_lexer->parse($raw);
}
/**
* Sets up the matching lexer. Starts in 'text' mode.
* @param SimpleSaxParser $parser Event generator, usually $self.
* @return SimpleLexer Lexer suitable for this parser.
* @access public
* @static
*/
function &createLexer(&$parser) {
$lexer = &new SimpleHtmlLexer($parser);
return $lexer;
}
/**
* Accepts a token from the tag mode. If the
* starting element completes then the element
* is dispatched and the current attributes
* set back to empty. The element or attribute
* name is converted to lower case.
* @param string $token Incoming characters.
* @param integer $event Lexer event type.
* @return boolean False if parse error.
* @access public
*/
function acceptStartToken($token, $event) {
if ($event == LEXER_ENTER) {
$this->_tag = strtolower(substr($token, 1));
return true;
}
if ($event == LEXER_EXIT) {
$success = $this->_listener->startElement(
$this->_tag,
$this->_attributes);
$this->_tag = '';
$this->_attributes = array();
return $success;
}
if ($token != '=') {
$this->_current_attribute = strtolower(SimpleHtmlSaxParser::decodeHtml($token));
$this->_attributes[$this->_current_attribute] = '';
}
return true;
}
/**
* Accepts a token from the end tag mode.
* The element name is converted to lower case.
* @param string $token Incoming characters.
* @param integer $event Lexer event type.
* @return boolean False if parse error.
* @access public
*/
function acceptEndToken($token, $event) {
if (! preg_match('/<\/(.*)>/', $token, $matches)) {
return false;
}
return $this->_listener->endElement(strtolower($matches[1]));
}
/**
* Part of the tag data.
* @param string $token Incoming characters.
* @param integer $event Lexer event type.
* @return boolean False if parse error.
* @access public
*/
function acceptAttributeToken($token, $event) {
if ($this->_current_attribute) {
if ($event == LEXER_UNMATCHED) {
$this->_attributes[$this->_current_attribute] .=
SimpleHtmlSaxParser::decodeHtml($token);
}
if ($event == LEXER_SPECIAL) {
$this->_attributes[$this->_current_attribute] .=
preg_replace('/^=\s*/' , '', SimpleHtmlSaxParser::decodeHtml($token));
}
}
return true;
}
/**
* A character entity.
* @param string $token Incoming characters.
* @param integer $event Lexer event type.
* @return boolean False if parse error.
* @access public
*/
function acceptEntityToken($token, $event) {
}
/**
* Character data between tags regarded as
* important.
* @param string $token Incoming characters.
* @param integer $event Lexer event type.
* @return boolean False if parse error.
* @access public
*/
function acceptTextToken($token, $event) {
return $this->_listener->addContent($token);
}
/**
* Incoming data to be ignored.
* @param string $token Incoming characters.
* @param integer $event Lexer event type.
* @return boolean False if parse error.
* @access public
*/
function ignore($token, $event) {
return true;
}
/**
* Decodes any HTML entities.
* @param string $html Incoming HTML.
* @return string Outgoing plain text.
* @access public
* @static
*/
function decodeHtml($html) {
return html_entity_decode($html, ENT_QUOTES);
}
/**
* Turns HTML into text browser visible text. Images
* are converted to their alt text and tags are supressed.
* Entities are converted to their visible representation.
* @param string $html HTML to convert.
* @return string Plain text.
* @access public
* @static
*/
function normalise($html) {
$text = preg_replace('|<!--.*?-->|', '', $html);
$text = preg_replace('|<script[^>]*>.*?</script>|', '', $text);
$text = preg_replace('|<img[^>]*alt\s*=\s*"([^"]*)"[^>]*>|', ' \1 ', $text);
$text = preg_replace('|<img[^>]*alt\s*=\s*\'([^\']*)\'[^>]*>|', ' \1 ', $text);
$text = preg_replace('|<img[^>]*alt\s*=\s*([a-zA-Z_]+)[^>]*>|', ' \1 ', $text);
$text = preg_replace('|<[^>]*>|', '', $text);
$text = SimpleHtmlSaxParser::decodeHtml($text);
$text = preg_replace('|\s+|', ' ', $text);
return trim(trim($text), "\xA0"); // TODO: The \xAO is a &nbsp;. Add a test for this.
}
}
/**
* SAX event handler.
* @package SimpleTest
* @subpackage WebTester
* @abstract
*/
class SimpleSaxListener {
/**
* Sets the document to write to.
* @access public
*/
function SimpleSaxListener() {
}
/**
* Start of element event.
* @param string $name Element name.
* @param hash $attributes Name value pairs.
* Attributes without content
* are marked as true.
* @return boolean False on parse error.
* @access public
*/
function startElement($name, $attributes) {
}
/**
* End of element event.
* @param string $name Element name.
* @return boolean False on parse error.
* @access public
*/
function endElement($name) {
}
/**
* Unparsed, but relevant data.
* @param string $text May include unparsed tags.
* @return boolean False on parse error.
* @access public
*/
function addContent($text) {
}
}
?>

View file

@ -1,136 +0,0 @@
<?php
/**
* base include file for SimpleTest
* @package SimpleTest
* @subpackage UnitTester
* @version $Id: reflection_php4.php 1672 2008-03-02 04:47:34Z edwardzyang $
*/
/**
* Version specific reflection API.
* @package SimpleTest
* @subpackage UnitTester
* @ignore duplicate with reflection_php5.php
*/
class SimpleReflection {
var $_interface;
/**
* Stashes the class/interface.
* @param string $interface Class or interface
* to inspect.
*/
function SimpleReflection($interface) {
$this->_interface = $interface;
}
/**
* Checks that a class has been declared.
* @return boolean True if defined.
* @access public
*/
function classExists() {
return class_exists($this->_interface);
}
/**
* Needed to kill the autoload feature in PHP5
* for classes created dynamically.
* @return boolean True if defined.
* @access public
*/
function classExistsSansAutoload() {
return class_exists($this->_interface);
}
/**
* Checks that a class or interface has been
* declared.
* @return boolean True if defined.
* @access public
*/
function classOrInterfaceExists() {
return class_exists($this->_interface);
}
/**
* Needed to kill the autoload feature in PHP5
* for classes created dynamically.
* @return boolean True if defined.
* @access public
*/
function classOrInterfaceExistsSansAutoload() {
return class_exists($this->_interface);
}
/**
* Gets the list of methods on a class or
* interface.
* @returns array List of method names.
* @access public
*/
function getMethods() {
return get_class_methods($this->_interface);
}
/**
* Gets the list of interfaces from a class. If the
* class name is actually an interface then just that
* interface is returned.
* @returns array List of interfaces.
* @access public
*/
function getInterfaces() {
return array();
}
/**
* Finds the parent class name.
* @returns string Parent class name.
* @access public
*/
function getParent() {
return strtolower(get_parent_class($this->_interface));
}
/**
* Determines if the class is abstract, which for PHP 4
* will never be the case.
* @returns boolean True if abstract.
* @access public
*/
function isAbstract() {
return false;
}
/**
* Determines if the the entity is an interface, which for PHP 4
* will never be the case.
* @returns boolean True if interface.
* @access public
*/
function isInterface() {
return false;
}
/**
* Scans for final methods, but as it's PHP 4 there
* aren't any.
* @returns boolean True if the class has a final method.
* @access public
*/
function hasFinal() {
return false;
}
/**
* Gets the source code matching the declaration
* of a method.
* @param string $method Method name.
* @access public
*/
function getSignature($method) {
return "function &$method()";
}
}
?>

View file

@ -1,380 +0,0 @@
<?php
/**
* base include file for SimpleTest
* @package SimpleTest
* @subpackage UnitTester
* @version $Id: reflection_php5.php 1683 2008-03-05 21:57:08Z lastcraft $
*/
/**
* Version specific reflection API.
* @package SimpleTest
* @subpackage UnitTester
*/
class SimpleReflection {
var $_interface;
/**
* Stashes the class/interface.
* @param string $interface Class or interface
* to inspect.
*/
function SimpleReflection($interface) {
$this->_interface = $interface;
}
/**
* Checks that a class has been declared. Versions
* before PHP5.0.2 need a check that it's not really
* an interface.
* @return boolean True if defined.
* @access public
*/
function classExists() {
if (! class_exists($this->_interface)) {
return false;
}
$reflection = new ReflectionClass($this->_interface);
return ! $reflection->isInterface();
}
/**
* Needed to kill the autoload feature in PHP5
* for classes created dynamically.
* @return boolean True if defined.
* @access public
*/
function classExistsSansAutoload() {
return class_exists($this->_interface, false);
}
/**
* Checks that a class or interface has been
* declared.
* @return boolean True if defined.
* @access public
*/
function classOrInterfaceExists() {
return $this->_classOrInterfaceExistsWithAutoload($this->_interface, true);
}
/**
* Needed to kill the autoload feature in PHP5
* for classes created dynamically.
* @return boolean True if defined.
* @access public
*/
function classOrInterfaceExistsSansAutoload() {
return $this->_classOrInterfaceExistsWithAutoload($this->_interface, false);
}
/**
* Needed to select the autoload feature in PHP5
* for classes created dynamically.
* @param string $interface Class or interface name.
* @param boolean $autoload True totriggerautoload.
* @return boolean True if interface defined.
* @access private
*/
function _classOrInterfaceExistsWithAutoload($interface, $autoload) {
if (function_exists('interface_exists')) {
if (interface_exists($this->_interface, $autoload)) {
return true;
}
}
return class_exists($this->_interface, $autoload);
}
/**
* Gets the list of methods on a class or
* interface.
* @returns array List of method names.
* @access public
*/
function getMethods() {
return array_unique(get_class_methods($this->_interface));
}
/**
* Gets the list of interfaces from a class. If the
* class name is actually an interface then just that
* interface is returned.
* @returns array List of interfaces.
* @access public
*/
function getInterfaces() {
$reflection = new ReflectionClass($this->_interface);
if ($reflection->isInterface()) {
return array($this->_interface);
}
return $this->_onlyParents($reflection->getInterfaces());
}
/**
* Gets the list of methods for the implemented
* interfaces only.
* @returns array List of enforced method signatures.
* @access public
*/
function getInterfaceMethods() {
$methods = array();
foreach ($this->getInterfaces() as $interface) {
$methods = array_merge($methods, get_class_methods($interface));
}
return array_unique($methods);
}
/**
* Checks to see if the method signature has to be tightly
* specified.
* @param string $method Method name.
* @returns boolean True if enforced.
* @access private
*/
function _isInterfaceMethod($method) {
return in_array($method, $this->getInterfaceMethods());
}
/**
* Finds the parent class name.
* @returns string Parent class name.
* @access public
*/
function getParent() {
$reflection = new ReflectionClass($this->_interface);
$parent = $reflection->getParentClass();
if ($parent) {
return $parent->getName();
}
return false;
}
/**
* Trivially determines if the class is abstract.
* @returns boolean True if abstract.
* @access public
*/
function isAbstract() {
$reflection = new ReflectionClass($this->_interface);
return $reflection->isAbstract();
}
/**
* Trivially determines if the class is an interface.
* @returns boolean True if interface.
* @access public
*/
function isInterface() {
$reflection = new ReflectionClass($this->_interface);
return $reflection->isInterface();
}
/**
* Scans for final methods, as they screw up inherited
* mocks by not allowing you to override them.
* @returns boolean True if the class has a final method.
* @access public
*/
function hasFinal() {
$reflection = new ReflectionClass($this->_interface);
foreach ($reflection->getMethods() as $method) {
if ($method->isFinal()) {
return true;
}
}
return false;
}
/**
* Whittles a list of interfaces down to only the
* necessary top level parents.
* @param array $interfaces Reflection API interfaces
* to reduce.
* @returns array List of parent interface names.
* @access private
*/
function _onlyParents($interfaces) {
$parents = array();
$blacklist = array();
foreach ($interfaces as $interface) {
foreach($interfaces as $possible_parent) {
if ($interface->getName() == $possible_parent->getName()) {
continue;
}
if ($interface->isSubClassOf($possible_parent)) {
$blacklist[$possible_parent->getName()] = true;
}
}
if (!isset($blacklist[$interface->getName()])) {
$parents[] = $interface->getName();
}
}
return $parents;
}
/**
* Checks whether a method is abstract or not.
* @param string $name Method name.
* @return bool true if method is abstract, else false
* @access private
*/
function _isAbstractMethod($name) {
$interface = new ReflectionClass($this->_interface);
if (! $interface->hasMethod($name)) {
return false;
}
return $interface->getMethod($name)->isAbstract();
}
/**
* Checks whether a method is the constructor.
* @param string $name Method name.
* @return bool true if method is the constructor
* @access private
*/
function _isConstructor($name) {
return ($name == '__construct') || ($name == $this->_interface);
}
/**
* Checks whether a method is abstract in all parents or not.
* @param string $name Method name.
* @return bool true if method is abstract in parent, else false
* @access private
*/
function _isAbstractMethodInParents($name) {
$interface = new ReflectionClass($this->_interface);
$parent = $interface->getParentClass();
while($parent) {
if (! $parent->hasMethod($name)) {
return false;
}
if ($parent->getMethod($name)->isAbstract()) {
return true;
}
$parent = $parent->getParentClass();
}
return false;
}
/**
* Checks whether a method is static or not.
* @param string $name Method name
* @return bool true if method is static, else false
* @access private
*/
function _isStaticMethod($name) {
$interface = new ReflectionClass($this->_interface);
if (! $interface->hasMethod($name)) {
return false;
}
return $interface->getMethod($name)->isStatic();
}
/**
* Writes the source code matching the declaration
* of a method.
* @param string $name Method name.
* @return string Method signature up to last
* bracket.
* @access public
*/
function getSignature($name) {
if ($name == '__set') {
return 'function __set($key, $value)';
}
if ($name == '__call') {
return 'function __call($method, $arguments)';
}
if (version_compare(phpversion(), '5.1.0', '>=')) {
if (in_array($name, array('__get', '__isset', $name == '__unset'))) {
return "function {$name}(\$key)";
}
}
if ($name == '__toString') {
return "function $name()";
}
if ($this->_isInterfaceMethod($name) ||
$this->_isAbstractMethod($name) ||
$this->_isAbstractMethodInParents($name) ||
$this->_isStaticMethod($name)) {
return $this->_getFullSignature($name);
}
return "function $name()";
}
/**
* For a signature specified in an interface, full
* details must be replicated to be a valid implementation.
* @param string $name Method name.
* @return string Method signature up to last
* bracket.
* @access private
*/
function _getFullSignature($name) {
$interface = new ReflectionClass($this->_interface);
$method = $interface->getMethod($name);
$reference = $method->returnsReference() ? '&' : '';
$static = $method->isStatic() ? 'static ' : '';
return "{$static}function $reference$name(" .
implode(', ', $this->_getParameterSignatures($method)) .
")";
}
/**
* Gets the source code for each parameter.
* @param ReflectionMethod $method Method object from
* reflection API
* @return array List of strings, each
* a snippet of code.
* @access private
*/
function _getParameterSignatures($method) {
$signatures = array();
foreach ($method->getParameters() as $parameter) {
$signature = '';
$type = $parameter->getClass();
if (is_null($type) && version_compare(phpversion(), '5.1.0', '>=') && $parameter->isArray()) {
$signature .= 'array ';
} elseif (!is_null($type)) {
$signature .= $type->getName() . ' ';
}
if ($parameter->isPassedByReference()) {
$signature .= '&';
}
$signature .= '$' . $this->_suppressSpurious($parameter->getName());
if ($this->_isOptional($parameter)) {
$signature .= ' = null';
}
$signatures[] = $signature;
}
return $signatures;
}
/**
* The SPL library has problems with the
* Reflection library. In particular, you can
* get extra characters in parameter names :(.
* @param string $name Parameter name.
* @return string Cleaner name.
* @access private
*/
function _suppressSpurious($name) {
return str_replace(array('[', ']', ' '), '', $name);
}
/**
* Test of a reflection parameter being optional
* that works with early versions of PHP5.
* @param reflectionParameter $parameter Is this optional.
* @return boolean True if optional.
* @access private
*/
function _isOptional($parameter) {
if (method_exists($parameter, 'isOptional')) {
return $parameter->isOptional();
}
return false;
}
}
?>

View file

@ -1,117 +0,0 @@
<?php
/**
* base include file for SimpleTest
* @package SimpleTest
* @subpackage UnitTester
* @version $Id: remote.php 1723 2008-04-08 00:34:10Z lastcraft $
*/
/**#@+
* include other SimpleTest class files
*/
require_once(dirname(__FILE__) . '/browser.php');
require_once(dirname(__FILE__) . '/xml.php');
require_once(dirname(__FILE__) . '/test_case.php');
/**#@-*/
/**
* Runs an XML formated test on a remote server.
* @package SimpleTest
* @subpackage UnitTester
*/
class RemoteTestCase {
var $_url;
var $_dry_url;
var $_size;
/**
* Sets the location of the remote test.
* @param string $url Test location.
* @param string $dry_url Location for dry run.
* @access public
*/
function RemoteTestCase($url, $dry_url = false) {
$this->_url = $url;
$this->_dry_url = $dry_url ? $dry_url : $url;
$this->_size = false;
}
/**
* Accessor for the test name for subclasses.
* @return string Name of the test.
* @access public
*/
function getLabel() {
return $this->_url;
}
/**
* Runs the top level test for this class. Currently
* reads the data as a single chunk. I'll fix this
* once I have added iteration to the browser.
* @param SimpleReporter $reporter Target of test results.
* @returns boolean True if no failures.
* @access public
*/
function run(&$reporter) {
$browser = &$this->_createBrowser();
$xml = $browser->get($this->_url);
if (! $xml) {
trigger_error('Cannot read remote test URL [' . $this->_url . ']');
return false;
}
$parser = &$this->_createParser($reporter);
if (! $parser->parse($xml)) {
trigger_error('Cannot parse incoming XML from [' . $this->_url . ']');
return false;
}
return true;
}
/**
* Creates a new web browser object for fetching
* the XML report.
* @return SimpleBrowser New browser.
* @access protected
*/
function &_createBrowser() {
$browser = &new SimpleBrowser();
return $browser;
}
/**
* Creates the XML parser.
* @param SimpleReporter $reporter Target of test results.
* @return SimpleTestXmlListener XML reader.
* @access protected
*/
function &_createParser(&$reporter) {
$parser = &new SimpleTestXmlParser($reporter);
return $parser;
}
/**
* Accessor for the number of subtests.
* @return integer Number of test cases.
* @access public
*/
function getSize() {
if ($this->_size === false) {
$browser = &$this->_createBrowser();
$xml = $browser->get($this->_dry_url);
if (! $xml) {
trigger_error('Cannot read remote test URL [' . $this->_dry_url . ']');
return false;
}
$reporter = &new SimpleReporter();
$parser = &$this->_createParser($reporter);
if (! $parser->parse($xml)) {
trigger_error('Cannot parse incoming XML from [' . $this->_dry_url . ']');
return false;
}
$this->_size = $reporter->getTestCaseCount();
}
return $this->_size;
}
}
?>

View file

@ -1,447 +0,0 @@
<?php
/**
* base include file for SimpleTest
* @package SimpleTest
* @subpackage UnitTester
* @version $Id: reporter.php 1702 2008-03-25 00:08:04Z lastcraft $
*/
/**#@+
* include other SimpleTest class files
*/
require_once(dirname(__FILE__) . '/scorer.php');
/**#@-*/
/**
* Sample minimal test displayer. Generates only
* failure messages and a pass count.
* @package SimpleTest
* @subpackage UnitTester
*/
class HtmlReporter extends SimpleReporter {
var $_character_set;
/**
* Does nothing yet. The first output will
* be sent on the first test start. For use
* by a web browser.
* @access public
*/
function HtmlReporter($character_set = 'ISO-8859-1') {
$this->SimpleReporter();
$this->_character_set = $character_set;
}
/**
* Paints the top of the web page setting the
* title to the name of the starting test.
* @param string $test_name Name class of test.
* @access public
*/
function paintHeader($test_name) {
$this->sendNoCacheHeaders();
print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">";
print "<html>\n<head>\n<title>$test_name</title>\n";
print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=" .
$this->_character_set . "\">\n";
print "<style type=\"text/css\">\n";
print $this->_getCss() . "\n";
print "</style>\n";
print "</head>\n<body>\n";
print "<h1>$test_name</h1>\n";
flush();
}
/**
* Send the headers necessary to ensure the page is
* reloaded on every request. Otherwise you could be
* scratching your head over out of date test data.
* @access public
* @static
*/
function sendNoCacheHeaders() {
if (! headers_sent()) {
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
}
}
/**
* Paints the CSS. Add additional styles here.
* @return string CSS code as text.
* @access protected
*/
function _getCss() {
return ".fail { background-color: inherit; color: red; }" .
".pass { background-color: inherit; color: green; }" .
" pre { background-color: lightgray; color: inherit; }";
}
/**
* Paints the end of the test with a summary of
* the passes and failures.
* @param string $test_name Name class of test.
* @access public
*/
function paintFooter($test_name) {
$colour = ($this->getFailCount() + $this->getExceptionCount() > 0 ? "red" : "green");
print "<div style=\"";
print "padding: 8px; margin-top: 1em; background-color: $colour; color: white;";
print "\">";
print $this->getTestCaseProgress() . "/" . $this->getTestCaseCount();
print " test cases complete:\n";
print "<strong>" . $this->getPassCount() . "</strong> passes, ";
print "<strong>" . $this->getFailCount() . "</strong> fails and ";
print "<strong>" . $this->getExceptionCount() . "</strong> exceptions.";
print "</div>\n";
print "</body>\n</html>\n";
}
/**
* Paints the test failure with a breadcrumbs
* trail of the nesting test suites below the
* top level test.
* @param string $message Failure message displayed in
* the context of the other tests.
* @access public
*/
function paintFail($message) {
parent::paintFail($message);
print "<span class=\"fail\">Fail</span>: ";
$breadcrumb = $this->getTestList();
array_shift($breadcrumb);
print implode(" -&gt; ", $breadcrumb);
print " -&gt; " . $this->_htmlEntities($message) . "<br />\n";
}
/**
* Paints a PHP error.
* @param string $message Message is ignored.
* @access public
*/
function paintError($message) {
parent::paintError($message);
print "<span class=\"fail\">Exception</span>: ";
$breadcrumb = $this->getTestList();
array_shift($breadcrumb);
print implode(" -&gt; ", $breadcrumb);
print " -&gt; <strong>" . $this->_htmlEntities($message) . "</strong><br />\n";
}
/**
* Paints a PHP exception.
* @param Exception $exception Exception to display.
* @access public
*/
function paintException($exception) {
parent::paintException($exception);
print "<span class=\"fail\">Exception</span>: ";
$breadcrumb = $this->getTestList();
array_shift($breadcrumb);
print implode(" -&gt; ", $breadcrumb);
$message = 'Unexpected exception of type [' . get_class($exception) .
'] with message ['. $exception->getMessage() .
'] in ['. $exception->getFile() .
' line ' . $exception->getLine() . ']';
print " -&gt; <strong>" . $this->_htmlEntities($message) . "</strong><br />\n";
}
/**
* Prints the message for skipping tests.
* @param string $message Text of skip condition.
* @access public
*/
function paintSkip($message) {
parent::paintSkip($message);
print "<span class=\"pass\">Skipped</span>: ";
$breadcrumb = $this->getTestList();
array_shift($breadcrumb);
print implode(" -&gt; ", $breadcrumb);
print " -&gt; " . $this->_htmlEntities($message) . "<br />\n";
}
/**
* Paints formatted text such as dumped variables.
* @param string $message Text to show.
* @access public
*/
function paintFormattedMessage($message) {
print '<pre>' . $this->_htmlEntities($message) . '</pre>';
}
/**
* Character set adjusted entity conversion.
* @param string $message Plain text or Unicode message.
* @return string Browser readable message.
* @access protected
*/
function _htmlEntities($message) {
return htmlentities($message, ENT_COMPAT, $this->_character_set);
}
}
/**
* Sample minimal test displayer. Generates only
* failure messages and a pass count. For command
* line use. I've tried to make it look like JUnit,
* but I wanted to output the errors as they arrived
* which meant dropping the dots.
* @package SimpleTest
* @subpackage UnitTester
*/
class TextReporter extends SimpleReporter {
/**
* Does nothing yet. The first output will
* be sent on the first test start.
* @access public
*/
function TextReporter() {
$this->SimpleReporter();
}
/**
* Paints the title only.
* @param string $test_name Name class of test.
* @access public
*/
function paintHeader($test_name) {
if (! SimpleReporter::inCli()) {
header('Content-type: text/plain');
}
print "$test_name\n";
flush();
}
/**
* Paints the end of the test with a summary of
* the passes and failures.
* @param string $test_name Name class of test.
* @access public
*/
function paintFooter($test_name) {
if ($this->getFailCount() + $this->getExceptionCount() == 0) {
print "OK\n";
} else {
print "FAILURES!!!\n";
}
print "Test cases run: " . $this->getTestCaseProgress() .
"/" . $this->getTestCaseCount() .
", Passes: " . $this->getPassCount() .
", Failures: " . $this->getFailCount() .
", Exceptions: " . $this->getExceptionCount() . "\n";
}
/**
* Paints the test failure as a stack trace.
* @param string $message Failure message displayed in
* the context of the other tests.
* @access public
*/
function paintFail($message) {
parent::paintFail($message);
print $this->getFailCount() . ") $message\n";
$breadcrumb = $this->getTestList();
array_shift($breadcrumb);
print "\tin " . implode("\n\tin ", array_reverse($breadcrumb));
print "\n";
}
/**
* Paints a PHP error or exception.
* @param string $message Message to be shown.
* @access public
* @abstract
*/
function paintError($message) {
parent::paintError($message);
print "Exception " . $this->getExceptionCount() . "!\n$message\n";
$breadcrumb = $this->getTestList();
array_shift($breadcrumb);
print "\tin " . implode("\n\tin ", array_reverse($breadcrumb));
print "\n";
}
/**
* Paints a PHP error or exception.
* @param Exception $exception Exception to describe.
* @access public
* @abstract
*/
function paintException($exception) {
parent::paintException($exception);
$message = 'Unexpected exception of type [' . get_class($exception) .
'] with message ['. $exception->getMessage() .
'] in ['. $exception->getFile() .
' line ' . $exception->getLine() . ']';
print "Exception " . $this->getExceptionCount() . "!\n$message\n";
$breadcrumb = $this->getTestList();
array_shift($breadcrumb);
print "\tin " . implode("\n\tin ", array_reverse($breadcrumb));
print "\n";
}
/**
* Prints the message for skipping tests.
* @param string $message Text of skip condition.
* @access public
*/
function paintSkip($message) {
parent::paintSkip($message);
print "Skip: $message\n";
}
/**
* Paints formatted text such as dumped variables.
* @param string $message Text to show.
* @access public
*/
function paintFormattedMessage($message) {
print "$message\n";
flush();
}
}
/**
* Runs just a single test group, a single case or
* even a single test within that case.
* @package SimpleTest
* @subpackage UnitTester
*/
class SelectiveReporter extends SimpleReporterDecorator {
var $_just_this_case = false;
var $_just_this_test = false;
var $_on;
/**
* Selects the test case or group to be run,
* and optionally a specific test.
* @param SimpleScorer $reporter Reporter to receive events.
* @param string $just_this_case Only this case or group will run.
* @param string $just_this_test Only this test method will run.
*/
function SelectiveReporter(&$reporter, $just_this_case = false, $just_this_test = false) {
if (isset($just_this_case) && $just_this_case) {
$this->_just_this_case = strtolower($just_this_case);
$this->_off();
} else {
$this->_on();
}
if (isset($just_this_test) && $just_this_test) {
$this->_just_this_test = strtolower($just_this_test);
}
$this->SimpleReporterDecorator($reporter);
}
/**
* Compares criteria to actual the case/group name.
* @param string $test_case The incoming test.
* @return boolean True if matched.
* @access protected
*/
function _matchesTestCase($test_case) {
return $this->_just_this_case == strtolower($test_case);
}
/**
* Compares criteria to actual the test name. If no
* name was specified at the beginning, then all tests
* can run.
* @param string $method The incoming test method.
* @return boolean True if matched.
* @access protected
*/
function _shouldRunTest($test_case, $method) {
if ($this->_isOn() || $this->_matchesTestCase($test_case)) {
if ($this->_just_this_test) {
return $this->_just_this_test == strtolower($method);
} else {
return true;
}
}
return false;
}
/**
* Switch on testing for the group or subgroup.
* @access private
*/
function _on() {
$this->_on = true;
}
/**
* Switch off testing for the group or subgroup.
* @access private
*/
function _off() {
$this->_on = false;
}
/**
* Is this group actually being tested?
* @return boolean True if the current test group is active.
* @access private
*/
function _isOn() {
return $this->_on;
}
/**
* Veto everything that doesn't match the method wanted.
* @param string $test_case Name of test case.
* @param string $method Name of test method.
* @return boolean True if test should be run.
* @access public
*/
function shouldInvoke($test_case, $method) {
if ($this->_shouldRunTest($test_case, $method)) {
return $this->_reporter->shouldInvoke($test_case, $method);
}
return false;
}
/**
* Paints the start of a group test.
* @param string $test_case Name of test or other label.
* @param integer $size Number of test cases starting.
* @access public
*/
function paintGroupStart($test_case, $size) {
if ($this->_just_this_case && $this->_matchesTestCase($test_case)) {
$this->_on();
}
$this->_reporter->paintGroupStart($test_case, $size);
}
/**
* Paints the end of a group test.
* @param string $test_case Name of test or other label.
* @access public
*/
function paintGroupEnd($test_case) {
$this->_reporter->paintGroupEnd($test_case);
if ($this->_just_this_case && $this->_matchesTestCase($test_case)) {
$this->_off();
}
}
}
/**
* Suppresses skip messages.
* @package SimpleTest
* @subpackage UnitTester
*/
class NoSkipsReporter extends SimpleReporterDecorator {
/**
* Does nothing.
* @param string $message Text of skip condition.
* @access public
*/
function paintSkip($message) { }
}
?>

View file

@ -1,863 +0,0 @@
<?php
/**
* base include file for SimpleTest
* @package SimpleTest
* @subpackage UnitTester
* @version $Id: scorer.php 1723 2008-04-08 00:34:10Z lastcraft $
*/
/**#@+*/
require_once(dirname(__FILE__) . '/invoker.php');
/**#@-*/
/**
* Can receive test events and display them. Display
* is achieved by making display methods available
* and visiting the incoming event.
* @package SimpleTest
* @subpackage UnitTester
* @abstract
*/
class SimpleScorer {
var $_passes;
var $_fails;
var $_exceptions;
var $_is_dry_run;
/**
* Starts the test run with no results.
* @access public
*/
function SimpleScorer() {
$this->_passes = 0;
$this->_fails = 0;
$this->_exceptions = 0;
$this->_is_dry_run = false;
}
/**
* Signals that the next evaluation will be a dry
* run. That is, the structure events will be
* recorded, but no tests will be run.
* @param boolean $is_dry Dry run if true.
* @access public
*/
function makeDry($is_dry = true) {
$this->_is_dry_run = $is_dry;
}
/**
* The reporter has a veto on what should be run.
* @param string $test_case_name name of test case.
* @param string $method Name of test method.
* @access public
*/
function shouldInvoke($test_case_name, $method) {
return ! $this->_is_dry_run;
}
/**
* Can wrap the invoker in preperation for running
* a test.
* @param SimpleInvoker $invoker Individual test runner.
* @return SimpleInvoker Wrapped test runner.
* @access public
*/
function &createInvoker(&$invoker) {
return $invoker;
}
/**
* Accessor for current status. Will be false
* if there have been any failures or exceptions.
* Used for command line tools.
* @return boolean True if no failures.
* @access public
*/
function getStatus() {
if ($this->_exceptions + $this->_fails > 0) {
return false;
}
return true;
}
/**
* Paints the start of a group test.
* @param string $test_name Name of test or other label.
* @param integer $size Number of test cases starting.
* @access public
*/
function paintGroupStart($test_name, $size) {
}
/**
* Paints the end of a group test.
* @param string $test_name Name of test or other label.
* @access public
*/
function paintGroupEnd($test_name) {
}
/**
* Paints the start of a test case.
* @param string $test_name Name of test or other label.
* @access public
*/
function paintCaseStart($test_name) {
}
/**
* Paints the end of a test case.
* @param string $test_name Name of test or other label.
* @access public
*/
function paintCaseEnd($test_name) {
}
/**
* Paints the start of a test method.
* @param string $test_name Name of test or other label.
* @access public
*/
function paintMethodStart($test_name) {
}
/**
* Paints the end of a test method.
* @param string $test_name Name of test or other label.
* @access public
*/
function paintMethodEnd($test_name) {
}
/**
* Increments the pass count.
* @param string $message Message is ignored.
* @access public
*/
function paintPass($message) {
$this->_passes++;
}
/**
* Increments the fail count.
* @param string $message Message is ignored.
* @access public
*/
function paintFail($message) {
$this->_fails++;
}
/**
* Deals with PHP 4 throwing an error.
* @param string $message Text of error formatted by
* the test case.
* @access public
*/
function paintError($message) {
$this->_exceptions++;
}
/**
* Deals with PHP 5 throwing an exception.
* @param Exception $exception The actual exception thrown.
* @access public
*/
function paintException($exception) {
$this->_exceptions++;
}
/**
* Prints the message for skipping tests.
* @param string $message Text of skip condition.
* @access public
*/
function paintSkip($message) {
}
/**
* Accessor for the number of passes so far.
* @return integer Number of passes.
* @access public
*/
function getPassCount() {
return $this->_passes;
}
/**
* Accessor for the number of fails so far.
* @return integer Number of fails.
* @access public
*/
function getFailCount() {
return $this->_fails;
}
/**
* Accessor for the number of untrapped errors
* so far.
* @return integer Number of exceptions.
* @access public
*/
function getExceptionCount() {
return $this->_exceptions;
}
/**
* Paints a simple supplementary message.
* @param string $message Text to display.
* @access public
*/
function paintMessage($message) {
}
/**
* Paints a formatted ASCII message such as a
* variable dump.
* @param string $message Text to display.
* @access public
*/
function paintFormattedMessage($message) {
}
/**
* By default just ignores user generated events.
* @param string $type Event type as text.
* @param mixed $payload Message or object.
* @access public
*/
function paintSignal($type, $payload) {
}
}
/**
* Recipient of generated test messages that can display
* page footers and headers. Also keeps track of the
* test nesting. This is the main base class on which
* to build the finished test (page based) displays.
* @package SimpleTest
* @subpackage UnitTester
*/
class SimpleReporter extends SimpleScorer {
var $_test_stack;
var $_size;
var $_progress;
/**
* Starts the display with no results in.
* @access public
*/
function SimpleReporter() {
$this->SimpleScorer();
$this->_test_stack = array();
$this->_size = null;
$this->_progress = 0;
}
/**
* Gets the formatter for variables and other small
* generic data items.
* @return SimpleDumper Formatter.
* @access public
*/
function getDumper() {
return new SimpleDumper();
}
/**
* Paints the start of a group test. Will also paint
* the page header and footer if this is the
* first test. Will stash the size if the first
* start.
* @param string $test_name Name of test that is starting.
* @param integer $size Number of test cases starting.
* @access public
*/
function paintGroupStart($test_name, $size) {
if (! isset($this->_size)) {
$this->_size = $size;
}
if (count($this->_test_stack) == 0) {
$this->paintHeader($test_name);
}
$this->_test_stack[] = $test_name;
}
/**
* Paints the end of a group test. Will paint the page
* footer if the stack of tests has unwound.
* @param string $test_name Name of test that is ending.
* @param integer $progress Number of test cases ending.
* @access public
*/
function paintGroupEnd($test_name) {
array_pop($this->_test_stack);
if (count($this->_test_stack) == 0) {
$this->paintFooter($test_name);
}
}
/**
* Paints the start of a test case. Will also paint
* the page header and footer if this is the
* first test. Will stash the size if the first
* start.
* @param string $test_name Name of test that is starting.
* @access public
*/
function paintCaseStart($test_name) {
if (! isset($this->_size)) {
$this->_size = 1;
}
if (count($this->_test_stack) == 0) {
$this->paintHeader($test_name);
}
$this->_test_stack[] = $test_name;
}
/**
* Paints the end of a test case. Will paint the page
* footer if the stack of tests has unwound.
* @param string $test_name Name of test that is ending.
* @access public
*/
function paintCaseEnd($test_name) {
$this->_progress++;
array_pop($this->_test_stack);
if (count($this->_test_stack) == 0) {
$this->paintFooter($test_name);
}
}
/**
* Paints the start of a test method.
* @param string $test_name Name of test that is starting.
* @access public
*/
function paintMethodStart($test_name) {
$this->_test_stack[] = $test_name;
}
/**
* Paints the end of a test method. Will paint the page
* footer if the stack of tests has unwound.
* @param string $test_name Name of test that is ending.
* @access public
*/
function paintMethodEnd($test_name) {
array_pop($this->_test_stack);
}
/**
* Paints the test document header.
* @param string $test_name First test top level
* to start.
* @access public
* @abstract
*/
function paintHeader($test_name) {
}
/**
* Paints the test document footer.
* @param string $test_name The top level test.
* @access public
* @abstract
*/
function paintFooter($test_name) {
}
/**
* Accessor for internal test stack. For
* subclasses that need to see the whole test
* history for display purposes.
* @return array List of methods in nesting order.
* @access public
*/
function getTestList() {
return $this->_test_stack;
}
/**
* Accessor for total test size in number
* of test cases. Null until the first
* test is started.
* @return integer Total number of cases at start.
* @access public
*/
function getTestCaseCount() {
return $this->_size;
}
/**
* Accessor for the number of test cases
* completed so far.
* @return integer Number of ended cases.
* @access public
*/
function getTestCaseProgress() {
return $this->_progress;
}
/**
* Static check for running in the comand line.
* @return boolean True if CLI.
* @access public
* @static
*/
function inCli() {
return php_sapi_name() == 'cli';
}
}
/**
* For modifying the behaviour of the visual reporters.
* @package SimpleTest
* @subpackage UnitTester
*/
class SimpleReporterDecorator {
var $_reporter;
/**
* Mediates between the reporter and the test case.
* @param SimpleScorer $reporter Reporter to receive events.
*/
function SimpleReporterDecorator(&$reporter) {
$this->_reporter = &$reporter;
}
/**
* Signals that the next evaluation will be a dry
* run. That is, the structure events will be
* recorded, but no tests will be run.
* @param boolean $is_dry Dry run if true.
* @access public
*/
function makeDry($is_dry = true) {
$this->_reporter->makeDry($is_dry);
}
/**
* Accessor for current status. Will be false
* if there have been any failures or exceptions.
* Used for command line tools.
* @return boolean True if no failures.
* @access public
*/
function getStatus() {
return $this->_reporter->getStatus();
}
/**
* The reporter has a veto on what should be run.
* @param string $test_case_name name of test case.
* @param string $method Name of test method.
* @return boolean True if test should be run.
* @access public
*/
function shouldInvoke($test_case_name, $method) {
return $this->_reporter->shouldInvoke($test_case_name, $method);
}
/**
* Can wrap the invoker in preperation for running
* a test.
* @param SimpleInvoker $invoker Individual test runner.
* @return SimpleInvoker Wrapped test runner.
* @access public
*/
function &createInvoker(&$invoker) {
return $this->_reporter->createInvoker($invoker);
}
/**
* Gets the formatter for variables and other small
* generic data items.
* @return SimpleDumper Formatter.
* @access public
*/
function getDumper() {
return $this->_reporter->getDumper();
}
/**
* Paints the start of a group test.
* @param string $test_name Name of test or other label.
* @param integer $size Number of test cases starting.
* @access public
*/
function paintGroupStart($test_name, $size) {
$this->_reporter->paintGroupStart($test_name, $size);
}
/**
* Paints the end of a group test.
* @param string $test_name Name of test or other label.
* @access public
*/
function paintGroupEnd($test_name) {
$this->_reporter->paintGroupEnd($test_name);
}
/**
* Paints the start of a test case.
* @param string $test_name Name of test or other label.
* @access public
*/
function paintCaseStart($test_name) {
$this->_reporter->paintCaseStart($test_name);
}
/**
* Paints the end of a test case.
* @param string $test_name Name of test or other label.
* @access public
*/
function paintCaseEnd($test_name) {
$this->_reporter->paintCaseEnd($test_name);
}
/**
* Paints the start of a test method.
* @param string $test_name Name of test or other label.
* @access public
*/
function paintMethodStart($test_name) {
$this->_reporter->paintMethodStart($test_name);
}
/**
* Paints the end of a test method.
* @param string $test_name Name of test or other label.
* @access public
*/
function paintMethodEnd($test_name) {
$this->_reporter->paintMethodEnd($test_name);
}
/**
* Chains to the wrapped reporter.
* @param string $message Message is ignored.
* @access public
*/
function paintPass($message) {
$this->_reporter->paintPass($message);
}
/**
* Chains to the wrapped reporter.
* @param string $message Message is ignored.
* @access public
*/
function paintFail($message) {
$this->_reporter->paintFail($message);
}
/**
* Chains to the wrapped reporter.
* @param string $message Text of error formatted by
* the test case.
* @access public
*/
function paintError($message) {
$this->_reporter->paintError($message);
}
/**
* Chains to the wrapped reporter.
* @param Exception $exception Exception to show.
* @access public
*/
function paintException($exception) {
$this->_reporter->paintException($exception);
}
/**
* Prints the message for skipping tests.
* @param string $message Text of skip condition.
* @access public
*/
function paintSkip($message) {
$this->_reporter->paintSkip($message);
}
/**
* Chains to the wrapped reporter.
* @param string $message Text to display.
* @access public
*/
function paintMessage($message) {
$this->_reporter->paintMessage($message);
}
/**
* Chains to the wrapped reporter.
* @param string $message Text to display.
* @access public
*/
function paintFormattedMessage($message) {
$this->_reporter->paintFormattedMessage($message);
}
/**
* Chains to the wrapped reporter.
* @param string $type Event type as text.
* @param mixed $payload Message or object.
* @return boolean Should return false if this
* type of signal should fail the
* test suite.
* @access public
*/
function paintSignal($type, &$payload) {
$this->_reporter->paintSignal($type, $payload);
}
}
/**
* For sending messages to multiple reporters at
* the same time.
* @package SimpleTest
* @subpackage UnitTester
*/
class MultipleReporter {
var $_reporters = array();
/**
* Adds a reporter to the subscriber list.
* @param SimpleScorer $reporter Reporter to receive events.
* @access public
*/
function attachReporter(&$reporter) {
$this->_reporters[] = &$reporter;
}
/**
* Signals that the next evaluation will be a dry
* run. That is, the structure events will be
* recorded, but no tests will be run.
* @param boolean $is_dry Dry run if true.
* @access public
*/
function makeDry($is_dry = true) {
for ($i = 0; $i < count($this->_reporters); $i++) {
$this->_reporters[$i]->makeDry($is_dry);
}
}
/**
* Accessor for current status. Will be false
* if there have been any failures or exceptions.
* If any reporter reports a failure, the whole
* suite fails.
* @return boolean True if no failures.
* @access public
*/
function getStatus() {
for ($i = 0; $i < count($this->_reporters); $i++) {
if (! $this->_reporters[$i]->getStatus()) {
return false;
}
}
return true;
}
/**
* The reporter has a veto on what should be run.
* It requires all reporters to want to run the method.
* @param string $test_case_name name of test case.
* @param string $method Name of test method.
* @access public
*/
function shouldInvoke($test_case_name, $method) {
for ($i = 0; $i < count($this->_reporters); $i++) {
if (! $this->_reporters[$i]->shouldInvoke($test_case_name, $method)) {
return false;
}
}
return true;
}
/**
* Every reporter gets a chance to wrap the invoker.
* @param SimpleInvoker $invoker Individual test runner.
* @return SimpleInvoker Wrapped test runner.
* @access public
*/
function &createInvoker(&$invoker) {
for ($i = 0; $i < count($this->_reporters); $i++) {
$invoker = &$this->_reporters[$i]->createInvoker($invoker);
}
return $invoker;
}
/**
* Gets the formatter for variables and other small
* generic data items.
* @return SimpleDumper Formatter.
* @access public
*/
function getDumper() {
return new SimpleDumper();
}
/**
* Paints the start of a group test.
* @param string $test_name Name of test or other label.
* @param integer $size Number of test cases starting.
* @access public
*/
function paintGroupStart($test_name, $size) {
for ($i = 0; $i < count($this->_reporters); $i++) {
$this->_reporters[$i]->paintGroupStart($test_name, $size);
}
}
/**
* Paints the end of a group test.
* @param string $test_name Name of test or other label.
* @access public
*/
function paintGroupEnd($test_name) {
for ($i = 0; $i < count($this->_reporters); $i++) {
$this->_reporters[$i]->paintGroupEnd($test_name);
}
}
/**
* Paints the start of a test case.
* @param string $test_name Name of test or other label.
* @access public
*/
function paintCaseStart($test_name) {
for ($i = 0; $i < count($this->_reporters); $i++) {
$this->_reporters[$i]->paintCaseStart($test_name);
}
}
/**
* Paints the end of a test case.
* @param string $test_name Name of test or other label.
* @access public
*/
function paintCaseEnd($test_name) {
for ($i = 0; $i < count($this->_reporters); $i++) {
$this->_reporters[$i]->paintCaseEnd($test_name);
}
}
/**
* Paints the start of a test method.
* @param string $test_name Name of test or other label.
* @access public
*/
function paintMethodStart($test_name) {
for ($i = 0; $i < count($this->_reporters); $i++) {
$this->_reporters[$i]->paintMethodStart($test_name);
}
}
/**
* Paints the end of a test method.
* @param string $test_name Name of test or other label.
* @access public
*/
function paintMethodEnd($test_name) {
for ($i = 0; $i < count($this->_reporters); $i++) {
$this->_reporters[$i]->paintMethodEnd($test_name);
}
}
/**
* Chains to the wrapped reporter.
* @param string $message Message is ignored.
* @access public
*/
function paintPass($message) {
for ($i = 0; $i < count($this->_reporters); $i++) {
$this->_reporters[$i]->paintPass($message);
}
}
/**
* Chains to the wrapped reporter.
* @param string $message Message is ignored.
* @access public
*/
function paintFail($message) {
for ($i = 0; $i < count($this->_reporters); $i++) {
$this->_reporters[$i]->paintFail($message);
}
}
/**
* Chains to the wrapped reporter.
* @param string $message Text of error formatted by
* the test case.
* @access public
*/
function paintError($message) {
for ($i = 0; $i < count($this->_reporters); $i++) {
$this->_reporters[$i]->paintError($message);
}
}
/**
* Chains to the wrapped reporter.
* @param Exception $exception Exception to display.
* @access public
*/
function paintException($exception) {
for ($i = 0; $i < count($this->_reporters); $i++) {
$this->_reporters[$i]->paintException($exception);
}
}
/**
* Prints the message for skipping tests.
* @param string $message Text of skip condition.
* @access public
*/
function paintSkip($message) {
for ($i = 0; $i < count($this->_reporters); $i++) {
$this->_reporters[$i]->paintSkip($message);
}
}
/**
* Chains to the wrapped reporter.
* @param string $message Text to display.
* @access public
*/
function paintMessage($message) {
for ($i = 0; $i < count($this->_reporters); $i++) {
$this->_reporters[$i]->paintMessage($message);
}
}
/**
* Chains to the wrapped reporter.
* @param string $message Text to display.
* @access public
*/
function paintFormattedMessage($message) {
for ($i = 0; $i < count($this->_reporters); $i++) {
$this->_reporters[$i]->paintFormattedMessage($message);
}
}
/**
* Chains to the wrapped reporter.
* @param string $type Event type as text.
* @param mixed $payload Message or object.
* @return boolean Should return false if this
* type of signal should fail the
* test suite.
* @access public
*/
function paintSignal($type, &$payload) {
for ($i = 0; $i < count($this->_reporters); $i++) {
$this->_reporters[$i]->paintSignal($type, $payload);
}
}
}
?>

View file

@ -1,137 +0,0 @@
<?php
/**
* Base include file for SimpleTest.
* @package SimpleTest
* @subpackage WebTester
* @version $Id: selector.php 1723 2008-04-08 00:34:10Z lastcraft $
*/
/**#@+
* include SimpleTest files
*/
require_once(dirname(__FILE__) . '/tag.php');
require_once(dirname(__FILE__) . '/encoding.php');
/**#@-*/
/**
* Used to extract form elements for testing against.
* Searches by name attribute.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleByName {
var $_name;
/**
* Stashes the name for later comparison.
* @param string $name Name attribute to match.
*/
function SimpleByName($name) {
$this->_name = $name;
}
function getName() {
return $this->_name;
}
/**
* Compares with name attribute of widget.
* @param SimpleWidget $widget Control to compare.
* @access public
*/
function isMatch($widget) {
return ($widget->getName() == $this->_name);
}
}
/**
* Used to extract form elements for testing against.
* Searches by visible label or alt text.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleByLabel {
var $_label;
/**
* Stashes the name for later comparison.
* @param string $label Visible text to match.
*/
function SimpleByLabel($label) {
$this->_label = $label;
}
/**
* Comparison. Compares visible text of widget or
* related label.
* @param SimpleWidget $widget Control to compare.
* @access public
*/
function isMatch($widget) {
if (! method_exists($widget, 'isLabel')) {
return false;
}
return $widget->isLabel($this->_label);
}
}
/**
* Used to extract form elements for testing against.
* Searches dy id attribute.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleById {
var $_id;
/**
* Stashes the name for later comparison.
* @param string $id ID atribute to match.
*/
function SimpleById($id) {
$this->_id = $id;
}
/**
* Comparison. Compares id attribute of widget.
* @param SimpleWidget $widget Control to compare.
* @access public
*/
function isMatch($widget) {
return $widget->isId($this->_id);
}
}
/**
* Used to extract form elements for testing against.
* Searches by visible label, name or alt text.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleByLabelOrName {
var $_label;
/**
* Stashes the name/label for later comparison.
* @param string $label Visible text to match.
*/
function SimpleByLabelOrName($label) {
$this->_label = $label;
}
/**
* Comparison. Compares visible text of widget or
* related label or name.
* @param SimpleWidget $widget Control to compare.
* @access public
*/
function isMatch($widget) {
if (method_exists($widget, 'isLabel')) {
if ($widget->isLabel($this->_label)) {
return true;
}
}
return ($widget->getName() == $this->_label);
}
}
?>

View file

@ -1,333 +0,0 @@
<?php
/**
* base include file for SimpleTest
* @package SimpleTest
* @subpackage UnitTester
* @version $Id: shell_tester.php 1723 2008-04-08 00:34:10Z lastcraft $
*/
/**#@+
* include other SimpleTest class files
*/
require_once(dirname(__FILE__) . '/test_case.php');
/**#@-*/
/**
* Wrapper for exec() functionality.
* @package SimpleTest
* @subpackage UnitTester
*/
class SimpleShell {
var $_output;
/**
* Executes the shell comand and stashes the output.
* @access public
*/
function SimpleShell() {
$this->_output = false;
}
/**
* Actually runs the command. Does not trap the
* error stream output as this need PHP 4.3+.
* @param string $command The actual command line
* to run.
* @return integer Exit code.
* @access public
*/
function execute($command) {
$this->_output = false;
exec($command, $this->_output, $ret);
return $ret;
}
/**
* Accessor for the last output.
* @return string Output as text.
* @access public
*/
function getOutput() {
return implode("\n", $this->_output);
}
/**
* Accessor for the last output.
* @return array Output as array of lines.
* @access public
*/
function getOutputAsList() {
return $this->_output;
}
}
/**
* Test case for testing of command line scripts and
* utilities. Usually scripts that are external to the
* PHP code, but support it in some way.
* @package SimpleTest
* @subpackage UnitTester
*/
class ShellTestCase extends SimpleTestCase {
var $_current_shell;
var $_last_status;
var $_last_command;
/**
* Creates an empty test case. Should be subclassed
* with test methods for a functional test case.
* @param string $label Name of test case. Will use
* the class name if none specified.
* @access public
*/
function ShellTestCase($label = false) {
$this->SimpleTestCase($label);
$this->_current_shell = &$this->_createShell();
$this->_last_status = false;
$this->_last_command = '';
}
/**
* Executes a command and buffers the results.
* @param string $command Command to run.
* @return boolean True if zero exit code.
* @access public
*/
function execute($command) {
$shell = &$this->_getShell();
$this->_last_status = $shell->execute($command);
$this->_last_command = $command;
return ($this->_last_status === 0);
}
/**
* Dumps the output of the last command.
* @access public
*/
function dumpOutput() {
$this->dump($this->getOutput());
}
/**
* Accessor for the last output.
* @return string Output as text.
* @access public
*/
function getOutput() {
$shell = &$this->_getShell();
return $shell->getOutput();
}
/**
* Accessor for the last output.
* @return array Output as array of lines.
* @access public
*/
function getOutputAsList() {
$shell = &$this->_getShell();
return $shell->getOutputAsList();
}
/**
* Called from within the test methods to register
* passes and failures.
* @param boolean $result Pass on true.
* @param string $message Message to display describing
* the test state.
* @return boolean True on pass
* @access public
*/
function assertTrue($result, $message = false) {
return $this->assert(new TrueExpectation(), $result, $message);
}
/**
* Will be true on false and vice versa. False
* is the PHP definition of false, so that null,
* empty strings, zero and an empty array all count
* as false.
* @param boolean $result Pass on false.
* @param string $message Message to display.
* @return boolean True on pass
* @access public
*/
function assertFalse($result, $message = '%s') {
return $this->assert(new FalseExpectation(), $result, $message);
}
/**
* Will trigger a pass if the two parameters have
* the same value only. Otherwise a fail. This
* is for testing hand extracted text, etc.
* @param mixed $first Value to compare.
* @param mixed $second Value to compare.
* @param string $message Message to display.
* @return boolean True on pass
* @access public
*/
function assertEqual($first, $second, $message = "%s") {
return $this->assert(
new EqualExpectation($first),
$second,
$message);
}
/**
* Will trigger a pass if the two parameters have
* a different value. Otherwise a fail. This
* is for testing hand extracted text, etc.
* @param mixed $first Value to compare.
* @param mixed $second Value to compare.
* @param string $message Message to display.
* @return boolean True on pass
* @access public
*/
function assertNotEqual($first, $second, $message = "%s") {
return $this->assert(
new NotEqualExpectation($first),
$second,
$message);
}
/**
* Tests the last status code from the shell.
* @param integer $status Expected status of last
* command.
* @param string $message Message to display.
* @return boolean True if pass.
* @access public
*/
function assertExitCode($status, $message = "%s") {
$message = sprintf($message, "Expected status code of [$status] from [" .
$this->_last_command . "], but got [" .
$this->_last_status . "]");
return $this->assertTrue($status === $this->_last_status, $message);
}
/**
* Attempt to exactly match the combined STDERR and
* STDOUT output.
* @param string $expected Expected output.
* @param string $message Message to display.
* @return boolean True if pass.
* @access public
*/
function assertOutput($expected, $message = "%s") {
$shell = &$this->_getShell();
return $this->assert(
new EqualExpectation($expected),
$shell->getOutput(),
$message);
}
/**
* Scans the output for a Perl regex. If found
* anywhere it passes, else it fails.
* @param string $pattern Regex to search for.
* @param string $message Message to display.
* @return boolean True if pass.
* @access public
*/
function assertOutputPattern($pattern, $message = "%s") {
$shell = &$this->_getShell();
return $this->assert(
new PatternExpectation($pattern),
$shell->getOutput(),
$message);
}
/**
* If a Perl regex is found anywhere in the current
* output then a failure is generated, else a pass.
* @param string $pattern Regex to search for.
* @param $message Message to display.
* @return boolean True if pass.
* @access public
*/
function assertNoOutputPattern($pattern, $message = "%s") {
$shell = &$this->_getShell();
return $this->assert(
new NoPatternExpectation($pattern),
$shell->getOutput(),
$message);
}
/**
* File existence check.
* @param string $path Full filename and path.
* @param string $message Message to display.
* @return boolean True if pass.
* @access public
*/
function assertFileExists($path, $message = "%s") {
$message = sprintf($message, "File [$path] should exist");
return $this->assertTrue(file_exists($path), $message);
}
/**
* File non-existence check.
* @param string $path Full filename and path.
* @param string $message Message to display.
* @return boolean True if pass.
* @access public
*/
function assertFileNotExists($path, $message = "%s") {
$message = sprintf($message, "File [$path] should not exist");
return $this->assertFalse(file_exists($path), $message);
}
/**
* Scans a file for a Perl regex. If found
* anywhere it passes, else it fails.
* @param string $pattern Regex to search for.
* @param string $path Full filename and path.
* @param string $message Message to display.
* @return boolean True if pass.
* @access public
*/
function assertFilePattern($pattern, $path, $message = "%s") {
$shell = &$this->_getShell();
return $this->assert(
new PatternExpectation($pattern),
implode('', file($path)),
$message);
}
/**
* If a Perl regex is found anywhere in the named
* file then a failure is generated, else a pass.
* @param string $pattern Regex to search for.
* @param string $path Full filename and path.
* @param string $message Message to display.
* @return boolean True if pass.
* @access public
*/
function assertNoFilePattern($pattern, $path, $message = "%s") {
$shell = &$this->_getShell();
return $this->assert(
new NoPatternExpectation($pattern),
implode('', file($path)),
$message);
}
/**
* Accessor for current shell. Used for testing the
* the tester itself.
* @return Shell Current shell.
* @access protected
*/
function &_getShell() {
return $this->_current_shell;
}
/**
* Factory for the shell to run the command on.
* @return Shell New shell object.
* @access protected
*/
function &_createShell() {
$shell = &new SimpleShell();
return $shell;
}
}
?>

View file

@ -1,478 +0,0 @@
<?php
/**
* Global state for SimpleTest and kicker script in future versions.
* @package SimpleTest
* @subpackage UnitTester
* @version $Id: simpletest.php 1723 2008-04-08 00:34:10Z lastcraft $
*/
/**#@+
* include SimpleTest files
*/
if (version_compare(phpversion(), '5') >= 0) {
require_once(dirname(__FILE__) . '/reflection_php5.php');
} else {
require_once(dirname(__FILE__) . '/reflection_php4.php');
}
require_once(dirname(__FILE__) . '/default_reporter.php');
require_once(dirname(__FILE__) . '/compatibility.php');
/**#@-*/
/**
* Registry and test context. Includes a few
* global options that I'm slowly getting rid of.
* @package SimpleTest
* @subpackage UnitTester
*/
class SimpleTest {
/**
* Reads the SimpleTest version from the release file.
* @return string Version string.
* @static
* @access public
*/
function getVersion() {
$content = file(dirname(__FILE__) . '/VERSION');
return trim($content[0]);
}
/**
* Sets the name of a test case to ignore, usually
* because the class is an abstract case that should
* not be run. Once PHP4 is dropped this will disappear
* as a public method and "abstract" will rule.
* @param string $class Add a class to ignore.
* @static
* @access public
*/
function ignore($class) {
$registry = &SimpleTest::_getRegistry();
$registry['IgnoreList'][strtolower($class)] = true;
}
/**
* Scans the now complete ignore list, and adds
* all parent classes to the list. If a class
* is not a runnable test case, then it's parents
* wouldn't be either. This is syntactic sugar
* to cut down on ommissions of ignore()'s or
* missing abstract declarations. This cannot
* be done whilst loading classes wiithout forcing
* a particular order on the class declarations and
* the ignore() calls. It's just nice to have the ignore()
* calls at the top of the file before the actual declarations.
* @param array $classes Class names of interest.
* @static
* @access public
*/
function ignoreParentsIfIgnored($classes) {
$registry = &SimpleTest::_getRegistry();
foreach ($classes as $class) {
if (SimpleTest::isIgnored($class)) {
$reflection = new SimpleReflection($class);
if ($parent = $reflection->getParent()) {
SimpleTest::ignore($parent);
}
}
}
}
/**
* Puts the object to the global pool of 'preferred' objects
* which can be retrieved with SimpleTest :: preferred() method.
* Instances of the same class are overwritten.
* @param object $object Preferred object
* @static
* @access public
* @see preferred()
*/
function prefer(&$object) {
$registry = &SimpleTest::_getRegistry();
$registry['Preferred'][] = &$object;
}
/**
* Retrieves 'preferred' objects from global pool. Class filter
* can be applied in order to retrieve the object of the specific
* class
* @param array|string $classes Allowed classes or interfaces.
* @static
* @access public
* @return array|object|null
* @see prefer()
*/
function &preferred($classes) {
if (! is_array($classes)) {
$classes = array($classes);
}
$registry = &SimpleTest::_getRegistry();
for ($i = count($registry['Preferred']) - 1; $i >= 0; $i--) {
foreach ($classes as $class) {
if (SimpleTestCompatibility::isA($registry['Preferred'][$i], $class)) {
return $registry['Preferred'][$i];
}
}
}
return null;
}
/**
* Test to see if a test case is in the ignore
* list. Quite obviously the ignore list should
* be a separate object and will be one day.
* This method is internal to SimpleTest. Don't
* use it.
* @param string $class Class name to test.
* @return boolean True if should not be run.
* @access public
* @static
*/
function isIgnored($class) {
$registry = &SimpleTest::_getRegistry();
return isset($registry['IgnoreList'][strtolower($class)]);
}
/**
* @deprecated
*/
function setMockBaseClass($mock_base) {
$registry = &SimpleTest::_getRegistry();
$registry['MockBaseClass'] = $mock_base;
}
/**
* @deprecated
*/
function getMockBaseClass() {
$registry = &SimpleTest::_getRegistry();
return $registry['MockBaseClass'];
}
/**
* Sets proxy to use on all requests for when
* testing from behind a firewall. Set host
* to false to disable. This will take effect
* if there are no other proxy settings.
* @param string $proxy Proxy host as URL.
* @param string $username Proxy username for authentication.
* @param string $password Proxy password for authentication.
* @access public
*/
function useProxy($proxy, $username = false, $password = false) {
$registry = &SimpleTest::_getRegistry();
$registry['DefaultProxy'] = $proxy;
$registry['DefaultProxyUsername'] = $username;
$registry['DefaultProxyPassword'] = $password;
}
/**
* Accessor for default proxy host.
* @return string Proxy URL.
* @access public
*/
function getDefaultProxy() {
$registry = &SimpleTest::_getRegistry();
return $registry['DefaultProxy'];
}
/**
* Accessor for default proxy username.
* @return string Proxy username for authentication.
* @access public
*/
function getDefaultProxyUsername() {
$registry = &SimpleTest::_getRegistry();
return $registry['DefaultProxyUsername'];
}
/**
* Accessor for default proxy password.
* @return string Proxy password for authentication.
* @access public
*/
function getDefaultProxyPassword() {
$registry = &SimpleTest::_getRegistry();
return $registry['DefaultProxyPassword'];
}
/**
* Accessor for global registry of options.
* @return hash All stored values.
* @access private
* @static
*/
function &_getRegistry() {
static $registry = false;
if (! $registry) {
$registry = SimpleTest::_getDefaults();
}
return $registry;
}
/**
* Accessor for the context of the current
* test run.
* @return SimpleTestContext Current test run.
* @access public
* @static
*/
function &getContext() {
static $context = false;
if (! $context) {
$context = new SimpleTestContext();
}
return $context;
}
/**
* Constant default values.
* @return hash All registry defaults.
* @access private
* @static
*/
function _getDefaults() {
return array(
'StubBaseClass' => 'SimpleStub',
'MockBaseClass' => 'SimpleMock',
'IgnoreList' => array(),
'DefaultProxy' => false,
'DefaultProxyUsername' => false,
'DefaultProxyPassword' => false,
'Preferred' => array(new HtmlReporter(), new TextReporter(), new XmlReporter()));
}
}
/**
* Container for all components for a specific
* test run. Makes things like error queues
* available to PHP event handlers, and also
* gets around some nasty reference issues in
* the mocks.
* @package SimpleTest
*/
class SimpleTestContext {
var $_test;
var $_reporter;
var $_resources;
/**
* Clears down the current context.
* @access public
*/
function clear() {
$this->_resources = array();
}
/**
* Sets the current test case instance. This
* global instance can be used by the mock objects
* to send message to the test cases.
* @param SimpleTestCase $test Test case to register.
* @access public
*/
function setTest(&$test) {
$this->clear();
$this->_test = &$test;
}
/**
* Accessor for currently running test case.
* @return SimpleTestCase Current test.
* @access public
*/
function &getTest() {
return $this->_test;
}
/**
* Sets the current reporter. This
* global instance can be used by the mock objects
* to send messages.
* @param SimpleReporter $reporter Reporter to register.
* @access public
*/
function setReporter(&$reporter) {
$this->clear();
$this->_reporter = &$reporter;
}
/**
* Accessor for current reporter.
* @return SimpleReporter Current reporter.
* @access public
*/
function &getReporter() {
return $this->_reporter;
}
/**
* Accessor for the Singleton resource.
* @return object Global resource.
* @access public
* @static
*/
function &get($resource) {
if (! isset($this->_resources[$resource])) {
$this->_resources[$resource] = &new $resource();
}
return $this->_resources[$resource];
}
}
/**
* Interrogates the stack trace to recover the
* failure point.
* @package SimpleTest
* @subpackage UnitTester
*/
class SimpleStackTrace {
var $_prefixes;
/**
* Stashes the list of target prefixes.
* @param array $prefixes List of method prefixes
* to search for.
*/
function SimpleStackTrace($prefixes) {
$this->_prefixes = $prefixes;
}
/**
* Extracts the last method name that was not within
* Simpletest itself. Captures a stack trace if none given.
* @param array $stack List of stack frames.
* @return string Snippet of test report with line
* number and file.
* @access public
*/
function traceMethod($stack = false) {
$stack = $stack ? $stack : $this->_captureTrace();
foreach ($stack as $frame) {
if ($this->_frameLiesWithinSimpleTestFolder($frame)) {
continue;
}
if ($this->_frameMatchesPrefix($frame)) {
return ' at [' . $frame['file'] . ' line ' . $frame['line'] . ']';
}
}
return '';
}
/**
* Test to see if error is generated by SimpleTest itself.
* @param array $frame PHP stack frame.
* @return boolean True if a SimpleTest file.
* @access private
*/
function _frameLiesWithinSimpleTestFolder($frame) {
if (isset($frame['file'])) {
$path = substr(SIMPLE_TEST, 0, -1);
if (strpos($frame['file'], $path) === 0) {
if (dirname($frame['file']) == $path) {
return true;
}
}
}
return false;
}
/**
* Tries to determine if the method call is an assert, etc.
* @param array $frame PHP stack frame.
* @return boolean True if matches a target.
* @access private
*/
function _frameMatchesPrefix($frame) {
foreach ($this->_prefixes as $prefix) {
if (strncmp($frame['function'], $prefix, strlen($prefix)) == 0) {
return true;
}
}
return false;
}
/**
* Grabs a current stack trace.
* @return array Fulle trace.
* @access private
*/
function _captureTrace() {
if (function_exists('debug_backtrace')) {
return array_reverse(debug_backtrace());
}
return array();
}
}
/**
* @package SimpleTest
* @subpackage UnitTester
* @deprecated
*/
class SimpleTestOptions extends SimpleTest {
/**
* @deprecated
*/
function getVersion() {
return Simpletest::getVersion();
}
/**
* @deprecated
*/
function ignore($class) {
return Simpletest::ignore($class);
}
/**
* @deprecated
*/
function isIgnored($class) {
return Simpletest::isIgnored($class);
}
/**
* @deprecated
*/
function setMockBaseClass($mock_base) {
return Simpletest::setMockBaseClass($mock_base);
}
/**
* @deprecated
*/
function getMockBaseClass() {
return Simpletest::getMockBaseClass();
}
/**
* @deprecated
*/
function useProxy($proxy, $username = false, $password = false) {
return Simpletest::useProxy($proxy, $username, $password);
}
/**
* @deprecated
*/
function getDefaultProxy() {
return Simpletest::getDefaultProxy();
}
/**
* @deprecated
*/
function getDefaultProxyUsername() {
return Simpletest::getDefaultProxyUsername();
}
/**
* @deprecated
*/
function getDefaultProxyPassword() {
return Simpletest::getDefaultProxyPassword();
}
}
?>

View file

@ -1,216 +0,0 @@
<?php
/**
* base include file for SimpleTest
* @package SimpleTest
* @subpackage MockObjects
* @version $Id: socket.php 1723 2008-04-08 00:34:10Z lastcraft $
*/
/**#@+
* include SimpleTest files
*/
require_once(dirname(__FILE__) . '/compatibility.php');
/**#@-*/
/**
* Stashes an error for later. Useful for constructors
* until PHP gets exceptions.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleStickyError {
var $_error = 'Constructor not chained';
/**
* Sets the error to empty.
* @access public
*/
function SimpleStickyError() {
$this->_clearError();
}
/**
* Test for an outstanding error.
* @return boolean True if there is an error.
* @access public
*/
function isError() {
return ($this->_error != '');
}
/**
* Accessor for an outstanding error.
* @return string Empty string if no error otherwise
* the error message.
* @access public
*/
function getError() {
return $this->_error;
}
/**
* Sets the internal error.
* @param string Error message to stash.
* @access protected
*/
function _setError($error) {
$this->_error = $error;
}
/**
* Resets the error state to no error.
* @access protected
*/
function _clearError() {
$this->_setError('');
}
}
/**
* Wrapper for TCP/IP socket.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleSocket extends SimpleStickyError {
var $_handle;
var $_is_open = false;
var $_sent = '';
var $lock_size;
/**
* Opens a socket for reading and writing.
* @param string $host Hostname to send request to.
* @param integer $port Port on remote machine to open.
* @param integer $timeout Connection timeout in seconds.
* @param integer $block_size Size of chunk to read.
* @access public
*/
function SimpleSocket($host, $port, $timeout, $block_size = 255) {
$this->SimpleStickyError();
if (! ($this->_handle = $this->_openSocket($host, $port, $error_number, $error, $timeout))) {
$this->_setError("Cannot open [$host:$port] with [$error] within [$timeout] seconds");
return;
}
$this->_is_open = true;
$this->_block_size = $block_size;
SimpleTestCompatibility::setTimeout($this->_handle, $timeout);
}
/**
* Writes some data to the socket and saves alocal copy.
* @param string $message String to send to socket.
* @return boolean True if successful.
* @access public
*/
function write($message) {
if ($this->isError() || ! $this->isOpen()) {
return false;
}
$count = fwrite($this->_handle, $message);
if (! $count) {
if ($count === false) {
$this->_setError('Cannot write to socket');
$this->close();
}
return false;
}
fflush($this->_handle);
$this->_sent .= $message;
return true;
}
/**
* Reads data from the socket. The error suppresion
* is a workaround for PHP4 always throwing a warning
* with a secure socket.
* @return integer/boolean Incoming bytes. False
* on error.
* @access public
*/
function read() {
if ($this->isError() || ! $this->isOpen()) {
return false;
}
$raw = @fread($this->_handle, $this->_block_size);
if ($raw === false) {
$this->_setError('Cannot read from socket');
$this->close();
}
return $raw;
}
/**
* Accessor for socket open state.
* @return boolean True if open.
* @access public
*/
function isOpen() {
return $this->_is_open;
}
/**
* Closes the socket preventing further reads.
* Cannot be reopened once closed.
* @return boolean True if successful.
* @access public
*/
function close() {
$this->_is_open = false;
return fclose($this->_handle);
}
/**
* Accessor for content so far.
* @return string Bytes sent only.
* @access public
*/
function getSent() {
return $this->_sent;
}
/**
* Actually opens the low level socket.
* @param string $host Host to connect to.
* @param integer $port Port on host.
* @param integer $error_number Recipient of error code.
* @param string $error Recipoent of error message.
* @param integer $timeout Maximum time to wait for connection.
* @access protected
*/
function _openSocket($host, $port, &$error_number, &$error, $timeout) {
return @fsockopen($host, $port, $error_number, $error, $timeout);
}
}
/**
* Wrapper for TCP/IP socket over TLS.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleSecureSocket extends SimpleSocket {
/**
* Opens a secure socket for reading and writing.
* @param string $host Hostname to send request to.
* @param integer $port Port on remote machine to open.
* @param integer $timeout Connection timeout in seconds.
* @access public
*/
function SimpleSecureSocket($host, $port, $timeout) {
$this->SimpleSocket($host, $port, $timeout);
}
/**
* Actually opens the low level socket.
* @param string $host Host to connect to.
* @param integer $port Port on host.
* @param integer $error_number Recipient of error code.
* @param string $error Recipient of error message.
* @param integer $timeout Maximum time to wait for connection.
* @access protected
*/
function _openSocket($host, $port, &$error_number, &$error, $timeout) {
return parent::_openSocket("tls://$host", $port, $error_number, $error, $timeout);
}
}
?>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,77 +0,0 @@
<?php
// $Id: adapter_test.php 1505 2007-04-30 23:39:59Z lastcraft $
require_once(dirname(__FILE__) . '/../autorun.php');
require_once(dirname(__FILE__) . '/../extensions/pear_test_case.php');
require_once(dirname(__FILE__) . '/../extensions/phpunit_test_case.php');
class SameTestClass {
}
class TestOfPearAdapter extends PHPUnit_TestCase {
function testBoolean() {
$this->assertTrue(true, "PEAR true");
$this->assertFalse(false, "PEAR false");
}
function testName() {
$this->assertTrue($this->getName() == get_class($this));
}
function testPass() {
$this->pass("PEAR pass");
}
function testNulls() {
$value = null;
$this->assertNull($value, "PEAR null");
$value = 0;
$this->assertNotNull($value, "PEAR not null");
}
function testType() {
$this->assertType("Hello", "string", "PEAR type");
}
function testEquals() {
$this->assertEquals(12, 12, "PEAR identity");
$this->setLooselyTyped(true);
$this->assertEquals("12", 12, "PEAR equality");
}
function testSame() {
$same = &new SameTestClass();
$this->assertSame($same, $same, "PEAR same");
}
function testRegExp() {
$this->assertRegExp('/hello/', "A big hello from me", "PEAR regex");
}
}
class TestOfPhpUnitAdapter extends TestCase {
function TestOfPhpUnitAdapter() {
$this->TestCase('TestOfPhpUnitAdapter');
}
function testBoolean() {
$this->assert(true, 'PHP Unit true');
}
function testName() {
$this->assert($this->name() == 'TestOfPhpUnitAdapter');
}
function testEquals() {
$this->assertEquals(12, 12, 'PHP Unit equality');
}
function testMultilineEquals() {
$this->assertEquals("a\nb\n", "a\nb\n", 'PHP Unit equality');
}
function testRegExp() {
$this->assertRegexp('/hello/', 'A big hello from me', 'PHPUnit regex');
}
}
?>

View file

@ -1,13 +0,0 @@
<?php
require_once(dirname(__FILE__) . '/../autorun.php');
class AllTests extends TestSuite {
function AllTests() {
$this->TestSuite('All tests for SimpleTest ' . SimpleTest::getVersion());
$this->addFile(dirname(__FILE__) . '/unit_tests.php');
$this->addFile(dirname(__FILE__) . '/shell_test.php');
$this->addFile(dirname(__FILE__) . '/live_test.php');
$this->addFile(dirname(__FILE__) . '/acceptance_test.php');
}
}
?>

View file

@ -1,145 +0,0 @@
<?php
// $Id: authentication_test.php 1505 2007-04-30 23:39:59Z lastcraft $
require_once(dirname(__FILE__) . '/../autorun.php');
require_once(dirname(__FILE__) . '/../authentication.php');
require_once(dirname(__FILE__) . '/../http.php');
Mock::generate('SimpleHttpRequest');
class TestOfRealm extends UnitTestCase {
function testWithinSameUrl() {
$realm = &new SimpleRealm(
'Basic',
new SimpleUrl('http://www.here.com/path/hello.html'));
$this->assertTrue($realm->isWithin(
new SimpleUrl('http://www.here.com/path/hello.html')));
}
function testInsideWithLongerUrl() {
$realm = &new SimpleRealm(
'Basic',
new SimpleUrl('http://www.here.com/path/'));
$this->assertTrue($realm->isWithin(
new SimpleUrl('http://www.here.com/path/hello.html')));
}
function testBelowRootIsOutside() {
$realm = &new SimpleRealm(
'Basic',
new SimpleUrl('http://www.here.com/path/'));
$this->assertTrue($realm->isWithin(
new SimpleUrl('http://www.here.com/path/more/hello.html')));
}
function testOldNetscapeDefinitionIsOutside() {
$realm = &new SimpleRealm(
'Basic',
new SimpleUrl('http://www.here.com/path/'));
$this->assertFalse($realm->isWithin(
new SimpleUrl('http://www.here.com/pathmore/hello.html')));
}
function testInsideWithMissingTrailingSlash() {
$realm = &new SimpleRealm(
'Basic',
new SimpleUrl('http://www.here.com/path/'));
$this->assertTrue($realm->isWithin(
new SimpleUrl('http://www.here.com/path')));
}
function testDifferentPageNameStillInside() {
$realm = &new SimpleRealm(
'Basic',
new SimpleUrl('http://www.here.com/path/hello.html'));
$this->assertTrue($realm->isWithin(
new SimpleUrl('http://www.here.com/path/goodbye.html')));
}
function testNewUrlInSameDirectoryDoesNotChangeRealm() {
$realm = &new SimpleRealm(
'Basic',
new SimpleUrl('http://www.here.com/path/hello.html'));
$realm->stretch(new SimpleUrl('http://www.here.com/path/goodbye.html'));
$this->assertTrue($realm->isWithin(
new SimpleUrl('http://www.here.com/path/index.html')));
$this->assertFalse($realm->isWithin(
new SimpleUrl('http://www.here.com/index.html')));
}
function testNewUrlMakesRealmTheCommonPath() {
$realm = &new SimpleRealm(
'Basic',
new SimpleUrl('http://www.here.com/path/here/hello.html'));
$realm->stretch(new SimpleUrl('http://www.here.com/path/there/goodbye.html'));
$this->assertTrue($realm->isWithin(
new SimpleUrl('http://www.here.com/path/here/index.html')));
$this->assertTrue($realm->isWithin(
new SimpleUrl('http://www.here.com/path/there/index.html')));
$this->assertTrue($realm->isWithin(
new SimpleUrl('http://www.here.com/path/index.html')));
$this->assertFalse($realm->isWithin(
new SimpleUrl('http://www.here.com/index.html')));
$this->assertFalse($realm->isWithin(
new SimpleUrl('http://www.here.com/paths/index.html')));
$this->assertFalse($realm->isWithin(
new SimpleUrl('http://www.here.com/pathindex.html')));
}
}
class TestOfAuthenticator extends UnitTestCase {
function testNoRealms() {
$request = &new MockSimpleHttpRequest();
$request->expectNever('addHeaderLine');
$authenticator = &new SimpleAuthenticator();
$authenticator->addHeaders($request, new SimpleUrl('http://here.com/'));
}
function &createSingleRealm() {
$authenticator = &new SimpleAuthenticator();
$authenticator->addRealm(
new SimpleUrl('http://www.here.com/path/hello.html'),
'Basic',
'Sanctuary');
$authenticator->setIdentityForRealm('www.here.com', 'Sanctuary', 'test', 'secret');
return $authenticator;
}
function testOutsideRealm() {
$request = &new MockSimpleHttpRequest();
$request->expectNever('addHeaderLine');
$authenticator = &$this->createSingleRealm();
$authenticator->addHeaders(
$request,
new SimpleUrl('http://www.here.com/hello.html'));
}
function testWithinRealm() {
$request = &new MockSimpleHttpRequest();
$request->expectOnce('addHeaderLine');
$authenticator = &$this->createSingleRealm();
$authenticator->addHeaders(
$request,
new SimpleUrl('http://www.here.com/path/more/hello.html'));
}
function testRestartingClearsRealm() {
$request = &new MockSimpleHttpRequest();
$request->expectNever('addHeaderLine');
$authenticator = &$this->createSingleRealm();
$authenticator->restartSession();
$authenticator->addHeaders(
$request,
new SimpleUrl('http://www.here.com/hello.html'));
}
function testDifferentHostIsOutsideRealm() {
$request = &new MockSimpleHttpRequest();
$request->expectNever('addHeaderLine');
$authenticator = &$this->createSingleRealm();
$authenticator->addHeaders(
$request,
new SimpleUrl('http://here.com/path/hello.html'));
}
}
?>

View file

@ -1,13 +0,0 @@
<?php
require_once(dirname(__FILE__) . '/../autorun.php');
require_once(dirname(__FILE__) . '/support/test1.php');
class LoadIfIncludedTestCase extends UnitTestCase {
function test_load_if_included() {
$tests = new GroupTest();
$tests->addFile(dirname(__FILE__) . '/support/test1.php');
$this->assertEqual($tests->getSize(), 1);
}
}
?>

View file

@ -1,10 +0,0 @@
<?php
require_once(dirname(__FILE__) . '/../autorun.php');
class BadTestCases extends TestSuite {
function BadTestCases() {
$this->TestSuite('Two bad test cases');
$this->addFile(dirname(__FILE__) . '/support/empty_test_file.php');
}
}
?>

View file

@ -1,779 +0,0 @@
<?php
// $Id: browser_test.php 1624 2008-01-01 15:00:43Z pp11 $
require_once(dirname(__FILE__) . '/../autorun.php');
require_once(dirname(__FILE__) . '/../browser.php');
require_once(dirname(__FILE__) . '/../user_agent.php');
require_once(dirname(__FILE__) . '/../http.php');
require_once(dirname(__FILE__) . '/../page.php');
require_once(dirname(__FILE__) . '/../encoding.php');
Mock::generate('SimpleHttpResponse');
Mock::generate('SimplePage');
Mock::generate('SimpleForm');
Mock::generate('SimpleUserAgent');
Mock::generatePartial(
'SimpleBrowser',
'MockParseSimpleBrowser',
array('_createUserAgent', '_parse'));
Mock::generatePartial(
'SimpleBrowser',
'MockUserAgentSimpleBrowser',
array('_createUserAgent'));
class TestOfHistory extends UnitTestCase {
function testEmptyHistoryHasFalseContents() {
$history = &new SimpleBrowserHistory();
$this->assertIdentical($history->getUrl(), false);
$this->assertIdentical($history->getParameters(), false);
}
function testCannotMoveInEmptyHistory() {
$history = &new SimpleBrowserHistory();
$this->assertFalse($history->back());
$this->assertFalse($history->forward());
}
function testCurrentTargetAccessors() {
$history = &new SimpleBrowserHistory();
$history->recordEntry(
new SimpleUrl('http://www.here.com/'),
new SimpleGetEncoding());
$this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.here.com/'));
$this->assertIdentical($history->getParameters(), new SimpleGetEncoding());
}
function testSecondEntryAccessors() {
$history = &new SimpleBrowserHistory();
$history->recordEntry(
new SimpleUrl('http://www.first.com/'),
new SimpleGetEncoding());
$history->recordEntry(
new SimpleUrl('http://www.second.com/'),
new SimplePostEncoding(array('a' => 1)));
$this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.second.com/'));
$this->assertIdentical(
$history->getParameters(),
new SimplePostEncoding(array('a' => 1)));
}
function testGoingBackwards() {
$history = &new SimpleBrowserHistory();
$history->recordEntry(
new SimpleUrl('http://www.first.com/'),
new SimpleGetEncoding());
$history->recordEntry(
new SimpleUrl('http://www.second.com/'),
new SimplePostEncoding(array('a' => 1)));
$this->assertTrue($history->back());
$this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.first.com/'));
$this->assertIdentical($history->getParameters(), new SimpleGetEncoding());
}
function testGoingBackwardsOffBeginning() {
$history = &new SimpleBrowserHistory();
$history->recordEntry(
new SimpleUrl('http://www.first.com/'),
new SimpleGetEncoding());
$this->assertFalse($history->back());
$this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.first.com/'));
$this->assertIdentical($history->getParameters(), new SimpleGetEncoding());
}
function testGoingForwardsOffEnd() {
$history = &new SimpleBrowserHistory();
$history->recordEntry(
new SimpleUrl('http://www.first.com/'),
new SimpleGetEncoding());
$this->assertFalse($history->forward());
$this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.first.com/'));
$this->assertIdentical($history->getParameters(), new SimpleGetEncoding());
}
function testGoingBackwardsAndForwards() {
$history = &new SimpleBrowserHistory();
$history->recordEntry(
new SimpleUrl('http://www.first.com/'),
new SimpleGetEncoding());
$history->recordEntry(
new SimpleUrl('http://www.second.com/'),
new SimplePostEncoding(array('a' => 1)));
$this->assertTrue($history->back());
$this->assertTrue($history->forward());
$this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.second.com/'));
$this->assertIdentical(
$history->getParameters(),
new SimplePostEncoding(array('a' => 1)));
}
function testNewEntryReplacesNextOne() {
$history = &new SimpleBrowserHistory();
$history->recordEntry(
new SimpleUrl('http://www.first.com/'),
new SimpleGetEncoding());
$history->recordEntry(
new SimpleUrl('http://www.second.com/'),
new SimplePostEncoding(array('a' => 1)));
$history->back();
$history->recordEntry(
new SimpleUrl('http://www.third.com/'),
new SimpleGetEncoding());
$this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.third.com/'));
$this->assertIdentical($history->getParameters(), new SimpleGetEncoding());
}
function testNewEntryDropsFutureEntries() {
$history = &new SimpleBrowserHistory();
$history->recordEntry(
new SimpleUrl('http://www.first.com/'),
new SimpleGetEncoding());
$history->recordEntry(
new SimpleUrl('http://www.second.com/'),
new SimpleGetEncoding());
$history->recordEntry(
new SimpleUrl('http://www.third.com/'),
new SimpleGetEncoding());
$history->back();
$history->back();
$history->recordEntry(
new SimpleUrl('http://www.fourth.com/'),
new SimpleGetEncoding());
$this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.fourth.com/'));
$this->assertFalse($history->forward());
$history->back();
$this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.first.com/'));
$this->assertFalse($history->back());
}
}
class TestOfParsedPageAccess extends UnitTestCase {
function &loadPage(&$page) {
$response = &new MockSimpleHttpResponse($this);
$agent = &new MockSimpleUserAgent($this);
$agent->setReturnReference('fetchResponse', $response);
$browser = &new MockParseSimpleBrowser($this);
$browser->setReturnReference('_createUserAgent', $agent);
$browser->setReturnReference('_parse', $page);
$browser->SimpleBrowser();
$browser->get('http://this.com/page.html');
return $browser;
}
function testAccessorsWhenNoPage() {
$agent = &new MockSimpleUserAgent($this);
$browser = &new MockParseSimpleBrowser($this);
$browser->setReturnReference('_createUserAgent', $agent);
$browser->SimpleBrowser();
$this->assertEqual($browser->getContent(), '');
}
function testParse() {
$page = &new MockSimplePage();
$page->setReturnValue('getRequest', "GET here.html\r\n\r\n");
$page->setReturnValue('getRaw', 'Raw HTML');
$page->setReturnValue('getTitle', 'Here');
$page->setReturnValue('getFrameFocus', 'Frame');
$page->setReturnValue('getMimeType', 'text/html');
$page->setReturnValue('getResponseCode', 200);
$page->setReturnValue('getAuthentication', 'Basic');
$page->setReturnValue('getRealm', 'Somewhere');
$page->setReturnValue('getTransportError', 'Ouch!');
$browser = &$this->loadPage($page);
$this->assertEqual($browser->getRequest(), "GET here.html\r\n\r\n");
$this->assertEqual($browser->getContent(), 'Raw HTML');
$this->assertEqual($browser->getTitle(), 'Here');
$this->assertEqual($browser->getFrameFocus(), 'Frame');
$this->assertIdentical($browser->getResponseCode(), 200);
$this->assertEqual($browser->getMimeType(), 'text/html');
$this->assertEqual($browser->getAuthentication(), 'Basic');
$this->assertEqual($browser->getRealm(), 'Somewhere');
$this->assertEqual($browser->getTransportError(), 'Ouch!');
}
function testLinkAffirmationWhenPresent() {
$page = &new MockSimplePage();
$page->setReturnValue('getUrlsByLabel', array('http://www.nowhere.com'));
$page->expectOnce('getUrlsByLabel', array('a link label'));
$browser = &$this->loadPage($page);
$this->assertIdentical($browser->getLink('a link label'), 'http://www.nowhere.com');
}
function testLinkAffirmationByIdWhenPresent() {
$page = &new MockSimplePage();
$page->setReturnValue('getUrlById', 'a_page.com', array(99));
$page->setReturnValue('getUrlById', false, array('*'));
$browser = &$this->loadPage($page);
$this->assertIdentical($browser->getLinkById(99), 'a_page.com');
$this->assertFalse($browser->getLinkById(98));
}
function testSettingFieldIsPassedToPage() {
$page = &new MockSimplePage();
$page->expectOnce('setField', array(new SimpleByLabelOrName('key'), 'Value', false));
$page->setReturnValue('getField', 'Value');
$browser = &$this->loadPage($page);
$this->assertEqual($browser->getField('key'), 'Value');
$browser->setField('key', 'Value');
}
}
class TestOfBrowserNavigation extends UnitTestCase {
function &createBrowser(&$agent, &$page) {
$browser = &new MockParseSimpleBrowser();
$browser->setReturnReference('_createUserAgent', $agent);
$browser->setReturnReference('_parse', $page);
$browser->SimpleBrowser();
return $browser;
}
function testClickLinkRequestsPage() {
$agent = &new MockSimpleUserAgent();
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
$agent->expectArgumentsAt(
0,
'fetchResponse',
array(new SimpleUrl('http://this.com/page.html'), new SimpleGetEncoding()));
$agent->expectArgumentsAt(
1,
'fetchResponse',
array(new SimpleUrl('http://this.com/new.html'), new SimpleGetEncoding()));
$agent->expectCallCount('fetchResponse', 2);
$page = &new MockSimplePage();
$page->setReturnValue('getUrlsByLabel', array(new SimpleUrl('http://this.com/new.html')));
$page->expectOnce('getUrlsByLabel', array('New'));
$page->setReturnValue('getRaw', 'A page');
$browser = &$this->createBrowser($agent, $page);
$browser->get('http://this.com/page.html');
$this->assertTrue($browser->clickLink('New'));
}
function testClickLinkWithUnknownFrameStillRequestsWholePage() {
$agent = &new MockSimpleUserAgent();
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
$agent->expectArgumentsAt(
0,
'fetchResponse',
array(new SimpleUrl('http://this.com/page.html'), new SimpleGetEncoding()));
$target = new SimpleUrl('http://this.com/new.html');
$target->setTarget('missing');
$agent->expectArgumentsAt(
1,
'fetchResponse',
array($target, new SimpleGetEncoding()));
$agent->expectCallCount('fetchResponse', 2);
$parsed_url = new SimpleUrl('http://this.com/new.html');
$parsed_url->setTarget('missing');
$page = &new MockSimplePage();
$page->setReturnValue('getUrlsByLabel', array($parsed_url));
$page->setReturnValue('hasFrames', false);
$page->expectOnce('getUrlsByLabel', array('New'));
$page->setReturnValue('getRaw', 'A page');
$browser = &$this->createBrowser($agent, $page);
$browser->get('http://this.com/page.html');
$this->assertTrue($browser->clickLink('New'));
}
function testClickingMissingLinkFails() {
$agent = &new MockSimpleUserAgent($this);
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
$page = &new MockSimplePage();
$page->setReturnValue('getUrlsByLabel', array());
$page->setReturnValue('getRaw', 'stuff');
$browser = &$this->createBrowser($agent, $page);
$this->assertTrue($browser->get('http://this.com/page.html'));
$this->assertFalse($browser->clickLink('New'));
}
function testClickIndexedLink() {
$agent = &new MockSimpleUserAgent();
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
$agent->expectArgumentsAt(
1,
'fetchResponse',
array(new SimpleUrl('1.html'), new SimpleGetEncoding()));
$agent->expectCallCount('fetchResponse', 2);
$page = &new MockSimplePage();
$page->setReturnValue(
'getUrlsByLabel',
array(new SimpleUrl('0.html'), new SimpleUrl('1.html')));
$page->setReturnValue('getRaw', 'A page');
$browser = &$this->createBrowser($agent, $page);
$browser->get('http://this.com/page.html');
$this->assertTrue($browser->clickLink('New', 1));
}
function testClinkLinkById() {
$agent = &new MockSimpleUserAgent();
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
$agent->expectArgumentsAt(1, 'fetchResponse', array(
new SimpleUrl('http://this.com/link.html'),
new SimpleGetEncoding()));
$agent->expectCallCount('fetchResponse', 2);
$page = &new MockSimplePage();
$page->setReturnValue('getUrlById', new SimpleUrl('http://this.com/link.html'));
$page->expectOnce('getUrlById', array(2));
$page->setReturnValue('getRaw', 'A page');
$browser = &$this->createBrowser($agent, $page);
$browser->get('http://this.com/page.html');
$this->assertTrue($browser->clickLinkById(2));
}
function testClickingMissingLinkIdFails() {
$agent = &new MockSimpleUserAgent();
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
$page = &new MockSimplePage();
$page->setReturnValue('getUrlById', false);
$browser = &$this->createBrowser($agent, $page);
$browser->get('http://this.com/page.html');
$this->assertFalse($browser->clickLink(0));
}
function testSubmitFormByLabel() {
$agent = &new MockSimpleUserAgent();
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
$agent->expectArgumentsAt(1, 'fetchResponse', array(
new SimpleUrl('http://this.com/handler.html'),
new SimplePostEncoding(array('a' => 'A'))));
$agent->expectCallCount('fetchResponse', 2);
$form = &new MockSimpleForm();
$form->setReturnValue('getAction', new SimpleUrl('http://this.com/handler.html'));
$form->setReturnValue('getMethod', 'post');
$form->setReturnValue('submitButton', new SimplePostEncoding(array('a' => 'A')));
$form->expectOnce('submitButton', array(new SimpleByLabel('Go'), false));
$page = &new MockSimplePage();
$page->setReturnReference('getFormBySubmit', $form);
$page->expectOnce('getFormBySubmit', array(new SimpleByLabel('Go')));
$page->setReturnValue('getRaw', 'stuff');
$browser = &$this->createBrowser($agent, $page);
$browser->get('http://this.com/page.html');
$this->assertTrue($browser->clickSubmit('Go'));
}
function testDefaultSubmitFormByLabel() {
$agent = &new MockSimpleUserAgent();
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
$agent->expectArgumentsAt(1, 'fetchResponse', array(
new SimpleUrl('http://this.com/page.html'),
new SimpleGetEncoding(array('a' => 'A'))));
$agent->expectCallCount('fetchResponse', 2);
$form = &new MockSimpleForm();
$form->setReturnValue('getAction', new SimpleUrl('http://this.com/page.html'));
$form->setReturnValue('getMethod', 'get');
$form->setReturnValue('submitButton', new SimpleGetEncoding(array('a' => 'A')));
$page = &new MockSimplePage();
$page->setReturnReference('getFormBySubmit', $form);
$page->expectOnce('getFormBySubmit', array(new SimpleByLabel('Submit')));
$page->setReturnValue('getRaw', 'stuff');
$page->setReturnValue('getUrl', new SimpleUrl('http://this.com/page.html'));
$browser = &$this->createBrowser($agent, $page);
$browser->get('http://this.com/page.html');
$this->assertTrue($browser->clickSubmit());
}
function testSubmitFormByName() {
$agent = &new MockSimpleUserAgent();
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
$form = &new MockSimpleForm();
$form->setReturnValue('getAction', new SimpleUrl('http://this.com/handler.html'));
$form->setReturnValue('getMethod', 'post');
$form->setReturnValue('submitButton', new SimplePostEncoding(array('a' => 'A')));
$page = &new MockSimplePage();
$page->setReturnReference('getFormBySubmit', $form);
$page->expectOnce('getFormBySubmit', array(new SimpleByName('me')));
$page->setReturnValue('getRaw', 'stuff');
$browser = &$this->createBrowser($agent, $page);
$browser->get('http://this.com/page.html');
$this->assertTrue($browser->clickSubmitByName('me'));
}
function testSubmitFormById() {
$agent = &new MockSimpleUserAgent();
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
$form = &new MockSimpleForm();
$form->setReturnValue('getAction', new SimpleUrl('http://this.com/handler.html'));
$form->setReturnValue('getMethod', 'post');
$form->setReturnValue('submitButton', new SimplePostEncoding(array('a' => 'A')));
$form->expectOnce('submitButton', array(new SimpleById(99), false));
$page = &new MockSimplePage();
$page->setReturnReference('getFormBySubmit', $form);
$page->expectOnce('getFormBySubmit', array(new SimpleById(99)));
$page->setReturnValue('getRaw', 'stuff');
$browser = &$this->createBrowser($agent, $page);
$browser->get('http://this.com/page.html');
$this->assertTrue($browser->clickSubmitById(99));
}
function testSubmitFormByImageLabel() {
$agent = &new MockSimpleUserAgent();
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
$form = &new MockSimpleForm();
$form->setReturnValue('getAction', new SimpleUrl('http://this.com/handler.html'));
$form->setReturnValue('getMethod', 'post');
$form->setReturnValue('submitImage', new SimplePostEncoding(array('a' => 'A')));
$form->expectOnce('submitImage', array(new SimpleByLabel('Go!'), 10, 11, false));
$page = &new MockSimplePage();
$page->setReturnReference('getFormByImage', $form);
$page->expectOnce('getFormByImage', array(new SimpleByLabel('Go!')));
$page->setReturnValue('getRaw', 'stuff');
$browser = &$this->createBrowser($agent, $page);
$browser->get('http://this.com/page.html');
$this->assertTrue($browser->clickImage('Go!', 10, 11));
}
function testSubmitFormByImageName() {
$agent = &new MockSimpleUserAgent();
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
$form = &new MockSimpleForm();
$form->setReturnValue('getAction', new SimpleUrl('http://this.com/handler.html'));
$form->setReturnValue('getMethod', 'post');
$form->setReturnValue('submitImage', new SimplePostEncoding(array('a' => 'A')));
$form->expectOnce('submitImage', array(new SimpleByName('a'), 10, 11, false));
$page = &new MockSimplePage();
$page->setReturnReference('getFormByImage', $form);
$page->expectOnce('getFormByImage', array(new SimpleByName('a')));
$page->setReturnValue('getRaw', 'stuff');
$browser = &$this->createBrowser($agent, $page);
$browser->get('http://this.com/page.html');
$this->assertTrue($browser->clickImageByName('a', 10, 11));
}
function testSubmitFormByImageId() {
$agent = &new MockSimpleUserAgent();
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
$form = &new MockSimpleForm();
$form->setReturnValue('getAction', new SimpleUrl('http://this.com/handler.html'));
$form->setReturnValue('getMethod', 'post');
$form->setReturnValue('submitImage', new SimplePostEncoding(array('a' => 'A')));
$form->expectOnce('submitImage', array(new SimpleById(99), 10, 11, false));
$page = &new MockSimplePage();
$page->setReturnReference('getFormByImage', $form);
$page->expectOnce('getFormByImage', array(new SimpleById(99)));
$page->setReturnValue('getRaw', 'stuff');
$browser = &$this->createBrowser($agent, $page);
$browser->get('http://this.com/page.html');
$this->assertTrue($browser->clickImageById(99, 10, 11));
}
function testSubmitFormByFormId() {
$agent = &new MockSimpleUserAgent();
$agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
$agent->expectArgumentsAt(1, 'fetchResponse', array(
new SimpleUrl('http://this.com/handler.html'),
new SimplePostEncoding(array('a' => 'A'))));
$agent->expectCallCount('fetchResponse', 2);
$form = &new MockSimpleForm();
$form->setReturnValue('getAction', new SimpleUrl('http://this.com/handler.html'));
$form->setReturnValue('getMethod', 'post');
$form->setReturnValue('submit', new SimplePostEncoding(array('a' => 'A')));
$page = &new MockSimplePage();
$page->setReturnReference('getFormById', $form);
$page->expectOnce('getFormById', array(33));
$page->setReturnValue('getRaw', 'stuff');
$browser = &$this->createBrowser($agent, $page);
$browser->get('http://this.com/page.html');
$this->assertTrue($browser->submitFormById(33));
}
}
class TestOfBrowserFrames extends UnitTestCase {
function &createBrowser(&$agent) {
$browser = &new MockUserAgentSimpleBrowser();
$browser->setReturnReference('_createUserAgent', $agent);
$browser->SimpleBrowser();
return $browser;
}
function &createUserAgent($pages) {
$agent = &new MockSimpleUserAgent();
foreach ($pages as $url => $raw) {
$url = new SimpleUrl($url);
$response = &new MockSimpleHttpResponse();
$response->setReturnValue('getUrl', $url);
$response->setReturnValue('getContent', $raw);
$agent->setReturnReference('fetchResponse', $response, array($url, '*'));
}
return $agent;
}
function testSimplePageHasNoFrames() {
$browser = &$this->createBrowser($this->createUserAgent(
array('http://site.with.no.frames/' => 'A non-framed page')));
$this->assertEqual(
$browser->get('http://site.with.no.frames/'),
'A non-framed page');
$this->assertIdentical($browser->getFrames(), 'http://site.with.no.frames/');
}
function testFramesetWithNoFrames() {
$browser = &$this->createBrowser($this->createUserAgent(
array('http://site.with.no.frames/' => '<frameset></frameset>')));
$this->assertEqual($browser->get('http://site.with.no.frames/'), '');
$this->assertIdentical($browser->getFrames(), array());
}
function testFramesetWithSingleFrame() {
$frameset = '<frameset><frame name="a" src="frame.html"></frameset>';
$browser = &$this->createBrowser($this->createUserAgent(array(
'http://site.with.one.frame/' => $frameset,
'http://site.with.one.frame/frame.html' => 'A frame')));
$this->assertEqual($browser->get('http://site.with.one.frame/'), 'A frame');
$this->assertIdentical(
$browser->getFrames(),
array('a' => 'http://site.with.one.frame/frame.html'));
}
function testTitleTakenFromFramesetPage() {
$frameset = '<title>Frameset title</title>' .
'<frameset><frame name="a" src="frame.html"></frameset>';
$browser = &$this->createBrowser($this->createUserAgent(array(
'http://site.with.one.frame/' => $frameset,
'http://site.with.one.frame/frame.html' => '<title>Page title</title>')));
$browser->get('http://site.with.one.frame/');
$this->assertEqual($browser->getTitle(), 'Frameset title');
}
function testFramesetWithSingleUnnamedFrame() {
$frameset = '<frameset><frame src="frame.html"></frameset>';
$browser = &$this->createBrowser($this->createUserAgent(array(
'http://site.with.one.frame/' => $frameset,
'http://site.with.one.frame/frame.html' => 'One frame')));
$this->assertEqual(
$browser->get('http://site.with.one.frame/'),
'One frame');
$this->assertIdentical(
$browser->getFrames(),
array(1 => 'http://site.with.one.frame/frame.html'));
}
function testFramesetWithMultipleFrames() {
$frameset = '<frameset>' .
'<frame name="a" src="frame_a.html">' .
'<frame name="b" src="frame_b.html">' .
'<frame name="c" src="frame_c.html">' .
'</frameset>';
$browser = &$this->createBrowser($this->createUserAgent(array(
'http://site.with.frames/' => $frameset,
'http://site.with.frames/frame_a.html' => 'A frame',
'http://site.with.frames/frame_b.html' => 'B frame',
'http://site.with.frames/frame_c.html' => 'C frame')));
$this->assertEqual(
$browser->get('http://site.with.frames/'),
'A frameB frameC frame');
$this->assertIdentical($browser->getFrames(), array(
'a' => 'http://site.with.frames/frame_a.html',
'b' => 'http://site.with.frames/frame_b.html',
'c' => 'http://site.with.frames/frame_c.html'));
}
function testFrameFocusByName() {
$frameset = '<frameset>' .
'<frame name="a" src="frame_a.html">' .
'<frame name="b" src="frame_b.html">' .
'<frame name="c" src="frame_c.html">' .
'</frameset>';
$browser = &$this->createBrowser($this->createUserAgent(array(
'http://site.with.frames/' => $frameset,
'http://site.with.frames/frame_a.html' => 'A frame',
'http://site.with.frames/frame_b.html' => 'B frame',
'http://site.with.frames/frame_c.html' => 'C frame')));
$browser->get('http://site.with.frames/');
$browser->setFrameFocus('a');
$this->assertEqual($browser->getContent(), 'A frame');
$browser->setFrameFocus('b');
$this->assertEqual($browser->getContent(), 'B frame');
$browser->setFrameFocus('c');
$this->assertEqual($browser->getContent(), 'C frame');
}
function testFramesetWithSomeNamedFrames() {
$frameset = '<frameset>' .
'<frame name="a" src="frame_a.html">' .
'<frame src="frame_b.html">' .
'<frame name="c" src="frame_c.html">' .
'<frame src="frame_d.html">' .
'</frameset>';
$browser = &$this->createBrowser($this->createUserAgent(array(
'http://site.with.frames/' => $frameset,
'http://site.with.frames/frame_a.html' => 'A frame',
'http://site.with.frames/frame_b.html' => 'B frame',
'http://site.with.frames/frame_c.html' => 'C frame',
'http://site.with.frames/frame_d.html' => 'D frame')));
$this->assertEqual(
$browser->get('http://site.with.frames/'),
'A frameB frameC frameD frame');
$this->assertIdentical($browser->getFrames(), array(
'a' => 'http://site.with.frames/frame_a.html',
2 => 'http://site.with.frames/frame_b.html',
'c' => 'http://site.with.frames/frame_c.html',
4 => 'http://site.with.frames/frame_d.html'));
}
function testFrameFocusWithMixedNamesAndIndexes() {
$frameset = '<frameset>' .
'<frame name="a" src="frame_a.html">' .
'<frame src="frame_b.html">' .
'<frame name="c" src="frame_c.html">' .
'<frame src="frame_d.html">' .
'</frameset>';
$browser = &$this->createBrowser($this->createUserAgent(array(
'http://site.with.frames/' => $frameset,
'http://site.with.frames/frame_a.html' => 'A frame',
'http://site.with.frames/frame_b.html' => 'B frame',
'http://site.with.frames/frame_c.html' => 'C frame',
'http://site.with.frames/frame_d.html' => 'D frame')));
$browser->get('http://site.with.frames/');
$browser->setFrameFocus('a');
$this->assertEqual($browser->getContent(), 'A frame');
$browser->setFrameFocus(2);
$this->assertEqual($browser->getContent(), 'B frame');
$browser->setFrameFocus('c');
$this->assertEqual($browser->getContent(), 'C frame');
$browser->setFrameFocus(4);
$this->assertEqual($browser->getContent(), 'D frame');
$browser->clearFrameFocus();
$this->assertEqual($browser->getContent(), 'A frameB frameC frameD frame');
}
function testNestedFrameset() {
$inner = '<frameset>' .
'<frame name="page" src="page.html">' .
'</frameset>';
$outer = '<frameset>' .
'<frame name="inner" src="inner.html">' .
'</frameset>';
$browser = &$this->createBrowser($this->createUserAgent(array(
'http://site.with.nested.frame/' => $outer,
'http://site.with.nested.frame/inner.html' => $inner,
'http://site.with.nested.frame/page.html' => 'The page')));
$this->assertEqual(
$browser->get('http://site.with.nested.frame/'),
'The page');
$this->assertIdentical($browser->getFrames(), array(
'inner' => array(
'page' => 'http://site.with.nested.frame/page.html')));
}
function testCanNavigateToNestedFrame() {
$inner = '<frameset>' .
'<frame name="one" src="one.html">' .
'<frame name="two" src="two.html">' .
'</frameset>';
$outer = '<frameset>' .
'<frame name="inner" src="inner.html">' .
'<frame name="three" src="three.html">' .
'</frameset>';
$browser = &$this->createBrowser($this->createUserAgent(array(
'http://site.with.nested.frames/' => $outer,
'http://site.with.nested.frames/inner.html' => $inner,
'http://site.with.nested.frames/one.html' => 'Page one',
'http://site.with.nested.frames/two.html' => 'Page two',
'http://site.with.nested.frames/three.html' => 'Page three')));
$browser->get('http://site.with.nested.frames/');
$this->assertEqual($browser->getContent(), 'Page onePage twoPage three');
$this->assertTrue($browser->setFrameFocus('inner'));
$this->assertEqual($browser->getFrameFocus(), array('inner'));
$this->assertTrue($browser->setFrameFocus('one'));
$this->assertEqual($browser->getFrameFocus(), array('inner', 'one'));
$this->assertEqual($browser->getContent(), 'Page one');
$this->assertTrue($browser->setFrameFocus('two'));
$this->assertEqual($browser->getFrameFocus(), array('inner', 'two'));
$this->assertEqual($browser->getContent(), 'Page two');
$browser->clearFrameFocus();
$this->assertTrue($browser->setFrameFocus('three'));
$this->assertEqual($browser->getFrameFocus(), array('three'));
$this->assertEqual($browser->getContent(), 'Page three');
$this->assertTrue($browser->setFrameFocus('inner'));
$this->assertEqual($browser->getContent(), 'Page onePage two');
}
function testCanNavigateToNestedFrameByIndex() {
$inner = '<frameset>' .
'<frame src="one.html">' .
'<frame src="two.html">' .
'</frameset>';
$outer = '<frameset>' .
'<frame src="inner.html">' .
'<frame src="three.html">' .
'</frameset>';
$browser = &$this->createBrowser($this->createUserAgent(array(
'http://site.with.nested.frames/' => $outer,
'http://site.with.nested.frames/inner.html' => $inner,
'http://site.with.nested.frames/one.html' => 'Page one',
'http://site.with.nested.frames/two.html' => 'Page two',
'http://site.with.nested.frames/three.html' => 'Page three')));
$browser->get('http://site.with.nested.frames/');
$this->assertEqual($browser->getContent(), 'Page onePage twoPage three');
$this->assertTrue($browser->setFrameFocusByIndex(1));
$this->assertEqual($browser->getFrameFocus(), array(1));
$this->assertTrue($browser->setFrameFocusByIndex(1));
$this->assertEqual($browser->getFrameFocus(), array(1, 1));
$this->assertEqual($browser->getContent(), 'Page one');
$this->assertTrue($browser->setFrameFocusByIndex(2));
$this->assertEqual($browser->getFrameFocus(), array(1, 2));
$this->assertEqual($browser->getContent(), 'Page two');
$browser->clearFrameFocus();
$this->assertTrue($browser->setFrameFocusByIndex(2));
$this->assertEqual($browser->getFrameFocus(), array(2));
$this->assertEqual($browser->getContent(), 'Page three');
$this->assertTrue($browser->setFrameFocusByIndex(1));
$this->assertEqual($browser->getContent(), 'Page onePage two');
}
}
?>

View file

@ -1,51 +0,0 @@
<?php
// $Id: collector_test.php 1505 2007-04-30 23:39:59Z lastcraft $
require_once(dirname(__FILE__) . '/../autorun.php');
require_once(dirname(__FILE__) . '/../collector.php');
SimpleTest::ignore('MockTestSuite');
Mock::generate('TestSuite');
class PathEqualExpectation extends EqualExpectation {
function PathEqualExpectation($value, $message = '%s') {
$this->EqualExpectation(str_replace("\\", '/', $value), $message);
}
function test($compare) {
return parent::test(str_replace("\\", '/', $compare));
}
}
class TestOfCollector extends UnitTestCase {
function testCollectionIsAddedToGroup() {
$suite = &new MockTestSuite();
$suite->expectMinimumCallCount('addTestFile', 2);
$suite->expectArguments(
'addTestFile',
array(new PatternExpectation('/collectable\\.(1|2)$/')));
$collector = &new SimpleCollector();
$collector->collect($suite, dirname(__FILE__) . '/support/collector/');
}
}
class TestOfPatternCollector extends UnitTestCase {
function testAddingEverythingToGroup() {
$suite = &new MockTestSuite();
$suite->expectCallCount('addTestFile', 2);
$suite->expectArguments(
'addTestFile',
array(new PatternExpectation('/collectable\\.(1|2)$/')));
$collector = &new SimplePatternCollector('/.*/');
$collector->collect($suite, dirname(__FILE__) . '/support/collector/');
}
function testOnlyMatchedFilesAreAddedToGroup() {
$suite = &new MockTestSuite();
$suite->expectOnce('addTestFile', array(new PathEqualExpectation(
dirname(__FILE__) . '/support/collector/collectable.1')));
$collector = &new SimplePatternCollector('/1$/');
$collector->collect($suite, dirname(__FILE__) . '/support/collector/');
}
}
?>

View file

@ -1,40 +0,0 @@
<?php
require_once(dirname(__FILE__) . '/../autorun.php');
require_once(dirname(__FILE__) . '/../default_reporter.php');
class TestOfCommandLineParsing extends UnitTestCase {
function testDefaultsToEmptyStringToMeanNullToTheSelectiveReporter() {
$parser = new SimpleCommandLineParser(array());
$this->assertIdentical($parser->getTest(), '');
$this->assertIdentical($parser->getTestCase(), '');
}
function testNotXmlByDefault() {
$parser = new SimpleCommandLineParser(array());
$this->assertFalse($parser->isXml());
}
function testCanDetectRequestForXml() {
$parser = new SimpleCommandLineParser(array('--xml'));
$this->assertTrue($parser->isXml());
}
function testCanReadAssignmentSyntax() {
$parser = new SimpleCommandLineParser(array('--test=myTest'));
$this->assertEqual($parser->getTest(), 'myTest');
}
function testCanReadFollowOnSyntax() {
$parser = new SimpleCommandLineParser(array('--test', 'myTest'));
$this->assertEqual($parser->getTest(), 'myTest');
}
function testCanReadShortForms() {
$parser = new SimpleCommandLineParser(array('-t', 'myTest', '-c', 'MyClass', '-x'));
$this->assertEqual($parser->getTest(), 'myTest');
$this->assertEqual($parser->getTestCase(), 'MyClass');
$this->assertTrue($parser->isXml());
}
}
?>

View file

@ -1,97 +0,0 @@
<?php
// $Id: compatibility_test.php 1505 2007-04-30 23:39:59Z lastcraft $
require_once(dirname(__FILE__) . '/../autorun.php');
require_once(dirname(__FILE__) . '/../compatibility.php');
class ComparisonClass {
}
class ComparisonSubclass extends ComparisonClass {
}
if (version_compare(phpversion(), '5') >= 0) {
eval('interface ComparisonInterface { }');
eval('class ComparisonClassWithInterface implements ComparisonInterface { }');
}
class TestOfCompatibility extends UnitTestCase {
function testIsA() {
$this->assertTrue(SimpleTestCompatibility::isA(
new ComparisonClass(),
'ComparisonClass'));
$this->assertFalse(SimpleTestCompatibility::isA(
new ComparisonClass(),
'ComparisonSubclass'));
$this->assertTrue(SimpleTestCompatibility::isA(
new ComparisonSubclass(),
'ComparisonClass'));
}
function testIdentityOfNumericStrings() {
$numericString1 = "123";
$numericString2 = "00123";
$this->assertNotIdentical($numericString1, $numericString2);
}
function testIdentityOfObjects() {
$object1 = new ComparisonClass();
$object2 = new ComparisonClass();
$this->assertIdentical($object1, $object2);
}
function testReferences () {
$thing = "Hello";
$thing_reference = &$thing;
$thing_copy = $thing;
$this->assertTrue(SimpleTestCompatibility::isReference(
$thing,
$thing));
$this->assertTrue(SimpleTestCompatibility::isReference(
$thing,
$thing_reference));
$this->assertFalse(SimpleTestCompatibility::isReference(
$thing,
$thing_copy));
}
function testObjectReferences () {
$object = &new ComparisonClass();
$object_reference = &$object;
$object_copy = new ComparisonClass();
$object_assignment = $object;
$this->assertTrue(SimpleTestCompatibility::isReference(
$object,
$object));
$this->assertTrue(SimpleTestCompatibility::isReference(
$object,
$object_reference));
$this->assertFalse(SimpleTestCompatibility::isReference(
$object,
$object_copy));
if (version_compare(phpversion(), '5', '>=')) {
$this->assertTrue(SimpleTestCompatibility::isReference(
$object,
$object_assignment));
} else {
$this->assertFalse(SimpleTestCompatibility::isReference(
$object,
$object_assignment));
}
}
function testInteraceComparison() {
if (version_compare(phpversion(), '5', '<')) {
return;
}
$object = new ComparisonClassWithInterface();
$this->assertFalse(SimpleTestCompatibility::isA(
new ComparisonClass(),
'ComparisonInterface'));
$this->assertTrue(SimpleTestCompatibility::isA(
new ComparisonClassWithInterface(),
'ComparisonInterface'));
}
}
?>

View file

@ -1,227 +0,0 @@
<?php
// $Id: cookies_test.php 1506 2007-05-07 00:58:03Z lastcraft $
require_once(dirname(__FILE__) . '/../autorun.php');
require_once(dirname(__FILE__) . '/../cookies.php');
class TestOfCookie extends UnitTestCase {
function testCookieDefaults() {
$cookie = new SimpleCookie("name");
$this->assertFalse($cookie->getValue());
$this->assertEqual($cookie->getPath(), "/");
$this->assertIdentical($cookie->getHost(), false);
$this->assertFalse($cookie->getExpiry());
$this->assertFalse($cookie->isSecure());
}
function testCookieAccessors() {
$cookie = new SimpleCookie(
"name",
"value",
"/path",
"Mon, 18 Nov 2002 15:50:29 GMT",
true);
$this->assertEqual($cookie->getName(), "name");
$this->assertEqual($cookie->getValue(), "value");
$this->assertEqual($cookie->getPath(), "/path/");
$this->assertEqual($cookie->getExpiry(), "Mon, 18 Nov 2002 15:50:29 GMT");
$this->assertTrue($cookie->isSecure());
}
function testFullHostname() {
$cookie = new SimpleCookie("name");
$this->assertTrue($cookie->setHost("host.name.here"));
$this->assertEqual($cookie->getHost(), "host.name.here");
$this->assertTrue($cookie->setHost("host.com"));
$this->assertEqual($cookie->getHost(), "host.com");
}
function testHostTruncation() {
$cookie = new SimpleCookie("name");
$cookie->setHost("this.host.name.here");
$this->assertEqual($cookie->getHost(), "host.name.here");
$cookie->setHost("this.host.com");
$this->assertEqual($cookie->getHost(), "host.com");
$this->assertTrue($cookie->setHost("dashes.in-host.com"));
$this->assertEqual($cookie->getHost(), "in-host.com");
}
function testBadHosts() {
$cookie = new SimpleCookie("name");
$this->assertFalse($cookie->setHost("gibberish"));
$this->assertFalse($cookie->setHost("host.here"));
$this->assertFalse($cookie->setHost("host..com"));
$this->assertFalse($cookie->setHost("..."));
$this->assertFalse($cookie->setHost("host.com."));
}
function testHostValidity() {
$cookie = new SimpleCookie("name");
$cookie->setHost("this.host.name.here");
$this->assertTrue($cookie->isValidHost("host.name.here"));
$this->assertTrue($cookie->isValidHost("that.host.name.here"));
$this->assertFalse($cookie->isValidHost("bad.host"));
$this->assertFalse($cookie->isValidHost("nearly.name.here"));
}
function testPathValidity() {
$cookie = new SimpleCookie("name", "value", "/path");
$this->assertFalse($cookie->isValidPath("/"));
$this->assertTrue($cookie->isValidPath("/path/"));
$this->assertTrue($cookie->isValidPath("/path/more"));
}
function testSessionExpiring() {
$cookie = new SimpleCookie("name", "value", "/path");
$this->assertTrue($cookie->isExpired(0));
}
function testTimestampExpiry() {
$cookie = new SimpleCookie("name", "value", "/path", 456);
$this->assertFalse($cookie->isExpired(0));
$this->assertTrue($cookie->isExpired(457));
$this->assertFalse($cookie->isExpired(455));
}
function testDateExpiry() {
$cookie = new SimpleCookie(
"name",
"value",
"/path",
"Mon, 18 Nov 2002 15:50:29 GMT");
$this->assertTrue($cookie->isExpired("Mon, 18 Nov 2002 15:50:30 GMT"));
$this->assertFalse($cookie->isExpired("Mon, 18 Nov 2002 15:50:28 GMT"));
}
function testAging() {
$cookie = new SimpleCookie("name", "value", "/path", 200);
$cookie->agePrematurely(199);
$this->assertFalse($cookie->isExpired(0));
$cookie->agePrematurely(2);
$this->assertTrue($cookie->isExpired(0));
}
}
class TestOfCookieJar extends UnitTestCase {
function testAddCookie() {
$jar = new SimpleCookieJar();
$jar->setCookie("a", "A");
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array('a=A'));
}
function testHostFilter() {
$jar = new SimpleCookieJar();
$jar->setCookie('a', 'A', 'my-host.com');
$jar->setCookie('b', 'B', 'another-host.com');
$jar->setCookie('c', 'C');
$this->assertEqual(
$jar->selectAsPairs(new SimpleUrl('my-host.com')),
array('a=A', 'c=C'));
$this->assertEqual(
$jar->selectAsPairs(new SimpleUrl('another-host.com')),
array('b=B', 'c=C'));
$this->assertEqual(
$jar->selectAsPairs(new SimpleUrl('www.another-host.com')),
array('b=B', 'c=C'));
$this->assertEqual(
$jar->selectAsPairs(new SimpleUrl('new-host.org')),
array('c=C'));
$this->assertEqual(
$jar->selectAsPairs(new SimpleUrl('/')),
array('a=A', 'b=B', 'c=C'));
}
function testPathFilter() {
$jar = new SimpleCookieJar();
$jar->setCookie('a', 'A', false, '/path/');
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array());
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/elsewhere')), array());
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/path/')), array('a=A'));
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/path')), array('a=A'));
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/pa')), array());
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/path/here')), array('a=A'));
}
function testPathFilterDeeply() {
$jar = new SimpleCookieJar();
$jar->setCookie('a', 'A', false, '/path/more_path/');
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/path/')), array());
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/path')), array());
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/pa')), array());
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/path/more_path/')), array('a=A'));
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/path/more_path/and_more')), array('a=A'));
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/path/not_here/')), array());
}
function testMultipleCookieWithDifferentPathsButSameName() {
$jar = new SimpleCookieJar();
$jar->setCookie('a', 'abc', false, '/');
$jar->setCookie('a', '123', false, '/path/here/');
$this->assertEqual(
$jar->selectAsPairs(new SimpleUrl('/')),
array('a=abc'));
$this->assertEqual(
$jar->selectAsPairs(new SimpleUrl('my-host.com/')),
array('a=abc'));
$this->assertEqual(
$jar->selectAsPairs(new SimpleUrl('my-host.com/path/')),
array('a=abc'));
$this->assertEqual(
$jar->selectAsPairs(new SimpleUrl('my-host.com/path/here')),
array('a=abc', 'a=123'));
$this->assertEqual(
$jar->selectAsPairs(new SimpleUrl('my-host.com/path/here/there')),
array('a=abc', 'a=123'));
}
function testOverwrite() {
$jar = new SimpleCookieJar();
$jar->setCookie('a', 'abc', false, '/');
$jar->setCookie('a', 'cde', false, '/');
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array('a=cde'));
}
function testClearSessionCookies() {
$jar = new SimpleCookieJar();
$jar->setCookie('a', 'A', false, '/');
$jar->restartSession();
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array());
}
function testExpiryFilterByDate() {
$jar = new SimpleCookieJar();
$jar->setCookie('a', 'A', false, '/', 'Wed, 25-Dec-02 04:24:20 GMT');
$jar->restartSession("Wed, 25-Dec-02 04:24:19 GMT");
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array('a=A'));
$jar->restartSession("Wed, 25-Dec-02 04:24:21 GMT");
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array());
}
function testExpiryFilterByAgeing() {
$jar = new SimpleCookieJar();
$jar->setCookie('a', 'A', false, '/', 'Wed, 25-Dec-02 04:24:20 GMT');
$jar->restartSession("Wed, 25-Dec-02 04:24:19 GMT");
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array('a=A'));
$jar->agePrematurely(2);
$jar->restartSession("Wed, 25-Dec-02 04:24:19 GMT");
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array());
}
function testCookieClearing() {
$jar = new SimpleCookieJar();
$jar->setCookie('a', 'abc', false, '/');
$jar->setCookie('a', '', false, '/');
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array('a='));
}
function testCookieClearByLoweringDate() {
$jar = new SimpleCookieJar();
$jar->setCookie('a', 'abc', false, '/', 'Wed, 25-Dec-02 04:24:21 GMT');
$jar->setCookie('a', 'def', false, '/', 'Wed, 25-Dec-02 04:24:19 GMT');
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array('a=def'));
$jar->restartSession('Wed, 25-Dec-02 04:24:20 GMT');
$this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array());
}
}
?>

View file

@ -1,15 +0,0 @@
<?php
// $Id: detached_test.php 1505 2007-04-30 23:39:59Z lastcraft $
require_once('../detached.php');
require_once('../reporter.php');
// The following URL will depend on your own installation.
$command = 'php ' . dirname(__FILE__) . '/visual_test.php xml';
$test = &new TestSuite('Remote tests');
$test->addTestCase(new DetachedTestCase($command));
if (SimpleReporter::inCli()) {
exit ($test->run(new TextReporter()) ? 0 : 1);
}
$test->run(new HtmlReporter());
?>

Some files were not shown because too many files have changed in this diff Show more