Reputation: 11595
What's the difference between my actual union case value and the expected value?
I have the following test:
[<Test>]
let ``black checker jumps to king``() =
let redChecker = { RedChecker.Position= { X=1 ; Y=6 } }
let target = (redChecker, [redChecker])
{ BlackChecker.Position= { X=0 ; Y=5 } } |> jumpRed target
|> fst
|> should equal (BlackKing { BlackKing.Position= { X=2 ; Y=7 } })
Here's the actual result when executing the test operation in the interactive window:
val redChecker : RedChecker = {Position = {X = 1;
Y = 6;};}
val target : RedChecker * RedChecker list =
({Position = {X = 1;
Y = 6;};}, [{Position = {X = 1;
Y = 6;};}])
val it : Checker = BlackKing {Position = {X = 2;
Y = 7;};}
I see that a BlackKing value is returned with xy being (2,7). Thus, I'm verifying in my test that union case value with that specific xy value.
I'm just not seeing why my test is failing.
Any suggestions?
Appendix:
open NUnit.Framework
open FsUnit
(* Types *)
type North = NorthEast | NorthWest
type South = SouthEast | SouthWest
type Direction =
| NorthEast
| NorthWest
| SouthEast
| SouthWest
type Position = { X:int; Y:int }
type BlackChecker = { Position:Position }
type RedChecker = { Position:Position }
type BlackKing = { Position:Position }
type RedKing = { Position:Position }
type Checker =
| BlackChecker of BlackChecker
| RedChecker of RedChecker
| BlackKing of BlackKing
| RedKing of RedKing
type King =
| BlackKing of BlackKing
| RedKing of RedKing
(* Functions *)
let rec remove item list = list |> List.filter (fun x -> x <> item)
let setRowPosition y1 y2 y3 index =
match index with
| x when x < 4 -> { X=x; Y=y1 }
| x when x < 8 -> { X=x-4; Y=y2 }
| _ -> { X=index-8; Y=y3 }
let initializeBlack () =
let setPosition index =
index |> setRowPosition 7 6 5
let blackCheckers = List.init 12 setPosition |> List.map (fun pos -> { BlackChecker.Position= { X=pos.X; Y=pos.Y } })
blackCheckers
let initializeRed () =
let setPosition index =
index |> setRowPosition 0 1 2
let redCheckers = List.init 12 setPosition |> List.map (fun pos -> { RedChecker.Position= { X=pos.X; Y=pos.Y } })
redCheckers
let set (x, y) positions (position:Position) =
match not (positions |> List.exists (fun pos -> pos = { X=x; Y=y })) with
| true -> { X=x; Y=y }
| false -> position
let moveBlack direction positions (checker:BlackChecker) =
let position = checker.Position
match direction with
| North.NorthEast -> { BlackChecker.Position= (positions, position) ||> set ((position.X + 1), (position.Y + 1 )) }
| North.NorthWest -> { BlackChecker.Position= (positions, position) ||> set ((position.X - 1), (position.Y + 1 )) }
let moveRed direction positions (checker:RedChecker) =
let position = checker.Position
match direction with
| South.SouthEast -> { RedChecker.Position= (positions, position) ||> set ((position.X + 1), (position.Y - 1 )) }
| South.SouthWest -> { RedChecker.Position= (positions, position) ||> set ((position.X - 1), (position.Y - 1 )) }
let moveKing direction positions (king:King) =
let position = match king with
| BlackKing bk -> bk.Position
| RedKing rk -> rk.Position
let result = match direction with
| NorthEast -> (positions, position) ||> set ((position.X + 1), (position.Y + 1 ))
| NorthWest -> (positions, position) ||> set ((position.X - 1), (position.Y + 1 ))
| SouthEast -> (positions, position) ||> set ((position.X + 1), (position.Y - 1 ))
| SouthWest -> (positions, position) ||> set ((position.X - 1), (position.Y - 1 ))
match king with
| BlackKing _ -> BlackKing { BlackKing.Position= result }
| RedKing _ -> RedKing { RedKing.Position= result }
let jump target yDirection source =
let updateX value = { X=target.X + value
Y=target.Y + yDirection }
match source with
| position when position.Y + yDirection = target.Y &&
position.X + 1 = target.X -> updateX 1
| position when position.Y + yDirection = target.Y &&
position.X - 1 = target.X -> updateX -1
| _ -> source
let jumpRed ((redChecker:RedChecker), (redCheckers:RedChecker list)) (blackChecker:BlackChecker) =
let yIncrementValue = 1
let maxY = 7
let position = blackChecker.Position |> jump redChecker.Position yIncrementValue
match position with
| pos when pos = blackChecker.Position -> BlackChecker { blackChecker with Position= position }, redCheckers
| pos when pos.Y = maxY -> Checker.BlackKing { BlackKing.Position=position }, redCheckers |> remove redChecker
| _ -> BlackChecker { blackChecker with Position= position }, redCheckers |> remove redChecker
let jumpBlack ((blackChecker:BlackChecker),(blackCheckers:BlackChecker list)) (redChecker:RedChecker) =
let yIncrementValue = -1
let minY = 0
let position = redChecker.Position |> jump blackChecker.Position yIncrementValue
match position with
| pos when pos = redChecker.Position -> RedChecker { redChecker with Position= position }, blackCheckers
| pos when pos.Y = minY -> Checker.RedKing { RedKing.Position=position }, blackCheckers |> remove blackChecker
| _ -> RedChecker { redChecker with Position= position }, blackCheckers |> remove blackChecker
Upvotes: 0
Views: 58
Reputation: 6527
Well this statement
{ BlackChecker.Position= { X=0 ; Y=5 } } |> jumpRed target
|> fst
gives:
val it : Checker = BlackKing {Position = {X = 2;
Y = 7;};}
It is of type Checker
. On the other hand:
(BlackKing { BlackKing.Position= { X=2 ; Y=7 } })
gives:
val it : King = BlackKing {Position = {X = 2;
Y = 7;};}
It is of type King
. They aren't the same types...
If you want to compare them you need to unwrap the BlackKing type inside the things you want to compare via pattern matching.
Upvotes: 2