コード例 #1
0
class MultiExactMatchTestCase(AutocompleterTestCase):
    fixtures = ['stock_test_data_small.json', 'indicator_test_data_small.json']

    def setUp(self):
        super(MultiExactMatchTestCase, self).setUp()
        setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 10)

        self.autocomp = Autocompleter("mixed")
        self.autocomp.store_all()

    def tearDown(self):
        setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 0)
        self.autocomp.remove_all()

    def test_exact_suggest(self):
        """
        Exact matching works in multi-provider autocompleters
        """
        matches = self.autocomp.exact_suggest('ma')
        self.assertEqual(len(matches['stock']), 1)

        matches = self.autocomp.exact_suggest('US Unemployment Rate')
        self.assertEqual(len(matches['ind']), 1)

    def test_move_exact_matches_to_top(self):
        """
        MOVE_EXACT_MATCHES_TO_TOP works in multi-provider autocompleters
        """
        matches = self.autocomp.suggest('Ma')
        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True)
        matches2 = self.autocomp.suggest('Ma')
        self.assertNotEqual(matches['stock'][0]['search_name'],
                            matches2['stock'][0]['search_name'])
        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', False)
コード例 #2
0
    def test_store_and_remove_all_basic_with_caching(self):
        """
        Storing and removing items all the once works with caching turned on
        """
        # Let's turn on caching because that will store things in Redis and we want to make
        # sure we clean them up.
        setattr(auto_settings, 'CACHE_TIMEOUT', 3600)

        autocomp = Autocompleter("stock")

        autocomp.store_all()
        keys = self.redis.hkeys('djac.stock')
        self.assertEqual(len(keys), 101)

        autocomp = Autocompleter("stock")
        for i in range(0, 3):
            autocomp.suggest('a')
            autocomp.suggest('z')
            autocomp.exact_suggest('aapl')
            autocomp.exact_suggest('xyz')

        autocomp.remove_all()
        keys = self.redis.keys('djac.stock*')
        self.assertEqual(len(keys), 0)

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'CACHE_TIMEOUT', 0)
コード例 #3
0
    def test_facet_match_with_move_exact_matches(self):
        """
        Exact matching still works with facet suggest
        """
        setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 10)
        temp_autocomp = Autocompleter('faceted_stock')
        temp_autocomp.store_all()

        facets = [
            {
                'type': 'or',
                'facets': [
                    {'key': 'sector', 'value': 'Technology'},
                    {'key': 'industry', 'value': 'Software'}
                ]
            }
        ]

        matches = temp_autocomp.suggest('Ma', facets=facets)
        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True)
        matches2 = temp_autocomp.suggest('Ma', facets=facets)
        self.assertNotEqual(matches[0]['search_name'], matches2[0]['search_name'])

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', False)
        temp_autocomp.remove_all()
コード例 #4
0
    def test_dict_store_and_remove_all_basic_with_caching(self):
        """
        Storing and removing items all at once works with caching turned on on dict ac
        """
        # Let's turn on caching because that will store things in Redis and we want to make
        # sure we clean them up.
        setattr(auto_settings, 'CACHE_TIMEOUT', 3600)

        autocomp = Autocompleter("metric")
        autocomp.store_all()

        keys = self.redis.hkeys('djac.test.metric')
        self.assertEqual(len(keys), 8)

        autocomp = Autocompleter("metric")
        for i in range(0, 3):
            autocomp.suggest('m')
            autocomp.suggest('e')
            autocomp.exact_suggest('PE Ratio TTM')
            autocomp.exact_suggest('Market Cap')

        autocomp.remove_all()

        keys = self.redis.keys('djac.test.metric*')
        self.assertEqual(len(keys), 0)

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'CACHE_TIMEOUT', 0)
コード例 #5
0
    def test_store_and_remove_all_basic_with_caching(self):
        """
        Storing and removing items all at once works with caching turned on
        """
        # Let's turn on caching because that will store things in Redis and we want to make
        # sure we clean them up.
        setattr(auto_settings, 'CACHE_TIMEOUT', 3600)

        autocomp = Autocompleter("stock")
        autocomp.store_all()

        keys = self.redis.hkeys('djac.test.stock')
        self.assertEqual(len(keys), 101)

        autocomp = Autocompleter("stock")
        for i in range(0, 3):
            autocomp.suggest('a')
            autocomp.suggest('z')
            autocomp.exact_suggest('aapl')
            autocomp.exact_suggest('xyz')

        autocomp.remove_all()
        keys = self.redis.keys('djac.test.stock*')
        self.assertEqual(len(keys), 0)

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'CACHE_TIMEOUT', 0)
コード例 #6
0
    def test_signal_based_update(self):
        """
        Turning on signals will automatically update objects in the autocompleter
        """
        signal_registry.register(Stock)

        aapl = Stock(symbol='AAPL', name='Apple', market_cap=50)
        aapl.save()

        autocomp = Autocompleter("stock")
        matches = autocomp.suggest('aapl')

        self.assertEqual(len(matches), 1)
        aapl.symbol = 'XYZ'
        aapl.name = 'XYZ & Co.'
        aapl.save()

        matches = autocomp.suggest('aapl')
        self.assertEqual(len(matches), 0)
        matches = autocomp.suggest('xyz')
        self.assertEqual(len(matches), 1)

        aapl.delete()
        keys = self.redis.keys('djac.test.stock*')
        self.assertEqual(len(keys), 0)

        signal_registry.unregister(Stock)
コード例 #7
0
class IndicatorAliasedMatchTestCase(AutocompleterTestCase):
    fixtures = ['indicator_test_data_small.json']

    def setUp(self):
        self.autocomp = Autocompleter("indicator_aliased")
        self.autocomp.store_all()
        super(IndicatorAliasedMatchTestCase, self).setUp()

    def tearDown(self):
        self.autocomp.remove_all()

    def test_aliasing(self):
        """
        Various permutations of aliased matching work
        """
        matches = self.autocomp.suggest('us consumer price index')
        self.assertNotEqual(len(matches), 0)

        matches = self.autocomp.suggest('united states consumer price index')
        self.assertNotEqual(len(matches), 0)

        matches = self.autocomp.suggest('us cpi')
        self.assertNotEqual(len(matches), 0)

        matches = self.autocomp.suggest('united states consumer price index')
        self.assertNotEqual(len(matches), 0)
コード例 #8
0
class MultiExactMatchTestCase(AutocompleterTestCase):
    fixtures = ['stock_test_data_small.json', 'indicator_test_data_small.json']

    def setUp(self):
        super(MultiExactMatchTestCase, self).setUp()
        setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 10)

        self.autocomp = Autocompleter("mixed")
        self.autocomp.store_all()
        

    def tearDown(self):
        setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 0)
        self.autocomp.remove_all()

    def test_exact_suggest(self):
        """
        Exact matching works in multi-provider autocompleters
        """
        matches = self.autocomp.exact_suggest('ma')
        self.assertEqual(len(matches['stock']), 1)

        matches = self.autocomp.exact_suggest('US Unemployment Rate')
        self.assertEqual(len(matches['ind']), 1)

    def test_move_exact_matches_to_top(self):
        """
        MOVE_EXACT_MATCHES_TO_TOP works in multi-provider autocompleters
        """
        matches = self.autocomp.suggest('Ma')
        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True)
        matches2 = self.autocomp.suggest('Ma')
        self.assertNotEqual(matches['stock'][0]['search_name'], matches2['stock'][0]['search_name'])
        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', False)
コード例 #9
0
    def test_signal_based_update(self):
        """
        Turning on signals will automatically update objects in the autocompleter
        """
        signal_registry.register(Stock)

        aapl = Stock(symbol='AAPL', name='Apple', market_cap=50)
        aapl.save()

        autocomp = Autocompleter("stock")
        matches = autocomp.suggest('aapl')

        self.assertEqual(len(matches), 1)

        aapl.symbol = 'XYZ'
        aapl.name = 'XYZ & Co.'
        aapl.save()

        matches = autocomp.suggest('aapl')
        self.assertEqual(len(matches), 0)
        matches = autocomp.suggest('xyz')
        self.assertEqual(len(matches), 1)

        aapl.delete()
        keys = self.redis.keys('djac.stock*')
        self.assertEqual(len(keys), 0)

        signal_registry.unregister(Stock)
コード例 #10
0
class MixedFacetProvidersMatchingTestCase(AutocompleterTestCase):
    fixtures = ['stock_test_data_small.json', 'indicator_test_data_small.json']

    def setUp(self):
        super(MixedFacetProvidersMatchingTestCase, self).setUp()
        self.autocomp = Autocompleter('facet_stock_no_facet_ind')
        self.autocomp.store_all()

    def test_autocompleter_with_facet_and_non_facet_providers(self):
        """
        Autocompleter with facet and non-facet providers works correctly
        """
        registry.set_autocompleter_setting('facet_stock_no_facet_ind', 'MAX_RESULTS', 100)
        facets = [
            {
                'type': 'and',
                'facets': [{'key': 'sector', 'value': 'Financial Services'}]
            }
        ]
        matches = self.autocomp.suggest('a')
        facet_matches = self.autocomp.suggest('a', facets=facets)

        # because we are using the faceted stock provider in the 'facet_stock_no_facet_ind' AC,
        # we expect using facets will decrease the amount of results when searching.
        self.assertEqual(len(matches['faceted_stock']), 25)
        self.assertEqual(len(facet_matches['faceted_stock']), 2)

        # since the indicator provider does not support facets,
        # we expect the search results from both a facet and non-facet search to be the same.
        self.assertEqual(len(matches['ind']), 16)
        self.assertEqual(len(matches['ind']), len(facet_matches['ind']))

        registry.del_autocompleter_setting('facet_stock_no_facet_ind', 'MAX_RESULTS')
コード例 #11
0
class StockExactMatchTestCase(AutocompleterTestCase):
    fixtures = ['stock_test_data_small.json']

    def setUp(self):
        super(StockExactMatchTestCase, self).setUp()
        setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 10)

        self.autocomp = Autocompleter("stock")
        self.autocomp.store_all()

    def tearDown(self):
        setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 0)
        self.autocomp.remove_all()

    def test_exact_suggest(self):
        """
        Exact matching works
        """
        matches_symbol = self.autocomp.exact_suggest('ma')
        self.assertEqual(len(matches_symbol), 1)

    def test_move_exact_matches_to_top_setting(self):
        """
        MOVE_EXACT_MATCHES_TO_TOP works
        """
        matches = self.autocomp.suggest('Ma')
        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True)
        matches2 = self.autocomp.suggest('Ma')
        self.assertNotEqual(matches[0]['search_name'], matches2[0]['search_name'])

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', False)

    def test_move_exact_matches_overridable_at_ac_level(self):
        """
        MOVE_EXACT_MATCHES_TO_TOP can be set at the autocompleter level
        """
        matches = self.autocomp.suggest('Ma')
        registry.set_autocompleter_setting(self.autocomp.name, 'MOVE_EXACT_MATCHES_TO_TOP', True)
        matches2 = self.autocomp.suggest('Ma')
        registry.del_autocompleter_setting(self.autocomp.name, 'MOVE_EXACT_MATCHES_TO_TOP')
        self.assertNotEqual(matches[0]['search_name'], matches2[0]['search_name'])

    def test_exact_caching(self):
        """
        Exact caching works
        """
        matches = self.autocomp.exact_suggest('aapl')

        setattr(auto_settings, 'CACHE_TIMEOUT', 3600)

        for i in range(0, 10):
            matches2 = self.autocomp.exact_suggest('aapl')

        self.assertEqual(len(matches), len(matches2))

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'CACHE_TIMEOUT', 0)
コード例 #12
0
    def test_remove_intermediate_results_suggest(self):
        """
        After suggest call, all intermediate result sets are removed
        """
        autocomp = Autocompleter('stock')
        autocomp.store_all()

        autocomp.suggest('aapl')
        keys = self.redis.keys('djac.results.*')
        self.assertEqual(len(keys), 0)
コード例 #13
0
class IndicatorAliasedMatchTestCase(AutocompleterTestCase):
    fixtures = ['indicator_test_data_small.json']

    def setUp(self):
        super(IndicatorAliasedMatchTestCase, self).setUp()
        self.autocomp = Autocompleter("indicator_aliased")
        self.autocomp.store_all()

    def tearDown(self):
        self.autocomp.remove_all()

    def test_basic_aliasing(self):
        """
        Various permutations of aliased matching work
        """
        matches = self.autocomp.suggest('us consumer price index')
        self.assertNotEqual(len(matches), 0)

        matches = self.autocomp.suggest('united states consumer price index')
        self.assertNotEqual(len(matches), 0)

        matches = self.autocomp.suggest('us cpi')
        self.assertNotEqual(len(matches), 0)

        matches = self.autocomp.suggest('united states consumer price index')
        self.assertNotEqual(len(matches), 0)

        matches = self.autocomp.suggest('u s a consumer price index')
        self.assertNotEqual(len(matches), 0)

    def test_alias_list_creation(self):
        """
        Alias lists have replacement char variations
        """
        provider = registry._providers_by_ac["indicator_aliased"][0]
        aliases = provider.get_norm_phrase_aliases()
        usa_aliases = aliases['usa']
        self.assertTrue('u sa' in usa_aliases)
        self.assertTrue('us a' in usa_aliases)
        self.assertTrue('u s a' in usa_aliases)
        self.assertFalse('usa' in usa_aliases)

    def test_multi_term_aliasing(self):
        matches = self.autocomp.suggest('us consumer price index')
        self.assertNotEqual(len(matches), 0)

        matches = self.autocomp.suggest('usa consumer price index')
        self.assertNotEqual(len(matches), 0)

        matches = self.autocomp.suggest('america consumer price index')
        self.assertNotEqual(len(matches), 0)

    def test_double_aliasing(self):
        """
        Double aliasing does not happen.
        California -> CA -> Canada
        """
        matches = self.autocomp.suggest('california unemployment')
        self.assertEqual(len(matches), 1)
コード例 #14
0
class IndicatorAliasedMatchTestCase(AutocompleterTestCase):
    fixtures = ['indicator_test_data_small.json']

    def setUp(self):
        super(IndicatorAliasedMatchTestCase, self).setUp()
        self.autocomp = Autocompleter("indicator_aliased")
        self.autocomp.store_all()

    def tearDown(self):
        self.autocomp.remove_all()

    def test_basic_aliasing(self):
        """
        Various permutations of aliased matching work
        """
        matches = self.autocomp.suggest('us consumer price index')
        self.assertNotEqual(len(matches), 0)

        matches = self.autocomp.suggest('united states consumer price index')
        self.assertNotEqual(len(matches), 0)

        matches = self.autocomp.suggest('us cpi')
        self.assertNotEqual(len(matches), 0)

        matches = self.autocomp.suggest('united states consumer price index')
        self.assertNotEqual(len(matches), 0)

        matches = self.autocomp.suggest('u s a consumer price index')
        self.assertNotEqual(len(matches), 0)

    def test_alias_list_creation(self):
        """
        Alias lists have replacement char variations
        """
        provider = registry._providers_by_ac["indicator_aliased"][0]
        aliases = provider.get_norm_phrase_aliases()
        usa_aliases = aliases['usa']
        self.assertTrue('u sa' in usa_aliases)
        self.assertTrue('us a' in usa_aliases)
        self.assertTrue('u s a' in usa_aliases)
        self.assertFalse('usa' in usa_aliases)

    def test_multi_term_aliasing(self):
        matches = self.autocomp.suggest('us consumer price index')
        self.assertNotEqual(len(matches), 0)

        matches = self.autocomp.suggest('usa consumer price index')
        self.assertNotEqual(len(matches), 0)

        matches = self.autocomp.suggest('america consumer price index')
        self.assertNotEqual(len(matches), 0)

    def test_double_aliasing(self):
        """
        Double aliasing does not happen.
        California -> CA -> Canada
        """
        matches = self.autocomp.suggest('california unemployment')
        self.assertEqual(len(matches), 1)
コード例 #15
0
class MultiMatchingPerfTestCase(AutocompleterTestCase):
    fixtures = ['stock_test_data.json', 'indicator_test_data.json']
    num_iterations = 1000

    def setUp(self):
        super(MultiMatchingPerfTestCase, self).setUp()
        self.autocomp = Autocompleter("mixed")
        self.autocomp.store_all()

    def tearDown(self):
        self.autocomp.remove_all()

    def test_repeated_matches(self):
        """
        Matching is fast
        """
        setattr(auto_settings, 'MATCH_OUT_OF_ORDER_WORDS', True)
        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True)

        for i in range(1, self.num_iterations):
            self.autocomp.suggest('ma')

        for i in range(1, self.num_iterations):
            self.autocomp.suggest('price consumer')

        for i in range(1, self.num_iterations):
            self.autocomp.suggest('a')

        for i in range(1, self.num_iterations):
            self.autocomp.suggest('non revolving')

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'MATCH_OUT_OF_ORDER_WORDS', False)
        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True)
コード例 #16
0
class MultiMatchingPerfTestCase(AutocompleterTestCase):
    fixtures = ['stock_test_data.json', 'indicator_test_data.json']
    num_iterations = 1000

    def setUp(self):
        self.autocomp = Autocompleter("mixed")
        self.autocomp.store_all()

    def tearDown(self):
        self.autocomp.remove_all()

    def test_repeated_matches(self):
        """
        Matching is fast
        """
        setattr(auto_settings, 'MATCH_OUT_OF_ORDER_WORDS', True)
        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True)

        for i in range(1, self.num_iterations):
            self.autocomp.suggest('ma')

        for i in range(1, self.num_iterations):
            self.autocomp.suggest('price consumer')

        for i in range(1, self.num_iterations):
            self.autocomp.suggest('a')

        for i in range(1, self.num_iterations):
            self.autocomp.suggest('non revolving')

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'MATCH_OUT_OF_ORDER_WORDS', False)
        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True)
コード例 #17
0
class StockExactMatchTestCase(AutocompleterTestCase):
    fixtures = ['stock_test_data_small.json']

    def setUp(self):
        super(StockExactMatchTestCase, self).setUp()
        setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 10)

        self.autocomp = Autocompleter("stock")
        self.autocomp.store_all()

    def tearDown(self):
        setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 0)
        self.autocomp.remove_all()

    def test_exact_suggest(self):
        """
        Exact matching works
        """
        matches_symbol = self.autocomp.exact_suggest('ma')
        self.assertEqual(len(matches_symbol), 1)

    def test_move_exact_matches_to_top_setting(self):
        """
        MOVE_EXACT_MATCHES_TO_TOP works
        """
        matches = self.autocomp.suggest('Ma')
        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True)
        matches2 = self.autocomp.suggest('Ma')
        self.assertNotEqual(matches[0]['search_name'],
                            matches2[0]['search_name'])

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', False)

    def test_exact_caching(self):
        """
        Exact caching works
        """
        matches = self.autocomp.exact_suggest('aapl')

        setattr(auto_settings, 'CACHE_TIMEOUT', 3600)

        for i in range(0, 10):
            matches2 = self.autocomp.exact_suggest('aapl')

        self.assertEqual(len(matches), len(matches2))

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'CACHE_TIMEOUT', 0)
コード例 #18
0
    def test_selective_add_and_remove(self):
        """
        We can exclude certain objects from the autocompleter selectively.
        """
        autocomp = Autocompleter("indicator")
        autocomp.store_all()
        matches = autocomp.suggest('us unemployment rate')
        self.assertEqual(len(matches), 1)
        autocomp.remove_all()

        autocomp = Autocompleter("indicator_selective")
        autocomp.store_all()
        matches = autocomp.suggest('us unemployment rate')
        self.assertEqual(len(matches), 0)
        autocomp.remove_all()
コード例 #19
0
class MultiMatchingTestCase(AutocompleterTestCase):
    fixtures = ['stock_test_data_small.json', 'indicator_test_data_small.json']

    def setUp(self):
        super(MultiMatchingTestCase, self).setUp()
        self.autocomp = Autocompleter("mixed")
        self.autocomp.store_all()

    def tearDown(self):
        self.autocomp.remove_all()

    def test_basic_match(self):
        """
        A single autocompleter can return results from multiple models.
        """
        matches = self.autocomp.suggest('Aapl')
        self.assertEqual(len(matches['stock']), 1)

        matches = self.autocomp.suggest('US Initial Claims')
        self.assertEqual(len(matches['ind']), 1)

        matches = self.autocomp.suggest('m')
        self.assertEqual(len(matches), 3)

        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches['stock']), 6)
        self.assertEqual(len(matches['ind']), 4)

    def test_min_letters_setting(self):
        """
        MIN_LETTERS is respected in multi-type search case.
        """
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches['stock']), 6)
        self.assertEqual(len(matches['ind']), 4)

        setattr(auto_settings, 'MIN_LETTERS', 2)
        matches = self.autocomp.suggest('a')
        self.assertEqual(matches, {})

        setattr(auto_settings, 'MIN_LETTERS', 1)

    def test_ac_provider_specific_min_letters_setting(self):
        """
        Autocompleter/Provider specific MIN_LETTERS is respected in multi-type search case.
        """
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches['stock']), 6)
        self.assertEqual(len(matches['ind']), 4)

        registry.set_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MIN_LETTERS', 2)
        registry.set_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MIN_LETTERS', 2)
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 10)
        self.assertEqual('ind' not in matches, True)

        registry.del_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MIN_LETTERS')
        registry.del_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MIN_LETTERS')
コード例 #20
0
class MultiMatchingTestCase(AutocompleterTestCase):
    fixtures = ['stock_test_data_small.json', 'indicator_test_data_small.json']

    def setUp(self):
        super(MultiMatchingTestCase, self).setUp()
        self.autocomp = Autocompleter("mixed")
        self.autocomp.store_all()

    def tearDown(self):
        self.autocomp.remove_all()

    def test_basic_match(self):
        """
        A single autocompleter can return results from multiple models.
        """
        matches = self.autocomp.suggest('Aapl')
        self.assertEqual(len(matches['stock']), 1)

        matches = self.autocomp.suggest('US Initial Claims')
        self.assertEqual(len(matches['ind']), 1)

        matches = self.autocomp.suggest('m')
        self.assertEqual(len(matches), 3)

        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches['stock']), 10)
        self.assertEqual(len(matches['ind']), 10)

    def test_min_letters_setting(self):
        """
        MIN_LETTERS is respected in multi-type search case.
        """
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches['stock']), 10)
        self.assertEqual(len(matches['ind']), 10)

        setattr(auto_settings, 'MIN_LETTERS', 2)
        matches = self.autocomp.suggest('a')
        self.assertEqual(matches, {})

        setattr(auto_settings, 'MIN_LETTERS', 1)

    def test_ac_provider_specific_min_letters_setting(self):
        """
        Autocompleter/Provider specific MIN_LETTERS is respected in multi-type search case.
        """
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches['stock']), 10)
        self.assertEqual(len(matches['ind']), 10)

        registry.set_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MIN_LETTERS', 2)
        registry.set_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MIN_LETTERS', 2)
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 10)
        self.assertEqual('ind' not in matches, True)

        registry.del_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MIN_LETTERS')
        registry.del_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MIN_LETTERS')
コード例 #21
0
    def get(self, request, name):
        if settings.SUGGEST_PARAMETER_NAME in request.GET:
            term = request.GET[settings.SUGGEST_PARAMETER_NAME]
            ac = Autocompleter(name)
            if settings.FACET_PARAMETER_NAME in request.GET:
                facets = request.GET[settings.FACET_PARAMETER_NAME]
                facets = json.loads(facets)
                if not self.validate_facets(facets):
                    return HttpResponseBadRequest('Malformed facet parameter.')
                results = ac.suggest(term, facets=facets)
            else:
                results = ac.suggest(term)

            json_response = json.dumps(results)
            return HttpResponse(json_response, content_type='application/json')
        return HttpResponseServerError('Search parameter not found.')
コード例 #22
0
def suggest(request, name):
    if settings.SUGGEST_PARAMETER_NAME in request.GET:
        term = request.GET[settings.SUGGEST_PARAMETER_NAME]
        ac = Autocompleter(name)
        results = ac.suggest(term)

        json_response = json.dumps(results)
        return HttpResponse(json_response, content_type='application/json')
    return HttpResponseServerError("Search parameter not found.")
コード例 #23
0
    def test_orphan_removal(self):
        """
        test orphan removal
        """
        signal_registry.register(Indicator)

        autocomp = Autocompleter("indicator")
        autocomp.store_all()

        unemployment = Indicator.objects.get(internal_name='unemployment_rate')

        unemployment.name = 'free parking'
        unemployment.save()

        self.assertTrue(autocomp.suggest('free parking')[0]['id'] == 1)
        self.assertTrue(len(autocomp.suggest('US Unemployment Rate')) == 0)

        autocomp.remove_all()
        signal_registry.unregister(Indicator)
コード例 #24
0
    def test_facet_mismatch_with_move_exact_matches(self):
        """
        Exact matching shouldn't move an object that doesn't have a matching facet value
        """
        # This test case depends on very specific data, which is why this test
        # issues multiple asserts to check our assumptions

        setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 10)
        temp_autocomp = Autocompleter('faceted_stock')
        temp_autocomp.store_all()

        facets = [
            {
                'type': 'and',
                'facets': [
                    {'key': 'sector', 'value': 'Healthcare'},
                    {'key': 'industry', 'value': 'Healthcare Plans'},
                ]
            }
        ]

        # When gathering suggestions for 'Un', based on the stock_data_small.json fixture,
        # the only match should be UnitedHealth Group Inc. when using the Healthcare sector facet
        matches = temp_autocomp.suggest('Un', facets=facets)
        self.assertEqual(len(matches), 1)
        self.assertEqual(matches[0]['search_name'], "UNH")

        # When MOVE_EXACT_MATCHES_TO_TOP is set to True and not using facets,
        # we are expecting Unilever to be moved to the top.
        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True)
        matches = temp_autocomp.suggest('Un')
        self.assertEqual(matches[0]['search_name'], "UN")

        # When MOVE_EXACT_MATCHES_TO_TOP is set to True and we are using the
        # Healthcare sector facet, we are expecting to see UnitedHealth group
        # since Unilever belongs to the Consumer Defensive sector
        matches = temp_autocomp.suggest('Un', facets=facets)
        self.assertEqual(matches[0]['search_name'], "UNH")

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', False)
        temp_autocomp.remove_all()
コード例 #25
0
class DictProviderMatchingTestCase(AutocompleterTestCase):
    def setUp(self):
        super(DictProviderMatchingTestCase, self).setUp()
        self.autocomp = Autocompleter("metric")
        self.autocomp.store_all()

    def tearDown(self):
        self.autocomp.remove_all()

    def test_basic_match(self):
        matches = self.autocomp.suggest('m')
        self.assertEqual(len(matches), 1)
コード例 #26
0
class DictProviderMatchingTestCase(AutocompleterTestCase):
    def setUp(self):
        super(DictProviderMatchingTestCase, self).setUp()
        self.autocomp = Autocompleter("metric")
        self.autocomp.store_all()

    def tearDown(self):
        self.autocomp.remove_all()

    def test_basic_match(self):
        matches = self.autocomp.suggest('m')
        self.assertEqual(len(matches), 1)
コード例 #27
0
class TestSuggestView(AutocompleterTestCase):
    fixtures = ['stock_test_data_small.json']

    def setUp(self):
        super(TestSuggestView, self).setUp()
        self.autocomp = Autocompleter('stock')
        self.autocomp.store_all()

    def tearDown(self):
        self.autocomp.remove_all()

    def test_simple_suggest_match(self):
        """
        SuggestView returns 200 status code and correct number of results on match
        """
        suggest_url = reverse('suggest', kwargs={'name': 'stock'})
        matches_symbol = self.autocomp.suggest('a')
        response = self.client.get(suggest_url, data={settings.SUGGEST_PARAMETER_NAME: 'a'})
        self.assertEqual(response.status_code, 200)

        json_response = json.loads(response.content.decode('utf-8'))
        self.assertGreaterEqual(len(json_response), 1)
        self.assertEqual(len(json_response), len(matches_symbol))

    def test_no_suggest_match(self):
        """
        SuggestView returns 200 status code when there is no match
        """
        url = reverse('suggest', kwargs={'name': 'stock'})
        matches_symbol = self.autocomp.suggest('gobblygook')
        response = self.client.get(url, data={settings.SUGGEST_PARAMETER_NAME: 'gobblygook'})
        self.assertEqual(response.status_code, 200)

        json_response = json.loads(response.content.decode('utf-8'))
        self.assertEqual(len(json_response), 0)
        self.assertEqual(len(json_response), len(matches_symbol))
コード例 #28
0
    def test_exact_match_low_score_still_at_top(self):
        """
        Exact matching when using facets should push low scoring object to top if exact match
        """
        # The setup for this test case is that we have three stocks that begin with the letter Z
        # but limit our MAX_RESULTS setting to just 2.
        # With MOVE_EXACT_MATCHES_TO_TOP initially set to False, we do not expect to see the
        # stock with symbol 'Z' in the suggest results since it has the lowest market cap of the 3 which is
        # what we base the score off of.
        # Once we set MOVE_EXACT_MATCHES_TO_TOP to True we expect Z to be right at the top even though
        # it didn't even show up in the previous suggest call since it is an exact match.
        setattr(auto_settings, 'MAX_RESULTS', 2)
        setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 10)
        temp_autocomp = Autocompleter('faceted_stock')
        temp_autocomp.store_all()
        facets = [
            {
                'type': 'and',
                'facets': [
                    {'key': 'sector', 'value': 'Technology'},
                    {'key': 'industry', 'value': 'Software'},
                ]
            }
        ]
        matches = temp_autocomp.suggest('Z', facets=facets)
        search_names = [match['search_name'] for match in matches]
        self.assertTrue('Z' not in search_names)

        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True)
        matches = temp_autocomp.suggest('Z', facets=facets)
        self.assertTrue(matches[0]['search_name'] == 'Z')

        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', False)
        setattr(auto_settings, 'MAX_RESULTS', 10)
        setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 0)
        temp_autocomp.remove_all()
コード例 #29
0
class CalcAutocompleteProviderTestCase(AutocompleterTestCase):
    fixtures = ['indicator_test_data_small.json']

    def setUp(self):
        super(CalcAutocompleteProviderTestCase, self).setUp()
        self.autocomp = Autocompleter("metric_aliased")
        self.autocomp.store_all()

    def tearDown(self):
        self.autocomp.remove_all()

    def test_one_way_alias_list_creation(self):
        """
        Test that oneway alias lists are created properly
        """
        provider = registry._providers_by_ac["metric_aliased"][0]
        aliases = provider.get_norm_phrase_aliases()
        self.assertTrue('revenue' in aliases)
        self.assertFalse('turnover' in aliases)

    def test_one_way_aliasing(self):
        """
        Aliases in get_one_way_phrase_aliases are not aliased both ways.
        """
        matches = self.autocomp.suggest('revenue')
        self.assertEqual(len(matches), 1)
        matches = self.autocomp.suggest('Turnover')
        self.assertEqual(len(matches), 2)

    def test_one_way_with_two_way_alias_list_creation(self):
        """
        Two way and one way aliases are both included/treated properly
        """
        provider = registry._providers_by_ac["metric_aliased"][0]
        aliases = provider.get_norm_phrase_aliases()
        self.assertTrue('ev' in aliases)
        self.assertTrue('enterprise value' in aliases)
        self.assertTrue('revenue' in aliases)
        self.assertFalse('turnover' in aliases)

    def test_one_way_with_two_way_aliasing(self):
        """
        Aliases in get_one_way_phrase_aliases are not aliased both ways.
        """
        rev_matches = self.autocomp.suggest('revenue')
        turn_matches = self.autocomp.suggest('Turnover')
        self.assertFalse(rev_matches == turn_matches)

        ev_matches = self.autocomp.suggest('EV')
        ent_val_matches = self.autocomp.suggest('Enterprise Value')
        self.assertEqual(ev_matches, ent_val_matches)
コード例 #30
0
class IndicatorMatchTestCase(AutocompleterTestCase):
    fixtures = ['indicator_test_data_small.json']

    def setUp(self):
        super(IndicatorMatchTestCase, self).setUp()
        self.autocomp = Autocompleter("indicator")
        self.autocomp.store_all()

    def tearDown(self):
        self.autocomp.remove_all()

    def test_same_score_word_based_id_ordering(self):
        """
        Two results with the same score are returned in lexographic order of object ID
        """

        matches = self.autocomp.suggest('us')
        self.assertEqual(matches[1]['display_name'], 'US Dollar to Australian Dollar Exchange Rate')
        self.assertEqual(matches[9]['display_name'], 'US Dollar to Chinese Yuan Exchange Rate')
        return matches

    def test_join_char_replacement(self):
        """
        Dashes are handled correctly
        """
        # Testing that both '3-month' and '3 month' match
        matches = self.autocomp.suggest('3-month')
        self.assertNotEqual(len(matches), 0)
        matches = self.autocomp.suggest('3 month')
        self.assertNotEqual(len(matches), 0)

        matches = self.autocomp.suggest('mortgage-backed')
        self.assertNotEqual(len(matches), 0)
        matches = self.autocomp.suggest('mortgagebacked')
        self.assertNotEqual(len(matches), 0)
        matches = self.autocomp.suggest('mortgage backed')
        self.assertNotEqual(len(matches), 0)
        matches = self.autocomp.suggest('backed mortgage')
        self.assertNotEqual(len(matches), 0)

        matches = self.autocomp.suggest('U S A')
        self.assertNotEqual(len(matches), 0)
        matches = self.autocomp.suggest('U SA')
        self.assertNotEqual(len(matches), 0)
        matches = self.autocomp.suggest('USA')
        self.assertNotEqual(len(matches), 0)
        matches = self.autocomp.suggest('U-S-A')
        self.assertNotEqual(len(matches), 0)
        matches = self.autocomp.suggest('U/S/A')
        self.assertNotEqual(len(matches), 0)
        matches = self.autocomp.suggest('U-S/A')
        self.assertNotEqual(len(matches), 0)

    def test_min_letters_setting(self):
        """
        MIN_LETTERS is respected.
        """
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 10)
        setattr(auto_settings, 'MIN_LETTERS', 2)
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 0)

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'MIN_LETTERS', 1)

    def test_ac_provider_specific_min_letters_setting(self):
        """
        Autocompleter/Provider specific MIN_LETTERS is respected.
        """
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 10)
        setattr(auto_settings, 'MIN_LETTERS', 2)
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 0)

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'MIN_LETTERS', 1)
コード例 #31
0
class ElasticMatchingTestCase(AutocompleterTestCase):
    fixtures = ['stock_test_data_small.json', 'indicator_test_data_small.json']

    def setUp(self):
        super(ElasticMatchingTestCase, self).setUp()
        self.autocomp = Autocompleter("mixed")
        self.autocomp.store_all()

    def tearDown(self):
        self.autocomp.remove_all()

    def test_basic_match(self):
        """
        Test basic multiple matching works
        """
        matches = self.autocomp.suggest('pe')
        self.assertEqual(len(matches['stock']), 5)
        self.assertEqual(len(matches['ind']), 10)
        self.assertEqual(len(matches['metric']), 1)

    def test_matching_with_max_results_cap(self):
        """
        Test that basic matching with results limit works
        """
        registry.set_ac_provider_setting("mixed",
                                         IndicatorAutocompleteProvider,
                                         'MAX_RESULTS', 5)
        registry.set_ac_provider_setting("mixed", StockAutocompleteProvider,
                                         'MAX_RESULTS', 5)
        registry.set_ac_provider_setting("mixed", CalcAutocompleteProvider,
                                         'MAX_RESULTS', 5)

        matches = self.autocomp.suggest('pe')

        self.assertEqual(len(matches['stock']), 5)
        self.assertEqual(len(matches['ind']), 5)
        self.assertEqual(len(matches['metric']), 1)

        registry.del_ac_provider_setting("mixed",
                                         IndicatorAutocompleteProvider,
                                         'MAX_RESULTS')
        registry.del_ac_provider_setting("mixed", StockAutocompleteProvider,
                                         'MAX_RESULTS')
        registry.del_ac_provider_setting("mixed", CalcAutocompleteProvider,
                                         'MAX_RESULTS')

    def test_matching_with_max_results_cap_and_elasticity(self):
        """
        Test that simple elastic results
        """
        registry.set_ac_provider_setting("mixed",
                                         IndicatorAutocompleteProvider,
                                         'MAX_RESULTS', 5)
        registry.set_ac_provider_setting("mixed", StockAutocompleteProvider,
                                         'MAX_RESULTS', 5)
        registry.set_ac_provider_setting("mixed", CalcAutocompleteProvider,
                                         'MAX_RESULTS', 5)

        setattr(auto_settings, 'ELASTIC_RESULTS', True)

        matches = self.autocomp.suggest('pe')
        self.assertEqual(len(matches['stock']), 5)
        self.assertEqual(len(matches['ind']), 9)
        self.assertEqual(len(matches['metric']), 1)

        setattr(auto_settings, 'ELASTIC_RESULTS', False)
        registry.del_ac_provider_setting("mixed",
                                         IndicatorAutocompleteProvider,
                                         'MAX_RESULTS')
        registry.del_ac_provider_setting("mixed", StockAutocompleteProvider,
                                         'MAX_RESULTS')
        registry.del_ac_provider_setting("mixed", CalcAutocompleteProvider,
                                         'MAX_RESULTS')

    def test_matching_with_uneven_max_results_cap_and_elasticity(self):
        """
        Test uneven redistribution of surplus result slots
        """
        registry.set_ac_provider_setting("mixed",
                                         IndicatorAutocompleteProvider,
                                         'MAX_RESULTS', 5)
        registry.set_ac_provider_setting("mixed", StockAutocompleteProvider,
                                         'MAX_RESULTS', 4)
        registry.set_ac_provider_setting("mixed", CalcAutocompleteProvider,
                                         'MAX_RESULTS', 6)

        setattr(auto_settings, 'ELASTIC_RESULTS', True)

        matches = self.autocomp.suggest('pe')
        self.assertEqual(len(matches['stock']), 5)
        self.assertEqual(len(matches['ind']), 9)
        self.assertEqual(len(matches['metric']), 1)

        setattr(auto_settings, 'ELASTIC_RESULTS', False)
        registry.del_ac_provider_setting("mixed",
                                         IndicatorAutocompleteProvider,
                                         'MAX_RESULTS')
        registry.del_ac_provider_setting("mixed", StockAutocompleteProvider,
                                         'MAX_RESULTS')
        registry.del_ac_provider_setting("mixed", CalcAutocompleteProvider,
                                         'MAX_RESULTS')
コード例 #32
0
class StockMatchTestCase(AutocompleterTestCase):
    fixtures = ['stock_test_data_small.json']

    def setUp(self):
        super(StockMatchTestCase, self).setUp()
        self.autocomp = Autocompleter("stock")
        self.autocomp.store_all()

    def tearDown(self):
        self.autocomp.remove_all()

    def test_simple_match(self):
        """
        Basic matching works
        """
        matches_symbol = self.autocomp.suggest('a')
        self.assertEqual(len(matches_symbol), 10)

    def test_no_match(self):
        """
        Phrases that match nothing work
        """
        matches_symbol = self.autocomp.suggest('gobblygook')
        self.assertEqual(len(matches_symbol), 0)

    def test_dual_term_matches(self):
        """
        Items in autocompleter can match against multiple unique terms
        """
        matches_symbol = self.autocomp.suggest('AAPL')
        self.assertEqual(len(matches_symbol), 1)

        matches_name = self.autocomp.suggest('Apple')
        self.assertEqual(len(matches_name), 1)

    def test_accented_matches(self):
        """
        Accented phrases match against both their orignal accented form, and their non-accented basic form.
        """
        matches = self.autocomp.suggest('estee lauder')
        self.assertEqual(len(matches), 1)
        self.assertEqual(matches[0]['search_name'], 'EL')

        matches = self.autocomp.suggest(u'estée lauder')
        self.assertEqual(len(matches), 1)
        self.assertEqual(matches[0]['search_name'], 'EL')

    def test_max_results_setting(self):
        """
        MAX_RESULTS is respected.
        """
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 10)
        setattr(auto_settings, 'MAX_RESULTS', 2)
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 2)

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'MAX_RESULTS', 10)

    def test_ac_provider_specific_max_results_setting(self):
        """
        Autocompleter/Provider specific MAX_RESULTS is respected
        """
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 10)

        registry.set_ac_provider_setting("stock", StockAutocompleteProvider, 'MAX_RESULTS', 5)
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 5)

        # Must set the setting back to where it was as it will persist
        registry.del_ac_provider_setting("stock", StockAutocompleteProvider, 'MAX_RESULTS')

    def test_caching(self):
        """
        Caching works
        """
        matches = self.autocomp.suggest('a')

        setattr(auto_settings, 'CACHE_TIMEOUT', 3600)

        for i in range(0, 3):
            matches2 = self.autocomp.suggest('a')

        self.assertEqual(len(matches), len(matches2))

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'CACHE_TIMEOUT', 0)

    def test_dropped_character_matching(self):
        """
        Searching for things that would be normalized to ' ' do not
        result in redis errors.
        """
        matches = self.autocomp.suggest('+')
        self.assertEqual(len(matches), 0)
        matches = self.autocomp.suggest('NBBC vs Regional - Mid-Atlantic Banks vs Financial')
        self.assertEqual(len(matches), 0)
コード例 #33
0
class ElasticMatchingTestCase(AutocompleterTestCase):
    fixtures = ['stock_test_data_small.json', 'indicator_test_data_small.json']

    def setUp(self):
        super(ElasticMatchingTestCase, self).setUp()
        self.autocomp = Autocompleter("mixed")
        self.autocomp.store_all()

    def tearDown(self):
        self.autocomp.remove_all()

    def test_basic_match(self):
        """
        Test basic multiple matching works
        """
        matches = self.autocomp.suggest('pe')
        self.assertEqual(len(matches['stock']), 5)
        self.assertEqual(len(matches['ind']), 10)
        self.assertEqual(len(matches['metric']), 1)

    def test_matching_with_max_results_cap(self):
        """
        Test that basic matching with results limit works
        """
        registry.set_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MAX_RESULTS', 5)
        registry.set_ac_provider_setting("mixed", StockAutocompleteProvider, 'MAX_RESULTS', 5)
        registry.set_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MAX_RESULTS', 5)

        matches = self.autocomp.suggest('pe')

        self.assertEqual(len(matches['stock']), 5)
        self.assertEqual(len(matches['ind']), 5)
        self.assertEqual(len(matches['metric']), 1)

        registry.del_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MAX_RESULTS')
        registry.del_ac_provider_setting("mixed", StockAutocompleteProvider, 'MAX_RESULTS')
        registry.del_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MAX_RESULTS')

    def test_matching_with_max_results_cap_and_elasticity(self):
        """
        Test that simple elastic results
        """
        registry.set_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MAX_RESULTS', 5)
        registry.set_ac_provider_setting("mixed", StockAutocompleteProvider, 'MAX_RESULTS', 5)
        registry.set_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MAX_RESULTS', 5)

        setattr(auto_settings, 'ELASTIC_RESULTS', True)

        matches = self.autocomp.suggest('pe')
        self.assertEqual(len(matches['stock']), 5)
        self.assertEqual(len(matches['ind']), 9)
        self.assertEqual(len(matches['metric']), 1)

        setattr(auto_settings, 'ELASTIC_RESULTS', False)
        registry.del_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MAX_RESULTS')
        registry.del_ac_provider_setting("mixed", StockAutocompleteProvider, 'MAX_RESULTS')
        registry.del_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MAX_RESULTS')

    def test_matching_with_uneven_max_results_cap_and_elasticity(self):
        """
        Test uneven redistribution of surplus result slots
        """
        registry.set_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MAX_RESULTS',5)
        registry.set_ac_provider_setting("mixed", StockAutocompleteProvider, 'MAX_RESULTS', 4)
        registry.set_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MAX_RESULTS', 6)

        setattr(auto_settings, 'ELASTIC_RESULTS', True)

        matches = self.autocomp.suggest('pe')
        self.assertEqual(len(matches['stock']), 5)
        self.assertEqual(len(matches['ind']), 9)
        self.assertEqual(len(matches['metric']), 1)

        setattr(auto_settings, 'ELASTIC_RESULTS', False)
        registry.del_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MAX_RESULTS')
        registry.del_ac_provider_setting("mixed", StockAutocompleteProvider, 'MAX_RESULTS')
        registry.del_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MAX_RESULTS')
コード例 #34
0
class FacetMatchingTestCase(AutocompleterTestCase):
    fixtures = ['stock_test_data_small.json']

    def setUp(self):
        super(FacetMatchingTestCase, self).setUp()
        self.autocomp = Autocompleter("faceted_stock")
        self.autocomp.store_all()

    def test_facet_or_match(self):
        """
        Matching using facets works with the 'or' type
        """
        facets = [
            {
                'type': 'or',
                'facets':
                    [
                        {'key': 'sector', 'value': 'Technology'},
                        {'key': 'sector', 'value': 'Consumer Defensive'},
                        {'key': 'industry', 'value': 'Thisdoesntexist'}
                    ]
            }
        ]
        matches = self.autocomp.suggest('a', facets=facets)
        self.assertEqual(len(matches), 4)

    def test_facet_and_match(self):
        """
        Matching using facets works with the 'and' type
        """
        facets = [
            {
                'type': 'and',
                'facets': [
                    {'key': 'sector', 'value': 'Technology'},
                    {'key': 'industry', 'value': 'SectorDoesntExist'}
                ]
            }
        ]
        matches = self.autocomp.suggest('ch', facets=facets)
        # since a stock can't have two different values for a sector, we expect calculating an 'and' on
        # two different sectors to have zero matches
        self.assertEqual(len(matches), 0)

        facets = [
            {
                'type': 'and',
                'facets': [
                    {'key': 'sector', 'value': 'Communication Services'},
                    {'key': 'industry', 'value': 'Telecom Services'}
                ]
            }
        ]

        matches = self.autocomp.suggest('ch', facets=facets)
        self.assertEqual(len(matches), 1)

        facets = [
            {
                'type': 'and',
                'facets': [
                    {'key': 'sector', 'value': 'Energy'},
                    {'key': 'industry', 'value': 'Oil & Gas Integrated'}
                ]
            }
        ]
        matches = self.autocomp.suggest('ch', facets=facets)
        self.assertEqual(len(matches), 2)

    def test_provider_keys_is_not_subset_of_facet_keys(self):
        """
        A provider's facet keys has to match at least one of the requested facet keys to kick in
        """

        facets = [
            {
                'type': 'and',
                'facets':
                    [
                        {'key': 'thisisfake', 'value': 'Technology'},
                    ]
            }
        ]
        facet_matches = self.autocomp.suggest('a', facets=facets)
        regular_matches = self.autocomp.suggest('a')
        # since the 'thisisfake' key does not exist in our provider, the results for a facet
        # suggest should be the same as a regular suggest
        self.assertEqual(facet_matches, regular_matches)

    def test_provider_keys_is_subset_of_facet_keys_no_match(self):
        """
        A provider which declares one of the requested facet keys but has no matches should not return any results
        """

        facets = [
            {
                'type': 'and',
                'facets':
                    [
                        {'key': 'sector', 'value': 'ZZ9 Plural Z Alpha'},
                    ]
            }
        ]
        facet_matches = self.autocomp.suggest('a', facets=facets)
        regular_matches = self.autocomp.suggest('a')
        # since the 'sector' key does belong to our faceted stock provider facets, we expected facets
        # logic to kick in, but with a bogus value there should be no results.
        self.assertEqual(len(facet_matches), 0)
        self.assertGreaterEqual(len(regular_matches), 1)

    def test_facet_doesnt_skew_suggest(self):
        """
        Test that using facets takes the suggest term into consideration
        """

        matches = self.autocomp.suggest('nosearchresultsforthisterm')
        self.assertEqual(len(matches), 0)
        facets = [
            {
                'type': 'or',
                'facets':
                    [
                        {'key': 'sector', 'value': 'Technology'},
                    ]
            }
        ]

        # we expect that adding facets to a suggest call with no results will not
        # add any results
        facet_matches = self.autocomp.suggest('nosearchresultsforthisterm', facets=facets)
        self.assertEqual(len(facet_matches), 0)

    def test_facet_match_with_move_exact_matches(self):
        """
        Exact matching still works with facet suggest
        """
        setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 10)
        temp_autocomp = Autocompleter('faceted_stock')
        temp_autocomp.store_all()

        facets = [
            {
                'type': 'or',
                'facets': [
                    {'key': 'sector', 'value': 'Technology'},
                    {'key': 'industry', 'value': 'Software'}
                ]
            }
        ]

        matches = temp_autocomp.suggest('Ma', facets=facets)
        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True)
        matches2 = temp_autocomp.suggest('Ma', facets=facets)
        self.assertNotEqual(matches[0]['search_name'], matches2[0]['search_name'])

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', False)
        temp_autocomp.remove_all()

    def test_facet_mismatch_with_move_exact_matches(self):
        """
        Exact matching shouldn't move an object that doesn't have a matching facet value
        """
        # This test case depends on very specific data, which is why this test
        # issues multiple asserts to check our assumptions

        setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 10)
        temp_autocomp = Autocompleter('faceted_stock')
        temp_autocomp.store_all()

        facets = [
            {
                'type': 'and',
                'facets': [
                    {'key': 'sector', 'value': 'Healthcare'},
                    {'key': 'industry', 'value': 'Healthcare Plans'},
                ]
            }
        ]

        # When gathering suggestions for 'Un', based on the stock_data_small.json fixture,
        # the only match should be UnitedHealth Group Inc. when using the Healthcare sector facet
        matches = temp_autocomp.suggest('Un', facets=facets)
        self.assertEqual(len(matches), 1)
        self.assertEqual(matches[0]['search_name'], "UNH")

        # When MOVE_EXACT_MATCHES_TO_TOP is set to True and not using facets,
        # we are expecting Unilever to be moved to the top.
        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True)
        matches = temp_autocomp.suggest('Un')
        self.assertEqual(matches[0]['search_name'], "UN")

        # When MOVE_EXACT_MATCHES_TO_TOP is set to True and we are using the
        # Healthcare sector facet, we are expecting to see UnitedHealth group
        # since Unilever belongs to the Consumer Defensive sector
        matches = temp_autocomp.suggest('Un', facets=facets)
        self.assertEqual(matches[0]['search_name'], "UNH")

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', False)
        temp_autocomp.remove_all()

    def test_exact_match_low_score_still_at_top(self):
        """
        Exact matching when using facets should push low scoring object to top if exact match
        """
        # The setup for this test case is that we have three stocks that begin with the letter Z
        # but limit our MAX_RESULTS setting to just 2.
        # With MOVE_EXACT_MATCHES_TO_TOP initially set to False, we do not expect to see the
        # stock with symbol 'Z' in the suggest results since it has the lowest market cap of the 3 which is
        # what we base the score off of.
        # Once we set MOVE_EXACT_MATCHES_TO_TOP to True we expect Z to be right at the top even though
        # it didn't even show up in the previous suggest call since it is an exact match.
        setattr(auto_settings, 'MAX_RESULTS', 2)
        setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 10)
        temp_autocomp = Autocompleter('faceted_stock')
        temp_autocomp.store_all()
        facets = [
            {
                'type': 'and',
                'facets': [
                    {'key': 'sector', 'value': 'Technology'},
                    {'key': 'industry', 'value': 'Software'},
                ]
            }
        ]
        matches = temp_autocomp.suggest('Z', facets=facets)
        search_names = [match['search_name'] for match in matches]
        self.assertTrue('Z' not in search_names)

        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True)
        matches = temp_autocomp.suggest('Z', facets=facets)
        self.assertTrue(matches[0]['search_name'] == 'Z')

        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', False)
        setattr(auto_settings, 'MAX_RESULTS', 10)
        setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 0)
        temp_autocomp.remove_all()

    def test_facet_works_with_cache(self):
        """
        Caching works with facet suggest
        """
        no_cache_no_facet_matches = self.autocomp.suggest('a')

        facets = [{'type': 'or', 'facets': [{'key': 'sector', 'value': 'Technology'}]}]

        no_cache_facet_matches = self.autocomp.suggest('a', facets=facets)

        setattr(auto_settings, 'CACHE_TIMEOUT', 3600)

        cache_facet_matches = self.autocomp.suggest('a', facets=facets)
        cache_no_facet_matches = self.autocomp.suggest('a')

        self.assertEqual(no_cache_no_facet_matches, cache_no_facet_matches)
        self.assertEqual(cache_facet_matches, no_cache_facet_matches)

        setattr(auto_settings, 'CACHE_TIMEOUT', 0)

    def test_multiple_facet_dicts_match(self):
        """
        Matching with multiple passed in facet dicts works
        """
        facets = [
            {
                'type': 'and',
                'facets': [{'key': 'sector', 'value': 'Communication Services'}]
            },
            {
                'type': 'and',
                'facets': [{'key': 'industry', 'value': 'Telecom Services'}]
            }
        ]
        matches = self.autocomp.suggest('ch', facets=facets)
        self.assertEqual(len(matches), 1)

        facets = [
            {
                'type': 'and',
                'facets': [{'key': 'sector', 'value': 'Energy'}]
            },
            {
                'type': 'and',
                'facets': [{'key': 'industry', 'value': 'Oil & Gas Integrated'}]
            },
        ]
        matches = self.autocomp.suggest('ch', facets=facets)
        self.assertEqual(len(matches), 2)
コード例 #35
0
class IndicatorMatchTestCase(AutocompleterTestCase):
    fixtures = ['indicator_test_data_small.json']

    def setUp(self):
        super(IndicatorMatchTestCase, self).setUp()
        self.autocomp = Autocompleter("indicator")
        self.autocomp.store_all()
        

    def tearDown(self):
        self.autocomp.remove_all()

    def test_same_score_word_based_id_ordering(self):
        """
        Two results with the same score are returned in lexographic order of object ID
        """

        matches = self.autocomp.suggest('us')
        self.assertEqual(matches[1]['display_name'], 'US Dollar to Australian Dollar Exchange Rate')
        self.assertEqual(matches[9]['display_name'], 'US Dollar to Chinese Yuan Exchange Rate')
        return matches

    def test_join_char_replacement(self):
        """
        Dashes are handled correctly
        """
        # Testing that both '3-month' and '3 month' match
        matches = self.autocomp.suggest('3-month')
        self.assertNotEqual(len(matches), 0)
        matches = self.autocomp.suggest('3 month')
        self.assertNotEqual(len(matches), 0)

        matches = self.autocomp.suggest('mortgage-backed')
        self.assertNotEqual(len(matches), 0)
        matches = self.autocomp.suggest('mortgagebacked')
        self.assertNotEqual(len(matches), 0)
        matches = self.autocomp.suggest('mortgage backed')
        self.assertNotEqual(len(matches), 0)
        matches = self.autocomp.suggest('backed mortgage')
        self.assertNotEqual(len(matches), 0)

        matches = self.autocomp.suggest('U S A')
        self.assertNotEqual(len(matches), 0)
        matches = self.autocomp.suggest('U SA')
        self.assertNotEqual(len(matches), 0)
        matches = self.autocomp.suggest('USA')
        self.assertNotEqual(len(matches), 0)
        matches = self.autocomp.suggest('U-S-A')
        self.assertNotEqual(len(matches), 0)
        matches = self.autocomp.suggest('U/S/A')
        self.assertNotEqual(len(matches), 0)
        matches = self.autocomp.suggest('U-S/A')
        self.assertNotEqual(len(matches), 0)

    def test_min_letters_setting(self):
        """
        MIN_LETTERS is respected.
        """
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 10)
        setattr(auto_settings, 'MIN_LETTERS', 2)
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 0)

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'MIN_LETTERS', 1)

    def test_ac_provider_specific_min_letters_setting(self):
        """
        Autocompleter/Provider specific MIN_LETTERS is respected.
        """
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 10)
        setattr(auto_settings, 'MIN_LETTERS', 2)
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 0)

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'MIN_LETTERS', 1)
コード例 #36
0
class MaxResultsMatchingTestCase(AutocompleterTestCase):
    fixtures = ['stock_test_data_small.json', 'indicator_test_data_small.json']

    def setUp(self):
        super(MaxResultsMatchingTestCase, self).setUp()
        self.autocomp = Autocompleter('ind_stock')
        self.autocomp.store_all()

    def test_max_results_respected(self):
        """
        MAX_RESULTS is respected for multi-type search case
        """
        # set MAX_RESULTS to an arbitrarily large number
        registry.set_autocompleter_setting('ind_stock', 'MAX_RESULTS', 100)

        matches = self.autocomp.suggest('a')
        total_matches_with_large_max_results = len(matches['stock']) + len(matches['ind'])
        self.assertGreaterEqual(100, total_matches_with_large_max_results)
        self.assertEqual(41, total_matches_with_large_max_results)

        registry.set_autocompleter_setting('ind_stock', 'MAX_RESULTS', 4)
        matches = self.autocomp.suggest('a')
        total_matches_with_small_max_results = len(matches['stock']) + len(matches['ind'])
        self.assertEqual(4, total_matches_with_small_max_results)

        self.assertGreater(total_matches_with_large_max_results, total_matches_with_small_max_results)

        registry.del_autocompleter_setting('ind_stock', 'MAX_RESULTS')

    def test_max_results_spreads_results_evenly(self):
        """
        MAX_RESULTS spreads the results among providers equally
        """
        registry.set_autocompleter_setting('ind_stock', 'MAX_RESULTS', 4)
        matches = self.autocomp.suggest('a')
        self.assertEqual(4, len(matches['stock']) + len(matches['ind']))
        self.assertEqual(len(matches['stock']), len(matches['ind']))

        registry.del_autocompleter_setting('ind_stock', 'MAX_RESULTS')

    def test_max_results_handles_surplus(self):
        """
        Suggest respects MAX_RESULTS while still dealing with surplus
        """
        # we know that there are 16 ind matches and 25 stock matches for 'a'
        registry.set_autocompleter_setting('ind_stock', 'MAX_RESULTS', 36)
        matches = self.autocomp.suggest('a')
        self.assertEqual(16, len(matches['ind']))
        self.assertEqual(20, len(matches['stock']))

        registry.del_autocompleter_setting('ind_stock', 'MAX_RESULTS')

    def test_max_results_handles_deficit_less_than_surplus(self):
        """
        MAX_RESULTS stops trying to hand out surplus matches when provider's deficits are met
        """
        # Previous code would have failed on this test case because of an infinite while loop that
        # failed to break when all provider's deficits were met. The setup requires
        # there to be at least one provider which will have a deficit less than the total surplus.
        # In this test case, the total surplus will be 3 (since stock has no matches) and the deficit
        # for indicators will be 2 (since there are 5 total matches for indicators and 3 slots are
        # reserved initially)
        registry.set_autocompleter_setting('ind_stock', 'MAX_RESULTS', 6)
        matches = self.autocomp.suggest('S&P')
        self.assertEqual(5, len(matches['ind']))
        self.assertEqual(0, len(matches['stock']))

        registry.del_autocompleter_setting('ind_stock', 'MAX_RESULTS')

    def test_max_results_has_hard_limit(self):
        """
        Suggest respects MAX_RESULTS over giving every provider at least 1 result
        """
        registry.set_autocompleter_setting('ind_stock', 'MAX_RESULTS', 1)
        matches = self.autocomp.suggest('a')
        # Either stock or indicator matches is empty
        self.assertEqual(1, len(matches['stock']) + len(matches['ind']))

        registry.del_autocompleter_setting('ind_stock', 'MAX_RESULTS')
コード例 #37
0
class StockMatchTestCase(AutocompleterTestCase):
    fixtures = ['stock_test_data_small.json']

    def setUp(self):
        self.autocomp = Autocompleter("stock")
        self.autocomp.store_all()
        super(StockMatchTestCase, self).setUp()

    def tearDown(self):
        self.autocomp.remove_all()

    def test_simple_match(self):
        """
        Basic matching works
        """
        matches_symbol = self.autocomp.suggest('a')
        self.assertEqual(len(matches_symbol), 10)

    def test_exact_match(self):
        """
        Exact matching works
        """
        matches_symbol = self.autocomp.exact_suggest('ma')
        self.assertEqual(len(matches_symbol), 1)

    def test_no_match(self):
        """
        Phrases that match nothing work
        """
        matches_symbol = self.autocomp.suggest('gobblygook')
        self.assertEqual(len(matches_symbol), 0)

    def test_dual_term_matches(self):
        """
        Items in autocompleter can match against multiple unique terms
        """
        matches_symbol = self.autocomp.suggest('AAPL')
        self.assertEqual(len(matches_symbol), 1)

        matches_name = self.autocomp.suggest('Apple')
        self.assertEqual(len(matches_name), 1)

    def test_accented_matches(self):
        """
        Accented phrases match against both their orignal accented form, and their non-accented basic form.
        """
        matches = self.autocomp.suggest('estee lauder')
        self.assertEqual(len(matches), 1)
        self.assertEqual(matches[0]['search_name'], 'EL')

        matches = self.autocomp.suggest(u'estée lauder')
        self.assertEqual(len(matches), 1)
        self.assertEqual(matches[0]['search_name'], 'EL')

    def test_exact_matches_setting(self):
        """
        MOVE_EXACT_MATCHES_TO_TOP works
        """
        matches = self.autocomp.suggest('Ma')
        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True)
        matches2 = self.autocomp.suggest('Ma')
        self.assertNotEqual(matches[0]['search_name'], matches2[0]['search_name'])

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', False)

    def test_max_results_setting(self):
        """
        MAX_RESULTS is respected.
        """
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 10)
        setattr(auto_settings, 'MAX_RESULTS', 2)
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 2)

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'MAX_RESULTS', 10)

    def test_ac_provider_specific_max_results_setting(self):
        """
        Autocompleter/Provider specific MAX_RESULTS is respected
        """
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 10)

        registry.set_ac_provider_setting("stock", StockAutocompleteProvider, 'MAX_RESULTS', 5)
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 5)

        # Must set the setting back to where it was as it will persist
        registry.del_ac_provider_setting("stock", StockAutocompleteProvider, 'MAX_RESULTS')

    def test_caching(self):
        """
        Caching works
        """
        matches = self.autocomp.suggest('a')

        setattr(auto_settings, 'CACHE_TIMEOUT', 3600)

        for i in range(0, 3):
            matches2 = self.autocomp.suggest('a')

        self.assertEqual(len(matches), len(matches2))

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'CACHE_TIMEOUT', 0)

    def test_exact_caching(self):
        """
        Exact caching works
        """
        matches = self.autocomp.exact_suggest('aapl')

        setattr(auto_settings, 'CACHE_TIMEOUT', 3600)

        for i in range(0, 10):
            matches2 = self.autocomp.exact_suggest('aapl')

        self.assertEqual(len(matches), len(matches2))

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'CACHE_TIMEOUT', 0)
コード例 #38
0
class StockMatchTestCase(AutocompleterTestCase):
    fixtures = ['stock_test_data_small.json']

    def setUp(self):
        super(StockMatchTestCase, self).setUp()
        self.autocomp = Autocompleter("stock")
        self.autocomp.store_all()

    def tearDown(self):
        self.autocomp.remove_all()

    def test_simple_match(self):
        """
        Basic matching works
        """
        matches_symbol = self.autocomp.suggest('a')
        self.assertEqual(len(matches_symbol), 10)

    def test_no_match(self):
        """
        Phrases that match nothing work
        """
        matches_symbol = self.autocomp.suggest('gobblygook')
        self.assertEqual(len(matches_symbol), 0)

    def test_dual_term_matches(self):
        """
        Items in autocompleter can match against multiple unique terms
        """
        matches_symbol = self.autocomp.suggest('AAPL')
        self.assertEqual(len(matches_symbol), 1)

        matches_name = self.autocomp.suggest('Apple')
        self.assertEqual(len(matches_name), 1)

    def test_accented_matches(self):
        """
        Accented phrases match against both their orignal accented form, and their non-accented basic form.
        """
        matches = self.autocomp.suggest('estee lauder')
        self.assertEqual(len(matches), 1)
        self.assertEqual(matches[0]['search_name'], 'EL')

        matches = self.autocomp.suggest(u'estée lauder')
        self.assertEqual(len(matches), 1)
        self.assertEqual(matches[0]['search_name'], 'EL')

    def test_max_results_setting(self):
        """
        MAX_RESULTS is respected.
        """
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 10)
        setattr(auto_settings, 'MAX_RESULTS', 2)
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 2)

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'MAX_RESULTS', 10)

    def test_ac_specific_max_results_setting(self):
        """
        Autocompleter specific MAX_RESULTS is respected
        """
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 10)

        registry.set_autocompleter_setting('stock', 'MAX_RESULTS', 5)
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 5)

        # Must set the setting back to where it was as it will persist
        registry.del_autocompleter_setting('stock', 'MAX_RESULTS')

    def test_caching(self):
        """
        Caching works
        """
        matches = self.autocomp.suggest('a')

        setattr(auto_settings, 'CACHE_TIMEOUT', 3600)

        for i in range(0, 3):
            matches2 = self.autocomp.suggest('a')

        self.assertEqual(len(matches), len(matches2))

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'CACHE_TIMEOUT', 0)

    def test_dropped_character_matching(self):
        """
        Searching for things that would be normalized to ' ' do not
        result in redis errors.
        """
        matches = self.autocomp.suggest('+')
        self.assertEqual(len(matches), 0)
        matches = self.autocomp.suggest('NBBC vs Regional - Mid-Atlantic Banks vs Financial')
        self.assertEqual(len(matches), 0)
コード例 #39
0
class IndicatorMatchTestCase(AutocompleterTestCase):
    fixtures = ['indicator_test_data_small.json']

    def setUp(self):
        self.autocomp = Autocompleter("indicator")
        self.autocomp.store_all()
        super(IndicatorMatchTestCase, self).setUp()

    def tearDown(self):
        self.autocomp.remove_all()

    def test_same_score_word_based_id_ordering(self):
        """
        Two results with the same score are returned in lexographic order of object ID
        """
        matches = self.autocomp.suggest('us')
        self.assertEqual(matches[1]['display_name'], 'Bank Credit of All US Commercial Banks')
        self.assertEqual(matches[9]['display_name'], 'Trade Weighted US Dollar Index: Major Currencies')
        return matches

    def test_dashes(self):
        """
        Dashes are handled correctly
        """
        # Testing that both '3-month' and '3 month' match
        matches = self.autocomp.suggest('3-month')
        self.assertNotEqual(len(matches), 0)
        matches = self.autocomp.suggest('3 month')
        self.assertNotEqual(len(matches), 0)

        matches = self.autocomp.suggest('mortgage-backed')
        self.assertNotEqual(len(matches), 0)
        matches = self.autocomp.suggest('mortgagebacked')
        self.assertNotEqual(len(matches), 0)
        matches = self.autocomp.suggest('mortgage backed')
        self.assertNotEqual(len(matches), 0)
        matches = self.autocomp.suggest('backed mortgage')
        self.assertNotEqual(len(matches), 0)

    def test_min_letters_setting(self):
        """
        MIN_LETTERS is respected.
        """
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 10)
        setattr(auto_settings, 'MIN_LETTERS', 2)
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 0)

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'MIN_LETTERS', 1)

    def test_ac_provider_specific_min_letters_setting(self):
        """
        Autocompleter/Provider specific MIN_LETTERS is respected.
        """
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 10)
        setattr(auto_settings, 'MIN_LETTERS', 2)
        matches = self.autocomp.suggest('a')
        self.assertEqual(len(matches), 0)

        # Must set the setting back to where it was as it will persist
        setattr(auto_settings, 'MIN_LETTERS', 1)
コード例 #40
0
class TextFacetSuggestView(AutocompleterTestCase):
    fixtures = ['stock_test_data_small.json']

    def setUp(self):
        super(TextFacetSuggestView, self).setUp()
        self.autocomp = Autocompleter('faceted_stock')
        self.autocomp.store_all()

    def tearDown(self):
        self.autocomp.remove_all()

    def test_facet_suggest_match(self):
        """
        Using suggest view works with facets
        """
        suggest_url = reverse('suggest', kwargs={'name': 'faceted_stock'})

        facets = [
            {
                'type': 'or',
                'facets': [{'key': 'sector', 'value': 'Technology'}]
            }
        ]

        matches_symbol = self.autocomp.suggest('a', facets=facets)

        data = {
            settings.SUGGEST_PARAMETER_NAME: 'a',
            settings.FACET_PARAMETER_NAME: json.dumps(facets)
        }
        response = self.client.get(suggest_url, data=data)
        self.assertEqual(response.status_code, 200)

        json_response = json.loads(response.content.decode('utf-8'))
        self.assertEqual(len(json_response), len(matches_symbol))

    def test_empty_facet_suggest(self):
        """
        An empty facet parameter still returns 200 response
        """
        suggest_url = reverse('suggest', kwargs={'name': 'faceted_stock'})

        matches_symbol = self.autocomp.suggest('a', facets=[])

        data = {
            settings.SUGGEST_PARAMETER_NAME: 'a',
            settings.FACET_PARAMETER_NAME: json.dumps([])
        }
        response = self.client.get(suggest_url, data=data)
        self.assertEqual(response.status_code, 200)

        json_response = json.loads(response.content.decode('utf-8'))
        self.assertEqual(len(json_response), len(matches_symbol))

    def test_invalid_facet(self):
        """
        An invalid facet should return a 400 response
        """
        suggest_url = reverse('suggest', kwargs={'name': 'faceted_stock'})

        no_type_facets = [
            {
                'facets': [{'key': 'sector', 'value': 'Technology'}]
            }
        ]

        data = {
            settings.SUGGEST_PARAMETER_NAME: 'a',
            settings.FACET_PARAMETER_NAME: json.dumps(no_type_facets)
        }
        response = self.client.get(suggest_url, data=data)
        self.assertEqual(response.status_code, 400)