# 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/package.gni")

# Helper template to create test component which runtests can execute.
#
# This template assumes that for all the test binaries in |tests| there would
# be a corresponding component manifest file in meta/ folder with same name.
# If there is none this template will fail with an error.
#
# Parameters
#
#   meta (optional)
#     [list of scopes] Defines the metadata entries in the package. A metadata
#     entry is typically a source file and is placed in the `meta/` directory of
#     the assembled package.
#
#     Entries in a scope in the meta list:
#
#       path (required)
#         [path] Location of entry in source or build directory. If the
#         resource is checked in, this will typically be specified as a
#         path relative to the BUILD.gn file containing the `package()`
#         target. If the resource is generated, this will typically be
#         specified relative to `$target_gen_dir`.
#
#       dest (required)
#         [path] Location the resource will be placed within `meta/`.
#
#   binaries (optional)
#     [list of scopes] Defines the binaries in the package. A binary is
#     typically produced by the build system and is placed in the `bin/`
#     directory of the assembled package.
#
#     Entries in a scope in the binaries list:
#
#       name (required)
#         [string] Name of the binary.
#
#       source (optional)
#         [path] Location of the binary in the build directory if it is not
#         at `$root_out_dir/$name`.
#
#       dest (optional)
#         [path] Location the binary will be placed within `bin/`.
#
#
#   tests (optional)
#     [list of scopes] Defines the test binaries in the package. A test is
#     typically produced by the build system and is placed in the `test/`
#     directory of the assembled package.
#
#     Entries in a scope in the tests list:
#
#       name (required)
#         [string] Name of the test.
#
#       dest (optional)
#         [path] Location the binary will be placed within `test/`.
#
#       disabled (optional)
#         [bool] Whether to disable the test on continuous integration
#         jobs. This can be used when a test is temporarily broken, or if
#         it is too flaky or slow for CI. The test will also be skipped by
#         the `runtests` command.
#
#     For each tests entry this expects a corresponding cmx file in meta directory.
#
#   resources (optional)
#     [list of scopes] Defines the resources in the package. A resource is a
#     data file that may be produced by the build system, checked in to a
#     source repository, or produced by another system that runs before the
#     build. Resources are placed in the `data/` directory of the assembled
#     package.
#
#     Entries in a scope in the resources list:
#
#       path (required)
#         [path] Location of resource in source or build directory. If the
#         resource is checked in, this will typically be specified as a
#         path relative to the BUILD.gn file containing the `package()`
#         target. If the resource is generated, this will typically be
#         specified relative to `$target_gen_dir`.
#
#       dest (required)
#         [path] Location the resource will be placed within `data/`.
#
#   extra (optional)
#     [list of paths] Manifest files containing extra entries, which
#     might be generated by the build.
#
#   deps (optional)
#   public_deps (optional)
#   data_deps (optional)
#     Usual GN meanings.
#
template("test_package") {
  forward_variables_from(invoker,
                         [
                           "tests",
                           "meta",
                         ])
  if (!defined(meta)) {
    meta = []
  }
  foreach(test, tests) {
    test_dest = test.name
    if (defined(test.dest)) {
      test_dest = test.dest
    }
    meta += [
      {
        path = "meta/${test_dest}.cmx"
        dest = "${test_dest}.cmx"
      },
    ]
  }

  package(target_name) {
    testonly = true
    forward_variables_from(invoker,
                           [
                             "binaries",
                             "components",
                             "data_deps",
                             "deprecated_global_persistent_storage",
                             "deps",
                             "extra",
                             "public_deps",
                             "resources",
                             "drivers",
                             "loadable_modules",
                             "package_name",
                           ])
  }
}
