Skip to content

Commit

Permalink
Add autocomplete unit tests for exact match
Browse files Browse the repository at this point in the history
  • Loading branch information
nimmolo committed Aug 29, 2024
1 parent 7e91a91 commit c72376a
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 62 deletions.
13 changes: 7 additions & 6 deletions app/classes/auto_complete/for_clade.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ def rough_matches(letter)
matches_array(clades)
end

def exact_match(string)
clade = Name.with_correct_spelling.with_rank_above_genus.
where(Name[:text_name].eq(string)).first
return [] unless clade
# Doesn't make sense to have exact match for clades
# def exact_match(string)
# clade = Name.with_correct_spelling.with_rank_above_genus.
# where(Name[:text_name].eq(string)).first
# return [] unless clade

matches_array([clade])
end
# matches_array([clade])
# end

# Turn the instances into hashes
def matches_array(clades)
Expand Down
13 changes: 7 additions & 6 deletions app/classes/auto_complete/for_region.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ def rough_matches(words)
matches_array(regions)
end

def exact_match(words)
words = Location.reverse_name(words) if reverse
region = Observation.in_region(words).select(:where, :location_id).first
return [] unless region
# Doesn't make sense to have an exact match for a region.
# def exact_match(words)
# words = Location.reverse_name(words) if reverse
# region = Observation.in_region(words).select(:where, :location_id).first
# return [] unless region

matches_array([region])
end
# matches_array([region])
# end

# Turn the instances into hashes, and alter name order if requested
# Also change the names of the hash keys.
Expand Down
7 changes: 4 additions & 3 deletions app/classes/auto_complete/for_user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ def rough_matches(letter)
end

def exact_match(string)
user = User.select(:login, :name, :id).distinct.
where(User[:login].eq(string)).or(User[:name].eq(string)).
order(login: :asc).first
user = User.select(:login, :name, :id).
where(User[:login].eq(string)).
or(User.where(User[:name].eq(string))).
order(login: :asc).distinct.first
return [] unless user

matches_array([user])
Expand Down
1 change: 1 addition & 0 deletions app/controllers/autocompleters_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def add_context_params
end

def auto_complete_results
# Don't pass region or clade as the @type with `exact` here.
if params[:exact].present?
return ::AutoComplete.subclass(@type).new(params).first_matching_record
end
Expand Down
143 changes: 96 additions & 47 deletions test/models/auto_complete_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,39 @@ def test_typical_use
assert_equal("A", results.first[:name])
assert(results.pluck(:name).include?("Agaricus"))
assert(results.pluck(:name).include?("Agaricus campestris"))

auto = AutoComplete::ForUser.new(string: "Rolf Singer")
results = auto.matching_records
assert(results.pluck(:name).include?("rolf <Rolf Singer>"))
end

def test_typical_use_with_exact_match
auto = AutoComplete::ForName.new(string: "Agaricus campestris")
results = auto.first_matching_record
assert_equal("Agaricus campestris", results.first[:name])

auto = AutoComplete::ForLocation.new(string: "Gualala, California, USA")
results = auto.first_matching_record
assert_equal("Gualala, California, USA", results.first[:name])

auto = AutoComplete::ForSpeciesList.new(string: "Another Species List")
results = auto.first_matching_record
assert_equal("Another Species List", results.first[:name])

auto = AutoComplete::ForProject.new(string: "Bolete Project")
results = auto.first_matching_record
assert_equal("Bolete Project", results.first[:name])

# Result strings include the code for the herbarium.
auto = AutoComplete::ForHerbarium.new(
string: "The New York Botanical Garden"
)
results = auto.first_matching_record
assert_equal("NY - The New York Botanical Garden", results.first[:name])

auto = AutoComplete::ForUser.new(string: "Rolf Singer")
results = auto.first_matching_record
assert_equal("rolf <Rolf Singer>", results.first[:name])
end

def test_truncate
Expand Down Expand Up @@ -77,7 +110,57 @@ def test_multiline_matches

def test_refine_token_by_string
pattern = "one two three"
@list = [
@list = string_list
string_examples.each do |limit, expected_matches, expected_string|
auto = AutoCompleteMock.new(string: pattern)
auto.matches = @list.sort_by { rand }.map { |str| { name: str, id: 0 } }
auto.limit = limit
assert_refines_correctly(auto, expected_matches, expected_string)
end
end

def test_refine_token_by_word
pattern = "one two shree"
@list = word_list
word_examples.each do |limit, expected_matches, expected_string|
auto = AutoComplete::ForMock.new(string: pattern)
auto.matches = @list.sort_by { rand }.map { |str| { name: str, id: 0 } }
auto.limit = limit
assert_refines_correctly(auto, expected_matches, expected_string)
end
end

def assert_refines_correctly(auto, expected_matches, expected_string)
string = auto.refine_token
if string != expected_string || auto.matches.length != expected_matches
msg = "Didn't refine matches correctly for limit = #{auto.limit}:\n" \
"Refined string: #{string.inspect}, " \
"expected: #{expected_string.inspect}\n #{show_matches(auto)}"
flunk(msg)
else
pass
end
end

def show_matches(auto)
result = ""
got = {}
@list.each do |str|
if auto.matches.include?(str)
result += "#{got.length + 1}: #{str.inspect}\n"
got[str] = true
else
result += "X: #{str.inspect}\n"
end
end
auto.matches.each do |str|
result += "UNEXPECTED!! #{str.inspect}\n" unless got[str]
end
result
end

def string_list
[
"one two three four", # 1
"one two threee", # 2
"one two three", # 3
Expand All @@ -89,7 +172,10 @@ def test_refine_token_by_string
"o", # 9
"something", # 10
"else" # 11
]
].freeze
end

def string_examples
[
[10, 9, "o"],
[9, 9, "o"],
Expand All @@ -100,17 +186,11 @@ def test_refine_token_by_string
[4, 4, "one two t"],
[3, 3, "one two th"],
[2, 3, "one two three"]
].each do |limit, expected_matches, expected_string|
auto = AutoCompleteMock.new(string: pattern)
auto.matches = @list.sort_by { rand }.map { |str| { name: str, id: 0 } }
auto.limit = limit
assert_refines_correctly(auto, expected_matches, expected_string)
end
].freeze
end

def test_refine_token_by_word
pattern = "one two shree"
@list = [
def word_list
[
"one two shree four", # 1 "one two shree"
"shreee two one", # 2 "one two shree"
"two-shirty-one", # 3 "one two sh"
Expand All @@ -122,7 +202,10 @@ def test_refine_token_by_word
"o", # 9 "o"
"something", # 10
"else" # 11
]
].freeze
end

def word_examples
[
[10, 9, "o"],
[9, 9, "o"],
Expand All @@ -134,40 +217,6 @@ def test_refine_token_by_word
[3, 3, "one two s"],
[2, 2, "one two shr"],
[1, 2, "one two shree"]
].each do |limit, expected_matches, expected_string|
auto = AutoComplete::ForMock.new(string: pattern)
auto.matches = @list.sort_by { rand }.map { |str| { name: str, id: 0 } }
auto.limit = limit
assert_refines_correctly(auto, expected_matches, expected_string)
end
end

def assert_refines_correctly(auto, expected_matches, expected_string)
string = auto.refine_token
if string != expected_string || auto.matches.length != expected_matches
msg = "Didn't refine matches correctly for limit = #{auto.limit}:\n" \
"Refined string: #{string.inspect}, " \
"expected: #{expected_string.inspect}\n #{show_matches(auto)}"
flunk(msg)
else
pass
end
end

def show_matches(auto)
result = ""
got = {}
@list.each do |str|
if auto.matches.include?(str)
result += "#{got.length + 1}: #{str.inspect}\n"
got[str] = true
else
result += "X: #{str.inspect}\n"
end
end
auto.matches.each do |str|
result += "UNEXPECTED!! #{str.inspect}\n" unless got[str]
end
result
].freeze
end
end

0 comments on commit c72376a

Please sign in to comment.