Skip to content

Commit

Permalink
[ChainNode] changes according to the latest comment
Browse files Browse the repository at this point in the history
  • Loading branch information
vatson committed Apr 9, 2012
1 parent eb2fb33 commit 0d414ac
Show file tree
Hide file tree
Showing 2 changed files with 183 additions and 159 deletions.
53 changes: 31 additions & 22 deletions src/BadaBoom/ChainNode/CallbackChainNode.php
Expand Up @@ -10,30 +10,39 @@
*/
class CallbackChainNode extends AbstractChainNode
{
/**
* @var Callable|Closure
*/
protected $callback;

/**
* @param Callable|Closure $callback
*/
public function __construct($callback)
{
if (false == is_callable($callback)) {
throw new \InvalidArgumentException('Invalid callable provided');
/**
* @var Callable|Closure
*/
protected $callback;

/**
* @var boolean
*/
protected $handleNextNode;

/**
* @param Callable|Closure $callback
* @param boolean $handleNextNode
*/
public function __construct($callback, $handleNextNode = true)
{
if (false == is_callable($callback)) {
throw new \InvalidArgumentException('Invalid callable provided');
}

$this->callback = $callback;
$this->handleNextNode = $handleNextNode;
}

$this->callback = $callback;
}
/**
* {@inheritdoc}
*/
public function handle(\Exception $exception, DataHolderInterface $data)
{
call_user_func_array($this->callback, array($exception, $data));

/**
* {@inheritdoc}
*/
public function handle(\Exception $exception, DataHolderInterface $data)
{
if (true === call_user_func_array($this->callback, array($exception, $data))) {
$this->handleNextNode($exception, $data);
if ($this->handleNextNode) {
$this->handleNextNode($exception, $data);
}
}
}
}
289 changes: 152 additions & 137 deletions tests/BadaBoom/Tests/ChainNode/CallbackChainNodeTest.php
Expand Up @@ -11,149 +11,164 @@
*/
class CallbackChainNodeTest extends \PHPUnit_Framework_TestCase
{
/**
* @test
*/
public function shouldBeSubclassOfAbstractChainNode()
{
$rc = new \ReflectionClass('BadaBoom\ChainNode\CallbackChainNode');
$this->assertTrue($rc->isSubclassOf('BadaBoom\ChainNode\AbstractChainNode'));
}

/**
* @test
*
* @dataProvider provideValidCallbacks
*/
public function shouldBeConstructedWithCallback($callback)
{
new CallbackChainNode($callback);
}

/**
* @test
*
* @dataProvider provideNoCallableItems
*
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Invalid callable provided
*/
public function throwWhenConstructedWithInvalidCallback($invalidCallback)
{
new CallbackChainNode($invalidCallback);
}

/**
* @test
*/
public function shouldDelegateHandlingToCallback()
{
$is_called = false;
$exception = new \Exception();
$data = new DataHolder();

$test = $this;

$node = new CallbackChainNode(function($e, $d) use ($exception, $data, $test, &$is_called) {
$test->assertSame($exception, $e);
$test->assertSame($data, $d);
$is_called = true;
});

$node->handle($exception, $data);

$this->assertTrue($is_called);
}

/**
* @test
*/
public function shouldGiveControlToNextNodeIfCallbackReturnTrue()
{
$exception = new \Exception();
$data = new DataHolder();

$nextNode = $this->createChainNodeMock();

$node = new CallbackChainNode(function() {
return true;
});
$node->nextNode($nextNode);

$nextNode->expects($this->once())
->method('handle')
->with($exception, $data)
;

$node->handle($exception, $data);
}

/**
* @test
*/
public function shouldNotGiveControlToNextNodeIfCallbackReturnFalse()
{
$nextNode = $this->createChainNodeMock();

$node = new CallbackChainNode(function() {
return false;
});
$node->nextNode($nextNode);

$node->handle(new \Exception(), new DataHolder());
}

/**
* @return \PHPUnit_Framework_MockObject_MockObject
*/
public function createChainNodeMock()
{
return $this->getMock('BadaBoom\ChainNode\ChainNodeInterface');
}

/**
* @return array
*/
public static function provideValidCallbacks()
{
$staticMethod = array(__NAMESPACE__.'\StubMethodCall', 'staticMethod');
$objectMethod = array(new StubMethodCall(), 'objectMethod');
$closure = function() {};
$function = 'is_callable';

return array(
array($staticMethod),
array($objectMethod),
array($closure),
array($function),
);
}

/**
* @return array
*/
public static function provideNoCallableItems()
{
return array(
array('string'),
array(1),
array(12.2),
array(array()),
array(false),
array(null),
array(new \stdClass()),
array(array(new \stdClass(), 'no_exist_method')),
array(array('stdClass', 'no_exist_method')),
);
}
/**
* @test
*/
public function shouldBeSubclassOfAbstractChainNode()
{
$rc = new \ReflectionClass('BadaBoom\ChainNode\CallbackChainNode');
$this->assertTrue($rc->isSubclassOf('BadaBoom\ChainNode\AbstractChainNode'));
}

/**
* @test
*
* @dataProvider provideValidCallbacks
*/
public function shouldBeConstructedWithCallback($callback)
{
new CallbackChainNode($callback);
}

/**
* @test
*/
public function couldBeConstructedWithFlagForProcessingNextNode()
{
new CallbackChainNode(function(){}, $handleNextNode = false);

new CallbackChainNode(function(){}, $handleNextNode = true);
}

/**
* @test
*
* @dataProvider provideNoCallableItems
*
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Invalid callable provided
*/
public function throwWhenConstructedWithInvalidCallback($invalidCallback)
{
new CallbackChainNode($invalidCallback);
}

/**
* @test
*/
public function shouldDelegateHandlingToCallback()
{
$exception = new \Exception();
$data = new DataHolder();

$callback = $this->getMock('BadaBoom\ChainNode\ChainNodeInterface');
$callback
->expects($this->once())
->method('handle')
->with($exception, $data)
;

$callbackNode = new CallbackChainNode(array($callback, 'handle'));
$callbackNode->handle($exception, $data);
}

/**
* @test
*/
public function shouldGiveControlToNextNode()
{
$exception = new \Exception();
$data = new DataHolder();

$nextNode = $this->createChainNodeMock();

$node = new CallbackChainNode(function() {
return true;

This comment has been minimized.

Copy link
@makasim

makasim Apr 9, 2012

Contributor

is this return make any sense?

This comment has been minimized.

Copy link
@vatson

vatson Apr 9, 2012

Author Contributor

Nope

});
$node->nextNode($nextNode);

$nextNode
->expects($this->once())
->method('handle')
->with($exception, $data)
;

$node->handle($exception, $data);
}

/**
* @test
*/
public function shouldNotGiveControlToNextNode()
{
$nextNode = $this->createChainNodeMock();
$nextNode
->expects($this->never())
->method('handle')
;

$node = new CallbackChainNode(function() {
return false;
},
$handleNextNode = false
);

$node->nextNode($nextNode);

$node->handle(new \Exception(), new DataHolder());
}

/**
* @return \PHPUnit_Framework_MockObject_MockObject
*/
public function createChainNodeMock()
{
return $this->getMock('BadaBoom\ChainNode\ChainNodeInterface');
}

/**
* @return array
*/
public static function provideValidCallbacks()
{
$staticMethod = array(__NAMESPACE__ . '\StubMethodCall', 'staticMethod');
$objectMethod = array(new StubMethodCall(), 'objectMethod');
$closure = function(){};
$function = 'is_callable';

return array(
array($staticMethod),
array($objectMethod),
array($closure),
array($function),
);
}

/**
* @return array
*/
public static function provideNoCallableItems()
{
return array(
array('string'),
array(1),
array(12.2),
array(array()),
array(false),
array(null),
array(new \stdClass()),
array(array(new \stdClass(), 'no_exist_method')),
array(array('stdClass', 'no_exist_method')),
);
}
}

/**
* Helper
*/
class StubMethodCall
{
public static function staticMethod() {}
public static function staticMethod(){}

public function objectMethod() {}
public function objectMethod(){}
}

0 comments on commit 0d414ac

Please sign in to comment.