Skip to content
This repository has been archived by the owner on Dec 29, 2022. It is now read-only.

Commit

Permalink
Auto merge of #1251 - Xanewok:translate-deglob-test, r=Xanewok
Browse files Browse the repository at this point in the history
Translate test_deglob

This fails often so I attempted to translate this to see if that helps.

One thing that I noticed is that we return an empty response to 'execute command' request, but we request from the client to apply a text edit using a side-channel and IIRC there are no guarantees which message arrives quicker. Since LSP 3.8 supports returning pre-calculated text edits we should probably use that instead.
  • Loading branch information
bors committed Jan 23, 2019
2 parents 361b9f2 + d6843c8 commit f7d5604
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 219 deletions.
135 changes: 135 additions & 0 deletions tests/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::path::Path;

use futures::future::Future;
use lsp_types::{*, request::*, notification::*};
use serde::de::Deserialize;
use serde_json::json;

use crate::support::{basic_bin_manifest, fixtures_dir};
Expand Down Expand Up @@ -1164,3 +1165,137 @@ fn client_find_definitions() {
}
}
}

#[test]
fn client_deglob() {
let p = ProjectBuilder::try_from_fixture(fixtures_dir().join("deglob"))
.unwrap()
.build();
let root_path = p.root();
let mut rls = p.spawn_rls_async();

rls.request::<Initialize>(0, initialize_params(root_path));

rls.wait_for_indexing();

// Test a single swglob
let commands = rls.request::<CodeActionRequest>(100, CodeActionParams {
text_document: TextDocumentIdentifier {
uri: Url::from_file_path(p.root().join("src/main.rs")).unwrap(),
},
range: Range {
start: Position::new(12, 0),
end: Position::new(12, 0),
},
context: CodeActionContext {
diagnostics: vec![],
only: None,
}
}).expect("No code actions returned for line 12");

// Right now we only support deglobbing via commands. Please update this
// test if we move to making text edits via CodeAction (which we should for
// deglobbing);
let Command { title, command, arguments, .. }= match commands {
CodeActionResponse::Commands(commands) => commands,
CodeActionResponse::Actions(_) => unimplemented!(),
}.into_iter().nth(0).unwrap();

let arguments = arguments.expect("Missing command arguments");

assert_eq!(title, "Deglob import".to_string());
assert!(command.starts_with("rls.deglobImports-"));

assert!(arguments[0]["new_text"].as_str() == Some("{Stdin, Stdout}"));
assert_eq!(
serde_json::from_value::<Location>(arguments[0]["location"].clone()).unwrap(),
Location {
range: Range {
start: Position::new(12, 13),
end: Position::new(12, 14),
},
uri: Url::from_file_path(p.root().join("src/main.rs")).unwrap(),
}
);

rls.request::<ExecuteCommand>(200, ExecuteCommandParams { command, arguments });
// Right now the execute command returns an empty response and sends
// appropriate apply edit request via a side-channel
let result = rls.messages().iter().rfind(|msg| msg["method"] == ApplyWorkspaceEdit::METHOD).unwrap().clone();
let params = <ApplyWorkspaceEdit as Request>::Params::deserialize(&result["params"])
.expect("Couldn't deserialize params");

let (url, edits) = params.edit.changes.unwrap().drain().nth(0).unwrap();
assert_eq!(url, Url::from_file_path(p.root().join("src/main.rs")).unwrap());
assert_eq!(edits, vec![TextEdit {
range: Range {
start: Position::new(12, 13),
end: Position::new(12, 14),
},
new_text: "{Stdin, Stdout}".to_string(),
}]);

// Test a deglob for double wildcard
let commands = rls.request::<CodeActionRequest>(1100, CodeActionParams {
text_document: TextDocumentIdentifier {
uri: Url::from_file_path(p.root().join("src/main.rs")).unwrap(),
},
range: Range {
start: Position::new(15, 0),
end: Position::new(15, 0),
},
context: CodeActionContext {
diagnostics: vec![],
only: None,
}
}).expect("No code actions returned for line 12");

// Right now we only support deglobbing via commands. Please update this
// test if we move to making text edits via CodeAction (which we should for
// deglobbing);
let Command { title, command, arguments, .. }= match commands {
CodeActionResponse::Commands(commands) => commands,
CodeActionResponse::Actions(_) => unimplemented!(),
}.into_iter().nth(0).unwrap();

let arguments = arguments.expect("Missing command arguments");

assert_eq!(title, "Deglob imports".to_string());
assert!(command.starts_with("rls.deglobImports-"));
let expected = [(14, 15, "size_of"), (31, 32, "max")];
for i in 0..2 {
assert!(arguments[i]["new_text"].as_str() == Some(expected[i].2));
assert_eq!(
serde_json::from_value::<Location>(arguments[i]["location"].clone()).unwrap(),
Location {
range: Range {
start: Position::new(15, expected[i].0),
end: Position::new(15, expected[i].1),
},
uri: Url::from_file_path(p.root().join("src/main.rs")).unwrap(),
}
);
}

rls.request::<ExecuteCommand>(1200, ExecuteCommandParams { command, arguments });
// Right now the execute command returns an empty response and sends
// appropriate apply edit request via a side-channel
let result = rls.messages().iter().rfind(|msg| msg["method"] == ApplyWorkspaceEdit::METHOD).unwrap().clone();
let params = <ApplyWorkspaceEdit as Request>::Params::deserialize(&result["params"])
.expect("Couldn't deserialize params");

let (url, edits) = params.edit.changes.unwrap().drain().nth(0).unwrap();
assert_eq!(url, Url::from_file_path(p.root().join("src/main.rs")).unwrap());
assert_eq!(
edits,
expected.iter().map(|e| TextEdit {
range: Range {
start: Position::new(15, e.0),
end: Position::new(15, e.1)
},
new_text: e.2.to_string()
}).collect::<Vec<_>>()
);

rls.shutdown();
}
219 changes: 0 additions & 219 deletions tests/tests_old.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1406,225 +1406,6 @@ fn test_no_default_features() {
// ExpectedMessage::new(None).expect_contains("progress").expect_contains(r#""done":true"#)]);
// }

#[test]
fn test_deglob() {
let mut env = Environment::generate_from_fixture("deglob");

let source_file_path = Path::new("src").join("main.rs");

let root_path = env.cache.abs_path(Path::new("."));
let url = Url::from_file_path(env.cache.abs_path(&source_file_path))
.expect("couldn't convert file path to URL");
let text_doc = TextDocumentIdentifier::new(url.clone());
let messages = vec![
initialize(0, root_path.as_os_str().to_str().map(|x| x.to_owned())).to_string(),
// request deglob for single wildcard
request::<requests::CodeAction>(
100,
CodeActionParams {
text_document: text_doc.clone(),
range: env.cache.mk_ls_range_from_line(12),
context: CodeActionContext {
diagnostics: vec![],
only: None,
},
},
).to_string(),
// deglob single
request::<requests::ExecuteCommand>(
200,
ExecuteCommandParams {
command: format!("rls.deglobImports-{}", ::std::process::id()),
arguments: vec![
serde_json::to_value(&requests::DeglobResult {
location: Location {
uri: url.clone(),
range: Range::new(Position::new(12, 13), Position::new(12, 14)),
},
new_text: "{Stdout, Stdin}".into(),
}).unwrap(),
],
},
).to_string(),
// request deglob for double wildcard
request::<requests::CodeAction>(
1100,
CodeActionParams {
text_document: text_doc,
range: env.cache.mk_ls_range_from_line(15),
context: CodeActionContext {
diagnostics: vec![],
only: None,
},
},
).to_string(),
// deglob two wildcards
request::<requests::ExecuteCommand>(
1200,
ExecuteCommandParams {
command: format!("rls.deglobImports-{}", ::std::process::id()),
arguments: vec![
serde_json::to_value(&requests::DeglobResult {
location: Location {
uri: url.clone(),
range: Range::new(Position::new(15, 14), Position::new(15, 15)),
},
new_text: "size_of".into(),
}).unwrap(),
serde_json::to_value(&requests::DeglobResult {
location: Location {
uri: url,
range: Range::new(Position::new(15, 31), Position::new(15, 32)),
},
new_text: "max".into(),
}).unwrap(),
],
},
).to_string(),
];

let (mut server, results, ..) = env.mock_server(messages);
// Initialize and build.
assert_eq!(
ls_server::LsService::handle_message(&mut server),
ls_server::ServerStateChange::Continue
);
expect_message(
&mut server,
results.clone(),
ExpectedMessage::new(Some(0)).expect_contains("rls.deglobImports-"),
);

expect_series(&mut server, results.clone(), vec!["progress"]);

assert_eq!(
ls_server::LsService::handle_message(&mut server),
ls_server::ServerStateChange::Continue
);
{
server.wait_for_concurrent_jobs();
let response: Value = serde_json::from_str(&results.lock().unwrap().remove(0)).unwrap();
assert_eq!(response["id"], 100);
assert_eq!(response["result"][0]["title"], "Deglob import");
assert_eq!(
response["result"][0]["command"],
&*format!("rls.deglobImports-{}", ::std::process::id())
);
let deglob = &response["result"][0]["arguments"][0];
assert!(
deglob["location"]["uri"]
.as_str()
.unwrap()
.ends_with("deglob/src/main.rs")
);
let deglob_loc = &deglob["location"]["range"];
assert_eq!(deglob_loc["start"]["line"], 12);
assert_eq!(deglob_loc["start"]["character"], 13);
assert_eq!(deglob_loc["end"]["line"], 12);
assert_eq!(deglob_loc["end"]["character"], 14);
let mut imports: Vec<_> = deglob["new_text"]
.as_str()
.unwrap()
.trim_matches('{')
.trim_matches('}')
.split(", ")
.collect();
imports.sort();
assert_eq!(imports, vec!["Stdin", "Stdout"]);
}

assert_eq!(
ls_server::LsService::handle_message(&mut server),
ls_server::ServerStateChange::Continue
);
{
server.wait_for_concurrent_jobs();
let response: Value = serde_json::from_str(&results.lock().unwrap().remove(0)).unwrap();
assert_eq!(response["id"], 0x0100_0001);
assert_eq!(response["method"], "workspace/applyEdit");
let (key, changes) = response["params"]["edit"]["changes"]
.as_object()
.unwrap()
.iter()
.next()
.unwrap();
assert!(key.ends_with("deglob/src/main.rs"));
let change = &changes[0];
assert_eq!(change["range"]["start"]["line"], 12);
assert_eq!(change["range"]["start"]["character"], 13);
assert_eq!(change["range"]["end"]["line"], 12);
assert_eq!(change["range"]["end"]["character"], 14);
let mut imports: Vec<_> = change["newText"]
.as_str()
.expect("newText missing")
.trim_matches('{')
.trim_matches('}')
.split(", ")
.collect();
imports.sort();
assert_eq!(imports, vec!["Stdin", "Stdout"]);

let response: Value = serde_json::from_str(&results.lock().unwrap().remove(0)).unwrap();
assert_eq!(response["id"], 200);
assert!(response["result"].is_null());
}

assert_eq!(
ls_server::LsService::handle_message(&mut server),
ls_server::ServerStateChange::Continue
);
expect_message(
&mut server,
results.clone(),
ExpectedMessage::new(Some(1100))
.expect_contains(r#""title":"Deglob imports""#)
.expect_contains(r#""command":"rls.deglobImports-"#)
.expect_contains(r#"{"location":{"range":{"end":{"character":15,"line":15},"start":{"character":14,"line":15}},"uri":"#)
.expect_contains(r#"deglob/src/main.rs"}"#)
.expect_contains(r#""new_text":"size_of""#)
.expect_contains(r#"{"location":{"range":{"end":{"character":32,"line":15},"start":{"character":31,"line":15}},"uri":"#)
.expect_contains(r#"deglob/src/main.rs"}"#)
.expect_contains(r#""new_text":"max""#)
);

assert_eq!(
ls_server::LsService::handle_message(&mut server),
ls_server::ServerStateChange::Continue
);

{
server.wait_for_concurrent_jobs();
let response: Value = serde_json::from_str(&results.lock().unwrap().remove(0)).unwrap();
assert_eq!(response["id"], 0x0100_0002);
assert_eq!(response["method"], "workspace/applyEdit");
let (key, changes) = response["params"]["edit"]["changes"]
.as_object()
.unwrap()
.iter()
.next()
.unwrap();
assert!(key.ends_with("deglob/src/main.rs"));
let change = &changes[0];
assert_eq!(change["range"]["start"]["line"], 15);
assert_eq!(change["range"]["start"]["character"], 14);
assert_eq!(change["range"]["end"]["line"], 15);
assert_eq!(change["range"]["end"]["character"], 15);
assert_eq!(change["newText"], "size_of");
let change = &changes[1];
assert_eq!(change["range"]["start"]["line"], 15);
assert_eq!(change["range"]["start"]["character"], 31);
assert_eq!(change["range"]["end"]["line"], 15);
assert_eq!(change["range"]["end"]["character"], 32);
assert_eq!(change["newText"], "max");
}

expect_message(
&mut server,
results,
ExpectedMessage::new(Some(1200)).expect_contains(r#"null"#),
);
}

#[test]
fn test_all_targets() {
let mut env = Environment::generate_from_fixture("bin_lib");
Expand Down

0 comments on commit f7d5604

Please sign in to comment.