Skip to content

Commit

Permalink
Add testset for Runic.main
Browse files Browse the repository at this point in the history
  • Loading branch information
fredrikekre committed Nov 6, 2024
1 parent 0b75076 commit 21cbf72
Show file tree
Hide file tree
Showing 2 changed files with 361 additions and 2 deletions.
15 changes: 13 additions & 2 deletions src/main.jl
Original file line number Diff line number Diff line change
Expand Up @@ -319,14 +319,25 @@ function main(argv)
if print_progress
@assert inputfile != "-"
input_pretty = relpath(inputfile)
if Sys.iswindows()
input_pretty = replace(input_pretty, "\\" => "/")

Check warning on line 323 in src/main.jl

View check run for this annotation

Codecov / codecov/patch

src/main.jl#L323

Added line #L323 was not covered by tests
end
if check
str = "Checking `$(input_pretty)` "
ndots = 80 - textwidth(str) - 1 - 1
dots = ndots > 0 ? "."^ndots : ""
printstyled(stderr, str * dots * " "; color = :blue)
else
to = output.output_is_samefile ? " " : " -> `$(relpath(output.file))` "
str = "Formatting `$(inputfile)`$(to)"
if output.output_is_samefile
output_pretty = " "
else
output_pretty = relpath(output.file)
if Sys.iswindows()
output_pretty = replace(output_pretty, "\\" => "/")

Check warning on line 336 in src/main.jl

View check run for this annotation

Codecov / codecov/patch

src/main.jl#L336

Added line #L336 was not covered by tests
end
output_pretty = " -> `$(output_pretty)` "
end
str = "Formatting `$(input_pretty)`$(output_pretty)"
ndots = 80 - textwidth(str) - 1 - 1
dots = ndots > 0 ? "."^ndots : ""
printstyled(stderr, str * dots * " "; color = :blue)
Expand Down
348 changes: 348 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1454,6 +1454,354 @@ end
end
end

@testset "Runic.main" begin
bad = "1+1"
good = "1 + 1\n"

# Utils
function cdtmp(f)
return mktempdir(tmp -> cd(f, tmp))
end
function runic(std_in::String)
return runic(String[], std_in)
end
function runic(argv::Vector{String} = String[], std_in::String = "")
rc, stdout_str, stderr_str = mktemp() do stdin_path, stdin
write(stdin_path, std_in)
mktemp() do stdout_path, stdout
mktemp() do stderr_path, stderr
rc = redirect_stdio(() -> Runic.main(copy(argv)); stdin, stdout, stderr)
close(stderr)
close(stdout)
return rc, read(stdout_path, String), read(stderr_path, String)
end
end
end
return rc, stdout_str, stderr_str
end

# runic --help
let (rc, fd1, fd2) = runic(["--help"])
@test rc == 0
@test occursin("Runic.main - format Julia source code", fd1)
@test isempty(fd2)
end

# runic <stdin >stdout
for argv in [
String[], ["-"],
["--output=-"], ["-o", "-"],
["--output=-", "-"], ["-o", "-", "-"],
]
rc, fd1, fd2 = runic(argv, bad)
@test rc == 0
@test occursin(good, fd1)
@test isempty(fd2)
end

# runic --output=out.jl <stdin
cdtmp() do
f_out = "out.jl"
for argv in [
["--output=$f_out"], ["-o", f_out],
["--output=$f_out", "-"], ["-o", f_out, "-"],
]
rm(f_out, force = true)
rc, fd1, fd2 = runic(argv, bad)
@test rc == 0
@test isempty(fd1)
@test isempty(fd2)
@test read(f_out, String) == good
end
end

# runic in.jl >stdout
cdtmp() do
f_in = "in.jl"
write(f_in, bad)
for argv in [[f_in], ["--output=-", f_in], ["-o", "-", f_in]]
rc, fd1, fd2 = runic(argv)
@test rc == 0
@test occursin(good, fd1)
@test isempty(fd2)
@test read(f_in, String) == bad
end
end

# runic --output=out.jl in.jl
cdtmp() do
f_in = "in.jl"
write(f_in, bad)
f_out = "out.jl"
for argv in [["--output=$f_out", f_in], ["-o", f_out, f_in]]
rm(f_out, force = true)
rc, fd1, fd2 = runic(argv)
@test rc == 0
@test isempty(fd1)
@test occursin("Formatting `in.jl` -> `out.jl` ...", fd2)
@test occursin("", fd2)
@test !occursin("", fd2)
@test read(f_out, String) == good
@test read(f_in, String) == bad
end
end

# runic --inplace in.jl (bad input)
cdtmp() do
f_in = "in.jl"
for argv in [["--inplace", f_in], ["-i", f_in]]
write(f_in, bad)
rc, fd1, fd2 = runic(argv)
@test rc == 0
@test isempty(fd1)
@test occursin("Formatting `in.jl` ...", fd2)
@test occursin("", fd2)
@test !occursin("", fd2)
@test read(f_in, String) == good
end
end

# runic --inplace in.jl (good input)
cdtmp() do
f_in = "in.jl"
for argv in [["--inplace", f_in], ["-i", f_in]]
write(f_in, good)
rc, fd1, fd2 = runic(argv)
@test rc == 0
@test isempty(fd1)
@test occursin("Formatting `in.jl` ...", fd2)
@test occursin("", fd2)
@test !occursin("", fd2)
@test read(f_in, String) == good
end
end

# runic --inplace in/
cdtmp() do
fgood = "good.jl"
mkdir("src")
fbad = joinpath("src", "bad.jl")
mkdir(".git")
gitfile = joinpath(".git", "git.jl")
write(gitfile, "this is not a Julia file")
markdownfile = "markdown.md"
write(markdownfile, "this is not a Julia file")
for argv in [["--inplace", "."], ["-i", "."], ["-i", ".", "src"]]
write(fgood, good)
write(fbad, bad)
rc, fd1, fd2 = runic(argv)
@test rc == 0
@test isempty(fd1)
@test occursin("Formatting `good.jl` ...", fd2)
@test occursin("Formatting `src/bad.jl` ...", fd2)
@test occursin("", fd2)
@test !occursin("", fd2)
@test !occursin("git.jl", fd2)
@test !occursin("markdown.jl", fd2)
@test read(fgood, String) == read(fbad, String) == good
end
end

# runic --check in.jl (bad input)
cdtmp() do
f_in = "in.jl"
for argv in [["--check", f_in], ["-c", f_in]]
write(f_in, bad)
rc, fd1, fd2 = runic(argv)
@test rc == 1
@test isempty(fd1)
@test occursin("Checking `in.jl` ...", fd2)
@test !occursin("", fd2)
@test occursin("", fd2)
@test read(f_in, String) == bad
end
end

# runic --check in.jl (good input)
cdtmp() do
f_in = "in.jl"
for argv in [["--check", f_in], ["-c", f_in]]
write(f_in, good)
rc, fd1, fd2 = runic(argv)
@test rc == 0
@test isempty(fd1)
@test occursin("Checking `in.jl` ...", fd2)
@test occursin("", fd2)
@test !occursin("", fd2)
@test read(f_in, String) == good
end
end

# runic --check in/
cdtmp() do
fgood = "good.jl"
mkdir("src")
fbad = joinpath("src", "bad.jl")
mkdir(".git")
gitfile = joinpath(".git", "git.jl")
write(gitfile, "this is not a Julia file")
markdownfile = "markdown.md"
write(markdownfile, "this is not a Julia file")
for argv in [["--check", "."], ["-c", "."]]
write(fgood, good)
write(fbad, bad)
rc, fd1, fd2 = runic(argv)
@test rc == 1
@test isempty(fd1)
@test occursin("Checking `good.jl` ...", fd2)
@test occursin("Checking `src/bad.jl` ...", fd2)
@test occursin("", fd2)
@test occursin("", fd2)
@test !occursin("git.jl", fd2)
@test !occursin("markdown.jl", fd2)
@test read(fgood, String) == good
@test read(fbad, String) == bad
end
end

# runic --check --diff in.jl
if Sys.which("git") !== nothing
cdtmp() do
f_in = "in.jl"
for argv in [["--check", "--diff", f_in], ["-c", "-d", f_in]]
write(f_in, bad)
rc, fd1, fd2 = runic(argv)
@test rc == 1
@test isempty(fd1)
@test occursin("Checking `in.jl` ...", fd2)
@test !occursin("", fd2)
@test occursin("", fd2)
@test occursin("diff --git", fd2)
@test occursin("-1+1", fd2)
@test occursin("+1 + 1", fd2)
@test read(f_in, String) == bad
end
end
end

# Error paths
# runic -o
let (rc, fd1, fd2) = runic(["-o"])
@test rc == 1
@test isempty(fd1)
@test occursin("expected output file argument after `-o`", fd2)
end

# runic in.jl -
let (rc, fd1, fd2) = runic(["in.jl", "-"])
@test rc == 1
@test isempty(fd1)
@test occursin("input `-` can not be used with multiple files", fd2)
end

# runic --inplace --check (TODO: perhaps this should be allowed?)
let (rc, fd1, fd2) = runic(["--inplace", "--check"])
@test rc == 1
@test isempty(fd1)
@test occursin("options `--inplace` and `--check` are mutually exclusive", fd2)
end

# runic --inplace --output=out.jl in.jl
let (rc, fd1, fd2) = runic(["--inplace", "--output=out.jl", "in.jl"])
@test rc == 1
@test isempty(fd1)
@test occursin("options `--inplace` and `--output` are mutually exclusive", fd2)
end

# runic --check --output=out.jl in.jl
let (rc, fd1, fd2) = runic(["--check", "--output=out.jl", "in.jl"])
@test rc == 1
@test isempty(fd1)
@test occursin("options `--check` and `--output` are mutually exclusive", fd2)
end

# runic --inplace
let (rc, fd1, fd2) = runic(["--inplace"])
@test rc == 1
@test isempty(fd1)
@test occursin("option `--inplace` can not be used together with stdin input", fd2)
end

# runic --output=out.jl in1.jl in2.jl
let (rc, fd1, fd2) = runic(["--output=out.jl", "in1.jl", "in2.jl"])
@test rc == 1
@test isempty(fd1)
@test occursin("option `--output` can not be used together with multiple input files", fd2)
end

# runic in1.jl in2.jl
let (rc, fd1, fd2) = runic(["in1.jl", "in2.jl"])
@test rc == 1
@test isempty(fd1)
@test occursin("option `--inplace` or `--check` required with multiple input files", fd2)
end

# runic --diff (with no git)
let (rc, fd1, fd2) = withenv(() -> runic(["--diff"]), "PATH" => "")
@test rc == 1
@test isempty(fd1)
@test occursin("option `--diff` requires `git` to be installed", fd2)
end

# runic in.jl (not readable)
cdtmp() do
f_in = "in.jl"
write(f_in, bad)
omode = filemode(f_in)
chmod(f_in, omode & (typemax(omode) 0o444))
rc, fd1, fd2 = runic([f_in])
chmod(f_in, omode)
@test rc == 1
@test isempty(fd1)
@test occursin("could not read input from file", fd2)
@test occursin("SystemError: opening file", fd2)
end

# runic doesntexist.jl
cdtmp() do
rc, fd1, fd2 = runic(["doesntexist.jl"])
@test rc == 1
@test isempty(fd1)
@test occursin("input file does not exist", fd2)
end

# runic -o in.jl in.jl
cdtmp() do
f_in = "in.jl"
write(f_in, bad)
rc, fd1, fd2 = runic(["-o", f_in, f_in])
@test rc == 1
@test isempty(fd1)
@test occursin("can not use same file for input and output", fd2)
end

# runic --check unparseable.jl
cdtmp() do
f_in = "in.jl"
write(f_in, "syntax error")
rc, fd1, fd2 = runic(["--check", f_in])
@test rc == 1
@test isempty(fd1)
@test occursin("failed to parse input", fd2)
end

# runic -o readonly.jl in.jl
cdtmp() do
f_in = "in.jl"
write(f_in, bad)
f_out = "readonly.jl"
touch(f_out)
omode = filemode(f_out)
chmod(f_out, omode & (typemax(omode) 0o222))
rc, fd1, fd2 = runic(["-o", f_out, f_in])
chmod(f_out, omode)
@test rc == 1
@test isempty(fd1)
@test occursin("could not write to output file", fd2)
end

end

const share_julia = joinpath(Sys.BINDIR, Base.DATAROOTDIR, "julia")
if Sys.isunix() && isdir(share_julia)
@testset "JuliaLang/julia" begin
Expand Down

0 comments on commit 21cbf72

Please sign in to comment.