1160 lines · 36.4 KB · Rust
RawDownload
use super::*;use crate::assemble_excerpts::assemble_excerpt_ranges;use futures::channel::mpsc::UnboundedReceiver;use gpui::TestAppContext;use indoc::indoc;use language::{Point, ToPoint as _, rust_lang};use lsp::FakeLanguageServer;use project::{FakeFs, LocationLink, Project, ProjectPath};use serde_json::json;use settings::SettingsStore;use std::fmt::Write as _;use util::rel_path::rel_path;use util::{path, test::marked_text_ranges}; #[gpui::test]async fn test_edit_prediction_context(cx: &mut TestAppContext) {    init_test(cx);    let fs = FakeFs::new(cx.executor());    fs.insert_tree(path!("/root"), test_project_1()).await;     let project = Project::test(fs.clone(), [path!("/root").as_ref()], cx).await;    let mut servers = setup_fake_lsp(&project, cx);     let (buffer, _handle) = project        .update(cx, |project, cx| {            project.open_local_buffer_with_lsp(path!("/root/src/main.rs"), cx)        })        .await        .unwrap();     let _server = servers.next().await.unwrap();    cx.run_until_parked();     let related_excerpt_store = cx.new(|cx| RelatedExcerptStore::new(&project, cx));    related_excerpt_store.update(cx, |store, cx| {        let position = {            let buffer = buffer.read(cx);            let offset = buffer.text().find("todo").unwrap();            buffer.anchor_before(offset)        };         store.set_identifier_line_count(0);        store.refresh(buffer.clone(), position, cx);    });     cx.executor().advance_clock(DEBOUNCE_DURATION);    related_excerpt_store.update(cx, |store, cx| {        let excerpts = store.related_files(cx);        assert_related_files(            &excerpts,            &[                (                    "root/src/person.rs",                    &[                        indoc! {"                        pub struct Person {                            first_name: String,                            last_name: String,                            email: String,                            age: u32,                        }                         impl Person {                            pub fn get_first_name(&self) -> &str {                                &self.first_name                            }"},                        "}",                    ],                ),                (                    "root/src/company.rs",                    &[indoc! {"                        pub struct Company {                            owner: Arc<Person>,                            address: Address,                        }"}],                ),                (                    "root/src/main.rs",                    &[                        indoc! {"                        pub struct Session {                            company: Arc<Company>,                        }                         impl Session {                            pub fn set_company(&mut self, company: Arc<Company>) {"},                        indoc! {"                            }                        }"},                    ],                ),            ],        );    });     let company_buffer = related_excerpt_store.update(cx, |store, cx| {        store            .related_files_with_buffers(cx)            .find(|(file, _)| file.path.to_str() == Some("root/src/company.rs"))            .map(|(_, buffer)| buffer)            .expect("company.rs buffer not found")    });     company_buffer.update(cx, |buffer, cx| {        let text = buffer.text();        let insert_pos = text.find("address: Address,").unwrap() + "address: Address,".len();        buffer.edit([(insert_pos..insert_pos, "\n    name: String,")], None, cx);    });     related_excerpt_store.update(cx, |store, cx| {        let excerpts = store.related_files(cx);        assert_related_files(            &excerpts,            &[                (                    "root/src/person.rs",                    &[                        indoc! {"                        pub struct Person {                            first_name: String,                            last_name: String,                            email: String,                            age: u32,                        }                         impl Person {                            pub fn get_first_name(&self) -> &str {                                &self.first_name                            }"},                        "}",                    ],                ),                (                    "root/src/company.rs",                    &[indoc! {"                        pub struct Company {                            owner: Arc<Person>,                            address: Address,                            name: String,                        }"}],                ),                (                    "root/src/main.rs",                    &[                        indoc! {"                        pub struct Session {                            company: Arc<Company>,                        }                         impl Session {                            pub fn set_company(&mut self, company: Arc<Company>) {"},                        indoc! {"                            }                        }"},                    ],                ),            ],        );    });} #[gpui::test]async fn test_assemble_excerpts(cx: &mut TestAppContext) {    let table = [        (            indoc! {r#"                struct User {                    first_name: String,                    «last_name»: String,                    age: u32,                    email: String,                    create_at: Instant,                }                 impl User {                    pub fn first_name(&self) -> String {                        self.first_name.clone()                    }                     pub fn full_name(&self) -> String {                «        format!("{} {}", self.first_name, self.last_name)                »    }                }            "#},            indoc! {r#"                struct User {                    first_name: String,                    last_name: String,                …                }                 impl User {                …                    pub fn full_name(&self) -> String {                        format!("{} {}", self.first_name, self.last_name)                    }                }            "#},        ),        (            indoc! {r#"                struct «User» {                    first_name: String,                    last_name: String,                    age: u32,                }                 impl User {                    // methods                }            "#},            indoc! {r#"                struct User {                    first_name: String,                    last_name: String,                    age: u32,                }                …            "#},        ),        (            indoc! {r#"                trait «FooProvider» {                    const NAME: &'static str;                     fn provide_foo(&self, id: usize) -> Foo;                     fn provide_foo_batched(&self, ids: &[usize]) -> Vec<Foo> {                            ids.iter()                            .map(|id| self.provide_foo(*id))                            .collect()                    }                     fn sync(&self);                }                "#            },            indoc! {r#"                trait FooProvider {                    const NAME: &'static str;                     fn provide_foo(&self, id: usize) -> Foo;                     fn provide_foo_batched(&self, ids: &[usize]) -> Vec<Foo> {                …                    }                     fn sync(&self);                }            "#},        ),        (            indoc! {r#"                trait «Something» {                    fn method1(&self, id: usize) -> Foo;                     fn method2(&self, ids: &[usize]) -> Vec<Foo> {                            struct Helper1 {                            field1: usize,                            }                             struct Helper2 {                            field2: usize,                            }                             struct Helper3 {                            filed2: usize,                        }                    }                     fn sync(&self);                }                "#            },            indoc! {r#"                trait Something {                    fn method1(&self, id: usize) -> Foo;                     fn method2(&self, ids: &[usize]) -> Vec<Foo> {                …                    }                     fn sync(&self);                }            "#},        ),    ];     for (input, expected_output) in table {        let (input, ranges) = marked_text_ranges(&input, false);        let buffer = cx.new(|cx| Buffer::local(input, cx).with_language(rust_lang(), cx));        buffer            .read_with(cx, |buffer, _| buffer.parsing_idle())            .await;        buffer.read_with(cx, |buffer, _cx| {            let ranges: Vec<(Range<Point>, usize)> = ranges                .into_iter()                .map(|range| (range.to_point(&buffer), 0))                .collect();             let assembled = assemble_excerpt_ranges(&buffer.snapshot(), ranges);            let excerpts: Vec<RelatedExcerpt> = assembled                .into_iter()                .map(|(row_range, order)| {                    let start = Point::new(row_range.start, 0);                    let end = Point::new(row_range.end, buffer.line_len(row_range.end));                    RelatedExcerpt {                        row_range,                        text: buffer.text_for_range(start..end).collect::<String>().into(),                        order,                        context_source: ContextSource::Lsp,                    }                })                .collect();             let output = format_excerpts(buffer, &excerpts);            assert_eq!(output, expected_output);        });    }} #[gpui::test]async fn test_fake_definition_lsp(cx: &mut TestAppContext) {    init_test(cx);     let fs = FakeFs::new(cx.executor());    fs.insert_tree(path!("/root"), test_project_1()).await;     let project = Project::test(fs.clone(), [path!("/root").as_ref()], cx).await;    let mut servers = setup_fake_lsp(&project, cx);     let (buffer, _handle) = project        .update(cx, |project, cx| {            project.open_local_buffer_with_lsp(path!("/root/src/main.rs"), cx)        })        .await        .unwrap();     let _server = servers.next().await.unwrap();    cx.run_until_parked();     let buffer_text = buffer.read_with(cx, |buffer, _| buffer.text());     let definitions = project        .update(cx, |project, cx| {            let offset = buffer_text.find("Address {").unwrap();            project.definitions(&buffer, offset, cx)        })        .await        .unwrap()        .unwrap();    assert_definitions(&definitions, &["pub struct Address {"], cx);     let definitions = project        .update(cx, |project, cx| {            let offset = buffer_text.find("State::CA").unwrap();            project.definitions(&buffer, offset, cx)        })        .await        .unwrap()        .unwrap();    assert_definitions(&definitions, &["pub enum State {"], cx);     let definitions = project        .update(cx, |project, cx| {            let offset = buffer_text.find("to_string()").unwrap();            project.definitions(&buffer, offset, cx)        })        .await        .unwrap()        .unwrap();    assert_definitions(&definitions, &["pub fn to_string(&self) -> String {"], cx);} #[gpui::test]async fn test_fake_type_definition_lsp(cx: &mut TestAppContext) {    init_test(cx);     let fs = FakeFs::new(cx.executor());    fs.insert_tree(path!("/root"), test_project_1()).await;     let project = Project::test(fs.clone(), [path!("/root").as_ref()], cx).await;    let mut servers = setup_fake_lsp(&project, cx);     let (buffer, _handle) = project        .update(cx, |project, cx| {            project.open_local_buffer_with_lsp(path!("/root/src/main.rs"), cx)        })        .await        .unwrap();     let _server = servers.next().await.unwrap();    cx.run_until_parked();     let buffer_text = buffer.read_with(cx, |buffer, _| buffer.text());     // Type definition on a type name returns its own definition    // (same as regular definition)    let type_defs = project        .update(cx, |project, cx| {            let offset = buffer_text.find("Address {").expect("Address { not found");            project.type_definitions(&buffer, offset, cx)        })        .await        .unwrap()        .unwrap();    assert_definitions(&type_defs, &["pub struct Address {"], cx);     // Type definition on a field resolves through the type annotation.    // company.rs has `owner: Arc<Person>`, so type-def of `owner` → Person.    let (company_buffer, _handle) = project        .update(cx, |project, cx| {            project.open_local_buffer_with_lsp(path!("/root/src/company.rs"), cx)        })        .await        .unwrap();    cx.run_until_parked();     let company_text = company_buffer.read_with(cx, |buffer, _| buffer.text());    let type_defs = project        .update(cx, |project, cx| {            let offset = company_text.find("owner").expect("owner not found");            project.type_definitions(&company_buffer, offset, cx)        })        .await        .unwrap()        .unwrap();    assert_definitions(&type_defs, &["pub struct Person {"], cx);     // Type definition on another field: `address: Address` → Address.    let type_defs = project        .update(cx, |project, cx| {            let offset = company_text.find("address").expect("address not found");            project.type_definitions(&company_buffer, offset, cx)        })        .await        .unwrap()        .unwrap();    assert_definitions(&type_defs, &["pub struct Address {"], cx);     // Type definition on a lowercase name with no type annotation returns empty.    let type_defs = project        .update(cx, |project, cx| {            let offset = buffer_text.find("main").expect("main not found");            project.type_definitions(&buffer, offset, cx)        })        .await;    let is_empty = match &type_defs {        Ok(Some(defs)) => defs.is_empty(),        Ok(None) => true,        Err(_) => false,    };    assert!(is_empty, "expected no type definitions for `main`");} #[gpui::test]async fn test_type_definitions_in_related_files(cx: &mut TestAppContext) {    init_test(cx);    let fs = FakeFs::new(cx.executor());    fs.insert_tree(        path!("/root"),        json!({            "src": {                "config.rs": indoc! {r#"                    pub struct Config {                        debug: bool,                        verbose: bool,                    }                "#},                "widget.rs": indoc! {r#"                    use super::config::Config;                     pub struct Widget {                        config: Config,                        name: String,                    }                     impl Widget {                        pub fn render(&self) {                            if self.config.debug {                                println!("debug mode");                            }                        }                    }                "#},            },        }),    )    .await;     let project = Project::test(fs.clone(), [path!("/root").as_ref()], cx).await;    let mut servers = setup_fake_lsp(&project, cx);     let (buffer, _handle) = project        .update(cx, |project, cx| {            project.open_local_buffer_with_lsp(path!("/root/src/widget.rs"), cx)        })        .await        .unwrap();

Lines 1–500 of 1160.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t