Skip to content

Commit

Permalink
Add unit tests for Section 02 12.
Browse files Browse the repository at this point in the history
  • Loading branch information
eminencegrs committed Feb 4, 2024
1 parent 6594e92 commit 8485391
Show file tree
Hide file tree
Showing 5 changed files with 291 additions and 26 deletions.
7 changes: 4 additions & 3 deletions src/FPinFSharp.Exercises/Chapter_02/Section_02_08.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ module Section_02_08 =
// A closure gives the means of explaining a value that is a function. A closure is a triple: (x, exp, env).
// Where 'x' is an argument identifier,
// 'exp' is the expression to evaluate to get a function value,
// while 'env' is an environment giving bindings to be used in such an evalua- tion.
// while 'env' is an environment giving bindings to be used in such an evaluation.

// The following simple example illustrates the role of the environment in the closure:
let pi = System.Math.PI
let circleArea r = pi * r * r // float -> float
let getPI = System.Math.PI

let circleArea r = getPI * r * r // float -> float
// These declarations bind the identifier 'pi' to a float value and 'circleArea' to a closure:
// pi --> 3.14159
// circleArea --> (r, pi * r * r, [pi --> 3.14159...])
145 changes: 126 additions & 19 deletions src/FPinFSharp.Exercises/Chapter_02/Section_02_12.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,141 @@ namespace FPinFSharp.Exercises.Chapter_02
// 2.12 Summary of the basic types
module Section_02_12 =

let getChar () : char = 'c'
// Helpers.
let formatNumeric (values: 'T * 'T) : string * string =
System.String.Format("{0}", fst values), System.String.Format("{0}", snd values)

let getByte isHex : byte =
let formatHexadecimal (values: 'T * 'T) : string * string =
if fst values < Unchecked.defaultof<'T>
then System.String.Format("-0x{0:X2}", fst values), System.String.Format("0x{0:X2}", snd values)
else System.String.Format("0x{0:X2}", fst values), System.String.Format("0x{0:X2}", snd values)

// Char
let convertIntToChar (x: int) : char =
System.Convert.ToChar x

// Byte
let getMinMaxByte (isHex: bool) : byte * byte =
match isHex with
| true -> (0x0uy, 0xFFuy)
| false -> (0uy, 255uy)

let getMinMaxByteInString (isHex: bool) : string * string =
match isHex with
| true -> getMinMaxByte true |> formatHexadecimal
| false -> getMinMaxByte false |> formatNumeric

// SByte
let getMinMaxSByte (isHex: bool) : sbyte * sbyte =
match isHex with
| true -> (0x80y, 0x7Fy)
| false -> (-128y, 127y)

let getMinMaxSByteInString (isHex: bool) : string * string =
match isHex with
| true -> getMinMaxSByte true |> formatHexadecimal
| false -> getMinMaxSByte false |> formatNumeric

// Int16
let getMinMaxInt16 (isHex: bool) : int16 * int16 =
match isHex with
| true -> (-0x8000s, 0x7FFFs)
| false -> (-32768s, 32767s)

let getMinMaxInt16InString (isHex: bool) : string * string =
match isHex with
| true -> getMinMaxInt16 true |> formatHexadecimal
| false -> getMinMaxInt16 false |> formatNumeric

// UInt16
let getMinMaxUInt16 (isHex: bool) : uint16 * uint16 =
match isHex with
| true -> (0x0us, 0xFFFFus)
| false -> (0us, 65535us)

let getMinMaxUInt16InString (isHex: bool) : string * string =
match isHex with
| true -> getMinMaxUInt16 true |> formatHexadecimal
| false -> getMinMaxUInt16 false |> formatNumeric

// Int32
let getInt32 (isHex: bool) : int32 * int32 =
match isHex with
| true -> (-0x80000000, 0x7FFFFFFF)
| false -> (-2147483648, 2147483647)

let getInt32InString (isHex: bool) : string * string =
match isHex with
| true -> getInt32 true |> formatHexadecimal
| false -> getInt32 false |> formatNumeric

// UInt32
let getUInt32 (isHex: bool) : uint32 * uint32 =
match isHex with
| true -> (0u, 0xFFFFFFFFu)
| false -> (0u, 4294967295u)

let getUInt32InString (isHex: bool) : string * string =
match isHex with
| true -> getUInt32 true |> formatHexadecimal
| false -> getUInt32 false |> formatNumeric

// Int64
let getInt64 (isHex: bool) : int64 * int64 =
match isHex with
| true -> 0xFFuy
| false -> 255uy
| true -> (-0x8000000000000000L, 0x7FFFFFFFFFFFFFFFL)
| false -> (-9223372036854775808L, 9223372036854775807L)

let getSByte isHex : sbyte =
let getInt64InString (isHex: bool) : string * string =
match isHex with
| true -> -0x80y
| false -> 127y
| true -> getInt64 true |> formatHexadecimal
| false -> getInt64 false |> formatNumeric

let getInt16 isHex : int16 =
// UInt64
let getUInt64 (isHex: bool) : uint64 * uint64 =
match isHex with
| true -> -0x8000s
| false -> 32767s
| true -> (0UL, 0xFFFFFFFFFFFFFFFFUL)
| false -> (0UL, 18446744073709551615UL)

let getUInt16 isHex : uint16 =
let getUInt64InString (isHex: bool) : string * string =
match isHex with
| true -> 0xFFFFus
| false -> 65535us
| true -> getUInt64 true |> formatHexadecimal
| false -> getUInt64 false |> formatNumeric

let getInt32 isHex : int32 =
// nativeint
let getNativeInt (isHex: bool) : nativeint * nativeint =
match isHex with
| true -> -0x80000000
| false -> 2147483647
| true -> (-0x80000000n, 0x7FFFFFFFn)
| false -> (-2147483648n, 2147483647n)

let getUInt32 isHex : uint32 =
let getNativeIntInString (isHex: bool) : string * string =
match isHex with
| true -> 0xFFFFFFFFu
| false -> 4294967295u
| true -> getNativeInt true |> formatHexadecimal
| false -> getNativeInt false |> formatNumeric

// unativeint
let getUNativeInt (isHex: bool) : unativeint * unativeint =
match isHex with
| true -> (0un, 0xFFFFFFFFun)
| false -> (0un, 4294967295un)

let getUNativeIntInString (isHex: bool) : string * string =
match isHex with
| true -> getUNativeInt true |> formatHexadecimal
| false -> getUNativeInt false |> formatNumeric

// Single
let getMinMaxSingle () : single * single =
(-3.40282346639e+38f, 3.40282346639e+38f)

// Double
let getMinMaxDouble () : double * double =
(-1.7976931348623157e+308, 1.7976931348623157e+308)

// Decimal
let getMinMaxDecimal () : decimal * decimal =
(System.Decimal.MinValue, System.Decimal.MaxValue)

// BigInt
let getBigInt () : bigint =
18446744073709551615I
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,21 @@ open Xunit
module Section_02_11_Tests =

[<Fact>]
let ``Given true when call raiseExceptionIfTrue then InvalidOperationException is thrown`` () =
let ``GIVEN true WHEN raiseExceptionIfTrue THEN InvalidOperationException is thrown`` () =
let action = fun () -> raiseExceptionIfTrue true
action |> ShouldThrowExtensions.ShouldThrow<InvalidOperationException>

[<Fact>]
let ``Given false when call raiseExceptionIfTrue then no exception is thrown`` () =
let ``GIVEN false WHEN raiseExceptionIfTrue THEN no exception is thrown`` () =
let action = fun () -> raiseExceptionIfTrue false
action |> ShouldThrowExtensions.ShouldNotThrow

[<Fact>]
let ``Given false when call raiseExceptionIfFalse then InvalidOperationException is thrown`` () =
let ``GIVEN false WHEN raiseExceptionIfFalse THEN InvalidOperationException is thrown`` () =
let action = fun () -> raiseExceptionIfFalse false
action |> ShouldThrowExtensions.ShouldThrow<InvalidOperationException>

[<Fact>]
let ``Given true when call raiseExceptionIfFalse then no exception is thrown`` () =
let ``GIVEN true WHEN raiseExceptionIfFalse THEN no exception is thrown`` () =
let action = fun () -> raiseExceptionIfFalse true
action |> ShouldThrowExtensions.ShouldNotThrow
156 changes: 156 additions & 0 deletions tests/FPinFSharp.Exercises.UnitTests/Chapter_02/Section_02_12_Tests.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
namespace FPinFSharp.Exercises.UnitTests.Chapter_02

open System
open System.Numerics
open FPinFSharp.Exercises.Chapter_02.Section_02_12
open Shouldly
open Xunit

module Section_02_12_Tests =

[<Theory>]
[<InlineData(Char.MinValue, Char.MinValue)>]
[<InlineData(Char.MaxValue, Char.MaxValue)>]
[<InlineData(65, 'A')>]
let ``GIVEN int WHEN convertIntToChar THEN result as expected`` (x:int) (expectedResult:char) =
let actualResult = convertIntToChar x
actualResult.ShouldBe(expectedResult)

[<Theory>]
[<InlineData(Int32.MinValue)>]
[<InlineData(-1)>]
let ``GIVEN invalid int WHEN convertIntToChar THEN OverflowException thrown`` (x:int) =
let action = fun () -> convertIntToChar x |> ignore
action |> ShouldThrowExtensions.ShouldThrow<OverflowException>

[<Theory>]
[<InlineData(true, Byte.MinValue, Byte.MaxValue)>]
[<InlineData(false, Byte.MinValue, Byte.MaxValue)>]
let ``GIVEN isHex WHEN getMinMaxByte THEN result as expected`` (isHex:bool) (expectedResult: byte * byte) =
let actualResult = getMinMaxByte isHex
actualResult.ShouldBe(expectedResult)

[<Theory>]
[<InlineData(true, "0x00", "0xFF")>]
[<InlineData(false, "0", "255")>]
let ``GIVEN isHex WHEN getMinMaxByteInString THEN result as expected`` (isHex:bool) (expectedResult: string * string) =
let actualResult = getMinMaxByteInString isHex
actualResult.ShouldBe(expectedResult);

[<Theory>]
[<InlineData(true, SByte.MinValue, SByte.MaxValue)>]
[<InlineData(false, SByte.MinValue, SByte.MaxValue)>]
let ``GIVEN isHex WHEN getMinMaxSByte THEN result as expected`` (isHex:bool) (expectedResult: sbyte * sbyte) =
let actualResult = getMinMaxSByte isHex
actualResult.ShouldBe(expectedResult)

[<Theory>]
[<InlineData(true, "-0x80", "0x7F")>]
[<InlineData(false, "-128", "127")>]
let ``GIVEN isHex WHEN getMinMaxSByteInString THEN result as expected`` (isHex:bool) (expectedResult: string * string) =
let actualResult = getMinMaxSByteInString isHex
actualResult.ShouldBe(expectedResult)

[<Theory>]
[<InlineData(true, Int16.MinValue, Int16.MaxValue)>]
[<InlineData(false, Int16.MinValue, Int16.MaxValue)>]
let ``GIVEN isHex WHEN getMinMaxInt16 THEN result as expected`` (isHex:bool) (expectedResult: int16 * int16) =
let actualResult = getMinMaxInt16 isHex
actualResult.ShouldBe(expectedResult)

[<Theory>]
[<InlineData(true, "-0x8000", "0x7FFF")>]
[<InlineData(false, "-32768", "32767")>]
let ``GIVEN isHex WHEN getMinMaxInt16InString THEN result as expected`` (isHex:bool) (expectedResult: string * string) =
let actualResult = getMinMaxInt16InString isHex
actualResult.ShouldBe(expectedResult)

[<Theory>]
[<InlineData(true, UInt16.MinValue, UInt16.MaxValue)>]
[<InlineData(false, UInt16.MinValue, UInt16.MaxValue)>]
let ``GIVEN isHex WHEN getMinMaxUInt16 THEN result as expected`` (isHex:bool) (expectedResult: uint16 * uint16) =
let actualResult = getMinMaxUInt16 isHex
expectedResult.ShouldBe(expectedResult)

[<Theory>]
[<InlineData(true, "0x00", "0xFFFF")>]
[<InlineData(false, "0", "65535")>]
let ``GIVEN isHex WHEN getMinMaxUInt16InString THEN result as expected`` (isHex:bool) (expectedResult: string * string) =
let actualResult = getMinMaxUInt16InString isHex
actualResult.ShouldBe(expectedResult)

[<Theory>]
[<InlineData(true, Int32.MinValue, Int32.MaxValue)>]
[<InlineData(false, Int32.MinValue, Int32.MaxValue)>]
let ``GIVEN isHex WHEN getInt32 THEN result as expected`` (isHex:bool) (expectedResult: int32 * int32) =
let actualResult = getInt32 isHex
actualResult.ShouldBe(expectedResult)

[<Theory>]
[<InlineData(true, "-0x80000000", "0x7FFFFFFF")>]
[<InlineData(false, "-2147483648", "2147483647")>]
let ``GIVEN isHex WHEN getInt32InString THEN result as expected`` (isHex:bool) (expectedResult: string * string) =
let actualResult = getInt32InString isHex
actualResult.ShouldBe(expectedResult)

[<Theory>]
[<InlineData(true, UInt32.MinValue, UInt32.MaxValue)>]
[<InlineData(false, UInt32.MinValue, UInt32.MaxValue)>]
let ``GIVEN isHex WHEN getUInt32 THEN result as expected`` (isHex:bool) (expectedResult: uint32 * uint32) =
let actualResult = getUInt32 isHex
actualResult.ShouldBe(expectedResult)

[<Theory>]
[<InlineData(true, "0x00", "0xFFFFFFFF")>]
[<InlineData(false, "0", "4294967295")>]
let ``GIVEN isHex WHEN getUInt32InString THEN result as expected`` (isHex:bool) (expectedResult: string * string) =
let actualResult = getUInt32InString isHex
actualResult.ShouldBe(expectedResult)

[<Theory>]
[<InlineData(true, -0x8000000000000000L, 0x7FFFFFFFFFFFFFFFL)>]
[<InlineData(false, -9223372036854775808L, 9223372036854775807L)>]
let ``GIVEN isHex WHEN getInt64 THEN result as expected`` (isHex:bool) (expectedResult: int64 * int64) =
let actualResult = getInt64 isHex
actualResult.ShouldBe(expectedResult)

[<Theory>]
[<InlineData(true, "-0x8000000000000000", "0x7FFFFFFFFFFFFFFF")>]
[<InlineData(false, "-9223372036854775808", "9223372036854775807")>]
let ``GIVEN isHex WHEN getInt64InString THEN result as expected`` (isHex:bool) (expectedResult: string * string) =
let actualResult = getInt64InString isHex
actualResult.ShouldBe(expectedResult)

[<Theory>]
[<InlineData(true, 0UL, 0xFFFFFFFFFFFFFFFFUL)>]
[<InlineData(false, 0UL, 18446744073709551615UL)>]
let ``GIVEN isHex WHEN getUInt64 THEN result as expected`` (isHex:bool) (expectedResult: uint64 * uint64) =
let actualResult = getUInt64 isHex
actualResult.ShouldBe(expectedResult)

[<Theory>]
[<InlineData(true, "0x00", "0xFFFFFFFFFFFFFFFF")>]
[<InlineData(false, "0", "18446744073709551615")>]
let ``GIVEN isHex WHEN getUInt64InString THEN result as expected`` (isHex:bool) (expectedResult: string * string) =
let actualResult = getUInt64InString isHex
actualResult.ShouldBe(expectedResult)

[<Fact>]
let ``WHEN getMinMaxSingle THEN result as expected`` () =
let actualResult = getMinMaxSingle()
actualResult.ShouldBe((Single.MinValue, Single.MaxValue))

[<Fact>]
let ``WHEN getMinMaxDouble THEN result as expected`` () =
let actualResult = getMinMaxDouble()
actualResult.ShouldBe((Double.MinValue, Double.MaxValue))

[<Fact>]
let ``WHEN getMinMaxDecimal THEN result as expected`` () =
let actualResult = getMinMaxDecimal()
actualResult.ShouldBe((Decimal.MinValue, Decimal.MaxValue))

[<Fact>]
let ``WHEN getBigInt THEN result as expected`` () =
let actualResult = getBigInt()
actualResult.ShouldBe(18446744073709551615I)
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
<Compile Include="Chapter_02\Section_02_09_Tests.fs" />
<Compile Include="Chapter_02\Section_02_10_Tests.fs" />
<Compile Include="Chapter_02\Section_02_11_Tests.fs" />
<Compile Include="Chapter_02\Section_02_12_Tests.fs" />
<Folder Include="Chapter_03\" />
</ItemGroup>

Expand Down

0 comments on commit 8485391

Please sign in to comment.