Skip to content
Browse files

Merge branch 'performance-improvements'

  • Loading branch information...
2 parents d691b0a + ea1c4e5 commit 30444bd146856cdead291d17c2c190ea5fdd3b5a @xaviershay committed Jul 4, 2012
Showing with 49 additions and 22 deletions.
  1. +18 −0 benchmark/verification.rb
  2. +31 −22 lib/rspec/fire.rb
View
18 benchmark/verification.rb
@@ -0,0 +1,18 @@
+require 'rspec/fire'
+
+class A
+ def method_1
+ end
+
+ def method_2; end
+end
+
+describe 'verification' do
+ include RSpec::Fire
+
+ it 'blah' do
+ 1000.times do
+ fire_double('A', method_1: 1, method_2: 2)
+ end
+ end
+end
View
53 lib/rspec/fire.rb
@@ -147,32 +147,41 @@ def with_doubled_class
protected
- def ensure_implemented(*method_names)
- with_doubled_class do |klass|
- klass.should implement(method_names, @__checked_methods)
- end
- end
+ # This cache gives a decent speed up when a class is doubled a lot.
+ def implemented_methods(doubled_class, checked_methods)
+ @@_implemented_methods_cache ||= {}
- define :implement do |expected_methods, checked_methods|
- unimplemented_methods = lambda {|doubled_class|
- implemented_methods = doubled_class.send(checked_methods)
- # to_sym for non-1.9 compat
- expected_methods - implemented_methods.map(&:to_sym)
- }
+ # to_sym for non-1.9 compat
+ @@_implemented_methods_cache[[doubled_class, checked_methods]] ||=
+ doubled_class.send(checked_methods).map(&:to_sym)
+ end
- match do |doubled_class|
- unimplemented_methods[ doubled_class ].empty?
- end
+ def unimplemented_methods(doubled_class, expected_methods, checked_methods)
+ expected_methods -
+ implemented_methods(doubled_class, checked_methods)
+ end
- failure_message_for_should do |doubled_class|
- implemented_methods =
- Object.public_methods - doubled_class.send(checked_methods)
- "%s does not implement:\n%s" % [
+ def ensure_implemented(*method_names)
+ with_doubled_class do |doubled_class|
+ methods = unimplemented_methods(
doubled_class,
- unimplemented_methods[ doubled_class ].sort.map {|x|
- " #{x}"
- }.join("\n")
- ]
+ method_names,
+ @__checked_methods
+ )
+
+ if methods.any?
+ implemented_methods =
+ Object.public_methods -
+ implemented_methods(doubled_class, @__checked_methods)
+
+ msg = "%s does not implement:\n%s" % [
+ doubled_class,
+ methods.sort.map {|x|
+ " #{x}"
+ }.join("\n")
+ ]
+ raise RSpec::Expectations::ExpectationNotMetError, msg
+ end
end
end
end

0 comments on commit 30444bd

Please sign in to comment.
Something went wrong with that request. Please try again.