<?php

namespace Http;

class RouterTest extends \PHPUnit_Framework_TestCase
{
    public function testSetRouteRule()
    {
        $router = new Router;
        $routeRule = new RouteRule('foo/route', 'foo/pattern');
        $router->setRouteRuleList(array($routeRule));
        $this->assertEquals('foo/route', $router->matchUrl('foo/pattern'));
    }

    public function testUrlNotFound()
    {
        $this->setExpectedException('Http\RouterException');
        $router = new Router;
        $router->matchUrl('404');
    }

    public function testRouteNotFound()
    {
        $this->setExpectedException('Http\RouterException');
        $router = new Router;
        $router->createUrl('404');
    }

    public function testRouteNotFoundParam()
    {
        $router = Router::fromArray(array(
            array('foo/bar/<id>', 'foo/bar')
        ));
        $this->assertEquals('/foo/bar/123', $router->createUrl('foo/bar', array('id' => 123)));

        $this->setExpectedException('Http\RouterException');
        $router->createUrl('foo/bar');
    }

    public function testSimpleRoute()
    {
        $router = Router::fromArray(array(
            array('foo/pattern', 'foo/route')
        ));
        $this->assertEquals('foo/route', $router->matchUrl('foo/pattern'));
        $this->assertEquals('foo/route', $router->matchUrl('/foo/pattern'));
        $this->assertEquals('/foo/pattern', $router->createUrl('foo/route'));
        $this->assertEquals('/foo/pattern', $router->createUrl('/foo/route'));
    }

    public function testCreateUrlWithHash()
    {
        $router = Router::fromArray(array(
            array('foo/pattern', 'foo/route')
        ));
        $this->assertEquals('/foo/pattern#ancor', $router->createUrl('foo/route', array('#' => 'ancor')));
    }

    public function testCreateUrlWithParams()
    {
        $router = Router::fromArray(array(
            array('foo/pattern', 'foo/route')
        ));
        $this->assertEquals('/foo/pattern?key=value', $router->createUrl('foo/route', array('key' => 'value')));
    }

    public function testLoadRequestAndGetArrays()
    {
        $this->assertArrayNotHasKey('c', $_GET);
        $this->assertArrayNotHasKey('c', $_REQUEST);
        $this->assertArrayNotHasKey('c', $_POST);

        $router = Router::fromArray(array(
            array('<c:(\w+)>/url', 'foo/route')
        ));

        $this->assertEquals('foo/route', $router->matchUrl('foo/url'));

        $this->assertArrayHasKey('c', $_GET);
        $this->assertArrayHasKey('c', $_REQUEST);
        $this->assertArrayNotHasKey('c', $_POST);
    }

    public function testExpressionRoute()
    {
        $router = Router::fromArray(array(
            array('<c:(\w+)>/url', '<c>/route')
        ));
        $this->assertEquals('foo/route', $router->matchUrl('foo/url'));
        $this->assertEquals('foo/route', $router->matchUrl('/foo/url'));
        $this->assertEquals('fooo/route', $router->matchUrl('fooo/url'));
        $this->assertEquals('fooo/route', $router->matchUrl('/fooo/url'));
        $this->assertEquals('/foo/url', $router->createUrl('foo/route'));
        $this->assertEquals('/foo/url', $router->createUrl('/foo/route'));
        $this->assertEquals('/fooo/url', $router->createUrl('fooo/route'));
        $this->assertEquals('/fooo/url', $router->createUrl('/fooo/route'));
    }

    public function testCreateUrlPatternNotFound()
    {
        $router = Router::fromArray(array(
            array('foo/<a>', 'foo/<a>')
        ));

        $this->assertEquals('/foo/bar', $router->createUrl('foo/bar'));
        $this->setExpectedException('Http\RouterException');
        $router->createUrl('bar/bar');
    }

    public function testMatchUrlPatternNotFound()
    {
        $router = Router::fromArray(array(
            array('foo/<a>', 'foo/<a>')
        ));

        $this->assertEquals('foo/bar', $router->matchUrl('foo/bar'));
        $this->setExpectedException('Http\RouterException');
        $router->matchUrl('bar/bar');
    }

    public function testAppendRoute()
    {
        $router = Router::fromArray(array(
            array('foo/*', 'foo/route')
        ));

        $this->assertEquals('foo/route', $router->matchUrl('foo/wefwefewfefw'));
    }

    public function testExpressionActionRoute()
    {
        $router = Router::fromArray(array(
            array('<c:(\w+)>/<a:\w+>', '<c>/<a>')
        ));
        $this->assertEquals('foo/bar', $router->matchUrl('foo/bar'));
        $this->assertEquals('controller/action', $router->matchUrl('controller/action'));
    }

    public function testStaticRoute()
    {
        $router = Router::fromArray(array(
            array('/foo/<foo:1>', 'foo'),
        ));
        $this->assertEquals('/foo/1', $router->createUrl('foo', array('foo'=>1)));
        $this->assertEquals('foo', $router->matchUrl('foo/1'));
    }
}
