diff options
| author | Nathaniel Saxe <NathanielSaxophone@gmail.com> | 2026-02-03 13:36:26 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-02-03 13:36:26 -0500 |
| commit | 358a0d4df11731e18231da055813e7e6301ce4db (patch) | |
| tree | 3969d79743e1c1c2a3b5614a8579c040e31b6b5d /tests | |
| parent | 1dddd343a6e2a70cba078379dcfde0d62cd28a7c (diff) | |
| parent | 68f7e739157f84c70d368c55d55f4996a61008e9 (diff) | |
Merge branch 'master' into master
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/action_invert_if_test.odin | 400 | ||||
| -rw-r--r-- | tests/completions_test.odin | 207 | ||||
| -rw-r--r-- | tests/definition_test.odin | 53 | ||||
| -rw-r--r-- | tests/hover_test.odin | 100 | ||||
| -rw-r--r-- | tests/signatures_test.odin | 38 |
5 files changed, 764 insertions, 34 deletions
diff --git a/tests/action_invert_if_test.odin b/tests/action_invert_if_test.odin new file mode 100644 index 0000000..bb12ad9 --- /dev/null +++ b/tests/action_invert_if_test.odin @@ -0,0 +1,400 @@ +package tests + +import "core:testing" + +import test "src:testing" + +INVERT_IF_ACTION :: "Invert if" + +@(test) +action_invert_if_simple :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + +main :: proc() { + x := 5 + if x{*} >= 0 { + foo() + } +} +`, + packages = {}, + } + + test.expect_action(t, &source, {INVERT_IF_ACTION}) +} + +@(test) +action_invert_if_simple_edit :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + +main :: proc() { + x := 5 + if x{*} >= 0 { + foo() + } +} +`, + packages = {}, + } + + expected := `if x < 0 { + } else { + foo() + }` + + test.expect_action_with_edit(t, &source, INVERT_IF_ACTION, expected) +} + +@(test) +action_invert_if_with_else :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + +main :: proc() { + x := 5 + if x{*} == 0 { + foo() + } else { + bar() + } +} +`, + packages = {}, + } + + test.expect_action(t, &source, {INVERT_IF_ACTION}) +} + +@(test) +action_invert_if_with_else_edit :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + +main :: proc() { + x := 5 + if x{*} == 0 { + foo() + } else { + bar() + } +} +`, + packages = {}, + } + + expected := `if x != 0 { + bar() + } else { + foo() + }` + + test.expect_action_with_edit(t, &source, INVERT_IF_ACTION, expected) +} + +@(test) +action_invert_if_with_init :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + +main :: proc() { + if x{*} := foo(); x < 0 { + bar() + } +} +`, + packages = {}, + } + + test.expect_action(t, &source, {INVERT_IF_ACTION}) +} + +@(test) +action_invert_if_with_init_edit :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + +main :: proc() { + if x{*} := foo(); x < 0 { + bar() + } +} +`, + packages = {}, + } + + expected := `if x := foo(); x >= 0 { + } else { + bar() + }` + + test.expect_action_with_edit(t, &source, INVERT_IF_ACTION, expected) +} + +@(test) +action_invert_if_not_on_if :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + +main :: proc() { + x :={*} 5 +} +`, + packages = {}, + } + + // Should not have the invert action when not on an if statement + test.expect_action(t, &source, {}) +} + + +@(test) +action_invert_if_inside_of_statement :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + +main :: proc() { + if x != 0 { + foo{*}() + } +} +`, + packages = {}, + } + + test.expect_action(t, &source, {}) +} + +@(test) +action_invert_if_not_eq :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + +main :: proc() { + if x{*} != 0 { + foo() + } +} +`, + packages = {}, + } + + expected := `if x == 0 { + } else { + foo() + }` + + test.expect_action_with_edit(t, &source, INVERT_IF_ACTION, expected) +} + +@(test) +action_invert_if_lt :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + +main :: proc() { + if x{*} < 5 { + foo() + } +} +`, + packages = {}, + } + + expected := `if x >= 5 { + } else { + foo() + }` + + test.expect_action_with_edit(t, &source, INVERT_IF_ACTION, expected) +} + +@(test) +action_invert_if_gt :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + +main :: proc() { + if x{*} > 5 { + foo() + } +} +`, + packages = {}, + } + + expected := `if x <= 5 { + } else { + foo() + }` + + test.expect_action_with_edit(t, &source, INVERT_IF_ACTION, expected) +} + +@(test) +action_invert_if_le :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + +main :: proc() { + if x{*} <= 5 { + foo() + } +} +`, + packages = {}, + } + + expected := `if x > 5 { + } else { + foo() + }` + + test.expect_action_with_edit(t, &source, INVERT_IF_ACTION, expected) +} + +@(test) +action_invert_if_negated :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + +main :: proc() { + if !x{*} { + foo() + } +} +`, + packages = {}, + } + + expected := `if x { + } else { + foo() + }` + + test.expect_action_with_edit(t, &source, INVERT_IF_ACTION, expected) +} + +@(test) +action_invert_if_boolean :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + +main :: proc() { + if x{*} { + foo() + } +} +`, + packages = {}, + } + + expected := `if !x { + } else { + foo() + }` + + test.expect_action_with_edit(t, &source, INVERT_IF_ACTION, expected) +} + +@(test) +action_invert_if_else_if_chain :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + +main :: proc() { + x := something() + if x{*} > 0 { + statement1() + } else if x < 0 { + statement2() + } else { + statement3() + } +} +`, + packages = {}, + } + + expected := `if x <= 0 { + if x < 0 { + statement2() + } else { + statement3() + } + } else { + statement1() + }` + + test.expect_action_with_edit(t, &source, INVERT_IF_ACTION, expected) +} + +@(test) +action_invert_if_not_on_else_if :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + +main :: proc() { + x := something() + if x > 0 { + statement1() + } else if x{*} < 0 { + statement2() + } else { + statement3() + } +} +`, + packages = {}, + } + + // Should not have the invert action when on an else-if statement + test.expect_action(t, &source, {}) +} + +@(test) +action_invert_if_not_on_else :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + +main :: proc() { + x := something() + if x > 0 { + statement1() + } else { + statement3(){*} + } +} +`, + packages = {}, + } + + // Should not have the invert action when in the else block (not on an if) + test.expect_action(t, &source, {}) +} + +@(test) +action_invert_if_nested_in_else_if_body :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + +main :: proc() { + x := something() + if x > 0 { + statement1() + } else if x < 0 { + if y{*} > 0 { + statement2() + } + } else { + statement3() + } +} +`, + packages = {}, + } + + // Should have the invert action for an if statement nested inside an else-if body + test.expect_action(t, &source, {INVERT_IF_ACTION}) +} diff --git a/tests/completions_test.odin b/tests/completions_test.odin index 033813b..56553c3 100644 --- a/tests/completions_test.odin +++ b/tests/completions_test.odin @@ -28,7 +28,7 @@ ast_simple_struct_completion :: proc(t: ^testing.T) { t, &source, ".", - {"My_Struct.one: int", "My_Struct.two: int\n// test comment", "My_Struct.three: int"}, + {"My_Struct.one: int", "My_Struct.two: int\n---\ntest comment", "My_Struct.three: int"}, ) } @@ -3296,7 +3296,7 @@ ast_completion_struct_documentation :: proc(t: ^testing.T) { packages = packages[:], } - test.expect_completion_docs(t, &source, "", {"Foo.bazz: my_package.My_Struct\n// bazz"}) + test.expect_completion_docs(t, &source, "", {"Foo.bazz: my_package.My_Struct\n---\nbazz"}) } @(test) @@ -3417,7 +3417,7 @@ ast_completion_poly_struct_another_package :: proc(t: ^testing.T) { packages = packages[:], } - test.expect_completion_docs(t, &source, "", {"Runner.state: test.State\n// state"}) + test.expect_completion_docs(t, &source, "", {"Runner.state: test.State\n---\nstate"}) } @(test) @@ -5299,3 +5299,204 @@ ast_completion_struct_using_named_vector_types :: proc(t: ^testing.T) { } test.expect_completion_docs(t, &source, "", {"Foo.bar: [3]f32", "r: f32", "x: f32"}) } + +@(test) +ast_completion_parapoly_struct_with_parapoly_child :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + SomeEnum :: enum { + enumVal1, + enumVal2 + } + + ChildStruct:: struct($enumGeneric: typeid){ + Something : string, + GenericParam: enumGeneric + } + + ParentStruct :: struct($enumGeneric: typeid){ + ParentSomething: string, + Child: ChildStruct(enumGeneric) + } + + TestGenericStructs :: proc(){ + parent : ParentStruct(SomeEnum) = {}; + parent.Child.{*} + } + `, + } + test.expect_completion_docs(t, &source, "", {"ChildStruct.GenericParam: test.SomeEnum", "ChildStruct.Something: string"}) +} + +@(test) +ast_completion_fake_method_simple :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + import "methods" + main :: proc() { + n: int + n.{*} + } + `, + packages = { + { + pkg = "methods", + source = `package methods + double :: proc(x: int) -> int { return x * 2 } + `, + }, + }, + config = {enable_fake_method = true}, + } + // Should show 'double' as a fake method for int + test.expect_completion_labels(t, &source, ".", {"double"}) +} + +@(test) +ast_completion_fake_method_proc_group :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + import "methods" + main :: proc() { + n: int + n.{*} + } + `, + packages = { + { + pkg = "methods", + source = `package methods + add_int :: proc(a, b: int) -> int { return a + b } + add_something :: proc(a: int, b: string) {} + add_float :: proc(a, b: f32) -> f32 { return a + b } + add :: proc { add_float, add_int, add_something } + `, + }, + }, + config = {enable_fake_method = true}, + } + // Should show 'add' (the proc group), not 'add_int' or 'add_something' (individual procs) + test.expect_completion_labels(t, &source, ".", {"add"}, {"add_int", "add_something"}) +} + +@(test) +ast_completion_fake_method_proc_group_only_shows_group :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + import "methods" + main :: proc() { + s: methods.My_Struct + s.{*} + } + `, + packages = { + { + pkg = "methods", + source = `package methods + My_Struct :: struct { x: int } + + do_thing_int :: proc(s: My_Struct, v: int) {} + do_thing_str :: proc(s: My_Struct, v: string) {} + do_thing :: proc { do_thing_int, do_thing_str } + + // standalone proc not in a group + standalone_method :: proc(s: My_Struct) {} + `, + }, + }, + config = {enable_fake_method = true}, + } + // Should show 'do_thing' (group) and 'standalone_method', but NOT 'do_thing_int' or 'do_thing_str' + test.expect_completion_labels(t, &source, ".", {"do_thing", "standalone_method"}, {"do_thing_int", "do_thing_str"}) +} + +@(test) +ast_completion_fake_method_proc_group_with_only_one_proc :: proc(t: ^testing.T) { + // This is to verify that even if a proc group has only one member, + // it still shows up as a group and does not show the individual proc. + source := test.Source { + main = `package test + import "methods" + main :: proc() { + s: methods.My_Struct + s.{*} + } + `, + packages = { + { + pkg = "methods", + source = `package methods + My_Struct :: struct { x: int } + + do_thing_int :: proc(s: My_Struct, v: int) {} + do_thing :: proc { do_thing_int } + + // standalone proc not in a group + standalone_method :: proc(s: My_Struct) {} + `, + }, + }, + config = {enable_fake_method = true}, + } + + test.expect_completion_labels(t, &source, ".", {"do_thing", "standalone_method"}, {"do_thing_int" }) +} + +@(test) +ast_completion_fake_method_builtin_type_uses_builtin_pkg :: proc(t: ^testing.T) { + // This test verifies that fake methods for builtin types (int, f32, string, etc.) + // are correctly looked up using "$builtin" as the package, not the package where + // the variable is declared. Without this fix, the method lookup would fail because: + // - Storage: method stored with key {pkg = "$builtin", name = "int"} + // - Lookup (wrong): would use {pkg = "test", name = "int"} based on variable's declaring package + // - Lookup (correct): uses {pkg = "$builtin", name = "int"} for builtin types + source := test.Source { + main = `package test + import "math_utils" + main :: proc() { + x: f32 + x.{*} + } + `, + packages = { + { + pkg = "math_utils", + source = `package math_utils + square :: proc(v: f32) -> f32 { return v * v } + cube :: proc(v: f32) -> f32 { return v * v * v } + `, + }, + }, + config = {enable_fake_method = true}, + } + // Both methods should appear as fake methods for f32, proving that + // the lookup correctly uses "$builtin" instead of "test" for the package + test.expect_completion_labels(t, &source, ".", {"square", "cube"}) +} + +@(test) +ast_completion_fake_method_proc_group_single_arg_cursor_position :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + import "methods" + main :: proc() { + n: int + n.{*} + } + `, + packages = { + { + pkg = "methods", + source = `package methods + // All members only take a single argument (the receiver) + negate_a :: proc(x: int) -> int { return -x } + negate_b :: proc(x: int) -> int { return 0 - x } + negate :: proc { negate_a, negate_b } + `, + }, + }, + config = {enable_fake_method = true}, + } + // The proc group 'negate' should have cursor AFTER parentheses since no additional args + test.expect_completion_edit_text(t, &source, ".", "negate", "methods.negate(n)$0") +} diff --git a/tests/definition_test.odin b/tests/definition_test.odin index 4810361..fe4cd3b 100644 --- a/tests/definition_test.odin +++ b/tests/definition_test.odin @@ -723,3 +723,56 @@ ast_goto_package_declaration_with_alias :: proc(t: ^testing.T) { test.expect_definition_locations(t, &source, locations[:]) } +@(test) +ast_goto_proc_group_overload_with_selector :: proc(t: ^testing.T) { + packages := make([dynamic]test.Package, context.temp_allocator) + + append(&packages, test.Package{pkg = "my_package", source = `package my_package + push_back :: proc(arr: ^[dynamic]int, val: int) {} + push_back_elems :: proc(arr: ^[dynamic]int, vals: ..int) {} + append :: proc{push_back, push_back_elems} + `}) + source := test.Source { + main = `package test + import mp "my_package" + + main :: proc() { + arr: [dynamic]int + mp.app{*}end(&arr, 1) + } + `, + packages = packages[:], + config = {enable_overload_resolution = true}, + } + // Should go to push_back (line 1, character 3) instead of append (line 3) + // because push_back is the overload being used with a single value argument + locations := []common.Location { + {range = {start = {line = 1, character = 3}, end = {line = 1, character = 12}}}, + } + + test.expect_definition_locations(t, &source, locations[:]) +} + +@(test) +ast_goto_proc_group_overload_identifier :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + push_back :: proc(arr: ^[dynamic]int, val: int) {} + push_back_elems :: proc(arr: ^[dynamic]int, vals: ..int) {} + append :: proc{push_back, push_back_elems} + + main :: proc() { + arr: [dynamic]int + app{*}end(&arr, 1) + } + `, + config = {enable_overload_resolution = true}, + } + // Should go to push_back (line 1, character 2) instead of append (line 3) + // because push_back is the overload being used with a single value argument + locations := []common.Location { + {range = {start = {line = 1, character = 2}, end = {line = 1, character = 11}}}, + } + + test.expect_definition_locations(t, &source, locations[:]) +}
\ No newline at end of file diff --git a/tests/hover_test.odin b/tests/hover_test.odin index 8c39b0f..630f4d7 100644 --- a/tests/hover_test.odin +++ b/tests/hover_test.odin @@ -401,7 +401,7 @@ ast_hover_proc_group :: proc(t: ^testing.T) { packages = {}, } - test.expect_hover(t, &source, "test.add :: proc(a, b: int) -> int\n docs\n\n// comment") + test.expect_hover(t, &source, "test.add :: proc(a, b: int) -> int\n---\ndocs\n---\ncomment") } @(test) @@ -672,7 +672,7 @@ ast_hover_struct_field_complex_definition :: proc(t: ^testing.T) { `, } - test.expect_hover(t, &source, "Foo.bar: ^test.Bar\n Docs\n\n// inline docs") + test.expect_hover(t, &source, "Foo.bar: ^test.Bar\n---\nDocs\n---\ninline docs") } @(test) @@ -1084,7 +1084,7 @@ ast_hover_proc_overloading_named_arg_with_selector_expr_with_another_package :: packages = packages[:], } - test.expect_hover(t, &source, "my_package.foo :: proc(x := 1) -> (_: int, _: bool)\n Docs\n\n// comment") + test.expect_hover(t, &source, "my_package.foo :: proc(x := 1) -> (_: int, _: bool)\n---\nDocs\n---\ncomment") } @(test) @@ -1479,7 +1479,7 @@ ast_hover_proc_comments :: proc(t: ^testing.T) { `, } - test.expect_hover(t, &source, "test.foo :: proc()\n doc\n\n// do foo") + test.expect_hover(t, &source, "test.foo :: proc()\n---\ndoc\n---\ndo foo") } @(test) @@ -1507,7 +1507,7 @@ ast_hover_proc_comments_package :: proc(t: ^testing.T) { packages = packages[:], } - test.expect_hover(t, &source, "my_package.foo :: proc()\n// do foo") + test.expect_hover(t, &source, "my_package.foo :: proc()\n---\ndo foo") } @(test) @@ -1525,7 +1525,7 @@ ast_hover_struct_field_distinct :: proc(t: ^testing.T) { `, } - test.expect_hover(t, &source, "S.fb: test.B\n// type: fb") + test.expect_hover(t, &source, "S.fb: test.B\n---\ntype: fb") } @(test) @@ -2135,7 +2135,7 @@ ast_hover_bit_field_field :: proc(t: ^testing.T) { } `, } - test.expect_hover(t, &source, "Foo.foo_aa: uint | 6\n// last 6 bits") + test.expect_hover(t, &source, "Foo.foo_aa: uint | 6\n---\nlast 6 bits") } @(test) @@ -2154,7 +2154,7 @@ ast_hover_bit_field_variable_with_docs :: proc(t: ^testing.T) { } `, } - test.expect_hover(t, &source, "Foo.foo_a: uint | 2\n doc\n\n// foo a") + test.expect_hover(t, &source, "Foo.foo_a: uint | 2\n---\ndoc\n---\nfoo a") } @(test) @@ -2353,7 +2353,7 @@ ast_hover_struct_field_should_show_docs_and_comments :: proc(t: ^testing.T) { } `, } - test.expect_hover(t, &source, "Foo.a: int\n a docs\n\n// a comment") + test.expect_hover(t, &source, "Foo.a: int\n---\na docs\n---\na comment") } @(test) @@ -2367,7 +2367,7 @@ ast_hover_struct_field_should_show_docs_and_comments_field :: proc(t: ^testing.T } `, } - test.expect_hover(t, &source, "Foo.a: int\n a docs\n\n// a comment") + test.expect_hover(t, &source, "Foo.a: int\n---\na docs\n---\na comment") } @(test) @@ -2388,7 +2388,7 @@ ast_hover_struct_field_should_show_docs_and_comments_struct_types :: proc(t: ^te } `, } - test.expect_hover(t, &source, "Foo.bar: test.Bar\n bar docs\n\n// bar comment") + test.expect_hover(t, &source, "Foo.bar: test.Bar\n---\nbar docs\n---\nbar comment") } @(test) @@ -2407,7 +2407,7 @@ ast_hover_struct_field_should_show_docs_and_comments_procs :: proc(t: ^testing.T } `, } - test.expect_hover(t, &source, "Foo.bar: proc(a: int) -> int\n bar docs\n\n// bar comment") + test.expect_hover(t, &source, "Foo.bar: proc(a: int) -> int\n---\nbar docs\n---\nbar comment") } @(test) @@ -2428,7 +2428,7 @@ ast_hover_struct_field_should_show_docs_and_comments_named_procs :: proc(t: ^tes } `, } - test.expect_hover(t, &source, "Foo.bar: proc(a: int) -> string\n bar docs\n\n// bar comment") + test.expect_hover(t, &source, "Foo.bar: proc(a: int) -> string\n---\nbar docs\n---\nbar comment") } @(test) @@ -2447,7 +2447,7 @@ ast_hover_struct_field_should_show_docs_and_comments_maps :: proc(t: ^testing.T) } `, } - test.expect_hover(t, &source, "Foo.bar: map[int]int\n bar docs\n\n// bar comment") + test.expect_hover(t, &source, "Foo.bar: map[int]int\n---\nbar docs\n---\nbar comment") } @(test) @@ -2466,7 +2466,7 @@ ast_hover_struct_field_should_show_docs_and_comments_bit_sets :: proc(t: ^testin } `, } - test.expect_hover(t, &source, "Foo.bar: bit_set[0 ..< 10]\n bar docs\n\n// bar comment") + test.expect_hover(t, &source, "Foo.bar: bit_set[0 ..< 10]\n---\nbar docs\n---\nbar comment") } @(test) @@ -2490,7 +2490,7 @@ ast_hover_struct_field_should_show_docs_and_comments_unions :: proc(t: ^testing. } `, } - test.expect_hover(t, &source, "Foo.bar: test.Bar\n bar docs\n\n// bar comment") + test.expect_hover(t, &source, "Foo.bar: test.Bar\n---\nbar docs\n---\nbar comment") } @(test) @@ -2509,7 +2509,7 @@ ast_hover_struct_field_should_show_docs_and_comments_multipointers :: proc(t: ^t } `, } - test.expect_hover(t, &source, "Foo.bar: [^]int\n bar docs\n\n// bar comment") + test.expect_hover(t, &source, "Foo.bar: [^]int\n---\nbar docs\n---\nbar comment") } @(test) @@ -2528,7 +2528,7 @@ ast_hover_struct_field_should_show_docs_and_comments_dynamic_arrays :: proc(t: ^ } `, } - test.expect_hover(t, &source, "Foo.bar: [dynamic]int\n bar docs\n\n// bar comment") + test.expect_hover(t, &source, "Foo.bar: [dynamic]int\n---\nbar docs\n---\nbar comment") } @(test) @@ -2547,7 +2547,7 @@ ast_hover_struct_field_should_show_docs_and_comments_fixed_arrays :: proc(t: ^te } `, } - test.expect_hover(t, &source, "Foo.bar: [5]int\n bar docs\n\n// bar comment") + test.expect_hover(t, &source, "Foo.bar: [5]int\n---\nbar docs\n---\nbar comment") } @(test) @@ -2566,7 +2566,7 @@ ast_hover_struct_field_should_show_docs_and_comments_matrix :: proc(t: ^testing. } `, } - test.expect_hover(t, &source, "Foo.bar: matrix[4,5]int\n bar docs\n\n// bar comment") + test.expect_hover(t, &source, "Foo.bar: matrix[4,5]int\n---\nbar docs\n---\nbar comment") } @(test) @@ -3191,7 +3191,7 @@ ast_hover_documentation_reexported :: proc(t: ^testing.T) { `, packages = packages[:], } - test.expect_hover(t, &source, "my_package.Foo :: struct{}\n Documentation for Foo") + test.expect_hover(t, &source, "my_package.Foo :: struct{}\n---\nDocumentation for Foo") } @(test) @@ -3217,7 +3217,7 @@ ast_hover_override_documentation_reexported :: proc(t: ^testing.T) { `, packages = packages[:], } - test.expect_hover(t, &source, "my_package.Foo :: struct{}\n New docs for Foo") + test.expect_hover(t, &source, "my_package.Foo :: struct{}\n---\nNew docs for Foo") } @(test) @@ -3495,7 +3495,7 @@ ast_hover_enum_field_directly :: proc(t: ^testing.T) { } `, } - test.expect_hover(t, &source, "test.Foo: .A\n Doc for A and B\n Mulitple lines!\n\n// comment for A and B") + test.expect_hover(t, &source, "test.Foo: .A\n---\nDoc for A and B\nMulitple lines!\n---\ncomment for A and B") } @(test) @@ -3624,7 +3624,7 @@ ast_hover_bit_set_intersection :: proc(t: ^testing.T) { foo_{*}b := foo_bar & {.Foo} // hover for foo_b `, } - test.expect_hover(t, &source, "test.foo_b: distinct bit_set[Flag]\n// hover for foo_b") + test.expect_hover(t, &source, "test.foo_b: distinct bit_set[Flag]\n---\nhover for foo_b") } @(test) @@ -3638,7 +3638,7 @@ ast_hover_bit_set_union :: proc(t: ^testing.T) { foo_{*}b := {.Foo} | foo_bar // hover for foo_b `, } - test.expect_hover(t, &source, "test.foo_b: distinct bit_set[Flag]\n// hover for foo_b") + test.expect_hover(t, &source, "test.foo_b: distinct bit_set[Flag]\n---\nhover for foo_b") } @(test) @@ -5366,7 +5366,7 @@ ast_hover_parapoly_other_package :: proc(t: ^testing.T) { `, packages = packages[:], } - test.expect_hover(t, &source, "my_package.bar :: proc(_: $T)\n Docs!\n\n// Comment!") + test.expect_hover(t, &source, "my_package.bar :: proc(_: $T)\n---\nDocs!\n---\nComment!") } @(test) @@ -5610,7 +5610,7 @@ ast_hover_local_proc_docs :: proc(t: ^testing.T) { } `, } - test.expect_hover(t, &source, "test.foo :: proc()\n foo doc") + test.expect_hover(t, &source, "test.foo :: proc()\n---\nfoo doc") } @(test) @@ -5785,7 +5785,7 @@ ast_hover_nested_proc_docs_tabs :: proc(t: ^testing.T) { } `, } - test.expect_hover(t, &source, "test.foo :: proc()\n\nDocs!\n\tDocs2\n") + test.expect_hover(t, &source, "test.foo :: proc()\n---\nDocs!\n\tDocs2\n") } @(test) @@ -5802,7 +5802,7 @@ ast_hover_nested_proc_docs_spaces :: proc(t: ^testing.T) { } `, } - test.expect_hover(t, &source, "test.foo :: proc()\n\nDocs!\n Docs2\n") + test.expect_hover(t, &source, "test.foo :: proc()\n---\nDocs!\n Docs2\n") } @(test) @@ -5825,7 +5825,7 @@ ast_hover_propagate_docs_alias_in_package :: proc(t: ^testing.T) { `, packages = packages[:], } - test.expect_hover(t, &source, "my_package.bar :: proc()\n Docs!\n\n// Comment!") + test.expect_hover(t, &source, "my_package.bar :: proc()\n---\nDocs!\n---\nComment!") } @(test) @@ -5849,7 +5849,7 @@ ast_hover_propagate_docs_alias_in_package_override :: proc(t: ^testing.T) { `, packages = packages[:], } - test.expect_hover(t, &source, "my_package.bar :: proc()\n Overridden\n\n// Comment!") + test.expect_hover(t, &source, "my_package.bar :: proc()\n---\nOverridden\n---\nComment!") } @(test) @@ -5986,6 +5986,44 @@ ast_hover_proc_group_bitset :: proc(t: ^testing.T) { } test.expect_hover(t, &source, "test.Foo: .A") } + +@(test) +ast_hover_soa_struct_field_indexed :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + Foo :: struct{} + + Bar :: struct { + foos: #soa[dynamic]Foo, + } + + bazz :: proc(bar: ^Bar, index: int) { + f{*}oo := &bar.foos[index] + } + `, + } + test.expect_hover(t, &source, "test.foo: #soa^#soa[dynamic]Foo") +} + +@(test) +ast_hover_proc_poly_params :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + foo :: proc($T{*}: int) {} + `, + } + test.expect_hover(t, &source, "test.$T: int") +} + +@(test) +ast_hover_proc_poly_params_where_clause :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + foo :: proc($T: int) where T{*} >= 0 {} + `, + } + test.expect_hover(t, &source, "test.$T: int") +} /* Waiting for odin fix diff --git a/tests/signatures_test.odin b/tests/signatures_test.odin index d81a4da..4ee9ff3 100644 --- a/tests/signatures_test.odin +++ b/tests/signatures_test.odin @@ -649,6 +649,44 @@ signature_comp_lit_bit_set :: proc(t: ^testing.T) { ) } +@(test) +signature_comp_lit_struct_field_after_comma :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + Foo :: struct { + A,{*} + B, + } + `, + config = { + enable_comp_lit_signature_help = true, + } + } + + test.expect_signature_labels( + t, + &source, + {}, + ) +} + +@(test) +signature_comp_lit_proc_field_after_comma :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + foo :: proc(a, b,{*}: int) {} + `, + config = { + enable_comp_lit_signature_help = true, + } + } + + test.expect_signature_labels( + t, + &source, + {}, + ) +} /* @(test) signature_function_inside_when :: proc(t: ^testing.T) { |