Added some general unit tests (without any engine-specific test nor mapping)
authorXavier Perseguers <typo3@perseguers.ch>
Tue, 3 Nov 2009 19:12:18 +0000 (19:12 +0000)
committerXavier Perseguers <typo3@perseguers.ch>
Tue, 3 Nov 2009 19:12:18 +0000 (19:12 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Extensions/dbal/trunk@26136 735d13b6-9817-0410-8766-e36946ffe9aa

typo3/sysext/dbal/ChangeLog
typo3/sysext/dbal/tests/BaseTestCase.php [new file with mode: 0644]
typo3/sysext/dbal/tests/sqlparser_general_testcase.php [new file with mode: 0644]

index a8c365f..810edb3 100644 (file)
@@ -1,5 +1,6 @@
 2009-11-03  Xavier Perseguers  <typo3@perseguers.ch>
 
+       * Added some general unit tests (without any engine-specific test nor mapping)
        * Cleanup #12440: Copy DBAL-only SQL parser methods from t3lib_sqlparser to ux_t3lib_sqlparser
        * Fixed bug #12231: New caching framework (4.3-dev) does not work with DBAL
 
diff --git a/typo3/sysext/dbal/tests/BaseTestCase.php b/typo3/sysext/dbal/tests/BaseTestCase.php
new file mode 100644 (file)
index 0000000..8246f4c
--- /dev/null
@@ -0,0 +1,88 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Robert Lemke <robert@typo3.org>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * The mother of all test cases.
+ *
+ * Subclass this base class if you want to take advantage of the framework
+ * capabilities.
+ * 
+ * $Id$
+ * 
+ * @author Robert Lemke <robert@typo3.org>
+ * 
+ * This method is backported from FLOW3's BaseTestCase class.
+ * @link https://svn.typo3.org/FLOW3/Packages/Testing/trunk/Classes/BaseTestCase.php
+ *
+ * @package TYPO3
+ * @subpackage dbal
+ */
+abstract class BaseTestCase extends tx_phpunit_testcase {
+
+       /**
+        * Creates a proxy class of the specified class which allows
+        * for calling even protected methods and access of protected properties.
+        *
+        * @param protected $className Full qualified name of the original class
+        * @return string Full qualified name of the built class
+        * @api
+        */
+       protected function buildAccessibleProxy($className) {
+               $accessibleClassName = uniqid('AccessibleTestProxy');
+               $class = new ReflectionClass($className);
+               $abstractModifier = $class->isAbstract() ? 'abstract ' : '';
+               eval('
+                       ' . $abstractModifier . 'class ' . $accessibleClassName . ' extends ' . $className . ' {
+                               public function _call($methodName) {
+                                       return call_user_func_array(array($this, $methodName), array_slice(func_get_args(), 1));
+                               }
+                               public function _callRef($methodName, &$arg1 = NULL, &$arg2 = NULL, &$arg3 = NULL, &$arg4 = NULL, &$arg5 = NULL, &$arg6 = NULL, &$arg7 = NULL, &$arg8 = NULL, &$arg9 = NULL) {
+                                       switch (func_num_args()) {
+                                               case 0 : return $this->$methodName();
+                                               case 1 : return $this->$methodName($arg1);
+                                               case 2 : return $this->$methodName($arg1, $arg2);
+                                               case 3 : return $this->$methodName($arg1, $arg2, $arg3);
+                                               case 4 : return $this->$methodName($arg1, $arg2, $arg3, $arg4);
+                                               case 5 : return $this->$methodName($arg1, $arg2, $arg3, $arg4, $arg5);
+                                               case 6 : return $this->$methodName($arg1, $arg2, $arg3, $arg4, $arg5, $arg6);
+                                               case 7 : return $this->$methodName($arg1, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7);
+                                               case 8 : return $this->$methodName($arg1, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7, $arg8);
+                                               case 9 : return $this->$methodName($arg1, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7, $arg8, $arg9);
+                                       }
+                               }
+                               public function _set($propertyName, $value) {
+                                       $this->$propertyName = $value;
+                               }
+                               public function _setRef($propertyName, &$value) {
+                                       $this->$propertyName = $value;
+                               }
+                               public function _get($propertyName) {
+                                       return $this->$propertyName;
+                               }
+                       }
+               ');
+               return $accessibleClassName;
+       }
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/dbal/tests/sqlparser_general_testcase.php b/typo3/sysext/dbal/tests/sqlparser_general_testcase.php
new file mode 100644 (file)
index 0000000..30b0435
--- /dev/null
@@ -0,0 +1,218 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Xavier Perseguers <typo3@perseguers.ch>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+
+require_once('BaseTestCase.php');
+
+/**
+ * Testcase for class ux_t3lib_sqlparser
+ * 
+ * $Id$
+ *
+ * @author Xavier Perseguers <typo3@perseguers.ch>
+ *
+ * @package TYPO3
+ * @subpackage dbal
+ */
+class sqlparser_general_testcase extends BaseTestCase {
+
+       /**
+        * @var t3lib_sqlparser (extended to make protected methods public)
+        */
+       protected $fixture;
+
+       public function setUp() {
+               $className = self::buildAccessibleProxy('ux_t3lib_sqlparser');
+               $this->fixture = new $className;
+       }
+
+       public function tearDown() {
+               unset($this->fixture);
+       }
+
+       /**
+        * Cleans a SQL query.
+        *  
+        * @param mixed $sql
+        * @return mixed (string or array)
+        */
+       private function cleanSql($sql) {
+               if (!is_string($sql)) {
+                       return $sql;
+               }
+
+               $sql = str_replace("\n", ' ', $sql);
+               $sql = preg_replace('/\s+/', ' ', $sql);
+               return $sql;
+       }
+
+       /**
+        * @test
+        */
+       public function canExtractPartsOfAQuery() {
+               $parseString = "SELECT   *\nFROM pages WHERE pid IN (1,2,3,4)";
+               $regex = '^SELECT[[:space:]]+(.*)[[:space:]]+';
+               $trimAll = TRUE;
+               $fields = $this->fixture->_callRef('nextPart', $parseString, $regex, $trimAll);
+
+               $this->assertEquals(
+                       '*',
+                       $fields
+               );
+               $this->assertEquals(
+                       'FROM pages WHERE pid IN (1,2,3,4)',
+                       $parseString
+               );
+
+               $regex = '^FROM ([^)]+) WHERE';
+               $table = $this->fixture->_callRef('nextPart', $parseString, $regex);
+
+               $this->assertEquals(
+                       'pages',
+                       $table
+               );
+               $this->assertEquals(
+                       'pages WHERE pid IN (1,2,3,4)',
+                       $parseString
+               );
+       }
+
+       /**
+        * @test
+        */
+       public function canGetIntegerValue() {
+               $parseString = '1024';
+               $value = $this->fixture->_callRef('getValue', $parseString);
+               $expected = array(1024);
+
+               $this->assertEquals($expected, $value);
+       }
+
+       /**
+        * @test
+        */
+       public function canGetStringValue() {
+               $parseString = '"some owner\\\' string"';
+               $value = $this->fixture->_callRef('getValue', $parseString);
+               $expected = array('some owner\' string', '"');
+
+               $this->assertEquals($expected, $value);
+       }
+
+       /**
+        * @test
+        */
+       public function canGetListOfValues() {
+               $parseString = '( 1,   2, 3  ,4)';
+               $operator = 'IN';
+               $values = $this->fixture->_callRef('getValue', $parseString, $operator);
+               $expected = array(
+                       array(1),
+                       array(2),
+                       array(3),
+                       array(4)
+               );
+
+               $this->assertEquals($expected, $values);
+       }
+
+       /**
+        * @test
+        */
+       public function parseFromTablesWithInnerJoinReturnsArray() {
+               $parseString = 'be_users INNER JOIN pages ON pages.cruser_id = be_users.uid';
+               $tables = $this->fixture->parseFromTables($parseString);
+
+               $this->assertTrue(is_array($tables), $tables);
+               $this->assertTrue(empty($parseString), 'parseString is not empty');
+       }
+
+       /**
+        * @test
+        */
+       public function parseFromTablesWithLeftOuterJoinReturnsArray() {
+               $parseString = 'be_users LEFT OUTER JOIN pages ON be_users.uid = pages.cruser_id';
+               $tables = $this->fixture->parseFromTables($parseString);
+
+               $this->assertTrue(is_array($tables), $tables);
+               $this->assertTrue(empty($parseString), 'parseString is not empty');
+       }
+
+       /**
+        * @test
+        */
+       public function parseFromTablesWithMultipleJoinsReturnsArray() {
+               $parseString = 'be_users LEFT OUTER JOIN pages ON be_users.uid = pages.cruser_id INNER JOIN cache_pages cp ON cp.page_id = pages.uid';
+               $tables = $this->fixture->parseFromTables($parseString);
+
+               $this->assertTrue(is_array($tables), $tables);
+               $this->assertTrue(empty($parseString), 'parseString is not empty');
+       }
+
+       /**
+        * @test
+        */
+       public function parseWhereClauseReturnsArray() {
+               $parseString = 'uid IN (1,2) AND (starttime < ' . time() . ' OR cruser_id + 10 < 20)';
+               $where = $this->fixture->parseWhereClause($parseString);
+
+               $this->assertTrue(is_array($where), $where);
+               $this->assertTrue(empty($parseString), 'parseString is not empty');
+       }
+
+       /**
+        * @test
+        */
+       public function canSelectAllFieldsFromPages() {
+               $sql = 'SELECT * FROM pages';
+               $expected = $sql;
+               $actual = $this->cleanSql($this->fixture->debug_testSQL($sql)); 
+
+               $this->assertEquals($expected, $actual);
+       }
+
+       /**
+        * @test
+        */
+       public function canUseInnerJoinInSelect() {
+               $sql = 'SELECT pages.uid, be_users.username FROM be_users INNER JOIN pages ON pages.cruser_id = be_users.uid';
+               $expected = 'SELECT pages.uid, be_users.username FROM be_users INNER JOIN pages ON pages.cruser_id=be_users.uid';
+               $actual = $this->cleanSql($this->fixture->debug_testSQL($sql)); 
+
+               $this->assertEquals($expected, $actual);
+       }
+
+       /**
+        * @test
+        */
+       public function canUseMultipleInnerJoinsInSelect() {
+               $sql = 'SELECT * FROM tt_news_cat INNER JOIN tt_news_cat_mm ON tt_news_cat.uid = tt_news_cat_mm.uid_foreign INNER JOIN tt_news ON tt_news.uid = tt_news_cat_mm.uid_local';
+               $expected = 'SELECT * FROM tt_news_cat INNER JOIN tt_news_cat_mm ON tt_news_cat.uid=tt_news_cat_mm.uid_foreign INNER JOIN tt_news ON tt_news.uid=tt_news_cat_mm.uid_local';
+               $actual = $this->cleanSql($this->fixture->debug_testSQL($sql)); 
+
+               $this->assertEquals($expected, $actual);
+       }
+
+}
+?>
\ No newline at end of file