# Copyright 2020 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("fuchsia_test_package.gni")
import("fuchsia_unittest_component.gni")

# Defines a package that contains a component that launches a test.
# See: https://fuchsia.dev/fuchsia-src/development/components/build
#
# This template is a useful shortcut for defining classic unit tests for target
# devices.
# Pure unit tests don't require any special capabilities, so their component
# manifest can be generated by the template if a manifest is not specified.
#
# Example:
# ```
# executable("rot13_encoder_decoder_test") {
#   sources = [ "rot13_encoder_decoder_test.cc" ]
#   testonly = true
# }
#
# fuchsia_unittest_package("rot13-test") {
#   deps = [ ":rot13_encoder_decoder_test" ]
# }
# ```
#
# The above will generate a manifest and create a test with the launch URL:
# fuchsia-pkg://fuchsia.com/rot13-test#meta/rot13-test.cmx
#
# Parameters
#
#   package_name (optional)
#     The name of the package.
#     Type: string
#     Default: target_name
#
#   component_name (optional)
#     The name of the component.
#     Type: string
#     Default: package_name if defined, else target_name
#
#   manifest (optional)
#     Specify a component manifest for the test.
#     If a manifest is not specified, a trivial manifest will be generated.
#     The generated manifest requests no special capabilities, which is good
#     enough for "pure" unit tests.
#     To view the generated manifest, see:
#     `fx gn outputs out/default path/to/your:<target_name>_component_generated_manifest`
#     Type: path
#
#   v2 (optional)
#     If specified and set to false, will generate a CFv1 (.cmx) manifest.
#     If `manifest` is specified then this is ignored.
#     Type: boolean
#
#   restricted_features (optional)
#     The set of restricted CML features to allow. Only applicable to v2 components.
#     The set of features is allowlisted here: //tools/cmc/build/restricted_features/BUILD.gn
#     where each feature name is represented by a group of the same name.
#     Type: list of strings
#     Default: []
#
#   test_specs (optional)
#     Additional test specifications to apply to the test defined above.
#     See `test_spec.gni`.
#     Type: scope
#
#   deprecated_legacy_test_execution (optional)
#     If set for a v2 test, the test will be forced to use ELF runner,
#     which sacrifices isolation for higher performance.
#     Type: boolean
#
#   wrap_cmx_test_with_cml_test (optional)
#     If enabled, test_components that are legacy (v1) tests with cmx manifests
#     will be wrapped with a modern (v2) test with a cml manifest. The launch
#     URL of the wrapper will be derived from the wrapped test's launch URL.
#     For instance:
#       fuchsia-pkg://fuchsia.com/package#meta/test_component.cmx
#     will become:
#       fuchsia-pkg://fuchsia.com/package#meta/test_component.cm
#     Type: bool
#     Default: true
#
#   data_deps
#   deps
#   visibility
template("fuchsia_unittest_package") {
  if (current_toolchain == default_toolchain) {
    component_target = "${target_name}_component"
    fuchsia_unittest_component(component_target) {
      forward_variables_from(invoker,
                             [
                               "component_name",
                               "data_deps",
                               "deps",
                               "manifest",
                               "restricted_features",
                               "deprecated_legacy_test_execution",
                               "v2",
                             ])
      if (!defined(component_name)) {
        if (defined(invoker.package_name)) {
          component_name = invoker.package_name
        } else {
          component_name = invoker.target_name
        }
      }
      visibility = [ ":*" ]
    }

    _test_specs = {
    }
    if (defined(invoker.test_specs)) {
      _test_specs = invoker.test_specs
    }

    _test_specs.build_rule = "fuchsia_unittest_package"
    _test_specs.has_generated_manifest = !defined(invoker.manifest)

    fuchsia_test_package(target_name) {
      forward_variables_from(invoker,
                             [
                               "package_name",
                               "visibility",
                               "wrap_cmx_test_with_cml_test",
                             ])
      test_specs = _test_specs
      test_components = [ ":$component_target" ]
    }
  } else {
    group(target_name) {
      testonly = true
      forward_variables_from(invoker, [ "visibility" ])
      deps = [ ":$target_name($default_toolchain)" ]
    }
    not_needed(invoker, "*")
  }
}
