QueryTestCase.php 13.7 KB
Newer Older
zYne's avatar
zYne committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
<?php
/*
 *  $Id$
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many individuals
 * and is licensed under the LGPL. For more information, see
 * <http://www.phpdoctrine.com>.
 */

/**
 * Doctrine_Search_Query_TestCase
 *
 * @package     Doctrine
 * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
 * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @category    Object Relational Mapping
 * @link        www.phpdoctrine.com
 * @since       1.0
 * @version     $Revision$
 */
class Doctrine_Search_Query_TestCase extends Doctrine_UnitTestCase
{
    public function prepareTables()
    {
        $this->tables = array('SearchTest', 'SearchTestIndex');
38

zYne's avatar
zYne committed
39 40 41 42 43 44 45
        parent::prepareTables();
    }
    public function prepareData()
    { }

    public function testInitData()
    {
46
        $e = new SearchTest();
zYne's avatar
zYne committed
47 48 49 50 51 52

        $e->title = 'Once there was an ORM framework';
        $e->content = 'There are many ORM frameworks, but nevertheless we decided to create one.';

        $e->save();

53
        $e = new SearchTest();
zYne's avatar
zYne committed
54 55 56 57 58 59

        $e->title = 'Doctrine development continues';
        $e->content = 'The development has been going well so far.';

        $e->save();
    }
zYne's avatar
zYne committed
60

zYne's avatar
zYne committed
61 62 63 64 65
    public function testParseClauseSupportsAndOperator()
    {
        $q = new Doctrine_Search_Query('SearchTestIndex');
        $ret = $q->parseClause('doctrine AND orm');

zYne's avatar
zYne committed
66 67
        $sql = 'search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?) '
             . 'AND search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?)';
68 69 70 71 72 73 74 75 76

        $this->assertEqual($ret, $sql);
    }

    public function testParseClauseSupportsMixingOfOperatorsAndParenthesis()
    {
        $q = new Doctrine_Search_Query('SearchTestIndex');
        $ret = $q->parseClause('((doctrine OR orm) AND dbal) OR database');

zYne's avatar
zYne committed
77
        $sql = '(search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ? OR keyword = ?) AND search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?)) OR keyword = ?';
zYne's avatar
zYne committed
78 79 80 81 82 83 84 85 86

        $this->assertEqual($ret, $sql);
    }

    public function testParseClauseSupportsMixingOfOperators3()
    {
        $q = new Doctrine_Search_Query('SearchTestIndex');
        $ret = $q->parseClause('doctrine OR orm AND dbal');

zYne's avatar
zYne committed
87
        $sql = 'keyword = ? OR search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?) AND search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?)';
88

zYne's avatar
zYne committed
89 90 91 92 93 94 95 96
        $this->assertEqual($ret, $sql);
    }

    public function testParseClauseSupportsMixingOfOperators()
    {
        $q = new Doctrine_Search_Query('SearchTestIndex');
        $ret = $q->parseClause('(doctrine OR orm) AND dbal');

zYne's avatar
zYne committed
97
        $sql = 'search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ? OR keyword = ?) AND search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?)';
98

zYne's avatar
zYne committed
99 100 101 102 103 104 105
        $this->assertEqual($ret, $sql);
    }

    public function testParseClauseSupportsMixingOfOperators2()
    {
        $q = new Doctrine_Search_Query('SearchTestIndex');
        $ret = $q->parseClause('(doctrine OR orm) dbal');
106

zYne's avatar
zYne committed
107
        $sql = 'search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ? OR keyword = ?) AND search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?)';
108 109 110 111 112 113 114 115 116

        $this->assertEqual($ret, $sql);
    }

    public function testParseClauseSupportsMixingOfOperatorsAndDeeplyNestedParenthesis()
    {
        $q = new Doctrine_Search_Query('SearchTestIndex');
        $ret = $q->parseClause('(((doctrine OR orm) AND dbal) OR database) AND rdbms');

zYne's avatar
zYne committed
117 118 119 120 121 122 123 124 125 126 127
        $sql = '((search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ? OR keyword = ?) AND search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?)) OR keyword = ?) AND search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?)';

        $this->assertEqual($ret, $sql);
    }

    public function testParseClauseSupportsMixingOfOperatorsAndParenthesis2()
    {
        $q = new Doctrine_Search_Query('SearchTestIndex');
        $ret = $q->parseClause('rdbms (dbal OR database)');

        $sql = 'search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?) AND search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ? OR keyword = ?)';
128

zYne's avatar
zYne committed
129 130
        $this->assertEqual($ret, $sql);
    }
zYne's avatar
zYne committed
131

zYne's avatar
zYne committed
132 133 134 135 136
    public function testParseClauseSupportsMixingOfOperatorsAndDeeplyNestedParenthesis2()
    {
        $q = new Doctrine_Search_Query('SearchTestIndex');
        $ret = $q->parseClause('rdbms (((doctrine OR orm) AND dbal) OR database)');

zYne's avatar
zYne committed
137
        $sql = 'search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?) AND ((search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ? OR keyword = ?) AND search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?)) OR keyword = ?)';
zYne's avatar
zYne committed
138

zYne's avatar
zYne committed
139 140
        $this->assertEqual($ret, $sql);
    }
zYne's avatar
zYne committed
141

zYne's avatar
zYne committed
142 143 144 145 146
    public function testParseClauseSupportsNegationOperator()
    {
        $q = new Doctrine_Search_Query('SearchTestIndex');
        $ret = $q->parseClause('rdbms -doctrine');

zYne's avatar
zYne committed
147 148
        $sql = 'search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?) AND '
             . 'search_test_id NOT IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?)';
zYne's avatar
zYne committed
149 150 151

        $this->assertEqual($ret, $sql);
    }
zYne's avatar
zYne committed
152

zYne's avatar
zYne committed
153 154 155 156 157
    public function testParseClauseOrOperator2()
    {
        $q = new Doctrine_Search_Query('SearchTestIndex');
        $ret = $q->parseClause('rdbms doctrine OR database');

zYne's avatar
zYne committed
158 159
        $sql = 'search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?) AND '
             . 'search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?) '
zYne's avatar
zYne committed
160 161 162 163
             . 'OR keyword = ?';

        $this->assertEqual($ret, $sql);
    }
zYne's avatar
zYne committed
164

zYne's avatar
zYne committed
165 166 167 168 169
    public function testParseClauseSupportsNegationOperatorWithOrOperator()
    {
        $q = new Doctrine_Search_Query('SearchTestIndex');
        $ret = $q->parseClause('rdbms -doctrine OR database');

zYne's avatar
zYne committed
170 171
        $sql = 'search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?) AND '
             . 'search_test_id NOT IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?) '
zYne's avatar
zYne committed
172 173 174 175
             . 'OR keyword = ?';

        $this->assertEqual($ret, $sql);
    }
zYne's avatar
zYne committed
176

zYne's avatar
zYne committed
177 178 179 180 181 182 183
    public function testSearchSupportsAndOperator()
    {
        $q = new Doctrine_Search_Query('SearchTestIndex');
        $q->search('doctrine AND orm');

        $sql = 'SELECT COUNT(keyword) AS relevance, search_test_id '
             . 'FROM search_test_index '
zYne's avatar
zYne committed
184 185
             . 'WHERE search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?) '
             . 'AND search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?) '
zYne's avatar
zYne committed
186 187 188 189
             . 'GROUP BY search_test_id ORDER BY relevance';

        $this->assertEqual($q->getSql(), $sql);
    }
zYne's avatar
zYne committed
190 191


zYne's avatar
zYne committed
192 193 194 195 196 197 198 199 200 201 202 203
    public function testSearchSupportsOrOperator()
    {
        $q = new Doctrine_Search_Query('SearchTestIndex');
        $q->search('doctrine OR orm');

        $sql = 'SELECT COUNT(keyword) AS relevance, search_test_id '
             . 'FROM search_test_index '
             . 'WHERE keyword = ? OR keyword = ? '
             . 'GROUP BY search_test_id ORDER BY relevance';

        $this->assertEqual($q->getSql(), $sql);
    }
zYne's avatar
zYne committed
204 205 206
    

    public function testQuerySupportsSingleWordSearch()
zYne's avatar
zYne committed
207 208
    {
        $q = new Doctrine_Search_Query('SearchTestIndex');
zYne's avatar
zYne committed
209
        $q->search('doctrine');
zYne's avatar
zYne committed
210 211

        $sql = 'SELECT COUNT(keyword) AS relevance, search_test_id '
zYne's avatar
zYne committed
212
             . 'FROM search_test_index WHERE keyword = ? GROUP BY search_test_id ORDER BY relevance';
zYne's avatar
zYne committed
213 214
        
        $this->assertEqual($q->getParams(), array('doctrine'));  
zYne's avatar
zYne committed
215 216
        $this->assertEqual($q->getSql(), $sql);
    }
zYne's avatar
zYne committed
217

zYne's avatar
zYne committed
218
    public function testSearchSupportsMixingOfOperators()
zYne's avatar
zYne committed
219
    {
zYne's avatar
zYne committed
220
        $q = new Doctrine_Search_Query('SearchTestIndex');
zYne's avatar
zYne committed
221
        $q->search('(doctrine OR orm) AND dbal');
zYne's avatar
zYne committed
222 223

        $sql = 'SELECT COUNT(keyword) AS relevance, search_test_id '
zYne's avatar
zYne committed
224
             . 'FROM search_test_index '
zYne's avatar
zYne committed
225 226
             . 'WHERE search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ? OR keyword = ?) '
             . 'AND search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?) '
zYne's avatar
zYne committed
227
             . 'GROUP BY search_test_id ORDER BY relevance';
zYne's avatar
zYne committed
228

zYne's avatar
zYne committed
229
        $this->assertEqual($q->getParams(), array('doctrine', 'orm', 'dbal'));
zYne's avatar
zYne committed
230 231 232 233 234 235 236
        $this->assertEqual($q->getSql(), $sql);
    }

    public function testSearchSupportsSingleTermWithQuotes()
    {
        $q = new Doctrine_Search_Query('SearchTestIndex');
        $q->search("'doctrine orm'");
zYne's avatar
zYne committed
237

zYne's avatar
zYne committed
238 239 240 241 242
        $sql = 'SELECT COUNT(keyword) AS relevance, search_test_id '
             . 'FROM search_test_index WHERE keyword = ? '
             . 'AND (position + 1) = (SELECT position FROM search_test_index WHERE keyword = ?) '
             . 'GROUP BY search_test_id ORDER BY relevance';

zYne's avatar
zYne committed
243
        $this->assertEqual($q->getParams(), array('doctrine', 'orm'));
zYne's avatar
zYne committed
244 245
        $this->assertEqual($q->getSql(), $sql);
    }
zYne's avatar
zYne committed
246

zYne's avatar
zYne committed
247 248 249 250
    public function testSearchSupportsSingleLongTermWithQuotes()
    {
        $q = new Doctrine_Search_Query('SearchTestIndex');
        $q->search("'doctrine orm dbal'");
zYne's avatar
zYne committed
251

zYne's avatar
zYne committed
252
        $sql = 'SELECT COUNT(keyword) AS relevance, search_test_id '
zYne's avatar
zYne committed
253 254 255 256 257
             . 'FROM search_test_index WHERE keyword = ? '
             . 'AND (position + 1) = (SELECT position FROM search_test_index WHERE keyword = ?) '
             . 'AND (position + 2) = (SELECT position FROM search_test_index WHERE keyword = ?) '
             . 'GROUP BY search_test_id ORDER BY relevance';

zYne's avatar
zYne committed
258
        $this->assertEqual($q->getParams(), array('doctrine', 'orm', 'dbal'));
zYne's avatar
zYne committed
259
        $this->assertEqual($q->getSql(), $sql);
zYne's avatar
zYne committed
260
    }
zYne's avatar
zYne committed
261

zYne's avatar
zYne committed
262
    public function testQuerySupportsMultiWordSearch()
zYne's avatar
zYne committed
263
    {
zYne's avatar
zYne committed
264 265
        $q = new Doctrine_Search_Query('SearchTestIndex');
        $q->search('doctrine orm');
zYne's avatar
zYne committed
266

zYne's avatar
zYne committed
267 268
        $sql = 'SELECT COUNT(keyword) AS relevance, search_test_id '
             . 'FROM search_test_index '
zYne's avatar
zYne committed
269 270
             . 'WHERE search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?) '
             . 'AND search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?) '
zYne's avatar
zYne committed
271
             . 'GROUP BY search_test_id ORDER BY relevance';
zYne's avatar
zYne committed
272

zYne's avatar
zYne committed
273
        $this->assertEqual($q->getSql(), $sql);
zYne's avatar
zYne committed
274
    }
zYne's avatar
zYne committed
275

zYne's avatar
zYne committed
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
    public function testQuerySupportsMultiWordSearchAndSingleLetterWildcards()
    {
        $q = new Doctrine_Search_Query('SearchTestIndex');
        $q->search('doct?ine orm');

        $sql = 'SELECT COUNT(keyword) AS relevance, search_test_id '
             . 'FROM search_test_index '
             . 'WHERE search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword LIKE ?) '
             . 'AND search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?) '
             . 'GROUP BY search_test_id ORDER BY relevance';

        $this->assertEqual($q->getParams(), array('doct?ine', 'orm'));
        $this->assertEqual($q->getSql(), $sql);
    }
    public function testQuerySupportsMultiWordSearchAndMultiLetterWildcards()
    {
        $q = new Doctrine_Search_Query('SearchTestIndex');
        $q->search('doc* orm');

        $sql = 'SELECT COUNT(keyword) AS relevance, search_test_id '
             . 'FROM search_test_index '
             . 'WHERE search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword LIKE ?) '
             . 'AND search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?) '
             . 'GROUP BY search_test_id ORDER BY relevance';

        $this->assertEqual($q->getParams(), array('doc%', 'orm'));
        $this->assertEqual($q->getSql(), $sql);
    }
zYne's avatar
zYne committed
304
    public function testSearchSupportsMultipleTermsWithQuotes()
zYne's avatar
zYne committed
305
    {
zYne's avatar
zYne committed
306
        $q = new Doctrine_Search_Query('SearchTestIndex');
zYne's avatar
zYne committed
307
        $q->search("doctrine 'orm database'");
zYne's avatar
zYne committed
308 309 310

        $sql = 'SELECT COUNT(keyword) AS relevance, search_test_id '
             . 'FROM search_test_index '
zYne's avatar
zYne committed
311 312 313
             . 'WHERE search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ?) '
             . 'AND search_test_id IN (SELECT search_test_id FROM search_test_index WHERE keyword = ? '
             . 'AND (position + 1) = (SELECT position FROM search_test_index WHERE keyword = ?)) '
zYne's avatar
zYne committed
314
             . 'GROUP BY search_test_id ORDER BY relevance';
zYne's avatar
zYne committed
315

zYne's avatar
zYne committed
316
        $this->assertEqual($q->getParams(), array('doctrine', 'orm', 'database'));
zYne's avatar
zYne committed
317 318
        $this->assertEqual($q->getSql(), $sql);
    }
zYne's avatar
zYne committed
319

zYne's avatar
zYne committed
320 321 322 323 324 325
    public function testSearchReturnsFalseForEmptyStrings()
    {
        $q = new Doctrine_Search_Query('SearchTestIndex');
        $result = $q->search(' ');

        $this->assertFalse($result);
zYne's avatar
zYne committed
326
    }
zYne's avatar
zYne committed
327

zYne's avatar
zYne committed
328
}