# Copyright 2018 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//build/testing/host_test.gni")

# This declares a test executable.
#
# The parameters are precisely those of an `executable`, along with
#
# environments
#   Optional: What environments this test should target. Only used here for
#     linux and mac tests, with a default value of a general linux/mac
#     environment (as a function of $current_os).
#     See //build/testing/test_spec.gni for more details.
#
template("test") {
  _is_host = is_linux || is_mac

  assert(_is_host || !defined(invoker.environments),
         "environments only supported for host tests")

  _exe_target_name = target_name

  _output_name = target_name
  if (defined(invoker.output_name)) {
    _output_name = invoker.output_name
  }
  if (_is_host || is_fuchsia) {
    _output_dir = root_out_dir
    if (defined(invoker.output_dir)) {
      _output_dir = invoker.output_dir
    }
  }
  _output_file = _output_name
  if (defined(invoker.output_extension)) {
    _output_extension = invoker.output_extension
  } else {
    if (is_win) {
      _output_extension = "exe"
    } else {
      _output_extension = ""
    }
  }
  if (_output_extension != "") {
    _output_file += "." + _output_extension
  }

  if (_is_host) {
    _exe_target_name = "${target_name}_executable"
    host_test(target_name) {
      binary_path = "${_output_dir}/${_output_file}"
      deps = [ ":${_exe_target_name}" ]
      if (defined(invoker.deps)) {
        deps += invoker.deps
      }
      if (defined(invoker.data_deps)) {
        deps += invoker.data_deps
      }
      forward_variables_from(invoker,
                             [
                               "environments",
                               "visibility",
                             ])
    }
  }

  executable(_exe_target_name) {
    forward_variables_from(invoker,
                           "*",
                           [
                             "output_name",
                             "target_name",
                             "testonly",
                           ])

    # Normally defaults to target_name, but we don't want to use
    # _exe_target_name.
    output_name = _output_name
    testonly = true

    if (is_fuchsia) {
      metadata = {
        # Used by the distribution_manifest template.
        distribution_entries = [
          {
            source =
                rebase_path("${_output_dir}/${_output_file}", root_build_dir)
            destination = "test/${_output_file}"
            label =
                get_label_info(":${_exe_target_name}", "label_with_toolchain")
          },
        ]

        # Used by the fuchsia_test_component_manifest() template.
        test_component_manifest_program = [
          {
            program = {
              binary = "test/${_output_file}"
            }
          },
        ]
        test_component_manifest_program_barrier = []
      }
    }
  }
}

set_defaults("test") {
  configs = default_executable_configs
}
