# Copyright 2017 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Unit testing support.

Unlike most Skylib files, this exports two modules: `unittest` which contains
functions to declare and define unit tests, and `asserts` which contains the
assertions used to within tests.
"""

load(":new_sets.bzl", new_sets = "sets")
load(":partial.bzl", "partial")
load(":types.bzl", "types")

# The following function should only be called from WORKSPACE files and workspace macros.
# buildifier: disable=unnamed-macro
def register_unittest_toolchains():
    """Registers the toolchains for unittest users."""
    native.register_toolchains(
        "@bazel_skylib//toolchains/unittest:cmd_toolchain",
        "@bazel_skylib//toolchains/unittest:bash_toolchain",
    )

TOOLCHAIN_TYPE = "@bazel_skylib//toolchains/unittest:toolchain_type"

_UnittestToolchainInfo = provider(
    doc = "Execution platform information for rules in the bazel_skylib repository.",
    fields = [
        "file_ext",
        "success_templ",
        "failure_templ",
        "join_on",
        "escape_chars_with",
        "escape_other_chars_with",
    ],
)

def _unittest_toolchain_impl(ctx):
    return [
        platform_common.ToolchainInfo(
            unittest_toolchain_info = _UnittestToolchainInfo(
                file_ext = ctx.attr.file_ext,
                success_templ = ctx.attr.success_templ,
                failure_templ = ctx.attr.failure_templ,
                join_on = ctx.attr.join_on,
                escape_chars_with = ctx.attr.escape_chars_with,
                escape_other_chars_with = ctx.attr.escape_other_chars_with,
            ),
        ),
    ]

unittest_toolchain = rule(
    implementation = _unittest_toolchain_impl,
    attrs = {
        "failure_templ": attr.string(
            mandatory = True,
            doc = (
                "Test script template with a single `%s`. That " +
                "placeholder is replaced with the lines in the " +
                "failure message joined with the string " +
                "specified in `join_with`. The resulting script " +
                "should print the failure message and exit with " +
                "non-zero status."
            ),
        ),
        "file_ext": attr.string(
            mandatory = True,
            doc = (
                "File extension for test script, including leading dot."
            ),
        ),
        "join_on": attr.string(
            mandatory = True,
            doc = (
                "String used to join the lines in the failure " +
                "message before including the resulting string " +
                "in the script specified in `failure_templ`."
            ),
        ),
        "success_templ": attr.string(
            mandatory = True,
            doc = (
                "Test script generated when the test passes. " +
                "Should exit with status 0."
            ),
        ),
        "escape_chars_with": attr.string_dict(
            doc = (
                "Dictionary of characters that need escaping in " +
                "test failure message to prefix appended to escape " +
                "those characters. For example, " +
                '`{"%": "%", ">": "^"}` would replace `%` with ' +
                "`%%` and `>` with `^>` in the failure message " +
                "before that is included in `success_templ`."
            ),
        ),
        "escape_other_chars_with": attr.string(
            default = "",
            doc = (
                "String to prefix every character in test failure " +
                "message which is not a key in `escape_chars_with` " +
                "before including that in `success_templ`. For " +
                'example, `"\"` would prefix every character in ' +
                "the failure message (except those in the keys of " +
                "`escape_chars_with`) with `\\`."
            ),
        ),
    },
)

def _impl_function_name(impl):
    """Derives the name of the given rule implementation function.

    This can be used for better test feedback.

    Args:
      impl: the rule implementation function

    Returns:
      The name of the given function
    """

    # Starlark currently stringifies a function as "<function NAME>", so we use
    # that knowledge to parse the "NAME" portion out. If this behavior ever
    # changes, we'll need to update this.
    # TODO(bazel-team): Expose a ._name field on functions to avoid this.
    impl_name = str(impl)
    impl_name = impl_name.partition("<function ")[-1]
    return impl_name.rpartition(">")[0]

def _make(impl, attrs = {}):
    """Creates a unit test rule from its implementation function.

    Each unit test is defined in an implementation function that must then be
    associated with a rule so that a target can be built. This function handles
    the boilerplate to create and return a test rule and captures the
    implementation function's name so that it can be printed in test feedback.

    The optional `attrs` argument can be used to define dependencies for this
    test, in order to form unit tests of rules.

    An example of a unit test:

    ```
    def _your_test(ctx):
      env = unittest.begin(ctx)

      # Assert statements go here

      return unittest.end(env)

    your_test = unittest.make(_your_test)
    ```

    Recall that names of test rules must end in `_test`.

    Args:
      impl: The implementation function of the unit test.
      attrs: An optional dictionary to supplement the attrs passed to the
          unit test's `rule()` constructor.

    Returns:
      A rule definition that should be stored in a global whose name ends in
      `_test`.
    """
    attrs = dict(attrs)
    attrs["_impl_name"] = attr.string(default = _impl_function_name(impl))

    return rule(
        impl,
        attrs = attrs,
        _skylark_testable = True,
        test = True,
        toolchains = [TOOLCHAIN_TYPE],
    )

_ActionInfo = provider(
    doc = "Information relating to the target under test.",
    fields = ["actions", "bin_path"],
)

def _action_retrieving_aspect_impl(target, ctx):
    return [
        _ActionInfo(
            actions = target.actions,
            bin_path = ctx.bin_dir.path,
        ),
    ]

_action_retrieving_aspect = aspect(
    attr_aspects = [],
    implementation = _action_retrieving_aspect_impl,
)

# TODO(cparsons): Provide more full documentation on analysis testing in README.
def _make_analysis_test(
        impl,
        expect_failure = False,
        attrs = {},
        fragments = [],
        config_settings = {},
        extra_target_under_test_aspects = [],
        doc = ""):
    """Creates an analysis test rule from its implementation function.

    An analysis test verifies the behavior of a "real" rule target by examining
    and asserting on the providers given by the real target.

    Each analysis test is defined in an implementation function that must then be
    associated with a rule so that a target can be built. This function handles
    the boilerplate to create and return a test rule and captures the
    implementation function's name so that it can be printed in test feedback.

    An example of an analysis test:

    ```
    def _your_test(ctx):
      env = analysistest.begin(ctx)

      # Assert statements go here

      return analysistest.end(env)

    your_test = analysistest.make(_your_test)
    ```

    Recall that names of test rules must end in `_test`.

    Args:
      impl: The implementation function of the unit test.
      expect_failure: If true, the analysis test will expect the target_under_test
          to fail. Assertions can be made on the underlying failure using asserts.expect_failure
      attrs: An optional dictionary to supplement the attrs passed to the
          unit test's `rule()` constructor.
      fragments: An optional list of fragment names that can be used to give rules access to
          language-specific parts of configuration.
      config_settings: A dictionary of configuration settings to change for the target under
          test and its dependencies. This may be used to essentially change 'build flags' for
          the target under test, and may thus be utilized to test multiple targets with different
          flags in a single build
      extra_target_under_test_aspects: An optional list of aspects to apply to the target_under_test
          in addition to those set up by default for the test harness itself.
      doc: A description of the rule that can be extracted by documentation generating tools.

    Returns:
      A rule definition that should be stored in a global whose name ends in
      `_test`.
    """
    attrs = dict(attrs)
    attrs["_impl_name"] = attr.string(default = _impl_function_name(impl))

    changed_settings = dict(config_settings)
    if expect_failure:
        changed_settings["//command_line_option:allow_analysis_failures"] = "True"

    target_attr_kwargs = {}
    if changed_settings:
        test_transition = analysis_test_transition(
            settings = changed_settings,
        )
        target_attr_kwargs["cfg"] = test_transition

    attrs["target_under_test"] = attr.label(
        aspects = [_action_retrieving_aspect] + extra_target_under_test_aspects,
        mandatory = True,
        **target_attr_kwargs
    )

    return rule(
        impl,
        doc = doc,
        attrs = attrs,
        fragments = fragments,
        test = True,
        toolchains = [TOOLCHAIN_TYPE],
        analysis_test = True,
    )

def _suite(name, *test_rules):
    """Defines a `test_suite` target that contains multiple tests.

    After defining your test rules in a `.bzl` file, you need to create targets
    from those rules so that `blaze test` can execute them. Doing this manually
    in a BUILD file would consist of listing each test in your `load` statement
    and then creating each target one by one. To reduce duplication, we recommend
    writing a macro in your `.bzl` file to instantiate all targets, and calling
    that macro from your BUILD file so you only have to load one symbol.

    You can use this function to create the targets and wrap them in a single
    test_suite target. If a test rule requires no arguments, you can simply list
    it as an argument. If you wish to supply attributes explicitly, you can do so
    using `partial.make()`. For instance, in your `.bzl` file, you could write:

    ```
    def your_test_suite():
      unittest.suite(
          "your_test_suite",
          your_test,
          your_other_test,
          partial.make(yet_another_test, timeout = "short"),
      )
    ```

    Then, in your `BUILD` file, simply load the macro and invoke it to have all
    of the targets created:

    ```
    load("//path/to/your/package:tests.bzl", "your_test_suite")
    your_test_suite()
    ```

    If you pass _N_ unit test rules to `unittest.suite`, _N_ + 1 targets will be
    created: a `test_suite` target named `${name}` (where `${name}` is the name
    argument passed in here) and targets named `${name}_test_${i}`, where `${i}`
    is the index of the test in the `test_rules` list, which is used to uniquely
    name each target.

    Args:
      name: The name of the `test_suite` target, and the prefix of all the test
          target names.
      *test_rules: A list of test rules defines by `unittest.test`.
    """
    test_names = []
    for index, test_rule in enumerate(test_rules):
        test_name = "%s_test_%d" % (name, index)
        if partial.is_instance(test_rule):
            partial.call(test_rule, name = test_name)
        else:
            test_rule(name = test_name)
        test_names.append(test_name)

    native.test_suite(
        name = name,
        tests = [":%s" % t for t in test_names],
    )

def _begin(ctx):
    """Begins a unit test.

    This should be the first function called in a unit test implementation
    function. It initializes a "test environment" that is used to collect
    assertion failures so that they can be reported and logged at the end of the
    test.

    Args:
      ctx: The Starlark context. Pass the implementation function's `ctx` argument
          in verbatim.

    Returns:
      A test environment struct that must be passed to assertions and finally to
      `unittest.end`. Do not rely on internal details about the fields in this
      struct as it may change.
    """
    return struct(ctx = ctx, failures = [])

def _end_analysis_test(env):
    """Ends an analysis test and logs the results.

    This must be called and returned at the end of an analysis test implementation function so
    that the results are reported.

    Args:
      env: The test environment returned by `analysistest.begin`.

    Returns:
      A list of providers needed to automatically register the analysis test result.
    """
    return [AnalysisTestResultInfo(
        success = (len(env.failures) == 0),
        message = "\n".join(env.failures),
    )]

def _end(env):
    """Ends a unit test and logs the results.

    This must be called and returned at the end of a unit test implementation function so
    that the results are reported.

    Args:
      env: The test environment returned by `unittest.begin`.

    Returns:
      A list of providers needed to automatically register the test result.
    """

    tc = env.ctx.toolchains[TOOLCHAIN_TYPE].unittest_toolchain_info
    testbin = env.ctx.actions.declare_file(env.ctx.label.name + tc.file_ext)
    if env.failures:
        failure_message_lines = "\n".join(env.failures).split("\n")
        escaped_failure_message_lines = [
            "".join([
                tc.escape_chars_with.get(c, tc.escape_other_chars_with) + c
                for c in line.elems()
            ])
            for line in failure_message_lines
        ]
        cmd = tc.failure_templ % tc.join_on.join(escaped_failure_message_lines)
    else:
        cmd = tc.success_templ

    env.ctx.actions.write(
        output = testbin,
        content = cmd,
        is_executable = True,
    )
    return [DefaultInfo(executable = testbin)]

def _fail(env, msg):
    """Unconditionally causes the current test to fail.

    Args:
      env: The test environment returned by `unittest.begin`.
      msg: The message to log describing the failure.
    """
    full_msg = "In test %s: %s" % (env.ctx.attr._impl_name, msg)

    # There isn't a better way to output the message in Starlark, so use print.
    # buildifier: disable=print
    print(full_msg)
    env.failures.append(full_msg)

def _assert_true(
        env,
        condition,
        msg = "Expected condition to be true, but was false."):
    """Asserts that the given `condition` is true.

    Args:
      env: The test environment returned by `unittest.begin`.
      condition: A value that will be evaluated in a Boolean context.
      msg: An optional message that will be printed that describes the failure.
          If omitted, a default will be used.
    """
    if not condition:
        _fail(env, msg)

def _assert_false(
        env,
        condition,
        msg = "Expected condition to be false, but was true."):
    """Asserts that the given `condition` is false.

    Args:
      env: The test environment returned by `unittest.begin`.
      condition: A value that will be evaluated in a Boolean context.
      msg: An optional message that will be printed that describes the failure.
          If omitted, a default will be used.
    """
    if condition:
        _fail(env, msg)

def _assert_equals(env, expected, actual, msg = None):
    """Asserts that the given `expected` and `actual` values are equal.

    Args:
      env: The test environment returned by `unittest.begin`.
      expected: The expected value of some computation.
      actual: The actual value returned by some computation.
      msg: An optional message that will be printed that describes the failure.
          If omitted, a default will be used.
    """
    if expected != actual:
        expectation_msg = 'Expected "%s", but got "%s"' % (expected, actual)
        if msg:
            full_msg = "%s (%s)" % (msg, expectation_msg)
        else:
            full_msg = expectation_msg
        _fail(env, full_msg)

def _assert_set_equals(env, expected, actual, msg = None):
    """Asserts that the given `expected` and `actual` sets are equal.

    Args:
      env: The test environment returned by `unittest.begin`.
      expected: The expected set resulting from some computation.
      actual: The actual set returned by some computation.
      msg: An optional message that will be printed that describes the failure.
          If omitted, a default will be used.
    """
    if not new_sets.is_equal(expected, actual):
        missing = new_sets.difference(expected, actual)
        unexpected = new_sets.difference(actual, expected)
        expectation_msg = "Expected %s, but got %s" % (new_sets.str(expected), new_sets.str(actual))
        if new_sets.length(missing) > 0:
            expectation_msg += ", missing are %s" % (new_sets.str(missing))
        if new_sets.length(unexpected) > 0:
            expectation_msg += ", unexpected are %s" % (new_sets.str(unexpected))
        if msg:
            full_msg = "%s (%s)" % (msg, expectation_msg)
        else:
            full_msg = expectation_msg
        _fail(env, full_msg)

_assert_new_set_equals = _assert_set_equals

def _expect_failure(env, expected_failure_msg = ""):
    """Asserts that the target under test has failed with a given error message.

    This requires that the analysis test is created with `analysistest.make()` and
    `expect_failures = True` is specified.

    Args:
      env: The test environment returned by `analysistest.begin`.
      expected_failure_msg: The error message to expect as a result of analysis failures.
    """
    dep = _target_under_test(env)
    if AnalysisFailureInfo in dep:
        actual_errors = ""
        for cause in dep[AnalysisFailureInfo].causes.to_list():
            actual_errors += cause.message + "\n"
        if actual_errors.find(expected_failure_msg) < 0:
            expectation_msg = "Expected errors to contain '%s' but did not. " % expected_failure_msg
            expectation_msg += "Actual errors:%s" % actual_errors
            _fail(env, expectation_msg)
    else:
        _fail(env, "Expected failure of target_under_test, but found success")

def _target_actions(env):
    """Returns a list of actions registered by the target under test.

    Args:
      env: The test environment returned by `analysistest.begin`.

    Returns:
      A list of actions registered by the target under test
    """

    # Validate?
    return _target_under_test(env)[_ActionInfo].actions

def _target_bin_dir_path(env):
    """Returns ctx.bin_dir.path for the target under test.

    Args:
      env: The test environment returned by `analysistest.begin`.

    Returns:
      Output bin dir path string.
    """
    return _target_under_test(env)[_ActionInfo].bin_path

def _target_under_test(env):
    """Returns the target under test.

    Args:
      env: The test environment returned by `analysistest.begin`.

    Returns:
      The target under test.
    """
    result = getattr(env.ctx.attr, "target_under_test")
    if types.is_list(result):
        if result:
            return result[0]
        else:
            fail("test rule does not have a target_under_test")
    return result

def _loading_test_impl(ctx):
    tc = ctx.toolchains[TOOLCHAIN_TYPE].unittest_toolchain_info
    content = tc.success_templ
    if ctx.attr.failure_message:
        content = tc.failure_templ % ctx.attr.failure_message

    testbin = ctx.actions.declare_file("loading_test_" + ctx.label.name + tc.file_ext)
    ctx.actions.write(
        output = testbin,
        content = content,
        is_executable = True,
    )
    return [DefaultInfo(executable = testbin)]

_loading_test = rule(
    implementation = _loading_test_impl,
    attrs = {
        "failure_message": attr.string(),
    },
    toolchains = [TOOLCHAIN_TYPE],
    test = True,
)

def _loading_make(name):
    """Creates a loading phase test environment and test_suite.

    Args:
       name: name of the suite of tests to create

    Returns:
       loading phase environment passed to other loadingtest functions
    """
    native.test_suite(
        name = name + "_tests",
        tags = [name + "_test_case"],
    )
    return struct(name = name)

def _loading_assert_equals(env, test_case, expected, actual):
    """Creates a test case for asserting state at LOADING phase.

    Args:
      env:       Loading test env created from loadingtest.make
      test_case: Name of the test case
      expected:  Expected value to test
      actual:    Actual value received.

    Returns:
      None, creates test case
    """

    msg = None
    if expected != actual:
        msg = 'Expected "%s", but got "%s"' % (expected, actual)

    _loading_test(
        name = "%s_%s" % (env.name, test_case),
        failure_message = msg,
        tags = [env.name + "_test_case"],
    )

asserts = struct(
    expect_failure = _expect_failure,
    equals = _assert_equals,
    false = _assert_false,
    set_equals = _assert_set_equals,
    new_set_equals = _assert_new_set_equals,
    true = _assert_true,
)

unittest = struct(
    make = _make,
    suite = _suite,
    begin = _begin,
    end = _end,
    fail = _fail,
)

analysistest = struct(
    make = _make_analysis_test,
    begin = _begin,
    end = _end_analysis_test,
    fail = _fail,
    target_actions = _target_actions,
    target_bin_dir_path = _target_bin_dir_path,
    target_under_test = _target_under_test,
)

loadingtest = struct(
    make = _loading_make,
    equals = _loading_assert_equals,
)
