# 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'
#
# 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 (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,
                           [
                             "visibility",
                             "inputs",
                           ])
  }
}
