| # Copyright 2013 The Flutter 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/compiled_action.gni") |
| import("//flutter/build/dart/rules.gni") |
| import("//flutter/common/config.gni") |
| |
| is_aot_test = |
| flutter_runtime_mode == "profile" || flutter_runtime_mode == "release" |
| |
| # Build unit tests when any of the following are true: |
| # * host_toolchain: non-cross-compile, so we can run tests on the host. |
| # * is_mac: arm64 builds can run x64 binaries. |
| # * is_fuchsia: build unittests for testing on device. |
| declare_args() { |
| enable_unittests = current_toolchain == host_toolchain || is_fuchsia || is_mac |
| } |
| |
| # Creates a translation unit that defines the flutter::testing::GetFixturesPath |
| # method that tests can use to locate their fixtures. |
| # |
| # Arguments |
| # assets_dir (required): The assets directory |
| template("fixtures_location") { |
| testonly = true |
| |
| assert(defined(invoker.assets_dir), "The assets directory.") |
| |
| location_path = rebase_path(invoker.assets_dir) |
| testing_assets_path = rebase_path("$root_out_dir/gen/flutter/testing/assets") |
| source_path = rebase_path("//") |
| |
| # Array of source lines. We use a list to ensure a trailing newline is |
| # emitted by write_file() to comply with -Wnewline-eof. |
| location_source = [ |
| "namespace flutter { namespace testing { ", |
| "const char* GetSourcePath() {return \"$source_path\";} ", |
| "const char* GetFixturesPath() {return \"$location_path\";} ", |
| "const char* GetTestingAssetsPath() {return \"$testing_assets_path\";} ", |
| "}}", |
| ] |
| location_source_path = "$target_gen_dir/_fl_$target_name.cc" |
| |
| write_file(location_source_path, location_source) |
| |
| source_set(target_name) { |
| public = [] |
| sources = [ location_source_path ] |
| } |
| } |
| |
| # Generates the Dart kernel snapshot. |
| # |
| # Arguments |
| # dart_main (required): The Main Dart file. |
| # |
| # dart_kernel (required): The path to the output kernel snapshot in the out |
| # directory. |
| template("dart_snapshot_kernel") { |
| testonly = true |
| |
| assert(defined(invoker.dart_main), "The Dart Main file must be specified") |
| assert(defined(invoker.dart_kernel), |
| "The Dart Kernel file location must be specified") |
| |
| args = [] |
| if (flutter_runtime_mode == "release" || |
| flutter_runtime_mode == "jit_release") { |
| args += [ "-Ddart.vm.product=true" ] |
| } |
| |
| if (is_aot_test) { |
| args += [ |
| "--aot", |
| |
| # type flow analysis |
| "--tfa", |
| ] |
| } |
| |
| flutter_frontend_server(target_name) { |
| testonly = true |
| main_dart = invoker.dart_main |
| kernel_output = invoker.dart_kernel |
| extra_args = args |
| } |
| } |
| |
| # Generates an AOT snapshot from a kernel snapshot. |
| # |
| # Arguments: |
| # |
| # dart_kernel (required): The path to the kernel snapshot. |
| # |
| # dart_elf_filename (required): The filename of the AOT ELF snapshot. |
| template("dart_snapshot_aot") { |
| testonly = true |
| |
| assert(defined(invoker.dart_kernel), |
| "The Dart Kernel file location must be specified") |
| |
| assert(defined(invoker.dart_elf_filename), |
| "The main Dart ELF filename must be specified.") |
| |
| compiled_action(target_name) { |
| testonly = true |
| |
| tool = "$dart_src/runtime/bin:gen_snapshot" |
| |
| pool = "//flutter/build/dart:dart_pool" |
| |
| inputs = [ invoker.dart_kernel ] |
| |
| # Custom ELF loader is used for Mac and Windows. |
| elf_object = "$target_gen_dir/assets/${invoker.dart_elf_filename}" |
| |
| loading_unit_manifest = "$target_gen_dir/assets/loading_unit_manifest.json" |
| |
| outputs = [ elf_object ] |
| |
| args = [ |
| "--deterministic", |
| "--snapshot_kind=app-aot-elf", |
| "--loading_unit_manifest=" + rebase_path(loading_unit_manifest), |
| "--elf=" + rebase_path(elf_object), |
| rebase_path(invoker.dart_kernel), |
| ] |
| |
| forward_variables_from(invoker, [ "deps" ]) |
| } |
| } |
| |
| # Generates a kernel or AOT snapshot as necessary from the main Dart file. |
| # Other Dart dependencies referenced by that main Dart file will be tracked. |
| # |
| # Arguments: |
| # |
| # dart_main (required): The path to the main Dart file. |
| # |
| # dart_kernel_filename (required): The filename of the kernel blob. |
| # |
| # dart_elf_filename (required): The filename of the AOT ELF snapshot only if is_aot_test is true. |
| template("dart_snapshot") { |
| assert(defined(invoker.dart_main), "The main Dart file must be specified.") |
| assert(defined(invoker.dart_kernel_filename), |
| "The main Dart kernel filename must be specified.") |
| |
| testonly = true |
| |
| dart_snapshot_kernel_target_name = "_dsk_$target_name" |
| |
| dart_snapshot_kernel_path = |
| "$target_gen_dir/assets/${invoker.dart_kernel_filename}" |
| |
| dart_snapshot_kernel(dart_snapshot_kernel_target_name) { |
| dart_main = invoker.dart_main |
| dart_kernel = dart_snapshot_kernel_path |
| } |
| |
| snapshot_deps = [] |
| snapshot_public_deps = [ ":$dart_snapshot_kernel_target_name" ] |
| |
| if (is_aot_test) { |
| assert(defined(invoker.dart_elf_filename), |
| "The main Dart ELF filename must be specified.") |
| |
| dart_snapshot_aot_target_name = "_dsa_$target_name" |
| dart_snapshot_aot(dart_snapshot_aot_target_name) { |
| dart_kernel = dart_snapshot_kernel_path |
| dart_elf_filename = invoker.dart_elf_filename |
| deps = [ ":$dart_snapshot_kernel_target_name" ] |
| } |
| snapshot_deps += [ ":$dart_snapshot_aot_target_name" ] |
| } |
| |
| group(target_name) { |
| testonly = true |
| deps = snapshot_deps |
| public_deps = snapshot_public_deps |
| } |
| } |
| |
| # Copies a (potentially empty) list of fixtures to the fixtures directory for |
| # the unit test. |
| # |
| # Arguments: |
| # |
| # fixtures (required): The list of fixtures to copy. |
| # |
| # dest (optional): When specified, the fixtures are placed under an |
| # 'assets' subdirectory of this path rather than an |
| # 'assets' subdirectory of target_gen_dir. |
| template("copy_fixtures") { |
| testonly = true |
| |
| assert(defined(invoker.fixtures), "The test fixtures must be specified.") |
| |
| dest = target_gen_dir |
| if (defined(invoker.dest)) { |
| dest = invoker.dest |
| } |
| |
| has_fixtures = false |
| foreach(fixture, invoker.fixtures) { |
| has_fixtures = true |
| } |
| |
| if (has_fixtures) { |
| copy(target_name) { |
| sources = invoker.fixtures |
| outputs = [ "$dest/assets/{{source_file_part}}" ] |
| forward_variables_from(invoker, [ "deps" ]) |
| } |
| } else { |
| group(target_name) { |
| # The copy target cannot accept an empty list. |
| } |
| } |
| } |
| |
| # Specifies the fixtures to copy to a location known by the specific unit test. |
| # Test executable can only depend on one such target. You can use either one of |
| # both arguments to expand this template. If you have none, then you'll see the |
| # unused invoker scope error. In such cases specify the fixtures using an empty |
| # array. |
| # |
| # The targets which generate the outputs from these test fixtures (e.g. the |
| # Dart kernel snapshot) are exposed as public dependencies of the test fixture |
| # target. This is so that users can depend on the test fixture target directly |
| # and be able to access the generated outputs without needing to know about the |
| # internal dependency structure generated by this template. |
| # |
| # Arguments: |
| # |
| # fixtures (optional): The list of test fixtures. An empty list may be |
| # specified. |
| # |
| # dart_main (optional): The path to the main Dart file. If specified, it is |
| # snapshotted. |
| # |
| # use_target_as_artifact_prefix(optional): If true, adds the target name as |
| # prefix of the kernel and AOT ELF snapshot filename. |
| # |
| # dest (optional): When specified, the fixtures are placed under an |
| # 'assets' subdirectory of this path rather than an |
| # 'assets' subdirectory of target_gen_dir. |
| template("test_fixtures") { |
| dest = target_gen_dir |
| if (defined(invoker.dest)) { |
| dest = invoker.dest |
| } |
| |
| # Not all paths use 'dest' |
| not_needed([ "dest" ]) |
| |
| # Even if no fixtures are present, the location of the fixtures directory |
| # must always be known to tests. |
| fixtures_location_target_name = "_fl_$target_name" |
| fixtures_location(fixtures_location_target_name) { |
| if (is_fuchsia) { |
| assets_dir = "/pkg/data/assets" |
| } else { |
| assets_dir = "$dest/assets" |
| } |
| } |
| test_deps = [ ":$fixtures_location_target_name" ] |
| test_public_deps = [] |
| |
| # If the fixtures are specified, copy them to the assets directory. |
| if (defined(invoker.fixtures)) { |
| copy_fixtures_target_name = "_cf_$target_name" |
| copy_fixtures(copy_fixtures_target_name) { |
| fixtures = invoker.fixtures |
| dest = dest |
| forward_variables_from(invoker, [ "deps" ]) |
| } |
| test_public_deps += [ ":$copy_fixtures_target_name" ] |
| } |
| |
| # If a Dart file is specified, snapshot it and place it in the generated |
| # assets directory. |
| if (defined(invoker.dart_main)) { |
| if (defined(invoker.use_target_as_artifact_prefix) && |
| invoker.use_target_as_artifact_prefix) { |
| artifact_prefix = "${target_name}_" |
| } else { |
| artifact_prefix = "" |
| } |
| dart_snapshot_target_name = "_ds_$target_name" |
| dart_snapshot(dart_snapshot_target_name) { |
| dart_main = invoker.dart_main |
| dart_kernel_filename = "${artifact_prefix}kernel_blob.bin" |
| if (is_aot_test) { |
| dart_elf_filename = "${artifact_prefix}app_elf_snapshot.so" |
| } |
| } |
| |
| test_public_deps += [ ":$dart_snapshot_target_name" ] |
| } |
| |
| group(target_name) { |
| testonly = true |
| deps = test_deps |
| public_deps = test_public_deps |
| } |
| } |