fix: 修复扫码相机竞态并调整金额与浅色外观
串行处理相机配置及启停,补充四项生命周期回归测试。快捷金额去除多余小数,固定浅色模式,版本更新至 2.1.1(2010101)。
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
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")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user