#[cfg(test)]
mod tests {
    use crate::handlers::test_lib::{ProviderVirtualWorkspace, VirtualHoverResult, check};
    use googletest::prelude::*;

    #[gtest]
    fn test_1() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        check!(ws.check_hover(
            r#"
                ---@param a number 参数a
                ---@return number a 返回值a
                local function delete(a)
                end

                local delete2 = delete
                local delete3 = delete2
                local <??>delete4 = delete3
            "#,
            VirtualHoverResult {
                value: "```lua\nlocal function delete(a: number)\n  -> a: number\n\n```\n\n---\n\n@*param* `a` — 参数a\n\n\n\n@*return* `a`  — 返回值a".to_string(),
            },
        ));

        check!(ws.check_hover(
            r#"
                -- 删除
                ---@param a number 参数a
                ---@return number a 返回值a
                local function delete(a)
                end

                local delete2 = delete
                local delete3 = delete2
                local delete4 = delete3
                local deleteObj = {
                    <??>aaa = delete4
                }
            "#,
            VirtualHoverResult {
                value: "```lua\nlocal function delete(a: number)\n  -> a: number\n\n```\n\n---\n\n删除\n\n@*param* `a` — 参数a\n\n\n\n@*return* `a`  — 返回值a".to_string(),
            },
        ));

        check!(ws.check_hover(
            r#"
                ---@param a number 参数a
                ---@return number a 返回值a
                local function delete(a)
                end

                local delete2 = delete
                local delete3 = delete2
                local delete4 = delete3
                local deleteObj = {
                    aa = delete4
                }

                local deleteObj2 = {
                    <??>aa = deleteObj.aa
                }
            "#,
            VirtualHoverResult {
                value: "```lua\nlocal function delete(a: number)\n  -> a: number\n\n```\n\n---\n\n@*param* `a` — 参数a\n\n\n\n@*return* `a`  — 返回值a".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_2() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        ws.def(
            r#"
                ---@class Game
                ---@field event fun(self: self, owner: "abc"): any 测试1
                ---@field event fun(self: self, owner: "def"): any 测试2
                local Game = {}

                ---说明
                ---@param key string 参数key
                ---@param value string 参数value
                ---@return number ret @返回值
                function Game:add(key, value)
                    self.aaa = 1
                end
            "#,
        );

        check!(ws.check_hover(
            r#"
                ---@type Game
                local game

                local local_a = game.add
                local <??>local_b = local_a
            "#,
            VirtualHoverResult {
                value: "```lua\n(method) Game:add(key: string, value: string)\n  -> ret: number\n\n```\n\n---\n\n说明\n\n@*param* `key` — 参数key\n\n@*param* `value` — 参数value\n\n\n\n@*return* `ret`  — 返回值".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_3() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        ws.def(
            r#"
                ---@class Hover.Test3<T>
                ---@field event fun(self: self, event: "A", key: T)
                ---@field event fun(self: self, event: "B", key: T)
                local Test3 = {}
            "#,
        );

        check!(ws.check_hover(
            r#"
                ---@type Hover.Test3<string>
                local test3

                local <??>event = test3.event
            "#,
            VirtualHoverResult {
                value: "```lua\n(method) Test3:event(event: \"A\", key: string) (+1 overloads)\n```\n\n&nbsp;&nbsp;in class `Hover.Test3`\n\n---\n\n---\n\n```lua\n(method) Test3:event(event: \"B\", key: string)\n```".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_mixed_class_field_and_real_definition() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        check!(ws.check_hover(
            r#"
                ---@class Trigger
                ---@class EventTypeA

                ---@class (partial) GameA
                local M

                -- 注册引擎事件
                ---@param event_type EventTypeA
                ---@param ... any
                ---@return Trigger
                function M:<??>event(event_type, ...)
                end

                ---@class (partial) GameA
                ---@field event fun(self: self, event: "游戏-初始化"): Trigger
                ---@field event fun(self: self, event: "游戏-追帧完成"): Trigger
            "#,
            VirtualHoverResult {
                value: "```lua\n(method) GameA:event(event_type: EventTypeA, ...: any) -> Trigger (+2 overloads)\n```\n\n---\n\n注册引擎事件\n\n---\n\n```lua\n(method) GameA:event(event: \"游戏-初始化\") -> Trigger\n```\n\n```lua\n(method) GameA:event(event: \"游戏-追帧完成\") -> Trigger\n```".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_4() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        check!(ws.check_hover(
            r#"
                ---@class ClosureTest
                ---@field e fun(a: string, b: number)
                local Test

                function Test.<??>e(a, b)
                    A = a
                end
            "#,
            VirtualHoverResult {
                value: "```lua\n(field) ClosureTest.e(a: string, b: number)\n```".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_return_overload_hover() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        check!(
            ws.check_hover(
                r#"
                ---@return_overload true, integer
                ---@return_overload false, string
                local function parse()
                end

                local <??>alias = parse
            "#,
            VirtualHoverResult {
                value: "```lua\nlocal function parse() -> (true|false), (string|integer)\n```\n\n---\n\n@*return_overload* `true, integer`\n\n@*return_overload* `false, string`".to_string(),
            },
        )
        );
        Ok(())
    }

    #[gtest]
    fn test_return_overload_description_hover() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        check!(ws.check_hover(
            r#"
                ---@return_overload true, integer success
                ---@return_overload false, string failed
                local function parse()
                end

                local <??>alias = parse
            "#,
            VirtualHoverResult {
                value: "```lua\nlocal function parse() -> (true|false), (string|integer)\n```\n\n---\n\n@*return_overload* `true, integer` — success\n\n@*return_overload* `false, string` — failed".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_return_overload_call_hover() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        check!(
            ws.check_hover(
                r#"
                ---@class B
                local B

                ---@generic T
                ---@param x T
                ---@return_overload true, T
                ---@return_overload false, string
                local function parse(x)
                end

                pa<??>rse(B)
            "#,
            VirtualHoverResult {
                value: "```lua\nlocal function parse(x: B) -> (true|false), (B|string)\n```\n\n---\n\n@*return_overload* `true, T`\n\n@*return_overload* `false, string`".to_string(),
            },
        )
        );
        Ok(())
    }

    #[gtest]
    fn test_return_overload_hover_short_row_keeps_nil() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        check!(
            ws.check_hover(
                r#"
                ---@param ok boolean
                ---@return_overload true, integer
                ---@return_overload false
                local function maybe(ok)
                end

                local <??>alias = maybe
            "#,
            VirtualHoverResult {
                value: "```lua\nlocal function maybe(ok: boolean) -> (true|false), integer?\n```\n\n---\n\n@*return_overload* `true, integer`\n\n@*return_overload* `false`".to_string(),
            },
        )
        );
        Ok(())
    }

    #[gtest]
    fn test_return_overload_call_hover_short_generic_row_keeps_nil() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        check!(ws.check_hover(
            r#"
                ---@class B
                local B

                ---@generic T
                ---@param x T
                ---@return_overload true, T
                ---@return_overload false
                local function parse(x)
                end

                pa<??>rse(B)
            "#,
            VirtualHoverResult {
                value: "```lua\nlocal function parse(x: B) -> (true|false), B?\n```\n\n---\n\n@*return_overload* `true, T`\n\n@*return_overload* `false`".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_pcall_return_overload_hover() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new_with_init_std_lib();
        check!(ws.check_hover(
            r#"
                --- @param a string
                --- @param b table<string,integer>
                --- @return_overload false, [string,string] comment
                --- @return_overload true, string comment
                local function foo(a, b)
                end

                local a, b = pca<??>ll(foo)
            "#,
            VirtualHoverResult {
                value: "```lua\nfunction pcall(f: sync fun(a: string, b: table<string,integer>) -> ((false|true),((string,string)|string)), a: string, b: table<string,integer>) -> (true|false), (false|true|string), (((string,string)|string))?\n```\n\n---\n\n\nCalls function `f` with the given arguments in *protected mode*. This\nmeans that any error inside `f` is not propagated; instead, `pcall` catches\nthe error and returns a status code. Its first result is the status code (a\nboolean), which is true if the call succeeds without errors. In such case,\n`pcall` also returns all results from the call, after this first result. In\ncase of any error, `pcall` returns **false** plus the error message.\n\n@*return_overload* `true, R ...`\n\n@*return_overload* `false, string`".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_table_field_function_1() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        check!(ws.check_hover(
            r#"
                ---@class T
                ---@field func fun(self:T) 注释注释

                ---@type T
                local t = {
                    func<??> = function(self)

                    end
                }
            "#,
            VirtualHoverResult {
                value: "```lua\n(method) T:func()\n```\n\n---\n\n注释注释".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_issue_499() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        check!(ws.check_hover(
            r#"
                ---@class T
                ---@field a string 注释注释a

                ---@type T
                local t = {
                    a<??> = "a"
                }
            "#,
            VirtualHoverResult {
                value: "```lua\n(field) a: string = \"a\"\n```\n\n---\n\n注释注释a".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_issue_499_2() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        check!(ws.check_hover(
            r#"
                ---@class T
                ---@field func fun(self:string) 注释注释

                ---@type T
                local t = {
                    fu<??>nc = function(self)
                    end,
                }
            "#,
            VirtualHoverResult {
                value: "```lua\n(field) T.func(self: string)\n```\n\n---\n\n注释注释".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_issue_499_3() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        check!(ws.check_hover(
            r#"
                ---@class T
                ---@field func fun(a:string) 注释1
                ---@field func fun(a:number) 注释2

                ---@type T
                local t = {
                    fu<??>nc = function(a)
                    end,
                }
            "#,
            VirtualHoverResult {
                value: "```lua\n(field) T.func(a: string) (+1 overloads)\n```\n\n---\n\n注释1\n\n---\n\n```lua\n(field) T.func(a: number) -- 注释2\n```"
                    .to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_issue_499_4() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        check!(ws.check_hover(
            r#"
                ---@class T
                ---@field func fun(a:string) 注释1
                ---@field func fun(a:number) 注释2

                ---@type T
                local t

                t.fu<??>nc(1)
            "#,
            VirtualHoverResult {
                value: "```lua\n(field) T.func(a: number)\n```\n\n---\n\n注释2".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_table_field_origin_decl() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        check!(ws.check_hover(
            r#"
                ---@class T
                ---@field func fun(a:string) 注释1
                ---@field func fun(a:number) 注释2

                ---@type T
                local t = {
                    func = function(a)
                    end
                }
                local ab<??>c = t.func
            "#,
            VirtualHoverResult {
                value: "```lua\n(field) T.func(a: string) (+1 overloads)\n```\n\n---\n\n注释1\n\n---\n\n```lua\n(field) T.func(a: number) -- 注释2\n```".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_first_generic() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        check!(ws.check_hover(
            r#"
                ---@class Reactive
                local M

                ---@generic T: table
                ---@param target T
                ---@return T
                function M.reac<??>tive(target)
                end
            "#,
            VirtualHoverResult {
                value: "```lua\nfunction Reactive.reactive(target: T) -> T\n```".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_table_field_function() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        check!(ws.check_hover(
            r#"
                local export = {}
                ---@type fun()
                export.NO<??>OP = function() end
            "#,
            VirtualHoverResult {
                value: "```lua\nfunction export.NOOP()\n```".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_return_union_function() -> Result<()> {
        // temp remove the test
        // let mut ws = ProviderVirtualWorkspace::new();
        // check!(ws.check_hover(
        //     r#"
        //         ---@generic T
        //         ---@param initialValue? T
        //         ---@return (fun(): T) | (fun(value: T))
        //         local function signal(initialValue)
        //         end

        //         ---测试
        //         local cou<??>nt = signal(1)
        //     "#,
        //     VirtualHoverResult {
        //         value: "```lua\nfunction count(value: 1)\n```\n\n---\n\n测试\n\n---\n\n```lua\nfunction count() -> 1\n```".to_string(),
        //     },
        // ));
        Ok(())
    }

    #[gtest]
    fn test_require_function() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        ws.def_file(
            "test.lua",
            r#"
                ---测试
                local function signal()
                end

                return {
                    signal = signal
                }
            "#,
        );
        check!(ws.check_hover(
            r#"
                local test = require("test")
                local si<??>gnal = test.signal
            "#,
            VirtualHoverResult {
                value: "```lua\nlocal function signal()\n```\n\n---\n\n测试".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_generic_function() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        ws.def_file(
            "test.lua",
            r#"
                ---@class Observable<T>
                local Observable

                ---@generic R
                ---@param selector fun(value: T, index?: integer): R
                function Observable:select(selector)
                end

                ---@type Observable<integer>
                source = {}
            "#,
        );
        check!(ws.check_hover(
            r#"
                source:<??>select(function(value)
                    return value
                end)
            "#,
            VirtualHoverResult {
                value: "```lua\n(method) Observable:select(selector: fun(value: integer, index: integer?) -> integer)\n```".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_other_file_function() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        ws.def_file(
            "a.lua",
            r#"
                ---测试
                local function zipLatest(...)
                end
                return zipLatest
            "#,
        );
        check!(ws.check_hover(
            r#"
                local zipLatest = require("a")
                <??>zipLatest()
            "#,
            VirtualHoverResult {
                value: "```lua\nlocal function zipLatest(...)\n```\n\n---\n\n测试".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_hover_generic_function_params_description() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        ws.def_file(
            "a.lua",
            r#"
                ---@class RingBuffer<T>
                local RingBuffer = {}

                ---@param index integer 索引
                ---@return T? item
                function RingBuffer:get(index)
                end
            "#,
        );
        check!(ws.check_hover(
            r#"
                ---@type RingBuffer<string>
                local RingBuffer
                RingBuffer:<??>get(1)
            "#,
            VirtualHoverResult {
                value: "```lua\n(method) RingBuffer:get(index: integer) -> string?\n```\n\n---\n\n@*param* `index` — 索引".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_annotation_search() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        ws.def_file(
            "a.lua",
            r#"
                ---@version 5.4
                ---测试
                function test()
                end
            "#,
        );
        check!(ws.check_hover(
            r#"
                <??>test()
            "#,
            VirtualHoverResult {
                value: "```lua\nfunction test()\n```\n\n---\n\n测试".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_field_remove_first() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        check!(ws.check_hover(
            r#"
                ---@class A<T>
                ---@field next fun(value: T) # 测试
                local A = {}

                A.<??>next()
            "#,
            VirtualHoverResult {
                value: "```lua\n(field) A.next(value: T)\n```\n\n---\n\n测试".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_first_strtpl() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        check!(ws.check_hover(
            r#"
                ---@class Fix
                local Fix

                ---@generic T
                ---@param  name `T`
                function Fix.ad<??>d(name)
                end
            "#,
            VirtualHoverResult {
                value: "```lua\nfunction Fix.add(name: T)\n```".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_call_1() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        check!(ws.check_hover(
            r#"
                ---@class A
                local A
                ---@class B
                local B

                ---@generic T
                ---@param x T
                function A.add(x)
                end

                A.ad<??>d(B)
            "#,
            VirtualHoverResult {
                value: "```lua\nfunction A.add(x: B)\n```".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_call_hover_shows_all_overloads_when_no_match() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        check!(ws.check_hover(
            r#"
                ---@overload fun(a: string): string
                ---@overload fun(a: number): number
                ---@param a table
                function test(a)
                end

                te<??>st(true)
            "#,
            VirtualHoverResult {
                value: "```lua\nfunction test(a: table) (+2 overloads)\n```\n\n---\n\n---\n\n```lua\nfunction test(a: string) -> string\n```\n\n```lua\nfunction test(a: number) -> number\n```".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_call_hover_shows_all_generic_overloads_when_no_match() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        check!(ws.check_hover(
            r#"
                ---@generic T, U
                ---@overload fun(value: string, fallback: T): T, U
                ---@overload fun(value: number, fallback: T): T, U
                ---@param value table
                ---@param fallback T
                ---@return T
                ---@return U
                function generic_test(value, fallback)
                end

                generic_te<??>st(true, false)
            "#,
            VirtualHoverResult {
                value: "```lua\nfunction generic_test(value: table, fallback: boolean) -> boolean, unknown (+2 overloads)\n```\n\n---\n\n---\n\n```lua\nfunction generic_test(value: string, fallback: boolean) -> boolean, unknown\n```\n\n```lua\nfunction generic_test(value: number, fallback: boolean) -> boolean, unknown\n```".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_fix_method_1() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        check!(ws.check_hover(
            r#"
            ---@class ClassControl
            local ClassControl = {}

            ---@generic T
            ---@param name `T`|T
            function ClassControl.ne<??>w(name)
            end
            "#,
            VirtualHoverResult {
                value: "```lua\nfunction ClassControl.new(name: T)\n```".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_fix_global_index_function_1() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        check!(ws.check_hover(
            r#"
            M = {}
            function M.te<??>st()
            end

            "#,
            VirtualHoverResult {
                value: "```lua\nfunction M.test()\n```".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_fix_global_index_function_2() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        // TODO: 构建完整的访问路径
        check!(ws.check_hover(
            r#"
            M = {
                K = {}
            }
            M.K.<??>Value = function()
            end
            "#,
            VirtualHoverResult {
                value: "```lua\nfunction Value()\n```".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_fix_ref() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        ws.def(
            r#"
            ---@class Player
            ---@field name string

            ---@param player Player
            function CreatePlayer(player)
            end
        "#,
        );
        check!(ws.check_hover(
            r#"
            Creat<??>ePlayer({name = "John"})
            "#,
            VirtualHoverResult {
                value: "```lua\nfunction CreatePlayer(player: Player)\n```".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_intersection_type() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        ws.def(
            r#"
                ---@class Matchers<T>
                ---@field toBe fun(self: self, expected: any)

                ---@class Assertions<T>: Matchers<T>
                Assertions = {}
        "#,
        );
        check!(ws.check_hover(
            r#"
            Assertions:to<??>Be(1)
            "#,
            VirtualHoverResult {
                value: "```lua\n(method) Matchers:toBe(expected: any)\n```".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_table_const_method() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        check!(ws.check_hover(
            r#"
            local M = {}

            ---@param x number
            function M:abc<??>d(x)
            end

            M:abcd(1)
            "#,
            VirtualHoverResult {
                value: "```lua\n(method) M:abcd(x: number)\n```".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_regression_generic_table_field_should_be_function_owner() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        ws.def(
            r#"
                ---@class ObserverParams<T>
                ---@field next fun(value: T): T # 测试

                ---@generic T
                ---@param params ObserverParams<T>
                function observe(params)
                end
            "#,
        );
        check!(
            ws.check_hover(
                r#"
                observe({
                    ---@param value string
                    <??>next = function(value)
                        return value
                    end
                })
            "#,
                VirtualHoverResult {
                    value: "```lua\n(field) ObserverParams.next(value: string) -> string\n```\n\n---\n\n测试"
                        .to_string(),
                },
            )
        );
        Ok(())
    }

    #[gtest]
    fn test_generic_table_field_value_without_inference_source() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        ws.def(
            r#"
                ---@class ObserverParams<T>
                ---@field next fun(value: T): T # 测试

                ---@generic T
                ---@param params ObserverParams<T>
                function observe(params)
                end
            "#,
        );
        check!(
            ws.check_hover(
                r#"
                observe({
                    <??>next = 1
                })
            "#,
                VirtualHoverResult {
                    value: "```lua\n(field) ObserverParams.next(value: unknown) -> unknown\n```\n\n---\n\n测试"
                        .to_string(),
                },
            )
        );
        Ok(())
    }

    #[gtest]
    fn test_generic_table_field_hover_filters_union_parent_without_field() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        ws.def(
            r#"
                ---@class ObserverParams<T>
                ---@field next fun(value: T): T # 测试

                ---@class OtherParams1
                ---@field other string

                ---@class OtherParams2<T>
                ---@field wait fun(value: T): T # 测试2
            "#,
        );
        check!(
            ws.check_hover(
                r#"
                ---@type OtherParams2<number>|ObserverParams<string>|OtherParams1
                local params = {
                    <??>next = function(value)
                        return value
                    end
                }
            "#,
                VirtualHoverResult {
                    value: "```lua\n(field) ObserverParams.next(value: string) -> string\n```\n\n---\n\n测试"
                        .to_string(),
                },
            )
        );
        Ok(())
    }

    #[gtest]
    fn test_table_field_hover_keeps_same_owner_same_name_overloads() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        ws.def(
            r#"
                ---@class OverloadedParams
                ---@field next fun(value: string): string # 字符串
                ---@field next fun(value: number): number # 数字
            "#,
        );
        check!(
            ws.check_hover(
                r#"
                ---@type OverloadedParams
                local params = {
                    <??>next = function(value)
                        return value
                    end
                }
            "#,
                VirtualHoverResult {
                    value: "```lua\n(field) OverloadedParams.next(value: string) -> string (+1 overloads)\n```\n\n---\n\n字符串\n\n---\n\n```lua\n(field) OverloadedParams.next(value: number) -> number -- 数字\n```"
                        .to_string(),
                },
            )
        );
        Ok(())
    }

    #[gtest]
    fn test_function_candidate_checks_all_origin_decls() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        ws.def(
            r#"
                ---@class MixedOrigin
                ---@field next string # 字符串
                ---@field next fun(): string # 函数
            "#,
        );
        check!(ws.check_hover(
            r#"
                ---@type MixedOrigin
                local params
                local next = params.<??>next
            "#,
            VirtualHoverResult {
                value:
                    "```lua\n(field) MixedOrigin.next() -> string\n```\n\n---\n\n函数".to_string(),
            },
        ));
        Ok(())
    }

    #[gtest]
    fn test_generic_table_field_uses_known_context_type() -> Result<()> {
        let mut ws = ProviderVirtualWorkspace::new();
        ws.def(
            r#"
                ---@class ObserverParams<T>
                ---@field next fun(value: T): T # 测试

                ---@generic T
                ---@param value T
                ---@param params ObserverParams<T>
                function observe(value, params)
                end
            "#,
        );
        check!(
            ws.check_hover(
                r#"
                observe("x", {
                    <??>next = function(value)
                        return value
                    end
                })
            "#,
                VirtualHoverResult {
                    value: "```lua\n(field) ObserverParams.next(value: string) -> string\n```\n\n---\n\n测试"
                        .to_string(),
                },
            )
        );
        Ok(())
    }
}
