Skip to content

Commit ded73b5

Browse files
mmahroussfda-odoo
authored andcommitted
[TEST] simple untitled test
1 parent b599b95 commit ded73b5

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed

server/src/core/entry_point.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ impl EntryPointMgr {
3333
/// Returns the file symbol for the untitled entry.
3434
pub fn add_entry_to_untitled(session: &mut SessionInfo, path: String) -> Rc<RefCell<Symbol>> {
3535
// For untitled files, we use a minimal tree: just the name as a single OYarn
36+
info!("Adding new untitled entry point: {}", path);
3637
let tree = vec![OYarn::from(path.clone())];
3738
let entry = EntryPoint::new(
3839
path.clone(),

server/tests/test_untitled.rs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
use lsp_types::{TextDocumentContentChangeEvent, Position};
2+
use odoo_ls_server::core::file_mgr::FileMgr;
3+
use odoo_ls_server::core::odoo::SyncOdoo;
4+
use odoo_ls_server::features::completion::CompletionFeature;
5+
use odoo_ls_server::features::hover::HoverFeature;
6+
use odoo_ls_server::features::definition::DefinitionFeature;
7+
mod setup;
8+
9+
#[test]
10+
/// Simple test to verify LSP features on untitled files, open, change, hover, complete.
11+
fn test_untitled_file_lifecycle() {
12+
// Setup server and session
13+
let mut odoo = setup::setup::setup_server(false);
14+
let mut session = setup::setup::create_session(&mut odoo);
15+
let untitled_uri = "untitled:Untitled-1".to_string();
16+
let initial_text = "def foo():\n return 42\nfoo()\n";
17+
18+
// Simulate didOpen for untitled file
19+
let did_open_params = lsp_types::DidOpenTextDocumentParams {
20+
text_document: lsp_types::TextDocumentItem {
21+
uri: FileMgr::pathname2uri(&untitled_uri),
22+
language_id: "python".to_string(),
23+
version: 1,
24+
text: initial_text.to_string(),
25+
}
26+
};
27+
odoo_ls_server::core::odoo::Odoo::handle_did_open(&mut session, did_open_params);
28+
29+
// Simulate didChange for untitled file
30+
let change_event2 = TextDocumentContentChangeEvent {
31+
range: Some(lsp_types::Range {
32+
start: Position::new(1, 11),
33+
end: Position::new(1, 13),
34+
}),
35+
range_length: Some(2),
36+
text: "43".to_string(),
37+
};
38+
let did_change_params = lsp_types::DidChangeTextDocumentParams {
39+
text_document: lsp_types::VersionedTextDocumentIdentifier {
40+
uri: FileMgr::pathname2uri(&untitled_uri),
41+
version: 2,
42+
},
43+
content_changes: vec![change_event2],
44+
};
45+
odoo_ls_server::core::odoo::Odoo::handle_did_change(&mut session, did_change_params);
46+
47+
// Get file symbol
48+
let file_symbol = SyncOdoo::get_symbol_of_opened_file(&mut session, &std::path::PathBuf::from(&untitled_uri)).expect("Untitled file symbol");
49+
// Hover on foo()
50+
let file_info = session.sync_odoo.get_file_mgr().borrow().get_file_info(&untitled_uri).unwrap();
51+
let hover = HoverFeature::hover_python(&mut session, &file_symbol, &file_info, 2, 0);
52+
assert!(hover.is_some(), "Hover result should be Some");
53+
let hover_content = match hover {
54+
Some(lsp_types::Hover { contents, .. }) => {
55+
match contents {
56+
lsp_types::HoverContents::Scalar(lsp_types::MarkedString::String(s)) => s,
57+
lsp_types::HoverContents::Scalar(lsp_types::MarkedString::LanguageString(ls)) => ls.value,
58+
lsp_types::HoverContents::Array(arr) => arr.iter().map(|ms| match ms {
59+
lsp_types::MarkedString::String(s) => s.clone(),
60+
lsp_types::MarkedString::LanguageString(ls) => ls.value.clone(),
61+
}).collect::<Vec<_>>().join("\n"),
62+
lsp_types::HoverContents::Markup(markup) => markup.value,
63+
}
64+
},
65+
None => String::new(),
66+
};
67+
assert!(hover_content.contains("foo"), "Hover should contain function name 'foo', got: {}", hover_content);
68+
assert!(hover_content.contains("def foo()"), "Hover should show function signature, got: {}", hover_content);
69+
70+
// Completion at return
71+
let completion = CompletionFeature::autocomplete(&mut session, &file_symbol, &file_info, 1, 11);
72+
assert!(completion.is_some(), "Completion result should be Some");
73+
let completion_items = match completion.unwrap() {
74+
lsp_types::CompletionResponse::Array(items) => items,
75+
lsp_types::CompletionResponse::List(list) => list.items,
76+
};
77+
assert!(!completion_items.is_empty(), "Completion items should not be empty");
78+
let labels: Vec<_> = completion_items.iter().map(|item| item.label.clone()).collect();
79+
assert!(labels.iter().any(|l| l.contains("foo")), "Completion should contain 'foo', got: {:?}", labels);
80+
81+
// Definition for foo
82+
let definition = DefinitionFeature::get_location(&mut session, &file_symbol, &file_info, 0, 4);
83+
assert!(definition.is_some(), "Definition result should be Some");
84+
let def_locs = match definition.unwrap() {
85+
lsp_types::GotoDefinitionResponse::Scalar(loc) => vec![loc],
86+
lsp_types::GotoDefinitionResponse::Array(arr) => arr,
87+
lsp_types::GotoDefinitionResponse::Link(arr) => arr.into_iter().map(|l| {
88+
// Convert LocationLink to Location using target_uri and target_range
89+
lsp_types::Location {
90+
uri: l.target_uri,
91+
range: l.target_range,
92+
}
93+
}).collect(),
94+
};
95+
assert!(!def_locs.is_empty(), "Definition locations should not be empty");
96+
let def_loc = &def_locs[0];
97+
// Should point to line 0 (def foo)
98+
assert_eq!(def_loc.range.start.line, 0, "Definition should start at line 0 (function definition), got: {:?}", def_loc);
99+
assert_eq!(def_loc.range.end.line, 1, "Definition should end at line 0 (function definition), got: {:?}", def_loc);
100+
}

0 commit comments

Comments
 (0)