spy 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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