# 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")

# Defines a Rust unit test, without also compiling a separate binary or library
# target.
#
# Parameters
#
#   output_name (optional)
#   name (optional, deprecated)
#     Name of the test binary, also used as the crate name as defined in its
#     manifest file. If not specified, it is assumed to be the same as the
#     target name.
#
#   version
#     Semver version of the crate as seen on crates.io.
#
#   edition (optional)
#     Edition of the Rust language to be used.
#     Options are "2015" and "2018". Defaults to "2018".
#
#   configs (optional)
#     A list of config labels applying to this target.
#
#   enforce_source_listing (optional)
#     When true, enforces that any source files used by the Rust compiler are
#     listed in `sources`. Defaults to true.
#
#   sources (optional)
#     List of source files which this crate is allowed to compile. Only
#     allowed when `enforce_source_listing = true`.
#     The Rust compiler discovers source files by following `mod` declarations
#     starting at the `source_root`. The discovered source files must match this
#     list.
#
#   inputs (optional)
#     List of additional non-source files read by the compiler. These are typically
#     configuration or test-data files included in the build with the `include_str!`
#     macro. Only allowed when `enforce_source_listing = true`.
#
#   deps (optional)
#     List of rust_library GN targets on which this crate depends.
#     Third party crates can be included through paths like
#     "//third_party/rust_crates:<cratename>",
#
#   non_rust_deps (optional)
#     List of non-rust_library GN targets on which this crate depends.
#
#   test_environments (optional)
#     What environments the unit 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 environments parameter on //build/testing/test_spec.gni for more
#     details.

#   args (optional)
#     List of flags to pass directly to the test binary, e.g.
#     ["--nocapture"].
#
#   source_root (optional)
#     Location of the crate root (e.g. `src/main.rs` or `src/lib.rs`).
#     This should usually be 'src/lib.rs/ for libraries (the default)
#     and `src/main.rs` for binaries.
#
#   features (optional)
#     A list of conditional compilation flags to enable. This can be used to set features for crates
#     built in-tree which are also published to crates.io. This would be passed to rustc as
#     '--cfg feature=XXX'
#
#   output_dir (optional)
#     Directory that the resulting test should be placed in.
#     See: `gn help output_dir`
#
# Example of usage:
#
#   rustc_test("foo_test") {
#     source_root = "src/foo_test.rs",
#     deps = [
#       "//garnet/public/rust/bar",
#       "//third_party/rust_crates:clap",
#       "//third_party/rust_crates:serde",
#       "//third_party/rust_crates:slab",
#     ]
#     sources = [ "src/lib.rs" ]
#   }
template("rustc_test") {
  not_needed(invoker,
             [
               "version",
               "edition",
               "force_opt",
               "testonly",
             ])

  # default location for rust libraries
  source_root = "src/lib.rs"
  if (defined(invoker.source_root)) {
    source_root = invoker.source_root
  }

  # use the target name unless another name is specified
  assert(!(defined(invoker.output_name) && defined(invoker.name)),
         "Only one of output_name and name may be specified.")
  package_name = target_name
  if (defined(invoker.output_name)) {
    package_name = invoker.output_name
  } else if (defined(invoker.name)) {
    package_name = invoker.name
  }

  # built-in gn rules do not support dashes
  crate_name = string_replace(package_name, "-", "_")

  exe_target_name = target_name

  if (is_host) {
    exe_target_name = "${target_name}_executable"
    all_deps = [ ":${exe_target_name}" ]
    if (defined(invoker.deps)) {
      all_deps += invoker.deps
    }
    if (defined(invoker.non_rust_deps)) {
      all_deps += invoker.non_rust_deps
    }

    host_test(target_name) {
      binary_path = "${root_out_dir}/${crate_name}"
      deps = all_deps
      if (defined(invoker.test_environments)) {
        environments = invoker.test_environments
      }
      forward_variables_from(invoker,
                             [
                               "args",
                               "visibility",
                             ])
    }
  } else {
    # if not a host-side target, we don't need this since it doesn't
    # propogate to package.gni
    not_needed(invoker, [ "test_environments" ])
  }

  # enable these features for the target
  features = []
  if (defined(invoker.features)) {
    foreach(i, invoker.features) {
      features += [ "--cfg=feature=\"${i}\"" ]
    }
  }

  _sources = []
  _deps = []

  if (!defined(invoker.enforce_source_listing) ||
      invoker.enforce_source_listing == true) {
    # fail early when the user forgets to list sources
    assert(defined(invoker.sources), "sources must be listed")
    _sources = invoker.sources
  } else {
    not_needed(invoker, [ "sources" ])

    # This is a hack to workaround the fact that a GN `tool` invocation can't receive arbitrary input.
    # Add a sentinel value so that enforcement is skipped.
    _sources = [ "//build/rust/__SKIP_ENFORCEMENT__.rs" ]

    # Opting out of strict sources check requires that the package is present
    # in a global allow-list.
    _deps += [ "//build/rust:disable_strict_sources_check_allowlist" ]
  }

  executable(exe_target_name) {
    # anything defined with rustc_test MUST be a test target
    testonly = true

    configs = []
    configs = invoker.configs

    crate_root = source_root
    output_name = crate_name
    crate_name = crate_name

    # tell rustc to compile in the test harness
    rustflags = features + [ "--test" ]

    deps = _deps
    if (defined(invoker.deps)) {
      deps += invoker.deps
    }
    if (defined(invoker.non_rust_deps)) {
      deps += invoker.non_rust_deps
    }

    # test_deps specified in the parent template (if not used directly)
    # should also be treated as normal dependencies
    if (defined(invoker.test_deps)) {
      deps += invoker.test_deps
    }

    data_deps = []
    if (defined(invoker.data_deps)) {
      data_deps = invoker.data_deps
    }
    if (is_fuchsia) {
      # Dynamic linking applies to not only to libstd but to libtest as well,
      # which means we must depend on it as a data_dep to get it in our
      # package.
      _dynamic_rust_config =
          [ "//build/config/fuchsia:dynamic_rust_standard_library" ]
      if (configs + _dynamic_rust_config - _dynamic_rust_config != configs) {
        data_deps += [ "//build/toolchain/runtime:shared-rust-libtest-deps" ]
      } else {
        data_deps += [ "//build/toolchain/runtime:static-rust-libtest-deps" ]
      }
    }

    if (is_fuchsia) {
      deps += [ "//build/test:rust_test_metadata" ]
      metadata = {
        cmx_patches_walk = [ "//build/test:rust_test_metadata" ]
      }
    }

    sources = _sources

    # in-tree default in 2018 edition
    if (defined(invoker.edition) && invoker.edition == "2015") {
      configs -= [ "//build/config:rust_edition_2018" ]
      configs += [ "//build/config:rust_edition_2015" ]
    }

    forward_variables_from(invoker,
                           [
                             "inputs",
                             "output_dir",
                             "visibility",
                           ])
  }
}
