-
Notifications
You must be signed in to change notification settings - Fork 310
autocomplete: Add and test MentionAutocompleteQuery #86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import '../api/model/model.dart'; | ||
|
||
class MentionAutocompleteQuery { | ||
MentionAutocompleteQuery(this.raw) | ||
: _lowercaseWords = raw.toLowerCase().split(' '); | ||
|
||
final String raw; | ||
|
||
final List<String> _lowercaseWords; | ||
|
||
bool testUser(User user) { | ||
// TODO test email too, not just name | ||
// TODO test with diacritics stripped, where appropriate | ||
|
||
// TODO cache, elsewhere | ||
final List<String> nameWords = user.fullName.toLowerCase().split(' '); | ||
|
||
int nameWordsIndex = 0; | ||
int queryWordsIndex = 0; | ||
while (true) { | ||
if (queryWordsIndex == _lowercaseWords.length) { | ||
return true; | ||
} | ||
if (nameWordsIndex == nameWords.length) { | ||
return false; | ||
} | ||
|
||
if (nameWords[nameWordsIndex].startsWith(_lowercaseWords[queryWordsIndex])) { | ||
queryWordsIndex++; | ||
} | ||
nameWordsIndex++; | ||
} | ||
} | ||
|
||
@override | ||
bool operator ==(Object other) { | ||
return other is MentionAutocompleteQuery && other.raw == raw; | ||
} | ||
|
||
@override | ||
int get hashCode => Object.hash('MentionAutocompleteQuery', raw); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,27 @@ final Uri realmUrl = Uri.parse('https://chat.example/'); | |
const String recentZulipVersion = '6.1'; | ||
const int recentZulipFeatureLevel = 164; | ||
|
||
User user({int? userId, String? fullName}) { | ||
return User( | ||
userId: userId ?? 123, // TODO generate example IDs | ||
deliveryEmailStaleDoNotUse: '[email protected]', | ||
email: '[email protected]', // TODO generate example emails | ||
fullName: fullName ?? 'A user',// TODO generate example names | ||
dateJoined: '2023-04-28', | ||
isActive: true, | ||
isOwner: false, | ||
isAdmin: false, | ||
isGuest: false, | ||
isBillingAdmin: false, | ||
isBot: false, | ||
role: 400, | ||
timezone: 'UTC', | ||
avatarUrl: null, | ||
avatarVersion: 0, | ||
profileData: null, | ||
); | ||
} | ||
|
||
final Account selfAccount = Account( | ||
id: 1001, | ||
realmUrl: realmUrl, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import 'package:checks/checks.dart'; | ||
import 'package:test/scaffolding.dart'; | ||
import 'package:zulip/api/model/model.dart'; | ||
import 'package:zulip/model/autocomplete.dart'; | ||
|
||
import '../example_data.dart' as eg; | ||
|
||
void main() { | ||
test('MentionAutocompleteQuery.testUser', () { | ||
doCheck(String rawQuery, User user, bool expected) { | ||
final result = MentionAutocompleteQuery(rawQuery).testUser(user); | ||
expected ? check(result).isTrue() : check(result).isFalse(); | ||
} | ||
|
||
doCheck('', eg.user(fullName: 'Full Name'), true); | ||
doCheck('', eg.user(fullName: ''), true); // Unlikely case, but should not crash | ||
doCheck('Full Name', eg.user(fullName: 'Full Name'), true); | ||
doCheck('full name', eg.user(fullName: 'Full Name'), true); | ||
doCheck('Full Name', eg.user(fullName: 'full name'), true); | ||
doCheck('Full', eg.user(fullName: 'Full Name'), true); | ||
doCheck('Name', eg.user(fullName: 'Full Name'), true); | ||
doCheck('Full Name', eg.user(fullName: 'Fully Named'), true); | ||
doCheck('Full Four', eg.user(fullName: 'Full Name Four Words'), true); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also test that "F Full" and "Four F" don't match this name, while "Full F" and "F Four" do. |
||
doCheck('Name Words', eg.user(fullName: 'Full Name Four Words'), true); | ||
doCheck('Full F', eg.user(fullName: 'Full Name Four Words'), true); | ||
doCheck('F Four', eg.user(fullName: 'Full Name Four Words'), true); | ||
doCheck('full full', eg.user(fullName: 'Full Full Name'), true); | ||
doCheck('full full', eg.user(fullName: 'Full Name Full'), true); | ||
|
||
doCheck('F', eg.user(fullName: ''), false); // Unlikely case, but should not crash | ||
doCheck('Fully Named', eg.user(fullName: 'Full Name'), false); | ||
doCheck('Full Name', eg.user(fullName: 'Full'), false); | ||
doCheck('Full Name', eg.user(fullName: 'Name'), false); | ||
doCheck('ull ame', eg.user(fullName: 'Full Name'), false); | ||
doCheck('ull Name', eg.user(fullName: 'Full Name'), false); | ||
doCheck('Full ame', eg.user(fullName: 'Full Name'), false); | ||
doCheck('Full Full', eg.user(fullName: 'Full Name'), false); | ||
doCheck('Name Name', eg.user(fullName: 'Full Name'), false); | ||
Comment on lines
+37
to
+38
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also test that "full full" does match "Full Full Name" and "Full Name Full". |
||
doCheck('Name Full', eg.user(fullName: 'Full Name'), false); | ||
doCheck('Name Four Full Words', eg.user(fullName: 'Full Name Four Words'), false); | ||
doCheck('F Full', eg.user(fullName: 'Full Name Four Words'), false); | ||
doCheck('Four F', eg.user(fullName: 'Full Name Four Words'), false); | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also include tests with empty
fullName
— one where query is also empty, one where nonempty.That isn't a super likely case, but it wouldn't be hard to have a bug where the search crashed on it.