Integrate live phone and watch remote prototype with guarded motion control
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
import Foundation
|
||||
import Testing
|
||||
import RemoteCore
|
||||
@testable import GestureCore
|
||||
|
||||
private func sample(_ t: Double, _ x: Double = 0, _ y: Double = 0, _ q: Double = 1) -> NormalizedMotionSample {
|
||||
NormalizedMotionSample(timestamp: t, x: x, y: y, quality: q)
|
||||
}
|
||||
|
||||
@Test func requiresStableNeutralAndEmitsOneDirectionalEvent() {
|
||||
var configuration = GestureRecognitionConfiguration(); configuration.maximumSampleGap = 0.3
|
||||
var recognizer = CalibratedGestureRecognizer(configuration: configuration)
|
||||
let id = UUID(); recognizer.arm(sessionID: id, at: 0)
|
||||
#expect(recognizer.process(sample(0)) == nil)
|
||||
#expect(recognizer.process(sample(0.21)) == nil)
|
||||
#expect(recognizer.process(sample(0.30, 0.65, 0)) == nil)
|
||||
#expect(recognizer.process(sample(0.41, 0.8, 0)) == nil)
|
||||
let result = recognizer.process(sample(0.50, 0.9, 0))
|
||||
#expect(result?.command == .right)
|
||||
#expect(result?.sessionID == id)
|
||||
#expect(recognizer.process(sample(0.55, 0.9, 0)) == nil)
|
||||
}
|
||||
|
||||
@Test func diagonalLowConfidenceGapAndOutOfOrderAreRejected() {
|
||||
var recognizer = CalibratedGestureRecognizer()
|
||||
recognizer.arm(sessionID: UUID(), at: 0)
|
||||
_ = recognizer.process(sample(0)); _ = recognizer.process(sample(0.21))
|
||||
_ = recognizer.process(sample(0.35, 0.8, 0.75))
|
||||
#expect(recognizer.process(sample(0.50, 0.8, 0.75)) == nil) // ambiguous
|
||||
#expect(recognizer.process(sample(0.49, 0.9, 0)) == nil) // stale
|
||||
_ = recognizer.process(sample(0.70))
|
||||
#expect(recognizer.process(sample(0.90, 0.9, 0, 0.2)) == nil)
|
||||
}
|
||||
|
||||
@Test func cooldownAndReturnToNeutralSuppressReverseMotion() {
|
||||
var configuration = GestureRecognitionConfiguration(); configuration.maximumSampleGap = 0.3
|
||||
var recognizer = CalibratedGestureRecognizer(configuration: configuration)
|
||||
recognizer.arm(sessionID: UUID(), at: 0)
|
||||
_ = recognizer.process(sample(0)); _ = recognizer.process(sample(0.21))
|
||||
#expect(recognizer.process(sample(0.30, 0.9, 0)) == nil)
|
||||
#expect(recognizer.process(sample(0.41, 0.9, 0)) == nil)
|
||||
#expect(recognizer.process(sample(0.50, 0.9, 0))?.command == .right)
|
||||
_ = recognizer.process(sample(0.60)); _ = recognizer.process(sample(0.70)); _ = recognizer.process(sample(0.80))
|
||||
_ = recognizer.process(sample(0.90)); _ = recognizer.process(sample(0.95))
|
||||
#expect(recognizer.process(sample(1.05, -0.9, 0)) == nil)
|
||||
#expect(recognizer.process(sample(1.15, -0.9, 0)) == nil)
|
||||
#expect(recognizer.process(sample(1.25, -0.9, 0))?.command == .left)
|
||||
}
|
||||
|
||||
@Test func disarmClearsSessionAndNoReplayAfterRearm() {
|
||||
var recognizer = CalibratedGestureRecognizer()
|
||||
recognizer.arm(sessionID: UUID(), at: 0); _ = recognizer.process(sample(0)); _ = recognizer.process(sample(0.21))
|
||||
recognizer.disarm()
|
||||
#expect(recognizer.process(sample(1, 0.9, 0)) == nil)
|
||||
recognizer.arm(sessionID: UUID(), at: 2)
|
||||
#expect(recognizer.process(sample(2.1, 0.9, 0)) == nil)
|
||||
}
|
||||
|
||||
@Test func invalidSampleDiscardsCandidateUntilFreshNeutral() {
|
||||
var recognizer = CalibratedGestureRecognizer()
|
||||
recognizer.arm(sessionID: UUID(), at: 0)
|
||||
for index in 0...20 {
|
||||
_ = recognizer.process(.init(timestamp: Double(index) / 50, x: 0, y: 0))
|
||||
}
|
||||
_ = recognizer.process(.init(timestamp: 0.42, x: 0.8, y: 0))
|
||||
_ = recognizer.process(.init(timestamp: 0.44, x: .nan, y: 0))
|
||||
for index in 23...40 {
|
||||
#expect(recognizer.process(.init(timestamp: Double(index) / 50, x: 0.8, y: 0)) == nil)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user