Router.php

<?php

namespace Lia\Test\Src;

class Router extends \Lia\Test\Tester {


    /**
     *
     * @note this test changes the varDelim
     */
    public function testOptionalParamater(){
        /** @var \Lia\Http\Router */
        $router = $this->unprotect(\Lia\Http\Router::class);
        
        $router->addRoute('/optional/{?checkingFor}/and/{required}/',
            function($route){
//                 print_r($route->paramaters());
                return $route->param('checkingFor').'::'.$route->param('required');
            }
        );
        
        
        $route1 = $router->getRoutes('/optional/abc/and/the-required/')[0];
        $callable1 = $route1->target;
        $ret1 = $callable1($route1);
        
        $this->compare('abc::the-required',$ret1);
        
        $request = new \Lia\Http\Request('/optional/and/the-required/');
        $route2 = $router->getRoutes($request->url, $request->method)[0];
        $callable2 = $route2->target;
        $ret2 = $callable2($route2);
        
        $this->compare('::the-required',$ret2);
        
    }

    public function testGetRoute(){
        /** @var \Lia\Http\Router */
        $router = $this->unprotect(\Lia\Http\Router::class);
        $c = function($route){};
        $router->addRoute($tParamPattern='@GET.@POST./ban/toxic/{type}/', $c);

        $tPlaceholderPattern = '/ban/toxic/?/';

        $request = new \Lia\Http\Request($tUrl='/ban/toxic/chemicals/',$tMethod='POST');
        $aRouteList = $router->getRoutes($request->url, $request->method);
        $aRouteList[0] = (array)$aRouteList[0];
        $tReg = $router->url_to_regex($tUrl);

        $route = new \Lia\Http\Route();
        $route->url = $tUrl;
        $route->method = $tMethod;
        $route->regexPattern = $tReg;
        $route->paramaters = ['type'=>'chemicals'];
        $route->allowedMethods = ['GET'=>'GET', 'POST'=> 'POST'];
        $route->originalPattern = $tParamPattern;
        $route->testPattern = $tPlaceholderPattern;
        $route->target = $c;
        $route->args = [];

        $tRouteList = [
            (array)$route
        ];

        $this->compare_arrays($tRouteList, $aRouteList);
    }

    public function testUrlToTestReg(){
        /** @var \Lia\Http\Router */
        $router = $this->unprotect(\Lia\Http\Router::class);
        $router->varDelim = './:-';

        $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->url_to_regex($url);
            $this->test($url)
                 ->compare($target, $actual);
        }
    }


    public function testParsePatterns(){
        // $this->setup($lia, $router, $package);
        //$router = new \Lia\Addon\Router();
        $router = $this->unprotect(\Lia\Http\Router::class);
        $router->varDelim = './:-';
        $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/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->decode_pattern($r[0]);
            ksort($actual['methods']);
            krsort($actual);
            krsort($t);
            if (is_string($key))$this->test($key);
            $this->compare($t, $actual,true);
        }

    }
    public function testPatternAndParamatersToUrl(){
        $router = $this->unprotect(\Lia\Http\Router::class);
        //if (is_object($router))$router = new \Lia\Http\Router();
        $pattern = '/blog/{category}/';
        $params = ['category'=>'some-category'];
        $target = '/blog/some-category/';

        $decoded = $router->decode_pattern($pattern);
        $filled = $router->decoded_pattern_to_url($decoded, $params);

        $this->compare(
            $target,
            $filled
        );
    }

    public function testExtractUrlParamaters(){
        $router = $this->unprotect(\Lia\Http\Router::class);
        $url = '/blog/some-category/';
        $pattern = '/blog/{category}/';
        $decoded = $router->decode_pattern($pattern);
        $extracted = $router->extract_url_paramaters($decoded, $url);

        $this->compare(
            ['category'=>'some-category'],
            $extracted
        );
    }

    public function testDecodePatternWithOptionalParamaters(){
        $router = $this->unprotect(\Lia\Http\Router::class);
        $pattern = '/blog/{?category}/';
        $decoded = $router->decode_pattern($pattern);

        $actual_decoded = $router->separate_optional_from_decoded_pattern($decoded);

        
        // $all = array_map(function($a){unset($a['extraParsedPattern']);unset($a['optionalParams']); return $a;},$all);
        // var_export($actual_decoded);
        // exit;

        $target = [
            [
                'pattern' => '/blog/{?category}/',
                'parsedPattern' => '/blog/?/',
                'params' => ['category'],
                'methods' => ['GET' => 'GET'],
            ],
            [
                'pattern' => '/blog/{?category}/',
                'parsedPattern' => '/blog/',
                'params' => [],
                'methods' => ['GET' => 'GET'],
            ],
        ];

        $this->compare($target, $actual_decoded);
    }

    /**
     * Example of `$router->url_to_regex()`
     */
    public function testUrlToRegex(){
        $router = $this->unprotect(\Lia\Http\Router::class);
        $url = '/one/two/';
        $test = $router->url_to_regex($url);

        $target = '^\/(?:one|\?)\/(?:two|\?)\/$';
        $this->compare($target ,$test);
    }

    /**
     * Example of `$router->decode_pattern()`
     */
    public function testDecodePattern(){
        $router = $this->unprotect(\Lia\Http\Router::class);

        $actual_parsed = $router->decode_pattern("/blog/{slug}/{id}/");

        $target_parsed = [
            "pattern" => "/blog/{slug}/{id}/",
            "parsedPattern" => "/blog/?/?/",
            "params" => [
                    0 => "slug",
                    1 => "id",
                ],
            "methods" => [
                "GET" => "GET",
            ],
        ];

        $this->compare($target_parsed, $actual_parsed);
    }

    /**
     * Example of `$router->decoded_pattern_to_url()`. @see(testParsePatternExample) to see what the `$decoded` array looks like
     *
     */
    public function testDecodedPatternToUrl(){
        $router = $this->unprotect(\Lia\Http\Router::class);

        $decoded = $router->decode_pattern("/blog/{slug}/{id}/");

        $fill = ['slug'=>'cats', 'id'=>33];
        $filled = $router->decoded_pattern_to_url($decoded, $fill);

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



}