/*
* Copyright (C) 2008 The Guava Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.common.net;
import static com.google.common.escape.testing.EscaperAsserts.assertEscaping;
import static com.google.common.escape.testing.EscaperAsserts.assertUnescaped;
import static com.google.common.escape.testing.EscaperAsserts.assertUnicodeEscaping;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Preconditions;
import com.google.common.escape.UnicodeEscaper;
import junit.framework.TestCase;
/**
* Tests for {@link PercentEscaper}.
*
* @author David Beaumont
*/
@GwtCompatible
public class PercentEscaperTest extends TestCase {
/** Tests that the simple escaper treats 0-9, a-z and A-Z as safe */
public void testSimpleEscaper() {
UnicodeEscaper e = new PercentEscaper("", false);
for (char c = 0; c < 128; c++) {
if ((c >= '0' && c <= '9') ||
(c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z')) {
assertUnescaped(e, c);
} else {
assertEscaping(e, escapeAscii(c), c);
}
}
// Testing mutlibyte escape sequences
assertEscaping(e, "%00", '\u0000'); // nul
assertEscaping(e, "%7F", '\u007f'); // del
assertEscaping(e, "%C2%80", '\u0080'); // xx-00010,x-000000
assertEscaping(e, "%DF%BF", '\u07ff'); // xx-11111,x-111111
assertEscaping(e, "%E0%A0%80", '\u0800'); // xxx-0000,x-100000,x-00,0000
assertEscaping(e, "%EF%BF%BF", '\uffff'); // xxx-1111,x-111111,x-11,1111
assertUnicodeEscaping(e, "%F0%90%80%80", '\uD800', '\uDC00');
assertUnicodeEscaping(e, "%F4%8F%BF%BF", '\uDBFF', '\uDFFF');
// simple string tests
assertEquals("", e.escape(""));
assertEquals("safestring", e.escape("safestring"));
assertEquals("embedded%00null", e.escape("embedded\0null"));
assertEquals("max%EF%BF%BFchar", e.escape("max\uffffchar"));
}
/** Tests the various ways that the space character can be handled */
public void testPlusForSpace() {
UnicodeEscaper basicEscaper = new PercentEscaper("", false);
UnicodeEscaper plusForSpaceEscaper = new PercentEscaper("", true);
UnicodeEscaper spaceEscaper = new PercentEscaper(" ", false);
assertEquals("string%20with%20spaces",
basicEscaper.escape("string with spaces"));
assertEquals("string+with+spaces",
plusForSpaceEscaper.escape("string with spaces"));
assertEquals("string with spaces",
spaceEscaper.escape("string with spaces"));
}
/** Tests that if we add extra 'safe' characters they remain unescaped */
public void testCustomEscaper() {
UnicodeEscaper e = new PercentEscaper("+*/-", false);
for (char c = 0; c < 128; c++) {
if ((c >= '0' && c <= '9') ||
(c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
"+*/-".indexOf(c) >= 0) {
assertUnescaped(e, c);
} else {
assertEscaping(e, escapeAscii(c), c);
}
}
}
/** Tests that if specify '%' as safe the result is an idempotent escaper. */
public void testCustomEscaper_withpercent() {
UnicodeEscaper e = new PercentEscaper("%", false);
assertEquals("foo%7Cbar", e.escape("foo|bar"));
assertEquals("foo%7Cbar", e.escape("foo%7Cbar")); // idempotent
}
/**
* Test that giving a null 'safeChars' string causes a
* {@link NullPointerException}.
*/
public void testBadArguments_null() {
try {
new PercentEscaper(null, false);
fail("Expected null pointer exception for null parameter");
} catch (NullPointerException expected) {
// pass
}
}
/**
* Tests that specifying any alphanumeric characters as 'safe' causes an
* {@link IllegalArgumentException}.
*/
public void testBadArguments_badchars() {
String msg = "Alphanumeric characters are always 'safe' " +
"and should not be explicitly specified";
try {
new PercentEscaper("-+#abc.!", false);
fail(msg);
} catch (IllegalArgumentException expected) {
assertEquals(msg, expected.getMessage());
}
}
/**
* Tests that if space is a safe character you cannot also specify
* 'plusForSpace' (throws {@link IllegalArgumentException}).
*/
public void testBadArguments_plusforspace() {
try {
new PercentEscaper(" ", false);
} catch (IllegalArgumentException e) {
fail("Space can be a 'safe' character if plusForSpace is false");
}
String msg =
"plusForSpace cannot be specified when space is a 'safe' character";
try {
new PercentEscaper(" ", true);
fail(msg);
} catch (IllegalArgumentException expected) {
assertEquals(msg, expected.getMessage());
}
}
/** Helper to manually escape a 7-bit ascii character */
private String escapeAscii(char c) {
Preconditions.checkArgument(c < 128);
String hex = "0123456789ABCDEF";
return "%" + hex.charAt((c >> 4) & 0xf) + hex.charAt(c & 0xf);
}
}