FancyClosure.php

<?php

namespace Liaison\Test;


class FancyClosure extends \Taeluf\Tester {
    
/**
 * Fancy closures enable binding of paramaters to a callable and inspection of callables, whether as `['\\StaticClass','functionName']`, `[$object, 'methodName']`, or `$anonymousFunction = function(){}`.
 * Example:  
 * ```php
 * $cat = new \Funny\Cat();
 * $loudness = 7;
 * $closure = new \Lia\Utility\FancyClosure([$cat, 'purr'], [$loudness]);
 * $closure->funcName === 'purr';
 * $closure->object === $cat;
 * $closure->class === 'Funny\\Cat'; //it prints with a single slash, but backslashes are generally better off being escaped in my experience
 * $closure->isStatic === false; // would be true if using ['Funny\Cat', 'purr'] instead of [$cat, 'purr']
 * $closure->isAnonymous === false; // would be true for function(){echo 'Kindness can be anonymous too.';}
 * $closure->function === null; // would be the anonymous function, if you had passed a function instead of an `[$obj, 'funcName']` callable
 * 
 * $closure->origCallable === [$cat, 'purr']; //just the first arg you pass to the constructor
 * $closure->bound === [$loudness]; // and this is the 2nd arg
 * ```
 * 
 * @export(Utility.FancyClosure)
 * @todo turn this big comment into a proper test & export the test for displaying documentation
 *
 */

    /** placeholder docblock */
    public function retBoundArg($boundArg, $passedArg){
        return $boundArg.' & '.$passedArg;
    }

    public function testObjectCallable(){
        $boundArg = 'Bind goodness to yourself';
        $passedArg = 'accept goodness from others';
        $callable = [$this, 'retBoundArg'];
        $closure = new \Lia\Utility\FancyClosure($callable,[$boundArg]);

        $aClass = $closure->class;
        $aObj = $closure->object;
        $aObjClass = get_class($aObj);
        $aFuncName = $closure->funcName;
        $aCallClosure = $closure($passedArg);

        $tClass = get_class($this);
        $tObj = $this;
        $tObjClass = get_class($this);
        $tFuncName = $callable[1];
        $tCallClosure = $callable($boundArg,$passedArg);
        
        return
            $this->test('ActualClassVActualObjClass')->compare($aClass,$aObjClass)
        &&  $this->test('Class')->compare($tClass,$aClass)
        &&  $this->test('Object')->compare($tObj,$aObj)
        &&  $this->test('ObjectClass')->compare($tObjClass, $aObjClass)
        &&  $this->test('FuncName')->compare($tFuncName, $aFuncName)
        &&  $this->test('CallClosure')->compare($tCallClosure,$aCallClosure)
        ;

        return false;
    }
    public function testStaticCallable(){
        $boundArg = 'I am a cat.';
        $callable = [get_class($this), 'retBoundArg'];
        $closure = new \Lia\Utility\FancyClosure($callable,[$boundArg]);

        return $this->compare(true,$closure->isStatic);
    }
    public function testAnonymousCallable(){
        $boundArg = 'I am a cat.';
        $callable = function(){echo "whatever";};
        $closure = new \Lia\Utility\FancyClosure($callable,[$boundArg]);
        return $this->compare(true,$closure->isAnonymous);
    }
}