149 lines
4.9 KiB
GDScript
149 lines
4.9 KiB
GDScript
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
|