rspec-fire 0.4.0 → 0.5.0

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