crispy 0.1.2 → 0.2.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: d8c2e227c900fbd250845f513639e9b1815d1d22
4
- data.tar.gz: f4bcd6597bb277ad1cbe8227f97ca7f3933d337f
3
+ metadata.gz: a5a304875b84ee789d83ba6420f4b57a2cd769d3
4
+ data.tar.gz: 50dddf1394a740c51c7a15dbfd5d4bd3227388b8
5
5
  SHA512:
6
- metadata.gz: 30f2c2baa3ee316befcc6bde7e6c01663bedaed3ef922c7bcb249b4644723c396e87cd889e70fc72a90a23aedf373101355365f682942d95abed2e23fce01004
7
- data.tar.gz: 75edd3b7832f9332111bfc6bfa457729292195f5b3a2629ba8f9b555b073a6321f7afcc02e6324ba2ea4e5f67813ee07fd97fc5a1fa7ad3a0ca35003218eced8
6
+ metadata.gz: 469caadde79084134b26358634de2830d156233e938b4ad2c1a21dd6653d0bd50d019530e6c5ad80bcf9b5e59526b135572bc8939b5d160b2f4a3f10129d79d8
7
+ data.tar.gz: 902018025f544c073758117e5072896cb7dbf5b6cbc2a41f52b6116036a485a24ff23090e36718d94fdabe0ca7b9a27c21fa18db2bf61be6e255247029c2c58d
data/.travis.yml CHANGED
@@ -3,9 +3,23 @@ install:
3
3
  - gem install bundler
4
4
  - bundle
5
5
  rvm:
6
- - 2.1.1
6
+ - ruby-head
7
+ - 2.2.0-preview1
8
+ - 2.1.3
7
9
  - 2.0.0
8
- - rbx-2
9
10
  script:
10
- - bundle exec ruby test/test_crispy.rb
11
- - bundle exec rubydoctest README.md
11
+ - CODECLIMATE_REPO_TOKEN=fe75ea4329c1e131ef79de66f8ba2f605fa2fd352bbbd61fed5024cb6eaaba73 bundle exec rubydoctest README.md
12
+ - CODECLIMATE_REPO_TOKEN=fe75ea4329c1e131ef79de66f8ba2f605fa2fd352bbbd61fed5024cb6eaaba73 bundle exec ruby test/test_crispy.rb
13
+ notifications:
14
+ email:
15
+ recipients:
16
+ - whosekiteneverfly@gmail.com
17
+ on_success: never
18
+ on_failure: never
19
+ addons:
20
+ code_climate:
21
+ repo_token: 4329c1e131ef79de66f8ba2f605fa2fd352bbbd61fed5024cb6eaaba73
22
+ matrix:
23
+ allow_failures:
24
+ - rvm: ruby-head
25
+ - rvm: 2.2.0-preview1
data/ChangeLog.md CHANGED
@@ -1,3 +1,13 @@
1
+ # 0.2.0 (2014.11.1)
2
+
3
+ - New Feature: `stub_const`. [#11](https://github.com/igrep/crispy/pull/11)
4
+ - New Feature: `spy_into_instances`, `spy_of_instances`. [#17](https://github.com/igrep/crispy/pull/17)
5
+ - New Feature: `spy().stop`, `spy().restart`. [#17](https://github.com/igrep/crispy/pull/17)
6
+ - Compatibility Change: change module structure. [#11](https://github.com/igrep/crispy/pull/11)
7
+ - Now public modules are prefixed with `Crispy` instead of `Crispy::`.
8
+ - Because it seems that we can't refer with `Crispy::World` when including the top level `::Crispy` module.
9
+ - So now we can refer with `CrispyWorld` by including `::Crispy`
10
+
1
11
  # 0.1.2 (2014.8.24)
2
12
 
3
13
  - Support Ruby 2.0 correctly.
data/Gemfile CHANGED
@@ -2,3 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in crispy.gemspec
4
4
  gemspec
5
+
6
+ gem 'codeclimate-test-reporter', group: :test, require: nil
data/README.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Crispy
2
2
 
3
+ [![Code Climate](https://codeclimate.com/github/igrep/crispy/badges/gpa.svg)](https://codeclimate.com/github/igrep/crispy)
4
+ [![Test Coverage](https://codeclimate.com/github/igrep/crispy/badges/coverage.svg)](https://codeclimate.com/github/igrep/crispy)
5
+ [![Build Status](https://travis-ci.org/igrep/crispy.svg?branch=master)](https://travis-ci.org/igrep/crispy)
6
+ [![Gem Version](https://badge.fury.io/rb/crispy.svg)](http://badge.fury.io/rb/crispy)
7
+
3
8
  Test Spy for Any Object in Ruby.
4
9
 
5
10
  ## Features
@@ -30,7 +35,7 @@ Or install it yourself as:
30
35
  doctest_require: './test/doctest-fixtures/your_cool_class.rb'
31
36
  -->
32
37
 
33
- ### Spy on a Object
38
+ ### Spy on an Object
34
39
 
35
40
  ```ruby
36
41
  >> require 'crispy'
@@ -96,7 +101,7 @@ Each argument is compared by `==` method.
96
101
  #### Get more detailed log
97
102
 
98
103
  You can check arbitrary received methods with the familliar Array's (and of course including Enumerable's!) methods such as `any?`, `all`, `first`, `[]`, `index`.
99
- Because `spy(object).received_messages` returns an array of `Crispy::ReceivedMessage` instances.
104
+ Because `spy(object).received_messages` returns an array of `CrispyReceivedMessage` instances.
100
105
  **You don't have to remember the tons of matchers for received arguments any more!!**
101
106
 
102
107
  ```ruby
@@ -113,6 +118,76 @@ Because `spy(object).received_messages` returns an array of `Crispy::ReceivedMes
113
118
  => true
114
119
  ```
115
120
 
121
+ ### Spy on Instances of a Class
122
+
123
+ ```ruby
124
+ >> spy_into_instances(YourCoolClass)
125
+ >> instance1 = YourCoolClass.new
126
+ >> instance2 = YourCoolClass.new
127
+
128
+ >> instance1.your_cool_method 'and', 'args'
129
+ >> instance2.your_lovely_method
130
+ >> instance2.your_lovely_method 'again!'
131
+ >> instance1.your_finalizer 'cleaning up...'
132
+ ```
133
+
134
+ You can check methods called by all instances of a class by the same query methods wth spy.
135
+
136
+ ```ruby
137
+ >> spy_of_instances(YourCoolClass).received? :your_cool_method, 'and', 'args'
138
+ => true
139
+
140
+ >> spy_of_instances(YourCoolClass).count_received :your_lovely_method
141
+ => 2
142
+
143
+ >> spy_of_instances(YourCoolClass).received_messages.last.method_name == :your_finalizer
144
+ => true
145
+ ```
146
+
147
+ In addition, you can check which instance calles a method as well as its arguments.
148
+
149
+ ```ruby
150
+ >> spy_of_instances(YourCoolClass).received_with_receiver? instance1, :your_cool_method
151
+ => true
152
+ >> spy_of_instances(YourCoolClass).received_with_receiver? instance2, :your_cool_method
153
+ => false
154
+
155
+ >> spy_of_instances(YourCoolClass).count_received_with_receiver instance1, :your_lovely_method
156
+ => 0
157
+ >> spy_of_instances(YourCoolClass).count_received_with_receiver instance2, :your_lovely_method
158
+ => 2
159
+
160
+ >> spy_of_instances(YourCoolClass).received_messages_with_receiver.last.receiver == instance1
161
+ => true
162
+ ```
163
+
164
+ Note that `spy_of_instances` stops to spy after called methods with `with_receiver` (or `with_receiver?`) prefix.
165
+ This is to prevent the spy from unexpectedly logging methods used to compare its receiver (such as `==`).
166
+
167
+ ```ruby
168
+ >> spy_into_instances(YourCoolClass::Again)
169
+ >> instance = YourCoolClass::Again.new
170
+
171
+ >> instance.your_another_method
172
+ >> # Stops spying here.
173
+ >> spy_of_instances(YourCoolClass::Again).received_with_receiver? instance, :your_another_method
174
+
175
+ >> # Perhaps you don't want to log methods in test code.
176
+ >> instance.some_method_for_testing
177
+ >> spy_of_instances(YourCoolClass::Again).received? :some_method_for_testing
178
+ >> false
179
+ ```
180
+
181
+ If you want to restart spying, use `restart` method literally.
182
+
183
+ ```ruby
184
+ >> spy_into_instances(YourCoolClass::Again).restart
185
+
186
+ >> instance.some_method_for_testing
187
+ >> spy_of_instances(YourCoolClass::Again).received? :some_method_for_testing
188
+ >> true
189
+ ```
190
+
116
191
  ### Stub Methods of a Spy
117
192
 
118
193
  ```ruby
@@ -141,6 +216,28 @@ Because `spy(object).received_messages` returns an array of `Crispy::ReceivedMes
141
216
  => "can be stubbed."
142
217
  ```
143
218
 
219
+ ### Stub Constants
220
+
221
+ Specify the **fully qualified name of the constant** instead of the constant itself.
222
+
223
+ ```ruby
224
+ >> YourCoolClass::YOUR_COOL_CONST
225
+ => "value before stubbed"
226
+
227
+ >> stub_const 'YourCoolClass::YOUR_COOL_CONST', 'more cool value!'
228
+ >> YourCoolClass::YOUR_COOL_CONST
229
+ => "more cool value!"
230
+ ```
231
+
232
+ Then you can recover the stubbed constant value by `CrispyWorld.reset`.
233
+
234
+ ```ruby
235
+ >> CrispyWorld.reset
236
+
237
+ >> YourCoolClass::YOUR_COOL_CONST
238
+ => "value before stubbed"
239
+ ```
240
+
144
241
  ## Contributing
145
242
 
146
243
  1. Fork it ( https://github.com/igrep/crispy/fork )
data/crispy.gemspec CHANGED
@@ -7,9 +7,9 @@ Gem::Specification.new do |spec|
7
7
  spec.version = Crispy::VERSION
8
8
  spec.authors = ["Yamamoto Yuji"]
9
9
  spec.email = ["whosekiteneverfly@gmail.com"]
10
- spec.summary = %q{Test spy for any object in Ruby.}
10
+ spec.summary = %q{Test spy for any object.}
11
11
  spec.description =
12
- "Test spy for any object in Ruby.\n" \
12
+ "Test spy for any object.\n" \
13
13
  "It makes mocks obsolete so you don't have to be worried about " \
14
14
  "where to put the expectations (i.e. before or after the subject method)."
15
15
  spec.homepage = "https://github.com/igrep/crispy"
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.add_development_dependency "rake"
25
25
  spec.add_development_dependency "minitest", "~> 5.4"
26
26
  spec.add_development_dependency "pry"
27
+ spec.add_development_dependency "byebug"
27
28
  spec.add_development_dependency "rubydoctest"
28
29
 
29
30
  spec.required_ruby_version = '>= 2.0'
@@ -0,0 +1,104 @@
1
+ require 'crispy/crispy_received_message_with_receiver'
2
+ require 'crispy/crispy_internal/spy_mixin'
3
+ require 'crispy/crispy_internal/with_stubber'
4
+
5
+ module Crispy
6
+ module CrispyInternal
7
+ class ClassSpy < ::Module
8
+ include SpyMixin
9
+ #include WithStubber
10
+
11
+ @registry = {}
12
+
13
+ def initialize klass#, stubs_map = {}
14
+ spy = self
15
+ super() do
16
+ define_method(:__CRISPY_CLASS_SPY__) { spy }
17
+ end
18
+
19
+ @received_messages_with_receiver = []
20
+ initialize_spy
21
+
22
+ #initialize_stubber stubs_map
23
+ #prepend_stubber klass
24
+
25
+ prepend_features klass
26
+ self.class.register spy: spy, of_class: klass
27
+ end
28
+
29
+ def received_messages
30
+ @received_messages_with_receiver.map {|m| m.received_message }
31
+ end
32
+
33
+ def received_messages_with_receiver
34
+ # stop spying in advance to prevent from unexpectedly spying receiver's methods in test code.
35
+ self.stop
36
+ @received_messages_with_receiver
37
+ end
38
+
39
+ COMMON_RECEIVED_MESSAGE_METHODS_DEFINITION.each do|method_name, core_definition|
40
+ method_name_with_receiver = method_name.sub(/\??\z/) do|question_mark|
41
+ "_with_receiver#{question_mark}"
42
+ end
43
+
44
+ binding.eval(<<-END, __FILE__, (__LINE__ + 1))
45
+ def #{method_name_with_receiver} receiver, received_method_name, *received_arguments, &received_block
46
+ assert_symbol! received_method_name
47
+ if received_arguments.empty? and received_block.nil?
48
+ recevier_and_received_method_name = [receiver, received_method_name]
49
+ received_messages_with_receiver.map do|received_message_with_receiver|
50
+ [received_message_with_receiver.receiver, received_message_with_receiver.method_name]
51
+ end.#{sprintf(core_definition, 'recevier_and_received_method_name')}
52
+ else
53
+ received_message_with_receiver = ::Crispy::CrispyReceivedMessageWithReceiver.new(
54
+ receiver, received_method_name, *received_arguments, &received_block
55
+ )
56
+ received_messages_with_receiver.#{sprintf(core_definition, 'received_message_with_receiver')}
57
+ end
58
+ end
59
+ END
60
+ end
61
+
62
+ def erase_log
63
+ @received_messages_with_receiver.clear
64
+ end
65
+
66
+ def append_received_message_with_receiver receiver, method_name, *arguments, &attached_block
67
+ if @spying
68
+ @received_messages_with_receiver <<
69
+ ::Crispy::CrispyReceivedMessageWithReceiver.new(receiver, method_name, *arguments, &attached_block)
70
+ end
71
+ end
72
+
73
+ def define_wrapper method_name
74
+ define_method method_name do|*arguments, &attached_block|
75
+ __CRISPY_CLASS_SPY__.append_received_message_with_receiver self, method_name, *arguments, &attached_block
76
+
77
+ super(*arguments, &attached_block)
78
+ end
79
+ method_name
80
+ end
81
+ private :define_wrapper
82
+
83
+ def self.new klass#, stubs_map = {}
84
+ spy = self.of_class(klass)
85
+ if spy
86
+ spy.restart
87
+ spy.erase_log
88
+ spy
89
+ else
90
+ super
91
+ end
92
+ end
93
+
94
+ def self.register(spy: nil, of_class: nil)
95
+ @registry[of_class] = spy
96
+ end
97
+
98
+ def self.of_class(klass)
99
+ @registry[klass]
100
+ end
101
+
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,42 @@
1
+ module Crispy
2
+ module CrispyInternal
3
+ module ConstChanger
4
+
5
+ @registry = {}
6
+
7
+ class << self
8
+
9
+ def change_by_full_name full_const_name, value
10
+ const_names = full_const_name.split('::'.freeze)
11
+
12
+ const_names.shift if const_names.first.empty?
13
+
14
+ target_const_name = const_names.pop
15
+
16
+ module_containing_target_const =
17
+ const_names.inject(::Kernel) do|const_value, const_name|
18
+ const_value.const_get const_name
19
+ end
20
+
21
+ saved_value = module_containing_target_const.module_eval do
22
+ remove_const target_const_name
23
+ end
24
+ module_containing_target_const.const_set target_const_name, value
25
+
26
+ saved_value
27
+ end
28
+
29
+ def save full_const_name, value
30
+ @registry[full_const_name] = value
31
+ end
32
+
33
+ def recover_all
34
+ @registry.each do|full_const_name, saved_value|
35
+ self.change_by_full_name(full_const_name, saved_value)
36
+ end
37
+ end
38
+
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,4 +1,4 @@
1
- require 'crispy/crispy/received_message'
1
+ require 'crispy/crispy_received_message'
2
2
  require 'crispy/crispy_internal/spy_mixin'
3
3
  require 'crispy/crispy_internal/with_stubber'
4
4
 
@@ -8,9 +8,17 @@ module Crispy
8
8
  include SpyMixin
9
9
  include WithStubber
10
10
 
11
+ attr_reader :received_messages
12
+
11
13
  def initialize target, stubs_map = {}
12
- super()
14
+ super() do
15
+ spy = self
16
+ define_method(:__CRISPY_SPY__) { spy }
17
+ end
18
+
13
19
  @received_messages = []
20
+ initialize_spy
21
+
14
22
  singleton_class =
15
23
  class << target
16
24
  self
@@ -19,29 +27,23 @@ module Crispy
19
27
  prepend_stubber singleton_class
20
28
 
21
29
  prepend_features singleton_class
22
- target.__CRISPY_SPY__ = self
23
30
  end
24
31
 
25
- def prepend_features klass
26
- super
27
- klass.public_instance_methods.each do|method_name|
28
- self.module_eval { public define_wrapper(method_name) }
29
- end
30
- klass.protected_instance_methods.each do|method_name|
31
- self.module_eval { protected define_wrapper(method_name) }
32
- end
33
- klass.private_instance_methods.each do|method_name|
34
- self.module_eval { private define_wrapper(method_name) }
35
- end
32
+ def erase_log
33
+ @received_messages.clear
34
+ end
36
35
 
37
- # define accessor after prepending to avoid to spy unexpectedly.
38
- module_eval { attr_accessor :__CRISPY_SPY__ }
36
+ def append_received_message method_name, *arguments, &attached_block
37
+ if @spying
38
+ @received_messages <<
39
+ ::Crispy::CrispyReceivedMessage.new(method_name, *arguments, &attached_block)
40
+ end
39
41
  end
40
42
 
41
43
  def define_wrapper method_name
42
44
  define_method method_name do|*arguments, &attached_block|
43
- @__CRISPY_SPY__.received_messages <<
44
- ::Crispy::Crispy::ReceivedMessage.new(method_name, *arguments, &attached_block)
45
+ __CRISPY_SPY__.append_received_message(method_name, *arguments, &attached_block)
46
+
45
47
  super(*arguments, &attached_block)
46
48
  end
47
49
  method_name
@@ -1,34 +1,80 @@
1
- require 'crispy/crispy/received_message'
1
+ require 'crispy/crispy_received_message'
2
2
 
3
3
  module Crispy
4
4
  module CrispyInternal
5
5
  module SpyMixin
6
6
 
7
- attr_reader :received_messages
7
+ BLACK_LISTED_METHODS = [
8
+ :__CRISPY_CLASS_SPY__,
9
+ :__CRISPY_SPY__,
10
+ ]
8
11
 
9
- def received? method_name, *arguments, &attached_block
10
- if arguments.empty? and attached_block.nil?
11
- @received_messages.map(&:method_name).include? method_name
12
- else
13
- @received_messages.include? ::Crispy::Crispy::ReceivedMessage.new(method_name, *arguments, &attached_block)
14
- end
12
+ def received_messages
13
+ raise NotImplementedError
14
+ end
15
+
16
+ def erase_log
17
+ raise NotImplementedError
18
+ end
19
+
20
+ def stop
21
+ @spying = false
15
22
  end
16
23
 
17
- def received_once? method_name, *arguments, &attached_block
18
- if arguments.empty? and attached_block.nil?
19
- @received_messages.map(&:method_name).one? {|self_method_name| self_method_name == method_name }
20
- else
21
- @received_messages.one? do |self_received_message|
22
- self_received_message == ::Crispy::Crispy::ReceivedMessage.new(method_name, *arguments, &attached_block)
24
+ def restart
25
+ @spying = true
26
+ end
27
+
28
+ COMMON_RECEIVED_MESSAGE_METHODS_DEFINITION = {
29
+ 'received?' => 'include? %s',
30
+ 'received_once?' => 'one? {|self_thing| self_thing == %s }',
31
+ 'count_received' => 'count %s',
32
+ }
33
+
34
+ COMMON_RECEIVED_MESSAGE_METHODS_DEFINITION.each do|method_name, core_definition|
35
+ binding.eval(<<-END, __FILE__, (__LINE__ + 1))
36
+ def #{method_name} received_method_name, *received_arguments, &received_block
37
+ assert_symbol! received_method_name
38
+ if received_arguments.empty? and received_block.nil?
39
+ received_messages.map(&:method_name).#{sprintf(core_definition, 'received_method_name')}
40
+ else
41
+ received_message = ::Crispy::CrispyReceivedMessage.new(
42
+ received_method_name, *received_arguments, &received_block
43
+ )
44
+ received_messages.#{sprintf(core_definition, 'received_message')}
45
+ end
23
46
  end
47
+ END
48
+ end
49
+
50
+ def prepend_features klass
51
+ super
52
+
53
+ without_black_listed_methods(klass.public_instance_methods).each do|method_name|
54
+ self.module_eval { define_wrapper(method_name) }
55
+ end
56
+ klass.protected_instance_methods.each do|method_name|
57
+ self.module_eval { protected define_wrapper(method_name) }
58
+ end
59
+ klass.private_instance_methods.each do|method_name|
60
+ self.module_eval { private define_wrapper(method_name) }
24
61
  end
25
62
  end
63
+ private :prepend_features
64
+
65
+ def without_black_listed_methods method_names
66
+ method_names.reject {|method_name| BLACK_LISTED_METHODS.include? method_name }
67
+ end
68
+ private :without_black_listed_methods
69
+
70
+ def initialize_spy
71
+ @spying = true
72
+ end
73
+ private :initialize_spy
26
74
 
27
- def count_received method_name, *arguments, &attached_block
28
- if arguments.empty? and attached_block.nil?
29
- @received_messages.map(&:method_name).count method_name
30
- else
31
- @received_messages.count ::Crispy::Crispy::ReceivedMessage.new(method_name, *arguments, &attached_block)
75
+ def assert_symbol! maybe_symbol
76
+ unless maybe_symbol.respond_to?(:to_sym) && maybe_symbol.to_sym.instance_of?(::Symbol)
77
+ raise TypeError, "TypeError: no implicit conversion from #{maybe_symbol.inspect} to symbol"
32
78
  end
33
79
  end
34
80
 
@@ -0,0 +1,52 @@
1
+ module Crispy
2
+ class CrispyReceivedMessage
3
+
4
+ DELEGATABLE_METHODS = [:method_name, :arguments, :attached_block]
5
+
6
+ attr_reader(*DELEGATABLE_METHODS)
7
+
8
+ class << self
9
+ alias [] new
10
+ end
11
+
12
+ def initialize method_name, *arguments, &attached_block
13
+ @method_name = method_name
14
+ @arguments = arguments
15
+ @attached_block = attached_block
16
+ end
17
+
18
+ def == other
19
+ @method_name == other.method_name &&
20
+ @arguments == other.arguments &&
21
+ @attached_block == other.attached_block
22
+ end
23
+
24
+ CLASS_NAME = self.name
25
+
26
+ def to_s
27
+ "#<#{CLASS_NAME}[#{(@method_name).inspect}, *#{@arguments.inspect}]>"
28
+ end
29
+
30
+ alias inspect to_s
31
+
32
+ PP_HEADER = "#<#{CLASS_NAME}["
33
+
34
+ def pretty_print pp
35
+ pp.group 2, PP_HEADER do
36
+ pp.pp @method_name
37
+ pp.text ','.freeze
38
+ pp.breakable
39
+ pp.text '*'.freeze
40
+ pp.pp @arguments
41
+ pp.text ']>'.freeze
42
+ end
43
+ end
44
+
45
+ PP_CYCLE = "#{PP_HEADER}...]>"
46
+
47
+ def pretty_print_cycle pp
48
+ pp.text PP_CYCLE
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,61 @@
1
+ require 'crispy/crispy_received_message'
2
+
3
+ module Crispy
4
+ class CrispyReceivedMessageWithReceiver
5
+ attr_reader :receiver, :received_message
6
+
7
+ class << self
8
+ alias [] new
9
+ end
10
+
11
+ CrispyReceivedMessage::DELEGATABLE_METHODS.each do|method_name|
12
+ binding.eval(<<-END, __FILE__, (__LINE__ + 1))
13
+ def #{method_name}
14
+ @received_message.#{method_name}
15
+ end
16
+ END
17
+ end
18
+
19
+ def initialize receiver, method_name, *arguments, &attached_block
20
+ @received_message = CrispyReceivedMessage.new(method_name, *arguments, &attached_block)
21
+ @receiver = receiver
22
+ end
23
+
24
+ def == other
25
+ @receiver == other.receiver && @received_message == other.received_message
26
+ end
27
+
28
+ CLASS_NAME = self.name
29
+
30
+ def to_s
31
+ "#<#{CLASS_NAME}[#{@receiver.inspect}, #{(@received_message.method_name).inspect}, *#{@received_message.arguments.inspect}]>"
32
+ end
33
+
34
+ alias inspect to_s
35
+
36
+ PP_HEADER = "#<#{CLASS_NAME}["
37
+
38
+ def pretty_print pp
39
+ pp.group 2, PP_HEADER do
40
+ pp.pp @receiver
41
+ pp.text ','.freeze
42
+ pp.breakable
43
+
44
+ pp.pp @received_message.method_name
45
+ pp.text ','.freeze
46
+ pp.breakable
47
+
48
+ pp.text '*'.freeze
49
+ pp.pp @received_message.arguments
50
+ pp.text ']>'.freeze
51
+ end
52
+ end
53
+
54
+ PP_CYCLE = "#{PP_HEADER}...]>"
55
+
56
+ def pretty_print_cycle pp
57
+ pp.text PP_CYCLE
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,13 @@
1
+ require 'crispy/crispy_internal/const_changer'
2
+
3
+ module Crispy
4
+ module CrispyWorld
5
+ class << self
6
+
7
+ def reset
8
+ ::Crispy::CrispyInternal::ConstChanger.recover_all
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -1,3 +1,3 @@
1
1
  module Crispy
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/crispy.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  require "crispy/version"
2
2
  require "crispy/crispy_internal/spy"
3
+ require "crispy/crispy_internal/class_spy"
3
4
  require "crispy/crispy_internal/double"
5
+ require "crispy/crispy_world"
4
6
 
5
7
  module Crispy
6
8
  # All methods of this module should be module_function.
@@ -16,8 +18,7 @@ module Crispy
16
18
  end
17
19
 
18
20
  # Make and returns a Crispy::ClassSpy's instance to spy all instances of a class.
19
- def spy_on_any_instance_of klass
20
- raise NotImplementedError, "Sorry, this feature is under construction :("
21
+ def spy_into_instances klass#, stubs_map = {}
21
22
  ::Crispy::CrispyInternal::ClassSpy.new klass
22
23
  end
23
24
 
@@ -25,17 +26,13 @@ module Crispy
25
26
  object.__CRISPY_SPY__
26
27
  end
27
28
 
28
- # Begins to log all instances and its received messages of a class.
29
- # _NOTE_: replace the constant containing the class
30
- def spy_into_class! klass
31
- raise NotImplementedError, "Sorry, this feature is under construction :("
32
- spy_class = spy_on_any_instance_of klass
33
- stub_const! klass.name, spy_class
34
- spy_class
29
+ def spy_of_instances klass
30
+ ::Crispy::CrispyInternal::ClassSpy.of_class(klass)
35
31
  end
36
32
 
37
- def stub_const! const_name, value
38
- raise NotImplementedError, "Sorry, this feature is under construction :("
33
+ def stub_const full_const_name, value
34
+ saved_value = ::Crispy::CrispyInternal::ConstChanger.change_by_full_name full_const_name, value
35
+ ::Crispy::CrispyInternal::ConstChanger.save full_const_name, saved_value
39
36
  end
40
37
 
41
38
  end
@@ -1,4 +1,5 @@
1
1
  class YourCoolClass
2
+ YOUR_COOL_CONST = 'value before stubbed'.freeze
2
3
  def your_cool_method *args
3
4
  end
4
5
  def your_method_without_argument
@@ -7,4 +8,11 @@ class YourCoolClass
7
8
  end
8
9
  def your_finalizer *args
9
10
  end
11
+
12
+ class Again < self
13
+ def your_another_method *args
14
+ end
15
+ def some_method_for_testing
16
+ end
17
+ end
10
18
  end
data/test/test_crispy.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  $VERBOSE = true # enable warnings
2
2
 
3
3
  require 'crispy'
4
+ require_relative 'test_helper'
4
5
  require 'minitest/autorun'
5
6
 
6
7
  class TestCrispy < MiniTest::Test
@@ -8,6 +9,9 @@ class TestCrispy < MiniTest::Test
8
9
 
9
10
  # Inherit BasicObject because it has fewer meta-programming methods than Object
10
11
  class ObjectClass < BasicObject
12
+
13
+ CONSTANT_TO_STUB = ::Crispy.double('value_before_stubbed')
14
+
11
15
  def hoge a, b, c
12
16
  private_foo a
13
17
  [a, b, c]
@@ -18,6 +22,8 @@ class TestCrispy < MiniTest::Test
18
22
  def bar
19
23
  []
20
24
  end
25
+ def baz
26
+ end
21
27
  def method_to_stub1
22
28
  fail "Not stubbed actually! The test fails."
23
29
  end
@@ -32,6 +38,25 @@ class TestCrispy < MiniTest::Test
32
38
 
33
39
  end
34
40
 
41
+ class TestCrispyStubConst < TestCrispy
42
+
43
+ def setup
44
+ @saved_value = ::TestCrispy::ObjectClass::CONSTANT_TO_STUB
45
+ @stubbbed_value = double('value_after_stubbed')
46
+ stub_const '::TestCrispy::ObjectClass::CONSTANT_TO_STUB', @stubbbed_value
47
+ end
48
+
49
+ def test_stubbed_const_value_changes_into_2nd_argument_value
50
+ assert_same @stubbbed_value, ::TestCrispy::ObjectClass::CONSTANT_TO_STUB
51
+ end
52
+
53
+ def test_stubbed_const_value_changes_back_after_resetting
54
+ CrispyWorld.reset
55
+ assert_same @saved_value, ::TestCrispy::ObjectClass::CONSTANT_TO_STUB
56
+ end
57
+
58
+ end
59
+
35
60
  class TestCrispySpyInto < TestCrispy
36
61
 
37
62
  def setup
@@ -51,11 +76,11 @@ class TestCrispy < MiniTest::Test
51
76
  def test_spy_logs_messages_sent_to_an_object
52
77
  assert_equal(
53
78
  [
54
- Crispy::ReceivedMessage[:hoge, 1, 2, 3],
55
- Crispy::ReceivedMessage[:private_foo, 1],
56
- Crispy::ReceivedMessage[:foo],
57
- Crispy::ReceivedMessage[:hoge, 3, 4, 5],
58
- Crispy::ReceivedMessage[:private_foo, 3],
79
+ CrispyReceivedMessage[:hoge, 1, 2, 3],
80
+ CrispyReceivedMessage[:private_foo, 1],
81
+ CrispyReceivedMessage[:foo],
82
+ CrispyReceivedMessage[:hoge, 3, 4, 5],
83
+ CrispyReceivedMessage[:private_foo, 3],
59
84
  ],
60
85
  @subject.received_messages
61
86
  )
@@ -113,6 +138,311 @@ class TestCrispy < MiniTest::Test
113
138
  assert_same @subject, @returned_spy
114
139
  end
115
140
 
141
+ def test_spy_raises_error_given_non_symbol_as_method_name
142
+ assert_raises(::TypeError){ @subject.received_once?(nil) }
143
+ assert_raises(::TypeError){ @subject.received_once?(nil) }
144
+ assert_raises(::TypeError){ @subject.count_received(nil) }
145
+ end
146
+
147
+ end
148
+
149
+ class TestCrispySpyIntoInstances < TestCrispy
150
+
151
+ def object_class
152
+ raise NotImplementedError
153
+ end
154
+
155
+ def setup
156
+ @returned_spy = spy_into_instances(
157
+ object_class#, method_to_stub1: :stubbed_instance_method1, method_to_stub2: :stubbed_instance_method2
158
+ )
159
+
160
+ @subject = spy_of_instances(object_class)
161
+ @object_instances = Array.new(3){ object_class.new }
162
+
163
+ @object_instances[0].hoge 3, 4, 5
164
+ @object_instances[1].hoge 1, 2, 3
165
+ @object_instances[0].foo
166
+ @object_instances[2].hoge 3, 4, 5
167
+ @object_instances[1].bar
168
+ @object_instances[2].hoge 7, 8, 9
169
+ @object_instances[1].bar
170
+ end
171
+
172
+ def teardown
173
+ CrispyWorld.reset
174
+ end
175
+
176
+ class TestReceivedMessage < self
177
+
178
+ def object_class
179
+ ObjectClass
180
+ end
181
+
182
+ def test_spy_logs_messages_sent_to_instances_of_a_class
183
+ assert_equal(
184
+ [
185
+ CrispyReceivedMessage[:initialize],
186
+ CrispyReceivedMessage[:initialize],
187
+ CrispyReceivedMessage[:initialize],
188
+ CrispyReceivedMessage[:hoge, 3, 4, 5],
189
+ CrispyReceivedMessage[:private_foo, 3],
190
+ CrispyReceivedMessage[:hoge, 1, 2, 3],
191
+ CrispyReceivedMessage[:private_foo, 1],
192
+ CrispyReceivedMessage[:foo],
193
+ CrispyReceivedMessage[:hoge, 3, 4, 5],
194
+ CrispyReceivedMessage[:private_foo, 3],
195
+ CrispyReceivedMessage[:bar],
196
+ CrispyReceivedMessage[:hoge, 7, 8, 9],
197
+ CrispyReceivedMessage[:private_foo, 7],
198
+ CrispyReceivedMessage[:bar],
199
+ ],
200
+ @subject.received_messages_with_receiver
201
+ )
202
+ end
203
+
204
+ def test_spy_has_received_messages_sent_to_an_object
205
+ assert @subject.received?(:hoge)
206
+ assert @subject.received?(:foo)
207
+ assert not(@subject.received?(:baz))
208
+ assert @subject.received?(:private_foo)
209
+ end
210
+
211
+ def test_spy_has_received_messages_with_arguments_sent_to_an_object
212
+ assert @subject.received?(:hoge, 1, 2, 3)
213
+ assert @subject.received?(:hoge, 3, 4, 5)
214
+ assert @subject.received?(:private_foo, 1)
215
+ assert @subject.received?(:private_foo, 3)
216
+ assert not(@subject.received?(:hoge, 0, 0, 0))
217
+ assert not(@subject.received?(:private_foo, 0, 0, 0))
218
+ assert not(@subject.received?(:foo, 1))
219
+ assert not(@subject.received?(:bar, nil))
220
+ assert not(@subject.received?(:baz, nil))
221
+ end
222
+
223
+ def test_spy_has_received_messages_once_sent_to_an_object
224
+ assert not(@subject.received_once?(:hoge))
225
+ assert not(@subject.received_once?(:private_foo))
226
+ assert not(@subject.received_once?(:hoge, 3, 4, 5))
227
+ assert not(@subject.received_once?(:private_foo, 3))
228
+ assert not(@subject.received_once?(:private_foo, 3, 4))
229
+ assert @subject.received_once?(:foo)
230
+ assert not(@subject.received_once?(:bar))
231
+ assert not(@subject.received_once?(:baz))
232
+ end
233
+
234
+ def test_spy_counts_received_messages_sent_to_an_object
235
+ assert_equal(1, @subject.count_received(:hoge, 1, 2, 3))
236
+ assert_equal(2, @subject.count_received(:hoge, 3, 4, 5))
237
+ assert_equal(0, @subject.count_received(:hoge, 0, 0, 0))
238
+ assert_equal(4, @subject.count_received(:hoge))
239
+
240
+ assert_equal(1, @subject.count_received(:private_foo, 1))
241
+ assert_equal(2, @subject.count_received(:private_foo, 3))
242
+ assert_equal(0, @subject.count_received(:private_foo, 0))
243
+ assert_equal(4, @subject.count_received(:private_foo))
244
+
245
+ assert_equal(1, @subject.count_received(:foo))
246
+ assert_equal(2, @subject.count_received(:bar))
247
+ end
248
+
249
+ def test_spy_raises_error_given_non_symbol_as_method_name
250
+ assert_raises(::TypeError){ @subject.received_once?(nil) }
251
+ assert_raises(::TypeError){ @subject.received_once?(nil) }
252
+ assert_raises(::TypeError){ @subject.count_received(nil) }
253
+ end
254
+
255
+ end
256
+
257
+ class TestReceivedMessageWithReceiver < self
258
+
259
+ def object_class
260
+ ObjectClassNonBasic
261
+ end
262
+
263
+ class ObjectClassNonBasic
264
+
265
+ def hoge a, b, c
266
+ private_foo a
267
+ [a, b, c]
268
+ end
269
+ def foo
270
+ 123
271
+ end
272
+ def bar
273
+ []
274
+ end
275
+ def baz
276
+ end
277
+ def method_to_stub1
278
+ fail "Not stubbed actually! The test fails."
279
+ end
280
+ def method_to_stub2
281
+ fail "Not stubbed actually! The test fails."
282
+ end
283
+
284
+ def private_foo a
285
+ :private_foo
286
+ end
287
+ private :private_foo
288
+
289
+ end
290
+
291
+ def test_spy_logs_messages_with_receiver_sent_to_instances_of_a_class
292
+ assert_equal(
293
+ [
294
+ CrispyReceivedMessageWithReceiver[@object_instances[0], :initialize],
295
+ CrispyReceivedMessageWithReceiver[@object_instances[1], :initialize],
296
+ CrispyReceivedMessageWithReceiver[@object_instances[2], :initialize],
297
+ CrispyReceivedMessageWithReceiver[@object_instances[0], :hoge, 3, 4, 5],
298
+ CrispyReceivedMessageWithReceiver[@object_instances[0], :private_foo, 3],
299
+ CrispyReceivedMessageWithReceiver[@object_instances[1], :hoge, 1, 2, 3],
300
+ CrispyReceivedMessageWithReceiver[@object_instances[1], :private_foo, 1],
301
+ CrispyReceivedMessageWithReceiver[@object_instances[0], :foo],
302
+ CrispyReceivedMessageWithReceiver[@object_instances[2], :hoge, 3, 4, 5],
303
+ CrispyReceivedMessageWithReceiver[@object_instances[2], :private_foo, 3],
304
+ CrispyReceivedMessageWithReceiver[@object_instances[1], :bar],
305
+ CrispyReceivedMessageWithReceiver[@object_instances[2], :hoge, 7, 8, 9],
306
+ CrispyReceivedMessageWithReceiver[@object_instances[2], :private_foo, 7],
307
+ CrispyReceivedMessageWithReceiver[@object_instances[1], :bar],
308
+ ],
309
+ @subject.received_messages_with_receiver
310
+ )
311
+ end
312
+
313
+ def test_spy_has_received_messages_with_receiver_sent_to_an_object
314
+ assert @subject.received_with_receiver?(@object_instances[0], :hoge)
315
+ assert @subject.received_with_receiver?(@object_instances[0], :foo)
316
+ assert not(@subject.received_with_receiver?(@object_instances[0], :baz))
317
+ assert not(@subject.received_with_receiver?(@object_instances[0], :bar))
318
+ assert @subject.received_with_receiver?(@object_instances[0], :private_foo)
319
+
320
+ assert @subject.received_with_receiver?(@object_instances[1], :hoge)
321
+ assert not(@subject.received_with_receiver?(@object_instances[1], :foo))
322
+ assert not(@subject.received_with_receiver?(@object_instances[1], :baz))
323
+ assert @subject.received_with_receiver?(@object_instances[1], :bar)
324
+ assert @subject.received_with_receiver?(@object_instances[1], :private_foo)
325
+
326
+ assert @subject.received_with_receiver?(@object_instances[2], :hoge)
327
+ assert not(@subject.received_with_receiver?(@object_instances[2], :foo))
328
+ assert not(@subject.received_with_receiver?(@object_instances[2], :baz))
329
+ assert not(@subject.received_with_receiver?(@object_instances[2], :bar))
330
+ assert @subject.received_with_receiver?(@object_instances[2], :private_foo)
331
+ end
332
+
333
+ def test_spy_has_received_messages_with_receiver_and_arguments_sent_to_an_object
334
+ assert @subject.received_with_receiver?(@object_instances[0], :hoge, 3, 4, 5)
335
+ assert @subject.received_with_receiver?(@object_instances[0], :private_foo, 3)
336
+ assert not(@subject.received_with_receiver?(@object_instances[0], :hoge, 1, 2, 3))
337
+ assert not(@subject.received_with_receiver?(@object_instances[0], :private_foo, 1))
338
+ assert not(@subject.received_with_receiver?(@object_instances[0], :foo, 1))
339
+ assert not(@subject.received_with_receiver?(@object_instances[0], :bar, nil))
340
+
341
+ assert @subject.received_with_receiver?(@object_instances[1], :hoge, 1, 2, 3)
342
+ assert @subject.received_with_receiver?(@object_instances[1], :private_foo, 1)
343
+ assert not(@subject.received_with_receiver?(@object_instances[1], :hoge, 0, 0, 0))
344
+ assert not(@subject.received_with_receiver?(@object_instances[1], :private_foo, 0, 0, 0))
345
+ assert not(@subject.received_with_receiver?(@object_instances[1], :hoge, 3, 4, 5))
346
+ assert not(@subject.received_with_receiver?(@object_instances[1], :private_foo, 3))
347
+ assert not(@subject.received_with_receiver?(@object_instances[1], :foo, 1))
348
+ assert not(@subject.received_with_receiver?(@object_instances[1], :baz, nil))
349
+
350
+ assert @subject.received_with_receiver?(@object_instances[2], :hoge, 7, 8, 9)
351
+ assert @subject.received_with_receiver?(@object_instances[2], :private_foo, 7)
352
+ assert @subject.received_with_receiver?(@object_instances[2], :hoge, 3, 4, 5)
353
+ assert @subject.received_with_receiver?(@object_instances[2], :private_foo, 3)
354
+ assert not(@subject.received_with_receiver?(@object_instances[2], :hoge, 1, 2, 3))
355
+ assert not(@subject.received_with_receiver?(@object_instances[2], :private_foo, 1))
356
+ assert not(@subject.received_with_receiver?(@object_instances[2], :hoge, 0, 0, 0))
357
+ assert not(@subject.received_with_receiver?(@object_instances[2], :private_foo, 0, 0, 0))
358
+ assert not(@subject.received_with_receiver?(@object_instances[2], :foo, 1))
359
+ assert not(@subject.received_with_receiver?(@object_instances[2], :bar, nil))
360
+ assert not(@subject.received_with_receiver?(@object_instances[2], :baz, nil))
361
+ end
362
+
363
+ def test_spy_has_received_messages_with_receiver_once_sent_to_an_object
364
+ assert @subject.received_once_with_receiver?(@object_instances[0], :hoge)
365
+ assert @subject.received_once_with_receiver?(@object_instances[0], :private_foo)
366
+ assert @subject.received_once_with_receiver?(@object_instances[0], :hoge, 3, 4, 5)
367
+ assert @subject.received_once_with_receiver?(@object_instances[0], :private_foo, 3)
368
+ assert not(@subject.received_once_with_receiver?(@object_instances[0], :hoge, 1, 2, 3))
369
+ assert not(@subject.received_once_with_receiver?(@object_instances[0], :private_foo, 1))
370
+ assert not(@subject.received_once_with_receiver?(@object_instances[0], :private_foo, 3, 4))
371
+ assert @subject.received_once_with_receiver?(@object_instances[0], :foo)
372
+ assert @subject.received_once_with_receiver?(@object_instances[0], :initialize)
373
+ assert not(@subject.received_once_with_receiver?(@object_instances[0], :bar))
374
+
375
+ assert @subject.received_once_with_receiver?(@object_instances[1], :hoge)
376
+ assert @subject.received_once_with_receiver?(@object_instances[1], :private_foo)
377
+ assert not(@subject.received_once_with_receiver?(@object_instances[1], :hoge, 3, 4, 5))
378
+ assert not(@subject.received_once_with_receiver?(@object_instances[1], :private_foo, 3))
379
+ assert @subject.received_once_with_receiver?(@object_instances[1], :hoge, 1, 2, 3)
380
+ assert @subject.received_once_with_receiver?(@object_instances[1], :private_foo, 1)
381
+ assert not(@subject.received_once_with_receiver?(@object_instances[1], :private_foo, 1, 2))
382
+ assert not(@subject.received_once_with_receiver?(@object_instances[1], :foo))
383
+ assert @subject.received_once_with_receiver?(@object_instances[1], :initialize)
384
+ assert not(@subject.received_once_with_receiver?(@object_instances[1], :bar))
385
+ assert not(@subject.received_once_with_receiver?(@object_instances[1], :baz))
386
+
387
+ assert not(@subject.received_once_with_receiver?(@object_instances[2], :hoge))
388
+ assert not(@subject.received_once_with_receiver?(@object_instances[2], :private_foo))
389
+ assert @subject.received_once_with_receiver?(@object_instances[2], :hoge, 7, 8, 9)
390
+ assert @subject.received_once_with_receiver?(@object_instances[2], :private_foo, 7)
391
+ assert not(@subject.received_once_with_receiver?(@object_instances[2], :hoge, 1, 2, 3))
392
+ assert not(@subject.received_once_with_receiver?(@object_instances[2], :private_foo, 1))
393
+ assert not(@subject.received_once_with_receiver?(@object_instances[2], :private_foo, 1, 2))
394
+ assert not(@subject.received_once_with_receiver?(@object_instances[2], :foo))
395
+ assert @subject.received_once_with_receiver?(@object_instances[2], :initialize)
396
+ assert not(@subject.received_once_with_receiver?(@object_instances[2], :baz))
397
+ end
398
+
399
+ def test_spy_counts_received_with_receiver_messages_with_receiver_sent_to_an_object
400
+ assert_equal(1, @subject.count_received_with_receiver(@object_instances[0], :initialize))
401
+ assert_equal(0, @subject.count_received_with_receiver(@object_instances[0], :initialize, 0))
402
+ assert_equal(1, @subject.count_received_with_receiver(@object_instances[0], :hoge))
403
+ assert_equal(1, @subject.count_received_with_receiver(@object_instances[0], :hoge, 3, 4, 5))
404
+ assert_equal(0, @subject.count_received_with_receiver(@object_instances[0], :hoge, 1, 2, 3))
405
+ assert_equal(1, @subject.count_received_with_receiver(@object_instances[0], :private_foo))
406
+ assert_equal(1, @subject.count_received_with_receiver(@object_instances[0], :private_foo, 3))
407
+ assert_equal(0, @subject.count_received_with_receiver(@object_instances[0], :private_foo, 1))
408
+ assert_equal(1, @subject.count_received_with_receiver(@object_instances[0], :foo))
409
+ assert_equal(0, @subject.count_received_with_receiver(@object_instances[0], :bar))
410
+
411
+ assert_equal(1, @subject.count_received_with_receiver(@object_instances[1], :initialize))
412
+ assert_equal(0, @subject.count_received_with_receiver(@object_instances[1], :initialize, 1))
413
+ assert_equal(1, @subject.count_received_with_receiver(@object_instances[1], :hoge))
414
+ assert_equal(1, @subject.count_received_with_receiver(@object_instances[1], :hoge, 1, 2, 3))
415
+ assert_equal(0, @subject.count_received_with_receiver(@object_instances[1], :hoge, 3, 4, 5))
416
+ assert_equal(1, @subject.count_received_with_receiver(@object_instances[1], :private_foo))
417
+ assert_equal(1, @subject.count_received_with_receiver(@object_instances[1], :private_foo, 1))
418
+ assert_equal(0, @subject.count_received_with_receiver(@object_instances[1], :private_foo, 3))
419
+ assert_equal(0, @subject.count_received_with_receiver(@object_instances[1], :foo))
420
+ assert_equal(2, @subject.count_received_with_receiver(@object_instances[1], :bar))
421
+ assert_equal(0, @subject.count_received_with_receiver(@object_instances[1], :bar, 9))
422
+
423
+ assert_equal(1, @subject.count_received_with_receiver(@object_instances[2], :initialize))
424
+ assert_equal(0, @subject.count_received_with_receiver(@object_instances[2], :initialize, 2))
425
+ assert_equal(2, @subject.count_received_with_receiver(@object_instances[2], :hoge))
426
+ assert_equal(1, @subject.count_received_with_receiver(@object_instances[2], :hoge, 3, 4, 5))
427
+ assert_equal(1, @subject.count_received_with_receiver(@object_instances[2], :hoge, 7, 8, 9))
428
+ assert_equal(0, @subject.count_received_with_receiver(@object_instances[2], :hoge, 1, 2, 3))
429
+ assert_equal(2, @subject.count_received_with_receiver(@object_instances[2], :private_foo))
430
+ assert_equal(1, @subject.count_received_with_receiver(@object_instances[2], :private_foo, 3))
431
+ assert_equal(1, @subject.count_received_with_receiver(@object_instances[2], :private_foo, 7))
432
+ assert_equal(0, @subject.count_received_with_receiver(@object_instances[2], :private_foo, 1))
433
+ assert_equal(0, @subject.count_received_with_receiver(@object_instances[2], :foo))
434
+ assert_equal(0, @subject.count_received_with_receiver(@object_instances[2], :bar))
435
+ assert_equal(0, @subject.count_received_with_receiver(@object_instances[2], :baz))
436
+ end
437
+
438
+ def test_spy_raises_error_given_non_symbol_as_method_name
439
+ assert_raises(::TypeError){ @subject.received_once?(@object_instances[0], nil) }
440
+ assert_raises(::TypeError){ @subject.received_once?(@object_instances[0], nil) }
441
+ assert_raises(::TypeError){ @subject.count_received(@object_instances[0], nil) }
442
+ end
443
+
444
+ end
445
+
116
446
  end
117
447
 
118
448
  class TestCrispyDouble < TestCrispy
@@ -0,0 +1,4 @@
1
+ if ENV['CODECLIMATE_REPO_TOKEN']
2
+ require 'codeclimate-test-reporter'
3
+ CodeClimate::TestReporter.start
4
+ 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.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yamamoto Yuji
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-24 00:00:00.000000000 Z
11
+ date: 2014-11-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: byebug
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rubydoctest
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -81,7 +95,7 @@ dependencies:
81
95
  - !ruby/object:Gem::Version
82
96
  version: '0'
83
97
  description: |-
84
- Test spy for any object in Ruby.
98
+ Test spy for any object.
85
99
  It makes mocks obsolete so you don't have to be worried about where to put the expectations (i.e. before or after the subject method).
86
100
  email:
87
101
  - whosekiteneverfly@gmail.com
@@ -98,15 +112,20 @@ files:
98
112
  - Rakefile
99
113
  - crispy.gemspec
100
114
  - lib/crispy.rb
101
- - lib/crispy/crispy/received_message.rb
115
+ - lib/crispy/crispy_internal/class_spy.rb
116
+ - lib/crispy/crispy_internal/const_changer.rb
102
117
  - lib/crispy/crispy_internal/double.rb
103
118
  - lib/crispy/crispy_internal/spy.rb
104
119
  - lib/crispy/crispy_internal/spy_mixin.rb
105
120
  - lib/crispy/crispy_internal/stubber.rb
106
121
  - lib/crispy/crispy_internal/with_stubber.rb
122
+ - lib/crispy/crispy_received_message.rb
123
+ - lib/crispy/crispy_received_message_with_receiver.rb
124
+ - lib/crispy/crispy_world.rb
107
125
  - lib/crispy/version.rb
108
126
  - test/doctest-fixtures/your_cool_class.rb
109
127
  - test/test_crispy.rb
128
+ - test/test_helper.rb
110
129
  homepage: https://github.com/igrep/crispy
111
130
  licenses:
112
131
  - MIT
@@ -130,7 +149,8 @@ rubyforge_project:
130
149
  rubygems_version: 2.2.2
131
150
  signing_key:
132
151
  specification_version: 4
133
- summary: Test spy for any object in Ruby.
152
+ summary: Test spy for any object.
134
153
  test_files:
135
154
  - test/doctest-fixtures/your_cool_class.rb
136
155
  - test/test_crispy.rb
156
+ - test/test_helper.rb
@@ -1,25 +0,0 @@
1
- module Crispy
2
- module Crispy
3
- class ReceivedMessage
4
-
5
- attr_reader :method_name, :arguments, :attached_block
6
-
7
- class << self
8
- alias [] new
9
- end
10
-
11
- def initialize method_name, *arguments, &attached_block
12
- @method_name = method_name
13
- @arguments = arguments
14
- @attached_block = attached_block
15
- end
16
-
17
- def == other
18
- @method_name == other.method_name &&
19
- @arguments == other.arguments &&
20
- @attached_block == other.attached_block
21
- end
22
-
23
- end
24
- end
25
- end