Skip to content

Commit 946a801

Browse files
committed
Merge pull request #47 from kaspth/readable-regex-errors
Readable regex errors
2 parents 007e160 + b810e9b commit 946a801

File tree

4 files changed

+36
-17
lines changed

4 files changed

+36
-17
lines changed

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

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -166,13 +166,14 @@ def assert_select(*args, &block)
166166

167167
selector = HTMLSelector.new(args, @selected) { nodeset document_root_element }
168168

169-
if selecting_no_body?(selector)
169+
if selector.selecting_no_body?
170170
assert true
171171
return
172172
end
173173

174174
selector.select.tap do |matches|
175-
assert_size_match!(matches.size, selector.tests, selector.selector, selector.message)
175+
assert_size_match!(matches.size, selector.tests,
176+
selector.css_selector, selector.message)
176177

177178
nest_selection(matches, &block) if block_given? && !matches.empty?
178179
end
@@ -284,12 +285,6 @@ def assert_size_match!(size, equals, css_selector, message = nil)
284285
end
285286
end
286287

287-
def selecting_no_body?(html_selector)
288-
# Nokogiri gives the document a body element. Which means we can't
289-
# run an assertion expecting there to not be a body.
290-
html_selector.selector == 'body' && html_selector.tests[:count] == 0
291-
end
292-
293288
def nest_selection(selection)
294289
# Set @selected to allow nested assert_select.
295290
# Can be nested several levels deep.

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
require_relative 'substitution_context'
33

44
class HTMLSelector #:nodoc:
5-
attr_reader :selector, :tests, :message
5+
attr_reader :css_selector, :tests, :message
66

77
def initialize(values, previous_selection = nil, &root_fallback)
88
@values = values
99
@root = extract_root(previous_selection, root_fallback)
10-
@selector = extract_selector
10+
extract_selectors
1111
@tests = extract_equality_tests
1212
@message = @values.shift
1313

@@ -16,8 +16,14 @@ def initialize(values, previous_selection = nil, &root_fallback)
1616
end
1717
end
1818

19+
def selecting_no_body? #:nodoc:
20+
# Nokogiri gives the document a body element. Which means we can't
21+
# run an assertion expecting there to not be a body.
22+
@selector == 'body' && @tests[:count] == 0
23+
end
24+
1925
def select
20-
filter @root.css(selector, context)
26+
filter @root.css(@selector, context)
2127
end
2228

2329
private
@@ -67,15 +73,15 @@ def extract_root(previous_selection, root_fallback)
6773
end
6874
end
6975

70-
def extract_selector
76+
def extract_selectors
7177
selector = @values.shift
7278

7379
unless selector.is_a? String
7480
raise ArgumentError, "Expecting a selector as the first argument"
7581
end
7682

77-
context.substitute!(selector, @values)
78-
selector
83+
@css_selector = context.substitute!(selector, @values.dup, true)
84+
@selector = context.substitute!(selector, @values)
7985
end
8086

8187
def extract_equality_tests

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

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,26 @@ def initialize
33
@substitute = '?'
44
end
55

6-
def substitute!(selector, values)
6+
def substitute!(selector, values, format_for_presentation = false)
7+
selector = selector.dup
8+
79
while !values.empty? && substitutable?(values.first) && selector.index(@substitute)
8-
selector.sub! @substitute, matcher_for(values.shift)
10+
selector.sub! @substitute, matcher_for(values.shift, format_for_presentation)
911
end
12+
13+
selector
1014
end
1115

1216
def match(matches, attribute, matcher)
1317
matches.find_all { |node| node[attribute] =~ Regexp.new(matcher) }
1418
end
1519

1620
private
17-
def matcher_for(value)
21+
def matcher_for(value, format_for_presentation)
22+
if format_for_presentation && value.is_a?(Regexp)
23+
value = value.inspect # Inspect Regexps for readability in error messages.
24+
end
25+
1826
value.to_s.inspect # Nokogiri doesn't like arbitrary values without quotes, hence inspect.
1927
end
2028

test/selector_assertions_test.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,16 @@ def test_css_select_with_invalid_selector
232232
end
233233
end
234234

235+
def test_nested_assert_select_with_match_failure_shows_nice_regex
236+
render_html %Q{<div id="1">foo</div>}
237+
238+
error = assert_raises Minitest::Assertion do
239+
assert_select "div:match('id', ?)", /wups/
240+
end
241+
242+
assert_match %Q{div:match('id', "/wups/")}, error.message
243+
end
244+
235245
def test_feed_item_encoded
236246
render_xml <<-EOF
237247
<rss version="2.0">

0 commit comments

Comments
 (0)