191 lines
4.6 KiB
TypeScript
191 lines
4.6 KiB
TypeScript
import assert from 'node:assert/strict'
|
|
import test from 'node:test'
|
|
|
|
import {
|
|
effectiveInstallProgress,
|
|
effectiveParallelProgress,
|
|
hasDeterminateInstallProgress,
|
|
installProgressFraction,
|
|
installProgressTextSource,
|
|
} from './install-progress.ts'
|
|
|
|
function progressJob(overrides: Record<string, unknown> = {}) {
|
|
return {
|
|
status: 'running',
|
|
phase: 'resolving_loader',
|
|
progress: null,
|
|
details: { type: 'empty' },
|
|
summary: {
|
|
files_completed: 0,
|
|
files_total: null,
|
|
bytes_downloaded: 0,
|
|
bytes_total: null,
|
|
},
|
|
...overrides,
|
|
}
|
|
}
|
|
|
|
test('clears completed content progress when the next phase has no progress', () => {
|
|
const completed = {
|
|
phase: 'downloading_content',
|
|
progress: { current: 10, total: 10 },
|
|
}
|
|
assert.equal(installProgressFraction(completed), 1)
|
|
|
|
const nextPhase = {
|
|
phase: 'downloading_minecraft',
|
|
progress: null,
|
|
}
|
|
assert.equal(effectiveInstallProgress(nextPhase), null)
|
|
assert.equal(installProgressFraction(nextPhase), null)
|
|
})
|
|
|
|
test('parallel track exposes its own progress', () => {
|
|
const job = {
|
|
phase: 'downloading_content',
|
|
progress: { current: 2, total: 3, secondary: { current: 220, total: 300 } },
|
|
parallel: {
|
|
phase: 'downloading_minecraft',
|
|
current: 120,
|
|
total: 300,
|
|
},
|
|
}
|
|
assert.deepEqual(effectiveInstallProgress(job), { current: 220, total: 300 })
|
|
assert.deepEqual(effectiveParallelProgress(job), { current: 120, total: 300 })
|
|
assert.equal(installProgressFraction(job), 220 / 300)
|
|
|
|
assert.equal(effectiveParallelProgress({ phase: 'downloading_minecraft', progress: null }), null)
|
|
})
|
|
|
|
test('treats zero and non-finite totals as indeterminate', () => {
|
|
for (const total of [0, Number.NaN, Number.POSITIVE_INFINITY]) {
|
|
const progress = { current: 1, total }
|
|
assert.equal(hasDeterminateInstallProgress(progress), false)
|
|
assert.equal(installProgressFraction({ phase: 'downloading_minecraft', progress }), null)
|
|
}
|
|
})
|
|
|
|
test('non-download phase ignores historical byte and file summary', () => {
|
|
const source = installProgressTextSource(
|
|
progressJob({
|
|
phase: 'resolving_loader',
|
|
summary: {
|
|
files_completed: 186,
|
|
files_total: 187,
|
|
bytes_downloaded: 268,
|
|
bytes_total: 18,
|
|
},
|
|
}),
|
|
)
|
|
|
|
assert.deepEqual(source, { type: 'phase' })
|
|
assert.doesNotMatch(JSON.stringify(source), /268|18 MiB/)
|
|
})
|
|
|
|
test('non-download phase ignores historical file counter', () => {
|
|
assert.deepEqual(
|
|
installProgressTextSource(
|
|
progressJob({
|
|
phase: 'resolving_loader',
|
|
summary: {
|
|
files_completed: 186,
|
|
files_total: 187,
|
|
bytes_downloaded: 0,
|
|
bytes_total: null,
|
|
},
|
|
}),
|
|
),
|
|
{ type: 'phase' },
|
|
)
|
|
})
|
|
|
|
test('pack download uses current progress instead of stale summary', () => {
|
|
assert.deepEqual(
|
|
installProgressTextSource(
|
|
progressJob({
|
|
phase: 'downloading_pack_file',
|
|
progress: { current: 0, total: 51 },
|
|
summary: {
|
|
files_completed: 0,
|
|
files_total: null,
|
|
bytes_downloaded: 268,
|
|
bytes_total: 300,
|
|
},
|
|
}),
|
|
),
|
|
{ type: 'bytes', current: 0, total: 51 },
|
|
)
|
|
})
|
|
|
|
test('minecraft download uses current progress instead of content summary', () => {
|
|
assert.deepEqual(
|
|
installProgressTextSource(
|
|
progressJob({
|
|
phase: 'downloading_minecraft',
|
|
progress: { current: 0, total: 18 },
|
|
summary: {
|
|
files_completed: 187,
|
|
files_total: 187,
|
|
bytes_downloaded: 268,
|
|
bytes_total: 300,
|
|
},
|
|
}),
|
|
),
|
|
{ type: 'bytes', current: 0, total: 18 },
|
|
)
|
|
})
|
|
|
|
test('content download uses current secondary bytes', () => {
|
|
assert.deepEqual(
|
|
installProgressTextSource(
|
|
progressJob({
|
|
phase: 'downloading_content',
|
|
progress: {
|
|
current: 2,
|
|
total: 3,
|
|
secondary: { current: 220, total: 300 },
|
|
},
|
|
}),
|
|
),
|
|
{ type: 'bytes', current: 220, total: 300 },
|
|
)
|
|
})
|
|
|
|
test('content download without secondary uses current file counter', () => {
|
|
assert.deepEqual(
|
|
installProgressTextSource(
|
|
progressJob({
|
|
phase: 'downloading_content',
|
|
progress: { current: 2, total: 3 },
|
|
}),
|
|
),
|
|
{ type: 'items', current: 2, total: 3 },
|
|
)
|
|
})
|
|
|
|
test('Java downloading uses current byte progress', () => {
|
|
assert.deepEqual(
|
|
installProgressTextSource(
|
|
progressJob({
|
|
phase: 'preparing_java',
|
|
progress: { current: 4, total: 12 },
|
|
details: { type: 'java', major_version: 21, step: 'downloading' },
|
|
}),
|
|
),
|
|
{ type: 'bytes', current: 4, total: 12 },
|
|
)
|
|
})
|
|
|
|
test('waiting job preserves required-file progress policy', () => {
|
|
assert.deepEqual(
|
|
installProgressTextSource(
|
|
progressJob({
|
|
status: 'waiting_for_user',
|
|
phase: 'downloading_content',
|
|
progress: { current: 2, total: 3 },
|
|
}),
|
|
),
|
|
{ type: 'required_files' },
|
|
)
|
|
})
|