Browse files

assert_select_rjs decodes escaped unicode chars since the Javascript …

…generators encode them. Closes #6240.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@5202 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
1 parent d767463 commit 643d17ce9e6937425a9e39e6ef6fae07efd15b8a @jeremy jeremy committed Sep 29, 2006
View
2 actionpack/CHANGELOG
@@ -1,5 +1,7 @@
*SVN*
+* assert_select_rjs decodes escaped unicode chars since the Javascript generators encode them. #6240 [japgolly]
+
* Deprecation: @request will be removed after 1.2. Use the request method instead. [Jeremy Kemper]
* Make the :status parameter expand to the default message for that status code if it is an integer. Also support symbol statuses. [Jamis Buck]. Examples:
View
40 actionpack/lib/action_controller/assertions/selector_assertions.rb
@@ -24,7 +24,7 @@ module Assertions
# * #assert_select_encoded -- Assertions on HTML encoded inside XML,
# for example for dealing with feed item descriptions.
# * #assert_select_email -- Assertions on the HTML body of an e-mail.
- #
+ #
# Also see HTML::Selector for learning how to use selectors.
module SelectorAssertions
# :call-seq:
@@ -79,12 +79,12 @@ def css_select(*args)
selector = HTML::Selector.new(arg, args)
when Array
selector = HTML::Selector.new(*arg)
- when HTML::Selector
+ when HTML::Selector
selector = arg
else raise ArgumentError, "Expecting a selector as the first argument"
end
- selector.select(root)
+ selector.select(root)
end
# :call-seq:
@@ -144,7 +144,7 @@ def css_select(*args)
# evaluated the block is called with an array of all matched elements.
#
# === Examples
- #
+ #
# # At least one form element
# assert_select "form"
#
@@ -200,7 +200,7 @@ def assert_select(*args, &block)
selector = HTML::Selector.new(arg, args)
when Array
selector = HTML::Selector.new(*arg)
- when HTML::Selector
+ when HTML::Selector
selector = arg
else raise ArgumentError, "Expecting a selector as the first argument"
end
@@ -242,7 +242,7 @@ def assert_select(*args, &block)
raise ArgumentError, "Not expecting that last argument, you either have too many arguments, or they're the wrong type"
end
- matches = selector.select(root)
+ matches = selector.select(root)
# Equality test.
equals.each do |type, value|
case type
@@ -405,14 +405,11 @@ def assert_select_rjs(*args, &block)
else
Regexp.new("#{statement}\\(\"#{id}\", #{RJS_PATTERN_HTML}\\)", Regexp::MULTILINE)
end
-
+
# Duplicate the body since the next step involves destroying it.
matches = nil
@response.body.gsub(pattern) do |match|
- html = $2
- # RJS encodes double quotes and line breaks.
- html.gsub!(/\\"/, "\"")
- html.gsub!(/\\n/, "\n")
+ html = unescape_rjs($2)
matches ||= []
matches.concat HTML::Document.new(html).root.children.select { |n| n.tag? }
""
@@ -449,7 +446,7 @@ def assert_select_rjs(*args, &block)
# === Example
#
# assert_select_feed :rss, 2.0 do
- # # Select description element of each feed item.
+ # # Select description element of each feed item.
# assert_select "channel>item>description" do
# # Run assertions on the encoded elements.
# assert_select_encoded do
@@ -536,6 +533,7 @@ def assert_select_email(&block)
RJS_PATTERN_HTML = /"((\\"|[^"])*)"/
RJS_PATTERN_EVERYTHING = Regexp.new("#{RJS_STATEMENTS[:any]}\\(\"([^\"]*)\", #{RJS_PATTERN_HTML}\\)",
Regexp::MULTILINE)
+ RJS_PATTERN_UNICODE_ESCAPED_CHAR = /\\u([0-9a-zA-Z]{4})/
end
# #assert_select and #css_select call this to obtain the content in the HTML
@@ -547,10 +545,7 @@ def response_from_page_or_rjs()
root = HTML::Node.new(nil)
while true
next if body.sub!(RJS_PATTERN_EVERYTHING) do |match|
- # RJS encodes double quotes and line breaks.
- html = $3
- html.gsub!(/\\"/, "\"")
- html.gsub!(/\\n/, "\n")
+ html = unescape_rjs($3)
matches = HTML::Document.new(html).root.children.select { |n| n.tag? }
root.children.concat matches
""
@@ -562,6 +557,17 @@ def response_from_page_or_rjs()
html_document.root
end
end
+
+ # Unescapes a RJS string.
+ def unescape_rjs(rjs_string)
+ # RJS encodes double quotes and line breaks.
+ unescaped= rjs_string.gsub('\"', '"')
+ unescaped.gsub!('\n', "\n")
+ # RJS encodes non-ascii characters.
+ unescaped.gsub!(RJS_PATTERN_UNICODE_ESCAPED_CHAR) {|u| [$1.hex].pack('U*')}
+ unescaped
+ end
+
end
end
-end
+end
View
12 actionpack/test/controller/assert_select_test.rb
@@ -288,6 +288,18 @@ def test_assert_select_rjs
assert_raises(AssertionFailedError) { assert_select_rjs }
end
+ def test_assert_select_rjs_with_unicode
+ # Test that non-ascii characters (which are converted into \uXXXX in RJS) are decoded correctly.
+ render_rjs do |page|
+ page.replace "test", "<div id=\"1\">\343\203\201\343\202\261\343\203\203\343\203\210</div>"
+ end
+ assert_select_rjs do
+ assert_select "#1", :text => "\343\203\201\343\202\261\343\203\203\343\203\210"
+ assert_select "#1", "\343\203\201\343\202\261\343\203\203\343\203\210"
+ assert_select "#1", Regexp.new("\343\203\201..\343\203\210",0,'U')
+ assert_raises(AssertionFailedError) { assert_select "#1", Regexp.new("\343\203\201.\343\203\210",0,'U') }
+ end
+ end
def test_assert_select_rjs_with_id
# Test that we can pick up all statements in the result.

0 comments on commit 643d17c

Please sign in to comment.