extends GutTest ## Unit tests for CPPool.gd var cp_pool: CPPool func before_each(): cp_pool = CPPool.new() ## Initialization Tests func test_initial_state_empty(): assert_eq(cp_pool.get_total_cp(), 0) for element in Enums.Element.values(): assert_eq(cp_pool.get_cp(element), 0) ## Basic CP Operations func test_add_cp(): cp_pool.add_cp(Enums.Element.FIRE, 2) assert_eq(cp_pool.get_cp(Enums.Element.FIRE), 2) assert_eq(cp_pool.get_total_cp(), 2) func test_add_cp_multiple_elements(): cp_pool.add_cp(Enums.Element.FIRE, 2) cp_pool.add_cp(Enums.Element.ICE, 3) cp_pool.add_cp(Enums.Element.WIND, 1) assert_eq(cp_pool.get_cp(Enums.Element.FIRE), 2) assert_eq(cp_pool.get_cp(Enums.Element.ICE), 3) assert_eq(cp_pool.get_cp(Enums.Element.WIND), 1) assert_eq(cp_pool.get_total_cp(), 6) func test_add_cp_accumulates(): cp_pool.add_cp(Enums.Element.FIRE, 2) cp_pool.add_cp(Enums.Element.FIRE, 3) assert_eq(cp_pool.get_cp(Enums.Element.FIRE), 5) func test_add_cp_floors_at_zero(): cp_pool.add_cp(Enums.Element.FIRE, 2) cp_pool.add_cp(Enums.Element.FIRE, -5) # Try to go negative assert_eq(cp_pool.get_cp(Enums.Element.FIRE), 0) func test_clear_resets_all(): cp_pool.add_cp(Enums.Element.FIRE, 2) cp_pool.add_cp(Enums.Element.ICE, 3) cp_pool.add_cp(Enums.Element.LIGHT, 1) cp_pool.clear() assert_eq(cp_pool.get_total_cp(), 0) assert_eq(cp_pool.get_cp(Enums.Element.FIRE), 0) assert_eq(cp_pool.get_cp(Enums.Element.ICE), 0) assert_eq(cp_pool.get_cp(Enums.Element.LIGHT), 0) ## Light/Dark CP Tests func test_get_non_light_dark_cp(): cp_pool.add_cp(Enums.Element.FIRE, 2) cp_pool.add_cp(Enums.Element.LIGHT, 3) cp_pool.add_cp(Enums.Element.DARK, 1) assert_eq(cp_pool.get_non_light_dark_cp(), 2) assert_eq(cp_pool.get_total_cp(), 6) func test_get_non_light_dark_cp_no_regular(): cp_pool.add_cp(Enums.Element.LIGHT, 3) cp_pool.add_cp(Enums.Element.DARK, 2) assert_eq(cp_pool.get_non_light_dark_cp(), 0) ## Single Element Card Affordability Tests func test_can_afford_single_element_card_with_exact_element(): var card = TestCardData.create_forward("id", "Test", Enums.Element.FIRE, 3, 5000) # Have exactly 3 Fire CP cp_pool.add_cp(Enums.Element.FIRE, 3) assert_true(cp_pool.can_afford_card(card)) func test_can_afford_single_element_card_with_mixed_cp(): var card = TestCardData.create_forward("id", "Test", Enums.Element.FIRE, 3, 5000) # Have 1 Fire + 2 Ice = enough total with required element cp_pool.add_cp(Enums.Element.FIRE, 1) cp_pool.add_cp(Enums.Element.ICE, 2) assert_true(cp_pool.can_afford_card(card)) func test_cannot_afford_single_element_without_matching_element(): var card = TestCardData.create_forward("id", "Test", Enums.Element.FIRE, 3, 5000) # Have plenty of CP but no Fire cp_pool.add_cp(Enums.Element.ICE, 5) assert_false(cp_pool.can_afford_card(card)) func test_cannot_afford_single_element_insufficient_total(): var card = TestCardData.create_forward("id", "Test", Enums.Element.FIRE, 3, 5000) # Have Fire but not enough total cp_pool.add_cp(Enums.Element.FIRE, 1) cp_pool.add_cp(Enums.Element.ICE, 1) assert_false(cp_pool.can_afford_card(card)) ## Multi-Element Card Affordability Tests func test_can_afford_multi_element_card(): var elements: Array[Enums.Element] = [Enums.Element.FIRE, Enums.Element.ICE] var card = TestCardData.create_multi_element_forward("id", "Multi", elements, 4, 7000) # Have 1 Fire + 1 Ice + 2 Wind = enough with both required elements cp_pool.add_cp(Enums.Element.FIRE, 1) cp_pool.add_cp(Enums.Element.ICE, 1) cp_pool.add_cp(Enums.Element.WIND, 2) assert_true(cp_pool.can_afford_card(card)) func test_cannot_afford_multi_element_missing_one_element(): var elements: Array[Enums.Element] = [Enums.Element.FIRE, Enums.Element.ICE] var card = TestCardData.create_multi_element_forward("id", "Multi", elements, 4, 7000) # Have only Fire, missing Ice cp_pool.add_cp(Enums.Element.FIRE, 4) assert_false(cp_pool.can_afford_card(card)) func test_cannot_afford_multi_element_insufficient_total(): var elements: Array[Enums.Element] = [Enums.Element.FIRE, Enums.Element.ICE] var card = TestCardData.create_multi_element_forward("id", "Multi", elements, 4, 7000) # Have both elements but not enough total cp_pool.add_cp(Enums.Element.FIRE, 1) cp_pool.add_cp(Enums.Element.ICE, 1) assert_false(cp_pool.can_afford_card(card)) ## Light Card Affordability Tests func test_can_afford_light_card(): var card = TestCardData.create_light_forward("id", "Light Forward", 5, 9000) # Light cards need at least 1 non-Light/Dark CP cp_pool.add_cp(Enums.Element.FIRE, 1) cp_pool.add_cp(Enums.Element.LIGHT, 4) assert_true(cp_pool.can_afford_card(card)) func test_cannot_afford_light_card_with_only_light_dark_cp(): var card = TestCardData.create_light_forward("id", "Light Forward", 5, 9000) # Only Light/Dark CP - not valid cp_pool.add_cp(Enums.Element.LIGHT, 5) assert_false(cp_pool.can_afford_card(card)) func test_cannot_afford_light_card_insufficient_total(): var card = TestCardData.create_light_forward("id", "Light Forward", 5, 9000) cp_pool.add_cp(Enums.Element.FIRE, 1) cp_pool.add_cp(Enums.Element.ICE, 2) assert_false(cp_pool.can_afford_card(card)) ## Dark Card Affordability Tests func test_can_afford_dark_card(): var card = TestCardData.create_dark_forward("id", "Dark Forward", 4, 8000) # Dark cards also need at least 1 non-Light/Dark CP cp_pool.add_cp(Enums.Element.WATER, 1) cp_pool.add_cp(Enums.Element.DARK, 3) assert_true(cp_pool.can_afford_card(card)) func test_cannot_afford_dark_card_with_only_light_dark_cp(): var card = TestCardData.create_dark_forward("id", "Dark Forward", 4, 8000) cp_pool.add_cp(Enums.Element.DARK, 10) assert_false(cp_pool.can_afford_card(card)) ## CP Spending Tests func test_spend_for_card_single_element(): var card = TestCardData.create_forward("id", "Test", Enums.Element.FIRE, 3, 5000) cp_pool.add_cp(Enums.Element.FIRE, 2) cp_pool.add_cp(Enums.Element.ICE, 2) var spent = cp_pool.spend_for_card(card) assert_false(spent.is_empty()) assert_eq(cp_pool.get_total_cp(), 1) # 4 - 3 = 1 assert_true(Enums.Element.FIRE in spent) # Must have spent at least 1 Fire func test_spend_for_card_returns_empty_if_cannot_afford(): var card = TestCardData.create_forward("id", "Test", Enums.Element.FIRE, 3, 5000) cp_pool.add_cp(Enums.Element.ICE, 2) # No Fire var spent = cp_pool.spend_for_card(card) assert_true(spent.is_empty()) assert_eq(cp_pool.get_total_cp(), 2) # No CP should be spent func test_spend_for_card_multi_element(): var elements: Array[Enums.Element] = [Enums.Element.FIRE, Enums.Element.ICE] var card = TestCardData.create_multi_element_forward("id", "Multi", elements, 4, 7000) cp_pool.add_cp(Enums.Element.FIRE, 2) cp_pool.add_cp(Enums.Element.ICE, 2) cp_pool.add_cp(Enums.Element.WIND, 1) var spent = cp_pool.spend_for_card(card) assert_false(spent.is_empty()) assert_eq(cp_pool.get_total_cp(), 1) # 5 - 4 = 1 assert_true(Enums.Element.FIRE in spent) assert_true(Enums.Element.ICE in spent) func test_spend_for_card_light(): var card = TestCardData.create_light_forward("id", "Light Forward", 3, 7000) cp_pool.add_cp(Enums.Element.FIRE, 1) cp_pool.add_cp(Enums.Element.LIGHT, 3) var spent = cp_pool.spend_for_card(card) assert_false(spent.is_empty()) assert_eq(cp_pool.get_total_cp(), 1) # 4 - 3 = 1 func test_spend_for_card_prefers_non_light_dark(): var card = TestCardData.create_forward("id", "Test", Enums.Element.FIRE, 2, 5000) cp_pool.add_cp(Enums.Element.FIRE, 2) cp_pool.add_cp(Enums.Element.LIGHT, 2) var spent = cp_pool.spend_for_card(card) assert_false(spent.is_empty()) # Should prefer spending Fire over Light assert_eq(cp_pool.get_cp(Enums.Element.LIGHT), 2) # Light should be untouched ## Ability Cost Tests func test_can_afford_ability_no_cost(): assert_true(cp_pool.can_afford_ability(null)) func test_can_afford_ability_with_element_requirements(): var cost = CardDatabase.CostData.new() cost.fire = 2 cp_pool.add_cp(Enums.Element.FIRE, 2) assert_true(cp_pool.can_afford_ability(cost)) func test_cannot_afford_ability_insufficient_element(): var cost = CardDatabase.CostData.new() cost.fire = 2 cp_pool.add_cp(Enums.Element.FIRE, 1) assert_false(cp_pool.can_afford_ability(cost)) func test_can_afford_ability_with_generic(): var cost = CardDatabase.CostData.new() cost.fire = 1 cost.generic = 2 cp_pool.add_cp(Enums.Element.FIRE, 1) cp_pool.add_cp(Enums.Element.ICE, 2) assert_true(cp_pool.can_afford_ability(cost)) func test_spend_for_ability(): var cost = CardDatabase.CostData.new() cost.fire = 1 cost.generic = 1 cp_pool.add_cp(Enums.Element.FIRE, 2) cp_pool.add_cp(Enums.Element.ICE, 1) var result = cp_pool.spend_for_ability(cost) assert_true(result) # Spent 1 Fire (required) + 1 generic (from Fire or Ice) assert_eq(cp_pool.get_total_cp(), 1) func test_spend_for_ability_fails_if_cannot_afford(): var cost = CardDatabase.CostData.new() cost.fire = 3 cp_pool.add_cp(Enums.Element.FIRE, 1) var result = cp_pool.spend_for_ability(cost) assert_false(result) assert_eq(cp_pool.get_cp(Enums.Element.FIRE), 1) # No CP spent ## Edge Cases func test_can_afford_null_card(): assert_false(cp_pool.can_afford_card(null)) func test_spend_for_null_card(): var spent = cp_pool.spend_for_card(null) assert_true(spent.is_empty()) func test_zero_cost_card(): var card = TestCardData.create_forward("id", "Free Card", Enums.Element.FIRE, 0, 3000) # Zero cost still needs at least 1 of the element cp_pool.add_cp(Enums.Element.FIRE, 1) # Actually, checking the code: cost is 0, so get_total_cp() >= 0 is always true # But need 1 Fire for single element check # Let me verify this is correct behavior - a 0 cost card needs element CP # Actually no - if cost is 0, we still check get_total_cp() >= cost which is 0 >= 0 # So we'd need 1 Fire (element check) but 0 total (cost check) # This might be a bug in the game logic - should test current behavior assert_true(cp_pool.can_afford_card(card)) func test_display_data(): cp_pool.add_cp(Enums.Element.FIRE, 2) cp_pool.add_cp(Enums.Element.ICE, 0) # Zero should not appear cp_pool.add_cp(Enums.Element.WIND, 1) var display = cp_pool.get_display_data() assert_true("Fire" in display) assert_eq(display["Fire"], 2) assert_true("Wind" in display) assert_eq(display["Wind"], 1) assert_false("Ice" in display) # Zero values excluded