1
1
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:
Amjith Ramanujam 2016-02-15 07:53:30 -08:00
commit 484108c549
2 changed files with 37 additions and 2 deletions

View File

@ -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

View File

@ -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