Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 1 | // Part of the Crubit project, under the Apache License v2.0 with LLVM |
| 2 | // Exceptions. See /LICENSE for license information. |
| 3 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 4 | |
| 5 | #include "rs_bindings_from_cc/cmdline.h" |
| 6 | |
| 7 | #include <string> |
| 8 | #include <vector> |
| 9 | |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 10 | #include "testing/base/public/gmock.h" |
| 11 | #include "testing/base/public/gunit.h" |
Marcel Hlopko | 3b254b3 | 2022-03-09 14:10:49 +0000 | [diff] [blame] | 12 | #include "rs_bindings_from_cc/bazel_types.h" |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 13 | |
Marcel Hlopko | f15e8ce | 2022-04-08 08:46:09 -0700 | [diff] [blame] | 14 | namespace crubit { |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 15 | namespace { |
| 16 | |
| 17 | using ::testing::AllOf; |
| 18 | using ::testing::ElementsAre; |
| 19 | using ::testing::HasSubstr; |
| 20 | using ::testing::Pair; |
| 21 | using ::testing::UnorderedElementsAre; |
| 22 | using ::testing::status::StatusIs; |
| 23 | |
| 24 | namespace { |
| 25 | |
| 26 | absl::StatusOr<Cmdline> TestCmdline(std::vector<std::string> public_headers, |
| 27 | const std::string& targets_and_headers) { |
Marcel Hlopko | 18bb5d2 | 2022-05-09 04:23:43 -0700 | [diff] [blame] | 28 | return Cmdline::CreateForTesting( |
| 29 | "cc_out", "rs_out", "ir_out", "crubit_support_path", |
| 30 | "rustfmt_config_path", |
| 31 | |
| 32 | /* do_nothing= */ false, std::move(public_headers), |
| 33 | std::move(targets_and_headers), /* rust_sources= */ {}, |
| 34 | /* instantiations_out= */ ""); |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 35 | } |
| 36 | |
| 37 | } // namespace |
| 38 | |
| 39 | TEST(CmdlineTest, BasicCorrectInput) { |
Lukasz Anforowicz | dd90770 | 2022-05-06 09:24:07 -0700 | [diff] [blame] | 40 | ASSERT_OK_AND_ASSIGN( |
| 41 | Cmdline cmdline, |
| 42 | Cmdline::CreateForTesting("cc_out", "rs_out", "ir_out", |
| 43 | "crubit_support_path", "rustfmt_config_path", |
| 44 | /* do_nothing= */ false, {"h1"}, |
Marcel Hlopko | 18bb5d2 | 2022-05-09 04:23:43 -0700 | [diff] [blame] | 45 | R"([{"t": "t1", "h": ["h1", "h2"]}])", |
| 46 | {"lib.rs"}, "instantiations_out")); |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 47 | EXPECT_EQ(cmdline.cc_out(), "cc_out"); |
| 48 | EXPECT_EQ(cmdline.rs_out(), "rs_out"); |
| 49 | EXPECT_EQ(cmdline.ir_out(), "ir_out"); |
Lukasz Anforowicz | dd90770 | 2022-05-06 09:24:07 -0700 | [diff] [blame] | 50 | EXPECT_EQ(cmdline.crubit_support_path(), "crubit_support_path"); |
Lukasz Anforowicz | 54ff318 | 2022-05-06 07:17:58 -0700 | [diff] [blame] | 51 | EXPECT_EQ(cmdline.rustfmt_config_path(), "rustfmt_config_path"); |
Marcel Hlopko | 18bb5d2 | 2022-05-09 04:23:43 -0700 | [diff] [blame] | 52 | EXPECT_EQ(cmdline.instantiations_out(), "instantiations_out"); |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 53 | EXPECT_EQ(cmdline.do_nothing(), false); |
| 54 | EXPECT_EQ(cmdline.current_target().value(), "t1"); |
| 55 | EXPECT_THAT(cmdline.public_headers(), ElementsAre(HeaderName("h1"))); |
Marcel Hlopko | 18bb5d2 | 2022-05-09 04:23:43 -0700 | [diff] [blame] | 56 | EXPECT_THAT(cmdline.rust_sources(), ElementsAre("lib.rs")); |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 57 | EXPECT_THAT(cmdline.headers_to_targets(), |
Googler | 6c3de12 | 2022-03-28 11:40:41 +0000 | [diff] [blame] | 58 | UnorderedElementsAre(Pair(HeaderName("h1"), BazelLabel("t1")), |
| 59 | Pair(HeaderName("h2"), BazelLabel("t1")))); |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 60 | } |
| 61 | |
| 62 | TEST(CmdlineTest, TargetsAndHeadersEmpty) { |
| 63 | ASSERT_THAT(TestCmdline({"h1"}, ""), |
| 64 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 65 | HasSubstr("please specify --targets_and_headers"))); |
| 66 | } |
| 67 | |
Lukasz Anforowicz | 45f2d26 | 2022-03-02 18:37:27 +0000 | [diff] [blame] | 68 | TEST(CmdlineTest, TargetsAndHeadersInvalidJson) { |
Lukasz Anforowicz | 3b4be12 | 2022-03-16 00:09:35 +0000 | [diff] [blame] | 69 | ASSERT_THAT(TestCmdline({"h1"}, "#!$%"), |
| 70 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 71 | AllOf(HasSubstr("--targets_and_headers"), |
| 72 | HasSubstr("Invalid JSON")))); |
Lukasz Anforowicz | 45f2d26 | 2022-03-02 18:37:27 +0000 | [diff] [blame] | 73 | } |
| 74 | |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 75 | TEST(CmdlineTest, TargetsAndHeadersIntInsteadOfTopLevelArray) { |
| 76 | ASSERT_THAT( |
| 77 | TestCmdline({"h1"}, "123"), |
| 78 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 79 | AllOf(HasSubstr("--targets_and_headers"), HasSubstr("array")))); |
| 80 | } |
| 81 | |
Lukasz Anforowicz | 45f2d26 | 2022-03-02 18:37:27 +0000 | [diff] [blame] | 82 | TEST(CmdlineTest, TargetsAndHeadersIntInTopLevelArray) { |
| 83 | ASSERT_THAT(TestCmdline({"h1"}, "[123, 456]"), |
| 84 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 85 | AllOf(HasSubstr("--targets_and_headers")))); |
| 86 | } |
| 87 | |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 88 | TEST(CmdlineTest, TargetsAndHeadersIntInsteadOfHeadersArray) { |
| 89 | ASSERT_THAT(TestCmdline({"h1"}, R"([{"t": "t1", "h": 123}])"), |
| 90 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 91 | AllOf(HasSubstr("--targets_and_headers"), |
Lukasz Anforowicz | 3b4be12 | 2022-03-16 00:09:35 +0000 | [diff] [blame] | 92 | HasSubstr(".h"), HasSubstr("array")))); |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 93 | } |
| 94 | |
Lukasz Anforowicz | 45f2d26 | 2022-03-02 18:37:27 +0000 | [diff] [blame] | 95 | TEST(CmdlineTest, TargetsAndHeadersMissingTarget) { |
| 96 | ASSERT_THAT(TestCmdline({"h1"}, R"([{"h": ["h1", "h2"]}])"), |
| 97 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 98 | AllOf(HasSubstr("--targets_and_headers"), |
Lukasz Anforowicz | 3b4be12 | 2022-03-16 00:09:35 +0000 | [diff] [blame] | 99 | HasSubstr(".t"), HasSubstr("missing")))); |
Lukasz Anforowicz | 45f2d26 | 2022-03-02 18:37:27 +0000 | [diff] [blame] | 100 | } |
| 101 | |
| 102 | TEST(CmdlineTest, TargetsAndHeadersMissingHeader) { |
| 103 | ASSERT_THAT(TestCmdline({"h1"}, R"([{"t": "t1"}])"), |
| 104 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 105 | AllOf(HasSubstr("--targets_and_headers"), |
Lukasz Anforowicz | 3b4be12 | 2022-03-16 00:09:35 +0000 | [diff] [blame] | 106 | HasSubstr(".h"), HasSubstr("missing")))); |
Lukasz Anforowicz | 45f2d26 | 2022-03-02 18:37:27 +0000 | [diff] [blame] | 107 | } |
| 108 | |
| 109 | TEST(CmdlineTest, TargetsAndHeadersEmptyHeader) { |
| 110 | ASSERT_THAT(TestCmdline({"h1"}, R"([{"t": "t1", "h": ["", "h2"]}])"), |
| 111 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 112 | AllOf(HasSubstr("--targets_and_headers"), |
| 113 | HasSubstr("`h`"), HasSubstr("empty string")))); |
| 114 | } |
| 115 | |
| 116 | TEST(CmdlineTest, TargetsAndHeadersEmptyTarget) { |
| 117 | ASSERT_THAT(TestCmdline({"h1"}, R"([{"t": "", "h": ["h1", "h2"]}])"), |
| 118 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 119 | AllOf(HasSubstr("--targets_and_headers"), |
| 120 | HasSubstr("`t`"), HasSubstr("empty string")))); |
| 121 | } |
| 122 | |
| 123 | TEST(CmdlineTest, TargetsAndHeadersIntInsteadOfTarget) { |
| 124 | ASSERT_THAT(TestCmdline({"h1"}, R"([{"t": 123, "h": ["h1", "h2"]}])"), |
| 125 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 126 | AllOf(HasSubstr("--targets_and_headers"), |
Lukasz Anforowicz | 3b4be12 | 2022-03-16 00:09:35 +0000 | [diff] [blame] | 127 | HasSubstr(".t"), HasSubstr("string")))); |
Lukasz Anforowicz | 45f2d26 | 2022-03-02 18:37:27 +0000 | [diff] [blame] | 128 | } |
| 129 | |
| 130 | TEST(CmdlineTest, TargetsAndHeadersIntInsteadOfHeader) { |
| 131 | ASSERT_THAT(TestCmdline({"h1"}, R"([{"t": "t1", "h": [123, "h2"]}])"), |
| 132 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 133 | AllOf(HasSubstr("--targets_and_headers"), |
Lukasz Anforowicz | 3b4be12 | 2022-03-16 00:09:35 +0000 | [diff] [blame] | 134 | HasSubstr(".h"), HasSubstr("string")))); |
Lukasz Anforowicz | 45f2d26 | 2022-03-02 18:37:27 +0000 | [diff] [blame] | 135 | } |
| 136 | |
| 137 | TEST(CmdlineTest, TargetsAndHeadersDuplicateHeader) { |
Marcel Hlopko | 315a2be | 2022-05-09 04:19:08 -0700 | [diff] [blame] | 138 | constexpr absl::string_view kTestInput = R"([ |
Lukasz Anforowicz | 45f2d26 | 2022-03-02 18:37:27 +0000 | [diff] [blame] | 139 | {"t": "t1", "h": ["h1"]}, |
| 140 | {"t": "t2", "h": ["h1"]} ])"; |
| 141 | ASSERT_THAT( |
Marcel Hlopko | 315a2be | 2022-05-09 04:19:08 -0700 | [diff] [blame] | 142 | TestCmdline({"h1"}, std::string(kTestInput)), |
Lukasz Anforowicz | 45f2d26 | 2022-03-02 18:37:27 +0000 | [diff] [blame] | 143 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 144 | AllOf(HasSubstr("--targets_and_headers"), HasSubstr("conflict"), |
| 145 | HasSubstr("h1"), HasSubstr("t1"), HasSubstr("t2")))); |
| 146 | } |
| 147 | |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 148 | TEST(CmdlineTest, PublicHeadersEmpty) { |
Marcel Hlopko | 315a2be | 2022-05-09 04:19:08 -0700 | [diff] [blame] | 149 | constexpr absl::string_view kTargetsAndHeaders = R"([ |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 150 | {"t": "target1", "h": ["a.h", "b.h"]} |
| 151 | ])"; |
Marcel Hlopko | 315a2be | 2022-05-09 04:19:08 -0700 | [diff] [blame] | 152 | ASSERT_THAT(TestCmdline({}, std::string(kTargetsAndHeaders)), |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 153 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 154 | HasSubstr("please specify --public_headers"))); |
| 155 | } |
| 156 | |
| 157 | TEST(CmdlineTest, PublicHeadersWhereFirstHeaderMissingInMap) { |
Marcel Hlopko | 315a2be | 2022-05-09 04:19:08 -0700 | [diff] [blame] | 158 | constexpr absl::string_view kTargetsAndHeaders = R"([ |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 159 | {"t": "target1", "h": ["a.h", "b.h"]} |
| 160 | ])"; |
| 161 | ASSERT_THAT( |
Marcel Hlopko | 315a2be | 2022-05-09 04:19:08 -0700 | [diff] [blame] | 162 | TestCmdline({"missing-in-map.h"}, std::string(kTargetsAndHeaders)), |
| 163 | StatusIs( |
| 164 | absl::StatusCode::kInvalidArgument, |
| 165 | AllOf(HasSubstr("missing-in-map.h"), HasSubstr("Couldn't find")))); |
| 166 | } |
| 167 | |
| 168 | TEST(CmdlineTest, PublicHeadersWhereSecondHeaderMissingInMap) { |
| 169 | constexpr absl::string_view kTargetsAndHeaders = R"([ |
| 170 | {"t": "target1", "h": ["a.h", "b.h"]} |
| 171 | ])"; |
| 172 | ASSERT_THAT( |
| 173 | TestCmdline({"a.h", "missing.h"}, std::string(kTargetsAndHeaders)), |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 174 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 175 | AllOf(HasSubstr("missing.h"), HasSubstr("Couldn't find")))); |
| 176 | } |
| 177 | |
| 178 | TEST(CmdlineTest, PublicHeadersCoveringMultipleTargets) { |
Marcel Hlopko | 315a2be | 2022-05-09 04:19:08 -0700 | [diff] [blame] | 179 | constexpr absl::string_view kTargetsAndHeaders = R"([ |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 180 | {"t": "target1", "h": ["a.h", "b.h"]}, |
| 181 | {"t": "target2", "h": ["c.h", "d.h"]} |
| 182 | ])"; |
Marcel Hlopko | 315a2be | 2022-05-09 04:19:08 -0700 | [diff] [blame] | 183 | ASSERT_THAT(TestCmdline({"a.h", "c.h"}, std::string(kTargetsAndHeaders)), |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 184 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 185 | AllOf(HasSubstr("Expected all public headers to belong " |
| 186 | "to the current target"), |
| 187 | HasSubstr("target1"), HasSubstr("target2"), |
| 188 | HasSubstr("c.h")))); |
| 189 | } |
| 190 | |
Marcel Hlopko | 18bb5d2 | 2022-05-09 04:23:43 -0700 | [diff] [blame] | 191 | TEST(CmdlineTest, InstantiationsOutEmpty) { |
Marcel Hlopko | 315a2be | 2022-05-09 04:19:08 -0700 | [diff] [blame] | 192 | constexpr absl::string_view kTargetsAndHeaders = R"([ |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 193 | {"t": "target1", "h": ["a.h", "b.h"]} |
| 194 | ])"; |
Marcel Hlopko | 315a2be | 2022-05-09 04:19:08 -0700 | [diff] [blame] | 195 | ASSERT_THAT( |
Marcel Hlopko | 18bb5d2 | 2022-05-09 04:23:43 -0700 | [diff] [blame] | 196 | (Cmdline::CreateForTesting("cc_out", "rs_out", "ir_out", |
| 197 | "crubit_support_path", "rustfmt_config_path", |
| 198 | /* do_nothing= */ false, {"a.h"}, |
| 199 | std::string(kTargetsAndHeaders), {"lib.rs"}, |
| 200 | /* instantiations_out= */ "")), |
| 201 | StatusIs( |
| 202 | absl::StatusCode::kInvalidArgument, |
| 203 | HasSubstr( |
| 204 | "please specify both --rust_sources and --instantiations_out " |
| 205 | "when requesting a template instantiation mode"))); |
| 206 | } |
| 207 | |
| 208 | TEST(CmdlineTest, RustSourcesEmpty) { |
| 209 | constexpr absl::string_view kTargetsAndHeaders = R"([ |
| 210 | {"t": "target1", "h": ["a.h", "b.h"]} |
| 211 | ])"; |
| 212 | ASSERT_THAT( |
| 213 | Cmdline::CreateForTesting("cc_out", "rs_out", "ir_out", |
| 214 | "crubit_support_path", "rustfmt_config_path", |
| 215 | /* do_nothing= */ false, {"a.h"}, |
| 216 | std::string(kTargetsAndHeaders), |
| 217 | /* rust_sources= */ {}, "instantiations_out"), |
| 218 | StatusIs( |
| 219 | absl::StatusCode::kInvalidArgument, |
| 220 | HasSubstr( |
| 221 | "please specify both --rust_sources and --instantiations_out " |
| 222 | "when requesting a template instantiation mode"))); |
| 223 | } |
| 224 | |
| 225 | TEST(CmdlineTest, CcOutEmpty) { |
| 226 | constexpr absl::string_view kTargetsAndHeaders = R"([ |
| 227 | {"t": "target1", "h": ["a.h", "b.h"]} |
| 228 | ])"; |
| 229 | ASSERT_THAT(Cmdline::CreateForTesting( |
| 230 | /* cc_out= */ "", "rs_out", "ir_out", "crubit_support_path", |
| 231 | "rustfmt_config_path", |
| 232 | /* do_nothing= */ false, {"a.h"}, |
| 233 | std::string(kTargetsAndHeaders), /* rust_sources= */ {}, |
| 234 | /* instantiations_out= */ ""), |
| 235 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 236 | HasSubstr("please specify --cc_out"))); |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 237 | } |
| 238 | |
| 239 | TEST(CmdlineTest, RsOutEmpty) { |
Marcel Hlopko | 315a2be | 2022-05-09 04:19:08 -0700 | [diff] [blame] | 240 | constexpr absl::string_view kTargetsAndHeaders = R"([ |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 241 | {"t": "target1", "h": ["a.h", "b.h"]} |
| 242 | ])"; |
Marcel Hlopko | 315a2be | 2022-05-09 04:19:08 -0700 | [diff] [blame] | 243 | ASSERT_THAT( |
| 244 | Cmdline::CreateForTesting("cc_out", /* rs_out= */ "", "ir_out", |
| 245 | "crubit_support_path", "rustfmt_config_path", |
| 246 | /* do_nothing= */ false, {"a.h"}, |
Marcel Hlopko | 18bb5d2 | 2022-05-09 04:23:43 -0700 | [diff] [blame] | 247 | std::string(kTargetsAndHeaders), |
| 248 | /* rust_sources= */ {}, |
| 249 | /* instantiations_out= */ ""), |
Marcel Hlopko | 315a2be | 2022-05-09 04:19:08 -0700 | [diff] [blame] | 250 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 251 | HasSubstr("please specify --rs_out"))); |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 252 | } |
| 253 | |
| 254 | TEST(CmdlineTest, IrOutEmpty) { |
Marcel Hlopko | 315a2be | 2022-05-09 04:19:08 -0700 | [diff] [blame] | 255 | constexpr absl::string_view kTargetsAndHeaders = R"([ |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 256 | {"t": "target1", "h": ["a.h", "b.h"]} |
| 257 | ])"; |
Lukasz Anforowicz | 54ff318 | 2022-05-06 07:17:58 -0700 | [diff] [blame] | 258 | ASSERT_OK(Cmdline::CreateForTesting( |
Lukasz Anforowicz | dd90770 | 2022-05-06 09:24:07 -0700 | [diff] [blame] | 259 | "cc_out", "rs_out", /* ir_out= */ "", "crubit_support_path", |
| 260 | "rustfmt_config_path", |
Marcel Hlopko | 18bb5d2 | 2022-05-09 04:23:43 -0700 | [diff] [blame] | 261 | /* do_nothing= */ false, {"a.h"}, std::string(kTargetsAndHeaders), |
| 262 | /* rust_sources= */ {}, |
| 263 | /* instantiations_out= */ "")); |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 264 | } |
| 265 | |
| 266 | } // namespace |
Marcel Hlopko | f15e8ce | 2022-04-08 08:46:09 -0700 | [diff] [blame] | 267 | } // namespace crubit |