Summary
register_hooks uses String#include? when checking whether a named before/after hook applies to a given example, producing the same false-positive behaviour already described for skip patterns in #2.
Location
lib/yard_example_test/example.rb — register_hooks (class method)
test_hooks = hooks.select { |hook| hook[:test] && example_name.include?(hook[:test]) }
Motivation
example_name is a YARD path such as "MyClass#foo" or "MyClass#foo@Some title". Using include? means any hook whose :test value is a substring of the path is treated as a match:
YardExampleTest.before('#foo') { @flag = true }
This hook fires for every example whose name includes the string '#foo':
example_name |
Intended? |
MyClass#foo |
yes |
MyClass#foobar |
no |
AnotherClass#foo_x |
no |
MyClass#foo@title |
yes |
Current behaviour
Hooks registered for a specific test name silently run before/after unrelated examples any time the test string is a substring of another example name.
Proposed solution
Apply the same fix proposed for skips in #2 — use File.fnmatch with File::FNM_PATHNAME after normalising :: separators:
test_hooks = hooks.select do |hook|
next false unless hook[:test]
pattern = hook[:test].gsub('::', '/')
name = example_name.gsub('::', '/')
File.fnmatch(pattern, name, File::FNM_PATHNAME)
end
Or, as a minimal fix that unblocks the most common confusions, use == (exact match) or anchor with # / . boundaries.
Acceptance criteria
Related
Summary
register_hooksusesString#include?when checking whether a named before/after hook applies to a given example, producing the same false-positive behaviour already described for skip patterns in #2.Location
lib/yard_example_test/example.rb—register_hooks(class method)Motivation
example_nameis a YARD path such as"MyClass#foo"or"MyClass#foo@Some title". Usinginclude?means any hook whose:testvalue is a substring of the path is treated as a match:This hook fires for every example whose name includes the string
'#foo':example_nameMyClass#fooMyClass#foobarAnotherClass#foo_xMyClass#foo@titleCurrent behaviour
Hooks registered for a specific test name silently run before/after unrelated examples any time the test string is a substring of another example name.
Proposed solution
Apply the same fix proposed for skips in #2 — use
File.fnmatchwithFile::FNM_PATHNAMEafter normalising::separators:Or, as a minimal fix that unblocks the most common confusions, use
==(exact match) or anchor with#/.boundaries.Acceptance criteria
before('#foo') { ... }does not run beforeMyClass#foobarbefore('#foo') { ... }still runs beforeMyClass#fooandMyClass#foo@some titleafter('MyClass') { ... }does not run afterMyClass#methodRelated
include?with glob-based matching to eliminate false positives #2 — same class of bug in the skip-pattern checklib/yard_example_test/example.rb—register_hookslib/yard_example_test.rb—YardExampleTest.before/.after