<commit_before>require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
require 'tmpdir'
require 'tempfile'
require 'timeout'

describe Mixlib::ShellOut do
  before do
    @shell_cmd = Mixlib::ShellOut.new("apt-get install chef")
  end

  it "has a command" do
    @shell_cmd.command.should == "apt-get install chef"
  end

  it "defaults to not setting a working directory" do
    @shell_cmd.cwd.should == nil
  end

  it "has a user to run the command as" do
    @shell_cmd.user.should be_nil
  end

  it "sets the user to run the command as" do
    @shell_cmd.user = 'root'
    @shell_cmd.user.should == 'root'
  end

  it "has a group to run the command as" do
    @shell_cmd.group.should be_nil
  end

  it "sets the group to run the command as" do
    @shell_cmd.group = 'wheel'
    @shell_cmd.group.should == 'wheel'
  end

  it "has a set of environment variables to set before running the command" do
    @shell_cmd.environment.should == {"LC_ALL" => "C"}
  end

  it "has a umask" do
    @shell_cmd.umask.should be_nil
  end

  it "sets the umask using an octal integer" do
    @shell_cmd.umask = 007777
    @shell_cmd.umask.should == 007777
  end

  it "sets the umask using a decimal integer" do
    @shell_cmd.umask = 2925
    @shell_cmd.umask.should == 005555
  end

  it "sets the umask using a string representation of an integer" do
    @shell_cmd.umask = '7777'
    @shell_cmd.umask.should == 007777
  end

  it "returns the user-supplied uid when present" do
    @shell_cmd.user = 0
    @shell_cmd.uid.should == 0
  end

  it "computes the uid of the user when a string/symbolic username is given" do
    unless windows?
      user_struct = Etc.getpwent
      username = user_struct.name
      expected_uid = user_struct.uid

      @shell_cmd.user = username
      @shell_cmd.uid.should == expected_uid
    end
  end

  it "returns the user-supplied gid when present" do
    @shell_cmd.group = 0
    @shell_cmd.gid.should == 0
  end

  it "computes the gid of the user when a string/symbolic groupname is given" do
    unless windows?
      a_group = Etc.getgrent
      @shell_cmd.group = a_group.name
      @shell_cmd.gid.should == a_group.gid
    end
  end

  it "has a timeout defaulting to 600 seconds" do
    Mixlib::ShellOut.new('foo').timeout.should == 600
  end

  it "sets the read timeout" do
    @shell_cmd.timeout = 10
    @shell_cmd.timeout.should == 10
  end

  it "has a list of valid exit codes which is just 0 by default" do
    @shell_cmd.valid_exit_codes.should == [0]
  end

  it "sets the list of valid exit codes" do
    @shell_cmd.valid_exit_codes = [0,23,42]
    @shell_cmd.valid_exit_codes.should == [0,23,42]
  end

  it "defaults to not having a live stream" do
    @shell_cmd.live_stream.should be_nil
  end

  it "sets a live stream" do
    stream = StringIO.new
    @shell_cmd.live_stream = stream
    @shell_cmd.live_stream.should == stream
  end

  context "when initialized with a hash of options" do
    before do
      @opts = { :cwd => '/tmp', :user => 'toor', :group => 'wheel', :umask => '2222',
                :timeout => 5, :environment => {'RUBY_OPTS' => '-w'}, :returns => [0,1,42],
                :live_stream => StringIO.new}
      @shell_cmd = Mixlib::ShellOut.new("brew install couchdb", @opts)
    end

    it "sets the working dir as specified in the options" do
      @shell_cmd.cwd.should == '/tmp'
    end

    it "sets the user as specified in the options" do
      @shell_cmd.user.should == 'toor'
    end

    it "sets the group as specified in the options" do
      @shell_cmd.group.should == 'wheel'
    end

    it "sets the umask as specified in the options" do
      @shell_cmd.umask.should == 002222
    end

    it "sets the timout as specified in the options" do
      @shell_cmd.timeout.should == 5
    end

    it "merges the environment with the default environment settings" do
      @shell_cmd.environment.should == {'LC_ALL' => 'C', 'RUBY_OPTS' => '-w'}
    end

    it "also accepts :env to set the enviroment for brevity's sake" do
      @shell_cmd = Mixlib::ShellOut.new("brew install couchdb", :env => {'RUBY_OPTS'=>'-w'})
      @shell_cmd.environment.should == {'LC_ALL' => 'C', 'RUBY_OPTS' => '-w'}
    end

    it "does not set any environment settings when given :environment => nil" do
      @shell_cmd = Mixlib::ShellOut.new("brew install couchdb", :environment => nil)
      @shell_cmd.environment.should == {}
    end

    it "sets the list of acceptable return values" do
      @shell_cmd.valid_exit_codes.should == [0,1,42]
    end

    it "sets the live stream specified in the options" do
      @shell_cmd.live_stream.should == @opts[:live_stream]
    end

    it "raises an error when given an invalid option" do
      klass = Mixlib::ShellOut::InvalidCommandOption
      msg   = "option ':frab' is not a valid option for Mixlib::ShellOut"
      lambda { Mixlib::ShellOut.new("foo", :frab => :jab) }.should raise_error(klass, msg)
    end

    it "chdir to the cwd directory if given" do
      # /bin should exists on all systems, and is not the default cwd
      if windows?
        dir = Dir.tmpdir
        cmd = Mixlib::ShellOut.new('echo %cd%', :cwd => dir)
      else
        dir = "/bin"
        cmd = Mixlib::ShellOut.new('pwd', :cwd => dir)
      end
      cmd.run_command
      File.expand_path(cmd.stdout.chomp).should == File.expand_path(dir)
    end
  end

  context "when initialized with an array of command+args and an options hash" do
    before do
      @opts = {:cwd => '/tmp', :user => 'nobody'}
      @shell_cmd = Mixlib::ShellOut.new('ruby', '-e', %q{'puts "hello"'}, @opts)
    end

    it "sets the command to the array of command and args" do
      @shell_cmd.command.should == ['ruby', '-e', %q{'puts "hello"'}]
    end

    it "evaluates the options" do
      @shell_cmd.cwd.should == '/tmp'
      @shell_cmd.user.should == 'nobody'
    end
  end

  context "when initialized with an array of command+args and no options" do
    before do
      @shell_cmd = Mixlib::ShellOut.new('ruby', '-e', %q{'puts "hello"'})
    end

    it "sets the command to the array of command+args" do
      @shell_cmd.command.should == ['ruby', '-e', %q{'puts "hello"'}]
    end

  end

  context "when created with a live stream" do
    before do
      @stream = StringIO.new
      @shell_cmd = Mixlib::ShellOut.new(%q{ruby -e 'puts "hello"'}, :live_stream => @stream)
    end

    it "copies the subprocess' stdout to the live stream" do
      @shell_cmd.run_command
      @stream.string.should == "hello#{LINE_ENDING}"
    end
  end
<commit_msg>[RSPEC] Refactored @ instant variables to let() definitions<commit_after>require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
require 'tmpdir'
require 'tempfile'
require 'timeout'

describe Mixlib::ShellOut do
  let(:shell_cmd) { Mixlib::ShellOut.new("apt-get install chef") }

  it "has a command" do
    shell_cmd.command.should == "apt-get install chef"
  end

  it "defaults to not setting a working directory" do
    shell_cmd.cwd.should == nil
  end

  it "has a user to run the command as" do
    shell_cmd.user.should be_nil
  end

  it "sets the user to run the command as" do
    shell_cmd.user = 'root'
    shell_cmd.user.should == 'root'
  end

  it "has a group to run the command as" do
    shell_cmd.group.should be_nil
  end

  it "sets the group to run the command as" do
    shell_cmd.group = 'wheel'
    shell_cmd.group.should == 'wheel'
  end

  it "has a set of environment variables to set before running the command" do
    shell_cmd.environment.should == {"LC_ALL" => "C"}
  end

  it "has a umask" do
    shell_cmd.umask.should be_nil
  end

  it "sets the umask using an octal integer" do
    shell_cmd.umask = 007777
    shell_cmd.umask.should == 007777
  end

  it "sets the umask using a decimal integer" do
    shell_cmd.umask = 2925
    shell_cmd.umask.should == 005555
  end

  it "sets the umask using a string representation of an integer" do
    shell_cmd.umask = '7777'
    shell_cmd.umask.should == 007777
  end

  it "returns the user-supplied uid when present" do
    shell_cmd.user = 0
    shell_cmd.uid.should == 0
  end

  it "computes the uid of the user when a string/symbolic username is given" do
    unless windows?
      user_struct = Etc.getpwent
      username = user_struct.name
      expected_uid = user_struct.uid

      shell_cmd.user = username
      shell_cmd.uid.should == expected_uid
    end
  end

  it "returns the user-supplied gid when present" do
    shell_cmd.group = 0
    shell_cmd.gid.should == 0
  end

  it "computes the gid of the user when a string/symbolic groupname is given" do
    unless windows?
      a_group = Etc.getgrent
      shell_cmd.group = a_group.name
      shell_cmd.gid.should == a_group.gid
    end
  end

  it "has a timeout defaulting to 600 seconds" do
    Mixlib::ShellOut.new('foo').timeout.should == 600
  end

  it "sets the read timeout" do
    shell_cmd.timeout = 10
    shell_cmd.timeout.should == 10
  end

  it "has a list of valid exit codes which is just 0 by default" do
    shell_cmd.valid_exit_codes.should == [0]
  end

  it "sets the list of valid exit codes" do
    shell_cmd.valid_exit_codes = [0,23,42]
    shell_cmd.valid_exit_codes.should == [0,23,42]
  end

  it "defaults to not having a live stream" do
    shell_cmd.live_stream.should be_nil
  end

  it "sets a live stream" do
    stream = StringIO.new
    shell_cmd.live_stream = stream
    shell_cmd.live_stream.should == stream
  end

  context "when initialized with a hash of options" do
      let(:options) { { :cwd => '/tmp', :user => 'toor', :group => 'wheel', :umask => '2222',
                :timeout => 5, :environment => {'RUBY_OPTS' => '-w'}, :returns => [0,1,42],
                :live_stream => StringIO.new} }
      let(:shell_cmd) { Mixlib::ShellOut.new("brew install couchdb", options) }

    it "sets the working dir as specified in the options" do
      shell_cmd.cwd.should == '/tmp'
    end

    it "sets the user as specified in the options" do
      shell_cmd.user.should == 'toor'
    end

    it "sets the group as specified in the options" do
      shell_cmd.group.should == 'wheel'
    end

    it "sets the umask as specified in the options" do
      shell_cmd.umask.should == 002222
    end

    it "sets the timout as specified in the options" do
      shell_cmd.timeout.should == 5
    end

    it "merges the environment with the default environment settings" do
      shell_cmd.environment.should == {'LC_ALL' => 'C', 'RUBY_OPTS' => '-w'}
    end

    it "also accepts :env to set the enviroment for brevity's sake" do
      shell_cmd = Mixlib::ShellOut.new("brew install couchdb", :env => {'RUBY_OPTS'=>'-w'})
      shell_cmd.environment.should == {'LC_ALL' => 'C', 'RUBY_OPTS' => '-w'}
    end

    it "does not set any environment settings when given :environment => nil" do
      shell_cmd = Mixlib::ShellOut.new("brew install couchdb", :environment => nil)
      shell_cmd.environment.should == {}
    end

    it "sets the list of acceptable return values" do
      shell_cmd.valid_exit_codes.should == [0,1,42]
    end

    it "sets the live stream specified in the options" do
      shell_cmd.live_stream.should == options[:live_stream]
    end

    it "raises an error when given an invalid option" do
      klass = Mixlib::ShellOut::InvalidCommandOption
      msg   = "option ':frab' is not a valid option for Mixlib::ShellOut"
      lambda { Mixlib::ShellOut.new("foo", :frab => :jab) }.should raise_error(klass, msg)
    end

    it "chdir to the cwd directory if given" do
      # /bin should exists on all systems, and is not the default cwd
      if windows?
        dir = Dir.tmpdir
        cmd = Mixlib::ShellOut.new('echo %cd%', :cwd => dir)
      else
        dir = "/bin"
        cmd = Mixlib::ShellOut.new('pwd', :cwd => dir)
      end
      cmd.run_command
      File.expand_path(cmd.stdout.chomp).should == File.expand_path(dir)
    end
  end

  context "when initialized with an array of command+args and an options hash" do
    let(:options) { {:cwd => '/tmp', :user => 'nobody'} }
    let(:shell_cmd) { Mixlib::ShellOut.new('ruby', '-e', %q{'puts "hello"'}, options) }

    it "sets the command to the array of command and args" do
      shell_cmd.command.should == ['ruby', '-e', %q{'puts "hello"'}]
    end

    it "evaluates the options" do
      shell_cmd.cwd.should == '/tmp'
      shell_cmd.user.should == 'nobody'
    end
  end

  context "when initialized with an array of command+args and no options" do
    let(:shell_cmd) { Mixlib::ShellOut.new('ruby', '-e', %q{'puts "hello"'}) }

    it "sets the command to the array of command+args" do
      shell_cmd.command.should == ['ruby', '-e', %q{'puts "hello"'}]
    end

  end

  context "when created with a live stream" do
    let(:stream) { StringIO.new }
    let(:shell_cmd) { Mixlib::ShellOut.new(%q{ruby -e 'puts "hello"'}, :live_stream => stream) }

    it "copies the subprocess' stdout to the live stream" do
      shell_cmd.run_command
      stream.string.should == "hello#{LINE_ENDING}"
    end
  end

{'fraction_non_alphanumeric': 0.11224879651562619, 'fraction_numerical': 0.011920226178650569, 'mean_word_length': 2.87333530630364, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7042996', 'n_tokens_mistral': 4478, 'n_tokens_neox': 4249, 'n_words': 1417}