crispy 0.3.3 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c3f5cac13b6c7c9ab3d1a02c14d7c4aab8d49a37
4
- data.tar.gz: 0d3a8f30a788ca7b6f65656e2d754500edfed384
3
+ metadata.gz: 145162d93fda035a4ce64022d92508d71fdab5c2
4
+ data.tar.gz: 0ec0fc67bb6b51810e38da470b8a582b5496ee00
5
5
  SHA512:
6
- metadata.gz: 18e6deacab79ac272ae87429c086e1f087209f237c428c1fd5f4a5e23fe58b02d583df118d8534692d79d03a167024f0559f266d8f4851cab6bbe25377d956f2
7
- data.tar.gz: 831d33b2b1878255f2396b2f2d14175569e5a6e5ad17d8d81a97864f27b93d69e8cadf7ce58b90ac070bfd973170ce5556bbc028a8679a4a22c3911d4e208e27
6
+ metadata.gz: 921b924827c9327a2343a3175e4cb7236704154af50e9fdda5836897e306031313a35763cee6ed38c338032ca7fb202b87ba224b2c985af43802142b7139f632
7
+ data.tar.gz: cc5ef58c6123edf2043ad0501051107b6c4e8a7c5823fa8722ed0a62151eb5d8fa86d944189af85988f3a38cbf091db98dc9a47db24521a1f11a942b73993fc2
@@ -4,8 +4,8 @@ install:
4
4
  - CODECLIMATE_REPO_TOKEN=fe75ea4329c1e131ef79de66f8ba2f605fa2fd352bbbd61fed5024cb6eaaba73 bundle
5
5
  rvm:
6
6
  - ruby-head
7
- - 2.2.0
8
- - 2.1.5
7
+ - 2.2.2
8
+ - 2.1.6
9
9
  - 2.0.0
10
10
  script:
11
11
  - CODECLIMATE_REPO_TOKEN=fe75ea4329c1e131ef79de66f8ba2f605fa2fd352bbbd61fed5024cb6eaaba73 bundle exec rubydoctest README.md
@@ -1,3 +1,12 @@
1
+ # 0.4.0 (2015.4.29)
2
+
3
+ - New Feature: Spy blacklist [\#37](https://github.com/igrep/crispy/pull/37).
4
+ - **Important**: Adding this feature changes the keyword arguments of Crispy.spy_into into `except` optional argument instead of stubbed methods.
5
+ If you specify stubbed methods, use `stub` methods of a spy as [the README](https://github.com/igrep/crispy#stub-methods-of-a-spy) describes.
6
+ - Fix Bug: Spy spy-methods of double unintentionally [\#30](https://github.com/igrep/crispy/issues/30), [\#37](https://github.com/igrep/crispy/pull/37).
7
+ - Minor Enhancement: Update Ruby versions to test on Travis CI [\#36](https://github.com/igrep/crispy/pull/36).
8
+ - Minor Enhancement: Specify minimum rubydoctest version. [da3ddaa](https://github.com/igrep/crispy/commit/da3ddaa37d912b81aa3a23f366765cc9fd47c387)
9
+
1
10
  # 0.3.3 (2015.3.27)
2
11
 
3
12
  - Fix Bug: Causes a crash when some of `@spies_to_reset` gets GCed just before `reinitialize`. [3a1ce2d](https://github.com/igrep/crispy/commit/3a1ce2dfc25ba48d07505b6ed1d7125f393e9579)
data/README.md CHANGED
@@ -268,6 +268,25 @@ Specify the **fully qualified name of the constant** instead of the constant its
268
268
  => "more cool value!"
269
269
  ```
270
270
 
271
+ ### Configure Methods which Spy Should NOT Log
272
+
273
+ Sometimes, you may want to make a spy ignore some methods.
274
+
275
+ ```ruby
276
+ >> x = YourCoolClass.new
277
+ >> spy_into x, except: [:method_to_ignore1, :method_to_ignore2]
278
+ >> x.method_to_ignore1
279
+ >> x.method_to_ignore2
280
+ >> x.your_cool_method
281
+
282
+ >> spy(x).received? :method_to_ignore1
283
+ => false
284
+ >> spy(x).received? :method_to_ignore2
285
+ => false
286
+ >> spy(x).received? :your_cool_method
287
+ => true
288
+ ```
289
+
271
290
  ### Embedding Crispy into your Testing Framework
272
291
 
273
292
  Remember to reset all the changes made by Crispy, call `CrispyWorld.reset`.
@@ -23,7 +23,8 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency "bundler", "~> 1.7"
24
24
  spec.add_development_dependency "rake"
25
25
  spec.add_development_dependency "minitest", "~> 5"
26
- spec.add_development_dependency "rubydoctest"
26
+ spec.add_development_dependency "rubydoctest", ">= 1.1.5"
27
+ spec.add_development_dependency "github_changelog_generator"
27
28
 
28
29
  spec.required_ruby_version = '>= 2.0'
29
30
  end
@@ -9,8 +9,8 @@ module Crispy
9
9
  module_function
10
10
 
11
11
  # Returns a Spy object to wrap all methods of the object.
12
- def spy_into object, stubs_map = {}
13
- ::Crispy::CrispyInternal::Spy.new object, stubs_map
12
+ def spy_into object, except: []
13
+ ::Crispy::CrispyInternal::Spy.new object, except: except
14
14
  end
15
15
 
16
16
  def double name_or_stubs_map = nil, stubs_map = {}
@@ -18,8 +18,8 @@ module Crispy
18
18
  end
19
19
 
20
20
  # Make and returns a Crispy::ClassSpy's instance to spy all instances of a class.
21
- def spy_into_instances klass, stubs_map = {}
22
- ::Crispy::CrispyInternal::ClassSpy.new klass, stubs_map
21
+ def spy_into_instances klass, except: []
22
+ ::Crispy::CrispyInternal::ClassSpy.new klass, except: except
23
23
  end
24
24
 
25
25
  def spy object
@@ -7,7 +7,7 @@ module Crispy
7
7
 
8
8
  @registry = {}
9
9
 
10
- def initialize klass, stubs_map = {}
10
+ def initialize klass, except: []
11
11
  @received_messages_with_receiver = []
12
12
 
13
13
  super
@@ -2,13 +2,15 @@ module Crispy
2
2
  module CrispyInternal
3
3
  class Double
4
4
 
5
+ SPY_METHODS = %i[received_messages stub] + SpyBase::COMMON_RECEIVED_MESSAGE_METHODS_DEFINITION.keys
6
+
5
7
  def initialize name_or_stubs_map = nil, stubs_map = {}
6
8
  if name_or_stubs_map.is_a? ::Hash
7
9
  @name = ''.freeze
8
- @spy = ::Crispy.spy_into(self, name_or_stubs_map)
10
+ spy_into_self_as_double(name_or_stubs_map)
9
11
  else
10
12
  @name = name_or_stubs_map
11
- @spy = ::Crispy.spy_into(self, stubs_map)
13
+ spy_into_self_as_double(stubs_map)
12
14
  end
13
15
  end
14
16
 
@@ -28,6 +30,11 @@ module Crispy
28
30
  END
29
31
  end
30
32
 
33
+ def spy_into_self_as_double stubs_map
34
+ @spy = ::Crispy.spy_into(self, except: SPY_METHODS).stub(stubs_map)
35
+ end
36
+ private :spy_into_self_as_double
37
+
31
38
  end
32
39
  end
33
40
  end
@@ -11,7 +11,7 @@ module Crispy
11
11
 
12
12
  attr_reader :received_messages
13
13
 
14
- def initialize target, stubs_map = {}
14
+ def initialize target, except: []
15
15
  spy = self
16
16
  module_eval do
17
17
  define_method(:__CRISPY_SPY__) { spy }
@@ -10,18 +10,24 @@ module Crispy
10
10
  :__CRISPY_SPY__,
11
11
  ]
12
12
 
13
- def initialize target, stubs_map = {}
13
+ def initialize target, except: []
14
+ @exceptions = Array(except).map(&:to_sym)
15
+
14
16
  prepend_features target_to_class(target)
15
17
 
16
18
  @stubbed_methods = []
17
- stub stubs_map
18
19
 
19
20
  @spying = true
20
21
  end
21
22
 
22
- def self.new target, stubs_map = {}
23
+ def self.new target, except: []
23
24
  spy = self.of_target(target)
24
- spy ? spy.reinitialize(stubs_map) : super
25
+ if spy
26
+ spy.update_exceptions(target, except)
27
+ spy.reinitialize
28
+ else
29
+ super
30
+ end
25
31
  end
26
32
 
27
33
  def self.of_target target
@@ -44,13 +50,27 @@ module Crispy
44
50
  raise NotImplementedError
45
51
  end
46
52
 
47
- def reinitialize stubs_map = {}
53
+ def reinitialize
48
54
  restart
49
55
  erase_log
50
- reinitialize_stubber stubs_map
56
+ reinitialize_stubber
51
57
  self
52
58
  end
53
59
 
60
+ def update_exceptions target, exceptions
61
+ return if exceptions.empty?
62
+
63
+ given_exceptions = Array(exceptions).map(&:to_sym)
64
+
65
+ new_exceptions = given_exceptions - @exceptions
66
+ remove_method(*new_exceptions)
67
+
68
+ old_exceptions = @exceptions - given_exceptions
69
+ redefine_wrappers target_to_class(target), old_exceptions
70
+
71
+ @exceptions.replace given_exceptions
72
+ end
73
+
54
74
  def stop
55
75
  @spying = false
56
76
  end
@@ -124,31 +144,44 @@ module Crispy
124
144
  self
125
145
  end
126
146
 
127
- def reinitialize_stubber stubs_map = {}
147
+ def reinitialize_stubber
128
148
  remove_method(*@stubbed_methods)
129
149
  @stubbed_methods.each {|stubbed_method| define_wrapper stubbed_method }
130
150
  @stubbed_methods.clear
131
- stub stubs_map
151
+ end
152
+
153
+ %w[only except].each do|inclusion|
154
+ not_sign = inclusion == 'except'.freeze ? '!'.freeze : ''.freeze
155
+ %w[public protected private].each do|visibility|
156
+ binding.eval(<<-END, __FILE__, (__LINE__ + 1))
157
+ def define_#{visibility}_wrappers_#{inclusion} klass, targets
158
+ klass.#{visibility}_instance_methods.each do|method_name|
159
+ #{visibility} define_wrapper(method_name) if method_name != :__CRISPY_SPY__ && #{not_sign}targets.include?(method_name)
160
+ end
161
+ end
162
+ END
163
+ end
132
164
  end
133
165
 
134
166
  def prepend_features klass
135
167
  super
136
168
 
137
169
  self.module_eval do
138
- klass.public_instance_methods.each do|method_name|
139
- next if method_name == :__CRISPY_SPY__
140
- define_wrapper(method_name)
141
- end
142
- klass.protected_instance_methods.each do|method_name|
143
- protected define_wrapper(method_name)
144
- end
145
- klass.private_instance_methods.each do|method_name|
146
- private define_wrapper(method_name)
147
- end
170
+ define_public_wrappers_except(klass, @exceptions)
171
+ define_protected_wrappers_except(klass, @exceptions)
172
+ define_private_wrappers_except(klass, @exceptions)
148
173
  end
149
174
  end
150
175
  private :prepend_features
151
176
 
177
+ def redefine_wrappers klass, method_names
178
+ self.module_eval do
179
+ define_public_wrappers_only(klass, method_names)
180
+ define_protected_wrappers_only(klass, method_names)
181
+ define_private_wrappers_only(klass, method_names)
182
+ end
183
+ end
184
+
152
185
  def assert_symbol! maybe_symbol
153
186
  unless maybe_symbol.respond_to?(:to_sym) && maybe_symbol.to_sym.instance_of?(::Symbol)
154
187
  raise TypeError, "TypeError: no implicit conversion from #{maybe_symbol.inspect} to symbol"
@@ -1,3 +1,3 @@
1
1
  module Crispy
2
- VERSION = "0.3.3"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -10,6 +10,10 @@ class YourCoolClass
10
10
  end
11
11
  def your_finalizer *args
12
12
  end
13
+ def method_to_ignore1
14
+ end
15
+ def method_to_ignore2
16
+ end
13
17
 
14
18
  class Again < self
15
19
  def your_another_method *args
@@ -62,6 +62,11 @@ class TestCrispy < MiniTest::Test
62
62
  123
63
63
  end
64
64
 
65
+ def self.non_spied1
66
+ end
67
+ def self.non_spied2
68
+ end
69
+
65
70
  def self.stubbed_method1
66
71
  'before stubbed 1'
67
72
  end
@@ -132,9 +137,8 @@ class TestCrispy < MiniTest::Test
132
137
  def setup
133
138
  @object = ObjectClass.new
134
139
 
135
- @returned_spy = spy_into(
136
- @object, method_to_stub1: :stubbed1, method_to_stub2: :stubbed2
137
- )
140
+ @returned_spy = spy_into(@object)
141
+ @returned_spy.stub(method_to_stub1: :stubbed1, method_to_stub2: :stubbed2)
138
142
 
139
143
  @object.hoge 1, 2, 3
140
144
  @object.foo
@@ -213,11 +217,12 @@ class TestCrispy < MiniTest::Test
213
217
  class TestCrispySpyIntoClass < TestCrispy
214
218
 
215
219
  def setup
216
- spy_into ObjectClass, stubbed_method1: 1, stubbed_method2: 2
220
+ spy_into(ObjectClass, except: :non_spied1).stub(stubbed_method1: 1, stubbed_method2: 2)
217
221
 
218
222
  ObjectClass.hoge 1, 2, 3
219
223
  ObjectClass.foo
220
224
  ObjectClass.hoge 3, 4, 5
225
+ ObjectClass.non_spied1
221
226
 
222
227
  @subject = spy(ObjectClass)
223
228
  end
@@ -238,7 +243,7 @@ class TestCrispy < MiniTest::Test
238
243
  end
239
244
 
240
245
  def test_spy_overrides_stubbed_methods
241
- spy_into ObjectClass, stubbed_method2: 'xx', stubbed_method3: 'xxx'
246
+ spy_into(ObjectClass).stub(stubbed_method2: 'xx', stubbed_method3: 'xxx')
242
247
 
243
248
  assert_equal 'before stubbed 1', ObjectClass.stubbed_method1
244
249
  assert_equal 'xx' , ObjectClass.stubbed_method2
@@ -267,6 +272,22 @@ class TestCrispy < MiniTest::Test
267
272
  assert_raises(::Crispy::CrispyError){ spy_of_instances(Class.new) }
268
273
  end
269
274
 
275
+ def test_spy_ignores_exceptions
276
+ assert not(spy(ObjectClass).received? :non_spied1)
277
+ end
278
+
279
+ def test_spy_overwrites_exceptions_by_spy_into_again
280
+ assert not(spy(ObjectClass).received? :non_spied1)
281
+
282
+ spy_into(ObjectClass, except: :non_spied2)
283
+
284
+ ObjectClass.non_spied1
285
+ ObjectClass.non_spied2
286
+
287
+ assert spy(ObjectClass).received? :non_spied1
288
+ assert not(spy(ObjectClass).received? :non_spied2)
289
+ end
290
+
270
291
  end
271
292
 
272
293
  class TestCrispySpyIntoInstances < TestCrispy
@@ -276,9 +297,8 @@ class TestCrispy < MiniTest::Test
276
297
  end
277
298
 
278
299
  def setup
279
- @returned_spy = spy_into_instances(
280
- object_class, method_to_stub1: :stubbed_instance_method1, method_to_stub2: :stubbed_instance_method2
281
- )
300
+ @returned_spy = spy_into_instances(object_class)
301
+ @returned_spy.stub(method_to_stub1: :stubbed_instance_method1, method_to_stub2: :stubbed_instance_method2)
282
302
 
283
303
  @subject = spy_of_instances(object_class)
284
304
  @object_instances = Array.new(3){ object_class.new }
@@ -306,7 +326,7 @@ class TestCrispy < MiniTest::Test
306
326
  end
307
327
 
308
328
  def test_spy_overrides_stubbed_methods
309
- spy_into_instances object_class, method_to_stub2: 'xx', method_to_stub3: 'xxx'
329
+ spy_into_instances(object_class).stub(method_to_stub2: 'xx', method_to_stub3: 'xxx')
310
330
 
311
331
  @object_instances.each do|object|
312
332
  assert_equal 'method to stub 1 (before stubbed)', object.method_to_stub1
@@ -633,7 +653,7 @@ class TestCrispy < MiniTest::Test
633
653
  assert_same @expected_baz, @actual_baz
634
654
  end
635
655
 
636
- def test_double_can_be_spied
656
+ def test_double_is_spied
637
657
  assert spied? @double
638
658
 
639
659
  assert_same @double.received_messages, spy(@double).received_messages
@@ -659,6 +679,23 @@ class TestCrispy < MiniTest::Test
659
679
  assert_equal 0, @double.count_received(:non_used_method)
660
680
  end
661
681
 
682
+ def test_double_doesnt_spy_spy_methods
683
+ @double.stub(a: 0)
684
+ @double.received? :hoge
685
+ @double.received_once? :hoge
686
+ @double.count_received :hoge
687
+
688
+ should_not_logged = %i[
689
+ received? received_once? count_received
690
+ stub received_messages
691
+ ]
692
+
693
+ assert_empty(
694
+ @double.received_messages.select {|received_messages| should_not_logged.include? received_messages.method_name }
695
+ )
696
+
697
+ end
698
+
662
699
  end
663
700
 
664
701
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crispy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yuji Yamamoto
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-26 00:00:00.000000000 Z
11
+ date: 2015-04-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -54,6 +54,20 @@ dependencies:
54
54
  version: '5'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rubydoctest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 1.1.5
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 1.1.5
69
+ - !ruby/object:Gem::Dependency
70
+ name: github_changelog_generator
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - ">="