mirror of
https://github.com/Kitware/CMake.git
synced 2026-08-09 09:12:00 +00:00
Add a regression test for the File API codemodel graph produced for an import std target. The test verifies that emitted target references, including those to the CMake-provided stdlib target, resolve to targets present in the codemodel. Closes: #27890
141 lines
5.0 KiB
Python
141 lines
5.0 KiB
Python
from check_index import *
|
|
|
|
import json
|
|
import os
|
|
|
|
def read_json(filename):
|
|
with open(os.path.join(reply_dir, filename)) as f:
|
|
return json.load(f)
|
|
|
|
def check_target_id(target_ids, std_target_ids, state, target_file, context, target_id):
|
|
assert target_id in target_ids, \
|
|
"Target '%s' has dangling %s target id '%s'." % (target_file, context, target_id)
|
|
|
|
if target_id in std_target_ids:
|
|
state["referenced_std_target"] = True
|
|
|
|
def collect_target_ids(codemodel):
|
|
target_ids = set()
|
|
target_json_files = set()
|
|
std_target_ids = set()
|
|
seen_main_target = False
|
|
seen_std_target = False
|
|
|
|
assert is_list(codemodel["configurations"])
|
|
assert len(codemodel["configurations"]) > 0
|
|
|
|
for configuration in codemodel["configurations"]:
|
|
for target_list_name in ("targets", "abstractTargets"):
|
|
for target in configuration[target_list_name]:
|
|
assert is_dict(target)
|
|
target_id = target["id"]
|
|
target_ids.add(target_id)
|
|
target_json_files.add(target["jsonFile"])
|
|
|
|
if target["name"] == "main":
|
|
seen_main_target = True
|
|
if target["name"] == "@cmake_cxx_std":
|
|
seen_std_target = True
|
|
std_target_ids.add(target_id)
|
|
|
|
assert seen_main_target, "The File API codemodel did not report the user target 'main'."
|
|
assert seen_std_target, \
|
|
"The File API codemodel did not report the import std target '@cmake_cxx_std'."
|
|
|
|
return target_ids, target_json_files, std_target_ids
|
|
|
|
def check_target_references(codemodel):
|
|
target_ids, target_json_files, std_target_ids = collect_target_ids(codemodel)
|
|
target_id_reference_fields = (
|
|
"dependencies",
|
|
"compileDependencies",
|
|
"interfaceCompileDependencies",
|
|
"objectDependencies",
|
|
"orderDependencies",
|
|
)
|
|
link_reference_fields = (
|
|
"linkLibraries",
|
|
"interfaceLinkLibraries",
|
|
)
|
|
state = {
|
|
"referenced_std_target": False,
|
|
}
|
|
|
|
for target_json_file in sorted(target_json_files):
|
|
target = read_json(target_json_file)
|
|
for target_reference_field in target_id_reference_fields:
|
|
if target_reference_field not in target:
|
|
continue
|
|
|
|
assert is_list(target[target_reference_field])
|
|
for reference in target[target_reference_field]:
|
|
assert is_dict(reference)
|
|
check_target_id(
|
|
target_ids,
|
|
std_target_ids,
|
|
state,
|
|
target_json_file,
|
|
target_reference_field,
|
|
reference["id"])
|
|
|
|
if "fromDependency" in reference:
|
|
assert is_dict(reference["fromDependency"])
|
|
assert sorted(reference["fromDependency"].keys()) == ["id"]
|
|
check_target_id(
|
|
target_ids,
|
|
std_target_ids,
|
|
state,
|
|
target_json_file,
|
|
target_reference_field + ".fromDependency",
|
|
reference["fromDependency"]["id"])
|
|
|
|
for target_reference_field in link_reference_fields:
|
|
if target_reference_field not in target:
|
|
continue
|
|
|
|
assert is_list(target[target_reference_field])
|
|
for reference in target[target_reference_field]:
|
|
assert is_dict(reference)
|
|
has_id = "id" in reference
|
|
has_fragment = "fragment" in reference
|
|
assert has_id != has_fragment
|
|
|
|
if has_id:
|
|
check_target_id(
|
|
target_ids,
|
|
std_target_ids,
|
|
state,
|
|
target_json_file,
|
|
target_reference_field,
|
|
reference["id"])
|
|
|
|
if "fromDependency" in reference:
|
|
assert is_dict(reference["fromDependency"])
|
|
assert sorted(reference["fromDependency"].keys()) == ["id"]
|
|
check_target_id(
|
|
target_ids,
|
|
std_target_ids,
|
|
state,
|
|
target_json_file,
|
|
target_reference_field + ".fromDependency",
|
|
reference["fromDependency"]["id"])
|
|
|
|
assert state["referenced_std_target"], \
|
|
"The File API codemodel did not reference '@cmake_cxx_std' from any target relationship."
|
|
|
|
assert is_dict(index)
|
|
assert sorted(index.keys()) == ["cmake", "objects", "reply"]
|
|
assert is_list(index["objects"])
|
|
|
|
codemodel_index = None
|
|
for index_object in index["objects"]:
|
|
if index_object["kind"] == "codemodel":
|
|
codemodel_index = index_object
|
|
break
|
|
|
|
assert codemodel_index is not None, "No codemodel object found in File API index."
|
|
assert codemodel_index["version"]["major"] == 2
|
|
|
|
codemodel = read_json(codemodel_index["jsonFile"])
|
|
check_target_references(codemodel)
|