/*
 * Copyright 2008 Google Inc.
 * 
 * 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.gwt.emultest.java.lang;

import com.google.gwt.junit.client.GWTTestCase;

/**
 * This test verifies that the static evaluation performed by the compiler
 * on constant string expressions is correct.
 * 
 * TODO: this is just copied from the old StringTest before it was improved,
 *     but we need to go through and remove tests that do not actually
 *     test the compiler. 
 */
public class CompilerConstantStringTest extends GWTTestCase {

  @Override
  public String getModuleName() {
    return "com.google.gwt.emultest.EmulSuite";
  }

  public void testCharAt() {
    assertEquals("abc".charAt(1), 'b');
  }

  public void testConcat() {
    assertEquals("abcdef", "abc" + "def");
    assertEquals("abcdef", "abc".concat("def"));
    assertEquals("".concat(""), "");
    char c = 'd';
    String s = "abc";
    assertEquals("abcd", "abc" + 'd');
    assertEquals("abcd", "abc" + c);
    assertEquals("abcd", s + 'd');
    assertEquals("abcd", s + c);
    s += c;
    assertEquals("abcd", s);
  }

  public void testConstructor() {
    char[] chars = {'a', 'b', 'c', 'd', 'e', 'f'};
    String constant = "abcdef";
    String shortString = "cde";
    assertEquals(new String(constant), constant);
    assertEquals(new String(chars), constant);
    assertEquals(new String(chars, 2, 3), shortString);
    assertEquals(new String(""), "");
    assertEquals(new String(new String(new String(new String("")))), "");
    assertEquals(new String(new char[] {}), "");
  }

  public void testContains() {
    // at the beginning
    assertTrue("abcdef".contains("ab"));
    assertTrue("abcdef".contains(new StringBuffer("ab")));
    // at the end
    assertTrue("abcdef".contains("ef"));
    assertTrue("abcdef".contains(new StringBuffer("ef")));
    // in the middle
    assertTrue("abcdef".contains("cd"));
    assertTrue("abcdef".contains(new StringBuffer("cd")));
    // the same
    assertTrue("abcdef".contains("abcdef"));
    assertTrue("abcdef".contains(new StringBuffer("abcdef")));
    // not present
    assertFalse("abcdef".contains("z"));
    assertFalse("abcdef".contains(new StringBuffer("z")));
  }

  public void testEndsWith() {
    String haystack = "abcdefghi";
    assertTrue("a", haystack.endsWith("defghi"));
    assertTrue("b", haystack.endsWith(haystack));
    assertFalse("c", haystack.endsWith(haystack + "j"));
  }

  public void testEquals() {
    assertFalse("ABC".equals("abc"));
    assertFalse("abc".equals("ABC"));
    assertTrue("abc".equals("abc"));
    assertTrue("ABC".equals("ABC"));
    assertFalse("AbC".equals("aBC"));
    assertFalse("AbC".equals("aBC"));
    assertTrue("".equals(""));
    assertFalse("".equals(null));
  }

  public void testEqualsIgnoreCase() {
    assertTrue("ABC".equalsIgnoreCase("abc"));
    assertTrue("abc".equalsIgnoreCase("ABC"));
    assertTrue("abc".equalsIgnoreCase("abc"));
    assertTrue("ABC".equalsIgnoreCase("ABC"));
    assertTrue("AbC".equalsIgnoreCase("aBC"));
    assertTrue("AbC".equalsIgnoreCase("aBC"));
    assertTrue("".equalsIgnoreCase(""));
    assertFalse("".equalsIgnoreCase(null));
  }

  /**
   * Tests hashing with strings.
   * 
   * The specific strings used in this test used to trigger failures because we
   * use a JavaScript object as a hash map to cache the computed hash codes.
   * This conflicts with built-in properties defined on objects -- see issue
   * #631.
   * 
   */
  public void testHashCode() {
    String[] testStrings = {
        "watch", "unwatch", "toString", "toSource", "eval", "valueOf",
        "constructor", "__proto__"};
    int[] savedHash = new int[testStrings.length];
    for (int i = 0; i < testStrings.length; ++i) {
      savedHash[i] = testStrings[i].hashCode();

      /*
       * Verify that the resulting hash code is numeric, since this is not
       * enforced in web mode.
       */
      String str = Integer.toString(savedHash[i]);
      for (int j = 0; j < str.length(); ++j) {
        char ch = str.charAt(j);
        assertTrue("Bad character '" + ch + "' (U+0" + Integer.toHexString(ch)
            + ")", ch == '-' || ch == ' ' || Character.isDigit(ch));
      }
    }
    // verify the hash codes are constant for a given string
    for (int i = 0; i < testStrings.length; ++i) {
      assertEquals(savedHash[i], testStrings[i].hashCode());
    }
  }

  public void testIndexOf() {
    String haystack = "abcdefghi";
    assertEquals(haystack.indexOf("q"), -1);
    assertEquals(haystack.indexOf('q'), -1);
    assertEquals(haystack.indexOf("a"), 0);
    assertEquals(haystack.indexOf('a'), 0);
    assertEquals(haystack.indexOf('a', 1), -1);
    assertEquals(haystack.indexOf("bc"), 1);
    assertEquals(haystack.indexOf(""), 0);
  }

  public void testLastIndexOf() {
    String x = "abcdeabcdef";
    assertEquals(9, x.lastIndexOf("e"));
    assertEquals(10, x.lastIndexOf("f"));
    assertEquals(-1, x.lastIndexOf("f", 1));
  }

  public void testLength() {
    assertEquals(3, "abc".length());
    String str = "x";
    for (int i = 0; i < 16; i++) {
      str = str + str;
    }
    assertEquals(1 << 16, str.length());
  }

  public void testLowerCase() {
    assertEquals("abc", "AbC".toLowerCase());
    assertEquals("abc", "abc".toLowerCase());
    assertEquals("", "".toLowerCase());
  }

  public void testMatch() {
    assertFalse("1f", "abbbbcd".matches("b*"));
    assertFalse("2f", "abbbbcd".matches("b+"));
    assertTrue("3t", "abbbbcd".matches("ab*bcd"));
    assertTrue("4t", "abbbbcd".matches("ab+cd"));
    assertTrue("5t", "abbbbcd".matches("ab+bcd"));
    assertFalse("6f", "abbbbcd".matches(""));
    assertTrue("7t", "abbbbcd".matches("a.*d"));
    assertFalse("8f", "abbbbcd".matches("a.*e"));
  }

  public void testNull() {
    assertNull(returnNull());
    /*
     * The ""+ is there because GWT currently does not translate a+b
     * defensively enough to handle the case that both a and b are null.
     * Revisit this test if that is ever changed.
     */
    String a = "" + returnNull() + returnNull();
    assertEquals("nullnull", a);
  }

  public void testReplace() {
    assertEquals("axax".replace('x', 'a'), "aaaa");
    assertEquals("aaaa".replace('x', 'a'), "aaaa");
    for (char from = 32; from < 250; ++from) {
      char to = (char) (from + 5);
      assertEquals(toS(to), toS(from).replace(from, to));
    }
    for (char to = 32; to < 250; ++to) {
      char from = (char) (to + 5);
      assertEquals(toS(to), toS(from).replace(from, to));
    }
    // issue 1480
    assertEquals("example xd", "example xd".replace('\r', ' ').replace('\n', ' '));
    assertEquals("dog food", "dog\u0120food".replace('\u0120', ' '));
    assertEquals("ABABAB", "\u1111B\u1111B\u1111B".replace('\u1111', 'A'));
  }

  public void testReplaceAll() {
    assertEquals("abcdef", "xxxxabcxxdexf".replaceAll("x*", ""));
    assertEquals("1\\1abc123\\123de1234\\1234f", "1abc123de1234f".replaceAll(
        "([1234]+)", "$1\\\\$1"));
    assertEquals("\n  \n", "x  x".replaceAll("x", "\n"));
    assertEquals("x  x", "\n  \n".replaceAll("\\\n", "x"));
    assertEquals("x\"\\", "x".replaceAll("x", "\\x\\\"\\\\"));
    assertEquals("$$x$", "x".replaceAll("(x)", "\\$\\$$1\\$"));
  }

  public void testSplit() {
    compareList("fullSplit", new String[] {"abc", "", "", "de", "f"},
        "abcxxxdexfxx".split("x"));
    compareList("emptyRegexSplit", new String[] {
        "", "a", "b", "c", "x", "x", "d", "e", "x", "f", "x"},
        "abcxxdexfx".split(""));
    compareList("2:", "boo:and:foo".split(":", 2), new String[] {
        "boo", "and:foo"});
    compareList("5:", "boo:and:foo".split(":", 5), new String[] {
        "boo", "and", "foo"});
    compareList("-2:", "boo:and:foo".split(":", -2), new String[] {
        "boo", "and", "foo"});
    compareList("5o", "boo:and:foo".split("o", 5), new String[] {
        "b", "", ":and:f", "", ""});
    compareList("-2o", "boo:and:foo".split("o", -2), new String[] {
        "b", "", ":and:f", "", ""});
    compareList("0o", "boo:and:foo".split("o", 0), new String[] {
        "b", "", ":and:f"});
    compareList("0:", "boo:and:foo".split(":", 0), new String[] {
        "boo", "and", "foo"});
  }

  public void testStartsWith() {
    String haystack = "abcdefghi";
    assertTrue(haystack.startsWith("abc"));
    assertTrue(haystack.startsWith("bc", 1));
    assertTrue(haystack.startsWith(haystack));
    assertFalse(haystack.startsWith(haystack + "j"));
  }

  public void testSubstring() {
    String haystack = "abcdefghi";
    assertEquals("cd", haystack.substring(2, 4));
    assertEquals("bc", "abcdef".substring(1, 3));
    assertEquals("bcdef", "abcdef".substring(1));
  }

  public void testToCharArray() {
    char[] a1 = "abc".toCharArray();
    char[] a2 = new char[] {'a', 'b', 'c'};
    for (int i = 0; i < a1.length; i++) {
      assertEquals(a1[i], a2[i]);
    }
  }

  public void testTrim() {
    trimRightAssertEquals("abc", "   \t abc \n  ");
    trimRightAssertEquals("abc", "abc".trim());
    trimRightAssertSame("abc", "abc");
    String s = '\u0023' + "hi";
    trimRightAssertSame(s, s);
    trimRightAssertEquals("abc", " abc".trim());
    trimRightAssertEquals("abc", "abc ".trim());
    trimRightAssertEquals("", "".trim());
    trimRightAssertEquals("", "   \t ".trim());
  }

  public void testUpperCase() {
    assertEquals("abc", "AbC".toLowerCase());
    assertEquals("abc", "abc".toLowerCase());
    assertEquals("", "".toLowerCase());
  }

  public void testValueOf() {
    assertTrue(String.valueOf(C.FLOAT_VALUE).startsWith(C.FLOAT_STRING));
    assertEquals(C.INT_STRING, String.valueOf(C.INT_VALUE));
    assertEquals(C.LONG_STRING, String.valueOf(C.LONG_VALUE));
    assertTrue(String.valueOf(C.DOUBLE_VALUE).startsWith(C.DOUBLE_STRING));
    assertEquals(C.CHAR_STRING, String.valueOf(C.CHAR_VALUE));
    assertEquals(C.CHAR_ARRAY_STRING, String.valueOf(C.CHAR_ARRAY_VALUE));
    assertEquals(C.CHAR_ARRAY_STRING_SUB, String.valueOf(C.CHAR_ARRAY_VALUE, 1,
        4));
    assertEquals(C.FALSE_STRING, String.valueOf(C.FALSE_VALUE));
    assertEquals(C.TRUE_STRING, String.valueOf(C.TRUE_VALUE));
  }

  /**
   * Helper method for testTrim to avoid compiler optimizations.
   */
  public void trimRightAssertEquals(String left, String right) {
    assertEquals(left, right.trim());
  }

  /**
   * Helper method for testTrim to avoid compiler optimizations.
   */
  public void trimRightAssertSame(String left, String right) {
    assertSame(left, right.trim());
  }

  private void compareList(String category, String[] desired, String[] got) {
    assertEquals(category + " length", desired.length, got.length);
    for (int i = 0; i < desired.length; i++) {
      assertEquals(category + " " + i, desired[i], got[i]);
    }
  }

  private String returnNull() {
    return null;
  }

  private String toS(char from) {
    return Character.toString(from);
  }

}
