aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorNathaniel Saxe <NathanielSaxophone@gmail.com>2026-02-03 13:36:26 -0500
committerGitHub <noreply@github.com>2026-02-03 13:36:26 -0500
commit358a0d4df11731e18231da055813e7e6301ce4db (patch)
tree3969d79743e1c1c2a3b5614a8579c040e31b6b5d /tests
parent1dddd343a6e2a70cba078379dcfde0d62cd28a7c (diff)
parent68f7e739157f84c70d368c55d55f4996a61008e9 (diff)
Merge branch 'master' into master
Diffstat (limited to 'tests')
-rw-r--r--tests/action_invert_if_test.odin400
-rw-r--r--tests/completions_test.odin207
-rw-r--r--tests/definition_test.odin53
-rw-r--r--tests/hover_test.odin100
-rw-r--r--tests/signatures_test.odin38
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) {