3 people like it.

MbUnit DSL

DSL for functional style, HUnit-like testing with MbUnit.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
49: 
50: 
51: 
52: 
53: 
54: 
55: 
56: 
57: 
58: 
59: 
60: 
61: 
62: 
63: 
64: 
65: 
66: 
open System.IO
open MbUnit.Framework

// DSL to define test suites and cases

let inline (->>) name tests =
    let suite = TestSuite(name)
    Seq.iter suite.Children.Add tests
    suite :> Test

let inline (-->) name (test: unit -> unit) =
    TestCase(name, Gallio.Common.Action test) :> Test

// Higher-order functions as setup/teardown

let withMemoryStream f () =
    use ms = new MemoryStream()
    f ms

let withTempFile f () =
    let file = Path.GetTempFileName()
    try 
        f file
    finally
        File.Delete file

// These can be easily composed:

let withMemoryStreamAndTempFile f =
    withMemoryStream (fun s -> withTempFile (fun t -> f s t) <| ())

// Test definition:

let tests = 
    [
        "A test suite" ->> [
            "2 + 2 = 4" --> 
                fun _ -> Assert.AreEqual(4, 2+2)
            "A test subsuite" ->> [
                // generate parameterized tests
                for i in [0..3] do
                for j in [1..4] do
                for k in [3..10] ->
                    sprintf "%d + %d = %d" i j k --> 
                        fun _ -> Assert.AreEqual(k, i+j)
            ]
        ]
        "Another suite" ->> [
            "File exists" -->
                withTempFile (Assert.IsTrue << File.Exists)
            "Write 'Hello World!'" -->
                withMemoryStreamAndTempFile
                    (fun ms tf ->
                        use w = new StreamWriter(ms)
                        w.Write "Hello World!"
                        w.Flush()
                        ms.Position <- 0L
                        File.WriteAllBytes(tf, ms.ToArray())
                        Assert.AreEqual(12L, FileInfo(tf).Length))
        ]
    ]

// boilerplate, MbUnit doesn't allow StaticTestFactory on F# functions yet
type Tests() =
    [<StaticTestFactory>]
    static member factory() = tests
namespace System
namespace System.IO
val name : 'a
val tests : seq<'b>
val suite : obj
module Seq

from Microsoft.FSharp.Collections
val iter : action:('T -> unit) -> source:seq<'T> -> unit

Full name: Microsoft.FSharp.Collections.Seq.iter
val test : (unit -> unit)
type unit = Unit

Full name: Microsoft.FSharp.Core.unit
val withMemoryStream : f:(MemoryStream -> 'a) -> unit -> 'a

Full name: Script.withMemoryStream
val f : (MemoryStream -> 'a)
val ms : MemoryStream
Multiple items
type MemoryStream =
  inherit Stream
  new : unit -> MemoryStream + 6 overloads
  member CanRead : bool
  member CanSeek : bool
  member CanWrite : bool
  member Capacity : int with get, set
  member Flush : unit -> unit
  member GetBuffer : unit -> byte[]
  member Length : int64
  member Position : int64 with get, set
  member Read : buffer:byte[] * offset:int * count:int -> int
  ...

Full name: System.IO.MemoryStream

--------------------
MemoryStream() : unit
MemoryStream(capacity: int) : unit
MemoryStream(buffer: byte []) : unit
MemoryStream(buffer: byte [], writable: bool) : unit
MemoryStream(buffer: byte [], index: int, count: int) : unit
MemoryStream(buffer: byte [], index: int, count: int, writable: bool) : unit
MemoryStream(buffer: byte [], index: int, count: int, writable: bool, publiclyVisible: bool) : unit
val withTempFile : f:(string -> 'a) -> unit -> 'a

Full name: Script.withTempFile
val f : (string -> 'a)
val file : string
type Path =
  static val DirectorySeparatorChar : char
  static val AltDirectorySeparatorChar : char
  static val VolumeSeparatorChar : char
  static val InvalidPathChars : char[]
  static val PathSeparator : char
  static member ChangeExtension : path:string * extension:string -> string
  static member Combine : [<ParamArray>] paths:string[] -> string + 3 overloads
  static member GetDirectoryName : path:string -> string
  static member GetExtension : path:string -> string
  static member GetFileName : path:string -> string
  ...

Full name: System.IO.Path
Path.GetTempFileName() : string
type File =
  static member AppendAllLines : path:string * contents:IEnumerable<string> -> unit + 1 overload
  static member AppendAllText : path:string * contents:string -> unit + 1 overload
  static member AppendText : path:string -> StreamWriter
  static member Copy : sourceFileName:string * destFileName:string -> unit + 1 overload
  static member Create : path:string -> FileStream + 3 overloads
  static member CreateText : path:string -> StreamWriter
  static member Decrypt : path:string -> unit
  static member Delete : path:string -> unit
  static member Encrypt : path:string -> unit
  static member Exists : path:string -> bool
  ...

Full name: System.IO.File
File.Delete(path: string) : unit
val withMemoryStreamAndTempFile : f:(MemoryStream -> string -> 'a) -> (unit -> 'a)

Full name: Script.withMemoryStreamAndTempFile
val f : (MemoryStream -> string -> 'a)
val s : MemoryStream
val t : string
val tests : obj list

Full name: Script.tests
val i : int
val j : int
val k : int
val sprintf : format:Printf.StringFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
File.Exists(path: string) : bool
val tf : string
val w : StreamWriter
Multiple items
type StreamWriter =
  inherit TextWriter
  new : stream:Stream -> StreamWriter + 6 overloads
  member AutoFlush : bool with get, set
  member BaseStream : Stream
  member Close : unit -> unit
  member Encoding : Encoding
  member Flush : unit -> unit
  member Write : value:char -> unit + 3 overloads
  static val Null : StreamWriter

Full name: System.IO.StreamWriter

--------------------
StreamWriter(stream: Stream) : unit
StreamWriter(path: string) : unit
StreamWriter(stream: Stream, encoding: System.Text.Encoding) : unit
StreamWriter(path: string, append: bool) : unit
StreamWriter(stream: Stream, encoding: System.Text.Encoding, bufferSize: int) : unit
StreamWriter(path: string, append: bool, encoding: System.Text.Encoding) : unit
StreamWriter(path: string, append: bool, encoding: System.Text.Encoding, bufferSize: int) : unit
TextWriter.Write(value: obj) : unit
   (+0 other overloads)
TextWriter.Write(value: decimal) : unit
   (+0 other overloads)
TextWriter.Write(value: float) : unit
   (+0 other overloads)
TextWriter.Write(value: float32) : unit
   (+0 other overloads)
TextWriter.Write(value: uint64) : unit
   (+0 other overloads)
TextWriter.Write(value: int64) : unit
   (+0 other overloads)
TextWriter.Write(value: uint32) : unit
   (+0 other overloads)
TextWriter.Write(value: int) : unit
   (+0 other overloads)
TextWriter.Write(value: bool) : unit
   (+0 other overloads)
StreamWriter.Write(value: string) : unit
   (+0 other overloads)
StreamWriter.Flush() : unit
property MemoryStream.Position: int64
File.WriteAllBytes(path: string, bytes: byte []) : unit
MemoryStream.ToArray() : byte []
Multiple items
type FileInfo =
  inherit FileSystemInfo
  new : fileName:string -> FileInfo
  member AppendText : unit -> StreamWriter
  member CopyTo : destFileName:string -> FileInfo + 1 overload
  member Create : unit -> FileStream
  member CreateText : unit -> StreamWriter
  member Decrypt : unit -> unit
  member Delete : unit -> unit
  member Directory : DirectoryInfo
  member DirectoryName : string
  member Encrypt : unit -> unit
  ...

Full name: System.IO.FileInfo

--------------------
FileInfo(fileName: string) : unit
Multiple items
type Tests =
  new : unit -> Tests
  static member factory : unit -> obj list

Full name: Script.Tests

--------------------
new : unit -> Tests
static member Tests.factory : unit -> obj list

Full name: Script.Tests.factory
Next Version Raw view Test code New version

More information

Link:http://fssnip.net/b5
Posted:12 years ago
Author:Mauricio Scheffer
Tags: mbunit , testing