New ability recursion tests using a four cycle

Using four abilities instead of two means the C++ checking_tag
mechanism needs to handle multiple values, or needs to be supported
by recursion counting.

The branching test lets one level of recursion finish, and then tries
to go deeper. This tests for bugs where a recursion detection tool in
the engine gets its count reset when exiting one level of recursion.
This commit is contained in:
Steve Cotton 2024-06-22 16:07:34 +02:00 committed by Steve Cotton
parent f272d9022e
commit 4afdc92f13
4 changed files with 348 additions and 3 deletions

View file

@ -0,0 +1,127 @@
#textdomain wesnoth-test
#####
# API(s) being tested: [filter_weapon]special_type_active=
##
# Actions:
# Alice and Bob are both of type Test Melee Quintain (10x1 melee attack)
# Give Alice's weapon specialN and specialM.
# Give Bob's weapon specialX, specialY, specialX2 and specialY2.
# specialN (damage) is active if a poison special (specialX or specialX2) is active
# specialX (poison) is active if a slow special (specialM) is active
# specialM (slow) is active if a parry special (specialY, specialY2) is active
# specialY (parry) is active if a damage special (specialN) is active
# Have Alice attack with his weapon.
##
# Expected end state:
# Deterministic end state, without crashing, but BROKE STRICT.
# All the specials are inactive.
# Bob takes 10 damage.
#####
{COMMON_KEEP_A_B_UNIT_TEST "four_cycle_recursion_branching" (
[event]
name=start
[modify_unit]
[filter]
id=alice
[/filter]
[effect]
apply_to=attack
[set_specials]
mode=replace
[damage]
id=specialN
name= _ "specialN"
[filter_opponent]
[filter_weapon]
special_type_active=poison
[/filter_weapon]
[/filter_opponent]
value=20
apply_to=self
[/damage]
[slow]
id=specialM
name= _ "specialM"
[filter_opponent]
[filter_weapon]
special_type_active=parry
[/filter_weapon]
[/filter_opponent]
apply_to=self
[/slow]
[/set_specials]
[/effect]
[/modify_unit]
[modify_unit]
[filter]
id=bob
[/filter]
[effect]
apply_to=attack
[set_specials]
mode=replace
[poison]
id=specialX
name= _ "specialX"
[filter_opponent]
[filter_weapon]
special_type_active=damage
[/filter_weapon]
[/filter_opponent]
apply_to=self
[/poison]
[parry]
id=specialY
name= _ "specialY"
[filter_opponent]
[filter_weapon]
special_type_active=slow
[/filter_weapon]
[/filter_opponent]
apply_to=self
[/parry]
[poison]
id=specialX2
name= _ "specialX2"
[filter_opponent]
[filter_weapon]
special_type_active=damage
[/filter_weapon]
[/filter_opponent]
apply_to=self
[/poison]
[parry]
id=specialY2
name= _ "specialY2"
[filter_opponent]
[filter_weapon]
special_type_active=slow
[/filter_weapon]
[/filter_opponent]
apply_to=self
[/parry]
[/set_specials]
[/effect]
[/modify_unit]
[test_do_attack_by_id]
attacker=alice
defender=bob
weapon=0
[/test_do_attack_by_id]
[store_unit]
[filter]
id=bob
[/filter]
variable=bob
[/store_unit]
{ASSERT ({VARIABLE_CONDITIONAL bob.hitpoints equals 90})}
{SUCCEED}
[/event]
) SIDE1_LEADER="Test Melee Quintain" SIDE2_LEADER="Test Melee Quintain"}

View file

@ -0,0 +1,107 @@
#textdomain wesnoth-test
#####
# API(s) being tested: [filter_weapon]special_id_active=
##
# Actions:
# Alice and Bob are both of type Test Melee Quintain.
# Give Alice's weapon specials specialN and specialM.
# Give Bob's weapon specials specialX and specialY.
# specialN (damage) is active if specialX is active
# specialX (poison) is active if specialM is active
# specialM (slow) is active if specialY is active
# specialY (parry) is active if specialN is active
# Have Alice attack with his weapon.
##
# Expected end state:
# Deterministic end state, without crashing, but BROKE STRICT.
# All the specials are inactive.
# Bob takes 10 damage.
#####
{COMMON_KEEP_A_B_UNIT_TEST "four_cycle_recursion_by_id" (
[event]
name=start
[modify_unit]
[filter]
id=alice
[/filter]
[effect]
apply_to=attack
[set_specials]
mode=replace
[damage]
id=specialN
name= _ "specialN"
[filter_opponent]
[filter_weapon]
special_id_active=specialX
[/filter_weapon]
[/filter_opponent]
value=20
apply_to=self
[/damage]
[slow]
id=specialM
name= _ "specialM"
[filter_opponent]
[filter_weapon]
special_id_active=specialY
[/filter_weapon]
[/filter_opponent]
apply_to=self
[/slow]
[/set_specials]
[/effect]
[/modify_unit]
[modify_unit]
[filter]
id=bob
[/filter]
[effect]
apply_to=attack
[set_specials]
mode=replace
[poison]
id=specialX
name= _ "specialX"
[filter_opponent]
[filter_weapon]
special_id_active=specialM
[/filter_weapon]
[/filter_opponent]
apply_to=self
[/poison]
[parry]
id=specialY
name= _ "specialY"
[filter_opponent]
[filter_weapon]
special_id_active=specialN
[/filter_weapon]
[/filter_opponent]
apply_to=self
[/parry]
[/set_specials]
[/effect]
[/modify_unit]
[test_do_attack_by_id]
attacker=alice
defender=bob
weapon=0
[/test_do_attack_by_id]
[store_unit]
[filter]
id=bob
[/filter]
variable=bob
[/store_unit]
{ASSERT ({VARIABLE_CONDITIONAL bob.hitpoints equals 90})}
{SUCCEED}
[/event]
) SIDE1_LEADER="Test Melee Quintain" SIDE2_LEADER="Test Melee Quintain"}

View file

@ -0,0 +1,108 @@
#textdomain wesnoth-test
#####
# API(s) being tested: [filter_weapon]special_type_active=
##
# Actions:
# Alice and Bob are both of type Test Melee Quintain (10x1 melee attack)
# Give Alice's weapon specialN and specialM.
# Give Bob's weapon specialX, specialY, specialX2 and specialY2.
# specialN (damage) is active if a poison special (specialX) is active
# specialX (poison) is active if a slow special (specialM) is active
# specialM (slow) is active if a parry special (specialY) is active
# specialY (parry) is active if a damage special (specialN) is active
# specialX2 and specialY2 have the same filters as specialX and specialY
# Have Alice attack with his weapon.
##
# Expected end state:
# Deterministic end state, without crashing, but BROKE STRICT.
# All the specials are inactive.
# Bob takes 10 damage.
#####
{COMMON_KEEP_A_B_UNIT_TEST "four_cycle_recursion_by_tagname" (
[event]
name=start
[modify_unit]
[filter]
id=alice
[/filter]
[effect]
apply_to=attack
[set_specials]
mode=replace
[damage]
id=specialN
name= _ "specialN"
[filter_opponent]
[filter_weapon]
special_type_active=poison
[/filter_weapon]
[/filter_opponent]
value=20
apply_to=self
[/damage]
[slow]
id=specialM
name= _ "specialM"
[filter_opponent]
[filter_weapon]
special_type_active=parry
[/filter_weapon]
[/filter_opponent]
apply_to=self
[/slow]
[/set_specials]
[/effect]
[/modify_unit]
[modify_unit]
[filter]
id=bob
[/filter]
[effect]
apply_to=attack
[set_specials]
mode=replace
[poison]
id=specialX
name= _ "specialX"
[filter_opponent]
[filter_weapon]
special_type_active=damage
[/filter_weapon]
[/filter_opponent]
apply_to=self
[/poison]
[parry]
id=specialY
name= _ "specialY"
[filter_opponent]
[filter_weapon]
special_type_active=slow
[/filter_weapon]
[/filter_opponent]
apply_to=self
[/parry]
[/set_specials]
[/effect]
[/modify_unit]
[test_do_attack_by_id]
attacker=alice
defender=bob
weapon=0
[/test_do_attack_by_id]
[store_unit]
[filter]
id=bob
[/filter]
variable=bob
[/store_unit]
{ASSERT ({VARIABLE_CONDITIONAL bob.hitpoints equals 90})}
{SUCCEED}
[/event]
) SIDE1_LEADER="Test Melee Quintain" SIDE2_LEADER="Test Melee Quintain"}

View file

@ -166,8 +166,8 @@
0 event_test_filter_attack_specials
0 event_test_filter_attack_on_moveto
0 event_test_filter_attack_opponent_weapon_condition
0 event_test_filter_attack_opponent_weapon_condition_no_triggered
0 event_test_filter_attack_student_weapon_condition
9 event_test_filter_attack_opponent_weapon_condition_no_triggered
9 event_test_filter_attack_student_weapon_condition
0 event_test_filter_wfl
0 event_test_filter_wfl2
0 event_test_filter_lua_serializable
@ -377,7 +377,10 @@
0 damage_type_test
0 damage_type_with_filter_test
0 damage_secondary_type_test
0 event_test_filter_damage_type_recursion
9 event_test_filter_damage_type_recursion
9 four_cycle_recursion_branching
9 four_cycle_recursion_by_id
9 four_cycle_recursion_by_tagname
0 negative_resistance_with_two_attack_types
0 positive_resistance_with_two_attack_types
0 taught_resistance_with_two_attack_types