208 lines
9.9 KiB
GDScript
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)
|