Skip to content

Commit

Permalink
Merge pull request #147 from thinkingmedia/thinkingmedia/widget-tests
Browse files Browse the repository at this point in the history
added button tests and support for btn-default as a default style.
  • Loading branch information
ADmad committed Apr 6, 2016
2 parents 7df0529 + efb0efc commit 2c6a789
Show file tree
Hide file tree
Showing 8 changed files with 416 additions and 31 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
"cakephp/cakephp": "~3.0"
},
"require-dev": {
"phpunit/phpunit": "4.1.*"
"phpunit/phpunit": "4.1.*",
"cakephp/cakephp-codesniffer": "dev-master"
},
"support": {
"issues": "http://github.com/friendsofcake/bootstrap-ui/issues",
Expand Down
19 changes: 16 additions & 3 deletions contrib/pre-commit
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/bin/sh
FILES=`git diff --cached --name-only --diff-filter=ACMR HEAD | grep \\\\.php`
PROJECT=`php -r "echo dirname(dirname(realpath('$0')));"`

# Determine if a file list is passed
if [ "$#" -eq 1 ]
Expand All @@ -12,14 +13,26 @@ then
fi
SFILES=${SFILES:-$FILES}

if [ "$FILES" != "" ]
echo "Checking PHP Lint..."
for FILE in $SFILES
do
php -l -d display_errors=0 $PROJECT/$FILE
if [ $? != 0 ]
then
echo "Fix the error before commit."
exit 1
fi
FILES="$FILES $PROJECT/$FILE"
done

if [ "$SFILES" != "" ]
then
echo "Running PHPCS"
./vendor/bin/phpcs --standard=vendor/cakephp/cakephp-codesniffer/CakePHP --ignore=*/config/Migrations/* $SFILES
./vendor/bin/phpcs --standard=vendor/cakephp/cakephp-codesniffer/CakePHP $SFILES
if [ $? != 0 ]
then
echo "PHPCS Errors found; commit aborted."
exit 1
fi
fi
exit $?
exit $?
10 changes: 1 addition & 9 deletions src/View/Helper/FormHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -154,15 +154,7 @@ public function create($model = null, array $options = [])
*/
public function submit($caption = null, array $options = [])
{
$class = ['btn'];
if (array_key_exists('class', $options)) {
$optionsClass = is_array($options['class']) ? $options['class'] : explode(' ', $options['class']);
$class = array_unique(array_merge($class, $optionsClass));
unset($options['class']);
}

$options = Hash::merge($options, ['class' => $class]);

$options = $this->applyButtonClasses($options);
return parent::submit($caption, $options);
}

Expand Down
91 changes: 90 additions & 1 deletion src/View/Helper/OptionsAwareTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,96 @@
trait OptionsAwareTrait
{
/**
* Injects classes into `$options['class']` when they don't already exist.
* A list of allowed styles for buttons.
*
* @var array
*/
public $buttonClasses = [
'default', 'btn-default',
'success', 'btn-success',
'warning', 'btn-warning',
'danger', 'btn-danger',
'info', 'btn-info',
'primary', 'btn-primary'
];

/**
* A mapping of aliases for button styles.
*
* @var array
*/
public $buttonClassAliases = [
'default' => 'btn-default',
'success' => 'btn-success',
'warning' => 'btn-warning',
'danger' => 'btn-danger',
'info' => 'btn-info',
'primary' => 'btn-primary'
];

/**
* Contains the logic for applying style classes for buttons.
*
* @param array $data An array of HTML attributes and options.
* @return array An array of HTML attributes and options.
*/
public function applyButtonClasses(array $data)
{
if ($this->hasAnyClass($this->buttonClasses, $data)) {
$data = $this->injectClasses('btn', $data);
} else {
$data = $this->injectClasses('btn btn-default', $data);
}
return $this->renameClasses($this->buttonClassAliases, $data);
}

/**
* Renames any CSS classes found in the options.
*
* @param array $classMap Key/Value pair of class(es) to be renamed.
* @param array $options An array of HTML attributes and options.
* @return array An array of HTML attributes and options.
*/
public function renameClasses(array $classMap, array $options)
{
$options += ['class' => []];
$options['class'] = $this->_toClassArray($options['class']);
$classes = [];
foreach ($options['class'] as $name) {
$classes[] = array_key_exists($name, $classMap)
? $classMap[$name]
: $name;
}
$options['class'] = trim(implode(' ', $classes));
return $options;
}

/**
* Checks if `$options['class']` contains any one of the class names.
*
* @param array|string $classes Name of class(es) to check.
* @param array $options An array of HTML attributes and options.
* @return bool True if any one of the class names was found.
*/
public function hasAnyClass($classes, array $options)
{
$options += ['class' => []];

$options['class'] = $this->_toClassArray($options['class']);
$classes = $this->_toClassArray($classes);

foreach ($classes as $class) {
if (in_array($class, $options['class'])) {
return true;
}
}
return false;
}

/**
* Injects classes into `$options['class']` when they don't already exist. If a class is defined
* in `$options['skip']` then it will not be injected. This method removes `$options['skip']` before
* returning.
*
* @param array|string $classes Name of class(es) to inject.
* @param array $options An array of HTML attributes and options.
Expand Down
18 changes: 7 additions & 11 deletions src/View/Widget/ButtonWidget.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ class ButtonWidget extends \Cake\View\Widget\ButtonWidget

use OptionsAwareTrait;


/**
* @var array
* @deprecated This property is no longer used.
* @see OptionsAwareTrait::applyButtonStyles
*/
protected $_styles = [
'default',
'success',
Expand All @@ -28,17 +34,7 @@ class ButtonWidget extends \Cake\View\Widget\ButtonWidget
*/
public function render(array $data, ContextInterface $context)
{
$data = $this->injectClasses('btn', $data);
$data['class'] = explode(' ', $data['class']);

foreach ($data['class'] as &$class) {
if (in_array($class, $this->_styles)) {
$class = 'btn-' . $class;
break;
}
}

$data['class'] = implode(' ', $data['class']);
$data = $this->applyButtonClasses($data);
return parent::render($data, $context);
}
}
12 changes: 6 additions & 6 deletions tests/TestCase/View/Helper/FormHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ public function testButtonPrependedInput()
'/label',
['div' => ['class' => 'input-group']],
'span' => ['class' => 'input-group-btn'],
'button' => ['type' => 'submit', 'class' => 'btn'],
'button' => ['type' => 'submit', 'class' => 'btn btn-default'],
'GO',
'/button',
'/span',
Expand Down Expand Up @@ -476,7 +476,7 @@ public function testButtonAppendedInput()
'required' => 'required'
],
'span' => ['class' => 'input-group-btn'],
'button' => ['type' => 'submit', 'class' => 'btn'],
'button' => ['type' => 'submit', 'class' => 'btn btn-default'],
'GO',
'/button',
'/span',
Expand Down Expand Up @@ -1046,7 +1046,7 @@ public function testBasicButton()
{
$result = $this->Form->button('Submit');
$expected = [
'button' => ['class' => 'btn', 'type' => 'submit'],
'button' => ['class' => 'btn btn-default', 'type' => 'submit'],
'Submit',
'/button'
];
Expand All @@ -1061,7 +1061,7 @@ public function testBasicFormSubmit()
'input' => [
'type' => 'submit',
'value' => 'Submit',
'class' => 'btn',
'class' => 'btn btn-default',
]
];
$this->assertHtml($expected, $result);
Expand All @@ -1075,7 +1075,7 @@ public function testStyledFormSubmit()
'input' => [
'type' => 'submit',
'value' => 'Submit',
'class' => 'btn btn-block',
'class' => 'btn btn-block btn-default',
]
];
$this->assertHtml($expected, $result);
Expand All @@ -1086,7 +1086,7 @@ public function testStyledFormSubmit()
'input' => [
'type' => 'submit',
'value' => 'Submit',
'class' => 'btn btn-block',
'class' => 'btn btn-block btn-default',
]
];
$this->assertHtml($expected, $result);
Expand Down
97 changes: 97 additions & 0 deletions tests/TestCase/View/Helper/OptionsAwareTraitTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

namespace BootstrapUI\Test\TestCase\View\Helper;

use BootstrapUI\View\Helper\OptionsAwareTrait;
use Cake\TestSuite\TestCase;

/**
* TestOptionsAware
*/
class TestOptionsAware
{

use OptionsAwareTrait;
}

/**
* OptionsAwareTraitTest
*/
class OptionsAwareTraitTest extends TestCase
{
/**
* @var OptionsAwareTrait
*/
public $object;

/**
* setUp method
*
* @return void
*/
public function setUp()
{
parent::setUp();
$this->object = new TestOptionsAware();
}

public function testApplyButtonStyles()
{
$this->assertEquals(['class' => 'btn btn-default'], $this->object->applyButtonClasses([]));
foreach (['default', 'success', 'warning', 'danger', 'info', 'primary'] as $style) {
$this->assertEquals(['class' => "btn-{$style} btn"], $this->object->applyButtonClasses(['class' => $style]));
$this->assertEquals(['class' => "btn-{$style} btn"], $this->object->applyButtonClasses(['class' => "btn-$style"]));
}
}

public function testRenameClasses()
{
$this->assertEquals(['class' => ''], $this->object->renameClasses(['a' => 'b'], []));
$this->assertEquals(['class' => 'b'], $this->object->renameClasses(['a' => 'b'], ['class' => 'a']));
$this->assertEquals(['class' => 'b'], $this->object->renameClasses(['a' => 'b', 'c' => 'd'], ['class' => 'a']));
}

public function testHasAnyClass()
{
$this->assertFalse($this->object->hasAnyClass('a', []));
$this->assertFalse($this->object->hasAnyClass('a', ['class' => 'x y z']));

$this->assertTrue($this->object->hasAnyClass('a', ['class' => 'a b c']));
$this->assertTrue($this->object->hasAnyClass('a w', ['class' => 'x y z a b c']));
}

public function testInjectClasses()
{
$this->assertEquals(['class' => 'a'], $this->object->injectClasses('a', []));
$this->assertEquals(['class' => 'a b c'], $this->object->injectClasses('a b c', []));
$this->assertEquals(['class' => 'x y z a'], $this->object->injectClasses('a', ['class' => 'x y z']));
$this->assertEquals(['class' => 'x y z a'], $this->object->injectClasses('a', ['class' => ['x', 'y', 'z']]));
$this->assertEquals(['class' => 'x y z a b c'], $this->object->injectClasses('a b c', ['class' => 'x y z']));
}

public function testOverlappingInjectClasses()
{
$this->assertEquals(['class' => 'a b c x y z'], $this->object->injectClasses('a b c', ['class' => 'a b c x y z']));
$this->assertEquals(['class' => 'a b c x y z'], $this->object->injectClasses('a', ['class' => 'a b c x y z']));
$this->assertEquals(['class' => 'a c x y z b'], $this->object->injectClasses('a b c', ['class' => 'a c x y z']));
}

public function testSkippingInjectClasses()
{
$this->assertEquals(['class' => 'x y z a c'], $this->object->injectClasses('a b c', ['class' => 'x y z', 'skip' => 'b']));
$this->assertEquals(['class' => 'x y z a b c'], $this->object->injectClasses('a b c', ['class' => 'x y z', 'skip' => 'm']));
}

public function testCheckClasses()
{
foreach (['a', 'a b c', ['a'], ['a', 'b', 'c']] as $class) {
$this->assertFalse($this->object->checkClasses($class, []));
$this->assertFalse($this->object->checkClasses($class, ['class' => 'x y z']));
$this->assertFalse($this->object->checkClasses($class, ['class' => ['x', 'y', 'z']]));
}

$this->assertTrue($this->object->checkClasses('a', ['class' => 'a']));
$this->assertTrue($this->object->checkClasses('a b c', ['class' => 'c b a']));
$this->assertTrue($this->object->checkClasses('a b c', ['class' => ['c', 'b', 'a']]));
}
}
Loading

0 comments on commit 2c6a789

Please sign in to comment.