<?php
/*
 * Copyright (c) 2012, webvariants GbR, http://www.webvariants.de
 *
 * This file is released under the terms of the MIT license. You can find the
 * complete text in the attached LICENSE file or online at:
 *
 * http://www.opensource.org/licenses/mit-license.php
 */

class RealURL2_URLGeneratorTest extends RealURL2_BaseTest {
	public function testBasics() {
		try {
			$generator = new WV24_Generator();
			$this->fail('Should not have been able to get a generator without route.');
		}
		catch (Exception $e) { /* ... */ }

		$generator = new WV24_Generator('/my/route');
		$generator = new WV24_Generator('/my/route', WV24_Util::getStorage());

		try {
			$generator->setRoute('');
			$this->fail('Should not have been able to set an empty route.');
		}
		catch (Exception $e) { /* ... */ }

		$this->assertEquals(1, $generator->bind('foo1', 'bar'));
		$this->assertEquals(1, $generator->bind('foo1', 'bar')); // do not increase number
		$this->assertEquals(2, $generator->bind('foo2', 'bar'));
		$this->assertEquals(3, $generator->bind('foo3', 'bar'));
		$this->assertEquals(2, $generator->unbind('foo3'));
		$this->assertEquals(2, $generator->unbind('foo3')); // still two elements left
		$this->assertEquals(2, $generator->unbind('foo4')); // still two elements left
		$this->assertEquals(1, $generator->unbind('foo2'));
		$this->assertEquals(0, $generator->unbindAll());

		$this->assertEquals(98, $generator->setArticle(98));
		$this->assertEquals(98, $generator->setArticle('98'));
		$this->assertEquals(98, $generator->setArticle(sly_Util_Article::findById(98, 5)));

		$this->assertEquals(5, $generator->setClang(5));
		$this->assertEquals('foo', $generator->setNamespace('foo'));
		$this->assertEquals('foo', $generator->setIdent('foo'));
		$this->assertEquals('foo', $generator->setPath('foo'));

		$this->assertTrue($generator->setIsFullUrl(true));
		$this->assertFalse($generator->setIsFullUrl(false));
	}

	public function testStorage() {
		$generator = new WV24_Generator(':foo.html');
		$generator->bind('foo', 'hallowelt');
		$generator->setNamespace('test');
		$generator->setIdent('1');
		$generator->setArticle(90);
		$generator->setClang(8);

		$url = $generator->generate();
		$this->assertInstanceof('_WV24_URL', $url);

		$storage = WV24_Util::getStorage();
		$urls    = $storage->findByIdent('test', '1', false, true);
		$this->assertCount(1, $urls);

		$url = reset($urls);

		$this->assertEquals('test',  $url->getNamespace());
		$this->assertEquals('1',     $url->getIdent());
		$this->assertEquals(90,      $url->getArticleID());
		$this->assertEquals(8,       $url->getClang());
		$this->assertEquals('',      $url->getPath());
		$this->assertEquals(array(), $url->getParams());
	}

	/**
	 * @dataProvider dataProvider
	 */
	public function testGenerate($route, $clang, $expected, array $params = array()) {
		$generator = new WV24_Generator($route);
		$generator->setNamespace('test');
		$generator->setIdent('1');
		$generator->setArticle(101);
		$generator->setClang($clang);

		$expectedParams = array();

		foreach ($params as $name => $param) {
			@list ($val, $restore, $raw) = $param;
			$generator->bind($name, $val, (boolean) $restore, (boolean) $raw);

			if ($restore) {
				$expectedParams[$name] = $val;
			}
		}

		$url = $generator->generate(false);
		$this->assertInstanceof('_WV24_URL', $url);
		$this->assertEquals($expected, $url->getRawURL());

		$params = $url->getParams();

		foreach ($expectedParams as $key => $value) {
			$this->assertArrayHasKey($key, $params);
			$this->assertEquals($value, $params[$key]);

			unset($params[$key]);
		}

		$this->assertCount(0, $params);
	}

	public function dataProvider() {
		return array(
			array(':name.html',      5, 'http://cli/hallo-welt.html',     array('name' => array('Hallo Welt!'))),
			array(':name.html',      8, 'http://cli/en/Hallo+Welt.html',  array('name' => array('Hallo Welt!'))),
			array(':name.html',      8, 'http://cli/en/Hallo+Welt.html',  array('name' => array('Hallo Welt!', true))),
			array(':name.html',      8, 'http://cli/en/Hallo Welt!.html', array('name' => array('Hallo Welt!', true, true))),
			array(':name-test.html', 8, 'http://cli/en/t-test.html',      array('name' => array('t'))),

			// test core variables
			array(':slyclang.html',  8, 'http://cli/en/8.html'),
			array(':slyartid.html',  8, 'http://cli/en/101.html'),
			array('/:slyartid.html', 8, 'http://cli/en/101.html'),

			// param names are case insensitive
			array(
				'/:a/:b:B::c.html', 8, 'http://cli/en/a/XX:c.html',
				array('a' => array('a'), 'b' => array('X'), 'c' => array('c')),
			)
		);
	}
}
