Skip to content

Commit 117d284

Browse files
committed
Fix replacement for multiple substitutions
Since SubstitutionContext#substitute! uses while/#sub! to replace '?' in the selector, and the replacement text contains that character, e.g., "(?-mix:\\d+)", if the selector requires more than one replacement, the replaced text is matched by the next iteration. # given this assertion assert_select "input[name=?][value=?]", /item-\d+/, /\d+/ # first iteration "input[name=\"(?-mix:item-\\d+)\"][value=?]" # second iteration "input[name=\"(\"(?-mix:\\d+)\"-mix:item-\\d+)\"][value=?]" This commit uses #gsub to avoid replacing already substituted text. Fixes #75.
1 parent 8f5acdf commit 117d284

File tree

2 files changed

+9
-7
lines changed

2 files changed

+9
-7
lines changed

lib/rails/dom/testing/assertions/selector_assertions/substitution_context.rb

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,10 @@ def initialize
44
end
55

66
def substitute!(selector, values, format_for_presentation = false)
7-
selector = selector.dup
8-
9-
while !values.empty? && substitutable?(values.first) && selector.index(@substitute)
10-
selector.sub! @substitute, matcher_for(values.shift, format_for_presentation)
7+
selector.gsub @substitute do |match|
8+
next match[0] if values.empty? || !substitutable?(values.first)
9+
matcher_for(values.shift, format_for_presentation)
1110
end
12-
13-
selector
1411
end
1512

1613
def match(matches, attribute, matcher)
@@ -23,7 +20,7 @@ def matcher_for(value, format_for_presentation)
2320
if format_for_presentation
2421
value.inspect # Avoid to_s so Regexps aren't put in quotes.
2522
else
26-
value.to_s.inspect
23+
"\"#{value}\""
2724
end
2825
end
2926

test/selector_assertions_test.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,11 @@ def test_substitution_values
135135
end
136136
end
137137

138+
def test_multiple_substitution_values
139+
render_html '<input name="foo[12]" value="34">'
140+
assert_select ":match('name', ?):match('value', ?)", /\w+\[\d+\]/, /\d+/
141+
end
142+
138143
def test_substitution_values_with_values_other_than_string_or_regexp
139144
render_html %Q{<div id="id_string">symbol</div><div id="1">numeric</div>}
140145
assert_select "div:match('id', ?)", :id_string do |elements|

0 commit comments

Comments
 (0)