feat: unify authored activity commands
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
extends GutTest
|
||||
|
||||
const ACTION_ID := &"test_activity_metric_action"
|
||||
|
||||
|
||||
func test_valid_activity_metric_action_uses_the_builtin_contract() -> void:
|
||||
var action := _valid_action()
|
||||
action.completion_cost_resource_id = SimulationIds.RESOURCE_WOOD
|
||||
action.completion_cost_amount = 1.0
|
||||
|
||||
var catalog := _catalog_with_action(action)
|
||||
assert_true(catalog.is_valid(), "%s" % [catalog.get_errors()])
|
||||
assert_not_null(catalog.get_action(ACTION_ID))
|
||||
|
||||
|
||||
func test_activity_metric_handler_rejects_non_activity_targets() -> void:
|
||||
var action := _valid_action()
|
||||
action.target_type = SimulationIds.TARGET_FREE
|
||||
|
||||
_assert_contract_error(action, "activity")
|
||||
|
||||
|
||||
func test_activity_metric_handler_requires_exactly_one_effect() -> void:
|
||||
var without_effects := _valid_action()
|
||||
without_effects.effects = []
|
||||
_assert_contract_error(without_effects, "exactly one")
|
||||
|
||||
var with_multiple_effects := _valid_action()
|
||||
var second_effect := _valid_effect()
|
||||
second_effect.effect_id = &"second_metric_effect"
|
||||
with_multiple_effects.effects = [_valid_effect(), second_effect]
|
||||
_assert_contract_error(with_multiple_effects, "exactly one")
|
||||
|
||||
|
||||
func test_activity_metric_handler_rejects_wrong_effect_kind() -> void:
|
||||
var action := _valid_action()
|
||||
var damage := ActionEffect.new()
|
||||
damage.effect_id = &"damage_instead_of_metric"
|
||||
damage.effect_kind = ActionEffect.KIND_DAMAGE
|
||||
damage.amount = 1.0
|
||||
action.effects = [damage]
|
||||
|
||||
_assert_contract_error(action, "metric_delta")
|
||||
|
||||
|
||||
func test_activity_metric_handler_rejects_unsupported_metric() -> void:
|
||||
var action := _valid_action()
|
||||
var effect := _valid_effect()
|
||||
effect.subject_key = &"morale"
|
||||
action.effects = [effect]
|
||||
|
||||
_assert_contract_error(action, "safety")
|
||||
|
||||
|
||||
func test_activity_metric_handler_rejects_malformed_player_multiplier() -> void:
|
||||
var action := _valid_action()
|
||||
var effect := _valid_effect()
|
||||
effect.parameters = {"player_multiplier": "three", "npc_productivity": true}
|
||||
action.effects = [effect]
|
||||
|
||||
_assert_contract_error(action, "player_multiplier")
|
||||
|
||||
|
||||
func test_activity_metric_handler_rejects_malformed_npc_productivity() -> void:
|
||||
var action := _valid_action()
|
||||
var effect := _valid_effect()
|
||||
effect.parameters = {"player_multiplier": 2.0, "npc_productivity": "yes"}
|
||||
action.effects = [effect]
|
||||
|
||||
_assert_contract_error(action, "npc_productivity")
|
||||
|
||||
|
||||
func test_activity_metric_handler_requires_a_completion_event_type() -> void:
|
||||
var action := _valid_action()
|
||||
action.event_type_id = &""
|
||||
|
||||
_assert_contract_error(action, "event_type_id")
|
||||
|
||||
|
||||
func test_activity_metric_completion_cost_must_have_a_storage_route() -> void:
|
||||
var action := _valid_action()
|
||||
action.completion_cost_resource_id = &"unrouted_activity_cost"
|
||||
action.completion_cost_amount = 1.0
|
||||
var unrouted_item := ItemDefinition.new()
|
||||
unrouted_item.item_id = action.completion_cost_resource_id
|
||||
unrouted_item.display_name = "Unrouted Activity Cost"
|
||||
unrouted_item.category = ItemDefinition.CATEGORY_RESOURCE
|
||||
|
||||
var catalog := _catalog_with_action(action, [unrouted_item])
|
||||
assert_false(catalog.is_valid(), "An executable cost needs an authoritative storage route")
|
||||
assert_true(
|
||||
_has_error(catalog.get_errors(), "storage"),
|
||||
"Expected a storage routing error, got %s" % [catalog.get_errors()]
|
||||
)
|
||||
|
||||
|
||||
func _assert_contract_error(action: ActionDefinition, expected_fragment: String) -> void:
|
||||
var catalog := _catalog_with_action(action)
|
||||
assert_false(catalog.is_valid(), "Invalid '%s' contract was published" % action.action_id)
|
||||
assert_true(
|
||||
_has_error(catalog.get_errors(), expected_fragment),
|
||||
"Expected '%s' in %s" % [expected_fragment, catalog.get_errors()]
|
||||
)
|
||||
|
||||
|
||||
func _catalog_with_action(
|
||||
action: ActionDefinition, items: Array[ItemDefinition] = []
|
||||
) -> ContentCatalog:
|
||||
var core := load(ContentCatalog.CORE_PACK_PATH) as SimulationContentPack
|
||||
var addon := SimulationContentPack.new()
|
||||
addon.pack_id = &"activity_contract_test"
|
||||
addon.display_name = "Activity Contract Test"
|
||||
addon.required_pack_ids = [&"core"]
|
||||
addon.required_handler_ids = [SimulationIds.ACTION_HANDLER_ACTIVITY_METRIC_DELTA]
|
||||
addon.actions = [action]
|
||||
addon.items = items
|
||||
var packs: Array[SimulationContentPack] = [addon, core]
|
||||
var catalog := ContentCatalog.new()
|
||||
catalog.rebuild(packs)
|
||||
return catalog
|
||||
|
||||
|
||||
func _valid_action() -> ActionDefinition:
|
||||
var action := ActionDefinition.new()
|
||||
action.action_id = ACTION_ID
|
||||
action.display_name = "Test Activity Metric Action"
|
||||
action.target_type = SimulationIds.TARGET_ACTIVITY
|
||||
action.completion_handler_id = SimulationIds.ACTION_HANDLER_ACTIVITY_METRIC_DELTA
|
||||
action.effects = [_valid_effect()]
|
||||
action.event_type_id = SimulationIds.EVENT_ACTIVITY_COMPLETED
|
||||
return action
|
||||
|
||||
|
||||
func _valid_effect() -> ActionEffect:
|
||||
var effect := ActionEffect.new()
|
||||
effect.effect_id = &"test_metric_effect"
|
||||
effect.effect_kind = ActionEffect.KIND_METRIC_DELTA
|
||||
effect.subject_key = &"safety"
|
||||
effect.value = 1.0
|
||||
effect.parameters = {"player_multiplier": 2.0, "npc_productivity": true}
|
||||
return effect
|
||||
|
||||
|
||||
func _has_error(errors: Array[String], fragment: String) -> bool:
|
||||
for error in errors:
|
||||
if fragment in error:
|
||||
return true
|
||||
return false
|
||||
Reference in New Issue
Block a user