escape_utils 0.2.4 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. data/.gitignore +2 -1
  2. data/.travis.yml +13 -0
  3. data/CHANGELOG.md +7 -0
  4. data/MIT-LICENSE +1 -1
  5. data/Rakefile +5 -18
  6. data/benchmark/html_escape.rb +9 -2
  7. data/benchmark/xml_escape.rb +29 -0
  8. data/escape_utils.gemspec +2 -3
  9. data/ext/escape_utils/buffer.c +181 -160
  10. data/ext/escape_utils/buffer.h +90 -68
  11. data/ext/escape_utils/escape_utils.c +77 -39
  12. data/ext/escape_utils/extconf.rb +1 -1
  13. data/ext/escape_utils/houdini.h +37 -8
  14. data/ext/escape_utils/houdini_href_e.c +115 -0
  15. data/ext/escape_utils/houdini_html_e.c +90 -0
  16. data/ext/escape_utils/houdini_html_u.c +122 -0
  17. data/ext/escape_utils/{houdini_js.c → houdini_js_e.c} +17 -75
  18. data/ext/escape_utils/houdini_js_u.c +60 -0
  19. data/ext/escape_utils/{uri_escape.h → houdini_uri_e.c} +68 -2
  20. data/ext/escape_utils/houdini_uri_u.c +65 -0
  21. data/ext/escape_utils/houdini_xml_e.c +136 -0
  22. data/lib/escape_utils/version.rb +1 -1
  23. data/lib/escape_utils/xml/builder.rb +8 -0
  24. data/test/helper.rb +14 -0
  25. data/test/html/escape_test.rb +61 -0
  26. data/test/html/unescape_test.rb +48 -0
  27. data/test/html_safety_test.rb +46 -0
  28. data/test/javascript/escape_test.rb +42 -0
  29. data/test/javascript/unescape_test.rb +46 -0
  30. data/test/query/escape_test.rb +50 -0
  31. data/test/query/unescape_test.rb +52 -0
  32. data/test/uri/escape_test.rb +50 -0
  33. data/test/uri/unescape_test.rb +55 -0
  34. data/test/url/escape_test.rb +58 -0
  35. data/test/url/unescape_test.rb +60 -0
  36. data/test/xml/escape_test.rb +67 -0
  37. metadata +136 -152
  38. data/.rspec +0 -2
  39. data/ext/escape_utils/houdini_html.c +0 -214
  40. data/ext/escape_utils/houdini_uri.c +0 -130
  41. data/spec/html/escape_spec.rb +0 -42
  42. data/spec/html/unescape_spec.rb +0 -37
  43. data/spec/html_safety_spec.rb +0 -48
  44. data/spec/javascript/escape_spec.rb +0 -34
  45. data/spec/javascript/unescape_spec.rb +0 -37
  46. data/spec/query/escape_spec.rb +0 -44
  47. data/spec/query/unescape_spec.rb +0 -46
  48. data/spec/rcov.opts +0 -3
  49. data/spec/spec_helper.rb +0 -5
  50. data/spec/uri/escape_spec.rb +0 -43
  51. data/spec/uri/unescape_spec.rb +0 -57
  52. data/spec/url/escape_spec.rb +0 -52
  53. data/spec/url/unescape_spec.rb +0 -57
@@ -0,0 +1,46 @@
1
+ require File.expand_path("../helper", __FILE__)
2
+
3
+ class Object
4
+ def html_safe?
5
+ false
6
+ end
7
+ end
8
+
9
+ class TestSafeBuffer < String
10
+ def html_safe?
11
+ true
12
+ end
13
+
14
+ def html_safe
15
+ self
16
+ end
17
+
18
+ def to_s
19
+ self
20
+ end
21
+ end
22
+
23
+ class String
24
+ def html_safe
25
+ TestSafeBuffer.new(self)
26
+ end
27
+ end
28
+
29
+ class HtmlEscapeTest < MiniTest::Unit::TestCase
30
+ include EscapeUtils::HtmlSafety
31
+
32
+ def test_marks_escaped_strings_safe
33
+ escaped = _escape_html("<strong>unsafe</strong>")
34
+ assert_equal "&lt;strong&gt;unsafe&lt;&#47;strong&gt;", escaped
35
+ assert escaped.html_safe?
36
+ end
37
+
38
+ def test_doesnt_escape_safe_strings
39
+ assert_equal "<p>safe string</p>", _escape_html("<p>safe string</p>".html_safe)
40
+ end
41
+
42
+ def test_
43
+ assert_equal "5", _escape_html(5)
44
+ assert_equal "hello", _escape_html(:hello)
45
+ end
46
+ end
@@ -0,0 +1,42 @@
1
+ require File.expand_path("../../helper", __FILE__)
2
+
3
+ class JavascriptEscapeTest < MiniTest::Unit::TestCase
4
+ def test_returns_empty_string_if_nil_passed
5
+ assert_equal "", EscapeUtils.escape_javascript(nil)
6
+ end
7
+
8
+ def test_quotes_and_newlines
9
+ assert_equal %(This \\"thing\\" is really\\n netos\\n\\n\\'), EscapeUtils.escape_javascript(%(This "thing" is really\n netos\r\n\n'))
10
+ end
11
+
12
+ def test_backslashes
13
+ assert_equal %(backslash\\\\test), EscapeUtils.escape_javascript(%(backslash\\test))
14
+ end
15
+
16
+ def test_closed_html_tags
17
+ assert_equal %(keep <open>, but dont <\\/close> tags), EscapeUtils.escape_javascript(%(keep <open>, but dont </close> tags))
18
+ end
19
+
20
+ if RUBY_VERSION =~ /^1.9/
21
+ def test_input_must_be_utf8_or_ascii
22
+ str = "dont </close> tags"
23
+
24
+ str.force_encoding 'ISO-8859-1'
25
+ assert_raises Encoding::CompatibilityError do
26
+ EscapeUtils.escape_javascript(str)
27
+ end
28
+
29
+ str.force_encoding 'UTF-8'
30
+ begin
31
+ EscapeUtils.escape_javascript(str)
32
+ rescue Encoding::CompatibilityError => e
33
+ assert_nil e, "#{e.class.name} raised, expected not to"
34
+ end
35
+ end
36
+
37
+ def test_return_value_is_tagged_as_utf8
38
+ str = "dont </close> tags"
39
+ assert_equal Encoding.find('UTF-8'), EscapeUtils.escape_javascript(str).encoding
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,46 @@
1
+ require File.expand_path("../../helper", __FILE__)
2
+
3
+ class JavascriptUnescapeTest < MiniTest::Unit::TestCase
4
+ def test_returns_empty_string_if_nil_passed
5
+ assert_equal "", EscapeUtils.unescape_javascript(nil)
6
+ end
7
+
8
+ def test_quotes_and_newlines
9
+ assert_equal %(This "thing" is really\n netos\n\n'), EscapeUtils.unescape_javascript(%(This \\"thing\\" is really\\n netos\\n\\n\\'))
10
+ end
11
+
12
+ def test_backslashes
13
+ assert_equal %(backslash\\test), EscapeUtils.unescape_javascript(%(backslash\\\\test))
14
+ end
15
+
16
+ def test_closed_html_tags
17
+ assert_equal %(dont </close> tags), EscapeUtils.unescape_javascript(%(dont <\\/close> tags))
18
+ end
19
+
20
+ def test_passes_through_standalone_backslash
21
+ assert_equal "\\", EscapeUtils.unescape_javascript("\\")
22
+ end
23
+
24
+ if RUBY_VERSION =~ /^1.9/
25
+ def test_input_must_be_utf8_or_ascii
26
+ escaped = EscapeUtils.escape_javascript("dont </close> tags")
27
+
28
+ escaped.force_encoding 'ISO-8859-1'
29
+ assert_raises Encoding::CompatibilityError do
30
+ EscapeUtils.unescape_javascript(escaped)
31
+ end
32
+
33
+ escaped.force_encoding 'UTF-8'
34
+ begin
35
+ EscapeUtils.unescape_javascript(escaped)
36
+ rescue Encoding::CompatibilityError => e
37
+ assert_nil e, "#{e.class.name} raised, expected not to"
38
+ end
39
+ end
40
+
41
+ def test_return_value_is_tagged_as_utf8
42
+ escaped = EscapeUtils.escape_javascript("dont </close> tags")
43
+ assert_equal Encoding.find('UTF-8'), EscapeUtils.unescape_javascript(escaped).encoding
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,50 @@
1
+ require File.expand_path("../../helper", __FILE__)
2
+
3
+ class QueryEscapeTest < MiniTest::Unit::TestCase
4
+ def test_basic_url
5
+ assert_equal "http%3A%2F%2Fwww.homerun.com%2F", EscapeUtils.escape_url("http://www.homerun.com/")
6
+ end
7
+
8
+ def test_url_containing_tags
9
+ assert_equal "fo%3Co%3Ebar", EscapeUtils.escape_url("fo<o>bar")
10
+ end
11
+
12
+ def test_url_containing_spaces
13
+ assert_equal "a+space", EscapeUtils.escape_url("a space")
14
+ assert_equal "a+++sp+ace+", EscapeUtils.escape_url("a sp ace ")
15
+ end
16
+
17
+ def test_url_of_mixed_characters
18
+ assert_equal "q1%212%22%27w%245%267%2Fz8%29%3F%5C", EscapeUtils.escape_url("q1!2\"'w$5&7/z8)?\\")
19
+ end
20
+
21
+ def test_url_with_multibyte_characters
22
+ matz_name = "\xE3\x81\xBE\xE3\x81\xA4\xE3\x82\x82\xE3\x81\xA8" # Matsumoto
23
+ assert_equal '%E3%81%BE%E3%81%A4%E3%82%82%E3%81%A8', EscapeUtils.escape_url(matz_name)
24
+ matz_name_sep = "\xE3\x81\xBE\xE3\x81\xA4 \xE3\x82\x82\xE3\x81\xA8" # Matsu moto
25
+ assert_equal '%E3%81%BE%E3%81%A4+%E3%82%82%E3%81%A8', EscapeUtils.escape_url(matz_name_sep)
26
+ end
27
+
28
+ if RUBY_VERSION =~ /^1.9/
29
+ def test_input_must_be_utf8_or_ascii
30
+ str = "a space"
31
+
32
+ str.force_encoding 'ISO-8859-1'
33
+ assert_raises Encoding::CompatibilityError do
34
+ EscapeUtils.escape_url(str)
35
+ end
36
+
37
+ str.force_encoding 'UTF-8'
38
+ begin
39
+ EscapeUtils.escape_url(str)
40
+ rescue Encoding::CompatibilityError => e
41
+ assert_nil e, "#{e.class.name} raised, expected not to"
42
+ end
43
+ end
44
+
45
+ def test_return_value_is_tagged_as_utf8
46
+ str = "a+space"
47
+ assert_equal Encoding.find('UTF-8'), EscapeUtils.escape_url(str).encoding
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,52 @@
1
+ require File.expand_path("../../helper", __FILE__)
2
+
3
+ class QueryUnescapeTest < MiniTest::Unit::TestCase
4
+ def test_basic_url
5
+ assert_equal "http://www.homerun.com/", EscapeUtils.unescape_url("http%3A%2F%2Fwww.homerun.com%2F")
6
+ end
7
+
8
+ def test_url_containing_tags
9
+ assert_equal "fo<o>bar", EscapeUtils.unescape_url("fo%3Co%3Ebar")
10
+ end
11
+
12
+ def test_url_containing_spaces
13
+ assert_equal "a space", EscapeUtils.unescape_url("a+space")
14
+ assert_equal "a sp ace ", EscapeUtils.unescape_url("a+++sp+ace+")
15
+ end
16
+
17
+ def test_url_containing_mixed_characters
18
+ assert_equal "q1!2\"'w$5&7/z8)?\\", EscapeUtils.unescape_url("q1%212%22%27w%245%267%2Fz8%29%3F%5C")
19
+ end
20
+
21
+ def test_url_containing_multibyte_characters
22
+ matz_name = "\xE3\x81\xBE\xE3\x81\xA4\xE3\x82\x82\xE3\x81\xA8" # Matsumoto
23
+ matz_name.force_encoding('UTF-8') if matz_name.respond_to?(:force_encoding)
24
+ assert_equal matz_name, EscapeUtils.unescape_url('%E3%81%BE%E3%81%A4%E3%82%82%E3%81%A8')
25
+ matz_name_sep = "\xE3\x81\xBE\xE3\x81\xA4 \xE3\x82\x82\xE3\x81\xA8" # Matsu moto
26
+ matz_name_sep.force_encoding('UTF-8') if matz_name_sep.respond_to?(:force_encoding)
27
+ assert_equal matz_name_sep, EscapeUtils.unescape_url('%E3%81%BE%E3%81%A4+%E3%82%82%E3%81%A8')
28
+ end
29
+
30
+ if RUBY_VERSION =~ /^1.9/
31
+ def test_input_must_be_valid_utf8_or_ascii
32
+ escaped = EscapeUtils.unescape_url("a+space")
33
+
34
+ escaped.force_encoding 'ISO-8859-1'
35
+ assert_raises Encoding::CompatibilityError do
36
+ EscapeUtils.unescape_url(escaped)
37
+ end
38
+
39
+ escaped.force_encoding 'UTF-8'
40
+ begin
41
+ EscapeUtils.unescape_url(escaped)
42
+ rescue Encoding::CompatibilityError => e
43
+ assert_nil e, "#{e.class.name} raised, expected not to"
44
+ end
45
+ end
46
+
47
+ def test_return_value_is_tagged_as_utf8
48
+ escaped = EscapeUtils.escape_url("a space")
49
+ assert_equal Encoding.find('UTF-8'), EscapeUtils.unescape_url(escaped).encoding
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,50 @@
1
+ require File.expand_path("../../helper", __FILE__)
2
+ require 'uri'
3
+
4
+ class UriEscapeTest < MiniTest::Unit::TestCase
5
+ def test_uri_stdlib_compatibility
6
+ (0..127).each do |i|
7
+ c = i.chr
8
+ assert_equal URI.escape(c), EscapeUtils.escape_uri(c)
9
+ end
10
+ end
11
+
12
+ def test_uri_containing_tags
13
+ assert_equal "fo%3Co%3Ebar", EscapeUtils.escape_uri("fo<o>bar")
14
+ end
15
+
16
+ def test_uri_containing_spaces
17
+ assert_equal "a%20space", EscapeUtils.escape_uri("a space")
18
+ assert_equal "a%20%20%20sp%20ace%20", EscapeUtils.escape_uri("a sp ace ")
19
+ end
20
+
21
+ def test_multibyte_characters
22
+ matz_name = "\xE3\x81\xBE\xE3\x81\xA4\xE3\x82\x82\xE3\x81\xA8" # Matsumoto
23
+ assert_equal '%E3%81%BE%E3%81%A4%E3%82%82%E3%81%A8', EscapeUtils.escape_uri(matz_name)
24
+ matz_name_sep = "\xE3\x81\xBE\xE3\x81\xA4 \xE3\x82\x82\xE3\x81\xA8" # Matsu moto
25
+ assert_equal '%E3%81%BE%E3%81%A4%20%E3%82%82%E3%81%A8', EscapeUtils.escape_uri(matz_name_sep)
26
+ end
27
+
28
+ if RUBY_VERSION =~ /^1.9/
29
+ def test_input_must_be_utf8_or_ascii
30
+ str = "fo<o>bar"
31
+
32
+ str.force_encoding 'ISO-8859-1'
33
+ assert_raises Encoding::CompatibilityError do
34
+ EscapeUtils.escape_uri(str)
35
+ end
36
+
37
+ str.force_encoding 'UTF-8'
38
+ begin
39
+ EscapeUtils.escape_uri(str)
40
+ rescue Encoding::CompatibilityError => e
41
+ assert_nil e, "#{e.class.name} raised, expected not to"
42
+ end
43
+ end
44
+
45
+ def test_return_value_is_tagged_as_utf8
46
+ str = "fo<o>bar"
47
+ assert_equal Encoding.find('UTF-8'), EscapeUtils.escape_uri(str).encoding
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,55 @@
1
+ require File.expand_path("../../helper", __FILE__)
2
+
3
+ class UriUnescapeTest < MiniTest::Unit::TestCase
4
+ def test_doesnt_unescape_an_incomplete_escape
5
+ assert_equal "%", EscapeUtils.unescape_uri("%")
6
+ assert_equal "http%", EscapeUtils.unescape_uri("http%")
7
+ end
8
+
9
+ def test_uri_containing_tags
10
+ assert_equal "fo<o>bar", EscapeUtils.unescape_uri("fo%3Co%3Ebar")
11
+ end
12
+
13
+ def test_uri_containing_spaces
14
+ assert_equal "a space", EscapeUtils.unescape_uri("a%20space")
15
+ assert_equal "a sp ace ", EscapeUtils.unescape_uri("a%20%20%20sp%20ace%20")
16
+ assert_equal "a+space", EscapeUtils.unescape_uri("a+space")
17
+ end
18
+
19
+ def test_uri_containing_mixed_characters
20
+ assert_equal "q1!2\"'w$5&7/z8)?\\", EscapeUtils.unescape_uri("q1%212%22%27w%245%267%2Fz8%29%3F%5C")
21
+ assert_equal "q1!2\"'w$5&7/z8)?\\", EscapeUtils.unescape_uri("q1!2%22'w$5&7/z8)?%5C")
22
+ end
23
+
24
+ def test_uri_containing_multibyte_charactes
25
+ matz_name = "\xE3\x81\xBE\xE3\x81\xA4\xE3\x82\x82\xE3\x81\xA8" # Matsumoto
26
+ matz_name.force_encoding('UTF-8') if matz_name.respond_to?(:force_encoding)
27
+ assert_equal matz_name, EscapeUtils.unescape_uri('%E3%81%BE%E3%81%A4%E3%82%82%E3%81%A8')
28
+ matz_name_sep = "\xE3\x81\xBE\xE3\x81\xA4 \xE3\x82\x82\xE3\x81\xA8" # Matsu moto
29
+ matz_name_sep.force_encoding('UTF-8') if matz_name_sep.respond_to?(:force_encoding)
30
+ assert_equal matz_name_sep, EscapeUtils.unescape_uri('%E3%81%BE%E3%81%A4%20%E3%82%82%E3%81%A8')
31
+ end
32
+
33
+ if RUBY_VERSION =~ /^1.9/
34
+ def test_input_must_be_valid_utf8_or_ascii
35
+ escaped = EscapeUtils.escape_uri("fo<o>bar")
36
+
37
+ escaped.force_encoding 'ISO-8859-1'
38
+ assert_raises Encoding::CompatibilityError do
39
+ EscapeUtils.unescape_url(escaped)
40
+ end
41
+
42
+ escaped.force_encoding 'UTF-8'
43
+ begin
44
+ EscapeUtils.unescape_url(escaped)
45
+ rescue Encoding::CompatibilityError => e
46
+ assert_nil e, "#{e.class.name} raised, expected not to"
47
+ end
48
+ end
49
+
50
+ def test_return_value_is_tagged_as_utf8
51
+ escaped = EscapeUtils.escape_uri("a space")
52
+ assert_equal Encoding.find('UTF-8'), EscapeUtils.unescape_url(escaped).encoding
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,58 @@
1
+ require File.expand_path("../../helper", __FILE__)
2
+ require 'cgi'
3
+
4
+ class UriEscapeTest < MiniTest::Unit::TestCase
5
+ def test_basic_url
6
+ assert_equal "http%3A%2F%2Fwww.homerun.com%2F", EscapeUtils.escape_url("http://www.homerun.com/")
7
+ end
8
+
9
+ def test_cgi_stdlib_compatibility
10
+ (0..127).each do |i|
11
+ c = i.chr
12
+ assert_equal CGI.escape(c), EscapeUtils.escape_url(c)
13
+ end
14
+ end
15
+
16
+ def test_url_containing_tags
17
+ assert_equal "fo%3Co%3Ebar", EscapeUtils.escape_url("fo<o>bar")
18
+ end
19
+
20
+ def test_url_containing_spaces
21
+ assert_equal "a+space", EscapeUtils.escape_url("a space")
22
+ assert_equal "a+++sp+ace+", EscapeUtils.escape_url("a sp ace ")
23
+ end
24
+
25
+ def test_url_containing_mixed_characters
26
+ assert_equal "q1%212%22%27w%245%267%2Fz8%29%3F%5C", EscapeUtils.escape_url("q1!2\"'w$5&7/z8)?\\")
27
+ end
28
+
29
+ def test_multibyte_characters
30
+ matz_name = "\xE3\x81\xBE\xE3\x81\xA4\xE3\x82\x82\xE3\x81\xA8" # Matsumoto
31
+ assert_equal '%E3%81%BE%E3%81%A4%E3%82%82%E3%81%A8', EscapeUtils.escape_url(matz_name)
32
+ matz_name_sep = "\xE3\x81\xBE\xE3\x81\xA4 \xE3\x82\x82\xE3\x81\xA8" # Matsu moto
33
+ assert_equal '%E3%81%BE%E3%81%A4+%E3%82%82%E3%81%A8', EscapeUtils.escape_url(matz_name_sep)
34
+ end
35
+
36
+ if RUBY_VERSION =~ /^1.9/
37
+ def test_input_must_be_utf8_or_ascii
38
+ str = "fo<o>bar"
39
+
40
+ str.force_encoding 'ISO-8859-1'
41
+ assert_raises Encoding::CompatibilityError do
42
+ EscapeUtils.escape_url(str)
43
+ end
44
+
45
+ str.force_encoding 'UTF-8'
46
+ begin
47
+ EscapeUtils.escape_url(str)
48
+ rescue Encoding::CompatibilityError => e
49
+ assert_nil e, "#{e.class.name} raised, expected not to"
50
+ end
51
+ end
52
+
53
+ def test_return_value_is_tagged_as_utf8
54
+ str = "fo<o>bar"
55
+ assert_equal Encoding.find('UTF-8'), EscapeUtils.escape_url(str).encoding
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,60 @@
1
+ require File.expand_path("../../helper", __FILE__)
2
+
3
+ class UriUnescapeTest < MiniTest::Unit::TestCase
4
+ def test_basic_url
5
+ assert_equal "http://www.homerun.com/", EscapeUtils.unescape_url("http%3A%2F%2Fwww.homerun.com%2F")
6
+ assert_equal "http://www.homerun.com/", EscapeUtils.unescape_url("http://www.homerun.com/")
7
+ end
8
+
9
+ def test_doesnt_unescape_an_incomplete_escape
10
+ assert_equal "%", EscapeUtils.unescape_url("%")
11
+ assert_equal "http%", EscapeUtils.unescape_url("http%")
12
+ end
13
+
14
+ def test_url_containing_tags
15
+ assert_equal "fo<o>bar", EscapeUtils.unescape_url("fo%3Co%3Ebar")
16
+ end
17
+
18
+ def test_url_containing_spaces
19
+ assert_equal "a space", EscapeUtils.unescape_url("a%20space")
20
+ assert_equal "a sp ace ", EscapeUtils.unescape_url("a%20%20%20sp%20ace%20")
21
+ assert_equal "a space", EscapeUtils.unescape_url("a+space")
22
+ end
23
+
24
+ def test_url_containing_mixed_characters
25
+ assert_equal "q1!2\"'w$5&7/z8)?\\", EscapeUtils.unescape_url("q1%212%22%27w%245%267%2Fz8%29%3F%5C")
26
+ assert_equal "q1!2\"'w$5&7/z8)?\\", EscapeUtils.unescape_url("q1!2%22'w$5&7/z8)?%5C")
27
+ end
28
+
29
+ def test_multibyte_characters
30
+ matz_name = "\xE3\x81\xBE\xE3\x81\xA4\xE3\x82\x82\xE3\x81\xA8" # Matsumoto
31
+ matz_name.force_encoding('UTF-8') if matz_name.respond_to?(:force_encoding)
32
+ assert_equal matz_name, EscapeUtils.unescape_url('%E3%81%BE%E3%81%A4%E3%82%82%E3%81%A8')
33
+ matz_name_sep = "\xE3\x81\xBE\xE3\x81\xA4 \xE3\x82\x82\xE3\x81\xA8" # Matsu moto
34
+ matz_name_sep.force_encoding('UTF-8') if matz_name_sep.respond_to?(:force_encoding)
35
+ assert_equal matz_name_sep, EscapeUtils.unescape_url('%E3%81%BE%E3%81%A4%20%E3%82%82%E3%81%A8')
36
+ end
37
+
38
+ if RUBY_VERSION =~ /^1.9/
39
+ def test_input_must_be_valid_utf8_or_ascii
40
+ escaped = EscapeUtils.escape_uri("fo<o>bar")
41
+
42
+ escaped.force_encoding 'ISO-8859-1'
43
+ assert_raises Encoding::CompatibilityError do
44
+ EscapeUtils.unescape_url(escaped)
45
+ end
46
+
47
+ escaped.force_encoding 'UTF-8'
48
+ begin
49
+ EscapeUtils.unescape_url(escaped)
50
+ rescue Encoding::CompatibilityError => e
51
+ assert_nil e, "#{e.class.name} raised, expected not to"
52
+ end
53
+ end
54
+
55
+ def test_return_value_is_tagged_as_utf8
56
+ escaped = EscapeUtils.escape_uri("fo<o>bar")
57
+ assert_equal Encoding.find('UTF-8'), EscapeUtils.unescape_url(escaped).encoding
58
+ end
59
+ end
60
+ end