1365 lines · 37.0 KB · Rust
RawDownload
use super::*;use crate::{LanguageConfig, LanguageMatcher};use gpui::AppContext;use rand::rngs::StdRng;use std::{env, ops::Range, sync::Arc};use text::{Buffer, BufferId};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.clone(), &[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 AppContext) {    let registry = Arc::new(LanguageRegistry::test(cx.background_executor().clone()));    let language = Arc::new(rust_lang());    registry.add(language.clone());     let mut buffer = Buffer::new(        0,        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();    syntax_map.set_language_registry(registry.clone());    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.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 (macro_invocation...",            "...(array_expression (struct_expression ...",        ],    );} #[gpui::test]fn test_dynamic_language_injection(cx: &mut AppContext) {    let registry = Arc::new(LanguageRegistry::test(cx.background_executor().clone()));    let markdown = Arc::new(markdown_lang());    registry.add(markdown.clone());    registry.add(Arc::new(rust_lang()));    registry.add(Arc::new(ruby_lang()));     let mut buffer = Buffer::new(        0,        BufferId::new(1).unwrap(),        r#"            This is a code block:             ```rs            fn foo() {}            ```        "#        .unindent(),    );     let mut syntax_map = SyntaxMap::new();    syntax_map.set_language_registry(registry.clone());    syntax_map.reparse(markdown.clone(), &buffer);    assert_layers_for_range(            &syntax_map,            &buffer,            Point::new(3, 0)..Point::new(3, 0),            &[                "...(fenced_code_block (fenced_code_block_delimiter) (info_string (language)) (code_fence_content) (fenced_code_block_delimiter...",                "...(function_item name: (identifier) parameters: (parameters) body: (block)...",            ],        );     // Replace Rust with Ruby in code block.    let macro_name_range = range_for_text(&buffer, "rs");    buffer.edit([(macro_name_range, "ruby")]);    syntax_map.interpolate(&buffer);    syntax_map.reparse(markdown.clone(), &buffer);    assert_layers_for_range(            &syntax_map,            &buffer,            Point::new(3, 0)..Point::new(3, 0),            &[                "...(fenced_code_block (fenced_code_block_delimiter) (info_string (language)) (code_fence_content) (fenced_code_block_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, "ruby");    buffer.edit([(macro_name_range, "html")]);    syntax_map.interpolate(&buffer);    syntax_map.reparse(markdown.clone(), &buffer);    assert_layers_for_range(            &syntax_map,            &buffer,            Point::new(3, 0)..Point::new(3, 0),            &[                "...(fenced_code_block (fenced_code_block_delimiter) (info_string (language)) (code_fence_content) (fenced_code_block_delimiter..."            ],        );    assert!(syntax_map.contains_unknown_injections());     registry.add(Arc::new(html_lang()));    syntax_map.reparse(markdown.clone(), &buffer);    assert_layers_for_range(            &syntax_map,            &buffer,            Point::new(3, 0)..Point::new(3, 0),            &[                "...(fenced_code_block (fenced_code_block_delimiter) (info_string (language)) (code_fence_content) (fenced_code_block_delimiter...",                "(fragment (text))",            ],        );    assert!(!syntax_map.contains_unknown_injections());} #[gpui::test]fn test_typing_multiple_new_injections(cx: &mut AppContext) {    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,        &["field"],        "fn a() { test_macro!(b.«c»(vec![d.«e»])) }",    );} #[gpui::test]fn test_pasting_new_injection_line_between_others(cx: &mut AppContext) {    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,        &["struct"],        "        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 AppContext) {    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],                    ˇ    f![seven.eight],                    );                }            ",        ],        cx,    );     assert_capture_ranges(        &syntax_map,        &buffer,        &["field"],        "        fn a() {            b!(                c![one.«two».«three»],                d![four.«five».«six»],                f![seven.«eight»],            );        }        ",    );} #[gpui::test]fn test_editing_edges_of_injection(cx: &mut AppContext) {    test_edit_sequence(        "Rust",        &[            "                fn a() {                    b!(c!())                }            ",            "                fn a() {                    «d»!(c!())                }            ",            "                fn a() {                    «e»d!(c!())                }            ",            "                fn a() {                    ed!«[»c!()«]»                }            ",        ],        cx,    );} #[gpui::test]fn test_edits_preceding_and_intersecting_injection(cx: &mut AppContext) {    test_edit_sequence(        "Rust",        &[            //            "const aaaaaaaaaaaa: B = c!(d(e.f));",            "const aˇa: B = c!(d(eˇ));",        ],        cx,    );} #[gpui::test]fn test_non_local_changes_create_injections(cx: &mut AppContext) {    test_edit_sequence(        "Rust",        &[            "                // a! {                    static B: C = d;                // }            ",            "                ˇa! {                    static B: C = d;                ˇ}            ",        ],        cx,    );} #[gpui::test]fn test_creating_many_injections_in_one_edit(cx: &mut AppContext) {    test_edit_sequence(        "Rust",        &[            "                fn a() {                    one(Two::three(3));                    four(Five::six(6));                    seven(Eight::nine(9));                }            ",            "                fn a() {                    one«!»(Two::three(3));                    four«!»(Five::six(6));                    seven«!»(Eight::nine(9));                }            ",            "                fn a() {                    one!(Two::three«!»(3));                    four!(Five::six«!»(6));                    seven!(Eight::nine«!»(9));                }            ",        ],        cx,    );} #[gpui::test]fn test_editing_across_injection_boundary(cx: &mut AppContext) {    test_edit_sequence(        "Rust",        &[            "                fn one() {                    two();                    three!(                        three.four,                        five.six,                    );                }            ",            "                fn one() {                    two();                    th«irty_five![»                        three.four,                        five.six,                    «   seven.eight,                    ];»                }            ",        ],        cx,    );

Lines 1–500 of 1365.