View.php

<?php

namespace Liaison\Test\Addon;

class View extends \Tlf\Tester {
    /**
     * @test view loads nested resources (view-name.php also loads view-name/*.css & view-name/*.js)
     */
    public function testNestedViewResources(){
        $lia = new \Lia();
        $package = new \Lia\Package($lia, 'test');
        $view_handler = new \Lia\Addon\View($package);
        $resources = new \Lia\Addon\Resources($package);
        $dir = $this->view_dir_2();

        \Lia\Addon\View::from($lia)->addView('nested', $dir);
        $output = \Lia\Addon\View::from($lia)->view('nested');

        $this->compare('nested', $output);


        $this->compare(
            [
                'css'=>[
                    $dir.'nested/one.css'=>$dir.'nested/one.css',
                    $dir.'nested/two.css'=>$dir.'nested/two.css'
                ],
                'js'=>[
                    $dir.'nested/one.js'=>$dir.'nested/one.js',
                    $dir.'nested/two.js'=>$dir.'nested/two.js'
                ],
            ]
            , \Lia\Addon\Resources::from($lia)->files
        );
    }

    /**
     * @test view loads sibling resources (view-name.php also loads view-name.css & view-name.js)
     */
    public function testSiblingViewResources(){
        $lia = new \Lia();
        $package = new \Lia\Package($lia, 'test');
        $view_handler = new \Lia\Addon\View($package);
        $resources = new \Lia\Addon\Resources($package);
        $dir = $this->view_dir_2();

        \Lia\Addon\View::from($lia)->addView('sibling', $dir);
        $output = \Lia\Addon\View::from($lia)->view('sibling');

        $this->compare('sibling', $output);


        $this->compare(
            [
                'js'=>[$dir.'sibling.js'=>$dir.'sibling.js'],
                'css'=>[$dir.'sibling.css'=>$dir.'sibling.css'],
            ]
            , \Lia\Addon\Resources::from($lia)->files
        );
    }


    public function testAddViewMain(){
        $view = new \Lia\Addon\View();
        $file = $this->view_dir().'/test.php';
        $view->addView('lia:test', $this->view_dir_2());

        $this->compare(
            'test-dir',
            $view->view('test'),
        );

        $this->compare(
            'test-dir',
            $view->view('lia:test'),
        );
    }

    public function testAddViewCallable(){
        $view = new \Lia\Addon\View();
        $file = $this->view_dir().'/test.php';
        $msg = 'View callable must return string content';

        // @export_start(Views.add_callable)
        $view->addViewCallable('lia:test', 
            function(string $view_name, array $args): string {
                return 'View callable must return string content';
            }
        );
        // @export_end(Views.add_callable)

        $this->compare(
            $msg,
            $view->view('test'),
        );

        $this->compare(
            $msg,
            $view->view('lia:test'),
        );
    }

    public function testAddViewFile(){
        $view = new \Lia\Addon\View();
        $file = $this->view_dir().'/test.php';
        $view->addViewFile('lia:test', $file);


        $this->compare(
            file_get_contents($file),
            $view->view('test'),
        );

        $this->compare(
            file_get_contents($file),
            $view->view('lia:test'),
        );
    }

    public function view_dir(){
        return realpath($this->cli->pwd.'/test/input/Views/').'/';
    }
    public function view_dir_2(){
        return realpath($this->cli->pwd.'/test/input/Views2/').'/';
    }
    

    /**
     * @test Exception message when view not found
     */
    public function testViewNotFound(){
        $v = new \Lia\Addon\View();
        $v->addViewCallable('found', function(){return 'nah';});

        $this->catch('Lia\\Exception')
             ->containing("View 'null:not-found' has not been added to Liaison");

        try {
            $view = $v->view('not-found');
        } catch (\Exception $e){
            $this->throw($e);
        }
    }


    /**
     * @test Exception when there are no views for the requested non-null namespace
     */
    public function testNamespaceNotFound(){
        $v = new \Lia\Addon\View();

        $this->catch('Lia\\Exception')
             ->containing("View 'nons:not-found' has not been added to Liaison")
         ;

        try {
            $view = $v->view('nons:not-found');
        } catch (\Exception $e){
            $this->throw($e);
        }
    }

    /**
     *
     * @test that a null-namespace view() call will fallback to a namespaced view (when null-namespace view was not explicitly set)
     */
    public function testNoNamespaceFallback(){
        $v = new \Lia\Addon\View();
        $v->addViewCallable('lia:theme', function(){return 'ok';});
        $output = $v->view('theme').'';

        $this->compare('ok', $output);

    }

    /**
     * @test views can be loaded from multiple namespaces
     * @test that overwrite happens when conflictMode == overwrite 
     */
    public function testAddViewCallableWithNamespace(){
        $lia = new \Lia();
        $package = new \Lia\Package($lia, 'asdfasdf');
        $view_addon = new \Lia\Addon\View($package);
        // apparently conflictMode isn't used at all any more???
        // $view_addon->conflictMode = 'overwrite';

        // This approach is extremely rudimentary and not recommended.
        $phrase = "Fight for your right to vote.";
        $view_addon->addViewCallable('lia:theme',
            $liaTheme=function($name, $args) use ($phrase){
                return $phrase;
            }
        );
        $view_addon->addViewCallable('theme',$liaTheme);
        $view_addon->addViewCallable('wrong:theme',
            function($name, $args) use ($phrase){
                return 'view with wrong namespace';
            }
        );
        $phraseAny = 'view with no namespace';
        $view_addon->addViewCallable('theme',
            function($name, $args) use ($phraseAny){
                return $phraseAny;
            }
        );
        $anyNamespace = \Lia\Addon\View::from($lia)->view('theme').'';
        $this->compare($phraseAny, $anyNamespace);

        $specificNamespace = \Lia\Addon\View::from($lia)->view('lia:theme').'';
        $this->compare($phrase, $specificNamespace);

        $this->compare('view with wrong namespace', \Lia\Addon\View::from($lia)->view('wrong:theme').'');
    }

    public function testAddViewCallable2(){
        $lia = new \Lia();
        $package = new \Lia\Package($lia,'aadsfa');
        $view_addon = new \Lia\Addon\View($package);

        //@export_start(Usage.View.AddViewCallable)
        $phrase = "Fight for your right to vote.";
        \Lia\Addon\View::from($lia)->addViewCallable('theme',
            function($name, $args) use ($phrase){
                return $phrase;
            }
        );
        $content = \Lia\Addon\View::from($lia)->view('theme').'';
        //@export_end(Usage.View.AddViewCallable)
        $this->compare($phrase, $content);
    }


}