blob: 3c079070e0df3b71406d6b731b944fac76658388 [file] [log] [blame]
<?php
/**
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
* @copyright Copyright (C) 2005-2010 eZ Systems AS. All rights reserved.
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @version //autogentag//
* @filesource
* @package Search
* @subpackage Tests
*/
require_once 'testfiles/test-classes.php';
/**
* Test the query tokenizer and builder
*
* @package Search
* @subpackage Tests
*/
class ezcSearchBuildSearchQueryTest extends ezcTestCase
{
public static function suite()
{
return new PHPUnit_Framework_TestSuite( "ezcSearchBuildSearchQueryTest" );
}
public static function testOneWord()
{
$result = BuildQueryQuery::tokenize( 'word' );
$expected = array( new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'word' ) );
self::assertEquals( $expected, $result );
}
public static function testMoreWords()
{
$result = BuildQueryQuery::tokenize( "I'll be back" );
$expected = array(
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, "I'll" ),
new ezcSearchQueryToken( ezcSearchQueryToken::SPACE, " " ),
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'be' ),
new ezcSearchQueryToken( ezcSearchQueryToken::SPACE, " " ),
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'back' ),
);
self::assertEquals( $expected, $result );
}
public static function testAnd1()
{
$result = BuildQueryQuery::tokenize( "me AND you" );
$expected = array(
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'me' ),
new ezcSearchQueryToken( ezcSearchQueryToken::SPACE, " " ),
new ezcSearchQueryToken( ezcSearchQueryToken::LOGICAL_AND, 'AND' ),
new ezcSearchQueryToken( ezcSearchQueryToken::SPACE, " " ),
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'you' ),
);
self::assertEquals( $expected, $result );
}
public static function testAnd2()
{
$result = BuildQueryQuery::tokenize( "me and you" );
$expected = array(
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'me' ),
new ezcSearchQueryToken( ezcSearchQueryToken::SPACE, " " ),
new ezcSearchQueryToken( ezcSearchQueryToken::LOGICAL_AND, 'and' ),
new ezcSearchQueryToken( ezcSearchQueryToken::SPACE, " " ),
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'you' ),
);
self::assertEquals( $expected, $result );
}
public static function testOr1()
{
$result = BuildQueryQuery::tokenize( "me OR you" );
$expected = array(
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'me' ),
new ezcSearchQueryToken( ezcSearchQueryToken::SPACE, " " ),
new ezcSearchQueryToken( ezcSearchQueryToken::LOGICAL_OR, 'OR' ),
new ezcSearchQueryToken( ezcSearchQueryToken::SPACE, " " ),
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'you' ),
);
self::assertEquals( $expected, $result );
}
public static function testOr2()
{
$result = BuildQueryQuery::tokenize( "me or you" );
$expected = array(
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'me' ),
new ezcSearchQueryToken( ezcSearchQueryToken::SPACE, " " ),
new ezcSearchQueryToken( ezcSearchQueryToken::LOGICAL_OR, 'or' ),
new ezcSearchQueryToken( ezcSearchQueryToken::SPACE, " " ),
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'you' ),
);
self::assertEquals( $expected, $result );
}
public static function testInternalAnd()
{
$result = BuildQueryQuery::tokenize( "meANDyou" );
$expected = array(
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'meANDyou' ),
);
self::assertEquals( $expected, $result );
}
public static function testInternalOr()
{
$result = BuildQueryQuery::tokenize( "meORyou" );
$expected = array(
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'meORyou' ),
);
self::assertEquals( $expected, $result );
}
public static function testWordsInQuotes()
{
$result = BuildQueryQuery::tokenize( '"The world is not enough"' );
$expected = array(
new ezcSearchQueryToken( ezcSearchQueryToken::QUOTE, '"' ),
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'The' ),
new ezcSearchQueryToken( ezcSearchQueryToken::SPACE, " " ),
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'world' ),
new ezcSearchQueryToken( ezcSearchQueryToken::SPACE, " " ),
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'is' ),
new ezcSearchQueryToken( ezcSearchQueryToken::SPACE, " " ),
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'not' ),
new ezcSearchQueryToken( ezcSearchQueryToken::SPACE, " " ),
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'enough' ),
new ezcSearchQueryToken( ezcSearchQueryToken::QUOTE, '"' ),
);
self::assertEquals( $expected, $result );
}
public static function testPlusMinus()
{
$result = BuildQueryQuery::tokenize( '+plus -minus' );
$expected = array(
new ezcSearchQueryToken( ezcSearchQueryToken::PLUS, '+' ),
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'plus' ),
new ezcSearchQueryToken( ezcSearchQueryToken::SPACE, " " ),
new ezcSearchQueryToken( ezcSearchQueryToken::MINUS, '-' ),
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'minus' ),
);
self::assertEquals( $expected, $result );
}
public static function testBraces()
{
$result = BuildQueryQuery::tokenize( 'a OR (b AND c)' );
$expected = array(
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'a' ),
new ezcSearchQueryToken( ezcSearchQueryToken::SPACE, " " ),
new ezcSearchQueryToken( ezcSearchQueryToken::LOGICAL_OR, 'OR' ),
new ezcSearchQueryToken( ezcSearchQueryToken::SPACE, " " ),
new ezcSearchQueryToken( ezcSearchQueryToken::BRACE_OPEN, '(' ),
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'b' ),
new ezcSearchQueryToken( ezcSearchQueryToken::SPACE, " " ),
new ezcSearchQueryToken( ezcSearchQueryToken::LOGICAL_AND, 'AND' ),
new ezcSearchQueryToken( ezcSearchQueryToken::SPACE, " " ),
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'c' ),
new ezcSearchQueryToken( ezcSearchQueryToken::BRACE_CLOSE, ')' ),
);
self::assertEquals( $expected, $result );
}
public static function testColon()
{
$result = BuildQueryQuery::tokenize( 'site:ezcomponents.org' );
$expected = array(
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'site' ),
new ezcSearchQueryToken( ezcSearchQueryToken::COLON, ':' ),
new ezcSearchQueryToken( ezcSearchQueryToken::STRING, 'ezcomponents.org' ),
);
self::assertEquals( $expected, $result );
}
public static function testAddOneWordOneField()
{
$q = self::setupQuery( 'DefinitionOneField' );
$qb = new ezcSearchQueryBuilder();
$qb->parseSearchQuery( $q, 'goldfinger', array( 'fieldOne' ) );
self::assertSame( array( "fieldOne_t:goldfinger" ), $q->whereClauses );
}
public static function testAddOneWordTwoField()
{
$q = self::setupQuery( 'DefinitionTwoFields' );
$qb = new ezcSearchQueryBuilder();
$qb->parseSearchQuery( $q, 'thunderball', array( 'fieldOne', 'fieldTwo' ) );
self::assertSame( array( "( fieldOne_t:thunderball OR fieldTwo_t:thunderball )" ), $q->whereClauses );
}
public static function testAddMoreWordsOneField()
{
$q = self::setupQuery( 'DefinitionOneField' );
$qb = new ezcSearchQueryBuilder();
$qb->parseSearchQuery( $q, 'from russia with love', array( 'fieldOne' ) );
self::assertSame( array( "fieldOne_t:from", "fieldOne_t:russia", "fieldOne_t:with", "fieldOne_t:love" ), $q->whereClauses );
}
public static function testAddMoreWordsTwoField()
{
$q = self::setupQuery( 'DefinitionTwoFields' );
$qb = new ezcSearchQueryBuilder();
$qb->parseSearchQuery( $q, 'you only live twice', array( 'fieldOne', 'fieldTwo' ) );
$expected = array(
"( fieldOne_t:you OR fieldTwo_t:you )",
"( fieldOne_t:only OR fieldTwo_t:only )",
"( fieldOne_t:live OR fieldTwo_t:live )",
"( fieldOne_t:twice OR fieldTwo_t:twice )",
);
self::assertSame( $expected, $q->whereClauses );
}
public static function testAddOnePhraseOneField()
{
$q = self::setupQuery( 'DefinitionOneField' );
$qb = new ezcSearchQueryBuilder();
$qb->parseSearchQuery( $q, '"diamonds are forever"', array( 'fieldOne' ) );
self::assertSame( array( 'fieldOne_t:"diamonds are forever"' ), $q->whereClauses );
}
public static function testAddOnePhraseTwoField()
{
$q = self::setupQuery( 'DefinitionTwoFields' );
$qb = new ezcSearchQueryBuilder();
$qb->parseSearchQuery( $q, '"live and let die"', array( 'fieldOne', 'fieldTwo' ) );
self::assertSame( array( '( fieldOne_t:"live and let die" OR fieldTwo_t:"live and let die" )' ), $q->whereClauses );
}
public static function testAddOnePhraseOneFieldMissingQuotes()
{
$q = self::setupQuery( 'DefinitionOneField' );
try
{
$qb = new ezcSearchQueryBuilder();
$qb->parseSearchQuery( $q, '"for your eyes only', array( 'fieldOne' ) );
self::fail( 'Expected exception not-thrown.' );
}
catch ( ezcSearchBuildQueryException $e )
{
self::assertSame( "Unterminated quotes in query string.", $e->getMessage() );
}
}
public static function testAddMorePhrasesTwoField()
{
$q = self::setupQuery( 'DefinitionTwoFields' );
$qb = new ezcSearchQueryBuilder();
$qb->parseSearchQuery( $q, '"the man with the golden gun" "the spy who loved me"', array( 'fieldOne', 'fieldTwo' ) );
$expected = array(
'( fieldOne_t:"the man with the golden gun" OR fieldTwo_t:"the man with the golden gun" )',
'( fieldOne_t:"the spy who loved me" OR fieldTwo_t:"the spy who loved me" )',
);
self::assertSame( $expected, $q->whereClauses );
}
public static function testOrMoreWordsOneField()
{
$q = self::setupQuery( 'DefinitionOneField' );
$qb = new ezcSearchQueryBuilder();
$qb->parseSearchQuery( $q, 'cake OR death', array( 'fieldOne' ) );
self::assertSame( array( '( fieldOne_t:cake OR fieldOne_t:death )' ), $q->whereClauses );
}
public static function testOrMoreWordsTwoField()
{
$q = self::setupQuery( 'DefinitionTwoFields' );
$qb = new ezcSearchQueryBuilder();
$qb->parseSearchQuery( $q, 'cake OR death', array( 'fieldOne', 'fieldTwo' ) );
$expected = array(
'( ( fieldOne_t:cake OR fieldTwo_t:cake ) OR ( fieldOne_t:death OR fieldTwo_t:death ) )',
);
self::assertSame( $expected, $q->whereClauses );
}
public static function testMixedAndAndOrWithoutBraces()
{
$q = self::setupQuery( 'DefinitionOneField' );
try
{
$qb = new ezcSearchQueryBuilder();
$qb->parseSearchQuery( $q, 'god OR does AND not OR play AND with OR dices', array( 'fieldOne' ) );
self::fail( 'Expected exception not-thrown.' );
}
catch ( ezcSearchBuildQueryException $e )
{
self::assertSame( 'You can not mix OR and AND without using "(" and ")".', $e->getMessage() );
}
}
public static function testMixedOrAndAndWithoutBraces()
{
$q = self::setupQuery( 'DefinitionOneField' );
try
{
$qb = new ezcSearchQueryBuilder();
$qb->parseSearchQuery( $q, 'I AND don\'t OR believe AND in OR mathematics', array( 'fieldOne' ) );
self::fail( 'Expected exception not-thrown.' );
}
catch ( ezcSearchBuildQueryException $e )
{
self::assertSame( 'You can not mix AND and OR without using "(" and ")".', $e->getMessage() );
}
}
public static function testOrMoreWordsTwoFieldWithBraces()
{
$q = self::setupQuery( 'DefinitionTwoFields' );
$qb = new ezcSearchQueryBuilder();
$qb->parseSearchQuery( $q, '(cake OR death)', array( 'fieldOne', 'fieldTwo' ) );
$expected = array(
'( ( fieldOne_t:cake OR fieldTwo_t:cake ) OR ( fieldOne_t:death OR fieldTwo_t:death ) )',
);
self::assertSame( $expected, $q->whereClauses );
}
public static function testMixedAndAndOrMoreWordsOneFieldWithBraces()
{
$q = self::setupQuery( 'DefinitionOneField' );
$qb = new ezcSearchQueryBuilder();
$qb->parseSearchQuery( $q, 'cake OR (cookies AND death)', array( 'fieldOne' ) );
$expected = array(
'( fieldOne_t:cake OR ( fieldOne_t:cookies AND fieldOne_t:death ) )',
);
self::assertSame( $expected, $q->whereClauses );
}
public static function testMixedAndAndOrMoreWordsTwoFieldWithBraces()
{
$q = self::setupQuery( 'DefinitionTwoFields' );
$qb = new ezcSearchQueryBuilder();
$qb->parseSearchQuery( $q, 'cake OR (cookies AND death)', array( 'fieldOne', 'fieldTwo' ) );
$expected = array(
'( ( fieldOne_t:cake OR fieldTwo_t:cake ) OR ( ( fieldOne_t:cookies OR fieldTwo_t:cookies ) AND ( fieldOne_t:death OR fieldTwo_t:death ) ) )',
);
self::assertSame( $expected, $q->whereClauses );
}
public static function testAddMoreWordsOneFieldWithPlus()
{
$q = self::setupQuery( 'DefinitionOneField' );
$qb = new ezcSearchQueryBuilder();
$qb->parseSearchQuery( $q, 'from +russia with love', array( 'fieldOne' ) );
self::assertSame( array( "fieldOne_t:from", "+fieldOne_t:russia", "fieldOne_t:with", "fieldOne_t:love" ), $q->whereClauses );
}
public static function testAddMoreWordsTwoFieldWithMinus()
{
$q = self::setupQuery( 'DefinitionTwoFields' );
$qb = new ezcSearchQueryBuilder();
$qb->parseSearchQuery( $q, '-you only live -twice', array( 'fieldOne', 'fieldTwo' ) );
$expected = array(
"( !fieldOne_t:you AND !fieldTwo_t:you )",
"( fieldOne_t:only OR fieldTwo_t:only )",
"( fieldOne_t:live OR fieldTwo_t:live )",
"( !fieldOne_t:twice AND !fieldTwo_t:twice )",
);
self::assertSame( $expected, $q->whereClauses );
}
public static function testSpecialCharsInQuotes()
{
$q = self::setupQuery( 'DefinitionTwoFields' );
$qb = new ezcSearchQueryBuilder();
$qb->parseSearchQuery( $q, '"Testing+more-less is (good): not! "', array( 'fieldOne', 'fieldTwo' ) );
self::assertSame( array( '( fieldOne_t:"Testing+more-less is (good): not!" OR fieldTwo_t:"Testing+more-less is (good): not!" )' ), $q->whereClauses );
}
// test for issue #14159
public static function testWithColon1()
{
$q = self::setupQuery( 'DefinitionTwoFields' );
$qb = new ezcSearchQueryBuilder();
$qb->parseSearchQuery( $q, '"http://blahblah"', array( 'fieldOne' ) );
self::assertSame( array( 'fieldOne_t:"http://blahblah"' ), $q->whereClauses );
}
public static function testWithColon2()
{
$q = self::setupQuery( 'DefinitionTwoFields' );
$qb = new ezcSearchQueryBuilder();
$qb->parseSearchQuery( $q, '"http://blahblah"', array( 'fieldOne', 'fieldTwo' ) );
self::assertSame( array( '( fieldOne_t:"http://blahblah" OR fieldTwo_t:"http://blahblah" )' ), $q->whereClauses );
}
// tests for issue #15298
public static function testAndOnlyWithDelimiters()
{
$q = self::setupQuery( 'DefinitionOneField' );
$qb = new ezcSearchQueryBuilder();
$qb->parseSearchQuery( $q, 'cakeANDdeath', array( 'fieldOne' ) );
self::assertSame( array( 'fieldOne_t:cakeANDdeath' ), $q->whereClauses );
}
public static function testOrdOnlyWithDelimiters()
{
$q = self::setupQuery( 'DefinitionOneField' );
$qb = new ezcSearchQueryBuilder();
$qb->parseSearchQuery( $q, 'INTERSPORT', array( 'fieldOne' ) );
self::assertSame( array( 'fieldOne_t:INTERSPORT' ), $q->whereClauses );
}
public static function setupQuery( $definition )
{
$h = new TestHandler;
$d = new ezcSearchDocumentDefinition( $definition );
$d->fields['fieldOne'] = new ezcSearchDefinitionDocumentField( 'fieldOne' );
if ( $definition == 'DefinitionTwoFields' )
{
$d->fields['fieldTwo'] = new ezcSearchDefinitionDocumentField( 'fieldTwo' );
}
$d->fields['ezcsearch_type'] = new ezcSearchDefinitionDocumentField( 'type' );
$q = $h->createFindQuery( 'DefinitionOneField', $d );
$q->whereClauses = array();
return $q;
}
}
?>