Example #1
0
    def setUp(self):
        super(XapianBoostBackendTestCase, self).setUp()

        self.site = SearchSite()
        self.sb = SearchBackend(site=self.site)
        self.smmi = XapianBoostMockSearchIndex(AFourthMockModel,
                                               backend=self.sb)
        self.site.register(AFourthMockModel, XapianBoostMockSearchIndex)

        # Stow.
        import haystack
        self.old_site = haystack.site
        haystack.site = self.site

        self.sample_objs = []

        for i in xrange(1, 5):
            mock = AFourthMockModel()
            mock.id = i
            if i % 2:
                mock.author = 'daniel'
                mock.editor = 'david'
            else:
                mock.author = 'david'
                mock.editor = 'daniel'
            mock.pub_date = datetime.date(2009, 2,
                                          25) - datetime.timedelta(days=i)
            self.sample_objs.append(mock)
Example #2
0
    def test_log_query(self):
        backends.reset_search_queries()
        self.assertEqual(len(backends.queries), 0)

        # Stow.
        old_debug = settings.DEBUG
        settings.DEBUG = False

        len(self.sq.get_results())
        self.assertEqual(len(backends.queries), 0)

        settings.DEBUG = True
        # Redefine it to clear out the cached results.
        self.sq = SearchQuery(backend=SearchBackend())
        self.sq.add_filter(SQ(name='bar'))
        len(self.sq.get_results())
        self.assertEqual(len(backends.queries), 1)
        self.assertEqual(str(backends.queries[0]['query_string']),
                         u'Xapian::Query((ZXNAMEbar OR XNAMEbar))')

        # And again, for good measure.
        self.sq = SearchQuery(backend=SearchBackend())
        self.sq.add_filter(SQ(name='bar'))
        self.sq.add_filter(SQ(text='moof'))
        len(self.sq.get_results())
        self.assertEqual(len(backends.queries), 2)
        self.assertEqual(str(backends.queries[0]['query_string']),
                         u'Xapian::Query((ZXNAMEbar OR XNAMEbar))')
        self.assertEqual(
            str(backends.queries[1]['query_string']),
            u'Xapian::Query(((ZXNAMEbar OR XNAMEbar) AND (ZXTEXTmoof OR XTEXTmoof)))'
        )

        # Restore.
        settings.DEBUG = old_debug
Example #3
0
    def setUp(self):
        super(XapianSearchBackendTestCase, self).setUp()

        self.site = SearchSite()
        self.backend = SearchBackend(site=self.site)
        self.index = XapianMockSearchIndex(XapianMockModel,
                                           backend=self.backend)
        self.site.register(XapianMockModel, XapianMockSearchIndex)

        self.sample_objs = []

        for i in xrange(1, 4):
            mock = XapianMockModel()
            mock.id = i
            mock.author = 'david%s' % i
            mock.pub_date = datetime.date(2009, 2,
                                          25) - datetime.timedelta(days=i)
            mock.exp_date = datetime.date(2009, 2,
                                          23) + datetime.timedelta(days=i)
            mock.value = i * 5
            mock.flag = bool(i % 2)
            mock.slug = 'http://example.com/%d/' % i
            mock.url = 'http://example.com/%d/' % i
            self.sample_objs.append(mock)

        self.sample_objs[0].popularity = 834.0
        self.sample_objs[1].popularity = 35.5
        self.sample_objs[2].popularity = 972.0
 def setUp(self):
     super(LiveXapianSearchQueryTestCase, self).setUp()
     
     site = SearchSite()
     backend = SearchBackend(site=site)
     index = LiveXapianMockSearchIndex(MockModel, backend=backend)
     site.register(MockModel, LiveXapianMockSearchIndex)
     backend.update(index, MockModel.objects.all())
     
     self.sq = SearchQuery(backend=backend)
Example #5
0
    def setUp(self):
        super(LiveXapianSearchQueryTestCase, self).setUp()

        site = SearchSite()
        backend = SearchBackend(site=site)
        index = LiveXapianMockSearchIndex(MockModel, backend=backend)
        site.register(MockModel, LiveXapianMockSearchIndex)
        backend.update(index, MockModel.objects.all())

        self.sq = SearchQuery(backend=backend)
 def setUp(self):
     super(LiveXapianAutocompleteTestCase, self).setUp()
     
     site = SearchSite()
     backend = SearchBackend(site=site)
     index = XapianAutocompleteMockModelSearchIndex(MockModel, backend=backend)
     site.register(MockModel, XapianAutocompleteMockModelSearchIndex)
     backend.update(index, MockModel.objects.all())
     
     self.sq = SearchQuery(backend=backend)
     self.sqs = SearchQuerySet(query=self.sq)
Example #7
0
class XapianBoostBackendTestCase(TestCase):
    def setUp(self):
        super(XapianBoostBackendTestCase, self).setUp()

        self.site = SearchSite()
        self.sb = SearchBackend(site=self.site)
        self.smmi = XapianBoostMockSearchIndex(AFourthMockModel,
                                               backend=self.sb)
        self.site.register(AFourthMockModel, XapianBoostMockSearchIndex)

        # Stow.
        import haystack
        self.old_site = haystack.site
        haystack.site = self.site

        self.sample_objs = []

        for i in xrange(1, 5):
            mock = AFourthMockModel()
            mock.id = i
            if i % 2:
                mock.author = 'daniel'
                mock.editor = 'david'
            else:
                mock.author = 'david'
                mock.editor = 'daniel'
            mock.pub_date = datetime.date(2009, 2,
                                          25) - datetime.timedelta(days=i)
            self.sample_objs.append(mock)

    def tearDown(self):
        import haystack
        haystack.site = self.old_site
        super(XapianBoostBackendTestCase, self).tearDown()

    def test_boost(self):
        self.sb.update(self.smmi, self.sample_objs)

        sqs = SearchQuerySet()

        self.assertEqual(len(sqs.all()), 4)

        results = sqs.filter(SQ(author='daniel') | SQ(editor='daniel'))

        self.assertEqual([result.id for result in results], [
            'core.afourthmockmodel.1', 'core.afourthmockmodel.3',
            'core.afourthmockmodel.2', 'core.afourthmockmodel.4'
        ])
class XapianBoostBackendTestCase(TestCase):
    def setUp(self):
        super(XapianBoostBackendTestCase, self).setUp()

        self.site = SearchSite()
        self.sb = SearchBackend(site=self.site)
        self.smmi = XapianBoostMockSearchIndex(AFourthMockModel, backend=self.sb)
        self.site.register(AFourthMockModel, XapianBoostMockSearchIndex)

        # Stow.
        import haystack
        self.old_site = haystack.site
        haystack.site = self.site

        self.sample_objs = []

        for i in xrange(1, 5):
            mock = AFourthMockModel()
            mock.id = i
            if i % 2:
                mock.author = 'daniel'
                mock.editor = 'david'
            else:
                mock.author = 'david'
                mock.editor = 'daniel'
            mock.pub_date = datetime.date(2009, 2, 25) - datetime.timedelta(days=i)
            self.sample_objs.append(mock)

    def tearDown(self):
        import haystack
        haystack.site = self.old_site
        super(XapianBoostBackendTestCase, self).tearDown()

    def test_boost(self):
        self.sb.update(self.smmi, self.sample_objs)
        
        sqs = SearchQuerySet()
        
        self.assertEqual(len(sqs.all()), 4)

        results = sqs.filter(SQ(author='daniel') | SQ(editor='daniel'))

        self.assertEqual([result.id for result in results], [
            'core.afourthmockmodel.1',
            'core.afourthmockmodel.3',
            'core.afourthmockmodel.2',
            'core.afourthmockmodel.4'
        ])
 def setUp(self):
     super(XapianSearchBackendTestCase, self).setUp()
     
     self.site = SearchSite()
     self.backend = SearchBackend(site=self.site)
     self.index = XapianMockSearchIndex(XapianMockModel, backend=self.backend)
     self.site.register(XapianMockModel, XapianMockSearchIndex)
     
     self.sample_objs = []
     
     for i in xrange(1, 4):
         mock = XapianMockModel()
         mock.id = i
         mock.author = 'david%s' % i
         mock.pub_date = datetime.date(2009, 2, 25) - datetime.timedelta(days=i)
         mock.exp_date = datetime.date(2009, 2, 23) + datetime.timedelta(days=i)
         mock.value = i * 5
         mock.flag = bool(i % 2)
         mock.slug = 'http://example.com/%d/' % i
         mock.url = 'http://example.com/%d/' % i
         self.sample_objs.append(mock)
     
     self.sample_objs[0].popularity = 834.0
     self.sample_objs[1].popularity = 35.5
     self.sample_objs[2].popularity = 972.0
Example #10
0
 def setUp(self):
     super(XapianSearchBackendTestCase, self).setUp()
     
     temp_path = os.path.join('tmp', 'test_xapian_query')
     self.old_xapian_path = getattr(settings, 'HAYSTACK_XAPIAN_PATH', temp_path)
     settings.HAYSTACK_XAPIAN_PATH = temp_path
     
     self.site = XapianSearchSite()
     self.sb = SearchBackend(site=self.site)
     self.msi = XapianMockSearchIndex(MockModel, backend=self.sb)
     self.site.register(MockModel, XapianMockSearchIndex)
     
     self.sample_objs = []
     
     for i in xrange(1, 4):
         mock = MockModel()
         mock.id = i
         mock.author = 'david%s' % i
         mock.pub_date = datetime.date(2009, 2, 25) - datetime.timedelta(days=i)
         mock.value = i * 5
         mock.flag = bool(i % 2)
         mock.slug = 'http://example.com/%d' % i
         self.sample_objs.append(mock)
         
     self.sample_objs[0].popularity = 834.0
     self.sample_objs[1].popularity = 35.0
     self.sample_objs[2].popularity = 972.0
Example #11
0
    def setUp(self):
        super(XapianBoostBackendTestCase, self).setUp()

        self.site = SearchSite()
        self.sb = SearchBackend(site=self.site)
        self.smmi = XapianBoostMockSearchIndex(AFourthMockModel, backend=self.sb)
        self.site.register(AFourthMockModel, XapianBoostMockSearchIndex)

        # Stow.
        import haystack
        self.old_site = haystack.site
        haystack.site = self.site

        self.sample_objs = []

        for i in xrange(1, 5):
            mock = AFourthMockModel()
            mock.id = i
            if i % 2:
                mock.author = 'daniel'
                mock.editor = 'david'
            else:
                mock.author = 'david'
                mock.editor = 'daniel'
            mock.pub_date = datetime.date(2009, 2, 25) - datetime.timedelta(days=i)
            self.sample_objs.append(mock)
Example #12
0
class XapianSearchBackendTestCase(TestCase):
    def setUp(self):
        super(XapianSearchBackendTestCase, self).setUp()
        
        self.site = SearchSite()
        self.backend = SearchBackend(site=self.site)
        self.index = XapianMockSearchIndex(XapianMockModel, backend=self.backend)
        self.site.register(XapianMockModel, XapianMockSearchIndex)
        
        self.sample_objs = []
        
        for i in xrange(1, 4):
            mock = XapianMockModel()
            mock.id = i
            mock.author = 'david%s' % i
            mock.pub_date = datetime.date(2009, 2, 25) - datetime.timedelta(days=i)
            mock.value = i * 5
            mock.flag = bool(i % 2)
            mock.slug = 'http://example.com/%d/' % i
            mock.url = 'http://example.com/%d/' % i
            self.sample_objs.append(mock)
        
        self.sample_objs[0].popularity = 834.0
        self.sample_objs[1].popularity = 35.5
        self.sample_objs[2].popularity = 972.0
    
    def tearDown(self):
        if os.path.exists(settings.HAYSTACK_XAPIAN_PATH):
            shutil.rmtree(settings.HAYSTACK_XAPIAN_PATH)
        
        super(XapianSearchBackendTestCase, self).tearDown()
    
    def test_update(self):
        self.backend.update(self.index, self.sample_objs)
        
        self.assertEqual(self.backend.document_count(), 3)
        self.assertEqual([result.pk for result in self.backend.search(xapian.Query(''))['results']], [1, 2, 3])
    
    def test_duplicate_update(self):
        self.backend.update(self.index, self.sample_objs)
        self.backend.update(self.index, self.sample_objs) # Duplicates should be updated, not appended -- http://github.com/notanumber/xapian-haystack/issues/#issue/6
        
        self.assertEqual(self.backend.document_count(), 3)
    
    def test_remove(self):
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(self.backend.document_count(), 3)
        
        self.backend.remove(self.sample_objs[0])
        self.assertEqual(self.backend.document_count(), 2)
        self.assertEqual([result.pk for result in self.backend.search(xapian.Query(''))['results']], [2, 3])
    
    def test_clear(self):
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(self.backend.document_count(), 3)
        
        self.backend.clear()
        self.assertEqual(self.backend.document_count(), 0)
        
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(self.backend.document_count(), 3)
        
        self.backend.clear([AnotherMockModel])
        self.assertEqual(self.backend.document_count(), 3)
        
        self.backend.clear([XapianMockModel])
        self.assertEqual(self.backend.document_count(), 0)
        
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(self.backend.document_count(), 3)
        
        self.backend.clear([AnotherMockModel, XapianMockModel])
        self.assertEqual(self.backend.document_count(), 0)
    
    def test_search(self):
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(self.backend.document_count(), 3)
        
        self.assertEqual(self.backend.search(xapian.Query()), {'hits': 0, 'results': []})
        self.assertEqual(self.backend.search(xapian.Query(''))['hits'], 3)
        self.assertEqual([result.pk for result in self.backend.search(xapian.Query(''))['results']], [1, 2, 3])
        self.assertEqual(self.backend.search(xapian.Query('indexed'))['hits'], 3)
        self.assertEqual([result.pk for result in self.backend.search(xapian.Query(''))['results']], [1, 2, 3])

    def test_search_field_with_punctuation(self):
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(self.backend.document_count(), 3)

        # self.assertEqual(self.backend.search(xapian.Query('http://example.com/'))['hits'], 3)
        self.assertEqual([result.pk for result in self.backend.search(xapian.Query('http://example.com/1/'))['results']], [1])

    def test_search_by_mvf(self):
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(self.backend.document_count(), 3)
        
        self.assertEqual(self.backend.search(xapian.Query('ab'))['hits'], 1)
        self.assertEqual(self.backend.search(xapian.Query('b'))['hits'], 1)
        self.assertEqual(self.backend.search(xapian.Query('to'))['hits'], 1)
        self.assertEqual(self.backend.search(xapian.Query('one'))['hits'], 3)
    
    def test_field_facets(self):
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(self.backend.document_count(), 3)
        
        self.assertEqual(self.backend.search(xapian.Query(), facets=['name']), {'hits': 0, 'results': []})
        results = self.backend.search(xapian.Query('indexed'), facets=['name'])
        self.assertEqual(results['hits'], 3)
        self.assertEqual(results['facets']['fields']['name'], [('david1', 1), ('david2', 1), ('david3', 1)])
        
        results = self.backend.search(xapian.Query('indexed'), facets=['flag'])
        self.assertEqual(results['hits'], 3)
        self.assertEqual(results['facets']['fields']['flag'], [(False, 1), (True, 2)])
        
        results = self.backend.search(xapian.Query('indexed'), facets=['sites'])
        self.assertEqual(results['hits'], 3)
        self.assertEqual(results['facets']['fields']['sites'], [('1', 1), ('3', 2), ('2', 2), ('4', 1), ('6', 2), ('9', 1)])
    
    def test_date_facets(self):
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(self.backend.document_count(), 3)
        
        self.assertEqual(self.backend.search(xapian.Query(), date_facets={'pub_date': {'start_date': datetime.datetime(2008, 10, 26), 'end_date': datetime.datetime(2009, 3, 26), 'gap_by': 'month'}}), {'hits': 0, 'results': []})
        results = self.backend.search(xapian.Query('indexed'), date_facets={'pub_date': {'start_date': datetime.datetime(2008, 10, 26), 'end_date': datetime.datetime(2009, 3, 26), 'gap_by': 'month'}})
        self.assertEqual(results['hits'], 3)
        self.assertEqual(results['facets']['dates']['pub_date'], [
            ('2009-02-26T00:00:00', 0),
            ('2009-01-26T00:00:00', 3),
            ('2008-12-26T00:00:00', 0),
            ('2008-11-26T00:00:00', 0),
            ('2008-10-26T00:00:00', 0),
        ])
        
        results = self.backend.search(xapian.Query('indexed'), date_facets={'pub_date': {'start_date': datetime.datetime(2009, 02, 01), 'end_date': datetime.datetime(2009, 3, 15), 'gap_by': 'day', 'gap_amount': 15}})
class XapianSearchBackendTestCase(TestCase):
    def setUp(self):
        super(XapianSearchBackendTestCase, self).setUp()
        
        self.site = SearchSite()
        self.backend = SearchBackend(site=self.site)
        self.index = XapianMockSearchIndex(XapianMockModel, backend=self.backend)
        self.site.register(XapianMockModel, XapianMockSearchIndex)
        
        self.sample_objs = []
        
        for i in xrange(1, 4):
            mock = XapianMockModel()
            mock.id = i
            mock.author = 'david%s' % i
            mock.pub_date = datetime.date(2009, 2, 25) - datetime.timedelta(days=i)
            mock.value = i * 5
            mock.flag = bool(i % 2)
            mock.slug = 'http://example.com/%d/' % i
            mock.url = 'http://example.com/%d/' % i
            self.sample_objs.append(mock)
        
        self.sample_objs[0].popularity = 834.0
        self.sample_objs[1].popularity = 35.5
        self.sample_objs[2].popularity = 972.0
    
    def tearDown(self):
        if os.path.exists(settings.HAYSTACK_XAPIAN_PATH):
            shutil.rmtree(settings.HAYSTACK_XAPIAN_PATH)
        
        super(XapianSearchBackendTestCase, self).tearDown()
    
    def xapian_search(self, query_string):
        database = xapian.Database(settings.HAYSTACK_XAPIAN_PATH)
        if query_string:
            qp = xapian.QueryParser()
            qp.set_database(database)
            query = qp.parse_query(query_string, xapian.QueryParser.FLAG_WILDCARD)
        else:
            query = xapian.Query(query_string) # Empty query matches all
        enquire = xapian.Enquire(database)
        enquire.set_query(query)
        matches = enquire.get_mset(0, database.get_doccount())
        
        document_list = []
        
        for match in matches:
            app_label, module_name, pk, model_data = pickle.loads(match.document.get_data())
            for key, value in model_data.iteritems():
                model_data[key] = _marshal_value(value)
            model_data['id'] = u'%s.%s.%d' % (app_label, module_name, pk)
            document_list.append(model_data)
        
        return document_list
    
    def test_update(self):
        self.backend.update(self.index, self.sample_objs)
        
        self.assertEqual(len(self.xapian_search('')), 3)
        self.assertEqual([dict(doc) for doc in self.xapian_search('')], [
            {'flag': u't', 'name': u'david1', 'name_exact': u'david1', 'tags': u"['a', 'b', 'c']", 'keys': u'[1, 2, 3]', 'text': u'indexed!\n1', 'sites': u"['1', '2', '3']", 'titles': u"['object one title one', 'object one title two']", 'pub_date': u'20090224000000', 'value': u'000000000005', 'month': u'02', 'id': u'tests.xapianmockmodel.1', 'slug': u'http://example.com/1/', 'url': u'http://example.com/1/', 'popularity': '\xca\x84', 'django_id': u'1', 'django_ct': u'tests.xapianmockmodel', 'empty': u''},
            {'flag': u'f', 'name': u'david2', 'name_exact': u'david2', 'tags': u"['ab', 'bc', 'cd']", 'keys': u'[2, 4, 6]', 'text': u'indexed!\n2', 'sites': u"['2', '4', '6']", 'titles': u"['object two title one', 'object two title two']", 'pub_date': u'20090223000000', 'value': u'000000000010', 'month': u'02', 'id': u'tests.xapianmockmodel.2', 'slug': u'http://example.com/2/', 'url': u'http://example.com/2/', 'popularity': '\xb4p', 'django_id': u'2', 'django_ct': u'tests.xapianmockmodel', 'empty': u''},
            {'flag': u't', 'name': u'david3', 'name_exact': u'david3', 'tags': u"['an', 'to', 'or']", 'keys': u'[3, 6, 9]', 'text': u'indexed!\n3', 'sites': u"['3', '6', '9']", 'titles': u"['object three title one', 'object three title two']", 'pub_date': u'20090222000000', 'value': u'000000000015', 'month': u'02', 'id': u'tests.xapianmockmodel.3', 'slug': u'http://example.com/3/', 'url': u'http://example.com/3/', 'popularity': '\xcb\x98', 'django_id': u'3', 'django_ct': u'tests.xapianmockmodel', 'empty': u''}
        ])
    
    def test_duplicate_update(self):
        self.backend.update(self.index, self.sample_objs)
        self.backend.update(self.index, self.sample_objs) # Duplicates should be updated, not appended -- http://github.com/notanumber/xapian-haystack/issues/#issue/6
        
        self.assertEqual(len(self.xapian_search('')), 3)
    
    def test_remove(self):
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(len(self.xapian_search('')), 3)
        
        self.backend.remove(self.sample_objs[0])
        self.assertEqual(len(self.xapian_search('')), 2)
        self.assertEqual([dict(doc) for doc in self.xapian_search('')], [
            {'flag': u'f', 'name': u'david2', 'name_exact': u'david2', 'tags': u"['ab', 'bc', 'cd']", 'keys': u'[2, 4, 6]', 'text': u'indexed!\n2', 'sites': u"['2', '4', '6']", 'titles': u"['object two title one', 'object two title two']", 'pub_date': u'20090223000000', 'value': u'000000000010', 'month': u'02', 'id': u'tests.xapianmockmodel.2', 'slug': u'http://example.com/2/', 'url': u'http://example.com/2/', 'popularity': '\xb4p', 'django_id': u'2', 'django_ct': u'tests.xapianmockmodel', 'empty': u''},
            {'flag': u't', 'name': u'david3', 'name_exact': u'david3', 'tags': u"['an', 'to', 'or']", 'keys': u'[3, 6, 9]', 'text': u'indexed!\n3', 'sites': u"['3', '6', '9']", 'titles': u"['object three title one', 'object three title two']", 'pub_date': u'20090222000000', 'value': u'000000000015', 'month': u'02', 'id': u'tests.xapianmockmodel.3', 'slug': u'http://example.com/3/', 'url': u'http://example.com/3/', 'popularity': '\xcb\x98', 'django_id': u'3', 'django_ct': u'tests.xapianmockmodel', 'empty': u''}
        ])
    
    def test_clear(self):
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(len(self.xapian_search('')), 3)
        
        self.backend.clear()
        self.assertEqual(len(self.xapian_search('')), 0)
        
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(len(self.xapian_search('')), 3)
        
        self.backend.clear([AnotherMockModel])
        self.assertEqual(len(self.xapian_search('')), 3)
        
        self.backend.clear([XapianMockModel])
        self.assertEqual(len(self.xapian_search('')), 0)
        
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(len(self.xapian_search('')), 3)
        
        self.backend.clear([AnotherMockModel, XapianMockModel])
        self.assertEqual(len(self.xapian_search('')), 0)
    
    def test_search(self):
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(len(self.xapian_search('')), 3)
        
        self.assertEqual(self.backend.search(xapian.Query()), {'hits': 0, 'results': []})
        self.assertEqual(self.backend.search(xapian.Query(''))['hits'], 3)
        self.assertEqual([result.pk for result in self.backend.search(xapian.Query(''))['results']], [1, 2, 3])
        self.assertEqual(self.backend.search(xapian.Query('indexed'))['hits'], 3)
        self.assertEqual([result.pk for result in self.backend.search(xapian.Query(''))['results']], [1, 2, 3])

    def test_search_field_with_punctuation(self):
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(len(self.xapian_search('')), 3)

        # self.assertEqual(self.backend.search(xapian.Query('http://example.com/'))['hits'], 3)
        self.assertEqual([result.pk for result in self.backend.search(xapian.Query('http://example.com/1/'))['results']], [1])

    def test_search_by_mvf(self):
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(len(self.xapian_search('')), 3)
        
        self.assertEqual(self.backend.search(xapian.Query('ab'))['hits'], 1)
        self.assertEqual(self.backend.search(xapian.Query('b'))['hits'], 1)
        self.assertEqual(self.backend.search(xapian.Query('to'))['hits'], 1)
        self.assertEqual(self.backend.search(xapian.Query('one'))['hits'], 3)
    
    def test_field_facets(self):
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(len(self.xapian_search('')), 3)
        
        self.assertEqual(self.backend.search(xapian.Query(), facets=['name']), {'hits': 0, 'results': []})
        results = self.backend.search(xapian.Query('indexed'), facets=['name'])
        self.assertEqual(results['hits'], 3)
        self.assertEqual(results['facets']['fields']['name'], [('david1', 1), ('david2', 1), ('david3', 1)])
        
        results = self.backend.search(xapian.Query('indexed'), facets=['flag'])
        self.assertEqual(results['hits'], 3)
        self.assertEqual(results['facets']['fields']['flag'], [(False, 1), (True, 2)])
        
        results = self.backend.search(xapian.Query('indexed'), facets=['sites'])
        self.assertEqual(results['hits'], 3)
        self.assertEqual(results['facets']['fields']['sites'], [('1', 1), ('3', 2), ('2', 2), ('4', 1), ('6', 2), ('9', 1)])
    
    def test_date_facets(self):
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(len(self.xapian_search('')), 3)
        
        self.assertEqual(self.backend.search(xapian.Query(), date_facets={'pub_date': {'start_date': datetime.datetime(2008, 10, 26), 'end_date': datetime.datetime(2009, 3, 26), 'gap_by': 'month'}}), {'hits': 0, 'results': []})
        results = self.backend.search(xapian.Query('indexed'), date_facets={'pub_date': {'start_date': datetime.datetime(2008, 10, 26), 'end_date': datetime.datetime(2009, 3, 26), 'gap_by': 'month'}})
        self.assertEqual(results['hits'], 3)
        self.assertEqual(results['facets']['dates']['pub_date'], [
            ('2009-02-26T00:00:00', 0),
            ('2009-01-26T00:00:00', 3),
            ('2008-12-26T00:00:00', 0),
            ('2008-11-26T00:00:00', 0),
            ('2008-10-26T00:00:00', 0),
        ])
        
        results = self.backend.search(xapian.Query('indexed'), date_facets={'pub_date': {'start_date': datetime.datetime(2009, 02, 01), 'end_date': datetime.datetime(2009, 3, 15), 'gap_by': 'day', 'gap_amount': 15}})
Example #14
0
 def setUp(self):
     super(XapianSearchQueryTestCase, self).setUp()
     self.sq = SearchQuery(backend=SearchBackend())
Example #15
0
class XapianSearchBackendTestCase(TestCase):
    def setUp(self):
        super(XapianSearchBackendTestCase, self).setUp()

        self.site = SearchSite()
        self.backend = SearchBackend(site=self.site)
        self.index = XapianMockSearchIndex(XapianMockModel,
                                           backend=self.backend)
        self.site.register(XapianMockModel, XapianMockSearchIndex)

        self.sample_objs = []

        for i in xrange(1, 4):
            mock = XapianMockModel()
            mock.id = i
            mock.author = 'david%s' % i
            mock.pub_date = datetime.date(2009, 2,
                                          25) - datetime.timedelta(days=i)
            mock.exp_date = datetime.date(2009, 2,
                                          23) + datetime.timedelta(days=i)
            mock.value = i * 5
            mock.flag = bool(i % 2)
            mock.slug = 'http://example.com/%d/' % i
            mock.url = 'http://example.com/%d/' % i
            self.sample_objs.append(mock)

        self.sample_objs[0].popularity = 834.0
        self.sample_objs[1].popularity = 35.5
        self.sample_objs[2].popularity = 972.0

    def tearDown(self):
        if os.path.exists(settings.HAYSTACK_XAPIAN_PATH):
            shutil.rmtree(settings.HAYSTACK_XAPIAN_PATH)

        super(XapianSearchBackendTestCase, self).tearDown()

    def test_update(self):
        self.backend.update(self.index, self.sample_objs)

        self.assertEqual(self.backend.document_count(), 3)
        self.assertEqual([
            result.pk
            for result in self.backend.search(xapian.Query(''))['results']
        ], [1, 2, 3])

    def test_duplicate_update(self):
        self.backend.update(self.index, self.sample_objs)
        self.backend.update(
            self.index, self.sample_objs
        )  # Duplicates should be updated, not appended -- http://github.com/notanumber/xapian-haystack/issues/#issue/6

        self.assertEqual(self.backend.document_count(), 3)

    def test_remove(self):
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(self.backend.document_count(), 3)

        self.backend.remove(self.sample_objs[0])
        self.assertEqual(self.backend.document_count(), 2)
        self.assertEqual([
            result.pk
            for result in self.backend.search(xapian.Query(''))['results']
        ], [2, 3])

    def test_clear(self):
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(self.backend.document_count(), 3)

        self.backend.clear()
        self.assertEqual(self.backend.document_count(), 0)

        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(self.backend.document_count(), 3)

        self.backend.clear([AnotherMockModel])
        self.assertEqual(self.backend.document_count(), 3)

        self.backend.clear([XapianMockModel])
        self.assertEqual(self.backend.document_count(), 0)

        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(self.backend.document_count(), 3)

        self.backend.clear([AnotherMockModel, XapianMockModel])
        self.assertEqual(self.backend.document_count(), 0)

    def test_search(self):
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(self.backend.document_count(), 3)

        self.assertEqual(self.backend.search(xapian.Query()), {
            'hits': 0,
            'results': []
        })
        self.assertEqual(self.backend.search(xapian.Query(''))['hits'], 3)
        self.assertEqual([
            result.pk
            for result in self.backend.search(xapian.Query(''))['results']
        ], [1, 2, 3])
        self.assertEqual(
            self.backend.search(xapian.Query('indexed'))['hits'], 3)
        self.assertEqual([
            result.pk
            for result in self.backend.search(xapian.Query(''))['results']
        ], [1, 2, 3])

        # Ensure that swapping the ``result_class`` works.
        self.assertTrue(
            isinstance(
                self.backend.search(
                    xapian.Query('indexed'),
                    result_class=MockSearchResult)['results'][0],
                MockSearchResult))

    def test_search_field_with_punctuation(self):
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(self.backend.document_count(), 3)

        # self.assertEqual(self.backend.search(xapian.Query('http://example.com/'))['hits'], 3)
        self.assertEqual([
            result.pk for result in self.backend.search(
                xapian.Query('http://example.com/1/'))['results']
        ], [1])

    def test_search_by_mvf(self):
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(self.backend.document_count(), 3)

        self.assertEqual(self.backend.search(xapian.Query('ab'))['hits'], 1)
        self.assertEqual(self.backend.search(xapian.Query('b'))['hits'], 1)
        self.assertEqual(self.backend.search(xapian.Query('to'))['hits'], 1)
        self.assertEqual(self.backend.search(xapian.Query('one'))['hits'], 3)

    def test_field_facets(self):
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(self.backend.document_count(), 3)

        self.assertEqual(self.backend.search(xapian.Query(), facets=['name']),
                         {
                             'hits': 0,
                             'results': []
                         })
        results = self.backend.search(xapian.Query('indexed'), facets=['name'])
        self.assertEqual(results['hits'], 3)
        self.assertEqual(results['facets']['fields']['name'], [('david1', 1),
                                                               ('david2', 1),
                                                               ('david3', 1)])

        results = self.backend.search(xapian.Query('indexed'), facets=['flag'])
        self.assertEqual(results['hits'], 3)
        self.assertEqual(results['facets']['fields']['flag'], [(False, 1),
                                                               (True, 2)])

        results = self.backend.search(xapian.Query('indexed'),
                                      facets=['sites'])
        self.assertEqual(results['hits'], 3)
        self.assertEqual(results['facets']['fields']['sites'], [('1', 1),
                                                                ('3', 2),
                                                                ('2', 2),
                                                                ('4', 1),
                                                                ('6', 2),
                                                                ('9', 1)])

    def test_date_facets(self):
        self.backend.update(self.index, self.sample_objs)
        self.assertEqual(self.backend.document_count(), 3)

        self.assertEqual(
            self.backend.search(xapian.Query(),
                                date_facets={
                                    'pub_date': {
                                        'start_date':
                                        datetime.datetime(2008, 10, 26),
                                        'end_date':
                                        datetime.datetime(2009, 3, 26),
                                        'gap_by':
                                        'month'
                                    }
                                }), {
                                    'hits': 0,
                                    'results': []
                                })
        results = self.backend.search(xapian.Query('indexed'),
                                      date_facets={
                                          'pub_date': {
                                              'start_date':
                                              datetime.datetime(2008, 10, 26),
                                              'end_date':
                                              datetime.datetime(2009, 3, 26),
                                              'gap_by':
                                              'month'
                                          }
                                      })
        self.assertEqual(results['hits'], 3)
        self.assertEqual(results['facets']['dates']['pub_date'], [
            ('2009-02-26T00:00:00', 0),
            ('2009-01-26T00:00:00', 3),
            ('2008-12-26T00:00:00', 0),
            ('2008-11-26T00:00:00', 0),
            ('2008-10-26T00:00:00', 0),
        ])

        results = self.backend.search(xapian.Query('indexed'),
                                      date_facets={
                                          'pub_date': {
                                              'start_date':
                                              datetime.datetime(2009, 02, 01),
                                              'end_date':
                                              datetime.datetime(2009, 3, 15),
                                              'gap_by':
                                              'day',
                                              'gap_amount':
                                              15
                                          }
                                      })
Example #16
0
class XapianSearchBackendTestCase(TestCase):
    def setUp(self):
        super(XapianSearchBackendTestCase, self).setUp()
        
        temp_path = os.path.join('tmp', 'test_xapian_query')
        self.old_xapian_path = getattr(settings, 'HAYSTACK_XAPIAN_PATH', temp_path)
        settings.HAYSTACK_XAPIAN_PATH = temp_path
        
        self.site = XapianSearchSite()
        self.sb = SearchBackend(site=self.site)
        self.msi = XapianMockSearchIndex(MockModel, backend=self.sb)
        self.site.register(MockModel, XapianMockSearchIndex)
        
        self.sample_objs = []
        
        for i in xrange(1, 4):
            mock = MockModel()
            mock.id = i
            mock.author = 'david%s' % i
            mock.pub_date = datetime.date(2009, 2, 25) - datetime.timedelta(days=i)
            mock.value = i * 5
            mock.flag = bool(i % 2)
            mock.slug = 'http://example.com/%d' % i
            self.sample_objs.append(mock)
            
        self.sample_objs[0].popularity = 834.0
        self.sample_objs[1].popularity = 35.0
        self.sample_objs[2].popularity = 972.0
    
    def tearDown(self):
        if os.path.exists(settings.HAYSTACK_XAPIAN_PATH):
            shutil.rmtree(settings.HAYSTACK_XAPIAN_PATH)

        settings.HAYSTACK_XAPIAN_PATH = self.old_xapian_path
        super(XapianSearchBackendTestCase, self).tearDown()
    
    def xapian_search(self, query_string):
        database = xapian.Database(settings.HAYSTACK_XAPIAN_PATH)
        if query_string:
            qp = xapian.QueryParser()
            qp.set_database(database)
            query = qp.parse_query(query_string, xapian.QueryParser.FLAG_WILDCARD)
        else:
            query = xapian.Query(query_string) # Empty query matches all
        enquire = xapian.Enquire(database)
        enquire.set_query(query)
        matches = enquire.get_mset(0, DEFAULT_MAX_RESULTS)
        
        document_list = []
        
        for match in matches:
            document = match.get_document()
            app_label, module_name, pk, model_data = pickle.loads(document.get_data())
            for key, value in model_data.iteritems():
                model_data[key] = self.sb._marshal_value(value)
            model_data['id'] = u'%s.%s.%d' % (app_label, module_name, pk)
            document_list.append(model_data)

        return document_list
    
    def test_update(self):
        self.sb.update(self.msi, self.sample_objs)
        self.sb.update(self.msi, self.sample_objs) # Duplicates should be updated, not appended -- http://github.com/notanumber/xapian-haystack/issues/#issue/6
        
        self.assertEqual(len(self.xapian_search('')), 3)
        self.assertEqual([dict(doc) for doc in self.xapian_search('')], [
            {'flag': u't', 'name': u'david1', 'text': u'Indexed!\n1', 'sites': u"['1', '2', '3']", 'pub_date': u'20090224000000', 'value': '000000000005', 'id': u'core.mockmodel.1', 'slug': 'http://example.com/1', 'popularity': '\xca\x84'},
            {'flag': u'f', 'name': u'david2', 'text': u'Indexed!\n2', 'sites': u"['2', '4', '6']", 'pub_date': u'20090223000000', 'value': '000000000010', 'id': u'core.mockmodel.2', 'slug': 'http://example.com/2', 'popularity': '\xb4`'},
            {'flag': u't', 'name': u'david3', 'text': u'Indexed!\n3', 'sites': u"['3', '6', '9']", 'pub_date': u'20090222000000', 'value': '000000000015', 'id': u'core.mockmodel.3', 'slug': 'http://example.com/3', 'popularity': '\xcb\x98'}
        ])

    def test_remove(self):
        self.sb.update(self.msi, self.sample_objs)
        self.assertEqual(len(self.xapian_search('')), 3)
        
        self.sb.remove(self.sample_objs[0])
        self.assertEqual(len(self.xapian_search('')), 2)
        self.assertEqual([dict(doc) for doc in self.xapian_search('')], [
            {'flag': u'f', 'name': u'david2', 'text': u'Indexed!\n2', 'sites': u"['2', '4', '6']", 'pub_date': u'20090223000000', 'value': '000000000010', 'id': u'core.mockmodel.2', 'slug': 'http://example.com/2', 'popularity': '\xb4`'},
            {'flag': u't', 'name': u'david3', 'text': u'Indexed!\n3', 'sites': u"['3', '6', '9']", 'pub_date': u'20090222000000', 'value': '000000000015', 'id': u'core.mockmodel.3', 'slug': 'http://example.com/3', 'popularity': '\xcb\x98'}
        ])
    
    def test_clear(self):
        self.sb.update(self.msi, self.sample_objs)
        self.assertEqual(len(self.xapian_search('')), 3)
        
        self.sb.clear()
        self.assertEqual(len(self.xapian_search('')), 0)
        
        self.sb.update(self.msi, self.sample_objs)
        self.assertEqual(len(self.xapian_search('')), 3)
        
        self.sb.clear([AnotherMockModel])
        self.assertEqual(len(self.xapian_search('')), 3)
        
        self.sb.clear([MockModel])
        self.assertEqual(len(self.xapian_search('')), 0)
        
        self.sb.update(self.msi, self.sample_objs)
        self.assertEqual(len(self.xapian_search('')), 3)
        
        self.sb.clear([AnotherMockModel, MockModel])
        self.assertEqual(len(self.xapian_search('')), 0)
    
    def test_search(self):
        self.sb.update(self.msi, self.sample_objs)
        self.assertEqual(len(self.xapian_search('')), 3)
        
        # Empty query
        self.assertEqual(self.sb.search(''), {'hits': 0, 'results': []})
        
        # Wildcard -- All
        self.assertEqual(self.sb.search('*')['hits'], 3)
        self.assertEqual([result.pk for result in self.sb.search('*')['results']], [1, 2, 3])
        
        # NOT operator
        self.assertEqual([result.pk for result in self.sb.search('NOT name:david1')['results']], [2, 3])
        self.assertEqual([result.pk for result in self.sb.search('NOT name:david1 AND index')['results']], [2, 3])
        self.assertEqual([result.pk for result in self.sb.search('index NOT name:david1')['results']], [2, 3])
        self.assertEqual([result.pk for result in self.sb.search('index NOT name:david1 NOT name:david2')['results']], [3])
        self.assertEqual([result.pk for result in self.sb.search('NOT name:david1 NOT name:david2')['results']], [3])

        # Ranges
        self.assertEqual([result.pk for result in self.sb.search('index name:david2..david3')['results']], [2, 3])
        self.assertEqual([result.pk for result in self.sb.search('index name:..david2')['results']], [1, 2])
        self.assertEqual([result.pk for result in self.sb.search('index name:david2..*')['results']], [2, 3])
        self.assertEqual([result.pk for result in self.sb.search('index pub_date:20090222000000..20090223000000')['results']], [2, 3])        
        self.assertEqual([result.pk for result in self.sb.search('index pub_date:..20090223000000')['results']], [2, 3])        
        self.assertEqual([result.pk for result in self.sb.search('index pub_date:20090223000000..*')['results']], [1, 2])        
        self.assertEqual([result.pk for result in self.sb.search('index value:10..15')['results']], [2, 3])
        self.assertEqual([result.pk for result in self.sb.search('index value:..10')['results']], [1, 2])
        self.assertEqual([result.pk for result in self.sb.search('index value:10..*')['results']], [2, 3])
        self.assertEqual([result.pk for result in self.sb.search('index popularity:..100.0')['results']], [2])
        self.assertEqual([result.pk for result in self.sb.search('index popularity:100.0..*')['results']], [1, 3])

    def test_field_facets(self):
        self.sb.update(self.msi, self.sample_objs)
        self.assertEqual(len(self.xapian_search('')), 3)
        
        self.assertEqual(self.sb.search('', facets=['name']), {'hits': 0, 'results': []})
        results = self.sb.search('index', facets=['name'])
        self.assertEqual(results['hits'], 3)
        self.assertEqual(results['facets']['fields']['name'], [('david1', 1), ('david2', 1), ('david3', 1)])

        results = self.sb.search('index', facets=['flag'])
        self.assertEqual(results['hits'], 3)
        self.assertEqual(results['facets']['fields']['flag'], [(False, 1), (True, 2)])
        
        results = self.sb.search('index', facets=['sites'])
        self.assertEqual(results['hits'], 3)
        self.assertEqual(results['facets']['fields']['sites'], [('1', 1), ('3', 2), ('2', 2), ('4', 1), ('6', 2), ('9', 1)])
            
    def test_date_facets(self):
        self.sb.update(self.msi, self.sample_objs)
        self.assertEqual(len(self.xapian_search('')), 3)

        self.assertEqual(self.sb.search('', date_facets={'pub_date': {'start_date': datetime.datetime(2008, 10, 26), 'end_date': datetime.datetime(2009, 3, 26), 'gap_by': 'month'}}), {'hits': 0, 'results': []})
        results = self.sb.search('index', date_facets={'pub_date': {'start_date': datetime.datetime(2008, 10, 26), 'end_date': datetime.datetime(2009, 3, 26), 'gap_by': 'month'}})
        self.assertEqual(results['hits'], 3)
        self.assertEqual(results['facets']['dates']['pub_date'], [
            ('2009-02-26T00:00:00', 0),
            ('2009-01-26T00:00:00', 3),
            ('2008-12-26T00:00:00', 0),
            ('2008-11-26T00:00:00', 0),
            ('2008-10-26T00:00:00', 0),
        ])

        results = self.sb.search('index', date_facets={'pub_date': {'start_date': datetime.datetime(2009, 02, 01), 'end_date': datetime.datetime(2009, 3, 15), 'gap_by': 'day', 'gap_amount': 15}})
Example #17
0
class XapianSearchBackendTestCase(TestCase):
    def setUp(self):
        super(XapianSearchBackendTestCase, self).setUp()

        temp_path = os.path.join('tmp', 'test_xapian_query')
        self.old_xapian_path = getattr(settings, 'HAYSTACK_XAPIAN_PATH', temp_path)
        settings.HAYSTACK_XAPIAN_PATH = temp_path

        self.site = XapianSearchSite()
        self.sb = SearchBackend(site=self.site)
        self.msi = XapianMockSearchIndex(MockModel, backend=self.sb)
        self.site.register(MockModel, XapianMockSearchIndex)

        self.sample_objs = []

        for i in xrange(1, 4):
            mock = MockModel()
            mock.id = i
            mock.author = 'david%s' % i
            mock.pub_date = datetime.date(2009, 2, 25) - datetime.timedelta(days=i)
            mock.value = i * 5
            mock.flag = bool(i % 2)
            self.sample_objs.append(mock)

    def tearDown(self):
        if os.path.exists(settings.HAYSTACK_XAPIAN_PATH):
            index_files = os.listdir(settings.HAYSTACK_XAPIAN_PATH)

            for index_file in index_files:
                os.remove(os.path.join(settings.HAYSTACK_XAPIAN_PATH, index_file))

            os.removedirs(settings.HAYSTACK_XAPIAN_PATH)

        settings.HAYSTACK_XAPIAN_PATH = self.old_xapian_path
        super(XapianSearchBackendTestCase, self).tearDown()

    def xapian_search(self, query_string):
        database = xapian.Database(settings.HAYSTACK_XAPIAN_PATH)
        if query_string:
            qp = xapian.QueryParser()
            qp.set_database(database)
            query = qp.parse_query(query_string, xapian.QueryParser.FLAG_WILDCARD)
        else:
            query = xapian.Query(query_string) # Empty query matches all
        enquire = xapian.Enquire(database)
        enquire.set_query(query)
        matches = enquire.get_mset(0, DEFAULT_MAX_RESULTS)

        document_list = []

        for match in matches:
            document = match.get_document()
            object_data = pickle.loads(document.get_data())
            for key, value in object_data.iteritems():
                object_data[key] = self.sb._from_python(value)
            object_data['id'] = force_unicode(document.get_value(0))
            document_list.append(object_data)

        return document_list
    
    def test_update(self):
        self.sb.update(self.msi, self.sample_objs)
        self.sb.update(self.msi, self.sample_objs) # Duplicates should be updated, not appended -- http://github.com/notanumber/xapian-haystack/issues/#issue/6

        self.assertEqual(len(self.xapian_search('')), 3)
        self.assertEqual([dict(doc) for doc in self.xapian_search('')], [{'flag': u'true', 'name': u'david1', 'text': u'Indexed!\n1', 'pub_date': u'2009-02-24T00:00:00', 'value': u'5', 'id': u'tests.mockmodel.1'}, {'flag': u'false', 'name': u'david2', 'text': u'Indexed!\n2', 'pub_date': u'2009-02-23T00:00:00', 'value': u'10', 'id': u'tests.mockmodel.2'}, {'flag': u'true', 'name': u'david3', 'text': u'Indexed!\n3', 'pub_date': u'2009-02-22T00:00:00', 'value': u'15', 'id': u'tests.mockmodel.3'}])

    def test_remove(self):
        self.sb.update(self.msi, self.sample_objs)
        self.assertEqual(len(self.xapian_search('')), 3)

        self.sb.remove(self.sample_objs[0])
        self.assertEqual(len(self.xapian_search('')), 2)
        self.assertEqual([dict(doc) for doc in self.xapian_search('')], [{'flag': u'false', 'name': u'david2', 'text': u'Indexed!\n2', 'pub_date': u'2009-02-23T00:00:00', 'value': u'10', 'id': u'tests.mockmodel.2'}, {'flag': u'true', 'name': u'david3', 'text': u'Indexed!\n3', 'pub_date': u'2009-02-22T00:00:00', 'value': u'15', 'id': u'tests.mockmodel.3'}])

    def test_clear(self):
        self.sb.update(self.msi, self.sample_objs)
        self.assertEqual(len(self.xapian_search('')), 3)
        
        self.sb.clear()
        self.assertEqual(len(self.xapian_search('')), 0)
        
        self.sb.update(self.msi, self.sample_objs)
        self.assertEqual(len(self.xapian_search('')), 3)
        
        self.sb.clear([AnotherMockModel])
        self.assertEqual(len(self.xapian_search('')), 3)
        
        self.sb.clear([MockModel])
        self.assertEqual(len(self.xapian_search('')), 0)
        
        self.sb.update(self.msi, self.sample_objs)
        self.assertEqual(len(self.xapian_search('')), 3)
        
        self.sb.clear([AnotherMockModel, MockModel])
        self.assertEqual(len(self.xapian_search('')), 0)
    
    def test_search(self):
        self.sb.update(self.msi, self.sample_objs)
        self.assertEqual(len(self.xapian_search('')), 3)
        
        self.assertEqual(self.sb.search(''), {'hits': 0, 'results': []})
        self.assertEqual(self.sb.search('*')['hits'], 3)
        self.assertEqual([result.pk for result in self.sb.search('*')['results']], [u'1', u'2', u'3'])
        
        # self.assertEqual(self.sb.search('', highlight=True), {'hits': 0, 'results': []})
        # self.assertEqual(self.sb.search('Index*', highlight=True)['hits'], 3)
        # self.assertEqual([result.highlighted['text'][0] for result in self.sb.search('Index*', highlight=True)['results']], ['<em>Indexed</em>!\n3', '<em>Indexed</em>!\n2', '<em>Indexed</em>!\n1'])
        # 
        self.assertEqual(self.sb.search('', facets=['name']), {'hits': 0, 'results': []})
        results = self.sb.search('index', facets=['name'])
        self.assertEqual(results['hits'], 3)
        self.assertEqual(results['facets']['fields']['name'], [('david1', 1), ('david2', 1), ('david3', 1)])

    #     self.assertEqual(self.sb.search('', date_facets={'pub_date': {'start_date': datetime.date(2008, 2, 26), 'end_date': datetime.date(2008, 2, 26), 'gap': '/MONTH'}}), [])
    #     results = self.sb.search('Index*', date_facets={'pub_date': {'start_date': datetime.date(2008, 2, 26), 'end_date': datetime.date(2008, 2, 26), 'gap': '/MONTH'}})
    #     self.assertEqual(results['hits'], 3)
    #     self.assertEqual(results['facets'], {})
    #     
    #     self.assertEqual(self.sb.search('', query_facets={'name': '[* TO e]'}), [])
    #     results = self.sb.search('Index*', query_facets={'name': '[* TO e]'})
    #     self.assertEqual(results['hits'], 3)
    #     self.assertEqual(results['facets'], {})

        self.assertEqual(self.sb.search('', narrow_queries=['name:david1']), {'hits': 0, 'results': []})
        results = self.sb.search('index*', narrow_queries=['name:david1'])
        self.assertEqual(results['hits'], 1)

    def test_spelling_suggestion(self):
        self.sb.update(self.msi, self.sample_objs)
        self.assertEqual(len(self.xapian_search('')), 3)

        self.assertEqual(self.sb.search('indxe')['hits'], 0)
        self.assertEqual(self.sb.search('indxe')['spelling_suggestion'], 'indexed')

        self.assertEqual(self.sb.search('indxed')['hits'], 0)
        self.assertEqual(self.sb.search('indxed')['spelling_suggestion'], 'indexed')

    def test_stemming(self):
        self.sb.update(self.msi, self.sample_objs)
        self.assertEqual(len(self.xapian_search('')), 3)

        results = self.sb.search('index', facets=['name'])
        self.assertEqual(results['hits'], 3)

        results = self.sb.search('indexing', facets=['name'])
        self.assertEqual(results['hits'], 3)

    def test_more_like_this(self):
        self.sb.update(self.msi, self.sample_objs)
        self.assertEqual(len(self.xapian_search('')), 3)

        results = self.sb.more_like_this(self.sample_objs[0])
        self.assertEqual(results['hits'], 2)
        self.assertEqual([result.pk for result in results['results']], [u'3', u'2'])

    def test_document_count(self):
        self.sb.update(self.msi, self.sample_objs)
        self.assertEqual(self.sb.document_count(), 3)

    def test_delete_index(self):
        self.sb.update(self.msi, self.sample_objs)
        self.assert_(self.sb.document_count() > 0)

        self.sb.delete_index()
        self.assertEqual(self.sb.document_count(), 0)

    def test_order_by(self):
        self.sb.update(self.msi, self.sample_objs)

        results = self.sb.search('*', sort_by=['pub_date'])
        self.assertEqual([result.pk for result in results['results']], [u'1', u'2', u'3'])

        results = self.sb.search('*', sort_by=['-pub_date'])
        self.assertEqual([result.pk for result in results['results']], [u'3', u'2', u'1'])

        results = self.sb.search('*', sort_by=['id'])
        self.assertEqual([result.pk for result in results['results']], [u'3', u'2', u'1'])

        results = self.sb.search('*', sort_by=['-id'])
        self.assertEqual([result.pk for result in results['results']], [u'1', u'2', u'3'])

        results = self.sb.search('*', sort_by=['value'])
        self.assertEqual([result.pk for result in results['results']], [u'3', u'2', u'1'])

        results = self.sb.search('*', sort_by=['-value'])
        self.assertEqual([result.pk for result in results['results']], [u'1', u'2', u'3'])

        results = self.sb.search('*', sort_by=['flag', 'id'])
        self.assertEqual([result.pk for result in results['results']], [u'3', u'1', u'2'])

        results = self.sb.search('*', sort_by=['flag', '-id'])
        self.assertEqual([result.pk for result in results['results']], [u'1', u'3', u'2'])

    def test__from_python(self):
        self.assertEqual(self.sb._from_python('abc'), u'abc')
        self.assertEqual(self.sb._from_python(1), u'1')
        self.assertEqual(self.sb._from_python(2653), u'2653')
        self.assertEqual(self.sb._from_python(25.5), u'25.5')
        self.assertEqual(self.sb._from_python([1, 2, 3]), u'[1, 2, 3]')
        self.assertEqual(self.sb._from_python((1, 2, 3)), u'(1, 2, 3)')
        self.assertEqual(self.sb._from_python({'a': 1, 'c': 3, 'b': 2}), u"{'a': 1, 'c': 3, 'b': 2}")
        self.assertEqual(self.sb._from_python(datetime.datetime(2009, 5, 9, 16, 14)), u'2009-05-09T16:14:00')
        self.assertEqual(self.sb._from_python(datetime.datetime(2009, 5, 9, 0, 0)), u'2009-05-09T00:00:00')
        self.assertEqual(self.sb._from_python(datetime.datetime(1899, 5, 18, 0, 0)), u'1899-05-18T00:00:00')
        self.assertEqual(self.sb._from_python(datetime.datetime(2009, 5, 18, 1, 16, 30, 250)), u'2009-05-18T01:16:30.000250')