156 lines
6.6 KiB
QML
156 lines
6.6 KiB
QML
import QtQuick
|
||
import QtTest
|
||
import BiLauncher
|
||
|
||
// Маленькие переиспользуемые компоненты: DarkCombo, LabelledField,
|
||
// ProgressPanel, LoaderRow.
|
||
TestCase {
|
||
id: testCase
|
||
name: "Components"
|
||
width: 600
|
||
height: 400
|
||
visible: true
|
||
when: windowShown
|
||
|
||
Component { id: comboComponent; DarkCombo { width: 200; height: 32 } }
|
||
Component { id: fieldComponent; LabelledField { width: 220 } }
|
||
Component { id: panelComponent; ProgressPanel {} }
|
||
Component { id: loaderRowComponent; LoaderRow { width: 300 } }
|
||
|
||
// Подставной backend для LoaderRow: те же методы и сигнал, что у LauncherBackend.
|
||
Component {
|
||
id: fakeBackendComponent
|
||
QtObject {
|
||
property var versions: ({})
|
||
property bool loading: false
|
||
property var refreshCalls: []
|
||
signal loaderVersionsChanged(string loaderKey, string gameVersion)
|
||
|
||
function loaderVersions(key, game) { return versions[key + "/" + game] || [] }
|
||
function refreshLoaderVersions(key, game) { refreshCalls.push(key + "/" + game) }
|
||
function loaderVersionsLoading(key, game) { return loading }
|
||
}
|
||
}
|
||
|
||
// --- DarkCombo -------------------------------------------------------------
|
||
|
||
function test_comboSelectsAndDisplays() {
|
||
const combo = createTemporaryObject(comboComponent, testCase, { model: ["Alpha", "Beta", "Gamma"] })
|
||
verify(combo)
|
||
compare(combo.count, 3)
|
||
compare(combo.displayText, "Alpha")
|
||
const activated = signalSpy.createObject(testCase, { target: combo, signalName: "activated" })
|
||
|
||
mouseClick(combo)
|
||
tryVerify(() => combo.popup.opened)
|
||
combo.currentIndex = 2
|
||
compare(combo.displayText, "Gamma")
|
||
combo.popup.close()
|
||
tryVerify(() => !combo.popup.visible)
|
||
|
||
// Клавиатура: стрелки меняют выбор и шлют activated.
|
||
combo.forceActiveFocus()
|
||
keyClick(Qt.Key_Up)
|
||
compare(combo.currentIndex, 1)
|
||
compare(activated.count, 1)
|
||
verify(combo.indicator.source.toString().length > 0)
|
||
}
|
||
|
||
// --- LabelledField -------------------------------------------------------
|
||
|
||
function test_labelledFieldAliasesAndSignal() {
|
||
const field = createTemporaryObject(fieldComponent, testCase, { label: "Ник", placeholder: "Steve" })
|
||
verify(field)
|
||
compare(field.children[0].text, "Ник")
|
||
const input = field.children[1]
|
||
compare(input.placeholderText, "Steve")
|
||
|
||
const finished = signalSpy.createObject(testCase, { target: field, signalName: "editingFinished" })
|
||
input.forceActiveFocus()
|
||
keyClick(Qt.Key_A)
|
||
keyClick(Qt.Key_B)
|
||
compare(field.text, "ab")
|
||
keyClick(Qt.Key_Return)
|
||
compare(finished.count, 1)
|
||
|
||
field.text = "preset"
|
||
compare(input.text, "preset")
|
||
}
|
||
|
||
// --- ProgressPanel -------------------------------------------------------
|
||
|
||
function test_progressPanelPercentAndCancel() {
|
||
const panel = createTemporaryObject(panelComponent, testCase,
|
||
{ title: "1.20.1", status: "Libraries", fraction: -1 })
|
||
verify(panel)
|
||
const texts = panel.children.filter(c => c.text !== undefined)
|
||
const percent = texts.find(t => t.text === "…")
|
||
verify(percent, "без известного итога показывается многоточие")
|
||
|
||
panel.fraction = 0.426
|
||
compare(percent.text, "43%")
|
||
panel.fraction = 1
|
||
compare(percent.text, "100%")
|
||
|
||
// Подпись: detail важнее status.
|
||
const detailText = texts.find(t => t.text === "Libraries")
|
||
verify(detailText)
|
||
panel.detail = "brigadier-1.1.8.jar"
|
||
compare(detailText.text, "brigadier-1.1.8.jar")
|
||
|
||
const cancel = signalSpy.createObject(testCase, { target: panel, signalName: "cancelRequested" })
|
||
mouseClick(panel, panel.width - 14, panel.height - 12)
|
||
compare(cancel.count, 1)
|
||
|
||
panel.cancellable = false
|
||
mouseClick(panel, panel.width - 14, panel.height - 12)
|
||
compare(cancel.count, 1, "крестик скрыт — отмены нет")
|
||
}
|
||
|
||
// --- LoaderRow -----------------------------------------------------------
|
||
|
||
function test_loaderRowFollowsBackend() {
|
||
const backend = createTemporaryObject(fakeBackendComponent, testCase)
|
||
backend.versions = {
|
||
"fabric/1.20.1": [ { version: "0.16.10", label: "0.16.10", recommended: false, stable: true },
|
||
{ version: "0.16.9", label: "0.16.9", recommended: false, stable: true } ]
|
||
}
|
||
const row = createTemporaryObject(loaderRowComponent, testCase,
|
||
{ backend: backend, loaderKey: "fabric", title: "Fabric Loader" })
|
||
verify(row)
|
||
const changed = signalSpy.createObject(testCase, { target: row, signalName: "changed" })
|
||
|
||
// Без версии игры галочка недоступна, список пуст.
|
||
compare(row.entries.length, 0)
|
||
row.gameVersion = "1.20.1"
|
||
compare(row.entries.length, 0, "пока галочка снята — версии не запрашиваются")
|
||
|
||
// Сборка уже с Fabric: выбранная версия сохраняется, запрос обновления уходит.
|
||
row.applyBuild("fabric", "0.16.9")
|
||
verify(row.checked)
|
||
compare(row.selectedVersion, "0.16.9")
|
||
compare(row.entries.length, 2)
|
||
verify(backend.refreshCalls.indexOf("fabric/1.20.1") >= 0)
|
||
compare(changed.count, 0, "применение сохранённой сборки не считается правкой")
|
||
|
||
// Каталог обновился и выбранной версии в нём больше нет — берётся первая.
|
||
backend.versions = { "fabric/1.20.1": [ { version: "0.17.0", label: "0.17.0", recommended: true, stable: true } ] }
|
||
backend.loaderVersionsChanged("fabric", "1.20.1")
|
||
compare(row.selectedVersion, "0.17.0")
|
||
compare(changed.count, 1)
|
||
|
||
// Чужой лоадер в сборке — галочка снимается.
|
||
row.applyBuild("forge", "47.4.0")
|
||
verify(!row.checked)
|
||
compare(row.selectedVersion, "")
|
||
compare(row.entries.length, 0)
|
||
|
||
// Смена версии игры сбрасывает выбор.
|
||
row.applyBuild("fabric", "0.17.0")
|
||
row.gameVersion = "1.19.4"
|
||
compare(row.selectedVersion, "")
|
||
}
|
||
|
||
Component { id: signalSpy; SignalSpy {} }
|
||
}
|