@@ -932,9 +932,11 @@ void main() {
932932 }
933933
934934 for (final option in WildcardMentionOption .values) {
935- // These are hard-coded, and they happened to be lowercase when written.
935+ // These are hard-coded, and they happened to be lowercase and without
936+ // diacritics when written.
936937 // Throw if that changes, to not accidentally break fuzzy matching.
937- check (option.canonicalString).equals (option.canonicalString.toLowerCase ());
938+ check (option.canonicalString).equals (
939+ AutocompleteQuery .lowercaseAndStripDiacritics (option.canonicalString));
938940 }
939941
940942 final testArabic = wildcardTesterForLocale ((locale) => locale.languageCode == 'ar' );
@@ -956,6 +958,10 @@ void main() {
956958 testGerman ('Thema' , topicNarrow, [WildcardMentionOption .topic]);
957959 testGerman ('thema' , topicNarrow, [WildcardMentionOption .topic]);
958960
961+ final testPolish = wildcardTesterForLocale ((locale) => locale.languageCode == 'pl' );
962+ testPolish ('wątek' , topicNarrow, [WildcardMentionOption .topic]);
963+ testPolish ('watek' , topicNarrow, [WildcardMentionOption .topic]);
964+
959965 test ('no wildcards for a silent mention' , () {
960966 check (getWildcardOptionsFor ('' , isSilent: true , narrow: channelNarrow))
961967 .isEmpty ();
@@ -1075,6 +1081,14 @@ void main() {
10751081 check (rankOf (query, a)! ).equals (rankOf (query, b)! );
10761082 }
10771083
1084+ void checkAllSameRank (String query, Iterable <Object > candidates) {
1085+ // (i.e. throw here if it's not a match)
1086+ final firstCandidateRank = rankOf (query, candidates.first)! ;
1087+
1088+ final ranks = candidates.skip (1 ).map ((candidate) => rankOf (query, candidate));
1089+ check (ranks).every ((it) => it.equals (firstCandidateRank));
1090+ }
1091+
10781092 test ('wildcards, then users' , () {
10791093 checkSameRank ('' , WildcardMentionOption .all, WildcardMentionOption .topic);
10801094 checkPrecedes ('' , WildcardMentionOption .topic, eg.user ());
@@ -1087,13 +1101,28 @@ void main() {
10871101 checkPrecedes (user.fullName, WildcardMentionOption .channel, user);
10881102 });
10891103
1090- test ('user name matched case-insensitively' , () {
1091- final user1 = eg.user (fullName: 'Chris Bobbe' );
1092- final user2 = eg.user (fullName: 'chris bobbe' );
1104+ test ('user name match is case- and diacritics-insensitive' , () {
1105+ final users = [
1106+ eg.user (fullName: 'Édith Piaf' ),
1107+ eg.user (fullName: 'édith piaf' ),
1108+ eg.user (fullName: 'Edith Piaf' ),
1109+ eg.user (fullName: 'edith piaf' ),
1110+ ];
1111+
1112+ checkAllSameRank ('Édith Piaf' , users); // exact
1113+ checkAllSameRank ('Edith Piaf' , users); // exact
1114+ checkAllSameRank ('édith piaf' , users); // exact
1115+ checkAllSameRank ('edith piaf' , users); // exact
10931116
1094- checkSameRank ('chris bobbe' , user1, user2); // exact
1095- checkSameRank ('chris bo' , user1, user2); // total-prefix
1096- checkSameRank ('chr bo' , user1, user2); // word-prefixes
1117+ checkAllSameRank ('Édith Pi' , users); // total-prefix
1118+ checkAllSameRank ('Edith Pi' , users); // total-prefix
1119+ checkAllSameRank ('édith pi' , users); // total-prefix
1120+ checkAllSameRank ('edith pi' , users); // total-prefix
1121+
1122+ checkAllSameRank ('Éd Pi' , users); // word-prefixes
1123+ checkAllSameRank ('Ed Pi' , users); // word-prefixes
1124+ checkAllSameRank ('éd pi' , users); // word-prefixes
1125+ checkAllSameRank ('ed pi' , users); // word-prefixes
10971126 });
10981127
10991128 test ('user name match: exact over total-prefix' , () {
@@ -1110,13 +1139,16 @@ void main() {
11101139 checkPrecedes ('so m' , user1, user2);
11111140 });
11121141
1113- test ('group name matched case-insensitively' , () {
1114- final userGroup1 = eg.userGroup (name: 'Mobile Team' );
1115- final userGroup2 = eg.userGroup (name: 'mobile team' );
1142+ test ('group name is case- and diacritics-insensitive' , () {
1143+ final userGroups = [
1144+ eg.userGroup (name: 'Mobile Team' ),
1145+ eg.userGroup (name: 'mobile team' ),
1146+ eg.userGroup (name: 'möbile team' ),
1147+ ];
11161148
1117- checkSameRank ('mobile team' , userGroup1, userGroup2 ); // exact
1118- checkSameRank ('mobile te' , userGroup1, userGroup2 ); // total-prefix
1119- checkSameRank ('mob te' , userGroup1, userGroup2 ); // word-prefixes
1149+ checkAllSameRank ('mobile team' , userGroups ); // exact
1150+ checkAllSameRank ('mobile te' , userGroups ); // total-prefix
1151+ checkAllSameRank ('mob te' , userGroups ); // word-prefixes
11201152 });
11211153
11221154 test ('group name match: exact over total-prefix' , () {
@@ -1133,16 +1165,19 @@ void main() {
11331165 checkPrecedes ('so m' , userGroup1, userGroup2);
11341166 });
11351167
1136- test ('email matched case-insensitively ' , () {
1168+ test ('email match is case- and diacritics-insensitive ' , () {
11371169 // "z" name to prevent accidental name match with example data
1138- final user1
= eg.
user (fullName
: 'z' , deliveryEmail
: '[email protected] ' );
1139- final user2
= eg.
user (fullName
: 'z' , deliveryEmail
: '[email protected] ' );
1140-
1141- checkSameRank (
'[email protected] ' , user1, user2);
1142- checkSameRank ('email@e' , user1, user2);
1143- checkSameRank ('email@' , user1, user2);
1144- checkSameRank ('email' , user1, user2);
1145- checkSameRank ('ema' , user1, user2);
1170+ final users = [
1171+ eg.
user (fullName
: 'z' , deliveryEmail
: '[email protected] ' ),
1172+ eg.
user (fullName
: 'z' , deliveryEmail
: '[email protected] ' ),
1173+ eg.
user (fullName
: 'z' , deliveryEmail
: 'ē[email protected] ' ),
1174+ ];
1175+
1176+ checkAllSameRank (
'[email protected] ' , users);
1177+ checkAllSameRank ('email@e' , users);
1178+ checkAllSameRank ('email@' , users);
1179+ checkAllSameRank ('email' , users);
1180+ checkAllSameRank ('ema' , users);
11461181 });
11471182
11481183 test ('email match is by prefix only' , () {
0 commit comments