Dynamically created test methods lose original test's source_location
Closed this issue · 3 comments
alexpjohnson commented
This is causing problems downstream in ArturT/knapsack where we are expecting the source_location of the method to point to a test file, but with shoulda-context installed links to lib/shoudla/context/context.rb
line 399, where we are dynamically defining methods. I'm looking into a way to fix this, but just wanted to raise the issue to the community at large.
cristianbica commented
Seems that it's still happening for cases like
context "validations"
should validate_presence...
end
A dirty fix could be the below. But obviously something more reliable is needed.
diff --git a/lib/shoulda/context/context.rb b/lib/shoulda/context/context.rb
index cff6860..dcdd04e 100644
--- a/lib/shoulda/context/context.rb
+++ b/lib/shoulda/context/context.rb
@@ -341,15 +341,18 @@ module Shoulda
end
def should(name_or_matcher, options = {}, &blk)
+ source = nil
if name_or_matcher.respond_to?(:description) && name_or_matcher.respond_to?(:matches?)
name = name_or_matcher.description
+ source = caller.grep(/#{test_unit_class.name}/).first.split(":")[0, 2]
+ source[1] = source[1].to_i
blk = lambda { assert_accepts name_or_matcher, subject }
else
name = name_or_matcher
end
if blk
- self.shoulds << { :name => name, :before => options[:before], :block => blk }
+ self.shoulds << { :name => name, :before => options[:before], :block => blk, :source => source }
else
self.should_eventuallys << { :name => name }
end
@@ -357,8 +360,10 @@ module Shoulda
def should_not(matcher)
name = matcher.description
+ source = caller.grep(/#{test_unit_class.name}/).first.split(":")[0, 2]
+ source[1] = source[1].to_i
blk = lambda { assert_rejects matcher, subject }
- self.shoulds << { :name => "not #{name}", :block => blk }
+ self.shoulds << { :name => "not #{name}", :block => blk, :source => source }
end
def should_eventually(name, &blk)
@@ -396,7 +401,7 @@ module Shoulda
end
test_methods[test_unit_class][test_name.to_s] = true
- file, line_no = should[:block].source_location
+ file, line_no = should[:source] || should[:block].source_location
context = self
test_unit_class.class_eval <<-end_eval, file, line_no
define_method test_name do
mcmire commented
Hi @cristianbica, can you make a new issue for this and provide a reproducible case? I'm having trouble understanding why this fix is needed.