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?
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.
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.