blob: f1782d0139b514e4bb16efc2fa457eb9df5cedcb [file] [log] [blame]
Lukasz Anforowicz016eb362022-03-02 18:37:03 +00001// 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 Anforowicz016eb362022-03-02 18:37:03 +000010#include "testing/base/public/gmock.h"
11#include "testing/base/public/gunit.h"
Marcel Hlopko3b254b32022-03-09 14:10:49 +000012#include "rs_bindings_from_cc/bazel_types.h"
Lukasz Anforowicz016eb362022-03-02 18:37:03 +000013
Marcel Hlopkof15e8ce2022-04-08 08:46:09 -070014namespace crubit {
Lukasz Anforowicz016eb362022-03-02 18:37:03 +000015namespace {
16
17using ::testing::AllOf;
18using ::testing::ElementsAre;
19using ::testing::HasSubstr;
20using ::testing::Pair;
21using ::testing::UnorderedElementsAre;
22using ::testing::status::StatusIs;
23
24namespace {
25
26absl::StatusOr<Cmdline> TestCmdline(std::vector<std::string> public_headers,
27 const std::string& targets_and_headers) {
Marcel Hlopko18bb5d22022-05-09 04:23:43 -070028 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 Anforowicz016eb362022-03-02 18:37:03 +000035}
36
37} // namespace
38
39TEST(CmdlineTest, BasicCorrectInput) {
Lukasz Anforowiczdd907702022-05-06 09:24:07 -070040 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 Hlopko18bb5d22022-05-09 04:23:43 -070045 R"([{"t": "t1", "h": ["h1", "h2"]}])",
46 {"lib.rs"}, "instantiations_out"));
Lukasz Anforowicz016eb362022-03-02 18:37:03 +000047 EXPECT_EQ(cmdline.cc_out(), "cc_out");
48 EXPECT_EQ(cmdline.rs_out(), "rs_out");
49 EXPECT_EQ(cmdline.ir_out(), "ir_out");
Lukasz Anforowiczdd907702022-05-06 09:24:07 -070050 EXPECT_EQ(cmdline.crubit_support_path(), "crubit_support_path");
Lukasz Anforowicz54ff3182022-05-06 07:17:58 -070051 EXPECT_EQ(cmdline.rustfmt_config_path(), "rustfmt_config_path");
Marcel Hlopko18bb5d22022-05-09 04:23:43 -070052 EXPECT_EQ(cmdline.instantiations_out(), "instantiations_out");
Lukasz Anforowicz016eb362022-03-02 18:37:03 +000053 EXPECT_EQ(cmdline.do_nothing(), false);
54 EXPECT_EQ(cmdline.current_target().value(), "t1");
55 EXPECT_THAT(cmdline.public_headers(), ElementsAre(HeaderName("h1")));
Marcel Hlopko18bb5d22022-05-09 04:23:43 -070056 EXPECT_THAT(cmdline.rust_sources(), ElementsAre("lib.rs"));
Lukasz Anforowicz016eb362022-03-02 18:37:03 +000057 EXPECT_THAT(cmdline.headers_to_targets(),
Googler6c3de122022-03-28 11:40:41 +000058 UnorderedElementsAre(Pair(HeaderName("h1"), BazelLabel("t1")),
59 Pair(HeaderName("h2"), BazelLabel("t1"))));
Lukasz Anforowicz016eb362022-03-02 18:37:03 +000060}
61
62TEST(CmdlineTest, TargetsAndHeadersEmpty) {
63 ASSERT_THAT(TestCmdline({"h1"}, ""),
64 StatusIs(absl::StatusCode::kInvalidArgument,
65 HasSubstr("please specify --targets_and_headers")));
66}
67
Lukasz Anforowicz45f2d262022-03-02 18:37:27 +000068TEST(CmdlineTest, TargetsAndHeadersInvalidJson) {
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +000069 ASSERT_THAT(TestCmdline({"h1"}, "#!$%"),
70 StatusIs(absl::StatusCode::kInvalidArgument,
71 AllOf(HasSubstr("--targets_and_headers"),
72 HasSubstr("Invalid JSON"))));
Lukasz Anforowicz45f2d262022-03-02 18:37:27 +000073}
74
Lukasz Anforowicz016eb362022-03-02 18:37:03 +000075TEST(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 Anforowicz45f2d262022-03-02 18:37:27 +000082TEST(CmdlineTest, TargetsAndHeadersIntInTopLevelArray) {
83 ASSERT_THAT(TestCmdline({"h1"}, "[123, 456]"),
84 StatusIs(absl::StatusCode::kInvalidArgument,
85 AllOf(HasSubstr("--targets_and_headers"))));
86}
87
Lukasz Anforowicz016eb362022-03-02 18:37:03 +000088TEST(CmdlineTest, TargetsAndHeadersIntInsteadOfHeadersArray) {
89 ASSERT_THAT(TestCmdline({"h1"}, R"([{"t": "t1", "h": 123}])"),
90 StatusIs(absl::StatusCode::kInvalidArgument,
91 AllOf(HasSubstr("--targets_and_headers"),
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +000092 HasSubstr(".h"), HasSubstr("array"))));
Lukasz Anforowicz016eb362022-03-02 18:37:03 +000093}
94
Lukasz Anforowicz45f2d262022-03-02 18:37:27 +000095TEST(CmdlineTest, TargetsAndHeadersMissingTarget) {
96 ASSERT_THAT(TestCmdline({"h1"}, R"([{"h": ["h1", "h2"]}])"),
97 StatusIs(absl::StatusCode::kInvalidArgument,
98 AllOf(HasSubstr("--targets_and_headers"),
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +000099 HasSubstr(".t"), HasSubstr("missing"))));
Lukasz Anforowicz45f2d262022-03-02 18:37:27 +0000100}
101
102TEST(CmdlineTest, TargetsAndHeadersMissingHeader) {
103 ASSERT_THAT(TestCmdline({"h1"}, R"([{"t": "t1"}])"),
104 StatusIs(absl::StatusCode::kInvalidArgument,
105 AllOf(HasSubstr("--targets_and_headers"),
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000106 HasSubstr(".h"), HasSubstr("missing"))));
Lukasz Anforowicz45f2d262022-03-02 18:37:27 +0000107}
108
109TEST(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
116TEST(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
123TEST(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 Anforowicz3b4be122022-03-16 00:09:35 +0000127 HasSubstr(".t"), HasSubstr("string"))));
Lukasz Anforowicz45f2d262022-03-02 18:37:27 +0000128}
129
130TEST(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 Anforowicz3b4be122022-03-16 00:09:35 +0000134 HasSubstr(".h"), HasSubstr("string"))));
Lukasz Anforowicz45f2d262022-03-02 18:37:27 +0000135}
136
137TEST(CmdlineTest, TargetsAndHeadersDuplicateHeader) {
Marcel Hlopko315a2be2022-05-09 04:19:08 -0700138 constexpr absl::string_view kTestInput = R"([
Lukasz Anforowicz45f2d262022-03-02 18:37:27 +0000139 {"t": "t1", "h": ["h1"]},
140 {"t": "t2", "h": ["h1"]} ])";
141 ASSERT_THAT(
Marcel Hlopko315a2be2022-05-09 04:19:08 -0700142 TestCmdline({"h1"}, std::string(kTestInput)),
Lukasz Anforowicz45f2d262022-03-02 18:37:27 +0000143 StatusIs(absl::StatusCode::kInvalidArgument,
144 AllOf(HasSubstr("--targets_and_headers"), HasSubstr("conflict"),
145 HasSubstr("h1"), HasSubstr("t1"), HasSubstr("t2"))));
146}
147
Lukasz Anforowicz016eb362022-03-02 18:37:03 +0000148TEST(CmdlineTest, PublicHeadersEmpty) {
Marcel Hlopko315a2be2022-05-09 04:19:08 -0700149 constexpr absl::string_view kTargetsAndHeaders = R"([
Lukasz Anforowicz016eb362022-03-02 18:37:03 +0000150 {"t": "target1", "h": ["a.h", "b.h"]}
151 ])";
Marcel Hlopko315a2be2022-05-09 04:19:08 -0700152 ASSERT_THAT(TestCmdline({}, std::string(kTargetsAndHeaders)),
Lukasz Anforowicz016eb362022-03-02 18:37:03 +0000153 StatusIs(absl::StatusCode::kInvalidArgument,
154 HasSubstr("please specify --public_headers")));
155}
156
157TEST(CmdlineTest, PublicHeadersWhereFirstHeaderMissingInMap) {
Marcel Hlopko315a2be2022-05-09 04:19:08 -0700158 constexpr absl::string_view kTargetsAndHeaders = R"([
Lukasz Anforowicz016eb362022-03-02 18:37:03 +0000159 {"t": "target1", "h": ["a.h", "b.h"]}
160 ])";
161 ASSERT_THAT(
Marcel Hlopko315a2be2022-05-09 04:19:08 -0700162 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
168TEST(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 Anforowicz016eb362022-03-02 18:37:03 +0000174 StatusIs(absl::StatusCode::kInvalidArgument,
175 AllOf(HasSubstr("missing.h"), HasSubstr("Couldn't find"))));
176}
177
178TEST(CmdlineTest, PublicHeadersCoveringMultipleTargets) {
Marcel Hlopko315a2be2022-05-09 04:19:08 -0700179 constexpr absl::string_view kTargetsAndHeaders = R"([
Lukasz Anforowicz016eb362022-03-02 18:37:03 +0000180 {"t": "target1", "h": ["a.h", "b.h"]},
181 {"t": "target2", "h": ["c.h", "d.h"]}
182 ])";
Marcel Hlopko315a2be2022-05-09 04:19:08 -0700183 ASSERT_THAT(TestCmdline({"a.h", "c.h"}, std::string(kTargetsAndHeaders)),
Lukasz Anforowicz016eb362022-03-02 18:37:03 +0000184 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 Hlopko18bb5d22022-05-09 04:23:43 -0700191TEST(CmdlineTest, InstantiationsOutEmpty) {
Marcel Hlopko315a2be2022-05-09 04:19:08 -0700192 constexpr absl::string_view kTargetsAndHeaders = R"([
Lukasz Anforowicz016eb362022-03-02 18:37:03 +0000193 {"t": "target1", "h": ["a.h", "b.h"]}
194 ])";
Marcel Hlopko315a2be2022-05-09 04:19:08 -0700195 ASSERT_THAT(
Marcel Hlopko18bb5d22022-05-09 04:23:43 -0700196 (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
208TEST(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
225TEST(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 Anforowicz016eb362022-03-02 18:37:03 +0000237}
238
239TEST(CmdlineTest, RsOutEmpty) {
Marcel Hlopko315a2be2022-05-09 04:19:08 -0700240 constexpr absl::string_view kTargetsAndHeaders = R"([
Lukasz Anforowicz016eb362022-03-02 18:37:03 +0000241 {"t": "target1", "h": ["a.h", "b.h"]}
242 ])";
Marcel Hlopko315a2be2022-05-09 04:19:08 -0700243 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 Hlopko18bb5d22022-05-09 04:23:43 -0700247 std::string(kTargetsAndHeaders),
248 /* rust_sources= */ {},
249 /* instantiations_out= */ ""),
Marcel Hlopko315a2be2022-05-09 04:19:08 -0700250 StatusIs(absl::StatusCode::kInvalidArgument,
251 HasSubstr("please specify --rs_out")));
Lukasz Anforowicz016eb362022-03-02 18:37:03 +0000252}
253
254TEST(CmdlineTest, IrOutEmpty) {
Marcel Hlopko315a2be2022-05-09 04:19:08 -0700255 constexpr absl::string_view kTargetsAndHeaders = R"([
Lukasz Anforowicz016eb362022-03-02 18:37:03 +0000256 {"t": "target1", "h": ["a.h", "b.h"]}
257 ])";
Lukasz Anforowicz54ff3182022-05-06 07:17:58 -0700258 ASSERT_OK(Cmdline::CreateForTesting(
Lukasz Anforowiczdd907702022-05-06 09:24:07 -0700259 "cc_out", "rs_out", /* ir_out= */ "", "crubit_support_path",
260 "rustfmt_config_path",
Marcel Hlopko18bb5d22022-05-09 04:23:43 -0700261 /* do_nothing= */ false, {"a.h"}, std::string(kTargetsAndHeaders),
262 /* rust_sources= */ {},
263 /* instantiations_out= */ ""));
Lukasz Anforowicz016eb362022-03-02 18:37:03 +0000264}
265
266} // namespace
Marcel Hlopkof15e8ce2022-04-08 08:46:09 -0700267} // namespace crubit