Files
suixinkan_uikit/suixinkanTests/QRCodeCaptureSessionControllerTests.swift
lujiuyin 3823d10423 fix: 修复扫码相机竞态并调整金额与浅色外观
串行处理相机配置及启停,补充四项生命周期回归测试。快捷金额去除多余小数,固定浅色模式,版本更新至 2.1.1(2010101)。
2026-09-18 09:37:00 +08:00

106 lines
3.7 KiB
Swift

import XCTest
@testable import suixinkan
/// 回归验证相机配置期间启动、快速关闭和重复启动的顺序。
final class QRCodeCaptureSessionControllerTests: XCTestCase {
func testStartWaitsForConfigurationCommit() {
let session = RecordingCaptureSession()
let queue = DispatchQueue(label: "qr-capture-test")
let controller = QRCodeCaptureSessionController(session: session, queue: queue)
let entered = DispatchSemaphore(value: 0)
let release = DispatchSemaphore(value: 0)
let completed = expectation(description: "configuration committed")
controller.configure({
entered.signal()
_ = release.wait(timeout: .now() + 5)
return true
}, completion: { succeeded in
XCTAssertTrue(Thread.isMainThread)
XCTAssertTrue(succeeded)
completed.fulfill()
})
XCTAssertEqual(entered.wait(timeout: .now() + 5), .success)
controller.setRunning(true)
release.signal()
queue.sync {
XCTAssertEqual(session.events, ["begin", "commit", "start"])
XCTAssertFalse(session.startedDuringConfiguration)
}
wait(for: [completed], timeout: 5)
}
func testImmediateCloseStopsPendingStart() {
let session = RecordingCaptureSession()
let queue = DispatchQueue(label: "qr-capture-test")
let controller = QRCodeCaptureSessionController(session: session, queue: queue)
controller.configure({ true }, completion: { _ in })
controller.setRunning(true)
controller.setRunning(false)
queue.sync {
XCTAssertEqual(session.events, ["begin", "commit", "start", "stop"])
XCTAssertFalse(session.isRunning)
}
}
func testRepeatedStartAndStopAreIdempotent() {
let session = RecordingCaptureSession()
let queue = DispatchQueue(label: "qr-capture-test")
let controller = QRCodeCaptureSessionController(session: session, queue: queue)
controller.configure({ true }, completion: { _ in })
controller.setRunning(true)
controller.setRunning(true)
controller.setRunning(false)
controller.setRunning(false)
queue.sync {
XCTAssertEqual(session.events, ["begin", "commit", "start", "stop"])
}
}
func testFailedConfigurationCommitsButDoesNotStart() {
let session = RecordingCaptureSession()
let queue = DispatchQueue(label: "qr-capture-test")
let controller = QRCodeCaptureSessionController(session: session, queue: queue)
let completed = expectation(description: "configuration failed")
controller.configure({ false }, completion: { succeeded in
XCTAssertFalse(succeeded)
completed.fulfill()
})
controller.setRunning(true)
queue.sync {
XCTAssertEqual(session.events, ["begin", "commit"])
XCTAssertFalse(session.isRunning)
}
wait(for: [completed], timeout: 5)
}
}
/// 记录调用顺序并检测配置事务内启动的会话替身,仅在测试串行队列读写。
private final class RecordingCaptureSession: QRCodeCaptureSession {
var isRunning = false
var events: [String] = []
var startedDuringConfiguration = false
private var configuring = false
func beginConfiguration() {
configuring = true
events.append("begin")
}
func commitConfiguration() {
configuring = false
events.append("commit")
}
func startRunning() {
startedDuringConfiguration = configuring
isRunning = true
events.append("start")
}
func stopRunning() {
isRunning = false
events.append("stop")
}
}