code_completion_tests.rs

   1use crate::code_context_menus::{CompletionsMenu, SortableMatch};
   2use fuzzy::StringMatch;
   3use gpui::TestAppContext;
   4
   5#[gpui::test]
   6fn test_sort_matches_local_variable_over_global_variable(_cx: &mut TestAppContext) {
   7    // Case 1: "foo"
   8    let query: Option<&str> = Some("foo");
   9    let mut matches: Vec<SortableMatch<'_>> = vec![
  10        SortableMatch {
  11            string_match: StringMatch {
  12                candidate_id: 0,
  13                score: 0.2727272727272727,
  14                positions: vec![],
  15                string: "foo_bar_baz".to_string(),
  16            },
  17            is_snippet: false,
  18            sort_text: Some("7fffffff"),
  19            sort_key: (2, "foo_bar_baz"),
  20        },
  21        SortableMatch {
  22            string_match: StringMatch {
  23                candidate_id: 0,
  24                score: 0.2727272727272727,
  25                positions: vec![],
  26                string: "foo_bar_qux".to_string(),
  27            },
  28            is_snippet: false,
  29            sort_text: Some("7ffffffe"),
  30            sort_key: (1, "foo_bar_qux"),
  31        },
  32        SortableMatch {
  33            string_match: StringMatch {
  34                candidate_id: 0,
  35                score: 0.22499999999999998,
  36                positions: vec![],
  37                string: "floorf64".to_string(),
  38            },
  39            is_snippet: false,
  40            sort_text: Some("80000000"),
  41            sort_key: (2, "floorf64"),
  42        },
  43        SortableMatch {
  44            string_match: StringMatch {
  45                candidate_id: 0,
  46                score: 0.22499999999999998,
  47                positions: vec![],
  48                string: "floorf32".to_string(),
  49            },
  50            is_snippet: false,
  51            sort_text: Some("80000000"),
  52            sort_key: (2, "floorf32"),
  53        },
  54        SortableMatch {
  55            string_match: StringMatch {
  56                candidate_id: 0,
  57                score: 0.22499999999999998,
  58                positions: vec![],
  59                string: "floorf16".to_string(),
  60            },
  61            is_snippet: false,
  62            sort_text: Some("80000000"),
  63            sort_key: (2, "floorf16"),
  64        },
  65        SortableMatch {
  66            string_match: StringMatch {
  67                candidate_id: 0,
  68                score: 0.2,
  69                positions: vec![],
  70                string: "floorf128".to_string(),
  71            },
  72            is_snippet: false,
  73            sort_text: Some("80000000"),
  74            sort_key: (2, "floorf128"),
  75        },
  76    ];
  77    CompletionsMenu::sort_matches(&mut matches, query);
  78    assert_eq!(
  79        matches[0].string_match.string.as_str(),
  80        "foo_bar_qux",
  81        "Match order not expected"
  82    );
  83    assert_eq!(
  84        matches[1].string_match.string.as_str(),
  85        "foo_bar_baz",
  86        "Match order not expected"
  87    );
  88    assert_eq!(
  89        matches[2].string_match.string.as_str(),
  90        "floorf128",
  91        "Match order not expected"
  92    );
  93    assert_eq!(
  94        matches[3].string_match.string.as_str(),
  95        "floorf16",
  96        "Match order not expected"
  97    );
  98
  99    // Case 2: "foobar"
 100    let query: Option<&str> = Some("foobar");
 101    let mut matches: Vec<SortableMatch<'_>> = vec![
 102        SortableMatch {
 103            string_match: StringMatch {
 104                candidate_id: 0,
 105                score: 0.4363636363636364,
 106                positions: vec![],
 107                string: "foo_bar_baz".to_string(),
 108            },
 109            is_snippet: false,
 110            sort_text: Some("7fffffff"),
 111            sort_key: (2, "foo_bar_baz"),
 112        },
 113        SortableMatch {
 114            string_match: StringMatch {
 115                candidate_id: 0,
 116                score: 0.4363636363636364,
 117                positions: vec![],
 118                string: "foo_bar_qux".to_string(),
 119            },
 120            is_snippet: false,
 121            sort_text: Some("7ffffffe"),
 122            sort_key: (1, "foo_bar_qux"),
 123        },
 124    ];
 125    CompletionsMenu::sort_matches(&mut matches, query);
 126    assert_eq!(
 127        matches[0].string_match.string.as_str(),
 128        "foo_bar_qux",
 129        "Match order not expected"
 130    );
 131    assert_eq!(
 132        matches[1].string_match.string.as_str(),
 133        "foo_bar_baz",
 134        "Match order not expected"
 135    );
 136}
 137
 138#[gpui::test]
 139fn test_sort_matches_local_variable_over_global_enum(_cx: &mut TestAppContext) {
 140    // Case 1: "ele"
 141    let query: Option<&str> = Some("ele");
 142    let mut matches: Vec<SortableMatch<'_>> = vec![
 143        SortableMatch {
 144            string_match: StringMatch {
 145                candidate_id: 0,
 146                score: 0.2727272727272727,
 147                positions: vec![],
 148                string: "ElementType".to_string(),
 149            },
 150            is_snippet: false,
 151            sort_text: Some("7fffffff"),
 152            sort_key: (2, "ElementType"),
 153        },
 154        SortableMatch {
 155            string_match: StringMatch {
 156                candidate_id: 0,
 157                score: 0.25,
 158                positions: vec![],
 159                string: "element_type".to_string(),
 160            },
 161            is_snippet: false,
 162            sort_text: Some("7ffffffe"),
 163            sort_key: (1, "element_type"),
 164        },
 165        SortableMatch {
 166            string_match: StringMatch {
 167                candidate_id: 0,
 168                score: 0.16363636363636364,
 169                positions: vec![],
 170                string: "simd_select".to_string(),
 171            },
 172            is_snippet: false,
 173            sort_text: Some("80000000"),
 174            sort_key: (2, "simd_select"),
 175        },
 176        SortableMatch {
 177            string_match: StringMatch {
 178                candidate_id: 0,
 179                score: 0.16,
 180                positions: vec![],
 181                string: "while let".to_string(),
 182            },
 183            is_snippet: false,
 184            sort_text: Some("7fffffff"),
 185            sort_key: (0, "while let"),
 186        },
 187    ];
 188    CompletionsMenu::sort_matches(&mut matches, query);
 189    assert_eq!(
 190        matches[0].string_match.string.as_str(),
 191        "element_type",
 192        "Match order not expected"
 193    );
 194    assert_eq!(
 195        matches[1].string_match.string.as_str(),
 196        "ElementType",
 197        "Match order not expected"
 198    );
 199
 200    // Case 2: "eleme"
 201    let query: Option<&str> = Some("eleme");
 202    let mut matches: Vec<SortableMatch<'_>> = vec![
 203        SortableMatch {
 204            string_match: StringMatch {
 205                candidate_id: 0,
 206                score: 0.4545454545454546,
 207                positions: vec![],
 208                string: "ElementType".to_string(),
 209            },
 210            is_snippet: false,
 211            sort_text: Some("7fffffff"),
 212            sort_key: (2, "ElementType"),
 213        },
 214        SortableMatch {
 215            string_match: StringMatch {
 216                candidate_id: 0,
 217                score: 0.41666666666666663,
 218                positions: vec![],
 219                string: "element_type".to_string(),
 220            },
 221            is_snippet: false,
 222            sort_text: Some("7ffffffe"),
 223            sort_key: (1, "element_type"),
 224        },
 225        SortableMatch {
 226            string_match: StringMatch {
 227                candidate_id: 0,
 228                score: 0.04714285714285713,
 229                positions: vec![],
 230                string: "REPLACEMENT_CHARACTER".to_string(),
 231            },
 232            is_snippet: false,
 233            sort_text: Some("80000000"),
 234            sort_key: (2, "REPLACEMENT_CHARACTER"),
 235        },
 236    ];
 237    CompletionsMenu::sort_matches(&mut matches, query);
 238    assert_eq!(
 239        matches[0].string_match.string.as_str(),
 240        "element_type",
 241        "Match order not expected"
 242    );
 243    assert_eq!(
 244        matches[1].string_match.string.as_str(),
 245        "ElementType",
 246        "Match order not expected"
 247    );
 248
 249    // Case 3: "Elem"
 250    let query: Option<&str> = Some("Elem");
 251    let mut matches: Vec<SortableMatch<'_>> = vec![
 252        SortableMatch {
 253            string_match: StringMatch {
 254                candidate_id: 0,
 255                score: 0.36363636363636365,
 256                positions: vec![],
 257                string: "ElementType".to_string(),
 258            },
 259            is_snippet: false,
 260            sort_text: Some("7fffffff"),
 261            sort_key: (2, "ElementType"),
 262        },
 263        SortableMatch {
 264            string_match: StringMatch {
 265                candidate_id: 0,
 266                score: 0.0003333333333333333,
 267                positions: vec![],
 268                string: "element_type".to_string(),
 269            },
 270            is_snippet: false,
 271            sort_text: Some("7ffffffe"),
 272            sort_key: (1, "element_type"),
 273        },
 274    ];
 275    CompletionsMenu::sort_matches(&mut matches, query);
 276    assert_eq!(
 277        matches[0].string_match.string.as_str(),
 278        "ElementType",
 279        "Match order not expected"
 280    );
 281    assert_eq!(
 282        matches[1].string_match.string.as_str(),
 283        "element_type",
 284        "Match order not expected"
 285    );
 286}
 287
 288#[gpui::test]
 289fn test_sort_matches_for_unreachable(_cx: &mut TestAppContext) {
 290    // Case 1: "unre"
 291    let query: Option<&str> = Some("unre");
 292    let mut matches: Vec<SortableMatch<'_>> = vec![
 293        SortableMatch {
 294            string_match: StringMatch {
 295                candidate_id: 0,
 296                score: 0.36363636363636365,
 297                positions: vec![],
 298                string: "unreachable".to_string(),
 299            },
 300            is_snippet: false,
 301            sort_text: Some("80000000"),
 302            sort_key: (2, "unreachable"),
 303        },
 304        SortableMatch {
 305            string_match: StringMatch {
 306                candidate_id: 0,
 307                score: 0.26666666666666666,
 308                positions: vec![],
 309                string: "unreachable!(…)".to_string(),
 310            },
 311            is_snippet: true,
 312            sort_text: Some("7fffffff"),
 313            sort_key: (2, "unreachable!(…)"),
 314        },
 315        SortableMatch {
 316            string_match: StringMatch {
 317                candidate_id: 0,
 318                score: 0.24615384615384617,
 319                positions: vec![],
 320                string: "unchecked_rem".to_string(),
 321            },
 322            is_snippet: false,
 323            sort_text: Some("80000000"),
 324            sort_key: (2, "unchecked_rem"),
 325        },
 326        SortableMatch {
 327            string_match: StringMatch {
 328                candidate_id: 0,
 329                score: 0.19047619047619047,
 330                positions: vec![],
 331                string: "unreachable_unchecked".to_string(),
 332            },
 333            is_snippet: false,
 334            sort_text: Some("80000000"),
 335            sort_key: (2, "unreachable_unchecked"),
 336        },
 337    ];
 338    CompletionsMenu::sort_matches(&mut matches, query);
 339    assert_eq!(
 340        matches[0].string_match.string.as_str(),
 341        "unreachable!(…)",
 342        "Match order not expected"
 343    );
 344
 345    // Case 2: "unrea"
 346    let query: Option<&str> = Some("unrea");
 347    let mut matches: Vec<SortableMatch<'_>> = vec![
 348        SortableMatch {
 349            string_match: StringMatch {
 350                candidate_id: 0,
 351                score: 0.4545454545454546,
 352                positions: vec![],
 353                string: "unreachable".to_string(),
 354            },
 355            is_snippet: true,
 356            sort_text: Some("80000000"),
 357            sort_key: (3, "unreachable"),
 358        },
 359        SortableMatch {
 360            string_match: StringMatch {
 361                candidate_id: 0,
 362                score: 0.3333333333333333,
 363                positions: vec![],
 364                string: "unreachable!(…)".to_string(),
 365            },
 366            is_snippet: true,
 367            sort_text: Some("7fffffff"),
 368            sort_key: (3, "unreachable!(…)"),
 369        },
 370        SortableMatch {
 371            string_match: StringMatch {
 372                candidate_id: 0,
 373                score: 0.23809523809523808,
 374                positions: vec![],
 375                string: "unreachable_unchecked".to_string(),
 376            },
 377            is_snippet: true,
 378            sort_text: Some("80000000"),
 379            sort_key: (3, "unreachable_unchecked"),
 380        },
 381    ];
 382    CompletionsMenu::sort_matches(&mut matches, query);
 383    assert_eq!(
 384        matches[0].string_match.string.as_str(),
 385        "unreachable!(…)",
 386        "Match order not expected"
 387    );
 388
 389    // Case 3: "unreach"
 390    let query: Option<&str> = Some("unreach");
 391    let mut matches: Vec<SortableMatch<'_>> = vec![
 392        SortableMatch {
 393            string_match: StringMatch {
 394                candidate_id: 0,
 395                score: 0.6363636363636364,
 396                positions: vec![],
 397                string: "unreachable".to_string(),
 398            },
 399            is_snippet: false,
 400            sort_text: Some("80000000"),
 401            sort_key: (2, "unreachable"),
 402        },
 403        SortableMatch {
 404            string_match: StringMatch {
 405                candidate_id: 0,
 406                score: 0.4666666666666667,
 407                positions: vec![],
 408                string: "unreachable!(…)".to_string(),
 409            },
 410            is_snippet: true,
 411            sort_text: Some("7fffffff"),
 412            sort_key: (2, "unreachable!(…)"),
 413        },
 414        SortableMatch {
 415            string_match: StringMatch {
 416                candidate_id: 0,
 417                score: 0.3333333333333333,
 418                positions: vec![],
 419                string: "unreachable_unchecked".to_string(),
 420            },
 421            is_snippet: false,
 422            sort_text: Some("80000000"),
 423            sort_key: (2, "unreachable_unchecked"),
 424        },
 425    ];
 426    CompletionsMenu::sort_matches(&mut matches, query);
 427    assert_eq!(
 428        matches[0].string_match.string.as_str(),
 429        "unreachable!(…)",
 430        "Match order not expected"
 431    );
 432
 433    // Case 4: "unreachable"
 434    let query: Option<&str> = Some("unreachable");
 435    let mut matches: Vec<SortableMatch<'_>> = vec![
 436        SortableMatch {
 437            string_match: StringMatch {
 438                candidate_id: 0,
 439                score: 1.0,
 440                positions: vec![],
 441                string: "unreachable".to_string(),
 442            },
 443            is_snippet: false,
 444            sort_text: Some("80000000"),
 445            sort_key: (2, "unreachable"),
 446        },
 447        SortableMatch {
 448            string_match: StringMatch {
 449                candidate_id: 0,
 450                score: 0.7333333333333333,
 451                positions: vec![],
 452                string: "unreachable!(…)".to_string(),
 453            },
 454            is_snippet: false,
 455            sort_text: Some("7fffffff"),
 456            sort_key: (2, "unreachable!(…)"),
 457        },
 458        SortableMatch {
 459            string_match: StringMatch {
 460                candidate_id: 0,
 461                score: 0.5238095238095237,
 462                positions: vec![],
 463                string: "unreachable_unchecked".to_string(),
 464            },
 465            is_snippet: false,
 466            sort_text: Some("80000000"),
 467            sort_key: (2, "unreachable_unchecked"),
 468        },
 469    ];
 470    CompletionsMenu::sort_matches(&mut matches, query);
 471    assert_eq!(
 472        matches[0].string_match.string.as_str(),
 473        "unreachable!(…)",
 474        "Match order not expected"
 475    );
 476}
 477
 478#[gpui::test]
 479fn test_sort_matches_variable_and_constants_over_function(_cx: &mut TestAppContext) {
 480    // Case 1: "var" as variable
 481    let query: Option<&str> = Some("var");
 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: "var".to_string(),
 489            },
 490            is_snippet: false,
 491            sort_text: Some("7fffffff"),
 492            sort_key: (3, "var"), // function
 493        },
 494        SortableMatch {
 495            string_match: StringMatch {
 496                candidate_id: 1,
 497                score: 1.0,
 498                positions: vec![],
 499                string: "var".to_string(),
 500            },
 501            is_snippet: false,
 502            sort_text: Some("7fffffff"),
 503            sort_key: (1, "var"), // variable
 504        },
 505    ];
 506    CompletionsMenu::sort_matches(&mut matches, query);
 507    assert_eq!(
 508        matches[0].string_match.candidate_id, 1,
 509        "Match order not expected"
 510    );
 511    assert_eq!(
 512        matches[1].string_match.candidate_id, 0,
 513        "Match order not expected"
 514    );
 515
 516    // Case 2:  "var" as constant
 517    let query: Option<&str> = Some("var");
 518    let mut matches: Vec<SortableMatch<'_>> = vec![
 519        SortableMatch {
 520            string_match: StringMatch {
 521                candidate_id: 0,
 522                score: 1.0,
 523                positions: vec![],
 524                string: "var".to_string(),
 525            },
 526            is_snippet: false,
 527            sort_text: Some("7fffffff"),
 528            sort_key: (3, "var"), // function
 529        },
 530        SortableMatch {
 531            string_match: StringMatch {
 532                candidate_id: 1,
 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: (2, "var"), // constant
 540        },
 541    ];
 542    CompletionsMenu::sort_matches(&mut matches, query);
 543    assert_eq!(
 544        matches[0].string_match.candidate_id, 1,
 545        "Match order not expected"
 546    );
 547    assert_eq!(
 548        matches[1].string_match.candidate_id, 0,
 549        "Match order not expected"
 550    );
 551}
 552
 553#[gpui::test]
 554fn test_sort_matches_jsx_event_handler(_cx: &mut TestAppContext) {
 555    // Case 1: "on"
 556    let query: Option<&str> = Some("on");
 557    let mut matches: Vec<SortableMatch<'_>> = vec![
 558        SortableMatch {
 559            string_match: StringMatch {
 560                candidate_id: 0,
 561                score: 0.3333333333333333,
 562                positions: vec![],
 563                string: "onCut?".to_string(),
 564            },
 565            is_snippet: false,
 566            sort_text: Some("12"),
 567            sort_key: (3, "onCut?"),
 568        },
 569        SortableMatch {
 570            string_match: StringMatch {
 571                candidate_id: 0,
 572                score: 0.2857142857142857,
 573                positions: vec![],
 574                string: "onPlay?".to_string(),
 575            },
 576            is_snippet: false,
 577            sort_text: Some("12"),
 578            sort_key: (3, "onPlay?"),
 579        },
 580        SortableMatch {
 581            string_match: StringMatch {
 582                candidate_id: 0,
 583                score: 0.25,
 584                positions: vec![],
 585                string: "color?".to_string(),
 586            },
 587            is_snippet: false,
 588            sort_text: Some("12"),
 589            sort_key: (3, "color?"),
 590        },
 591        SortableMatch {
 592            string_match: StringMatch {
 593                candidate_id: 0,
 594                score: 0.25,
 595                positions: vec![],
 596                string: "defaultValue?".to_string(),
 597            },
 598            is_snippet: false,
 599            sort_text: Some("12"),
 600            sort_key: (3, "defaultValue?"),
 601        },
 602        SortableMatch {
 603            string_match: StringMatch {
 604                candidate_id: 0,
 605                score: 0.25,
 606                positions: vec![],
 607                string: "style?".to_string(),
 608            },
 609            is_snippet: false,
 610            sort_text: Some("12"),
 611            sort_key: (3, "style?"),
 612        },
 613        SortableMatch {
 614            string_match: StringMatch {
 615                candidate_id: 0,
 616                score: 0.20,
 617                positions: vec![],
 618                string: "className?".to_string(),
 619            },
 620            is_snippet: false,
 621            sort_text: Some("12"),
 622            sort_key: (3, "className?"),
 623        },
 624    ];
 625    CompletionsMenu::sort_matches(&mut matches, query);
 626    assert_eq!(
 627        matches[0].string_match.string, "onCut?",
 628        "Match order not expected"
 629    );
 630    assert_eq!(
 631        matches[1].string_match.string, "onPlay?",
 632        "Match order not expected"
 633    );
 634
 635    // Case 2: "ona"
 636    let query: Option<&str> = Some("ona");
 637    let mut matches: Vec<SortableMatch<'_>> = vec![
 638        SortableMatch {
 639            string_match: StringMatch {
 640                candidate_id: 0,
 641                score: 0.375,
 642                positions: vec![],
 643                string: "onAbort?".to_string(),
 644            },
 645            is_snippet: false,
 646            sort_text: Some("12"),
 647            sort_key: (3, "onAbort?"),
 648        },
 649        SortableMatch {
 650            string_match: StringMatch {
 651                candidate_id: 0,
 652                score: 0.2727272727272727,
 653                positions: vec![],
 654                string: "onAuxClick?".to_string(),
 655            },
 656            is_snippet: false,
 657            sort_text: Some("12"),
 658            sort_key: (3, "onAuxClick?"),
 659        },
 660        SortableMatch {
 661            string_match: StringMatch {
 662                candidate_id: 0,
 663                score: 0.23571428571428565,
 664                positions: vec![],
 665                string: "onPlay?".to_string(),
 666            },
 667            is_snippet: false,
 668            sort_text: Some("12"),
 669            sort_key: (3, "onPlay?"),
 670        },
 671        SortableMatch {
 672            string_match: StringMatch {
 673                candidate_id: 0,
 674                score: 0.23571428571428565,
 675                positions: vec![],
 676                string: "onLoad?".to_string(),
 677            },
 678            is_snippet: false,
 679            sort_text: Some("12"),
 680            sort_key: (3, "onLoad?"),
 681        },
 682        SortableMatch {
 683            string_match: StringMatch {
 684                candidate_id: 0,
 685                score: 0.23571428571428565,
 686                positions: vec![],
 687                string: "onDrag?".to_string(),
 688            },
 689            is_snippet: false,
 690            sort_text: Some("12"),
 691            sort_key: (3, "onDrag?"),
 692        },
 693        SortableMatch {
 694            string_match: StringMatch {
 695                candidate_id: 0,
 696                score: 0.22499999999999998,
 697                positions: vec![],
 698                string: "onPause?".to_string(),
 699            },
 700            is_snippet: false,
 701            sort_text: Some("12"),
 702            sort_key: (3, "onPause?"),
 703        },
 704        SortableMatch {
 705            string_match: StringMatch {
 706                candidate_id: 0,
 707                score: 0.22499999999999998,
 708                positions: vec![],
 709                string: "onPaste?".to_string(),
 710            },
 711            is_snippet: false,
 712            sort_text: Some("12"),
 713            sort_key: (3, "onPaste?"),
 714        },
 715        SortableMatch {
 716            string_match: StringMatch {
 717                candidate_id: 0,
 718                score: 0.2,
 719                positions: vec![],
 720                string: "onAnimationEnd?".to_string(),
 721            },
 722            is_snippet: false,
 723            sort_text: Some("12"),
 724            sort_key: (3, "onAnimationEnd?"),
 725        },
 726        SortableMatch {
 727            string_match: StringMatch {
 728                candidate_id: 0,
 729                score: 0.2,
 730                positions: vec![],
 731                string: "onAbortCapture?".to_string(),
 732            },
 733            is_snippet: false,
 734            sort_text: Some("12"),
 735            sort_key: (3, "onAbortCapture?"),
 736        },
 737        SortableMatch {
 738            string_match: StringMatch {
 739                candidate_id: 0,
 740                score: 0.1833333333333333,
 741                positions: vec![],
 742                string: "onChange?".to_string(),
 743            },
 744            is_snippet: false,
 745            sort_text: Some("12"),
 746            sort_key: (3, "onChange?"),
 747        },
 748        SortableMatch {
 749            string_match: StringMatch {
 750                candidate_id: 0,
 751                score: 0.18,
 752                positions: vec![],
 753                string: "onWaiting?".to_string(),
 754            },
 755            is_snippet: false,
 756            sort_text: Some("12"),
 757            sort_key: (3, "onWaiting?"),
 758        },
 759        SortableMatch {
 760            string_match: StringMatch {
 761                candidate_id: 0,
 762                score: 0.18,
 763                positions: vec![],
 764                string: "onCanPlay?".to_string(),
 765            },
 766            is_snippet: false,
 767            sort_text: Some("12"),
 768            sort_key: (3, "onCanPlay?"),
 769        },
 770        SortableMatch {
 771            string_match: StringMatch {
 772                candidate_id: 0,
 773                score: 0.1764705882352941,
 774                positions: vec![],
 775                string: "onAnimationStart?".to_string(),
 776            },
 777            is_snippet: false,
 778            sort_text: Some("12"),
 779            sort_key: (3, "onAnimationStart?"),
 780        },
 781        SortableMatch {
 782            string_match: StringMatch {
 783                candidate_id: 0,
 784                score: 0.16666666666666666,
 785                positions: vec![],
 786                string: "onAuxClickCapture?".to_string(),
 787            },
 788            is_snippet: false,
 789            sort_text: Some("12"),
 790            sort_key: (3, "onAuxClickCapture?"),
 791        },
 792        SortableMatch {
 793            string_match: StringMatch {
 794                candidate_id: 0,
 795                score: 0.16499999999999998,
 796                positions: vec![],
 797                string: "onStalled?".to_string(),
 798            },
 799            is_snippet: false,
 800            sort_text: Some("12"),
 801            sort_key: (3, "onStalled?"),
 802        },
 803        SortableMatch {
 804            string_match: StringMatch {
 805                candidate_id: 0,
 806                score: 0.16499999999999998,
 807                positions: vec![],
 808                string: "onPlaying?".to_string(),
 809            },
 810            is_snippet: false,
 811            sort_text: Some("12"),
 812            sort_key: (3, "onPlaying?"),
 813        },
 814        SortableMatch {
 815            string_match: StringMatch {
 816                candidate_id: 0,
 817                score: 0.16499999999999998,
 818                positions: vec![],
 819                string: "onDragEnd?".to_string(),
 820            },
 821            is_snippet: false,
 822            sort_text: Some("12"),
 823            sort_key: (3, "onDragEnd?"),
 824        },
 825        SortableMatch {
 826            string_match: StringMatch {
 827                candidate_id: 0,
 828                score: 0.15000000000000002,
 829                positions: vec![],
 830                string: "onInvalid?".to_string(),
 831            },
 832            is_snippet: false,
 833            sort_text: Some("12"),
 834            sort_key: (3, "onInvalid?"),
 835        },
 836        SortableMatch {
 837            string_match: StringMatch {
 838                candidate_id: 0,
 839                score: 0.15,
 840                positions: vec![],
 841                string: "onDragOver?".to_string(),
 842            },
 843            is_snippet: false,
 844            sort_text: Some("12"),
 845            sort_key: (3, "onDragOver?"),
 846        },
 847        SortableMatch {
 848            string_match: StringMatch {
 849                candidate_id: 0,
 850                score: 0.15,
 851                positions: vec![],
 852                string: "onDragExit?".to_string(),
 853            },
 854            is_snippet: false,
 855            sort_text: Some("12"),
 856            sort_key: (3, "onDragExit?"),
 857        },
 858        SortableMatch {
 859            string_match: StringMatch {
 860                candidate_id: 0,
 861                score: 0.14285714285714285,
 862                positions: vec![],
 863                string: "onAnimationIteration?".to_string(),
 864            },
 865            is_snippet: false,
 866            sort_text: Some("12"),
 867            sort_key: (3, "onAnimationIteration?"),
 868        },
 869        SortableMatch {
 870            string_match: StringMatch {
 871                candidate_id: 0,
 872                score: 0.13846153846153847,
 873                positions: vec![],
 874                string: "onRateChange?".to_string(),
 875            },
 876            is_snippet: false,
 877            sort_text: Some("12"),
 878            sort_key: (3, "onRateChange?"),
 879        },
 880        SortableMatch {
 881            string_match: StringMatch {
 882                candidate_id: 0,
 883                score: 0.13749999999999996,
 884                positions: vec![],
 885                string: "onLoadStart?".to_string(),
 886            },
 887            is_snippet: false,
 888            sort_text: Some("12"),
 889            sort_key: (3, "onLoadStart?"),
 890        },
 891        SortableMatch {
 892            string_match: StringMatch {
 893                candidate_id: 0,
 894                score: 0.13749999999999996,
 895                positions: vec![],
 896                string: "onDragStart?".to_string(),
 897            },
 898            is_snippet: false,
 899            sort_text: Some("12"),
 900            sort_key: (3, "onDragStart?"),
 901        },
 902        SortableMatch {
 903            string_match: StringMatch {
 904                candidate_id: 0,
 905                score: 0.13749999999999996,
 906                positions: vec![],
 907                string: "onDragLeave?".to_string(),
 908            },
 909            is_snippet: false,
 910            sort_text: Some("12"),
 911            sort_key: (3, "onDragLeave?"),
 912        },
 913        SortableMatch {
 914            string_match: StringMatch {
 915                candidate_id: 0,
 916                score: 0.13749999999999996,
 917                positions: vec![],
 918                string: "onDragEnter?".to_string(),
 919            },
 920            is_snippet: false,
 921            sort_text: Some("12"),
 922            sort_key: (3, "onDragEnter?"),
 923        },
 924        SortableMatch {
 925            string_match: StringMatch {
 926                candidate_id: 0,
 927                score: 0.13636363636363635,
 928                positions: vec![],
 929                string: "onAnimationEndCapture?".to_string(),
 930            },
 931            is_snippet: false,
 932            sort_text: Some("12"),
 933            sort_key: (3, "onAnimationEndCapture?"),
 934        },
 935        SortableMatch {
 936            string_match: StringMatch {
 937                candidate_id: 0,
 938                score: 0.12692307692307692,
 939                positions: vec![],
 940                string: "onLoadedData?".to_string(),
 941            },
 942            is_snippet: false,
 943            sort_text: Some("12"),
 944            sort_key: (3, "onLoadedData?"),
 945        },
 946    ];
 947    CompletionsMenu::sort_matches(&mut matches, query);
 948    assert_eq!(
 949        matches
 950            .iter()
 951            .take(12)
 952            .map(|m| m.string_match.string.as_str())
 953            .collect::<Vec<&str>>(),
 954        vec![
 955            "onAbort?",
 956            "onAbortCapture?",
 957            "onAnimationEnd?",
 958            "onAnimationEndCapture?",
 959            "onAnimationIteration?",
 960            "onAnimationStart?",
 961            "onAuxClick?",
 962            "onAuxClickCapture?",
 963            "onCanPlay?",
 964            "onChange?",
 965            "onDrag?",
 966            "onDragEnd?",
 967        ]
 968    );
 969}
 970
 971#[gpui::test]
 972fn test_sort_matches_for_snippets(_cx: &mut TestAppContext) {
 973    // Case 1: "prin"
 974    let query: Option<&str> = Some("prin");
 975    let mut matches: Vec<SortableMatch<'_>> = vec![
 976        SortableMatch {
 977            string_match: StringMatch {
 978                candidate_id: 0,
 979                score: 0.2,
 980                positions: vec![],
 981                string: "println".to_string(),
 982            },
 983            is_snippet: false,
 984            sort_text: Some("80000000"),
 985            sort_key: (2, "unreachable"),
 986        },
 987        SortableMatch {
 988            string_match: StringMatch {
 989                candidate_id: 0,
 990                score: 0.2,
 991                positions: vec![],
 992                string: "println!(…)".to_string(),
 993            },
 994            is_snippet: true,
 995            sort_text: Some("80000000"),
 996            sort_key: (2, "println!(…)"),
 997        },
 998    ];
 999    CompletionsMenu::sort_matches(&mut matches, query);
1000    assert_eq!(
1001        matches[0].string_match.string.as_str(),
1002        "println!(…)",
1003        "Match order not expected"
1004    );
1005}