-
Notifications
You must be signed in to change notification settings - Fork 309
autocomplete: Add and test MentionAutocompleteView #102
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
Conversation
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.
Thanks! Small comments below, mostly about the tests.
I think after those are resolved, it'd make sense to merge this (sans the demo commit). Then probably next is to build a UI for it, and that'll be enough for #49.
We can then file a followup issue for coming back to support wildcards and user groups, as well as other ways of matching queries to users or ranking matches.
lib/model/autocomplete.dart
Outdated
final Map<int, List<String>> _nameWordsByUser = {}; | ||
List<String> nameWordsForUser(User user) { | ||
return _nameWordsByUser[user.userId] ??= user.fullName.toLowerCase().split(' '); | ||
} | ||
invalidateUser(int userId) { |
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.
nit:
final Map<int, List<String>> _nameWordsByUser = {}; | |
List<String> nameWordsForUser(User user) { | |
return _nameWordsByUser[user.userId] ??= user.fullName.toLowerCase().split(' '); | |
} | |
invalidateUser(int userId) { | |
final Map<int, List<String>> _nameWordsByUser = {}; | |
List<String> nameWordsForUser(User user) { | |
return _nameWordsByUser[user.userId] ??= user.fullName.toLowerCase().split(' '); | |
} | |
invalidateUser(int userId) { |
lib/model/autocomplete.dart
Outdated
invalidateUser(int userId) { | ||
_nameWordsByUser.remove(userId); |
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.
invalidateUser(int userId) { | |
_nameWordsByUser.remove(userId); | |
void invalidateUser(int userId) { | |
_nameWordsByUser.remove(userId); |
.equals(eg.thirdUser.userId); | ||
}); | ||
|
||
test('MentionAutocompleteView not starve timers', () { |
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.
Co-authored-by: Greg Price <[email protected]>
should be greg@, not gnprice@ :)
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.
Ah, haha yeah that's right! I've sometimes wondered whether it would have been neater if I took chris@
, especially if I was the first to break the pattern of using just a first name.
test/model/autocomplete_test.dart
Outdated
check(done).isTrue(); | ||
check(view.results).single | ||
.isA<UserMentionAutocompleteResult>() | ||
.has((r) => r.userId, 'userId').equals(2999); |
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.
should pull these .has
calls out into a little extension, similar to #94 (comment)
Here, as a bonus that will dedupe them.
test/model/autocomplete_test.dart
Outdated
test('MentionAutocompleteView yield between batches of 1000', () async { | ||
const narrow = AllMessagesNarrow(); | ||
final store = eg.store(); | ||
for (int i = 0; i < 3000; i++) { |
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.
Let's make this a less round number, like 2500. That will make it easier to reason through why the number of yields below is what it is, because it will avoid any fencepost questions — questions like whether another yield becomes involved when the number of users reaches 3000, or when it exceeds 3000.
(The answer turns out to be "reaches" — so if this becomes "< 2999", then we need one fewer yield below.)
test/model/autocomplete_test.dart
Outdated
test('MentionAutocompleteView new query during computation replaces old', () async { | ||
const narrow = AllMessagesNarrow(); | ||
final store = eg.store(); | ||
for (int i = 0; i < 2000; i++) { |
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.
similarly, make this 1500 or 2500
368f3fb
to
f8d95ff
Compare
Thanks for the review! Revision pushed. |
Co-authored-by: Greg Price <[email protected]>
Thanks! Looks good; merging. |
f8d95ff
to
d21886a
Compare
import 'package:checks/checks.dart'; | ||
import 'package:zulip/model/autocomplete.dart'; | ||
|
||
extension UserMentionAutocompleteResultChecks on Subject<UserMentionAutocompleteResult> { |
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.
(FWIW I'd be inclined to put this one inside the individual test file, down at the end after main
, because it seems likely we'll only want it within the one file and because it'd be easy to move later if we want it in several files after all. But in a separate file is fine too.)
Thanks @gnprice for demonstrating tests for this tricky async logic (and also guiding its implementation)! I've added some more tests in this revision:
and kept the "DEV DEMO" commit from my earlier draft in case that's convenient for more manual testing. (Marking as a draft just because of that commit.)