spy 1.0.3 → 1.0.5
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 +4 -4
- data/.github/workflows/ruby.yml +38 -0
- data/.tool-versions +1 -1
- data/CHANGELOG.md +20 -0
- data/README.md +3 -4
- data/lib/spy/call_log.rb +6 -3
- data/lib/spy/subroutine.rb +14 -26
- data/lib/spy/version.rb +1 -1
- data/spy.gemspec +1 -1
- data/test/spy/test_subroutine.rb +22 -0
- data/test/support/pen.rb +4 -0
- metadata +4 -36
- data/.travis.yml +0 -13
- data/spec/spec_helper.rb +0 -41
- data/spec/spy/and_call_original_spec.rb +0 -152
- data/spec/spy/and_yield_spec.rb +0 -123
- data/spec/spy/any_instance_spec.rb +0 -518
- data/spec/spy/hash_excluding_matcher_spec.rb +0 -63
- data/spec/spy/hash_including_matcher_spec.rb +0 -86
- data/spec/spy/mutate_const_spec.rb +0 -471
- data/spec/spy/nil_expectation_warning_spec.rb +0 -56
- data/spec/spy/null_object_mock_spec.rb +0 -79
- data/spec/spy/partial_mock_spec.rb +0 -81
- data/spec/spy/passing_argument_matchers_spec.rb +0 -140
- data/spec/spy/serialization_spec.rb +0 -116
- data/spec/spy/stash_spec.rb +0 -47
- data/spec/spy/stub_implementation_spec.rb +0 -64
- data/spec/spy/stub_spec.rb +0 -79
- data/spec/spy/to_ary_spec.rb +0 -40
@@ -1,140 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Spy
|
4
|
-
describe "Matchers", :broken do
|
5
|
-
before(:each) do
|
6
|
-
@double = double('double')
|
7
|
-
Spy.on(Kernel, :warn)
|
8
|
-
end
|
9
|
-
|
10
|
-
after(:each) do
|
11
|
-
@double.rspec_verify
|
12
|
-
end
|
13
|
-
|
14
|
-
context "handling argument matchers" do
|
15
|
-
it "accepts true as boolean()" do
|
16
|
-
@double.should_receive(:random_call).with(boolean())
|
17
|
-
@double.random_call(true)
|
18
|
-
end
|
19
|
-
|
20
|
-
it "accepts false as boolean()" do
|
21
|
-
@double.should_receive(:random_call).with(boolean())
|
22
|
-
@double.random_call(false)
|
23
|
-
end
|
24
|
-
|
25
|
-
it "accepts fixnum as kind_of(Numeric)" do
|
26
|
-
@double.should_receive(:random_call).with(kind_of(Numeric))
|
27
|
-
@double.random_call(1)
|
28
|
-
end
|
29
|
-
|
30
|
-
it "accepts float as an_instance_of(Numeric)" do
|
31
|
-
@double.should_receive(:random_call).with(kind_of(Numeric))
|
32
|
-
@double.random_call(1.5)
|
33
|
-
end
|
34
|
-
|
35
|
-
it "accepts fixnum as instance_of(Fixnum)" do
|
36
|
-
@double.should_receive(:random_call).with(instance_of(Fixnum))
|
37
|
-
@double.random_call(1)
|
38
|
-
end
|
39
|
-
|
40
|
-
it "does NOT accept fixnum as instance_of(Numeric)" do
|
41
|
-
@double.should_not_receive(:random_call).with(instance_of(Numeric))
|
42
|
-
@double.random_call(1)
|
43
|
-
end
|
44
|
-
|
45
|
-
it "does NOT accept float as instance_of(Numeric)" do
|
46
|
-
@double.should_not_receive(:random_call).with(instance_of(Numeric))
|
47
|
-
@double.random_call(1.5)
|
48
|
-
end
|
49
|
-
|
50
|
-
it "accepts string as anything()" do
|
51
|
-
@double.should_receive(:random_call).with("a", anything(), "c")
|
52
|
-
@double.random_call("a", "whatever", "c")
|
53
|
-
end
|
54
|
-
|
55
|
-
it "matches duck type with one method" do
|
56
|
-
@double.should_receive(:random_call).with(duck_type(:length))
|
57
|
-
@double.random_call([])
|
58
|
-
end
|
59
|
-
|
60
|
-
it "matches duck type with two methods" do
|
61
|
-
@double.should_receive(:random_call).with(duck_type(:abs, :div))
|
62
|
-
@double.random_call(1)
|
63
|
-
end
|
64
|
-
|
65
|
-
it "matches no args against any_args()" do
|
66
|
-
@double.should_receive(:random_call).with(any_args)
|
67
|
-
@double.random_call()
|
68
|
-
end
|
69
|
-
|
70
|
-
it "matches one arg against any_args()" do
|
71
|
-
@double.should_receive(:random_call).with(any_args)
|
72
|
-
@double.random_call("a string")
|
73
|
-
end
|
74
|
-
|
75
|
-
it "matches no args against no_args()" do
|
76
|
-
@double.should_receive(:random_call).with(no_args)
|
77
|
-
@double.random_call()
|
78
|
-
end
|
79
|
-
|
80
|
-
it "matches hash with hash_including same hash" do
|
81
|
-
@double.should_receive(:random_call).with(hash_including(:a => 1))
|
82
|
-
@double.random_call(:a => 1)
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
context "handling block matchers" do
|
87
|
-
it "matches arguments against RSpec expectations" do
|
88
|
-
@double.should_receive(:random_call).with {|arg1, arg2, arr, *rest|
|
89
|
-
expect(arg1).to eq 5
|
90
|
-
expect(arg2).to have_at_least(3).characters
|
91
|
-
expect(arg2).to have_at_most(10).characters
|
92
|
-
expect(arr.map {|i| i * 2}).to eq [2,4,6]
|
93
|
-
expect(rest).to eq [:fee, "fi", 4]
|
94
|
-
}
|
95
|
-
@double.random_call 5, "hello", [1,2,3], :fee, "fi", 4
|
96
|
-
end
|
97
|
-
|
98
|
-
it "does not eval the block as the return value" do
|
99
|
-
eval_count = 0
|
100
|
-
@double.should_receive(:msg).with {|a| eval_count += 1}
|
101
|
-
@double.msg(:ignore)
|
102
|
-
expect(eval_count).to eq(1)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
context "handling non-matcher arguments" do
|
107
|
-
it "matches non special symbol (can be removed when deprecated symbols are removed)" do
|
108
|
-
@double.should_receive(:random_call).with(:some_symbol)
|
109
|
-
@double.random_call(:some_symbol)
|
110
|
-
end
|
111
|
-
|
112
|
-
it "matches string against regexp" do
|
113
|
-
@double.should_receive(:random_call).with(/bcd/)
|
114
|
-
@double.random_call("abcde")
|
115
|
-
end
|
116
|
-
|
117
|
-
it "matches regexp against regexp" do
|
118
|
-
@double.should_receive(:random_call).with(/bcd/)
|
119
|
-
@double.random_call(/bcd/)
|
120
|
-
end
|
121
|
-
|
122
|
-
it "matches against a hash submitted and received by value" do
|
123
|
-
@double.should_receive(:random_call).with(:a => "a", :b => "b")
|
124
|
-
@double.random_call(:a => "a", :b => "b")
|
125
|
-
end
|
126
|
-
|
127
|
-
it "matches against a hash submitted by reference and received by value" do
|
128
|
-
opts = {:a => "a", :b => "b"}
|
129
|
-
@double.should_receive(:random_call).with(opts)
|
130
|
-
@double.random_call(:a => "a", :b => "b")
|
131
|
-
end
|
132
|
-
|
133
|
-
it "matches against a hash submitted by value and received by reference" do
|
134
|
-
opts = {:a => "a", :b => "b"}
|
135
|
-
@double.should_receive(:random_call).with(:a => "a", :b => "b")
|
136
|
-
@double.random_call(opts)
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
@@ -1,116 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'yaml'
|
3
|
-
require 'psych'
|
4
|
-
require 'syck'
|
5
|
-
|
6
|
-
module Spy
|
7
|
-
describe "serialization" do
|
8
|
-
|
9
|
-
class SerializableObject < Struct.new(:foo, :bar); end
|
10
|
-
|
11
|
-
class SerializableMockProxy
|
12
|
-
attr_reader :mock_proxy
|
13
|
-
|
14
|
-
def initialize(mock_proxy)
|
15
|
-
@mock_proxy = mock_proxy
|
16
|
-
end
|
17
|
-
|
18
|
-
def ==(other)
|
19
|
-
other.class == self.class && other.mock_proxy == mock_proxy
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.with_yaml_loaded(&block)
|
24
|
-
context 'with YAML loaded' do
|
25
|
-
module_eval(&block)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def self.without_yaml_loaded(&block)
|
30
|
-
context 'without YAML loaded' do
|
31
|
-
before do
|
32
|
-
# We can't really unload yaml, but we can fake it here...
|
33
|
-
@yaml = YAML
|
34
|
-
Object.send(:remove_const, "YAML")
|
35
|
-
Struct.class_eval do
|
36
|
-
alias __old_to_yaml to_yaml
|
37
|
-
undef to_yaml
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
module_eval(&block)
|
42
|
-
|
43
|
-
after do
|
44
|
-
Struct.class_eval do
|
45
|
-
alias to_yaml __old_to_yaml
|
46
|
-
undef __old_to_yaml
|
47
|
-
end
|
48
|
-
|
49
|
-
Object.send(:const_set, "YAML", @yaml)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
let(:serializable_object) { SerializableObject.new(7, "something") }
|
55
|
-
|
56
|
-
def set_spy
|
57
|
-
Spy::Subroutine.new(serializable_object, :bazz).hook(force: true).and_return(5)
|
58
|
-
end
|
59
|
-
|
60
|
-
shared_examples_for 'normal YAML serialization' do
|
61
|
-
it 'serializes to yaml the same with and without stubbing, using #to_yaml' do
|
62
|
-
set_spy
|
63
|
-
expect { Spy.get(serializable_object, :bazz) }.to_not change { serializable_object.to_yaml }
|
64
|
-
end
|
65
|
-
|
66
|
-
it 'serializes to yaml the same with and without stubbing, using YAML.dump' do
|
67
|
-
set_spy
|
68
|
-
expect { Spy.get(serializable_object, :bazz) }.to_not change { ::YAML.dump(serializable_object) }
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
with_yaml_loaded do
|
73
|
-
compiled_with_psych = begin
|
74
|
-
require 'psych'
|
75
|
-
true
|
76
|
-
rescue LoadError
|
77
|
-
false
|
78
|
-
end
|
79
|
-
|
80
|
-
if compiled_with_psych
|
81
|
-
context 'using Syck as the YAML engine' do
|
82
|
-
before(:each) { ::YAML::ENGINE.yamler = 'syck' }
|
83
|
-
it_behaves_like 'normal YAML serialization'
|
84
|
-
end
|
85
|
-
|
86
|
-
context 'using Psych as the YAML engine' do
|
87
|
-
before(:each) { ::YAML::ENGINE.yamler = 'psych' }
|
88
|
-
it_behaves_like 'normal YAML serialization'
|
89
|
-
end
|
90
|
-
else
|
91
|
-
it_behaves_like 'normal YAML serialization'
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
without_yaml_loaded do
|
96
|
-
it 'does not add #to_yaml to the stubbed object' do
|
97
|
-
expect(serializable_object).not_to respond_to(:to_yaml)
|
98
|
-
set_spy
|
99
|
-
expect(serializable_object).not_to respond_to(:to_yaml)
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
it 'marshals the same with and without stubbing' do
|
104
|
-
expect { Spy.get(serializable_object, :bazz) }.to_not change { Marshal.dump(serializable_object) }
|
105
|
-
end
|
106
|
-
|
107
|
-
describe "an object that has its own mock_proxy instance variable" do
|
108
|
-
let(:serializable_object) { SerializableMockProxy.new(:my_mock_proxy) }
|
109
|
-
|
110
|
-
it 'does not interfere with its marshalling' do
|
111
|
-
marshalled_copy = Marshal.load(Marshal.dump(serializable_object))
|
112
|
-
expect(marshalled_copy).to eq serializable_object
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
data/spec/spy/stash_spec.rb
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Spy
|
4
|
-
describe "only stashing the original method" do
|
5
|
-
let(:klass) do
|
6
|
-
Class.new do
|
7
|
-
def self.foo(arg)
|
8
|
-
:original_value
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
it "keeps the original method intact after multiple expectations are added on the same method" do
|
14
|
-
spy = Spy.on(klass, :foo)
|
15
|
-
klass.foo(:bazbar)
|
16
|
-
expect(spy).to have_been_called
|
17
|
-
Spy.off(klass, :foo)
|
18
|
-
|
19
|
-
expect(klass.foo(:yeah)).to equal(:original_value)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
describe "when a class method is aliased on a subclass and the method is mocked" do
|
24
|
-
let(:klass) do
|
25
|
-
Class.new do
|
26
|
-
class << self
|
27
|
-
alias alternate_new new
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
it "restores the original aliased public method" do
|
33
|
-
klass = Class.new do
|
34
|
-
class << self
|
35
|
-
alias alternate_new new
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
spy = Spy.on(klass, :alternate_new)
|
40
|
-
expect(klass.alternate_new).to be_nil
|
41
|
-
expect(spy).to have_been_called
|
42
|
-
|
43
|
-
Spy.off(klass, :alternate_new)
|
44
|
-
expect(klass.alternate_new).to be_an_instance_of(klass)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Spy
|
4
|
-
describe Subroutine do
|
5
|
-
class Bar
|
6
|
-
def foo(given = nil)
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
let(:obj) { Bar.new }
|
11
|
-
describe "stub implementation" do
|
12
|
-
describe "with no args" do
|
13
|
-
it "execs the block when called" do
|
14
|
-
Subroutine.new(obj, :foo).hook.and_return { :bar }
|
15
|
-
expect(obj.foo).to eq :bar
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
describe "with one arg" do
|
20
|
-
it "execs the block with that arg when called" do
|
21
|
-
Subroutine.new(obj, :foo).hook.and_return {|given| given}
|
22
|
-
expect(obj.foo(:bar)).to eq :bar
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
describe "with variable args" do
|
27
|
-
it "execs the block when called" do
|
28
|
-
Subroutine.new(obj, :foo).hook.and_return {|*given| given.first}
|
29
|
-
expect(obj.foo(:bar)).to eq :bar
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
|
35
|
-
describe "unstub implementation" do
|
36
|
-
it "replaces the stubbed method with the original method" do
|
37
|
-
obj = Object.new
|
38
|
-
def obj.foo; :original; end
|
39
|
-
Subroutine.new(obj, :foo).hook.unhook
|
40
|
-
expect(obj.foo).to eq :original
|
41
|
-
end
|
42
|
-
|
43
|
-
it "restores the correct implementations when stubbed and unstubbed on a parent and child class" do
|
44
|
-
parent = Class.new
|
45
|
-
child = Class.new(parent)
|
46
|
-
|
47
|
-
Spy.on(parent, :new)
|
48
|
-
Spy.on(child, :new)
|
49
|
-
Spy.off(parent, :new)
|
50
|
-
Spy.off(child, :new)
|
51
|
-
|
52
|
-
expect(parent.new).to be_an_instance_of parent
|
53
|
-
expect(child.new).to be_an_instance_of child
|
54
|
-
end
|
55
|
-
|
56
|
-
it "raises a MockExpectationError if the method has not been stubbed" do
|
57
|
-
obj = Object.new
|
58
|
-
expect {
|
59
|
-
Spy.off(obj, :foo)
|
60
|
-
}.to raise_error
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
data/spec/spy/stub_spec.rb
DELETED
@@ -1,79 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module RSpec
|
4
|
-
module Mocks
|
5
|
-
describe "A method stub" do
|
6
|
-
before(:each) do
|
7
|
-
@class = Class.new do
|
8
|
-
class << self
|
9
|
-
def existing_class_method
|
10
|
-
existing_private_class_method
|
11
|
-
end
|
12
|
-
|
13
|
-
private
|
14
|
-
def existing_private_class_method
|
15
|
-
:original_value
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def existing_instance_method
|
20
|
-
existing_private_instance_method
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
def existing_private_instance_method
|
25
|
-
:original_value
|
26
|
-
end
|
27
|
-
end
|
28
|
-
@instance = @class.new
|
29
|
-
@stub = Object.new
|
30
|
-
end
|
31
|
-
|
32
|
-
describe "using Spy::Subroutine.new" do
|
33
|
-
it "returns declared value when message is received" do
|
34
|
-
Spy::Subroutine.new(@instance, :msg).hook(force: true).and_return(:return_value)
|
35
|
-
expect(@instance.msg).to equal(:return_value)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
it "instructs an instance to respond_to the message" do
|
40
|
-
Spy::Subroutine.new(@instance, :msg).hook(force: true)
|
41
|
-
expect(@instance).to respond_to(:msg)
|
42
|
-
end
|
43
|
-
|
44
|
-
it "instructs a class object to respond_to the message" do
|
45
|
-
Spy::Subroutine.new(@class, :msg).hook(force: true)
|
46
|
-
expect(@class).to respond_to(:msg)
|
47
|
-
end
|
48
|
-
|
49
|
-
it "yields a specified object" do
|
50
|
-
Spy::Subroutine.new(@instance, :method_that_yields).hook(force: true).and_yield(:yielded_obj)
|
51
|
-
current_value = :value_before
|
52
|
-
@instance.method_that_yields {|val| current_value = val}
|
53
|
-
expect(current_value).to eq :yielded_obj
|
54
|
-
end
|
55
|
-
|
56
|
-
it "yields a specified object and return another specified object" do
|
57
|
-
yielded_obj = Spy.double("my mock")
|
58
|
-
Spy::Subroutine.new(yielded_obj, :foo).hook(force: true)
|
59
|
-
Spy::Subroutine.new(@instance, :method_that_yields_and_returns).hook(force: true).and_yield(yielded_obj).and_return(:baz)
|
60
|
-
expect(@instance.method_that_yields_and_returns { |o| o.foo :bar }).to eq :baz
|
61
|
-
end
|
62
|
-
|
63
|
-
it "throws when told to" do
|
64
|
-
Spy::Subroutine.new(@stub, :something).hook(force: true).and_throw(:up)
|
65
|
-
expect { @stub.something }.to throw_symbol(:up)
|
66
|
-
end
|
67
|
-
|
68
|
-
it "throws with argument when told to" do
|
69
|
-
Spy::Subroutine.new(@stub, :something).hook(force: true).and_throw(:up, 'high')
|
70
|
-
expect { @stub.something }.to throw_symbol(:up, 'high')
|
71
|
-
end
|
72
|
-
|
73
|
-
it "overrides a pre-existing method" do
|
74
|
-
Spy::Subroutine.new(@stub, :existing_instance_method).hook(force: true).and_return(:updated_stub_value)
|
75
|
-
expect(@stub.existing_instance_method).to eq :updated_stub_value
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
data/spec/spy/to_ary_spec.rb
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe "a double receiving to_ary" do
|
4
|
-
shared_examples "to_ary" do
|
5
|
-
it "returns nil" do
|
6
|
-
expect do
|
7
|
-
expect(obj.to_ary).to be_nil
|
8
|
-
end.to raise_error(NoMethodError)
|
9
|
-
end
|
10
|
-
|
11
|
-
it "doesn't respond" do
|
12
|
-
expect(obj).not_to respond_to(:to_ary)
|
13
|
-
end
|
14
|
-
|
15
|
-
it "can be overridden with a stub" do
|
16
|
-
Spy::Subroutine.new(obj, :to_ary).hook(force: true).and_return(:non_nil_value)
|
17
|
-
expect(obj.to_ary).to be(:non_nil_value)
|
18
|
-
end
|
19
|
-
|
20
|
-
it "responds when overriden" do
|
21
|
-
Spy::Subroutine.new(obj, :to_ary).hook(force: true).and_return(:non_nil_value)
|
22
|
-
expect(obj).to respond_to(:to_ary)
|
23
|
-
end
|
24
|
-
|
25
|
-
it "supports Array#flatten" do
|
26
|
-
obj = Spy.double('foo')
|
27
|
-
expect([obj].flatten).to eq([obj])
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
context "double as_null_object" do
|
32
|
-
let(:obj) { Spy.double('obj').as_null_object }
|
33
|
-
include_examples "to_ary"
|
34
|
-
end
|
35
|
-
|
36
|
-
context "double without as_null_object" do
|
37
|
-
let(:obj) { Spy.double('obj') }
|
38
|
-
include_examples "to_ary"
|
39
|
-
end
|
40
|
-
end
|