refactor: move embedded tests into dedicated test directory
This commit is contained in:
+2
-246
@@ -2993,249 +2993,5 @@ fn uri_path(uri: &str) -> Result<PathBuf, String> {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn native_definitions_preserve_snapshot_identity_and_utf16_until_navigation() {
|
||||
let source = Source {
|
||||
buffer_id: 7,
|
||||
revision: 3,
|
||||
row: 0,
|
||||
column: 0,
|
||||
request_id: 11,
|
||||
};
|
||||
let path = Path::new("/vamp-immutable-snapshot/Before/renamed/λ.rs");
|
||||
let span = json!({
|
||||
"start": {"line": 4, "character": 5},
|
||||
"end": {"line": 4, "character": 8}
|
||||
});
|
||||
for location in [
|
||||
json!({"uri": file_uri(path).unwrap(), "range": span}),
|
||||
json!({"targetUri": file_uri(path).unwrap(),
|
||||
"targetRange": span, "targetSelectionRange": span}),
|
||||
] {
|
||||
let effects = Runtime::definition_effects(&source, &location).unwrap();
|
||||
let expected_target_range = location.get("targetUri").map(|_| Utf16Range {
|
||||
start: (4, 5),
|
||||
end: (4, 8),
|
||||
});
|
||||
assert!(matches!(
|
||||
effects.as_slice(),
|
||||
[UpdateEffect::NavigateUtf16 {
|
||||
buffer_id: 7, revision: 3, path: target,
|
||||
range: Utf16Range { start: (4, 5), end: (4, 8) }, target_range,
|
||||
}] if target == path && *target_range == expected_target_range
|
||||
));
|
||||
}
|
||||
for invalid in [
|
||||
json!({"start": {"line": 4, "character": 8},
|
||||
"end": {"line": 4, "character": 5}}),
|
||||
json!({"start": {"line": -1, "character": 0},
|
||||
"end": {"line": 0, "character": 0}}),
|
||||
] {
|
||||
for location in [
|
||||
json!({"uri": file_uri(path).unwrap(), "range": invalid}),
|
||||
json!({"targetUri": file_uri(path).unwrap(),
|
||||
"targetRange": invalid, "targetSelectionRange": span}),
|
||||
json!({"targetUri": file_uri(path).unwrap(),
|
||||
"targetRange": span, "targetSelectionRange": invalid}),
|
||||
] {
|
||||
assert!(Runtime::definition_effects(&source, &location).is_err());
|
||||
}
|
||||
}
|
||||
assert!(
|
||||
serde_json::from_value::<UpdateEffect>(json!({
|
||||
"type": "navigate_utf16", "buffer_id": 7, "revision": 3,
|
||||
"path": path, "range": {"start": [4,5], "end": [4,8]},
|
||||
"target_range": null
|
||||
}))
|
||||
.is_err()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn semantic_decoder_validates_raw_coordinates_before_grapheme_rounding() {
|
||||
let options = semantic_options(Some(&json!({
|
||||
"full": true,
|
||||
"legend": {"tokenTypes": ["custom", "function"],
|
||||
"tokenModifiers": ["custom", "readonly", "declaration", "async"]}
|
||||
})))
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let tokens = decode_semantic_tokens(
|
||||
"A😀e\u{301}Z\r\n\r\nx",
|
||||
&json!({"data": [
|
||||
0, 1, 2, 1, 2,
|
||||
0, 2, 1, 1, 12,
|
||||
0, 1, 1, 1, 0,
|
||||
0, 1, 999, 0, 0,
|
||||
1, 0, 1, 1, 0,
|
||||
1, 0, 0, 1, 0,
|
||||
0, 0, 100, 1, 0
|
||||
]}),
|
||||
&options,
|
||||
)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert_eq!(tokens.len(), 4);
|
||||
assert_eq!(tokens[0].start, TextPosition { row: 0, column: 1 });
|
||||
assert_eq!(tokens[0].end, TextPosition { row: 0, column: 2 });
|
||||
assert_eq!(tokens[0].modifiers, SemanticTokenModifier::Readonly as u16);
|
||||
assert_eq!(tokens[1].start, TextPosition { row: 0, column: 2 });
|
||||
assert_eq!(tokens[1].end, TextPosition { row: 0, column: 3 });
|
||||
assert_eq!(
|
||||
tokens[1].modifiers,
|
||||
SemanticTokenModifier::Declaration as u16 | SemanticTokenModifier::Async as u16
|
||||
);
|
||||
assert_eq!(tokens[2].start, tokens[1].start);
|
||||
assert_eq!(tokens[3].end, TextPosition { row: 2, column: 1 });
|
||||
for data in [
|
||||
json!([0, 0, 1, 1]),
|
||||
json!([-1, 0, 1, 1, 0]),
|
||||
json!([0, 0.5, 1, 1, 0]),
|
||||
json!([0, 0, 1, 1, 2147483648u64]),
|
||||
json!([0, 0, 1, 65536, 0]),
|
||||
json!([0, 0, 1, 2, 0]),
|
||||
json!([0, 0, 1, 1, 16]),
|
||||
json!([0, 2, 1, 0, 0]),
|
||||
json!([0, 1, 1, 1, 0]),
|
||||
json!([0, 7, 1, 1, 0]),
|
||||
json!([2, 0, 1, 1, 0]),
|
||||
json!([0, 1, 2, 1, 0, 0, 1, 1, 1, 0]),
|
||||
] {
|
||||
assert!(
|
||||
decode_semantic_tokens("A😀e\u{301}Z\n", &json!({"data": data}), &options).is_err(),
|
||||
"{data}"
|
||||
);
|
||||
}
|
||||
let count = MAX_BODY / std::mem::size_of::<SemanticToken>() + 1;
|
||||
assert!(
|
||||
decode_semantic_tokens("x", &json!({"data": vec![0; count * 5]}), &options).is_err()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unicode_positions_and_local_uri_boundaries() {
|
||||
let text = "A😀e\u{301}Z\n";
|
||||
let (start, end) = range(
|
||||
text,
|
||||
&json!({"start": {"line": 0, "character": 2}, "end": {"line": 0, "character": 4}}),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(start, TextPosition { row: 0, column: 1 });
|
||||
assert_eq!(end, TextPosition { row: 0, column: 3 });
|
||||
assert_eq!(
|
||||
outbound_position(text, 0, 3).unwrap(),
|
||||
json!({"line": 0, "character": 5})
|
||||
);
|
||||
assert_eq!(
|
||||
position(text, &json!({"line": 1, "character": 999}), false).unwrap(),
|
||||
TextPosition { row: 1, column: 0 }
|
||||
);
|
||||
assert!(
|
||||
range(
|
||||
text,
|
||||
&json!({"start": {"line": 0, "character": 3}, "end": {"line": 0, "character": 2}})
|
||||
)
|
||||
.is_err()
|
||||
);
|
||||
let path = Path::new("/tmp/source space λ😀.rs");
|
||||
assert_eq!(uri_path(&file_uri(path).unwrap()).unwrap(), path);
|
||||
assert_eq!(
|
||||
uri_path("file://localhost/tmp/a%23b").unwrap(),
|
||||
Path::new("/tmp/a#b")
|
||||
);
|
||||
for uri in [
|
||||
"https://example.invalid/a",
|
||||
"file://remote/tmp/a",
|
||||
"file:///tmp/%",
|
||||
"file:///tmp/%00",
|
||||
"file:///tmp/%FF",
|
||||
"file:///tmp/a?query",
|
||||
] {
|
||||
assert!(uri_path(uri).is_err(), "{uri}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hover_contents_keep_lines_and_reject_malformed_values() {
|
||||
let source = "A😀e\u{301}Z\r\n";
|
||||
for kind in ["plaintext", "markdown"] {
|
||||
assert_eq!(
|
||||
hover_text(
|
||||
&json!({
|
||||
"contents": {"kind": kind, "value": "😀e\u{301}\r\n\tcode\rnext\u{1b}\u{85}"},
|
||||
"range": {"start": {"line": 0, "character": 2},
|
||||
"end": {"line": 0, "character": 4}}
|
||||
}),
|
||||
source,
|
||||
)
|
||||
.unwrap(),
|
||||
Some("😀e\u{301}\n code\nnext ".into()),
|
||||
);
|
||||
}
|
||||
for contents in [
|
||||
json!("line\ncode"),
|
||||
json!({"language": "rust", "value": "line\ncode"}),
|
||||
] {
|
||||
assert_eq!(
|
||||
hover_text(&json!({"contents": contents}), source).unwrap(),
|
||||
Some("line\ncode".into()),
|
||||
);
|
||||
}
|
||||
assert_eq!(
|
||||
hover_text(
|
||||
&json!({"contents": ["first", {"language": "rust", "value": "fn main() {\n}"}]}),
|
||||
source,
|
||||
)
|
||||
.unwrap(),
|
||||
Some("first\n\nfn main() {\n}".into()),
|
||||
);
|
||||
for value in [
|
||||
Value::Null,
|
||||
json!({"contents": ""}),
|
||||
json!({"contents": []}),
|
||||
] {
|
||||
assert_eq!(hover_text(&value, source).unwrap(), None);
|
||||
}
|
||||
for value in [
|
||||
json!({}),
|
||||
json!({"contents": {"kind": "html", "value": "x"}}),
|
||||
json!({"contents": {"language": "rust", "value": false}}),
|
||||
json!({"contents": [{"kind": "markdown", "value": "x"}]}),
|
||||
json!({"contents": "x", "range": {"start": {"line": 1, "character": 0},
|
||||
"end": {"line": 0, "character": 0}}}),
|
||||
json!({"contents": "\t".repeat(MAX_BODY / 4 + 1)}),
|
||||
] {
|
||||
assert!(hover_text(&value, source).is_err());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn completion_text_limit_counts_the_atomic_batch_not_sort_metadata() {
|
||||
let source = Source {
|
||||
buffer_id: 1,
|
||||
revision: 0,
|
||||
row: 0,
|
||||
column: 0,
|
||||
request_id: 1,
|
||||
};
|
||||
let at_limit = json!([{"label": "x", "insertText": "x".repeat(MAX_BODY - 1)}]);
|
||||
assert_eq!(
|
||||
decode_completion("", &at_limit, &source, None).unwrap()[0].edits[0]
|
||||
.text
|
||||
.len(),
|
||||
MAX_BODY - 1
|
||||
);
|
||||
let over_limit = json!([
|
||||
{"label": "x", "insertText": "x".repeat(MAX_BODY - 1)},
|
||||
{"label": "y"}
|
||||
]);
|
||||
assert!(
|
||||
decode_completion("", &over_limit, &source, None)
|
||||
.unwrap_err()
|
||||
.contains("4 MiB")
|
||||
);
|
||||
}
|
||||
}
|
||||
#[path = "../tests/unit/lsp.rs"]
|
||||
mod tests;
|
||||
|
||||
Reference in New Issue
Block a user