# FsUnit for MsTest

The FsUnit library for MsTest can be installed from NuGet:
PM> Install-Package Fs30Unit.MsTest
Sample FsUnit tests for MsTest can be installed from NuGet:
PM> Install-Package Fs30Unit.MsTest.Sample

## Euler - Problem 1

module Project Euler - Problem 1 =
open Microsoft.VisualStudio.TestTools.UnitTesting
open FsUnit.MsTest

let GetSumOfMultiplesOf3And5 max =
seq{3..max-1} |> Seq.fold(fun acc number ->
(if (number % 3 = 0 || number % 5 = 0) then
acc + number else acc)) 0

[<TestMethod>]
let When getting sum of multiples of 3 and 5 to a max number of 10 it should return a sum of 23 () =
GetSumOfMultiplesOf3And5(10) |> should equal 23


## LightBulb

module LightBulb Tests =
open Microsoft.VisualStudio.TestTools.UnitTesting
open FsUnit.MsTest

type LightBulb(state) =
member x.On = state
override x.ToString() =
match x.On with
| true  -> "On"
| false -> "Off"

[<TestClass>]
type Given a LightBulb that has had its state set to true ()=
let lightBulb = new LightBulb(true)

[<TestMethod>] member x.
when I ask whether it is On it answers true. ()=
lightBulb.On |> should be True

[<TestMethod>] member x.
when I convert it to a string it becomes "On". ()=
string lightBulb |> should equal "On"

[<TestClass>]
type Given a LightBulb that has had its state set to false ()=
let lightBulb = new LightBulb(false)

[<TestMethod>] member x.
when I ask whether it is On it answers false. ()=
lightBulb.On |> should be False

[<TestMethod>] member x.
when I convert it to a string it becomes "Off". ()=
string lightBulb |> should equal "Off"


## BowlingGame

Thanks to Keith Nicholas and Julian from hubFS for this example!

module BowlingGame A game of bowling =
open Microsoft.VisualStudio.TestTools.UnitTesting
open FsUnit.MsTest

let (|EndOfGame|IncompleteStrike|Strike|Normal|Other|) (l, frame) =
match l with
| _ when frame = 11            -> EndOfGame(0)
| [10;s]                       -> IncompleteStrike(10+s+s)
| 10::s::n::tail               -> Strike(10+s+n, s::n::tail)
|  f::s::n::tail when f+s = 10 -> Normal(f+s+n,  n::tail)
|  f::s::n::tail               -> Normal(f+s,    n::tail)
| ls                           -> Other(List.fold (+) 0 ls)

let scoreBowls bowls =
let rec scoreBowls' frame l current_score =
let nextframe = scoreBowls' (frame+1)
match (l, frame) with
| EndOfGame(score)        -> current_score + score
| IncompleteStrike(score) -> current_score + score
| Strike(score, l)        -> nextframe l (current_score + score)
| Normal(score, l)        -> nextframe l (current_score + score)
| Other(score)            -> current_score + score
scoreBowls' 1 bowls 0

[<TestMethod>]
let with simple scores should get the expected score. () =
scoreBowls [1;2;3] |> should equal 6

[<TestMethod>]
let with a spare should get the expected score (spare). () =
scoreBowls [2;8;1] |> should equal 12

[<TestMethod>]
let with a strike should get the expected score (strike). () =
scoreBowls [10;1;2] |> should equal 16

[<TestMethod>]
let that is perfect should get a score of 300.() =
scoreBowls [for i in 1..18 -> 10] |> should equal 300

[<TestMethod>]
let with spares in the last frame should get the expected score (spare in last frame). () =
scoreBowls ([for i in 1..18 -> 0] @ [2;8;1]) |> should equal 11

[<TestMethod>]
let with a strike in the last frame should get the expected score (strike in last frame). () =
scoreBowls ([for i in 1..18 -> 0] @ [10;10;1]) |> should equal 21

[<TestMethod>]
let with double strikes should add the score of the first strike to the score of the second. () =
scoreBowls [10;10;1] |> should equal 33

[<TestMethod>]
let that looks like an average bowler's game should get the expected score (example game). () =
scoreBowls [1;4;4;5;6;4;5;5;10;0;1;7;3;6;4;10;2;8;6] |> should equal 133

Namespace Microsoft
Namespace Microsoft.VisualStudio
Namespace Microsoft.VisualStudio.TestTools
Namespace Microsoft.VisualStudio.TestTools.UnitTesting
Namespace FsUnit
Modul MsTest aus FsUnit
val GetSumOfMultiplesOf3And5: max: int -> int
val max: int
Multiple items
val seq: sequence: seq<'T> -> seq<'T>
<summary>Builds a sequence using sequence expression syntax</summary>
<param name="sequence">The input sequence.</param>
<returns>The result sequence.</returns>
<example id="seq-cast-example"><code lang="fsharp"> seq { for i in 0..10 do yield (i, i*i) } </code></example>

--------------------
type seq<'T> = System.Collections.Generic.IEnumerable<'T>
<summary>An abbreviation for the CLI type <see cref="T:System.Collections.Generic.IEnumerable1" /></summary>
<remarks> See the <see cref="T:Microsoft.FSharp.Collections.SeqModule" /> module for further operations related to sequences. See also <a href="https://docs.microsoft.com/dotnet/fsharp/language-reference/sequences">F# Language Guide - Sequences</a>. </remarks>
Modul Seq aus Microsoft.FSharp.Collections
<summary>Contains operations for working with values of type <see cref="T:Microsoft.FSharp.Collections.seq1" />.</summary>
val fold: folder: ('State -> 'T -> 'State) -> state: 'State -> source: seq<'T> -> 'State
<summary>Applies a function to each element of the collection, threading an accumulator argument through the computation. If the input function is <c>f</c> and the elements are <c>i0...iN</c> then computes <c>f (... (f s i0)...) iN</c></summary>
<param name="folder">A function that updates the state with each element from the sequence.</param>
<param name="state">The initial state.</param>
<param name="source">The input sequence.</param>
<returns>The state object after the folding function is applied to each element of the sequence.</returns>
<exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
<example id="fold-1"><code lang="fsharp"> type Charge = | In of int | Out of int let inputs = [In 1; Out 2; In 3] (0, inputs) ||&gt; Seq.fold (fun acc charge -&gt; match charge with | In i -&gt; acc + i | Out o -&gt; acc - o) </code> Evaluates to <c>2</c></example>
val acc: int
val number: int
Multiple items
type TestMethodAttribute = inherit Attribute new: unit -> unit + 1 Überladung member Execute: testMethod: ITestMethod -> TestResult[] member DisplayName: string
<summary> The test method attribute. </summary>

--------------------
TestMethodAttribute() : TestMethodAttribute
TestMethodAttribute(displayName: string) : TestMethodAttribute
val should: f: ('a -> #NHamcrest.IMatcher<obj>) -> x: 'a -> actual: obj -> unit
val equal: expected: 'a -> NHamcrest.Core.CustomMatcher<obj>
Multiple items
type LightBulb = new: state: bool -> LightBulb override ToString: unit -> string member On: bool

--------------------
new: state: bool -> LightBulb
val state: bool
val x: LightBulb
Eigenschaft LightBulb.On: bool with get
Multiple items
type TestClassAttribute = inherit Attribute new: unit -> unit member GetTestMethodAttribute: testMethodAttribute: TestMethodAttribute -> TestMethodAttribute
<summary> The test class attribute. </summary>

--------------------
TestClassAttribute() : TestClassAttribute
val lightBulb: LightBulb
val x: Given a LightBulb that has had its state set to true
val be: ('a -> 'a)
val True: NHamcrest.Core.CustomMatcher<obj>
Multiple items
val string: value: 'T -> string
<summary>Converts the argument to a string using <c>ToString</c>.</summary>
<remarks>For standard integer and floating point values the and any type that implements <c>IFormattable</c><c>ToString</c> conversion uses <c>CultureInfo.InvariantCulture</c>. </remarks>
<param name="value">The input value.</param>
<returns>The converted string.</returns>
<example id="string-example"><code lang="fsharp"></code></example>

--------------------
type string = System.String
<summary>An abbreviation for the CLI type <see cref="T:System.String" />.</summary>
<category>Basic Types</category>
val x: Given a LightBulb that has had its state set to false
val False: NHamcrest.Core.CustomMatcher<obj>
val l: int list
val frame: int
val s: int
val n: int
val tail: int list
val f: int
val ls: int list
Multiple items
Modul List aus Microsoft.FSharp.Collections
<summary>Contains operations for working with values of type <see cref="T:Microsoft.FSharp.Collections.list`1" />.</summary>
<namespacedoc><summary>Operations for collections such as lists, arrays, sets, maps and sequences. See also <a href="https://docs.microsoft.com/dotnet/fsharp/language-reference/fsharp-collection-types">F# Collection Types</a> in the F# Language Guide. </summary></namespacedoc>

--------------------
type List<'T> = | op_Nil | op_ColonColon of Head: 'T * Tail: 'T list interface IReadOnlyList<'T> interface IReadOnlyCollection<'T> interface IEnumerable interface IEnumerable<'T> member GetReverseIndex: rank: int * offset: int -> int member GetSlice: startIndex: int option * endIndex: int option -> 'T list static member Cons: head: 'T * tail: 'T list -> 'T list member Head: 'T member IsEmpty: bool member Item: index: int -> 'T with get ...
<summary>The type of immutable singly-linked lists.</summary>
<remarks>Use the constructors <c>[]</c> and <c>::</c> (infix) to create values of this type, or the notation <c>[1;2;3]</c>. Use the values in the <c>List</c> module to manipulate values of this type, or pattern match against the values directly. </remarks>
<exclude />
val fold: folder: ('State -> 'T -> 'State) -> state: 'State -> list: 'T list -> 'State
<summary>Applies a function to each element of the collection, threading an accumulator argument through the computation. Take the second argument, and apply the function to it and the first element of the list. Then feed this result into the function along with the second element and so on. Return the final result. If the input function is <c>f</c> and the elements are <c>i0...iN</c> then computes <c>f (... (f s i0) i1 ...) iN</c>.</summary>
<param name="folder">The function to update the state given the input elements.</param>
<param name="state">The initial state.</param>
<param name="list">The input list.</param>
<returns>The final state value.</returns>
<example id="fold-1"> Making the sum of squares for the first 5 natural numbers <code lang="fsharp"> (0, [1..5]) ||&gt; List.fold (fun s v -&gt; s + v * v) // evaluates 55 </code></example>
<example id="fold-2"> Shopping for fruits hungry, you tend to take more of each as the hunger grows <code lang="fsharp"> type Fruit = Apple | Pear | Orange type BagItem = { fruit: Fruit; quantity: int } let takeMore (previous: BagItem list) fruit = let toTakeThisTime = match previous with | bagItem :: otherBagItems -&gt; bagItem.quantity + 1 | [] -&gt; 1 { fruit = fruit; quantity = toTakeThisTime } :: previous let inputs = [ Apple; Pear; Orange ] ([], inputs) ||&gt; List.fold takeMore </code> Evaluates to <code lang="fsharp"> [{ fruit = Orange; quantity = 3 } { fruit = Pear; quantity = 2 } { fruit = Apple; quantity = 1 }] </code></example>
val scoreBowls: bowls: int list -> int
val bowls: int list
val scoreBowls': (int -> int list -> int -> int)
val current_score: int
val nextframe: (int list -> int -> int)
aktive Erkennung EndOfGame: int list * int -> Choice<int,int,(int * int list),(int * int list),int>
val score: int
aktive Erkennung IncompleteStrike: int list * int -> Choice<int,int,(int * int list),(int * int list),int>
aktive Erkennung Strike: int list * int -> Choice<int,int,(int * int list),(int * int list),int>
aktive Erkennung Normal: int list * int -> Choice<int,int,(int * int list),(int * int list),int>
aktive Erkennung Other: int list * int -> Choice<int,int,(int * int list),(int * int list),int>
val i: int