shell_mock 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b82fb0b1848c54881355c530fcf8fa4f22d292a4
4
- data.tar.gz: cf94368b1e001a8f7ecc80a10ff1b0ff94655cc7
3
+ metadata.gz: b5d26902e2b08b891fd639c5d2c9d8fcfb91fdbf
4
+ data.tar.gz: 134fb6f92164e23d0f32383b697b048d2c499548
5
5
  SHA512:
6
- metadata.gz: e1e789a08c56339d8356d97d585bf405754582ad03a4c574f10873a05eb63951bd6ba867e725bb795a034cb096b19a6fd467d70cf9a760062462295c3dc1eb63
7
- data.tar.gz: 07bc5c7aa946c4a34d932c61812d970da5cfb31cfea5bf35aca899b965011290a2e13a2fce010677354bf89cb51a2bc98241b2362ab4f70341af5aff2695140b
6
+ metadata.gz: 3d4062f5eb6a898e2521db636c2ac5f91d5290c76bab7f67256f3a5f77e595c5005909a85b6b8edb6541b91a26f5b882bca7e102c3f6db619d5a41e31341b309
7
+ data.tar.gz: 2b25642dfe523d750bc3bda8a828b102d4340012fe5c23d96d38f11e7aa9d71643abde1adc9f9bd53ff8146d7c6a9df6250e7a59b06abec1043da6f82af3301c
data/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  * add `with_side_effect(&blk)` for specifying desired side effects
4
4
 
5
+ ## RELEASE 0.3.1
6
+
7
+ * FIX: ``Kernel.` ``, `Kernel.exec`, and `Kernel.system` are now all supported as well. This is useful to testing thor suites that shell out, because thor (for reasons passing understanding) redefines `#exec`, so we have to resort to `Kernel.exec`.
8
+
5
9
  ## RELEASE 0.3.0
6
10
 
7
11
  * FEATURE: you can now stub & mock `Kernel#exec`.
data/README.md CHANGED
@@ -14,6 +14,8 @@ describe 'something' do
14
14
  end
15
15
  ```
16
16
 
17
+ Currently, `` ` ``, `exec`, and `system` are supported. Nothing in the `Open3` standard library module is currently supported.
18
+
17
19
  ### More complex expectations are also supported.
18
20
 
19
21
  Called exactly once: `expect(stub).to have_been_called.once`
@@ -2,10 +2,13 @@ require 'shell_mock/call_verifier'
2
2
 
3
3
  module ShellMock
4
4
  class CommandStub
5
- attr_reader :command, :expected_output, :exitstatus
5
+ attr_reader :command, :expected_output, :exitstatus, :env, :options, :side_effect
6
6
 
7
7
  def initialize(command)
8
- @command = command
8
+ @command = command
9
+ @env = {}
10
+ @options = {}
11
+ @side_effect = proc {}
9
12
  end
10
13
 
11
14
  def with_env(env)
@@ -14,20 +17,12 @@ module ShellMock
14
17
  self
15
18
  end
16
19
 
17
- def env
18
- @env || {}
19
- end
20
-
21
20
  def with_option(option)
22
21
  @options = options
23
22
 
24
23
  self
25
24
  end
26
25
 
27
- def options
28
- @options || {}
29
- end
30
-
31
26
  def and_return(expected_output)
32
27
  @expected_output = expected_output
33
28
  @exitstatus ||= 0
@@ -41,10 +36,6 @@ module ShellMock
41
36
  self
42
37
  end
43
38
 
44
- def side_effect
45
- @side_effect || proc {}
46
- end
47
-
48
39
  def calls
49
40
  @calls ||= []
50
41
  end
@@ -0,0 +1,5 @@
1
+ Module.class_exec do
2
+ def eigenclass
3
+ @eigenclass ||= class << self; self; end
4
+ end
5
+ end
@@ -1,7 +1,47 @@
1
1
  require 'shell_mock/no_stub_specified'
2
2
 
3
- module Kernel
4
- def __shell_mocked_system(env, command = nil, **options)
3
+ module ShellMock
4
+ class MonkeyPatch
5
+ attr_reader :original, :alias_for_original
6
+
7
+ def initialize(original_name, interpolable_name = original_name, &block)
8
+ @original = original_name
9
+ @alias_for_original = "__un_shell_mocked_#{interpolable_name}"
10
+ @replacement = "__shell_mocked_#{interpolable_name}"
11
+ @block = block
12
+ end
13
+
14
+ def to_proc
15
+ @block.to_proc
16
+ end
17
+
18
+ def enable_for(class_or_module)
19
+ class_or_module.send(:alias_method, alias_for_original, original)
20
+
21
+ begin
22
+ class_or_module.send(:remove_method, original) # for warnings
23
+ rescue NameError
24
+ end
25
+
26
+ class_or_module.send(:define_method, original, &to_proc)
27
+ end
28
+
29
+ def disable_for(class_or_module)
30
+ begin
31
+ class_or_module.send(:remove_method, original) # for warnings
32
+ rescue NameError
33
+ end
34
+
35
+ class_or_module.send(:alias_method, original, alias_for_original)
36
+
37
+ begin
38
+ class_or_module.send(:remove_method, alias_for_original)
39
+ rescue NameError
40
+ end
41
+ end
42
+ end
43
+
44
+ SystemMonkeyPatch = MonkeyPatch.new(:system) do |env, command = nil, **options|
5
45
  env, command = {}, env if command.nil?
6
46
 
7
47
  # other arg manipulation
@@ -10,8 +50,8 @@ module Kernel
10
50
 
11
51
  if stub
12
52
  stub.side_effect.call
13
- `exit #{stub.exitstatus}`
14
53
  stub.called_with(env, command, options)
54
+ __un_shell_mocked_backtick("exit #{stub.exitstatus}")
15
55
 
16
56
  return stub.exitstatus == 0
17
57
  else
@@ -27,7 +67,7 @@ module Kernel
27
67
  # have very similar if not identical method signatures. I'm not sure
28
68
  # whether extracting the commonalities would be worth it or just
29
69
  # confuse.
30
- def __shell_mocked_exec(env, command = nil, **options)
70
+ ExecMonkeyPatch = MonkeyPatch.new(:exec) do |env, command = nil, **options|
31
71
  env, command = {}, env if command.nil?
32
72
 
33
73
  # other arg manipulation
@@ -36,10 +76,9 @@ module Kernel
36
76
 
37
77
  if stub
38
78
  stub.side_effect.call
39
- `exit #{stub.exitstatus}`
40
79
  stub.called_with(env, command, options)
41
80
 
42
- return stub.exitstatus == 0
81
+ exit stub.exitstatus
43
82
  else
44
83
  if ShellMock.let_commands_run?
45
84
  __un_shell_mocked_exec(env, command, **options)
@@ -49,12 +88,12 @@ module Kernel
49
88
  end
50
89
  end
51
90
 
52
- def __shell_mocked_backtick(command)
91
+ BacktickMonkeyPatch = MonkeyPatch.new(:`, :backtick) do |command|
53
92
  stub = ShellMock::StubRegistry.stub_matching({}, command, {})
54
93
 
55
94
  if stub
56
95
  stub.side_effect.call
57
- `exit #{stub.exitstatus}`
96
+ __un_shell_mocked_backtick("exit #{stub.exitstatus}")
58
97
  stub.called_with({}, command, {})
59
98
 
60
99
  return stub.expected_output
@@ -5,9 +5,6 @@ require 'rspec/expectations'
5
5
 
6
6
  require 'shell_mock/rspec/matchers'
7
7
 
8
- ShellMock.enable
9
- ShellMock.dont_let_commands_run
10
-
11
8
  RSpec.configure do |config|
12
9
  config.include ShellMock::Matchers
13
10
  end
@@ -1,3 +1,3 @@
1
1
  module ShellMock
2
- VERSION = "0.3.0"
2
+ VERSION = "0.3.1"
3
3
  end
data/lib/shell_mock.rb CHANGED
@@ -1,7 +1,8 @@
1
1
  require "shell_mock/version"
2
2
  require 'shell_mock/stub_registry'
3
3
  require 'shell_mock/command_stub'
4
- require 'shell_mock/core_ext/kernel'
4
+ require 'shell_mock/monkey_patch'
5
+ require 'shell_mock/core_ext/module'
5
6
 
6
7
  module ShellMock
7
8
  def self.stub_command(command)
@@ -28,35 +29,22 @@ module ShellMock
28
29
  end
29
30
 
30
31
  def self.enable
31
- Kernel.module_exec do
32
- ShellMock.alias_specifications.each do |spec|
33
- if respond_to?(spec.replacement)
34
- define_method(spec.alias_for_original, &method(spec.original).to_proc)
35
- define_method(spec.original, &method(spec.replacement).to_proc)
36
- end
37
- end
32
+ ShellMock.monkey_patches.each do |patch|
33
+ patch.enable_for(Kernel.eigenclass) unless Kernel.respond_to?(patch.alias_for_original, true)
34
+ patch.enable_for(Kernel) unless Object.new.respond_to?(patch.alias_for_original, true)
38
35
  end
39
36
  end
40
37
 
41
38
  def self.disable
42
- Kernel.module_exec do
43
- ShellMock.alias_specifications.each do |spec|
44
- if respond_to?(spec.alias_for_original)
45
- define_method(spec.original, &method(spec.alias_for_original).to_proc)
46
- end
47
- end
39
+ ShellMock.monkey_patches.each do |patch|
40
+ patch.disable_for(Kernel.eigenclass) if Kernel.respond_to?(patch.alias_for_original, true)
41
+ patch.disable_for(Kernel) if Object.new.respond_to?(patch.alias_for_original, true)
48
42
  end
49
43
 
50
44
  StubRegistry.clear
51
45
  end
52
46
 
53
- AliasSpecification = Struct.new(:original, :alias_for_original, :replacement)
54
-
55
- def self.alias_specifications
56
- [
57
- AliasSpecification.new(:system, :__un_shell_mocked_system, :__shell_mocked_system),
58
- AliasSpecification.new(:exec, :__un_shell_mocked_exec, :__shell_mocked_exec),
59
- AliasSpecification.new(:`, :__un_shell_mocked_backtick, :__shell_mocked_backtick),
60
- ]
47
+ def self.monkey_patches
48
+ [SystemMonkeyPatch, ExecMonkeyPatch, BacktickMonkeyPatch]
61
49
  end
62
50
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shell_mock
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Hoffman
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-04-06 00:00:00.000000000 Z
11
+ date: 2017-04-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -116,7 +116,8 @@ files:
116
116
  - lib/shell_mock.rb
117
117
  - lib/shell_mock/call_verifier.rb
118
118
  - lib/shell_mock/command_stub.rb
119
- - lib/shell_mock/core_ext/kernel.rb
119
+ - lib/shell_mock/core_ext/module.rb
120
+ - lib/shell_mock/monkey_patch.rb
120
121
  - lib/shell_mock/no_stub_specified.rb
121
122
  - lib/shell_mock/rspec.rb
122
123
  - lib/shell_mock/rspec/matchers.rb