EMMA Coverage Report (generated Mon Nov 01 16:48:29 PDT 2010)
[all classes][com.google.caja.parser.js]

COVERAGE SUMMARY FOR SOURCE FILE [StringLiteralTest.java]

nameclass, %method, %block, %line, %
StringLiteralTest.java100% (1/1)100% (10/10)96%  (531/556)98%  (133.8/136)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class StringLiteralTest100% (1/1)100% (10/10)96%  (531/556)98%  (133.8/136)
StringLiteralTest (): void 100% (1/1)100% (3/3)100% (1/1)
escapeSequence (char, int, int): String 100% (1/1)100% (24/24)100% (5/5)
makeRandomQuotedString (Random): String 100% (1/1)100% (162/162)100% (42/42)
makeRandomString (Random): String 100% (1/1)100% (26/26)100% (5/5)
randomChar (Random): char 100% (1/1)100% (18/18)100% (4/4)
randomCodePoint (Random): int 100% (1/1)100% (28/28)100% (10/10)
testQuoteValue (): void 100% (1/1)100% (49/49)100% (13/13)
testQuotingAndUnquotingAreComplements (): void 100% (1/1)100% (20/20)100% (6/6)
testRandomStringsParseable (): void 100% (1/1)78%  (88/113)89%  (18.8/21)
testUnquotedValue (): void 100% (1/1)100% (113/113)100% (29/29)

1// Copyright (C) 2005 Google Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14 
15package com.google.caja.parser.js;
16 
17import com.google.caja.util.CajaTestCase;
18 
19import java.util.Random;
20 
21/**
22 *
23 * @author mikesamuel@gmail.com
24 */
25public class StringLiteralTest extends CajaTestCase {
26  public final void testUnquotedValue() {
27    assertEquals("", StringLiteral.getUnquotedValueOf(""));
28    assertEquals("foo", StringLiteral.getUnquotedValueOf("foo"));
29    assertEquals("foo\\bar", StringLiteral.getUnquotedValueOf("foo\\bar"));
30    assertEquals("", StringLiteral.getUnquotedValueOf("''"));
31    assertEquals("\"\"", StringLiteral.getUnquotedValueOf("'\"\"'"));
32    assertEquals("\"\"", StringLiteral.getUnquotedValueOf("'\\\"\\\"'"));
33    assertEquals("foo\bar", StringLiteral.getUnquotedValueOf("'foo\\bar'"));
34    assertEquals("foo\nbar", StringLiteral.getUnquotedValueOf("'foo\\nbar'"));
35    assertEquals("foo\\bar\\baz",
36        StringLiteral.getUnquotedValueOf("'foo\\\\bar\\\\baz'"));
37    assertEquals(
38        "foo bar", StringLiteral.getUnquotedValueOf("'foo\\u0020bar'"));
39    assertEquals("foo bar", StringLiteral.getUnquotedValueOf("'foo\\040bar'"));
40    assertEquals("foo bar", StringLiteral.getUnquotedValueOf("'foo\\40bar'"));
41    assertEquals("foo\0bar", StringLiteral.getUnquotedValueOf("'foo\\0bar'"));
42    assertEquals("foo\0bar", StringLiteral.getUnquotedValueOf("'foo\\00bar'"));
43    assertEquals("foo\0" + "0bar",
44        StringLiteral.getUnquotedValueOf("'foo\\0000bar'"));
45    assertEquals("foo8bar", StringLiteral.getUnquotedValueOf("'foo\\8bar'"));
46    assertEquals("\n3", StringLiteral.getUnquotedValueOf("'\\0123'"));
47    assertEquals(
48        "\u0123" + "4", StringLiteral.getUnquotedValueOf("'\\u01234'"));
49    assertEquals(
50        "\u0123" + "a", StringLiteral.getUnquotedValueOf("'\\u0123a'"));
51    assertEquals(
52        "\u0123" + "A", StringLiteral.getUnquotedValueOf("'\\u0123A'"));
53    assertEquals(
54        "\u0123" + "f", StringLiteral.getUnquotedValueOf("'\\u0123f'"));
55    assertEquals(
56        "\u0123" + "F", StringLiteral.getUnquotedValueOf("'\\u0123F'"));
57    assertEquals("'", StringLiteral.getUnquotedValueOf("'\\u0027'"));
58    assertEquals("\"", StringLiteral.getUnquotedValueOf("'\\u0022'"));
59    assertEquals("'", StringLiteral.getUnquotedValueOf("\"\\u0027\""));
60    assertEquals("\"", StringLiteral.getUnquotedValueOf("\"\\u0022\""));
61    assertEquals("@", StringLiteral.getUnquotedValueOf("'\\x40'"));
62    assertEquals("x4", StringLiteral.getUnquotedValueOf("'\\x4'"));
63  }
64 
65  public final void testQuoteValue() {
66    assertEquals("''", StringLiteral.toQuotedValue(""));
67    assertEquals("'foo'", StringLiteral.toQuotedValue("foo"));
68    assertEquals("'foo\\bar'", StringLiteral.toQuotedValue("foo\bar"));
69    assertEquals("'foo\\nbar'", StringLiteral.toQuotedValue("foo\nbar"));
70    assertEquals(
71        "'foo\\\\bar\\\\baz'", StringLiteral.toQuotedValue("foo\\bar\\baz"));
72    assertEquals("'foo bar'", StringLiteral.toQuotedValue("foo bar"));
73    assertEquals("'foo\\x00bar'", StringLiteral.toQuotedValue("foo\0bar"));
74    assertEquals("'foo\\x7fbar'", StringLiteral.toQuotedValue("foo\u007fbar"));
75    assertEquals(
76        "'foo\\uabcdbar'", StringLiteral.toQuotedValue("foo\uabcdbar"));
77    assertEquals("'\\'foo\\''", StringLiteral.toQuotedValue("'foo'"));
78    assertEquals("'\\\"foo\\\"'", StringLiteral.toQuotedValue("\"foo\""));
79    assertEquals("'\\\"foo\\\\\\\"'", StringLiteral.toQuotedValue("\"foo\\\""));
80  }
81 
82  public final void testQuotingAndUnquotingAreComplements() {
83    Random rnd = new Random(SEED);
84    for (int i = 2000; --i >= 0;) {
85      String s = makeRandomString(rnd);
86      assertEquals(
87          s, StringLiteral.getUnquotedValueOf(StringLiteral.toQuotedValue(s)));
88    }
89  }
90 
91  public final void testRandomStringsParseable() {
92    Random rnd = new Random(SEED);
93    for (int i = 2000; --i >= 0;) {
94      String literal = makeRandomQuotedString(rnd);
95      // Test that it parses.
96      String value = StringLiteral.getUnquotedValueOf(literal);
97      String requoted = StringLiteral.toQuotedValue(value);
98      // Now make sure that our unquoting works
99      assertEquals(value, StringLiteral.getUnquotedValueOf(requoted));
100      // Make sure that the requoted string is coherent.
101      char delimiter = requoted.charAt(0);
102      assertTrue(requoted.length() >= 2);
103      assertEquals(delimiter, requoted.charAt(requoted.length() - 1));
104      if ("'\"".indexOf(delimiter) < 0) {
105        fail("delimiter 0x" + Integer.toString(delimiter, 16));
106      }
107      for (int ci = 1, end = requoted.length() - 1; ci < end; ++ci) {
108        char ch = requoted.charAt(ci);
109        if (ch == '\\') {
110          ++ci;
111          assertTrue("close delimiter is escaped", ci < end - 1);
112        }
113        assertTrue("delimiter appears unescaped", ch != delimiter);
114        if ("\r\n\u2028\u2029".indexOf(ch) >= 0) {
115          fail("newline 0x" + Integer.toString(ch, 16));
116        }
117      }
118    }
119  }
120 
121  private static String makeRandomString(Random rnd) {
122    int len = (int) Math.min(Math.abs(rnd.nextGaussian() * 128), 1024);
123    StringBuilder sb = new StringBuilder(len);
124    while (--len >= 0) {
125      sb.appendCodePoint(randomCodePoint(rnd));
126    }
127    return sb.toString();
128  }
129 
130  private static String makeRandomQuotedString(Random rnd) {
131    int len = (int) Math.min(Math.abs(rnd.nextGaussian() * 128), 1024);
132    int delim = rnd.nextInt(2) == 0 ? '"' : '\'';
133    StringBuilder sb = new StringBuilder(len);
134    sb.append(delim);
135    while (--len >= 0) {
136      char ch = randomChar(rnd);
137      boolean escape;
138      String sequence = null;
139      switch (ch) {
140        case '\u2028':
141          escape = true;
142          sequence = "\\u2028";
143          break;
144        case '\u2029':
145          escape = true;
146          sequence = "\\u2029";
147          break;
148        case '\r':
149          escape = true;
150          sequence = "\\r";
151          break;
152        case '\n':
153          escape = true;
154          sequence = "\\n";
155          break;
156        default:
157          escape = ch == 0 || ch == delim;
158          break;
159      }
160      if (!escape) {
161        int escapeType = rnd.nextInt(16);
162        switch (escapeType) {
163          case 0:
164            if (ch < 0377) {
165              sequence = escapeSequence(ch, 8, rnd.nextInt(3));
166            } else {
167              sequence = "u" + escapeSequence(ch, 16, 4);
168            }
169            break;
170          case 1:
171            if (ch < 0x100) {
172              sequence = escapeSequence(ch, 16, 2);
173            } else {
174              sequence = "u" + escapeSequence(ch, 16, 4);
175            }
176            break;
177          case 2:
178            sequence = "u" + escapeSequence(ch, 16, 4);
179            break;
180        }
181        escape = sequence != null;
182      }
183      if (escape) {
184        sb.append('\\');
185      }
186      if (sequence == null) {
187        sb.append(ch);
188      } else {
189        sb.append(sequence);
190      }
191    }
192    sb.append(delim);
193    return sb.toString();
194  }
195 
196  private static int randomCodePoint(Random rnd) {
197    int mag;
198    switch (rnd.nextInt(4)) {
199      default:
200        mag = 1 << 8;
201        break;
202      case 2:
203        mag = 1 << 16;
204        break;
205      case 3:
206        mag = 0x10ffff;
207        break;
208    }
209    int codePoint = rnd.nextInt(mag);
210    if (0xd800 <= codePoint && codePoint <= 0xdfff) {  // surrogates
211      codePoint = codePoint & 0xff;
212    }
213    return codePoint;
214  }
215 
216  private static char randomChar(Random rnd) {
217    char ch = (char) rnd.nextInt(Character.MAX_VALUE - Character.MIN_VALUE + 1);
218    if (0xd800 <= ch && ch <= 0xdfff) {  // surrogates
219      ch = (char) (ch & 0xff);
220    }
221    return ch;
222  }
223 
224  /**
225   * Generates the numeric portion of an octal, hex, or unicode escape sequence.
226   * @param ch the character to escape
227   * @param radix 8 for octal, 16 for hex or unicode.
228   * @param nDigits the minimum number of digits.  0's will be added to the left
229   *   to pad the value to at least nDigits.
230   */
231  private static String escapeSequence(char ch, int radix, int nDigits) {
232    StringBuilder sb = new StringBuilder(nDigits);
233    sb.append(Integer.toString(ch, radix));
234    while (sb.length() < nDigits) {
235      sb.insert(0, '0');
236    }
237    return sb.toString();
238  }
239}

[all classes][com.google.caja.parser.js]
EMMA 2.0.5312 (C) Vladimir Roubtsov