def setUp(self): super(LiveSolrSearchQuerySetTestCase, self).setUp() # With the models registered, you get the proper bits. import haystack from haystack.sites import SearchSite # Stow. self.old_debug = settings.DEBUG settings.DEBUG = True self.old_site = haystack.site test_site = SearchSite() test_site.register(MockModel, SolrMockModelSearchIndex) haystack.site = test_site self.sqs = SearchQuerySet() self.rsqs = RelatedSearchQuerySet() # Ugly but not constantly reindexing saves us almost 50% runtime. global lssqstc_all_loaded if lssqstc_all_loaded is None: print 'Reloading data...' lssqstc_all_loaded = True # Wipe it clean. clear_solr_index() # Force indexing of the content. mockmodel_index = test_site.get_index(MockModel) mockmodel_index.update()
class LiveWhooshMultiSearchQuerySetTestCase(TestCase): fixtures = ['bulk_data.json'] def setUp(self): super(LiveWhooshMultiSearchQuerySetTestCase, self).setUp() # Stow. temp_path = os.path.join('tmp', 'test_whoosh_query') self.old_whoosh_path = getattr(settings, 'HAYSTACK_WHOOSH_PATH', temp_path) settings.HAYSTACK_WHOOSH_PATH = temp_path self.site = SearchSite() self.sb = SearchBackend(site=self.site) self.smmi = WhooshMockSearchIndex(MockModel, backend=self.sb) self.sammi = WhooshAnotherMockSearchIndex(AnotherMockModel, backend=self.sb) self.site.register(MockModel, WhooshMockSearchIndex) self.site.register(AnotherMockModel, WhooshAnotherMockSearchIndex) # Stow. import haystack self.old_debug = settings.DEBUG settings.DEBUG = True self.old_site = haystack.site haystack.site = self.site self.sb.setup() self.raw_whoosh = self.sb.index self.parser = QueryParser(self.sb.content_field_name, schema=self.sb.schema) self.sb.delete_index() self.sq = SearchQuery(backend=self.sb) self.sqs = SearchQuerySet(site=self.site) self.smmi.update() self.sammi.update() def tearDown(self): if os.path.exists(settings.HAYSTACK_WHOOSH_PATH): shutil.rmtree(settings.HAYSTACK_WHOOSH_PATH) settings.HAYSTACK_WHOOSH_PATH = self.old_whoosh_path import haystack haystack.site = self.old_site settings.DEBUG = self.old_debug super(LiveWhooshMultiSearchQuerySetTestCase, self).tearDown() def test_searchquerysets_with_models(self): sqs = self.sqs.all() self.assertEqual(sqs.query.build_query(), u'*') self.assertEqual(len(sqs), 25) sqs = self.sqs.models(MockModel) self.assertEqual(sqs.query.build_query(), u'django_ct:core.mockmodel') self.assertEqual(len(sqs), 23) sqs = self.sqs.models(AnotherMockModel) self.assertEqual(sqs.query.build_query(), u'django_ct:core.anothermockmodel') self.assertEqual(len(sqs), 2)
class LiveSimpleSearchQuerySetTestCase(TestCase): fixtures = ['bulk_data.json'] def setUp(self): super(LiveSimpleSearchQuerySetTestCase, self).setUp() import haystack # Stow. self.old_debug = settings.DEBUG settings.DEBUG = True self.old_site = haystack.site self.site = SearchSite() self.backend = SearchBackend(site=self.site) self.index = SimpleMockSearchIndex(MockModel, backend=self.backend) self.site.register(MockModel, SimpleMockSearchIndex) haystack.site = self.site self.sample_objs = MockModel.objects.all() self.sqs = SearchQuerySet() def tearDown(self): # Restore. import haystack haystack.site = self.old_site settings.DEBUG = self.old_debug super(LiveSimpleSearchQuerySetTestCase, self).tearDown() def test_general_queries(self): # For now, just make sure these don't throw an exception. # They won't work until the simple backend is improved. self.assertTrue(len(self.sqs.auto_query('daniel')) > 0) self.assertTrue(len(self.sqs.filter(text='index')) > 0) self.assertTrue(len(self.sqs.exclude(name='daniel')) > 0) self.assertTrue(len(self.sqs.order_by('-pub_date')) > 0)
def test_use_correct_site(self): import haystack test_site = SearchSite() test_site.register(MockModel, WhooshMockSearchIndex) self.sb.update(self.smmi, self.sample_objs) # Make sure that ``_process_results`` uses the right ``site``. self.assertEqual(self.sb.search('*:*')['hits'], 23) self.assertEqual([result.pk for result in self.sb.search('*:*')['results']], [u'%s' % i for i in xrange(1, 24)]) haystack.site.unregister(MockModel) self.assertEqual(len(haystack.site.get_indexed_models()), 0) self.sb.site = test_site self.assertTrue(len(self.sb.site.get_indexed_models()) > 0) # Should still be there, despite the main ``site`` not having that model # registered any longer. self.assertEqual(self.sb.search('*:*')['hits'], 23) self.assertEqual([result.pk for result in self.sb.search('*:*')['results']], [u'%s' % i for i in xrange(1, 24)]) # Unregister it on the backend & make sure it takes effect. self.sb.site.unregister(MockModel) self.assertEqual(len(self.sb.site.get_indexed_models()), 0) self.assertEqual(self.sb.search('*:*')['hits'], 0) # Nuke it & fallback on the main ``site``. self.sb.site = haystack.site self.assertEqual(self.sb.search('*:*')['hits'], 0) haystack.site.register(MockModel, WhooshMockSearchIndex) self.assertEqual(self.sb.search('*:*')['hits'], 23)
def test_regression_site_kwarg(self): mock_index_site = SearchSite() mock_index_site.register(MockModel) mock_index_site.register(AnotherMockModel) bsqs = SearchQuerySet(site=mock_index_site) self.assertEqual(set(bsqs.query.backend.site.get_indexed_models()), set([MockModel, AnotherMockModel]))
def test_model_choices(self): mis = SearchSite() mis.register(MockModel) mis.register(AnotherMockModel) self.assertEqual(len(model_choices(site=mis)), 2) self.assertEqual([option[1] for option in model_choices(site=mis)], [u'Another mock models', u'Mock models'])
def test_log_query(self): backends.reset_search_queries() self.assertEqual(len(backends.queries), 0) # Stow. old_site = haystack.site old_debug = settings.DEBUG test_site = SearchSite() test_site.register(MockModel) haystack.site = test_site settings.DEBUG = False msq = MockSearchQuery(backend=MockSearchBackend()) self.assertEqual(len(msq.get_results()), 100) self.assertEqual(len(backends.queries), 0) settings.DEBUG = True # Redefine it to clear out the cached results. msq2 = MockSearchQuery(backend=MockSearchBackend()) self.assertEqual(len(msq2.get_results()), 100) self.assertEqual(len(backends.queries), 1) self.assertEqual(backends.queries[0]['query_string'], '') msq3 = MockSearchQuery(backend=MockSearchBackend()) msq3.add_filter(SQ(foo='bar')) len(msq3.get_results()) self.assertEqual(len(backends.queries), 2) self.assertEqual(backends.queries[0]['query_string'], '') self.assertEqual(backends.queries[1]['query_string'], '') # Restore. haystack.site = old_site settings.DEBUG = old_debug
def test_use_correct_site(self): test_site = SearchSite() test_site.register(XapianMockModel, XapianMockSearchIndex) self.backend.update(self.index, self.sample_objs) # Make sure that ``_process_results`` uses the right ``site``. self.assertEqual(self.backend.search(xapian.Query('indexed'))['hits'], 3) self.assertEqual([result.pk for result in self.backend.search(xapian.Query('indexed'))['results']], [1, 2, 3]) self.site.unregister(XapianMockModel) self.assertEqual(len(self.site.get_indexed_models()), 0) self.backend.site = test_site self.assertTrue(len(self.backend.site.get_indexed_models()) > 0) # Should still be there, despite the main ``site`` not having that model # registered any longer. self.assertEqual(self.backend.search(xapian.Query('indexed'))['hits'], 3) self.assertEqual([result.pk for result in self.backend.search(xapian.Query('indexed'))['results']], [1, 2, 3]) # Unregister it on the backend & make sure it takes effect. self.backend.site.unregister(XapianMockModel) self.assertEqual(len(self.backend.site.get_indexed_models()), 0) self.assertEqual(self.backend.search(xapian.Query('indexed'))['hits'], 0) # Nuke it & fallback on the main ``site``. self.backend.site = haystack.site self.assertEqual(self.backend.search(xapian.Query('indexed'))['hits'], 0) self.site.register(XapianMockModel, XapianMockSearchIndex) self.assertEqual(self.backend.search(xapian.Query('indexed'))['hits'], 3)
def setUp(self): super(SearchModelAdminTestCase, self).setUp() # With the models registered, you get the proper bits. import haystack from haystack.sites import SearchSite # Stow. self.old_debug = settings.DEBUG settings.DEBUG = True self.old_site = haystack.site test_site = SearchSite() test_site.register(MockModel, SolrMockModelSearchIndex) haystack.site = test_site # Wipe it clean. clear_solr_index() # Force indexing of the content. mockmodel_index = test_site.get_index(MockModel) mockmodel_index.update() superuser = User.objects.create_superuser( username='******', password='******', email='*****@*****.**', )
def test_regression_site_kwarg(self): # Stow. test_site = SearchSite() test_site.register(MockModel) msq = MockSearchQuery(site=test_site) self.assertEqual(msq.backend.site.get_indexed_models(), [MockModel])
def setUp(self): super(LiveSolrMoreLikeThisTestCase, self).setUp() self.sqs = SearchQuerySet() # Wipe it clean. self.sqs.query.backend.clear() # With the models registered, you get the proper bits. import haystack from haystack.sites import SearchSite # Stow. self.old_site = haystack.site test_site = SearchSite() test_site.register(MockModel, SolrMockModelSearchIndex) test_site.register(AnotherMockModel, SolrAnotherMockModelSearchIndex) haystack.site = test_site # Force indexing of the content. for mock in MockModel.objects.all(): mock.save() # Force indexing of the content. for mock in AnotherMockModel.objects.all(): mock.save() self.sqs = SearchQuerySet()
def test_load_all_read_queryset(self): # stow old_site = haystack.site test_site = SearchSite() # Register a default SearchIndex first (without the SoftDeleteMangaer as the read_queryset) test_site.register(AFifthMockModel) haystack.site = test_site sqs = SearchQuerySet(query=MockSearchQuery(backend=ReadQuerySetMockSearchBackend())) results = sqs.load_all().all() results._fill_cache(0, 2) # The deleted result isn't returned self.assertEqual(len([result for result in results._result_cache if result is not None]), 1) test_site.unregister(AFifthMockModel) # Register a SearchIndex with a read_queryset that returns deleted items test_site.register(AFifthMockModel, ReadQuerySetTestSearchIndex) sqs = SearchQuerySet(query=MockSearchQuery(backend=ReadQuerySetMockSearchBackend())) results = sqs.load_all().all() results._fill_cache(0, 2) # Both the deleted and not deleted items are returned self.assertEqual(len([result for result in results._result_cache if result is not None]), 2) # restore haystack.site = old_site
class ManagementCommandTestCase(TestCase): fixtures = ['bulk_data.json'] def setUp(self): super(ManagementCommandTestCase, self).setUp() self.solr = pysolr.Solr(settings.HAYSTACK_SOLR_URL) self.site = SearchSite() self.site.register(MockModel, SolrMockSearchIndex) # Stow. import haystack self.old_site = haystack.site haystack.site = self.site def tearDown(self): import haystack haystack.site = self.old_site super(ManagementCommandTestCase, self).tearDown() def test_basic_commands(self): call_command('clear_index', interactive=False, verbosity=0) self.assertEqual(self.solr.search('*:*').hits, 0) call_command('update_index', verbosity=0) self.assertEqual(self.solr.search('*:*').hits, 23) call_command('clear_index', interactive=False, verbosity=0) self.assertEqual(self.solr.search('*:*').hits, 0) call_command('rebuild_index', interactive=False, verbosity=0) self.assertEqual(self.solr.search('*:*').hits, 23) def test_remove(self): call_command('clear_index', interactive=False, verbosity=0) self.assertEqual(self.solr.search('*:*').hits, 0) call_command('update_index', verbosity=0) self.assertEqual(self.solr.search('*:*').hits, 23) # Remove a model instance. MockModel.objects.get(pk=1).delete() self.assertEqual(self.solr.search('*:*').hits, 23) # Plain ``update_index`` doesn't fix it. call_command('update_index', verbosity=0) self.assertEqual(self.solr.search('*:*').hits, 23) # With the remove flag, it's gone. call_command('update_index', remove=True, verbosity=0) self.assertEqual(self.solr.search('*:*').hits, 22) def test_multiprocessing(self): call_command('clear_index', interactive=False, verbosity=0) self.assertEqual(self.solr.search('*:*').hits, 0) # Watch the output, make sure there are multiple pids. call_command('update_index', verbosity=2, workers=2, batchsize=5) self.assertEqual(self.solr.search('*:*').hits, 23)
class LiveWhooshAutocompleteTestCase(TestCase): fixtures = ['bulk_data.json'] def setUp(self): super(LiveWhooshAutocompleteTestCase, self).setUp() # Stow. temp_path = os.path.join('tmp', 'test_whoosh_query') self.old_whoosh_path = getattr(settings, 'HAYSTACK_WHOOSH_PATH', temp_path) settings.HAYSTACK_WHOOSH_PATH = temp_path self.site = SearchSite() self.sb = SearchBackend(site=self.site) self.wacsi = WhooshAutocompleteMockModelSearchIndex(MockModel, backend=self.sb) self.site.register(MockModel, WhooshAutocompleteMockModelSearchIndex) # Stow. import haystack self.old_debug = settings.DEBUG settings.DEBUG = True self.old_site = haystack.site haystack.site = self.site self.sb.setup() self.sqs = SearchQuerySet(site=self.site) # Wipe it clean. self.sqs.query.backend.clear() for mock in MockModel.objects.all(): self.wacsi.update_object(mock) def tearDown(self): if os.path.exists(settings.HAYSTACK_WHOOSH_PATH): shutil.rmtree(settings.HAYSTACK_WHOOSH_PATH) settings.HAYSTACK_WHOOSH_PATH = self.old_whoosh_path import haystack haystack.site = self.old_site settings.DEBUG = self.old_debug super(LiveWhooshAutocompleteTestCase, self).tearDown() def test_autocomplete(self): autocomplete = self.sqs.autocomplete(text_auto='mod') self.assertEqual(autocomplete.count(), 5) self.assertEqual([result.pk for result in autocomplete], [u'1', u'12', u'6', u'7', u'14']) self.assertTrue('mod' in autocomplete[0].text.lower()) self.assertTrue('mod' in autocomplete[1].text.lower()) self.assertTrue('mod' in autocomplete[2].text.lower()) self.assertTrue('mod' in autocomplete[3].text.lower()) self.assertTrue('mod' in autocomplete[4].text.lower()) self.assertEqual(len([result.pk for result in autocomplete]), 5) def test_edgengram_regression(self): autocomplete = self.sqs.autocomplete(text_auto='ngm') self.assertEqual(autocomplete.count(), 0)
class SimpleSearchBackendTestCase(TestCase): fixtures = ['bulk_data.json'] def setUp(self): super(SimpleSearchBackendTestCase, self).setUp() self.site = SearchSite() self.backend = SearchBackend(site=self.site) self.index = SimpleMockSearchIndex(MockModel, backend=self.backend) self.site.register(MockModel, SimpleMockSearchIndex) self.sample_objs = MockModel.objects.all() def test_update(self): self.backend.update(self.index, self.sample_objs) def test_remove(self): self.backend.remove(self.sample_objs[0]) def test_clear(self): self.backend.clear() def test_search(self): # No query string should always yield zero results. self.assertEqual(self.backend.search(u''), {'hits': 0, 'results': []}) self.assertEqual(self.backend.search(u'*')['hits'], 23) self.assertEqual([result.pk for result in self.backend.search(u'*')['results']], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]) self.assertEqual(self.backend.search(u'daniel')['hits'], 23) self.assertEqual([result.pk for result in self.backend.search(u'daniel')['results']], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]) self.assertEqual(self.backend.search(u'should be a string')['hits'], 1) self.assertEqual([result.pk for result in self.backend.search(u'should be a string')['results']], [8]) self.assertEqual(self.backend.search(u'index document')['hits'], 6) self.assertEqual([result.pk for result in self.backend.search(u'index document')['results']], [2, 3, 15, 16, 17, 18]) # No support for spelling suggestions self.assertEqual(self.backend.search(u'Indx')['hits'], 0) self.assertFalse(self.backend.search(u'Indx').get('spelling_suggestion')) # No support for facets self.assertEqual(self.backend.search(u'', facets=['name']), {'hits': 0, 'results': []}) self.assertEqual(self.backend.search(u'daniel', facets=['name'])['hits'], 23) self.assertEqual(self.backend.search(u'', date_facets={'pub_date': {'start_date': date(2008, 2, 26), 'end_date': date(2008, 2, 26), 'gap': '/MONTH'}}), {'hits': 0, 'results': []}) self.assertEqual(self.backend.search(u'daniel', date_facets={'pub_date': {'start_date': date(2008, 2, 26), 'end_date': date(2008, 2, 26), 'gap': '/MONTH'}})['hits'], 23) self.assertEqual(self.backend.search(u'', query_facets={'name': '[* TO e]'}), {'hits': 0, 'results': []}) self.assertEqual(self.backend.search(u'daniel', query_facets={'name': '[* TO e]'})['hits'], 23) self.assertFalse(self.backend.search(u'').get('facets')) self.assertFalse(self.backend.search(u'daniel').get('facets')) def test_more_like_this(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(self.backend.search(u'*')['hits'], 23) # Unsupported by 'dummy'. Should see empty results. self.assertEqual(self.backend.more_like_this(self.sample_objs[0])['hits'], 0)
class LiveWhooshAutocompleteTestCase(TestCase): fixtures = ['bulk_data.json'] def setUp(self): super(LiveWhooshAutocompleteTestCase, self).setUp() # Stow. temp_path = os.path.join('tmp', 'test_whoosh_query') self.old_whoosh_path = getattr(settings, 'HAYSTACK_WHOOSH_PATH', temp_path) settings.HAYSTACK_WHOOSH_PATH = temp_path self.site = SearchSite() self.sb = SearchBackend(site=self.site) self.wacsi = WhooshAutocompleteMockModelSearchIndex(MockModel, backend=self.sb) self.site.register(MockModel, WhooshAutocompleteMockModelSearchIndex) # Stow. import haystack self.old_debug = settings.DEBUG settings.DEBUG = True self.old_site = haystack.site haystack.site = self.site self.sb.setup() self.sqs = SearchQuerySet(site=self.site) # Wipe it clean. self.sqs.query.backend.clear() for mock in MockModel.objects.all(): self.wacsi.update_object(mock) def tearDown(self): if os.path.exists(settings.HAYSTACK_WHOOSH_PATH): shutil.rmtree(settings.HAYSTACK_WHOOSH_PATH) settings.HAYSTACK_WHOOSH_PATH = self.old_whoosh_path import haystack haystack.site = self.old_site settings.DEBUG = self.old_debug super(LiveWhooshAutocompleteTestCase, self).tearDown() def test_autocomplete(self): autocomplete = self.sqs.autocomplete(text_auto='mod') self.assertEqual(autocomplete.count(), 5) self.assertEqual([result.pk for result in autocomplete], [u'1', u'12', u'14', u'7', u'6']) self.assertTrue('mod' in autocomplete[0].text.lower()) self.assertTrue('mod' in autocomplete[1].text.lower()) self.assertTrue('mod' in autocomplete[2].text.lower()) self.assertTrue('mod' in autocomplete[3].text.lower()) self.assertTrue('mod' in autocomplete[4].text.lower()) self.assertEqual(len([result.pk for result in autocomplete]), 5)
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(SearchQuerySetTestCase, self).setUp() self.bsqs = SearchQuerySet(query=DummySearchQuery(backend=DummySearchBackend())) self.msqs = SearchQuerySet(query=MockSearchQuery(backend=MockSearchBackend())) # Stow. self.old_site = haystack.site test_site = SearchSite() test_site.register(MockModel) haystack.site = test_site
class MoreLikeThisTagTestCase(TestCase): fixtures = ["bulk_data.json"] def setUp(self): super(MoreLikeThisTagTestCase, self).setUp() self.raw_solr = pysolr.Solr(settings.HAYSTACK_SOLR_URL) self.raw_solr.delete(q="*:*") self.site = SearchSite() self.sb = SearchBackend(site=self.site) self.smmi = MLTSearchIndex(MockModel, backend=self.sb) self.site.register(MockModel, MLTSearchIndex) # Stow. import haystack self.old_site = haystack.site haystack.site = self.site # Force indexing of the content. for mock in MockModel.objects.all(): mock.save() def tearDown(self): import haystack haystack.site = self.old_site super(MoreLikeThisTagTestCase, self).tearDown() def render(self, template, context): # Why on Earth does Django not have a TemplateTestCase yet? t = Template(template) c = Context(context) return t.render(c) def test_more_like_this_with_limit(self): mock = MockModel.objects.get(pk=3) template = """{% load more_like_this %}{% more_like_this entry as related_content limit 5 %}{% for rc in related_content %}{{ rc.id }} {% endfor %}""" context = {"entry": mock} self.assertEqual( set(self.render(template, context).split()), set(u"core.mockmodel.2 core.mockmodel.18 core.mockmodel.23 core.mockmodel.15 core.mockmodel.21 ".split()), ) def test_more_like_this_without_limit(self): mock = MockModel.objects.get(pk=3) template = """{% load more_like_this %}{% more_like_this entry as related_content %}{% for rc in related_content %}{{ rc.id }} {% endfor %}""" context = {"entry": mock} self.assertEqual( set(self.render(template, context).split()), set( u"core.mockmodel.2 core.mockmodel.18 core.mockmodel.23 core.mockmodel.15 core.mockmodel.21 core.mockmodel.13 core.mockmodel.17 core.mockmodel.16 core.mockmodel.20 core.mockmodel.1 core.mockmodel.22 core.mockmodel.19 core.mockmodel.8 core.mockmodel.6 core.mockmodel.4 core.mockmodel.11 core.mockmodel.14 core.mockmodel.12 core.mockmodel.9 core.mockmodel.7 core.mockmodel.10 core.mockmodel.5".split() ), )
class SolrBoostBackendTestCase(TestCase): def setUp(self): super(SolrBoostBackendTestCase, self).setUp() # Wipe it clean. self.raw_solr = pysolr.Solr(settings.HAYSTACK_SOLR_URL) clear_solr_index() self.site = SearchSite() self.sb = SearchBackend(site=self.site) self.smmi = SolrBoostMockSearchIndex(AFourthMockModel, backend=self.sb) self.site.register(AFourthMockModel, SolrBoostMockSearchIndex) # 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(SolrBoostBackendTestCase, self).tearDown() def test_boost(self): self.sb.update(self.smmi, self.sample_objs) self.assertEqual(self.raw_solr.search("*:*").hits, 4) results = SearchQuerySet().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 MoreLikeThisTagTestCase(TestCase): fixtures = ['bulk_data.json'] def setUp(self): super(MoreLikeThisTagTestCase, self).setUp() self.raw_solr = pysolr.Solr(settings.HAYSTACK_SOLR_URL) self.raw_solr.delete(q='*:*') self.site = SearchSite() self.sb = SearchBackend(site=self.site) self.smmi = MLTSearchIndex(MockModel, backend=self.sb) self.site.register(MockModel, MLTSearchIndex) # Stow. import haystack self.old_site = haystack.site haystack.site = self.site # Force indexing of the content. for mock in MockModel.objects.all(): mock.save() def tearDown(self): import haystack haystack.site = self.old_site super(MoreLikeThisTagTestCase, self).tearDown() def render(self, template, context): # Why on Earth does Django not have a TemplateTestCase yet? t = Template(template) c = Context(context) return t.render(c) def test_more_like_this_with_limit(self): mock = MockModel.objects.get(pk=3) template = """{% load more_like_this %}{% more_like_this entry as related_content limit 5 %}{% for rc in related_content %}{{ rc.id }} {% endfor %}""" context = { 'entry': mock, } self.assertEqual( set(self.render(template, context).split()), set(u'core.mockmodel.2 core.mockmodel.18 core.mockmodel.23 core.mockmodel.15 core.mockmodel.21 ' .split())) def test_more_like_this_without_limit(self): mock = MockModel.objects.get(pk=3) template = """{% load more_like_this %}{% more_like_this entry as related_content %}{% for rc in related_content %}{{ rc.id }} {% endfor %}""" context = { 'entry': mock, } self.assertEqual( set(self.render(template, context).split()), set(u'core.mockmodel.2 core.mockmodel.18 core.mockmodel.23 core.mockmodel.15 core.mockmodel.21 core.mockmodel.13 core.mockmodel.17 core.mockmodel.16 core.mockmodel.20 core.mockmodel.1 core.mockmodel.22 core.mockmodel.19 core.mockmodel.8 core.mockmodel.6 core.mockmodel.4 core.mockmodel.11 core.mockmodel.14 core.mockmodel.12 core.mockmodel.9 core.mockmodel.7 core.mockmodel.10 core.mockmodel.5' .split()))
def setUp(self): super(FacetedSearchFormTestCase, self).setUp() mock_index_site = SearchSite() mock_index_site.register(MockModel) mock_index_site.register(AnotherMockModel) # Stow. self.old_site = haystack.site haystack.site = mock_index_site self.sqs = SearchQuerySet(query=DummySearchQuery(backend=DummySearchBackend()), site=mock_index_site)
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)
def setUp(self): super(SearchViewTestCase, self).setUp() mock_index_site = SearchSite() mock_index_site.register(MockModel) mock_index_site.register(AnotherMockModel) # Stow. self.old_site = haystack.site haystack.site = mock_index_site self.old_engine = getattr(settings, 'HAYSTACK_SEARCH_ENGINE') settings.HAYSTACK_SEARCH_ENGINE = 'dummy'
def test_run(self): # Stow. old_site = haystack.site test_site = SearchSite() test_site.register(MockModel) haystack.site = test_site msq = MockSearchQuery(backend=MockSearchBackend()) self.assertEqual(len(msq.get_results()), 100) self.assertEqual(msq.get_results()[0], MOCK_SEARCH_RESULTS[0]) # Restore. haystack.site = old_site
def setUp(self): super(ModelSearchFormTestCase, self).setUp() mock_index_site = SearchSite() mock_index_site.register(MockModel) mock_index_site.register(AnotherMockModel) # Stow. self.old_site = haystack.site haystack.site = mock_index_site self.sqs = SearchQuerySet( query=DummySearchQuery(backend=DummySearchBackend()), site=mock_index_site)
class SolrBoostBackendTestCase(TestCase): def setUp(self): super(SolrBoostBackendTestCase, self).setUp() # Wipe it clean. self.raw_solr = pysolr.Solr(settings.HAYSTACK_SOLR_URL) clear_solr_index() self.site = SearchSite() self.sb = SearchBackend(site=self.site) self.smmi = SolrBoostMockSearchIndex(AFourthMockModel, backend=self.sb) self.site.register(AFourthMockModel, SolrBoostMockSearchIndex) # 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(SolrBoostBackendTestCase, self).tearDown() def test_boost(self): self.sb.update(self.smmi, self.sample_objs) self.assertEqual(self.raw_solr.search('*:*').hits, 4) results = SearchQuerySet().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(SearchQuerySetTestCase, self).setUp() self.bsqs = SearchQuerySet(query=DummySearchQuery(backend=DummySearchBackend())) self.msqs = SearchQuerySet(query=MockSearchQuery(backend=MockSearchBackend())) self.mmsqs = SearchQuerySet(query=MockSearchQuery(backend=MixedMockSearchBackend())) # Stow. self.old_debug = settings.DEBUG settings.DEBUG = True self.old_site = haystack.site test_site = SearchSite() test_site.register(MockModel) haystack.site = test_site backends.reset_search_queries()
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(PickleSearchQuerySetTestCase, self).setUp() self.bsqs = SearchQuerySet(query=DummySearchQuery(backend=DummySearchBackend())) self.msqs = SearchQuerySet(query=MockSearchQuery(backend=MockSearchBackend())) self.mmsqs = SearchQuerySet(query=MockSearchQuery(backend=MixedMockSearchBackend())) # Stow. self.old_debug = settings.DEBUG settings.DEBUG = True self.old_site = haystack.site test_site = SearchSite() test_site.register(MockModel) test_site.register(CharPKMockModel) haystack.site = test_site backends.reset_search_queries()
def setUp(self): super(LiveSolrSearchQueryTestCase, self).setUp() # Wipe it clean. clear_solr_index() site = SearchSite() site.register(MockModel, SolrMockSearchIndex) sb = SearchBackend(site=site) smmi = SolrMockSearchIndex(MockModel, backend=sb) self.sq = SearchQuery(backend=sb) # Force indexing of the content. mockmodel_index = site.get_index(MockModel) mockmodel_index.update()
def test_all_cases(self): self.sample_objs = [] for i in xrange(1, 4): mock = MockModel() mock.id = i mock.author = "daniel%s" % i mock.pub_date = datetime.date(2009, 2, 25) - datetime.timedelta(days=i) self.sample_objs.append(mock) # Stow. # Point the backend at a URL that doesn't exist so we can watch the # sparks fly. old_solr_url = settings.HAYSTACK_SOLR_URL settings.HAYSTACK_SOLR_URL = "%s/foo/" % settings.HAYSTACK_SOLR_URL cap = CaptureHandler() logging.getLogger("haystack").addHandler(cap) import haystack logging.getLogger("haystack").removeHandler(haystack.stream) # Setup the rest of the bits. site = SearchSite() site.register(MockModel, SolrMockSearchIndex) sb = SearchBackend(site=site) smmi = SolrMockSearchIndex(MockModel, backend=sb) # Prior to the addition of the try/except bits, these would all fail miserably. self.assertEqual(len(CaptureHandler.logs_seen), 0) sb.update(smmi, self.sample_objs) self.assertEqual(len(CaptureHandler.logs_seen), 1) sb.remove(self.sample_objs[0]) self.assertEqual(len(CaptureHandler.logs_seen), 2) sb.search("search") self.assertEqual(len(CaptureHandler.logs_seen), 3) sb.more_like_this(self.sample_objs[0]) self.assertEqual(len(CaptureHandler.logs_seen), 4) sb.clear([MockModel]) self.assertEqual(len(CaptureHandler.logs_seen), 5) sb.clear() self.assertEqual(len(CaptureHandler.logs_seen), 6) # Restore. settings.HAYSTACK_SOLR_URL = old_solr_url logging.getLogger("haystack").removeHandler(cap) logging.getLogger("haystack").addHandler(haystack.stream)
def test_all_cases(self): self.sample_objs = [] for i in xrange(1, 4): mock = MockModel() mock.id = i mock.author = 'daniel%s' % i mock.pub_date = datetime.date(2009, 2, 25) - datetime.timedelta(days=i) self.sample_objs.append(mock) # Stow. # Point the backend at a URL that doesn't exist so we can watch the # sparks fly. old_solr_url = settings.HAYSTACK_SOLR_URL settings.HAYSTACK_SOLR_URL = "%s/foo/" % settings.HAYSTACK_SOLR_URL cap = CaptureHandler() logging.getLogger('haystack').addHandler(cap) import haystack logging.getLogger('haystack').removeHandler(haystack.stream) # Setup the rest of the bits. site = SearchSite() site.register(MockModel, SolrMockSearchIndex) sb = SearchBackend(site=site) smmi = SolrMockSearchIndex(MockModel, backend=sb) # Prior to the addition of the try/except bits, these would all fail miserably. self.assertEqual(len(CaptureHandler.logs_seen), 0) sb.update(smmi, self.sample_objs) self.assertEqual(len(CaptureHandler.logs_seen), 1) sb.remove(self.sample_objs[0]) self.assertEqual(len(CaptureHandler.logs_seen), 2) sb.search('search') self.assertEqual(len(CaptureHandler.logs_seen), 3) sb.more_like_this(self.sample_objs[0]) self.assertEqual(len(CaptureHandler.logs_seen), 4) sb.clear([MockModel]) self.assertEqual(len(CaptureHandler.logs_seen), 5) sb.clear() self.assertEqual(len(CaptureHandler.logs_seen), 6) # Restore. settings.HAYSTACK_SOLR_URL = old_solr_url logging.getLogger('haystack').removeHandler(cap) logging.getLogger('haystack').addHandler(haystack.stream)
def setUp(self): super(LiveSolrSearchQuerySetTestCase, self).setUp() self.sqs = SearchQuerySet() # With the models registered, you get the proper bits. import haystack from haystack.sites import SearchSite # Stow. self.old_site = haystack.site test_site = SearchSite() test_site.register(MockModel) haystack.site = test_site # Force indexing of the content. for mock in MockModel.objects.all(): mock.save()
def test_models(self): mock_index_site = SearchSite() mock_index_site.register(MockModel) mock_index_site.register(AnotherMockModel) bsqs = SearchQuerySet(site=mock_index_site) sqs = bsqs.all() self.assert_(isinstance(sqs, SearchQuerySet)) self.assertEqual(len(sqs.query.models), 0) sqs = bsqs.models(MockModel) self.assert_(isinstance(sqs, SearchQuerySet)) self.assertEqual(len(sqs.query.models), 1) sqs = bsqs.models(MockModel, AnotherMockModel) self.assert_(isinstance(sqs, SearchQuerySet)) self.assertEqual(len(sqs.query.models), 2)
def setUp(self): super(LiveSolrAutocompleteTestCase, self).setUp() # Wipe it clean. clear_solr_index() # With the models registered, you get the proper bits. import haystack from haystack.sites import SearchSite # Stow. self.old_site = haystack.site test_site = SearchSite() test_site.register(MockModel, SolrAutocompleteMockModelSearchIndex) haystack.site = test_site self.sqs = SearchQuerySet() test_site.get_index(MockModel).update()
def test_use_correct_site(self): test_site = SearchSite() test_site.register(XapianMockModel, XapianMockSearchIndex) self.backend.update(self.index, self.sample_objs) # Make sure that ``_process_results`` uses the right ``site``. self.assertEqual( self.backend.search(xapian.Query('indexed'))['hits'], 3) self.assertEqual([ result.pk for result in self.backend.search(xapian.Query( 'indexed'))['results'] ], [1, 2, 3]) self.site.unregister(XapianMockModel) self.assertEqual(len(self.site.get_indexed_models()), 0) self.backend.site = test_site self.assertTrue(len(self.backend.site.get_indexed_models()) > 0) # Should still be there, despite the main ``site`` not having that model # registered any longer. self.assertEqual( self.backend.search(xapian.Query('indexed'))['hits'], 3) self.assertEqual([ result.pk for result in self.backend.search(xapian.Query( 'indexed'))['results'] ], [1, 2, 3]) # Unregister it on the backend & make sure it takes effect. self.backend.site.unregister(XapianMockModel) self.assertEqual(len(self.backend.site.get_indexed_models()), 0) self.assertEqual( self.backend.search(xapian.Query('indexed'))['hits'], 0) # Nuke it & fallback on the main ``site``. self.backend.site = haystack.site self.assertEqual( self.backend.search(xapian.Query('indexed'))['hits'], 0) self.site.register(XapianMockModel, XapianMockSearchIndex) self.assertEqual( self.backend.search(xapian.Query('indexed'))['hits'], 3)
def setUp(self): super(LiveSolrRelatedSearchQuerySetTestCase, self).setUp() # With the models registered, you get the proper bits. import haystack from haystack.sites import SearchSite # Stow. self.old_debug = settings.DEBUG settings.DEBUG = True self.old_site = haystack.site test_site = SearchSite() test_site.register(MockModel, SolrMockModelSearchIndex) haystack.site = test_site self.rsqs = RelatedSearchQuerySet() # Wipe it clean. self.rsqs.query.backend.clear() # Force indexing of the content. for mock in MockModel.objects.all(): mock.save()
def test_models(self): mock_index_site = SearchSite() mock_index_site.register(MockModel) mock_index_site.register(AnotherMockModel) bsqs = SearchQuerySet(site=mock_index_site) sqs = bsqs.all() self.assert_(isinstance(sqs, SearchQuerySet)) self.assertEqual(len(sqs.query.models), 0) sqs = bsqs.models(MockModel) self.assert_(isinstance(sqs, SearchQuerySet)) self.assertEqual(len(sqs.query.models), 1) sqs = bsqs.models(MockModel, AnotherMockModel) self.assert_(isinstance(sqs, SearchQuerySet)) self.assertEqual(len(sqs.query.models), 2) # This will produce a warning. mock_index_site.unregister(AnotherMockModel) sqs = bsqs.models(AnotherMockModel) self.assert_(isinstance(sqs, SearchQuerySet)) self.assertEqual(len(sqs.query.models), 1)
def setUp(self): super(LiveSolrRoundTripTestCase, self).setUp() # Wipe it clean. clear_solr_index() # With the models registered, you get the proper bits. import haystack from haystack.sites import SearchSite # Stow. self.old_site = haystack.site test_site = SearchSite() test_site.register(MockModel, SolrRoundTripSearchIndex) haystack.site = test_site self.sqs = SearchQuerySet() # Fake indexing. sb = SearchBackend(site=test_site) srtsi = SolrRoundTripSearchIndex(MockModel) mock = MockModel() mock.id = 1 sb.update(srtsi, [mock])
def test_load_all_read_queryset(self): # stow old_site = haystack.site test_site = SearchSite() # Register a default SearchIndex first (without the SoftDeleteMangaer as the read_queryset) test_site.register(AFifthMockModel) haystack.site = test_site sqs = SearchQuerySet(query=MockSearchQuery( backend=ReadQuerySetMockSearchBackend())) results = sqs.load_all().all() results._fill_cache(0, 2) # The deleted result isn't returned self.assertEqual( len([ result for result in results._result_cache if result is not None ]), 1) test_site.unregister(AFifthMockModel) # Register a SearchIndex with a read_queryset that returns deleted items test_site.register(AFifthMockModel, ReadQuerySetTestSearchIndex) sqs = SearchQuerySet(query=MockSearchQuery( backend=ReadQuerySetMockSearchBackend())) results = sqs.load_all().all() results._fill_cache(0, 2) # Both the deleted and not deleted items are returned self.assertEqual( len([ result for result in results._result_cache if result is not None ]), 2) # restore haystack.site = old_site
class WhooshSearchBackendTestCase(TestCase): fixtures = ['bulk_data.json'] def setUp(self): super(WhooshSearchBackendTestCase, self).setUp() # Stow. temp_path = os.path.join('tmp', 'test_whoosh_query') self.old_whoosh_path = getattr(settings, 'HAYSTACK_WHOOSH_PATH', temp_path) settings.HAYSTACK_WHOOSH_PATH = temp_path self.site = SearchSite() self.sb = SearchBackend(site=self.site) self.smmi = WhooshMockSearchIndex(MockModel, backend=self.sb) self.wmtmmi = WhooshMaintainTypeMockSearchIndex(MockModel, backend=self.sb) self.site.register(MockModel, WhooshMockSearchIndex) # With the models registered, you get the proper bits. import haystack # Stow. self.old_site = haystack.site haystack.site = self.site self.sb.setup() self.raw_whoosh = self.sb.index self.parser = QueryParser(self.sb.content_field_name, schema=self.sb.schema) self.sb.delete_index() self.sample_objs = MockModel.objects.all() def tearDown(self): if os.path.exists(settings.HAYSTACK_WHOOSH_PATH): shutil.rmtree(settings.HAYSTACK_WHOOSH_PATH) settings.HAYSTACK_WHOOSH_PATH = self.old_whoosh_path # Restore. import haystack haystack.site = self.old_site super(WhooshSearchBackendTestCase, self).tearDown() def whoosh_search(self, query): self.raw_whoosh = self.raw_whoosh.refresh() searcher = self.raw_whoosh.searcher() return searcher.search(self.parser.parse(query), limit=1000) def test_update(self): self.sb.update(self.smmi, self.sample_objs) # Check what Whoosh thinks is there. self.assertEqual(len(self.whoosh_search(u'*')), 23) self.assertEqual( [doc.fields()['id'] for doc in self.whoosh_search(u'*')], [u'core.mockmodel.%s' % i for i in xrange(1, 24)]) def test_remove(self): self.sb.update(self.smmi, self.sample_objs) self.assertEqual(self.sb.index.doc_count(), 23) self.sb.remove(self.sample_objs[0]) self.assertEqual(self.sb.index.doc_count(), 22) def test_clear(self): self.sb.update(self.smmi, self.sample_objs) self.assertEqual(self.sb.index.doc_count(), 23) self.sb.clear() self.assertEqual(self.sb.index.doc_count(), 0) self.sb.update(self.smmi, self.sample_objs) self.assertEqual(self.sb.index.doc_count(), 23) self.sb.clear([AnotherMockModel]) self.assertEqual(self.sb.index.doc_count(), 23) self.sb.clear([MockModel]) self.assertEqual(self.sb.index.doc_count(), 0) self.sb.index.refresh() self.sb.update(self.smmi, self.sample_objs) self.assertEqual(self.sb.index.doc_count(), 23) self.sb.clear([AnotherMockModel, MockModel]) self.assertEqual(self.raw_whoosh.doc_count(), 0) def test_search(self): self.sb.update(self.smmi, self.sample_objs) self.assertEqual(len(self.whoosh_search(u'*')), 23) # No query string should always yield zero results. self.assertEqual(self.sb.search(u''), {'hits': 0, 'results': []}) # A one letter query string gets nabbed by a stopwords filter. Should # always yield zero results. self.assertEqual(self.sb.search(u'a'), {'hits': 0, 'results': []}) # Possible AttributeError? # self.assertEqual(self.sb.search(u'a b'), {'hits': 0, 'results': [], 'spelling_suggestion': '', 'facets': {}}) self.assertEqual(self.sb.search(u'*')['hits'], 23) self.assertEqual( [result.pk for result in self.sb.search(u'*')['results']], [u'%s' % i for i in xrange(1, 24)]) self.assertEqual(self.sb.search(u'', highlight=True), { 'hits': 0, 'results': [] }) self.assertEqual(self.sb.search(u'index*', highlight=True)['hits'], 23) # DRL_FIXME: Uncomment once highlighting works. # 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(u'Indx')['hits'], 0) self.assertEqual( self.sb.search(u'Indx')['spelling_suggestion'], u'index') self.assertEqual(self.sb.search(u'', facets=['name']), { 'hits': 0, 'results': [] }) results = self.sb.search(u'Index*', facets=['name']) results = self.sb.search(u'index*', facets=['name']) self.assertEqual(results['hits'], 23) self.assertEqual(results['facets'], {}) self.assertEqual( self.sb.search(u'', date_facets={ 'pub_date': { 'start_date': date(2008, 2, 26), 'end_date': date(2008, 2, 26), 'gap': '/MONTH' } }), { 'hits': 0, 'results': [] }) results = self.sb.search(u'Index*', date_facets={ 'pub_date': { 'start_date': date(2008, 2, 26), 'end_date': date(2008, 2, 26), 'gap': '/MONTH' } }) results = self.sb.search(u'index*', date_facets={ 'pub_date': { 'start_date': date(2008, 2, 26), 'end_date': date(2008, 2, 26), 'gap': '/MONTH' } }) self.assertEqual(results['hits'], 23) self.assertEqual(results['facets'], {}) self.assertEqual( self.sb.search(u'', query_facets={'name': '[* TO e]'}), { 'hits': 0, 'results': [] }) results = self.sb.search(u'Index*', query_facets={'name': '[* TO e]'}) results = self.sb.search(u'index*', query_facets={'name': '[* TO e]'}) self.assertEqual(results['hits'], 23) self.assertEqual(results['facets'], {}) # self.assertEqual(self.sb.search('', narrow_queries=set(['name:daniel1'])), {'hits': 0, 'results': []}) # results = self.sb.search('Index*', narrow_queries=set(['name:daniel1'])) # self.assertEqual(results['hits'], 1) # Ensure that swapping the ``result_class`` works. self.assertTrue( isinstance( self.sb.search(u'Index*', result_class=MockSearchResult)['results'][0], MockSearchResult)) # Check the use of ``limit_to_registered_models``. self.assertEqual(self.sb.search(u'', limit_to_registered_models=False), { 'hits': 0, 'results': [] }) self.assertEqual( self.sb.search(u'*', limit_to_registered_models=False)['hits'], 23) self.assertEqual([ result.pk for result in self.sb.search( u'*', limit_to_registered_models=False)['results'] ], [u'%s' % i for i in xrange(1, 24)]) # Stow. old_limit_to_registered_models = getattr( settings, 'HAYSTACK_LIMIT_TO_REGISTERED_MODELS', True) settings.HAYSTACK_LIMIT_TO_REGISTERED_MODELS = False self.assertEqual(self.sb.search(u''), {'hits': 0, 'results': []}) self.assertEqual(self.sb.search(u'*')['hits'], 23) self.assertEqual( [result.pk for result in self.sb.search(u'*')['results']], [u'%s' % i for i in xrange(1, 24)]) # Restore. settings.HAYSTACK_LIMIT_TO_REGISTERED_MODELS = old_limit_to_registered_models def test_more_like_this(self): self.sb.update(self.smmi, self.sample_objs) self.assertEqual(len(self.whoosh_search(u'*')), 23) # Unsupported by Whoosh. Should see empty results. self.assertEqual( self.sb.more_like_this(self.sample_objs[0])['hits'], 0) # Make sure that swapping the ``result_class`` doesn't blow up. try: self.sb.search(u'index document', result_class=MockSearchResult) except: self.fail() def test_delete_index(self): self.sb.update(self.smmi, self.sample_objs) self.assert_(self.sb.index.doc_count() > 0) self.sb.delete_index() self.assertEqual(self.sb.index.doc_count(), 0) def test_order_by(self): self.sb.update(self.smmi, self.sample_objs) results = self.sb.search(u'*', sort_by=['pub_date']) self.assertEqual([result.pk for result in results['results']], [ u'1', u'3', u'2', u'4', u'5', u'6', u'7', u'8', u'9', u'10', u'11', u'12', u'13', u'14', u'15', u'16', u'17', u'18', u'19', u'20', u'21', u'22', u'23' ]) results = self.sb.search(u'*', sort_by=['-pub_date']) self.assertEqual([result.pk for result in results['results']], [ u'23', u'22', u'21', u'20', u'19', u'18', u'17', u'16', u'15', u'14', u'13', u'12', u'11', u'10', u'9', u'8', u'7', u'6', u'5', u'4', u'2', u'3', u'1' ]) results = self.sb.search(u'*', sort_by=['id']) self.assertEqual([result.pk for result in results['results']], [ u'1', u'10', u'11', u'12', u'13', u'14', u'15', u'16', u'17', u'18', u'19', u'2', u'20', u'21', u'22', u'23', u'3', u'4', u'5', u'6', u'7', u'8', u'9' ]) results = self.sb.search(u'*', sort_by=['-id']) self.assertEqual([result.pk for result in results['results']], [ u'9', u'8', u'7', u'6', u'5', u'4', u'3', u'23', u'22', u'21', u'20', u'2', u'19', u'18', u'17', u'16', u'15', u'14', u'13', u'12', u'11', u'10', u'1' ]) def test__from_python(self): self.assertEqual(self.sb._from_python('abc'), u'abc') self.assertEqual(self.sb._from_python(1), 1) self.assertEqual(self.sb._from_python(2653), 2653) self.assertEqual(self.sb._from_python(25.5), 25.5) 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(2009, 5, 9, 16, 14)), datetime(2009, 5, 9, 16, 14)) self.assertEqual(self.sb._from_python(datetime(2009, 5, 9, 0, 0)), datetime(2009, 5, 9, 0, 0)) self.assertEqual(self.sb._from_python(datetime(1899, 5, 18, 0, 0)), datetime(1899, 5, 18, 0, 0)) self.assertEqual( self.sb._from_python(datetime(2009, 5, 18, 1, 16, 30, 250)), datetime(2009, 5, 18, 1, 16, 30, 250)) def test__to_python(self): self.assertEqual(self.sb._to_python('abc'), 'abc') self.assertEqual(self.sb._to_python('1'), 1) self.assertEqual(self.sb._to_python('2653'), 2653) self.assertEqual(self.sb._to_python('25.5'), 25.5) self.assertEqual(self.sb._to_python('[1, 2, 3]'), [1, 2, 3]) self.assertEqual(self.sb._to_python('{"a": 1, "b": 2, "c": 3}'), { 'a': 1, 'c': 3, 'b': 2 }) self.assertEqual(self.sb._to_python('2009-05-09T16:14:00'), datetime(2009, 5, 9, 16, 14)) self.assertEqual(self.sb._to_python('2009-05-09T00:00:00'), datetime(2009, 5, 9, 0, 0)) self.assertEqual(self.sb._to_python(None), None) def test_range_queries(self): self.sb.update(self.smmi, self.sample_objs) self.assertEqual(len(self.whoosh_search(u'[d TO]')), 23) self.assertEqual(len(self.whoosh_search(u'name:[d TO]')), 23) self.assertEqual(len(self.whoosh_search(u'Ind* AND name:[d TO]')), 23) self.assertEqual(len(self.whoosh_search(u'Ind* AND name:[TO c]')), 0) def test_date_queries(self): self.sb.update(self.smmi, self.sample_objs) self.assertEqual(len(self.whoosh_search(u"pub_date:20090717T003000")), 1) self.assertEqual(len(self.whoosh_search(u"pub_date:20090717T000000")), 0) self.assertEqual( len(self.whoosh_search(u'Ind* AND pub_date:[TO 20090717T003000]')), 3) def test_escaped_characters_queries(self): self.sb.update(self.smmi, self.sample_objs) self.assertEqual(len(self.whoosh_search(u"Indexed\!")), 23) self.assertEqual( len(self.whoosh_search(u"http\:\/\/www\.example\.com")), 0) def test_build_schema(self): self.site.unregister(MockModel) self.site.register(MockModel, AllTypesWhooshMockSearchIndex) (content_field_name, schema) = self.sb.build_schema(self.site.all_searchfields()) self.assertEqual(content_field_name, 'text') self.assertEqual(len(schema.names()), 8) self.assertEqual(schema.names(), [ 'django_ct', 'django_id', 'id', 'name', 'pub_date', 'seen_count', 'sites', 'text' ]) self.assert_(isinstance(schema._fields['text'], TEXT)) self.assert_(isinstance(schema._fields['pub_date'], DATETIME)) self.assert_(isinstance(schema._fields['seen_count'], NUMERIC)) self.assert_(isinstance(schema._fields['sites'], KEYWORD)) def test_verify_type(self): import haystack haystack.site.unregister(MockModel) haystack.site.register(MockModel, WhooshMaintainTypeMockSearchIndex) self.sb.setup() self.sb.update(self.wmtmmi, self.sample_objs) self.assertEqual(self.sb.search(u'*')['hits'], 23) self.assertEqual( [result.month for result in self.sb.search(u'*')['results']], [ u'06', u'07', u'06', u'07', u'07', u'07', u'07', u'07', u'07', u'07', u'07', u'07', u'07', u'07', u'07', u'07', u'07', u'07', u'07', u'07', u'07', u'07', u'07' ]) def test_writable(self): if getattr(settings, 'HAYSTACK_WHOOSH_STORAGE', 'file') == 'file': if not os.path.exists(settings.HAYSTACK_WHOOSH_PATH): os.makedirs(settings.HAYSTACK_WHOOSH_PATH) os.chmod(settings.HAYSTACK_WHOOSH_PATH, 0400) try: self.sb.setup() self.fail() except IOError: # Yay. We failed pass os.chmod(settings.HAYSTACK_WHOOSH_PATH, 0755) def test_slicing(self): self.sb.update(self.smmi, self.sample_objs) page_1 = self.sb.search(u'*', start_offset=0, end_offset=20) page_2 = self.sb.search(u'*', start_offset=20, end_offset=30) self.assertEqual(len(page_1['results']), 20) self.assertEqual([result.pk for result in page_1['results']], [u'%s' % i for i in xrange(1, 21)]) self.assertEqual(len(page_2['results']), 3) self.assertEqual([result.pk for result in page_2['results']], [u'21', u'22', u'23']) # This used to throw an error. page_0 = self.sb.search(u'*', start_offset=0, end_offset=0) self.assertEqual(len(page_0['results']), 1) def test_scoring(self): self.sb.update(self.smmi, self.sample_objs) page_1 = self.sb.search(u'index', start_offset=0, end_offset=20) page_2 = self.sb.search(u'index', start_offset=20, end_offset=30) self.assertEqual(len(page_1['results']), 20) self.assertEqual( ["%0.2f" % result.score for result in page_1['results']], [ '0.51', '0.51', '0.51', '0.51', '0.51', '0.51', '0.51', '0.51', '0.51', '0.40', '0.40', '0.40', '0.40', '0.40', '0.40', '0.40', '0.40', '0.40', '0.40', '0.40' ]) self.assertEqual(len(page_2['results']), 3) self.assertEqual( ["%0.2f" % result.score for result in page_2['results']], ['0.40', '0.40', '0.40'])
class LiveWhooshSearchQuerySetTestCase(TestCase): def setUp(self): super(LiveWhooshSearchQuerySetTestCase, self).setUp() # Stow. temp_path = os.path.join('tmp', 'test_whoosh_query') self.old_whoosh_path = getattr(settings, 'HAYSTACK_WHOOSH_PATH', temp_path) settings.HAYSTACK_WHOOSH_PATH = temp_path self.site = SearchSite() self.sb = SearchBackend(site=self.site) self.smmi = WhooshMockSearchIndex(MockModel, backend=self.sb) self.site.register(MockModel, WhooshMockSearchIndex) # Stow. import haystack self.old_debug = settings.DEBUG settings.DEBUG = True self.old_site = haystack.site haystack.site = self.site self.sb.setup() self.raw_whoosh = self.sb.index self.parser = QueryParser(self.sb.content_field_name, schema=self.sb.schema) self.sb.delete_index() self.sample_objs = [] for i in xrange(1, 4): mock = MockModel() mock.id = i mock.author = 'daniel%s' % i mock.pub_date = date(2009, 2, 25) - timedelta(days=i) self.sample_objs.append(mock) self.sq = SearchQuery(backend=self.sb) self.sqs = SearchQuerySet(site=self.site) def tearDown(self): if os.path.exists(settings.HAYSTACK_WHOOSH_PATH): shutil.rmtree(settings.HAYSTACK_WHOOSH_PATH) settings.HAYSTACK_WHOOSH_PATH = self.old_whoosh_path import haystack haystack.site = self.old_site settings.DEBUG = self.old_debug super(LiveWhooshSearchQuerySetTestCase, self).tearDown() def test_various_searchquerysets(self): self.sb.update(self.smmi, self.sample_objs) sqs = self.sqs.filter(content='Index') self.assertEqual(sqs.query.build_query(), u'Index') self.assertEqual(len(sqs), 3) sqs = self.sqs.auto_query('Indexed!') self.assertEqual(sqs.query.build_query(), u"'Indexed!'") self.assertEqual(len(sqs), 3) sqs = self.sqs.auto_query('Indexed!').filter( pub_date__lte=date(2009, 8, 31)) self.assertEqual(sqs.query.build_query(), u"('Indexed!' AND pub_date:[TO 20090831T000000])") self.assertEqual(len(sqs), 3) sqs = self.sqs.auto_query('Indexed!').filter( pub_date__lte=date(2009, 2, 23)) self.assertEqual(sqs.query.build_query(), u"('Indexed!' AND pub_date:[TO 20090223T000000])") self.assertEqual(len(sqs), 2) sqs = self.sqs.auto_query('Indexed!').filter( pub_date__lte=date(2009, 2, 25)).filter( django_id__in=[1, 2]).exclude(name='daniel1') self.assertEqual( sqs.query.build_query(), u"('Indexed!' AND pub_date:[TO 20090225T000000] AND (django_id:\"1\" OR django_id:\"2\") AND NOT (name:daniel1))" ) self.assertEqual(len(sqs), 1) sqs = self.sqs.auto_query('re-inker') self.assertEqual(sqs.query.build_query(), u"'re-inker'") self.assertEqual(len(sqs), 0) sqs = self.sqs.auto_query('0.7 wire') self.assertEqual(sqs.query.build_query(), u"('0.7' AND wire)") self.assertEqual(len(sqs), 0) sqs = self.sqs.auto_query("daler-rowney pearlescent 'bell bronze'") self.assertEqual( sqs.query.build_query(), u"('daler-rowney' AND pearlescent AND 'bell AND bronze')") self.assertEqual(len(sqs), 0) sqs = self.sqs.models(MockModel) self.assertEqual(sqs.query.build_query(), u'django_ct:core.mockmodel') self.assertEqual(len(sqs), 3) def test_all_regression(self): sqs = SearchQuerySet() self.assertEqual([result.pk for result in sqs], []) self.sb.update(self.smmi, self.sample_objs) self.assert_(self.sb.index.doc_count() > 0) sqs = SearchQuerySet() self.assertEqual(len(sqs), 3) self.assertEqual(sorted([result.pk for result in sqs]), [u'1', u'2', u'3']) try: sqs = repr(SearchQuerySet()) except: self.fail() def test_regression_space_query(self): self.sb.update(self.smmi, self.sample_objs) self.assert_(self.sb.index.doc_count() > 0) sqs = SearchQuerySet().auto_query(" ") self.assertEqual(len(sqs), 3) sqs = SearchQuerySet().filter(content=" ") self.assertEqual(len(sqs), 0) def test_iter(self): self.sb.update(self.smmi, self.sample_objs) backends.reset_search_queries() self.assertEqual(len(backends.queries), 0) sqs = self.sqs.auto_query('Indexed!') results = [int(result.pk) for result in sqs] self.assertEqual(sorted(results), [1, 2, 3]) self.assertEqual(len(backends.queries), 1) def test_slice(self): self.sb.update(self.smmi, self.sample_objs) backends.reset_search_queries() self.assertEqual(len(backends.queries), 0) results = self.sqs.auto_query('Indexed!') self.assertEqual(sorted([int(result.pk) for result in results[1:3]]), [1, 2]) self.assertEqual(len(backends.queries), 1) backends.reset_search_queries() self.assertEqual(len(backends.queries), 0) results = self.sqs.auto_query('Indexed!') self.assertEqual(int(results[0].pk), 1) self.assertEqual(len(backends.queries), 1) def test_manual_iter(self): self.sb.update(self.smmi, self.sample_objs) results = self.sqs.auto_query('Indexed!') backends.reset_search_queries() self.assertEqual(len(backends.queries), 0) results = [int(result.pk) for result in results._manual_iter()] self.assertEqual(sorted(results), [1, 2, 3]) self.assertEqual(len(backends.queries), 1) def test_fill_cache(self): self.sb.update(self.smmi, self.sample_objs) backends.reset_search_queries() self.assertEqual(len(backends.queries), 0) results = self.sqs.auto_query('Indexed!') self.assertEqual(len(results._result_cache), 0) self.assertEqual(len(backends.queries), 0) results._fill_cache(0, 10) self.assertEqual( len([ result for result in results._result_cache if result is not None ]), 3) self.assertEqual(len(backends.queries), 1) results._fill_cache(10, 20) self.assertEqual( len([ result for result in results._result_cache if result is not None ]), 3) self.assertEqual(len(backends.queries), 2) def test_cache_is_full(self): self.sb.update(self.smmi, self.sample_objs) backends.reset_search_queries() self.assertEqual(len(backends.queries), 0) self.assertEqual(self.sqs._cache_is_full(), False) results = self.sqs.auto_query('Indexed!') fire_the_iterator_and_fill_cache = [result for result in results] self.assertEqual(results._cache_is_full(), True) self.assertEqual(len(backends.queries), 1) def test_count(self): more_samples = [] for i in xrange(1, 50): mock = MockModel() mock.id = i mock.author = 'daniel%s' % i mock.pub_date = date(2009, 2, 25) - timedelta(days=i) more_samples.append(mock) self.sb.update(self.smmi, more_samples) backends.reset_search_queries() self.assertEqual(len(backends.queries), 0) results = self.sqs.all() self.assertEqual(len(results), 49) self.assertEqual(results._cache_is_full(), False) self.assertEqual(len(backends.queries), 1) def test_result_class(self): self.sb.update(self.smmi, self.sample_objs) # Assert that we're defaulting to ``SearchResult``. sqs = self.sqs.all() self.assertTrue(isinstance(sqs[0], SearchResult)) # Custom class. sqs = self.sqs.result_class(MockSearchResult).all() self.assertTrue(isinstance(sqs[0], MockSearchResult)) # Reset to default. sqs = self.sqs.result_class(None).all() self.assertTrue(isinstance(sqs[0], SearchResult))
class WhooshBoostBackendTestCase(TestCase): def setUp(self): super(WhooshBoostBackendTestCase, self).setUp() # Stow. temp_path = os.path.join('tmp', 'test_whoosh_query') self.old_whoosh_path = getattr(settings, 'HAYSTACK_WHOOSH_PATH', temp_path) settings.HAYSTACK_WHOOSH_PATH = temp_path self.site = SearchSite() self.sb = SearchBackend(site=self.site) self.smmi = WhooshBoostMockSearchIndex(AFourthMockModel, backend=self.sb) self.site.register(AFourthMockModel, WhooshBoostMockSearchIndex) # With the models registered, you get the proper bits. import haystack # Stow. self.old_site = haystack.site haystack.site = self.site self.sb.setup() self.raw_whoosh = self.sb.index self.parser = QueryParser(self.sb.content_field_name, schema=self.sb.schema) self.sb.delete_index() 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 = date(2009, 2, 25) - timedelta(days=i) self.sample_objs.append(mock) def tearDown(self): if os.path.exists(settings.HAYSTACK_WHOOSH_PATH): shutil.rmtree(settings.HAYSTACK_WHOOSH_PATH) settings.HAYSTACK_WHOOSH_PATH = self.old_whoosh_path # Restore. import haystack haystack.site = self.old_site def test_boost(self): self.sb.update(self.smmi, self.sample_objs) self.raw_whoosh = self.raw_whoosh.refresh() searcher = self.raw_whoosh.searcher() self.assertEqual(len(searcher.search(self.parser.parse(u'*'), limit=1000)), 4) results = SearchQuerySet().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 LiveWhooshSearchQueryTestCase(TestCase): def setUp(self): super(LiveWhooshSearchQueryTestCase, self).setUp() # Stow. temp_path = os.path.join('tmp', 'test_whoosh_query') self.old_whoosh_path = getattr(settings, 'HAYSTACK_WHOOSH_PATH', temp_path) settings.HAYSTACK_WHOOSH_PATH = temp_path self.site = SearchSite() self.sb = SearchBackend(site=self.site) self.smmi = WhooshMockSearchIndex(MockModel, backend=self.sb) self.site.register(MockModel, WhooshMockSearchIndex) self.sb.setup() self.raw_whoosh = self.sb.index self.parser = QueryParser(self.sb.content_field_name, schema=self.sb.schema) self.sb.delete_index() self.sample_objs = [] for i in xrange(1, 4): mock = MockModel() mock.id = i mock.author = 'daniel%s' % i mock.pub_date = date(2009, 2, 25) - timedelta(days=i) self.sample_objs.append(mock) self.sq = SearchQuery(backend=self.sb) def tearDown(self): if os.path.exists(settings.HAYSTACK_WHOOSH_PATH): shutil.rmtree(settings.HAYSTACK_WHOOSH_PATH) settings.HAYSTACK_WHOOSH_PATH = self.old_whoosh_path super(LiveWhooshSearchQueryTestCase, self).tearDown() def test_get_spelling(self): self.sb.update(self.smmi, self.sample_objs) self.sq.add_filter(SQ(content='Indx')) self.assertEqual(self.sq.get_spelling_suggestion(), u'index') def test_log_query(self): from django.conf import settings from haystack import backends 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=self.sb) self.sq.add_filter(SQ(name='bar')) len(self.sq.get_results()) self.assertEqual(len(backends.queries), 1) self.assertEqual(backends.queries[0]['query_string'], 'name:bar') # And again, for good measure. self.sq = SearchQuery(backend=self.sb) self.sq.add_filter(SQ(name='baz')) self.sq.add_filter(SQ(text='foo')) len(self.sq.get_results()) self.assertEqual(len(backends.queries), 2) self.assertEqual(backends.queries[0]['query_string'], 'name:bar') self.assertEqual(backends.queries[1]['query_string'], u'(name:baz AND text:foo)') # Restore. settings.DEBUG = old_debug
class SimpleSearchBackendTestCase(TestCase): fixtures = ['bulk_data.json'] def setUp(self): super(SimpleSearchBackendTestCase, self).setUp() self.site = SearchSite() self.backend = SearchBackend(site=self.site) self.index = SimpleMockSearchIndex(MockModel, backend=self.backend) self.site.register(MockModel, SimpleMockSearchIndex) self.sample_objs = MockModel.objects.all() self.backend.update(self.index, self.sample_objs) def test_update(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(len(self.sample_objs), SearchableObject.objects.count()) def test_remove(self): self.backend.remove(self.sample_objs[0]) self.assertEqual(len(self.sample_objs)-1, SearchableObject.objects.count()) def test_clear(self): self.backend.clear() self.assertEqual(0, SearchableObject.objects.count()) def test_search(self): # No query string should always yield zero results. self.assertEqual(self.backend.search(None), {'hits': 0, 'results': []}) EMPTY = MultiValueDict() DANIEL = MultiValueDict({'content':['daniel1']}) STRING = MultiValueDict({'content':['should be a string']}) INDX = MultiValueDict({'content':['Indx']}) search_results = self.backend.search(EMPTY) self.assertEqual(search_results['hits'], 23) self.assertEqual([result.pk for result in search_results['results']], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]) search_results = self.backend.search(DANIEL) #print SearchableObject.objects.filter(search_text__icontains='daniel') self.assertEqual(search_results['hits'], 7) self.assertEqual([result.pk for result in search_results['results']], [1, 5, 18, 6, 11, 7, 9]) search_results = self.backend.search(STRING) self.assertEqual(search_results['hits'], 1) self.assertEqual([result.pk for result in search_results['results']], [8]) # Ensure the results are ``SearchResult`` instances... self.assertEqual(search_results['results'][0].score, 0) ''' #Ands are not supported currently search_results = self.backend.search(u'[["index", "document"]]', debug=True) self.assertEqual(search_results['hits'], 6) self.assertEqual([result.pk for result in search_results['results']], [2, 3, 15, 16, 17, 18]) # Regression-ville self.assertEqual([result.object.id for result in search_results['results']], [2, 3, 15, 16, 17, 18]) self.assertEqual(search_results['results'][0].model, MockModel) ''' # No support for spelling suggestions self.assertEqual(self.backend.search(INDX)['hits'], 0) self.assertFalse(self.backend.search(INDX).get('spelling_suggestion')) # No support for facets #self.assertEqual(self.backend.search(MultiValueDict(), facets=['name']), {'hits': 0, 'results': []}) self.assertEqual(self.backend.search(DANIEL, facets=['name'])['hits'], 7) self.assertEqual(self.backend.search(EMPTY, date_facets={'pub_date': {'start_date': date(2008, 2, 26), 'end_date': date(2008, 2, 26), 'gap': '/MONTH'}}), {'hits': 0, 'results': []}) self.assertEqual(self.backend.search(DANIEL, date_facets={'pub_date': {'start_date': date(2008, 2, 26), 'end_date': date(2008, 2, 26), 'gap': '/MONTH'}})['hits'], 7) self.assertEqual(self.backend.search(EMPTY, query_facets={'name': '[* TO e]'}), {'hits': 0, 'results': []}) self.assertEqual(self.backend.search(DANIEL, query_facets={'name': '[* TO e]'})['hits'], 7) self.assertFalse(self.backend.search(EMPTY).get('facets')) self.assertFalse(self.backend.search(DANIEL).get('facets')) # Contextual fields are lumped in #self.assertEqual(self.backend.search(u'["2009-06-18"]', debug=True)['hits'], 2) def test_more_like_this(self): self.assertEqual(self.backend.search(MultiValueDict())['hits'], 23) # Unsupported by 'dummy'. Should see empty results. self.assertEqual(self.backend.more_like_this(self.sample_objs[0])['hits'], 0)
class LiveWhooshRamStorageTestCase(TestCase): def setUp(self): super(LiveWhooshRamStorageTestCase, self).setUp() # Stow. self.old_whoosh_storage = getattr(settings, 'HAYSTACK_WHOOSH_STORAGE', 'file') settings.HAYSTACK_WHOOSH_STORAGE = 'ram' self.site = SearchSite() self.sb = SearchBackend(site=self.site) self.wrtsi = WhooshRoundTripSearchIndex(MockModel, backend=self.sb) self.site.register(MockModel, WhooshRoundTripSearchIndex) # Stow. import haystack self.old_debug = settings.DEBUG settings.DEBUG = True self.old_site = haystack.site haystack.site = self.site self.sb.setup() self.raw_whoosh = self.sb.index self.parser = QueryParser(self.sb.content_field_name, schema=self.sb.schema) self.sqs = SearchQuerySet(site=self.site) # Wipe it clean. self.sqs.query.backend.clear() # Fake indexing. mock = MockModel() mock.id = 1 self.sb.update(self.wrtsi, [mock]) def tearDown(self): self.sqs.query.backend.clear() settings.HAYSTACK_WHOOSH_STORAGE = self.old_whoosh_storage import haystack haystack.site = self.old_site settings.DEBUG = self.old_debug super(LiveWhooshRamStorageTestCase, self).tearDown() def test_ram_storage(self): results = self.sqs.filter(id='core.mockmodel.1') # Sanity check. self.assertEqual(results.count(), 1) # Check the individual fields. result = results[0] self.assertEqual(result.id, 'core.mockmodel.1') self.assertEqual(result.text, 'This is some example text.') self.assertEqual(result.name, 'Mister Pants') self.assertEqual(result.is_active, True) self.assertEqual(result.post_count, 25) self.assertEqual(result.average_rating, 3.6) self.assertEqual(result.pub_date, datetime(2009, 11, 21, 0, 0)) self.assertEqual(result.created, datetime(2009, 11, 21, 21, 31, 00)) self.assertEqual(result.tags, ['staff', 'outdoor', 'activist', 'scientist']) self.assertEqual(result.sites, [u'3', u'5', u'1']) self.assertEqual(result.empty_list, [])
class SearchSiteTestCase(TestCase): def setUp(self): super(SearchSiteTestCase, self).setUp() self.site = SearchSite() def test_register(self): self.assertRaises(AttributeError, self.site.register, MockNotAModel) self.site.register(MockModel) self.assertEqual(len(self.site._registry), 1) self.assert_(MockModel in self.site._registry) self.assertRaises(AlreadyRegistered, self.site.register, MockModel) def test_unregister(self): self.assertRaises(NotRegistered, self.site.unregister, MockModel) # Depends on proper function of register. self.site.register(MockModel) self.site.unregister(MockModel) self.assertEqual(len(self.site._registry), 0) self.assertFalse(MockModel in self.site._registry) def test_get_index(self): self.assertRaises(NotRegistered, self.site.get_index, MockModel) self.site.register(MockModel) self.assert_( isinstance(self.site.get_index(MockModel), BasicSearchIndex)) def test_get_indexes(self): self.assertEqual(self.site.get_indexes(), {}) self.site.register(MockModel) indexes = self.site.get_indexes() self.assert_(isinstance(indexes, dict)) self.assertEqual(len(indexes), 1) self.assert_(MockModel in indexes) def test_get_indexed_models(self): self.assertEqual(self.site.get_indexed_models(), []) self.site.register(MockModel) indexed_models = self.site.get_indexed_models() self.assertEqual(len(indexed_models), 1) self.assert_(MockModel in indexed_models) def test_all_searchfields(self): self.site.register(MockModel) fields = self.site.all_searchfields() self.assertEqual(len(fields), 1) self.assert_('text' in fields) self.assert_(isinstance(fields['text'], CharField)) self.assertEqual(fields['text'].document, True) self.assertEqual(fields['text'].use_template, True) self.site.register(AnotherMockModel) fields = self.site.all_searchfields() self.assertEqual(len(fields), 1) self.assert_('text' in fields) self.assert_(isinstance(fields['text'], CharField)) self.assertEqual(fields['text'].document, True) self.assertEqual(fields['text'].use_template, True) self.site.unregister(AnotherMockModel) self.site.register(AnotherMockModel, AlternateValidSearchIndex) fields = self.site.all_searchfields() self.assertEqual(len(fields), 3) self.assertEqual(sorted(fields.keys()), ['author', 'text', 'title']) self.assert_('text' in fields) self.assert_(isinstance(fields['text'], CharField)) self.assertEqual(fields['text'].document, True) self.assertEqual(fields['text'].use_template, True) self.assert_('title' in fields) self.assert_(isinstance(fields['title'], CharField)) self.assertEqual(fields['title'].document, False) self.assertEqual(fields['title'].use_template, False) self.assertEqual(fields['title'].faceted, True) self.assertEqual(fields['title'].indexed, True) self.assert_('author' in fields) self.assert_(isinstance(fields['author'], CharField)) self.assertEqual(fields['author'].document, False) self.assertEqual(fields['author'].use_template, False) self.assertEqual(fields['author'].faceted, True) self.assertEqual(fields['author'].index_fieldname, 'author') self.site.unregister(MockModel) self.site.register(MockModel, ValidSearchIndex) fields = self.site.all_searchfields() self.assertEqual(len(fields), 4) self.assertEqual(sorted(fields.keys()), ['author', 'name', 'text', 'title']) self.assert_('text' in fields) self.assert_(isinstance(fields['text'], CharField)) self.assertEqual(fields['text'].document, True) self.assertEqual(fields['text'].use_template, False) self.assert_('title' in fields) self.assert_(isinstance(fields['title'], CharField)) self.assertEqual(fields['title'].document, False) self.assertEqual(fields['title'].use_template, False) self.assertEqual(fields['title'].faceted, True) self.assertEqual(fields['title'].indexed, True) self.assert_('author' in fields) self.assert_(isinstance(fields['author'], CharField)) self.assertEqual(fields['author'].document, False) self.assertEqual(fields['author'].use_template, False) self.assertEqual(fields['author'].faceted, True) self.assertEqual(fields['author'].index_fieldname, 'author') self.assertEqual(fields['name'].document, False) self.assertEqual(fields['name'].use_template, False) self.assertEqual(fields['name'].faceted, False) self.assertEqual(fields['name'].index_fieldname, 'name') self.site.unregister(AnotherMockModel) self.site.register(AnotherMockModel, InvalidSearchIndex) self.assertRaises(SearchFieldError, self.site.all_searchfields) def test_get_index_fieldname(self): self.assertEqual(self.site._field_mapping, None) self.site.register(MockModel, ValidSearchIndex) self.site.register(AnotherMockModel) field = self.site.get_index_fieldname('text') self.assertEqual(self.site._field_mapping, { 'text': 'text', 'title': 'title', 'author': 'name' }) self.assertEqual(self.site.get_index_fieldname('text'), 'text') self.assertEqual(self.site.get_index_fieldname('author'), 'name') self.assertEqual(self.site.get_index_fieldname('title'), 'title') # Reset the internal state to test the invalid case. self.site._field_mapping = None self.assertEqual(self.site._field_mapping, None) self.site.unregister(AnotherMockModel) self.site.register(AnotherMockModel, AlternateValidSearchIndex) self.assertRaises(SearchFieldError, self.site.get_index_fieldname, 'text') def test_update_object(self): self.site.register(MockModel, FakeSearchIndex) mock = MockModel() mock.pk = 20 mock.user = '******' % mock.id mock.pub_date = datetime.datetime(2009, 1, 31, 4, 19, 0) self.assertEqual(self.site.update_object(mock), True) def test_remove_object(self): self.site.register(MockModel, FakeSearchIndex) mock = MockModel() mock.pk = 20 self.assertEqual(self.site.remove_object(mock), True)