include(cmake_test/cmake_test)

ct_add_test("_cpp_compare_names")
    include(cmakepp_core/types/is_callable)

    set(sig0 a_fxn int bool)
    ct_add_section("Names match")
        set(sig1 a_fxn bool int)
        _cpp_compare_names(result sig0 sig1)
        ct_assert_equal(result TRUE)
    ct_end_section()

    ct_add_section("Names do not match")
        set(sig1 another_fxn bool int)
        _cpp_compare_names(result sig0 sig1)
        ct_assert_equal(result FALSE)
    ct_end_section()

    ct_add_section("Case-insensitive compare")
        set(sig1 a_FXN bool int)
        _cpp_compare_names(result sig0 sig1)
        ct_assert_equal(result TRUE)
    ct_end_section()
ct_end_test()

ct_add_test("_cpp_compare_lengths")
    include(cmakepp_core/types/is_callable)

    ct_add_section("Function takes no arguments")
        set(sig0 a_fxn)

        ct_add_section("Trial signature takes no arguments")
            set(sig1 a_fxn)
            _cpp_compare_lengths(result sig0 sig1)
            ct_assert_equal(result TRUE)
        ct_end_section()

        ct_add_section("Trial signature takes more arguments")
            set(sig1 a_fxn int)
            _cpp_compare_lengths(result sig0 sig1)
            ct_assert_equal(result FALSE)
        ct_end_section()
    ct_end_section()

    ct_add_section("Pure variadic function")
        set(sig0 a_fxn args)

        ct_add_section("Trial signature takes no arguments")
            set(sig1 a_fxn)
            _cpp_compare_lengths(result sig0 sig1)
            ct_assert_equal(result TRUE)
        ct_end_section()

        ct_add_section("Trial signature takes more arguments")
            set(sig1 a_fxn int)
            _cpp_compare_lengths(result sig0 sig1)
            ct_assert_equal(result TRUE)
        ct_end_section()
    ct_end_section()

    ct_add_section("Non-variadic function with one argument")
        set(sig0 a_fxn int)

        ct_add_section("Trial signature takes no arguments")
            set(sig1 a_fxn)
            _cpp_compare_lengths(result sig0 sig1)
            ct_assert_equal(result FALSE)
        ct_end_section()

        ct_add_section("Trial signature takes one argument")
            set(sig1 a_fxn int)
            _cpp_compare_lengths(result sig0 sig1)
            ct_assert_equal(result TRUE)
        ct_end_section()

        ct_add_section("Trial signature takes more arguments")
            set(sig1 a_fxn int bool)
            _cpp_compare_lengths(result sig0 sig1)
            ct_assert_equal(result FALSE)
        ct_end_section()
    ct_end_section()

    ct_add_section("Variadic function with one argument")
        set(sig0 a_fxn int args)

        ct_add_section("Trial signature takes no arguments")
            set(sig1 a_fxn)
            _cpp_compare_lengths(result sig0 sig1)
            ct_assert_equal(result FALSE)
        ct_end_section()

        ct_add_section("Trial signature takes one argument")
            set(sig1 a_fxn int)
            _cpp_compare_lengths(result sig0 sig1)
            ct_assert_equal(result TRUE)
        ct_end_section()

        ct_add_section("Trial signature takes more arguments")
            set(sig1 a_fxn int bool)
            _cpp_compare_lengths(result sig0 sig1)
            ct_assert_equal(result TRUE)
        ct_end_section()
    ct_end_section()

    ct_add_section("No-variadic function with two arguments")
        set(sig0 a_fxn int bool)

        ct_add_section("Trial signature takes no arguments")
            set(sig1 a_fxn)
            _cpp_compare_lengths(result sig0 sig1)
            ct_assert_equal(result FALSE)
        ct_end_section()

        ct_add_section("Trial signature takes one argument")
            set(sig1 a_fxn int)
            _cpp_compare_lengths(result sig0 sig1)
            ct_assert_equal(result FALSE)
        ct_end_section()

        ct_add_section("Trial signature takes two arguments")
            set(sig1 a_fxn int bool)
            _cpp_compare_lengths(result sig0 sig1)
            ct_assert_equal(result TRUE)
        ct_end_section()

        ct_add_section("Trial signature takes more arguments")
            set(sig1 a_fxn int bool path)
            _cpp_compare_lengths(result sig0 sig1)
            ct_assert_equal(result FALSE)
        ct_end_section()
    ct_end_section()

    ct_add_section("Variadic function with two arguments")
        set(sig0 a_fxn int bool args)

        ct_add_section("Trial signature takes no arguments")
            set(sig1 a_fxn)
            _cpp_compare_lengths(result sig0 sig1)
            ct_assert_equal(result FALSE)
        ct_end_section()

        ct_add_section("Trial signature takes one argument")
            set(sig1 a_fxn int)
            _cpp_compare_lengths(result sig0 sig1)
            ct_assert_equal(result FALSE)
        ct_end_section()

        ct_add_section("Trial signature takes two arguments")
            set(sig1 a_fxn int bool)
            _cpp_compare_lengths(result sig0 sig1)
            ct_assert_equal(result TRUE)
        ct_end_section()

        ct_add_section("Trial signature takes more arguments")
            set(sig1 a_fxn int bool path)
            _cpp_compare_lengths(result sig0 sig1)
            ct_assert_equal(result TRUE)
        ct_end_section()
    ct_end_section()
ct_end_test()

ct_add_test("cpp_is_callable")
    include(cmakepp_core/types/is_callable)

    ct_add_section("Signature")
        set(CMAKEPP_CORE_DEBUG_MODE ON)

        ct_add_section("0th argument must be desc")
            cpp_is_callable(TRUE a_list b_list)
            ct_assert_fails_as("Assertion: bool is convertible to desc failed.")
        ct_end_section()

        ct_add_section("1st argument must be desc")
            cpp_is_callable(result TRUE b_list)
            ct_assert_fails_as("Assertion: bool is convertible to desc failed.")
        ct_end_section()

        ct_add_section("2nd argument must be desc")
            cpp_is_callable(result a_list FALSE)
            ct_assert_fails_as("Assertion: bool is convertible to desc failed.")
        ct_end_section()

        ct_add_section("Takes only three arguments")
            cpp_is_callable(result a_list b_list hello)
            ct_assert_fails_as("Function takes 3 argument(s), but 4 was/were")
        ct_end_section()
    ct_end_section()

    ct_add_section("Function takes no arguments")
        set(sig0 a_fxn)

        ct_add_section("Trial signature takes no arguments")
            set(sig1 a_fxn)
            cpp_is_callable(result sig0 sig1)
            ct_assert_equal(result TRUE)
        ct_end_section()

        ct_add_section("Trial signature takes more arguments")
            set(sig1 a_fxn int)
            cpp_is_callable(result sig0 sig1)
            ct_assert_equal(result FALSE)
        ct_end_section()
    ct_end_section()

    ct_add_section("Pure variadic function")
        set(sig0 a_fxn args)

        ct_add_section("Trial signature takes no arguments")
            set(sig1 a_fxn)
            cpp_is_callable(result sig0 sig1)
            ct_assert_equal(result TRUE)
        ct_end_section()

        ct_add_section("Trial signature takes more arguments")
            set(sig1 a_fxn int)
            cpp_is_callable(result sig0 sig1)
            ct_assert_equal(result TRUE)
        ct_end_section()
    ct_end_section()

    ct_add_section("Non-variadic with one argument")
        set(sig0 a_fxn int)

        ct_add_section("Trial signature takes same argument")
            set(sig1 a_fxn int)
            cpp_is_callable(result sig0 sig1)
            ct_assert_equal(result TRUE)
        ct_end_section()

        ct_add_section("Trial signature takes different argument")
            set(sig1 a_fxn bool)
            cpp_is_callable(result sig0 sig1)
            ct_assert_equal(result FALSE)
        ct_end_section()
    ct_end_section()

    ct_add_section("Variadic with one argument")
        set(sig0 a_fxn int args)

        ct_add_section("Trial signature takes same argument")
            set(sig1 a_fxn int)
            cpp_is_callable(result sig0 sig1)
            ct_assert_equal(result TRUE)
        ct_end_section()

        ct_add_section("Trial signature takes same first argument plus others")
            set(sig1 a_fxn int bool)
            cpp_is_callable(result sig0 sig1)
            ct_assert_equal(result TRUE)
        ct_end_section()

        ct_add_section("Trial signature takes different argument")
            set(sig1 a_fxn bool)
            cpp_is_callable(result sig0 sig1)
            ct_assert_equal(result FALSE)
        ct_end_section()
    ct_end_section()

    ct_add_section("Non-variadic with two arguments")
        set(sig0 a_fxn int bool)

        ct_add_section("Trial signature takes same arguments")
            set(sig1 a_fxn int bool)
            cpp_is_callable(result sig0 sig1)
            ct_assert_equal(result TRUE)
        ct_end_section()

        ct_add_section("Trial signature takes different first argument")
            set(sig1 a_fxn bool bool)
            cpp_is_callable(result sig0 sig1)
            ct_assert_equal(result FALSE)
        ct_end_section()

        ct_add_section("Trial signature takes different second argument")
            set(sig1 a_fxn int int)
            cpp_is_callable(result sig0 sig1)
            ct_assert_equal(result FALSE)
        ct_end_section()
    ct_end_section()

    ct_add_section("Variadic with two arguments")
        set(sig0 a_fxn int bool args)

        ct_add_section("Trial signature takes same arguments")
            set(sig1 a_fxn int bool)
            cpp_is_callable(result sig0 sig1)
            ct_assert_equal(result TRUE)
        ct_end_section()

        ct_add_section("Trial signature takes same arguments plus others")
            set(sig1 a_fxn int bool path)
            cpp_is_callable(result sig0 sig1)
            ct_assert_equal(result TRUE)
        ct_end_section()

        ct_add_section("Trial signature takes different first argument")
            set(sig1 a_fxn bool bool)
            cpp_is_callable(result sig0 sig1)
            ct_assert_equal(result FALSE)
        ct_end_section()

        ct_add_section("Trial signature takes different second argument")
            set(sig1 a_fxn int int)
            cpp_is_callable(result sig0 sig1)
            ct_assert_equal(result FALSE)
        ct_end_section()
    ct_end_section()
ct_end_test()
