Skip to content

Commit

Permalink
Add tree tests to fable tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ThisFunctionalTom committed Jan 23, 2021
1 parent 2492a47 commit a7f6122
Show file tree
Hide file tree
Showing 8 changed files with 230 additions and 97 deletions.
2 changes: 1 addition & 1 deletion src/Hedgehog/Tuple.fs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module private Tuple =
x, f y


module private GenTuple =
module GenTuple =

let mapFst (f : 'a -> 'c) (gen : Gen<'a * 'b>) : Gen<'c * 'b> =
Gen.map (Tuple.mapFst f) gen
Expand Down
33 changes: 10 additions & 23 deletions tests/Hedgehog.Fable.Tests/GenTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,22 @@ open Hedgehog
let dtRange = Range.constantFrom (System.DateTime (2000, 1, 1)) System.DateTime.MinValue System.DateTime.MaxValue

let genTests = xunitTests "Gen tests" [
theory "dateTime creates System.DateTime instances"
theory "dateTime creates System.DateTime instances"
[ 8; 16; 32; 64; 128; 256; 512 ] <| fun count ->
let actual = Gen.dateTime dtRange |> Gen.sample 0 count
actual
|> List.distinct
|> List.length
=! actual.Length

fact "unicode doesn't return any surrogate" <| fun _ ->
let actual = Gen.sample 100 100000 Gen.unicode
let actual = Gen.sample 100 100000 Gen.unicode
[] =! List.filter System.Char.IsSurrogate actual

theory "unicode doesn't return any noncharacter"
theory "unicode doesn't return any noncharacter"
[ 65534; 65535 ] <| fun nonchar ->
let isNoncharacter = (=) <| Operators.char nonchar
let actual = Gen.sample 100 100000 Gen.unicode
[] =! List.filter isNoncharacter actual
[] =! List.filter (fun ch -> ch = char nonchar) actual

fact "dateTime randomly generates value between max and min ticks" <| fun _ ->
let seed0 = Seed.random()
Expand Down Expand Up @@ -54,26 +53,14 @@ let genTests = xunitTests "Gen tests" [
System.DateTime (2000, 1, 1) =! result

pfact "int64 can create exponentially bounded integer" <| fun _ ->
Property.check <| property {
Property.check (property {
let! _ = Gen.int64 (Range.exponentialBounded ())
return true
}
})

pfact "uint64 can create exponentially bounded integer" <| fun _ ->
Property.check <| property {
Property.check (property {
let! _ = Gen.uint64 (Range.exponentialBounded ())
return true
}

fact "int can create exponentially bounded integer" <| fun _ ->
Property.check <| property {
let! _ = Gen.int (Range.exponentialBounded ())
return true
}

pfact "uint32 can create exponentially bounded integer" <| fun _ ->
Property.check <| property {
let! _ = Gen.uint32 (Range.exponentialBounded ())
return true
}
]
})
]
3 changes: 2 additions & 1 deletion tests/Hedgehog.Fable.Tests/Hedgehog.Fable.Tests.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="TestHelpers.fs" />
<Compile Include="TreeTests.fs" />
<Compile Include="RangeTests.fs" />
<Compile Include="GenTests.fs" />
<Compile Include="SeedTests.fs" />
Expand All @@ -22,4 +23,4 @@
<PackageReference Include="Fable.Core" Version="3.1.5" />
<PackageReference Include="Fable.Mocha" Version="2.9.1" />
</ItemGroup>
</Project>
</Project>
28 changes: 16 additions & 12 deletions tests/Hedgehog.Fable.Tests/MinimalTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -50,20 +50,24 @@ let rec tryFindSmallest (p : 'a -> bool) (Node (x, xs) : Tree<'a>) : 'a option =

#nowarn "40"
let rec genExp : Gen<Exp> =
Gen.delay <| fun _ ->
Gen.shrink shrinkExp <| // comment this out to see the property fail
Gen.choiceRec [
Lit <!> Gen.int (Range.constant 0 10)
Var <!> genName
] [
Lam <!> Gen.zip genName genExp
App <!> Gen.zip genExp genExp
]
Gen.delay (fun _ ->
let recs = [
Lit <!> Gen.int (Range.constant 0 10)
Var <!> genName
]

let nonrecs = [
Lam <!> Gen.zip genName genExp
App <!> Gen.zip genExp genExp
]

Gen.choiceRec recs nonrecs
|> Gen.shrink shrinkExp
)

let minimalTests = xunitTests "Minimal tests" [
fact "greedy traversal with a predicate yields the perfect minimal shrink" <| fun _ ->
Property.check <| property {
Property.check (property {
let! xs = Gen.mapTree Tree.duplicate genExp |> Gen.resize 20
match tryFindSmallest noAppLit10 xs with
| None ->
Expand All @@ -81,5 +85,5 @@ let minimalTests = xunitTests "Minimal tests" [
counterexample (sprintf "%A" x)
return false
}
}
]
})
]
5 changes: 3 additions & 2 deletions tests/Hedgehog.Fable.Tests/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ let smokeTests = testList "Smoke tests" [

let allTests = testList "All tests" [
smokeTests
TreeTests.treeTests
RangeTests.rangeTests
GenTests.genTests
SeedTests.seedTests
Expand All @@ -27,9 +28,9 @@ let allTests = testList "All tests" [
]

[<EntryPoint>]
let main (args: string[]) =
let main (args: string[]) =
#if FABLE_COMPILER
Mocha.runTests allTests
#else
runTestsWithArgs defaultConfig args allTests
#endif
#endif
97 changes: 62 additions & 35 deletions tests/Hedgehog.Fable.Tests/RangeTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,18 @@ let rangeTests = xunitTests "Range tests" [
( 256, 128)
( 512, 256)
(1024, 512) ] <| fun (sz, x) ->

let actual =
Range.bounds sz <| Range.singleton x
Range.singleton x
|> Range.bounds sz
(x, x) =! actual

theory "singleton origin returns correct result"
[ 1; 2; 3; 30; 128; 256; 512; 1024 ] <| fun x ->

let actual =
Range.origin <| Range.singleton x
Range.singleton x
|> Range.origin
x =! actual

theory "constant bounds returns correct result"
Expand All @@ -34,7 +36,8 @@ let rangeTests = xunitTests "Range tests" [
(1024, 511, 512) ] <| fun (sz, x, y) ->

let actual =
Range.bounds sz <| Range.constant x y
Range.constant x y
|> Range.bounds sz
(x, y) =! actual

theory "constant origin returns correct result"
Expand All @@ -47,14 +50,16 @@ let rangeTests = xunitTests "Range tests" [
(1024, 511) ] <| fun (x, y) ->

let actual =
Range.origin <| Range.constant x y
x =! actual
Range.constant x y
|> Range.origin
x =! actual

theory "range from -x to x, with the origin at"
[ 1; 2; 3; 30; 128; 256; 512; 1024] <| fun x ->

let actual =
Range.origin <| Range.constantFrom x -10 10
Range.constantFrom x -10 10
|> Range.origin
x =! actual

theory "range from -x to x, with the bounds at"
Expand All @@ -67,31 +72,35 @@ let rangeTests = xunitTests "Range tests" [
(1024, 511) ] <| fun (sz, x) ->

let actual =
Range.bounds sz <| Range.constantFrom 0 -x x
Range.constantFrom 0 -x x
|> Range.bounds sz
(-x, x) =! actual

theory "constantBounded bounds returns correct result - Byte range"
theory "constantBounded bounds returns correct result - Byte range"
[ 1; 2; 3; 30; 128; 256; 512; 1024 ] <| fun sz ->

let x =
Range.bounds sz <| (Range.constantBounded () : Range<Byte>)
(Range.constantBounded () : Range<Byte>)
|> Range.bounds sz
(Byte.MinValue, Byte.MaxValue) =! x

theory "constantBounded bounds returns correct result - Int32 range"
theory "constantBounded bounds returns correct result - Int32 range"
[ 1; 2; 3; 30; 128; 256; 512; 1024 ] <| fun sz ->

let x =
Range.bounds sz <| (Range.constantBounded () : Range<Int32>)
(Range.constantBounded () : Range<Int32>)
|> Range.bounds sz
(Int32.MinValue, Int32.MaxValue) =! x

theory "constantBounded bounds returns correct result - Int64 range"
theory "constantBounded bounds returns correct result - Int64 range"
[ 1; 2; 3; 30; 128; 256; 512; 1024 ] <| fun sz ->

let x =
Range.bounds sz <| (Range.constantBounded () : Range<Int64>)
(Range.constantBounded () : Range<Int64>)
|> Range.bounds sz
(Int64.MinValue, Int64.MaxValue) =! x

theory "clamp truncates a value so it stays within some range"
theory "clamp truncates a value so it stays within some range"
[ (5, 10, 15, 10)
(5, 10, 0, 5) ] <| fun (x, y, n, expected) ->

Expand All @@ -101,92 +110,110 @@ let rangeTests = xunitTests "Range tests" [

fact "linear scales the second bound relative to the size - example 1" <| fun _ ->
let actual =
Range.bounds 0 <| Range.linear 0 10
Range.linear 0 10
|> Range.bounds 0
(0, 0) =! actual

fact "linear scales the second bound relative to the size - example 2" <| fun _ ->
let actual =
Range.bounds 50 <| Range.linear 0 10
Range.linear 0 10
|> Range.bounds 50
(0, 5) =! actual

fact "linear scales the second bound relative to the size - example 3" <| fun _ ->
let actual =
Range.bounds 99 <| Range.linear 0 10
Range.linear 0 10
|> Range.bounds 99
(0, 10) =! actual

fact "linearFrom scales the bounds relative to the size - example 1" <| fun _ ->
let actual =
Range.bounds 0 <| Range.linearFrom 0 -10 10
Range.linearFrom 0 -10 10
|> Range.bounds 0
(0, 0) =! actual

fact "linearFrom scales the bounds relative to the size - example 2" <| fun _ ->
let actual =
Range.bounds 50 <| Range.linearFrom 0 -10 20
Range.linearFrom 0 -10 20
|> Range.bounds 50
(-5, 10) =! actual

fact "linearFrom scales the bounds relative to the size - example 3" <| fun _ ->
let actual =
Range.bounds 99 <| Range.linearFrom 0 -10 20
Range.linearFrom 0 -10 20
|> Range.bounds 99
(-10, 20) =! actual

fact "linearBounded uses the full range of a data type - example 1" <| fun _ ->
let actual =
Range.bounds 0 <| (Range.linearBounded () : Range<sbyte>)
(Range.linearBounded () : Range<sbyte>)
|> Range.bounds 0
(-0y, 0y) =! actual

fact "linearBounded uses the full range of a data type - example 2" <| fun _ ->
let actual =
Range.bounds 50 <| (Range.linearBounded () : Range<sbyte>)
(Range.linearBounded () : Range<sbyte>)
|> Range.bounds 50
(-64y, 64y) =! actual

fact "linearBounded uses the full range of a data type - example 3" <| fun _ ->
let actual =
Range.bounds 99 <| (Range.linearBounded () : Range<sbyte>)
(Range.linearBounded () : Range<sbyte>)
|> Range.bounds 99
(-128y, 127y) =! actual

fact "exponential scales the second bound exponentially relative to the size - example 1" <| fun _ ->
let actual =
Range.bounds 0 <| Range.exponential 1 512
Range.exponential 1 512
|> Range.bounds 0
(1, 1) =! actual

fact "exponential scales the second bound exponentially relative to the size - example 2" <| fun _ ->
let actual =
Range.bounds 77 <| Range.exponential 1 512
Range.exponential 1 512
|> Range.bounds 77
(1, 128) =! actual

fact "exponential scales the second bound exponentially relative to the size - example 3" <| fun _ ->
let actual =
Range.bounds 99 <| Range.exponential 1 512
Range.exponential 1 512
|> Range.bounds 99
(1, 512) =! actual

fact "exponentialFrom scales the bounds exponentially relative to the size - example 1" <| fun _ ->
let actual =
Range.bounds 0 <| Range.exponentialFrom 0 -128 512
Range.exponentialFrom 0 -128 512
|> Range.bounds 0
(0, 0) =! actual

fact "exponentialFrom scales the bounds exponentially relative to the size - example 2" <| fun _ ->
let actual =
Range.bounds 50 <| Range.exponentialFrom 0 -128 512
Range.exponentialFrom 0 -128 512
|> Range.bounds 50
(-11, 22) =! actual

fact "exponentialFrom scales the bounds exponentially relative to the size - example 3" <| fun _ ->
let actual =
Range.bounds 99 <| Range.exponentialFrom 3 -128 512
Range.exponentialFrom 3 -128 512
|> Range.bounds 99
(-128, 512) =! actual

fact "exponentialBounded uses the full range of a data type - example 1" <| fun _ ->
let actual =
Range.bounds 0 <| (Range.exponentialBounded () : Range<sbyte>)
(Range.exponentialBounded () : Range<sbyte>)
|> Range.bounds 0
(-0y, 0y) =! actual

fact "exponentialBounded uses the full range of a data type - example 2" <| fun _ ->
let actual =
Range.bounds 50 <| (Range.exponentialBounded () : Range<sbyte>)
(Range.exponentialBounded () : Range<sbyte>)
|> Range.bounds 50
(-11y, 11y) =! actual

fact "exponentialBounded uses the full range of a data type - example 3" <| fun _ ->
let actual =
Range.bounds 99 <| (Range.exponentialBounded () : Range<sbyte>)
(Range.exponentialBounded () : Range<sbyte>)
|> Range.bounds 99
(-128y, 127y) =! actual

]
]
Loading

0 comments on commit a7f6122

Please sign in to comment.