ocaml
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Remove fragile language server tests; remove dep on neovim

Please feel free to restore and modify to be in compliance with
https://todo.sr.ht/~jonsterling/forester/164.

References: https://todo.sr.ht/~jonsterling/forester/164

-840
-1
.builds/build.yaml
··· 19 19 - setup: | 20 20 nix-env -iA cachix -f https://cachix.org/api/v1/install 21 21 nix-env -iA nixos.jq 22 - nix-env -iA nixos.neovim 23 22 cachix use forester 24 23 - build: | 25 24 cd ocaml-forester
-439
lib/language_server/test/Test_completion.ml
··· 1 - (* 2 - subtree_completion_text* SPDX-FileCopyrightText: 2024 The Forester Project Contributors 3 - * 4 - * SPDX-License-Identifier: GPL-3.0-or-later 5 - *) 6 - 7 - open Forester_prelude 8 - open Forester_core 9 - open Forester_compiler 10 - open Forester_frontend 11 - open Forester_lsp 12 - open Forester_test 13 - open Testables 14 - 15 - open struct module L = Lsp.Types end 16 - 17 - let test_find_with_prev () = 18 - let code = 19 - Result.get_ok @@ 20 - parse_string 21 - {| 22 - \li{I am on line 1} 23 - \li{I am on line 2} 24 - \li{I am on line 3} 25 - \li{I am on line 4} 26 - |} 27 - in 28 - Logs.debug (fun m -> m "%a" Code.pp code); 29 - let result = Analysis.find_with_prev ~position: {line = 4; character = 5;} code in 30 - begin 31 - let@ {loc; _} = List.iter @~ code in 32 - Logs.debug (fun m -> m "%s" (Yojson.Safe.to_string (L.Range.yojson_of_t (Lsp_shims.Loc.lsp_range_of_range loc)))); 33 - end; 34 - match result with 35 - | None -> Alcotest.fail "no result" 36 - | Some (prev, node) -> 37 - let open DSL.Code in 38 - Alcotest.(check code_node) 39 - "node" 40 - ( 41 - Group 42 - ( 43 - Braces, 44 - [ 45 - text "I"; 46 - text " "; 47 - text "am"; 48 - text " "; 49 - text "on"; 50 - text " "; 51 - text "line"; 52 - text " "; 53 - text "4" 54 - ] 55 - ) 56 - ) 57 - (Code.map strip_code node.value); 58 - match prev with 59 - | None -> Alcotest.fail "no prev" 60 - | Some prev -> 61 - Alcotest.(check code_node) "Pred" (Ident ["li"]) prev.value 62 - 63 - let test_node_at_pos_with_prev_or_parent () = 64 - let code = 65 - Result.get_ok @@ 66 - parse_string 67 - {| 68 - \def\foo[arg]{Hello, \arg!} 69 - \p{\ul{\li{item}}} 70 - |} 71 - in 72 - let prev = Analysis.find_with_prev ~position: {character = 5; line = 2;} code in 73 - begin 74 - match prev with 75 - | None -> Alcotest.fail "node not found" 76 - | Some (prev, node) -> 77 - match prev with 78 - | None -> Alcotest.fail "no pred" 79 - | Some prev -> 80 - Alcotest.(check code_node) "check pred" (Ident ["p"]) prev.value; 81 - Alcotest.(check code_node) 82 - "check node" 83 - (DSL.Code.(braces [ul; braces [li; braces [text "item"]]]).value) 84 - (Code.map strip_code node.value) 85 - end; 86 - let result = Analysis.parent_or_prev_at_code ~position: {character = 5; line = 2;} code in 87 - match result with 88 - | None -> Alcotest.fail "no result" 89 - | Some (Prev (_pred, _node)) -> Alcotest.fail "pred" 90 - | Some (Top node) -> Alcotest.(check code_node) "node" (Ident ["ul"]) node.value 91 - | Some (Parent _) -> Alcotest.fail "parent" 92 - 93 - let test_word_before () = 94 - let@ () = Reporter.easy_run in 95 - let text = 96 - (* 1 2 *) 97 - (*01234567890123456789012*) 98 - {|asdfasdf \route-asset{assets/|} 99 - in 100 - let doc = 101 - Lsp.Text_document.make 102 - ~position_encoding: `UTF8 103 - { 104 - textDocument = 105 - L.TextDocumentItem.create 106 - ~languageId: "forester" 107 - ~uri: (Lsp.Uri.of_string "") 108 - ~version: 1 109 - ~text 110 - } 111 - in 112 - let result = 113 - Option.get @@ 114 - let position = L.Position.create ~character: 22 ~line: 0 in 115 - Analysis.word_before ~position doc 116 - in 117 - Alcotest.(check string) "" "\\route-asset{" result 118 - 119 - let test_uri_completion () = 120 - let result_1 = Completion.uri_completion.text "complete](" in 121 - let result_2 = Completion.uri_completion.text "\\transclude{" in 122 - Alcotest.(check @@ option completion_type) "link" (Some Addrs) result_1; 123 - Alcotest.(check @@ option completion_type) "transclusion" (Some Addrs) result_2 124 - 125 - let test_completion_types ~env () = 126 - let@ () = Reporter.easy_run in 127 - let forest = State.make ~env ~config: (Config.default ()) ~dev: false () in 128 - let result_1 = 129 - (* 0123456789012*) 130 - let code = Result.get_ok @@ parse_string {|\route-asset{}|} in 131 - let uri = URI.of_string_exn "http://localhost/tree" in 132 - let expanded = 133 - Resolver.Scope.run ~init_visible: Expand.initial_visible_trie @@ fun () -> 134 - Expand.expand ~forest code 135 - in 136 - let tree = mk_tree ~uri ~code ~expanded in 137 - Logs.debug (fun m -> m "%a" Tree.pp tree); 138 - Completion.(S.to_list (completion_types ~position: {line = 0; character = 12} tree)) 139 - in 140 - let result_2 = 141 - (* 0123456789012*) 142 - let text = {|\p{[link](}|} in 143 - let tree = 144 - let uri = Lsp.Uri.of_path "/foo" in 145 - Tree.Document 146 - ( 147 - Lsp.Text_document.make 148 - ~position_encoding: `UTF8 149 - { 150 - textDocument = { 151 - languageId = "forester"; 152 - text; 153 - uri; 154 - version = 1 155 - } 156 - } 157 - ) 158 - in 159 - Logs.debug (fun m -> m "%a" Tree.pp tree); 160 - Completion.(S.to_list (completion_types ~position: {line = 0; character = 10} tree)) 161 - in 162 - Alcotest.(check @@ list completion_type) "" [Assets] result_1; 163 - Alcotest.(check @@ list completion_type) "" [Addrs] result_2 164 - 165 - let test_contains () = 166 - let position = L.Position.create ~character: 12 ~line: 0 in 167 - let src = `File "foo" in 168 - let start_pos = Asai.Range.{source = src; offset = 1; start_of_line = 0; line_num = 1} in 169 - let end_pos = Asai.Range.{source = src; offset = 13; start_of_line = 0; line_num = 1} in 170 - let loc = Option.some @@ Asai.Range.make (start_pos, end_pos) in 171 - let result = Analysis.contains ~position loc in 172 - Alcotest.(check bool) "" true result 173 - 174 - let test_node_at () = 175 - let case_1 = 176 - let position = L.Position.create ~character: 12 ~line: 0 in 177 - (* 0123456789012*) 178 - let code = Result.get_ok @@ parse_string {|\import{asdf}|} in 179 - let result = Option.get @@ Analysis.node_at_code ~position code in 180 - Alcotest.(check code_node) 181 - "" 182 - (Import (Private, "asdf")) 183 - (Asai.Range.(result.value)) 184 - in 185 - let case_2 = 186 - let code = 187 - Result.get_ok @@ 188 - parse_string 189 - (* 1 2 3 4 5 *) 190 - (*0123456789012345678901234567890123456789012345678901234567890123*) 191 - {|\def\Mor[arg1][arg2][arg3]{#{{\arg2}\xrightarrow{\arg1}{\arg3}}} 192 - |} 193 - in 194 - let position_1 = L.Position.create ~character: 40 ~line: 0 in 195 - let position_2 = L.Position.create ~character: 50 ~line: 0 in 196 - let result1 = Option.get @@ Analysis.node_at_code ~position: position_1 code in 197 - let result2 = Option.get @@ Analysis.node_at_code ~position: position_2 code in 198 - Alcotest.(check code_node) "" (Ident ["xrightarrow"]) (Asai.Range.(result1.value)); 199 - Alcotest.(check code_node) "" (Ident ["arg1"]) (Asai.Range.(result2.value)) 200 - in 201 - let case_3 = 202 - let code = 203 - Result.get_ok @@ 204 - parse_string 205 - {| 206 - %123456789012345678901234567890123456789012345678901234567890 207 - \p{ 208 - \foo{ 209 - \ul{ 210 - \li{asdf} 211 - } 212 - } 213 - } 214 - |} 215 - in 216 - let position = L.Position.create ~character: 12 ~line: 5 in 217 - let result = Option.get @@ Analysis.node_at_code ~position code in 218 - Alcotest.(check code_node) "" (Text "asdf") (Asai.Range.(result.value)) 219 - in 220 - case_1; 221 - case_2; 222 - case_3 223 - 224 - let test_addr_at () = 225 - let code = Result.get_ok @@ parse_string {|\transclude{tfmt-0005}|} in 226 - let position = L.Position.create ~character: 13 ~line: 0 in 227 - let result = Option.get @@ Analysis.addr_at ~position code in 228 - Alcotest.(check string) "" "tfmt-0005" (Asai.Range.(result.value)) 229 - 230 - let test_word_at () = 231 - let text = 232 - {|Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor 233 - incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis 234 - nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo 235 - consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse 236 - cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat 237 - non proident, sunt in culpa qui officia deserunt mollit anim id est laborum 238 - |} 239 - in 240 - let doc = 241 - Lsp.Text_document.make 242 - ~position_encoding: `UTF8 243 - { 244 - textDocument = 245 - L.TextDocumentItem.create 246 - ~languageId: "forester" 247 - ~uri: (Lsp.Uri.of_string "") 248 - ~version: 1 249 - ~text 250 - } 251 - in 252 - let lorem = 253 - Option.get @@ 254 - let position = L.Position.create ~character: 0 ~line: 0 in 255 - Analysis.word_at ~position doc 256 - in 257 - let dolor = 258 - Option.get @@ 259 - let position = L.Position.create ~character: 13 ~line: 0 in 260 - Analysis.word_at ~position doc 261 - in 262 - let irure = 263 - Option.get @@ 264 - let position = L.Position.create ~character: 25 ~line: 3 in 265 - Analysis.word_at ~position doc 266 - in 267 - Alcotest.(check string) "" "Lorem" lorem; 268 - Alcotest.(check string) "" "dolor" dolor; 269 - Alcotest.(check string) "" "irure" irure 270 - 271 - let test_enclosing_group ~env () = 272 - let forest = State.make ~env ~config: (Config.default ()) ~dev: false () in 273 - (* 012345678901234*) 274 - let code = Result.get_ok @@ parse_string {|\foo{\bar{baz}}|} in 275 - let expanded = 276 - Resolver.Scope.run ~init_visible: Expand.initial_visible_trie @@ fun () -> 277 - Expand.expand ~forest code 278 - in 279 - let uri = URI.of_string_exn "localhost:foo" in 280 - let tree = mk_tree ~uri ~code ~expanded in 281 - let case_1 = 282 - let position = L.Position.{line = 0; character = 6} in 283 - match Analysis.get_enclosing_syn_group ~position tree with 284 - | None -> Alcotest.fail "no enclosing group" 285 - | Some {value = (d, nodes); _} -> 286 - let open DSL.Syn in 287 - Alcotest.(check delim) "" Braces d; 288 - Alcotest.(check syn) 289 - "" 290 - [tex_cs "bar"; braces [text "baz"]] 291 - (strip_syn nodes) 292 - in 293 - let case_2 = 294 - let position = L.Position.{line = 0; character = 10} in 295 - match Analysis.get_enclosing_syn_group ~position tree with 296 - | None -> Alcotest.fail "no enclosing group" 297 - | Some {value = (d, nodes); _} -> 298 - let open DSL.Syn in 299 - Alcotest.(check delim) "" Braces d; 300 - Alcotest.(check syn) "" [text "baz"] (strip_syn nodes) 301 - in 302 - List.iter Fun.id [case_1; case_2] 303 - 304 - let test_subtree_completion_text () = 305 - (* 012345678*) 306 - let text = {|\subtree[|} in 307 - let position : L.Position.t = {line = 0; character = 9;} in 308 - let doc = 309 - Lsp.Text_document.make 310 - ~position_encoding: `UTF8 311 - { 312 - textDocument = 313 - L.TextDocumentItem.create 314 - ~languageId: "forester" 315 - ~uri: (Lsp.Uri.of_string "") 316 - ~version: 1 317 - ~text 318 - } 319 - in 320 - let result = Completion.(S.to_list @@ completion_types ~position (Document doc)) in 321 - Alcotest.(check bool) 322 - "" 323 - (Str.(string_match (regexp {|.*route-asset.*|}) {|\subtree[|} 0)) 324 - false; 325 - Alcotest.(check @@ list completion_type) 326 - "" 327 - [New_addr] 328 - result 329 - 330 - let test_subtree_completion_code () = 331 - Alcotest.(check string) 332 - "" 333 - "" 334 - "" 335 - 336 - let test_asset_completion_text () = 337 - (* 0123456789012*) 338 - let text = {|\route-asset{|} in 339 - let position : L.Position.t = {line = 0; character = 13;} in 340 - let doc = 341 - Lsp.Text_document.make 342 - ~position_encoding: `UTF8 343 - { 344 - textDocument = 345 - L.TextDocumentItem.create 346 - ~languageId: "forester" 347 - ~uri: (Lsp.Uri.of_string "") 348 - ~version: 1 349 - ~text 350 - } 351 - in 352 - let result = Completion.(S.to_list @@ completion_types ~position (Document doc)) in 353 - Alcotest.(check @@ list completion_type) 354 - "" 355 - [Assets] 356 - result 357 - 358 - let test_asset_completion_syn () = 359 - let@ () = Reporter.easy_run in 360 - let textDocument = find_doc (Test_env.get ()) "sterling-2024-cl-forester" in 361 - let position : L.Position.t = {line = 4; character = 27} in 362 - let params = L.CompletionParams.create ~position ~textDocument () in 363 - let completions = 364 - Completion.compute params 365 - |> Option.map (fun (`CompletionList L.CompletionList.{items; _}) -> 366 - String.concat "" @@ 367 - List.map 368 - (fun i -> Format.asprintf "%s" (Yojson.Safe.to_string @@ L.CompletionItem.yojson_of_t i)) 369 - items 370 - ) 371 - in 372 - Alcotest.(check @@ option string) 373 - "" 374 - (Some {|{\"insertText\":\"assets/autocomplete.png\",\"kind\":17,\"label\":\"assets/autocomplete.png\"}{\"insertText\":\"assets/asset-completions.png\",\"kind\":17,\"label\":\"assets/asset-completions.png\"}{\"insertText\":\"assets/sterling-2024-cl-forester.pdf\",\"kind\":17,\"label\":\"assets/sterling-2024-cl-forester.pdf\"}{\"insertText\":\"assets/workspace-symbols.png\",\"kind\":17,\"label\":\"assets/workspace-symbols.png\"}{\"insertText\":\"assets/diagnostics.png\",\"kind\":17,\"label\":\"assets/diagnostics.png\"}{\"insertText\":\"assets/virtual-text.png\",\"kind\":17,\"label\":\"assets/virtual-text.png\"}{\"insertText\":\"assets/code-action.png\",\"kind\":17,\"label\":\"assets/code-action.png\"}{\"insertText\":\"assets/document-symbols.png\",\"kind\":17,\"label\":\"assets/document-symbols.png\"}{\"insertText\":\"assets/inlay-hints.png\",\"kind\":17,\"label\":\"assets/inlay-hints.png\"}|}) 375 - completions 376 - 377 - (* let test_uri () = *) 378 - (* Alcotest.(check string) *) 379 - (* "" *) 380 - (* "" *) 381 - (* "" *) 382 - 383 - let () = 384 - Random.self_init (); 385 - Printexc.record_backtrace true; 386 - Logs.set_reporter (Logs_fmt.reporter ()); 387 - Logs.set_level (Some Debug); 388 - let@ env = Eio_main.run in 389 - let@ () = Reporter.easy_run in 390 - let config = Config_parser.parse_forest_config_file "forest.toml" in 391 - let forest = Driver.batch_run ~env ~config ~dev: true in 392 - let lsp_io = LspEio.init env in 393 - let init = Lsp_state.{forest; lsp_io; should_shutdown = false;} in 394 - let dirs = Eio_util.paths_of_dirs ~env config.trees in 395 - let position = L.Position.create ~line: 17 ~character: 1 in 396 - let test_env = { 397 - dirs; 398 - config; 399 - position; 400 - } 401 - in 402 - let@ () = Test_env.run ~init: test_env in 403 - let@ () = Lsp_state.run ~init in 404 - Alcotest.run 405 - "Test_completion" 406 - [ 407 - "Context", 408 - [ 409 - "find_with_pred", `Quick, test_find_with_prev; 410 - "node_at_pos_with_predecessor_or_parent", `Quick, test_node_at_pos_with_prev_or_parent; 411 - "word_before", `Quick, test_word_before; 412 - ]; 413 - "Analysis", 414 - [ 415 - "contains", `Quick, test_contains; 416 - "node_at", `Quick, test_node_at; 417 - "addr_at", `Quick, test_addr_at; 418 - "word_at", `Quick, test_word_at; 419 - "get_enclosing_group", `Quick, (test_enclosing_group ~env); 420 - ]; 421 - "Completion", 422 - [ 423 - "completion_type", `Quick, (test_completion_types ~env); 424 - ]; 425 - "subtree_completion", 426 - [ 427 - "text", `Quick, test_subtree_completion_text; 428 - "code", `Quick, test_subtree_completion_code; 429 - ]; 430 - "asset_completion", 431 - [ 432 - "text", `Quick, test_asset_completion_text; 433 - "syn", `Quick, test_asset_completion_syn; 434 - ]; 435 - "uri", 436 - [ 437 - "uri_completion", `Quick, test_uri_completion; 438 - ]; 439 - ]
-314
lib/language_server/test/Test_lsp.ml
··· 1 - (* 2 - * SPDX-FileCopyrightText: 2024 The Forester Project Contributors 3 - * 4 - * SPDX-License-Identifier: GPL-3.0-or-later 5 - *) 6 - 7 - open Forester_prelude 8 - open Forester_core 9 - open Forester_compiler 10 - open Forester_frontend 11 - open Forester_lsp 12 - open Forester_test 13 - 14 - open struct module L = Lsp.Types end 15 - 16 - let test_code_actions () = 17 - let@ () = Reporter.easy_run in 18 - let env = Test_env.get () in 19 - let textDocument = find_doc env "tfmt-0005" in 20 - let params = 21 - L.CodeActionParams.create 22 - ~context: (L.CodeActionContext.create ~diagnostics: [] ()) 23 - ~textDocument 24 - ~range: (L.Range.create ~start: env.position ~end_: env.position) 25 - () 26 - in 27 - let result = 28 - Code_action.compute params |> function 29 - | None -> assert false 30 - | Some actions -> List.map (function `CodeAction a -> a | _ -> assert false) actions 31 - in 32 - Alcotest.(check int) 33 - "" 34 - 2 35 - (List.length result) 36 - 37 - let test_call_hierarchy () = 38 - let@ () = Reporter.easy_run in 39 - let env = Test_env.get () in 40 - let textDocument = find_doc env "tfmt-0005" in 41 - let params = 42 - L.CallHierarchyPrepareParams.create 43 - ~textDocument 44 - ~position: env.position 45 - () 46 - in 47 - let result = Call_hierarchy.compute params in 48 - Alcotest.(check @@ option @@ list unit) 49 - "" 50 - None 51 - result 52 - 53 - let test_change_configuration () = 54 - let@ () = Reporter.easy_run in 55 - (* Eio.Path.save ~create: *) 56 - let settings = `Assoc ["configuration_file", `String "other.toml"] in 57 - let params = L.DidChangeConfigurationParams.create ~settings in 58 - let result = Change_configuration.compute params in 59 - Alcotest.(check unit) 60 - "" 61 - result 62 - () 63 - 64 - let location = 65 - (module struct 66 - type t = L.Location.t 67 - let pp fmt t = Yojson.Safe.pp fmt (L.Location.yojson_of_t t) 68 - let equal = (=) 69 - end: Alcotest.TESTABLE with type t = L.Location.t) 70 - 71 - let test_definitions () = 72 - let@ () = Reporter.easy_run in 73 - let path = find_tree "tfmt-0005" in 74 - let textDocument : L.TextDocumentIdentifier.t = {uri = Lsp.Uri.of_path path} in 75 - let position = L.Position.create ~line: 16 ~character: 13 in 76 - let params = L.DefinitionParams.create ~position ~textDocument () in 77 - let result = 78 - Definitions.compute params |> function 79 - | Some (`Location locations) -> locations 80 - | Some (`LocationLink _location_links) -> 81 - assert false 82 - (* location_links *) 83 - | None -> assert false 84 - in 85 - Alcotest.(check int) "" 1 (List.length result); 86 - let start = L.Position.create ~character: 1 ~line: 0 in 87 - let end_ = L.Position.create ~character: 1 ~line: 0 in 88 - let range = L.Range.create ~start ~end_ in 89 - let uri = Lsp.Uri.of_path @@ find_tree "tfmt-0006" in 90 - Alcotest.(check location) 91 - "" 92 - (L.Location.create ~range ~uri) 93 - (List.hd result) 94 - 95 - let test_code_lens () = 96 - let@ () = Reporter.easy_run in 97 - let env = Test_env.get () in 98 - let textDocument = find_doc env "tfmt-0005" in 99 - let params = L.CodeLensParams.create ~textDocument () in 100 - let result = List.length @@ Code_lens.compute params in 101 - Alcotest.(check int) "" 0 result 102 - 103 - let test_completion () = 104 - let@ () = Reporter.easy_run in 105 - let env = Test_env.get () in 106 - let position = env.position in 107 - let textDocument = find_doc env "tfmt-0005" in 108 - let params = L.CompletionParams.create ~position ~textDocument () in 109 - let result = 110 - Completion.compute params |> function 111 - | Some (`CompletionList completions) -> List.length completions.items 112 - | None -> -1 113 - in 114 - Alcotest.(check int) 115 - "" 116 - 0 117 - result 118 - 119 - let test_did_change () = 120 - let@ () = Reporter.easy_run in 121 - let env = Test_env.get () in 122 - let textDocument = find_doc env "tfmt-0005" in 123 - let params = 124 - L.DidChangeTextDocumentParams.create 125 - ~contentChanges: [] 126 - ~textDocument: ({uri = textDocument.uri; version = 2}) 127 - in 128 - let result = Did_change.compute params in 129 - Alcotest.(check unit) 130 - "" 131 - () 132 - result 133 - 134 - let test_did_open () = 135 - let@ () = Reporter.easy_run in 136 - let env = Test_env.get () in 137 - let textDocument = find_doc env "tfmt-0005" in 138 - let params = 139 - L.DidOpenTextDocumentParams.create 140 - ~textDocument: { 141 - uri = textDocument.uri; 142 - languageId = "forester"; 143 - text = "\\title{hello}"; 144 - version = 1; 145 - } 146 - in 147 - let result = Did_open.compute params in 148 - Alcotest.(check unit) 149 - "" 150 - () 151 - result 152 - 153 - let test_document_link () = 154 - let _document_link = 155 - (module struct 156 - type t = L.DocumentLink.t 157 - let pp fmt t = Yojson.Safe.pp fmt (L.DocumentLink.yojson_of_t t) 158 - let equal = (=) 159 - end: Alcotest.TESTABLE with type t = L.DocumentLink.t) 160 - in 161 - let@ () = Reporter.easy_run in 162 - let env = Test_env.get () in 163 - let textDocument = find_doc env "jms-0052" in 164 - let params = L.DocumentLinkParams.create ~textDocument () in 165 - let Lsp_state.{forest; _} = Lsp_state.get () in 166 - (* URI.Tbl.iter *) 167 - (* (fun uri tree -> Logs.debug (fun m -> m "%a ~> %s" URI.pp uri (Tree.pp_stage tree))) *) 168 - (* forest.index; *) 169 - URI.Tbl.iter 170 - (fun _ diag -> List.iter Reporter.Tty.display diag) 171 - forest.diagnostics; 172 - let result = Document_link.compute params in 173 - Alcotest.(check int) 174 - "" 175 - 10 176 - (List.length @@ Option.get result) 177 - 178 - let test_document_symbols () = 179 - let@ () = Reporter.easy_run in 180 - let _document_symbol = 181 - (module struct 182 - type t = L.DocumentSymbol.t 183 - let pp fmt t = Yojson.Safe.pp fmt (L.DocumentSymbol.yojson_of_t t) 184 - let equal = (=) 185 - end: Alcotest.TESTABLE with type t = L.DocumentSymbol.t) 186 - in 187 - let env = Test_env.get () in 188 - let textDocument = find_doc env "jms-0052" in 189 - let params = L.DocumentSymbolParams.create ~textDocument () in 190 - let `DocumentSymbol result = Option.get @@ Document_symbols.compute params in 191 - Alcotest.(check int) 192 - "" 193 - 29 194 - (List.length result) 195 - 196 - let test_highlight () = 197 - let@ () = Reporter.easy_run in 198 - let _document_highlight = 199 - (module struct 200 - type t = L.DocumentHighlight.t 201 - let pp fmt t = Yojson.Safe.pp fmt (L.DocumentHighlight.yojson_of_t t) 202 - let equal = (=) 203 - end: Alcotest.TESTABLE with type t = L.DocumentHighlight.t) 204 - in 205 - let env = Test_env.get () in 206 - let textDocument = find_doc env "jms-0052" in 207 - let params = L.DocumentHighlightParams.create ~position: env.position ~textDocument () in 208 - let result = Highlight.compute params in 209 - Alcotest.(check int) 210 - "" 211 - 48 212 - (List.length @@ Option.get result) 213 - 214 - let test_hover () = 215 - let@ () = Reporter.easy_run in 216 - let env = Test_env.get () in 217 - let hover = 218 - (module struct 219 - type t = L.Hover.t 220 - let pp fmt t = Yojson.Safe.pp fmt (L.Hover.yojson_of_t t) 221 - let equal = (=) 222 - end: Alcotest.TESTABLE with type t = L.Hover.t) 223 - in 224 - let textDocument = find_doc env "jms-0052" in 225 - let params = L.HoverParams.create ~position: {character = 12; line = 32;} ~textDocument () in 226 - let result = Hover.compute params in 227 - let expected = 228 - Some 229 - ( 230 - L.Hover.create 231 - ~contents: ( 232 - `MarkupContent 233 - { 234 - kind = L.MarkupKind.Markdown; 235 - value = "In this section, we will walk through the installation of the Forester software.<omitted content: System requirements of Forester><omitted content: Installing the Forester software>" 236 - } 237 - ) 238 - () 239 - ) 240 - in 241 - Alcotest.(check @@ option hover) 242 - "" 243 - expected 244 - result 245 - 246 - let test_inlay_hint () = 247 - let@ () = Reporter.easy_run in 248 - let env = Test_env.get () in 249 - let _inlay_hint = 250 - (module struct 251 - type t = L.InlayHint.t 252 - let pp fmt t = Yojson.Safe.pp fmt (L.InlayHint.yojson_of_t t) 253 - let equal = (=) 254 - end: Alcotest.TESTABLE with type t = L.InlayHint.t) 255 - in 256 - let textDocument = find_doc env "jms-0052" in 257 - let params = L.InlayHintParams.create ~range: (L.Range.create ~start: env.position ~end_: env.position) ~textDocument () in 258 - let result = Inlay_hint.compute params in 259 - Alcotest.(check int) 260 - "" 261 - 25 262 - (List.length @@ Option.get result) 263 - 264 - let test_workspace_symbols () = 265 - let@ () = Reporter.easy_run in 266 - let params = L.WorkspaceSymbolParams.create ~query: "foo" () in 267 - let result = Option.get @@ Workspace_symbols.compute params in 268 - Alcotest.(check int) 269 - "" 270 - 151 271 - (List.length result) 272 - 273 - let () = 274 - Random.self_init (); 275 - Printexc.record_backtrace true; 276 - Logs.set_reporter (Logs_fmt.reporter ()); 277 - Logs.set_level (Some Debug); 278 - let@ env = Eio_main.run in 279 - let@ () = Reporter.easy_run in 280 - let config = Config_parser.parse_forest_config_file "forest.toml" in 281 - let forest = Driver.batch_run ~env ~config ~dev: true in 282 - let lsp_io = LspEio.init env in 283 - let init = Lsp_state.{forest; lsp_io; should_shutdown = false;} in 284 - let dirs = Eio_util.paths_of_dirs ~env config.trees in 285 - let position = L.Position.create ~line: 17 ~character: 1 in 286 - let test_env = { 287 - dirs; 288 - config; 289 - position; 290 - } 291 - in 292 - let@ () = Test_env.run ~init: test_env in 293 - let@ () = Lsp_state.run ~init in 294 - Alcotest.run 295 - "Test_lsp" 296 - [ 297 - "Handlers", 298 - [ 299 - "call hierarchy", `Quick, test_call_hierarchy; 300 - "change configuration", `Quick, test_change_configuration; 301 - "code actions", `Quick, test_code_actions; 302 - "code lens", `Quick, test_code_lens; 303 - "completion", `Quick, test_completion; 304 - "definitions", `Quick, test_definitions; 305 - "did change", `Quick, test_did_change; 306 - "did open", `Quick, test_did_open; 307 - "document link", `Quick, test_document_link; 308 - "document symbols", `Quick, test_document_symbols; 309 - "highlight", `Quick, test_highlight; 310 - "hover", `Quick, test_hover; 311 - "inlay hint", `Quick, test_inlay_hint; 312 - "workspace symbols", `Quick, test_workspace_symbols; 313 - ] 314 - ]
-47
lib/language_server/test/dune
··· 1 - ;;; SPDX-FileCopyrightText: 2024 The Forester Project Contributors 2 - ;;; 3 - ;;; SPDX-License-Identifier: GPL-3.0-or-later 4 - 5 - (cram 6 - (deps test.lua %{bin:forester} %{bin:nvim} %{bin:test-lsp})) 7 - 8 - (rule 9 - (alias runtest) 10 - (deps %{bin:test-lsp}) 11 - (targets) 12 - (action 13 - (progn 14 - (run git clone https://git.sr.ht/~jonsterling/forester-notes.org) 15 - (chdir 16 - forester-notes.org 17 - (progn 18 - (run git checkout 73e99405b6d243aca116e5b162a69dd1e4fe6343) 19 - (run %{bin:test-completion}) 20 - (run %{bin:test-lsp})))))) 21 - 22 - (executables 23 - (names Test_lsp Test_completion) 24 - (public_names test-lsp test-completion) 25 - (preprocess 26 - (pps ppx_yojson_conv ppx_deriving.show)) 27 - (libraries 28 - asai 29 - alcotest 30 - algaeff 31 - fmt 32 - logs 33 - logs.fmt 34 - eio 35 - eio_main 36 - eio.core 37 - eio.unix 38 - lsp 39 - yojson 40 - yuujinchou 41 - str 42 - forester.test 43 - forester.prelude 44 - forester.core 45 - forester.compiler 46 - forester.frontend 47 - forester.language_server))
-25
lib/language_server/test/test.lua
··· 1 - -- SPDX-FileCopyrightText: 2024 The Forester Project Contributors 2 - -- 3 - -- SPDX-License-Identifier: GPL-3.0-or-later 4 - 5 - vim.filetype.add({ extension = { tree = "forester" } }) 6 - 7 - vim.cmd("edit trees/index.tree") 8 - 9 - local client_id = vim.lsp.start({ 10 - name = "forester-lsp", 11 - cmd = { "forester", "lsp" }, 12 - root_dir = vim.fs.root(0, { "forest.toml" }), 13 - }) 14 - 15 - vim.print(string.format("client_id: %d", client_id)) 16 - vim.print(string.format("filetype: %s", vim.bo.filetype)) 17 - 18 - local bufnr = vim.api.nvim_get_current_buf() 19 - 20 - vim.print(vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)) 21 - 22 - vim.print(vim.lsp.get_clients()) 23 - 24 - local symbols = vim.lsp.buf.document_symbol() 25 - vim.print(vim.inspect(symbols))
-14
lib/language_server/test/test.t
··· 1 - SPDX-FileCopyrightText: 2024 The Forester Project Contributors 2 - 3 - SPDX-License-Identifier: GPL-3.0-or-later 4 - 5 - $ git clone https://git.sr.ht/~jonsterling/forester-notes.org 6 - Cloning into 'forester-notes.org'... 7 - $ cd forester-notes.org 8 - $ nvim --headless --clean -l ../test.lua 9 - client_id: 1 10 - filetype: forester 11 - { "\\title{Forester}", "", "\\p{\\em{Forester} is a tool for authoring, exploring, and sharing scientific and mathematical hypertexts. It is your lab notebook, your journal, your blackboard, and the home of your lecture notes.}", "", "\\p{Forester is maintained by [[jonmsterling]] and [[kentookura]].}", "", "\\ul{", " \\li{[Project information](0065)}", " \\li{[Forester blog](30FM)}", " \\li{[Presentations](5CDY)}", " \\li{[Release notes](005P)}", "}", "", "\\syndicate-query-as-json-blob{forester-notes.org}{", " \\datalog{", " ?X -: {\\rel/in-host ?X '{www.forester-notes.org}}", " }", "}" } 12 - {} 13 - nil 14 -