Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions spec/compiler/compiler_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe "Compiler" do

File.exists?(path).should be_true

`#{Process.quote(path)}`.should eq("Hello!")
Process.capture!(path).should eq("Hello!")
end
end

Expand All @@ -23,7 +23,7 @@ describe "Compiler" do

File.exists?(path).should be_true

`#{Process.quote(path)}`.should eq("Hello!")
Process.capture!(path).should eq("Hello!")
end
end
end
Expand Down
78 changes: 38 additions & 40 deletions spec/compiler/crystal/tools/doc/project_info_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ require "../../../../support/tempfile"

private alias ProjectInfo = Crystal::Doc::ProjectInfo

private def run_git(command)
Process.run(%(git -c user.email="" -c user.name="spec" #{command}), shell: true)
private def run_git(*args : String)
Process.capture!("git", ["-c", %(user.email=""), "-c", %(user.name="spec"), *args])
rescue IO::Error
pending! "Git is not available"
end
Expand Down Expand Up @@ -58,9 +58,9 @@ describe Crystal::Doc::ProjectInfo do

it "git tagged version" do
run_git "init"
run_git "add shard.yml"
run_git "commit -m \"Initial commit\" --no-gpg-sign"
run_git "tag v3.0"
run_git "add", "shard.yml"
run_git "commit", "-m", "Initial commit", "--no-gpg-sign"
run_git "tag", "v3.0"

assert_with_defaults(ProjectInfo.new(nil, nil), ProjectInfo.new("foo", "3.0", refname: "v3.0"))
assert_with_defaults(ProjectInfo.new("bar", "2.0"), ProjectInfo.new("bar", "2.0", refname: "v3.0"))
Expand All @@ -69,9 +69,9 @@ describe Crystal::Doc::ProjectInfo do

it "git tagged version dirty" do
run_git "init"
run_git "add shard.yml"
run_git "commit -m \"Initial commit\" --no-gpg-sign"
run_git "tag v3.0"
run_git "add", "shard.yml"
run_git "commit", "-m", "Initial commit", "--no-gpg-sign"
run_git "tag", "v3.0"
File.write("shard.yml", "\n", mode: "a")

assert_with_defaults(ProjectInfo.new(nil, nil), ProjectInfo.new("foo", "3.0-dev", refname: nil))
Expand All @@ -81,20 +81,20 @@ describe Crystal::Doc::ProjectInfo do

it "git untracked file doesn't prevent detection" do
run_git "init"
run_git "add shard.yml"
run_git "commit -m \"Initial commit\" --no-gpg-sign"
run_git "tag v3.0"
run_git "add", "shard.yml"
run_git "commit", "-m", "Initial commit", "--no-gpg-sign"
run_git "tag", "v3.0"
File.write("foo.txt", "bar")

assert_with_defaults(ProjectInfo.new(nil, nil), ProjectInfo.new("foo", "3.0", refname: "v3.0"))
end

it "git non-tagged commit" do
run_git "init"
run_git "checkout -B master"
run_git "add shard.yml"
run_git "commit -m \"Initial commit\" --no-gpg-sign"
commit_sha = `git rev-parse HEAD`.chomp
run_git "checkout", "-B", "master"
run_git "add", "shard.yml"
run_git "commit", "-m", "Initial commit", "--no-gpg-sign"
commit_sha = run_git("rev-parse", "HEAD").chomp

assert_with_defaults(ProjectInfo.new(nil, nil), ProjectInfo.new("foo", "master", refname: commit_sha))
assert_with_defaults(ProjectInfo.new(nil, "1.1"), ProjectInfo.new("foo", "1.1", refname: commit_sha))
Expand All @@ -104,9 +104,9 @@ describe Crystal::Doc::ProjectInfo do

it "git non-tagged commit dirty" do
run_git "init"
run_git "checkout -B master"
run_git "add shard.yml"
run_git "commit -m \"Initial commit\" --no-gpg-sign"
run_git "checkout", "-B", "master"
run_git "add", "shard.yml"
run_git "commit", "-m", "Initial commit", "--no-gpg-sign"
File.write("shard.yml", "\n", mode: "a")

assert_with_defaults(ProjectInfo.new(nil, nil), ProjectInfo.new("foo", "master-dev", refname: nil))
Expand All @@ -116,7 +116,7 @@ describe Crystal::Doc::ProjectInfo do

it "git with remote" do
run_git "init"
run_git "remote add origin git@github.com:foo/bar"
run_git "remote", "add", "origin", "git@github.com:foo/bar"

url_pattern = "https://github.com/foo/bar/blob/%{refname}/%{path}#L%{line}"
assert_with_defaults(ProjectInfo.new(nil, nil), ProjectInfo.new("foo", "1.0", refname: nil, source_url_pattern: url_pattern))
Expand All @@ -129,9 +129,9 @@ describe Crystal::Doc::ProjectInfo do
it "no shard.yml, but git tagged version" do
File.write("foo.txt", "bar")
run_git "init"
run_git "add foo.txt"
run_git "commit -m \"Remove shard.yml\" --no-gpg-sign"
run_git "tag v4.0"
run_git "add", "foo.txt"
run_git "commit", "-m", "Remove shard.yml", "--no-gpg-sign"
run_git "tag", "v4.0"

assert_with_defaults(ProjectInfo.new(nil, nil), ProjectInfo.new(nil, "4.0", refname: "v4.0"))
assert_with_defaults(ProjectInfo.new("foo", nil), ProjectInfo.new("foo", "4.0", refname: "v4.0"))
Expand All @@ -146,43 +146,43 @@ describe Crystal::Doc::ProjectInfo do

# Empty git directory
run_git "init"
run_git "checkout -B master"
run_git "checkout", "-B", "master"
ProjectInfo.find_git_version.should be_nil

# Non-tagged commit
File.write("file.txt", "foo")
run_git "add file.txt"
run_git "commit -m \"Initial commit\" --no-gpg-sign"
run_git "add", "file.txt"
run_git "commit", "-m", "Initial commit", "--no-gpg-sign"
ProjectInfo.find_git_version.should eq "master"

# Other branch
run_git "checkout -b foo"
run_git "checkout", "-b", "foo"
ProjectInfo.find_git_version.should eq "foo"

# Non-tagged commit, dirty workdir
run_git "checkout master"
run_git "checkout", "master"
File.write("file.txt", "bar")
ProjectInfo.find_git_version.should eq "master-dev"

run_git "checkout -- ."
run_git "checkout", "--", "."

# Tagged commit
run_git "tag v0.1.0"
run_git "tag", "v0.1.0"
ProjectInfo.find_git_version.should eq "0.1.0"

# Tagged commit, dirty workdir
File.write("file.txt", "bar")
ProjectInfo.find_git_version.should eq "0.1.0-dev"

# Tagged commit, dirty index
run_git "add file.txt"
run_git "add", "file.txt"
ProjectInfo.find_git_version.should eq "0.1.0-dev"

run_git "reset --hard v0.1.0"
run_git "reset", "--hard", "v0.1.0"
ProjectInfo.find_git_version.should eq "0.1.0"

# Multiple tags
run_git "tag v0.2.0"
run_git "tag", "v0.2.0"
ProjectInfo.find_git_version.should eq "0.1.0"
end

Expand All @@ -198,24 +198,22 @@ describe Crystal::Doc::ProjectInfo do

it "simple origin" do
run_git "init"
run_git "remote add origin https://example.com/foo.git"
run_git "remote", "add", "origin", "https://example.com/foo.git"
ProjectInfo.git_remote.should eq "https://example.com/foo.git"
end

it "origin plus other" do
run_git "init"
run_git "remote add bar https://example.com/bar.git"
run_git "remote add origin https://example.com/foo.git"
run_git "remote add baz https://example.com/baz.git"
`git remote -v`
run_git "remote", "add", "bar", "https://example.com/bar.git"
run_git "remote", "add", "origin", "https://example.com/foo.git"
run_git "remote", "add", "baz", "https://example.com/baz.git"
ProjectInfo.git_remote.should eq "https://example.com/foo.git"
end

it "no origin remote" do
run_git "init"
run_git "remote add bar https://example.com/bar.git"
run_git "remote add baz https://example.com/baz.git"
`git remote -v`
run_git "remote", "add", "bar", "https://example.com/bar.git"
run_git "remote", "add", "baz", "https://example.com/baz.git"
ProjectInfo.git_remote.should eq "https://example.com/bar.git"
end
end
Expand Down
6 changes: 3 additions & 3 deletions spec/compiler/loader/spec_helper.cr
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ def build_c_dynlib(c_filename, *, lib_name = nil, target_dir = SPEC_CRYSTAL_LOAD

{% if flag?(:msvc) %}
o_basename = o_filename.rchop(".lib")
`#{ENV["CC"]? || "cl.exe"} /nologo /LD #{Process.quote(c_filename)} #{Process.quote("/Fo#{o_basename}")} #{Process.quote("/Fe#{o_basename}")}`
Process.run(ENV.fetch("CC", "cl.exe"), {"/nologo", "/LD", c_filename, "/Fo#{o_basename}", "/Fe#{o_basename}"})
{% elsif flag?(:win32) && flag?(:gnu) %}
o_basename = o_filename.rchop(".a")
`#{ENV["CC"]? || "cc"} -shared -fvisibility=hidden #{Process.quote(c_filename)} -o #{Process.quote(o_basename + ".dll")} #{Process.quote("-Wl,--out-implib,#{o_basename}.a")}`
Process.run(ENV.fetch("CC", "cc"), {"-shared", "-fvisibility=hidden", c_filename, "-o", "#{o_basename}.dll", "-Wl,--out-implib,#{o_basename}.a"})
{% else %}
`#{ENV["CC"]? || "cc"} -shared -fvisibility=hidden #{Process.quote(c_filename)} -o #{Process.quote(o_filename)}`
Process.run(ENV.fetch("CC", "cc"), {"-shared", "-fvisibility=hidden", c_filename, "-o", o_filename})
{% end %}

raise "BUG: failed to compile dynamic library" unless $?.success?
Expand Down
8 changes: 7 additions & 1 deletion spec/std/dir_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,13 @@ describe "Dir" do
describe ".current" do
# can't use backtick in interpreted code (#12241)
pending_interpreted "matches shell" do
Dir.current.should eq(`#{{{ flag?(:win32) ? "cmd /c cd" : "pwd" }}}`.chomp)
pwd =
{% if flag?(:win32) %}
Process.capture!("cmd", {"/c", "cd"}).chomp
{% else %}
Process.capture!("pwd").chomp
{% end %}
Dir.current.should eq(pwd)
end

# Skip spec on Windows due to weak support for symlinks and $PWD.
Expand Down
20 changes: 8 additions & 12 deletions spec/std/io/file_descriptor_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,6 @@ end

private CLOSE_ON_EXEC_AVAILABLE = {{ !flag?(:win32) }}

private def shell_command(command)
{% if flag?(:win32) %}
"cmd.exe /c #{Process.quote(command)}"
{% else %}
"/bin/sh -c #{Process.quote(command)}"
{% end %}
end

describe IO::FileDescriptor do
describe "#initialize" do
it "handles closed file descriptor gracefully" do
Expand All @@ -28,10 +20,12 @@ describe IO::FileDescriptor do
end

it "reopen STDIN with the right mode", tags: %w[slow] do
code = %q(puts "#{STDIN.blocking} #{STDIN.info.type}")
code = %q(print "#{STDIN.blocking} #{STDIN.info.type}")
compile_source(code) do |binpath|
`#{shell_command %(#{Process.quote(binpath)} < #{Process.quote(binpath)})}`.chomp.should eq("true File")
`#{shell_command %(echo "" | #{Process.quote(binpath)})}`.chomp.should eq("#{{{ flag?(:win32) }}} Pipe")
File.open(binpath) do |input|
Process.capture!(binpath, input: input).should eq("true File")
end
Process.capture!(binpath, input: Process::Redirect::Pipe).should eq("#{{{ flag?(:win32) }}} Pipe")
end
end

Expand All @@ -45,7 +39,9 @@ describe IO::FileDescriptor do
it "returns false for standard streams redirected to null device", tags: %w[slow] do
code = %q(print STDIN.tty?, ' ', STDERR.tty?)
compile_source(code) do |binpath|
`#{shell_command %(#{Process.quote(binpath)} < #{File::NULL} 2> #{File::NULL})}`.should eq("false false")
File.open(File::NULL) do |null|
Process.capture!(binpath, input: null, error: null).should eq("false false")
end
end
end
end
Expand Down
64 changes: 46 additions & 18 deletions spec/std/process_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -273,28 +273,22 @@ describe Process do

it "sets working directory with string" do
parent = File.dirname(Dir.current)
command = {% if flag?(:win32) %}
"cmd.exe /c echo %cd%"
{% else %}
"pwd"
{% end %}
value = Process.run(command, shell: true, chdir: parent, output: Process::Redirect::Pipe) do |proc|
proc.output.gets_to_end
end
value.should eq "#{parent}#{newline}"
pwd = {% if flag?(:win32) %}
Process.capture!("cmd.exe", {"/c", "echo %cd%"}, chdir: parent)
{% else %}
Process.capture!("pwd", chdir: parent)
{% end %}
pwd.should eq "#{parent}#{newline}"
end

it "sets working directory with path" do
parent = Path.new File.dirname(Dir.current)
command = {% if flag?(:win32) %}
"cmd.exe /c echo %cd%"
{% else %}
"pwd"
{% end %}
value = Process.run(command, shell: true, chdir: parent, output: Process::Redirect::Pipe) do |proc|
proc.output.gets_to_end
end
value.should eq "#{parent}#{newline}"
pwd = {% if flag?(:win32) %}
Process.capture!("cmd.exe", {"/c", "echo %cd%"}, chdir: parent)
{% else %}
Process.capture!("pwd", chdir: parent)
{% end %}
pwd.should eq "#{parent}#{newline}"
end

pending_win32 "disallows passing arguments to nowhere" do
Expand Down Expand Up @@ -627,6 +621,40 @@ describe Process do
end
end

describe ".capture!" do
it "gets output" do
value = Process.capture!(*shell_command("echo hello"))
value.should eq("hello#{newline}")
$?.exit_code.should eq(0)
end

it "raises on unsuccessful exit code" do
expect_raises(IO::Error, "Command failed with exit code 17") do
Process.capture!(*exit_code_command(17))
end
$?.exit_code.should eq(17)
end
end

describe ".capture" do
it "gets output" do
# TODO: call command that prints to both stdout and stderr
status, output, error = Process.capture(*shell_command("echo hello"))
output.should eq("hello#{newline}")
error.should eq("")
status.exit_code.should eq(0)
$?.exit_code.should eq(0)
end

it "raises on unsuccessful exit code" do
status, output, error = Process.capture(*exit_code_command(17))
output.should eq("")
error.should eq("")
status.exit_code.should eq(17)
$?.exit_code.should eq(17)
end
end

describe ".on_interrupt" do
it "compiles" do
typeof(Process.on_interrupt { })
Expand Down
10 changes: 5 additions & 5 deletions spec/std/signal_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,13 @@ describe "Signal" do

it "CHLD.reset sets default Crystal child handler" do
Signal::CHLD.reset
child = Process.new("true", shell: true)
child = Process.new("true")
child.wait # doesn't block forever
end

it "CHLD.ignore sets default Crystal child handler" do
Signal::CHLD.ignore
child = Process.new("true", shell: true)
child = Process.new("true")
child.wait # doesn't block forever
end

Expand All @@ -97,7 +97,7 @@ describe "Signal" do
existed.send(Process.exists?(child_process.pid))
end

child = Process.new("true", shell: true)
child = Process.new("true")
child.wait # doesn't block forever
chan.send(child)
existed.receive.should be_false
Expand All @@ -112,14 +112,14 @@ describe "Signal" do
call_count += 1
end

Process.new("true", shell: true).wait
Process.new("true").wait
Fiber.yield

call_count.should eq(1)

Signal::CHLD.reset

Process.new("true", shell: true).wait
Process.new("true").wait
Fiber.yield

call_count.should eq(1)
Expand Down
Loading