rspec-fire 0.4.0 → 0.5.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.
data/HISTORY CHANGED
@@ -20,3 +20,7 @@
20
20
  * Allow `mock.stub(:foo => 17)` syntax.
21
21
  * Don't count block params when determining max arity.
22
22
  * Restore original const value when a const is stubbed more than once.
23
+
24
+ 0.5.0 - 4 July 2012
25
+ * Performance improvements, overhead is now roughly 10% down from 100%
26
+ * Allow both instance and class doubles for unloaded classes.
data/README.md CHANGED
@@ -101,7 +101,18 @@ Create a new file `unit_helper.rb` that _does not_ require `spec_helper.rb`.
101
101
  Require this file where needed for isolated tests. To run an isolated spec in
102
102
  the context of your app:
103
103
 
104
- rspec -rspec/spec_helper.rb spec/unit/my_spec.rb
104
+ rspec -r./spec/spec_helper.rb spec/unit/my_spec.rb
105
+
106
+ ### Using with ActiveRecord
107
+
108
+ ActiveRecord methods defined implicitly from database columns are not detected.
109
+ A workaround is to explicitly define the methods you are mocking:
110
+
111
+ class User < ActiveRecord::Base
112
+ # Explicit column definitions for rspec-fire
113
+ def name; super; end
114
+ def email; super; end
115
+ end
105
116
 
106
117
  ### Doubling constants
107
118
 
data/lib/rspec/fire.rb CHANGED
@@ -135,41 +135,53 @@ module RSpec
135
135
  end
136
136
 
137
137
  def with_doubled_class
138
- if original_stubbed_const_value = ConstantStubber.original_value_for(@__doubled_class_name)
139
- yield original_stubbed_const_value
140
- elsif recursive_const_defined?(@__doubled_class_name)
138
+ ConstantStubber.find_original_value_for(@__doubled_class_name) do |value|
139
+ yield value if value
140
+ return
141
+ end
142
+
143
+ if recursive_const_defined?(@__doubled_class_name)
141
144
  yield recursive_const_get(@__doubled_class_name)
142
145
  end
143
146
  end
144
147
 
145
148
  protected
146
149
 
147
- def ensure_implemented(*method_names)
148
- with_doubled_class do |klass|
149
- klass.should implement(method_names, @__checked_methods)
150
- end
151
- end
150
+ # This cache gives a decent speed up when a class is doubled a lot.
151
+ def implemented_methods(doubled_class, checked_methods)
152
+ @@_implemented_methods_cache ||= {}
152
153
 
153
- define :implement do |expected_methods, checked_methods|
154
- unimplemented_methods = lambda {|doubled_class|
155
- implemented_methods = doubled_class.send(checked_methods)
156
- # to_sym for non-1.9 compat
157
- expected_methods - implemented_methods.map(&:to_sym)
158
- }
154
+ # to_sym for non-1.9 compat
155
+ @@_implemented_methods_cache[[doubled_class, checked_methods]] ||=
156
+ doubled_class.send(checked_methods).map(&:to_sym)
157
+ end
159
158
 
160
- match do |doubled_class|
161
- unimplemented_methods[ doubled_class ].empty?
162
- end
159
+ def unimplemented_methods(doubled_class, expected_methods, checked_methods)
160
+ expected_methods -
161
+ implemented_methods(doubled_class, checked_methods)
162
+ end
163
163
 
164
- failure_message_for_should do |doubled_class|
165
- implemented_methods =
166
- Object.public_methods - doubled_class.send(checked_methods)
167
- "%s does not implement:\n%s" % [
164
+ def ensure_implemented(*method_names)
165
+ with_doubled_class do |doubled_class|
166
+ methods = unimplemented_methods(
168
167
  doubled_class,
169
- unimplemented_methods[ doubled_class ].sort.map {|x|
170
- " #{x}"
171
- }.join("\n")
172
- ]
168
+ method_names,
169
+ @__checked_methods
170
+ )
171
+
172
+ if methods.any?
173
+ implemented_methods =
174
+ Object.public_methods -
175
+ implemented_methods(doubled_class, @__checked_methods)
176
+
177
+ msg = "%s does not implement:\n%s" % [
178
+ doubled_class,
179
+ methods.sort.map {|x|
180
+ " #{x}"
181
+ }.join("\n")
182
+ ]
183
+ raise RSpec::Expectations::ExpectationNotMetError, msg
184
+ end
173
185
  end
174
186
  end
175
187
  end
@@ -390,9 +402,10 @@ module RSpec
390
402
  @stubbers ||= []
391
403
  end
392
404
 
393
- def self.original_value_for(constant_name)
405
+ def self.find_original_value_for(constant_name)
394
406
  stubber = stubbers.find { |s| s.full_constant_name == constant_name }
395
- stubber.original_value if stubber
407
+ yield stubber.original_value if stubber
408
+ self
396
409
  end
397
410
  end
398
411
 
data/rspec-fire.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'rspec-fire'
3
- s.version = '0.4.0'
3
+ s.version = '0.5.0'
4
4
  s.summary = 'More resilient test doubles for RSpec.'
5
5
  s.platform = Gem::Platform::RUBY
6
6
  s.authors = ["Xavier Shay"]
@@ -270,6 +270,28 @@ describe '#fire_replaced_class_double (for a non-existant class)' do
270
270
  double.should_receive(:foo).with("a").and_return(:bar)
271
271
  A::B::C.foo("a").should eq(:bar)
272
272
  end
273
+
274
+ def use_doubles(class_double, instance_double)
275
+ instance_double.should_receive(:undefined_method).and_return(3)
276
+ class_double.should_receive(:undefined_method).and_return(4)
277
+
278
+ instance_double.undefined_method.should eq(3)
279
+ class_double.undefined_method.should eq(4)
280
+ end
281
+
282
+ it 'can be used after a declared fire_double for the same class' do
283
+ instance_double = fire_double("A::B::C")
284
+ class_double = fire_replaced_class_double("A::B::C")
285
+
286
+ use_doubles class_double, instance_double
287
+ end
288
+
289
+ it 'can be used before a declared fire_double for the same class' do
290
+ class_double = fire_replaced_class_double("A::B::C")
291
+ instance_double = fire_double("A::B::C")
292
+
293
+ use_doubles class_double, instance_double
294
+ end
273
295
  end
274
296
 
275
297
  shared_examples_for "loaded constant stubbing" do |const_name|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-fire
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-01 00:00:00.000000000 Z
12
+ date: 2012-07-04 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
16
- requirement: &2160595040 !ruby/object:Gem::Requirement
16
+ requirement: &2159223000 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *2160595040
24
+ version_requirements: *2159223000
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &2160594520 !ruby/object:Gem::Requirement
27
+ requirement: &2159222320 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: '2.5'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2160594520
35
+ version_requirements: *2159222320
36
36
  description:
37
37
  email:
38
38
  - hello@xaviershay.com
@@ -68,7 +68,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
68
68
  version: '0'
69
69
  requirements: []
70
70
  rubyforge_project:
71
- rubygems_version: 1.8.6
71
+ rubygems_version: 1.8.10
72
72
  signing_key:
73
73
  specification_version: 3
74
74
  summary: More resilient test doubles for RSpec.