emmylua_code_analysis 0.24.0

A library for analyzing lua code.
Documentation
#[cfg(test)]
mod test {
    use crate::{DiagnosticCode, VirtualWorkspace};

    #[test]
    fn test() {
        let mut ws = VirtualWorkspace::new();

        assert!(!ws.has_no_diagnostic(
            DiagnosticCode::RedundantParameter,
            r#"
            ---@class Test
            local Test = {}

            ---@param a string
            function Test.name(a)
            end

            Test:name("")
        "#
        ));

        assert!(!ws.has_no_diagnostic(
            DiagnosticCode::RedundantParameter,
            r#"
            ---@class Test2
            local Test = {}

            ---@param a string
            function Test.name(a)
            end

            Test.name("", "")
        "#
        ));

        assert!(!ws.has_no_diagnostic(
            DiagnosticCode::RedundantParameter,
            r#"
            ---@class A
            ---@field event fun()

            ---@type A
            local a = {
                event = function(aaa)
                end,
            }
        "#
        ));
    }

    #[test]
    fn test_1() {
        let mut ws = VirtualWorkspace::new();

        assert!(ws.has_no_diagnostic(
            DiagnosticCode::RedundantParameter,
            r#"
                ---@type fun(...)[]
                local a = {}

                a[1] = function(ccc, ...)
                end
        "#
        ));
    }

    #[test]
    fn test_dots() {
        let mut ws = VirtualWorkspace::new();

        assert!(ws.has_no_diagnostic(
            DiagnosticCode::RedundantParameter,
            r#"
            ---@class Test
            local Test = {}

            ---@param a string
            ---@param ... any
            function Test.dots(a, ...)
                print(a, ...)
            end

            Test.dots(1, 2, 3)
            Test:dots(1, 2, 3)
        "#
        ));
    }

    #[test]
    fn test_variadic_call_operator() {
        let mut ws = VirtualWorkspace::new();
        let source = r#"
            ---@class Callable
            ---@operator call(string...): string

            ---@type Callable
            local callable

            callable("a", "b")
            callable("a", 1)
        "#;

        assert!(ws.has_no_diagnostic(DiagnosticCode::RedundantParameter, source));
        assert!(!ws.has_no_diagnostic(DiagnosticCode::ParamTypeMismatch, source));
    }

    #[test]
    fn test_issue_360() {
        let mut ws = VirtualWorkspace::new();
        let source = r#"
            ---@alias buz number

            ---@param a buz
            ---@overload fun(): number
            function test(a)
            end

            local c = test({'test'})
        "#;

        assert!(ws.has_no_diagnostic(DiagnosticCode::RedundantParameter, source));
        assert!(!ws.has_no_diagnostic(DiagnosticCode::ParamTypeMismatch, source));
    }

    #[test]
    fn test_function_param() {
        let mut ws = VirtualWorkspace::new();
        assert!(!ws.has_no_diagnostic(
            DiagnosticCode::RedundantParameter,
            r#"
                ---@param callback fun()
                local function with_local(callback)
                end

                with_local(function(local_player) end)
        "#
        ));
    }

    #[test]
    fn test_generic_infer_function() {
        // temp disable this test, future fix this
        let mut ws = VirtualWorkspace::new();
        ws.def(
            r#"
            ---@alias Parameters<T extends function> T extends (fun(...: infer P): any) and P or never

            ---@alias Procedure fun(...: any[]): any

            ---@alias MockParameters<T> T extends Procedure and Parameters<T> or never

            ---@class Mock<T>
            ---@overload fun(...: MockParameters<T>...)

            ---@generic T: Procedure
            ---@param a T
            ---@return Mock<T>
            function fn(a)
            end

            sum = fn(function(a, b)
                return a + b
            end)
            "#,
        );
        assert!(!ws.has_no_diagnostic(
            DiagnosticCode::RedundantParameter,
            r#"
            sum(1, 2, 3)
        "#
        ));
    }

    #[test]
    fn test_generic_variadic_instantiated_params_reports_redundant_parameter() {
        let mut ws = VirtualWorkspace::new();
        ws.def(
            r#"
            ---@generic T
            ---@param ... T...
            ---@return fun(...: T...)
            local function bind(...)
            end

            bound = bind(1, "a")
            "#,
        );

        assert!(!ws.has_no_diagnostic(
            DiagnosticCode::RedundantParameter,
            r#"
            bound(1, "a", true)
        "#
        ));
    }

    #[test]
    fn test_issue_894() {
        let mut ws = VirtualWorkspace::new();
        ws.def(
            r#"
            _nop = function() end
            "#,
        );
        assert!(ws.has_no_diagnostic(
            DiagnosticCode::RedundantParameter,
            r#"
            function a(...) _nop(...) end
        "#
        ));
    }
}