Skip to content

Commit

Permalink
Merge pull request #895 from cucumber/improve-be-a-command-found-in-path
Browse files Browse the repository at this point in the history
Improve be_a_command_found_in_path matcher and its tests
  • Loading branch information
mvz authored Jan 22, 2023
2 parents d3049ec + a2ddad0 commit e727e6e
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 102 deletions.
Original file line number Diff line number Diff line change
@@ -1,114 +1,26 @@
Feature: Check if command can be found in PATH

If you need to check if a given command can be found in path, you can use the
`be_an_existing_executable`-matcher.

```ruby
require 'spec_helper'

RSpec.describe 'Check if command can be found in PATH', :type => :aruba do
let(:file) { 'file.sh' }
before { touch(file) }
before { chmod(0o755, file) }
before { prepend_environment_variable('PATH', format('%s:', expand_path('.')) }

it { expect(file).to be_an_existing_executable }
end
```
`be_a_command_found_in_path`-matcher.

Background:
Given I use a fixture named "cli-app"

Scenario: Expect single existing executable file
Given a file named "spec/existing_executable_spec.rb" with:
"""
require 'spec_helper'
RSpec.describe 'Check if command can be found in PATH', :type => :aruba do
let(:file) { 'file.sh' }
before { touch(file) }
before { chmod(0o755, file) }
before { prepend_environment_variable('PATH', format('%s:', expand_path('.'))) }
it { expect(file).to be_a_command_found_in_path }
end
"""
When I run `rspec`
Then the specs should all pass

Scenario: Expect single non-existing executable file
Given a file named "spec/existing_executable_spec.rb" with:
"""
require 'spec_helper'
RSpec.describe 'Check if command can be found in PATH', :type => :aruba do
let(:file) { 'file.sh' }
before { prepend_environment_variable('PATH', format('%s:', expand_path('.'))) }
it { expect(file).not_to be_a_command_found_in_path }
end
"""
When I run `rspec`
Then the specs should all pass

Scenario: Expect single non-executable file
Scenario: Checking an existing executable file in PATH
Given a file named "spec/existing_executable_spec.rb" with:
"""
require 'spec_helper'
RSpec.describe 'Check if command can be found in PATH', :type => :aruba do
let(:file) { 'file.sh' }
RSpec.describe 'Check if command can be found in PATH', type: :aruba do
let(:file) { 'my-exe' }
before { touch(file) }
before { prepend_environment_variable('PATH', format('%s:', expand_path('.'))) }
it { expect(file).not_to be_a_command_found_in_path }
end
"""
When I run `rspec`
Then the specs should all pass

Scenario: Expect multiple existing executable files
Given a file named "spec/existing_executable_spec.rb" with:
"""
require 'spec_helper'
RSpec.describe 'Check if file exists and is an executable file', :type => :aruba do
let(:files) { %w(file1.sh file2.sh) }
before :each do
files.each do |f|
touch(f)
chmod(0o755, f)
end
end
before { prepend_environment_variable('PATH', format('%s:', expand_path('.'))) }
it { expect(files).to all be_a_command_found_in_path }
end
"""
When I run `rspec`
Then the specs should all pass

Scenario: Expect a least one existing executable file
Given a file named "spec/existing_executable_spec.rb" with:
"""
require 'spec_helper'
RSpec.describe 'Check if file exists and is an executable file', :type => :aruba do
let(:files) { %w(file1.sh file2.sh) }
before :each do
touch(files.first)
chmod(0o755, files.first)
before do
touch(file)
chmod(0o755, file)
prepend_environment_variable('PATH', format('%s:', expand_path('.')))
end
before { prepend_environment_variable('PATH', format('%s:', expand_path('.'))) }
it { expect(files).to include a_command_found_in_path }
it { expect(file).to be_a_command_found_in_path }
end
"""
When I run `rspec`
Expand Down
10 changes: 5 additions & 5 deletions lib/aruba/matchers/file/be_a_command_found_in_path.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@
# end
RSpec::Matchers.define :be_a_command_found_in_path do
match do |actual|
@actual = Shellwords.split(actual.commandline).first if actual.respond_to? :commandline

!which(@actual).nil?
!which(actual).nil?
end

failure_message do |actual|
format(%(expected that command "%s" can be found in PATH "#{ENV['PATH']}".), actual)
format(%(expected that command "%s" can be found in PATH "%s".),
actual, aruba.environment["PATH"])
end

failure_message_when_negated do |actual|
format(%(expected that command "%s" cannot be found in PATH "#{ENV['PATH']}".), actual)
format(%(expected that command "%s" cannot be found in PATH "%s".),
actual, aruba.environment["PATH"])
end
end

Expand Down
86 changes: 86 additions & 0 deletions spec/aruba/matchers/file_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -249,4 +249,90 @@ def fail_with(message)
end
end
end

describe "#be_a_command_found_in_path" do
context "when file exists in path and is executable" do
let(:file) { Gem.win_platform? ? "foo.bat" : "foo" }

before do
prepend_environment_variable("PATH", expand_path(".") + File::PATH_SEPARATOR)
@aruba.write_file(file, "")
@aruba.chmod(0x755, file) unless Gem.win_platform?
end

it "matches" do
expect(file).to be_a_command_found_in_path
end
end

context "when file exists and is executable but is not in path" do
let(:file) { Gem.win_platform? ? "foo.bat" : "foo" }

before do
@aruba.write_file(file, "")
@aruba.chmod(0x755, file) unless Gem.win_platform?
end

it "does not match" do
expect(file).not_to be_a_command_found_in_path
end
end

context "when file exists in path and is not executable" do
let(:file) { Gem.win_platform? ? "foo.txt" : "foo" }

before do
prepend_environment_variable("PATH", expand_path(".") + File::PATH_SEPARATOR)
@aruba.write_file(file, "")
end

it "does not match" do
expect(file).not_to be_a_command_found_in_path
end
end

context "when file does not exist" do
let(:file) { Gem.win_platform? ? "foo.bat" : "foo" }

before do
prepend_environment_variable("PATH", expand_path(".") + File::PATH_SEPARATOR)
end

it "does not match" do
expect(file).not_to be_a_command_found_in_path
end
end

context "when the positive matcher fails" do
let(:file) { Gem.win_platform? ? "foo.bat" : "foo" }

before do
set_environment_variable "PATH", expand_path(".")
end

it "provides the correct path value in the message" do
expect { expect(file).to be_a_command_found_in_path }
.to raise_error RSpec::Expectations::ExpectationNotMetError,
"expected that command \"#{file}\" can be found" \
" in PATH \"#{expand_path('.')}\"."
end
end

context "when the negative matcher fails" do
let(:file) { Gem.win_platform? ? "foo.bat" : "foo" }

before do
set_environment_variable("PATH", expand_path("."))
@aruba.write_file(file, "")
@aruba.chmod(0x755, file) unless Gem.win_platform?
end

it "provides the correct path value in the message" do
expect { expect(file).not_to be_a_command_found_in_path }
.to raise_error RSpec::Expectations::ExpectationNotMetError,
"expected that command \"#{file}\" cannot be found" \
" in PATH \"#{expand_path('.')}\"."
end
end
end
end

0 comments on commit e727e6e

Please sign in to comment.