spy 0.0.1 → 0.1.0

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.
@@ -0,0 +1,40 @@
1
+ require 'test_helper'
2
+
3
+ class TestSpy < MiniTest::Unit::TestCase
4
+ def setup
5
+ Spy::Agency.instance.dissolve!
6
+ @pen = Pen.new
7
+ end
8
+
9
+ def test_spy_on_hooks_and_saves_spy_with_array
10
+ pen_write_spy, pen_write_hello_spy = Spy::Subroutine.on(@pen, :write, :write_hello)
11
+ assert_nil @pen.write(nil)
12
+ assert_nil @pen.write_hello
13
+
14
+ assert_kind_of Spy::Subroutine, pen_write_spy
15
+ assert_kind_of Spy::Subroutine, pen_write_hello_spy
16
+ assert_equal [pen_write_spy, pen_write_hello_spy], Spy::Agency.instance.subroutines
17
+ assert pen_write_spy.has_been_called?
18
+ assert pen_write_hello_spy.has_been_called?
19
+ end
20
+
21
+ def test_spy_on_hooks_and_saves_spy_with_array
22
+ pen_write_spy, pen_write_hello_spy = Spy.on(@pen, write: "hello", write_hello: "world")
23
+ assert_equal "hello", @pen.write(nil)
24
+ assert_equal "world", @pen.write_hello
25
+
26
+ assert_kind_of Spy::Subroutine, pen_write_spy
27
+ assert_kind_of Spy::Subroutine, pen_write_hello_spy
28
+ assert_equal [pen_write_spy, pen_write_hello_spy], Spy::Agency.instance.subroutines
29
+ assert pen_write_spy.has_been_called?
30
+ assert pen_write_hello_spy.has_been_called?
31
+ end
32
+
33
+ def test_spy_off_unhooks_a_method
34
+ pen_write_spy = Spy.on(@pen, :write)
35
+ Spy.off(@pen,:write)
36
+ assert_equal "hello world", @pen.write("hello world")
37
+ refute pen_write_spy.has_been_called?
38
+ end
39
+
40
+ end
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class Spy
3
+ module Spy
4
4
  class TestDouble < MiniTest::Unit::TestCase
5
5
  def test_double_creation
6
6
  double = Double.new("NewDouble", :meth_1, :meth_2)
@@ -0,0 +1,191 @@
1
+ require 'test_helper'
2
+
3
+ module Spy
4
+ class TestSubroutine < MiniTest::Unit::TestCase
5
+ def spy_on(base_object, method_name)
6
+ Subroutine.new(base_object, method_name).hook
7
+ end
8
+
9
+ def setup
10
+ Agency.instance.dissolve!
11
+ @pen = Pen.new
12
+ end
13
+
14
+ def test_spy_on_hook_and_saves_spy
15
+ pen_write_spy = spy_on(@pen, :write).and_return("hello")
16
+ assert_equal "hello", @pen.write(nil)
17
+ assert_kind_of Subroutine, pen_write_spy
18
+ assert_equal [pen_write_spy], Agency.instance.subroutines
19
+ assert pen_write_spy.has_been_called?
20
+ end
21
+
22
+ def test_spy_can_hook_and_record_a_method_call
23
+ pen_write_spy = spy_on(@pen, :write)
24
+ refute pen_write_spy.has_been_called?
25
+ @pen.write("hello")
26
+ assert pen_write_spy.has_been_called?
27
+ assert_empty @pen.written
28
+ end
29
+
30
+ def test_spy_can_hook_and_record_a_method_call_on_a_constant
31
+ another_spy = spy_on(Pen, :another)
32
+ refute another_spy.has_been_called?
33
+ assert_nil Pen.another
34
+ assert another_spy.has_been_called?
35
+ another_spy.unhook
36
+ assert_equal "another", Pen.another
37
+ end
38
+
39
+ def test_spy_can_unhook_a_method
40
+ pen_write_spy = spy_on(@pen, :write)
41
+ pen_write_spy.unhook
42
+ @pen.write("hello")
43
+ refute pen_write_spy.has_been_called?
44
+ end
45
+
46
+ def test_spy_cannot_hook_a_non_existent_method
47
+ spy = Subroutine.new(@pen, :no_method)
48
+ assert_raises NameError do
49
+ spy.hook
50
+ end
51
+ end
52
+
53
+ def test_spy_can_hook_a_non_existent_method_if_param_set
54
+ spy = Subroutine.new(@pen, :no_method).and_return(:yep)
55
+ spy.hook(force: true)
56
+ assert_equal :yep, @pen.no_method
57
+ end
58
+
59
+ def test_spy_and_return_returns_the_set_value
60
+ result = "hello world"
61
+
62
+ spy_on(@pen, :write).and_return(result)
63
+
64
+ assert_equal result, @pen.write(nil)
65
+ end
66
+
67
+ def test_spy_and_return_can_call_a_block
68
+ result = "hello world"
69
+
70
+ spy_on(@pen, :write).and_return {}.and_return do |string|
71
+ string.reverse
72
+ end
73
+
74
+ assert_equal result.reverse, @pen.write(result)
75
+ assert_empty @pen.written
76
+ end
77
+
78
+ def test_spy_and_return_can_call_a_block_raises_when_there_is_an_arity_mismatch
79
+ write_spy = spy_on(@pen, :write)
80
+ write_spy.and_return do |*args|
81
+ end
82
+ write_spy.and_return do |string, *args|
83
+ end
84
+ assert_raises ArgumentError do
85
+ write_spy.and_return do |string, b|
86
+ end
87
+ end
88
+ end
89
+
90
+ def test_spy_and_return_can_call_a_block_that_recieves_a_block
91
+ string = "hello world"
92
+
93
+ spy_on(@pen, :write_block).and_return do |&block|
94
+ block.call
95
+ end
96
+
97
+ result = @pen.write_block do
98
+ string
99
+ end
100
+ assert_equal string, result
101
+ end
102
+
103
+ def test_spy_hook_records_number_of_calls
104
+ pen_write_spy = spy_on(@pen, :write)
105
+ assert_equal 0, pen_write_spy.calls.size
106
+ 5.times do |i|
107
+ @pen.write("hello world")
108
+ assert_equal i + 1, pen_write_spy.calls.size
109
+ end
110
+ end
111
+
112
+ def test_has_been_called_with?
113
+ pen_write_spy = spy_on(@pen, :write)
114
+ refute pen_write_spy.has_been_called_with?("hello")
115
+ @pen.write("hello")
116
+ assert pen_write_spy.has_been_called_with?("hello")
117
+ @pen.write("world")
118
+ assert pen_write_spy.has_been_called_with?("hello")
119
+ @pen.write("hello world")
120
+ assert pen_write_spy.has_been_called_with?("hello")
121
+ end
122
+
123
+ def test_spy_hook_records_number_of_calls
124
+ args = ["hello world"]
125
+ block = Proc.new {}
126
+ pen_write_spy = spy_on(@pen, :write)
127
+ @pen.write(*args, &block)
128
+ call_log = pen_write_spy.calls.first
129
+ assert_equal @pen, call_log.object
130
+ assert_equal args, call_log.args
131
+ assert_equal block, call_log.block
132
+ end
133
+
134
+ def test_that_method_spy_keeps_arity
135
+ spy_on(@pen, :write)
136
+ @pen.write("hello world")
137
+ assert_raises ArgumentError do
138
+ @pen.write("hello", "world")
139
+ end
140
+
141
+ spy_on(@pen, :write_hello)
142
+ @pen.write_hello
143
+ assert_raises ArgumentError do
144
+ @pen.write_hello("hello")
145
+ end
146
+
147
+ spy_on(@pen, :write_array)
148
+ @pen.write_hello
149
+ assert_raises ArgumentError do
150
+ @pen.write_hello("hello")
151
+ end
152
+
153
+ spy_on(@pen, :greet)
154
+ @pen.greet("bob")
155
+ assert_raises ArgumentError do
156
+ @pen.greet
157
+ end
158
+ assert_raises ArgumentError do
159
+ @pen.greet("hello", "bob", "error")
160
+ end
161
+ end
162
+
163
+ def test_hook_mimics_public_visibility
164
+ spy_on(@pen, :public_method)
165
+ assert @pen.singleton_class.public_method_defined? :public_method
166
+ refute @pen.singleton_class.protected_method_defined? :public_method
167
+ refute @pen.singleton_class.private_method_defined? :public_method
168
+ end
169
+
170
+ def test_hook_mimics_protected_visibility
171
+ spy_on(@pen, :protected_method)
172
+ refute @pen.singleton_class.public_method_defined? :protected_method
173
+ assert @pen.singleton_class.protected_method_defined? :protected_method
174
+ refute @pen.singleton_class.private_method_defined? :protected_method
175
+ end
176
+
177
+ def test_hook_mimics_private_visibility
178
+ spy_on(@pen, :private_method)
179
+ refute @pen.singleton_class.public_method_defined? :private_method
180
+ refute @pen.singleton_class.protected_method_defined? :private_method
181
+ assert @pen.singleton_class.private_method_defined? :private_method
182
+ end
183
+
184
+ def test_spy_get_can_retrieve_a_spy
185
+ pen_write_spy = spy_on(@pen, :write).and_return(:hello)
186
+ assert_equal :hello, @pen.write(:world)
187
+ assert_equal pen_write_spy, Subroutine.get(@pen, :write)
188
+ assert Subroutine.get(@pen, :write).has_been_called?
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,50 @@
1
+ class Pen
2
+ attr_reader :written, :color
3
+
4
+ def initialize(color = :black)
5
+ @color = color
6
+ @written = []
7
+ end
8
+
9
+ def write(string)
10
+ @written << string
11
+ string
12
+ end
13
+
14
+ def write_block(&block)
15
+ string = yield
16
+ @written << string
17
+ string
18
+ end
19
+
20
+ def write_hello
21
+ write("hello")
22
+ end
23
+
24
+ def write_array(*args)
25
+ args.each do |arg|
26
+ write(arg)
27
+ end
28
+ end
29
+
30
+ def greet(hello = "hello", name)
31
+ write("#{hello} #{name}")
32
+ end
33
+
34
+ def public_method
35
+ end
36
+
37
+ protected
38
+ def protected_method
39
+ end
40
+
41
+ private
42
+ def private_method
43
+ end
44
+
45
+ class << self
46
+ def another
47
+ "another"
48
+ end
49
+ end
50
+ end
@@ -4,3 +4,7 @@ require 'pry'
4
4
  require 'pry-nav'
5
5
 
6
6
  require 'spy'
7
+
8
+ Dir.glob(File.expand_path("../support/*", __FILE__)).each do |file|
9
+ require file
10
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-05 00:00:00.000000000 Z
12
+ date: 2013-02-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: minitest
@@ -28,7 +28,23 @@ dependencies:
28
28
  - !ruby/object:Gem::Version
29
29
  version: 4.5.0
30
30
  - !ruby/object:Gem::Dependency
31
- name: rspec
31
+ name: rspec-core
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec-expectations
32
48
  requirement: !ruby/object:Gem::Requirement
33
49
  none: false
34
50
  requirements:
@@ -51,14 +67,18 @@ extensions: []
51
67
  extra_rdoc_files: []
52
68
  files:
53
69
  - .gitignore
70
+ - .yardopts
54
71
  - Gemfile
55
72
  - LICENSE.txt
56
73
  - README.md
57
74
  - Rakefile
58
- - TODO.md
59
75
  - lib/spy.rb
76
+ - lib/spy/agency.rb
77
+ - lib/spy/constant.rb
78
+ - lib/spy/core_ext/marshal.rb
60
79
  - lib/spy/double.rb
61
- - lib/spy/dsl.rb
80
+ - lib/spy/nest.rb
81
+ - lib/spy/subroutine.rb
62
82
  - lib/spy/version.rb
63
83
  - spec/spec_helper.rb
64
84
  - spec/spy/and_call_original_spec.rb
@@ -76,7 +96,6 @@ files:
76
96
  - spec/spy/hash_excluding_matcher_spec.rb
77
97
  - spec/spy/hash_including_matcher_spec.rb
78
98
  - spec/spy/mock_spec.rb
79
- - spec/spy/multiple_return_value_spec.rb
80
99
  - spec/spy/mutate_const_spec.rb
81
100
  - spec/spy/nil_expectation_warning_spec.rb
82
101
  - spec/spy/null_object_mock_spec.rb
@@ -92,9 +111,12 @@ files:
92
111
  - spec/spy/test_double_spec.rb
93
112
  - spec/spy/to_ary_spec.rb
94
113
  - spy.gemspec
114
+ - test/integration/test_constant_spying.rb
115
+ - test/integration/test_subroutine_spying.rb
95
116
  - test/spy/test_double.rb
117
+ - test/spy/test_subroutine.rb
118
+ - test/support/pen.rb
96
119
  - test/test_helper.rb
97
- - test/test_spy.rb
98
120
  homepage: ''
99
121
  licenses: []
100
122
  post_install_message:
@@ -136,7 +158,6 @@ test_files:
136
158
  - spec/spy/hash_excluding_matcher_spec.rb
137
159
  - spec/spy/hash_including_matcher_spec.rb
138
160
  - spec/spy/mock_spec.rb
139
- - spec/spy/multiple_return_value_spec.rb
140
161
  - spec/spy/mutate_const_spec.rb
141
162
  - spec/spy/nil_expectation_warning_spec.rb
142
163
  - spec/spy/null_object_mock_spec.rb
@@ -151,7 +172,10 @@ test_files:
151
172
  - spec/spy/stubbed_message_expectations_spec.rb
152
173
  - spec/spy/test_double_spec.rb
153
174
  - spec/spy/to_ary_spec.rb
175
+ - test/integration/test_constant_spying.rb
176
+ - test/integration/test_subroutine_spying.rb
154
177
  - test/spy/test_double.rb
178
+ - test/spy/test_subroutine.rb
179
+ - test/support/pen.rb
155
180
  - test/test_helper.rb
156
- - test/test_spy.rb
157
181
  has_rdoc:
data/TODO.md DELETED
@@ -1,8 +0,0 @@
1
- # Todo
2
-
3
- * and_yield
4
- * and_raise
5
- * spy on CONSTANTS
6
- * argument matchers
7
- * count matchers
8
- * watch all calls to an object
@@ -1,7 +0,0 @@
1
- class Spy
2
- module Dsl
3
- def spy
4
- Spy
5
- end
6
- end
7
- end
@@ -1,119 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module RSpec
4
- module Mocks
5
- describe "a message expectation with multiple return values and no specified count" do
6
- before(:each) do
7
- @double = double
8
- @return_values = [1,2,3]
9
- @double.should_receive(:do_something).and_return(@return_values[0],@return_values[1],@return_values[2])
10
- end
11
-
12
- it "returns values in order" do
13
- expect(@double.do_something).to eq @return_values[0]
14
- expect(@double.do_something).to eq @return_values[1]
15
- expect(@double.do_something).to eq @return_values[2]
16
- @double.rspec_verify
17
- end
18
-
19
- it "falls back to a previously stubbed value" do
20
- @double.stub :do_something => :stub_result
21
- expect(@double.do_something).to eq @return_values[0]
22
- expect(@double.do_something).to eq @return_values[1]
23
- expect(@double.do_something).to eq @return_values[2]
24
- expect(@double.do_something).to eq :stub_result
25
- end
26
-
27
- it "fails when there are too few calls (if there is no stub)" do
28
- @double.do_something
29
- @double.do_something
30
- expect { @double.rspec_verify }.to raise_error
31
- end
32
-
33
- it "fails when there are too many calls (if there is no stub)" do
34
- @double.do_something
35
- @double.do_something
36
- @double.do_something
37
- @double.do_something
38
- expect { @double.rspec_verify }.to raise_error
39
- end
40
- end
41
-
42
- describe "a message expectation with multiple return values with a specified count equal to the number of values" do
43
- before(:each) do
44
- @double = double
45
- @return_values = [1,2,3]
46
- @double.should_receive(:do_something).exactly(3).times.and_return(@return_values[0],@return_values[1],@return_values[2])
47
- end
48
-
49
- it "returns values in order to consecutive calls" do
50
- expect(@double.do_something).to eq @return_values[0]
51
- expect(@double.do_something).to eq @return_values[1]
52
- expect(@double.do_something).to eq @return_values[2]
53
- @double.rspec_verify
54
- end
55
- end
56
-
57
- describe "a message expectation with multiple return values specifying at_least less than the number of values" do
58
- before(:each) do
59
- @double = double
60
- @double.should_receive(:do_something).at_least(:twice).with(no_args).and_return(11, 22)
61
- end
62
-
63
- it "uses the last return value for subsequent calls" do
64
- expect(@double.do_something).to equal(11)
65
- expect(@double.do_something).to equal(22)
66
- expect(@double.do_something).to equal(22)
67
- @double.rspec_verify
68
- end
69
-
70
- it "fails when called less than the specified number" do
71
- expect(@double.do_something).to equal(11)
72
- expect { @double.rspec_verify }.to raise_error(RSpec::Mocks::MockExpectationError)
73
- end
74
-
75
- context "when method is stubbed too" do
76
- before { Spy.on(@double, :do_something).and_return :stub_result }
77
-
78
- it "uses the last value for subsequent calls" do
79
- expect(@double.do_something).to equal(11)
80
- expect(@double.do_something).to equal(22)
81
- expect(@double.do_something).to equal(22)
82
- @double.rspec_verify
83
- end
84
-
85
- it "fails when called less than the specified number" do
86
- expect(@double.do_something).to equal(11)
87
- expect { @double.rspec_verify }.to raise_error(RSpec::Mocks::MockExpectationError)
88
- end
89
- end
90
- end
91
-
92
- describe "a message expectation with multiple return values with a specified count larger than the number of values" do
93
- before(:each) do
94
- @double = RSpec::Mocks::Mock.new("double")
95
- @double.should_receive(:do_something).exactly(3).times.and_return(11, 22)
96
- end
97
-
98
- it "uses the last return value for subsequent calls" do
99
- expect(@double.do_something).to equal(11)
100
- expect(@double.do_something).to equal(22)
101
- expect(@double.do_something).to equal(22)
102
- @double.rspec_verify
103
- end
104
-
105
- it "fails when called less than the specified number" do
106
- @double.do_something
107
- @double.do_something
108
- expect { @double.rspec_verify }.to raise_error
109
- end
110
-
111
- it "fails fast when called greater than the specified number" do
112
- @double.do_something
113
- @double.do_something
114
- @double.do_something
115
- expect { @double.do_something }.to raise_error
116
- end
117
- end
118
- end
119
- end