1"""Unittest to verify properties of rustdoc rules""" 2 3load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") 4load("@rules_cc//cc:defs.bzl", "cc_library") 5load("//cargo:defs.bzl", "cargo_build_script") 6load("//rust:defs.bzl", "rust_binary", "rust_doc", "rust_doc_test", "rust_library", "rust_proc_macro", "rust_test") 7load( 8 "//test/unit:common.bzl", 9 "assert_action_mnemonic", 10 "assert_argv_contains", 11 "assert_argv_contains_prefix_not", 12) 13 14def _get_rustdoc_action(env, tut): 15 actions = tut.actions 16 action = actions[0] 17 assert_action_mnemonic(env, action, "Rustdoc") 18 19 return action 20 21def _common_rustdoc_checks(env, tut): 22 action = _get_rustdoc_action(env, tut) 23 24 # These flags, while required for `Rustc` actions, should be omitted for 25 # `Rustdoc` actions 26 assert_argv_contains_prefix_not(env, action, "--remap-path-prefix") 27 assert_argv_contains_prefix_not(env, action, "--emit") 28 29def _rustdoc_for_lib_test_impl(ctx): 30 env = analysistest.begin(ctx) 31 tut = analysistest.target_under_test(env) 32 33 _common_rustdoc_checks(env, tut) 34 35 return analysistest.end(env) 36 37def _rustdoc_for_bin_test_impl(ctx): 38 env = analysistest.begin(ctx) 39 tut = analysistest.target_under_test(env) 40 41 _common_rustdoc_checks(env, tut) 42 43 return analysistest.end(env) 44 45def _rustdoc_for_bin_with_cc_lib_test_impl(ctx): 46 env = analysistest.begin(ctx) 47 tut = analysistest.target_under_test(env) 48 49 _common_rustdoc_checks(env, tut) 50 51 return analysistest.end(env) 52 53def _rustdoc_for_bin_with_transitive_cc_lib_test_impl(ctx): 54 env = analysistest.begin(ctx) 55 tut = analysistest.target_under_test(env) 56 57 _common_rustdoc_checks(env, tut) 58 59 return analysistest.end(env) 60 61def _rustdoc_for_proc_macro_test_impl(ctx): 62 env = analysistest.begin(ctx) 63 tut = analysistest.target_under_test(env) 64 65 _common_rustdoc_checks(env, tut) 66 67 return analysistest.end(env) 68 69def _rustdoc_for_lib_with_proc_macro_test_impl(ctx): 70 env = analysistest.begin(ctx) 71 tut = analysistest.target_under_test(env) 72 73 _common_rustdoc_checks(env, tut) 74 75 return analysistest.end(env) 76 77def _rustdoc_for_bin_with_transitive_proc_macro_test_impl(ctx): 78 env = analysistest.begin(ctx) 79 tut = analysistest.target_under_test(env) 80 81 _common_rustdoc_checks(env, tut) 82 83 return analysistest.end(env) 84 85def _rustdoc_for_lib_with_cc_lib_test_impl(ctx): 86 env = analysistest.begin(ctx) 87 tut = analysistest.target_under_test(env) 88 89 _common_rustdoc_checks(env, tut) 90 91 return analysistest.end(env) 92 93def _rustdoc_with_args_test_impl(ctx): 94 env = analysistest.begin(ctx) 95 tut = analysistest.target_under_test(env) 96 97 _common_rustdoc_checks(env, tut) 98 99 action = _get_rustdoc_action(env, tut) 100 101 assert_argv_contains(env, action, "--allow=rustdoc::broken_intra_doc_links") 102 103 return analysistest.end(env) 104 105def _rustdoc_zip_output_test_impl(ctx): 106 env = analysistest.begin(ctx) 107 tut = analysistest.target_under_test(env) 108 109 files = tut[DefaultInfo].files.to_list() 110 asserts.equals( 111 env, 112 len(files), 113 1, 114 "The target under this test should have 1 DefaultInfo file but has {}".format( 115 len(files), 116 ), 117 ) 118 119 zip_file = files[0] 120 asserts.true( 121 env, 122 zip_file.basename.endswith(".zip"), 123 "{} did not end with `.zip`".format( 124 zip_file.path, 125 ), 126 ) 127 128 return analysistest.end(env) 129 130def _rustdoc_with_json_error_format_test_impl(ctx): 131 env = analysistest.begin(ctx) 132 tut = analysistest.target_under_test(env) 133 134 _common_rustdoc_checks(env, tut) 135 136 action = _get_rustdoc_action(env, tut) 137 138 assert_argv_contains(env, action, "--error-format=json") 139 140 return analysistest.end(env) 141 142rustdoc_for_lib_test = analysistest.make(_rustdoc_for_lib_test_impl) 143rustdoc_for_bin_test = analysistest.make(_rustdoc_for_bin_test_impl) 144rustdoc_for_bin_with_cc_lib_test = analysistest.make(_rustdoc_for_bin_with_cc_lib_test_impl) 145rustdoc_for_bin_with_transitive_cc_lib_test = analysistest.make(_rustdoc_for_bin_with_transitive_cc_lib_test_impl) 146rustdoc_for_proc_macro_test = analysistest.make(_rustdoc_for_proc_macro_test_impl) 147rustdoc_for_lib_with_proc_macro_test = analysistest.make(_rustdoc_for_lib_with_proc_macro_test_impl) 148rustdoc_for_bin_with_transitive_proc_macro_test = analysistest.make(_rustdoc_for_bin_with_transitive_proc_macro_test_impl) 149rustdoc_for_lib_with_cc_lib_test = analysistest.make(_rustdoc_for_lib_with_cc_lib_test_impl) 150rustdoc_with_args_test = analysistest.make(_rustdoc_with_args_test_impl) 151rustdoc_zip_output_test = analysistest.make(_rustdoc_zip_output_test_impl) 152rustdoc_with_json_error_format_test = analysistest.make(_rustdoc_with_json_error_format_test_impl, config_settings = { 153 str(Label("//:error_format")): "json", 154}) 155 156def _target_maker(rule_fn, name, rustdoc_deps = [], **kwargs): 157 rule_fn( 158 name = name, 159 edition = "2018", 160 **kwargs 161 ) 162 163 rust_test( 164 name = "{}_test".format(name), 165 crate = ":{}".format(name), 166 edition = "2018", 167 ) 168 169 rust_doc( 170 name = "{}_doc".format(name), 171 crate = ":{}".format(name), 172 ) 173 174 rust_doc_test( 175 name = "{}_doctest".format(name), 176 crate = ":{}".format(name), 177 deps = rustdoc_deps, 178 ) 179 180def _define_targets(): 181 rust_library( 182 name = "adder", 183 srcs = ["adder.rs"], 184 edition = "2018", 185 ) 186 187 _target_maker( 188 rust_binary, 189 name = "bin", 190 srcs = ["rustdoc_bin.rs"], 191 ) 192 193 _target_maker( 194 rust_binary, 195 name = "bin_with_cc", 196 srcs = ["rustdoc_bin.rs"], 197 crate_features = ["with_cc"], 198 deps = [":cc_lib"], 199 ) 200 201 _target_maker( 202 rust_binary, 203 name = "bin_with_transitive_cc", 204 srcs = ["rustdoc_bin.rs"], 205 crate_features = ["with_cc"], 206 deps = [":transitive_cc_lib"], 207 ) 208 209 _target_maker( 210 rust_library, 211 name = "lib", 212 srcs = ["rustdoc_lib.rs"], 213 rustdoc_deps = [":adder"], 214 ) 215 216 _target_maker( 217 rust_library, 218 name = "nodep_lib", 219 srcs = ["rustdoc_nodep_lib.rs"], 220 ) 221 222 _target_maker( 223 rust_proc_macro, 224 name = "rustdoc_proc_macro", 225 srcs = ["rustdoc_proc_macro.rs"], 226 ) 227 228 _target_maker( 229 rust_library, 230 name = "lib_with_proc_macro", 231 srcs = ["rustdoc_lib.rs"], 232 rustdoc_deps = [":adder"], 233 proc_macro_deps = [":rustdoc_proc_macro"], 234 crate_features = ["with_proc_macro"], 235 ) 236 237 _target_maker( 238 rust_library, 239 name = "lib_nodep_with_proc_macro", 240 srcs = ["rustdoc_nodep_lib.rs"], 241 proc_macro_deps = [":rustdoc_proc_macro"], 242 crate_features = ["with_proc_macro"], 243 ) 244 245 _target_maker( 246 rust_binary, 247 name = "bin_with_transitive_proc_macro", 248 srcs = ["rustdoc_bin.rs"], 249 deps = [":lib_with_proc_macro"], 250 proc_macro_deps = [":rustdoc_proc_macro"], 251 crate_features = ["with_proc_macro"], 252 ) 253 254 cc_library( 255 name = "cc_lib", 256 hdrs = ["rustdoc.h"], 257 srcs = ["rustdoc.cc"], 258 ) 259 260 cc_library( 261 name = "transitive_cc_lib", 262 hdrs = ["rustdoc.h"], 263 srcs = ["rustdoc.cc"], 264 deps = [":cc_lib"], 265 # This is not needed for :cc_lib, but it is needed in other 266 # circumstances to link in system libraries. 267 linkopts = ["-lcc_lib"], 268 linkstatic = True, 269 ) 270 271 _target_maker( 272 rust_library, 273 name = "lib_with_cc", 274 srcs = ["rustdoc_lib.rs"], 275 rustdoc_deps = [":adder"], 276 crate_features = ["with_cc"], 277 deps = [":cc_lib"], 278 ) 279 280 _target_maker( 281 rust_library, 282 name = "lib_nodep_with_cc", 283 srcs = ["rustdoc_nodep_lib.rs"], 284 crate_features = ["with_cc"], 285 deps = [":cc_lib"], 286 ) 287 288 cargo_build_script( 289 name = "lib_build_script", 290 srcs = ["rustdoc_build.rs"], 291 edition = "2018", 292 ) 293 294 _target_maker( 295 rust_library, 296 name = "lib_with_build_script", 297 srcs = ["rustdoc_lib.rs"], 298 rustdoc_deps = [":adder"], 299 crate_features = ["with_build_script"], 300 deps = [":lib_build_script"], 301 ) 302 303 _target_maker( 304 rust_library, 305 name = "lib_nodep_with_build_script", 306 srcs = ["rustdoc_nodep_lib.rs"], 307 crate_features = ["with_build_script"], 308 deps = [":lib_build_script"], 309 ) 310 311 rust_library( 312 name = "lib_requires_args", 313 srcs = ["rustdoc_requires_args.rs"], 314 edition = "2018", 315 ) 316 317 rust_doc( 318 name = "rustdoc_with_args", 319 crate = ":lib_requires_args", 320 rustdoc_flags = [ 321 "--allow=rustdoc::broken_intra_doc_links", 322 ], 323 ) 324 325 rust_library( 326 name = "lib_dep_with_alias", 327 srcs = ["rustdoc_test_dep_with_alias.rs"], 328 edition = "2018", 329 deps = [":adder"], 330 aliases = { 331 ":adder": "aliased_adder", 332 }, 333 ) 334 335 rust_doc_test( 336 name = "rustdoc_test_with_alias_test", 337 crate = ":lib_dep_with_alias", 338 ) 339 340def rustdoc_test_suite(name): 341 """Entry-point macro called from the BUILD file. 342 343 Args: 344 name (str): Name of the macro. 345 """ 346 347 _define_targets() 348 349 rustdoc_for_lib_test( 350 name = "rustdoc_for_lib_test", 351 target_under_test = ":lib_doc", 352 ) 353 354 rustdoc_for_bin_test( 355 name = "rustdoc_for_bin_test", 356 target_under_test = ":bin_doc", 357 ) 358 359 rustdoc_for_bin_with_cc_lib_test( 360 name = "rustdoc_for_bin_with_cc_lib_test", 361 target_under_test = ":bin_with_cc_doc", 362 ) 363 364 rustdoc_for_bin_with_transitive_cc_lib_test( 365 name = "rustdoc_for_bin_with_transitive_cc_lib_test", 366 target_under_test = ":bin_with_transitive_cc_doc", 367 ) 368 369 rustdoc_for_proc_macro_test( 370 name = "rustdoc_for_proc_macro_test", 371 target_under_test = ":rustdoc_proc_macro_doc", 372 ) 373 374 rustdoc_for_lib_with_proc_macro_test( 375 name = "rustdoc_for_lib_with_proc_macro_test", 376 target_under_test = ":lib_with_proc_macro_doc", 377 ) 378 379 rustdoc_for_bin_with_transitive_proc_macro_test( 380 name = "rustdoc_for_bin_with_transitive_proc_macro_test", 381 target_under_test = ":bin_with_transitive_proc_macro_doc", 382 ) 383 384 rustdoc_for_lib_with_cc_lib_test( 385 name = "rustdoc_for_lib_with_cc_lib_test", 386 target_under_test = ":lib_with_cc_doc", 387 ) 388 389 rustdoc_with_args_test( 390 name = "rustdoc_with_args_test", 391 target_under_test = ":rustdoc_with_args", 392 ) 393 394 rustdoc_with_json_error_format_test( 395 name = "rustdoc_with_json_error_format_test", 396 target_under_test = ":lib_doc", 397 ) 398 399 native.filegroup( 400 name = "lib_doc_zip", 401 srcs = [":lib_doc.zip"], 402 ) 403 404 rustdoc_zip_output_test( 405 name = "rustdoc_zip_output_test", 406 target_under_test = ":lib_doc_zip", 407 ) 408 409 native.test_suite( 410 name = name, 411 tests = [ 412 ":rustdoc_for_lib_test", 413 ":rustdoc_for_bin_test", 414 ":rustdoc_for_bin_with_cc_lib_test", 415 ":rustdoc_for_bin_with_transitive_cc_lib_test", 416 ":rustdoc_for_proc_macro_test", 417 ":rustdoc_for_lib_with_proc_macro_test", 418 ":rustdoc_for_lib_with_cc_lib_test", 419 ":rustdoc_with_args_test", 420 ":rustdoc_with_json_error_format_test", 421 ":rustdoc_zip_output_test", 422 ], 423 ) 424