Merge branch '1.3-jshelper' into 1.3

This commit is contained in:
gwoo 2009-08-03 11:55:40 -07:00
commit 946f0c85fc
12 changed files with 4053 additions and 413 deletions

View file

@ -1,6 +1,5 @@
<?php
/* SVN FILE: $Id$ */
/**
* Html Helper class file.
*
@ -23,7 +22,6 @@
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
/**
* Html Helper class for easy use of HTML widgets.
*
@ -33,19 +31,11 @@
* @subpackage cake.cake.libs.view.helpers
*/
class HtmlHelper extends AppHelper {
/*************************************************************************
* Public variables
*************************************************************************/
/**#@+
* @access public
*/
/**
* html tags used by this helper.
*
* @var array
* @access public
*/
var $tags = array(
'meta' => '<meta%s/>',
@ -99,13 +89,18 @@ class HtmlHelper extends AppHelper {
'ul' => '<ul%s>%s</ul>',
'ol' => '<ol%s>%s</ol>',
'li' => '<li%s>%s</li>',
'error' => '<div%s>%s</div>'
'error' => '<div%s>%s</div>',
'javascriptblock' => '<script type="text/javascript">%s</script>',
'javascriptstart' => '<script type="text/javascript">',
'javascriptlink' => '<script type="text/javascript" src="%s"></script>',
'javascriptend' => '</script>'
);
/**
* Base URL
*
* @var string
* @access public
*/
var $base = null;
@ -113,6 +108,7 @@ class HtmlHelper extends AppHelper {
* URL to current action.
*
* @var string
* @access public
*/
var $here = null;
@ -120,6 +116,7 @@ class HtmlHelper extends AppHelper {
* Parameter array.
*
* @var array
* @access public
*/
var $params = array();
@ -127,6 +124,7 @@ class HtmlHelper extends AppHelper {
* Current action.
*
* @var string
* @access public
*/
var $action = null;
@ -134,27 +132,31 @@ class HtmlHelper extends AppHelper {
* Enter description here...
*
* @var array
* @access public
*/
var $data = null;
/**#@-*/
/*************************************************************************
* Private variables
*************************************************************************/
/**#@+
* @access private
*/
/**
* Breadcrumbs.
*
* @var array
* @access private
* @access protected
*/
var $_crumbs = array();
/**
* Names of script files that have been included once
*
* @var array
* @access private
**/
var $__includedScripts = array();
/**
* Options for the currently opened script block buffer if any.
*
* @var array
* @access protected
**/
var $_scriptBlockOptions = array();
/**
* Document type definitions
*
@ -177,6 +179,7 @@ class HtmlHelper extends AppHelper {
* @param string $name Text for link
* @param string $link URL for link (if empty it won't be a link)
* @param mixed $options Link attributes e.g. array('id'=>'selected')
* @access public
*/
function addCrumb($name, $link = null, $options = null) {
$this->_crumbs[] = array($name, $link, $options);
@ -195,7 +198,8 @@ class HtmlHelper extends AppHelper {
* + xhtml11: XHTML1.1.
*
* @param string $type Doctype to use.
* @return string Doctype.
* @return string Doctype string
* @access public
*/
function docType($type = 'xhtml-strict') {
if (isset($this->__docTypes[$type])) {
@ -212,6 +216,7 @@ class HtmlHelper extends AppHelper {
* @param array $attributes Other attributes for the generated tag. If the type attribute is html, rss, atom, or icon, the mime-type is returned.
* @param boolean $inline If set to false, the generated tag appears in the head tag of the layout.
* @return string
* @access public
*/
function meta($type, $url = null, $attributes = array(), $inline = true) {
if (!is_array($type)) {
@ -272,6 +277,7 @@ class HtmlHelper extends AppHelper {
*
* @param string $charset The character set to be used in the meta tag. Example: "utf-8".
* @return string A meta tag containing the specified character set.
* @access public
*/
function charset($charset = null) {
if (empty($charset)) {
@ -295,6 +301,7 @@ class HtmlHelper extends AppHelper {
* @param string $confirmMessage JavaScript confirmation message.
* @param boolean $escapeTitle Whether or not $title should be HTML escaped.
* @return string An <a /> element.
* @access public
*/
function link($title, $url = null, $htmlAttributes = array(), $confirmMessage = false, $escapeTitle = true) {
if ($url !== null) {
@ -344,6 +351,7 @@ class HtmlHelper extends AppHelper {
* @param array $htmlAttributes Array of HTML attributes.
* @param boolean $inline If set to false, the generated tag appears in the head tag of the layout.
* @return string CSS <link /> or <style /> tag, depending on the type of link.
* @access public
*/
function css($path, $rel = null, $htmlAttributes = array(), $inline = true) {
if (is_array($path)) {
@ -373,7 +381,11 @@ class HtmlHelper extends AppHelper {
$path = $this->webroot($path);
$url = $path;
if (strpos($path, '?') === false && ((Configure::read('Asset.timestamp') === true && Configure::read() > 0) || Configure::read('Asset.timestamp') === 'force')) {
$timestampEnabled = (
(Configure::read('Asset.timestamp') === true && Configure::read() > 0) ||
Configure::read('Asset.timestamp') === 'force'
);
if (strpos($path, '?') === false && $timestampEnabled) {
$url .= '?' . @filemtime(WWW_ROOT . str_replace('/', DS, $path));
}
@ -400,12 +412,137 @@ class HtmlHelper extends AppHelper {
}
}
/**
* Returns one or many <script> tags depending on the number of scripts given.
*
* If the filename is prefixed with "/", the path will be relative to the base path of your
* application. Otherwise, the path will be relative to your JavaScript path, usually webroot/js.
*
* Can include one or many Javascript files.
*
* @param mixed $url String or array of javascript files to include
* @param boolean $inline Whether script should be output inline or into scripts_for_layout.
* @param boolean $once Whether or not the script should be checked for uniqueness. If true scripts will only be
* included once, use false to allow the same script to be included more than once per request.
* @return mixed String of <script /> tags or null if $inline is false or if $once is true and the file has been
* included before.
**/
function script($url, $inline = true, $once = true) {
if (is_array($url)) {
$out = '';
foreach ($url as $i) {
$out .= "\n\t" . $this->script($i, $inline, $once);
}
if ($inline) {
return $out . "\n";
}
return null;
}
if ($once && isset($this->__includedScripts[$url])) {
return null;
}
$this->__includedScripts[$url] = true;
if (strpos($url, '://') === false) {
if ($url[0] !== '/') {
$url = JS_URL . $url;
}
$url = $this->webroot($url);
if (strpos($url, '?') === false) {
if (strpos($url, '.js') === false) {
$url .= '.js';
}
}
$timestampEnabled = (
(Configure::read('Asset.timestamp') === true && Configure::read('debug') > 0) ||
Configure::read('Asset.timestamp') === 'force'
);
if (strpos($url, '?') === false && $timestampEnabled) {
$url .= '?' . @filemtime(WWW_ROOT . str_replace('/', DS, $url));
}
if (Configure::read('Asset.filter.js')) {
$url = str_replace(JS_URL, 'cjs/', $url);
}
}
$out = $this->output(sprintf($this->tags['javascriptlink'], $url));
if ($inline) {
return $out;
} else {
$view =& ClassRegistry::getObject('view');
$view->addScript($out);
}
}
/**
* Wrap $script in a script tag.
*
* ### Options
*
* - `safe` (boolean) Whether or not the $script should be wrapped in <![CDATA[ ]]>
* - `inline` (boolean) Whether or not the $script should be added to $scripts_for_layout or output inline
*
* @param string $script The script to wrap
* @param array $options The options to use.
* @return mixed string or null
**/
function scriptBlock($script, $options = array()) {
$defaultOptions = array('safe' => true, 'inline' => true);
$options = array_merge($defaultOptions, $options);
if ($options['safe']) {
$script = "\n" . '//<![CDATA[' . "\n" . $script . "\n" . '//]]>' . "\n";
}
if ($options['inline']) {
return sprintf($this->tags['javascriptblock'], $script);
} else {
$view =& ClassRegistry::getObject('view');
$view->addScript(sprintf($this->tags['javascriptblock'], $script));
return null;
}
}
/**
* Begin a script block that captures output until HtmlHelper::scriptEnd()
* is called. This capturing block will capture all output between the methods
* and create a scriptBlock from it.
*
* ### Options
*
* - `safe` Whether the code block should contain a CDATA
* - `inline` Should the generated script tag be output inline or in `$scripts_for_layout`
*
* @param array $options Options for the code block.
* @return void
**/
function scriptStart($options = array()) {
$defaultOptions = array('safe' => true, 'inline' => true);
$options = array_merge($defaultOptions, $options);
$this->_scriptBlockOptions = $options;
ob_start();
return null;
}
/**
* End a Buffered section of Javascript capturing.
* Generates a script tag inline or in `$scripts_for_layout` depending on the settings
* used when the scriptBlock was started
*
* @return mixed depending on the settings of scriptStart() either a script tag or null
**/
function scriptEnd() {
$buffer = ob_get_clean();
$options = $this->_scriptBlockOptions;
$this->_scriptBlockOptions = array();
return $this->scriptBlock($buffer, $options);
}
/**
* Builds CSS style data from an array of CSS properties
*
* @param array $data Style data array
* @param boolean $inline Whether or not the style block should be displayed inline
* @return string CSS styling data
* @access public
*/
function style($data, $inline = true) {
if (!is_array($data)) {
@ -427,6 +564,7 @@ class HtmlHelper extends AppHelper {
* @param string $separator Text to separate crumbs.
* @param string $startText This will be the first crumb, if false it defaults to first crumb in array
* @return string
* @access public
*/
function getCrumbs($separator = '&raquo;', $startText = false) {
if (count($this->_crumbs)) {
@ -453,7 +591,8 @@ class HtmlHelper extends AppHelper {
*
* @param string $path Path to the image file, relative to the app/webroot/img/ directory.
* @param array $options Array of HTML attributes.
* @return string
* @return string completed img tag
* @access public
*/
function image($path, $options = array()) {
if (is_array($path)) {
@ -462,7 +601,6 @@ class HtmlHelper extends AppHelper {
$path = $this->webroot($path);
} elseif (strpos($path, '://') === false) {
$path = $this->webroot(IMAGES_URL . $path);
if ((Configure::read('Asset.timestamp') == true && Configure::read() > 0) || Configure::read('Asset.timestamp') === 'force') {
$path .= '?' . @filemtime(str_replace('/', DS, WWW_ROOT . $path));
}
@ -490,10 +628,11 @@ class HtmlHelper extends AppHelper {
/**
* Returns a row of formatted and named TABLE headers.
*
* @param array $names Array of tablenames.
* @param array $trOptions HTML options for TR elements.
* @param array $thOptions HTML options for TH elements.
* @return string
* @param array $names Array of tablenames.
* @param array $trOptions HTML options for TR elements.
* @param array $thOptions HTML options for TH elements.
* @return string Completed table headers
* @access public
*/
function tableHeaders($names, $trOptions = null, $thOptions = null) {
$out = array();
@ -513,6 +652,7 @@ class HtmlHelper extends AppHelper {
* @param bool $useCount adds class "column-$i"
* @param bool $continueOddEven If false, will use a non-static $count variable, so that the odd/even count is reset to zero just for that call
* @return string Formatted HTML
* @access public
*/
function tableCells($data, $oddTrOptions = null, $evenTrOptions = null, $useCount = false, $continueOddEven = true) {
if (empty($data[0]) || !is_array($data[0])) {
@ -565,6 +705,7 @@ class HtmlHelper extends AppHelper {
* @param array $attributes Additional HTML attributes of the DIV tag
* @param boolean $escape If true, $text will be HTML-escaped
* @return string The formatted tag element
* @access public
*/
function tag($name, $text = null, $attributes = array(), $escape = false) {
if ($escape) {
@ -590,6 +731,7 @@ class HtmlHelper extends AppHelper {
* @param array $attributes Additional HTML attributes of the DIV tag
* @param boolean $escape If true, $text will be HTML-escaped
* @return string The formatted DIV element
* @access public
*/
function div($class = null, $text = null, $attributes = array(), $escape = false) {
if ($class != null && !empty($class)) {
@ -606,6 +748,7 @@ class HtmlHelper extends AppHelper {
* @param array $attributes Additional HTML attributes of the P tag
* @param boolean $escape If true, $text will be HTML-escaped
* @return string The formatted P element
* @access public
*/
function para($class, $text, $attributes = array(), $escape = false) {
if ($escape) {

View file

@ -0,0 +1,334 @@
<?php
/**
* jQuery Engine Helper for JsHelper
*
* Provides jQuery specific Javascript for JsHelper.
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake
* @subpackage cake.view.helpers
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
App::import('Helper', 'Js');
class JqueryEngineHelper extends JsBaseEngineHelper {
/**
* Option mappings for jQuery
*
* @var array
**/
var $_optionMap = array(
'request' => array(
'type' => 'dataType',
'before' => 'beforeSend',
'method' => 'type',
),
'sortable' => array(
'complete' => 'stop',
),
'drag' => array(
'snapGrid' => 'grid',
'container' => 'containment',
),
'drop' => array(
'leave' => 'out',
'hover' => 'over'
),
'slider' => array(
'complete' => 'stop',
'direction' => 'orientation'
)
);
/**
* callback arguments lists
*
* @var string
**/
var $_callbackArguments = array(
'slider' => array(
'start' => 'event, ui',
'slide' => 'event, ui',
'change' => 'event, ui',
'stop' => 'event, ui'
),
'sortable' => array(
'start' => 'event, ui',
'sort' => 'event, ui',
'change' => 'event, ui',
'beforeStop' => 'event, ui',
'stop' => 'event, ui',
'update' => 'event, ui',
'receive' => 'event, ui',
'remove' => 'event, ui',
'over' => 'event, ui',
'out' => 'event, ui',
'activate' => 'event, ui',
'deactivate' => 'event, ui'
),
'drag' => array(
'start' => 'event, ui',
'drag' => 'event, ui',
'stop' => 'event, ui',
),
'drop' => array(
'activate' => 'event, ui',
'deactivate' => 'event, ui',
'over' => 'event, ui',
'out' => 'event, ui',
'drop' => 'event, ui'
),
'request' => array(
'beforeSend' => 'XMLHttpRequest',
'error' => 'XMLHttpRequest, textStatus, errorThrown',
'success' => 'data, textStatus',
'complete' => 'XMLHttpRequest, textStatus',
'xhr' => ''
)
);
/**
* The variable name of the jQuery Object, useful
* when jQuery is put into noConflict() mode.
*
* @var string
**/
var $jQueryObject = '$';
/**
* Helper function to wrap repetitive simple method templating.
*
* @param string $method The method name being generated.
* @param string $template The method template
* @param string $selection the selection to apply
* @param string $options Array of options for method
* @param string $callbacks Array of callback / special options.
* @access public
* @return string
**/
function _methodTemplate($method, $template, $options, $extraSafeKeys = array()) {
$options = $this->_mapOptions($method, $options);
$options = $this->_prepareCallbacks($method, $options);
$callbacks = array_keys($this->_callbackArguments[$method]);
if (!empty($extraSafeKeys)) {
$callbacks = array_merge($callbacks, $extraSafeKeys);
}
$options = $this->_parseOptions($options, $callbacks);
return sprintf($template, $this->selection, $options);
}
/**
* Create javascript selector for a CSS rule
*
* @param string $selector The selector that is targeted
* @return object instance of $this. Allows chained methods.
**/
function get($selector) {
if ($selector == 'window' || $selector == 'document') {
$this->selection = $this->jQueryObject . '(' . $selector .')';
} else {
$this->selection = $this->jQueryObject . '("' . $selector . '")';
}
return $this;
}
/**
* Add an event to the script cache. Operates on the currently selected elements.
*
* ### Options
*
* - 'wrap' - Whether you want the callback wrapped in an anonymous function. (defaults true)
* - 'stop' - Whether you want the event to stopped. (defaults true)
*
* @param string $type Type of event to bind to the current dom id
* @param string $callback The Javascript function you wish to trigger or the function literal
* @param array $options Options for the event.
* @return string completed event handler
**/
function event($type, $callback, $options = array()) {
$defaults = array('wrap' => true, 'stop' => true);
$options = array_merge($defaults, $options);
$function = 'function (event) {%s}';
if ($options['wrap'] && $options['stop']) {
$callback .= "\nreturn false;";
}
if ($options['wrap']) {
$callback = sprintf($function, $callback);
}
return sprintf('%s.bind("%s", %s);', $this->selection, $type, $callback);
}
/**
* Create a domReady event. This is a special event in many libraries
*
* @param string $functionBody The code to run on domReady
* @return string completed domReady method
**/
function domReady($functionBody) {
$this->get('document');
return $this->event('ready', $functionBody, array('stop' => false));
}
/**
* Create an iteration over the current selection result.
*
* @param string $method The method you want to apply to the selection
* @param string $callback The function body you wish to apply during the iteration.
* @return string completed iteration
**/
function each($callback) {
return $this->selection . '.each(function () {' . $callback . '});';
}
/**
* Trigger an Effect.
*
* @param string $name The name of the effect to trigger.
* @param array $options Array of options for the effect.
* @return string completed string with effect.
* @see JsBaseEngineHelper::effect()
**/
function effect($name, $options = array()) {
$speed = null;
if (isset($options['speed']) && in_array($options['speed'], array('fast', 'slow'))) {
$speed = $this->value($options['speed']);
}
$effect = '';
switch ($name) {
case 'slideIn':
case 'slideOut':
$name = ($name == 'slideIn') ? 'slideDown' : 'slideUp';
case 'hide':
case 'show':
case 'fadeIn':
case 'fadeOut':
case 'slideDown':
case 'slideUp':
$effect = ".$name($speed);";
break;
}
return $this->selection . $effect;
}
/**
* Create an $.ajax() call.
*
* If the 'update' key is set, success callback will be overridden.
*
* @param mixed $url
* @param array $options
* @return string The completed ajax call.
**/
function request($url, $options = array()) {
$url = $this->url($url);
$options = $this->_mapOptions('request', $options);
if (isset($options['data']) && is_array($options['data'])) {
$options['data'] = $this->_toQuerystring($options['data']);
}
$options['url'] = $url;
if (isset($options['update'])) {
$options['success'] = 'function (msg, status) {$("' . $options['update'] . '").html(msg);}';
unset($options['update']);
}
$callbacks = array('success', 'error', 'beforeSend', 'complete');
if (isset($options['dataExpression'])) {
$callbacks[] = 'data';
unset($options['dataExpression']);
}
$options = $this->_prepareCallbacks('request', $options);
$options = $this->_parseOptions($options, $callbacks);
return '$.ajax({' . $options .'});';
}
/**
* Create a sortable element.
*
* Requires both Ui.Core and Ui.Sortables to be loaded.
*
* @param array $options Array of options for the sortable.
* @return string Completed sortable script.
* @see JsHelper::sortable() for options list.
**/
function sortable($options = array()) {
$template = '%s.sortable({%s});';
return $this->_methodTemplate('sortable', $template, $options);
}
/**
* Create a Draggable element
*
* Requires both Ui.Core and Ui.Draggable to be loaded.
*
* @param array $options Array of options for the draggable element.
* @return string Completed Draggable script.
* @see JsHelper::drag() for options list.
**/
function drag($options = array()) {
$template = '%s.draggable({%s});';
return $this->_methodTemplate('drag', $template, $options);
}
/**
* Create a Droppable element
*
* Requires both Ui.Core and Ui.Droppable to be loaded.
*
* @param array $options Array of options for the droppable element.
* @return string Completed Droppable script.
* @see JsHelper::drop() for options list.
**/
function drop($options = array()) {
$template = '%s.droppable({%s});';
return $this->_methodTemplate('drop', $template, $options);
}
/**
* Create a Slider element
*
* Requires both Ui.Core and Ui.Slider to be loaded.
*
* @param array $options Array of options for the droppable element.
* @return string Completed Slider script.
* @see JsHelper::slider() for options list.
**/
function slider($options = array()) {
$callbacks = array('start', 'change', 'slide', 'stop');
$template = '%s.slider({%s});';
return $this->_methodTemplate('slider', $template, $options, $callbacks);
}
/**
* Serialize a form attached to $selector. If the current selection is not an input or
* form, errors will be created in the Javascript.
*
* @param array $options Options for the serialization
* @return string completed form serialization script
* @see JsHelper::serializeForm() for option list.
**/
function serializeForm($options = array()) {
$options = array_merge(array('isForm' => false, 'inline' => false), $options);
$selector = $this->selection;
if (!$options['isForm']) {
$selector = $this->selection . '.closest("form")';
}
$method = '.serialize()';
if (!$options['inline']) {
$method .= ';';
}
return $selector . $method;
}
}
?>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,376 @@
<?php
/**
* MooTools Engine Helper for JsHelper
*
* Provides MooTools specific Javascript for JsHelper.
* Assumes that you have the following MooTools packages
*
* - Remote, Remote.HTML, Remote.JSON
* - Fx, Fx.Tween, Fx.Morph
* - Selectors, DomReady,
* - Drag, Drag.Move
*
* PHP versions 4 and 5
*
* CakePHP(tm) : Rapid Development Framework (http://www.cakephp.org)
* Copyright 2005-2009, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2005-2009, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
* @package cake
* @subpackage cake.libs.view.helpers
* @since CakePHP(tm) v 1.3
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
App::import('Helper', 'Js');
class MootoolsEngineHelper extends JsBaseEngineHelper {
/**
* Option mappings for MooTools
*
* @var array
**/
var $_optionMap = array(
'request' => array(
'complete' => 'onComplete',
'success' => 'onSuccess',
'before' => 'onRequest',
'error' => 'onFailure'
),
'sortable' => array(
'distance' => 'snap',
'containment' => 'constrain',
'sort' => 'onSort',
'complete' => 'onComplete',
'start' => 'onStart',
),
'drag' => array(
'snapGrid' => 'snap',
'start' => 'onStart',
'drag' => 'onDrag',
'stop' => 'onComplete',
),
'drop' => array(
'drop' => 'onDrop',
'hover' => 'onEnter',
'leave' => 'onLeave',
),
'slider' => array(
'complete' => 'onComplete',
'change' => 'onChange',
'direction' => 'mode',
'step' => 'steps'
)
);
/**
* Contains a list of callback names -> default arguments.
*
* @var array
**/
var $_callbackArguments = array(
'slider' => array(
'onTick' => 'position',
'onChange' => 'step',
'onComplete' => 'event'
),
'request' => array(
'onRequest' => '',
'onComplete' => '',
'onCancel' => '',
'onSuccess' => 'responseText, responseXML',
'onFailure' => 'xhr',
'onException' => 'headerName, value',
),
'drag' => array(
'onBeforeStart' => 'element',
'onStart' => 'element',
'onSnap' => 'element',
'onDrag' => 'element, event',
'onComplete' => 'element, event',
'onCancel' => 'element',
),
'drop' => array(
'onBeforeStart' => 'element',
'onStart' => 'element',
'onSnap' => 'element',
'onDrag' => 'element, event',
'onComplete' => 'element, event',
'onCancel' => 'element',
'onDrop' => 'element, droppable, event',
'onLeave' => 'element, droppable',
'onEnter' => 'element, droppable',
),
'sortable' => array(
'onStart' => 'element, clone',
'onSort' => 'element, clone',
'onComplete' => 'element',
)
);
/**
* Create javascript selector for a CSS rule
*
* @param string $selector The selector that is targeted
* @return object instance of $this. Allows chained methods.
**/
function get($selector) {
$this->_multipleSelection = false;
if ($selector == 'window' || $selector == 'document') {
$this->selection = "$(" . $selector .")";
return $this;
}
if (preg_match('/^#[^\s.]+$/', $selector)) {
$this->selection = '$("' . substr($selector, 1) . '")';
return $this;
}
$this->_multipleSelection = true;
$this->selection = '$$("' . $selector . '")';
return $this;
}
/**
* Add an event to the script cache. Operates on the currently selected elements.
*
* ### Options
*
* - 'wrap' - Whether you want the callback wrapped in an anonymous function. (defaults true)
* - 'stop' - Whether you want the event to stopped. (defaults true)
*
* @param string $type Type of event to bind to the current dom id
* @param string $callback The Javascript function you wish to trigger or the function literal
* @param array $options Options for the event.
* @return string completed event handler
**/
function event($type, $callback, $options = array()) {
$defaults = array('wrap' => true, 'stop' => true);
$options = array_merge($defaults, $options);
$function = 'function (event) {%s}';
if ($options['wrap'] && $options['stop']) {
$callback = "event.stop();\n" . $callback;
}
if ($options['wrap']) {
$callback = sprintf($function, $callback);
}
$out = $this->selection . ".addEvent(\"{$type}\", $callback);";
return $out;
}
/**
* Create a domReady event. This is a special event in many libraries
*
* @param string $functionBody The code to run on domReady
* @return string completed domReady method
**/
function domReady($functionBody) {
$this->selection = 'window';
return $this->event('domready', $functionBody, array('stop' => false));
}
/**
* Create an iteration over the current selection result.
*
* @param string $method The method you want to apply to the selection
* @param string $callback The function body you wish to apply during the iteration.
* @return string completed iteration
**/
function each($callback) {
return $this->selection . '.each(function (item, index) {' . $callback . '});';
}
/**
* Trigger an Effect.
*
* @param string $name The name of the effect to trigger.
* @param array $options Array of options for the effect.
* @return string completed string with effect.
* @see JsBaseEngineHelper::effect()
**/
function effect($name, $options = array()) {
$speed = null;
if (isset($options['speed']) && in_array($options['speed'], array('fast', 'slow'))) {
if ($options['speed'] == 'fast') {
$speed = '"short"';
} elseif ($options['speed'] == 'slow') {
$speed = '"long"';
}
}
$effect = '';
switch ($name) {
case 'hide':
$effect = 'setStyle("display", "none")';
break;
case 'show':
$effect = 'setStyle("display", "")';
break;
case 'fadeIn':
case 'fadeOut':
case 'slideIn':
case 'slideOut':
list($effectName, $direction) = preg_split('/([A-Z][a-z]+)/', $name, -1, PREG_SPLIT_DELIM_CAPTURE);
$direction = strtolower($direction);
if ($speed) {
$effect .= "set(\"$effectName\", {duration:$speed}).";
}
$effect .= "$effectName(\"$direction\")";
break;
}
return $this->selection . '.' . $effect . ';';
}
/**
* Create an new Request.
*
* Requires `Request`. If you wish to use 'update' key you must have ```Request.HTML```
* if you wish to do Json requests you will need ```JSON``` and ```Request.JSON```.
*
* @param mixed $url
* @param array $options
* @return string The completed ajax call.
**/
function request($url, $options = array()) {
$url = $this->url($url);
$options = $this->_mapOptions('request', $options);
$type = $data = null;
if (isset($options['type']) || isset($options['update'])) {
if (isset($options['type']) && strtolower($options['type']) == 'json') {
$type = '.JSON';
}
if (isset($options['update'])) {
$options['update'] = str_replace('#', '', $options['update']);
$type = '.HTML';
}
unset($options['type']);
}
if (!empty($options['data'])) {
$data = $options['data'];
unset($options['data']);
}
$options['url'] = $url;
$options = $this->_prepareCallbacks('request', $options);
if (isset($options['dataExpression'])) {
$callbacks[] = 'data';
unset($options['dataExpression']);
} elseif (!empty($data)) {
$data = $this->object($data);
}
$options = $this->_parseOptions($options, array_keys($this->_callbackArguments['request']));
return "var jsRequest = new Request$type({{$options}}).send($data);";
}
/**
* Create a sortable element.
*
* Requires the `Sortables` plugin from MootoolsMore
*
* @param array $options Array of options for the sortable.
* @return string Completed sortable script.
* @see JsHelper::sortable() for options list.
**/
function sortable($options = array()) {
$options = $this->_processOptions('sortable', $options);
return 'var jsSortable = new Sortables(' . $this->selection . ', {' . $options . '});';
}
/**
* Create a Draggable element.
*
* Requires the `Drag` plugin from MootoolsMore
*
* @param array $options Array of options for the draggable.
* @return string Completed draggable script.
* @see JsHelper::drag() for options list.
**/
function drag($options = array()) {
$options = $this->_processOptions('drag', $options);
return $this->selection . '.makeDraggable({' . $options . '});';
}
/**
* Create a Droppable element.
*
* Requires the `Drag` and `Drag.Move` plugins from MootoolsMore
*
* Droppables in Mootools function differently from other libraries. Droppables
* are implemented as an extension of Drag. So in addtion to making a get() selection for
* the droppable element. You must also provide a selector rule to the draggable element. Furthermore,
* Mootools droppables inherit all options from Drag.
*
* @param array $options Array of options for the droppable.
* @return string Completed droppable script.
* @see JsHelper::drop() for options list.
**/
function drop($options = array()) {
if (empty($options['drag'])) {
trigger_error(
__('MootoolsEngine::drop() requires a "drag" option to properly function', true), E_USER_WARNING
);
return false;
}
$options['droppables'] = $this->selection;
$this->get($options['drag']);
unset($options['drag']);
$options = $this->_mapOptions('drag', $this->_mapOptions('drop', $options));
$options = $this->_prepareCallbacks('drop', $options);
$safe = array_merge(array_keys($this->_callbackArguments['drop']), array('droppables'));
$optionString = $this->_parseOptions($options, $safe);
$out = $this->selection . '.makeDraggable({' . $optionString . '});';
$this->selection = $options['droppables'];
return $out;
}
/**
* Create a slider control
*
* Requires `Slider` from MootoolsMore
*
* @param array $options Array of options for the slider.
* @return string Completed slider script.
* @see JsHelper::slider() for options list.
**/
function slider($options = array()) {
$slider = $this->selection;
$this->get($options['handle']);
unset($options['handle']);
if (isset($options['min']) && isset($options['max'])) {
$options['range'] = array($options['min'], $options['max']);
unset($options['min'], $options['max']);
}
$optionString = $this->_processOptions('slider', $options);
if (!empty($optionString)) {
$optionString = ', {' . $optionString . '}';
}
$out = 'var jsSlider = new Slider(' . $slider . ', ' . $this->selection . $optionString . ');';
$this->selection = $slider;
return $out;
}
/**
* Serialize the form attached to $selector.
*
* @param array $options Array of options.
* @return string Completed serializeForm() snippet
* @see JsHelper::serializeForm()
**/
function serializeForm($options = array()) {
$options = array_merge(array('isForm' => false, 'inline' => false), $options);
$selection = $this->selection;
if (!$options['isForm']) {
$selection = '$(' . $this->selection . '.form)';
}
$method = '.toQueryString()';
if (!$options['inline']) {
$method .= ';';
}
return $selection . $method;
}
}
?>

View file

@ -0,0 +1,348 @@
<?php
/**
* Prototype Engine Helper for JsHelper
*
* Provides Prototype specific Javascript for JsHelper. Requires at least
* Prototype 1.6
*
* PHP versions 4 and 5
*
* CakePHP(tm) : Rapid Development Framework (http://www.cakephp.org)
* Copyright 2005-2009, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2005-2009, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
* @package cake
* @subpackage cake.libs.view.helpers
* @since CakePHP(tm) v 1.3
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
App::import('Helper', 'Js');
class PrototypeEngineHelper extends JsBaseEngineHelper {
/**
* Is the current selection a multiple selection? or is it just a single element.
*
* @var boolean
**/
var $_multiple = false;
/**
* Option mappings for Prototype
*
* @var array
**/
var $_optionMap = array(
'request' => array(
'async' => 'asyncrhronous',
'data' => 'parameters',
'before' => 'onCreate',
'success' => 'onSuccess',
'complete' => 'onComplete',
'error' => 'onFailure'
),
'sortable' => array(
'start' => 'onStart',
'sort' => 'onChange',
'complete' => 'onUpdate',
'distance' => 'snap',
),
'drag' => array(
'snapGrid' => 'snap',
'container' => 'constraint',
'stop' => 'onEnd',
'start' => 'onStart',
'drag' => 'onDrag',
),
'drop' => array(
'hover' => 'onHover',
'drop' => 'onDrop',
'hoverClass' => 'hoverclass',
),
'slider' => array(
'direction' => 'axis',
'change' => 'onSlide',
'complete' => 'onChange',
'value' => 'sliderValue',
)
);
/**
* Contains a list of callback names -> default arguments.
*
* @var array
**/
var $_callbackArguments = array(
'slider' => array(
'onSlide' => 'value',
'onChange' => 'value',
),
'drag' => array(
'onStart' => 'event',
'onDrag' => 'event',
'change' => 'draggable',
'onEnd' => 'event',
),
'drop' => array(
'onHover' => 'draggable, droppable, event',
'onDrop' => 'draggable, droppable, event',
),
'request' => array(
'onCreate' => 'transport',
'onComplete' => 'transport',
'onFailure' => 'response, jsonHeader',
'onRequest' => 'transport',
'onSuccess' => 'response, jsonHeader'
),
'sortable' => array(
'onStart' => 'element',
'onChange' => 'element',
'onUpdate' => 'element',
),
);
/**
* Create javascript selector for a CSS rule
*
* @param string $selector The selector that is targeted
* @return object instance of $this. Allows chained methods.
**/
function get($selector) {
$this->_multiple = false;
if ($selector == 'window' || $selector == 'document') {
$this->selection = "$(" . $selector .")";
return $this;
}
if (preg_match('/^#[^\s.]+$/', $selector)) {
$this->selection = '$("' . substr($selector, 1) . '")';
return $this;
}
$this->_multiple = true;
$this->selection = '$$("' . $selector . '")';
return $this;
}
/**
* Add an event to the script cache. Operates on the currently selected elements.
*
* ### Options
*
* - 'wrap' - Whether you want the callback wrapped in an anonymous function. (defaults true)
* - 'stop' - Whether you want the event to stopped. (defaults true)
*
* @param string $type Type of event to bind to the current 946 id
* @param string $callback The Javascript function you wish to trigger or the function literal
* @param array $options Options for the event.
* @return string completed event handler
**/
function event($type, $callback, $options = array()) {
$defaults = array('wrap' => true, 'stop' => true);
$options = array_merge($defaults, $options);
$function = 'function (event) {%s}';
if ($options['wrap'] && $options['stop']) {
$callback = "event.stop();\n" . $callback;
}
if ($options['wrap']) {
$callback = sprintf($function, $callback);
}
$out = $this->selection . ".observe(\"{$type}\", $callback);";
return $out;
}
/**
* Create a domReady event. This is a special event in many libraries
*
* @param string $functionBody The code to run on domReady
* @return string completed domReady method
**/
function domReady($functionBody) {
$this->selection = 'document';
return $this->event('dom:loaded', $functionBody, array('stop' => false));
}
/**
* Create an iteration over the current selection result.
*
* @param string $method The method you want to apply to the selection
* @param string $callback The function body you wish to apply during the iteration.
* @return string completed iteration
**/
function each($callback) {
return $this->selection . '.each(function (item, index) {' . $callback . '});';
}
/**
* Trigger an Effect.
*
* #### Note: Effects require Scriptaculous to be loaded.
*
* @param string $name The name of the effect to trigger.
* @param array $options Array of options for the effect.
* @return string completed string with effect.
* @see JsBaseEngineHelper::effect()
**/
function effect($name, $options = array()) {
$effect = '';
$optionString = null;
if (isset($options['speed'])) {
if ($options['speed'] == 'fast') {
$options['duration'] = 0.5;
} elseif ($options['speed'] == 'slow') {
$options['duration'] = 2;
} else {
$options['duration'] = 1;
}
unset($options['speed']);
}
if (!empty($options)) {
$optionString = ', {' . $this->_parseOptions($options) . '}';
}
switch ($name) {
case 'hide':
case 'show':
$effect = $this->selection . '.' . $name . '();';
break;
case 'slideIn':
case 'slideOut':
$name = ($name == 'slideIn') ? 'slideDown' : 'slideUp';
$effect = 'Effect.' . $name . '(' . $this->selection . $optionString . ');';
break;
case 'fadeIn':
case 'fadeOut':
$name = ($name == 'fadeIn') ? 'appear' : 'fade';
$effect = $this->selection . '.' . $name .'(' . substr($optionString, 2) . ');';
break;
}
return $effect;
}
/**
* Create an Ajax or Ajax.Updater call.
*
* @param mixed $url
* @param array $options
* @return string The completed ajax call.
**/
function request($url, $options = array()) {
$url = '"'. $this->url($url) . '"';
$options = $this->_mapOptions('request', $options);
$type = '.Request';
$data = null;
if (isset($options['type']) && strtolower($options['type']) == 'json') {
unset($options['type']);
}
if (isset($options['update'])) {
$url = '"' . str_replace('#', '', $options['update']) . '", ' . $url;
$type = '.Updater';
unset($options['update'], $options['type']);
}
$safe = array();
if (isset($options['dataExpression'])) {
$safe[] = 'parameters';
unset($options['dataExpression']);
}
$safe = array_merge($safe, array_keys($this->_callbackArguments['request']));
$options = $this->_prepareCallbacks('request', $options, $safe);
$options = $this->_parseOptions($options, $safe);
if (!empty($options)) {
$options = ', {' . $options . '}';
}
return "var jsRequest = new Ajax$type($url$options);";
}
/**
* Create a sortable element.
*
* #### Note: Requires scriptaculous to be loaded.
*
* @param array $options Array of options for the sortable.
* @return string Completed sortable script.
* @see JsHelper::sortable() for options list.
**/
function sortable($options = array()) {
$options = $this->_processOptions('sortable', $options);
if (!empty($options)) {
$options = ', {' . $options . '}';
}
return 'var jsSortable = Sortable.create(' . $this->selection . $options . ');';
}
/**
* Create a Draggable element.
*
* #### Note: Requires scriptaculous to be loaded.
*
* @param array $options Array of options for the draggable.
* @return string Completed draggable script.
* @see JsHelper::draggable() for options list.
**/
function drag($options = array()) {
$options = $this->_processOptions('drag', $options);
if (!empty($options)) {
$options = ', {' . $options . '}';
}
if ($this->_multiple) {
return $this->each('new Draggable(item' . $options . ');');
}
return 'var jsDrag = new Draggable(' . $this->selection . $options . ');';
}
/**
* Create a Droppable element.
*
* #### Note: Requires scriptaculous to be loaded.
*
* @param array $options Array of options for the droppable.
* @return string Completed droppable script.
* @see JsHelper::droppable() for options list.
**/
function drop($options = array()) {
$options = $this->_processOptions('drop', $options);
if (!empty($options)) {
$options = ', {' . $options . '}';
}
return 'Droppables.add(' . $this->selection . $options . ');';
}
/**
* Creates a slider control widget.
*
* ### Note: Requires scriptaculous to be loaded.
*
* @param array $options Array of options for the slider.
* @return string Completed slider script.
* @see JsHelper::slider() for options list.
**/
function slider($options = array()) {
$slider = $this->selection;
$this->get($options['handle']);
unset($options['handle']);
if (isset($options['min']) && isset($options['max'])) {
$options['range'] = array($options['min'], $options['max']);
unset($options['min'], $options['max']);
}
$optionString = $this->_processOptions('slider', $options);
if (!empty($optionString)) {
$optionString = ', {' . $optionString . '}';
}
$out = 'var jsSlider = new Control.Slider(' . $this->selection . ', ' . $slider . $optionString . ');';
$this->selection = $slider;
return $out;
}
/**
* Serialize the form attached to $selector.
*
* @param array $options Array of options.
* @return string Completed serializeForm() snippet
* @see JsHelper::serializeForm()
**/
function serializeForm($options = array()) {
$options = array_merge(array('isForm' => false, 'inline' => false), $options);
$selection = $this->selection;
if (!$options['isForm']) {
$selection = '$(' . $this->selection . '.form)';
}
$method = '.serialize()';
if (!$options['inline']) {
$method .= ';';
}
return $selection . $method;
}
}
?>

View file

@ -53,6 +53,8 @@ class TheHtmlTestController extends Controller {
var $uses = null;
}
Mock::generate('View', 'HtmlHelperMockView');
/**
* HtmlHelperTest class
*
@ -62,7 +64,19 @@ class TheHtmlTestController extends Controller {
class HtmlHelperTest extends CakeTestCase {
/**
* Html property
* Regexp for CDATA start block
*
* @var string
*/
var $cDataStart = 'preg:/^\/\/<!\[CDATA\[[\n\r]*/';
/**
* Regexp for CDATA end block
*
* @var string
*/
var $cDataEnd = 'preg:/[^\]]*\]\]\>[\s\r\n]*/';
/**
* html property
*
* @var object
* @access public
@ -99,7 +113,7 @@ class HtmlHelperTest extends CakeTestCase {
* @access public
* @return void
*/
function setUp() {
function startTest() {
$this->Html =& new HtmlHelper();
$view =& new View(new TheHtmlTestController());
ClassRegistry::addObject('view', $view);
@ -248,7 +262,7 @@ class HtmlHelperTest extends CakeTestCase {
);
$this->assertTags($result, $expected);
Configure::write('Asset.timestamp', true);
Configure::write('Asset.timestamp', 'force');
$result = $this->Html->link($this->Html->image('test.gif'), '#', array(), false, false, false);
$expected = array(
@ -288,7 +302,7 @@ class HtmlHelperTest extends CakeTestCase {
$result = $this->Html->image('/test/view/1.gif');
$this->assertTags($result, array('img' => array('src' => '/test/view/1.gif', 'alt' => '')));
Configure::write('Asset.timestamp', true);
Configure::write('Asset.timestamp', 'force');
$result = $this->Html->image('cake.icon.gif');
$this->assertTags($result, array('img' => array('src' => 'preg:/img\/cake\.icon\.gif\?\d+/', 'alt' => '')));
@ -372,6 +386,7 @@ class HtmlHelperTest extends CakeTestCase {
$result = $this->Html->css('cake.generic');
$expected['link']['href'] = 'preg:/.*ccss\/cake\.generic\.css/';
$this->assertTags($result, $expected);
Configure::write('Asset.filter.css', false);
$result = explode("\n", trim($this->Html->css(array('cake.generic', 'vendor.generic'))));
@ -381,6 +396,7 @@ class HtmlHelperTest extends CakeTestCase {
$this->assertTags($result[1], $expected);
$this->assertEqual(count($result), 2);
Configure::write('debug', 2);
Configure::write('Asset.timestamp', true);
Configure::write('Asset.filter.css', 'css.php');
@ -420,6 +436,162 @@ class HtmlHelperTest extends CakeTestCase {
$this->Html->webroot = $webroot;
}
/**
* test timestamp enforcement for script tags.
*
* @return void
**/
function testScriptTimestamping() {
$skip = $this->skipIf(!is_writable(JS), 'webroot/js is not Writable, timestamp testing has been skipped');
if ($skip) {
return;
}
Configure::write('debug', 2);
Configure::write('Asset.timestamp', true);
touch(WWW_ROOT . 'js' . DS. '__cake_js_test.js');
$timestamp = substr(strtotime('now'), 0, 8);
$result = $this->Html->script('__cake_js_test', true, false);
$this->assertPattern('/__cake_js_test.js\?' . $timestamp . '[0-9]{2}"/', $result, 'Timestamp value not found %s');
Configure::write('debug', 0);
Configure::write('Asset.timestamp', 'force');
$result = $this->Html->script('__cake_js_test', true, false);
$this->assertPattern('/__cake_js_test.js\?' . $timestamp . '[0-9]{2}"/', $result, 'Timestamp value not found %s');
unlink(WWW_ROOT . 'js' . DS. '__cake_js_test.js');
Configure::write('Asset.timestamp', false);
}
/**
* test that scripts added with uses() are only ever included once.
* test script tag generation
*
* @return void
**/
function testScript() {
$result = $this->Html->script('foo');
$expected = array(
'script' => array('type' => 'text/javascript', 'src' => 'js/foo.js')
);
$this->assertTags($result, $expected);
$result = $this->Html->script(array('foobar', 'bar'));
$expected = array(
array('script' => array('type' => 'text/javascript', 'src' => 'js/foobar.js')),
'/script',
array('script' => array('type' => 'text/javascript', 'src' => 'js/bar.js')),
'/script',
);
$this->assertTags($result, $expected);
$result = $this->Html->script('jquery-1.3');
$expected = array(
'script' => array('type' => 'text/javascript', 'src' => 'js/jquery-1.3.js')
);
$this->assertTags($result, $expected);
$result = $this->Html->script('/plugin/js/jquery-1.3.2.js?someparam=foo');
$expected = array(
'script' => array('type' => 'text/javascript', 'src' => '/plugin/js/jquery-1.3.2.js?someparam=foo')
);
$this->assertTags($result, $expected);
$result = $this->Html->script('foo');
$this->assertNull($result, 'Script returned upon duplicate inclusion %s');
$result = $this->Html->script(array('foo', 'bar', 'baz'));
$this->assertNoPattern('/foo.js/', $result);
$result = $this->Html->script('foo', true, false);
$this->assertNotNull($result);
}
/**
* test Script block generation
*
* @return void
**/
function testScriptBlock() {
$result = $this->Html->scriptBlock('window.foo = 2;');
$expected = array(
'script' => array('type' => 'text/javascript'),
$this->cDataStart,
'window.foo = 2;',
$this->cDataEnd,
'/script',
);
$this->assertTags($result, $expected);
$result = $this->Html->scriptBlock('window.foo = 2;', array('safe' => false));
$expected = array(
'script' => array('type' => 'text/javascript'),
'window.foo = 2;',
'/script',
);
$this->assertTags($result, $expected);
$result = $this->Html->scriptBlock('window.foo = 2;', array('safe' => true));
$expected = array(
'script' => array('type' => 'text/javascript'),
$this->cDataStart,
'window.foo = 2;',
$this->cDataEnd,
'/script',
);
$this->assertTags($result, $expected);
$view =& ClassRegistry::getObject('view');
$view =& new HtmlHelperMockView();
$view->expectAt(0, 'addScript', array(new PatternExpectation('/window\.foo\s\=\s2;/')));
$result = $this->Html->scriptBlock('window.foo = 2;', array('inline' => false));
$this->assertNull($result);
}
/**
* test script tag output buffering when using scriptStart() and scriptEnd();
*
* @return void
**/
function testScriptStartAndScriptEnd() {
$result = $this->Html->scriptStart(array('safe' => true));
$this->assertNull($result);
echo 'this is some javascript';
$result = $this->Html->scriptEnd();
$expected = array(
'script' => array('type' => 'text/javascript'),
$this->cDataStart,
'this is some javascript',
$this->cDataEnd,
'/script'
);
$this->assertTags($result, $expected);
$result = $this->Html->scriptStart(array('safe' => false));
$this->assertNull($result);
echo 'this is some javascript';
$result = $this->Html->scriptEnd();
$expected = array(
'script' => array('type' => 'text/javascript'),
'this is some javascript',
'/script'
);
$this->assertTags($result, $expected);
ClassRegistry::removeObject('view');
$View =& new HtmlHelperMockView();
$View->expectOnce('addScript');
ClassRegistry::addObject('view', $View);
$result = $this->Html->scriptStart(array('safe' => false, 'inline' => false));
$this->assertNull($result);
echo 'this is some javascript';
$result = $this->Html->scriptEnd();
$this->assertNull($result);
}
/**
* testCharsetTag method
*
@ -973,5 +1145,15 @@ class HtmlHelperTest extends CakeTestCase {
$result = $this->Html->para('class-name', '<text>', array(), true);
$this->assertTags($result, array('p' => array('class' => 'class-name'), '&lt;text&gt;', '/p'));
}
/**
* endTest method
*
* @access public
* @return void
*/
function endTest() {
ClassRegistry::flush();
unset($this->Html);
}
}
?>

View file

@ -0,0 +1,343 @@
<?php
/**
* JqueryEngineTestCase
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake.tests
* @subpackage cake.tests.cases.views.helpers
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
App::import('Helper', array('Html', 'Js', 'JqueryEngine'));
class JqueryEngineHelperTestCase extends CakeTestCase {
/**
* startTest
*
* @return void
**/
function startTest() {
$this->Jquery =& new JqueryEngineHelper();
}
/**
* end test
*
* @return void
**/
function endTest() {
unset($this->Jquery);
}
/**
* test selector method
*
* @return void
**/
function testSelector() {
$result = $this->Jquery->get('#content');
$this->assertEqual($result, $this->Jquery);
$this->assertEqual($this->Jquery->selection, '$("#content")');
$result = $this->Jquery->get('document');
$this->assertEqual($result, $this->Jquery);
$this->assertEqual($this->Jquery->selection, '$(document)');
$result = $this->Jquery->get('window');
$this->assertEqual($result, $this->Jquery);
$this->assertEqual($this->Jquery->selection, '$(window)');
$result = $this->Jquery->get('ul');
$this->assertEqual($result, $this->Jquery);
$this->assertEqual($this->Jquery->selection, '$("ul")');
}
/**
* test event binding
*
* @return void
**/
function testEvent() {
$this->Jquery->get('#myLink');
$result = $this->Jquery->event('click', 'doClick', array('wrap' => false));
$expected = '$("#myLink").bind("click", doClick);';
$this->assertEqual($result, $expected);
$result = $this->Jquery->event('click', '$(this).show();', array('stop' => false));
$expected = '$("#myLink").bind("click", function (event) {$(this).show();});';
$this->assertEqual($result, $expected);
$result = $this->Jquery->event('click', '$(this).hide();');
$expected = '$("#myLink").bind("click", function (event) {$(this).hide();'."\n".'return false;});';
$this->assertEqual($result, $expected);
}
/**
* test dom ready event creation
*
* @return void
**/
function testDomReady() {
$result = $this->Jquery->domReady('foo.name = "bar";');
$expected = '$(document).bind("ready", function (event) {foo.name = "bar";});';
$this->assertEqual($result, $expected);
}
/**
* test Each method
*
* @return void
**/
function testEach() {
$this->Jquery->get('#foo');
$result = $this->Jquery->each('$(this).hide();');
$expected = '$("#foo").each(function () {$(this).hide();});';
$this->assertEqual($result, $expected);
}
/**
* test Effect generation
*
* @return void
**/
function testEffect() {
$this->Jquery->get('#foo');
$result = $this->Jquery->effect('show');
$expected = '$("#foo").show();';
$this->assertEqual($result, $expected);
$result = $this->Jquery->effect('hide');
$expected = '$("#foo").hide();';
$this->assertEqual($result, $expected);
$result = $this->Jquery->effect('hide', array('speed' => 'fast'));
$expected = '$("#foo").hide("fast");';
$this->assertEqual($result, $expected);
$result = $this->Jquery->effect('fadeIn');
$expected = '$("#foo").fadeIn();';
$this->assertEqual($result, $expected);
$result = $this->Jquery->effect('fadeOut');
$expected = '$("#foo").fadeOut();';
$this->assertEqual($result, $expected);
$result = $this->Jquery->effect('slideIn');
$expected = '$("#foo").slideDown();';
$this->assertEqual($result, $expected);
$result = $this->Jquery->effect('slideOut');
$expected = '$("#foo").slideUp();';
$this->assertEqual($result, $expected);
$result = $this->Jquery->effect('slideDown');
$expected = '$("#foo").slideDown();';
$this->assertEqual($result, $expected);
$result = $this->Jquery->effect('slideUp');
$expected = '$("#foo").slideUp();';
$this->assertEqual($result, $expected);
}
/**
* Test Request Generation
*
* @return void
**/
function testRequest() {
$result = $this->Jquery->request(array('controller' => 'posts', 'action' => 'view', 1));
$expected = '$.ajax({url:"\\/posts\\/view\\/1"});';
$this->assertEqual($result, $expected);
$result = $this->Jquery->request('/people/edit/1', array(
'method' => 'post',
'before' => 'doBefore',
'complete' => 'doComplete',
'success' => 'doSuccess',
'error' => 'handleError',
'type' => 'json',
'data' => array('name' => 'jim', 'height' => '185cm'),
'wrapCallbacks' => false
));
$expected = '$.ajax({beforeSend:doBefore, complete:doComplete, data:"name=jim&height=185cm", dataType:"json", error:handleError, success:doSuccess, type:"post", url:"\\/people\\/edit\\/1"});';
$this->assertEqual($result, $expected);
$result = $this->Jquery->request('/people/edit/1', array(
'update' => '#updated',
'success' => 'doFoo',
'method' => 'post',
'wrapCallbacks' => false
));
$expected = '$.ajax({success:function (msg, status) {$("#updated").html(msg);}, type:"post", url:"\\/people\\/edit\\/1"});';
$this->assertEqual($result, $expected);
$result = $this->Jquery->request('/people/edit/1', array(
'update' => '#updated',
'success' => 'doFoo',
'method' => 'post',
'dataExpression' => true,
'data' => '$("#someId").serialize()',
'wrapCallbacks' => false
));
$expected = '$.ajax({data:$("#someId").serialize(), success:function (msg, status) {$("#updated").html(msg);}, type:"post", url:"\\/people\\/edit\\/1"});';
$this->assertEqual($result, $expected);
$result = $this->Jquery->request('/people/edit/1', array(
'success' => 'doFoo',
'before' => 'doBefore',
'method' => 'post',
'dataExpression' => true,
'data' => '$("#someId").serialize()',
));
$expected = '$.ajax({beforeSend:function (XMLHttpRequest) {doBefore}, data:$("#someId").serialize(), success:function (data, textStatus) {doFoo}, type:"post", url:"\\/people\\/edit\\/1"});';
$this->assertEqual($result, $expected);
}
/**
* test sortable list generation
*
* @return void
**/
function testSortable() {
$this->Jquery->get('#myList');
$result = $this->Jquery->sortable(array(
'distance' => 5,
'containment' => 'parent',
'start' => 'onStart',
'complete' => 'onStop',
'sort' => 'onSort',
'wrapCallbacks' => false
));
$expected = '$("#myList").sortable({containment:"parent", distance:5, sort:onSort, start:onStart, stop:onStop});';
$this->assertEqual($result, $expected);
$result = $this->Jquery->sortable(array(
'distance' => 5,
'containment' => 'parent',
'start' => 'onStart',
'complete' => 'onStop',
'sort' => 'onSort',
));
$expected = '$("#myList").sortable({containment:"parent", distance:5, sort:function (event, ui) {onSort}, start:function (event, ui) {onStart}, stop:function (event, ui) {onStop}});';
$this->assertEqual($result, $expected);
}
/**
* test drag() method
*
* @return void
**/
function testDrag() {
$this->Jquery->get('#element');
$result = $this->Jquery->drag(array(
'container' => '#content',
'start' => 'onStart',
'drag' => 'onDrag',
'stop' => 'onStop',
'snapGrid' => array(10, 10),
'wrapCallbacks' => false
));
$expected = '$("#element").draggable({containment:"#content", drag:onDrag, grid:[10,10], start:onStart, stop:onStop});';
$this->assertEqual($result, $expected);
$result = $this->Jquery->drag(array(
'container' => '#content',
'start' => 'onStart',
'drag' => 'onDrag',
'stop' => 'onStop',
'snapGrid' => array(10, 10),
));
$expected = '$("#element").draggable({containment:"#content", drag:function (event, ui) {onDrag}, grid:[10,10], start:function (event, ui) {onStart}, stop:function (event, ui) {onStop}});';
$this->assertEqual($result, $expected);
}
/**
* test drop() method
*
* @return void
**/
function testDrop() {
$this->Jquery->get('#element');
$result = $this->Jquery->drop(array(
'accept' => '.items',
'hover' => 'onHover',
'leave' => 'onExit',
'drop' => 'onDrop',
'wrapCallbacks' => false
));
$expected = '$("#element").droppable({accept:".items", drop:onDrop, out:onExit, over:onHover});';
$this->assertEqual($result, $expected);
$result = $this->Jquery->drop(array(
'accept' => '.items',
'hover' => 'onHover',
'leave' => 'onExit',
'drop' => 'onDrop',
));
$expected = '$("#element").droppable({accept:".items", drop:function (event, ui) {onDrop}, out:function (event, ui) {onExit}, over:function (event, ui) {onHover}});';
$this->assertEqual($result, $expected);
}
/**
* test slider generation
*
* @return void
**/
function testSlider() {
$this->Jquery->get('#element');
$result = $this->Jquery->slider(array(
'complete' => 'onComplete',
'change' => 'onChange',
'min' => 0,
'max' => 10,
'value' => 2,
'direction' => 'vertical',
'wrapCallbacks' => false
));
$expected = '$("#element").slider({change:onChange, max:10, min:0, orientation:"vertical", stop:onComplete, value:2});';
$this->assertEqual($result, $expected);
$result = $this->Jquery->slider(array(
'complete' => 'onComplete',
'change' => 'onChange',
'min' => 0,
'max' => 10,
'value' => 2,
'direction' => 'vertical',
));
$expected = '$("#element").slider({change:function (event, ui) {onChange}, max:10, min:0, orientation:"vertical", stop:function (event, ui) {onComplete}, value:2});';
$this->assertEqual($result, $expected);
}
/**
* test the serializeForm method
*
* @return void
**/
function testSerializeForm() {
$this->Jquery->get('#element');
$result = $this->Jquery->serializeForm(array('isForm' => false));
$expected = '$("#element").closest("form").serialize();';
$this->assertEqual($result, $expected);
$result = $this->Jquery->serializeForm(array('isForm' => true));
$expected = '$("#element").serialize();';
$this->assertEqual($result, $expected);
$result = $this->Jquery->serializeForm(array('isForm' => false, 'inline' => true));
$expected = '$("#element").closest("form").serialize()';
$this->assertEqual($result, $expected);
}
}
?>

View file

@ -1,9 +1,8 @@
<?php
/* SVN FILE: $Id$ */
/**
* JsHelperTest file
* JsHelper Test Case
*
* Long description for file
* TestCase for the JsHelper
*
* PHP versions 4 and 5
*
@ -18,48 +17,664 @@
* @link https://trac.cakephp.org/wiki/Developement/TestSuite CakePHP(tm) Tests
* @package cake
* @subpackage cake.tests.cases.libs.view.helpers
* @since CakePHP(tm) v 1.2.0.4206
* @version $Revision$
* @modifiedby $LastChangedBy$
* @lastmodified $Date$
* @since CakePHP(tm) v 1.3
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
*/
if (!defined('CAKEPHP_UNIT_TEST_EXECUTION')) {
define('CAKEPHP_UNIT_TEST_EXECUTION', 1);
}
App::import('Helper', array('Js', 'Html', 'Form'));
App::import('Core', array('View', 'ClassRegistry'));
Mock::generate('JsBaseEngineHelper', 'TestJsEngineHelper', array('methodOne'));
Mock::generate('View', 'JsHelperMockView');
class OptionEngineHelper extends JsBaseEngineHelper {
var $_optionMap = array(
'request' => array(
'complete' => 'success',
'request' => 'beforeSend',
'type' => 'dataType'
)
);
/**
* JsHelperTest class
* test method for testing option mapping
*
* @return array
**/
function testMap($options = array()) {
return $this->_mapOptions('request', $options);
}
/**
* test method for option parsing
*
* @return void
**/
function testParseOptions($options, $safe = array()) {
return $this->_parseOptions($options, $safe);
}
}
/**
* JsHelper TestCase.
*
* @package cake
* @subpackage cake.tests.cases.libs.view.helpers
*/
class JsHelperTest extends UnitTestCase {
class JsHelperTestCase extends CakeTestCase {
/**
* skip method
* Regexp for CDATA start block
*
* @var string
*/
var $cDataStart = 'preg:/^\/\/<!\[CDATA\[[\n\r]*/';
/**
* Regexp for CDATA end block
*
* @var string
*/
var $cDataEnd = 'preg:/[^\]]*\]\]\>[\s\r\n]*/';
/**
* startTest method
*
* @access public
* @return void
*/
function skip() {
$this->skipIf(true, '%s JsHelper test not implemented');
function startTest() {
$this->Js =& new JsHelper('JsBase');
$this->Js->Html =& new HtmlHelper();
$this->Js->Form =& new FormHelper();
$this->Js->Form->Html =& new HtmlHelper();
$this->Js->JsBaseEngine =& new JsBaseEngineHelper();
$view =& new JsHelperMockView();
ClassRegistry::addObject('view', $view);
}
/**
* setUp method
* endTest method
*
* @access public
* @return void
*/
function setUp() {
$this->Js = new JsHelper();
}
/**
* tearDown method
*
* @access public
* @return void
*/
function tearDown() {
function endTest() {
ClassRegistry::removeObject('view');
unset($this->Js);
}
/**
* Switches $this->Js to a mocked engine.
*
* @return void
**/
function _useMock() {
$this->Js =& new JsHelper(array('TestJs'));
$this->Js->TestJsEngine =& new TestJsEngineHelper($this);
$this->Js->Html =& new HtmlHelper();
$this->Js->Form =& new FormHelper();
$this->Js->Form->Html =& new HtmlHelper();
}
/**
* test object construction
*
* @return void
**/
function testConstruction() {
$js =& new JsHelper();
$this->assertEqual($js->helpers, array('Html', 'Form', 'JqueryEngine'));
$js =& new JsHelper(array('mootools'));
$this->assertEqual($js->helpers, array('Html', 'Form', 'mootoolsEngine'));
$js =& new JsHelper('prototype');
$this->assertEqual($js->helpers, array('Html', 'Form', 'prototypeEngine'));
$js =& new JsHelper('MyPlugin.Dojo');
$this->assertEqual($js->helpers, array('Html', 'Form', 'MyPlugin.DojoEngine'));
}
/**
* test that methods dispatch internally and to the engine class
*
* @return void
**/
function testMethodDispatching() {
$this->_useMock();
$this->Js->TestJsEngine->expectOnce('dispatchMethod', array(new PatternExpectation('/methodOne/i'), array()));
$this->Js->methodOne();
/* $this->Js->TestEngine =& new StdClass();
$this->expectError();
$this->Js->someMethodThatSurelyDoesntExist();*/
}
/**
* Test that method dispatching respects buffer parameters and bufferedMethods Lists.
*
* @return void
**/
function testMethodDispatchWithBuffering() {
$this->_useMock();
$this->Js->TestJsEngine->bufferedMethods = array('event', 'sortables');
$this->Js->TestJsEngine->setReturnValue('dispatchMethod', 'This is an event call', array('event', '*'));
$this->Js->event('click', 'foo');
$result = $this->Js->getBuffer();
$this->assertEqual(count($result), 1);
$this->assertEqual($result[0], 'This is an event call');
$result = $this->Js->event('click', 'foo', array('buffer' => false));
$buffer = $this->Js->getBuffer();
$this->assertTrue(empty($buffer));
$this->assertEqual($result, 'This is an event call');
$result = $this->Js->event('click', 'foo', false);
$buffer = $this->Js->getBuffer();
$this->assertTrue(empty($buffer));
$this->assertEqual($result, 'This is an event call');
$this->Js->TestJsEngine->setReturnValue('dispatchMethod', 'I am not buffered.', array('effect', '*'));
$result = $this->Js->effect('slideIn');
$buffer = $this->Js->getBuffer();
$this->assertTrue(empty($buffer));
$this->assertEqual($result, 'I am not buffered.');
$result = $this->Js->effect('slideIn', true);
$buffer = $this->Js->getBuffer();
$this->assertNull($result);
$this->assertEqual(count($buffer), 1);
$this->assertEqual($buffer[0], 'I am not buffered.');
$result = $this->Js->effect('slideIn', array('speed' => 'slow'), true);
$buffer = $this->Js->getBuffer();
$this->assertNull($result);
$this->assertEqual(count($buffer), 1);
$this->assertEqual($buffer[0], 'I am not buffered.');
$result = $this->Js->effect('slideIn', array('speed' => 'slow', 'buffer' => true));
$buffer = $this->Js->getBuffer();
$this->assertNull($result);
$this->assertEqual(count($buffer), 1);
$this->assertEqual($buffer[0], 'I am not buffered.');
}
/**
* test that writeScripts generates scripts inline.
*
* @return void
**/
function testWriteScriptsNoFile() {
$this->_useMock();
$this->Js->buffer('one = 1;');
$this->Js->buffer('two = 2;');
$result = $this->Js->writeBuffer(array('onDomReady' => false, 'cache' => false));
$expected = array(
'script' => array('type' => 'text/javascript'),
$this->cDataStart,
"one = 1;\ntwo = 2;",
$this->cDataEnd,
'/script',
);
$this->assertTags($result, $expected, true);
$this->Js->TestJsEngine->expectAtLeastOnce('domReady');
$result = $this->Js->writeBuffer(array('onDomReady' => true, 'cache' => false));
$view =& new JsHelperMockView();
$view->expectAt(0, 'addScript', array(new PatternExpectation('/one\s=\s1;\ntwo\=\2;/')));
$result = $this->Js->writeBuffer(array('onDomReady' => false, 'inline' => false, 'cache' => false));
}
/**
* test that writeScripts makes files, and puts the events into them.
*
* @return void
**/
function testWriteScriptsInFile() {
if ($this->skipIf(!is_writable(JS), 'webroot/js is not Writable, script caching test has been skipped')) {
return;
}
$this->Js->JsBaseEngine = new TestJsEngineHelper();
$this->Js->buffer('one = 1;');
$this->Js->buffer('two = 2;');
$result = $this->Js->writeBuffer(array('onDomReady' => false, 'cache' => true));
$expected = array(
'script' => array('type' => 'text/javascript', 'src' => 'preg:/(.)*\.js/'),
);
$this->assertTags($result, $expected);
preg_match('/src="(.*\.js)"/', $result, $filename);
$this->assertTrue(file_exists(WWW_ROOT . $filename[1]));
$contents = file_get_contents(WWW_ROOT . $filename[1]);
$this->assertPattern('/one\s=\s1;\ntwo\s=\s2;/', $contents);
@unlink(WWW_ROOT . $filename[1]);
}
/**
* test link()
*
* @return void
**/
function testLinkWithMock() {
$this->_useMock();
$options = array('update' => '#content');
$this->Js->TestJsEngine->setReturnValue('dispatchMethod', 'ajax code', array('request', '*'));
$this->Js->TestJsEngine->expectAt(0, 'dispatchMethod', array('get', new AnythingExpectation()));
$this->Js->TestJsEngine->expectAt(1, 'dispatchMethod', array(
'request', array('/posts/view/1', $options)
));
$this->Js->TestJsEngine->expectAt(2, 'dispatchMethod', array(
'event', array('click', 'ajax code', $options)
));
$result = $this->Js->link('test link', '/posts/view/1', $options);
$expected = array(
'a' => array('id' => 'preg:/link-\d+/', 'href' => '/posts/view/1'),
'test link',
'/a'
);
$this->assertTags($result, $expected);
$options = array(
'confirm' => 'Are you sure?',
'update' => '#content',
'class' => 'my-class',
'id' => 'custom-id',
'escape' => false
);
$this->Js->TestJsEngine->expectAt(0, 'confirm', array($options['confirm']));
$this->Js->TestJsEngine->expectAt(1, 'request', array('/posts/view/1', '*'));
$code = <<<CODE
var _confirm = confirm("Are you sure?");
if (!_confirm) {
return false;
}
CODE;
$this->Js->TestJsEngine->expectAt(1, 'event', array('click', $code));
$result = $this->Js->link('test link »', '/posts/view/1', $options);
$expected = array(
'a' => array('id' => $options['id'], 'class' => $options['class'], 'href' => '/posts/view/1'),
'test link »',
'/a'
);
$this->assertTags($result, $expected);
$options = array('id' => 'something', 'htmlAttributes' => array('arbitrary' => 'value', 'batman' => 'robin'));
$result = $this->Js->link('test link', '/posts/view/1', $options);
$expected = array(
'a' => array('id' => $options['id'], 'href' => '/posts/view/1', 'arbitrary' => 'value',
'batman' => 'robin'),
'test link',
'/a'
);
$this->assertTags($result, $expected);
}
/**
* test that link() and no buffering returns an <a> and <script> tags.
*
* @return void
**/
function testLinkWithNoBuffering() {
$this->_useMock();
$this->Js->TestJsEngine->setReturnValue('dispatchMethod', 'ajax code', array('request', '*'));
$this->Js->TestJsEngine->setReturnValue('dispatchMethod', '-event handler-', array('event', '*'));
$options = array('update' => '#content', 'buffer' => false);
$result = $this->Js->link('test link', '/posts/view/1', $options);
$expected = array(
'a' => array('id' => 'preg:/link-\d+/', 'href' => '/posts/view/1'),
'test link',
'/a',
'script' => array('type' => 'text/javascript'),
$this->cDataStart,
'-event handler-',
$this->cDataEnd,
'/script'
);
$this->assertTags($result, $expected);
$options = array('update' => '#content', 'buffer' => false, 'safe' => false);
$result = $this->Js->link('test link', '/posts/view/1', $options);
$expected = array(
'a' => array('id' => 'preg:/link-\d+/', 'href' => '/posts/view/1'),
'test link',
'/a',
'script' => array('type' => 'text/javascript'),
'-event handler-',
'/script'
);
$this->assertTags($result, $expected);
}
/**
* test submit() with a Mock to check Engine method calls
*
* @return void
**/
function testSubmitWithMock() {
$this->_useMock();
$options = array('update' => '#content', 'id' => 'test-submit');
$this->Js->TestJsEngine->setReturnValue('dispatchMethod', 'serialize-code', array('serializeform', '*'));
$this->Js->TestJsEngine->setReturnValue('dispatchMethod', 'serialize-code', array('serializeForm', '*'));
$this->Js->TestJsEngine->setReturnValue('dispatchMethod', 'ajax-code', array('request', '*'));
$this->Js->TestJsEngine->expectAt(0, 'dispatchMethod', array('get', '*'));
$this->Js->TestJsEngine->expectAt(1, 'dispatchMethod', array(new PatternExpectation('/serializeForm/i'), '*'));
$this->Js->TestJsEngine->expectAt(2, 'dispatchMethod', array('request', '*'));
$params = array(
'update' => $options['update'], 'data' => 'serialize-code',
'method' => 'post', 'dataExpression' => true
);
$this->Js->TestJsEngine->expectAt(3, 'dispatchMethod', array(
'event', array('click', "ajax-code", $params)
));
$result = $this->Js->submit('Save', $options);
$expected = array(
'div' => array('class' => 'submit'),
'input' => array('type' => 'submit', 'id' => $options['id'], 'value' => 'Save'),
'/div'
);
$this->assertTags($result, $expected);
$this->Js->TestJsEngine->expectAt(4, 'dispatchMethod', array('get', '*'));
$this->Js->TestJsEngine->expectAt(5, 'dispatchMethod', array(new PatternExpectation('/serializeForm/i'), '*'));
$requestParams = array(
'/custom/url', array(
'update' => '#content',
'data' => 'serialize-code',
'method' => 'post',
'dataExpression' => true
)
);
$this->Js->TestJsEngine->expectAt(6, 'dispatchMethod', array('request', $requestParams));
$params = array(
'update' => '#content', 'data' => 'serialize-code',
'method' => 'post', 'dataExpression' => true
);
$this->Js->TestJsEngine->expectAt(7, 'dispatchMethod', array(
'event', array('click', "ajax-code", $params)
));
$options = array('update' => '#content', 'id' => 'test-submit', 'url' => '/custom/url');
$result = $this->Js->submit('Save', $options);
$expected = array(
'div' => array('class' => 'submit'),
'input' => array('type' => 'submit', 'id' => $options['id'], 'value' => 'Save'),
'/div'
);
$this->assertTags($result, $expected);
}
}
/**
* JsBaseEngine Class Test case
*
* @package cake.tests.view.helpers
**/
class JsBaseEngineTestCase extends CakeTestCase {
/**
* startTest method
*
* @access public
* @return void
*/
function startTest() {
$this->JsEngine = new JsBaseEngineHelper();
}
/**
* endTest method
*
* @access public
* @return void
*/
function endTest() {
ClassRegistry::removeObject('view');
unset($this->JsEngine);
}
/**
* test escape string skills
*
* @return void
**/
function testEscaping() {
$result = $this->JsEngine->escape('');
$expected = '';
$this->assertEqual($result, $expected);
$result = $this->JsEngine->escape('CakePHP' . "\n" . 'Rapid Development Framework');
$expected = 'CakePHP\\nRapid Development Framework';
$this->assertEqual($result, $expected);
$result = $this->JsEngine->escape('CakePHP' . "\r\n" . 'Rapid Development Framework' . "\r" . 'For PHP');
$expected = 'CakePHP\\r\\nRapid Development Framework\\rFor PHP';
$this->assertEqual($result, $expected);
$result = $this->JsEngine->escape('CakePHP: "Rapid Development Framework"');
$expected = 'CakePHP: \\"Rapid Development Framework\\"';
$this->assertEqual($result, $expected);
$result = $this->JsEngine->escape("CakePHP: 'Rapid Development Framework'");
$expected = "CakePHP: 'Rapid Development Framework'";
$this->assertEqual($result, $expected);
$result = $this->JsEngine->escape('my \\"string\\"');
$expected = 'my \\\\\\"string\\\\\\"';
$this->assertEqual($result, $expected);
}
/**
* test prompt() creation
*
* @return void
**/
function testPrompt() {
$result = $this->JsEngine->prompt('Hey, hey you', 'hi!');
$expected = 'prompt("Hey, hey you", "hi!");';
$this->assertEqual($result, $expected);
$result = $this->JsEngine->prompt('"Hey"', '"hi"');
$expected = 'prompt("\"Hey\"", "\"hi\"");';
$this->assertEqual($result, $expected);
}
/**
* test alert generation
*
* @return void
**/
function testAlert() {
$result = $this->JsEngine->alert('Hey there');
$expected = 'alert("Hey there");';
$this->assertEqual($result, $expected);
$result = $this->JsEngine->alert('"Hey"');
$expected = 'alert("\"Hey\"");';
$this->assertEqual($result, $expected);
}
/**
* test confirm generation
*
* @return void
**/
function testConfirm() {
$result = $this->JsEngine->confirm('Are you sure?');
$expected = 'confirm("Are you sure?");';
$this->assertEqual($result, $expected);
$result = $this->JsEngine->confirm('"Are you sure?"');
$expected = 'confirm("\"Are you sure?\"");';
$this->assertEqual($result, $expected);
}
/**
* test Redirect
*
* @return void
**/
function testRedirect() {
$result = $this->JsEngine->redirect(array('controller' => 'posts', 'action' => 'view', 1));
$expected = 'window.location = "/posts/view/1";';
$this->assertEqual($result, $expected);
}
/**
* testObject encoding with non-native methods.
*
* @return void
**/
function testObject() {
$this->JsEngine->useNative = false;
$object = array('title' => 'New thing', 'indexes' => array(5, 6, 7, 8));
$result = $this->JsEngine->object($object);
$expected = '{"title":"New thing","indexes":[5,6,7,8]}';
$this->assertEqual($result, $expected);
$result = $this->JsEngine->object(array('default' => 0));
$expected = '{"default":0}';
$this->assertEqual($result, $expected);
$result = $this->JsEngine->object(array(
'2007' => array(
'Spring' => array(
'1' => array('id' => 1, 'name' => 'Josh'), '2' => array('id' => 2, 'name' => 'Becky')
),
'Fall' => array(
'1' => array('id' => 1, 'name' => 'Josh'), '2' => array('id' => 2, 'name' => 'Becky')
)
),
'2006' => array(
'Spring' => array(
'1' => array('id' => 1, 'name' => 'Josh'), '2' => array('id' => 2, 'name' => 'Becky')
),
'Fall' => array(
'1' => array('id' => 1, 'name' => 'Josh'), '2' => array('id' => 2, 'name' => 'Becky')
)
)
));
$expected = '{"2007":{"Spring":{"1":{"id":1,"name":"Josh"},"2":{"id":2,"name":"Becky"}},"Fall":{"1":{"id":1,"name":"Josh"},"2":{"id":2,"name":"Becky"}}},"2006":{"Spring":{"1":{"id":1,"name":"Josh"},"2":{"id":2,"name":"Becky"}},"Fall":{"1":{"id":1,"name":"Josh"},"2":{"id":2,"name":"Becky"}}}}';
$this->assertEqual($result, $expected);
foreach (array('true' => true, 'false' => false, 'null' => null) as $expected => $data) {
$result = $this->JsEngine->object($data);
$this->assertEqual($result, $expected);
}
}
/**
* test compatibility of JsBaseEngineHelper::object() vs. json_encode()
*
* @return void
**/
function testObjectAgainstJsonEncode() {
$skip = $this->skipIf(!function_exists('json_encode'), 'json_encode() not found, comparison tests skipped. %s');
if ($skip) {
return;
}
$this->JsEngine->useNative = false;
$data = array();
$data['mystring'] = "simple string";
$this->assertEqual(json_encode($data), $this->JsEngine->object($data));
$data['mystring'] = "strïng with spécial chârs";
$this->assertEqual(json_encode($data), $this->JsEngine->object($data));
$data['mystring'] = "a two lines\nstring";
$this->assertEqual(json_encode($data), $this->JsEngine->object($data));
$data['mystring'] = "a \t tabbed \t string";
$this->assertEqual(json_encode($data), $this->JsEngine->object($data));
$data['mystring'] = "a \"double-quoted\" string";
$this->assertEqual(json_encode($data), $this->JsEngine->object($data));
$data['mystring'] = 'a \\"double-quoted\\" string';
$this->assertEqual(json_encode($data), $this->JsEngine->object($data));
unset($data['mystring']);
$data[3] = array(1, 2, 3);
$this->assertEqual(json_encode($data), $this->JsEngine->object($data));
unset($data[3]);
$data = array('mystring' => null, 'bool' => false, 'array' => array(1, 44, 66));
$this->assertEqual(json_encode($data), $this->JsEngine->object($data));
}
/**
* test that JSON made with JsBaseEngineHelper::object() against json_decode()
*
* @return void
**/
function testObjectAgainstJsonDecode() {
$skip = $this->skipIf(!function_exists('json_encode'), 'json_encode() not found, comparison tests skipped. %s');
if ($skip) {
return;
}
$this->JsEngine->useNative = false;
$data = array("simple string");
$result = $this->JsEngine->object($data);
$this->assertEqual(json_decode($result), $data);
$data = array('my "string"');
$result = $this->JsEngine->object($data);
$this->assertEqual(json_decode($result), $data);
$data = array('my \\"string\\"');
$result = $this->JsEngine->object($data);
$this->assertEqual(json_decode($result), $data);
}
/**
* test Mapping of options.
*
* @return void
**/
function testOptionMapping() {
$JsEngine = new OptionEngineHelper();
$result = $JsEngine->testMap();
$this->assertEqual($result, array());
$result = $JsEngine->testMap(array('foo' => 'bar', 'baz' => 'sho'));
$this->assertEqual($result, array('foo' => 'bar', 'baz' => 'sho'));
$result = $JsEngine->testMap(array('complete' => 'myFunc', 'type' => 'json', 'update' => '#element'));
$this->assertEqual($result, array('success' => 'myFunc', 'dataType' => 'json', 'update' => '#element'));
$result = $JsEngine->testMap(array('success' => 'myFunc', 'dataType' => 'json', 'update' => '#element'));
$this->assertEqual($result, array('success' => 'myFunc', 'dataType' => 'json', 'update' => '#element'));
}
/**
* test that option parsing escapes strings and saves what is supposed to be saved.
*
* @return void
**/
function testOptionParsing() {
$JsEngine = new OptionEngineHelper();
$result = $JsEngine->testParseOptions(array('url' => '/posts/view/1', 'key' => 1));
$expected = 'key:1, url:"\\/posts\\/view\\/1"';
$this->assertEqual($result, $expected);
$result = $JsEngine->testParseOptions(array('url' => '/posts/view/1', 'success' => 'doSuccess'), array('success'));
$expected = 'success:doSuccess, url:"\\/posts\\/view\\/1"';
$this->assertEqual($result, $expected);
}
}
?>

View file

@ -0,0 +1,356 @@
<?php
/**
* MooEngineTestCase
*
*
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake.tests
* @subpackage cake.tests.cases.views.helpers
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
App::import('Helper', array('Html', 'Js', 'MootoolsEngine'));
class MooEngineHelperTestCase extends CakeTestCase {
/**
* startTest
*
* @return void
**/
function startTest() {
$this->Moo =& new MootoolsEngineHelper();
}
/**
* end test
*
* @return void
**/
function endTest() {
unset($this->Moo);
}
/**
* test selector method
*
* @return void
**/
function testSelector() {
$result = $this->Moo->get('#content');
$this->assertEqual($result, $this->Moo);
$this->assertEqual($this->Moo->selection, '$("content")');
$result = $this->Moo->get('a .remove');
$this->assertEqual($result, $this->Moo);
$this->assertEqual($this->Moo->selection, '$$("a .remove")');
$result = $this->Moo->get('document');
$this->assertEqual($result, $this->Moo);
$this->assertEqual($this->Moo->selection, "$(document)");
$result = $this->Moo->get('window');
$this->assertEqual($result, $this->Moo);
$this->assertEqual($this->Moo->selection, "$(window)");
$result = $this->Moo->get('ul');
$this->assertEqual($result, $this->Moo);
$this->assertEqual($this->Moo->selection, '$$("ul")');
$result = $this->Moo->get('#some_long-id.class');
$this->assertEqual($result, $this->Moo);
$this->assertEqual($this->Moo->selection, '$$("#some_long-id.class")');
}
/**
* test event binding
*
* @return void
**/
function testEvent() {
$this->Moo->get('#myLink');
$result = $this->Moo->event('click', 'doClick', array('wrap' => false));
$expected = '$("myLink").addEvent("click", doClick);';
$this->assertEqual($result, $expected);
$result = $this->Moo->event('click', 'this.setStyle("display", "");', array('stop' => false));
$expected = '$("myLink").addEvent("click", function (event) {this.setStyle("display", "");});';
$this->assertEqual($result, $expected);
$result = $this->Moo->event('click', 'this.setStyle("display", "none");');
$expected = "\$(\"myLink\").addEvent(\"click\", function (event) {event.stop();\nthis.setStyle(\"display\", \"none\");});";
$this->assertEqual($result, $expected);
}
/**
* test dom ready event creation
*
* @return void
**/
function testDomReady() {
$result = $this->Moo->domReady('foo.name = "bar";');
$expected = 'window.addEvent("domready", function (event) {foo.name = "bar";});';
$this->assertEqual($result, $expected);
}
/**
* test Each method
*
* @return void
**/
function testEach() {
$this->Moo->get('#foo');
$result = $this->Moo->each('item.setStyle("display", "none");');
$expected = '$("foo").each(function (item, index) {item.setStyle("display", "none");});';
$this->assertEqual($result, $expected);
}
/**
* test Effect generation
*
* @return void
**/
function testEffect() {
$this->Moo->get('#foo');
$result = $this->Moo->effect('show');
$expected = '$("foo").setStyle("display", "");';
$this->assertEqual($result, $expected);
$result = $this->Moo->effect('hide');
$expected = '$("foo").setStyle("display", "none");';
$this->assertEqual($result, $expected);
$result = $this->Moo->effect('fadeIn');
$expected = '$("foo").fade("in");';
$this->assertEqual($result, $expected);
$result = $this->Moo->effect('fadeOut');
$expected = '$("foo").fade("out");';
$this->assertEqual($result, $expected);
$result = $this->Moo->effect('slideIn');
$expected = '$("foo").slide("in");';
$this->assertEqual($result, $expected);
$result = $this->Moo->effect('slideOut');
$expected = '$("foo").slide("out");';
$this->assertEqual($result, $expected);
$result = $this->Moo->effect('slideOut', array('speed' => 'fast'));
$expected = '$("foo").set("slide", {duration:"short"}).slide("out");';
$this->assertEqual($result, $expected);
$result = $this->Moo->effect('slideOut', array('speed' => 'slow'));
$expected = '$("foo").set("slide", {duration:"long"}).slide("out");';
$this->assertEqual($result, $expected);
}
/**
* Test Request Generation
*
* @return void
**/
function testRequest() {
$result = $this->Moo->request(array('controller' => 'posts', 'action' => 'view', 1));
$expected = 'var jsRequest = new Request({url:"\\/posts\\/view\\/1"}).send();';
$this->assertEqual($result, $expected);
$result = $this->Moo->request('/posts/view/1', array('update' => 'content'));
$expected = 'var jsRequest = new Request.HTML({update:"content", url:"\\/posts\\/view\\/1"}).send();';
$this->assertEqual($result, $expected);
$result = $this->Moo->request('/people/edit/1', array(
'method' => 'post',
'complete' => 'doSuccess',
'error' => 'handleError',
'type' => 'json',
'data' => array('name' => 'jim', 'height' => '185cm'),
'wrapCallbacks' => false
));
$expected = 'var jsRequest = new Request.JSON({method:"post", onComplete:doSuccess, onFailure:handleError, url:"\\/people\\/edit\\/1"}).send({"name":"jim","height":"185cm"});';
$this->assertEqual($result, $expected);
$result = $this->Moo->request('/people/edit/1', array(
'method' => 'post',
'complete' => 'doSuccess',
'update' => '#update-zone',
'wrapCallbacks' => false
));
$expected = 'var jsRequest = new Request.HTML({method:"post", onComplete:doSuccess, update:"update-zone", url:"\\/people\\/edit\\/1"}).send();';
$this->assertEqual($result, $expected);
$result = $this->Moo->request('/people/edit/1', array(
'method' => 'post',
'complete' => 'doComplete',
'success' => 'doSuccess',
'error' => 'doFailure',
'before' => 'doBefore',
'update' => 'update-zone',
'wrapCallbacks' => false
));
$expected = 'var jsRequest = new Request.HTML({method:"post", onComplete:doComplete, onFailure:doFailure, onRequest:doBefore, onSuccess:doSuccess, update:"update-zone", url:"\\/people\\/edit\\/1"}).send();';
$this->assertEqual($result, $expected);
$result = $this->Moo->request('/people/edit/1', array(
'method' => 'post',
'complete' => 'doComplete',
'success' => 'doSuccess',
'error' => 'doFailure',
'before' => 'doBefore',
'update' => 'update-zone',
'dataExpression' => true,
'data' => '$("foo").toQueryString()',
'wrapCallbacks' => false
));
$expected = 'var jsRequest = new Request.HTML({method:"post", onComplete:doComplete, onFailure:doFailure, onRequest:doBefore, onSuccess:doSuccess, update:"update-zone", url:"\\/people\\/edit\\/1"}).send($("foo").toQueryString());';
$this->assertEqual($result, $expected);
$result = $this->Moo->request('/people/edit/1', array(
'method' => 'post',
'before' => 'doBefore',
'success' => 'doSuccess',
'complete' => 'doComplete',
'update' => '#update-zone',
));
$expected = 'var jsRequest = new Request.HTML({method:"post", onComplete:function () {doComplete}, onRequest:function () {doBefore}, onSuccess:function (responseText, responseXML) {doSuccess}, update:"update-zone", url:"\\/people\\/edit\\/1"}).send();';
$this->assertEqual($result, $expected);
}
/**
* test sortable list generation
*
* @return void
**/
function testSortable() {
$this->Moo->get('#myList');
$result = $this->Moo->sortable(array(
'distance' => 5,
'containment' => 'parent',
'start' => 'onStart',
'complete' => 'onStop',
'sort' => 'onSort',
'wrapCallbacks' => false
));
$expected = 'var jsSortable = new Sortables($("myList"), {constrain:"parent", onComplete:onStop, onSort:onSort, onStart:onStart, snap:5});';
$this->assertEqual($result, $expected);
}
/**
* test drag() method
*
* @return void
**/
function testDrag() {
$this->Moo->get('#drag-me');
$result = $this->Moo->drag(array(
'start' => 'onStart',
'drag' => 'onDrag',
'stop' => 'onStop',
'snapGrid' => array(10,10),
'wrapCallbacks' => false
));
$expected = '$("drag-me").makeDraggable({onComplete:onStop, onDrag:onDrag, onStart:onStart, snap:[10,10]});';
$this->assertEqual($result, $expected);
}
/**
* test drop() method
*
* @return void
**/
function testDrop() {
$this->expectError();
$this->Moo->get('#drop-me');
$this->Moo->drop(array(
'drop' => 'onDrop',
'leave' => 'onLeave',
'hover' => 'onHover',
));
$result = $this->Moo->drop(array(
'drop' => 'onDrop',
'leave' => 'onLeave',
'hover' => 'onHover',
'drag' => '#my-drag',
'wrapCallbacks' => false
));
$expected = '$("my-drag").makeDraggable({droppables:$("drop-me"), onDrop:onDrop, onEnter:onHover, onLeave:onLeave});';
$this->assertEqual($result, $expected);
$this->assertEqual($this->Moo->selection, '$("drop-me")');
$result = $this->Moo->drop(array(
'drop' => 'onDrop',
'leave' => 'onLeave',
'hover' => 'onHover',
'drag' => '#my-drag',
));
$expected = '$("my-drag").makeDraggable({droppables:$("drop-me"), onDrop:function (element, droppable, event) {onDrop}, onEnter:function (element, droppable) {onHover}, onLeave:function (element, droppable) {onLeave}});';
$this->assertEqual($result, $expected);
}
/**
* test slider generation
*
* @return void
**/
function testSlider() {
$this->Moo->get('#slider');
$result = $this->Moo->slider(array(
'handle' => '#my-handle',
'complete' => 'onComplete',
'change' => 'onChange',
'direction' => 'horizontal',
'wrapCallbacks' => false
));
$expected = 'var jsSlider = new Slider($("slider"), $("my-handle"), {mode:"horizontal", onChange:onChange, onComplete:onComplete});';
$this->assertEqual($result, $expected);
$this->assertEqual($this->Moo->selection, '$("slider")');
$this->Moo->get('#slider');
$result = $this->Moo->slider(array(
'handle' => '#my-handle',
'complete' => 'onComplete',
'change' => 'onChange',
'direction' => 'horizontal',
'min' => 10,
'max' => 40,
'wrapCallbacks' => false
));
$expected = 'var jsSlider = new Slider($("slider"), $("my-handle"), {mode:"horizontal", onChange:onChange, onComplete:onComplete, range:[10,40]});';
$this->assertEqual($result, $expected);
$this->Moo->get('#slider');
$result = $this->Moo->slider(array(
'handle' => '#my-handle',
'complete' => 'complete;',
'change' => 'change;',
'direction' => 'horizontal',
));
$expected = 'var jsSlider = new Slider($("slider"), $("my-handle"), {mode:"horizontal", onChange:function (step) {change;}, onComplete:function (event) {complete;}});';
$this->assertEqual($result, $expected);
}
/**
* test the serializeForm implementation.
*
* @return void
**/
function testSerializeForm() {
$this->Moo->get('#element');
$result = $this->Moo->serializeForm(array('isForm' => true));
$expected = '$("element").toQueryString();';
$this->assertEqual($result, $expected);
$result = $this->Moo->serializeForm(array('isForm' => true, 'inline' => true));
$expected = '$("element").toQueryString()';
$this->assertEqual($result, $expected);
$result = $this->Moo->serializeForm(array('isForm' => false));
$expected = '$($("element").form).toQueryString();';
$this->assertEqual($result, $expected);
$result = $this->Moo->serializeForm(array('isForm' => false, 'inline' => true));
$expected = '$($("element").form).toQueryString()';
$this->assertEqual($result, $expected);
}
}
?>

View file

@ -0,0 +1,360 @@
<?php
/**
* PrototypeEngine TestCase
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
* Copyright 2006-2008, Cake Software Foundation, Inc.
* 1785 E. Sahara Avenue, Suite 490-204
* Las Vegas, Nevada 89104
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
* @package cake.tests
* @subpackage cake.tests.cases.views.helpers
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
App::import('Helper', array('Html', 'Js', 'PrototypeEngine'));
class PrototypeEngineHelperTestCase extends CakeTestCase {
/**
* startTest
*
* @return void
**/
function startTest() {
$this->Proto =& new PrototypeEngineHelper();
}
/**
* end test
*
* @return void
**/
function endTest() {
unset($this->Proto);
}
/**
* test selector method
*
* @return void
**/
function testSelector() {
$result = $this->Proto->get('#content');
$this->assertEqual($result, $this->Proto);
$this->assertEqual($this->Proto->selection, '$("content")');
$result = $this->Proto->get('a .remove');
$this->assertEqual($result, $this->Proto);
$this->assertEqual($this->Proto->selection, '$$("a .remove")');
$result = $this->Proto->get('document');
$this->assertEqual($result, $this->Proto);
$this->assertEqual($this->Proto->selection, "$(document)");
$result = $this->Proto->get('window');
$this->assertEqual($result, $this->Proto);
$this->assertEqual($this->Proto->selection, "$(window)");
$result = $this->Proto->get('ul');
$this->assertEqual($result, $this->Proto);
$this->assertEqual($this->Proto->selection, '$$("ul")');
$result = $this->Proto->get('#some_long-id.class');
$this->assertEqual($result, $this->Proto);
$this->assertEqual($this->Proto->selection, '$$("#some_long-id.class")');
}
/**
* test event binding
*
* @return void
**/
function testEvent() {
$this->Proto->get('#myLink');
$result = $this->Proto->event('click', 'doClick', array('wrap' => false));
$expected = '$("myLink").observe("click", doClick);';
$this->assertEqual($result, $expected);
$result = $this->Proto->event('click', 'Element.hide(this);', array('stop' => false));
$expected = '$("myLink").observe("click", function (event) {Element.hide(this);});';
$this->assertEqual($result, $expected);
$result = $this->Proto->event('click', 'Element.hide(this);');
$expected = "\$(\"myLink\").observe(\"click\", function (event) {event.stop();\nElement.hide(this);});";
$this->assertEqual($result, $expected);
}
/**
* test dom ready event creation
*
* @return void
**/
function testDomReady() {
$result = $this->Proto->domReady('foo.name = "bar";');
$expected = 'document.observe("dom:loaded", function (event) {foo.name = "bar";});';
$this->assertEqual($result, $expected);
}
/**
* test Each method
*
* @return void
**/
function testEach() {
$this->Proto->get('#foo li');
$result = $this->Proto->each('item.hide();');
$expected = '$$("#foo li").each(function (item, index) {item.hide();});';
$this->assertEqual($result, $expected);
}
/**
* test Effect generation
*
* @return void
**/
function testEffect() {
$this->Proto->get('#foo');
$result = $this->Proto->effect('show');
$expected = '$("foo").show();';
$this->assertEqual($result, $expected);
$result = $this->Proto->effect('hide');
$expected = '$("foo").hide();';
$this->assertEqual($result, $expected);
$result = $this->Proto->effect('fadeIn');
$expected = '$("foo").appear();';
$this->assertEqual($result, $expected);
$result = $this->Proto->effect('fadeIn', array('speed' => 'fast'));
$expected = '$("foo").appear({duration:0.50000000000});';
$this->assertEqual($result, $expected);
$result = $this->Proto->effect('fadeIn', array('speed' => 'slow'));
$expected = '$("foo").appear({duration:2});';
$this->assertEqual($result, $expected);
$result = $this->Proto->effect('fadeOut');
$expected = '$("foo").fade();';
$this->assertEqual($result, $expected);
$result = $this->Proto->effect('fadeOut', array('speed' => 'fast'));
$expected = '$("foo").fade({duration:0.50000000000});';
$this->assertEqual($result, $expected);
$result = $this->Proto->effect('fadeOut', array('speed' => 'slow'));
$expected = '$("foo").fade({duration:2});';
$this->assertEqual($result, $expected);
$result = $this->Proto->effect('slideIn');
$expected = 'Effect.slideDown($("foo"));';
$this->assertEqual($result, $expected);
$result = $this->Proto->effect('slideOut');
$expected = 'Effect.slideUp($("foo"));';
$this->assertEqual($result, $expected);
$result = $this->Proto->effect('slideOut', array('speed' => 'fast'));
$expected = 'Effect.slideUp($("foo"), {duration:0.50000000000});';
$this->assertEqual($result, $expected);
$result = $this->Proto->effect('slideOut', array('speed' => 'slow'));
$expected = 'Effect.slideUp($("foo"), {duration:2});';
$this->assertEqual($result, $expected);
}
/**
* Test Request Generation
*
* @return void
**/
function testRequest() {
$result = $this->Proto->request(array('controller' => 'posts', 'action' => 'view', 1));
$expected = 'var jsRequest = new Ajax.Request("/posts/view/1");';
$this->assertEqual($result, $expected);
$result = $this->Proto->request('/posts/view/1', array(
'method' => 'post',
'complete' => 'doComplete',
'before' => 'doBefore',
'success' => 'doSuccess',
'error' => 'doError',
'data' => array('name' => 'jim', 'height' => '185cm'),
'wrapCallbacks' => false
));
$expected = 'var jsRequest = new Ajax.Request("/posts/view/1", {method:"post", onComplete:doComplete, onCreate:doBefore, onFailure:doError, onSuccess:doSuccess, parameters:{"name":"jim","height":"185cm"}});';
$this->assertEqual($result, $expected);
$result = $this->Proto->request('/posts/view/1', array('update' => 'content'));
$expected = 'var jsRequest = new Ajax.Updater("content", "/posts/view/1");';
$this->assertEqual($result, $expected);
$result = $this->Proto->request('/people/edit/1', array(
'method' => 'post',
'complete' => 'doSuccess',
'update' => '#update-zone',
'wrapCallbacks' => false
));
$expected = 'var jsRequest = new Ajax.Updater("update-zone", "/people/edit/1", {method:"post", onComplete:doSuccess});';
$this->assertEqual($result, $expected);
$result = $this->Proto->request('/people/edit/1', array(
'method' => 'post',
'complete' => 'doSuccess',
'error' => 'handleError',
'type' => 'json',
'data' => array('name' => 'jim', 'height' => '185cm'),
'wrapCallbacks' => false
));
$expected = 'var jsRequest = new Ajax.Request("/people/edit/1", {method:"post", onComplete:doSuccess, onFailure:handleError, parameters:{"name":"jim","height":"185cm"}});';
$this->assertEqual($result, $expected);
$result = $this->Proto->request('/people/edit/1', array(
'method' => 'post',
'complete' => 'doSuccess',
'error' => 'handleError',
'type' => 'json',
'data' => '$("element").serialize()',
'dataExpression' => true,
'wrapCallbacks' => false
));
$expected = 'var jsRequest = new Ajax.Request("/people/edit/1", {method:"post", onComplete:doSuccess, onFailure:handleError, parameters:$("element").serialize()});';
$this->assertEqual($result, $expected);
$result = $this->Proto->request('/people/edit/1', array(
'method' => 'post',
'before' => 'doBefore();',
'success' => 'doSuccess();',
'complete' => 'doComplete();',
'error' => 'handleError();',
));
$expected = 'var jsRequest = new Ajax.Request("/people/edit/1", {method:"post", onComplete:function (transport) {doComplete();}, onCreate:function (transport) {doBefore();}, onFailure:function (response, jsonHeader) {handleError();}, onSuccess:function (response, jsonHeader) {doSuccess();}});';
$this->assertEqual($result, $expected);
}
/**
* test sortable list generation
*
* @return void
**/
function testSortable() {
$this->Proto->get('#myList');
$result = $this->Proto->sortable(array(
'distance' => 5,
'start' => 'onStart',
'complete' => 'onComplete',
'sort' => 'onSort',
'wrapCallbacks' => false
));
$expected = 'var jsSortable = Sortable.create($("myList"), {onChange:onSort, onStart:onStart, onUpdate:onComplete, snap:5});';
$this->assertEqual($result, $expected);
}
/**
* test drag() method. Scriptaculous lacks the ability to take an Array of Elements
* in new Drag() when selection is a multiple type. Iterate over the array.
*
* @return void
**/
function testDrag() {
$this->Proto->get('#element');
$result = $this->Proto->drag(array(
'start' => 'onStart',
'drag' => 'onDrag',
'stop' => 'onStop',
'snapGrid' => array(10, 10),
'wrapCallbacks' => false
));
$expected = 'var jsDrag = new Draggable($("element"), {onDrag:onDrag, onEnd:onStop, onStart:onStart, snap:[10,10]});';
$this->assertEqual($result, $expected);
$this->Proto->get('div.dragger');
$result = $this->Proto->drag(array(
'start' => 'onStart',
'drag' => 'onDrag',
'stop' => 'onStop',
'snapGrid' => array(10, 10),
'wrapCallbacks' => false
));
$expected = '$$("div.dragger").each(function (item, index) {new Draggable(item, {onDrag:onDrag, onEnd:onStop, onStart:onStart, snap:[10,10]});});';
$this->assertEqual($result, $expected);
}
/**
* test drop() method
*
* @return void
**/
function testDrop() {
$this->Proto->get('#element');
$result = $this->Proto->drop(array(
'hover' => 'onHover',
'drop' => 'onDrop',
'accept' => '.drag-me',
'wrapCallbacks' => false
));
$expected = 'Droppables.add($("element"), {accept:".drag-me", onDrop:onDrop, onHover:onHover});';
$this->assertEqual($result, $expected);
}
/**
* ensure that slider() method behaves properly
*
* @return void
**/
function testSlider() {
$this->Proto->get('#element');
$result = $this->Proto->slider(array(
'handle' => '#handle',
'direction' => 'horizontal',
'change' => 'onChange',
'complete' => 'onComplete',
'value' => 4,
'wrapCallbacks' => false
));
$expected = 'var jsSlider = new Control.Slider($("handle"), $("element"), {axis:"horizontal", onChange:onComplete, onSlide:onChange, sliderValue:4});';
$this->assertEqual($result, $expected);
$this->Proto->get('#element');
$result = $this->Proto->slider(array(
'handle' => '#handle',
'change' => 'change();',
'complete' => 'complete();',
'value' => 4
));
$expected = 'var jsSlider = new Control.Slider($("handle"), $("element"), {onChange:function (value) {complete();}, onSlide:function (value) {change();}, sliderValue:4});';
$this->assertEqual($result, $expected);
}
/**
* test the serializeForm implementation.
*
* @return void
**/
function testSerializeForm() {
$this->Proto->get('#element');
$result = $this->Proto->serializeForm(array('isForm' => true));
$expected = '$("element").serialize();';
$this->assertEqual($result, $expected);
$result = $this->Proto->serializeForm(array('isForm' => true, 'inline' => true));
$expected = '$("element").serialize()';
$this->assertEqual($result, $expected);
$result = $this->Proto->serializeForm(array('isForm' => false));
$expected = '$($("element").form).serialize();';
$this->assertEqual($result, $expected);
$result = $this->Proto->serializeForm(array('isForm' => false, 'inline' => true));
$expected = '$($("element").form).serialize()';
$this->assertEqual($result, $expected);
}
}
?>

View file

@ -0,0 +1,53 @@
<?php
/**
* AllCoreJavascriptHelpersGroupTest file
*
*
* PHP versions 4 and 5
*
* CakePHP(tm) Tests <https://trac.cakephp.org/wiki/Developement/TestSuite>
* Copyright 2005-2009, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
*
* Licensed under The Open Group Test Suite License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2005-2009, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
* @link https://trac.cakephp.org/wiki/Developement/TestSuite CakePHP(tm) Tests
* @package cake
* @subpackage cake.tests.groups
* @since CakePHP(tm) v 1.3
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
*/
/**
* AllCoreJavascriptHelpersGroupTest class
*
* This test group will run all test in the cases/libs/view/helpers directory related
* to Js helper and its engines
*
* @package cake
* @subpackage cake.tests.groups
*/
class AllCoreJavascriptHelpersGroupTest extends GroupTest {
/**
* label property
*
* @var string 'All core helpers'
* @access public
*/
var $label = 'Js Helper and all Engine Helpers';
/**
* AllCoreHelpersGroupTest method
*
* @access public
* @return void
*/
function AllCoreJavascriptHelpersGroupTest() {
$helperTestPath = CORE_TEST_CASES . DS . 'libs' . DS . 'view' . DS . 'helpers' . DS;
TestManager::addTestFile($this, $helperTestPath . 'js.test.php');
TestManager::addTestFile($this, $helperTestPath . 'jquery_engine.test.php');
TestManager::addTestFile($this, $helperTestPath . 'mootools_engine.test.php');
TestManager::addTestFile($this, $helperTestPath . 'prototype_engine.test.php');
}
}
?>

View file

@ -30,7 +30,7 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv='content-Type' content='text/html; <?php echo $characterSet; ?>' />
<title>CakePHP Test Suite 1.3</title>
<title>CakePHP Test Suite v 1.3.0.0</title>
<style type="text/css">
h3 {font-size: 170%; padding-top: 1em}
a {font-size: 120%}