From b53151b4c5ed82f141a599cd11efeb3fa266df44 Mon Sep 17 00:00:00 2001 From: Sven van Heugten Date: Fri, 9 Jan 2026 19:23:19 +0100 Subject: [PATCH] Re-write tests without ==> --- .../InteractionListGenerators.fs | 18 +++++++++ NightLight.Core.Tests/NightLightTests.fs | 40 +++++-------------- 2 files changed, 27 insertions(+), 31 deletions(-) diff --git a/NightLight.Core.Tests/InteractionListGenerators.fs b/NightLight.Core.Tests/InteractionListGenerators.fs index bc5679b..a6c2871 100644 --- a/NightLight.Core.Tests/InteractionListGenerators.fs +++ b/NightLight.Core.Tests/InteractionListGenerators.fs @@ -33,3 +33,21 @@ let ensureStartsWithTimeChanged (genInteractions: Gen) = match interactions with | Interaction.TimeChanged _ :: _ -> Gen.constant interactions | _ -> genTimeChanged |> Gen.map (fun tc -> tc :: interactions)) + +let ensureLightHasPower (light: Light) (genInteractions: Gen) = + genInteractions + |> Gen.map (fun interactions -> + let lightHasPower = + interactions + |> Seq.choose (fun interaction -> + match interaction with + | HumanInteraction(LightPoweredOff l) when l = light -> Some false + | HumanInteraction(LightPoweredOn l) when l = light -> Some true + | _ -> None) + |> Seq.tryLast + |> Option.defaultValue false + + if lightHasPower then + interactions + else + interactions @ [ HumanInteraction(LightPoweredOn light) ]) diff --git a/NightLight.Core.Tests/NightLightTests.fs b/NightLight.Core.Tests/NightLightTests.fs index 302e19f..b3218fe 100644 --- a/NightLight.Core.Tests/NightLightTests.fs +++ b/NightLight.Core.Tests/NightLightTests.fs @@ -25,24 +25,6 @@ type NightLightTests() = fakeHome - let doesLightHavePowerAfter light interactions = - // `FakeHome` intentionally doesn't expose this information, since there is no - // (easy) way for a person in the real world either to distinguish between - // a lamp that *physically* does not have power, and a lamp that has simply - // been turned off programmatically (but which still has power and can thus - // receive new commands). - // - // They can, however, deduce it by remembering the last time that they flicked - // the lamp's switch, just like this function does. - interactions - |> Seq.choose (fun interaction -> - match interaction with - | HumanInteraction(LightPoweredOff l) when l = light -> Some false - | HumanInteraction(LightPoweredOn l) when l = light -> Some true - | _ -> None) - |> Seq.tryLast - |> Option.defaultValue false - [ |])>] let ``All lights should be either off, white or yellow during the day`` (light: Light) = concatGens @@ -76,15 +58,15 @@ type NightLightTests() = | On(_, color) -> color = Red) [ |])>] - let ``All non-remotely controlled lights should be on iff they have power`` (light: Light) = + let ``All non-remotely controlled lights should be on if they have power`` (light: Light) = genRandomInteractions light |> ensureStartsWithTimeChanged + |> ensureLightHasPower light |> Arb.fromGen |> Prop.forAll <| fun interactions -> let fakeHome = createFakeHomeWithNightLightAndInteract interactions - - doesLightHavePowerAfter light interactions = fakeHome.LightShouldHaveState light _.IsOn + fakeHome.LightShouldHaveState light _.IsOn [ |])>] let ``All remote controlled lights with power should be on if the 'Off' button on the remote was never pressed`` @@ -92,13 +74,12 @@ type NightLightTests() = = genRandomInteractionsExcept light ((=) (HumanInteraction RemotePressedOffButton)) |> ensureStartsWithTimeChanged + |> ensureLightHasPower light |> Arb.fromGen |> Prop.forAll <| fun interactions -> let fakeHome = createFakeHomeWithNightLightAndInteract interactions - - doesLightHavePowerAfter light interactions - ==> fakeHome.LightShouldHaveState light _.IsOn + fakeHome.LightShouldHaveState light _.IsOn [ |])>] let ``After pressing 'On' on the remote, if the 'Off' button isn't pressed, all remotely controlled lights with power should be on`` @@ -109,13 +90,12 @@ type NightLightTests() = HumanInteraction RemotePressedOnButton |> List.singleton |> Gen.constant genRandomInteractionsExcept light ((=) (HumanInteraction RemotePressedOffButton)) ] |> ensureStartsWithTimeChanged + |> ensureLightHasPower light |> Arb.fromGen |> Prop.forAll <| fun interactions -> let fakeHome = createFakeHomeWithNightLightAndInteract interactions - - doesLightHavePowerAfter light interactions - ==> fakeHome.LightShouldHaveState light _.IsOn + fakeHome.LightShouldHaveState light _.IsOn [ |])>] let ``After a new day starts, if the 'Off' button isn't pressed, all remotely controlled lights with power should be on`` @@ -128,13 +108,12 @@ type NightLightTests() = genTimeChangedToRandomDayTime |> Gen.map List.singleton genRandomInteractionsExcept light ((=) (HumanInteraction RemotePressedOffButton)) ] |> ensureStartsWithTimeChanged + |> ensureLightHasPower light |> Arb.fromGen |> Prop.forAll <| fun interactions -> let fakeHome = createFakeHomeWithNightLightAndInteract interactions - - doesLightHavePowerAfter light interactions - ==> fakeHome.LightShouldHaveState light _.IsOn + fakeHome.LightShouldHaveState light _.IsOn [ |])>] let ``After pressing 'Off' on the remote, if the 'On' button isn't pressed and a new day doesn't start, all remotely controlled lights should be off`` @@ -151,5 +130,4 @@ type NightLightTests() = |> Prop.forAll <| fun interactions -> let fakeHome = createFakeHomeWithNightLightAndInteract interactions - fakeHome.LightShouldHaveState light _.IsOff