diff --git a/app/lib/search/mem_index.dart b/app/lib/search/mem_index.dart index 5fbcbbe05f..c96aa61f80 100644 --- a/app/lib/search/mem_index.dart +++ b/app/lib/search/mem_index.dart @@ -757,7 +757,11 @@ class PackageNameIndex { /// Returns the list of package names where the collapsed name matches. List? lookupMatchingNames(String text) { - return _collapsedNameResolvesToMap[_removeUnderscores(text.toLowerCase())]; + // convert to lowercase, remove spaces and underscores + final collapsedName = _removeUnderscores( + text.toLowerCase().replaceAll(' ', ''), + ); + return _collapsedNameResolvesToMap[collapsedName]; } } diff --git a/app/test/search/mem_index_test.dart b/app/test/search/mem_index_test.dart index 1c6df593cf..f9b6a73119 100644 --- a/app/test/search/mem_index_test.dart +++ b/app/test/search/mem_index_test.dart @@ -742,6 +742,44 @@ server.dart adds a small, prescriptive server (PicoServer) that can be configure }, ); }); + + test('exact name match with multi-phrase query', () { + final index = InMemoryPackageIndex( + documents: [ + PackageDocument( + package: 'abc_def_xyz', + description: 'abc def xyz', + maxPoints: 100, + grantedPoints: 100, + tags: ['sdk:dart', 'sdk:flutter'], + likeCount: 400, + downloadCount: 400, + ), + + PackageDocument( + package: 'abc_def', + description: 'some package', + maxPoints: 100, + grantedPoints: 0, + tags: ['sdk:dart', 'sdk:flutter'], + likeCount: 4, + downloadCount: 4, + ), + ], + ); + + final rs = index.search(ServiceSearchQuery.parse(query: 'abc def')); + expect(rs.toJson(), { + 'timestamp': isNotEmpty, + 'totalCount': 2, + 'nameMatches': ['abc_def'], + 'sdkLibraryHits': [], + 'packageHits': [ + {'package': 'abc_def', 'score': closeTo(0.55, 0.01)}, + {'package': 'abc_def_xyz', 'score': closeTo(1.0, 0.01)}, + ], + }); + }); }); });