spy 0.4.3 → 1.0.2

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
- SHA1:
3
- metadata.gz: 60daeb7dc9a4b41de1284dcc4353bcf278ddce75
4
- data.tar.gz: 93534dcf719a49ac1907e585d6633cd561cd2546
2
+ SHA256:
3
+ metadata.gz: 3906b9e65a981746a6dc4e51106ed64fc925478cb73335eb8a9d46ae9fc31931
4
+ data.tar.gz: 85e19b544c6ccb98616dd846db8263da3d0e8abcfd2158a5749d8988c5dc32e8
5
5
  SHA512:
6
- metadata.gz: c4177bc16ff8d22aa2236bdcfa35c79248bf73ef93117c91a75d0c7515a71d2a833304df1abf893905992f4765bf4b92c530fd7807f6421ea18ec4bead99e75a
7
- data.tar.gz: 2d803b1a5ddac06a0f218a963cf01e0be05a9d4bb835f3ff86e7edb49e4dd22b88844ebe4ca65348e85def83ef1c125220a52ed31a9536d4a5fa8fa54f52a63e
6
+ metadata.gz: 57544c0872ff818dc065037e1e2a10c34b1edb698ad84ebf1e184aa190d24c8663d51d011619bb6a1024c93f1d94a03a8bd6578274605a56f0b0ba06aabf6abc
7
+ data.tar.gz: 43b7ca82d10759bb6083fdd76b27941425cefbcc63bc2b8a585b34d3c8e2c2659f24c1f4f32843ee1c1b8f3aee1d64c127fb769774430e77a31ea7005aeebbcb
data/.tool-versions ADDED
@@ -0,0 +1 @@
1
+ ruby 2.7.0
data/.travis.yml CHANGED
@@ -1,11 +1,13 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9.3
4
- - 2.0.0
5
- - jruby-19mode
3
+ - '2.1'
4
+ - '2.5'
5
+ - '2.7'
6
+ - jruby
6
7
  - ruby-head
7
- - rbx-19mode
8
+ - rbx-3
8
9
  matrix:
9
10
  allow_failures:
10
11
  - rvm: ruby-head
11
- - rvm: rbx-19mode
12
+ - rvm: rbx-3
13
+ - rvm: jruby
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## Spy 1.0.1 (August 20th, 2020) ##
2
+
3
+ * Fix call_through w/ instance methods (@lreeves)
4
+ * Replace implicit Proc.new by explicit given block reference (@Hugo-Hache)
5
+ * Remove 2.7 warnings (@byroot)
6
+
7
+ ## Spy 1.0.0 (October 10, 2018) ##
8
+
9
+ * drop support for ruby 1.9.3, 2.0. Only support 2.1+ (@dylanahsmith)
10
+ * support named arguments (@dylanahsmith)
11
+ * Fix readme (@ignat-z)
12
+
1
13
  ## Spy 0.4.3 (April 14, 2016) ##
2
14
 
3
15
  * Double performance of spy lookups (@BlakeMesdag)
data/README.md CHANGED
@@ -9,7 +9,8 @@
9
9
 
10
10
  Spy is a lightweight stubbing framework with support for method spies, constant stubs, and object mocks.
11
11
 
12
- Spy was designed for 1.9.3+.
12
+ Spy supports ruby 2.1.0+.
13
+ For versions less than 2.1 use v0.4.5
13
14
 
14
15
  Spy features that were completed were tested against the rspec-mocks tests so it covers all cases that rspec-mocks does.
15
16
 
@@ -197,7 +198,7 @@ In your test file
197
198
  ```ruby
198
199
  def test_title
199
200
  book = Book.new
200
- title_spy = Spy.on(book, title)
201
+ title_spy = Spy.on(book, :title)
201
202
  book.title
202
203
  book.title
203
204
 
data/Rakefile CHANGED
@@ -3,7 +3,7 @@ require 'rake/testtask'
3
3
 
4
4
  Rake::TestTask.new do |t|
5
5
  t.libs << "test"
6
- t.test_files = FileList['test/**/test*.rb']
6
+ t.test_files = FileList['test/**/test_*.rb']
7
7
  t.verbose = true
8
8
  end
9
9
 
data/lib/spy/api.rb CHANGED
@@ -36,8 +36,8 @@ module Spy
36
36
  end
37
37
  end
38
38
 
39
- def with(*args)
40
- @with = block_given? ? Proc.new : args
39
+ def with(*args, &block)
40
+ @with = block_given? ? block : args
41
41
  self
42
42
  end
43
43
 
@@ -32,6 +32,8 @@ module Spy
32
32
  def initialize(object, method_name, singleton_method = true)
33
33
  @base_object, @method_name = object, method_name
34
34
  @singleton_method = singleton_method
35
+ @plan = nil
36
+ @call_through = false
35
37
  reset!
36
38
  end
37
39
 
@@ -51,8 +53,21 @@ module Spy
51
53
  @original_method = current_method
52
54
  end
53
55
 
54
- define_method_with = singleton_method ? :define_singleton_method : :define_method
55
- base_object.send(define_method_with, method_name, override_method)
56
+ if original_method && original_method.owner == base_object
57
+ original_method.owner.send(:remove_method, method_name)
58
+ end
59
+
60
+ if singleton_method
61
+ if base_object.singleton_class.method_defined?(method_name) || base_object.singleton_class.private_method_defined?(method_name)
62
+ base_object.singleton_class.send(:alias_method, method_name, method_name)
63
+ end
64
+ base_object.define_singleton_method(method_name, override_method)
65
+ else
66
+ if base_object.method_defined?(method_name) || base_object.private_method_defined?(method_name)
67
+ base_object.send(:alias_method, method_name, method_name)
68
+ end
69
+ base_object.send(:define_method, method_name, override_method)
70
+ end
56
71
 
57
72
  if [:public, :protected, :private].include? hook_opts[:visibility]
58
73
  method_owner.send(hook_opts[:visibility], method_name)
@@ -68,11 +83,10 @@ module Spy
68
83
  def unhook
69
84
  raise NeverHookedError, "'#{method_name}' method has not been hooked" unless hooked?
70
85
 
86
+ method_owner.send(:remove_method, method_name)
71
87
  if original_method && method_owner == original_method.owner
72
- method_owner.send(:define_method, method_name, original_method)
73
- method_owner.send(original_method_visibility, method_name) if original_method_visibility
74
- else
75
- method_owner.send(:remove_method, method_name)
88
+ original_method.owner.send(:define_method, method_name, original_method)
89
+ original_method.owner.send(original_method_visibility, method_name) if original_method_visibility
76
90
  end
77
91
 
78
92
  clear_method!
@@ -104,7 +118,7 @@ module Spy
104
118
  # spy.and_return(force: true) { |invalid_arity| true }
105
119
  #
106
120
  # @return [self]
107
- def and_return(value = nil)
121
+ def and_return(value = nil, &block)
108
122
  @do_not_check_plan_arity = false
109
123
 
110
124
  if block_given?
@@ -114,7 +128,7 @@ module Spy
114
128
  raise ArgumentError, "value and block conflict. Choose one"
115
129
  end
116
130
 
117
- @plan = Proc.new
131
+ @plan = block
118
132
  check_for_too_many_arguments!(@plan)
119
133
  else
120
134
  @plan = Proc.new { value }
@@ -135,13 +149,8 @@ module Spy
135
149
  # tells the spy to call the original method
136
150
  # @return [self]
137
151
  def and_call_through
138
- @plan = Proc.new do |*args, &block|
139
- if original_method
140
- original_method.call(*args, &block)
141
- else
142
- base_object.send(:method_missing, method_name, *args, &block)
143
- end
144
- end
152
+ @call_through = true
153
+
145
154
  self
146
155
  end
147
156
 
@@ -167,6 +176,7 @@ module Spy
167
176
  end
168
177
 
169
178
  @plan = Proc.new { raise exception }
179
+ self
170
180
  end
171
181
 
172
182
  # @overload and_throw(symbol)
@@ -191,9 +201,9 @@ module Spy
191
201
  # check if the method was called with the exact arguments
192
202
  # @param args Arguments that should have been sent to the method
193
203
  # @return [Boolean]
194
- def has_been_called_with?(*args)
204
+ def has_been_called_with?(*args, &block)
195
205
  raise NeverHookedError unless @was_hooked
196
- match = block_given? ? Proc.new : proc { |call| call.args == args }
206
+ match = block_given? ? block : proc { |call| call.args == args }
197
207
  calls.any?(&match)
198
208
  end
199
209
 
@@ -201,10 +211,18 @@ module Spy
201
211
  # method.
202
212
  def invoke(object, args, block, called_from)
203
213
  check_arity!(args.size)
204
- result = if @plan
205
- check_for_too_many_arguments!(@plan)
206
- @plan.call(*args, &block)
207
- end
214
+
215
+ result =
216
+ if @call_through
217
+ call_plan(build_call_through_plan(object), block, *args)
218
+ elsif @plan
219
+ check_for_too_many_arguments!(@plan)
220
+ if base_object.is_a? Class
221
+ call_plan(@plan, block, object, *args)
222
+ else
223
+ call_plan(@plan, block, *args)
224
+ end
225
+ end
208
226
  ensure
209
227
  calls << CallLog.new(object, called_from, args, block, result)
210
228
  end
@@ -272,6 +290,8 @@ module Spy
272
290
  min_arity = block.arity
273
291
  min_arity = min_arity.abs - 1 if min_arity < 0
274
292
 
293
+ min_arity -=1 if base_object.is_a? Class # Instance-method procs take an extra param for receiving object
294
+
275
295
  if min_arity > arity_range.max
276
296
  raise ArgumentError.new("block requires #{min_arity} arguments while original_method require a maximum of #{arity_range.max}")
277
297
  end
@@ -281,6 +301,8 @@ module Spy
281
301
  @arity_range ||=
282
302
  if original_method
283
303
  min = max = 0
304
+ key_args = false
305
+ opt_keys = false
284
306
  original_method.parameters.each do |type,_|
285
307
  case type
286
308
  when :req
@@ -290,8 +312,17 @@ module Spy
290
312
  max += 1
291
313
  when :rest
292
314
  max = Float::INFINITY
315
+ when :keyreq
316
+ key_args = true
317
+ when :keyrest, :key
318
+ key_args = true
319
+ opt_keys = true
293
320
  end
294
321
  end
322
+ if key_args
323
+ max += 1
324
+ min += 1 unless opt_keys
325
+ end
295
326
  (min..max)
296
327
  end
297
328
  end
@@ -304,6 +335,39 @@ module Spy
304
335
  @method_owner ||= current_method.owner
305
336
  end
306
337
 
338
+ def build_call_through_plan(object)
339
+ if original_method
340
+ if @base_object.is_a?(Class) && original_method.is_a?(UnboundMethod)
341
+ original_method.bind(object)
342
+ else
343
+ original_method
344
+ end
345
+ else
346
+ Proc.new do |*args, &block|
347
+ base_object.send(:method_missing, method_name, *args, &block)
348
+ end
349
+ end
350
+ end
351
+
352
+ def call_plan(plan, block, *args)
353
+ if ruby_27_last_arg_hash?(args)
354
+ *prefix, last = args
355
+ plan.call(*prefix, **last, &block)
356
+ else
357
+ plan.call(*args, &block)
358
+ end
359
+ end
360
+
361
+ # Ruby 2.7 gives a deprecation warning about passing hash as last argument for a method
362
+ # with a double-splat operator (**), and Ruby 3 raises an ArgumentError exception.
363
+ # This checks if args has a hash as last element to extract it and pass it with double-splat to avoid an exception.
364
+ def ruby_27_last_arg_hash?(args)
365
+ last = args.last
366
+ last.instance_of?(Hash) &&
367
+ !last.empty? &&
368
+ Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.7.0")
369
+ end
370
+
307
371
  class << self
308
372
 
309
373
  # retrieve the method spy from an object or create a new one
data/lib/spy/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Spy
2
- VERSION = "0.4.3"
2
+ VERSION = "1.0.2"
3
3
  end
data/lib/spy.rb CHANGED
@@ -34,8 +34,6 @@ module Spy
34
34
  spy = Subroutine.get(base_object, method_name)
35
35
  if spy
36
36
  spy.unhook
37
- else
38
- raise NoSpyError, "#{method_name} was not hooked on #{base_object.inspect}."
39
37
  end
40
38
  end
41
39
 
data/spy.gemspec CHANGED
@@ -6,12 +6,12 @@ require 'spy/version'
6
6
  Gem::Specification.new do |gem|
7
7
  gem.name = "spy"
8
8
  gem.version = Spy::VERSION
9
- gem.required_ruby_version = '>= 1.9.3'
9
+ gem.required_ruby_version = '>= 2.1.0'
10
10
  gem.license = 'MIT'
11
11
  gem.authors = ["Ryan Ong"]
12
12
  gem.email = ["ryanong@gmail.com"]
13
13
  gem.summary = %q{A simple modern mocking library that uses the spy pattern and checks method's existence and arity.}
14
- gem.description = %q{Spy is a mocking library that was made for the modern age. It supports only 1.9.3+. Spy by default will raise an error if you attempt to stub a method that doesn't exist or call the stubbed method with the wrong arity.}
14
+ gem.description = %q{Spy is a mocking library that was made for the modern age. It supports only 2.1.0+. Spy by default will raise an error if you attempt to stub a method that doesn't exist or call the stubbed method with the wrong arity.}
15
15
  gem.homepage = "https://github.com/ryanong/spy"
16
16
 
17
17
  gem.files = `git ls-files`.split($/)
@@ -19,8 +19,9 @@ Gem::Specification.new do |gem|
19
19
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
20
20
  gem.require_paths = ["lib"]
21
21
  gem.add_development_dependency('pry')
22
- gem.add_development_dependency('pry-nav')
22
+ gem.add_development_dependency('pry-byebug')
23
23
  gem.add_development_dependency('minitest', '>= 4.5.0')
24
+ gem.add_development_dependency('minitest-reporters')
24
25
  gem.add_development_dependency('rspec-core')
25
26
  gem.add_development_dependency('rspec-expectations')
26
27
  gem.add_development_dependency('coveralls')
@@ -30,7 +30,7 @@ class TestConstantSpying < Minitest::Test
30
30
  assert_equal "hello world", Foo.hello
31
31
 
32
32
  spy = Spy.on_const(Foo, :HELLO)
33
- assert_equal nil, Foo.hello
33
+ assert_nil Foo.hello
34
34
  spy.and_return("awesome")
35
35
  assert_equal "awesome", Foo.hello
36
36
 
@@ -39,7 +39,7 @@ class TestConstantSpying < Minitest::Test
39
39
 
40
40
  assert_equal "hello world", Foo::Bar.hello
41
41
  spy = Spy.on_const(Foo, :HELLO)
42
- assert_equal nil, Foo::Bar.hello
42
+ assert_nil Foo::Bar.hello
43
43
  spy.and_return("awesome")
44
44
  assert_equal "awesome", Foo::Bar.hello
45
45
 
@@ -48,7 +48,7 @@ class TestConstantSpying < Minitest::Test
48
48
 
49
49
  assert_equal "hello world", ChildFoo.hello
50
50
  spy = Spy.on_const(Foo, :HELLO)
51
- assert_equal nil, ChildFoo.hello
51
+ assert_nil ChildFoo.hello
52
52
  spy.and_return("awesome")
53
53
  assert_equal "awesome", ChildFoo.hello
54
54
 
@@ -17,6 +17,12 @@ class TestAnyInstanceOf < Minitest::Test
17
17
  Spy::Agency.instance.dissolve!
18
18
  end
19
19
 
20
+ def test_call_through_with_instance_method
21
+ Spy.on_instance_method(Foo, :bar).and_call_through
22
+ assert_equal "foobar", Foo.new.bar
23
+ Spy.off_instance_method(Foo, :bar)
24
+ end
25
+
20
26
  def test_it_overides_all_methods
21
27
  assert_equal Foo.new.bar, "foobar"
22
28
  spy = Spy.on_instance_method(Foo, bar: "timshel")
@@ -16,12 +16,12 @@ class TestSpy < Minitest::Test
16
16
 
17
17
  assert_kind_of Spy::Subroutine, pen_write_spy
18
18
  assert_kind_of Spy::Subroutine, pen_write_hello_spy
19
- assert_equal [pen_write_spy, pen_write_hello_spy], Spy::Agency.instance.subroutines
19
+ assert_equal [pen_write_spy, pen_write_hello_spy], Spy::Agency.instance.spies
20
20
  assert pen_write_spy.has_been_called?
21
21
  assert pen_write_hello_spy.has_been_called?
22
22
  end
23
23
 
24
- def test_spy_on_hooks_and_saves_spy_with_array
24
+ def test_spy_on_hooks_and_saves_spy_with_hash
25
25
  pen_write_spy, pen_write_hello_spy = Spy.on(@pen, write: "hello", write_hello: "world")
26
26
  assert_equal "hello", @pen.write(nil)
27
27
  assert_equal "world", @pen.write_hello
@@ -68,6 +68,7 @@ module Spy
68
68
  end
69
69
  end
70
70
 
71
+ BUGGY_METHODS = %i(tap pretty_print_inspect trust untrust untrusted? debugger byebug taint untaint tainted?)
71
72
  def test_mocked_methods
72
73
  pen_methods = Pen.public_instance_methods(false) +
73
74
  Pen.protected_instance_methods(false) +
@@ -76,8 +77,7 @@ module Spy
76
77
  assert_equal pen_methods.sort, @pen_mock.mocked_methods.sort
77
78
  end
78
79
 
79
- buggy_methods = [:tap, :pretty_print_inspect]
80
- methods_to_test = Object.instance_methods - buggy_methods
80
+ methods_to_test = Object.instance_methods - BUGGY_METHODS
81
81
  methods_to_test.each do |method_name|
82
82
  object_method = Object.instance_method(method_name)
83
83
  if object_method.arity == 0 || (RUBY_ENGINE != "jruby" && object_method.parameters == [])
@@ -6,6 +6,10 @@ module Spy
6
6
  Subroutine.new(base_object, method_name).hook
7
7
  end
8
8
 
9
+ def spy_on_instance_method(base_object, method_name)
10
+ Subroutine.new(base_object, method_name, false).hook
11
+ end
12
+
9
13
  def setup
10
14
  @pen = Pen.new
11
15
  end
@@ -40,13 +44,13 @@ module Spy
40
44
  end
41
45
 
42
46
  def test_spy_can_hook_and_record_a_meta_method_call_on_a_constant
43
- assert_equal "meta_method", Pen.meta_method
44
- meta_spy = spy_on(Pen, :meta_method)
47
+ assert_equal "meta_class_method", Pen.meta_class_method
48
+ meta_spy = spy_on(Pen, :meta_class_method)
45
49
  refute meta_spy.has_been_called?
46
- assert_nil Pen.meta_method
50
+ assert_nil Pen.meta_class_method
47
51
  assert meta_spy.has_been_called?
48
52
  meta_spy.unhook
49
- assert_equal "meta_method", Pen.meta_method
53
+ assert_equal "meta_class_method", Pen.meta_class_method
50
54
  end
51
55
 
52
56
  def test_spy_can_hook_record_and_unhook_a_meta_method
@@ -86,6 +90,18 @@ module Spy
86
90
  assert_equal result, @pen.write(nil)
87
91
  end
88
92
 
93
+ def test_spy_and_raise_raises_the_set_exception
94
+ pen_write_spy = spy_on(@pen, :write).and_raise(ArgumentError, "problems!")
95
+ assert_kind_of Subroutine, pen_write_spy
96
+ assert_equal [pen_write_spy], Agency.instance.spies
97
+
98
+ e = assert_raises ArgumentError do
99
+ @pen.write(nil)
100
+ end
101
+ assert_equal "problems!", e.message
102
+ assert pen_write_spy.has_been_called?
103
+ end
104
+
89
105
  def test_spy_and_return_can_call_a_block
90
106
  result = "hello world"
91
107
 
@@ -97,6 +113,15 @@ module Spy
97
113
  assert_empty @pen.written
98
114
  end
99
115
 
116
+ def test_spy_and_return_can_call_a_block_with_hash
117
+ result = "hello world"
118
+
119
+ spy_on(@pen, :write_hash).and_return { |**opts| opts[:test] }
120
+
121
+ assert_equal result, @pen.write_hash(test: result)
122
+ assert_empty @pen.written
123
+ end
124
+
100
125
  def test_spy_and_return_can_call_a_block_raises_when_there_is_an_arity_mismatch
101
126
  write_spy = spy_on(@pen, :write)
102
127
  write_spy.and_return do |*args|
@@ -125,6 +150,73 @@ module Spy
125
150
  assert_equal string, result
126
151
  end
127
152
 
153
+ def test_spy_and_call_through_returns_original_method_result
154
+ string = "hello world"
155
+
156
+ write_spy = spy_on(@pen, :write).and_call_through
157
+ another_spy = spy_on(@pen, :another).and_call_through
158
+
159
+ result = @pen.write(string)
160
+
161
+ assert_equal string, result
162
+ assert write_spy.has_been_called?
163
+ assert_equal 'another', @pen.another
164
+ assert another_spy.has_been_called?
165
+ end
166
+
167
+ def test_spy_and_call_through_with_hash_original_method
168
+ string = 'test:hello world'
169
+
170
+ write_spy = spy_on(@pen, :write_hash).and_call_through
171
+
172
+ @pen.write_hash(test: 'hello world')
173
+ assert_equal string, @pen.written.last
174
+ assert write_spy.has_been_called?
175
+ end
176
+
177
+ def test_spy_on_instance_and_call_through_returns_original_method_result
178
+ string = "hello world"
179
+
180
+ inst_write_spy = spy_on_instance_method(Pen, :write).and_call_through
181
+ inst_another_spy = spy_on_instance_method(Pen, :another).and_call_through
182
+
183
+ result = @pen.write(string)
184
+
185
+ assert_equal string, result
186
+ assert inst_write_spy.has_been_called?
187
+ assert_equal 'another', @pen.another
188
+ assert inst_another_spy.has_been_called?
189
+ end
190
+
191
+ def test_spy_on_instance_and_call_through_with_hash
192
+ string = 'test:hello world'
193
+
194
+ inst_write_spy = spy_on_instance_method(Pen, :write_hash).and_call_through
195
+
196
+ @pen.write_hash(test: 'hello world')
197
+
198
+ assert_equal string, @pen.written.last
199
+ assert inst_write_spy.has_been_called?
200
+ end
201
+
202
+ def test_spy_on_instance_and_call_through_to_aryable
203
+ to_aryable = Class.new do
204
+ def hello
205
+ 'hello'
206
+ end
207
+
208
+ def to_ary
209
+ [1]
210
+ end
211
+ end
212
+
213
+ inst_hello_spy = spy_on_instance_method(to_aryable, :hello).and_call_through
214
+ inst = to_aryable.new
215
+
216
+ assert_equal 'hello', inst.hello
217
+ assert inst_hello_spy.has_been_called?
218
+ end
219
+
128
220
  def test_spy_hook_records_number_of_calls
129
221
  pen_write_spy = spy_on(@pen, :write)
130
222
  assert_equal 0, pen_write_spy.calls.size
@@ -145,7 +237,7 @@ module Spy
145
237
  assert pen_write_spy.has_been_called_with?("hello")
146
238
  end
147
239
 
148
- def test_spy_hook_records_number_of_calls
240
+ def test_spy_hook_records_number_of_calls2
149
241
  args = ["hello world"]
150
242
  block = Proc.new {}
151
243
  pen_write_spy = spy_on(@pen, :write)
@@ -187,6 +279,38 @@ module Spy
187
279
  end
188
280
  end
189
281
 
282
+ def test_that_method_spy_keeps_arity_with_optional_keyword_args
283
+ spy_on(@pen, :opt_kwargs)
284
+ @pen.opt_kwargs(:pos1)
285
+ @pen.opt_kwargs(:pos1, opt: 1, opt2: 2)
286
+ assert_raises ArgumentError do
287
+ @pen.opt_kwargs
288
+ end
289
+ assert_raises ArgumentError do
290
+ @pen.opt_kwargs(:pos1, :pos2, opt: 1)
291
+ end
292
+ end
293
+
294
+ def test_that_method_spy_keeps_arity_with_keyword_splat
295
+ spy_on(@pen, :keyrest)
296
+ @pen.keyrest
297
+ @pen.keyrest(a: 1, b: 2)
298
+ assert_raises ArgumentError do
299
+ @pen.keyrest(:pos1, :pos2)
300
+ end
301
+ end
302
+
303
+ def test_that_method_spy_keeps_arity_with_required_keyword_args
304
+ spy_on(@pen, :req_kwargs)
305
+ @pen.req_kwargs(req1: 1, req2: 2)
306
+ assert_raises ArgumentError do
307
+ @pen.req_kwargs
308
+ end
309
+ assert_raises ArgumentError do
310
+ @pen.req_kwargs(:pos1, :pos2)
311
+ end
312
+ end
313
+
190
314
  def test_hook_mimics_public_visibility
191
315
  spy_on(@pen, :public_method)
192
316
  assert @pen.singleton_class.public_method_defined? :public_method
data/test/support/pen.rb CHANGED
@@ -27,6 +27,12 @@ class Pen
27
27
  end
28
28
  end
29
29
 
30
+ def write_hash(**params)
31
+ params.each do |p|
32
+ write(p.join(':'))
33
+ end
34
+ end
35
+
30
36
  def greet(hello = "hello", name)
31
37
  write("#{hello} #{name}")
32
38
  end
@@ -38,6 +44,18 @@ class Pen
38
44
  "another"
39
45
  end
40
46
 
47
+ def opt_kwargs(required, opt: nil, opt2: nil)
48
+ [required, opt: opt, opt2: opt2]
49
+ end
50
+
51
+ def keyrest(**kwargs)
52
+ kwargs
53
+ end
54
+
55
+ def req_kwargs(req1:, req2:)
56
+ [req1, req2]
57
+ end
58
+
41
59
  protected
42
60
  def protected_method
43
61
  end
@@ -65,13 +83,11 @@ class Pen
65
83
  end
66
84
  end
67
85
 
68
- another = "meta_method"
69
-
70
- Pen.define_singleton_method(:meta_method) do
71
- another
86
+ Pen.define_singleton_method(:meta_class_method) do
87
+ "meta_class_method".freeze
72
88
  end
73
89
 
74
90
  Pen.send(:define_method, :meta_method) do
75
- another
91
+ "meta_method".freeze
76
92
  end
77
93
 
data/test/test_helper.rb CHANGED
@@ -1,9 +1,11 @@
1
1
  require 'bundler/setup'
2
- require 'minitest/autorun'
3
2
  require 'pry'
4
- require 'pry-nav'
3
+ require 'pry-byebug'
4
+ require 'minitest/autorun'
5
+ require "minitest/reporters"
5
6
  require 'coveralls'
6
7
  Coveralls.wear!
8
+ Minitest::Reporters.use!
7
9
 
8
10
  require 'spy'
9
11
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Ong
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-14 00:00:00.000000000 Z
11
+ date: 2022-01-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: pry-nav
28
+ name: pry-byebug
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: 4.5.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest-reporters
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rspec-core
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -95,7 +109,7 @@ dependencies:
95
109
  - !ruby/object:Gem::Version
96
110
  version: '0'
97
111
  description: Spy is a mocking library that was made for the modern age. It supports
98
- only 1.9.3+. Spy by default will raise an error if you attempt to stub a method
112
+ only 2.1.0+. Spy by default will raise an error if you attempt to stub a method
99
113
  that doesn't exist or call the stubbed method with the wrong arity.
100
114
  email:
101
115
  - ryanong@gmail.com
@@ -104,6 +118,7 @@ extensions: []
104
118
  extra_rdoc_files: []
105
119
  files:
106
120
  - ".gitignore"
121
+ - ".tool-versions"
107
122
  - ".travis.yml"
108
123
  - ".yardopts"
109
124
  - CHANGELOG.md
@@ -154,7 +169,7 @@ homepage: https://github.com/ryanong/spy
154
169
  licenses:
155
170
  - MIT
156
171
  metadata: {}
157
- post_install_message:
172
+ post_install_message:
158
173
  rdoc_options: []
159
174
  require_paths:
160
175
  - lib
@@ -162,16 +177,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
162
177
  requirements:
163
178
  - - ">="
164
179
  - !ruby/object:Gem::Version
165
- version: 1.9.3
180
+ version: 2.1.0
166
181
  required_rubygems_version: !ruby/object:Gem::Requirement
167
182
  requirements:
168
183
  - - ">="
169
184
  - !ruby/object:Gem::Version
170
185
  version: '0'
171
186
  requirements: []
172
- rubyforge_project:
173
- rubygems_version: 2.6.1
174
- signing_key:
187
+ rubygems_version: 3.1.2
188
+ signing_key:
175
189
  specification_version: 4
176
190
  summary: A simple modern mocking library that uses the spy pattern and checks method's
177
191
  existence and arity.
@@ -201,4 +215,3 @@ test_files:
201
215
  - test/spy/test_subroutine.rb
202
216
  - test/support/pen.rb
203
217
  - test/test_helper.rb
204
- has_rdoc: