1642 lines · 46.3 KB · Rust
RawDownload
use super::*;use crate::{    LanguageConfig, LanguageMatcher, LanguageQueries, buffer_tests::markdown_inline_lang,    markdown_lang, rust_lang,};use gpui::App;use pretty_assertions::assert_eq;use rand::rngs::StdRng;use std::borrow::Cow;use std::{env, ops::Range, sync::Arc};use text::{Buffer, BufferId, ReplicaId};use tree_sitter::Node;use unindent::Unindent as _;use util::test::marked_text_ranges; #[test]fn test_splice_included_ranges() {    let ranges = vec![ts_range(20..30), ts_range(50..60), ts_range(80..90)];     let (new_ranges, change) = splice_included_ranges(        ranges.clone(),        &[54..56, 58..68],        &[ts_range(50..54), ts_range(59..67)],    );    assert_eq!(        new_ranges,        &[            ts_range(20..30),            ts_range(50..54),            ts_range(59..67),            ts_range(80..90),        ]    );    assert_eq!(change, 1..3);     let (new_ranges, change) = splice_included_ranges(ranges.clone(), &[70..71, 91..100], &[]);    assert_eq!(        new_ranges,        &[ts_range(20..30), ts_range(50..60), ts_range(80..90)]    );    assert_eq!(change, 2..3);     let (new_ranges, change) =        splice_included_ranges(ranges.clone(), &[], &[ts_range(0..2), ts_range(70..75)]);    assert_eq!(        new_ranges,        &[            ts_range(0..2),            ts_range(20..30),            ts_range(50..60),            ts_range(70..75),            ts_range(80..90)        ]    );    assert_eq!(change, 0..4);     let (new_ranges, change) =        splice_included_ranges(ranges.clone(), &[30..50], &[ts_range(25..55)]);    assert_eq!(new_ranges, &[ts_range(25..55), ts_range(80..90)]);    assert_eq!(change, 0..1);     // does not create overlapping ranges    let (new_ranges, change) = splice_included_ranges(ranges, &[0..18], &[ts_range(20..32)]);    assert_eq!(        new_ranges,        &[ts_range(20..32), ts_range(50..60), ts_range(80..90)]    );    assert_eq!(change, 0..1);     fn ts_range(range: Range<usize>) -> tree_sitter::Range {        tree_sitter::Range {            start_byte: range.start,            start_point: tree_sitter::Point {                row: 0,                column: range.start,            },            end_byte: range.end,            end_point: tree_sitter::Point {                row: 0,                column: range.end,            },        }    }} #[gpui::test]fn test_syntax_map_layers_for_range(cx: &mut App) {    let registry = Arc::new(LanguageRegistry::test(cx.background_executor().clone()));    let language = rust_lang();    registry.add(language.clone());     let mut buffer = Buffer::new(        ReplicaId::LOCAL,        BufferId::new(1).unwrap(),        r#"            fn a() {                assert_eq!(                    b(vec![C {}]),                    vec![d.e],                );                println!("{}", f(|_| true));            }        "#        .unindent(),    );     let mut syntax_map = SyntaxMap::new(&buffer);    syntax_map.set_language_registry(registry);    syntax_map.reparse(language.clone(), &buffer);     assert_layers_for_range(        &syntax_map,        &buffer,        Point::new(2, 0)..Point::new(2, 0),        &[            "...(function_item ... (block (expression_statement (macro_invocation...",            "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...",        ],    );    assert_layers_for_range(        &syntax_map,        &buffer,        Point::new(2, 14)..Point::new(2, 16),        &[            "...(function_item ...",            "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...",            "...(array_expression (struct_expression ...",        ],    );    assert_layers_for_range(        &syntax_map,        &buffer,        Point::new(3, 14)..Point::new(3, 16),        &[            "...(function_item ...",            "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...",            "...(array_expression (field_expression ...",        ],    );    assert_layers_for_range(        &syntax_map,        &buffer,        Point::new(5, 12)..Point::new(5, 16),        &[            "...(function_item ...",            "...(call_expression ... (arguments (closure_expression ...",        ],    );     // Replace a vec! macro invocation with a plain slice, removing a syntactic layer.    let macro_name_range = range_for_text(&buffer, "vec!");    buffer.edit([(macro_name_range, "&")]);    syntax_map.interpolate(&buffer);    syntax_map.reparse(language.clone(), &buffer);     assert_layers_for_range(        &syntax_map,        &buffer,        Point::new(2, 14)..Point::new(2, 16),        &[            "...(function_item ...",            "...(tuple_expression (call_expression ... arguments: (arguments (reference_expression value: (array_expression...",        ],    );     // Put the vec! macro back, adding back the syntactic layer.    buffer.undo();    syntax_map.interpolate(&buffer);    syntax_map.reparse(language, &buffer);     assert_layers_for_range(        &syntax_map,        &buffer,        Point::new(2, 14)..Point::new(2, 16),        &[            "...(function_item ...",            "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...",            "...(array_expression (struct_expression ...",        ],    );} #[gpui::test]fn test_syntax_map_languages_match_layers_for_range(cx: &mut App) {    let registry = Arc::new(LanguageRegistry::test(cx.background_executor().clone()));    let markdown = markdown_lang();    let markdown_inline = Arc::new(markdown_inline_lang());    registry.add(markdown.clone());    registry.add(markdown_inline);    registry.add(rust_lang());     let buffer = Buffer::new(        ReplicaId::LOCAL,        BufferId::new(1).unwrap(),        r#"            This is `inline`.             ```rs            fn a() {}            ```        "#        .unindent(),    );     let mut syntax_map = SyntaxMap::new(&buffer);    syntax_map.set_language_registry(registry);    syntax_map.reparse(markdown, &buffer);     let all_language_names = syntax_map        .languages(&buffer, true)        .map(|language| language.name().to_string())        .collect::<Vec<_>>();    let all_layer_language_names = syntax_map        .layers_for_range(0..buffer.len(), &buffer, true)        .map(|layer| layer.language.name().to_string())        .collect::<Vec<_>>();     assert_eq!(all_language_names, all_layer_language_names);    assert!(        all_language_names            .iter()            .any(|language_name| language_name == "Markdown-Inline"),        "expected hidden languages to be included when include_hidden is true"    );    assert!(        all_language_names            .iter()            .any(|language_name| language_name == "Markdown")    );    assert!(        all_language_names            .iter()            .any(|language_name| language_name == "Rust")    );     let visible_language_names = syntax_map        .languages(&buffer, false)        .map(|language| language.name().to_string())        .collect::<Vec<_>>();    let visible_layer_language_names = syntax_map        .layers_for_range(0..buffer.len(), &buffer, false)        .map(|layer| layer.language.name().to_string())        .collect::<Vec<_>>();     assert_eq!(visible_language_names, visible_layer_language_names);    assert!(        !visible_language_names            .iter()            .any(|language_name| language_name == "Markdown-Inline"),        "expected hidden languages to be excluded when include_hidden is false"    );    assert!(        visible_language_names            .iter()            .any(|language_name| language_name == "Markdown")    );    assert!(        visible_language_names            .iter()            .any(|language_name| language_name == "Rust")    );} #[gpui::test]fn test_dynamic_language_injection(cx: &mut App) {    let registry = Arc::new(LanguageRegistry::test(cx.background_executor().clone()));    let markdown = markdown_lang();    let markdown_inline = Arc::new(markdown_inline_lang());    registry.add(markdown.clone());    registry.add(markdown_inline.clone());    registry.add(rust_lang());    registry.add(Arc::new(ruby_lang()));     let mut buffer = Buffer::new(        ReplicaId::LOCAL,        BufferId::new(1).unwrap(),        r#"            This is a code block:             ```rs            fn foo() {}            ```        "#        .unindent(),    );     let mut syntax_map = SyntaxMap::new(&buffer);    syntax_map.set_language_registry(registry.clone());    syntax_map.reparse(markdown.clone(), &buffer);    syntax_map.reparse(markdown_inline.clone(), &buffer);    assert_layers_for_range(        &syntax_map,        &buffer,        Point::new(3, 0)..Point::new(3, 0),        &[            "(document (section (paragraph (inline)) (fenced_code_block (fenced_code_block_delimiter) (info_string (language)) (block_continuation) (code_fence_content (block_continuation)) (fenced_code_block_delimiter))))",            "(inline (code_span (code_span_delimiter) (code_span_delimiter)))",            "...(function_item name: (identifier) parameters: (parameters) body: (block)...",        ],    );     // Replace `rs` with a path to ending in `.rb` in code block.    let macro_name_range = range_for_text(&buffer, "rs");    buffer.edit([(macro_name_range, "foo/bar/baz.rb")]);    syntax_map.interpolate(&buffer);    syntax_map.reparse(markdown.clone(), &buffer);    syntax_map.reparse(markdown_inline.clone(), &buffer);    assert_layers_for_range(        &syntax_map,        &buffer,        Point::new(3, 0)..Point::new(3, 0),        &[            "(document (section (paragraph (inline)) (fenced_code_block (fenced_code_block_delimiter) (info_string (language)) (block_continuation) (code_fence_content (block_continuation)) (fenced_code_block_delimiter))))",            "(inline (code_span (code_span_delimiter) (code_span_delimiter)))",            "...(call method: (identifier) arguments: (argument_list (call method: (identifier) arguments: (argument_list) block: (block)...",        ],    );     // Replace Ruby with a language that hasn't been loaded yet.    let macro_name_range = range_for_text(&buffer, "foo/bar/baz.rb");    buffer.edit([(macro_name_range, "html")]);    syntax_map.interpolate(&buffer);    syntax_map.reparse(markdown.clone(), &buffer);    syntax_map.reparse(markdown_inline.clone(), &buffer);    assert_layers_for_range(        &syntax_map,        &buffer,        Point::new(3, 0)..Point::new(3, 0),        &[            "(document (section (paragraph (inline)) (fenced_code_block (fenced_code_block_delimiter) (info_string (language)) (block_continuation) (code_fence_content (block_continuation)) (fenced_code_block_delimiter))))",            "(inline (code_span (code_span_delimiter) (code_span_delimiter)))",        ],    );    assert!(syntax_map.contains_unknown_injections());     registry.add(Arc::new(html_lang()));    syntax_map.reparse(markdown, &buffer);    syntax_map.reparse(markdown_inline, &buffer);    assert_layers_for_range(        &syntax_map,        &buffer,        Point::new(3, 0)..Point::new(3, 0),        &[            "(document (section (paragraph (inline)) (fenced_code_block (fenced_code_block_delimiter) (info_string (language)) (block_continuation) (code_fence_content (block_continuation)) (fenced_code_block_delimiter))))",            "(inline (code_span (code_span_delimiter) (code_span_delimiter)))",            "(document (text))",        ],    );    assert!(!syntax_map.contains_unknown_injections());} #[gpui::test]fn test_rust_json_macro_empty_string_highlighting(cx: &mut App) {    let registry = Arc::new(LanguageRegistry::test(cx.background_executor().clone()));    let language = rust_lang();    registry.add(language.clone());     let buffer = Buffer::new(        ReplicaId::LOCAL,        BufferId::new(1).unwrap(),        r#"            serde_json::json!({                "email": "",                "password": "password123",                "requires2FA": false            })        "#        .unindent(),    );     let mut syntax_map = SyntaxMap::new(&buffer);    syntax_map.set_language_registry(registry);    syntax_map.reparse(language, &buffer);     assert_capture_ranges(        &syntax_map,        &buffer,        &["string"],        r#"            serde_json::json!({                «"email"»: «""»,                «"password"»: «"password123"»,                «"requires2FA"»: false            })        "#,    );     assert_capture_ranges(        &syntax_map,        &buffer,        &["boolean"],        r#"            serde_json::json!({                "email": "",                "password": "password123",                "requires2FA": «false»            })        "#,    );} #[gpui::test]fn test_typing_multiple_new_injections(cx: &mut App) {    let (buffer, syntax_map) = test_edit_sequence(        "Rust",        &[            "fn a() { test_macro }",            "fn a() { test_macro«!» }",            "fn a() { test_macro!«()» }",            "fn a() { test_macro!(«b») }",            "fn a() { test_macro!(b«.») }",            "fn a() { test_macro!(b.«c») }",            "fn a() { test_macro!(b.c«()») }",            "fn a() { test_macro!(b.c(«vec»)) }",            "fn a() { test_macro!(b.c(vec«!»)) }",            "fn a() { test_macro!(b.c(vec!«[]»)) }",            "fn a() { test_macro!(b.c(vec![«d»])) }",            "fn a() { test_macro!(b.c(vec![d«.»])) }",            "fn a() { test_macro!(b.c(vec![d.«e»])) }",        ],        cx,    );     assert_capture_ranges(        &syntax_map,        &buffer,        &["property"],        "fn a() { test_macro!(b.«c»(vec![d.«e»])) }",    );} #[gpui::test]fn test_pasting_new_injection_line_between_others(cx: &mut App) {    let (buffer, syntax_map) = test_edit_sequence(        "Rust",        &[            "                fn a() {                    b!(B {});                    c!(C {});                    d!(D {});                    e!(E {});                    f!(F {});                    g!(G {});                }            ",            "                fn a() {                    b!(B {});                    c!(C {});                    d!(D {});                «    h!(H {});                »    e!(E {});                    f!(F {});                    g!(G {});                }            ",        ],        cx,    );     assert_capture_ranges(        &syntax_map,        &buffer,        &["type"],        "        fn a() {            b!(«B» {});            c!(«C» {});            d!(«D» {});            h!(«H» {});            e!(«E» {});            f!(«F» {});            g!(«G» {});        }        ",    );} #[gpui::test]fn test_joining_injections_with_child_injections(cx: &mut App) {    let (buffer, syntax_map) = test_edit_sequence(        "Rust",        &[            "                fn a() {                    b!(                        c![one.two.three],                        d![four.five.six],                    );                    e!(                        f![seven.eight],                    );                }            ",            "                fn a() {                    b!(                        c![one.two.three],                        d![four.five.six],

Lines 1–500 of 1642.