Router.php

<?php

namespace Liaison\Test\Compo;

class Router extends \Taeluf\Tester {

    public function testFillPattern(){
        $parsed = [
            "pattern" => "/blog/{slug}/{id}/",
            "parsedPattern" => "/blog/?/?/",
            "params" => [
                    0 => "slug",
                    1 => "id",
                ],
            "methods" => [
                "GET" => "GET",
            ],
        ];

        $fill = ['slug'=>'cats', 'id'=>33];
        $this->setup($lia,$router);
        $filled = $router->fillPattern($parsed, $fill);

        $this->compare('/blog/cats/33/', $filled);
    }

    //@TODO Fill in placeholder tests for Router

    // public function testNotImplemented_InvalidMethods(){
    //     $this->disable();
    //     echo "This is not implemented currently, but the test-method is left here as a placeholder, as a note.";
    // }
    // public function testPublicDirRouting(){
    //     $this->disable();
    // }
    // public function testConflictBetweenRoutesWithDifferentVarCounts(){
    //     $this->disable();
    // }
    // public function testConflictBetweenRoutesWithSameVarCounts(){
    //     $this->disable();
    // }
    // public function testConflictBetweenStaticRouteAndVarRoute(){
    //     $this->disable();
    // }
    //
    // public function testCustomRouteMethod(){
    //     $this->disable();
    //     // echo "This is not implemented currently, but the test-method is left here as a placeholder, as a note.";
    //     return false;
    // }
    public function testOptionalParamater(){
        $this->setup($lia,$router, $package);
        
        $lia->addRoute('/optional/{?checkingFor}/and/{required}/',
            function($route){
//                 print_r($route->paramaters());
                return $route->param('checkingFor').'::'.$route->param('required');
            }
        );
        
        $success = true;
        
        $route1 = $lia->route(new \Lia\Obj\Request('/optional/abc/and/the-required/'))[0];
        $callable1 = $route1->target();
        $ret1 = $callable1($route1);
        
        $success = $success && $this->compare('abc::the-required',$ret1);
        
        $route2 = $lia->route(new \Lia\Obj\Request('/optional/and/the-required/'))[0];
        $callable2 = $route2->target();
        $ret2 = $callable2($route2);
        
        $success = $success && $this->compare('::the-required',$ret2);
        
        return $success
        ;
    }
    public function testPatternRouteMethod(){
        $this->setup($lia,$router, $package);

        // print_r($lia->getApiPrefixes());

        $compo = new class($lia) {
            use \Lia\CompoTrait\Scanner;

            public $lia;
            public function __construct($lia){
                $this->lia = $lia;
            }

            //@export_start(Usage.Router.PatternCallback)
            // Declare functions inside your component with the 'routePattern' prefix, followed by an uppercase letter or underscore
            // I believe this implementation is going to change.
            public function routePatternBlog($route) {
                if ($route===false)return [
                    '/blog/{article}/',
                    '/blog/{article}',
                    '/about/{page}/'
                ];
                $blogs = [
                    'black-lives-matter'=> 'Have you looked at traffic data in your home town? Is there a racial disparity?',
                    'toxic-pollution' => 'The US EPA, under Trump, has rolled back many protections for U.S. citizens',
                    'us-voter-suppression' => 'Why are mailboxes and mail-sorting machines being removed from cities? Why isn\'t the post office tax-payer funded?',
                ];
                $abouts = [
                    'me'=>"Hi, I'm Reed. I'm an indie developer. I'm very opinionated and wish the world were a better place."
                ];
                $var = $route->var(0);
                if ($route->part(0)=='about'
                    &&isset($abouts[$var]))return $abouts[$var];
                else if ($route->part(0)=='blog'
                    &&isset($blogs[$var]))return $blogs[$var];
                else return "A blog was not found for '{$var}'";
            }
            //@export_end(Usage.Router.PatternCallback)
        };
        // $compo->autoRegisterScannedPrefixes($lia);
        $compo->autoHandlePrefixedMethods();
        $urls = [
            '/blog/black-lives-matter/',
            '/blog/toxic-pollution',
            '/about/me/',
            '/blog/global-warming/',
        ];

        $success = true;
        foreach ($urls as $url){
            $route = new \Lia\Obj\Route(
                [
                    'url'=>$url,
                    'paramaters'=>array_slice(explode('/',$url),2,1)
                ]
            );
            $aRoute = $lia->route(new \Lia\Obj\Request($url))[0];
            // print_r($aRoute);
            $success = $success && $this->compare($compo->routePatternBlog($route), ($aRoute->target())($aRoute));
        }

        $t1 = $lia->route(new \Lia\Obj\Request('/blog/us-voter-suppression'))[0]->target();
        $a1 = $lia->route(new \Lia\Obj\Request('/blog/us-voter-suppression/'))[0]->target();

        $compo->lia = null;

        return $success
        && $this->compare($t1,$a1)
        && $this->compare([], $lia->route(new \Lia\Obj\Request('/ranked-choice-voting/')))
        && $this->compare([], $lia->route(new \Lia\Obj\Request('/about/me')))
        ;
    }


    public function testGetRoute(){
        $this->setup($lia, $router, $package);
        $c = function($route){};
        $lia->addRoute(
            $tParamPattern='@GET.@POST./ban/toxic/{type}/'
        ,$c);
        $tPlaceholderPattern = '/ban/toxic/?/';
        
        $aRouteList = $lia->route(new \Lia\Obj\Request($tUrl='/ban/toxic/chemicals/',$tMethod='POST'));
        $tReg = $router->urlToTestReg($tUrl);

        $active = [
            'url' => $tUrl,
            'method'=>$tMethod,
            'urlRegex'=>$tReg,
        ];
        $shared = [
            'paramaters'=>['type'=>'chemicals']
        ];
        $static = [
            'allowedMethods'=>["GET"=>"GET", "POST"=>"POST"],
            'paramaterizedPattern'=>$tParamPattern,
            'placeholderPattern'=>$tPlaceholderPattern,
            'target'=>$c,
            'package'=>null,
        ];
        $route = new \Lia\Obj\Route(array_merge($active,$shared,$static));
        $tRouteList = [
            $route
        ];

        return 
            $this->compare($tRouteList, $aRouteList)

        ;
    }
    public function testUrlToTestReg(){
        $this->setup($lia, $router, $package);
        $urls = [
            '/one/two/three/'=>'^\\/(?:one|\?)\\/(?:two|\?)\\/(?:three|\?)\\/$',
            '/one.two.three/'=>'^\\/(?:one|\?)\\.(?:two|\?)\\.(?:three|\?)\\/$',
            '/one.two-three/four'=>'^\\/(?:one|\?)\\.(?:two\\-three|\?)\\/(?:four|\?)$',
            '/five/six.seven.eight/.nine'=>'^\\/(?:five|\?)\\/(?:six|\?)\\.(?:seven|\?)\\.(?:eight|\?)\\/\\.(?:nine|\?)$',
            '/-thing-/'=>'^\\/(?:\\-thing\\-|\?)\\/$',
            '/.thing./'=>'^\\/\\.(?:thing|\?)\\.\\/$',
            '/..../'=>'^\\/\\.\\.\\.\\.\\/$'
        ];
        $success = true;
        foreach ($urls as $url=>$target){
            $actual = $router->urlToTestReg($url);
            $success = $success && $this->test($url)->compare($target, $actual);
        }
        return $success;
    }


    public function testParsePatterns(){
        $this->setup($lia, $router, $package);
        $routes = [
            'static'=>'/black-lives-matter/',
            '/save/the/environment/',
            'params'=>['/{any}.{person}/deserves/respect/','/?.?/deserves/respect/',['any','person']],
            ['/abc/{dyn}/something/', '/abc/?/something/', ['dyn']],
            ['/abc/def/{dynam}.{two}/', '/abc/def/?.?/', ['dynam','two']],
            ['/abc/def/{dynam}-{two}', '/abc/def/{dynam}-{two}', []],
            ['/abc/def/{dynam}{two}.{abc}', '/abc/def/{dynam}{two}.?',['abc']],
            'method'=>['/@POST.greed/kills/@GET.people/','/greed/kills/people/',null,['GET','POST']],
            ['/flarg/harp/@POST.@GET.{dyn}/', '/flarg/harp/?/',['dyn'], ['GET','POST']],
            ['@POST./regulations/on/{megacorp}/', '/regulations/on/?/',['megacorp'],['POST']]
        ];
        $success = true;
        foreach ($routes as $key => $r){
            if (is_string($r))$r = [$r];
            $t = [];
            $t['pattern'] = $r[0];
            $t['parsedPattern'] = $r[1] ?? $r[0];
            $t['params'] = $r[2] ?? [];
            $tMethods = $r[3] ?? ['GET'];
            $t['methods'] = array_combine($tMethods,$tMethods);
            ksort($t['methods']);
            $actual = $router->parsePattern($r[0]);
            ksort($actual['methods']);
            krsort($actual);
            krsort($t);
            if (is_string($key))$this->test($key);
            $success = $success && $this->compare($t, $actual,true);
        }


        return $success;
    }

    // public function testBenchmarktestPatternRouteMethod(){
        // $this->disable();
        // echo 'to save energy, this benchmark is disabled, as it does not actually test anything.';
        // return false;
        // $i=0;
        // ob_start();
        // while ($i++<100)$this->testPatternRouteMethod();
        // ob_get_clean();
        // return true;
    // }
    // public function testBenchmarkGetRoute(){
        // $this->disable();
        // echo 'to save energy, this benchmark is disabled, as it does not actually test anything.';
        // return false;
        // $i=0;
        // ob_start();
        // while ($i++<100)$this->testGetRoute();
        // ob_get_clean();
        // return true;
    // }
    // public function testBenchmarkUrlToTestReg(){
        // $this->disable();
        // echo 'to save energy, this benchmark is disabled, as it does not actually test anything.';
        // return false;
        // $i=0;
        // ob_start();
        // while ($i++<100)$this->testUrlToTestReg();
        // ob_get_clean();
        // return true;
    // }
    // public function testBenchmarkParsePatternsOneHundredTimes(){
        // $this->disable();
        // echo 'to save energy, this benchmark is disabled, as it does not actually test anything.';
        // return false;
        // $i=0;
        // ob_start();
        // while ($i++<100)$this->testParsePatterns();
        // ob_get_clean();
        // return true;
    // }

    public function deliverUrl($url){

        if ($url=='/black-lives-matter/'){
            echo "There is still so much work to do.";
            return;
        } 

        echo "Url not found.";

    }

    protected function setup(&$lia, &$router=null, &$package=null){
        $_SERVER['REQUEST_METHOD'] = 'GET';
        $lia = new \Liaison(['bare'=>true]);
        $package = new \Liaison\Test\Mock\Package($lia);
        $router = new \Lia\Compo\Router($package);
    }
}

Router::runAll();