Module: ShellMock

Defined in:
lib/shell_mock.rb,
lib/shell_mock/version.rb,
lib/shell_mock/command_stub.rb,
lib/shell_mock/monkey_patch.rb,
lib/shell_mock/call_verifier.rb,
lib/shell_mock/stub_registry.rb,
lib/shell_mock/monkey_patches.rb,
lib/shell_mock/rspec/matchers.rb,
lib/shell_mock/no_stub_specified.rb

Defined Under Namespace

Modules: Matchers Classes: CallVerifier, CommandStub, MonkeyPatch, NoStubSpecified

Constant Summary collapse

VERSION =
"0.4.0"
StubRegistry =
Object.new
SpawnMonkeyPatch =
MonkeyPatch.new(:spawn) do |env, command = nil, **options|
  env, command = {}, env if command.nil?

  # other arg manipulation can go here if necessary

  stub = StubRegistry.stub_matching(env, command, options)

  if stub
    stub.side_effect.call
    stub.called_with(env, command, options)

    __un_shell_mocked_spawn("exit #{stub.exitstatus}")
  else
    if ShellMock.let_commands_run?
      __un_shell_mocked_spawn(env, command, **options)
    else
      raise NoStubSpecified.new(env, command, options)
    end
  end
end
SystemMonkeyPatch =
MonkeyPatch.new(:system) do |env, command = nil, **options|
  env, command = {}, env if command.nil?

  # other arg manipulation can go here if necessary

  stub = StubRegistry.stub_matching(env, command, options)

  if stub
    stub.side_effect.call
    stub.called_with(env, command, options)
    __un_shell_mocked_backtick("exit #{stub.exitstatus}")

    return stub.exitstatus == 0
  else
    if ShellMock.let_commands_run?
      __un_shell_mocked_system(env, command, **options)
    else
      raise NoStubSpecified.new(env, command, options)
    end
  end
end
ExecMonkeyPatch =

This feels very boilerplatey because Kernel::system and Kernel::exec have very similar if not identical method signatures. I’m not sure whether extracting the commonalities would be worth it or would just confuse.

MonkeyPatch.new(:exec) do |env, command = nil, **options|
  env, command = {}, env if command.nil?

  # other arg manipulation can go here if necessary

  stub = StubRegistry.stub_matching(env, command, options)

  if stub
    stub.side_effect.call
    stub.called_with(env, command, options)

    exit stub.exitstatus
  else
    if ShellMock.let_commands_run?
      __un_shell_mocked_exec(env, command, **options)
    else
      raise NoStubSpecified.new(env, command, options)
    end
  end
end
BacktickMonkeyPatch =
MonkeyPatch.new('`', :backtick) do |command|
  stub = StubRegistry.stub_matching({}, command, {})

  if stub
    stub.side_effect.call
    stub.called_with({}, command, {})
    __un_shell_mocked_backtick("exit #{stub.exitstatus}")

    return stub.expected_output
  else
    if ShellMock.let_commands_run?
      __un_shell_mocked_backtick(command)
    else
      raise NoStubSpecified.new({}, command, {})
    end
  end
end

Class Method Summary collapse

Class Method Details

.disableObject



38
39
40
41
42
43
44
45
# File 'lib/shell_mock.rb', line 38

def self.disable
  ShellMock.monkey_patches.each do |patch|
    patch.disable_for(Kernel.eigenclass) if Kernel.respond_to?(patch.alias_for_original, true)
    patch.disable_for(Kernel)            if Object.new.respond_to?(patch.alias_for_original, true)
  end

  StubRegistry.clear
end

.dont_let_commands_runObject



18
19
20
# File 'lib/shell_mock.rb', line 18

def self.dont_let_commands_run
  @let_commands_run = false
end

.dont_let_commands_run?Boolean

Returns:

  • (Boolean)


27
28
29
# File 'lib/shell_mock.rb', line 27

def self.dont_let_commands_run?
  !let_commands_run?
end

.enableObject



31
32
33
34
35
36
# File 'lib/shell_mock.rb', line 31

def self.enable
  ShellMock.monkey_patches.each do |patch|
    patch.enable_for(Kernel.eigenclass) unless Kernel.respond_to?(patch.alias_for_original, true)
    patch.enable_for(Kernel)            unless Object.new.respond_to?(patch.alias_for_original, true)
  end
end

.let_commands_runObject



14
15
16
# File 'lib/shell_mock.rb', line 14

def self.let_commands_run
  @let_commands_run = true
end

.let_commands_run?Boolean

Returns:

  • (Boolean)


22
23
24
25
# File 'lib/shell_mock.rb', line 22

def self.let_commands_run?
  @let_commands_run = true if @let_commands_run.nil?
  @let_commands_run
end

.monkey_patchesObject



47
48
49
50
51
52
53
54
# File 'lib/shell_mock.rb', line 47

def self.monkey_patches
  [
    SpawnMonkeyPatch,
    SystemMonkeyPatch,
    ExecMonkeyPatch,
    BacktickMonkeyPatch
  ]
end

.stub_command(command) ⇒ Object



8
9
10
11
12
# File 'lib/shell_mock.rb', line 8

def self.stub_command(command)
  command_stub = CommandStub.new(command)

  StubRegistry.register_command_stub(command_stub)
end