1use crate::{
2 code_context_menus::{CompletionsMenu, SortableMatch},
3 editor_settings::SnippetSortOrder,
4};
5use fuzzy::StringMatch;
6use gpui::TestAppContext;
7
8#[gpui::test]
9fn test_sort_matches_local_variable_over_global_variable(_cx: &mut TestAppContext) {
10 // Case 1: "foo"
11 let query: Option<&str> = Some("foo");
12 let mut matches: Vec<SortableMatch<'_>> = vec![
13 SortableMatch {
14 string_match: StringMatch {
15 candidate_id: 0,
16 score: 0.2727272727272727,
17 positions: vec![],
18 string: "foo_bar_baz".to_string(),
19 },
20 is_snippet: false,
21 sort_text: Some("7fffffff"),
22 sort_key: (2, "foo_bar_baz"),
23 },
24 SortableMatch {
25 string_match: StringMatch {
26 candidate_id: 0,
27 score: 0.2727272727272727,
28 positions: vec![],
29 string: "foo_bar_qux".to_string(),
30 },
31 is_snippet: false,
32 sort_text: Some("7ffffffe"),
33 sort_key: (1, "foo_bar_qux"),
34 },
35 SortableMatch {
36 string_match: StringMatch {
37 candidate_id: 0,
38 score: 0.22499999999999998,
39 positions: vec![],
40 string: "floorf64".to_string(),
41 },
42 is_snippet: false,
43 sort_text: Some("80000000"),
44 sort_key: (2, "floorf64"),
45 },
46 SortableMatch {
47 string_match: StringMatch {
48 candidate_id: 0,
49 score: 0.22499999999999998,
50 positions: vec![],
51 string: "floorf32".to_string(),
52 },
53 is_snippet: false,
54 sort_text: Some("80000000"),
55 sort_key: (2, "floorf32"),
56 },
57 SortableMatch {
58 string_match: StringMatch {
59 candidate_id: 0,
60 score: 0.22499999999999998,
61 positions: vec![],
62 string: "floorf16".to_string(),
63 },
64 is_snippet: false,
65 sort_text: Some("80000000"),
66 sort_key: (2, "floorf16"),
67 },
68 SortableMatch {
69 string_match: StringMatch {
70 candidate_id: 0,
71 score: 0.2,
72 positions: vec![],
73 string: "floorf128".to_string(),
74 },
75 is_snippet: false,
76 sort_text: Some("80000000"),
77 sort_key: (2, "floorf128"),
78 },
79 ];
80 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::default());
81 assert_eq!(
82 matches[0].string_match.string.as_str(),
83 "foo_bar_qux",
84 "Match order not expected"
85 );
86 assert_eq!(
87 matches[1].string_match.string.as_str(),
88 "foo_bar_baz",
89 "Match order not expected"
90 );
91 assert_eq!(
92 matches[2].string_match.string.as_str(),
93 "floorf16",
94 "Match order not expected"
95 );
96 assert_eq!(
97 matches[3].string_match.string.as_str(),
98 "floorf32",
99 "Match order not expected"
100 );
101
102 // Case 2: "foobar"
103 let query: Option<&str> = Some("foobar");
104 let mut matches: Vec<SortableMatch<'_>> = vec![
105 SortableMatch {
106 string_match: StringMatch {
107 candidate_id: 0,
108 score: 0.4363636363636364,
109 positions: vec![],
110 string: "foo_bar_baz".to_string(),
111 },
112 is_snippet: false,
113 sort_text: Some("7fffffff"),
114 sort_key: (2, "foo_bar_baz"),
115 },
116 SortableMatch {
117 string_match: StringMatch {
118 candidate_id: 0,
119 score: 0.4363636363636364,
120 positions: vec![],
121 string: "foo_bar_qux".to_string(),
122 },
123 is_snippet: false,
124 sort_text: Some("7ffffffe"),
125 sort_key: (1, "foo_bar_qux"),
126 },
127 ];
128 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::default());
129 assert_eq!(
130 matches[0].string_match.string.as_str(),
131 "foo_bar_qux",
132 "Match order not expected"
133 );
134 assert_eq!(
135 matches[1].string_match.string.as_str(),
136 "foo_bar_baz",
137 "Match order not expected"
138 );
139}
140
141#[gpui::test]
142fn test_sort_matches_local_variable_over_global_enum(_cx: &mut TestAppContext) {
143 // Case 1: "ele"
144 let query: Option<&str> = Some("ele");
145 let mut matches: Vec<SortableMatch<'_>> = vec![
146 SortableMatch {
147 string_match: StringMatch {
148 candidate_id: 0,
149 score: 0.2727272727272727,
150 positions: vec![],
151 string: "ElementType".to_string(),
152 },
153 is_snippet: false,
154 sort_text: Some("7fffffff"),
155 sort_key: (2, "ElementType"),
156 },
157 SortableMatch {
158 string_match: StringMatch {
159 candidate_id: 0,
160 score: 0.25,
161 positions: vec![],
162 string: "element_type".to_string(),
163 },
164 is_snippet: false,
165 sort_text: Some("7ffffffe"),
166 sort_key: (1, "element_type"),
167 },
168 SortableMatch {
169 string_match: StringMatch {
170 candidate_id: 0,
171 score: 0.16363636363636364,
172 positions: vec![],
173 string: "simd_select".to_string(),
174 },
175 is_snippet: false,
176 sort_text: Some("80000000"),
177 sort_key: (2, "simd_select"),
178 },
179 SortableMatch {
180 string_match: StringMatch {
181 candidate_id: 0,
182 score: 0.16,
183 positions: vec![],
184 string: "while let".to_string(),
185 },
186 is_snippet: false,
187 sort_text: Some("7fffffff"),
188 sort_key: (0, "while let"),
189 },
190 ];
191 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::default());
192 assert_eq!(
193 matches[0].string_match.string.as_str(),
194 "element_type",
195 "Match order not expected"
196 );
197 assert_eq!(
198 matches[1].string_match.string.as_str(),
199 "ElementType",
200 "Match order not expected"
201 );
202
203 // Case 2: "eleme"
204 let query: Option<&str> = Some("eleme");
205 let mut matches: Vec<SortableMatch<'_>> = vec![
206 SortableMatch {
207 string_match: StringMatch {
208 candidate_id: 0,
209 score: 0.4545454545454546,
210 positions: vec![],
211 string: "ElementType".to_string(),
212 },
213 is_snippet: false,
214 sort_text: Some("7fffffff"),
215 sort_key: (2, "ElementType"),
216 },
217 SortableMatch {
218 string_match: StringMatch {
219 candidate_id: 0,
220 score: 0.41666666666666663,
221 positions: vec![],
222 string: "element_type".to_string(),
223 },
224 is_snippet: false,
225 sort_text: Some("7ffffffe"),
226 sort_key: (1, "element_type"),
227 },
228 SortableMatch {
229 string_match: StringMatch {
230 candidate_id: 0,
231 score: 0.04714285714285713,
232 positions: vec![],
233 string: "REPLACEMENT_CHARACTER".to_string(),
234 },
235 is_snippet: false,
236 sort_text: Some("80000000"),
237 sort_key: (2, "REPLACEMENT_CHARACTER"),
238 },
239 ];
240 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::default());
241 assert_eq!(
242 matches[0].string_match.string.as_str(),
243 "element_type",
244 "Match order not expected"
245 );
246 assert_eq!(
247 matches[1].string_match.string.as_str(),
248 "ElementType",
249 "Match order not expected"
250 );
251
252 // Case 3: "Elem"
253 let query: Option<&str> = Some("Elem");
254 let mut matches: Vec<SortableMatch<'_>> = vec![
255 SortableMatch {
256 string_match: StringMatch {
257 candidate_id: 0,
258 score: 0.36363636363636365,
259 positions: vec![],
260 string: "ElementType".to_string(),
261 },
262 is_snippet: false,
263 sort_text: Some("7fffffff"),
264 sort_key: (2, "ElementType"),
265 },
266 SortableMatch {
267 string_match: StringMatch {
268 candidate_id: 0,
269 score: 0.0003333333333333333,
270 positions: vec![],
271 string: "element_type".to_string(),
272 },
273 is_snippet: false,
274 sort_text: Some("7ffffffe"),
275 sort_key: (1, "element_type"),
276 },
277 ];
278 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::default());
279 assert_eq!(
280 matches[0].string_match.string.as_str(),
281 "ElementType",
282 "Match order not expected"
283 );
284 assert_eq!(
285 matches[1].string_match.string.as_str(),
286 "element_type",
287 "Match order not expected"
288 );
289}
290
291#[gpui::test]
292fn test_sort_matches_for_unreachable(_cx: &mut TestAppContext) {
293 // Case 1: "unre"
294 let query: Option<&str> = Some("unre");
295 let mut matches: Vec<SortableMatch<'_>> = vec![
296 SortableMatch {
297 string_match: StringMatch {
298 candidate_id: 0,
299 score: 0.36363636363636365,
300 positions: vec![],
301 string: "unreachable".to_string(),
302 },
303 is_snippet: false,
304 sort_text: Some("80000000"),
305 sort_key: (2, "unreachable"),
306 },
307 SortableMatch {
308 string_match: StringMatch {
309 candidate_id: 0,
310 score: 0.26666666666666666,
311 positions: vec![],
312 string: "unreachable!(…)".to_string(),
313 },
314 is_snippet: true,
315 sort_text: Some("7fffffff"),
316 sort_key: (2, "unreachable!(…)"),
317 },
318 SortableMatch {
319 string_match: StringMatch {
320 candidate_id: 0,
321 score: 0.24615384615384617,
322 positions: vec![],
323 string: "unchecked_rem".to_string(),
324 },
325 is_snippet: false,
326 sort_text: Some("80000000"),
327 sort_key: (2, "unchecked_rem"),
328 },
329 SortableMatch {
330 string_match: StringMatch {
331 candidate_id: 0,
332 score: 0.19047619047619047,
333 positions: vec![],
334 string: "unreachable_unchecked".to_string(),
335 },
336 is_snippet: false,
337 sort_text: Some("80000000"),
338 sort_key: (2, "unreachable_unchecked"),
339 },
340 ];
341 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::default());
342 assert_eq!(
343 matches[0].string_match.string.as_str(),
344 "unreachable!(…)",
345 "Match order not expected"
346 );
347
348 // Case 2: "unrea"
349 let query: Option<&str> = Some("unrea");
350 let mut matches: Vec<SortableMatch<'_>> = vec![
351 SortableMatch {
352 string_match: StringMatch {
353 candidate_id: 0,
354 score: 0.4545454545454546,
355 positions: vec![],
356 string: "unreachable".to_string(),
357 },
358 is_snippet: true,
359 sort_text: Some("80000000"),
360 sort_key: (3, "unreachable"),
361 },
362 SortableMatch {
363 string_match: StringMatch {
364 candidate_id: 0,
365 score: 0.3333333333333333,
366 positions: vec![],
367 string: "unreachable!(…)".to_string(),
368 },
369 is_snippet: true,
370 sort_text: Some("7fffffff"),
371 sort_key: (3, "unreachable!(…)"),
372 },
373 SortableMatch {
374 string_match: StringMatch {
375 candidate_id: 0,
376 score: 0.23809523809523808,
377 positions: vec![],
378 string: "unreachable_unchecked".to_string(),
379 },
380 is_snippet: true,
381 sort_text: Some("80000000"),
382 sort_key: (3, "unreachable_unchecked"),
383 },
384 ];
385 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::default());
386 assert_eq!(
387 matches[0].string_match.string.as_str(),
388 "unreachable!(…)",
389 "Match order not expected"
390 );
391
392 // Case 3: "unreach"
393 let query: Option<&str> = Some("unreach");
394 let mut matches: Vec<SortableMatch<'_>> = vec![
395 SortableMatch {
396 string_match: StringMatch {
397 candidate_id: 0,
398 score: 0.6363636363636364,
399 positions: vec![],
400 string: "unreachable".to_string(),
401 },
402 is_snippet: false,
403 sort_text: Some("80000000"),
404 sort_key: (2, "unreachable"),
405 },
406 SortableMatch {
407 string_match: StringMatch {
408 candidate_id: 0,
409 score: 0.4666666666666667,
410 positions: vec![],
411 string: "unreachable!(…)".to_string(),
412 },
413 is_snippet: true,
414 sort_text: Some("7fffffff"),
415 sort_key: (2, "unreachable!(…)"),
416 },
417 SortableMatch {
418 string_match: StringMatch {
419 candidate_id: 0,
420 score: 0.3333333333333333,
421 positions: vec![],
422 string: "unreachable_unchecked".to_string(),
423 },
424 is_snippet: false,
425 sort_text: Some("80000000"),
426 sort_key: (2, "unreachable_unchecked"),
427 },
428 ];
429 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::default());
430 assert_eq!(
431 matches[0].string_match.string.as_str(),
432 "unreachable!(…)",
433 "Match order not expected"
434 );
435
436 // Case 4: "unreachabl"
437 let query: Option<&str> = Some("unreachable");
438 let mut matches: Vec<SortableMatch<'_>> = vec![
439 SortableMatch {
440 string_match: StringMatch {
441 candidate_id: 0,
442 score: 0.9090909090909092,
443 positions: vec![],
444 string: "unreachable".to_string(),
445 },
446 is_snippet: false,
447 sort_text: Some("80000000"),
448 sort_key: (3, "unreachable"),
449 },
450 SortableMatch {
451 string_match: StringMatch {
452 candidate_id: 0,
453 score: 0.6666666666666666,
454 positions: vec![],
455 string: "unreachable!(…)".to_string(),
456 },
457 is_snippet: false,
458 sort_text: Some("7fffffff"),
459 sort_key: (3, "unreachable!(…)"),
460 },
461 SortableMatch {
462 string_match: StringMatch {
463 candidate_id: 0,
464 score: 0.47619047619047616,
465 positions: vec![],
466 string: "unreachable_unchecked".to_string(),
467 },
468 is_snippet: false,
469 sort_text: Some("80000000"),
470 sort_key: (3, "unreachable_unchecked"),
471 },
472 ];
473 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::default());
474 assert_eq!(
475 matches[0].string_match.string.as_str(),
476 "unreachable!(…)",
477 "Match order not expected"
478 );
479
480 // Case 5: "unreachable"
481 let query: Option<&str> = Some("unreachable");
482 let mut matches: Vec<SortableMatch<'_>> = vec![
483 SortableMatch {
484 string_match: StringMatch {
485 candidate_id: 0,
486 score: 1.0,
487 positions: vec![],
488 string: "unreachable".to_string(),
489 },
490 is_snippet: false,
491 sort_text: Some("80000000"),
492 sort_key: (2, "unreachable"),
493 },
494 SortableMatch {
495 string_match: StringMatch {
496 candidate_id: 0,
497 score: 0.7333333333333333,
498 positions: vec![],
499 string: "unreachable!(…)".to_string(),
500 },
501 is_snippet: false,
502 sort_text: Some("7fffffff"),
503 sort_key: (2, "unreachable!(…)"),
504 },
505 SortableMatch {
506 string_match: StringMatch {
507 candidate_id: 0,
508 score: 0.5238095238095237,
509 positions: vec![],
510 string: "unreachable_unchecked".to_string(),
511 },
512 is_snippet: false,
513 sort_text: Some("80000000"),
514 sort_key: (2, "unreachable_unchecked"),
515 },
516 ];
517 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::default());
518 assert_eq!(
519 matches[0].string_match.string.as_str(),
520 "unreachable",
521 "Perfect fuzzy match should be preferred over others"
522 );
523}
524
525#[gpui::test]
526fn test_sort_matches_variable_and_constants_over_function(_cx: &mut TestAppContext) {
527 // Case 1: "var" as variable
528 let query: Option<&str> = Some("var");
529 let mut matches: Vec<SortableMatch<'_>> = vec![
530 SortableMatch {
531 string_match: StringMatch {
532 candidate_id: 0,
533 score: 1.0,
534 positions: vec![],
535 string: "var".to_string(),
536 },
537 is_snippet: false,
538 sort_text: Some("7fffffff"),
539 sort_key: (3, "var"), // function
540 },
541 SortableMatch {
542 string_match: StringMatch {
543 candidate_id: 1,
544 score: 1.0,
545 positions: vec![],
546 string: "var".to_string(),
547 },
548 is_snippet: false,
549 sort_text: Some("7fffffff"),
550 sort_key: (1, "var"), // variable
551 },
552 ];
553 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::default());
554 assert_eq!(
555 matches[0].string_match.candidate_id, 1,
556 "Match order not expected"
557 );
558 assert_eq!(
559 matches[1].string_match.candidate_id, 0,
560 "Match order not expected"
561 );
562
563 // Case 2: "var" as constant
564 let query: Option<&str> = Some("var");
565 let mut matches: Vec<SortableMatch<'_>> = vec![
566 SortableMatch {
567 string_match: StringMatch {
568 candidate_id: 0,
569 score: 1.0,
570 positions: vec![],
571 string: "var".to_string(),
572 },
573 is_snippet: false,
574 sort_text: Some("7fffffff"),
575 sort_key: (3, "var"), // function
576 },
577 SortableMatch {
578 string_match: StringMatch {
579 candidate_id: 1,
580 score: 1.0,
581 positions: vec![],
582 string: "var".to_string(),
583 },
584 is_snippet: false,
585 sort_text: Some("7fffffff"),
586 sort_key: (2, "var"), // constant
587 },
588 ];
589 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::default());
590 assert_eq!(
591 matches[0].string_match.candidate_id, 1,
592 "Match order not expected"
593 );
594 assert_eq!(
595 matches[1].string_match.candidate_id, 0,
596 "Match order not expected"
597 );
598}
599
600#[gpui::test]
601fn test_sort_matches_jsx_event_handler(_cx: &mut TestAppContext) {
602 // Case 1: "on"
603 let query: Option<&str> = Some("on");
604 let mut matches: Vec<SortableMatch<'_>> = vec![
605 SortableMatch {
606 string_match: StringMatch {
607 candidate_id: 0,
608 score: 0.3333333333333333,
609 positions: vec![],
610 string: "onCut?".to_string(),
611 },
612 is_snippet: false,
613 sort_text: Some("12"),
614 sort_key: (3, "onCut?"),
615 },
616 SortableMatch {
617 string_match: StringMatch {
618 candidate_id: 0,
619 score: 0.2857142857142857,
620 positions: vec![],
621 string: "onPlay?".to_string(),
622 },
623 is_snippet: false,
624 sort_text: Some("12"),
625 sort_key: (3, "onPlay?"),
626 },
627 SortableMatch {
628 string_match: StringMatch {
629 candidate_id: 0,
630 score: 0.25,
631 positions: vec![],
632 string: "color?".to_string(),
633 },
634 is_snippet: false,
635 sort_text: Some("12"),
636 sort_key: (3, "color?"),
637 },
638 SortableMatch {
639 string_match: StringMatch {
640 candidate_id: 0,
641 score: 0.25,
642 positions: vec![],
643 string: "defaultValue?".to_string(),
644 },
645 is_snippet: false,
646 sort_text: Some("12"),
647 sort_key: (3, "defaultValue?"),
648 },
649 SortableMatch {
650 string_match: StringMatch {
651 candidate_id: 0,
652 score: 0.25,
653 positions: vec![],
654 string: "style?".to_string(),
655 },
656 is_snippet: false,
657 sort_text: Some("12"),
658 sort_key: (3, "style?"),
659 },
660 SortableMatch {
661 string_match: StringMatch {
662 candidate_id: 0,
663 score: 0.20,
664 positions: vec![],
665 string: "className?".to_string(),
666 },
667 is_snippet: false,
668 sort_text: Some("12"),
669 sort_key: (3, "className?"),
670 },
671 ];
672 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::default());
673 assert_eq!(
674 matches[0].string_match.string, "onCut?",
675 "Match order not expected"
676 );
677 assert_eq!(
678 matches[1].string_match.string, "onPlay?",
679 "Match order not expected"
680 );
681
682 // Case 2: "ona"
683 let query: Option<&str> = Some("ona");
684 let mut matches: Vec<SortableMatch<'_>> = vec![
685 SortableMatch {
686 string_match: StringMatch {
687 candidate_id: 0,
688 score: 0.375,
689 positions: vec![],
690 string: "onAbort?".to_string(),
691 },
692 is_snippet: false,
693 sort_text: Some("12"),
694 sort_key: (3, "onAbort?"),
695 },
696 SortableMatch {
697 string_match: StringMatch {
698 candidate_id: 0,
699 score: 0.2727272727272727,
700 positions: vec![],
701 string: "onAuxClick?".to_string(),
702 },
703 is_snippet: false,
704 sort_text: Some("12"),
705 sort_key: (3, "onAuxClick?"),
706 },
707 SortableMatch {
708 string_match: StringMatch {
709 candidate_id: 0,
710 score: 0.23571428571428565,
711 positions: vec![],
712 string: "onPlay?".to_string(),
713 },
714 is_snippet: false,
715 sort_text: Some("12"),
716 sort_key: (3, "onPlay?"),
717 },
718 SortableMatch {
719 string_match: StringMatch {
720 candidate_id: 0,
721 score: 0.23571428571428565,
722 positions: vec![],
723 string: "onLoad?".to_string(),
724 },
725 is_snippet: false,
726 sort_text: Some("12"),
727 sort_key: (3, "onLoad?"),
728 },
729 SortableMatch {
730 string_match: StringMatch {
731 candidate_id: 0,
732 score: 0.23571428571428565,
733 positions: vec![],
734 string: "onDrag?".to_string(),
735 },
736 is_snippet: false,
737 sort_text: Some("12"),
738 sort_key: (3, "onDrag?"),
739 },
740 SortableMatch {
741 string_match: StringMatch {
742 candidate_id: 0,
743 score: 0.22499999999999998,
744 positions: vec![],
745 string: "onPause?".to_string(),
746 },
747 is_snippet: false,
748 sort_text: Some("12"),
749 sort_key: (3, "onPause?"),
750 },
751 SortableMatch {
752 string_match: StringMatch {
753 candidate_id: 0,
754 score: 0.22499999999999998,
755 positions: vec![],
756 string: "onPaste?".to_string(),
757 },
758 is_snippet: false,
759 sort_text: Some("12"),
760 sort_key: (3, "onPaste?"),
761 },
762 SortableMatch {
763 string_match: StringMatch {
764 candidate_id: 0,
765 score: 0.2,
766 positions: vec![],
767 string: "onAnimationEnd?".to_string(),
768 },
769 is_snippet: false,
770 sort_text: Some("12"),
771 sort_key: (3, "onAnimationEnd?"),
772 },
773 SortableMatch {
774 string_match: StringMatch {
775 candidate_id: 0,
776 score: 0.2,
777 positions: vec![],
778 string: "onAbortCapture?".to_string(),
779 },
780 is_snippet: false,
781 sort_text: Some("12"),
782 sort_key: (3, "onAbortCapture?"),
783 },
784 SortableMatch {
785 string_match: StringMatch {
786 candidate_id: 0,
787 score: 0.1833333333333333,
788 positions: vec![],
789 string: "onChange?".to_string(),
790 },
791 is_snippet: false,
792 sort_text: Some("12"),
793 sort_key: (3, "onChange?"),
794 },
795 SortableMatch {
796 string_match: StringMatch {
797 candidate_id: 0,
798 score: 0.18,
799 positions: vec![],
800 string: "onWaiting?".to_string(),
801 },
802 is_snippet: false,
803 sort_text: Some("12"),
804 sort_key: (3, "onWaiting?"),
805 },
806 SortableMatch {
807 string_match: StringMatch {
808 candidate_id: 0,
809 score: 0.18,
810 positions: vec![],
811 string: "onCanPlay?".to_string(),
812 },
813 is_snippet: false,
814 sort_text: Some("12"),
815 sort_key: (3, "onCanPlay?"),
816 },
817 SortableMatch {
818 string_match: StringMatch {
819 candidate_id: 0,
820 score: 0.1764705882352941,
821 positions: vec![],
822 string: "onAnimationStart?".to_string(),
823 },
824 is_snippet: false,
825 sort_text: Some("12"),
826 sort_key: (3, "onAnimationStart?"),
827 },
828 SortableMatch {
829 string_match: StringMatch {
830 candidate_id: 0,
831 score: 0.16666666666666666,
832 positions: vec![],
833 string: "onAuxClickCapture?".to_string(),
834 },
835 is_snippet: false,
836 sort_text: Some("12"),
837 sort_key: (3, "onAuxClickCapture?"),
838 },
839 SortableMatch {
840 string_match: StringMatch {
841 candidate_id: 0,
842 score: 0.16499999999999998,
843 positions: vec![],
844 string: "onStalled?".to_string(),
845 },
846 is_snippet: false,
847 sort_text: Some("12"),
848 sort_key: (3, "onStalled?"),
849 },
850 SortableMatch {
851 string_match: StringMatch {
852 candidate_id: 0,
853 score: 0.16499999999999998,
854 positions: vec![],
855 string: "onPlaying?".to_string(),
856 },
857 is_snippet: false,
858 sort_text: Some("12"),
859 sort_key: (3, "onPlaying?"),
860 },
861 SortableMatch {
862 string_match: StringMatch {
863 candidate_id: 0,
864 score: 0.16499999999999998,
865 positions: vec![],
866 string: "onDragEnd?".to_string(),
867 },
868 is_snippet: false,
869 sort_text: Some("12"),
870 sort_key: (3, "onDragEnd?"),
871 },
872 SortableMatch {
873 string_match: StringMatch {
874 candidate_id: 0,
875 score: 0.15000000000000002,
876 positions: vec![],
877 string: "onInvalid?".to_string(),
878 },
879 is_snippet: false,
880 sort_text: Some("12"),
881 sort_key: (3, "onInvalid?"),
882 },
883 SortableMatch {
884 string_match: StringMatch {
885 candidate_id: 0,
886 score: 0.15,
887 positions: vec![],
888 string: "onDragOver?".to_string(),
889 },
890 is_snippet: false,
891 sort_text: Some("12"),
892 sort_key: (3, "onDragOver?"),
893 },
894 SortableMatch {
895 string_match: StringMatch {
896 candidate_id: 0,
897 score: 0.15,
898 positions: vec![],
899 string: "onDragExit?".to_string(),
900 },
901 is_snippet: false,
902 sort_text: Some("12"),
903 sort_key: (3, "onDragExit?"),
904 },
905 SortableMatch {
906 string_match: StringMatch {
907 candidate_id: 0,
908 score: 0.14285714285714285,
909 positions: vec![],
910 string: "onAnimationIteration?".to_string(),
911 },
912 is_snippet: false,
913 sort_text: Some("12"),
914 sort_key: (3, "onAnimationIteration?"),
915 },
916 SortableMatch {
917 string_match: StringMatch {
918 candidate_id: 0,
919 score: 0.13846153846153847,
920 positions: vec![],
921 string: "onRateChange?".to_string(),
922 },
923 is_snippet: false,
924 sort_text: Some("12"),
925 sort_key: (3, "onRateChange?"),
926 },
927 SortableMatch {
928 string_match: StringMatch {
929 candidate_id: 0,
930 score: 0.13749999999999996,
931 positions: vec![],
932 string: "onLoadStart?".to_string(),
933 },
934 is_snippet: false,
935 sort_text: Some("12"),
936 sort_key: (3, "onLoadStart?"),
937 },
938 SortableMatch {
939 string_match: StringMatch {
940 candidate_id: 0,
941 score: 0.13749999999999996,
942 positions: vec![],
943 string: "onDragStart?".to_string(),
944 },
945 is_snippet: false,
946 sort_text: Some("12"),
947 sort_key: (3, "onDragStart?"),
948 },
949 SortableMatch {
950 string_match: StringMatch {
951 candidate_id: 0,
952 score: 0.13749999999999996,
953 positions: vec![],
954 string: "onDragLeave?".to_string(),
955 },
956 is_snippet: false,
957 sort_text: Some("12"),
958 sort_key: (3, "onDragLeave?"),
959 },
960 SortableMatch {
961 string_match: StringMatch {
962 candidate_id: 0,
963 score: 0.13749999999999996,
964 positions: vec![],
965 string: "onDragEnter?".to_string(),
966 },
967 is_snippet: false,
968 sort_text: Some("12"),
969 sort_key: (3, "onDragEnter?"),
970 },
971 SortableMatch {
972 string_match: StringMatch {
973 candidate_id: 0,
974 score: 0.13636363636363635,
975 positions: vec![],
976 string: "onAnimationEndCapture?".to_string(),
977 },
978 is_snippet: false,
979 sort_text: Some("12"),
980 sort_key: (3, "onAnimationEndCapture?"),
981 },
982 SortableMatch {
983 string_match: StringMatch {
984 candidate_id: 0,
985 score: 0.12692307692307692,
986 positions: vec![],
987 string: "onLoadedData?".to_string(),
988 },
989 is_snippet: false,
990 sort_text: Some("12"),
991 sort_key: (3, "onLoadedData?"),
992 },
993 ];
994 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::default());
995 assert_eq!(
996 matches
997 .iter()
998 .take(12)
999 .map(|m| m.string_match.string.as_str())
1000 .collect::<Vec<&str>>(),
1001 vec![
1002 "onAbort?",
1003 "onAuxClick?",
1004 "onAbortCapture?",
1005 "onAnimationEnd?",
1006 "onAnimationStart?",
1007 "onAuxClickCapture?",
1008 "onAnimationIteration?",
1009 "onAnimationEndCapture?",
1010 "onDrag?",
1011 "onLoad?",
1012 "onPlay?",
1013 "onPaste?",
1014 ]
1015 );
1016}
1017
1018#[gpui::test]
1019fn test_sort_matches_for_snippets(_cx: &mut TestAppContext) {
1020 // Case 1: "prin"
1021 let query: Option<&str> = Some("prin");
1022 let mut matches: Vec<SortableMatch<'_>> = vec![
1023 SortableMatch {
1024 string_match: StringMatch {
1025 candidate_id: 0,
1026 score: 0.2,
1027 positions: vec![],
1028 string: "println".to_string(),
1029 },
1030 is_snippet: false,
1031 sort_text: Some("80000000"),
1032 sort_key: (2, "println"),
1033 },
1034 SortableMatch {
1035 string_match: StringMatch {
1036 candidate_id: 0,
1037 score: 0.2,
1038 positions: vec![],
1039 string: "println!(…)".to_string(),
1040 },
1041 is_snippet: true,
1042 sort_text: Some("80000000"),
1043 sort_key: (2, "println!(…)"),
1044 },
1045 ];
1046 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::Top);
1047 assert_eq!(
1048 matches[0].string_match.string.as_str(),
1049 "println!(…)",
1050 "Match order not expected"
1051 );
1052}
1053
1054#[gpui::test]
1055fn test_sort_matches_for_exact_match(_cx: &mut TestAppContext) {
1056 // Case 1: "set_text"
1057 let query: Option<&str> = Some("set_text");
1058 let mut matches: Vec<SortableMatch<'_>> = vec![
1059 SortableMatch {
1060 string_match: StringMatch {
1061 candidate_id: 0,
1062 score: 1.0,
1063 positions: vec![],
1064 string: "set_text".to_string(),
1065 },
1066 is_snippet: false,
1067 sort_text: Some("7fffffff"),
1068 sort_key: (3, "set_text"),
1069 },
1070 SortableMatch {
1071 string_match: StringMatch {
1072 candidate_id: 0,
1073 score: 0.32000000000000006,
1074 positions: vec![],
1075 string: "set_placeholder_text".to_string(),
1076 },
1077 is_snippet: false,
1078 sort_text: Some("7fffffff"),
1079 sort_key: (3, "set_placeholder_text"),
1080 },
1081 SortableMatch {
1082 string_match: StringMatch {
1083 candidate_id: 0,
1084 score: 0.32,
1085 positions: vec![],
1086 string: "set_text_style_refinement".to_string(),
1087 },
1088 is_snippet: false,
1089 sort_text: Some("7fffffff"),
1090 sort_key: (3, "set_text_style_refinement"),
1091 },
1092 SortableMatch {
1093 string_match: StringMatch {
1094 candidate_id: 0,
1095 score: 0.16666666666666666,
1096 positions: vec![],
1097 string: "set_context_menu_options".to_string(),
1098 },
1099 is_snippet: false,
1100 sort_text: Some("7fffffff"),
1101 sort_key: (3, "set_context_menu_options"),
1102 },
1103 SortableMatch {
1104 string_match: StringMatch {
1105 candidate_id: 0,
1106 score: 0.08695652173913043,
1107 positions: vec![],
1108 string: "select_to_next_word_end".to_string(),
1109 },
1110 is_snippet: false,
1111 sort_text: Some("7fffffff"),
1112 sort_key: (3, "select_to_next_word_end"),
1113 },
1114 SortableMatch {
1115 string_match: StringMatch {
1116 candidate_id: 0,
1117 score: 0.07692307692307693,
1118 positions: vec![],
1119 string: "select_to_next_subword_end".to_string(),
1120 },
1121 is_snippet: false,
1122 sort_text: Some("7fffffff"),
1123 sort_key: (3, "select_to_next_subword_end"),
1124 },
1125 SortableMatch {
1126 string_match: StringMatch {
1127 candidate_id: 0,
1128 score: 0.06956521739130435,
1129 positions: vec![],
1130 string: "set_custom_context_menu".to_string(),
1131 },
1132 is_snippet: false,
1133 sort_text: Some("7fffffff"),
1134 sort_key: (3, "set_custom_context_menu"),
1135 },
1136 SortableMatch {
1137 string_match: StringMatch {
1138 candidate_id: 0,
1139 score: 0.06,
1140 positions: vec![],
1141 string: "select_to_end_of_excerpt".to_string(),
1142 },
1143 is_snippet: false,
1144 sort_text: Some("7fffffff"),
1145 sort_key: (3, "select_to_end_of_excerpt"),
1146 },
1147 SortableMatch {
1148 string_match: StringMatch {
1149 candidate_id: 0,
1150 score: 0.055384615384615386,
1151 positions: vec![],
1152 string: "select_to_start_of_excerpt".to_string(),
1153 },
1154 is_snippet: false,
1155 sort_text: Some("7fffffff"),
1156 sort_key: (3, "select_to_start_of_excerpt"),
1157 },
1158 SortableMatch {
1159 string_match: StringMatch {
1160 candidate_id: 0,
1161 score: 0.0464516129032258,
1162 positions: vec![],
1163 string: "select_to_start_of_next_excerpt".to_string(),
1164 },
1165 is_snippet: false,
1166 sort_text: Some("7fffffff"),
1167 sort_key: (3, "select_to_start_of_next_excerpt"),
1168 },
1169 SortableMatch {
1170 string_match: StringMatch {
1171 candidate_id: 0,
1172 score: 0.04363636363636363,
1173 positions: vec![],
1174 string: "select_to_end_of_previous_excerpt".to_string(),
1175 },
1176 is_snippet: false,
1177 sort_text: Some("7fffffff"),
1178 sort_key: (3, "select_to_end_of_previous_excerpt"),
1179 },
1180 ];
1181 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::Top);
1182 assert_eq!(
1183 matches
1184 .iter()
1185 .map(|m| m.string_match.string.as_str())
1186 .collect::<Vec<&str>>(),
1187 vec![
1188 "set_text",
1189 "set_text_style_refinement",
1190 "set_placeholder_text",
1191 "set_context_menu_options",
1192 "set_custom_context_menu",
1193 "select_to_next_word_end",
1194 "select_to_next_subword_end",
1195 "select_to_end_of_excerpt",
1196 "select_to_start_of_excerpt",
1197 "select_to_start_of_next_excerpt",
1198 "select_to_end_of_previous_excerpt",
1199 ]
1200 );
1201}
1202
1203#[gpui::test]
1204fn test_sort_matches_for_prefix_matches(_cx: &mut TestAppContext) {
1205 // Case 1: "set"
1206 let query: Option<&str> = Some("set");
1207 let mut matches: Vec<SortableMatch<'_>> = vec![
1208 SortableMatch {
1209 string_match: StringMatch {
1210 candidate_id: 0,
1211 score: 0.12631578947368421,
1212 positions: vec![],
1213 string: "select_to_beginning".to_string(),
1214 },
1215 is_snippet: false,
1216 sort_text: Some("7fffffff"),
1217 sort_key: (3, "select_to_beginning"),
1218 },
1219 SortableMatch {
1220 string_match: StringMatch {
1221 candidate_id: 0,
1222 score: 0.15000000000000002,
1223 positions: vec![],
1224 string: "set_collapse_matches".to_string(),
1225 },
1226 is_snippet: false,
1227 sort_text: Some("7fffffff"),
1228 sort_key: (3, "set_collapse_matches"),
1229 },
1230 SortableMatch {
1231 string_match: StringMatch {
1232 candidate_id: 0,
1233 score: 0.21428571428571427,
1234 positions: vec![],
1235 string: "set_autoindent".to_string(),
1236 },
1237 is_snippet: false,
1238 sort_text: Some("7fffffff"),
1239 sort_key: (3, "set_autoindent"),
1240 },
1241 SortableMatch {
1242 string_match: StringMatch {
1243 candidate_id: 0,
1244 score: 0.11538461538461539,
1245 positions: vec![],
1246 string: "set_all_diagnostics_active".to_string(),
1247 },
1248 is_snippet: false,
1249 sort_text: Some("7fffffff"),
1250 sort_key: (3, "set_all_diagnostics_active"),
1251 },
1252 SortableMatch {
1253 string_match: StringMatch {
1254 candidate_id: 0,
1255 score: 0.1142857142857143,
1256 positions: vec![],
1257 string: "select_to_end_of_line".to_string(),
1258 },
1259 is_snippet: false,
1260 sort_text: Some("7fffffff"),
1261 sort_key: (3, "select_to_end_of_line"),
1262 },
1263 SortableMatch {
1264 string_match: StringMatch {
1265 candidate_id: 0,
1266 score: 0.15000000000000002,
1267 positions: vec![],
1268 string: "select_all".to_string(),
1269 },
1270 is_snippet: false,
1271 sort_text: Some("7fffffff"),
1272 sort_key: (3, "select_all"),
1273 },
1274 SortableMatch {
1275 string_match: StringMatch {
1276 candidate_id: 0,
1277 score: 0.13636363636363635,
1278 positions: vec![],
1279 string: "select_line".to_string(),
1280 },
1281 is_snippet: false,
1282 sort_text: Some("7fffffff"),
1283 sort_key: (3, "select_line"),
1284 },
1285 SortableMatch {
1286 string_match: StringMatch {
1287 candidate_id: 0,
1288 score: 0.13636363636363635,
1289 positions: vec![],
1290 string: "select_left".to_string(),
1291 },
1292 is_snippet: false,
1293 sort_text: Some("7fffffff"),
1294 sort_key: (3, "select_left"),
1295 },
1296 SortableMatch {
1297 string_match: StringMatch {
1298 candidate_id: 0,
1299 score: 0.13636363636363635,
1300 positions: vec![],
1301 string: "select_down".to_string(),
1302 },
1303 is_snippet: false,
1304 sort_text: Some("7fffffff"),
1305 sort_key: (3, "select_down"),
1306 },
1307 ];
1308 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::Top);
1309 assert_eq!(
1310 matches
1311 .iter()
1312 .map(|m| m.string_match.string.as_str())
1313 .collect::<Vec<&str>>(),
1314 vec![
1315 "set_autoindent",
1316 "set_collapse_matches",
1317 "set_all_diagnostics_active",
1318 "select_all",
1319 "select_down",
1320 "select_left",
1321 "select_line",
1322 "select_to_beginning",
1323 "select_to_end_of_line",
1324 ]
1325 );
1326}
1327
1328#[gpui::test]
1329fn test_sort_matches_for_await(_cx: &mut TestAppContext) {
1330 // Case 1: "awa"
1331 let query: Option<&str> = Some("awa");
1332 let mut matches: Vec<SortableMatch<'_>> = vec![
1333 SortableMatch {
1334 string_match: StringMatch {
1335 candidate_id: 0,
1336 score: 0.6000000000000001,
1337 positions: vec![],
1338 string: "await".to_string(),
1339 },
1340 is_snippet: false,
1341 sort_text: Some("7fffffff"),
1342 sort_key: (0, "await"),
1343 },
1344 SortableMatch {
1345 string_match: StringMatch {
1346 candidate_id: 35,
1347 score: 0.375,
1348 positions: vec![],
1349 string: "await.ne".to_string(),
1350 },
1351 is_snippet: false,
1352 sort_text: Some("80000010"),
1353 sort_key: (3, "await.ne"),
1354 },
1355 SortableMatch {
1356 string_match: StringMatch {
1357 candidate_id: 34,
1358 score: 0.375,
1359 positions: vec![],
1360 string: "await.eq".to_string(),
1361 },
1362 is_snippet: false,
1363 sort_text: Some("80000010"),
1364 sort_key: (3, "await.eq"),
1365 },
1366 SortableMatch {
1367 string_match: StringMatch {
1368 candidate_id: 18,
1369 score: 0.375,
1370 positions: vec![],
1371 string: "await.or".to_string(),
1372 },
1373 is_snippet: false,
1374 sort_text: Some("7ffffff8"),
1375 sort_key: (3, "await.or"),
1376 },
1377 SortableMatch {
1378 string_match: StringMatch {
1379 candidate_id: 21,
1380 score: 0.3333333333333333,
1381 positions: vec![],
1382 string: "await.zip".to_string(),
1383 },
1384 is_snippet: false,
1385 sort_text: Some("80000006"),
1386 sort_key: (3, "await.zip"),
1387 },
1388 SortableMatch {
1389 string_match: StringMatch {
1390 candidate_id: 20,
1391 score: 0.3333333333333333,
1392 positions: vec![],
1393 string: "await.xor".to_string(),
1394 },
1395 is_snippet: false,
1396 sort_text: Some("7ffffff8"),
1397 sort_key: (3, "await.xor"),
1398 },
1399 SortableMatch {
1400 string_match: StringMatch {
1401 candidate_id: 15,
1402 score: 0.3333333333333333,
1403 positions: vec![],
1404 string: "await.and".to_string(),
1405 },
1406 is_snippet: false,
1407 sort_text: Some("80000006"),
1408 sort_key: (3, "await.and"),
1409 },
1410 SortableMatch {
1411 string_match: StringMatch {
1412 candidate_id: 9,
1413 score: 0.3333333333333333,
1414 positions: vec![],
1415 string: "await.map".to_string(),
1416 },
1417 is_snippet: false,
1418 sort_text: Some("80000006"),
1419 sort_key: (3, "await.map"),
1420 },
1421 SortableMatch {
1422 string_match: StringMatch {
1423 candidate_id: 47,
1424 score: 0.30000000000000004,
1425 positions: vec![],
1426 string: "await.take".to_string(),
1427 },
1428 is_snippet: false,
1429 sort_text: Some("7ffffff8"),
1430 sort_key: (3, "await.take"),
1431 },
1432 ];
1433 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::Top);
1434 assert_eq!(
1435 matches
1436 .iter()
1437 .map(|m| m.string_match.string.as_str())
1438 .collect::<Vec<&str>>(),
1439 vec![
1440 "await",
1441 "await.or",
1442 "await.xor",
1443 "await.take",
1444 "await.and",
1445 "await.map",
1446 "await.zip",
1447 "await.eq",
1448 "await.ne"
1449 ]
1450 );
1451 // Case 2: "await"
1452 let query: Option<&str> = Some("await");
1453 let mut matches: Vec<SortableMatch<'_>> = vec![
1454 SortableMatch {
1455 string_match: StringMatch {
1456 candidate_id: 0,
1457 score: 1.0,
1458 positions: vec![],
1459 string: "await".to_string(),
1460 },
1461 is_snippet: false,
1462 sort_text: Some("7fffffff"),
1463 sort_key: (0, "await"),
1464 },
1465 SortableMatch {
1466 string_match: StringMatch {
1467 candidate_id: 35,
1468 score: 0.625,
1469 positions: vec![],
1470 string: "await.ne".to_string(),
1471 },
1472 is_snippet: false,
1473 sort_text: Some("80000010"),
1474 sort_key: (3, "await.ne"),
1475 },
1476 SortableMatch {
1477 string_match: StringMatch {
1478 candidate_id: 34,
1479 score: 0.625,
1480 positions: vec![],
1481 string: "await.eq".to_string(),
1482 },
1483 is_snippet: false,
1484 sort_text: Some("80000010"),
1485 sort_key: (3, "await.eq"),
1486 },
1487 SortableMatch {
1488 string_match: StringMatch {
1489 candidate_id: 18,
1490 score: 0.625,
1491 positions: vec![],
1492 string: "await.or".to_string(),
1493 },
1494 is_snippet: false,
1495 sort_text: Some("7ffffff8"),
1496 sort_key: (3, "await.or"),
1497 },
1498 SortableMatch {
1499 string_match: StringMatch {
1500 candidate_id: 21,
1501 score: 0.5555555555555556,
1502 positions: vec![],
1503 string: "await.zip".to_string(),
1504 },
1505 is_snippet: false,
1506 sort_text: Some("80000006"),
1507 sort_key: (3, "await.zip"),
1508 },
1509 SortableMatch {
1510 string_match: StringMatch {
1511 candidate_id: 20,
1512 score: 0.5555555555555556,
1513 positions: vec![],
1514 string: "await.xor".to_string(),
1515 },
1516 is_snippet: false,
1517 sort_text: Some("7ffffff8"),
1518 sort_key: (3, "await.xor"),
1519 },
1520 SortableMatch {
1521 string_match: StringMatch {
1522 candidate_id: 15,
1523 score: 0.5555555555555556,
1524 positions: vec![],
1525 string: "await.and".to_string(),
1526 },
1527 is_snippet: false,
1528 sort_text: Some("80000006"),
1529 sort_key: (3, "await.and"),
1530 },
1531 SortableMatch {
1532 string_match: StringMatch {
1533 candidate_id: 9,
1534 score: 0.5555555555555556,
1535 positions: vec![],
1536 string: "await.map".to_string(),
1537 },
1538 is_snippet: false,
1539 sort_text: Some("80000006"),
1540 sort_key: (3, "await.map"),
1541 },
1542 SortableMatch {
1543 string_match: StringMatch {
1544 candidate_id: 47,
1545 score: 0.5,
1546 positions: vec![],
1547 string: "await.take".to_string(),
1548 },
1549 is_snippet: false,
1550 sort_text: Some("7ffffff8"),
1551 sort_key: (3, "await.take"),
1552 },
1553 ];
1554 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::Top);
1555 assert_eq!(
1556 matches
1557 .iter()
1558 .map(|m| m.string_match.string.as_str())
1559 .collect::<Vec<&str>>(),
1560 vec![
1561 "await",
1562 "await.or",
1563 "await.xor",
1564 "await.take",
1565 "await.and",
1566 "await.map",
1567 "await.zip",
1568 "await.eq",
1569 "await.ne"
1570 ]
1571 );
1572}
1573
1574#[gpui::test]
1575fn test_sort_matches_for_python_init(_cx: &mut TestAppContext) {
1576 // Case 1: "__in"
1577 let query: Option<&str> = Some("__in");
1578 let mut matches: Vec<SortableMatch<'_>> = vec![
1579 SortableMatch {
1580 string_match: StringMatch {
1581 candidate_id: 211,
1582 score: 0.5,
1583 positions: vec![],
1584 string: "__init__".to_string(),
1585 },
1586 is_snippet: false,
1587 sort_text: Some("05.0003.__init__"),
1588 sort_key: (3, "__init__"),
1589 },
1590 SortableMatch {
1591 string_match: StringMatch {
1592 candidate_id: 0,
1593 score: 0.5,
1594 positions: vec![],
1595 string: "__init__".to_string(),
1596 },
1597 is_snippet: false,
1598 sort_text: Some("05.0003"),
1599 sort_key: (3, "__init__"),
1600 },
1601 SortableMatch {
1602 string_match: StringMatch {
1603 candidate_id: 215,
1604 score: 0.23529411764705882,
1605 positions: vec![],
1606 string: "__instancecheck__".to_string(),
1607 },
1608 is_snippet: false,
1609 sort_text: Some("05.0005.__instancecheck__"),
1610 sort_key: (3, "__instancecheck__"),
1611 },
1612 SortableMatch {
1613 string_match: StringMatch {
1614 candidate_id: 213,
1615 score: 0.23529411764705882,
1616 positions: vec![],
1617 string: "__init_subclass__".to_string(),
1618 },
1619 is_snippet: false,
1620 sort_text: Some("05.0004.__init_subclass__"),
1621 sort_key: (3, "__init_subclass__"),
1622 },
1623 SortableMatch {
1624 string_match: StringMatch {
1625 candidate_id: 4,
1626 score: 0.23529411764705882,
1627 positions: vec![],
1628 string: "__instancecheck__".to_string(),
1629 },
1630 is_snippet: false,
1631 sort_text: Some("05.0005"),
1632 sort_key: (3, "__instancecheck__"),
1633 },
1634 SortableMatch {
1635 string_match: StringMatch {
1636 candidate_id: 2,
1637 score: 0.23529411764705882,
1638 positions: vec![],
1639 string: "__init_subclass__".to_string(),
1640 },
1641 is_snippet: false,
1642 sort_text: Some("05.0004"),
1643 sort_key: (3, "__init_subclass__"),
1644 },
1645 ];
1646 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::Top);
1647 assert_eq!(
1648 matches
1649 .iter()
1650 .map(|m| m.string_match.string.as_str())
1651 .collect::<Vec<&str>>(),
1652 vec![
1653 "__init__",
1654 "__init__",
1655 "__init_subclass__",
1656 "__init_subclass__",
1657 "__instancecheck__",
1658 "__instancecheck__",
1659 ]
1660 );
1661 // Case 2: "__ini"
1662 let query: Option<&str> = Some("__ini");
1663 let mut matches: Vec<SortableMatch<'_>> = vec![
1664 SortableMatch {
1665 string_match: StringMatch {
1666 candidate_id: 9,
1667 score: 0.625,
1668 positions: vec![],
1669 string: "__init__".to_string(),
1670 },
1671 is_snippet: false,
1672 sort_text: Some("05.0004.__init__"),
1673 sort_key: (3, "__init__"),
1674 },
1675 SortableMatch {
1676 string_match: StringMatch {
1677 candidate_id: 0,
1678 score: 0.625,
1679 positions: vec![],
1680 string: "__init__".to_string(),
1681 },
1682 is_snippet: false,
1683 sort_text: Some("05.0004"),
1684 sort_key: (3, "__init__"),
1685 },
1686 SortableMatch {
1687 string_match: StringMatch {
1688 candidate_id: 10,
1689 score: 0.29411764705882354,
1690 positions: vec![],
1691 string: "__init_subclass__".to_string(),
1692 },
1693 is_snippet: false,
1694 sort_text: Some("05.0003.__init_subclass__"),
1695 sort_key: (3, "__init_subclass__"),
1696 },
1697 SortableMatch {
1698 string_match: StringMatch {
1699 candidate_id: 1,
1700 score: 0.29411764705882354,
1701 positions: vec![],
1702 string: "__init_subclass__".to_string(),
1703 },
1704 is_snippet: false,
1705 sort_text: Some("05.0003"),
1706 sort_key: (3, "__init_subclass__"),
1707 },
1708 ];
1709 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::Top);
1710 assert_eq!(
1711 matches
1712 .iter()
1713 .map(|m| m.string_match.string.as_str())
1714 .collect::<Vec<&str>>(),
1715 vec![
1716 "__init__",
1717 "__init__",
1718 "__init_subclass__",
1719 "__init_subclass__",
1720 ]
1721 );
1722 // Case 3: "__init"
1723 let query: Option<&str> = Some("__init");
1724 let mut matches: Vec<SortableMatch<'_>> = vec![
1725 SortableMatch {
1726 string_match: StringMatch {
1727 candidate_id: 7,
1728 score: 0.75,
1729 positions: vec![],
1730 string: "__init__".to_string(),
1731 },
1732 is_snippet: false,
1733 sort_text: Some("05.0000.__init__"),
1734 sort_key: (3, "__init__"),
1735 },
1736 SortableMatch {
1737 string_match: StringMatch {
1738 candidate_id: 0,
1739 score: 0.75,
1740 positions: vec![],
1741 string: "__init__".to_string(),
1742 },
1743 is_snippet: false,
1744 sort_text: Some("05.0000"),
1745 sort_key: (3, "__init__"),
1746 },
1747 SortableMatch {
1748 string_match: StringMatch {
1749 candidate_id: 8,
1750 score: 0.3529411764705882,
1751 positions: vec![],
1752 string: "__init_subclass__".to_string(),
1753 },
1754 is_snippet: false,
1755 sort_text: Some("05.0001.__init_subclass__"),
1756 sort_key: (3, "__init_subclass__"),
1757 },
1758 SortableMatch {
1759 string_match: StringMatch {
1760 candidate_id: 1,
1761 score: 0.3529411764705882,
1762 positions: vec![],
1763 string: "__init_subclass__".to_string(),
1764 },
1765 is_snippet: false,
1766 sort_text: Some("05.0001"),
1767 sort_key: (3, "__init_subclass__"),
1768 },
1769 ];
1770 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::Top);
1771 assert_eq!(
1772 matches
1773 .iter()
1774 .map(|m| m.string_match.string.as_str())
1775 .collect::<Vec<&str>>(),
1776 vec![
1777 "__init__",
1778 "__init__",
1779 "__init_subclass__",
1780 "__init_subclass__",
1781 ]
1782 );
1783 // Case 4: "__init_"
1784 let query: Option<&str> = Some("__init_");
1785 let mut matches: Vec<SortableMatch<'_>> = vec![
1786 SortableMatch {
1787 string_match: StringMatch {
1788 candidate_id: 4,
1789 score: 0.875,
1790 positions: vec![],
1791 string: "__init__".to_string(),
1792 },
1793 is_snippet: false,
1794 sort_text: Some("11.9999.__init__"),
1795 sort_key: (3, "__init__"),
1796 },
1797 SortableMatch {
1798 string_match: StringMatch {
1799 candidate_id: 0,
1800 score: 0.875,
1801 positions: vec![],
1802 string: "__init__".to_string(),
1803 },
1804 is_snippet: false,
1805 sort_text: Some("11.9999"),
1806 sort_key: (3, "__init__"),
1807 },
1808 SortableMatch {
1809 string_match: StringMatch {
1810 candidate_id: 5,
1811 score: 0.4117647058823529,
1812 positions: vec![],
1813 string: "__init_subclass__".to_string(),
1814 },
1815 is_snippet: false,
1816 sort_text: Some("05.0000.__init_subclass__"),
1817 sort_key: (3, "__init_subclass__"),
1818 },
1819 SortableMatch {
1820 string_match: StringMatch {
1821 candidate_id: 1,
1822 score: 0.4117647058823529,
1823 positions: vec![],
1824 string: "__init_subclass__".to_string(),
1825 },
1826 is_snippet: false,
1827 sort_text: Some("05.0000"),
1828 sort_key: (3, "__init_subclass__"),
1829 },
1830 ];
1831 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::Top);
1832 assert_eq!(
1833 matches
1834 .iter()
1835 .map(|m| m.string_match.string.as_str())
1836 .collect::<Vec<&str>>(),
1837 vec![
1838 "__init__",
1839 "__init__",
1840 "__init_subclass__",
1841 "__init_subclass__",
1842 ]
1843 );
1844}
1845
1846#[gpui::test]
1847fn test_sort_matches_for_rust_into(_cx: &mut TestAppContext) {
1848 // Case 1: "int"
1849 let query: Option<&str> = Some("int");
1850 let mut matches: Vec<SortableMatch<'_>> = vec![
1851 SortableMatch {
1852 string_match: StringMatch {
1853 candidate_id: 67,
1854 score: 0.75,
1855 positions: vec![],
1856 string: "into".to_string(),
1857 },
1858 is_snippet: false,
1859 sort_text: Some("80000004"),
1860 sort_key: (3, "into"),
1861 },
1862 SortableMatch {
1863 string_match: StringMatch {
1864 candidate_id: 68,
1865 score: 0.30000000000000004,
1866 positions: vec![],
1867 string: "try_into".to_string(),
1868 },
1869 is_snippet: false,
1870 sort_text: Some("80000004"),
1871 sort_key: (3, "try_into"),
1872 },
1873 SortableMatch {
1874 string_match: StringMatch {
1875 candidate_id: 108,
1876 score: 0.2571428571428571,
1877 positions: vec![],
1878 string: "println".to_string(),
1879 },
1880 is_snippet: true,
1881 sort_text: Some("80000004"),
1882 sort_key: (3, "println"),
1883 },
1884 SortableMatch {
1885 string_match: StringMatch {
1886 candidate_id: 73,
1887 score: 0.24,
1888 positions: vec![],
1889 string: "clone_into".to_string(),
1890 },
1891 is_snippet: false,
1892 sort_text: Some("80000004"),
1893 sort_key: (3, "clone_into"),
1894 },
1895 SortableMatch {
1896 string_match: StringMatch {
1897 candidate_id: 1,
1898 score: 0.23076923076923078,
1899 positions: vec![],
1900 string: "into_searcher".to_string(),
1901 },
1902 is_snippet: false,
1903 sort_text: Some("80000000"),
1904 sort_key: (3, "into_searcher"),
1905 },
1906 SortableMatch {
1907 string_match: StringMatch {
1908 candidate_id: 109,
1909 score: 0.22499999999999998,
1910 positions: vec![],
1911 string: "eprintln".to_string(),
1912 },
1913 is_snippet: true,
1914 sort_text: Some("80000004"),
1915 sort_key: (3, "eprintln"),
1916 },
1917 ];
1918 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::default());
1919 assert_eq!(
1920 matches[0].string_match.string.as_str(),
1921 "into",
1922 "Match order not expected"
1923 );
1924 // Case 2: "into"
1925 let query: Option<&str> = Some("into");
1926 let mut matches: Vec<SortableMatch<'_>> = vec![
1927 SortableMatch {
1928 string_match: StringMatch {
1929 candidate_id: 65,
1930 score: 1.0,
1931 positions: vec![],
1932 string: "into".to_string(),
1933 },
1934 is_snippet: false,
1935 sort_text: Some("80000004"),
1936 sort_key: (3, "into"),
1937 },
1938 SortableMatch {
1939 string_match: StringMatch {
1940 candidate_id: 66,
1941 score: 0.4,
1942 positions: vec![],
1943 string: "try_into".to_string(),
1944 },
1945 is_snippet: false,
1946 sort_text: Some("80000004"),
1947 sort_key: (3, "try_into"),
1948 },
1949 SortableMatch {
1950 string_match: StringMatch {
1951 candidate_id: 71,
1952 score: 0.32,
1953 positions: vec![],
1954 string: "clone_into".to_string(),
1955 },
1956 is_snippet: false,
1957 sort_text: Some("80000004"),
1958 sort_key: (3, "clone_into"),
1959 },
1960 SortableMatch {
1961 string_match: StringMatch {
1962 candidate_id: 0,
1963 score: 0.3076923076923077,
1964 positions: vec![],
1965 string: "into_searcher".to_string(),
1966 },
1967 is_snippet: false,
1968 sort_text: Some("80000000"),
1969 sort_key: (3, "into_searcher"),
1970 },
1971 SortableMatch {
1972 string_match: StringMatch {
1973 candidate_id: 27,
1974 score: 0.09,
1975 positions: vec![],
1976 string: "split_terminator".to_string(),
1977 },
1978 is_snippet: false,
1979 sort_text: Some("7fffffff"),
1980 sort_key: (3, "split_terminator"),
1981 },
1982 SortableMatch {
1983 string_match: StringMatch {
1984 candidate_id: 28,
1985 score: 0.08470588235294117,
1986 positions: vec![],
1987 string: "rsplit_terminator".to_string(),
1988 },
1989 is_snippet: false,
1990 sort_text: Some("7fffffff"),
1991 sort_key: (3, "rsplit_terminator"),
1992 },
1993 ];
1994 CompletionsMenu::sort_matches(&mut matches, query, SnippetSortOrder::default());
1995 assert_eq!(
1996 matches[0].string_match.string.as_str(),
1997 "into",
1998 "Match order not expected"
1999 );
2000}