Help Testing Repl Modes

I’m developing a package for letting others define their own REPL modes but before I can put it on METADATA I need to develop tests for it. Unfortunately, in order to actually perform tests on it, I need a running REPL which is proving to be quite a hassle.

The main issue is that my tests rely on inspecting Base.active_repl and making sure that ReplMaker is properly modifying the active repl, but in a standard pkg> test script there is no REPL defined. Is there any way to make the test script get run with a REPL defined and active? Or is there some Julia command I can run from inside the test script to spawn the REPL?

2 Likes

I use VT100.jl to test my RPEL modes:

Another way is to spawn a julia process that we write commands into. If we want to test for example the st command of the Pkg repl mode we could do something like

Base.include(@__MODULE__, joinpath(Sys.BINDIR, "..", "share", "julia", "test", "testhelpers", "FakePTYs.jl"))
import .FakePTYs: open_fake_pty

slave, master = open_fake_pty()

CTRL_C = '\x03'

# Script that we want the REPL to execute, here simply st for Pkg REPLMode
test_script = """
]st
$CTRL_C"""

function run_test()
    slave, master = open_fake_pty()
    # Start a julia process
    p = run(`$(Base.julia_cmd()) --history-file=no --startup-file=no`, slave, slave, slave; wait=false)
    
    # Read until the prompt
    readuntil(master, "julia>", keep=true)
    done = false
    repl_output_buffer = IOBuffer()

    # A task that just keeps reading the output
    @async begin
        while true
            done && break
            write(repl_output_buffer, readavailable(master))
        end
    end

    # Execute our "script"
    for l in split(test_script, '\n'; keepempty=false)
        write(master, l, '\n')
    end

    # Let the REPL exit
    write(master, "exit()\n")
    wait(p)
    done = true

    # Gather the output
    repl_output = String(take!(repl_output_buffer))
    println(repl_output)
end

The repl_output could be tested for what you expect.

3 Likes

Thanks so much for the thorough example and help! I really appreciate it. This was helpful.

The tests for the Julia REPL are also likely useful to look at https://github.com/JuliaLang/julia/blob/master/stdlib/REPL/test/repl.jl#L93

Yeah, my first efforts were directed at that but the fake repl implemented there was missing some important features for my purposes such as repl.interface and I was a bit over my head in understanding most of what the test set up was doing anyway.