69 lines
2.9 KiB
Swift
69 lines
2.9 KiB
Swift
import Foundation
|
|
import Testing
|
|
import RemoteCore
|
|
@testable import GestureCore
|
|
|
|
@Test func directionsRequireArmingAndNeutralThenEmitOnce() {
|
|
let samples: [(Double, Double, RemoteCommand)] = [(0.9, 0, .right), (-0.9, 0, .left), (0, 0.9, .up), (0, -0.9, .down)]
|
|
for (x, y, command) in samples {
|
|
var gate = DirectionalGestureGate()
|
|
#expect(gate.process(x: x, y: y, at: 0) == nil)
|
|
let session = UUID()
|
|
gate.arm(sessionID: session, at: 0)
|
|
#expect(gate.process(x: x, y: y, at: 0.1) == nil)
|
|
#expect(gate.process(x: 0, y: 0, at: 0.2) == nil)
|
|
let intent = gate.process(x: x, y: y, at: 0.3)
|
|
#expect(intent?.command == command)
|
|
#expect(intent?.sessionID == session)
|
|
#expect(gate.process(x: x, y: y, at: 1) == nil)
|
|
#expect(gate.process(x: -x, y: -y, at: 2) == nil)
|
|
}
|
|
}
|
|
|
|
@Test func hysteresisAndDebounceConsumeSuppressedExcursion() {
|
|
var gate = DirectionalGestureGate()
|
|
gate.arm(sessionID: UUID(), at: 0)
|
|
#expect(gate.process(x: 0, y: 0, at: 0.1) == nil)
|
|
#expect(gate.process(x: 0.9, y: 0, at: 0.2)?.command == .right)
|
|
#expect(gate.process(x: 0.4, y: 0, at: 0.3) == nil)
|
|
#expect(gate.process(x: 0.9, y: 0, at: 0.35) == nil)
|
|
#expect(gate.process(x: 0, y: 0, at: 0.4) == nil)
|
|
#expect(gate.process(x: -0.9, y: 0, at: 0.45) == nil)
|
|
#expect(gate.process(x: -0.9, y: 0, at: 1) == nil)
|
|
#expect(gate.process(x: 0, y: 0, at: 1.1) == nil)
|
|
#expect(gate.process(x: -0.9, y: 0, at: 1.2)?.command == .left)
|
|
}
|
|
|
|
@Test func ambiguityInvalidInputAndOutOfOrderSamplesAreSuppressed() {
|
|
var gate = DirectionalGestureGate()
|
|
gate.arm(sessionID: UUID(), at: 0)
|
|
#expect(gate.process(x: 0, y: 0, at: 0.1) == nil)
|
|
#expect(gate.process(x: 0.9, y: 0.9, at: 0.2) == nil)
|
|
#expect(gate.process(x: 0.9, y: 0, at: 0.3) == nil)
|
|
#expect(gate.process(x: 0, y: 0, at: 0.4) == nil)
|
|
#expect(gate.process(x: .nan, y: 0, at: 0.5) == nil)
|
|
#expect(gate.process(x: 0.9, y: 0, at: 0.6) == nil)
|
|
#expect(gate.process(x: 0, y: 0, at: 1) == nil)
|
|
#expect(gate.process(x: 0.9, y: 0, at: 0.9) == nil)
|
|
#expect(gate.process(x: 0.9, y: 0, at: 1.1)?.command == .right)
|
|
}
|
|
|
|
@Test func timeoutAndDisarmPreventActionsAndRearmingRequiresNeutral() {
|
|
var gate = DirectionalGestureGate()
|
|
gate.arm(sessionID: UUID(), at: 0)
|
|
#expect(gate.process(x: 0, y: 0, at: 1) == nil)
|
|
#expect(gate.process(x: 0.9, y: 0, at: 10) == nil)
|
|
#expect(gate.sessionID == nil)
|
|
gate.arm(sessionID: UUID(), at: 20)
|
|
#expect(gate.process(x: 0.9, y: 0, at: 20.1) == nil)
|
|
#expect(gate.process(x: 0, y: 0, at: 20.2) == nil)
|
|
gate.disarm()
|
|
#expect(gate.process(x: 0.9, y: 0, at: 20.3) == nil)
|
|
}
|
|
|
|
@Test func rejectsInvalidConfiguration() {
|
|
#expect(throws: GestureConfiguration.ConfigurationError.self) {
|
|
try GestureConfiguration(activationThreshold: 0.2, neutralThreshold: 0.3, minimumInterval: 0.3, maximumArmedDuration: 10, axisDominanceRatio: 0.6)
|
|
}
|
|
}
|