Verify that non-remotely controlled lights are on if they have power

This commit is contained in:
Sven van Heugten 2026-01-08 21:45:46 +01:00
parent d57ca23822
commit d7fac9c3d0
3 changed files with 21 additions and 6 deletions

View file

@ -19,14 +19,14 @@ let private genHumanInteraction biasTowardsLight =
let private genInteraction biasTowardsLight = let private genInteraction biasTowardsLight =
Gen.oneof [ genTimeChanged; genHumanInteraction biasTowardsLight ] Gen.oneof [ genTimeChanged; genHumanInteraction biasTowardsLight ]
let private genInteractionsListThatStartsWithTimeChanged biasTowardsLight = let genInitialInteractions biasTowardsLight =
[ genTimeChanged |> Gen.map List.singleton [ genTimeChanged |> Gen.map List.singleton
Gen.listOf <| genInteraction biasTowardsLight ] Gen.listOf <| genInteraction biasTowardsLight ]
|> concatGens |> concatGens
let genInitialInteractionsAndEndWith biasTowardsLight (endsWith: Interaction) = let genInitialInteractionsAndEndWith biasTowardsLight (endsWith: Interaction) =
let genNonTrivialList = let genNonTrivialList =
genInteractionsListThatStartsWithTimeChanged biasTowardsLight genInitialInteractions biasTowardsLight
|> Gen.map (fun lst -> lst @ [ endsWith ]) |> Gen.map (fun lst -> lst @ [ endsWith ])
match endsWith with match endsWith with

View file

@ -6,6 +6,13 @@ open FsCheck.FSharp
type ArbitraryLight = type ArbitraryLight =
static member Light() = lights |> Gen.elements |> Arb.fromGen static member Light() = lights |> Gen.elements |> Arb.fromGen
type ArbitraryNonRemotelyControlledLight =
static member Light() =
lights
|> Seq.filter (not << _.ControlledWithRemote)
|> Gen.elements
|> Arb.fromGen
type ArbitraryRemotelyControlledLight = type ArbitraryRemotelyControlledLight =
static member Light() = static member Light() =
lights |> Seq.filter _.ControlledWithRemote |> Gen.elements |> Arb.fromGen lights |> Seq.filter _.ControlledWithRemote |> Gen.elements |> Arb.fromGen

View file

@ -63,8 +63,16 @@ type NightLightTests() =
| Off -> true | Off -> true
| On(_, color) -> color = Red) | On(_, color) -> color = Red)
[<Property(Arbitrary = [| typeof<ArbitraryLight> |])>] [<Property(Arbitrary = [| typeof<ArbitraryNonRemotelyControlledLight> |])>]
let ``After pressing 'On' on the remote, all lights with power should be on, as long as the 'Off' button isn't pressed`` let ``All non-remotely controlled lights should be on *if and only if* they have power`` (light: Light) =
genInitialInteractions light |> Arb.fromGen |> Prop.forAll
<| fun interactions ->
let fakeHome = createFakeHomeWithNightLightAndInteract interactions
doesLightHavePowerAfter light interactions = fakeHome.LightShouldHaveState light _.IsOn
[<Property(Arbitrary = [| typeof<ArbitraryRemotelyControlledLight> |])>]
let ``After pressing 'On' on the remote, all remotely controlled lights with power should be on, as long as the 'Off' button isn't pressed``
(light: Light) (light: Light)
= =
concatGens concatGens
@ -78,8 +86,8 @@ type NightLightTests() =
doesLightHavePowerAfter light interactions doesLightHavePowerAfter light interactions
==> fakeHome.LightShouldHaveState light _.IsOn ==> fakeHome.LightShouldHaveState light _.IsOn
[<Property(Arbitrary = [| typeof<ArbitraryLight> |])>] [<Property(Arbitrary = [| typeof<ArbitraryRemotelyControlledLight> |])>]
let ``After a new day starts, all lights with power should be on, as long as the 'Off' button isn't pressed`` let ``After a new day starts, all remotely controlled lights with power should be on, as long as the 'Off' button isn't pressed``
(light: Light) (light: Light)
= =
concatGens concatGens