From 23d3a7b601eaa67a320e68a99fa1c19a44394d63 Mon Sep 17 00:00:00 2001 From: Sven van Heugten Date: Sun, 18 Jan 2026 07:13:26 +0100 Subject: [PATCH] Test alarm in existing test --- .../InteractionListHelpers.fs | 18 ++++---- NightLight.Core.Tests/NightLightTests.fs | 43 ++++++++++++++----- 2 files changed, 43 insertions(+), 18 deletions(-) diff --git a/NightLight.Core.Tests/InteractionListHelpers.fs b/NightLight.Core.Tests/InteractionListHelpers.fs index bc70c70..4a2a817 100644 --- a/NightLight.Core.Tests/InteractionListHelpers.fs +++ b/NightLight.Core.Tests/InteractionListHelpers.fs @@ -6,23 +6,25 @@ type PartOfDay = | Day | Night -let private getPartOfDay (dateTime: DateTime) = +let startOfDay = TimeSpan.FromHours 6 +let endOfAlarm = TimeSpan.FromHours 6.25 +let endOfDay = TimeSpan.FromHours 20.5 + +let getPartOfDay (dateTime: DateTime) = match dateTime with - | _ when - dateTime.TimeOfDay >= TimeSpan.FromHours 6 - && dateTime.TimeOfDay < TimeSpan.FromHours 20.5 - -> - Day + | _ when dateTime.TimeOfDay >= startOfDay && dateTime.TimeOfDay < endOfDay -> Day | _ -> Night -let getPartOfDayAfterInteractions interactions = +let getTimeAfterInteractions interactions = interactions |> Seq.choose (fun interaction -> match interaction with | Interaction.TimeChanged time -> Some time | _ -> None) |> Seq.last - |> getPartOfDay + +let getPartOfDayAfterInteractions interactions = + interactions |> getTimeAfterInteractions |> getPartOfDay let doesLightHavePowerAfterInteractions light interactions = interactions diff --git a/NightLight.Core.Tests/NightLightTests.fs b/NightLight.Core.Tests/NightLightTests.fs index e7bd636..4bc386f 100644 --- a/NightLight.Core.Tests/NightLightTests.fs +++ b/NightLight.Core.Tests/NightLightTests.fs @@ -41,21 +41,44 @@ type NightLightTests() = |> Prop.label fakeHome.Label |> Prop.trivial (fakeHome.LightsThatAreOn.Length = 0) - [ |])>] + // TODO: Bias generator for alarm cases so that `MaxTest` can be reduced + [ |], MaxTest = 10_000)>] let ``All lights should either be off or have a brightness that fits its color`` (interactions: Interaction list) = let fakeHome = createFakeHomeWithNightLightAndInteract interactions + let time = getTimeAfterInteractions interactions |> _.TimeOfDay + + let alarm = + hasNewDayStartedSince interactions (tryGetLastRemoteInteraction interactions) + && startOfDay <= time + && time <= endOfAlarm + + let scaledForAlarm light brightness = + if light.ControlledWithRemote <> NonRemote && alarm then + float brightness * ((time - startOfDay) / (endOfAlarm - startOfDay)) |> byte + else + brightness fakeHome.LightStates - |> Seq.forall (function - | _, Off - | { Bulb = IkeaBulb }, On(254uy, White) -> true - | { Bulb = IkeaBulb }, On(210uy, Yellow) -> true - | { Bulb = IkeaBulb }, On(254uy, Red) -> true - | { Bulb = PaulmannBulb }, On(35uy, White) -> true - | { Bulb = PaulmannBulb }, On(35uy, Yellow) -> true - | { Bulb = PaulmannBulb }, On(80uy, Red) -> true - | _ -> false) + |> Seq.forall (fun (light, state) -> + let maybeExpectedBrightness = + match light, state with + | _, Off -> None + | { Bulb = IkeaBulb }, On(_, White) -> Some 254uy + | { Bulb = IkeaBulb }, On(_, Yellow) -> Some 210uy + | { Bulb = IkeaBulb }, On(_, Red) -> Some 254uy + | { Bulb = PaulmannBulb }, On(_, White) -> Some 35uy + | { Bulb = PaulmannBulb }, On(_, Yellow) -> Some 35uy + | { Bulb = PaulmannBulb }, On(_, Red) -> Some 80uy + |> Option.map (scaledForAlarm light) + + let maybeActualBrightness = + match state with + | Off -> None + | On(brightness, _) -> Some brightness + + maybeExpectedBrightness = maybeActualBrightness) |> Prop.collect $"{fakeHome.LightsThatAreOn.Length} light(s) on" + |> Prop.classify alarm "alarm" |> Prop.label fakeHome.Label |> Prop.trivial (fakeHome.LightsThatAreOn.Length = 0)