Browse Source

Fixing test and implementing return values for events

Jose Lorenzo Rodriguez 14 years ago
parent
commit
ffa12f4d47

+ 2 - 4
lib/Cake/Controller/ComponentCollection.php

@@ -117,10 +117,8 @@ class ComponentCollection extends ObjectCollection implements CakeEventListener
  */
 	public function implementedEvents() {
 		return array(
-			'Controller.startup' => array(
-				array('callable' => 'trigger', 'priority' => 9),
-				array('callable' => 'trigger')
-			),
+			'Controller.initialize' => array('callable' => 'trigger'),
+			'Controller.startup' => array('callable' => 'trigger'),
 			'Controller.beforeRender' => array('callable' => 'trigger'),
 			'Controller.beforeRedirect' => array('callable' => 'trigger'),
 			'Controller.shutdown' => array('callable' => 'trigger', 'priority' => 9),

+ 1 - 1
lib/Cake/Controller/Controller.php

@@ -591,7 +591,6 @@ class Controller extends Object implements CakeEventListener {
 		return array(
 			'Controller.startup' => 'beforeFilter',
 			'Controller.beforeRender' => 'beforeRender',
-			'Controller.beforeRedirect' => array('callable' => 'beforeRedirect', 'passParams' => true),
 			'Controller.shutdown' => 'afterFilter'
 		);
 	}
@@ -643,6 +642,7 @@ class Controller extends Object implements CakeEventListener {
  * @return void
  */
 	public function startupProcess() {
+		$this->getEventManager()->dispatch(new CakeEvent('Controller.initialize', $this));
 		$this->getEventManager()->dispatch(new CakeEvent('Controller.startup', $this));
 	}
 

+ 6 - 0
lib/Cake/Event/CakeEvent.php

@@ -46,6 +46,12 @@ class CakeEvent {
  */
 	public $data = null;
 
+/**
+ * Property used to retain the result value of the event listeners
+ *
+ * @var mixed $result
+ */
+	public $result = null;
 
 /**
  * Flags an event as stopped or not, default is false

+ 8 - 2
lib/Cake/Event/CakeEventManager.php

@@ -240,9 +240,15 @@ class CakeEventManager {
 				break;
 			}
 			if ($listener['passParams'] === true) {
-				call_user_func_array($listener['callable'], $event->data);
+				$result = call_user_func_array($listener['callable'], $event->data);
 			} else {
-				call_user_func($listener['callable'], $event);
+				$result = call_user_func($listener['callable'], $event);
+			}
+			if ($result === false) {
+				$event->stopPropagation();
+			}
+			if ($result !== null) {
+				$event->result = $result;
 			}
 			continue;
 		}

+ 19 - 17
lib/Cake/Test/Case/Console/Command/ApiShellTest.php

@@ -65,23 +65,25 @@ class ApiShellTest extends CakeTestCase {
 			'8. constructClasses()',
 			'9. disableCache()',
 			'10. flash($message, $url, $pause = 1, $layout = \'flash\')',
-			'11. header($status)',
-			'12. httpCodes($code = NULL)',
-			'13. invokeAction($request)',
-			'14. loadModel($modelClass = NULL, $id = NULL)',
-			'15. paginate($object = NULL, $scope = array (), $whitelist = array ())',
-			'16. postConditions($data = array (), $op = NULL, $bool = \'AND\', $exclusive = false)',
-			'17. redirect($url, $status = NULL, $exit = true)',
-			'18. referer($default = NULL, $local = false)',
-			'19. render($view = NULL, $layout = NULL)',
-			'20. scaffoldError($method)',
-			'21. set($one, $two = NULL)',
-			'22. setAction($action)',
-			'23. setRequest($request)',
-			'24. shutdownProcess()',
-			'25. startupProcess()',
-			'26. validate()',
-			'27. validateErrors()'
+			'11. getEventManager()',
+			'12. header($status)',
+			'13. httpCodes($code = NULL)',
+			'14. implementedEvents()',
+			'15. invokeAction($request)',
+			'16. loadModel($modelClass = NULL, $id = NULL)',
+			'17. paginate($object = NULL, $scope = array (), $whitelist = array ())',
+			'18. postConditions($data = array (), $op = NULL, $bool = \'AND\', $exclusive = false)',
+			'19. redirect($url, $status = NULL, $exit = true)',
+			'20. referer($default = NULL, $local = false)',
+			'21. render($view = NULL, $layout = NULL)',
+			'22. scaffoldError($method)',
+			'23. set($one, $two = NULL)',
+			'24. setAction($action)',
+			'25. setRequest($request)',
+			'26. shutdownProcess()',
+			'27. startupProcess()',
+			'28. validate()',
+			'29. validateErrors()'
 		);
 		$this->Shell->expects($this->at(2))->method('out')->with($expected);
 

+ 10 - 2
lib/Cake/Test/Case/Controller/ControllerTest.php

@@ -1114,7 +1114,15 @@ class ControllerTest extends CakeTestCase {
 		$Controller = $this->getMock('Controller', array('getEventManager'));
 
 		$eventManager = $this->getMock('CakeEventManager');
-		$eventManager->expects($this->once())->method('dispatch')
+		$eventManager->expects($this->at(0))->method('dispatch')
+			->with(
+				$this->logicalAnd(
+					$this->isInstanceOf('CakeEvent'),
+					$this->attributeEqualTo('_name', 'Controller.initialize'),
+					$this->attributeEqualTo('_subject', $Controller)
+				)
+			);
+		$eventManager->expects($this->at(1))->method('dispatch')
 			->with(
 				$this->logicalAnd(
 					$this->isInstanceOf('CakeEvent'),
@@ -1122,7 +1130,7 @@ class ControllerTest extends CakeTestCase {
 					$this->attributeEqualTo('_subject', $Controller)
 				)
 			);
-		$Controller->expects($this->once())->method('getEventManager')
+		$Controller->expects($this->exactly(2))->method('getEventManager')
 			->will($this->returnValue($eventManager));
 		$Controller->startupProcess();
 	}

+ 45 - 0
lib/Cake/Test/Case/Event/CakeEventManagerTest.php

@@ -211,6 +211,51 @@ class CakeEventManagerTest extends CakeTestCase {
 	}
 
 /**
+ * Tests event dispatching with a return value
+ *
+ * @return void
+ */
+	public function testDispatchReturnValue() {
+		$manager = new CakeEventManager;
+		$listener = $this->getMock('CakeEventTestListener');
+		$anotherListener = $this->getMock('CakeEventTestListener');
+		$manager->attach(array($listener, 'listenerFunction'), 'fake.event');
+		$manager->attach(array($anotherListener, 'listenerFunction'), 'fake.event');
+		$event = new CakeEvent('fake.event');
+
+		$firstStep = clone $event;
+		$listener->expects($this->at(0))->method('listenerFunction')
+			->with($firstStep)
+			->will($this->returnValue('something special'));
+		$anotherListener->expects($this->at(0))->method('listenerFunction')->with($event);
+		$manager->dispatch($event);
+		$this->assertEquals('something special', $event->result);
+	}
+
+/**
+ * Tests that returning false in a callback stops the event
+ *
+ * @return void
+ */
+	public function testDispatchFalseStopsEvent() {
+		$manager = new CakeEventManager;
+		$listener = $this->getMock('CakeEventTestListener');
+		$anotherListener = $this->getMock('CakeEventTestListener');
+		$manager->attach(array($listener, 'listenerFunction'), 'fake.event');
+		$manager->attach(array($anotherListener, 'listenerFunction'), 'fake.event');
+		$event = new CakeEvent('fake.event');
+
+		$originalEvent = clone $event;
+		$listener->expects($this->at(0))->method('listenerFunction')
+			->with($originalEvent)
+			->will($this->returnValue(false));
+		$anotherListener->expects($this->never())->method('listenerFunction');
+		$manager->dispatch($event);
+		$this->assertTrue($event->isStopped());
+	}
+
+
+/**
  * Tests event dispatching using priorities
  *
  * @return void