izzum\statemachine\TransitionTest::shouldAcceptMultipleCallableTypes PHP Method

shouldAcceptMultipleCallableTypes() public method

    public function shouldAcceptMultipleCallableTypes()
    {
        //there are diverse ways to use callables: closures, anonymous function, instance methods
        //static methods.
        //https://php.net/manual/en/functions.anonymous.php
        //https://php.net/manual/en/language.types.callable.php
        $context = new Context(new Identifier('123', 'foo-machine'));
        $event = 'foo';
        $a = new State('a');
        $b = new State('b');
        //scenario 1: Closure without variables from the parent scope
        $transition_callable = function ($entity) {
            $entity->setEntityId('234');
        };
        $t = new Transition($a, $b, $event, null, null, null, $transition_callable);
        $this->assertEquals('123', $context->getEntityId());
        $t->process($context);
        $this->assertEquals('234', $context->getEntityId());
        //scenario 2: Closure with Inheriting variables from the parent scope
        $x = 4;
        $transition_callable = function ($entity) use(&$x) {
            $x += 1;
        };
        $t = new Transition($a, $b, $event, null, null, null, $transition_callable);
        $this->assertEquals(4, $x);
        $t->process($context);
        $this->assertEquals(5, $x);
        //scenario 3: Anonymous function / literal
        $context->getIdentifier()->setEntityId('123');
        $t = new Transition($a, $b, $event, null, null, null, function ($entity) {
            $entity->setEntityId('234');
        });
        $this->assertEquals('123', $context->getEntityId());
        $t->process($context);
        $this->assertEquals('234', $context->getEntityId());
        //scenario 4: instance method invocation (method as string)
        $helper = new CallableHelper();
        $transition_callable = array($helper, 'increaseInstanceId');
        $t = new Transition($a, $b, $event, null, null, null, $transition_callable);
        $this->assertEquals(0, $helper->instance_id);
        $t->process($context);
        $this->assertEquals(1, $helper->instance_id);
        $t->process($context);
        $this->assertEquals(2, $helper->instance_id);
        //scenario 5: static method invocation in array (use fully qualified name)
        $helper = new CallableHelper();
        $transition_callable = array('izzum\\statemachine\\CallableHelper', 'increaseId');
        $t = new Transition($a, $b, $event, null, null, null, $transition_callable);
        $this->assertEquals(0, CallableHelper::$id);
        $t->process($context);
        $this->assertEquals(1, CallableHelper::$id);
        //scenario 6: static method invocation in string (use fully qualified name)
        //THIS IS THE WAY TO be able to specify a callable in a configuration file.
        $helper = new CallableHelper();
        $transition_callable = 'izzum\\statemachine\\CallableHelper::increaseId';
        $t = new Transition($a, $b, $event, null, null, null, $transition_callable);
        $this->assertEquals(1, CallableHelper::$id);
        $t->process($context);
        $this->assertEquals(2, CallableHelper::$id);
        //scenario 7: wrap an existing method in a closure (this is THE way to reuse an existing method)
        function jo($entity)
        {
            $entity->setEntityId($entity->getEntityId() + 1);
        }
        $callable = function ($context) {
            jo($context);
        };
        $context->getIdentifier()->setEntityId('123');
        $t = new Transition($a, $b, $event, null, null, null, $callable);
        $this->assertEquals('123', $context->getEntityId());
        $t->process($context);
        $this->assertEquals('124', $context->getEntityId());
    }