Files
aetherbound-guild/runtime/tests/dev4/risk_selection_test.gd
T

208 lines
9.9 KiB
GDScript

extends SceneTree
const EntryShell = preload("res://entry/entry_shell.gd")
const SettingsStore = preload("res://entry/settings_store.gd")
const DraftService = preload("res://entry/initial_company_draft_service.gd")
const ContractService = preload("res://entry/guild_contract_service.gd")
const FormationService = preload("res://entry/formation_risk_service.gd")
const DRAFT_PATH := "user://dev4_risk_draft.json"
const COMPANY_PATH := "user://dev4_risk_company.json"
const SEED := "02468ace13579bdffdb97531eca86420"
const CONTRACT_OP := "aaaaaaaa22222222bbbbbbbb33333333"
const HIRE_OP_1 := "12121212343434345656565678787878"
const HIRE_OP_2 := "90909090ababababcdcdcdcdefefefef"
const ORDER_OP := "13571357246824681357135724682468"
const READY_OP := "deadbeefdeadbeefdeadbeefdeadbeef"
var failures: Array[String] = []
var parsed_touches := 0
func _initialize() -> void:
call_deferred("run_test")
func run_test() -> void:
_cleanup()
root.content_scale_mode = Window.CONTENT_SCALE_MODE_CANVAS_ITEMS
root.content_scale_aspect = Window.CONTENT_SCALE_ASPECT_EXPAND
root.size = Vector2i(844, 390)
await verify_locale("en")
_cleanup()
await verify_locale("zh_CN")
_cleanup()
if failures.is_empty():
print("ABG_DEV4_RISK_OK options=3 auto_selected=false recommended=false compare=threat,uncertainty,cost,reward,recovery,coverage compact_copy=true selection=local cancel=true back=guild settings_return=risk_board restart=readiness commitment=frozen_party begin_battle=disabled_dev5 no_battle_receipt=true locales=zh_CN,en text_100=true text_130=non_blocking parsed_touch=%d" % parsed_touches)
quit(0)
else:
for failure in failures:
push_error(failure)
quit(1)
func verify_locale(locale: String) -> void:
var prepared := _create_prepared_company()
if prepared.is_empty():
return
var settings := SettingsStore.new().defaults()
settings.setup_completed = true
settings.locale = locale
settings.text_scale = 1.0
var shell := EntryShell.new()
shell.auto_start = false
shell.initial_company_service.path = DRAFT_PATH
shell.initial_company_service.company_path = COMPANY_PATH
root.add_child(shell)
await _frames(3)
expect(shell.app_services.has_service(&"risk_board_page_controller"), "%s AppServices registers Risk Board controller" % locale)
shell.settings = settings
shell.setup_draft = settings.duplicate(true)
shell.show_readiness_review(prepared)
await _frames(3)
await _touch(shell.find_child("ReadinessRisk", true, false))
expect(shell.current_screen == "risk_board", "%s accepted readiness reaches Risk Board" % locale)
expect(shell.risk_view_data.ok and shell.risk_view_data.page_id == "risk_board", "%s Risk Board consumes controller snapshot" % locale)
expect(shell.risk_view_data.selection.state == "no_selection" and not shell.risk_view_data.commands.review_enabled, "%s controller preserves no-auto-selection boundary" % locale)
expect(shell.risk_selected_id.is_empty() and shell.find_child("RiskNoSelection", true, false) != null, "%s Risk Board begins with no automatic selection" % locale)
var options: Array = prepared.active_contract.formation.risk_options
for option in options:
var control := shell.find_child("RiskOption%s" % String(option.risk_option_id), true, false) as Button
expect(control != null and not bool(control.get_meta("selected", false)), "%s stable risk option begins unselected" % locale)
_verify_compact_fact_copy(shell, locale, options)
var before_hash := String(_draft_service().load_company().company.company_hash)
var selected_id := String(options[1].risk_option_id)
await _touch(shell.find_child("RiskOption%s" % selected_id, true, false))
expect(shell.risk_selected_id == selected_id and shell.find_child("RiskSelectedDetail", true, false) != null, "%s selecting one option expands its complete comparison" % locale)
expect(shell.risk_view_data.selection.selected_risk_id == selected_id and shell.risk_view_data.commands.review_enabled, "%s controller refreshes selected option and Review eligibility" % locale)
expect(String(_draft_service().load_company().company.company_hash) == before_hash, "%s risk selection changes no persisted Company state" % locale)
var review := shell.find_child("RiskReview", true, false) as Button
expect(review != null and not review.disabled, "%s selected risk enables review" % locale)
await _touch(review)
expect(shell.current_screen == "risk_commitment", "%s review opens attached commitment preview" % locale)
expect(shell.find_child("RiskCommitmentDetail", true, false) != null and shell.find_child("RiskFrozenMembers", true, false).get_child_count() == 4, "%s commitment retains exact risk facts and frozen four-member party" % locale)
var begin := shell.find_child("RiskBeginBattleUnavailable", true, false) as Button
expect(begin != null and begin.disabled and shell.find_child("RiskBeginBattleReason", true, false) != null, "%s Begin Battle is visibly disabled with DEV-5 reason" % locale)
var unchanged: Dictionary = _draft_service().load_company()
expect(String(unchanged.company.company_hash) == before_hash and not unchanged.company.active_contract.has("battle_receipts"), "%s commitment preview creates no battle receipt or mutation" % locale)
await _touch(shell.find_child("RiskCommitmentCancel", true, false))
expect(shell.current_screen == "risk_board" and shell.risk_selected_id == selected_id, "%s Cancel returns to the same selected risk" % locale)
await _touch(shell.find_child("RiskSettings", true, false))
expect(shell.current_screen == "settings", "%s Risk Board opens Settings" % locale)
await _touch(shell.find_child("SettingsBack", true, false))
expect(shell.current_screen == "risk_board" and shell.risk_selected_id == selected_id, "%s Settings returns to the same selected Risk Board" % locale)
await _touch(shell.find_child("RiskBackReadiness", true, false))
expect(shell.current_screen == "guild_handoff", "%s Back returns to Guild" % locale)
shell.queue_free()
await _frames(3)
var resumed := EntryShell.new()
resumed.auto_start = false
resumed.initial_company_service.path = DRAFT_PATH
resumed.initial_company_service.company_path = COMPANY_PATH
root.add_child(resumed)
await _frames(2)
resumed.settings = settings
resumed.setup_draft = settings.duplicate(true)
resumed._open_company_destination(unchanged.company)
await _frames(3)
expect(resumed.current_screen == "readiness_review" and resumed.risk_selected_id.is_empty(), "%s restart resumes readiness without persisting local risk selection" % locale)
resumed.queue_free()
await _frames(3)
func _create_prepared_company() -> Dictionary:
var draft: Dictionary = _draft_service().begin_or_load(SEED)
if not draft.ok:
return {}
_draft_service().set_selection([String(draft.draft.offers[0].offer_id), String(draft.draft.offers[2].offer_id)])
var committed: Dictionary = _draft_service().commit_company()
if not committed.ok:
return {}
var created: Dictionary = _contract_service().create_contract(CONTRACT_OP, "CTR-R1-01", "standard")
if not created.ok:
return {}
var offers: Array = created.company.active_contract.market_board.recruit_offers
_contract_service().hire_recruit(HIRE_OP_1, String(offers[0].source_offer_id), 14)
var hired: Dictionary = _contract_service().hire_recruit(HIRE_OP_2, String(offers[1].source_offer_id), 14)
if not hired.ok:
return {}
var begun: Dictionary = _formation_service().begin_formation()
if not begun.ok:
return {}
var saved: Dictionary = _formation_service().save_order(ORDER_OP, begun.formation.base_front_to_rear_ids)
if not saved.ok:
return {}
var accepted: Dictionary = _formation_service().accept_readiness(READY_OP, String(saved.receipt.order_hash))
return accepted.company if accepted.ok else {}
func _draft_service() -> RefCounted:
var service := DraftService.new()
service.path = DRAFT_PATH
service.company_path = COMPANY_PATH
return service
func _contract_service() -> RefCounted:
var service := ContractService.new()
service.company_path = COMPANY_PATH
return service
func _formation_service() -> RefCounted:
var service := FormationService.new()
service.company_path = COMPANY_PATH
return service
func _touch(control: Control) -> void:
if control == null:
expect(false, "touch target exists")
return
var center := control.get_global_rect().get_center()
var press := InputEventScreenTouch.new()
press.position = center
press.pressed = true
press.index = 0
Input.parse_input_event(press)
await _frames(2)
var release := InputEventScreenTouch.new()
release.position = center
release.pressed = false
release.index = 0
Input.parse_input_event(release)
parsed_touches += 1
await _frames(5)
func _frames(count: int) -> void:
for _index in range(count):
await process_frame
func _verify_compact_fact_copy(shell: Control, locale: String, options: Array) -> void:
var prefixes := ["威胁", "信息", "成本", "奖励", "恢复", "覆盖"] if locale == "zh_CN" else ["THREAT", "INFO", "COST", "REWARD", "RECOVERY", "COVERAGE"]
for option in options:
var button := shell.find_child("RiskOption%s" % String(option.risk_option_id), true, false) as Button
expect(button != null, "%s compact option exists" % locale)
if button == null:
continue
for index in range(prefixes.size()):
var label := button.find_child("RiskOptionFact%d" % index, true, false) as Label
expect(label != null, "%s compact fact row %d exists" % [locale, index])
if label == null:
continue
expect(label.text.begins_with(String(prefixes[index])), "%s compact fact row %d uses short semantic label" % [locale, index])
expect(label.text.length() <= (18 if locale == "zh_CN" else 28), "%s compact fact row %d stays concise: %s" % [locale, index, label.text])
func _cleanup() -> void:
for path in [DRAFT_PATH, "%s.bak" % DRAFT_PATH, "%s.candidate" % DRAFT_PATH, "%s.bak.candidate" % DRAFT_PATH, COMPANY_PATH, "%s.bak" % COMPANY_PATH, "%s.candidate" % COMPANY_PATH, "%s.bak.candidate" % COMPANY_PATH, "%s.corrupt" % COMPANY_PATH]:
if FileAccess.file_exists(path):
DirAccess.remove_absolute(path)
func expect(condition: bool, message: String) -> void:
if not condition:
failures.append("DEV-4 Risk: %s" % message)