# 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("//build/testing/config.gni")
import("//build/testing/host_test.gni")
import("//build/testing/host_test_data.gni")

# Declares a golden test.
#
# This template creates a test to verify that certain generated files match
# golden copies checked into the source tree. When invoked with the --regen
# flag, the test instead overwrites the golden files with freshly generated
# copies, guaranteeing that the next test run will pass.
#
# Set the `bless_goldens` build arg to true to include `--regen` in the arguments
# to the test script.
#
# For simpler, single-file golden testing that executes during the build, see
# //build/testing/golden_file.gni.
#
# Example
# ```
# golden_test("foo_golden_tests") {
#   goldens_dir = "goldens"
#   deps = [ ":generate_json" ]
#   reformat_goldens_bin = "path/to/my/json/formatter"
#   reformat_goldens_args = [ "--pretty" ]
#   reformat_goldens_inputs = [ "path/to/my/json/formatter.config" ]
#   entries = [
#     {
#       golden = "out.json.golden"
#       generated = "$target_gen_dir/foo_out.json"
#     },
#   ]
# }
# ```
#
# Setup
# ```
# $ $EDITOR BUILD.gn  # add the example code above
# $ mkdir goldens
# $ touch goldens/goldens.txt
# $ fx test foo_golden_tests -- --regen
# Regenerating goldens in /path/to/your/goldens
# ...
# $ fx test foo_golden_tests
# ...
# PASS
# ```
#
# Parameters
#
#   goldens_dir (required)
#     Directory of golden files, relative to the invoking BUILD.gn file. Must
#     contain a goldens.txt file. Each file path listed in goldens.txt must
#     exist, otherwise a gen-time error is produced.
#     Type: path
#
#   entries (required)
#     List of scopes, each with `golden` and `generated` fields. The `golden`
#     field is a file path relative to `goldens_dir`. The `generated` field is
#     an absolute path to the corresponding generated file, which must be
#     produced by one of the targets in `deps`.
#     Type: list(scope)
#
#   reformat_goldens_bin (optional)
#     A command that will reformat from stdin to stdout.
#     The command will be invoked for each golden file checked into the tree
#     before comparing it to the newly generated version. This allows changes
#     to source formatting tools to not cause goldens tests to fail.
#     Type: string
#
#   reformat_goldens_args (optional)
#     A list of args for invoking `reformat_goldens_bin`.
#     Type: list(string)
#     Default: empty
#
#   reformat_goldens_inputs (optional)
#     Inputs the reformat_goldens_command uses, this should typically include
#     a config file the formatter uses, if any. This makes sure when the config
#     changes, this template can correctly rerun the reformat action.
#     Type: list(string)
#     Default: empty
#
#   deps (required)
#   visibility
#
template("golden_test") {
  assert(is_host, "The golden_test template can only be used on host")

  assert(defined(invoker.goldens_dir))
  assert(defined(invoker.entries))
  assert(defined(invoker.deps))

  copied_goldens_dir = "${target_gen_dir}/${target_name}"
  manifest_file = "${target_gen_dir}/${target_name}_manifest.json"

  # Read the checked-in list of golden files.
  goldens_list = read_file("${invoker.goldens_dir}/goldens.txt", "list lines")
  assert(goldens_list ==
             process_file_template(goldens_list, "{{source_file_part}}"),
         "Subdirectories are not allowed in goldens.txt")

  # Copy the goldens.txt list and make it available to the test at runtime.
  target_test_data_goldens_list = "${target_name}_test_data_goldens_list"
  host_test_data(target_test_data_goldens_list) {
    visibility = [ ":*" ]
    sources = [ "${invoker.goldens_dir}/goldens.txt" ]
    outputs = [ "${copied_goldens_dir}/goldens.txt" ]
  }

  # Reformat or copy the goldens from the source directory by piping each
  # golden file through `reformat_goldens`.
  target_reformat_goldens = "${target_name}_reformat_goldens"
  if (goldens_list == []) {
    # No-op target to avoid breaking `gn gen` when goldens.txt is empty
    # (action_foreach is not allowed to have zero source files).
    group(target_reformat_goldens) {
    }
    not_needed(invoker,
               [
                 "reformat_goldens_bin",
                 "reformat_goldens_args",
                 "reformat_goldens_inputs",
               ])
  } else {
    action_foreach(target_reformat_goldens) {
      testonly = true
      visibility = [ ":*" ]

      # Always copy & format the goldens when the generated files change to avoid
      # comparing stale goldens.
      deps = invoker.deps

      script = "//build/testing/reformat_goldens.py"
      sources = rebase_path(goldens_list, ".", invoker.goldens_dir)
      inputs = []
      if (defined(invoker.reformat_goldens_inputs)) {
        inputs += invoker.reformat_goldens_inputs
      }

      outputs = [ "${copied_goldens_dir}/{{source_file_part}}" ]
      output_dir = rebase_path(copied_goldens_dir, root_build_dir)

      args = [
        "--source",
        "{{source}}",
        "--output",
        "${output_dir}/{{source_file_part}}",
      ]
      if (defined(invoker.reformat_goldens_bin)) {
        inputs += [ invoker.reformat_goldens_bin ]
        args += [
          "--formatter",
          rebase_path(invoker.reformat_goldens_bin, root_build_dir),
        ]
        if (defined(invoker.reformat_goldens_args)) {
          args += [ "--" ] + invoker.reformat_goldens_args
        }
      } else {
        assert(
            !defined(invoker.reformat_goldens_args),
            "reformat_golden_args is only valid if a reformat_goldens_bin is specified")
      }
    }
  }

  # Make the copy of the goldens available to the test at runtime.
  target_test_data_goldens = "${target_name}_test_data_goldens"
  host_test_data(target_test_data_goldens) {
    visibility = [ ":*" ]
    deps = [ ":${target_reformat_goldens}" ]
    sources = []
    foreach(golden, goldens_list) {
      sources += [ "${copied_goldens_dir}/${golden}" ]
    }
  }

  # Generate the manifest file.
  target_generate_manifest = "${target_name}_generate_manifest"
  generated_file(target_generate_manifest) {
    visibility = [ ":*" ]
    testonly = true
    contents = {
      test_goldens_dir = rebase_path(copied_goldens_dir, root_build_dir)
      regen_goldens_dir = rebase_path(invoker.goldens_dir, root_build_dir)
      entries = []
    }
    foreach(entry, invoker.entries) {
      assert(get_path_info(entry.golden, "extension") == "golden",
             "Golden filename '${entry.golden}' does not end in '.golden'")
      contents.entries += [
        {
          golden = entry.golden
          generated = rebase_path(entry.generated, root_build_dir)
        },
      ]
    }
    outputs = [ manifest_file ]
    output_conversion = "json"
  }

  # Allow the test to access the manifest file and generated files.
  target_generated_files = "${target_name}_generated_files"
  host_test_data(target_generated_files) {
    visibility = [ ":*" ]
    sources = [ manifest_file ]
    foreach(entry, invoker.entries) {
      sources += [ entry.generated ]
    }
    deps = [ ":${target_generate_manifest}" ] + invoker.deps
  }

  # Generate a test target, so that this test can be executed with `fx test`.
  host_test(target_name) {
    forward_variables_from(invoker, [ "visibility" ])
    binary_path = "${root_out_dir}/golden-util"
    args = [
      "--manifest",
      rebase_path(manifest_file, root_build_dir),
    ]
    if (bless_goldens) {
      args += [ "--regen" ]
    }
    deps = [
      ":${target_generated_files}",
      ":${target_test_data_goldens_list}",
      ":${target_test_data_goldens}",
      "//tools/golden-util",
    ]
  }
}
