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 | #include "util/task/status_macros.h" |
| 14 | |
| 15 | namespace rs_bindings_from_cc { |
| 16 | namespace { |
| 17 | |
| 18 | using ::testing::AllOf; |
| 19 | using ::testing::ElementsAre; |
| 20 | using ::testing::HasSubstr; |
| 21 | using ::testing::Pair; |
| 22 | using ::testing::UnorderedElementsAre; |
| 23 | using ::testing::status::StatusIs; |
| 24 | |
| 25 | namespace { |
| 26 | |
| 27 | absl::StatusOr<Cmdline> TestCmdline(std::vector<std::string> public_headers, |
| 28 | const std::string& targets_and_headers) { |
| 29 | return Cmdline::CreateForTesting("cc_out", "rs_out", "ir_out", |
| 30 | /* do_nothing= */ false, public_headers, |
| 31 | targets_and_headers); |
| 32 | } |
| 33 | |
| 34 | } // namespace |
| 35 | |
| 36 | TEST(CmdlineTest, BasicCorrectInput) { |
| 37 | ASSERT_OK_AND_ASSIGN( |
| 38 | Cmdline cmdline, |
| 39 | Cmdline::CreateForTesting("cc_out", "rs_out", "ir_out", |
| 40 | /* do_nothing= */ false, {"h1"}, |
| 41 | R"([{"t": "t1", "h": ["h1", "h2"]}])")); |
| 42 | EXPECT_EQ(cmdline.cc_out(), "cc_out"); |
| 43 | EXPECT_EQ(cmdline.rs_out(), "rs_out"); |
| 44 | EXPECT_EQ(cmdline.ir_out(), "ir_out"); |
| 45 | EXPECT_EQ(cmdline.do_nothing(), false); |
| 46 | EXPECT_EQ(cmdline.current_target().value(), "t1"); |
| 47 | EXPECT_THAT(cmdline.public_headers(), ElementsAre(HeaderName("h1"))); |
| 48 | EXPECT_THAT(cmdline.headers_to_targets(), |
| 49 | UnorderedElementsAre(Pair(HeaderName("h1"), BlazeLabel("t1")), |
| 50 | Pair(HeaderName("h2"), BlazeLabel("t1")))); |
| 51 | } |
| 52 | |
| 53 | TEST(CmdlineTest, TargetsAndHeadersEmpty) { |
| 54 | ASSERT_THAT(TestCmdline({"h1"}, ""), |
| 55 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 56 | HasSubstr("please specify --targets_and_headers"))); |
| 57 | } |
| 58 | |
Lukasz Anforowicz | 45f2d26 | 2022-03-02 18:37:27 +0000 | [diff] [blame] | 59 | TEST(CmdlineTest, TargetsAndHeadersInvalidJson) { |
Lukasz Anforowicz | 3b4be12 | 2022-03-16 00:09:35 +0000 | [diff] [blame^] | 60 | ASSERT_THAT(TestCmdline({"h1"}, "#!$%"), |
| 61 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 62 | AllOf(HasSubstr("--targets_and_headers"), |
| 63 | HasSubstr("Invalid JSON")))); |
Lukasz Anforowicz | 45f2d26 | 2022-03-02 18:37:27 +0000 | [diff] [blame] | 64 | } |
| 65 | |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 66 | TEST(CmdlineTest, TargetsAndHeadersIntInsteadOfTopLevelArray) { |
| 67 | ASSERT_THAT( |
| 68 | TestCmdline({"h1"}, "123"), |
| 69 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 70 | AllOf(HasSubstr("--targets_and_headers"), HasSubstr("array")))); |
| 71 | } |
| 72 | |
Lukasz Anforowicz | 45f2d26 | 2022-03-02 18:37:27 +0000 | [diff] [blame] | 73 | TEST(CmdlineTest, TargetsAndHeadersIntInTopLevelArray) { |
| 74 | ASSERT_THAT(TestCmdline({"h1"}, "[123, 456]"), |
| 75 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 76 | AllOf(HasSubstr("--targets_and_headers")))); |
| 77 | } |
| 78 | |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 79 | TEST(CmdlineTest, TargetsAndHeadersIntInsteadOfHeadersArray) { |
| 80 | ASSERT_THAT(TestCmdline({"h1"}, R"([{"t": "t1", "h": 123}])"), |
| 81 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 82 | AllOf(HasSubstr("--targets_and_headers"), |
Lukasz Anforowicz | 3b4be12 | 2022-03-16 00:09:35 +0000 | [diff] [blame^] | 83 | HasSubstr(".h"), HasSubstr("array")))); |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 84 | } |
| 85 | |
Lukasz Anforowicz | 45f2d26 | 2022-03-02 18:37:27 +0000 | [diff] [blame] | 86 | TEST(CmdlineTest, TargetsAndHeadersMissingTarget) { |
| 87 | ASSERT_THAT(TestCmdline({"h1"}, R"([{"h": ["h1", "h2"]}])"), |
| 88 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 89 | AllOf(HasSubstr("--targets_and_headers"), |
Lukasz Anforowicz | 3b4be12 | 2022-03-16 00:09:35 +0000 | [diff] [blame^] | 90 | HasSubstr(".t"), HasSubstr("missing")))); |
Lukasz Anforowicz | 45f2d26 | 2022-03-02 18:37:27 +0000 | [diff] [blame] | 91 | } |
| 92 | |
| 93 | TEST(CmdlineTest, TargetsAndHeadersMissingHeader) { |
| 94 | ASSERT_THAT(TestCmdline({"h1"}, R"([{"t": "t1"}])"), |
| 95 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 96 | AllOf(HasSubstr("--targets_and_headers"), |
Lukasz Anforowicz | 3b4be12 | 2022-03-16 00:09:35 +0000 | [diff] [blame^] | 97 | HasSubstr(".h"), HasSubstr("missing")))); |
Lukasz Anforowicz | 45f2d26 | 2022-03-02 18:37:27 +0000 | [diff] [blame] | 98 | } |
| 99 | |
| 100 | TEST(CmdlineTest, TargetsAndHeadersEmptyHeader) { |
| 101 | ASSERT_THAT(TestCmdline({"h1"}, R"([{"t": "t1", "h": ["", "h2"]}])"), |
| 102 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 103 | AllOf(HasSubstr("--targets_and_headers"), |
| 104 | HasSubstr("`h`"), HasSubstr("empty string")))); |
| 105 | } |
| 106 | |
| 107 | TEST(CmdlineTest, TargetsAndHeadersEmptyTarget) { |
| 108 | ASSERT_THAT(TestCmdline({"h1"}, R"([{"t": "", "h": ["h1", "h2"]}])"), |
| 109 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 110 | AllOf(HasSubstr("--targets_and_headers"), |
| 111 | HasSubstr("`t`"), HasSubstr("empty string")))); |
| 112 | } |
| 113 | |
| 114 | TEST(CmdlineTest, TargetsAndHeadersIntInsteadOfTarget) { |
| 115 | ASSERT_THAT(TestCmdline({"h1"}, R"([{"t": 123, "h": ["h1", "h2"]}])"), |
| 116 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 117 | AllOf(HasSubstr("--targets_and_headers"), |
Lukasz Anforowicz | 3b4be12 | 2022-03-16 00:09:35 +0000 | [diff] [blame^] | 118 | HasSubstr(".t"), HasSubstr("string")))); |
Lukasz Anforowicz | 45f2d26 | 2022-03-02 18:37:27 +0000 | [diff] [blame] | 119 | } |
| 120 | |
| 121 | TEST(CmdlineTest, TargetsAndHeadersIntInsteadOfHeader) { |
| 122 | ASSERT_THAT(TestCmdline({"h1"}, R"([{"t": "t1", "h": [123, "h2"]}])"), |
| 123 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 124 | AllOf(HasSubstr("--targets_and_headers"), |
Lukasz Anforowicz | 3b4be12 | 2022-03-16 00:09:35 +0000 | [diff] [blame^] | 125 | HasSubstr(".h"), HasSubstr("string")))); |
Lukasz Anforowicz | 45f2d26 | 2022-03-02 18:37:27 +0000 | [diff] [blame] | 126 | } |
| 127 | |
| 128 | TEST(CmdlineTest, TargetsAndHeadersDuplicateHeader) { |
| 129 | constexpr char kTestInput[] = R"([ |
| 130 | {"t": "t1", "h": ["h1"]}, |
| 131 | {"t": "t2", "h": ["h1"]} ])"; |
| 132 | ASSERT_THAT( |
| 133 | TestCmdline({"h1"}, kTestInput), |
| 134 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 135 | AllOf(HasSubstr("--targets_and_headers"), HasSubstr("conflict"), |
| 136 | HasSubstr("h1"), HasSubstr("t1"), HasSubstr("t2")))); |
| 137 | } |
| 138 | |
Lukasz Anforowicz | 016eb36 | 2022-03-02 18:37:03 +0000 | [diff] [blame] | 139 | TEST(CmdlineTest, PublicHeadersEmpty) { |
| 140 | constexpr char kTargetsAndHeaders[] = R"([ |
| 141 | {"t": "target1", "h": ["a.h", "b.h"]} |
| 142 | ])"; |
| 143 | ASSERT_THAT(TestCmdline({}, kTargetsAndHeaders), |
| 144 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 145 | HasSubstr("please specify --public_headers"))); |
| 146 | } |
| 147 | |
| 148 | TEST(CmdlineTest, PublicHeadersWhereFirstHeaderMissingInMap) { |
| 149 | constexpr char kTargetsAndHeaders[] = R"([ |
| 150 | {"t": "target1", "h": ["a.h", "b.h"]} |
| 151 | ])"; |
| 152 | ASSERT_THAT(TestCmdline({"missing-in-map.h"}, kTargetsAndHeaders), |
| 153 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 154 | AllOf(HasSubstr("missing-in-map.h"), |
| 155 | HasSubstr("Couldn't find")))); |
| 156 | } |
| 157 | |
| 158 | TEST(CmdlineTest, PublicHeadersWhereSecondHeaderMissingInMap) { |
| 159 | constexpr char kTargetsAndHeaders[] = R"([ |
| 160 | {"t": "target1", "h": ["a.h", "b.h"]} |
| 161 | ])"; |
| 162 | ASSERT_THAT( |
| 163 | TestCmdline({"a.h", "missing.h"}, kTargetsAndHeaders), |
| 164 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 165 | AllOf(HasSubstr("missing.h"), HasSubstr("Couldn't find")))); |
| 166 | } |
| 167 | |
| 168 | TEST(CmdlineTest, PublicHeadersCoveringMultipleTargets) { |
| 169 | constexpr char kTargetsAndHeaders[] = R"([ |
| 170 | {"t": "target1", "h": ["a.h", "b.h"]}, |
| 171 | {"t": "target2", "h": ["c.h", "d.h"]} |
| 172 | ])"; |
| 173 | ASSERT_THAT(TestCmdline({"a.h", "c.h"}, kTargetsAndHeaders), |
| 174 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 175 | AllOf(HasSubstr("Expected all public headers to belong " |
| 176 | "to the current target"), |
| 177 | HasSubstr("target1"), HasSubstr("target2"), |
| 178 | HasSubstr("c.h")))); |
| 179 | } |
| 180 | |
| 181 | TEST(CmdlineTest, CcOutEmpty) { |
| 182 | constexpr char kTargetsAndHeaders[] = R"([ |
| 183 | {"t": "target1", "h": ["a.h", "b.h"]} |
| 184 | ])"; |
| 185 | ASSERT_THAT(Cmdline::CreateForTesting( |
| 186 | /* cc_out= */ "", "rs_out", "ir_out", /* do_nothing= */ false, |
| 187 | {"a.h"}, kTargetsAndHeaders), |
| 188 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 189 | HasSubstr("please specify --cc_out"))); |
| 190 | } |
| 191 | |
| 192 | TEST(CmdlineTest, RsOutEmpty) { |
| 193 | constexpr char kTargetsAndHeaders[] = R"([ |
| 194 | {"t": "target1", "h": ["a.h", "b.h"]} |
| 195 | ])"; |
| 196 | ASSERT_THAT(Cmdline::CreateForTesting("cc_out", /* rs_out= */ "", "ir_out", |
| 197 | /* do_nothing= */ false, {"a.h"}, |
| 198 | kTargetsAndHeaders), |
| 199 | StatusIs(absl::StatusCode::kInvalidArgument, |
| 200 | HasSubstr("please specify --rs_out"))); |
| 201 | } |
| 202 | |
| 203 | TEST(CmdlineTest, IrOutEmpty) { |
| 204 | constexpr char kTargetsAndHeaders[] = R"([ |
| 205 | {"t": "target1", "h": ["a.h", "b.h"]} |
| 206 | ])"; |
| 207 | ASSERT_OK(Cmdline::CreateForTesting("cc_out", "rs_out", /* ir_out= */ "", |
| 208 | /* do_nothing= */ false, {"a.h"}, |
| 209 | kTargetsAndHeaders)); |
| 210 | } |
| 211 | |
| 212 | } // namespace |
| 213 | } // namespace rs_bindings_from_cc |