Exemplo n.º 1
0
class RankingTest(SearchTestBase):

    def setUp(self):
        super(RankingTest, self).setUp()
        self.test11.title += " fooo baar fooo"
        self.test11.save()
        self.test12.content += " fooo baar"
        self.test12.save()

    def testRankingParamPresentOnSearch(self):
        self.assertGreater(watson.search("TITLE")[0].watson_rank, 0)
        
    def testRankingParamPresentOnFilter(self):
        self.assertGreater(watson.filter(WatsonTestModel1, "TITLE")[0].watson_rank, 0)
        
    def testRankingParamAbsentOnSearch(self):
        self.assertRaises(AttributeError, lambda: watson.search("TITLE", ranking=False)[0].watson_rank)
        
    def testRankingParamAbsentOnFilter(self):
        self.assertRaises(AttributeError, lambda: watson.filter(WatsonTestModel1, "TITLE", ranking=False)[0].watson_rank)
    
    @skipUnless(get_backend().supports_ranking, "search backend does not support ranking")
    def testRankingWithSearch(self):
        self.assertEqual(
            [entry.title for entry in watson.search("FOOO")],
            ["title model1 instance11 fooo baar fooo", "title model1 instance12"]
        )
            
    @skipUnless(get_backend().supports_ranking, "search backend does not support ranking")
    def testRankingWithFilter(self):
        self.assertEqual(
            [entry.title for entry in watson.filter(WatsonTestModel1, "FOOO")],
            ["title model1 instance11 fooo baar fooo", "title model1 instance12"]
        )
Exemplo n.º 2
0
class InstallUninstallTestBase(TestCase):
    @skipUnless(get_backend().requires_installation,
                "search backend does not require installation")
    def testUninstallAndInstall(self):
        backend = get_backend()
        call_command("uninstallwatson", verbosity=0)
        self.assertFalse(backend.is_installed())
        call_command("installwatson", verbosity=0)
        self.assertTrue(backend.is_installed())
Exemplo n.º 3
0
 def handle_noargs(self, **options):
     """Runs the management command."""
     verbosity = int(options.get("verbosity", 1))
     backend = get_backend()
     if not backend.requires_installation:
         if verbosity >= 2:
             self.stdout.write("Your search backend does not require installation.\n")
     elif backend.is_installed():
         if verbosity >= 2:
             self.stdout.write("django-watson is already installed.\n")
     else:
         backend.do_install()
         if verbosity >= 2:
             self.stdout.write("django-watson has been successfully installed.\n")
Exemplo n.º 4
0
class InstallUninstallTestBase(TestCase):
    def testUninstallAndInstall(self):
        # Not too much to test here, as some backends don't require installation.
        # Just make sure the commands don't error.
        call_command("uninstallwatson", verbosity=0)
        call_command("installwatson", verbosity=0)

    @skipUnless(get_backend().requires_installation,
                "search backend does not require installation")
    def testRealInstallAndUninstall(self):
        backend = get_backend()
        call_command("uninstallwatson", verbosity=0)
        self.assertFalse(backend.is_installed())
        call_command("installwatson", verbosity=0)
        self.assertTrue(backend.is_installed())
Exemplo n.º 5
0
 def handle_noargs(self, **options):
     """Runs the management command."""
     verbosity = int(options.get("verbosity", 1))
     backend = get_backend()
     if not backend.requires_installation:
         if verbosity >= 2:
             self.stdout.write(
                 "Your search backend does not require installation.\n")
     elif backend.is_installed():
         if verbosity >= 2:
             self.stdout.write("django-watson is already installed.\n")
     else:
         backend.do_install()
         if verbosity >= 2:
             self.stdout.write(
                 "django-watson has been successfully installed.\n")
Exemplo n.º 6
0
 def testUninstallAndInstall(self):
     backend = get_backend()
     call_command("uninstallwatson", verbosity=0)
     self.assertFalse(backend.is_installed())
     call_command("installwatson", verbosity=0)
     self.assertTrue(backend.is_installed())
Exemplo n.º 7
0
class SearchTest(SearchTestBase):
    def emptySearchTextGivesNoResults(self):
        self.assertEqual(watson.search("").count(), 0)
        self.assertEqual(watson.search(" ").count(), 0)

    def testMultiTableSearch(self):
        # Test a search that should get all models.
        self.assertEqual(watson.search("TITLE").count(), 4)
        self.assertEqual(watson.search("CONTENT").count(), 4)
        self.assertEqual(watson.search("DESCRIPTION").count(), 4)
        self.assertEqual(watson.search("TITLE CONTENT DESCRIPTION").count(), 4)
        # Test a search that should get two models.
        self.assertEqual(watson.search("MODEL1").count(), 2)
        self.assertEqual(watson.search("MODEL2").count(), 2)
        self.assertEqual(watson.search("TITLE MODEL1").count(), 2)
        self.assertEqual(watson.search("TITLE MODEL2").count(), 2)
        # Test a search that should get one model.
        self.assertEqual(watson.search("INSTANCE11").count(), 1)
        self.assertEqual(watson.search("INSTANCE21").count(), 1)
        self.assertEqual(watson.search("TITLE INSTANCE11").count(), 1)
        self.assertEqual(watson.search("TITLE INSTANCE21").count(), 1)
        # Test a search that should get zero models.
        self.assertEqual(watson.search("FOOO").count(), 0)
        self.assertEqual(watson.search("FOOO INSTANCE11").count(), 0)
        self.assertEqual(watson.search("MODEL2 INSTANCE11").count(), 0)

    @skipUnless(get_backend().supports_prefix_matching,
                "Search backend does not support prefix matching.")
    def testMultiTablePrefixSearch(self):
        self.assertEqual(watson.search("DESCR").count(), 4)

    def testLimitedModelList(self):
        # Test a search that should get all models.
        self.assertEqual(
            watson.search("TITLE",
                          models=(WatsonTestModel1, WatsonTestModel2)).count(),
            4)
        # Test a search that should get two models.
        self.assertEqual(
            watson.search("MODEL1",
                          models=(WatsonTestModel1, WatsonTestModel2)).count(),
            2)
        self.assertEqual(
            watson.search("MODEL1", models=(WatsonTestModel1, )).count(), 2)
        self.assertEqual(
            watson.search("MODEL2",
                          models=(WatsonTestModel1, WatsonTestModel2)).count(),
            2)
        self.assertEqual(
            watson.search("MODEL2", models=(WatsonTestModel2, )).count(), 2)
        # Test a search that should get one model.
        self.assertEqual(
            watson.search("INSTANCE11",
                          models=(WatsonTestModel1, WatsonTestModel2)).count(),
            1)
        self.assertEqual(
            watson.search("INSTANCE11", models=(WatsonTestModel1, )).count(),
            1)
        self.assertEqual(
            watson.search("INSTANCE21",
                          models=(
                              WatsonTestModel1,
                              WatsonTestModel2,
                          )).count(), 1)
        self.assertEqual(
            watson.search("INSTANCE21", models=(WatsonTestModel2, )).count(),
            1)
        # Test a search that should get zero models.
        self.assertEqual(
            watson.search("MODEL1", models=(WatsonTestModel2, )).count(), 0)
        self.assertEqual(
            watson.search("MODEL2", models=(WatsonTestModel1, )).count(), 0)
        self.assertEqual(
            watson.search("INSTANCE21", models=(WatsonTestModel1, )).count(),
            0)
        self.assertEqual(
            watson.search("INSTANCE11", models=(WatsonTestModel2, )).count(),
            0)

    def testExcludedModelList(self):
        # Test a search that should get all models.
        self.assertEqual(watson.search("TITLE", exclude=()).count(), 4)
        # Test a search that should get two models.
        self.assertEqual(watson.search("MODEL1", exclude=()).count(), 2)
        self.assertEqual(
            watson.search("MODEL1", exclude=(WatsonTestModel2, )).count(), 2)
        self.assertEqual(watson.search("MODEL2", exclude=()).count(), 2)
        self.assertEqual(
            watson.search("MODEL2", exclude=(WatsonTestModel1, )).count(), 2)
        # Test a search that should get one model.
        self.assertEqual(watson.search("INSTANCE11", exclude=()).count(), 1)
        self.assertEqual(
            watson.search("INSTANCE11", exclude=(WatsonTestModel2, )).count(),
            1)
        self.assertEqual(watson.search("INSTANCE21", exclude=()).count(), 1)
        self.assertEqual(
            watson.search("INSTANCE21", exclude=(WatsonTestModel1, )).count(),
            1)
        # Test a search that should get zero models.
        self.assertEqual(
            watson.search("MODEL1", exclude=(WatsonTestModel1, )).count(), 0)
        self.assertEqual(
            watson.search("MODEL2", exclude=(WatsonTestModel2, )).count(), 0)
        self.assertEqual(
            watson.search("INSTANCE21", exclude=(WatsonTestModel2, )).count(),
            0)
        self.assertEqual(
            watson.search("INSTANCE11", exclude=(WatsonTestModel1, )).count(),
            0)

    def testLimitedModelQuerySet(self):
        # Test a search that should get all models.
        self.assertEqual(
            watson.search(
                "TITLE",
                models=(
                    WatsonTestModel1.objects.filter(title__icontains="TITLE"),
                    WatsonTestModel2.objects.filter(title__icontains="TITLE"),
                )).count(), 4)
        # Test a search that should get two models.
        self.assertEqual(
            watson.search("MODEL1",
                          models=(WatsonTestModel1.objects.filter(
                              title__icontains="MODEL1",
                              description__icontains="MODEL1",
                          ), )).count(), 2)
        self.assertEqual(
            watson.search("MODEL2",
                          models=(WatsonTestModel2.objects.filter(
                              title__icontains="MODEL2",
                              description__icontains="MODEL2",
                          ), )).count(), 2)
        # Test a search that should get one model.
        self.assertEqual(
            watson.search("INSTANCE11",
                          models=(WatsonTestModel1.objects.filter(
                              title__icontains="MODEL1", ), )).count(), 1)
        self.assertEqual(
            watson.search("INSTANCE21",
                          models=(WatsonTestModel2.objects.filter(
                              title__icontains="MODEL2", ), )).count(), 1)
        # Test a search that should get no models.
        self.assertEqual(
            watson.search("INSTANCE11",
                          models=(WatsonTestModel1.objects.filter(
                              title__icontains="MODEL2", ), )).count(), 0)
        self.assertEqual(
            watson.search("INSTANCE21",
                          models=(WatsonTestModel2.objects.filter(
                              title__icontains="MODEL1", ), )).count(), 0)

    def testExcludedModelQuerySet(self):
        # Test a search that should get all models.
        self.assertEqual(
            watson.search(
                "TITLE",
                exclude=(
                    WatsonTestModel1.objects.filter(title__icontains="FOOO"),
                    WatsonTestModel2.objects.filter(title__icontains="FOOO"),
                )).count(), 4)
        # Test a search that should get two models.
        self.assertEqual(
            watson.search("MODEL1",
                          exclude=(WatsonTestModel1.objects.filter(
                              title__icontains="INSTANCE21",
                              description__icontains="INSTANCE22",
                          ), )).count(), 2)
        self.assertEqual(
            watson.search("MODEL2",
                          exclude=(WatsonTestModel2.objects.filter(
                              title__icontains="INSTANCE11",
                              description__icontains="INSTANCE12",
                          ), )).count(), 2)
        # Test a search that should get one model.
        self.assertEqual(
            watson.search("INSTANCE11",
                          exclude=(WatsonTestModel1.objects.filter(
                              title__icontains="MODEL2", ), )).count(), 1)
        self.assertEqual(
            watson.search("INSTANCE21",
                          exclude=(WatsonTestModel2.objects.filter(
                              title__icontains="MODEL1", ), )).count(), 1)
        # Test a search that should get no models.
        self.assertEqual(
            watson.search("INSTANCE11",
                          exclude=(WatsonTestModel1.objects.filter(
                              title__icontains="MODEL1", ), )).count(), 0)
        self.assertEqual(
            watson.search("INSTANCE21",
                          exclude=(WatsonTestModel2.objects.filter(
                              title__icontains="MODEL2", ), )).count(), 0)

    def testKitchenSink(self):
        """For sanity, let's just test everything together in one giant search of doom!"""
        self.assertEqual(
            watson.search(
                "INSTANCE11",
                models=(
                    WatsonTestModel1.objects.filter(
                        title__icontains="INSTANCE11"),
                    WatsonTestModel2.objects.filter(title__icontains="TITLE"),
                ),
                exclude=(
                    WatsonTestModel1.objects.filter(title__icontains="MODEL2"),
                    WatsonTestModel2.objects.filter(title__icontains="MODEL1"),
                )).get().title, "title model1 instance11")
Exemplo n.º 8
0
class InternalsTest(SearchTestBase):
    def testSearchEntriesCreated(self):
        self.assertEqual(
            SearchEntry.objects.filter(engine_slug="default").count(), 4)

    def testBuildWatsonCommand(self):
        # Hack a change into the model using a bulk update, which doesn't send signals.
        WatsonTestModel1.objects.filter(id=self.test11.id).update(title="fooo")
        # Test that no update has happened.
        self.assertEqual(watson.search("fooo").count(), 0)
        # Run the rebuild command.
        call_command("buildwatson", verbosity=0)
        # Test that the update is now applies.
        self.assertEqual(watson.search("fooo").count(), 1)

    def testUpdateSearchIndex(self):
        # Update a model and make sure that the search results match.
        self.test11.title = "fooo"
        self.test11.save()
        # Test a search that should get one model.
        exact_search = watson.search("fooo")
        self.assertEqual(len(exact_search), 1)
        self.assertEqual(exact_search[0].title, "fooo")
        # Delete a model and make sure that the search results match.
        self.test11.delete()
        self.assertEqual(watson.search("fooo").count(), 0)

    def testSearchIndexUpdateDeferredByContext(self):
        with watson.update_index():
            self.test11.title = "fooo"
            self.test11.save()
            self.assertEqual(watson.search("fooo").count(), 0)
        self.assertEqual(watson.search("fooo").count(), 1)

    def testSearchIndexUpdateAbandonedOnError(self):
        try:
            with watson.update_index():
                self.test11.title = "fooo"
                self.test11.save()
                raise Exception("Foo")
        except:
            pass
        # Test a search that should get not model.
        self.assertEqual(watson.search("fooo").count(), 0)

    def testFixesDuplicateSearchEntries(self):
        search_entries = SearchEntry.objects.filter(engine_slug="default")
        # Duplicate a couple of search entries.
        for search_entry in search_entries.all()[:2]:
            search_entry.id = None
            search_entry.save()
        # Make sure that we have six (including duplicates).
        self.assertEqual(search_entries.all().count(), 6)
        # Run the rebuild command.
        call_command("buildwatson", verbosity=0)
        # Make sure that we have four again (including duplicates).
        self.assertEqual(search_entries.all().count(), 4)

    def testEmptyFilterGivesAllResults(self):
        for model in (WatsonTestModel1, WatsonTestModel2):
            self.assertEqual(watson.filter(model, "").count(), 2)
            self.assertEqual(watson.filter(model, " ").count(), 2)

    def testFilter(self):
        for model in (WatsonTestModel1, WatsonTestModel2):
            # Test can find all.
            self.assertEqual(watson.filter(model, "TITLE").count(), 2)
        # Test can find a specific one.
        obj = watson.filter(WatsonTestModel1, "INSTANCE12").get()
        self.assertTrue(isinstance(obj, WatsonTestModel1))
        self.assertEqual(obj.title, "title model1 instance12")
        # Test can do filter on a queryset.
        obj = watson.filter(
            WatsonTestModel1.objects.filter(title__icontains="TITLE"),
            "INSTANCE12").get()
        self.assertTrue(isinstance(obj, WatsonTestModel1))
        self.assertEqual(obj.title, "title model1 instance12")

    @skipUnless(get_backend().supports_prefix_matching,
                "Search backend does not support prefix matching.")
    def testPrefixFilter(self):
        self.assertEqual(watson.filter(WatsonTestModel1, "INSTAN").count(), 2)
Exemplo n.º 9
0
 def testRealInstallAndUninstall(self):
     backend = get_backend()
     call_command("uninstallwatson", verbosity=0)
     self.assertFalse(backend.is_installed())
     call_command("installwatson", verbosity=0)
     self.assertTrue(backend.is_installed())
Exemplo n.º 10
0
class SearchTest(SearchTestBase):
    def emptySearchTextGivesNoResults(self):
        self.assertEqual(watson.search("").count(), 0)
        self.assertEqual(watson.search(" ").count(), 0)

    def testMultiTableSearch(self):
        # Test a search that should get all models.
        self.assertEqual(watson.search("TITLE").count(), 4)
        self.assertEqual(watson.search("CONTENT").count(), 4)
        self.assertEqual(watson.search("DESCRIPTION").count(), 4)
        self.assertEqual(watson.search("TITLE CONTENT DESCRIPTION").count(), 4)
        # Test a search that should get two models.
        self.assertEqual(watson.search("MODEL1").count(), 2)
        self.assertEqual(watson.search("MODEL2").count(), 2)
        self.assertEqual(watson.search("TITLE MODEL1").count(), 2)
        self.assertEqual(watson.search("TITLE MODEL2").count(), 2)
        # Test a search that should get one model.
        self.assertEqual(watson.search("INSTANCE11").count(), 1)
        self.assertEqual(watson.search("INSTANCE21").count(), 1)
        self.assertEqual(watson.search("TITLE INSTANCE11").count(), 1)
        self.assertEqual(watson.search("TITLE INSTANCE21").count(), 1)
        # Test a search that should get zero models.
        self.assertEqual(watson.search("FOOO").count(), 0)
        self.assertEqual(watson.search("FOOO INSTANCE11").count(), 0)
        self.assertEqual(watson.search("MODEL2 INSTANCE11").count(), 0)

    def testSearchWithAccent(self):
        WatsonTestModel1.objects.create(
            title="title model1 instance12",
            content="content model1 instance13 café",
            description="description model1 instance13",
        )
        self.assertEqual(watson.search("café").count(), 1)

    def testSearchWithApostrophe(self):
        WatsonTestModel1.objects.create(
            title="title model1 instance12",
            content="content model1 instance13 d'Argent",
            description="description model1 instance13",
        )
        self.assertEqual(watson.search("d'Argent").count(), 1)

    def testSearchWithLeadingApostrophe(self):
        WatsonTestModel1.objects.create(
            title="title model1 instance12",
            content="'content model1 instance13",
            description="description model1 instance13",
        )
        self.assertTrue(
            watson.search("'content").exists()
        )  # Some database engines ignore leading apostrophes, some count them.

    @skipUnless(get_backend().supports_prefix_matching,
                "Search backend does not support prefix matching.")
    def testMultiTablePrefixSearch(self):
        self.assertEqual(watson.search("DESCR").count(), 4)

    def testLimitedModelList(self):
        # Test a search that should get all models.
        self.assertEqual(
            watson.search("TITLE",
                          models=(WatsonTestModel1, WatsonTestModel2)).count(),
            4)
        # Test a search that should get two models.
        self.assertEqual(
            watson.search("MODEL1",
                          models=(WatsonTestModel1, WatsonTestModel2)).count(),
            2)
        self.assertEqual(
            watson.search("MODEL1", models=(WatsonTestModel1, )).count(), 2)
        self.assertEqual(
            watson.search("MODEL2",
                          models=(WatsonTestModel1, WatsonTestModel2)).count(),
            2)
        self.assertEqual(
            watson.search("MODEL2", models=(WatsonTestModel2, )).count(), 2)
        # Test a search that should get one model.
        self.assertEqual(
            watson.search("INSTANCE11",
                          models=(WatsonTestModel1, WatsonTestModel2)).count(),
            1)
        self.assertEqual(
            watson.search("INSTANCE11", models=(WatsonTestModel1, )).count(),
            1)
        self.assertEqual(
            watson.search("INSTANCE21",
                          models=(
                              WatsonTestModel1,
                              WatsonTestModel2,
                          )).count(), 1)
        self.assertEqual(
            watson.search("INSTANCE21", models=(WatsonTestModel2, )).count(),
            1)
        # Test a search that should get zero models.
        self.assertEqual(
            watson.search("MODEL1", models=(WatsonTestModel2, )).count(), 0)
        self.assertEqual(
            watson.search("MODEL2", models=(WatsonTestModel1, )).count(), 0)
        self.assertEqual(
            watson.search("INSTANCE21", models=(WatsonTestModel1, )).count(),
            0)
        self.assertEqual(
            watson.search("INSTANCE11", models=(WatsonTestModel2, )).count(),
            0)

    def testExcludedModelList(self):
        # Test a search that should get all models.
        self.assertEqual(watson.search("TITLE", exclude=()).count(), 4)
        # Test a search that should get two models.
        self.assertEqual(watson.search("MODEL1", exclude=()).count(), 2)
        self.assertEqual(
            watson.search("MODEL1", exclude=(WatsonTestModel2, )).count(), 2)
        self.assertEqual(watson.search("MODEL2", exclude=()).count(), 2)
        self.assertEqual(
            watson.search("MODEL2", exclude=(WatsonTestModel1, )).count(), 2)
        # Test a search that should get one model.
        self.assertEqual(watson.search("INSTANCE11", exclude=()).count(), 1)
        self.assertEqual(
            watson.search("INSTANCE11", exclude=(WatsonTestModel2, )).count(),
            1)
        self.assertEqual(watson.search("INSTANCE21", exclude=()).count(), 1)
        self.assertEqual(
            watson.search("INSTANCE21", exclude=(WatsonTestModel1, )).count(),
            1)
        # Test a search that should get zero models.
        self.assertEqual(
            watson.search("MODEL1", exclude=(WatsonTestModel1, )).count(), 0)
        self.assertEqual(
            watson.search("MODEL2", exclude=(WatsonTestModel2, )).count(), 0)
        self.assertEqual(
            watson.search("INSTANCE21", exclude=(WatsonTestModel2, )).count(),
            0)
        self.assertEqual(
            watson.search("INSTANCE11", exclude=(WatsonTestModel1, )).count(),
            0)

    def testLimitedModelQuerySet(self):
        # Test a search that should get all models.
        self.assertEqual(
            watson.search(
                "TITLE",
                models=(
                    WatsonTestModel1.objects.filter(title__icontains="TITLE"),
                    WatsonTestModel2.objects.filter(title__icontains="TITLE"),
                )).count(), 4)
        # Test a search that should get two models.
        self.assertEqual(
            watson.search("MODEL1",
                          models=(WatsonTestModel1.objects.filter(
                              title__icontains="MODEL1",
                              description__icontains="MODEL1",
                          ), )).count(), 2)
        self.assertEqual(
            watson.search("MODEL2",
                          models=(WatsonTestModel2.objects.filter(
                              title__icontains="MODEL2",
                              description__icontains="MODEL2",
                          ), )).count(), 2)
        # Test a search that should get one model.
        self.assertEqual(
            watson.search("INSTANCE11",
                          models=(WatsonTestModel1.objects.filter(
                              title__icontains="MODEL1", ), )).count(), 1)
        self.assertEqual(
            watson.search("INSTANCE21",
                          models=(WatsonTestModel2.objects.filter(
                              title__icontains="MODEL2", ), )).count(), 1)
        # Test a search that should get no models.
        self.assertEqual(
            watson.search("INSTANCE11",
                          models=(WatsonTestModel1.objects.filter(
                              title__icontains="MODEL2", ), )).count(), 0)
        self.assertEqual(
            watson.search("INSTANCE21",
                          models=(WatsonTestModel2.objects.filter(
                              title__icontains="MODEL1", ), )).count(), 0)

    def testExcludedModelQuerySet(self):
        # Test a search that should get all models.
        self.assertEqual(
            watson.search(
                "TITLE",
                exclude=(
                    WatsonTestModel1.objects.filter(title__icontains="FOOO"),
                    WatsonTestModel2.objects.filter(title__icontains="FOOO"),
                )).count(), 4)
        # Test a search that should get two models.
        self.assertEqual(
            watson.search("MODEL1",
                          exclude=(WatsonTestModel1.objects.filter(
                              title__icontains="INSTANCE21",
                              description__icontains="INSTANCE22",
                          ), )).count(), 2)
        self.assertEqual(
            watson.search("MODEL2",
                          exclude=(WatsonTestModel2.objects.filter(
                              title__icontains="INSTANCE11",
                              description__icontains="INSTANCE12",
                          ), )).count(), 2)
        # Test a search that should get one model.
        self.assertEqual(
            watson.search("INSTANCE11",
                          exclude=(WatsonTestModel1.objects.filter(
                              title__icontains="MODEL2", ), )).count(), 1)
        self.assertEqual(
            watson.search("INSTANCE21",
                          exclude=(WatsonTestModel2.objects.filter(
                              title__icontains="MODEL1", ), )).count(), 1)
        # Test a search that should get no models.
        self.assertEqual(
            watson.search("INSTANCE11",
                          exclude=(WatsonTestModel1.objects.filter(
                              title__icontains="MODEL1", ), )).count(), 0)
        self.assertEqual(
            watson.search("INSTANCE21",
                          exclude=(WatsonTestModel2.objects.filter(
                              title__icontains="MODEL2", ), )).count(), 0)

    def testKitchenSink(self):
        """For sanity, let's just test everything together in one giant search of doom!"""
        self.assertEqual(
            watson.search(
                "INSTANCE11",
                models=(
                    WatsonTestModel1.objects.filter(
                        title__icontains="INSTANCE11"),
                    WatsonTestModel2.objects.filter(title__icontains="TITLE"),
                ),
                exclude=(
                    WatsonTestModel1.objects.filter(title__icontains="MODEL2"),
                    WatsonTestModel2.objects.filter(title__icontains="MODEL1"),
                )).get().title, "title model1 instance11")