Thanks to a recent article by Cameron Taggart it is now possible to Create F# Silverlight Apps from Visual Studio 2010 Shell. This means that you now don’t need to use a C# project to build the XAP file; which previously outside of VS2010 Pro meant resorting to building the XAP with Visual Web Developer 2010 Express and F# libraries in the VS2010 shell. The only issue I’ve found with this solution is that it is not possible to directly add new files to the F# application project, but you can easily add existing files.
From his example I've created a small reference Silverlight solution with a Tic-tac-toe theme:
- TicTacToe: the Silverlight application
- Game: a Silverlight library with some game logic
- TicTacToe.Test: a Silverlight Unit Test project for testing game logic
If you have Silverlight 4 installed you should see a Tic-tac-toe board that you can mark:
The Silverlight Unit Test project contains a small Behavioural Driven Development (BDD) example to test winning positions using TickSpec:
Feature: Winning positions
Scenario: Winning positions
Given a board layout:
| 1 | 2 | 3 |
| <O> | <O> | <X> |
| <O> | | |
| <X> | | <X> |
When a player marks <X> at <row> <col>
Then <X> wins
Examples:
| row | col |
| middle | right |
| middle | middle |
| bottom | middle |
Examples:
| X | O |
| X | O |
| O | X |
The example above shows that TickSpec will execute all combinations for multiple examples blocks. This makes it possible to also run the tests with X’s swapped for O’s:
The steps in the scenario are mapped to attributed F# tick methods:
let [<Given>] ``a board layout:`` (table:Table) =
table.Rows |> Seq.iteri (fun y row ->
row |> Seq.iteri (fun x value -> board.[x,y] <- parseMark value)
)
let [<When>] ``a player marks (X|O) at (top|middle|bottom) (left|middle|right)``
(mark:string,Row row,Col col) =
board.[col,row] <- parseMark mark
let [<Then>] ``(X|O) wins`` (mark:string) =
Game.mark <- parseMark mark |> Option.get
let line = winningLine()
Assert.IsTrue(line.IsSome)
With the column and row positions parsed with F# Active Patterns:
let (|Col|) = function
| "left" -> 0 | "middle" -> 1 | "right" -> 2
| s -> invalidCast s
let (|Row|) = function
| "top" -> 0 | "middle" -> 1 | "bottom" -> 2
| s -> invalidCast s
If you are interested in learning more about BDD & TickSpec there is a free F#unctional Londoners Meetup Group evening event on Wed 24th Nov 2010 at Skills Matter:
Teaser for Tomas Petricek’s talk on his Agent’s:
References:
Source code: TicTacToe.zip (334.65 kb)