Home | History | Annotate | Download | only in net
      1 /*
      2  * Copyright (C) 2008 The Guava Authors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.common.net;
     18 
     19 import static com.google.common.escape.testing.EscaperAsserts.assertEscaping;
     20 import static com.google.common.escape.testing.EscaperAsserts.assertUnescaped;
     21 import static com.google.common.escape.testing.EscaperAsserts.assertUnicodeEscaping;
     22 
     23 import com.google.common.annotations.GwtCompatible;
     24 import com.google.common.base.Preconditions;
     25 import com.google.common.escape.UnicodeEscaper;
     26 
     27 import junit.framework.TestCase;
     28 
     29 /**
     30  * Tests for {@link PercentEscaper}.
     31  *
     32  * @author David Beaumont
     33  */
     34 @GwtCompatible
     35 public class PercentEscaperTest extends TestCase {
     36 
     37   /** Tests that the simple escaper treats 0-9, a-z and A-Z as safe */
     38   public void testSimpleEscaper() {
     39     UnicodeEscaper e = new PercentEscaper("", false);
     40     for (char c = 0; c < 128; c++) {
     41       if ((c >= '0' && c <= '9') ||
     42           (c >= 'a' && c <= 'z') ||
     43           (c >= 'A' && c <= 'Z')) {
     44         assertUnescaped(e, c);
     45       } else {
     46         assertEscaping(e, escapeAscii(c), c);
     47       }
     48     }
     49 
     50     // Testing mutlibyte escape sequences
     51     assertEscaping(e, "%00", '\u0000');       // nul
     52     assertEscaping(e, "%7F", '\u007f');       // del
     53     assertEscaping(e, "%C2%80", '\u0080');    // xx-00010,x-000000
     54     assertEscaping(e, "%DF%BF", '\u07ff');    // xx-11111,x-111111
     55     assertEscaping(e, "%E0%A0%80", '\u0800'); // xxx-0000,x-100000,x-00,0000
     56     assertEscaping(e, "%EF%BF%BF", '\uffff'); // xxx-1111,x-111111,x-11,1111
     57     assertUnicodeEscaping(e, "%F0%90%80%80", '\uD800', '\uDC00');
     58     assertUnicodeEscaping(e, "%F4%8F%BF%BF", '\uDBFF', '\uDFFF');
     59 
     60     // simple string tests
     61     assertEquals("", e.escape(""));
     62     assertEquals("safestring", e.escape("safestring"));
     63     assertEquals("embedded%00null", e.escape("embedded\0null"));
     64     assertEquals("max%EF%BF%BFchar", e.escape("max\uffffchar"));
     65   }
     66 
     67   /** Tests the various ways that the space character can be handled */
     68   public void testPlusForSpace() {
     69     UnicodeEscaper basicEscaper = new PercentEscaper("", false);
     70     UnicodeEscaper plusForSpaceEscaper = new PercentEscaper("", true);
     71     UnicodeEscaper spaceEscaper = new PercentEscaper(" ", false);
     72 
     73     assertEquals("string%20with%20spaces",
     74         basicEscaper.escape("string with spaces"));
     75     assertEquals("string+with+spaces",
     76         plusForSpaceEscaper.escape("string with spaces"));
     77     assertEquals("string with spaces",
     78         spaceEscaper.escape("string with spaces"));
     79   }
     80 
     81   /** Tests that if we add extra 'safe' characters they remain unescaped */
     82   public void testCustomEscaper() {
     83     UnicodeEscaper e = new PercentEscaper("+*/-", false);
     84     for (char c = 0; c < 128; c++) {
     85       if ((c >= '0' && c <= '9') ||
     86           (c >= 'a' && c <= 'z') ||
     87           (c >= 'A' && c <= 'Z') ||
     88           "+*/-".indexOf(c) >= 0) {
     89         assertUnescaped(e, c);
     90       } else {
     91         assertEscaping(e, escapeAscii(c), c);
     92       }
     93     }
     94   }
     95 
     96   /** Tests that if specify '%' as safe the result is an idempotent escaper. */
     97   public void testCustomEscaper_withpercent() {
     98     UnicodeEscaper e = new PercentEscaper("%", false);
     99     assertEquals("foo%7Cbar", e.escape("foo|bar"));
    100     assertEquals("foo%7Cbar", e.escape("foo%7Cbar"));  // idempotent
    101   }
    102 
    103   /**
    104    * Test that giving a null 'safeChars' string causes a
    105    * {@link NullPointerException}.
    106    */
    107   public void testBadArguments_null() {
    108     try {
    109       new PercentEscaper(null, false);
    110       fail("Expected null pointer exception for null parameter");
    111     } catch (NullPointerException expected) {
    112       // pass
    113     }
    114   }
    115 
    116   /**
    117    * Tests that specifying any alphanumeric characters as 'safe' causes an
    118    * {@link IllegalArgumentException}.
    119    */
    120   public void testBadArguments_badchars() {
    121     String msg = "Alphanumeric characters are always 'safe' " +
    122         "and should not be explicitly specified";
    123     try {
    124       new PercentEscaper("-+#abc.!", false);
    125       fail(msg);
    126     } catch (IllegalArgumentException expected) {
    127       assertEquals(msg, expected.getMessage());
    128     }
    129   }
    130 
    131   /**
    132    * Tests that if space is a safe character you cannot also specify
    133    * 'plusForSpace' (throws {@link IllegalArgumentException}).
    134    */
    135   public void testBadArguments_plusforspace() {
    136     try {
    137       new PercentEscaper(" ", false);
    138     } catch (IllegalArgumentException e) {
    139       fail("Space can be a 'safe' character if plusForSpace is false");
    140     }
    141     String msg =
    142         "plusForSpace cannot be specified when space is a 'safe' character";
    143     try {
    144       new PercentEscaper(" ", true);
    145       fail(msg);
    146     } catch (IllegalArgumentException expected) {
    147       assertEquals(msg, expected.getMessage());
    148     }
    149   }
    150 
    151   /** Helper to manually escape a 7-bit ascii character */
    152   private String escapeAscii(char c) {
    153     Preconditions.checkArgument(c < 128);
    154     String hex = "0123456789ABCDEF";
    155     return "%" + hex.charAt((c >> 4) & 0xf) + hex.charAt(c & 0xf);
    156   }
    157 }
    158