1from check_index import * 2 3import json 4import sys 5import os 6 7def read_codemodel_json_data(filename): 8 abs_filename = os.path.join(os.path.dirname(os.path.realpath(__file__)), "codemodel-v2-data", filename) 9 with open(abs_filename, "r") as f: 10 return json.load(f) 11 12def check_objects(o, g): 13 assert is_list(o) 14 assert len(o) == 1 15 check_index_object(o[0], "codemodel", 2, 3, check_object_codemodel(g)) 16 17def check_backtrace(t, b, backtrace): 18 btg = t["backtraceGraph"] 19 for expected in backtrace: 20 assert is_int(b) 21 node = btg["nodes"][b] 22 expected_keys = ["file"] 23 assert matches(btg["files"][node["file"]], expected["file"]) 24 25 if expected["line"] is not None: 26 expected_keys.append("line") 27 assert is_int(node["line"], expected["line"]) 28 29 if expected["command"] is not None: 30 expected_keys.append("command") 31 assert is_int(node["command"]) 32 assert is_string(btg["commands"][node["command"]], expected["command"]) 33 34 if expected["hasParent"]: 35 expected_keys.append("parent") 36 assert is_int(node["parent"]) 37 b = node["parent"] 38 else: 39 b = None 40 41 assert sorted(node.keys()) == sorted(expected_keys) 42 43 assert b is None 44 45def check_backtraces(t, actual, expected): 46 assert is_list(actual) 47 assert is_list(expected) 48 assert len(actual) == len(expected) 49 50 i = 0 51 while i < len(actual): 52 check_backtrace(t, actual[i], expected[i]) 53 i += 1 54 55def check_directory(c): 56 def _check(actual, expected): 57 assert is_dict(actual) 58 expected_keys = ["build", "jsonFile", "source", "projectIndex"] 59 assert matches(actual["build"], expected["build"]) 60 61 assert is_int(actual["projectIndex"]) 62 assert is_string(c["projects"][actual["projectIndex"]]["name"], expected["projectName"]) 63 64 if expected["parentSource"] is not None: 65 expected_keys.append("parentIndex") 66 assert is_int(actual["parentIndex"]) 67 assert matches(c["directories"][actual["parentIndex"]]["source"], expected["parentSource"]) 68 69 if expected["childSources"] is not None: 70 expected_keys.append("childIndexes") 71 check_list_match(lambda a, e: matches(c["directories"][a]["source"], e), 72 actual["childIndexes"], expected["childSources"], 73 missing_exception=lambda e: "Child source: %s" % e, 74 extra_exception=lambda a: "Child source: %s" % a["source"]) 75 76 if expected["targetIds"] is not None: 77 expected_keys.append("targetIndexes") 78 check_list_match(lambda a, e: matches(c["targets"][a]["id"], e), 79 actual["targetIndexes"], expected["targetIds"], 80 missing_exception=lambda e: "Target ID: %s" % e, 81 extra_exception=lambda a: "Target ID: %s" % c["targets"][a]["id"]) 82 83 if expected["minimumCMakeVersion"] is not None: 84 expected_keys.append("minimumCMakeVersion") 85 assert is_dict(actual["minimumCMakeVersion"]) 86 assert sorted(actual["minimumCMakeVersion"].keys()) == ["string"] 87 assert is_string(actual["minimumCMakeVersion"]["string"], expected["minimumCMakeVersion"]) 88 89 if expected["hasInstallRule"] is not None: 90 expected_keys.append("hasInstallRule") 91 assert is_bool(actual["hasInstallRule"], expected["hasInstallRule"]) 92 93 assert sorted(actual.keys()) == sorted(expected_keys) 94 95 assert is_string(actual["jsonFile"]) 96 filepath = os.path.join(reply_dir, actual["jsonFile"]) 97 with open(filepath) as f: 98 d = json.load(f) 99 100 assert is_dict(d) 101 assert sorted(d.keys()) == ["backtraceGraph", "installers", "paths"] 102 103 assert is_string(d["paths"]["source"], actual["source"]) 104 assert is_string(d["paths"]["build"], actual["build"]) 105 106 check_backtrace_graph(d["backtraceGraph"]) 107 108 assert is_list(d["installers"]) 109 assert len(d["installers"]) == len(expected["installers"]) 110 for a, e in zip(d["installers"], expected["installers"]): 111 assert is_dict(a) 112 expected_keys = ["component", "type"] 113 114 assert is_string(a["component"], e["component"]) 115 assert is_string(a["type"], e["type"]) 116 117 if e["destination"] is not None: 118 expected_keys.append("destination") 119 assert is_string(a["destination"], e["destination"]) 120 121 if e["paths"] is not None: 122 expected_keys.append("paths") 123 assert is_list(a["paths"]) 124 assert len(a["paths"]) == len(e["paths"]) 125 126 for ap, ep in zip(a["paths"], e["paths"]): 127 if is_string(ep): 128 assert matches(ap, ep) 129 else: 130 assert is_dict(ap) 131 assert sorted(ap.keys()) == ["from", "to"] 132 assert matches(ap["from"], ep["from"]) 133 assert matches(ap["to"], ep["to"]) 134 135 if e["isExcludeFromAll"] is not None: 136 expected_keys.append("isExcludeFromAll") 137 assert is_bool(a["isExcludeFromAll"], e["isExcludeFromAll"]) 138 139 if e["isForAllComponents"] is not None: 140 expected_keys.append("isForAllComponents") 141 assert is_bool(a["isForAllComponents"], e["isForAllComponents"]) 142 143 if e["isOptional"] is not None: 144 expected_keys.append("isOptional") 145 assert is_bool(a["isOptional"], e["isOptional"]) 146 147 if e["targetId"] is not None: 148 expected_keys.append("targetId") 149 assert matches(a["targetId"], e["targetId"]) 150 151 if e["targetIndex"] is not None: 152 expected_keys.append("targetIndex") 153 assert is_int(a["targetIndex"]) 154 assert c["targets"][a["targetIndex"]]["name"] == e["targetIndex"] 155 156 if e["targetIsImportLibrary"] is not None: 157 expected_keys.append("targetIsImportLibrary") 158 assert is_bool(a["targetIsImportLibrary"], e["targetIsImportLibrary"]) 159 160 if e["targetInstallNamelink"] is not None: 161 expected_keys.append("targetInstallNamelink") 162 assert is_string(a["targetInstallNamelink"], e["targetInstallNamelink"]) 163 164 if e["exportName"] is not None: 165 expected_keys.append("exportName") 166 assert is_string(a["exportName"], e["exportName"]) 167 168 if e["exportTargets"] is not None: 169 expected_keys.append("exportTargets") 170 assert is_list(a["exportTargets"]) 171 assert len(a["exportTargets"]) == len(e["exportTargets"]) 172 for at, et in zip(a["exportTargets"], e["exportTargets"]): 173 assert is_dict(at) 174 assert sorted(at.keys()) == ["id", "index"] 175 assert matches(at["id"], et["id"]) 176 assert is_int(at["index"]) 177 assert c["targets"][at["index"]]["name"] == et["index"] 178 179 if e["scriptFile"] is not None: 180 expected_keys.append("scriptFile") 181 assert is_string(a["scriptFile"], e["scriptFile"]) 182 183 if e.get("runtimeDependencySetName", None) is not None: 184 expected_keys.append("runtimeDependencySetName") 185 assert is_string(a["runtimeDependencySetName"], e["runtimeDependencySetName"]) 186 187 if e.get("runtimeDependencySetType", None) is not None: 188 expected_keys.append("runtimeDependencySetType") 189 assert is_string(a["runtimeDependencySetType"], e["runtimeDependencySetType"]) 190 191 if e["backtrace"] is not None: 192 expected_keys.append("backtrace") 193 check_backtrace(d, a["backtrace"], e["backtrace"]) 194 195 assert sorted(a.keys()) == sorted(expected_keys) 196 197 return _check 198 199def check_backtrace_graph(btg): 200 assert is_dict(btg) 201 assert sorted(btg.keys()) == ["commands", "files", "nodes"] 202 assert is_list(btg["commands"]) 203 204 for c in btg["commands"]: 205 assert is_string(c) 206 207 for f in btg["files"]: 208 assert is_string(f) 209 210 for n in btg["nodes"]: 211 expected_keys = ["file"] 212 assert is_dict(n) 213 assert is_int(n["file"]) 214 assert 0 <= n["file"] < len(btg["files"]) 215 216 if "line" in n: 217 expected_keys.append("line") 218 assert is_int(n["line"]) 219 220 if "command" in n: 221 expected_keys.append("command") 222 assert is_int(n["command"]) 223 assert 0 <= n["command"] < len(btg["commands"]) 224 225 if "parent" in n: 226 expected_keys.append("parent") 227 assert is_int(n["parent"]) 228 assert 0 <= n["parent"] < len(btg["nodes"]) 229 230 assert sorted(n.keys()) == sorted(expected_keys) 231 232def check_target(c): 233 def _check(actual, expected): 234 assert is_dict(actual) 235 assert sorted(actual.keys()) == ["directoryIndex", "id", "jsonFile", "name", "projectIndex"] 236 assert is_int(actual["directoryIndex"]) 237 assert matches(c["directories"][actual["directoryIndex"]]["source"], expected["directorySource"]) 238 assert is_string(actual["name"], expected["name"]) 239 assert is_string(actual["jsonFile"]) 240 assert is_int(actual["projectIndex"]) 241 assert is_string(c["projects"][actual["projectIndex"]]["name"], expected["projectName"]) 242 243 filepath = os.path.join(reply_dir, actual["jsonFile"]) 244 with open(filepath) as f: 245 obj = json.load(f) 246 247 expected_keys = ["name", "id", "type", "backtraceGraph", "paths", "sources"] 248 assert is_dict(obj) 249 assert is_string(obj["name"], expected["name"]) 250 assert matches(obj["id"], expected["id"]) 251 assert is_string(obj["type"], expected["type"]) 252 check_backtrace_graph(obj["backtraceGraph"]) 253 254 assert is_dict(obj["paths"]) 255 assert sorted(obj["paths"].keys()) == ["build", "source"] 256 assert matches(obj["paths"]["build"], expected["build"]) 257 assert matches(obj["paths"]["source"], expected["source"]) 258 259 def check_source(actual, expected): 260 assert is_dict(actual) 261 expected_keys = ["path"] 262 263 if expected["compileGroupLanguage"] is not None: 264 expected_keys.append("compileGroupIndex") 265 assert is_string(obj["compileGroups"][actual["compileGroupIndex"]]["language"], expected["compileGroupLanguage"]) 266 267 if expected["sourceGroupName"] is not None: 268 expected_keys.append("sourceGroupIndex") 269 assert is_string(obj["sourceGroups"][actual["sourceGroupIndex"]]["name"], expected["sourceGroupName"]) 270 271 if expected["isGenerated"] is not None: 272 expected_keys.append("isGenerated") 273 assert is_bool(actual["isGenerated"], expected["isGenerated"]) 274 275 if expected["backtrace"] is not None: 276 expected_keys.append("backtrace") 277 check_backtrace(obj, actual["backtrace"], expected["backtrace"]) 278 279 assert sorted(actual.keys()) == sorted(expected_keys) 280 281 check_list_match(lambda a, e: matches(a["path"], e["path"]), obj["sources"], 282 expected["sources"], check=check_source, 283 check_exception=lambda a, e: "Source file: %s" % a["path"], 284 missing_exception=lambda e: "Source file: %s" % e["path"], 285 extra_exception=lambda a: "Source file: %s" % a["path"]) 286 287 if expected["backtrace"] is not None: 288 expected_keys.append("backtrace") 289 check_backtrace(obj, obj["backtrace"], expected["backtrace"]) 290 291 if expected["folder"] is not None: 292 expected_keys.append("folder") 293 assert is_dict(obj["folder"]) 294 assert sorted(obj["folder"].keys()) == ["name"] 295 assert is_string(obj["folder"]["name"], expected["folder"]) 296 297 if expected["nameOnDisk"] is not None: 298 expected_keys.append("nameOnDisk") 299 assert matches(obj["nameOnDisk"], expected["nameOnDisk"]) 300 301 if expected["artifacts"] is not None: 302 expected_keys.append("artifacts") 303 304 def check_artifact(actual, expected): 305 assert is_dict(actual) 306 assert sorted(actual.keys()) == ["path"] 307 308 check_list_match(lambda a, e: matches(a["path"], e["path"]), 309 obj["artifacts"], expected["artifacts"], 310 check=check_artifact, 311 check_exception=lambda a, e: "Artifact: %s" % a["path"], 312 missing_exception=lambda e: "Artifact: %s" % e["path"], 313 extra_exception=lambda a: "Artifact: %s" % a["path"]) 314 315 if expected["isGeneratorProvided"] is not None: 316 expected_keys.append("isGeneratorProvided") 317 assert is_bool(obj["isGeneratorProvided"], expected["isGeneratorProvided"]) 318 319 if expected["install"] is not None: 320 expected_keys.append("install") 321 assert is_dict(obj["install"]) 322 assert sorted(obj["install"].keys()) == ["destinations", "prefix"] 323 324 assert is_dict(obj["install"]["prefix"]) 325 assert sorted(obj["install"]["prefix"].keys()) == ["path"] 326 assert matches(obj["install"]["prefix"]["path"], expected["install"]["prefix"]) 327 328 def check_install_destination(actual, expected): 329 assert is_dict(actual) 330 expected_keys = ["path"] 331 332 if expected["backtrace"] is not None: 333 expected_keys.append("backtrace") 334 check_backtrace(obj, actual["backtrace"], expected["backtrace"]) 335 336 assert sorted(actual.keys()) == sorted(expected_keys) 337 338 check_list_match(lambda a, e: matches(a["path"], e["path"]), 339 obj["install"]["destinations"], expected["install"]["destinations"], 340 check=check_install_destination, 341 check_exception=lambda a, e: "Install path: %s" % a["path"], 342 missing_exception=lambda e: "Install path: %s" % e["path"], 343 extra_exception=lambda a: "Install path: %s" % a["path"]) 344 345 if expected["link"] is not None: 346 expected_keys.append("link") 347 assert is_dict(obj["link"]) 348 link_keys = ["language"] 349 350 assert is_string(obj["link"]["language"], expected["link"]["language"]) 351 352 if "commandFragments" in obj["link"]: 353 link_keys.append("commandFragments") 354 assert is_list(obj["link"]["commandFragments"]) 355 for f in obj["link"]["commandFragments"]: 356 assert is_dict(f) 357 assert sorted(f.keys()) == ["fragment", "role"] or sorted(f.keys()) == ["backtrace", "fragment", "role"] 358 assert is_string(f["fragment"]) 359 assert is_string(f["role"]) 360 assert f["role"] in ("flags", "libraries", "libraryPath", "frameworkPath") 361 362 if expected["link"]["commandFragments"] is not None: 363 def check_link_command_fragments(actual, expected): 364 assert is_dict(actual) 365 expected_keys = ["fragment", "role"] 366 367 if expected["backtrace"] is not None: 368 expected_keys.append("backtrace") 369 assert matches(actual["fragment"], expected["fragment"]) 370 assert actual["role"] == expected["role"] 371 check_backtrace(obj, actual["backtrace"], expected["backtrace"]) 372 373 assert sorted(actual.keys()) == sorted(expected_keys) 374 375 check_list_match(lambda a, e: matches(a["fragment"], e["fragment"]), 376 obj["link"]["commandFragments"], expected["link"]["commandFragments"], 377 check=check_link_command_fragments, 378 check_exception=lambda a, e: "Link fragment: %s" % a["fragment"], 379 missing_exception=lambda e: "Link fragment: %s" % e["fragment"], 380 extra_exception=lambda a: "Link fragment: %s" % a["fragment"], 381 allow_extra=True) 382 383 if expected["link"]["lto"] is not None: 384 link_keys.append("lto") 385 assert is_bool(obj["link"]["lto"], expected["link"]["lto"]) 386 387 # FIXME: Properly test sysroot 388 if "sysroot" in obj["link"]: 389 link_keys.append("sysroot") 390 assert is_string(obj["link"]["sysroot"]) 391 392 assert sorted(obj["link"].keys()) == sorted(link_keys) 393 394 if expected["archive"] is not None: 395 expected_keys.append("archive") 396 assert is_dict(obj["archive"]) 397 archive_keys = [] 398 399 # FIXME: Properly test commandFragments 400 if "commandFragments" in obj["archive"]: 401 archive_keys.append("commandFragments") 402 assert is_list(obj["archive"]["commandFragments"]) 403 for f in obj["archive"]["commandFragments"]: 404 assert is_dict(f) 405 assert sorted(f.keys()) == ["fragment", "role"] 406 assert is_string(f["fragment"]) 407 assert is_string(f["role"]) 408 assert f["role"] in ("flags") 409 410 if expected["archive"]["lto"] is not None: 411 archive_keys.append("lto") 412 assert is_bool(obj["archive"]["lto"], expected["archive"]["lto"]) 413 414 assert sorted(obj["archive"].keys()) == sorted(archive_keys) 415 416 if expected["dependencies"] is not None: 417 expected_keys.append("dependencies") 418 419 def check_dependency(actual, expected): 420 assert is_dict(actual) 421 expected_keys = ["id"] 422 423 if expected["backtrace"] is not None: 424 expected_keys.append("backtrace") 425 check_backtrace(obj, actual["backtrace"], expected["backtrace"]) 426 427 assert sorted(actual.keys()) == sorted(expected_keys) 428 429 check_list_match(lambda a, e: matches(a["id"], e["id"]), 430 obj["dependencies"], expected["dependencies"], 431 check=check_dependency, 432 check_exception=lambda a, e: "Dependency ID: %s" % a["id"], 433 missing_exception=lambda e: "Dependency ID: %s" % e["id"], 434 extra_exception=lambda a: "Dependency ID: %s" % a["id"]) 435 436 if expected["sourceGroups"] is not None: 437 expected_keys.append("sourceGroups") 438 439 def check_source_group(actual, expected): 440 assert is_dict(actual) 441 assert sorted(actual.keys()) == ["name", "sourceIndexes"] 442 443 check_list_match(lambda a, e: matches(obj["sources"][a]["path"], e), 444 actual["sourceIndexes"], expected["sourcePaths"], 445 missing_exception=lambda e: "Source path: %s" % e, 446 extra_exception=lambda a: "Source path: %s" % obj["sources"][a]["path"]) 447 448 check_list_match(lambda a, e: is_string(a["name"], e["name"]), 449 obj["sourceGroups"], expected["sourceGroups"], 450 check=check_source_group, 451 check_exception=lambda a, e: "Source group: %s" % a["name"], 452 missing_exception=lambda e: "Source group: %s" % e["name"], 453 extra_exception=lambda a: "Source group: %s" % a["name"]) 454 455 if expected["compileGroups"] is not None: 456 expected_keys.append("compileGroups") 457 458 def check_compile_group(actual, expected): 459 assert is_dict(actual) 460 expected_keys = ["sourceIndexes", "language"] 461 462 check_list_match(lambda a, e: matches(obj["sources"][a]["path"], e), 463 actual["sourceIndexes"], expected["sourcePaths"], 464 missing_exception=lambda e: "Source path: %s" % e, 465 extra_exception=lambda a: "Source path: %s" % obj["sources"][a]["path"]) 466 467 if "compileCommandFragments" in actual: 468 expected_keys.append("compileCommandFragments") 469 assert is_list(actual["compileCommandFragments"]) 470 for f in actual["compileCommandFragments"]: 471 assert is_dict(f) 472 assert is_string(f["fragment"]) 473 474 if expected["compileCommandFragments"] is not None: 475 def check_compile_command_fragments(actual, expected): 476 assert is_dict(actual) 477 expected_keys = ["fragment"] 478 479 if expected["backtrace"] is not None: 480 expected_keys.append("backtrace") 481 assert actual["fragment"] == expected["fragment"] 482 check_backtrace(obj, actual["backtrace"], expected["backtrace"]) 483 484 assert sorted(actual.keys()) == sorted(expected_keys) 485 486 check_list_match(lambda a, e: is_string(a["fragment"], e["fragment"]), 487 actual["compileCommandFragments"], expected["compileCommandFragments"], 488 check=check_compile_command_fragments, 489 check_exception=lambda a, e: "Compile fragment: %s" % a["fragment"], 490 missing_exception=lambda e: "Compile fragment: %s" % e["fragment"], 491 extra_exception=lambda a: "Compile fragment: %s" % a["fragment"], 492 allow_extra=True) 493 494 if expected["includes"] is not None: 495 expected_keys.append("includes") 496 497 def check_include(actual, expected): 498 assert is_dict(actual) 499 expected_keys = ["path"] 500 501 if expected["isSystem"] is not None: 502 expected_keys.append("isSystem") 503 assert is_bool(actual["isSystem"], expected["isSystem"]) 504 505 if expected["backtrace"] is not None: 506 expected_keys.append("backtrace") 507 check_backtrace(obj, actual["backtrace"], expected["backtrace"]) 508 509 assert sorted(actual.keys()) == sorted(expected_keys) 510 511 check_list_match(lambda a, e: matches(a["path"], e["path"]), 512 actual["includes"], expected["includes"], 513 check=check_include, 514 check_exception=lambda a, e: "Include path: %s" % a["path"], 515 missing_exception=lambda e: "Include path: %s" % e["path"], 516 extra_exception=lambda a: "Include path: %s" % a["path"]) 517 518 if "precompileHeaders" in expected: 519 expected_keys.append("precompileHeaders") 520 521 def check_precompile_header(actual, expected): 522 assert is_dict(actual) 523 expected_keys = ["backtrace", "header"] 524 check_backtrace(obj, actual["backtrace"], expected["backtrace"]) 525 526 assert sorted(actual.keys()) == sorted(expected_keys) 527 528 check_list_match(lambda a, e: matches(a["header"], e["header"]), 529 actual["precompileHeaders"], expected["precompileHeaders"], 530 check=check_precompile_header, 531 check_exception=lambda a, e: "Precompile header: %s" % a["header"], 532 missing_exception=lambda e: "Precompile header: %s" % e["header"], 533 extra_exception=lambda a: "Precompile header: %s" % a["header"]) 534 535 if "languageStandard" in expected: 536 expected_keys.append("languageStandard") 537 538 def check_language_standard(actual, expected): 539 assert is_dict(actual) 540 expected_keys = ["backtraces", "standard"] 541 assert actual["standard"] == expected["standard"] 542 check_backtraces(obj, actual["backtraces"], expected["backtraces"]) 543 544 assert sorted(actual.keys()) == sorted(expected_keys) 545 546 check_language_standard(actual["languageStandard"], expected["languageStandard"]) 547 548 if expected["defines"] is not None: 549 expected_keys.append("defines") 550 551 def check_define(actual, expected): 552 assert is_dict(actual) 553 expected_keys = ["define"] 554 555 if expected["backtrace"] is not None: 556 expected_keys.append("backtrace") 557 check_backtrace(obj, actual["backtrace"], expected["backtrace"]) 558 559 assert sorted(actual.keys()) == sorted(expected_keys) 560 561 check_list_match(lambda a, e: is_string(a["define"], e["define"]), 562 actual["defines"], expected["defines"], 563 check=check_define, 564 check_exception=lambda a, e: "Define: %s" % a["define"], 565 missing_exception=lambda e: "Define: %s" % e["define"], 566 extra_exception=lambda a: "Define: %s" % a["define"]) 567 568 # FIXME: Properly test sysroot 569 if "sysroot" in actual: 570 expected_keys.append("sysroot") 571 assert is_string(actual["sysroot"]) 572 573 assert sorted(actual.keys()) == sorted(expected_keys) 574 575 check_list_match(lambda a, e: is_string(a["language"], e["language"]), 576 obj["compileGroups"], expected["compileGroups"], 577 check=check_compile_group, 578 check_exception=lambda a, e: "Compile group: %s" % a["language"], 579 missing_exception=lambda e: "Compile group: %s" % e["language"], 580 extra_exception=lambda a: "Compile group: %s" % a["language"]) 581 582 assert sorted(obj.keys()) == sorted(expected_keys) 583 584 return _check 585 586def check_project(c): 587 def _check(actual, expected): 588 assert is_dict(actual) 589 expected_keys = ["name", "directoryIndexes"] 590 591 check_list_match(lambda a, e: matches(c["directories"][a]["source"], e), 592 actual["directoryIndexes"], expected["directorySources"], 593 missing_exception=lambda e: "Directory source: %s" % e, 594 extra_exception=lambda a: "Directory source: %s" % c["directories"][a]["source"]) 595 596 if expected["parentName"] is not None: 597 expected_keys.append("parentIndex") 598 assert is_int(actual["parentIndex"]) 599 assert is_string(c["projects"][actual["parentIndex"]]["name"], expected["parentName"]) 600 601 if expected["childNames"] is not None: 602 expected_keys.append("childIndexes") 603 check_list_match(lambda a, e: is_string(c["projects"][a]["name"], e), 604 actual["childIndexes"], expected["childNames"], 605 missing_exception=lambda e: "Child name: %s" % e, 606 extra_exception=lambda a: "Child name: %s" % c["projects"][a]["name"]) 607 608 if expected["targetIds"] is not None: 609 expected_keys.append("targetIndexes") 610 check_list_match(lambda a, e: matches(c["targets"][a]["id"], e), 611 actual["targetIndexes"], expected["targetIds"], 612 missing_exception=lambda e: "Target ID: %s" % e, 613 extra_exception=lambda a: "Target ID: %s" % c["targets"][a]["id"]) 614 615 assert sorted(actual.keys()) == sorted(expected_keys) 616 617 return _check 618 619def gen_check_directories(c, g): 620 expected = [ 621 read_codemodel_json_data("directories/top.json"), 622 read_codemodel_json_data("directories/alias.json"), 623 read_codemodel_json_data("directories/custom.json"), 624 read_codemodel_json_data("directories/cxx.json"), 625 read_codemodel_json_data("directories/imported.json"), 626 read_codemodel_json_data("directories/interface.json"), 627 read_codemodel_json_data("directories/object.json"), 628 read_codemodel_json_data("directories/dir.json"), 629 read_codemodel_json_data("directories/dir_dir.json"), 630 read_codemodel_json_data("directories/external.json"), 631 ] 632 633 if matches(g["name"], "^Visual Studio "): 634 for e in expected: 635 if e["parentSource"] is not None: 636 e["targetIds"] = filter_list(lambda t: not matches(t, "^\\^ZERO_CHECK"), e["targetIds"]) 637 638 elif g["name"] == "Xcode": 639 if ';' in os.environ.get("CMAKE_OSX_ARCHITECTURES", ""): 640 for e in expected: 641 e["targetIds"] = filter_list(lambda t: not matches(t, "^\\^(link_imported_object_exe)"), e["targetIds"]) 642 643 else: 644 for e in expected: 645 e["targetIds"] = filter_list(lambda t: not matches(t, "^\\^(ALL_BUILD|ZERO_CHECK)"), e["targetIds"]) 646 647 if sys.platform in ("win32", "cygwin", "msys") or "aix" in sys.platform: 648 for e in expected: 649 e["installers"] = list(filter(lambda i: i["targetInstallNamelink"] is None or i["targetInstallNamelink"] == "skip", e["installers"])) 650 for i in e["installers"]: 651 i["targetInstallNamelink"] = None 652 653 if sys.platform not in ("win32", "cygwin", "msys"): 654 for e in expected: 655 e["installers"] = list(filter(lambda i: not i.get("_dllExtra", False), e["installers"])) 656 if "aix" not in sys.platform: 657 for i in e["installers"]: 658 if "pathsNamelink" in i: 659 i["paths"] = i["pathsNamelink"] 660 661 if sys.platform not in ("win32", "darwin") and "linux" not in sys.platform: 662 for e in expected: 663 e["installers"] = list(filter(lambda i: i["type"] != "runtimeDependencySet", e["installers"])) 664 665 if sys.platform != "darwin": 666 for e in expected: 667 e["installers"] = list(filter(lambda i: i.get("runtimeDependencySetType", None) != "framework", e["installers"])) 668 669 return expected 670 671def check_directories(c, g): 672 check_list_match(lambda a, e: matches(a["source"], e["source"]), c["directories"], gen_check_directories(c, g), 673 check=check_directory(c), 674 check_exception=lambda a, e: "Directory source: %s" % a["source"], 675 missing_exception=lambda e: "Directory source: %s" % e["source"], 676 extra_exception=lambda a: "Directory source: %s" % a["source"]) 677 678def gen_check_targets(c, g, inSource): 679 expected = [ 680 read_codemodel_json_data("targets/all_build_top.json"), 681 read_codemodel_json_data("targets/zero_check_top.json"), 682 read_codemodel_json_data("targets/interface_exe.json"), 683 read_codemodel_json_data("targets/c_lib.json"), 684 read_codemodel_json_data("targets/c_exe.json"), 685 read_codemodel_json_data("targets/c_shared_lib.json"), 686 read_codemodel_json_data("targets/c_shared_exe.json"), 687 read_codemodel_json_data("targets/c_static_lib.json"), 688 read_codemodel_json_data("targets/c_static_exe.json"), 689 690 read_codemodel_json_data("targets/all_build_cxx.json"), 691 read_codemodel_json_data("targets/zero_check_cxx.json"), 692 read_codemodel_json_data("targets/cxx_lib.json"), 693 read_codemodel_json_data("targets/cxx_exe.json"), 694 read_codemodel_json_data("targets/cxx_standard_compile_feature_exe.json"), 695 read_codemodel_json_data("targets/cxx_standard_exe.json"), 696 read_codemodel_json_data("targets/cxx_shared_lib.json"), 697 read_codemodel_json_data("targets/cxx_shared_exe.json"), 698 read_codemodel_json_data("targets/cxx_static_lib.json"), 699 read_codemodel_json_data("targets/cxx_static_exe.json"), 700 701 read_codemodel_json_data("targets/all_build_alias.json"), 702 read_codemodel_json_data("targets/zero_check_alias.json"), 703 read_codemodel_json_data("targets/c_alias_exe.json"), 704 read_codemodel_json_data("targets/cxx_alias_exe.json"), 705 706 read_codemodel_json_data("targets/all_build_object.json"), 707 read_codemodel_json_data("targets/zero_check_object.json"), 708 read_codemodel_json_data("targets/c_object_lib.json"), 709 read_codemodel_json_data("targets/c_object_exe.json"), 710 read_codemodel_json_data("targets/cxx_object_lib.json"), 711 read_codemodel_json_data("targets/cxx_object_exe.json"), 712 713 read_codemodel_json_data("targets/all_build_imported.json"), 714 read_codemodel_json_data("targets/zero_check_imported.json"), 715 read_codemodel_json_data("targets/link_imported_exe.json"), 716 read_codemodel_json_data("targets/link_imported_shared_exe.json"), 717 read_codemodel_json_data("targets/link_imported_static_exe.json"), 718 read_codemodel_json_data("targets/link_imported_object_exe.json"), 719 read_codemodel_json_data("targets/link_imported_interface_exe.json"), 720 721 read_codemodel_json_data("targets/all_build_interface.json"), 722 read_codemodel_json_data("targets/zero_check_interface.json"), 723 read_codemodel_json_data("targets/iface_srcs.json"), 724 725 read_codemodel_json_data("targets/all_build_custom.json"), 726 read_codemodel_json_data("targets/zero_check_custom.json"), 727 read_codemodel_json_data("targets/custom_tgt.json"), 728 read_codemodel_json_data("targets/custom_exe.json"), 729 read_codemodel_json_data("targets/all_build_external.json"), 730 read_codemodel_json_data("targets/zero_check_external.json"), 731 read_codemodel_json_data("targets/generated_exe.json"), 732 ] 733 734 if cxx_compiler_id in ['Clang', 'AppleClang', 'GNU', 'Intel', 'IntelLLVM', 'MSVC', 'Embarcadero'] and g["name"] != "Xcode": 735 for e in expected: 736 if e["name"] == "cxx_exe": 737 if matches(g["name"], "^(Visual Studio |Ninja Multi-Config)"): 738 precompile_header_data = read_codemodel_json_data("targets/cxx_exe_precompileheader_multigen.json") 739 else: 740 if ';' in os.environ.get("CMAKE_OSX_ARCHITECTURES", ""): 741 precompile_header_data = read_codemodel_json_data("targets/cxx_exe_precompileheader_2arch.json") 742 else: 743 precompile_header_data = read_codemodel_json_data("targets/cxx_exe_precompileheader.json") 744 e["compileGroups"] = precompile_header_data["compileGroups"] 745 e["sources"] = precompile_header_data["sources"] 746 e["sourceGroups"] = precompile_header_data["sourceGroups"] 747 748 if os.path.exists(os.path.join(reply_dir, "..", "..", "..", "..", "cxx", "cxx_std_11.txt")): 749 for e in expected: 750 if e["name"] == "cxx_standard_compile_feature_exe": 751 language_standard_data = read_codemodel_json_data("targets/cxx_standard_compile_feature_exe_languagestandard.json") 752 e["compileGroups"][0]["languageStandard"] = language_standard_data["languageStandard"] 753 754 if not os.path.exists(os.path.join(reply_dir, "..", "..", "..", "..", "ipo_enabled.txt")): 755 for e in expected: 756 try: 757 e["link"]["lto"] = None 758 except TypeError: # "link" is not a dict, no problem. 759 pass 760 try: 761 e["archive"]["lto"] = None 762 except TypeError: # "archive" is not a dict, no problem. 763 pass 764 765 if inSource: 766 for e in expected: 767 if e["sources"] is not None: 768 for s in e["sources"]: 769 s["path"] = s["path"].replace("^.*/Tests/RunCMake/FileAPI/", "^", 1) 770 if e["sourceGroups"] is not None: 771 for group in e["sourceGroups"]: 772 group["sourcePaths"] = [p.replace("^.*/Tests/RunCMake/FileAPI/", "^", 1) for p in group["sourcePaths"]] 773 if e["compileGroups"] is not None: 774 for group in e["compileGroups"]: 775 group["sourcePaths"] = [p.replace("^.*/Tests/RunCMake/FileAPI/", "^", 1) for p in group["sourcePaths"]] 776 777 if matches(g["name"], "^Visual Studio "): 778 expected = filter_list(lambda e: e["name"] not in ("ZERO_CHECK") or e["id"] == "^ZERO_CHECK::@6890427a1f51a3e7e1df$", expected) 779 for e in expected: 780 if e["type"] == "UTILITY": 781 if e["id"] == "^ZERO_CHECK::@6890427a1f51a3e7e1df$": 782 e["sources"] = [ 783 { 784 "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/([0-9a-f]+/)?generate\\.stamp\\.rule$", 785 "isGenerated": True, 786 "sourceGroupName": "CMake Rules", 787 "compileGroupLanguage": None, 788 "backtrace": [ 789 { 790 "file": "^CMakeLists\\.txt$", 791 "line": None, 792 "command": None, 793 "hasParent": False, 794 }, 795 ], 796 }, 797 ] 798 e["sourceGroups"] = [ 799 { 800 "name": "CMake Rules", 801 "sourcePaths": [ 802 "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/([0-9a-f]+/)?generate\\.stamp\\.rule$", 803 ], 804 }, 805 ] 806 elif e["name"] in ("ALL_BUILD"): 807 e["sources"] = [] 808 e["sourceGroups"] = None 809 if e["dependencies"] is not None: 810 for d in e["dependencies"]: 811 if matches(d["id"], "^\\^ZERO_CHECK::@"): 812 d["id"] = "^ZERO_CHECK::@6890427a1f51a3e7e1df$" 813 814 elif g["name"] == "Xcode": 815 if ';' in os.environ.get("CMAKE_OSX_ARCHITECTURES", ""): 816 expected = filter_list(lambda e: e["name"] not in ("link_imported_object_exe"), expected) 817 for e in expected: 818 e["dependencies"] = filter_list(lambda d: not matches(d["id"], "^\\^link_imported_object_exe::@"), e["dependencies"]) 819 if e["name"] in ("c_object_lib", "cxx_object_lib"): 820 e["artifacts"] = None 821 822 else: 823 for e in expected: 824 e["dependencies"] = filter_list(lambda d: not matches(d["id"], "^\\^ZERO_CHECK::@"), e["dependencies"]) 825 826 expected = filter_list(lambda t: t["name"] not in ("ALL_BUILD", "ZERO_CHECK"), expected) 827 828 if sys.platform not in ("win32", "cygwin", "msys"): 829 for e in expected: 830 e["artifacts"] = filter_list(lambda a: not a["_dllExtra"], e["artifacts"]) 831 if e["install"] is not None: 832 e["install"]["destinations"] = filter_list(lambda d: "_dllExtra" not in d or not d["_dllExtra"], e["install"]["destinations"]) 833 834 else: 835 for e in expected: 836 if e["install"] is not None: 837 e["install"]["destinations"] = filter_list(lambda d: "_namelink" not in d or not d["_namelink"], e["install"]["destinations"]) 838 839 if "aix" not in sys.platform: 840 for e in expected: 841 e["artifacts"] = filter_list(lambda a: not a.get("_aixExtra", False), e["artifacts"]) 842 843 return expected 844 845def check_targets(c, g, inSource): 846 check_list_match(lambda a, e: matches(a["id"], e["id"]), 847 c["targets"], gen_check_targets(c, g, inSource), 848 check=check_target(c), 849 check_exception=lambda a, e: "Target ID: %s" % a["id"], 850 missing_exception=lambda e: "Target ID: %s" % e["id"], 851 extra_exception=lambda a: "Target ID: %s" % a["id"]) 852 853def gen_check_projects(c, g): 854 expected = [ 855 read_codemodel_json_data("projects/codemodel-v2.json"), 856 read_codemodel_json_data("projects/cxx.json"), 857 read_codemodel_json_data("projects/alias.json"), 858 read_codemodel_json_data("projects/object.json"), 859 read_codemodel_json_data("projects/imported.json"), 860 read_codemodel_json_data("projects/interface.json"), 861 read_codemodel_json_data("projects/custom.json"), 862 read_codemodel_json_data("projects/external.json"), 863 ] 864 865 if matches(g["name"], "^Visual Studio "): 866 for e in expected: 867 if e["parentName"] is not None: 868 e["targetIds"] = filter_list(lambda t: not matches(t, "^\\^ZERO_CHECK"), e["targetIds"]) 869 870 elif g["name"] == "Xcode": 871 if ';' in os.environ.get("CMAKE_OSX_ARCHITECTURES", ""): 872 for e in expected: 873 e["targetIds"] = filter_list(lambda t: not matches(t, "^\\^(link_imported_object_exe)"), e["targetIds"]) 874 875 else: 876 for e in expected: 877 e["targetIds"] = filter_list(lambda t: not matches(t, "^\\^(ALL_BUILD|ZERO_CHECK)"), e["targetIds"]) 878 879 return expected 880 881def check_projects(c, g): 882 check_list_match(lambda a, e: is_string(a["name"], e["name"]), c["projects"], gen_check_projects(c, g), 883 check=check_project(c), 884 check_exception=lambda a, e: "Project name: %s" % a["name"], 885 missing_exception=lambda e: "Project name: %s" % e["name"], 886 extra_exception=lambda a: "Project name: %s" % a["name"]) 887 888def check_object_codemodel_configuration(c, g, inSource): 889 assert sorted(c.keys()) == ["directories", "name", "projects", "targets"] 890 assert is_string(c["name"]) 891 check_directories(c, g) 892 check_targets(c, g, inSource) 893 check_projects(c, g) 894 895def check_object_codemodel(g): 896 def _check(o): 897 assert sorted(o.keys()) == ["configurations", "kind", "paths", "version"] 898 # The "kind" and "version" members are handled by check_index_object. 899 assert is_dict(o["paths"]) 900 assert sorted(o["paths"].keys()) == ["build", "source"] 901 assert matches(o["paths"]["build"], "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build$") 902 assert matches(o["paths"]["source"], "^.*/Tests/RunCMake/FileAPI$") 903 904 inSource = os.path.dirname(o["paths"]["build"]) == o["paths"]["source"] 905 906 if g["multiConfig"]: 907 assert sorted([c["name"] for c in o["configurations"]]) == ["Debug", "MinSizeRel", "RelWithDebInfo", "Release"] 908 else: 909 assert len(o["configurations"]) == 1 910 assert o["configurations"][0]["name"] in ("", "Debug", "Release", "RelWithDebInfo", "MinSizeRel") 911 912 for c in o["configurations"]: 913 check_object_codemodel_configuration(c, g, inSource) 914 return _check 915 916cxx_compiler_id = sys.argv[2] 917assert is_dict(index) 918assert sorted(index.keys()) == ["cmake", "objects", "reply"] 919check_objects(index["objects"], index["cmake"]["generator"]) 920