Skip to content

Commit

Permalink
Move to static methods for koans.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryan Riley committed Jun 7, 2012
1 parent 3aee06b commit b0c382d
Show file tree
Hide file tree
Showing 11 changed files with 75 additions and 86 deletions.
1 change: 1 addition & 0 deletions FSharpKoans.Core/Helpers.fs
@@ -1,5 +1,6 @@
[<AutoOpenAttribute>]
module FSharpKoans.Core.Helpers

open System
open NUnit.Framework

Expand Down
2 changes: 1 addition & 1 deletion FSharpKoans.Core/KoanAttribute.fs
Expand Up @@ -4,4 +4,4 @@ open System

[<AttributeUsage(AttributeTargets.Method, AllowMultiple = false)>]
type KoanAttribute () =
inherit Attribute()
inherit Attribute()
19 changes: 10 additions & 9 deletions FSharpKoans.Core/KoanContainer.fs
@@ -1,21 +1,22 @@
module FSharpKoans.Core.KoanContainer

open System
open System.IO
open System.Reflection

let findKoanMethods container =
let hasKoanAttribute (info:MethodInfo) =
info.GetCustomAttributes(typeof<KoanAttribute>, true)
|> Seq.isEmpty
|> not
container.GetType().GetMethods()
let hasKoanAttribute (info:MethodInfo) =
info.GetCustomAttributes(typeof<KoanAttribute>, true)
|> Seq.isEmpty
|> not

let findKoanMethods (container: Type) =
container.GetMethods(BindingFlags.Public ||| BindingFlags.Static)
|> Seq.filter hasKoanAttribute

let runKoans container =
let getKoanResult (m:MethodInfo) =
try
m.Invoke(container, [||]) |> ignore
m.Invoke(null, [||]) |> ignore
Success <| sprintf "%s has expanded your awareness." m.Name
with
| ex ->
Expand All @@ -24,4 +25,4 @@ let runKoans container =

container
|> findKoanMethods
|> Seq.map getKoanResult
|> Seq.map getKoanResult
2 changes: 1 addition & 1 deletion FSharpKoans.Core/KoanResult.fs
Expand Up @@ -16,4 +16,4 @@ module KoanResult =
let map f (x:KoanResult) =
match x with
| Success m -> Success <| f m
| Failure (m, e) -> Failure (f m, e)
| Failure (m, e) -> Failure (f m, e)
19 changes: 13 additions & 6 deletions FSharpKoans.Core/KoanRunner.fs
@@ -1,6 +1,8 @@
namespace FSharpKoans.Core

open System
open System.Collections.Generic
open System.Reflection

type KoanRunner(containers) =
let findFailureOrLastResult (values:seq<KoanResult>) =
Expand All @@ -19,16 +21,21 @@ type KoanRunner(containers) =
next
|> KoanResult.map (sprintf builderString current.Message)

let getContainerResult container =
let name = container.GetType().Name.ToString()
let getContainerResult (container: Type) =
let name = container.Name
let lineOne = sprintf "When contemplating %s:" name

container
|> KoanContainer.runKoans
container |> KoanContainer.runKoans
|> Seq.scan (buildKoanResult "%s\n %s") (Success lineOne)
|> findFailureOrLastResult

new () =
let containers =
Assembly.GetCallingAssembly().GetTypes()
|> Array.filter (not << Seq.isEmpty << KoanContainer.findKoanMethods)
KoanRunner(containers)

member this.ExecuteKoans =
member this.ExecuteKoans() =
let result =
containers
|> Seq.map getContainerResult
Expand All @@ -37,4 +44,4 @@ type KoanRunner(containers) =

match result with
| Success m -> Success (m.Replace("\n", Environment.NewLine))
| Failure (m, e) -> Failure (m.Replace("\n", Environment.NewLine), e)
| Failure (m, e) -> Failure (m.Replace("\n", Environment.NewLine), e)
21 changes: 11 additions & 10 deletions FSharpKoans.Test/FindingKoans.fs
@@ -1,4 +1,5 @@
module KoansRunner.Test.FindingKoans

open FSharpKoans.Core
open FSharpKoans.Core.KoanContainer

Expand All @@ -8,11 +9,11 @@ open System.IO

type TestContainer() =
[<Koan>]
member this.Koan1 () =
static member Koan1 () =
()

[<Koan>]
member this.Koan2() =
static member Koan2() =
()

let getKoanNames container =
Expand All @@ -23,33 +24,33 @@ let getKoanNames container =

[<Test>]
let ``getting koans from a container`` () =
let koanNames = getKoanNames <| new TestContainer()
let koanNames = getKoanNames typeof<TestContainer>
let expected = [ "Koan1"; "Koan2" ]
Assert.AreEqual(expected, koanNames)

type TestContainer2() =
[<Koan>]
member this.Z () =
static member Z () =
()

[<Koan>]
member this.A () =
static member A () =
()

[<Koan>]
member this.a () =
static member a () =
()

[<Koan>]
member this._0 () =
static member _0 () =
()

[<Koan>]
member this.``0`` () =
static member ``0`` () =
()

[<Test>]
let ``Koans are returned in defined order regardless of name`` () =
let koanNames = getKoanNames <| new TestContainer2()
let koanNames = getKoanNames typeof<TestContainer2>
let expected = [ "Z"; "A"; "a"; "_0"; "0" ]
Assert.AreEqual(expected, koanNames)
Assert.AreEqual(expected, koanNames)
16 changes: 8 additions & 8 deletions FSharpKoans.Test/GettingTheWholeOutput.fs
Expand Up @@ -4,35 +4,35 @@ open NUnit.Framework

type ContainerOne() =
[<Koan>]
member this.One() =
static member One() =
"FTW!"

[<Koan>]
member this.Two() =
static member Two() =
"FTW!"

[<Koan>]
member this.Three() =
static member Three() =
"FTW!"

type ContainerTwo() =
[<Koan>]
member this.Four() =
static member Four() =
"FTW!"

[<Koan>]
member this.Five() =
static member Five() =
Assert.Fail("Expected")


[<Koan>]
member this.Six() =
static member Six() =
"FTW!"

[<Test>]
let ``Output contains container name followed by koan results. Stops on failure`` () =
let runner = KoanRunner([ContainerOne(); ContainerTwo()])
let result = runner.ExecuteKoans
let runner = KoanRunner([| typeof<ContainerOne>; typeof<ContainerTwo> |])
let result = runner.ExecuteKoans()

let expected =
"
Expand Down
25 changes: 13 additions & 12 deletions FSharpKoans.Test/RunningKoans.fs
@@ -1,39 +1,40 @@
module KoansRunner.Test.RunningKoans

open FSharpKoans.Core
open NUnit.Framework

type FailureContainer() =
[<Koan>]
member this.FailureKoan() =
static member FailureKoan() =
Assert.Fail("expected failure")

type SuccessContainer() =
[<Koan>]
member this.SuccessKoan() =
static member SuccessKoan() =
"FTW!"

type SomeSuccesses() =
[<Koan>]
member this.One() =
static member One() =
"YAY"

[<Koan>]
member this.Two() =
static member Two() =
"WOOT"

type MixedBag() =
[<Koan>]
member this.One() =
static member One() =
Assert.Fail("Game over")

[<Koan>]
member this.Two() =
static member Two() =
"OH YEAH!"

[<Test>]
let ``A failing koan returns its exception`` () =
let result =
new FailureContainer()
typeof<FailureContainer>
|> KoanContainer.runKoans
|> Seq.head

Expand All @@ -47,7 +48,7 @@ let ``A failing koan returns its exception`` () =
[<Test>]
let ``A failing koan returns a failure message`` () =
let result =
new FailureContainer()
typeof<FailureContainer>
|> KoanContainer.runKoans
|> Seq.head

Expand All @@ -56,7 +57,7 @@ let ``A failing koan returns a failure message`` () =
[<Test>]
let ``A successful koans returns a success message`` () =
let result =
new SuccessContainer()
typeof<SuccessContainer>
|> KoanContainer.runKoans
|> Seq.head

Expand All @@ -65,7 +66,7 @@ let ``A successful koans returns a success message`` () =
[<Test>]
let ``The outcome of all successful koans is returned`` () =
let result =
new SomeSuccesses()
typeof<SomeSuccesses>
|> KoanContainer.runKoans
|> Seq.map (fun x -> x.Message)
|> Seq.reduce (fun x y -> x + System.Environment.NewLine + y)
Expand All @@ -80,7 +81,7 @@ let ``The outcome of all successful koans is returned`` () =
//might want to change this behavior
let ``Failed Koans don't stop the enumeration`` () =
let result =
new MixedBag()
typeof<MixedBag>
|> KoanContainer.runKoans
|> Seq.map (fun x -> x.Message)
|> Seq.reduce (fun x y -> x + System.Environment.NewLine + y)
Expand All @@ -90,4 +91,4 @@ let ``Failed Koans don't stop the enumeration`` () =
"One has damaged your karma." + System.Environment.NewLine +
"Two has expanded your awareness."

Assert.AreEqual(expected, result)
Assert.AreEqual(expected, result)
14 changes: 7 additions & 7 deletions FSharpKoans/AboutAsserts.fs
@@ -1,33 +1,33 @@
namespace FSharpKoans
open FSharpKoans.Core

type ``about asserts``() =
module ``about asserts`` =

// We shall contemplate truth by testing reality, via asserts.

[<Koan>]
member this.AssertTruth() =
let AssertTruth() =
// This should be true
Assert false
Assert false

(* Enlightenment may be more easily achieved with appropriate
messages. *)

[<Koan>]
member this.AssertWithMessage() =
let AssertWithMessage() =
AssertWithMessage false "This should be true -- Please fix this"

(* To understand reality, we must compare our expectations against
reality. *)

[<Koan>]
member this.AssertEquality() =
let AssertExpectation() =
let expected_value = 1 + 1
let actual_value = __

AssertEquality expected_value actual_value

// Sometimes we will ask you to fill in the values
[<Koan>]
member this.FillInValues() =
AssertEquality (1 + 1) __
let FillInValues() =
AssertEquality (1 + 1) __

0 comments on commit b0c382d

Please sign in to comment.