375 lines
14 KiB
GDScript
375 lines
14 KiB
GDScript
|
|
|
|
|
|
# ------------------------------- WARNING --------------------------------
|
|
# These tests were auto generated by an LLM according to a design document
|
|
# to simply test the workflow. These tests should not be completely relied
|
|
# on for tesing full functionality of the datapack system.
|
|
# ------------------------------------------------------------------------
|
|
|
|
|
|
class_name DatapackTestNode
|
|
extends Node
|
|
|
|
# --- PRIMARY PACK CONSTANTS ---
|
|
const PACK_NAME = "core_data_test_pack"
|
|
const ENTRY_ID = "test_item_sword"
|
|
const WEAPONS_DATASET_ID = "weapons_dataset"
|
|
const SKILLS_DATASET_ID = "skills_dataset"
|
|
const CHAR_TEMPLATE_ID = "base_char_template"
|
|
const SESSION_TEMPLATE_ID = "basic_session_template"
|
|
|
|
# --- NEW CROSS-PACK CONSTANTS ---
|
|
const DEPENDENCY_PACK_NAME = "stat_core_pack"
|
|
const DEPENDENCY_DATASET_ID = "core_stats_dataset"
|
|
const DEPENDENCY_ENTRY_ID = "base_strength"
|
|
const DEPENDER_PACK_NAME = "class_pack"
|
|
const DEPENDER_DATASET_ID = "warrior_class"
|
|
|
|
|
|
func _ready() -> void:
|
|
|
|
print("--- Starting Datapack Test ---")
|
|
|
|
# --- Primary Test (Pack 1) ---
|
|
var creation_success = _create_and_save_datapack()
|
|
if not creation_success:
|
|
push_error("TEST FAILED: Datapack creation failed.")
|
|
return
|
|
|
|
_load_and_verify_datapack()
|
|
_test_formula_resolution()
|
|
|
|
# --- New Cross-Pack Dependency Test (Pack 2 & 3) ---
|
|
_test_cross_datapack_dependency()
|
|
|
|
print("--- Datapack Test Complete ---")
|
|
|
|
#----------------------------------------------------------------------
|
|
## --- STEP 2: CREATION AND SAVING ---
|
|
#----------------------------------------------------------------------
|
|
func _create_and_save_datapack() -> bool:
|
|
print("\n--- 2. Creating and Saving Datapack ---")
|
|
|
|
# --- 0. Setup Core Data ---
|
|
var stats_group := DatasetGroup.new()
|
|
stats_group.id = "base_stats"
|
|
stats_group.name = "Base Stats"
|
|
|
|
# Simple Numeric Field
|
|
var damage_field := DataFieldValue.new()
|
|
damage_field.field_type = DataFieldValue.DataFieldType.NUMBER
|
|
damage_field.value = 12
|
|
stats_group.fields["damage"] = damage_field
|
|
|
|
# --- FORMULA Field ---
|
|
var formula_res := FormulaValue.new()
|
|
formula_res.expression = "Base_Damage * Critical_Multiplier"
|
|
|
|
var crit_damage_field := DataFieldValue.new()
|
|
crit_damage_field.field_type = DataFieldValue.DataFieldType.FORMULA
|
|
crit_damage_field.value = formula_res
|
|
stats_group.fields["critical_damage"] = crit_damage_field
|
|
|
|
# --- LIST Field ---
|
|
var list_res := ListValue.new()
|
|
|
|
# Add nested DataFieldValue items to the ListValue resource
|
|
var list_item_1 := DataFieldValue.new()
|
|
list_item_1.field_type = DataFieldValue.DataFieldType.NUMBER
|
|
list_item_1.value = 5
|
|
|
|
var list_item_2 := DataFieldValue.new()
|
|
list_item_2.field_type = DataFieldValue.DataFieldType.TEXT
|
|
list_item_2.value = "Stun"
|
|
|
|
list_res.items.append(list_item_1)
|
|
list_res.items.append(list_item_2)
|
|
|
|
var effect_list_field := DataFieldValue.new()
|
|
effect_list_field.field_type = DataFieldValue.DataFieldType.LIST
|
|
effect_list_field.value = list_res
|
|
stats_group.fields["on_hit_effects"] = effect_list_field
|
|
|
|
# Create Dataset Entry
|
|
var sword_entry := DatasetEntry.new()
|
|
sword_entry.id = ENTRY_ID
|
|
sword_entry.name = "Longsword of Testing"
|
|
sword_entry.description = "A sword for unit testing."
|
|
sword_entry.groups.append(stats_group)
|
|
|
|
# Create Dataset Model (Weapons)
|
|
var weapons_dataset := DatasetModel.new()
|
|
weapons_dataset.id = WEAPONS_DATASET_ID
|
|
weapons_dataset.name = "Weapons"
|
|
weapons_dataset.entries[sword_entry.id] = sword_entry
|
|
weapons_dataset.sz_type = "Weapon"
|
|
|
|
# --- Dependency Setup: Skills Dataset ---
|
|
var skills_dataset := DatasetModel.new()
|
|
skills_dataset.id = SKILLS_DATASET_ID
|
|
skills_dataset.name = "Skills"
|
|
skills_dataset.sz_type = "Skill"
|
|
|
|
# --- Dependency Setup: CharacterTemplate ---
|
|
var char_template := CharacterTemplate.new()
|
|
char_template.id = CHAR_TEMPLATE_ID
|
|
char_template.name = "Standard Character"
|
|
|
|
var skills_dependency := DependencySource.new()
|
|
skills_dependency.mode = DependencySource.DependencyMode.SPECIFIC_DATASET
|
|
skills_dependency.target_sz_object_id = SKILLS_DATASET_ID
|
|
|
|
char_template.data_dependencies["Skills_Source"] = skills_dependency
|
|
|
|
# --- Dependency Setup: SessionTemplate ---
|
|
var session_template := SessionTemplate.new()
|
|
session_template.id = SESSION_TEMPLATE_ID
|
|
session_template.name = "Basic Campaign Session"
|
|
|
|
var char_dep_source := DependencySource.new()
|
|
char_dep_source.mode = DependencySource.DependencyMode.SPECIFIC_DATASET
|
|
char_dep_source.target_sz_object_id = CHAR_TEMPLATE_ID
|
|
session_template.character_template_ref = char_dep_source
|
|
|
|
# --- Create and Save Datapack Model ---
|
|
var datapack := DatapackModel.new()
|
|
datapack.name = "Test Pack"
|
|
datapack.version = "1.0.0"
|
|
|
|
datapack.sz_objects.append(weapons_dataset)
|
|
datapack.sz_objects.append(skills_dataset)
|
|
datapack.sz_objects.append(char_template)
|
|
datapack.sz_objects.append(session_template)
|
|
|
|
var creator = DatapackCreator.new()
|
|
var success = creator.save_datapack(datapack, PACK_NAME)
|
|
|
|
return success
|
|
|
|
#----------------------------------------------------------------------
|
|
## --- STEP 3: LOADING AND VERIFICATION (Omitted for brevity, assumed stable) ---
|
|
#----------------------------------------------------------------------
|
|
func _load_and_verify_datapack() -> void:
|
|
print("\n--- 3. Loading and Verification ---")
|
|
var loader = DatapackLoader.new()
|
|
|
|
var loaded_pack: DatapackModel = loader.load_datapack(PACK_NAME)
|
|
|
|
if not loaded_pack:
|
|
push_error("TEST FAILED: DatapackLoader returned null.")
|
|
return
|
|
|
|
DatapackManager.register_pack(loaded_pack)
|
|
print("Verification: Datapack registered with DatapackManager.")
|
|
|
|
var loaded_weapons_dataset: DatasetModel = loaded_pack.get_object_by_id(WEAPONS_DATASET_ID)
|
|
var loaded_entry: DatasetEntry = loaded_weapons_dataset.entries.get(ENTRY_ID)
|
|
var loaded_group: DatasetGroup = loaded_entry.groups.filter(func(g): return g.id == "base_stats").front()
|
|
var loaded_char_template: CharacterTemplate = loaded_pack.get_object_by_id(CHAR_TEMPLATE_ID)
|
|
var loaded_session_template: SessionTemplate = loaded_pack.get_object_by_id(SESSION_TEMPLATE_ID)
|
|
|
|
# 1. SessionTemplate Character Reference
|
|
var char_ref_dep_source: DependencySource = loaded_session_template.character_template_ref
|
|
var resolved_char_template_array = DatapackManager.resolve_dependency_source(char_ref_dep_source)
|
|
if resolved_char_template_array.size() == 1 and resolved_char_template_array.front() == loaded_char_template:
|
|
print("✅ SUCCESS: SessionTemplate dependency link resolved.")
|
|
else:
|
|
push_error("TEST FAILED: SessionTemplate character_template_ref resolution failed.")
|
|
|
|
# 2. CharacterTemplate Skills Dependency
|
|
var skills_dep_source: DependencySource = loaded_char_template.data_dependencies.get("Skills_Source")
|
|
var resolved_skills_array = DatapackManager.resolve_dependency_source(skills_dep_source)
|
|
var loaded_skills_dataset = loaded_pack.get_object_by_id(SKILLS_DATASET_ID)
|
|
if resolved_skills_array.size() == 1 and resolved_skills_array.front() == loaded_skills_dataset:
|
|
print("✅ SUCCESS: CharacterTemplate data dependency link resolved.")
|
|
else:
|
|
push_error("TEST FAILED: CharacterTemplate data dependency resolution failed.")
|
|
|
|
# 3. Verify FORMULA field
|
|
var loaded_crit_field: DataFieldValue = loaded_group.fields.get("critical_damage")
|
|
if loaded_crit_field and loaded_crit_field.field_type == DataFieldValue.DataFieldType.FORMULA:
|
|
var formula: FormulaValue = loaded_crit_field.value
|
|
if formula is FormulaValue and formula.expression == "Base_Damage * Critical_Multiplier":
|
|
print("✅ SUCCESS: Found and verified FormulaValue resource.")
|
|
else:
|
|
push_error("TEST FAILED: FormulaValue verification failed (wrong type or expression).")
|
|
else:
|
|
push_error("TEST FAILED: Critical damage field not found or wrong type.")
|
|
|
|
# 4. Verify LIST field
|
|
var loaded_list_field: DataFieldValue = loaded_group.fields.get("on_hit_effects")
|
|
if loaded_list_field and loaded_list_field.field_type == DataFieldValue.DataFieldType.LIST:
|
|
var list_val: ListValue = loaded_list_field.value
|
|
if list_val is ListValue and list_val.items.size() == 2:
|
|
if list_val.items[1] is DataFieldValue and list_val.items[1].value == "Stun":
|
|
print("✅ SUCCESS: Found and verified ListValue and its nested contents.")
|
|
else:
|
|
push_error("TEST FAILED: ListValue contents verification failed.")
|
|
else:
|
|
push_error("TEST FAILED: ListValue resource failed to load correctly.")
|
|
else:
|
|
push_error("TEST FAILED: On hit effects field not found or wrong type.")
|
|
|
|
print("\nVerification: All checks completed.")
|
|
|
|
#----------------------------------------------------------------------
|
|
## --- STEP 4: FORMULA RESOLUTION TEST (Omitted for brevity, assumed stable) ---
|
|
#----------------------------------------------------------------------
|
|
func _test_formula_resolution():
|
|
print("\n--- 4. Testing Formula Resolver with Variable Substitution ---")
|
|
|
|
var resolver := FormulaResolver.new()
|
|
var raw_expression := "Base_Damage * Critical_Multiplier + floor(Skill_Level / 2)"
|
|
|
|
var context: Dictionary = {
|
|
"Base_Damage": 15,
|
|
"Critical_Multiplier": 2.5,
|
|
"Skill_Level": 7
|
|
}
|
|
|
|
var expected_result = 40.5
|
|
var result = resolver.resolve_formula(raw_expression, context)
|
|
|
|
if abs(result - expected_result) < 0.001:
|
|
print("✅ SUCCESS: FormulaResolver calculated the correct result: %f" % result)
|
|
else:
|
|
push_error("TEST FAILED: FormulaResolver result incorrect. Expected %f, Got %f" % [expected_result, result])
|
|
|
|
|
|
#----------------------------------------------------------------------
|
|
## --- STEP 5: CROSS-PACK DEPENDENCY RESOLUTION ---
|
|
#----------------------------------------------------------------------
|
|
func _test_cross_datapack_dependency():
|
|
print("\n--- 5. Testing Cross-Pack Dependency Resolution ---")
|
|
|
|
DatapackManager.clear_loaded_packs()
|
|
print("DatapackManager cleared for cross-pack test.")
|
|
|
|
# --- 5a. Create and Save DEPENDENCY PACK (Pack A: Stat Core) ---
|
|
# FIX: Capture the DatapackModel to get its GUID
|
|
var pack_a_model: DatapackModel = _create_dependency_pack_a()
|
|
if not pack_a_model:
|
|
push_error("TEST FAILED: Failed to create Dependency Pack A.")
|
|
return
|
|
|
|
var dependency_pack_guid: Guid = pack_a_model.guid # <--- This is the Guid object needed
|
|
print("Pack A GUID captured: %s" % dependency_pack_guid.to_string())
|
|
|
|
# --- 5b. Create and Save DEPENDER PACK (Pack B: Class Pack) ---
|
|
# FIX: Pass the GUID object to the creator function
|
|
var success_b = _create_depender_pack_b(dependency_pack_guid)
|
|
if not success_b:
|
|
push_error("TEST FAILED: Failed to create Depender Pack B.")
|
|
return
|
|
|
|
# --- 5c. Load and Register Both Packs ---
|
|
var loader = DatapackLoader.new()
|
|
var pack_a: DatapackModel = loader.load_datapack(DEPENDENCY_PACK_NAME)
|
|
var pack_b: DatapackModel = loader.load_datapack(DEPENDER_PACK_NAME)
|
|
|
|
if not pack_a or not pack_b:
|
|
push_error("TEST FAILED: Failed to load one or both dependency test packs.")
|
|
return
|
|
|
|
DatapackManager.register_pack(pack_a)
|
|
DatapackManager.register_pack(pack_b)
|
|
print("Registered both Dependency (A) and Depender (B) packs.")
|
|
|
|
# --- 5d. Resolve Dependency in Pack B ---
|
|
var depender_dataset: DatasetModel = pack_b.get_object_by_id(DEPENDER_DATASET_ID)
|
|
if not depender_dataset:
|
|
push_error("TEST FAILED: Could not find Depender Dataset in Pack B.")
|
|
return
|
|
|
|
var dependency_source: DependencySource = depender_dataset.get_meta("core_stats_source")
|
|
if not dependency_source:
|
|
push_error("TEST FAILED: Could not find the DependencySource object in Pack B.")
|
|
return
|
|
|
|
var resolved_objects: Array = DatapackManager.resolve_dependency_source(dependency_source)
|
|
|
|
# --- 5e. Verification ---
|
|
if resolved_objects.size() != 1:
|
|
push_error("TEST FAILED: Dependency resolution returned incorrect count: %d" % resolved_objects.size())
|
|
return
|
|
|
|
var resolved_dataset: DatasetModel = resolved_objects.front()
|
|
var expected_dataset: DatasetModel = pack_a.get_object_by_id(DEPENDENCY_DATASET_ID)
|
|
|
|
if resolved_dataset == expected_dataset:
|
|
print("✅ SUCCESS: Cross-pack dependency successfully resolved.")
|
|
if resolved_dataset.entries.has(DEPENDENCY_ENTRY_ID):
|
|
print("✅ SUCCESS: Resolved dataset contains the expected entry '%s'." % DEPENDENCY_ENTRY_ID)
|
|
else:
|
|
push_error("TEST FAILED: Dependency resolved to the wrong object.")
|
|
|
|
|
|
# --- Helper Functions for Cross-Pack Test ---
|
|
|
|
# UPDATED: Returns the DatapackModel for GUID retrieval
|
|
func _create_dependency_pack_a() -> DatapackModel:
|
|
# Create entry
|
|
var str_field := DataFieldValue.new()
|
|
str_field.field_type = DataFieldValue.DataFieldType.NUMBER
|
|
str_field.value = 10
|
|
|
|
var strength_entry := DatasetEntry.new()
|
|
strength_entry.id = DEPENDENCY_ENTRY_ID
|
|
strength_entry.name = "Strength"
|
|
strength_entry.top_level_fields["value"] = str_field
|
|
|
|
# Create dataset
|
|
var core_stats_dataset := DatasetModel.new()
|
|
core_stats_dataset.id = DEPENDENCY_DATASET_ID
|
|
core_stats_dataset.name = "Core Stats"
|
|
core_stats_dataset.sz_type = "StatDefinition"
|
|
core_stats_dataset.entries[strength_entry.id] = strength_entry
|
|
|
|
# Create datapack
|
|
var datapack := DatapackModel.new()
|
|
datapack.name = "Stat Core Pack"
|
|
datapack.version = "1.0.0"
|
|
datapack.sz_objects.append(core_stats_dataset)
|
|
|
|
var creator = DatapackCreator.new()
|
|
var success = creator.save_datapack(datapack, DEPENDENCY_PACK_NAME)
|
|
|
|
if success:
|
|
return datapack
|
|
else:
|
|
return null # Return null on failure
|
|
|
|
# UPDATED: Accepts the GUID to correctly create the DatapackDependency
|
|
func _create_depender_pack_b(dependency_pack_guid: Guid) -> bool:
|
|
# Create DependencySource (internal reference by string ID)
|
|
var dependency_source := DependencySource.new()
|
|
dependency_source.mode = DependencySource.DependencyMode.SPECIFIC_DATASET
|
|
dependency_source.target_sz_object_id = DEPENDENCY_DATASET_ID
|
|
|
|
# Create Depender Dataset
|
|
var warrior_class_dataset := DatasetModel.new()
|
|
warrior_class_dataset.id = DEPENDER_DATASET_ID
|
|
warrior_class_dataset.name = "Warrior Class"
|
|
warrior_class_dataset.sz_type = "ClassDefinition"
|
|
|
|
warrior_class_dataset.set_meta("core_stats_source", dependency_source)
|
|
|
|
# Create Datapack
|
|
var datapack := DatapackModel.new()
|
|
datapack.name = "Warrior Class Pack"
|
|
datapack.version = "1.0.0"
|
|
datapack.sz_objects.append(warrior_class_dataset)
|
|
|
|
# Add the explicit pack dependency
|
|
var pack_dep := DatapackDependency.new()
|
|
# FIX: Assign the Guid object to the 'id' property
|
|
pack_dep.id = dependency_pack_guid
|
|
pack_dep.name = "Stat Core Pack"
|
|
pack_dep.version = "1.0.0"
|
|
datapack.dependencies.append(pack_dep)
|
|
|
|
var creator = DatapackCreator.new()
|
|
var success = creator.save_datapack(datapack, DEPENDER_PACK_NAME)
|
|
return success
|