Implement the Right button on the bedroom remote

This commit is contained in:
Sven van Heugten 2026-02-27 19:09:13 +01:00
parent b9fc8bfaea
commit d3a00b8a77
5 changed files with 74 additions and 64 deletions

View file

@ -82,55 +82,59 @@ type NightLightTests() =
|> Prop.trivial (fakeHome.LightsThatAreOn.Length = 0)
[<Property(Arbitrary = [| typeof<ArbitraryInteractions> |])>]
let ``All non-remotely controlled lights with power should be on`` (interactions: Interaction list) =
let ``All lights with power should have the correct state`` (interactions: Interaction list) =
let fakeHome = createFakeHomeWithNightLightAndInteract interactions
let nonRemotelyControlledLightsWithPower =
fakeHome.NonRemotelyControlledLightStates
let lightsWithPower =
fakeHome.LightStates
|> Seq.filter (fun (light, _) -> doesLightHavePowerAfterInteractions light interactions)
|> Seq.toList
nonRemotelyControlledLightsWithPower
|> Seq.forall (snd >> _.IsOn)
|> Prop.collect $"{nonRemotelyControlledLightsWithPower.Length} non-remotely controlled light(s) with power"
let lastBedroomRemoteInteraction =
interactions
|> Seq.indexed
|> Seq.choose (fun (index, interaction) ->
match interaction with
| Interaction.RemoteInteraction remoteInteraction ->
match remoteInteraction with
| RemotePressedOnButton
| RemotePressedOffButton
| RemotePressedLeftButton -> Some(index, remoteInteraction)
| RemotePressedRightButton -> None
| _ -> None)
|> Seq.tryLast
let newDayStartedSinceBedroomRemote =
hasNewDayStartedSince interactions lastBedroomRemoteInteraction
let hasPressedRight =
interactions
|> Seq.exists (function
| Interaction.RemoteInteraction RemotePressedRightButton -> true
| _ -> false)
let isExpectedOn light =
match light with
| LeftBedroomLamp
| RightBedroomLamp ->
if newDayStartedSinceBedroomRemote then
true
else
match lastBedroomRemoteInteraction with
| Some(_, RemotePressedOffButton) -> false
| Some(_, RemotePressedLeftButton) -> light = LeftBedroomLamp
| Some(_, RemotePressedOnButton) -> true
| Some(_, RemotePressedRightButton) -> failwith "unexpected"
| None -> true
| LivingRoomWallLamp
| LivingRoomFloorLamp -> not hasPressedRight
| BathroomCeilingLamp -> true
lightsWithPower
|> Seq.forall (fun (light, state) -> state.IsOn = isExpectedOn light)
|> Prop.collect $"last bedroom remote interaction is {lastBedroomRemoteInteraction |> Option.map snd}"
|> Prop.collect $"pressed right: {hasPressedRight}"
|> Prop.collect $"{lightsWithPower.Length} light(s) with power"
|> Prop.classify newDayStartedSinceBedroomRemote "new day since bedroom remote"
|> Prop.label fakeHome.Label
|> Prop.trivial (nonRemotelyControlledLightsWithPower.Length = 0)
[<Property(Arbitrary = [| typeof<ArbitraryInteractions> |])>]
let ``All remotely-controlled lights with power should have the correct state`` (interactions: Interaction list) =
let fakeHome = createFakeHomeWithNightLightAndInteract interactions
let remotelyControlledLightsWithPower =
fakeHome.RemotelyControlledLightStates
|> Seq.filter (fun (light, _) -> doesLightHavePowerAfterInteractions light interactions)
|> Seq.toList
let allOn (ls: (Light * LightState) seq) = ls |> Seq.forall (snd >> _.IsOn)
let allOff (ls: (Light * LightState) seq) = ls |> Seq.forall (snd >> _.IsOff)
let controlledByLeft ls =
ls |> Seq.filter (fun (light, _) -> light = LeftBedroomLamp)
let controlledByRight ls =
ls |> Seq.filter (fun (light, _) -> light = RightBedroomLamp)
let maybeLastRemoteInteraction = tryGetLastRemoteInteraction interactions
let hasNewDayStartedSinceThen =
hasNewDayStartedSince interactions maybeLastRemoteInteraction
if hasNewDayStartedSinceThen then
remotelyControlledLightsWithPower |> allOn
else
match maybeLastRemoteInteraction with
| Some(_, RemotePressedOnButton) -> remotelyControlledLightsWithPower |> allOn
| Some(_, RemotePressedOffButton) -> remotelyControlledLightsWithPower |> allOff
| Some(_, RemotePressedLeftButton) ->
remotelyControlledLightsWithPower |> controlledByLeft |> allOn
&& remotelyControlledLightsWithPower |> controlledByRight |> allOff
| None -> remotelyControlledLightsWithPower |> allOn
|> Prop.collect $"last remote interaction is {maybeLastRemoteInteraction |> Option.map snd}"
|> Prop.collect $"{remotelyControlledLightsWithPower.Length} remotely controlled light(s) with power"
|> Prop.classify hasNewDayStartedSinceThen "new day has started since then"
|> Prop.label fakeHome.Label
|> Prop.trivial (remotelyControlledLightsWithPower.Length = 0)
|> Prop.trivial (lightsWithPower.Length = 0)