| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- import Foundation
- import Testing
- @testable import Trio
- @Suite("Trio Alerts: GlucoseAlert") struct GlucoseAlertTests {
- // MARK: - Group A: shouldEvaluate
- @Test("urgentLow evaluates even when isEnabled is false") func urgentLowDisabledStillEvaluates() {
- var a = GlucoseAlert(type: .urgentLow)
- a.isEnabled = false
- #expect(a.shouldEvaluate == true)
- }
- @Test("urgentLow evaluates when isEnabled is true") func urgentLowEnabledEvaluates() {
- var a = GlucoseAlert(type: .urgentLow)
- a.isEnabled = true
- #expect(a.shouldEvaluate == true)
- }
- @Test("low does not evaluate when disabled") func lowDisabledDoesNotEvaluate() {
- var a = GlucoseAlert(type: .low)
- a.isEnabled = false
- #expect(a.shouldEvaluate == false)
- }
- @Test("low evaluates when enabled") func lowEnabledEvaluates() {
- var a = GlucoseAlert(type: .low)
- a.isEnabled = true
- #expect(a.shouldEvaluate == true)
- }
- @Test("high does not evaluate when disabled") func highDisabledDoesNotEvaluate() {
- var a = GlucoseAlert(type: .high)
- a.isEnabled = false
- #expect(a.shouldEvaluate == false)
- }
- @Test("high evaluates when enabled") func highEnabledEvaluates() {
- var a = GlucoseAlert(type: .high)
- a.isEnabled = true
- #expect(a.shouldEvaluate == true)
- }
- @Test("forecastedLow does not evaluate when disabled") func forecastedLowDisabledDoesNotEvaluate() {
- var a = GlucoseAlert(type: .forecastedLow)
- a.isEnabled = false
- #expect(a.shouldEvaluate == false)
- }
- @Test("forecastedLow evaluates when enabled") func forecastedLowEnabledEvaluates() {
- var a = GlucoseAlert(type: .forecastedLow)
- a.isEnabled = true
- #expect(a.shouldEvaluate == true)
- }
- @Test("carbsRequired does not evaluate when disabled") func carbsRequiredDisabledDoesNotEvaluate() {
- var a = GlucoseAlert(type: .carbsRequired)
- a.isEnabled = false
- #expect(a.shouldEvaluate == false)
- }
- @Test("carbsRequired evaluates when enabled") func carbsRequiredEnabledEvaluates() {
- var a = GlucoseAlert(type: .carbsRequired)
- a.isEnabled = true
- #expect(a.shouldEvaluate == true)
- }
- // MARK: - Group A.5: type metadata
- @Test("carbsRequired defaults: threshold 10 g, bloop.caf, no override") func carbsRequiredDefaults() {
- let a = GlucoseAlert(type: .carbsRequired)
- #expect(a.thresholdMgDL == 10)
- #expect(a.soundFilename == "bloop.caf")
- #expect(a.overridesSilenceAndDND == false)
- }
- @Test("isReadingDriven: true for low family + high, false for forecast + carbs") func isReadingDriven() {
- #expect(GlucoseAlertType.urgentLow.isReadingDriven)
- #expect(GlucoseAlertType.low.isReadingDriven)
- #expect(GlucoseAlertType.high.isReadingDriven)
- #expect(!GlucoseAlertType.forecastedLow.isReadingDriven)
- #expect(!GlucoseAlertType.carbsRequired.isReadingDriven)
- }
- // MARK: - Group B: decoder defaults
- @Test("Omitted isEnabled defaults to true") func decodeOmittedIsEnabledDefaultsTrue() throws {
- let json = """
- {
- "id": "11111111-1111-1111-1111-111111111111",
- "type": "low",
- "name": "Low Glucose",
- "thresholdMgDL": 72
- }
- """
- let decoded = try JSONDecoder().decode(GlucoseAlert.self, from: Data(json.utf8))
- #expect(decoded.isEnabled == true)
- }
- @Test("urgentLow with isEnabled false decodes false but still evaluates") func decodeUrgentLowDisabledStillEvaluates() throws {
- let json = """
- {
- "id": "22222222-2222-2222-2222-222222222222",
- "type": "urgentLow",
- "name": "Urgent Low Glucose",
- "isEnabled": false,
- "thresholdMgDL": 54
- }
- """
- let decoded = try JSONDecoder().decode(GlucoseAlert.self, from: Data(json.utf8))
- #expect(decoded.isEnabled == false)
- #expect(decoded.shouldEvaluate == true)
- }
- @Test("high with optional fields omitted uses type defaults") func decodeHighDefaults() throws {
- let json = """
- {
- "id": "33333333-3333-3333-3333-333333333333",
- "type": "high",
- "name": "High Glucose",
- "thresholdMgDL": 270
- }
- """
- let decoded = try JSONDecoder().decode(GlucoseAlert.self, from: Data(json.utf8))
- #expect(decoded.soundFilename == GlucoseAlertType.high.defaultSoundFilename)
- #expect(decoded.playsSound == true)
- #expect(decoded.overridesSilenceAndDND == false)
- #expect(decoded.activeOption == .always)
- #expect(decoded.snoozedUntil == nil)
- #expect(decoded.isEnabled == true)
- }
- @Test("urgentLow with overridesSilenceAndDND omitted uses type defaults") func decodeUrgentLowOverrideDefault() throws {
- let json = """
- {
- "id": "44444444-4444-4444-4444-444444444444",
- "type": "urgentLow",
- "name": "Urgent Low Glucose",
- "thresholdMgDL": 54
- }
- """
- let decoded = try JSONDecoder().decode(GlucoseAlert.self, from: Data(json.utf8))
- #expect(decoded.overridesSilenceAndDND == true)
- #expect(decoded.soundFilename == GlucoseAlertType.urgentLow.defaultSoundFilename)
- }
- // MARK: - Group C: round-trip
- @Test("Fully-populated value survives encode/decode round-trip") func roundTrip() throws {
- var original = GlucoseAlert(type: .low)
- original.name = "Custom Low Alarm"
- original.isEnabled = false
- original.thresholdMgDL = 65
- original.soundFilename = "custom_sound.caf"
- original.playsSound = false
- original.overridesSilenceAndDND = true
- original.activeOption = .night
- original.snoozedUntil = Date(timeIntervalSinceReferenceDate: 1_000_000)
- let data = try JSONEncoder().encode(original)
- let decoded = try JSONDecoder().decode(GlucoseAlert.self, from: data)
- #expect(decoded == original)
- }
- }
|