@@ -245,128 +245,137 @@ module Reporters =
245245type TestContext = {
246246 ParentBeforeHooks: HookFunction list
247247 ParentAfterHooks: HookFunction list
248- Reporter: ITestReporter
249248 Log: string -> unit
250- Order: CollectedStep list -> CollectedStep list // <-- Add this line
251249}
252250with
253251 static member New = {
254252 ParentBeforeHooks = []
255253 ParentAfterHooks = []
256- Reporter = Reporters.ConsoleReporter() :> ITestReporter
257254 Log = printfn " %s "
258- Order = id // Default: preserve order
259255 }
260256
261- module Runner =
262- let collectDescribes ( describe : Describe ) =
263- let rec loop parentPath parentBefore parentAfter ( d : Describe ) =
264- let beforeHooks , afterHooks = d.CollectHooks()
265- let beforeHooks = List.rev beforeHooks @ parentBefore
266- let afterHooks = parentAfter @ List.rev afterHooks
267- let path = parentPath @ [ d.Name]
268- let steps =
269- d.Steps
270- |> List.map ( function
271- | ItStep it -> CollectedIt ( Path path, beforeHooks, afterHooks, it)
272- | LogStatementStep log -> CollectedLog ( Path path, log))
273- let children =
274- d.Children
275- |> List.map ( loop path beforeHooks afterHooks)
276- {
277- Name = d.Name
278- Path = Path path
279- Steps = steps
280- Children = children
257+ [<AbstractClass>]
258+ type Runner () =
259+ abstract member Run: Describe -> Async < TestResult []>
260+ abstract member CollectDescribes: Describe -> CollectedDescribe
261+ abstract member RunTestCase: Path -> It -> HookFunction list -> HookFunction list -> Async < TestResult >
262+ abstract member RunCollectedDescribe: CollectedDescribe -> Async < TestResult []>
263+
264+ type StepsOrderingDelegate = CollectedStep list -> CollectedStep list
265+ type DefaultRunner ( reporter : ITestReporter , order : StepsOrderingDelegate ) =
266+ inherit Runner()
267+ override this.Run suite =
268+ async {
269+ reporter.Begin suite.TotalCount
270+ let collected = this.CollectDescribes suite
271+ let! testResults = this.RunCollectedDescribe collected
272+ reporter.EndSuite( suite.Name, Path [ suite.Name])
273+ reporter.End testResults
274+ return testResults
281275 }
282- loop [] [] [] describe
283-
284- let private runTestCase path ( testCase : It ) beforeHooks afterHooks : Async < TestResult > =
285- async {
286- // setup logging functions
287- let info ' , debug' = info, debug
288- use _ = { new System.IDisposable with
289- member _.Dispose () = info <- info'; debug <- debug' }
290- let mutable logs = []
291- info <- fun s -> logs <- Info s :: logs
292- debug <- fun s -> logs <- Debug s :: logs
293- for hookFunction in beforeHooks do
294- do ! hookFunction()
295- let! result =
296- match testCase.Body with
297- | Some body ->
298- async {
299- try
300- do ! body()
301- return Passed ( path, testCase.Name)
302- with ex ->
303- return Failed ( path, testCase.Name, ex)
304- }
305- | None ->
306- async {
307- return Pending ( path, testCase.Name)
308- }
309- for hookFunction in afterHooks do
310- do ! hookFunction()
311- return {
312- Outcome = result
313- Logs = List.rev logs
276+ override _.CollectDescribes describe =
277+ let rec loop parentPath parentBefore parentAfter ( d : Describe ) =
278+ let beforeHooks , afterHooks = d.CollectHooks()
279+ let beforeHooks = List.rev beforeHooks @ parentBefore
280+ let afterHooks = parentAfter @ List.rev afterHooks
281+ let path = parentPath @ [ d.Name]
282+ let steps =
283+ d.Steps
284+ |> List.map ( function
285+ | ItStep it -> CollectedIt ( Path path, beforeHooks, afterHooks, it)
286+ | LogStatementStep log -> CollectedLog ( Path path, log))
287+ let children =
288+ d.Children
289+ |> List.map ( loop path beforeHooks afterHooks)
290+ {
291+ Name = d.Name
292+ Path = Path path
293+ Steps = steps
294+ Children = children
295+ }
296+ loop [] [] [] describe
297+
298+ override this.RunTestCase ( path : Path ) ( testCase : It ) ( beforeHooks : HookFunction list ) ( afterHooks : HookFunction list ): Async < TestResult > =
299+ async {
300+ // setup logging functions
301+ let info ' , debug' = info, debug
302+ use _ = { new System.IDisposable with
303+ member _.Dispose () = info <- info'; debug <- debug' }
304+ let mutable logs = []
305+ info <- fun s -> logs <- Info s :: logs
306+ debug <- fun s -> logs <- Debug s :: logs
307+ for hookFunction in beforeHooks do
308+ do ! hookFunction()
309+ let! result =
310+ match testCase.Body with
311+ | Some body ->
312+ async {
313+ try
314+ do ! body()
315+ return Passed ( path, testCase.Name)
316+ with ex ->
317+ return Failed ( path, testCase.Name, ex)
318+ }
319+ | None ->
320+ async {
321+ return Pending ( path, testCase.Name)
322+ }
323+ for hookFunction in afterHooks do
324+ do ! hookFunction()
325+ return {
326+ Outcome = result
327+ Logs = List.rev logs
328+ }
314329 }
315- }
316330
317- let rec runCollectedDescribe ( context : TestContext ) ( cd : CollectedDescribe ) =
318- async {
319- context.Reporter .BeginSuite( cd.Name, cd.Path)
320- let! stepResults =
321- cd.Steps
322- |> context.Order
323- |> List.map ( function
324- | CollectedIt ( path, beforeHooks, afterHooks, it) ->
331+ override this.RunCollectedDescribe ( cd : CollectedDescribe ): Async < TestResult array > =
332+ async {
333+ reporter .BeginSuite( cd.Name, cd.Path)
334+ let! stepResults =
335+ cd.Steps
336+ |> order
337+ |> List.map ( function
338+ | CollectedIt ( path, beforeHooks, afterHooks, it) ->
325339 async {
326- let! result = runTestCase path it beforeHooks afterHooks
340+ let! result = this.RunTestCase path it beforeHooks afterHooks
327341 for log in result.Logs do
328342 match log with
329- | Info message -> context.Reporter .Info( message, path)
330- | Debug message -> context.Reporter .Debug( message, path)
331- context.Reporter .ReportResult( result, path)
343+ | Info message -> reporter .Info( message, path)
344+ | Debug message -> reporter .Debug( message, path)
345+ reporter .ReportResult( result, path)
332346 return Some result
333347 }
334- | CollectedLog ( path, log) ->
348+ | CollectedLog ( path, log) ->
335349 async {
336350 match log with
337- | Info message -> context.Reporter .Info( message, path)
338- | Debug message -> context.Reporter .Debug( message, path)
351+ | Info message -> reporter .Info( message, path)
352+ | Debug message -> reporter .Debug( message, path)
339353 return None
340354 })
341- |> Async.Sequential
342- let! childResults =
343- cd.Children
344- |> List.map ( runCollectedDescribe context)
345- |> Async.Sequential
346- context.Reporter.EndSuite( cd.Name, cd.Path)
347-
348- let allResults =
349- Array.concat [
350- Array.choose id stepResults
351- Array.concat childResults
352- ]
353- return allResults
354- }
355+ |> Async.Sequential
356+ let! childResults =
357+ cd.Children
358+ |> List.map this.RunCollectedDescribe
359+ |> Async.Sequential
360+ reporter.EndSuite( cd.Name, cd.Path)
361+ let allResults =
362+ Array.concat [
363+ Array.choose id stepResults
364+ Array.concat childResults
365+ ]
366+ return allResults
367+ }
355368
356- let runTestSuiteWithContext ( context : TestContext ) ( suite : Describe ) =
369+ let runTestSuiteCustom ( runner : Runner ) ( suite : Describe ) =
357370 async {
358- context.Reporter.Begin suite.TotalCount
359- let collected = Runner.collectDescribes suite
360- let! testResults = Runner.runCollectedDescribe context collected
361- context.Reporter.EndSuite( suite.Name, Path [ suite.Name])
362- context.Reporter.End testResults
363- return testResults
371+ return ! runner.Run suite
364372 }
365373
366374let runTestSuite ( describe : Describe ) =
367- runTestSuiteWithContext
368- TestContext.New
369- describe
375+ async {
376+ let reporter = Reporters.ConsoleReporter() :> ITestReporter
377+ return ! runTestSuiteCustom ( DefaultRunner( reporter, id)) describe
378+ }
370379
371380[<AutoOpen>]
372381module Constraints =
0 commit comments