| // Copyright 2019 The Chromium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "gn/config.h" | |
| #include "gn/scheduler.h" | |
| #include "gn/scope.h" | |
| #include "gn/test_with_scheduler.h" | |
| #include "gn/test_with_scope.h" | |
| #include "util/test/test.h" | |
| using RustFunctionsTarget = TestWithScheduler; | |
| // Checks that the appropriate crate type is used. | |
| TEST_F(RustFunctionsTarget, CrateName) { | |
| TestWithScope setup; | |
| // The target generator needs a place to put the targets or it will fail. | |
| Scope::ItemVector item_collector; | |
| setup.scope()->set_item_collector(&item_collector); | |
| setup.scope()->set_source_dir(SourceDir("/")); | |
| TestParseInput exe_input( | |
| "executable(\"foo\") {\n" | |
| " crate_name = \"foo_crate\"\n" | |
| " sources = [ \"foo.rs\", \"lib.rs\", \"main.rs\" ]\n" | |
| "}\n"); | |
| ASSERT_FALSE(exe_input.has_error()); | |
| Err err; | |
| exe_input.parsed()->Execute(setup.scope(), &err); | |
| ASSERT_FALSE(err.has_error()) << err.message(); | |
| ASSERT_EQ(item_collector.back()->AsTarget()->rust_values().crate_name(), | |
| "foo_crate"); | |
| TestParseInput lib_input( | |
| "executable(\"foo\") {\n" | |
| " sources = [ \"lib.rs\" ]\n" | |
| "}\n"); | |
| ASSERT_FALSE(lib_input.has_error()); | |
| err = Err(); | |
| lib_input.parsed()->Execute(setup.scope(), &err); | |
| ASSERT_FALSE(err.has_error()) << err.message(); | |
| ASSERT_EQ(item_collector.back()->AsTarget()->rust_values().crate_name(), | |
| "foo") | |
| << item_collector.back()->AsTarget()->rust_values().crate_name(); | |
| } | |
| // Checks that the appropriate crate root is found. | |
| TEST_F(RustFunctionsTarget, CrateRootFind) { | |
| TestWithScope setup; | |
| // The target generator needs a place to put the targets or it will fail. | |
| Scope::ItemVector item_collector; | |
| setup.scope()->set_item_collector(&item_collector); | |
| setup.scope()->set_source_dir(SourceDir("/")); | |
| TestParseInput normal_input( | |
| "executable(\"foo\") {\n" | |
| " crate_root = \"foo.rs\"" | |
| " sources = [ \"main.rs\" ]\n" | |
| "}\n"); | |
| ASSERT_FALSE(normal_input.has_error()); | |
| Err err; | |
| normal_input.parsed()->Execute(setup.scope(), &err); | |
| ASSERT_FALSE(err.has_error()) << err.message(); | |
| ASSERT_EQ( | |
| item_collector.back()->AsTarget()->rust_values().crate_root().value(), | |
| "/foo.rs"); | |
| TestParseInput normal_shlib_input( | |
| "shared_library(\"foo\") {\n" | |
| " crate_root = \"foo.rs\"" | |
| " crate_type = \"dylib\"\n" | |
| " sources = [ \"main.rs\" ]\n" | |
| "}\n"); | |
| ASSERT_FALSE(normal_shlib_input.has_error()); | |
| err = Err(); | |
| normal_shlib_input.parsed()->Execute(setup.scope(), &err); | |
| ASSERT_FALSE(err.has_error()) << err.message(); | |
| ASSERT_EQ( | |
| item_collector.back()->AsTarget()->rust_values().crate_root().value(), | |
| "/foo.rs"); | |
| TestParseInput exe_input( | |
| "executable(\"foo\") {\n" | |
| " sources = [ \"foo.rs\", \"lib.rs\", \"main.rs\" ]\n" | |
| "}\n"); | |
| ASSERT_FALSE(exe_input.has_error()); | |
| err = Err(); | |
| exe_input.parsed()->Execute(setup.scope(), &err); | |
| ASSERT_FALSE(err.has_error()) << err.message(); | |
| ASSERT_EQ( | |
| item_collector.back()->AsTarget()->rust_values().crate_root().value(), | |
| "/main.rs"); | |
| TestParseInput lib_input( | |
| "rust_library(\"libfoo\") {\n" | |
| " sources = [ \"foo.rs\", \"lib.rs\", \"main.rs\" ]\n" | |
| "}\n"); | |
| ASSERT_FALSE(lib_input.has_error()); | |
| err = Err(); | |
| lib_input.parsed()->Execute(setup.scope(), &err); | |
| ASSERT_FALSE(err.has_error()) << err.message(); | |
| ASSERT_EQ( | |
| item_collector.back()->AsTarget()->rust_values().crate_root().value(), | |
| "/lib.rs"); | |
| TestParseInput singlesource_input( | |
| "executable(\"bar\") {\n" | |
| " sources = [ \"bar.rs\" ]\n" | |
| "}\n"); | |
| ASSERT_FALSE(singlesource_input.has_error()); | |
| err = Err(); | |
| singlesource_input.parsed()->Execute(setup.scope(), &err); | |
| ASSERT_FALSE(err.has_error()) << err.message(); | |
| ASSERT_EQ( | |
| item_collector.back()->AsTarget()->rust_values().crate_root().value(), | |
| "/bar.rs"); | |
| TestParseInput error_input( | |
| "rust_library(\"foo\") {\n" | |
| " sources = [ \"foo.rs\", \"main.rs\" ]\n" | |
| "}\n"); | |
| ASSERT_FALSE(error_input.has_error()); | |
| err = Err(); | |
| error_input.parsed()->Execute(setup.scope(), &err); | |
| ASSERT_TRUE(err.has_error()); | |
| EXPECT_EQ("Missing \"crate_root\" and missing \"lib.rs\" in sources.", | |
| err.message()); | |
| TestParseInput nosources_input( | |
| "executable(\"bar\") {\n" | |
| " crate_root = \"bar.rs\"\n" | |
| "}\n"); | |
| ASSERT_FALSE(nosources_input.has_error()); | |
| err = Err(); | |
| nosources_input.parsed()->Execute(setup.scope(), &err); | |
| ASSERT_FALSE(err.has_error()) << err.message(); | |
| ASSERT_EQ( | |
| item_collector.back()->AsTarget()->rust_values().crate_root().value(), | |
| "/bar.rs"); | |
| } | |
| // Checks that the appropriate crate type is used. | |
| TEST_F(RustFunctionsTarget, CrateTypeSelection) { | |
| TestWithScope setup; | |
| // The target generator needs a place to put the targets or it will fail. | |
| Scope::ItemVector item_collector; | |
| setup.scope()->set_item_collector(&item_collector); | |
| setup.scope()->set_source_dir(SourceDir("/")); | |
| TestParseInput lib_input( | |
| "shared_library(\"libfoo\") {\n" | |
| " crate_type = \"dylib\"\n" | |
| " sources = [ \"lib.rs\" ]\n" | |
| "}\n"); | |
| ASSERT_FALSE(lib_input.has_error()); | |
| Err err; | |
| lib_input.parsed()->Execute(setup.scope(), &err); | |
| ASSERT_FALSE(err.has_error()) << err.message(); | |
| ASSERT_EQ(item_collector.back()->AsTarget()->rust_values().crate_type(), | |
| RustValues::CRATE_DYLIB); | |
| TestParseInput exe_non_default_input( | |
| "executable(\"foo\") {\n" | |
| " crate_type = \"rlib\"\n" | |
| " sources = [ \"main.rs\" ]\n" | |
| "}\n"); | |
| ASSERT_FALSE(exe_non_default_input.has_error()); | |
| err = Err(); | |
| exe_non_default_input.parsed()->Execute(setup.scope(), &err); | |
| ASSERT_FALSE(err.has_error()) << err.message(); | |
| ASSERT_EQ(item_collector.back()->AsTarget()->rust_values().crate_type(), | |
| RustValues::CRATE_RLIB); | |
| TestParseInput lib_error_input( | |
| "shared_library(\"foo\") {\n" | |
| " crate_type = \"bad\"\n" | |
| " sources = [ \"lib.rs\" ]\n" | |
| "}\n"); | |
| ASSERT_FALSE(lib_error_input.has_error()); | |
| err = Err(); | |
| lib_error_input.parsed()->Execute(setup.scope(), &err); | |
| ASSERT_TRUE(err.has_error()); | |
| EXPECT_EQ("Inadmissible crate type \"bad\".", err.message()) << err.message(); | |
| TestParseInput lib_missing_error_input( | |
| "shared_library(\"foo\") {\n" | |
| " sources = [ \"lib.rs\" ]\n" | |
| "}\n"); | |
| ASSERT_FALSE(lib_missing_error_input.has_error()); | |
| err = Err(); | |
| lib_missing_error_input.parsed()->Execute(setup.scope(), &err); | |
| ASSERT_TRUE(err.has_error()); | |
| EXPECT_EQ("Must set \"crate_type\" on a Rust \"shared_library\".", | |
| err.message()); | |
| } | |
| // Checks that the appropriate config values are propagated. | |
| TEST_F(RustFunctionsTarget, ConfigValues) { | |
| TestWithScope setup; | |
| // The target generator needs a place to put the targets or it will fail. | |
| Scope::ItemVector item_collector; | |
| setup.scope()->set_item_collector(&item_collector); | |
| setup.scope()->set_source_dir(SourceDir("/")); | |
| TestParseInput exe_input( | |
| "config(\"foo\") {\n" | |
| " rustflags = [ \"-Cdebuginfo=2\" ]\n" | |
| " rustenv = [ \"RUST_BACKTRACE=1\" ]" | |
| "}\n"); | |
| ASSERT_FALSE(exe_input.has_error()); | |
| Err err; | |
| exe_input.parsed()->Execute(setup.scope(), &err); | |
| ASSERT_FALSE(err.has_error()) << err.message(); | |
| EXPECT_EQ(item_collector.back()->AsConfig()->own_values().rustflags().size(), | |
| 1U); | |
| EXPECT_EQ(item_collector.back()->AsConfig()->own_values().rustflags()[0], | |
| "-Cdebuginfo=2"); | |
| EXPECT_EQ(item_collector.back()->AsConfig()->own_values().rustenv().size(), | |
| 1U); | |
| EXPECT_EQ(item_collector.back()->AsConfig()->own_values().rustenv()[0], | |
| "RUST_BACKTRACE=1"); | |
| } | |
| // Checks that set_defaults works properly. | |
| TEST_F(RustFunctionsTarget, SetDefaults) { | |
| TestWithScope setup; | |
| // The target generator needs a place to put the targets or it will fail. | |
| Scope::ItemVector item_collector; | |
| setup.scope()->set_item_collector(&item_collector); | |
| setup.scope()->set_source_dir(SourceDir("/")); | |
| TestParseInput exe_input( | |
| "config(\"foo\") {\n" | |
| " rustflags = [ \"-Cdebuginfo=2\" ]\n" | |
| " rustenv = [ \"RUST_BACKTRACE=1\" ]" | |
| "}\n" | |
| "set_defaults(\"rust_library\") {\n" | |
| " configs = [ \":foo\" ]\n" | |
| "}\n"); | |
| ASSERT_FALSE(exe_input.has_error()); | |
| Err err; | |
| exe_input.parsed()->Execute(setup.scope(), &err); | |
| ASSERT_FALSE(err.has_error()) << err.message() << err.message(); | |
| EXPECT_EQ(setup.scope() | |
| ->GetTargetDefaults("rust_library") | |
| ->GetValue("configs") | |
| ->type(), | |
| Value::LIST); | |
| EXPECT_EQ(setup.scope() | |
| ->GetTargetDefaults("rust_library") | |
| ->GetValue("configs") | |
| ->list_value() | |
| .size(), | |
| 1U); | |
| EXPECT_EQ(setup.scope() | |
| ->GetTargetDefaults("rust_library") | |
| ->GetValue("configs") | |
| ->list_value()[0] | |
| .type(), | |
| Value::STRING); | |
| EXPECT_EQ(setup.scope() | |
| ->GetTargetDefaults("rust_library") | |
| ->GetValue("configs") | |
| ->list_value()[0] | |
| .string_value(), | |
| ":foo"); | |
| } | |
| // Checks aliased_deps parsing. | |
| TEST_F(RustFunctionsTarget, AliasedDeps) { | |
| TestWithScope setup; | |
| // The target generator needs a place to put the targets or it will fail. | |
| Scope::ItemVector item_collector; | |
| setup.scope()->set_item_collector(&item_collector); | |
| setup.scope()->set_source_dir(SourceDir("/")); | |
| TestParseInput exe_input( | |
| "executable(\"foo\") {\n" | |
| " sources = [ \"main.rs\" ]\n" | |
| " deps = [ \"//bar\", \"//baz\" ]\n" | |
| " aliased_deps = {\n" | |
| " bar_renamed = \"//bar\"\n" | |
| " baz_renamed = \"//baz:baz\"\n" | |
| " }\n" | |
| "}\n"); | |
| ASSERT_FALSE(exe_input.has_error()); | |
| Err err; | |
| exe_input.parsed()->Execute(setup.scope(), &err); | |
| ASSERT_FALSE(err.has_error()) << err.message(); | |
| EXPECT_EQ( | |
| item_collector.back()->AsTarget()->rust_values().aliased_deps().size(), | |
| 2U); | |
| } | |
| TEST_F(RustFunctionsTarget, PublicConfigs) { | |
| TestWithScope setup; | |
| Scope::ItemVector item_collector; | |
| setup.scope()->set_item_collector(&item_collector); | |
| setup.scope()->set_source_dir(SourceDir("/")); | |
| TestParseInput exe_input( | |
| "config(\"bar\") {\n" | |
| " defines = [ \"DOOM_MELON\" ]" | |
| "}\n" | |
| "executable(\"foo\") {\n" | |
| " crate_name = \"foo_crate\"\n" | |
| " sources = [ \"foo.rs\", \"lib.rs\", \"main.rs\" ]\n" | |
| " public_configs = [ \":bar\" ]" | |
| "}\n"); | |
| ASSERT_FALSE(exe_input.has_error()); | |
| Err err; | |
| exe_input.parsed()->Execute(setup.scope(), &err); | |
| ASSERT_FALSE(err.has_error()) << err.message(); | |
| } |