# -*- coding: utf-8 -*-
'''
Created on Aug 1, 2012

@author: ymh
'''
from django.test import SimpleTestCase
from ldt.indexation.query_parser import QueryParser
from haystack.query import SQ
import unittest

class QueryParserTest(SimpleTestCase):
    
    def test_simple_term(self):
        
        qp = QueryParser("text")
        res = qp.parse("hello")
        
        self.assertEqual(str(res), str(SQ(text="hello")))

    def test_multiple_terms(self):
        
        qp = QueryParser("text")
        res = qp.parse("hello title:world")
        
        self.assertEquals(str(res), str(SQ(text="hello")|SQ(title="world")))


    def test_operator(self):
        
        qp = QueryParser("text")
        res = qp.parse("title:hello AND world")
        
        self.assertEquals(str(res), str(SQ(title="hello")&SQ(text="world")))

    def test_complex(self):
        
        qp = QueryParser("text")
        res = qp.parse("hello AND world foo")

        self.assertEquals(str(res), str(SQ(text="hello")&SQ(text="world")|SQ(text="foo")))
        
    def test_minus(self):
        qp = QueryParser("text")
        res = qp.parse("hello -world")
        
        self.assertEquals(str(res), str(SQ(text="hello")&~SQ(text="world")))
        
    def test_not(self):
        qp = QueryParser("text")
        res = qp.parse("hello NOT world")
        
        self.assertEquals(str(res), str(SQ(text="hello")|~SQ(text="world")))    

    def test_exact(self):
        qp = QueryParser("text")
        res = qp.parse('title:"hello world"')
        
        self.assertEquals(str(res), str(SQ(title__exact="hello world")))    

    def test_single_quote(self):
        qp = QueryParser("text")
        res = qp.parse("title:'hello world'")
        
        self.assertEquals(str(res), str(SQ(title="hello world")))
        
    def test_group(self):
        qp = QueryParser("text")
        
        res = qp.parse("(hello world) AND (foo bar)")
        
        self.assertEquals(str(res), str(SQ(text="hello")&SQ(text="world")&SQ(text="foo")&SQ(text="bar")))
        
    def test_group_or(self):
        qp = QueryParser("text")
        
        res = qp.parse("(hello world) OR (foo bar)")
        
        self.assertEquals(str(res), str((SQ(text="hello")&SQ(text="world"))|(SQ(text="foo")&SQ(text="bar")) ))
        
    def test_prefix(self):
        qp = QueryParser("text")
        res = qp.parse("title:foo*")
        self.assertEquals(str(res), str(SQ(title__startswith='foo')))
        
    def test_plus(self):
        qp = QueryParser("text")
        res = qp.parse("title:foo +bar")
        self.assertEquals(str(res), str(SQ(text='bar')&SQ(title='foo')))

    def test_plus_multiple(self):
        qp = QueryParser("text")
        
        res = qp.parse("title:foo +bar +fighter")
        self.assertEquals(str(res), str(SQ(text='bar')&SQ(text="fighter")&SQ(title='foo')))

        res = qp.parse("+title:foo +bar +fighter")
        self.assertEquals(str(res), str(SQ(title='foo')&SQ(text='bar')&SQ(text="fighter")))

    def test_ltgt(self):
        qp = QueryParser("text")
        res = qp.parse("count:<10")
        self.assertEquals(str(res), str(SQ(count__lt=10)))
        res = qp.parse("count:>10")
        self.assertEquals(str(res), str(SQ(count__gt=10)))
        res = qp.parse("count:<=10")
        self.assertEquals(str(res), str(SQ(count__lte=10)))
        res = qp.parse("count:>=10")
        self.assertEquals(str(res), str(SQ(count__gte=10)))

    def test_ltgt_float(self):
        qp = QueryParser("text")
        res = qp.parse("count:<3.14")
        self.assertEquals(str(res), str(SQ(count__lt=3.14)))
        res = qp.parse("count:>3.14")
        self.assertEquals(str(res), str(SQ(count__gt=3.14)))
        res = qp.parse("count:<=3.14")
        self.assertEquals(str(res), str(SQ(count__lte=3.14)))
        res = qp.parse("count:>=3.14")
        self.assertEquals(str(res), str(SQ(count__gte=3.14)))

    def test_ltgt_str(self):
        qp = QueryParser("text")
        res = qp.parse("count:<foo")
        self.assertEquals(str(res), str(SQ(count__lt='foo')))
        res = qp.parse("count:>foo")
        self.assertEquals(str(res), str(SQ(count__gt='foo')))
        res = qp.parse("count:<=foo")
        self.assertEquals(str(res), str(SQ(count__lte='foo')))
        res = qp.parse("count:>=foo")
        self.assertEquals(str(res), str(SQ(count__gte='foo')))

        
    def test_range(self):
        qp = QueryParser("text")
        res = qp.parse("count:[foo to bar]")
        self.assertEquals(str(res), str(SQ(count__range=['foo','bar'])))
        
    def test_range_nb(self):
        qp = QueryParser("text")
        res = qp.parse("count:[3 to 5]")
        self.assertEquals(str(res), str(SQ(count__range=[3,5])))
        
if __name__ == '__main__':
    unittest.main()