mirror of
https://github.com/samsonjs/csc360-a1-shell.git
synced 2026-03-25 08:45:52 +00:00
Merge pull request #2 from samsonjs/ruby-4
Update to Ruby 4 and add GitHub workflow
This commit is contained in:
commit
0e19e57734
16 changed files with 185 additions and 144 deletions
33
.github/workflows/test.yml
vendored
Normal file
33
.github/workflows/test.yml
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
name: Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ruby
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Set up Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
env:
|
||||
BUNDLE_GEMFILE: ruby/Gemfile
|
||||
with:
|
||||
ruby-version: 4.0.0
|
||||
bundler-cache: true
|
||||
- name: Run tests
|
||||
run: bundle exec rake test
|
||||
- name: Run standard
|
||||
run: bundle exec rake standard
|
||||
- name: Install C dependencies
|
||||
working-directory: .
|
||||
run: sudo apt-get update && sudo apt-get install -y libreadline-dev
|
||||
- name: Run C tests
|
||||
working-directory: .
|
||||
run: make c
|
||||
8
Makefile
8
Makefile
|
|
@ -1,9 +1,7 @@
|
|||
default: all
|
||||
|
||||
all: c ruby
|
||||
default: c ruby
|
||||
|
||||
bootstrap:
|
||||
cd ruby && bundle
|
||||
cd ruby && bundle install --jobs 8
|
||||
|
||||
c:
|
||||
cd c && make test
|
||||
|
|
@ -15,4 +13,4 @@ clean:
|
|||
cd c && make clean
|
||||
cd ruby && bundle exec rake clean
|
||||
|
||||
.PHONY: c ruby clean
|
||||
.PHONY: c ruby clean bootstrap
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
AllCops:
|
||||
NewCops: enable
|
||||
|
||||
Layout/EmptyLineAfterGuardClause:
|
||||
Enabled: false
|
||||
|
||||
Layout/FirstHashElementIndentation:
|
||||
EnforcedStyle: consistent
|
||||
|
||||
Metrics/AbcSize:
|
||||
Max: 25
|
||||
|
||||
Metrics/MethodLength:
|
||||
Max: 30
|
||||
|
||||
Style/Documentation:
|
||||
Enabled: false
|
||||
|
||||
Style/FrozenStringLiteralComment:
|
||||
Enabled: false
|
||||
|
||||
Style/HashSyntax:
|
||||
EnforcedShorthandSyntax: never
|
||||
|
||||
Style/TrailingCommaInHashLiteral:
|
||||
EnforcedStyleForMultiline: consistent_comma
|
||||
|
|
@ -1 +1 @@
|
|||
3.2.2
|
||||
4.0.0
|
||||
|
|
|
|||
4
ruby/.standard.yml
Normal file
4
ruby/.standard.yml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
fix: true
|
||||
parallel: true
|
||||
ignore:
|
||||
- "test_bin/**/*"
|
||||
13
ruby/Gemfile
13
ruby/Gemfile
|
|
@ -1,7 +1,8 @@
|
|||
source 'https://rubygems.org'
|
||||
ruby '3.2.2'
|
||||
source "https://rubygems.org"
|
||||
|
||||
gem 'minitest', '~> 5.20'
|
||||
gem 'rake', '~> 13.0'
|
||||
gem 'rubocop', '1.56.4'
|
||||
gem 'wordexp', '~> 0.2'
|
||||
gem "minitest", "~> 6.0"
|
||||
gem "parser", "~> 3.3.10"
|
||||
gem "rake", "~> 13.0"
|
||||
gem "reline", "~> 0.6"
|
||||
gem "standard", "~> 1.52.0", require: false
|
||||
gem "wordexp", "~> 0.2"
|
||||
|
|
|
|||
|
|
@ -1,51 +1,74 @@
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
ast (2.4.2)
|
||||
base64 (0.1.1)
|
||||
json (2.6.3)
|
||||
language_server-protocol (3.17.0.3)
|
||||
minitest (5.20.0)
|
||||
parallel (1.23.0)
|
||||
parser (3.2.2.4)
|
||||
ast (2.4.3)
|
||||
io-console (0.8.2)
|
||||
json (2.18.0)
|
||||
language_server-protocol (3.17.0.5)
|
||||
lint_roller (1.1.0)
|
||||
minitest (6.0.1)
|
||||
prism (~> 1.5)
|
||||
parallel (1.27.0)
|
||||
parser (3.3.10.0)
|
||||
ast (~> 2.4.1)
|
||||
racc
|
||||
racc (1.7.1)
|
||||
prism (1.7.0)
|
||||
racc (1.8.1)
|
||||
rainbow (3.1.1)
|
||||
rake (13.0.6)
|
||||
regexp_parser (2.8.1)
|
||||
rexml (3.2.6)
|
||||
rubocop (1.56.4)
|
||||
base64 (~> 0.1.1)
|
||||
rake (13.3.1)
|
||||
regexp_parser (2.11.3)
|
||||
reline (0.6.3)
|
||||
io-console (~> 0.5)
|
||||
rubocop (1.81.7)
|
||||
json (~> 2.3)
|
||||
language_server-protocol (>= 3.17.0)
|
||||
language_server-protocol (~> 3.17.0.2)
|
||||
lint_roller (~> 1.1.0)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 3.2.2.3)
|
||||
parser (>= 3.3.0.2)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
regexp_parser (>= 1.8, < 3.0)
|
||||
rexml (>= 3.2.5, < 4.0)
|
||||
rubocop-ast (>= 1.28.1, < 2.0)
|
||||
regexp_parser (>= 2.9.3, < 3.0)
|
||||
rubocop-ast (>= 1.47.1, < 2.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 2.4.0, < 3.0)
|
||||
rubocop-ast (1.29.0)
|
||||
parser (>= 3.2.1.0)
|
||||
unicode-display_width (>= 2.4.0, < 4.0)
|
||||
rubocop-ast (1.49.0)
|
||||
parser (>= 3.3.7.2)
|
||||
prism (~> 1.7)
|
||||
rubocop-performance (1.26.1)
|
||||
lint_roller (~> 1.1)
|
||||
rubocop (>= 1.75.0, < 2.0)
|
||||
rubocop-ast (>= 1.47.1, < 2.0)
|
||||
ruby-progressbar (1.13.0)
|
||||
unicode-display_width (2.5.0)
|
||||
wordexp (0.2.0)
|
||||
standard (1.52.0)
|
||||
language_server-protocol (~> 3.17.0.2)
|
||||
lint_roller (~> 1.0)
|
||||
rubocop (~> 1.81.7)
|
||||
standard-custom (~> 1.0.0)
|
||||
standard-performance (~> 1.8)
|
||||
standard-custom (1.0.2)
|
||||
lint_roller (~> 1.0)
|
||||
rubocop (~> 1.50)
|
||||
standard-performance (1.9.0)
|
||||
lint_roller (~> 1.1)
|
||||
rubocop-performance (~> 1.26.0)
|
||||
unicode-display_width (3.2.0)
|
||||
unicode-emoji (~> 4.1)
|
||||
unicode-emoji (4.2.0)
|
||||
wordexp (0.2.2)
|
||||
|
||||
PLATFORMS
|
||||
arm64-darwin-21
|
||||
arm64-darwin-22
|
||||
arm64-darwin-23
|
||||
arm64-darwin-25
|
||||
x86_64-linux
|
||||
|
||||
DEPENDENCIES
|
||||
minitest (~> 5.20)
|
||||
minitest (~> 6.0)
|
||||
parser (~> 3.3.10)
|
||||
rake (~> 13.0)
|
||||
rubocop (= 1.56.4)
|
||||
reline (~> 0.6)
|
||||
standard (~> 1.52.0)
|
||||
wordexp (~> 0.2)
|
||||
|
||||
RUBY VERSION
|
||||
ruby 3.2.2p53
|
||||
|
||||
BUNDLED WITH
|
||||
2.4.20
|
||||
4.0.3
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
require 'rake/testtask'
|
||||
require "rake/testtask"
|
||||
require "standard/rake"
|
||||
|
||||
task default: 'test'
|
||||
task default: %i[test standard]
|
||||
|
||||
Rake::TestTask.new do |task|
|
||||
task.pattern = 'test/*_test.rb'
|
||||
task.pattern = "test/*_test.rb"
|
||||
end
|
||||
|
||||
task :clean do
|
||||
FileUtils.rm_rf('test_bin')
|
||||
FileUtils.rm_rf("test_bin")
|
||||
end
|
||||
|
|
|
|||
6
ruby/a1
6
ruby/a1
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env ruby -w
|
||||
#!/usr/bin/env -S ruby -w
|
||||
|
||||
require 'English'
|
||||
require_relative 'shell'
|
||||
require "English"
|
||||
require_relative "shell"
|
||||
|
||||
Shell::CLI.new.run(args: ARGV) if $PROGRAM_NAME == __FILE__
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
$LOAD_PATH << File.expand_path(__dir__)
|
||||
|
||||
require 'shell/cli'
|
||||
require 'shell/repl'
|
||||
require "shell/cli"
|
||||
require "shell/repl"
|
||||
|
||||
module Shell
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
require 'shell/job_control'
|
||||
require 'shell/logger'
|
||||
require "shell/job_control"
|
||||
require "shell/logger"
|
||||
|
||||
module Shell
|
||||
class Builtins
|
||||
|
|
@ -34,14 +34,14 @@ module Shell
|
|||
jobs.each do |job|
|
||||
puts job_control.format_job(job)
|
||||
end
|
||||
plural = jobs.count == 1 ? '' : 's'
|
||||
plural = (jobs.count == 1) ? "" : "s"
|
||||
puts "#{jobs.count} background job#{plural}"
|
||||
0
|
||||
end
|
||||
|
||||
def builtin_bgkill(args)
|
||||
if args.count != 1
|
||||
logger.warn 'Usage: bgkill <job>'
|
||||
logger.warn "Usage: bgkill <job>"
|
||||
return -1
|
||||
end
|
||||
|
||||
|
|
@ -57,11 +57,11 @@ module Shell
|
|||
|
||||
def builtin_export(args)
|
||||
# only supports one variable and doesn't support quoting
|
||||
name, *value_parts = args.first.strip.split('=')
|
||||
name, *value_parts = args.first.strip.split("=")
|
||||
if name.nil? || name.empty?
|
||||
logger.warn "#{red('[ERROR]')} Invalid export command"
|
||||
logger.warn "#{red("[ERROR]")} Invalid export command"
|
||||
else
|
||||
ENV[name] = value_parts.join('=').gsub(/\$\w+/) { |m| ENV[m[1..]] || '' }
|
||||
ENV[name] = value_parts.join("=").gsub(/\$\w+/) { |m| ENV[m[1..]] || "" }
|
||||
end
|
||||
0
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
require 'shell/colours'
|
||||
require 'shell/logger'
|
||||
require 'shell/repl'
|
||||
require "shell/colours"
|
||||
require "shell/logger"
|
||||
require "shell/repl"
|
||||
|
||||
module Shell
|
||||
class CLI
|
||||
|
|
@ -29,20 +29,20 @@ module Shell
|
|||
|
||||
def parse_options(args)
|
||||
options = {
|
||||
verbose: false,
|
||||
verbose: false
|
||||
}
|
||||
while (arg = args.shift)
|
||||
case arg
|
||||
when '-c'
|
||||
when "-c"
|
||||
options[:command] = args.shift
|
||||
if options[:command].nil?
|
||||
warn 'ERROR: expected string after -c'
|
||||
warn "ERROR: expected string after -c"
|
||||
exit 1
|
||||
end
|
||||
when '-v', '--verbose'
|
||||
when "-v", "--verbose"
|
||||
options[:verbose] = true
|
||||
else
|
||||
logger.warn "#{red('[ERROR]')} Unknown argument: #{arg}"
|
||||
logger.warn "#{red("[ERROR]")} Unknown argument: #{arg}"
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
require 'English'
|
||||
require "English"
|
||||
|
||||
require 'shell/colours'
|
||||
require 'shell/job'
|
||||
require 'shell/logger'
|
||||
require "shell/colours"
|
||||
require "shell/job"
|
||||
require "shell/logger"
|
||||
|
||||
module Shell
|
||||
class JobControl
|
||||
|
|
@ -17,7 +17,7 @@ module Shell
|
|||
|
||||
def exec_command(cmd, args, background: false)
|
||||
unless (path = resolve_executable(cmd))
|
||||
warn "#{red('[ERROR]')} command not found: #{cmd}"
|
||||
warn "#{red("[ERROR]")} command not found: #{cmd}"
|
||||
return -2
|
||||
end
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ module Shell
|
|||
if background
|
||||
job = Job.new(next_job_id, pid, cmd, args)
|
||||
@jobs_by_pid[pid] = job
|
||||
puts white('Running job ') + yellow(job.id) + white(" (pid #{pid}) in background")
|
||||
puts white("Running job ") + yellow(job.id) + white(" (pid #{pid}) in background")
|
||||
Process.waitpid(pid, Process::WNOHANG)
|
||||
0
|
||||
else
|
||||
|
|
@ -38,8 +38,8 @@ module Shell
|
|||
0
|
||||
end
|
||||
end
|
||||
rescue StandardError => e
|
||||
warn "#{red('[ERROR]')} #{e.message} #{e.inspect}"
|
||||
rescue => e
|
||||
warn "#{red("[ERROR]")} #{e.message} #{e.inspect}"
|
||||
-5
|
||||
end
|
||||
|
||||
|
|
@ -50,7 +50,7 @@ module Shell
|
|||
return
|
||||
end
|
||||
|
||||
Process.kill('TERM', job.pid)
|
||||
Process.kill("TERM", job.pid)
|
||||
rescue Errno::ESRCH
|
||||
logger.warn "No such proccess: #{job.pid}"
|
||||
end
|
||||
|
|
@ -60,24 +60,24 @@ module Shell
|
|||
end
|
||||
|
||||
def format_job(job)
|
||||
args = job.args.join(' ')
|
||||
"#{yellow(job.id)}: #{white('(pid ', job.pid, ')')} #{green(job.cmd)} #{args}"
|
||||
args = job.args.join(" ")
|
||||
"#{yellow(job.id)}: #{white("(pid ", job.pid, ")")} #{green(job.cmd)} #{args}"
|
||||
end
|
||||
|
||||
def trap_sigchld
|
||||
# handler for SIGCHLD when a child's state changes
|
||||
Signal.trap('CHLD') do |_signo|
|
||||
Signal.trap("CHLD") do |_signo|
|
||||
pid = Process.waitpid(-1, Process::WNOHANG)
|
||||
if pid.nil?
|
||||
# no-op
|
||||
elsif (job = @jobs_by_pid[pid])
|
||||
@jobs_by_pid.delete(pid)
|
||||
time = Time.now.strftime('%T')
|
||||
job_text = yellow('job ', job.id, ' exited')
|
||||
args = job.args.join(' ')
|
||||
puts "\n[#{time}] #{job_text} #{white('(pid ', job.pid, ')')}: #{green(job.cmd)} #{args}"
|
||||
time = Time.now.strftime("%T")
|
||||
job_text = yellow("job ", job.id, " exited")
|
||||
args = job.args.join(" ")
|
||||
puts "\n[#{time}] #{job_text} #{white("(pid ", job.pid, ")")}: #{green(job.cmd)} #{args}"
|
||||
else
|
||||
warn "\n#{yellow('[WARN]')} No job found for child with PID #{pid}"
|
||||
warn "\n#{yellow("[WARN]")} No job found for child with PID #{pid}"
|
||||
end
|
||||
Readline.refresh_line
|
||||
end
|
||||
|
|
@ -88,11 +88,11 @@ module Shell
|
|||
# Returns nil when no such command was found.
|
||||
def resolve_executable(path_or_filename)
|
||||
# process absolute and relative paths directly
|
||||
return path_or_filename if path_or_filename['/'] && \
|
||||
File.executable?(path_or_filename)
|
||||
return path_or_filename if path_or_filename["/"] &&
|
||||
File.executable?(path_or_filename)
|
||||
|
||||
filename = path_or_filename
|
||||
ENV['PATH'].split(':').each do |dir|
|
||||
ENV["PATH"].split(":").each do |dir|
|
||||
path = File.join(dir, filename)
|
||||
next unless File.exist?(path)
|
||||
return path if File.executable?(path)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
require 'shell/colours'
|
||||
require "shell/colours"
|
||||
|
||||
module Shell
|
||||
# Queues up messages to be printed out when readline is waiting for input, to prevent
|
||||
|
|
@ -19,16 +19,16 @@ module Shell
|
|||
end
|
||||
|
||||
def log(message)
|
||||
@logs << Log.new(:info, "#{white('[INFO]')} #{message}")
|
||||
@logs << Log.new(:info, "#{white("[INFO]")} #{message}")
|
||||
end
|
||||
alias info log
|
||||
alias_method :info, :log
|
||||
|
||||
def warn(message)
|
||||
@logs << Log.new(:warning, "#{yellow('[WARN]')} #{message}")
|
||||
@logs << Log.new(:warning, "#{yellow("[WARN]")} #{message}")
|
||||
end
|
||||
|
||||
def error(message)
|
||||
@logs << Log.new(:error, "#{red('[ERROR]')} #{message}")
|
||||
@logs << Log.new(:error, "#{red("[ERROR]")} #{message}")
|
||||
end
|
||||
|
||||
def verbose(message)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
require 'readline'
|
||||
require 'wordexp'
|
||||
begin
|
||||
require "readline"
|
||||
rescue LoadError
|
||||
require "reline"
|
||||
end
|
||||
require "wordexp"
|
||||
|
||||
require 'shell/builtins'
|
||||
require 'shell/colours'
|
||||
require 'shell/job_control'
|
||||
require 'shell/logger'
|
||||
require "shell/builtins"
|
||||
require "shell/colours"
|
||||
require "shell/job_control"
|
||||
require "shell/logger"
|
||||
|
||||
module Shell
|
||||
class REPL
|
||||
|
|
@ -55,13 +59,13 @@ module Shell
|
|||
job_control.exec_command(cmd, args)
|
||||
end
|
||||
rescue Errno => e
|
||||
warn "#{red('[ERROR]')} #{e.message}"
|
||||
warn "#{red("[ERROR]")} #{e.message}"
|
||||
-1
|
||||
end
|
||||
|
||||
# Looks like this: /path/to/somewhere%
|
||||
def prompt(pwd)
|
||||
"#{blue(pwd)}#{white('%')} #{CLEAR}"
|
||||
"#{blue(pwd)}#{white("%")} #{CLEAR}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
require 'minitest/autorun'
|
||||
require "minitest/autorun"
|
||||
|
||||
class ShellTest < Minitest::Test
|
||||
TRIVIAL_SHELL_SCRIPT = "#!/bin/sh\ntrue".freeze
|
||||
|
||||
A1_PATH = ENV.fetch('A1_PATH', './a1').freeze
|
||||
A1_PATH = ENV.fetch("A1_PATH", "./a1").freeze
|
||||
|
||||
def setup
|
||||
FileUtils.mkdir_p('test_bin')
|
||||
FileUtils.mkdir_p("test_bin")
|
||||
end
|
||||
|
||||
def teardown
|
||||
FileUtils.rm_rf('test_bin')
|
||||
FileUtils.rm_rf("test_bin")
|
||||
end
|
||||
|
||||
def unique_shell_script(code)
|
||||
|
|
@ -31,42 +31,45 @@ class ShellTest < Minitest::Test
|
|||
#################################
|
||||
|
||||
def test_background_job
|
||||
output = `#{A1_PATH} -c 'bg echo hello'`.gsub(/\e\[([;\d]+)?m/, '')
|
||||
output = `#{A1_PATH} -c 'bg echo hello'`.gsub(/\e\[([;\d]+)?m/, "")
|
||||
pid = /\(pid (\d+)\)/.match(output)[1]
|
||||
assert_equal "Running job 1 (pid #{pid}) in background\nhello\n", output
|
||||
lines = output.split("\n").map(&:chomp)
|
||||
assert_equal ["Running job 1 (pid #{pid}) in background", "hello"], lines.sort
|
||||
end
|
||||
|
||||
def test_resolves_executables_with_absolute_paths
|
||||
assert_equal '/usr/bin/which', `#{A1_PATH} -c '/usr/bin/which -a which'`.chomp
|
||||
output = `#{A1_PATH} -c '/usr/bin/which -a which'`.lines.map(&:chomp)
|
||||
assert_includes output, "/usr/bin/which"
|
||||
end
|
||||
|
||||
def test_resolves_executables_with_relative_paths
|
||||
File.write('test_bin/something', TRIVIAL_SHELL_SCRIPT)
|
||||
File.chmod(0o755, 'test_bin/something')
|
||||
File.write("test_bin/something", TRIVIAL_SHELL_SCRIPT)
|
||||
File.chmod(0o755, "test_bin/something")
|
||||
assert system("#{A1_PATH} -c ./test_bin/something")
|
||||
end
|
||||
|
||||
def test_resolves_executables_in_absolute_paths
|
||||
assert_equal '/usr/bin/which', `#{A1_PATH} -c 'which -a which'`.chomp
|
||||
output = `#{A1_PATH} -c 'which -a which'`.lines.map(&:chomp)
|
||||
assert_includes output, "/usr/bin/which"
|
||||
end
|
||||
|
||||
def test_resolves_executables_in_relative_paths
|
||||
code = rand(1_000_000).to_s
|
||||
File.write('test_bin/definitely_executable', unique_shell_script(code))
|
||||
File.chmod(0o755, 'test_bin/definitely_executable')
|
||||
File.write("test_bin/definitely_executable", unique_shell_script(code))
|
||||
File.chmod(0o755, "test_bin/definitely_executable")
|
||||
actual = `PATH="./test_bin:$PATH" #{A1_PATH} -c definitely_executable`.chomp
|
||||
assert_equal code, actual
|
||||
end
|
||||
|
||||
def test_does_not_resolve_non_executable_files_in_path
|
||||
File.write('test_bin/definitely_not_executable', TRIVIAL_SHELL_SCRIPT)
|
||||
File.chmod(0o644, 'test_bin/definitely_not_executable')
|
||||
File.write("test_bin/definitely_not_executable", TRIVIAL_SHELL_SCRIPT)
|
||||
File.chmod(0o644, "test_bin/definitely_not_executable")
|
||||
actual = system("PATH=\"./test_bin:$PATH\" #{A1_PATH} -c definitely_not_executable 2>/dev/null")
|
||||
assert_equal false, actual
|
||||
end
|
||||
|
||||
def test_refreshes_readline_after_bg_execution
|
||||
skip 'unimplemented'
|
||||
skip "unimplemented"
|
||||
end
|
||||
|
||||
#########################
|
||||
|
|
@ -74,25 +77,25 @@ class ShellTest < Minitest::Test
|
|||
#########################
|
||||
|
||||
def test_builtin_cd_no_args
|
||||
skip 'cannot easily implement without sequencing with ; or &&'
|
||||
skip "cannot easily implement without sequencing with ; or &&"
|
||||
end
|
||||
|
||||
def test_builtin_cd
|
||||
skip 'cannot easily implement without sequencing with ; or &&'
|
||||
skip "cannot easily implement without sequencing with ; or &&"
|
||||
end
|
||||
|
||||
def test_builtin_cd_dash
|
||||
skip 'cannot easily implement without sequencing with ; or &&'
|
||||
skip "cannot easily implement without sequencing with ; or &&"
|
||||
end
|
||||
|
||||
def test_builtin_cd_parent
|
||||
skip 'cannot easily implement without sequencing with ; or &&'
|
||||
skip "cannot easily implement without sequencing with ; or &&"
|
||||
end
|
||||
|
||||
def test_builtin_pwd
|
||||
assert_equal Dir.pwd, `#{A1_PATH} -c pwd`.chomp
|
||||
|
||||
shell_path = File.expand_path(A1_PATH, Dir.pwd)
|
||||
assert_equal '/usr/bin', `cd /usr/bin && '#{shell_path}' -c pwd`.chomp
|
||||
assert_equal "/usr/bin", `cd /usr/bin && '#{shell_path}' -c pwd`.chomp
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in a new issue