spectreconsole/spectre.console

How to use `TestConsole` for testing CLI prompts workflows?

MangelMaxime opened this issue · 3 comments

Hello,

I am working on a CLI tool and would like to test the workflow of it.

After some trial and error, and by looking at the source code of this project I was able to find the TestConsole class.

It allowed me to write code like that:

open Spectre.Console.Testing
open Spectre.Console

[<Test>]
let ``Prompt.commitType works`` () =
    let console = new TestConsole()
    console.Profile.Capabilities.Interactive <- true

    AnsiConsole.Console <- console

    console.Input.PushKey(ConsoleKey.DownArrow)
    console.Input.PushKey(ConsoleKey.Enter)

    let selectedCommitType = Prompt.commitType CommitParserConfig.Default

    Expect.equal
        selectedCommitType
        CommitParserConfig.Default.Types[1]

[<Test>]
let test () =
    let console = new TestConsole()
    console.Profile.Capabilities.Interactive <- true

    AnsiConsole.Console <- console

    console.Input.PushKey(ConsoleKey.DownArrow)
    console.Input.PushKey(ConsoleKey.Enter)
    console.Input.PushTextWithEnter("an amazing feature")

    let selectedCommitType = Prompt.commitType CommitParserConfig.Default
    let shortMessage = Prompt.shortMessage ()

    printfn "%A" selectedCommitType
    printfn "%A" shortMessage

I am not sure if using AnsiConsole.Console <- console is the correct way of doing it? I am asking because I didn't see something similar in spectre.console repository.

I am also wondering if I should not revert AnsiConsole.Console to its original value after the test?

You should test using the TestConsole, and not use AnsiConsole.Console at all.

Also, your control should accept an instance of IAnsiConsole, not working with AnsiConsole directly.

Oh I see, I didn't think about it this way.

So you mean that I should convert:

let shortMessage () =
    AnsiConsole.Clear()

    TextPrompt<string>("Short message:") |> AnsiConsole.Prompt

to

let shortMessage (console :IAnsiConsole) =
    console.Clear()

    TextPrompt<string>("Short message:") |> console.Prompt

and then pass either AnsiConsole.Console or new TestConsole()

Thank you