diff options
| author | Nils Adermann <naderman@naderman.de> | 2010-03-10 16:24:19 +0100 | 
|---|---|---|
| committer | Nils Adermann <naderman@naderman.de> | 2010-03-10 16:24:19 +0100 | 
| commit | 60bd1edcb5e5992e6e693d0f68db47e678f7d54a (patch) | |
| tree | dffc10407f0ef6a85d034415d7e30407ccf3f21a | |
| parent | d9567f121b11d3f5b068b85e7c862c27fc495005 (diff) | |
| download | forums-60bd1edcb5e5992e6e693d0f68db47e678f7d54a.tar forums-60bd1edcb5e5992e6e693d0f68db47e678f7d54a.tar.gz forums-60bd1edcb5e5992e6e693d0f68db47e678f7d54a.tar.bz2 forums-60bd1edcb5e5992e6e693d0f68db47e678f7d54a.tar.xz forums-60bd1edcb5e5992e6e693d0f68db47e678f7d54a.zip | |
[develop-olympus] Backported 3.1 unit tests to 3.0.
Start adding unit tests for bugs you fix! Tests for anything are
welcome really. We have to work on these a lot.
29 files changed, 1766 insertions, 0 deletions
| diff --git a/tests/all_tests.php b/tests/all_tests.php new file mode 100644 index 0000000000..1ed6126e80 --- /dev/null +++ b/tests/all_tests.php @@ -0,0 +1,54 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +error_reporting(E_ALL); + +if (!defined('PHPUnit_MAIN_METHOD')) +{ +	define('PHPUnit_MAIN_METHOD', 'phpbb_all_tests::main'); +} + +require_once 'test_framework/framework.php'; +require_once 'PHPUnit/TextUI/TestRunner.php'; + +require_once 'utf/all_tests.php'; +require_once 'request/all_tests.php'; +require_once 'security/all_tests.php'; +require_once 'template/all_tests.php'; +require_once 'text_processing/all_tests.php'; + +// exclude the test directory from code coverage reports +PHPUnit_Util_Filter::addDirectoryToFilter('./'); + +class phpbb_all_tests +{ +	public static function main() +	{ +		PHPUnit_TextUI_TestRunner::run(self::suite()); +	} + +	public static function suite() +	{ +		$suite = new PHPUnit_Framework_TestSuite('phpBB'); + +		$suite->addTest(phpbb_utf_all_tests::suite()); +		$suite->addTest(phpbb_request_all_tests::suite()); +		$suite->addTest(phpbb_security_all_tests::suite()); +		$suite->addTest(phpbb_template_all_tests::suite()); +		$suite->addTest(phpbb_text_processing_all_tests::suite()); + +		return $suite; +	} +} + +if (PHPUnit_MAIN_METHOD == 'phpbb_all_tests::main') +{ +	phpbb_all_tests::main(); +} + diff --git a/tests/request/all_tests.php b/tests/request/all_tests.php new file mode 100644 index 0000000000..1ee3029b36 --- /dev/null +++ b/tests/request/all_tests.php @@ -0,0 +1,41 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +if (!defined('PHPUnit_MAIN_METHOD')) +{ +	define('PHPUnit_MAIN_METHOD', 'phpbb_request_all_tests::main'); +} + +require_once 'test_framework/framework.php'; +require_once 'PHPUnit/TextUI/TestRunner.php'; + +require_once 'request/request_var.php'; + +class phpbb_request_all_tests +{ +	public static function main() +	{ +		PHPUnit_TextUI_TestRunner::run(self::suite()); +	} + +	public static function suite() +	{ +		$suite = new PHPUnit_Framework_TestSuite('phpBB Request Parameter Handling'); + +		$suite->addTestSuite('phpbb_request_request_var_test'); + +		return $suite; +	} +} + +if (PHPUnit_MAIN_METHOD == 'phpbb_request_all_tests::main') +{ +	phpbb_request_all_tests::main(); +} + diff --git a/tests/request/request_var.php b/tests/request/request_var.php new file mode 100644 index 0000000000..b1dacef3fd --- /dev/null +++ b/tests/request/request_var.php @@ -0,0 +1,180 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once 'test_framework/framework.php'; +require_once '../phpBB/includes/functions.php'; + +class phpbb_request_request_var_test extends phpbb_test_case +{ +	/** +	* @dataProvider request_variables +	*/ +	public function test_post($variable_value, $default, $multibyte, $expected) +	{ +		$variable_name = 'name'; +		$this->unset_variables($variable_name); + +		$_POST[$variable_name] = $variable_value; +		$_REQUEST[$variable_name] = $variable_value; + +		$result = request_var($variable_name, $default, $multibyte); + +		$label = 'Requesting POST variable, converting from ' . gettype($variable_value) . ' to ' . gettype($default) . (($multibyte) ? ' multibyte' : ''); +		$this->assertEquals($expected, $result, $label); +	} + +	/** +	* @dataProvider request_variables +	*/ +	public function test_get($variable_value, $default, $multibyte, $expected) +	{ +		$variable_name = 'name'; +		$this->unset_variables($variable_name); + +		$_GET[$variable_name] = $variable_value; +		$_REQUEST[$variable_name] = $variable_value; + +		$result = request_var($variable_name, $default, $multibyte); + +		$label = 'Requesting GET variable, converting from ' . gettype($variable_value) . ' to ' . gettype($default) . (($multibyte) ? ' multibyte' : ''); +		$this->assertEquals($expected, $result, $label); +	} + +	/** +	* @dataProvider request_variables +	*/ +	public function test_cookie($variable_value, $default, $multibyte, $expected) +	{ +		$variable_name = 'name'; +		$this->unset_variables($variable_name); + +		$_GET[$variable_name] = false; +		$_POST[$variable_name] = false; +		$_REQUEST[$variable_name] = false; +		$_COOKIE[$variable_name] = $variable_value; + +		$result = request_var($variable_name, $default, $multibyte, true); + +		$label = 'Requesting COOKIE variable, converting from ' . gettype($variable_value) . ' to ' . gettype($default) . (($multibyte) ? ' multibyte' : ''); +		$this->assertEquals($expected, $result, $label); +	} + +	/** +	* Helper for unsetting globals +	*/ +	private function unset_variables($var) +	{ +		unset($_GET[$var], $_POST[$var], $_REQUEST[$var], $_COOKIE[$var]); +	} + +	public static function request_variables() +	{ +		return array( +			// strings +			array('abc', '', false, 'abc'), +			array('  some  spaces  ', '', true, 'some  spaces'), +			array("\r\rsome\rcarriage\r\rreturns\r", '', true, "some\ncarriage\n\nreturns"), +			array("\n\nsome\ncarriage\n\nreturns\n", '', true, "some\ncarriage\n\nreturns"), +			array("\r\n\r\nsome\r\ncarriage\r\n\r\nreturns\r\n", '', true, "some\ncarriage\n\nreturns"), +			array("we\xC2\xA1rd\xE1\x9A\x80ch\xCE\xB1r\xC2\xADacters", '', true, "we\xC2\xA1rd\xE1\x9A\x80ch\xCE\xB1r\xC2\xADacters"), +			array("we\xC2\xA1rd\xE1\x9A\x80ch\xCE\xB1r\xC2\xADacters", '', false, "we??rd???ch??r??acters"), +			array("Some <html> \"entities\" like &", '', true, "Some <html> "entities" like &"), + +			// integers +			array('1234', 0, false, 1234), +			array('abc', 12, false, 0), +			array('324abc', 0, false, 324), + +			// string to array +			array('123', array(0), false, array()), +			array('123', array(''), false, array()), + +			// 1 dimensional arrays +			array( +				// input: +				array('123', 'abc'), +				// default: +				array(''), +				false, +				// expected: +				array('123', 'abc') +			), +			array( +				// input: +				array('123', 'abc'), +				// default: +				array(999), +				false, +				// expected: +				array(123, 0) +			), +			array( +				// input: +				array('xyz' => '123', 'abc' => 'abc'), +				// default: +				array('' => ''), +				false, +				// expected: +				array('xyz' => '123', 'abc' => 'abc') +			), +			array( +				// input: +				array('xyz' => '123', 'abc' => 'abc'), +				// default: +				array('' => 0), +				false, +				// expected: +				array('xyz' => 123, 'abc' => 0) +			), + +			// 2 dimensional arrays +			array( +				// input: +				'', +				// default: +				array(array(0)), +				false, +				// expected: +				array() +			), +			array( +				// input: +				array( +					'xyz' => array('123', 'def'), +					'abc' => 'abc' +				), +				// default: +				array('' => array('')), +				false, +				// expected: +				array( +					'xyz' => array('123', 'def'), +					'abc' => array() +				) +			), +			array( +				// input: +				array( +					'xyz' => array('123', 'def'), +					'abc' => 'abc' +				), +				// default: +				array('' => array(0)), +				false, +				// expected: +				array( +					'xyz' => array(123, 0), +					'abc' => array() +				) +			), +		); +	} + +} + diff --git a/tests/security/all_tests.php b/tests/security/all_tests.php new file mode 100644 index 0000000000..8e3916733f --- /dev/null +++ b/tests/security/all_tests.php @@ -0,0 +1,86 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +if (!defined('PHPUnit_MAIN_METHOD')) +{ +	define('PHPUnit_MAIN_METHOD', 'phpbb_security_all_tests::main'); +} + +require_once 'test_framework/framework.php'; +require_once 'PHPUnit/TextUI/TestRunner.php'; + +require_once 'security/extract_current_page.php'; +require_once 'security/redirect.php'; + +class phpbb_security_all_tests extends PHPUnit_Framework_TestSuite +{ +	/** +	* Set up the required user object and server variables for the suites +	*/ +	protected function setUp() +	{ +		global $user, $phpbb_root_path; + +		// Put this into a global function being run by every test to init a proper user session +		$_SERVER['HTTP_HOST']		= 'localhost'; +		$_SERVER['SERVER_NAME']		= 'localhost'; +		$_SERVER['SERVER_ADDR']		= '127.0.0.1'; +		$_SERVER['SERVER_PORT']		= 80; +		$_SERVER['REMOTE_ADDR']		= '127.0.0.1'; +		$_SERVER['QUERY_STRING']	= ''; +		$_SERVER['REQUEST_URI']		= '/tests/'; +		$_SERVER['SCRIPT_NAME']		= '/tests/index.php'; +		$_SERVER['PHP_SELF']		= '/tests/index.php'; +		$_SERVER['HTTP_USER_AGENT']	= 'Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14'; +		$_SERVER['HTTP_ACCEPT_LANGUAGE']	= 'de-de,de;q=0.8,en-us;q=0.5,en;q=0.3'; + +/* +		[HTTP_ACCEPT_ENCODING] => gzip,deflate +		[HTTP_ACCEPT_CHARSET] => ISO-8859-1,utf-8;q=0.7,*;q=0.7 +		DOCUMENT_ROOT] => /var/www/ +		[SCRIPT_FILENAME] => /var/www/tests/index.php +*/ + +		// Set no user and trick a bit to circumvent errors +		$user = new user(); +		$user->lang = true; +		$user->browser				= (!empty($_SERVER['HTTP_USER_AGENT'])) ? htmlspecialchars((string) $_SERVER['HTTP_USER_AGENT']) : ''; +		$user->referer				= (!empty($_SERVER['HTTP_REFERER'])) ? htmlspecialchars((string) $_SERVER['HTTP_REFERER']) : ''; +		$user->forwarded_for		= (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) ? (string) $_SERVER['HTTP_X_FORWARDED_FOR'] : ''; +		$user->host					= (!empty($_SERVER['HTTP_HOST'])) ? (string) strtolower($_SERVER['HTTP_HOST']) : ((!empty($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : getenv('SERVER_NAME')); +		$user->page = session::extract_current_page($phpbb_root_path); +	} + +	protected function tearDown() +	{ +		global $user; +		$user = NULL; +	} + +	public static function main() +	{ +		PHPUnit_TextUI_TestRunner::run(self::suite()); +	} + +	public static function suite() +	{ +		// I bet there is a better method calling this... :) +		$suite = new phpbb_security_all_tests('phpBB Security Fixes'); + +		$suite->addTestSuite('phpbb_security_extract_current_page_test'); +		$suite->addTestSuite('phpbb_security_redirect_test'); + +		return $suite; +	} +} + +if (PHPUnit_MAIN_METHOD == 'phpbb_security_all_tests::main') +{ +	phpbb_security_all_tests::main(); +} diff --git a/tests/security/extract_current_page.php b/tests/security/extract_current_page.php new file mode 100644 index 0000000000..8c72fe1440 --- /dev/null +++ b/tests/security/extract_current_page.php @@ -0,0 +1,53 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once 'test_framework/framework.php'; + +require_once '../phpBB/includes/functions.php'; +require_once '../phpBB/includes/session.php'; + +class phpbb_security_extract_current_page_test extends phpbb_test_case +{ +	public static function security_variables() +	{ +		return array( +			array('http://localhost/phpBB/index.php', 'mark=forums&x="><script>alert(/XSS/);</script>', 'mark=forums&x=%22%3E%3Cscript%3Ealert(/XSS/);%3C/script%3E'), +			array('http://localhost/phpBB/index.php', 'mark=forums&x=%22%3E%3Cscript%3Ealert(/XSS/);%3C/script%3E', 'mark=forums&x=%22%3E%3Cscript%3Ealert(/XSS/);%3C/script%3E'), +		); +	} + +	/** +	* @dataProvider security_variables +	*/ +	public function test_query_string_php_self($url, $query_string, $expected) +	{ +		$_SERVER['PHP_SELF'] = $url; +		$_SERVER['QUERY_STRING'] = $query_string; + +		$result = session::extract_current_page('./'); + +		$label = 'Running extract_current_page on ' . $query_string . ' with PHP_SELF filled.'; +		$this->assertEquals($expected, $result['query_string'], $label); +	} + +	/** +	* @dataProvider security_variables +	*/ +	public function test_query_string_request_uri($url, $query_string, $expected) +	{ +		$_SERVER['REQUEST_URI'] = $url . '?' . $query_string; +		$_SERVER['QUERY_STRING'] = $query_string; + +		$result = session::extract_current_page('./'); + +		$label = 'Running extract_current_page on ' . $query_string . ' with REQUEST_URI filled.'; +		$this->assertEquals($expected, $result['query_string'], $label); +	} +} + diff --git a/tests/security/redirect.php b/tests/security/redirect.php new file mode 100644 index 0000000000..37b0a5bb41 --- /dev/null +++ b/tests/security/redirect.php @@ -0,0 +1,58 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once 'test_framework/framework.php'; + +require_once '../phpBB/includes/functions.php'; +require_once '../phpBB/includes/session.php'; + +class phpbb_security_redirect_test extends phpbb_test_case +{ +	public static function provider() +	{ +		// array(Input -> redirect(), expected triggered error (else false), expected returned result url (else false)) +		return array( +			array('data://x', false, 'http://localhost/phpBB'), +			array('bad://localhost/phpBB/index.php', 'Tried to redirect to potentially insecure url.', false), +			array('http://www.otherdomain.com/somescript.php', false, 'http://localhost/phpBB'), +			array("http://localhost/phpBB/memberlist.php\n\rConnection: close", 'Tried to redirect to potentially insecure url.', false), +			array('javascript:test', false, 'http://localhost/phpBB/../tests/javascript:test'), +			array('http://localhost/phpBB/index.php;url=', 'Tried to redirect to potentially insecure url.', false), +		); +	} + +	protected function setUp() +	{ +		$GLOBALS['config'] = array( +			'force_server_vars'	=> '0', +		); +	} + +	/** +	* @dataProvider provider +	*/ +	public function test_redirect($test, $expected_error, $expected_result) +	{ +		global $user; + +		if ($expected_error !== false) +		{ +			$this->setExpectedTriggerError(E_USER_ERROR, $expected_error); +		} + +		$result = redirect($test, true); + +		// only verify result if we did not expect an error +		if ($expected_error === false) +		{ +			$this->assertEquals($expected_result, $result); +		} +	} +} + diff --git a/tests/template/all_tests.php b/tests/template/all_tests.php new file mode 100644 index 0000000000..ea258c1680 --- /dev/null +++ b/tests/template/all_tests.php @@ -0,0 +1,40 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +if (!defined('PHPUnit_MAIN_METHOD')) +{ +	define('PHPUnit_MAIN_METHOD', 'phpbb_template_all_tests::main'); +} + +require_once 'test_framework/framework.php'; +require_once 'PHPUnit/TextUI/TestRunner.php'; + +require_once 'template/template.php'; + +class phpbb_template_all_tests +{ +	public static function main() +	{ +		PHPUnit_TextUI_TestRunner::run(self::suite()); +	} + +	public static function suite() +	{ +		$suite = new PHPUnit_Framework_TestSuite('phpBB Template Engine'); + +		$suite->addTestSuite('phpbb_template_template_test'); + +		return $suite; +	} +} + +if (PHPUnit_MAIN_METHOD == 'phpbb_template_all_tests::main') +{ +	phpbb_template_all_tests::main(); +} diff --git a/tests/template/template.php b/tests/template/template.php new file mode 100644 index 0000000000..df12f92046 --- /dev/null +++ b/tests/template/template.php @@ -0,0 +1,671 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once 'test_framework/framework.php'; + +require_once '../phpBB/includes/template.php'; + +class phpbb_template_template_test extends phpbb_test_case +{ +	private $template; +	private $template_path; + +	// Keep the contents of the cache for debugging? +	const PRESERVE_CACHE = true; + +	private function display($handle) +	{ +		// allow the templates to throw notices +		$error_level = error_reporting(); +		error_reporting($error_level & ~E_NOTICE); + +		ob_start(); +		$this->assertTrue($this->template->display($handle, false)); + +		// reset error level +		error_reporting($error_level); + +		return self::trim_template_result(ob_get_clean()); +	} + +	private static function trim_template_result($result) +	{ +		return str_replace("\n\n", "\n", implode("\n", array_map('trim', explode("\n", trim($result))))); +	} + +	private function setup_engine() +	{ +		$this->template_path = dirname(__FILE__) . '/templates'; +		$this->template = new template(); +		$this->template->set_custom_template($this->template_path, 'tests'); +	} + +	protected function setUp() +	{ +		// Test the engine can be used +		$this->setup_engine(); + +		if (!is_writable(dirname($this->template->cachepath))) +		{ +			$this->markTestSkipped("Template cache directory is not writable."); +		} + +		foreach (glob($this->template->cachepath . '*') as $file) +		{ +			unlink($file); +		} + +		$GLOBALS['config'] = array( +			'load_tplcompile'	=> true, +			'tpl_allow_php'		=> false, +		); +	} + +	protected function tearDown() +	{ +		if (is_object($this->template)) +		{ +			foreach (glob($this->template->cachepath . '*') as $file) +			{ +				unlink($file); +			} +		} +	} + +	/** +	 * @todo put test data into templates/xyz.test +	 */ +	public static function template_data() +	{ +		return array( +			/* +			array( +				'', // File +				array(), // vars +				array(), // block vars +				array(), // destroy +				'', // Expected result +			), +			*/ +			array( +				'basic.html', +				array(), +				array(), +				array(), +				"pass\npass\n<!-- DUMMY var -->", +			), +			array( +				'variable.html', +				array('VARIABLE' => 'value'), +				array(), +				array(), +				'value', +			), +			array( +				'if.html', +				array(), +				array(), +				array(), +				'0', +			), +			array( +				'if.html', +				array('S_VALUE' => true), +				array(), +				array(), +				"1\n0", +			), +			array( +				'if.html', +				array('S_VALUE' => true, 'S_OTHER_VALUE' => true), +				array(), +				array(), +				'1', +			), +			array( +				'if.html', +				array('S_VALUE' => false, 'S_OTHER_VALUE' => true), +				array(), +				array(), +				'2', +			), +			array( +				'loop.html', +				array(), +				array(), +				array(), +				"noloop\nnoloop", +			), +			array( +				'loop.html', +				array(), +				array('loop' => array(array())), +				array(), +				"loop\nloop", +			), +			array( +				'loop.html', +				array(), +				array('loop' => array(array(), array()), 'loop.block' => array(array())), +				array(), +				"loop\nloop\nloop\nloop", +			), +			array( +				'loop.html', +				array(), +				array('loop' => array(array(), array()), 'loop.block' => array(array()), 'block' => array(array(), array())), +				array(), +				"loop\nloop\nloop\nloop\nloop#0-block#0\nloop#0-block#1\nloop#1-block#0\nloop#1-block#1", +			), +			array( +				'loop_vars.html', +				array(), +				array('loop' => array(array('VARIABLE' => 'x'))), +				array(), +				"first\n0\nx\nset\nlast", +			),/* no nested top level loops +			array( +				'loop_vars.html', +				array(), +				array('loop' => array(array('VARIABLE' => 'x'), array('VARIABLE' => 'y'))), +				array(), +				"first\n0\n0\n2\nx\nset\n1\n1\n2\ny\nset\nlast", +			), +			array( +				'loop_vars.html', +				array(), +				array('loop' => array(array('VARIABLE' => 'x'), array('VARIABLE' => 'y')), 'loop.inner' => array(array(), array())), +				array(), +				"first\n0\n0\n2\nx\nset\n1\n1\n2\ny\nset\nlast\n0\n\n1\nlast inner\ninner loop", +			),*/ +			array( +				'loop_advanced.html', +				array(), +				array('loop' => array(array(), array(), array(), array(), array(), array(), array())), +				array(), +				"101234561\nx\n101234561\nx\n101234561\nx\n1234561\nx\n1\nx\n101\nx\n234\nx\n10\nx\n561\nx\n561", +			), +			array( +				'define.html', +				array(), +				array('loop' => array(array(), array(), array(), array(), array(), array(), array()), 'test' => array(array()), 'test.deep' => array(array()), 'test.deep.defines' => array(array())), +				array(), +				"xyz\nabc", +			), +			array( +				'expressions.html', +				array(), +				array(), +				array(), +				trim(str_repeat("pass", 39)), +			), +			array( +				'php.html', +				array(), +				array(), +				array(), +				'', +			), +			array( +				'include.html', +				array('VARIABLE' => 'value'), +				array(), +				array(), +				'value', +			), +			array( +				'loop_vars.html', +				array(), +				array('loop' => array(array('VARIABLE' => 'x'), array('VARIABLE' => 'y')), 'loop.inner' => array(array(), array())), +				array('loop'), +				'', +			),/* no top level nested loops +			array( +				'loop_vars.html', +				array(), +				array('loop' => array(array('VARIABLE' => 'x'), array('VARIABLE' => 'y')), 'loop.inner' => array(array(), array())), +				array('loop.inner'), +				"first\n0\n0\n2\nx\nset\n1\n1\n2\ny\nset\nlast", +			),*/ +			array( +				'lang.html', +				array(), +				array(), +				array(), +				"{ VARIABLE }\n{ VARIABLE }", +			), +			array( +				'lang.html', +				array('L_VARIABLE' => "Value'"), +				array(), +				array(), +				"Value'\nValue\'", +			), +			array( +				'lang.html', +				array('LA_VARIABLE' => "Value'"), +				array(), +				array(), +				"{ VARIABLE }\nValue'", +			), +		); +	} + +	public function test_missing_file() +	{ +		$filename = 'file_not_found.html'; + +		$this->template->set_filenames(array('test' => $filename)); +		$this->assertFileNotExists($this->template_path . '/' . $filename, 'Testing missing file, file cannot exist'); + +		$expecting = sprintf('template->_tpl_load_file(): File %s does not exist or is empty', realpath($this->template_path) . '/' . $filename); +		$this->setExpectedTriggerError(E_USER_ERROR, $expecting); + +		$this->display('test'); +	} + +	public function test_empty_file() +	{ +		$expecting = 'template->set_filenames: Empty filename specified for test'; + +		$this->setExpectedTriggerError(E_USER_ERROR, $expecting); +		$this->template->set_filenames(array('test' => '')); +	} + +	public function test_invalid_handle() +	{ +		$expecting = 'template->_tpl_load(): No file specified for handle test'; +		$this->setExpectedTriggerError(E_USER_ERROR, $expecting); + +		$this->display('test'); +	} + +	private function run_template($file, array $vars, array $block_vars, array $destroy, $expected, $cache_file) +	{ +		$this->template->set_filenames(array('test' => $file)); +		$this->template->assign_vars($vars); + +		foreach ($block_vars as $block => $loops) +		{ +			foreach ($loops as $_vars) +			{ +				$this->template->assign_block_vars($block, $_vars); +			} +		} + +		foreach ($destroy as $block) +		{ +			$this->template->destroy_block_vars($block); +		} + +		try +		{ +			$this->assertEquals($expected, $this->display('test'), "Testing $file"); +			$this->assertFileExists($cache_file); +		} +		catch (ErrorException $e) +		{ +			if (file_exists($cache_file)) +			{ +				copy($cache_file, str_replace('ctpl_', 'tests_ctpl_', $cache_file)); +			} + +			throw $e; +		} + +		// For debugging +		if (self::PRESERVE_CACHE) +		{ +			copy($cache_file, str_replace('ctpl_', 'tests_ctpl_', $cache_file)); +		} +	} + +	/** +	* @dataProvider template_data +	*/ +	public function test_template($file, array $vars, array $block_vars, array $destroy, $expected) +	{ +		global $phpEx; +		$cache_file = $this->template->cachepath . str_replace('/', '.', $file) . '.' . $phpEx; + +		$this->assertFileNotExists($cache_file); + +		$this->run_template($file, $vars, $block_vars, $destroy, $expected, $cache_file); + +		// Reset the engine state +		$this->setup_engine(); + +		$this->run_template($file, $vars, $block_vars, $destroy, $expected, $cache_file); +	} + +	/** +	* @dataProvider template_data +	*/ +	public function test_assign_display($file, array $vars, array $block_vars, array $destroy, $expected) +	{ +		$this->template->set_filenames(array( +			'test' => $file, +			'container' => 'variable.html', +		)); +		$this->template->assign_vars($vars); + +		foreach ($block_vars as $block => $loops) +		{ +			foreach ($loops as $_vars) +			{ +				$this->template->assign_block_vars($block, $_vars); +			} +		} + +		foreach ($destroy as $block) +		{ +			$this->template->destroy_block_vars($block); +		} + +		$this->assertEquals($expected, self::trim_template_result($this->template->assign_display('test')), "Testing assign_display($file)"); + +		$this->template->assign_display('test', 'VARIABLE', false); +		$this->assertEquals($expected, $this->display('container'), "Testing assign_display($file)"); +	} + +	public function test_php() +	{ +		global $phpEx; + +		$GLOBALS['config']['tpl_allow_php'] = true; + +		$cache_file = $this->template->cachepath . 'php.html.' . $phpEx; + +		$this->assertFileNotExists($cache_file); + +		$this->run_template('php.html', array(), array(), array(), 'test', $cache_file); + +		$GLOBALS['config']['tpl_allow_php'] = false; +	} + +	public function test_includephp() +	{ +		$this->markTestIncomplete('Include PHP test file paths are broken'); + +		$GLOBALS['config']['tpl_allow_php'] = true; + +		$cache_file = $this->template->cachepath . 'includephp.html.' . PHP_EXT; + +		$cwd = getcwd(); +		chdir(dirname(__FILE__) . '/templates'); + +		$this->run_template('includephp.html', array(), array(), array(), 'testing included php', $cache_file); + +		$this->template->set_filenames(array('test' => 'includephp.html')); +		$this->assertEquals('testing included php', $this->display('test'), "Testing $file"); + +		chdir($cwd); + +		$GLOBALS['config']['tpl_allow_php'] = false; +	} + +	public static function alter_block_array_data() +	{ +		return array( +			array( +				'outer', +				array('VARIABLE' => 'before'), +				false, +				'insert', +				<<<EOT +outer - 0/4 - before +outer - 1/4 +middle - 0/2 +middle - 1/2 +outer - 2/4 +middle - 0/3 +middle - 1/3 +middle - 2/3 +outer - 3/4 +middle - 0/2 +middle - 1/2 +EOT +, +				'Test inserting before on top level block', +			), +			array( +				'outer', +				array('VARIABLE' => 'after'), +				true, +				'insert', +				<<<EOT +outer - 0/4 +middle - 0/2 +middle - 1/2 +outer - 1/4 +middle - 0/3 +middle - 1/3 +middle - 2/3 +outer - 2/4 +middle - 0/2 +middle - 1/2 +outer - 3/4 - after +EOT +, +				'Test inserting after on top level block', +			), +			array( +				'outer', +				array('VARIABLE' => 'pos #1'), +				1, +				'insert', +				<<<EOT +outer - 0/4 +middle - 0/2 +middle - 1/2 +outer - 1/4 - pos #1 +outer - 2/4 +middle - 0/3 +middle - 1/3 +middle - 2/3 +outer - 3/4 +middle - 0/2 +middle - 1/2 +EOT +, +				'Test inserting at 1 on top level block', +			), +			array( +				'outer', +				array('VARIABLE' => 'pos #1'), +				0, +				'change', +				<<<EOT +outer - 0/3 - pos #1 +middle - 0/2 +middle - 1/2 +outer - 1/3 +middle - 0/3 +middle - 1/3 +middle - 2/3 +outer - 2/3 +middle - 0/2 +middle - 1/2 +EOT +, +				'Test inserting at 1 on top level block', +			), +			array( +				'outer[0].middle', +				array('VARIABLE' => 'before'), +				false, +				'insert', +				<<<EOT +outer - 0/3 +middle - 0/3 - before +middle - 1/3 +middle - 2/3 +outer - 1/3 +middle - 0/3 +middle - 1/3 +middle - 2/3 +outer - 2/3 +middle - 0/2 +middle - 1/2 +EOT +, +				'Test inserting before on nested block', +			), +			array( +				'outer[0].middle', +				array('VARIABLE' => 'after'), +				true, +				'insert', +				<<<EOT +outer - 0/3 +middle - 0/3 +middle - 1/3 +middle - 2/3 - after +outer - 1/3 +middle - 0/3 +middle - 1/3 +middle - 2/3 +outer - 2/3 +middle - 0/2 +middle - 1/2 +EOT +, +				'Test inserting after on nested block', +			), +			array( +				'outer[0].middle', +				array('VARIABLE' => 'pos #1'), +				1, +				'insert', +				<<<EOT +outer - 0/3 +middle - 0/3 +middle - 1/3 - pos #1 +middle - 2/3 +outer - 1/3 +middle - 0/3 +middle - 1/3 +middle - 2/3 +outer - 2/3 +middle - 0/2 +middle - 1/2 +EOT +, +				'Test inserting at pos 1 on nested block', +			), +			array( +				'outer[1].middle', +				array('VARIABLE' => 'before'), +				false, +				'insert', +				<<<EOT +outer - 0/3 +middle - 0/2 +middle - 1/2 +outer - 1/3 +middle - 0/4 - before +middle - 1/4 +middle - 2/4 +middle - 3/4 +outer - 2/3 +middle - 0/2 +middle - 1/2 +EOT +, +				'Test inserting before on nested block (pos 1)', +			), +			array( +				'outer[].middle', +				array('VARIABLE' => 'before'), +				false, +				'insert', +				<<<EOT +outer - 0/3 +middle - 0/2 +middle - 1/2 +outer - 1/3 +middle - 0/3 +middle - 1/3 +middle - 2/3 +outer - 2/3 +middle - 0/3 - before +middle - 1/3 +middle - 2/3 +EOT +, +				'Test inserting before on nested block (end)', +			), +			array( +				'outer.middle', +				array('VARIABLE' => 'before'), +				false, +				'insert', +				<<<EOT +outer - 0/3 +middle - 0/2 +middle - 1/2 +outer - 1/3 +middle - 0/3 +middle - 1/3 +middle - 2/3 +outer - 2/3 +middle - 0/3 - before +middle - 1/3 +middle - 2/3 +EOT +, +				'Test inserting before on nested block (end)', +			), +		); +	} + +/* +				<<<EOT +outer - 0/3 +middle - 0/2 +middle - 1/2 +outer - 1/3 +middle - 0/3 +middle - 1/3 +middle - 2/3 +outer - 2/3 +middle - 0/2 +middle - 1/2 +EOT +, +*/ + +	/** +	* @dataProvider alter_block_array_data +	*/ +	public function test_alter_block_array($alter_block, array $vararray, $key, $mode, $expect, $description) +	{ +		$this->markTestIncomplete('Alter Block Test is broken'); + +		$this->template->set_filenames(array('test' => 'loop_nested.html')); + +		// @todo Change this +		$this->template->assign_block_vars('outer', array()); +		$this->template->assign_block_vars('outer.middle', array()); +		$this->template->assign_block_vars('outer.middle', array()); +		$this->template->assign_block_vars('outer', array()); +		$this->template->assign_block_vars('outer.middle', array()); +		$this->template->assign_block_vars('outer.middle', array()); +		$this->template->assign_block_vars('outer.middle', array()); +		$this->template->assign_block_vars('outer', array()); +		$this->template->assign_block_vars('outer.middle', array()); +		$this->template->assign_block_vars('outer.middle', array()); + +		$this->assertEquals("outer - 0/3\nmiddle - 0/2\nmiddle - 1/2\nouter - 1/3\nmiddle - 0/3\nmiddle - 1/3\nmiddle - 2/3\nouter - 2/3\nmiddle - 0/2\nmiddle - 1/2", $this->display('test'), 'Ensuring template is built correctly before modification'); + +		$this->template->alter_block_array($alter_block, $vararray, $key, $mode); +		$this->assertEquals($expect, $this->display('test'), $description); +	} +} + diff --git a/tests/template/templates/_dummy_include.php b/tests/template/templates/_dummy_include.php new file mode 100644 index 0000000000..1de5dddf59 --- /dev/null +++ b/tests/template/templates/_dummy_include.php @@ -0,0 +1,3 @@ +<?php + +echo "testing included php"; diff --git a/tests/template/templates/basic.html b/tests/template/templates/basic.html new file mode 100644 index 0000000000..c1dd690260 --- /dev/null +++ b/tests/template/templates/basic.html @@ -0,0 +1,20 @@ +<!-- IF S_FALSE --> +fail +<!-- ENDIF --> +<!-- IF S_TRUE --> +pass +<!-- ENDIF --> +<!-- IF S_FALSE --> +fail +<!-- ELSEIF S_FALSE and not S_TRUE --> +fail +<!-- ELSE --> +pass +<!-- ENDIF --> +<!-- BEGIN empty --> +fail +<!-- BEGINELSE --> +pass +<!-- END empty --> + +<!-- DUMMY var --> diff --git a/tests/template/templates/define.html b/tests/template/templates/define.html new file mode 100644 index 0000000000..82237d21a3 --- /dev/null +++ b/tests/template/templates/define.html @@ -0,0 +1,8 @@ +<!-- DEFINE $VALUE = 'xyz' --> +{$VALUE} +<!-- DEFINE $VALUE = 'abc' --> +{$VALUE} +<!-- UNDEFINE $VALUE --> +{$VALUE} +<!-- DEFINE $VALUE --> + diff --git a/tests/template/templates/expressions.html b/tests/template/templates/expressions.html new file mode 100644 index 0000000000..c40d967dab --- /dev/null +++ b/tests/template/templates/expressions.html @@ -0,0 +1,86 @@ +<!-- IF 10 is even -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 9 is even -->fail<!-- ELSE -->pass<!-- ENDIF --> + +<!-- IF not 390 is even -->fail<!-- ELSE -->pass<!-- ENDIF --> + +<!-- IF 9 is odd -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 32 is odd -->fail<!-- ELSE -->pass<!-- ENDIF --> + +<!-- IF 32 is div by 16 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 10 is not even -->fail<!-- ELSE -->pass<!-- ENDIF --> + +<!-- IF 24 == 24 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 24 eq 24 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF ((((((24 == 24)))))) -->pass<!-- ELSE -->fail<!-- ENDIF --> + + +<!-- IF 24 != 20 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 24 <> 20 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 24 ne 20 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 24 neq 20 -->pass<!-- ELSE -->fail<!-- ENDIF --> + + +<!-- IF 10 lt 20 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 10 < 20 -->pass<!-- ELSE -->fail<!-- ENDIF --> + + +<!-- IF 10 le 20 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 10 lte 20 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 10 <= 20 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 20 le 20 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 20 lte 20 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 20 <= 20 -->pass<!-- ELSE -->fail<!-- ENDIF --> + + +<!-- IF 9 gt 1 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 9 > 1 -->pass<!-- ELSE -->fail<!-- ENDIF --> + + +<!-- IF 9 >= 1 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 9 gte 1 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 9 ge 1 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 9 >= 9 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 9 gte 9 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 9 ge 9 -->pass<!-- ELSE -->fail<!-- ENDIF --> + + +<!-- IF true && (10 > 4) -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF true and (10 > 4) -->pass<!-- ELSE -->fail<!-- ENDIF --> + + +<!-- IF false || true -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF false or true -->pass<!-- ELSE -->fail<!-- ENDIF --> + + +<!-- IF !false -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF not false -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF not not not false -->pass<!-- ELSE -->fail<!-- ENDIF --> + + +<!-- IF 6 % 4 == 2 -->pass<!-- ELSE -->fail<!-- ENDIF --> + +<!-- IF 24 mod 12 == 0 -->pass<!-- ELSE -->fail<!-- ENDIF --> diff --git a/tests/template/templates/if.html b/tests/template/templates/if.html new file mode 100644 index 0000000000..c502e52f51 --- /dev/null +++ b/tests/template/templates/if.html @@ -0,0 +1,11 @@ +<!-- IF S_VALUE --> +1 +<!-- ELSEIF S_OTHER_VALUE --> +2 +<!-- ELSE --> +0 +<!-- ENDIF --> + +<!-- IF (S_VALUE > S_OTHER_VALUE) --> +0 +<!-- ENDIF --> diff --git a/tests/template/templates/include.html b/tests/template/templates/include.html new file mode 100644 index 0000000000..730d713d65 --- /dev/null +++ b/tests/template/templates/include.html @@ -0,0 +1 @@ +<!-- INCLUDE variable.html --> diff --git a/tests/template/templates/includephp.html b/tests/template/templates/includephp.html new file mode 100644 index 0000000000..3e13fa33fa --- /dev/null +++ b/tests/template/templates/includephp.html @@ -0,0 +1 @@ +<!-- INCLUDEPHP ../templates/_dummy_include.php --> diff --git a/tests/template/templates/lang.html b/tests/template/templates/lang.html new file mode 100644 index 0000000000..2b5ea1cafe --- /dev/null +++ b/tests/template/templates/lang.html @@ -0,0 +1,3 @@ +{L_VARIABLE} + +{LA_VARIABLE} diff --git a/tests/template/templates/loop.html b/tests/template/templates/loop.html new file mode 100644 index 0000000000..de1a10004d --- /dev/null +++ b/tests/template/templates/loop.html @@ -0,0 +1,21 @@ +<!-- BEGIN loop --> +loop +<!-- BEGINELSE --> +noloop +<!-- END loop --> + +<!-- IF .loop --> +loop +<!-- ELSE --> +noloop +<!-- ENDIF --> + +<!-- IF .loop == 2 --> +loop +<!-- ENDIF --> + +<!-- BEGIN loop --> +<!-- BEGIN !block --> +loop#{loop.S_ROW_COUNT}-block#{block.S_ROW_COUNT} +<!-- END !block --> +<!-- END loop --> diff --git a/tests/template/templates/loop_advanced.html b/tests/template/templates/loop_advanced.html new file mode 100644 index 0000000000..c75fe55f03 --- /dev/null +++ b/tests/template/templates/loop_advanced.html @@ -0,0 +1,19 @@ +<!-- BEGIN loop -->{loop.S_FIRST_ROW}{loop.S_ROW_COUNT}{loop.S_LAST_ROW}<!-- END loop --> +x +<!-- BEGIN loop(0) -->{loop.S_FIRST_ROW}{loop.S_ROW_COUNT}{loop.S_LAST_ROW}<!-- END loop --> +x +<!-- BEGIN loop(0,-1) -->{loop.S_FIRST_ROW}{loop.S_ROW_COUNT}{loop.S_LAST_ROW}<!-- END loop --> +x +<!-- BEGIN loop(1) -->{loop.S_FIRST_ROW}{loop.S_ROW_COUNT}{loop.S_LAST_ROW}<!-- END loop --> +x +<!-- BEGIN loop(1,1) -->{loop.S_FIRST_ROW}{loop.S_ROW_COUNT}{loop.S_LAST_ROW}<!-- END loop --> +x +<!-- BEGIN loop(0,1) -->{loop.S_FIRST_ROW}{loop.S_ROW_COUNT}{loop.S_LAST_ROW}<!-- END loop --> +x +<!-- BEGIN loop(2,4) -->{loop.S_FIRST_ROW}{loop.S_ROW_COUNT}{loop.S_LAST_ROW}<!-- END loop --> +x +<!-- BEGIN loop(0,-7) -->{loop.S_FIRST_ROW}{loop.S_ROW_COUNT}{loop.S_LAST_ROW}<!-- END loop --> +x +<!-- BEGIN loop(-2,6) -->{loop.S_FIRST_ROW}{loop.S_ROW_COUNT}{loop.S_LAST_ROW}<!-- END loop --> +x +<!-- BEGIN loop(-2,-1) -->{loop.S_FIRST_ROW}{loop.S_ROW_COUNT}{loop.S_LAST_ROW}<!-- END loop --> diff --git a/tests/template/templates/loop_nested.html b/tests/template/templates/loop_nested.html new file mode 100644 index 0000000000..571df97b4c --- /dev/null +++ b/tests/template/templates/loop_nested.html @@ -0,0 +1,8 @@ +<!-- BEGIN outer --> +	{outer.S_BLOCK_NAME} - {outer.S_ROW_NUM}/{outer.S_NUM_ROWS}<!-- IF outer.VARIABLE --> - {outer.VARIABLE}<!-- ENDIF --> + +	<!-- BEGIN middle --> +		{middle.S_BLOCK_NAME} - {middle.S_ROW_NUM}/{middle.S_NUM_ROWS}<!-- IF middle.VARIABLE --> - {middle.VARIABLE}<!-- ENDIF --> + +	<!-- END middle --> +<!-- END outer --> diff --git a/tests/template/templates/loop_vars.html b/tests/template/templates/loop_vars.html new file mode 100644 index 0000000000..4f02fd2e6c --- /dev/null +++ b/tests/template/templates/loop_vars.html @@ -0,0 +1,21 @@ +<!-- BEGIN loop --> +<!-- IF loop.S_FIRST_ROW -->first<!-- ENDIF --> + +{loop.S_ROW_COUNT} + +{loop.VARIABLE} + +<!-- IF loop.VARIABLE -->set<!-- ENDIF --> + +<!-- IF loop.S_LAST_ROW --> +last +<!-- ENDIF --> +<!-- BEGIN inner --> + +{inner.S_ROW_COUNT} + +<!-- IF inner.S_LAST_ROW and inner.S_ROW_COUNT and inner.S_NUM_ROWS -->last inner<!-- ENDIF --> + +<!-- END inner --> +<!-- END loop --> +<!-- IF .loop.inner -->inner loop<!-- ENDIF --> diff --git a/tests/template/templates/php.html b/tests/template/templates/php.html new file mode 100644 index 0000000000..07a260cdb3 --- /dev/null +++ b/tests/template/templates/php.html @@ -0,0 +1 @@ +<!-- PHP -->echo "test";<!-- ENDPHP --> diff --git a/tests/template/templates/variable.html b/tests/template/templates/variable.html new file mode 100644 index 0000000000..f68f91597c --- /dev/null +++ b/tests/template/templates/variable.html @@ -0,0 +1 @@ +{VARIABLE} diff --git a/tests/test_framework/framework.php b/tests/test_framework/framework.php new file mode 100644 index 0000000000..5913d20ca0 --- /dev/null +++ b/tests/test_framework/framework.php @@ -0,0 +1,36 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +define('IN_PHPBB', true); +$phpbb_root_path = '../phpBB/'; +$phpEx = 'php'; +$table_prefix = ''; + +// If we are on PHP >= 6.0.0 we do not need some code +if (version_compare(PHP_VERSION, '6.0.0-dev', '>=')) +{ +	define('STRIP', false); +} +else +{ +	@set_magic_quotes_runtime(0); +	define('STRIP', (get_magic_quotes_gpc()) ? true : false); +} + +require_once $phpbb_root_path . 'includes/constants.php'; + +// require at least PHPUnit 3.3.0 +require_once 'PHPUnit/Runner/Version.php'; +if (version_compare(PHPUnit_Runner_Version::id(), '3.3.0', '<')) +{ +	trigger_error('PHPUnit >= 3.3.0 required'); +} + +require_once 'PHPUnit/Framework.php'; +require_once 'test_framework/phpbb_test_case.php'; diff --git a/tests/test_framework/phpbb_test_case.php b/tests/test_framework/phpbb_test_case.php new file mode 100644 index 0000000000..3cf2a9d442 --- /dev/null +++ b/tests/test_framework/phpbb_test_case.php @@ -0,0 +1,37 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +class phpbb_test_case extends PHPUnit_Framework_TestCase +{ +	protected $expectedTriggerError = false; + +	public function setExpectedTriggerError($errno, $message = '') +	{ +		$exceptionName = ''; +		switch ($errno) +		{ +			case E_NOTICE: +			case E_STRICT: +				PHPUnit_Framework_Error_Notice::$enabled = true; +				$exceptionName = 'PHPUnit_Framework_Error_Notice'; +			break; + +			case E_WARNING: +				PHPUnit_Framework_Error_Warning::$enabled = true; +				$exceptionName = 'PHPUnit_Framework_Error_Warning'; +			break; + +			default: +				$exceptionName = 'PHPUnit_Framework_Error'; +			break; +		} +		$this->expectedTriggerError = true; +		$this->setExpectedException($exceptionName, (string) $message, $errno); +	} +} diff --git a/tests/text_processing/all_tests.php b/tests/text_processing/all_tests.php new file mode 100644 index 0000000000..5e759c72ee --- /dev/null +++ b/tests/text_processing/all_tests.php @@ -0,0 +1,41 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +if (!defined('PHPUnit_MAIN_METHOD')) +{ +	define('PHPUnit_MAIN_METHOD', 'phpbb_text_processing_all_tests::main'); +} + +require_once 'test_framework/framework.php'; +require_once 'PHPUnit/TextUI/TestRunner.php'; + +require_once 'text_processing/make_clickable.php'; + +class phpbb_text_processing_all_tests +{ +	public static function main() +	{ +		PHPUnit_TextUI_TestRunner::run(self::suite()); +	} + +	public static function suite() +	{ +		$suite = new PHPUnit_Framework_TestSuite('phpBB Text Processing Tools'); + +		$suite->addTestSuite('phpbb_text_processing_make_clickable_test'); + +		return $suite; +	} +} + +if (PHPUnit_MAIN_METHOD == 'phpbb_text_processing_all_tests::main') +{ +	phpbb_text_processing_all_tests::main(); +} + diff --git a/tests/text_processing/make_clickable.php b/tests/text_processing/make_clickable.php new file mode 100644 index 0000000000..a667dd705e --- /dev/null +++ b/tests/text_processing/make_clickable.php @@ -0,0 +1,106 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once 'test_framework/framework.php'; + +require_once '../phpBB/includes/functions.php'; +require_once '../phpBB/includes/functions_content.php'; + +class phpbb_text_processing_make_clickable_test extends phpbb_test_case +{ +	public static function make_clickable_data() +	{ +		// value => whether it should work +		$prefix_texts = array( +			'' => true, +			"np \n" => true, +			'bp text ' => true, +			'cp text>' => true, +			'ep text.' => array('w' => false), // doesn't work for www. type urls, but for everything else +		); +		$suffix_texts = array( +			'' => true, +			"\n ns" => true, +			' bs text.' => true, +			'>cs text' => true, +			'"ds text' => true, +			'. es text.' => true, +			', fs text.' => true, +		); + +		$urls = array( +			'http://example.com' => array('tag' => 'm', 'url' => false, 'text' => false), // false means same as key +			'http://example.com/' => array('tag' => 'm', 'url' => false, 'text' => false), +			'http://example.com/path?query=abc' => array('tag' => 'm', 'url' => false, 'text' => false), +			'http://example.com/1' => array('tag' => 'm', 'url' => false, 'text' => false), +			'http://example.com/some/very/long/path/with/over/55/characters?and=a&long=query&too=1' => array('tag' => 'm', 'url' => false, 'text' => 'http://example.com/some/very/long/path/ ... uery&too=1'), +			'http://localhost' => array('tag' => 'm', 'url' => false, 'text' => false), +			'http://localhost/#abc' => array('tag' => 'm', 'url' => false, 'text' => false), + +			'www.example.com/path/' => array('tag' => 'w', 'url' => 'http://www.example.com/path/', 'text' => false), +			'randomwww.example.com/path/' => false, + +			'http://thisdomain.org' => array('tag' => 'm', 'url' => false, 'text' => false), +			'http://thisdomain.org/' => array('tag' => 'm', 'url' => false, 'text' => false), +			'http://thisdomain.org/1' => array('tag' => 'l', 'url' => false, 'text' => '1'), +			'http://thisdomain.org/path/some?query=abc#test' => array('tag' => 'l', 'url' => false, 'text' => 'path/some?query=abc#test'), + +			'javascript:www.example.com/' => false, +		); + +		$test_data = array(); + +		// run the test for each combination +		foreach ($prefix_texts as $prefix => $prefix_success) +		{ +			foreach ($suffix_texts as $suffix => $suffix_success) +			{ +				foreach ($urls as $url => $url_type) +				{ +					$input = $prefix . $url . $suffix; +					// no valid url => no change +					$output = $input; + +					if ( +						($prefix_success && $suffix_success && is_array($url_type)) && +						// handle except syntax for prefix/suffix +						(!is_array($prefix_success) || !isset($prefix_success[$url_type['tag']]) || $prefix_success[$url_type['tag']] == true) && +						(!is_array($suffix_success) || !isset($suffix_success[$url_type['tag']]) || $suffix_success[$url_type['tag']] == true) +					) +					{ +						// false means it's the same as the url, less typing +						$url_type['url'] = ($url_type['url']) ? $url_type['url'] : $url; +						$url_type['text'] = ($url_type['text']) ? $url_type['text'] : $url; + +						$class = ($url_type['tag'] === 'l') ? 'postlink-local' : 'postlink'; + +						// replace the url with the desired output format +						$output = $prefix . '<!-- ' . $url_type['tag'] . ' --><a class="' . $class . '" href="' . $url_type['url'] . '">' . $url_type['text'] . '</a><!-- ' . $url_type['tag'] . ' -->' . $suffix; +					} +					$test_data[] = array($input, $output); +				} +			} +		} + +		return $test_data; +	} + +	/** +	* @dataProvider make_clickable_data +	*/ +	public function test_make_clickable($input, $expected) +	{ +		$result = make_clickable($input, 'http://thisdomain.org'); + +		$label = 'Making text clickable: ' . $input; +		$this->assertEquals($expected, $result, $label); +	} + +} + diff --git a/tests/utf/all_tests.php b/tests/utf/all_tests.php new file mode 100644 index 0000000000..0d5d44d695 --- /dev/null +++ b/tests/utf/all_tests.php @@ -0,0 +1,43 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +if (!defined('PHPUnit_MAIN_METHOD')) +{ +	define('PHPUnit_MAIN_METHOD', 'phpbb_utf_all_tests::main'); +} + +require_once 'test_framework/framework.php'; +require_once 'PHPUnit/TextUI/TestRunner.php'; + +require_once 'utf/utf8_wordwrap_test.php'; +require_once 'utf/utf8_clean_string_test.php'; + +class phpbb_utf_all_tests +{ +	public static function main() +	{ +		PHPUnit_TextUI_TestRunner::run(self::suite()); +	} + +	public static function suite() +	{ +		$suite = new PHPUnit_Framework_TestSuite('phpBB Unicode Transformation Format'); + +		$suite->addTestSuite('phpbb_utf_utf8_wordwrap_test'); +		$suite->addTestSuite('phpbb_utf_utf8_clean_string_test'); + +		return $suite; +	} +} + +if (PHPUnit_MAIN_METHOD == 'phpbb_utf_all_tests::main') +{ +	phpbb_utf_all_tests::main(); +} + diff --git a/tests/utf/utf8_clean_string_test.php b/tests/utf/utf8_clean_string_test.php new file mode 100644 index 0000000000..870ad76fc4 --- /dev/null +++ b/tests/utf/utf8_clean_string_test.php @@ -0,0 +1,32 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once 'test_framework/framework.php'; +require_once '../phpBB/includes/utf/utf_tools.php'; + +class phpbb_utf_utf8_clean_string_test extends phpbb_test_case +{ +	public static function cleanable_strings() +	{ +		return array( +			array('MiXed CaSe', 'mixed case', 'Checking case folding'), +			array('  many   spaces   ', 'many spaces', 'Checking whitespace reduction'), +			array("we\xC2\xA1rd\xE1\x9A\x80ch\xCE\xB1r\xC2\xADacters", 'weird characters', 'Checking confusables replacement'), +		); +	} + +	/** +	* @dataProvider cleanable_strings +	*/ +	public function test_utf8_clean_string($input, $output, $label) +	{ +		$this->assertEquals($output, utf8_clean_string($input), $label); +	} +} + diff --git a/tests/utf/utf8_wordwrap_test.php b/tests/utf/utf8_wordwrap_test.php new file mode 100644 index 0000000000..ef1165a897 --- /dev/null +++ b/tests/utf/utf8_wordwrap_test.php @@ -0,0 +1,84 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2008 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +require_once 'test_framework/framework.php'; +require_once '../phpBB/includes/utf/utf_tools.php'; + +class phpbb_utf_utf8_wordwrap_test extends phpbb_test_case +{ +	public function test_utf8_wordwrap_ascii() +	{ +		// if the input is all ascii it should work exactly like php's wordwrap + +		$text = 'The quick brown fox jumped over the lazy dog.'; + +		$php_wordwrap = wordwrap($text, 20); +		$phpbb_utf8_wordwrap = utf8_wordwrap($text, 20); +		$this->assertEquals($php_wordwrap, $phpbb_utf8_wordwrap, "Checking ASCII standard behaviour with length 20"); + +		$php_wordwrap = wordwrap($text, 30, "<br />\n"); +		$phpbb_utf8_wordwrap = utf8_wordwrap($text, 30, "<br />\n"); +		$this->assertEquals($php_wordwrap, $phpbb_utf8_wordwrap, "Checking ASCII special break string with length 30"); + +		$text = 'A very long woooooooooooord.'; + +		$php_wordwrap = wordwrap($text, 8, "\n"); +		$phpbb_utf8_wordwrap = utf8_wordwrap($text, 8, "\n"); +		$this->assertEquals($php_wordwrap, $phpbb_utf8_wordwrap, 'Checking ASCII not cutting long words'); + +		$php_wordwrap = wordwrap($text, 8, "\n", true); +		$phpbb_utf8_wordwrap = utf8_wordwrap($text, 8, "\n", true); +		$this->assertEquals($php_wordwrap, $phpbb_utf8_wordwrap, 'Checking ASCII cutting long words'); +	} + +	/** +	* Helper function that generates meaningless greek text +	*/ +	private function turn_into_greek($string) +	{ +		$greek_chars = array("\xCE\x90", "\xCE\x91", "\xCE\x92", "\xCE\x93", "\xCE\x94", "\xCE\x95", "\xCE\x96", "\xCE\x97", "\xCE\x98", "\xCE\x99"); + +		$greek = ''; +		for ($i = 0, $n = strlen($string); $i < $n; $i++) +		{ +			// replace each number with the character from the array +			if (ctype_digit($string[$i])) +			{ +				$greek .= $greek_chars[(int) $string[$i]]; +			} +			else +			{ +				$greek .= $string[$i]; +			} +		} + +		return $greek; +	} + +	public function test_utf8_wordwrap_utf8() +	{ +		$text = "0123456 0123 012345 01234"; +		$greek = $this->turn_into_greek($text); + +		$expected = $this->turn_into_greek(wordwrap($text, 10)); +		$phpbb_utf8_wordwrap = utf8_wordwrap($greek, 10); +		$this->assertEquals($expected, $phpbb_utf8_wordwrap, 'Checking UTF-8 standard behaviour with length 10'); +	} + +	public function test_utf8_wordwrap_utf8_cut() +	{ +		$text = "0123456 0123 012345 01234"; +		$greek = $this->turn_into_greek($text); + +		$expected = $this->turn_into_greek(wordwrap($text, 5, "\n", true)); +		$phpbb_utf8_wordwrap = utf8_wordwrap($greek, 5, "\n", true); +		$this->assertEquals($expected, $phpbb_utf8_wordwrap, 'Checking UTF-8 cutting long words'); +	} +} + | 
