diff --git a/NightLight.Core.Tests/Arbitraries.fs b/NightLight.Core.Tests/Arbitraries.fs deleted file mode 100644 index 379c39e..0000000 --- a/NightLight.Core.Tests/Arbitraries.fs +++ /dev/null @@ -1,29 +0,0 @@ -namespace NightLight.Core.Tests - -open System -open FsCheck -open FsCheck.FSharp -open NightLight.Core.Models - -type Arbitraries = - static member Interactions() : Arbitrary = - gen { - let genTimeChangedInteraction = - gen { - let! time = ArbMap.defaults |> ArbMap.generate - return Interaction.TimeChanged time - } - - let genHumanInteraction = - gen { - let! light = Gen.elements lights - let! humanInteraction = Gen.elements [ LightTurnedOn light; LightTurnedOff light ] - return Interaction.HumanInteraction humanInteraction - } - - let! initialTimeChangedInteraction = genTimeChangedInteraction - let! remainingInteractions = Gen.oneof [ genTimeChangedInteraction; genHumanInteraction ] |> Gen.listOf - - return initialTimeChangedInteraction :: remainingInteractions - } - |> Arb.fromGen diff --git a/NightLight.Core.Tests/ArbitraryInteractionLists.fs b/NightLight.Core.Tests/ArbitraryInteractionLists.fs new file mode 100644 index 0000000..9098db1 --- /dev/null +++ b/NightLight.Core.Tests/ArbitraryInteractionLists.fs @@ -0,0 +1,25 @@ +module NightLight.Core.Tests.ArbitraryInteractionLists + +open System +open FsCheck.FSharp +open NightLight.Core.Tests.InteractionListGenerators + +let private isDay (time: DateTime) = + time.TimeOfDay >= TimeSpan.FromHours 5.5 + && time.TimeOfDay < TimeSpan.FromHours 20.5 + +type ArbitraryInteractionsListThatEndsDuringTheDay = + static member InteractionsList() = + ArbMap.defaults + |> ArbMap.generate + |> Gen.filter isDay + |> Gen.bind genInteractionsListThatEndsAtTime + |> Arb.fromGen + +type ArbitraryInteractionsListThatEndsDuringTheNight = + static member InteractionsList() = + ArbMap.defaults + |> ArbMap.generate + |> Gen.filter (not << isDay) + |> Gen.bind genInteractionsListThatEndsAtTime + |> Arb.fromGen diff --git a/NightLight.Core.Tests/InteractionListGenerators.fs b/NightLight.Core.Tests/InteractionListGenerators.fs new file mode 100644 index 0000000..d1e1925 --- /dev/null +++ b/NightLight.Core.Tests/InteractionListGenerators.fs @@ -0,0 +1,41 @@ +module NightLight.Core.Tests.InteractionListGenerators + +open System +open FsCheck.FSharp +open NightLight.Core.Models + +let private genTimeChangedInteraction = + ArbMap.defaults |> ArbMap.generate |> Gen.map Interaction.TimeChanged + +let private genHumanInteraction = + Gen.elements lights + |> Gen.bind (fun light -> + [ LightTurnedOn light; LightTurnedOff light ] + |> Gen.elements + |> Gen.map Interaction.HumanInteraction) + +let private genInteraction = + Gen.oneof [ genTimeChangedInteraction; genHumanInteraction ] + +let private genInteractionsListThatStartsWithTimeChange = + gen { + let! firstInteraction = genTimeChangedInteraction + let! remainingInteractions = Gen.listOf genInteraction + return firstInteraction :: remainingInteractions + } + +let private genInteractionsListWhere condition = + Gen.listOf (genInteraction |> Gen.filter condition) + +let genInteractionsListThatEndsAtTime time = + let genTrivialList = Gen.constant <| List.singleton (Interaction.TimeChanged time) + + let genNonTrivialList = + gen { + let! before = genInteractionsListThatStartsWithTimeChange + let interactionThatSetsEndTime = Interaction.TimeChanged time + let! after = genInteractionsListWhere (not << _.IsTimeChanged) + return before @ interactionThatSetsEndTime :: after + } + + Gen.frequency [ 1, genTrivialList; 9, genNonTrivialList ] diff --git a/NightLight.Core.Tests/NightLight.Core.Tests.fsproj b/NightLight.Core.Tests/NightLight.Core.Tests.fsproj index 5d37e21..66f25e0 100644 --- a/NightLight.Core.Tests/NightLight.Core.Tests.fsproj +++ b/NightLight.Core.Tests/NightLight.Core.Tests.fsproj @@ -8,7 +8,8 @@ - + + diff --git a/NightLight.Core.Tests/NightLightTests.fs b/NightLight.Core.Tests/NightLightTests.fs index d33631c..0402695 100644 --- a/NightLight.Core.Tests/NightLightTests.fs +++ b/NightLight.Core.Tests/NightLightTests.fs @@ -1,31 +1,9 @@ namespace NightLight.Core.Tests -open System open NightLight.Core.Core +open NightLight.Core.Tests.ArbitraryInteractionLists open FsCheck.Xunit -open FsCheck.FSharp -module InteractionsHelpers = - let getTimeAfter interactions = - interactions - |> Seq.choose (fun interaction -> - match interaction with - | TimeChanged time -> Some time - | _ -> None) - |> Seq.tryLast - |> function - | Some time -> time - | None -> failwith "Time wasn't changed" - - let isDayAfter interactions = - let time = getTimeAfter interactions - - time.TimeOfDay >= TimeSpan.FromHours 5.5 - && time.TimeOfDay < TimeSpan.FromHours 20.5 - - let isNightAfter = not << isDayAfter - -[ |])>] type NightLightTests() = let createFakeHomeWithNightLightAndInteract (interactions: Interaction list) = let mutable nightLightStateMachine = NightLightStateMachine() @@ -43,16 +21,12 @@ type NightLightTests() = fakeHome - [] + [ |])>] let ``Lights should be red during the night`` (interactions: Interaction list) = let fakeHome = createFakeHomeWithNightLightAndInteract interactions + fakeHome.ForAllLightsThatAreOn(fun (_, _, color) -> color = Red) - InteractionsHelpers.isNightAfter interactions - ==> fakeHome.ForAllLightsThatAreOn(fun (_, _, color) -> color = Red) - - [] + [ |])>] let ``Lights should be white or yellow during the day`` (interactions: Interaction list) = let fakeHome = createFakeHomeWithNightLightAndInteract interactions - - InteractionsHelpers.isDayAfter interactions - ==> fakeHome.ForAllLightsThatAreOn(fun (_, _, color) -> color = White || color = Yellow) + fakeHome.ForAllLightsThatAreOn(fun (_, _, color) -> color = White || color = Yellow)