mirror of
https://github.com/dbcli/pgcli.git
synced 2024-10-06 10:17:15 +03:00
Merge pull request #461 from drocco007/master
Use lexical order to break ties when fuzzy matching
This commit is contained in:
commit
484108c549
@ -212,7 +212,7 @@ class PGCompleter(Completer):
|
||||
else:
|
||||
fuzzy = False
|
||||
priority_func = self.prioritizer.keyword_count
|
||||
|
||||
|
||||
# Construct a `_match` function for either fuzzy or non-fuzzy matching
|
||||
# The match function returns a 2-tuple used for sorting the matches,
|
||||
# or None if the item doesn't match
|
||||
@ -236,6 +236,14 @@ class PGCompleter(Completer):
|
||||
# fuzzy matches
|
||||
return -float('Infinity'), -match_point
|
||||
|
||||
# Lexical order of items in the collection, used for tiebreaking items
|
||||
# with the same match group length and start position. In Python,
|
||||
# 'user' < 'users', i.e. the "lower" value comes first. Since we use
|
||||
# *higher* priority to mean "more important," we need to flip Python's
|
||||
# usual position ranking, hence -position.
|
||||
lexical_order = dict([(name, -position) for position, name in
|
||||
enumerate(sorted(collection))])
|
||||
|
||||
if meta_collection:
|
||||
# Each possible completion in the collection has a corresponding
|
||||
# meta-display string
|
||||
@ -253,9 +261,11 @@ class PGCompleter(Completer):
|
||||
# Truncate meta-text to 50 characters, if necessary
|
||||
meta = meta[:47] + u'...'
|
||||
|
||||
priority = sort_key, priority_func(item), lexical_order[item]
|
||||
|
||||
matches.append(Match(
|
||||
completion=Completion(item, -text_len, display_meta=meta),
|
||||
priority=(sort_key, priority_func(item))))
|
||||
priority=priority))
|
||||
|
||||
return matches
|
||||
|
||||
|
@ -49,3 +49,28 @@ def test_ranking_based_on_shortest_match(completer):
|
||||
matches = completer.find_matches(text, collection)
|
||||
|
||||
assert matches[1].priority > matches[0].priority
|
||||
|
||||
|
||||
@pytest.mark.parametrize('collection', [
|
||||
['user_action', 'user'],
|
||||
['user_group', 'user'],
|
||||
['user_group', 'user_action'],
|
||||
])
|
||||
def test_should_break_ties_using_lexical_order(completer, collection):
|
||||
"""Fuzzy result rank should use lexical order to break ties.
|
||||
|
||||
When fuzzy matching, if multiple matches have the same match length and
|
||||
start position, present them in lexical (rather than arbitrary) order. For
|
||||
example, if we have tables 'user', 'user_action', and 'user_group', a
|
||||
search for the text 'user' should present these tables in this order.
|
||||
|
||||
The input collections to this test are out of order; each run checks that
|
||||
the search text 'user' results in the input tables being reordered
|
||||
lexically.
|
||||
|
||||
"""
|
||||
|
||||
text = 'user'
|
||||
matches = completer.find_matches(text, collection)
|
||||
|
||||
assert matches[1].priority > matches[0].priority
|
||||
|
Loading…
Reference in New Issue
Block a user