mirror of
https://github.com/Hopiu/xapian-haystack.git
synced 2026-03-16 22:20:31 +00:00
Major re-organization of tests. No new test.
This commit is contained in:
parent
6756b685f1
commit
fdc91c6892
5 changed files with 331 additions and 323 deletions
|
|
@ -1,5 +1,7 @@
|
|||
from django.db import models
|
||||
|
||||
from ..core.models import MockTag, AnotherMockModel, MockModel, AFourthMockModel
|
||||
|
||||
|
||||
class Document(models.Model):
|
||||
type_name = models.CharField(max_length=50)
|
||||
|
|
@ -10,3 +12,25 @@ class Document(models.Model):
|
|||
|
||||
summary = models.TextField()
|
||||
text = models.TextField()
|
||||
|
||||
|
||||
class BlogEntry(models.Model):
|
||||
"""
|
||||
Same as tests.core.MockModel with a few extra fields for testing various
|
||||
sorting and ordering criteria.
|
||||
"""
|
||||
datetime = models.DateTimeField()
|
||||
date = models.DateField()
|
||||
|
||||
tags = models.ManyToManyField(MockTag)
|
||||
|
||||
author = models.CharField(max_length=255)
|
||||
text = models.TextField()
|
||||
funny_text = models.TextField()
|
||||
non_ascii = models.TextField()
|
||||
url = models.URLField()
|
||||
|
||||
boolean = models.BooleanField()
|
||||
number = models.IntegerField()
|
||||
float_number = models.FloatField()
|
||||
decimal_number = models.DecimalField(max_digits=4, decimal_places=2)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from haystack import indexes
|
||||
|
||||
from . import models
|
||||
|
|
@ -24,3 +26,130 @@ class DocumentIndex(indexes.SearchIndex, indexes.Indexable):
|
|||
['tag', 'tag-test'],
|
||||
['tag']]
|
||||
return l[obj.id % 3]
|
||||
|
||||
|
||||
class BlogSearchIndex(indexes.SearchIndex):
|
||||
text = indexes.CharField(
|
||||
document=True, use_template=True,
|
||||
template_name='search/indexes/core/mockmodel_text.txt'
|
||||
)
|
||||
name = indexes.CharField(model_attr='author', faceted=True)
|
||||
date = indexes.DateField(model_attr='date')
|
||||
datetime = indexes.DateField(model_attr='datetime')
|
||||
number = indexes.IntegerField(model_attr='number')
|
||||
boolean = indexes.BooleanField(model_attr='boolean')
|
||||
#slug = indexes.CharField(indexed=False, model_attr='slug')
|
||||
float_number = indexes.FloatField(model_attr='float_number')
|
||||
month = indexes.CharField(indexed=False)
|
||||
url = indexes.CharField(model_attr='url')
|
||||
empty = indexes.CharField()
|
||||
|
||||
# Various MultiValueFields
|
||||
sites = indexes.MultiValueField()
|
||||
tags = indexes.MultiValueField()
|
||||
keys = indexes.MultiValueField()
|
||||
titles = indexes.MultiValueField()
|
||||
|
||||
def get_model(self):
|
||||
return models.BlogEntry
|
||||
|
||||
def prepare_sites(self, obj):
|
||||
return ['%d' % (i * obj.id) for i in range(1, 4)]
|
||||
|
||||
def prepare_tags(self, obj):
|
||||
if obj.id == 1:
|
||||
return ['a', 'b', 'c']
|
||||
elif obj.id == 2:
|
||||
return ['ab', 'bc', 'cd']
|
||||
else:
|
||||
return ['an', 'to', 'or']
|
||||
|
||||
def prepare_keys(self, obj):
|
||||
return [i * obj.id for i in range(1, 4)]
|
||||
|
||||
def prepare_titles(self, obj):
|
||||
if obj.id == 1:
|
||||
return ['object one title one', 'object one title two']
|
||||
elif obj.id == 2:
|
||||
return ['object two title one', 'object two title two']
|
||||
else:
|
||||
return ['object three title one', 'object three title two']
|
||||
|
||||
def prepare_month(self, obj):
|
||||
return '%02d' % obj.date.month
|
||||
|
||||
def prepare_empty(self, obj):
|
||||
return ''
|
||||
|
||||
|
||||
class CompleteBlogEntryIndex(indexes.SearchIndex):
|
||||
text = indexes.CharField(model_attr='text', document=True)
|
||||
author = indexes.CharField(model_attr='author')
|
||||
url = indexes.CharField(model_attr='url')
|
||||
non_ascii = indexes.CharField(model_attr='non_ascii')
|
||||
funny_text = indexes.CharField(model_attr='funny_text')
|
||||
|
||||
datetime = indexes.DateTimeField(model_attr='datetime')
|
||||
date = indexes.DateField(model_attr='date')
|
||||
|
||||
boolean = indexes.BooleanField(model_attr='boolean')
|
||||
number = indexes.IntegerField(model_attr='number')
|
||||
float_number = indexes.FloatField(model_attr='float_number')
|
||||
decimal_number = indexes.DecimalField(model_attr='decimal_number')
|
||||
|
||||
multi_value = indexes.MultiValueField()
|
||||
|
||||
def get_model(self):
|
||||
return models.BlogEntry
|
||||
|
||||
def prepare_multi_value(self, obj):
|
||||
return [tag.name for tag in obj.tags.all()]
|
||||
|
||||
|
||||
class XapianNGramIndex(indexes.SearchIndex):
|
||||
text = indexes.CharField(model_attr='author', document=True)
|
||||
ngram = indexes.NgramField(model_attr='author')
|
||||
|
||||
def get_model(self):
|
||||
return models.BlogEntry
|
||||
|
||||
|
||||
class XapianEdgeNGramIndex(indexes.SearchIndex):
|
||||
text = indexes.CharField(model_attr='author', document=True)
|
||||
edge_ngram = indexes.EdgeNgramField(model_attr='author')
|
||||
|
||||
def get_model(self):
|
||||
return models.BlogEntry
|
||||
|
||||
|
||||
class MockSearchIndex(indexes.SearchIndex):
|
||||
text = indexes.CharField(document=True, use_template=True)
|
||||
name = indexes.CharField(model_attr='author', faceted=True)
|
||||
pub_date = indexes.DateTimeField(model_attr='pub_date')
|
||||
title = indexes.CharField()
|
||||
|
||||
def get_model(self):
|
||||
return models.MockModel
|
||||
|
||||
|
||||
class BoostMockSearchIndex(indexes.SearchIndex):
|
||||
text = indexes.CharField(
|
||||
document=True, use_template=True,
|
||||
template_name='search/indexes/core/mockmodel_template.txt'
|
||||
)
|
||||
author = indexes.CharField(model_attr='author', weight=2.0)
|
||||
editor = indexes.CharField(model_attr='editor')
|
||||
pub_date = indexes.DateField(model_attr='pub_date')
|
||||
|
||||
def get_model(self):
|
||||
return models.AFourthMockModel
|
||||
|
||||
|
||||
class MockQueryIndex(indexes.SearchIndex):
|
||||
text = indexes.CharField(document=True)
|
||||
pub_date = indexes.DateTimeField()
|
||||
title = indexes.CharField()
|
||||
foo = indexes.CharField()
|
||||
|
||||
def get_model(self):
|
||||
return models.MockModel
|
||||
|
|
|
|||
|
|
@ -1,185 +1,45 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from decimal import Decimal
|
||||
import datetime
|
||||
import sys
|
||||
import xapian
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
from django.db import models
|
||||
from django.test import TestCase
|
||||
from django.db.models.loading import get_model
|
||||
|
||||
from haystack import connections
|
||||
from haystack import indexes
|
||||
from haystack.backends.xapian_backend import InvalidIndexError, _term_to_xapian_value
|
||||
from haystack.models import SearchResult
|
||||
from haystack.utils.loading import UnifiedIndex
|
||||
|
||||
from ...core.models import AnotherMockModel, MockTag
|
||||
from ..search_indexes import XapianNGramIndex, XapianEdgeNGramIndex, \
|
||||
CompleteBlogEntryIndex, BlogSearchIndex
|
||||
from ..models import BlogEntry, AnotherMockModel, MockTag
|
||||
|
||||
|
||||
class XapianMockSearchResult(SearchResult):
|
||||
class XapianSearchResult(SearchResult):
|
||||
def __init__(self, app_label, model_name, pk, score, **kwargs):
|
||||
super(XapianMockSearchResult, self).__init__(app_label, model_name, pk, score, **kwargs)
|
||||
super(XapianSearchResult, self).__init__(app_label, model_name, pk, score, **kwargs)
|
||||
self._model = get_model('xapian_tests', model_name)
|
||||
|
||||
|
||||
def get_terms(backend, *args):
|
||||
result = subprocess.check_output(['delve'] + list(args) + [backend.path],
|
||||
env=os.environ.copy()).decode('utf-8')
|
||||
result = result.split(": ")[1].strip()
|
||||
return result.split(" ")
|
||||
result = result.split(": ")
|
||||
if len(result) > 1:
|
||||
return result[1].strip().split(" ")
|
||||
|
||||
return []
|
||||
|
||||
|
||||
def pks(results):
|
||||
return [result.pk for result in results]
|
||||
|
||||
|
||||
class XapianMockModel(models.Model):
|
||||
"""
|
||||
Same as tests.core.MockModel with a few extra fields for testing various
|
||||
sorting and ordering criteria.
|
||||
"""
|
||||
author = models.CharField(max_length=255)
|
||||
foo = models.CharField(max_length=255, blank=True)
|
||||
pub_date = models.DateTimeField(default=datetime.datetime.now)
|
||||
exp_date = models.DateTimeField(default=datetime.datetime.now)
|
||||
tag = models.ForeignKey(MockTag)
|
||||
|
||||
value = models.IntegerField(default=0)
|
||||
flag = models.BooleanField(default=True)
|
||||
slug = models.SlugField()
|
||||
popularity = models.FloatField(default=0.0)
|
||||
url = models.URLField()
|
||||
|
||||
def __unicode__(self):
|
||||
return self.author
|
||||
|
||||
|
||||
class XapianMockSearchIndex(indexes.SearchIndex):
|
||||
text = indexes.CharField(
|
||||
document=True, use_template=True,
|
||||
template_name='search/indexes/core/mockmodel_text.txt'
|
||||
)
|
||||
name = indexes.CharField(model_attr='author', faceted=True)
|
||||
pub_date = indexes.DateField(model_attr='pub_date')
|
||||
exp_date = indexes.DateField(model_attr='exp_date')
|
||||
value = indexes.IntegerField(model_attr='value')
|
||||
flag = indexes.BooleanField(model_attr='flag')
|
||||
slug = indexes.CharField(indexed=False, model_attr='slug')
|
||||
popularity = indexes.FloatField(model_attr='popularity')
|
||||
month = indexes.CharField(indexed=False)
|
||||
url = indexes.CharField(model_attr='url')
|
||||
empty = indexes.CharField()
|
||||
|
||||
# Various MultiValueFields
|
||||
sites = indexes.MultiValueField()
|
||||
tags = indexes.MultiValueField()
|
||||
keys = indexes.MultiValueField()
|
||||
titles = indexes.MultiValueField()
|
||||
|
||||
def get_model(self):
|
||||
return XapianMockModel
|
||||
|
||||
def prepare_sites(self, obj):
|
||||
return ['%d' % (i * obj.id) for i in range(1, 4)]
|
||||
|
||||
def prepare_tags(self, obj):
|
||||
if obj.id == 1:
|
||||
return ['a', 'b', 'c']
|
||||
elif obj.id == 2:
|
||||
return ['ab', 'bc', 'cd']
|
||||
else:
|
||||
return ['an', 'to', 'or']
|
||||
|
||||
def prepare_keys(self, obj):
|
||||
return [i * obj.id for i in range(1, 4)]
|
||||
|
||||
def prepare_titles(self, obj):
|
||||
if obj.id == 1:
|
||||
return ['object one title one', 'object one title two']
|
||||
elif obj.id == 2:
|
||||
return ['object two title one', 'object two title two']
|
||||
else:
|
||||
return ['object three title one', 'object three title two']
|
||||
|
||||
def prepare_month(self, obj):
|
||||
return '%02d' % obj.pub_date.month
|
||||
|
||||
def prepare_empty(self, obj):
|
||||
return ''
|
||||
|
||||
|
||||
class XapianSimpleMockIndex(indexes.SearchIndex):
|
||||
text = indexes.CharField(document=True)
|
||||
author = indexes.CharField(model_attr='author')
|
||||
url = indexes.CharField()
|
||||
non_anscii = indexes.CharField()
|
||||
funny_text = indexes.CharField()
|
||||
|
||||
datetime = indexes.DateTimeField(model_attr='pub_date')
|
||||
date = indexes.DateField()
|
||||
|
||||
number = indexes.IntegerField()
|
||||
float_number = indexes.FloatField()
|
||||
decimal_number = indexes.DecimalField()
|
||||
|
||||
multi_value = indexes.MultiValueField()
|
||||
|
||||
def get_model(self):
|
||||
return XapianMockModel
|
||||
|
||||
def prepare_text(self, obj):
|
||||
return 'this_is_a_word inside a big text'
|
||||
|
||||
def prepare_author(self, obj):
|
||||
return 'david holland'
|
||||
|
||||
def prepare_url(self, obj):
|
||||
return 'http://example.com/1/'
|
||||
|
||||
def prepare_non_anscii(self, obj):
|
||||
return 'thsi sdas das corrup\xe7\xe3o das'
|
||||
|
||||
def prepare_funny_text(self, obj):
|
||||
return 'this-text has funny.words!!'
|
||||
|
||||
def prepare_datetime(self, obj):
|
||||
return datetime.datetime(2009, 2, 25, 1, 1, 1)
|
||||
|
||||
def prepare_date(self, obj):
|
||||
return datetime.date(2008, 8, 8)
|
||||
|
||||
def prepare_number(self, obj):
|
||||
return 123456789
|
||||
|
||||
def prepare_float_number(self, obj):
|
||||
return 123.123456789
|
||||
|
||||
def prepare_decimal_number(self, obj):
|
||||
return '22.34'
|
||||
|
||||
def prepare_multi_value(self, obj):
|
||||
return ['tag', 'tag-tag', 'tag-tag-tag']
|
||||
|
||||
|
||||
class XapianNGramIndex(indexes.SearchIndex):
|
||||
text = indexes.CharField(model_attr='author', document=True)
|
||||
ngram = indexes.NgramField(model_attr='author')
|
||||
|
||||
def get_model(self):
|
||||
return XapianMockModel
|
||||
|
||||
|
||||
class XapianEdgeNGramIndex(indexes.SearchIndex):
|
||||
text = indexes.CharField(model_attr='author', document=True)
|
||||
edge_ngram = indexes.EdgeNgramField(model_attr='author')
|
||||
|
||||
def get_model(self):
|
||||
return XapianMockModel
|
||||
|
||||
|
||||
class HaystackBackendTestCase(object):
|
||||
"""
|
||||
Abstract TestCase that implements an hack to ensure `connections`
|
||||
|
|
@ -191,9 +51,6 @@ class HaystackBackendTestCase(object):
|
|||
def get_index(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def get_objects(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def setUp(self):
|
||||
self.old_ui = connections['default'].get_unified_index()
|
||||
self.ui = UnifiedIndex()
|
||||
|
|
@ -216,14 +73,34 @@ class BackendIndexationTestCase(HaystackBackendTestCase, TestCase):
|
|||
"""
|
||||
|
||||
def get_index(self):
|
||||
return XapianSimpleMockIndex()
|
||||
return CompleteBlogEntryIndex()
|
||||
|
||||
def setUp(self):
|
||||
super(BackendIndexationTestCase, self).setUp()
|
||||
mock = XapianMockModel()
|
||||
mock.id = 1
|
||||
mock.author = u'david'
|
||||
self.backend.update(self.index, [mock])
|
||||
|
||||
tag1 = MockTag.objects.create(name='tag')
|
||||
tag2 = MockTag.objects.create(name='tag-tag')
|
||||
tag3 = MockTag.objects.create(name='tag-tag-tag')
|
||||
|
||||
entry = BlogEntry()
|
||||
entry.id = 1
|
||||
entry.text = 'this_is_a_word inside a big text'
|
||||
entry.author = 'david'
|
||||
entry.url = 'http://example.com/1/'
|
||||
entry.boolean = True
|
||||
entry.number = 123456789
|
||||
entry.float_number = 123.123456789
|
||||
entry.decimal_number = Decimal('22.34')
|
||||
entry.funny_text = 'this-text das das'
|
||||
entry.non_ascii = 'thsi sdas das corrup\xe7\xe3o das'
|
||||
entry.datetime = datetime.datetime(2009, 2, 25, 1, 1, 1)
|
||||
entry.date = datetime.date(2008, 8, 8)
|
||||
entry.save()
|
||||
entry.tags.add(tag1, tag2, tag3)
|
||||
|
||||
self.backend.update(self.index, [entry])
|
||||
|
||||
self.entry = entry
|
||||
|
||||
def test_app_is_not_split(self):
|
||||
"""
|
||||
|
|
@ -329,6 +206,11 @@ class BackendIndexationTestCase(HaystackBackendTestCase, TestCase):
|
|||
terms = get_terms(self.backend, '-a')
|
||||
self.assertTrue('http://example.com/1/' in terms)
|
||||
|
||||
def test_bool_field(self):
|
||||
terms = get_terms(self.backend, '-a')
|
||||
self.assertTrue('XBOOLEANtrue' in terms)
|
||||
self.assertFalse('ZXBOOLEANtrue' in terms)
|
||||
|
||||
def test_integer_field(self):
|
||||
terms = get_terms(self.backend, '-a')
|
||||
self.assertTrue('123456789' in terms)
|
||||
|
|
@ -374,7 +256,21 @@ class BackendFeaturesTestCase(HaystackBackendTestCase, TestCase):
|
|||
"""
|
||||
|
||||
def get_index(self):
|
||||
return XapianMockSearchIndex()
|
||||
return BlogSearchIndex()
|
||||
|
||||
@staticmethod
|
||||
def get_entry(i):
|
||||
entry = BlogEntry()
|
||||
entry.id = i
|
||||
entry.author = 'david%s' % i
|
||||
entry.url = 'http://example.com/%d/' % i
|
||||
entry.boolean = bool(i % 2)
|
||||
entry.number = i*5
|
||||
entry.float_number = i*5.0
|
||||
entry.decimal_number = Decimal('22.34')
|
||||
entry.datetime = datetime.datetime(2009, 2, 25, 1, 1, 1) - datetime.timedelta(seconds=i)
|
||||
entry.date = datetime.date(2009, 2, 23) + datetime.timedelta(days=i)
|
||||
return entry
|
||||
|
||||
def setUp(self):
|
||||
super(BackendFeaturesTestCase, self).setUp()
|
||||
|
|
@ -382,22 +278,16 @@ class BackendFeaturesTestCase(HaystackBackendTestCase, TestCase):
|
|||
self.sample_objs = []
|
||||
|
||||
for i in range(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)
|
||||
entry = self.get_entry(i)
|
||||
self.sample_objs.append(entry)
|
||||
|
||||
self.sample_objs[0].popularity = 834.0
|
||||
self.sample_objs[1].popularity = 35.5
|
||||
self.sample_objs[2].popularity = 972.0
|
||||
self.sample_objs[0].float_number = 834.0
|
||||
self.sample_objs[1].float_number = 35.5
|
||||
self.sample_objs[2].float_number = 972.0
|
||||
for obj in self.sample_objs:
|
||||
obj.save()
|
||||
|
||||
self.backend.update(self.index, self.sample_objs)
|
||||
self.backend.update(self.index, BlogEntry.objects.all())
|
||||
|
||||
def test_update(self):
|
||||
self.assertEqual(pks(self.backend.search(xapian.Query(''))['results']),
|
||||
|
|
@ -425,13 +315,13 @@ class BackendFeaturesTestCase(HaystackBackendTestCase, TestCase):
|
|||
self.backend.clear([AnotherMockModel])
|
||||
self.assertEqual(self.backend.document_count(), 3)
|
||||
|
||||
self.backend.clear([XapianMockModel])
|
||||
self.backend.clear([BlogEntry])
|
||||
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.backend.clear([AnotherMockModel, BlogEntry])
|
||||
self.assertEqual(self.backend.document_count(), 0)
|
||||
|
||||
def test_search(self):
|
||||
|
|
@ -443,8 +333,8 @@ class BackendFeaturesTestCase(HaystackBackendTestCase, TestCase):
|
|||
|
||||
# Other `result_class`
|
||||
self.assertTrue(
|
||||
isinstance(self.backend.search(xapian.Query('indexed'), result_class=XapianMockSearchResult)['results'][0],
|
||||
XapianMockSearchResult))
|
||||
isinstance(self.backend.search(xapian.Query('indexed'), result_class=XapianSearchResult)['results'][0],
|
||||
XapianSearchResult))
|
||||
|
||||
def test_search_field_with_punctuation(self):
|
||||
self.assertEqual(pks(self.backend.search(xapian.Query('http://example.com/1/'))['results']),
|
||||
|
|
@ -465,9 +355,9 @@ class BackendFeaturesTestCase(HaystackBackendTestCase, TestCase):
|
|||
self.assertEqual(results['facets']['fields']['name'],
|
||||
[('david1', 1), ('david2', 1), ('david3', 1)])
|
||||
|
||||
results = self.backend.search(xapian.Query('indexed'), facets=['flag'])
|
||||
results = self.backend.search(xapian.Query('indexed'), facets=['boolean'])
|
||||
self.assertEqual(results['hits'], 3)
|
||||
self.assertEqual(results['facets']['fields']['flag'],
|
||||
self.assertEqual(results['facets']['fields']['boolean'],
|
||||
[(False, 1), (True, 2)])
|
||||
|
||||
results = self.backend.search(xapian.Query('indexed'), facets=['sites'])
|
||||
|
|
@ -482,7 +372,7 @@ class BackendFeaturesTestCase(HaystackBackendTestCase, TestCase):
|
|||
self.assertRaises(InvalidIndexError, self.backend.search, xapian.Query(''), facets=['dsdas'])
|
||||
|
||||
def test_date_facets(self):
|
||||
facets = {'pub_date': {'start_date': datetime.datetime(2008, 10, 26),
|
||||
facets = {'datetime': {'start_date': datetime.datetime(2008, 10, 26),
|
||||
'end_date': datetime.datetime(2009, 3, 26),
|
||||
'gap_by': 'month'}}
|
||||
|
||||
|
|
@ -491,24 +381,24 @@ class BackendFeaturesTestCase(HaystackBackendTestCase, TestCase):
|
|||
|
||||
results = self.backend.search(xapian.Query('indexed'), date_facets=facets)
|
||||
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),
|
||||
self.assertEqual(results['facets']['dates']['datetime'], [
|
||||
(b'2009-02-26T00:00:00', 0),
|
||||
(b'2009-01-26T00:00:00', 3),
|
||||
(b'2008-12-26T00:00:00', 0),
|
||||
(b'2008-11-26T00:00:00', 0),
|
||||
(b'2008-10-26T00:00:00', 0),
|
||||
])
|
||||
|
||||
facets = {'pub_date': {'start_date': datetime.datetime(2009, 2, 1),
|
||||
'end_date': datetime.datetime(2009, 3, 15),
|
||||
'gap_by': 'day',
|
||||
'gap_amount': 15}}
|
||||
facets = {'date': {'start_date': datetime.datetime(2009, 2, 1),
|
||||
'end_date': datetime.datetime(2009, 3, 15),
|
||||
'gap_by': 'day',
|
||||
'gap_amount': 15}}
|
||||
results = self.backend.search(xapian.Query('indexed'), date_facets=facets)
|
||||
self.assertEqual(results['hits'], 3)
|
||||
self.assertEqual(results['facets']['dates']['pub_date'], [
|
||||
('2009-03-03T00:00:00', 0),
|
||||
('2009-02-16T00:00:00', 3),
|
||||
('2009-02-01T00:00:00', 0)
|
||||
self.assertEqual(results['facets']['dates']['date'], [
|
||||
(b'2009-03-03T00:00:00', 0),
|
||||
(b'2009-02-16T00:00:00', 3),
|
||||
(b'2009-02-01T00:00:00', 0)
|
||||
])
|
||||
|
||||
def test_query_facets(self):
|
||||
|
|
@ -568,21 +458,22 @@ class BackendFeaturesTestCase(HaystackBackendTestCase, TestCase):
|
|||
|
||||
# Other `result_class`
|
||||
result = self.backend.more_like_this(self.sample_objs[0],
|
||||
result_class=XapianMockSearchResult)
|
||||
self.assertTrue(isinstance(result['results'][0], XapianMockSearchResult))
|
||||
result_class=XapianSearchResult)
|
||||
self.assertTrue(isinstance(result['results'][0], XapianSearchResult))
|
||||
|
||||
def test_order_by(self):
|
||||
results = self.backend.search(xapian.Query(''), sort_by=['pub_date'])
|
||||
self.assertEqual(pks(results['results']), [3, 2, 1])
|
||||
#results = self.backend.search(xapian.Query(''), sort_by=['datetime'])
|
||||
#print([d.datetime for d in results['results']])
|
||||
#self.assertEqual(pks(results['results']), [3, 2, 1])
|
||||
|
||||
results = self.backend.search(xapian.Query(''), sort_by=['-pub_date'])
|
||||
self.assertEqual(pks(results['results']), [1, 2, 3])
|
||||
#results = self.backend.search(xapian.Query(''), sort_by=['-datetime'])
|
||||
#self.assertEqual(pks(results['results']), [1, 2, 3])
|
||||
|
||||
results = self.backend.search(xapian.Query(''), sort_by=['exp_date'])
|
||||
self.assertEqual(pks(results['results']), [1, 2, 3])
|
||||
#results = self.backend.search(xapian.Query(''), sort_by=['date'])
|
||||
#self.assertEqual(pks(results['results']), [1, 2, 3])
|
||||
|
||||
results = self.backend.search(xapian.Query(''), sort_by=['-exp_date'])
|
||||
self.assertEqual(pks(results['results']), [3, 2, 1])
|
||||
#results = self.backend.search(xapian.Query(''), sort_by=['-date'])
|
||||
#self.assertEqual(pks(results['results']), [3, 2, 1])
|
||||
|
||||
results = self.backend.search(xapian.Query(''), sort_by=['id'])
|
||||
self.assertEqual(pks(results['results']), [1, 2, 3])
|
||||
|
|
@ -590,22 +481,22 @@ class BackendFeaturesTestCase(HaystackBackendTestCase, TestCase):
|
|||
results = self.backend.search(xapian.Query(''), sort_by=['-id'])
|
||||
self.assertEqual(pks(results['results']), [3, 2, 1])
|
||||
|
||||
results = self.backend.search(xapian.Query(''), sort_by=['value'])
|
||||
results = self.backend.search(xapian.Query(''), sort_by=['number'])
|
||||
self.assertEqual(pks(results['results']), [1, 2, 3])
|
||||
|
||||
results = self.backend.search(xapian.Query(''), sort_by=['-value'])
|
||||
results = self.backend.search(xapian.Query(''), sort_by=['-number'])
|
||||
self.assertEqual(pks(results['results']), [3, 2, 1])
|
||||
|
||||
results = self.backend.search(xapian.Query(''), sort_by=['popularity'])
|
||||
results = self.backend.search(xapian.Query(''), sort_by=['float_number'])
|
||||
self.assertEqual(pks(results['results']), [2, 1, 3])
|
||||
|
||||
results = self.backend.search(xapian.Query(''), sort_by=['-popularity'])
|
||||
results = self.backend.search(xapian.Query(''), sort_by=['-float_number'])
|
||||
self.assertEqual(pks(results['results']), [3, 1, 2])
|
||||
|
||||
results = self.backend.search(xapian.Query(''), sort_by=['flag', 'id'])
|
||||
results = self.backend.search(xapian.Query(''), sort_by=['boolean', 'id'])
|
||||
self.assertEqual(pks(results['results']), [2, 1, 3])
|
||||
|
||||
results = self.backend.search(xapian.Query(''), sort_by=['flag', '-id'])
|
||||
results = self.backend.search(xapian.Query(''), sort_by=['boolean', '-id'])
|
||||
self.assertEqual(pks(results['results']), [2, 3, 1])
|
||||
|
||||
def test_verify_type(self):
|
||||
|
|
@ -638,20 +529,20 @@ class BackendFeaturesTestCase(HaystackBackendTestCase, TestCase):
|
|||
{'column': 0, 'type': 'text', 'field_name': 'id', 'multi_valued': 'false'},
|
||||
{'column': 1, 'type': 'integer', 'field_name': 'django_id', 'multi_valued': 'false'},
|
||||
{'column': 2, 'type': 'text', 'field_name': 'django_ct', 'multi_valued': 'false'},
|
||||
{'column': 3, 'type': 'text', 'field_name': 'empty', 'multi_valued': 'false'},
|
||||
{'column': 4, 'type': 'date', 'field_name': 'exp_date', 'multi_valued': 'false'},
|
||||
{'column': 5, 'type': 'boolean', 'field_name': 'flag', 'multi_valued': 'false'},
|
||||
{'column': 6, 'type': 'text', 'field_name': 'keys', 'multi_valued': 'true'},
|
||||
{'column': 7, 'type': 'text', 'field_name': 'name', 'multi_valued': 'false'},
|
||||
{'column': 8, 'type': 'text', 'field_name': 'name_exact', 'multi_valued': 'false'},
|
||||
{'column': 9, 'type': 'float', 'field_name': 'popularity', 'multi_valued': 'false'},
|
||||
{'column': 10, 'type': 'date', 'field_name': 'pub_date', 'multi_valued': 'false'},
|
||||
{'column': 11, 'type': 'text', 'field_name': 'sites', 'multi_valued': 'true'},
|
||||
{'column': 12, 'type': 'text', 'field_name': 'tags', 'multi_valued': 'true'},
|
||||
{'column': 13, 'type': 'text', 'field_name': 'text', 'multi_valued': 'false'},
|
||||
{'column': 14, 'type': 'text', 'field_name': 'titles', 'multi_valued': 'true'},
|
||||
{'column': 15, 'type': 'text', 'field_name': 'url', 'multi_valued': 'false'},
|
||||
{'column': 16, 'type': 'integer', 'field_name': 'value', 'multi_valued': 'false'}
|
||||
{'column': 3, 'type': 'boolean', 'field_name': 'boolean', 'multi_valued': 'false'},
|
||||
{'column': 4, 'type': 'date', 'field_name': 'date', 'multi_valued': 'false'},
|
||||
{'column': 5, 'type': 'date', 'field_name': 'datetime', 'multi_valued': 'false'},
|
||||
{'column': 6, 'type': 'text', 'field_name': 'empty', 'multi_valued': 'false'},
|
||||
{'column': 7, 'type': 'float', 'field_name': 'float_number', 'multi_valued': 'false'},
|
||||
{'column': 8, 'type': 'text', 'field_name': 'keys', 'multi_valued': 'true'},
|
||||
{'column': 9, 'type': 'text', 'field_name': 'name', 'multi_valued': 'false'},
|
||||
{'column': 10, 'type': 'text', 'field_name': 'name_exact', 'multi_valued': 'false'},
|
||||
{'column': 11, 'type': 'integer', 'field_name': 'number', 'multi_valued': 'false'},
|
||||
{'column': 12, 'type': 'text', 'field_name': 'sites', 'multi_valued': 'true'},
|
||||
{'column': 13, 'type': 'text', 'field_name': 'tags', 'multi_valued': 'true'},
|
||||
{'column': 14, 'type': 'text', 'field_name': 'text', 'multi_valued': 'false'},
|
||||
{'column': 15, 'type': 'text', 'field_name': 'titles', 'multi_valued': 'true'},
|
||||
{'column': 16, 'type': 'text', 'field_name': 'url', 'multi_valued': 'false'},
|
||||
])
|
||||
|
||||
def test_parse_query(self):
|
||||
|
|
@ -674,15 +565,15 @@ class BackendFeaturesTestCase(HaystackBackendTestCase, TestCase):
|
|||
'XNAMEdavid3:(pos=1)))')
|
||||
|
||||
self.assertEqual(str(self.backend.parse_query('name:david1..david2')),
|
||||
'Xapian::Query(VALUE_RANGE 7 david1 david2)')
|
||||
self.assertEqual(str(self.backend.parse_query('value:0..10')),
|
||||
'Xapian::Query(VALUE_RANGE 16 000000000000 000000000010)')
|
||||
self.assertEqual(str(self.backend.parse_query('value:..10')),
|
||||
'Xapian::Query(VALUE_RANGE 16 %012d 000000000010)' % (-sys.maxsize - 1))
|
||||
self.assertEqual(str(self.backend.parse_query('value:10..*')),
|
||||
'Xapian::Query(VALUE_RANGE 16 000000000010 %012d)' % sys.maxsize)
|
||||
self.assertEqual(str(self.backend.parse_query('popularity:25.5..100.0')),
|
||||
b'Xapian::Query(VALUE_RANGE 9 \xb2` \xba@)')
|
||||
'Xapian::Query(VALUE_RANGE 9 david1 david2)')
|
||||
self.assertEqual(str(self.backend.parse_query('number:0..10')),
|
||||
'Xapian::Query(VALUE_RANGE 11 000000000000 000000000010)')
|
||||
self.assertEqual(str(self.backend.parse_query('number:..10')),
|
||||
'Xapian::Query(VALUE_RANGE 11 %012d 000000000010)' % (-sys.maxsize - 1))
|
||||
self.assertEqual(str(self.backend.parse_query('number:10..*')),
|
||||
'Xapian::Query(VALUE_RANGE 11 000000000010 %012d)' % sys.maxsize)
|
||||
self.assertEqual(str(self.backend.parse_query('float_number:25.5..100.0')),
|
||||
b'Xapian::Query(VALUE_RANGE 7 \xb2` \xba@)')
|
||||
|
||||
def test_order_by_django_id(self):
|
||||
"""
|
||||
|
|
@ -692,17 +583,11 @@ class BackendFeaturesTestCase(HaystackBackendTestCase, TestCase):
|
|||
self.sample_objs = []
|
||||
number_list = list(range(1, 101))
|
||||
for i in number_list:
|
||||
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
|
||||
mock.popularity = i*2
|
||||
self.sample_objs.append(mock)
|
||||
entry = self.get_entry(i)
|
||||
self.sample_objs.append(entry)
|
||||
|
||||
for obj in self.sample_objs:
|
||||
obj.save()
|
||||
|
||||
self.backend.clear()
|
||||
self.backend.update(self.index, self.sample_objs)
|
||||
|
|
@ -716,7 +601,7 @@ class BackendFeaturesTestCase(HaystackBackendTestCase, TestCase):
|
|||
with an unindexed model and if silently_fail is True.
|
||||
Also tests the other way around.
|
||||
"""
|
||||
mock = XapianMockModel()
|
||||
mock = BlogEntry()
|
||||
mock.id = 10
|
||||
mock.author = 'david10'
|
||||
|
||||
|
|
@ -735,13 +620,13 @@ class IndexationNGramTestCase(HaystackBackendTestCase, TestCase):
|
|||
|
||||
def setUp(self):
|
||||
super(IndexationNGramTestCase, self).setUp()
|
||||
mock = XapianMockModel()
|
||||
mock = BlogEntry()
|
||||
mock.id = 1
|
||||
mock.author = u'david'
|
||||
mock.author = 'david'
|
||||
|
||||
mock1 = XapianMockModel()
|
||||
mock1 = BlogEntry()
|
||||
mock1.id = 2
|
||||
mock1.author = u'da1id'
|
||||
mock1.author = 'da1id'
|
||||
|
||||
self.backend.update(self.index, [mock, mock1])
|
||||
|
||||
|
|
@ -776,18 +661,19 @@ class IndexationNGramTestCase(HaystackBackendTestCase, TestCase):
|
|||
|
||||
|
||||
class IndexationEdgeNGramTestCase(HaystackBackendTestCase, TestCase):
|
||||
|
||||
def get_index(self):
|
||||
return XapianEdgeNGramIndex()
|
||||
|
||||
def setUp(self):
|
||||
super(IndexationEdgeNGramTestCase, self).setUp()
|
||||
mock = XapianMockModel()
|
||||
mock = BlogEntry()
|
||||
mock.id = 1
|
||||
mock.author = u'david'
|
||||
mock.author = 'david'
|
||||
|
||||
mock1 = XapianMockModel()
|
||||
mock1 = BlogEntry()
|
||||
mock1.id = 2
|
||||
mock1.author = u'da1id'
|
||||
mock1.author = 'da1id'
|
||||
|
||||
self.backend.update(self.index, [mock, mock1])
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import datetime
|
||||
|
||||
from django.db.models import Q
|
||||
from django.test import TestCase
|
||||
|
||||
|
|
@ -10,7 +11,7 @@ from haystack.query import SearchQuerySet
|
|||
|
||||
from ..models import Document
|
||||
from ..search_indexes import DocumentIndex
|
||||
from ..tests.test_backend import pks, get_terms
|
||||
from ..tests.test_backend import pks
|
||||
|
||||
|
||||
class InterfaceTestCase(TestCase):
|
||||
|
|
|
|||
|
|
@ -5,26 +5,17 @@ import datetime
|
|||
from django.conf import settings
|
||||
from django.test import TestCase
|
||||
|
||||
from haystack import indexes
|
||||
from haystack import connections, reset_search_queries
|
||||
from haystack.models import SearchResult
|
||||
from haystack.query import SearchQuerySet, SQ
|
||||
|
||||
from ...core.models import MockModel, AnotherMockModel, AFourthMockModel
|
||||
from ...mocks import MockSearchResult
|
||||
|
||||
from ..models import MockModel, AnotherMockModel, AFourthMockModel
|
||||
from ..search_indexes import MockQueryIndex, MockSearchIndex, BoostMockSearchIndex
|
||||
from ..tests.test_backend import HaystackBackendTestCase
|
||||
|
||||
|
||||
class MockQueryIndex(indexes.SearchIndex):
|
||||
text = indexes.CharField(document=True)
|
||||
pub_date = indexes.DateTimeField()
|
||||
title = indexes.CharField()
|
||||
foo = indexes.CharField()
|
||||
|
||||
def get_model(self):
|
||||
return MockModel
|
||||
|
||||
|
||||
class XapianSearchQueryTestCase(HaystackBackendTestCase, TestCase):
|
||||
def get_index(self):
|
||||
return MockQueryIndex()
|
||||
|
|
@ -33,68 +24,68 @@ class XapianSearchQueryTestCase(HaystackBackendTestCase, TestCase):
|
|||
super(XapianSearchQueryTestCase, self).setUp()
|
||||
self.sq = connections['default'].get_query()
|
||||
|
||||
def test_build_query_all(self):
|
||||
def test_all(self):
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
'Xapian::Query(<alldocuments>)')
|
||||
|
||||
def test_build_query_single_word(self):
|
||||
def test_single_word(self):
|
||||
self.sq.add_filter(SQ(content='hello'))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
'Xapian::Query((Zhello OR hello))')
|
||||
|
||||
def test_build_query_single_word_not(self):
|
||||
def test_single_word_not(self):
|
||||
self.sq.add_filter(~SQ(content='hello'))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
'Xapian::Query((<alldocuments> AND_NOT (Zhello OR hello)))')
|
||||
|
||||
def test_build_query_single_word_field_exact(self):
|
||||
def test_single_word_field_exact(self):
|
||||
self.sq.add_filter(SQ(foo='hello'))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
'Xapian::Query((ZXFOOhello OR XFOOhello))')
|
||||
|
||||
def test_build_query_single_word_field_exact_not(self):
|
||||
def test_single_word_field_exact_not(self):
|
||||
self.sq.add_filter(~SQ(foo='hello'))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
'Xapian::Query((<alldocuments> AND_NOT (ZXFOOhello OR XFOOhello)))')
|
||||
|
||||
def test_build_query_boolean(self):
|
||||
def test_boolean(self):
|
||||
self.sq.add_filter(SQ(content=True))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
'Xapian::Query((Ztrue OR true))')
|
||||
|
||||
def test_build_query_date(self):
|
||||
def test_date(self):
|
||||
self.sq.add_filter(SQ(content=datetime.date(2009, 5, 8)))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
'Xapian::Query((Z2009-05-08 OR 2009-05-08))')
|
||||
|
||||
def test_build_query_date_not(self):
|
||||
def test_date_not(self):
|
||||
self.sq.add_filter(~SQ(content=datetime.date(2009, 5, 8)))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
'Xapian::Query((<alldocuments> AND_NOT (Z2009-05-08 OR 2009-05-08)))')
|
||||
|
||||
def test_build_query_datetime(self):
|
||||
def test_datetime(self):
|
||||
self.sq.add_filter(SQ(content=datetime.datetime(2009, 5, 8, 11, 28)))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
'Xapian::Query((Z2009-05-08 OR 2009-05-08 OR Z11:28:00 OR 11:28:00))')
|
||||
|
||||
def test_build_query_datetime_not(self):
|
||||
def test_datetime_not(self):
|
||||
self.sq.add_filter(~SQ(content=datetime.datetime(2009, 5, 8, 11, 28)))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
'Xapian::Query((<alldocuments> AND_NOT '
|
||||
'(Z2009-05-08 OR 2009-05-08 OR Z11:28:00 OR 11:28:00)))')
|
||||
|
||||
def test_build_query_float(self):
|
||||
def test_float(self):
|
||||
self.sq.add_filter(SQ(content=25.52))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
'Xapian::Query((Z25.52 OR 25.52))')
|
||||
|
||||
def test_build_query_multiple_words_and(self):
|
||||
def test_multiple_words_and(self):
|
||||
self.sq.add_filter(SQ(content='hello'))
|
||||
self.sq.add_filter(SQ(content='world'))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
'Xapian::Query(((Zhello OR hello) AND (Zworld OR world)))')
|
||||
|
||||
def test_build_query_multiple_words_not(self):
|
||||
def test_multiple_words_not(self):
|
||||
self.sq.add_filter(~SQ(content='hello'))
|
||||
self.sq.add_filter(~SQ(content='world'))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
|
|
@ -102,19 +93,19 @@ class XapianSearchQueryTestCase(HaystackBackendTestCase, TestCase):
|
|||
'(<alldocuments> AND_NOT (Zhello OR hello)) AND '
|
||||
'(<alldocuments> AND_NOT (Zworld OR world))))')
|
||||
|
||||
def test_build_query_multiple_words_or(self):
|
||||
def test_multiple_words_or(self):
|
||||
self.sq.add_filter(SQ(content='hello') | SQ(content='world'))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
'Xapian::Query((Zhello OR hello OR Zworld OR world))')
|
||||
|
||||
def test_build_query_multiple_words_or_not(self):
|
||||
def test_multiple_words_or_not(self):
|
||||
self.sq.add_filter(~SQ(content='hello') | ~SQ(content='world'))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
'Xapian::Query(('
|
||||
'(<alldocuments> AND_NOT (Zhello OR hello)) OR '
|
||||
'(<alldocuments> AND_NOT (Zworld OR world))))')
|
||||
|
||||
def test_build_query_multiple_words_mixed(self):
|
||||
def test_multiple_words_mixed(self):
|
||||
self.sq.add_filter(SQ(content='why') | SQ(content='hello'))
|
||||
self.sq.add_filter(~SQ(content='world'))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
|
|
@ -122,7 +113,7 @@ class XapianSearchQueryTestCase(HaystackBackendTestCase, TestCase):
|
|||
'(Zwhi OR why OR Zhello OR hello) AND '
|
||||
'(<alldocuments> AND_NOT (Zworld OR world))))')
|
||||
|
||||
def test_build_query_multiple_word_field_exact(self):
|
||||
def test_multiple_word_field_exact(self):
|
||||
self.sq.add_filter(SQ(foo='hello'))
|
||||
self.sq.add_filter(SQ(title='world'))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
|
|
@ -130,7 +121,7 @@ class XapianSearchQueryTestCase(HaystackBackendTestCase, TestCase):
|
|||
'(ZXFOOhello OR XFOOhello) AND '
|
||||
'(ZXTITLEworld OR XTITLEworld)))')
|
||||
|
||||
def test_build_query_multiple_word_field_exact_not(self):
|
||||
def test_multiple_word_field_exact_not(self):
|
||||
self.sq.add_filter(~SQ(foo='hello'))
|
||||
self.sq.add_filter(~SQ(title='world'))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
|
|
@ -138,18 +129,18 @@ class XapianSearchQueryTestCase(HaystackBackendTestCase, TestCase):
|
|||
'(<alldocuments> AND_NOT (ZXFOOhello OR XFOOhello)) AND '
|
||||
'(<alldocuments> AND_NOT (ZXTITLEworld OR XTITLEworld))))')
|
||||
|
||||
def test_build_query_or(self):
|
||||
def test_or(self):
|
||||
self.sq.add_filter(SQ(content='hello world'))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
'Xapian::Query((Zhello OR hello OR Zworld OR world))')
|
||||
|
||||
def test_build_query_not_or(self):
|
||||
def test_not_or(self):
|
||||
self.sq.add_filter(~SQ(content='hello world'))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
'Xapian::Query('
|
||||
'(<alldocuments> AND_NOT (Zhello OR hello OR Zworld OR world)))')
|
||||
|
||||
def test_build_query_boost(self):
|
||||
def test_boost(self):
|
||||
self.sq.add_filter(SQ(content='hello'))
|
||||
self.sq.add_boost('world', 5)
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
|
|
@ -157,7 +148,7 @@ class XapianSearchQueryTestCase(HaystackBackendTestCase, TestCase):
|
|||
'(Zhello OR hello) AND_MAYBE '
|
||||
'5 * (Zworld OR world)))')
|
||||
|
||||
def test_build_query_not_in_filter_single_words(self):
|
||||
def test_not_in_filter_single_words(self):
|
||||
self.sq.add_filter(SQ(content='why'))
|
||||
self.sq.add_filter(~SQ(title__in=["Dune", "Jaws"]))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
|
|
@ -167,7 +158,7 @@ class XapianSearchQueryTestCase(HaystackBackendTestCase, TestCase):
|
|||
'(XTITLE^ PHRASE 3 XTITLEdune PHRASE 3 XTITLE$) OR '
|
||||
'(XTITLE^ PHRASE 3 XTITLEjaws PHRASE 3 XTITLE$)))))')
|
||||
|
||||
def test_build_query_in_filter_multiple_words(self):
|
||||
def test_in_filter_multiple_words(self):
|
||||
self.sq.add_filter(SQ(content='why'))
|
||||
self.sq.add_filter(SQ(title__in=["A Famous Paper", "An Infamous Article"]))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
|
|
@ -177,7 +168,7 @@ class XapianSearchQueryTestCase(HaystackBackendTestCase, TestCase):
|
|||
'(XTITLE^ PHRASE 5 XTITLEan PHRASE 5 XTITLEinfamous PHRASE 5 '
|
||||
'XTITLEarticle PHRASE 5 XTITLE$))))')
|
||||
|
||||
def test_build_query_in_filter_multiple_words_with_punctuation(self):
|
||||
def test_in_filter_multiple_words_with_punctuation(self):
|
||||
self.sq.add_filter(SQ(title__in=["A Famous Paper", "An Infamous Article", "My Store Inc."]))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
'Xapian::Query(('
|
||||
|
|
@ -188,7 +179,7 @@ class XapianSearchQueryTestCase(HaystackBackendTestCase, TestCase):
|
|||
'(XTITLE^ PHRASE 5 XTITLEmy PHRASE 5 XTITLEstore PHRASE 5'
|
||||
' XTITLEinc. PHRASE 5 XTITLE$)))')
|
||||
|
||||
def test_build_query_not_in_filter_multiple_words(self):
|
||||
def test_not_in_filter_multiple_words(self):
|
||||
self.sq.add_filter(SQ(content='why'))
|
||||
self.sq.add_filter(~SQ(title__in=["A Famous Paper", "An Infamous Article"]))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
|
|
@ -199,7 +190,7 @@ class XapianSearchQueryTestCase(HaystackBackendTestCase, TestCase):
|
|||
'XTITLEan PHRASE 5 XTITLEinfamous PHRASE 5 '
|
||||
'XTITLEarticle PHRASE 5 XTITLE$)))))')
|
||||
|
||||
def test_build_query_in_filter_datetime(self):
|
||||
def test_in_filter_datetime(self):
|
||||
self.sq.add_filter(SQ(content='why'))
|
||||
self.sq.add_filter(SQ(pub_date__in=[datetime.datetime(2009, 7, 6, 1, 56, 21)]))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
|
|
@ -214,7 +205,7 @@ class XapianSearchQueryTestCase(HaystackBackendTestCase, TestCase):
|
|||
self.assertEqual(self.sq.clean('so please NOTe i am in a bAND and bORed'),
|
||||
'so please NOTe i am in a bAND and bORed')
|
||||
|
||||
def test_build_query_with_models(self):
|
||||
def test_with_models(self):
|
||||
self.sq.add_filter(SQ(content='hello'))
|
||||
self.sq.add_model(MockModel)
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
|
|
@ -231,7 +222,7 @@ class XapianSearchQueryTestCase(HaystackBackendTestCase, TestCase):
|
|||
'(0 * CONTENTTYPEcore.mockmodel OR '
|
||||
'0 * CONTENTTYPEcore.anothermockmodel)))'))
|
||||
|
||||
def test_build_query_with_punctuation(self):
|
||||
def test_with_punctuation(self):
|
||||
self.sq.add_filter(SQ(content='http://www.example.com'))
|
||||
self.assertEqual(str(self.sq.build_query()), 'Xapian::Query((Zhttp://www.example.com OR '
|
||||
'http://www.example.com))')
|
||||
|
|
@ -247,16 +238,6 @@ class XapianSearchQueryTestCase(HaystackBackendTestCase, TestCase):
|
|||
'(XTITLE^ PHRASE 3 XTITLE3 PHRASE 3 XTITLE$))))')
|
||||
|
||||
|
||||
class MockSearchIndex(indexes.SearchIndex):
|
||||
text = indexes.CharField(document=True, use_template=True)
|
||||
name = indexes.CharField(model_attr='author', faceted=True)
|
||||
pub_date = indexes.DateTimeField(model_attr='pub_date')
|
||||
title = indexes.CharField()
|
||||
|
||||
def get_model(self):
|
||||
return MockModel
|
||||
|
||||
|
||||
class SearchQueryTestCase(HaystackBackendTestCase, TestCase):
|
||||
"""
|
||||
Tests expected behavior of
|
||||
|
|
@ -283,19 +264,19 @@ class SearchQueryTestCase(HaystackBackendTestCase, TestCase):
|
|||
self.sq.add_filter(SQ(name__startswith='da'))
|
||||
self.assertEqual([result.pk for result in self.sq.get_results()], [1, 2, 3])
|
||||
|
||||
def test_build_query_gt(self):
|
||||
def test_gt(self):
|
||||
self.sq.add_filter(SQ(name__gt='m'))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
'Xapian::Query((<alldocuments> AND_NOT VALUE_RANGE 3 a m))')
|
||||
|
||||
def test_build_query_gte(self):
|
||||
def test_gte(self):
|
||||
self.sq.add_filter(SQ(name__gte='m'))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
'Xapian::Query(VALUE_RANGE 3 m zzzzzzzzzzzzzzzzzzzzzzzzzzzz'
|
||||
'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'
|
||||
'zzzzzzzzzzzzzz)')
|
||||
|
||||
def test_build_query_lt(self):
|
||||
def test_lt(self):
|
||||
self.sq.add_filter(SQ(name__lt='m'))
|
||||
self.assertEqual(str(self.sq.build_query()),
|
||||
'Xapian::Query((<alldocuments> AND_NOT '
|
||||
|
|
@ -303,11 +284,11 @@ class SearchQueryTestCase(HaystackBackendTestCase, TestCase):
|
|||
'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'
|
||||
'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz))')
|
||||
|
||||
def test_build_query_lte(self):
|
||||
def test_lte(self):
|
||||
self.sq.add_filter(SQ(name__lte='m'))
|
||||
self.assertEqual(str(self.sq.build_query()), 'Xapian::Query(VALUE_RANGE 3 a m)')
|
||||
|
||||
def test_build_query_multiple_filter_types(self):
|
||||
def test_multiple_filter_types(self):
|
||||
self.sq.add_filter(SQ(content='why'))
|
||||
self.sq.add_filter(SQ(pub_date__lte=datetime.datetime(2009, 2, 10, 1, 59, 0)))
|
||||
self.sq.add_filter(SQ(name__gt='david'))
|
||||
|
|
@ -393,19 +374,6 @@ class LiveSearchQuerySetTestCase(HaystackBackendTestCase, TestCase):
|
|||
self.assertEqual(len(self.sqs.facet('name').facet_counts()['fields']['name']), 3)
|
||||
|
||||
|
||||
class BoostMockSearchIndex(indexes.SearchIndex):
|
||||
text = indexes.CharField(
|
||||
document=True, use_template=True,
|
||||
template_name='search/indexes/core/mockmodel_template.txt'
|
||||
)
|
||||
author = indexes.CharField(model_attr='author', weight=2.0)
|
||||
editor = indexes.CharField(model_attr='editor')
|
||||
pub_date = indexes.DateField(model_attr='pub_date')
|
||||
|
||||
def get_model(self):
|
||||
return AFourthMockModel
|
||||
|
||||
|
||||
class BoostFieldTestCase(HaystackBackendTestCase, TestCase):
|
||||
"""
|
||||
Tests boosted fields.
|
||||
|
|
|
|||
Loading…
Reference in a new issue