/*
 * Copyright 2007 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.i18n.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.i18n.client.TestAnnotatedMessages.Nested;
import com.google.gwt.i18n.client.gen.Colors;
import com.google.gwt.i18n.client.gen.Shapes;
import com.google.gwt.i18n.client.gen.TestMessages;
import com.google.gwt.i18n.client.resolutiontest.Inners;
import com.google.gwt.i18n.client.resolutiontest.Inners.ExtendsInnerInner;
import com.google.gwt.i18n.client.resolutiontest.Inners.HasInner;
import com.google.gwt.i18n.client.resolutiontest.Inners.InnerClass;
import com.google.gwt.i18n.client.resolutiontest.Inners.LocalizableSimpleInner;
import com.google.gwt.i18n.client.resolutiontest.Inners.OuterLoc;
import com.google.gwt.i18n.client.resolutiontest.Inners.SimpleInner;
import com.google.gwt.i18n.client.resolutiontest.Inners.HasInner.IsInner;
import com.google.gwt.i18n.client.resolutiontest.Inners.InnerClass.InnerInner;
import com.google.gwt.i18n.client.resolutiontest.Inners.InnerClass.InnerInnerMessages;
import com.google.gwt.i18n.client.resolutiontest.Inners.InnerClass.LocalizableInnerInner;
import com.google.gwt.junit.client.GWTTestCase;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Set;

/**
 * Tests Internationalization. Assumes locale is set to piglatin_UK
 */
public class I18NTest extends GWTTestCase {

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

  @SuppressWarnings("unchecked") // intentional test of raw map
  public void testAnnotatedConstants() {
    TestAnnotatedConstants c = GWT.create(TestAnnotatedConstants.class);
    assertEquals(14, c.fourteen());
    assertFalse(c.isFalse());
    assertTrue(c.isTrue());
    assertArrayEquals(new String[] {"String array with one string"},
        c.singleString());
    assertArrayEquals(new String[] {"One", "Two", "Three,Comma"},
        c.threeStrings());
    assertEquals("Properties value #s need quoting!", c.propertiesQuoting());
    Map<String, String> stringMap = c.stringMap();
    assertTrue(stringMap.containsKey("key1"));
    assertTrue(stringMap.containsKey("key2"));
    assertEquals("value1", stringMap.get("key1"));
    assertEquals("value2", stringMap.get("key2"));
    assertEquals(2, stringMap.size());
    stringMap = c.rawMap();
    assertTrue(stringMap.containsKey("key1"));
    assertTrue(stringMap.containsKey("key2"));
    assertEquals("value1", stringMap.get("key1"));
    assertEquals("value2", stringMap.get("key2"));
    assertEquals(2, stringMap.size());
    assertEquals("Test me", c.testMe());
    assertEquals(13.7f, c.thirteenPointSeven());
    assertEquals(3.14, c.threePointOneFour());
    assertEquals("Once more, with meaning", c.withMeaning());
  }

  public void testAnnotatedConstantsGenMD5() {
    TestAnnotatedConstantsGenMD5 c = GWT.create(TestAnnotatedConstantsGenMD5.class);
    assertEquals(14, c.fourteen());
    assertFalse(c.isFalse());
    assertTrue(c.isTrue());
    assertArrayEquals(new String[] {"String array with one string"},
        c.singleString());
    assertArrayEquals(new String[] {"One", "Two"}, c.twoStrings());
    Map<String, String> stringMap = c.stringMap();
    assertTrue(stringMap.containsKey("key1"));
    assertTrue(stringMap.containsKey("key2"));
    assertEquals("value1", stringMap.get("key1"));
    assertEquals("value2", stringMap.get("key2"));
    assertEquals(2, stringMap.size());
    assertEquals("Test me", c.testMe());
    assertEquals(13.7f, c.thirteenPointSeven());
    assertEquals(3.14, c.threePointOneFour());
    assertEquals("Once more, with meaning", c.withMeaning());
  }

  public void testAnnotatedMessages() {
    TestAnnotatedMessages m = GWT.create(TestAnnotatedMessages.class);
    assertEquals("Estay emay", m.basicText());
    assertEquals("Oncay oremay, ithway eaningmay", m.withMeaning());
    assertEquals("PL: One argument: one", m.oneArgument("one"));
    assertEquals("PL: One argument (where am I?), which is optional",
        m.optionalArgument("where am I?"));
    assertEquals("Two arguments, second and first, inverted",
        m.invertedArguments("first", "second")); // from default locale
    assertEquals("PL: Don't tell me I can't {quote things in braces}",
        m.quotedText());
    assertEquals("PL: This {0} would be an argument if not quoted",
        m.quotedArg());
    assertEquals("PL: Total is US$11,305.01", m.currencyFormat(11305.01));
    assertEquals("PL: Default number format is 1,017.1",
        m.defaultNumberFormat(1017.1));
    @SuppressWarnings("deprecation")
    Date date = new Date(107, 11, 1, 12, 1, 2);
    assertEquals("PL: It is 12:01 PM on Saturday, December 1, 2007",
        m.getTimeDate(date));
    assertEquals("PL: 13 widgets", m.pluralWidgetsOther(13));
    assertEquals("Too many widgets to count (150) in pig-latin",
        m.pluralWidgetsOther(150));
  }

  public void testAnnotationInheritance() {
    TestAnnotationGrandchild m = GWT.create(TestAnnotationGrandchild.class);
    assertEquals("foo", m.foo());
    assertEquals("bar_piglatin", m.bar());
    assertEquals("baz_piglatin", m.baz());
  }

  public void testBindings() {
    TestBinding b = GWT.create(TestBinding.class);
    assertEquals("default", b.a());
    TestLeafBundle c = GWT.create(TestLeafBundle.class);
    assertEquals("TestLeafBundle_piglatin_UK_WINDOWS", c.b());
    com.google.gwt.i18n.client.Wrapper2.TestBindingImpl d = GWT.create(com.google.gwt.i18n.client.Wrapper2.TestBindingImpl.class);
    assertEquals("default", d.a());
  }

  public void testColors() {
    Colors colors = GWT.create(Colors.class);
    assertNotNull(colors);
    // No piglatin version exists for grey
    assertEquals("ĝréý", colors.grey());
    assertEquals("ackblay", colors.black());
    assertEquals("ueblay", colors.blue());
  }

  public void testColorsAndShapes() {
    ColorsAndShapes s = GWT.create(ColorsAndShapes.class);
    assertEquals("ueblay", s.blue());
    assertEquals("ĝréý", s.grey());
  }

  public void testConstantBooleans() {
    TestConstants types = GWT.create(TestConstants.class);
    assertEquals(false, types.booleanFalse());
    assertEquals(true, types.booleanTrue());
  }

  public void testConstantDoubles() {
    TestConstants types = GWT.create(TestConstants.class);
    double delta = 0.0000001;
    assertEquals(3.14159, types.doublePi(), delta);
    assertEquals(0.0, types.doubleZero(), delta);
    assertEquals(1.0, types.doubleOne(), delta);
    assertEquals(-1.0, types.doubleNegOne(), delta);
    assertEquals(Double.MAX_VALUE, types.doublePosMax(), delta);
    assertEquals(Double.MIN_VALUE, types.doublePosMin(), delta);
    assertEquals(-Double.MAX_VALUE, types.doubleNegMax(), delta);
    assertEquals(-Double.MIN_VALUE, types.doubleNegMin(), delta);
  }

  public void testConstantFloats() {
    TestConstants types = GWT.create(TestConstants.class);
    double delta = 0.0000001;
    assertEquals(3.14159f, types.floatPi(), delta);
    assertEquals(0.0f, types.floatZero(), delta);
    assertEquals(1.0f, types.floatOne(), delta);
    assertEquals(-1.0f, types.floatNegOne(), delta);
    assertEquals(Float.MAX_VALUE, types.floatPosMax(), delta);
    assertEquals(Float.MIN_VALUE, types.floatPosMin(), delta);
    assertEquals(-Float.MAX_VALUE, types.floatNegMax(), delta);
    assertEquals(-Float.MIN_VALUE, types.floatNegMin(), delta);
  }

  /**
   * Exercises ConstantMap more than the other map tests.
   */
  public void testConstantMapABCD() {
    TestConstants types = GWT.create(TestConstants.class);

    Map<String, String> map = types.mapABCD();
    Map<String, String> expectedMap = getMapFromArrayUsingASimpleRule(new String[] {
        "A", "B", "C", "D"});
    assertNull(map.get("bogus"));
    compareMapsComprehensively(map, expectedMap);

    /*
     * Test if the returned map can be modified in any way. Things are working
     * as expected if exceptions are thrown in each case.
     */
    String failureMessage = "Should have thrown UnsupportedOperationException";
    /* test map operations */
    try {
      map.remove("keyA");
      fail(failureMessage + " on map.remove");
    } catch (UnsupportedOperationException e) {
    }
    try {
      map.put("keyA", "allA");
      fail(failureMessage + "on map.put of existing key");
    } catch (UnsupportedOperationException e) {
    }
    try {
      map.put("keyZ", "allZ");
      fail(failureMessage + "on map.put of new key");
    } catch (UnsupportedOperationException e) {
    }
    try {
      map.clear();
      fail(failureMessage + " on map.clear");
    } catch (UnsupportedOperationException e) {
    }

    /* test map.keySet() operations */
    try {
      map.keySet().add("keyZ");
      fail(failureMessage + " on map.keySet().add");
    } catch (UnsupportedOperationException e) {
    }
    try {
      map.keySet().remove("keyA");
      fail(failureMessage + " on map.keySet().remove");
    } catch (UnsupportedOperationException e) {
    }
    try {
      map.keySet().clear();
      fail(failureMessage + " on map.keySet().clear");
    } catch (UnsupportedOperationException e) {
    }

    /* test map.values() operations */
    try {
      map.values().add("valueZ");
      fail(failureMessage + " on map.values().add");
    } catch (UnsupportedOperationException e) {
    }
    try {
      map.values().remove("valueA");
      fail(failureMessage + " on map.values().clear()");
    } catch (UnsupportedOperationException e) {
    }
    try {
      map.values().clear();
      fail(failureMessage + " on map.values().clear()");
    } catch (UnsupportedOperationException e) {
    }

    /* test map.entrySet() operations */
    Map.Entry<String, String> firstEntry = map.entrySet().iterator().next();
    try {
      map.entrySet().clear();
      fail(failureMessage + "on map.entrySet().clear");
    } catch (UnsupportedOperationException e) {
    }
    try {
      map.entrySet().remove(firstEntry);
      fail(failureMessage + " on map.entrySet().remove");
    } catch (UnsupportedOperationException e) {
    }
    try {
      map.entrySet().add(firstEntry);
      fail(failureMessage + "on map.entrySet().add");
    } catch (UnsupportedOperationException e) {
    }
    try {
      firstEntry.setValue("allZ");
      fail(failureMessage + "on firstEntry.setValue");
    } catch (UnsupportedOperationException e) {
    }
    try {
      map.clear();
      fail(failureMessage + " on map.clear");
    } catch (UnsupportedOperationException e) {
    }
  }

  /**
   * Tests exercise the cache.
   */
  public void testConstantMapBACD() {
    TestConstants types = GWT.create(TestConstants.class);
    Map<String, String> map = types.mapBACD();
    Map<String, String> expectedMap = getMapFromArrayUsingASimpleRule(new String[] {
        "B", "A", "C", "D"});
    compareMapsComprehensively(map, expectedMap);
  }

  /**
   * Tests exercise the cache.
   */
  public void testConstantMapBBB() {
    TestConstants types = GWT.create(TestConstants.class);
    Map<String, String> map = types.mapBBB();
    Map<String, String> expectedMap = getMapFromArrayUsingASimpleRule(new String[] {"B"});
    compareMapsComprehensively(map, expectedMap);
  }

  /**
   * Tests exercise the cache and check if Map works as the declared return
   * type.
   */
  @SuppressWarnings("unchecked")
  public void testConstantMapDCBA() {
    TestConstants types = GWT.create(TestConstants.class);
    Map<String, String> map = types.mapDCBA();
    Map<String, String> expectedMap = getMapFromArrayUsingASimpleRule(new String[] {
        "D", "C", "B", "A"});
    compareMapsComprehensively(map, expectedMap);
  }

  /**
   * Tests focus on correctness of entries, since ABCD exercises the map.
   */
  public void testConstantMapEmpty() {
    TestConstants types = GWT.create(TestConstants.class);
    Map<String, String> map = types.mapEmpty();
    Map<String, String> expectedMap = new HashMap<String, String>();
    compareMapsComprehensively(map, expectedMap);
  }

  /**
   * Tests exercise the cache and check if Map works as the declared return
   * type.
   */
  public void testConstantMapXYZ() {
    TestConstants types = GWT.create(TestConstants.class);
    Map<String, String> map = types.mapXYZ();
    Map<String, String> expectedMap = new HashMap<String, String>();
    expectedMap.put("keyX", "valueZ");
    expectedMap.put("keyY", "valueZ");
    expectedMap.put("keyZ", "valueZ");
    compareMapsComprehensively(map, expectedMap);
  }

  public void testConstantStringArrays() {
    TestConstants types = GWT.create(TestConstants.class);
    String[] s;

    s = types.stringArrayABCDEFG();
    assertArrayEquals(new String[] {"A", "B", "C", "D", "E", "F", "G"}, s);

    s = types.stringArraySizeOneEmptyString();
    assertArrayEquals(new String[] {""}, s);

    s = types.stringArraySizeOneX();
    assertArrayEquals(new String[] {"X"}, s);

    s = types.stringArraySizeTwoBothEmpty();
    assertArrayEquals(new String[] {"", ""}, s);

    s = types.stringArraySizeThreeAllEmpty();
    assertArrayEquals(new String[] {"", "", ""}, s);

    s = types.stringArraySizeTwoWithEscapedComma();
    assertArrayEquals(new String[] {"X", ", Y"}, s);

    s = types.stringArraySizeOneWithBackslashX();
    assertArrayEquals(new String[] {"\\X"}, s);

    s = types.stringArraySizeThreeWithDoubleBackslash();
    assertArrayEquals(new String[] {"X", "\\", "Y"}, s);
  }

  public void testConstantStrings() {
    TestConstants types = GWT.create(TestConstants.class);
    assertEquals("string", types.getString());
    assertEquals("stringTrimsLeadingWhitespace",
        types.stringTrimsLeadingWhitespace());
    assertEquals("stringDoesNotTrimTrailingThreeSpaces   ",
        types.stringDoesNotTrimTrailingThreeSpaces());
    assertEquals("", types.stringEmpty());
    String jaBlue = types.stringJapaneseBlue();
    assertEquals("あお", jaBlue);
    String jaGreen = types.stringJapaneseGreen();
    assertEquals("みどり", jaGreen);
    String jaRed = types.stringJapaneseRed();
    assertEquals("あか", jaRed);
  }

  public void testConstantsWithLookup() {
    TestConstantsWithLookup l = GWT.create(TestConstantsWithLookup.class);
    Map<String, String> map = l.getMap("mapABCD");
    assertEquals("valueA", map.get("keyA"));
    map = l.getMap("mapDCBA");
    assertEquals("valueD", map.get("keyD"));
    assertEquals(l.mapABCD(), l.getMap("mapABCD"));
    assertEquals(l.mapDCBA(), l.getMap("mapDCBA"));
    assertEquals(l.mapBACD(), l.getMap("mapBACD"));
    assertEquals(l.getString(), l.getString("getString"));
    assertSame(l.stringArrayABCDEFG(), l.getStringArray("stringArrayABCDEFG"));
    assertEquals(l.booleanFalse(), l.getBoolean("booleanFalse"));
    assertEquals(l.floatPi(), l.getFloat("floatPi"), .001);
    assertEquals(l.doublePi(), l.getDouble("doublePi"), .001);
    try {
      // even though getString has the gwt.key "string", it is not the lookup
      // value
      l.getMap("string");
      fail("Should have thrown MissingResourceException");
    } catch (MissingResourceException e) {
      // success if the exception was caught
    }
  }

  public void testDictionary() {
    createDummyDictionaries();
    Dictionary d = Dictionary.getDictionary("testDic");
    assertEquals("3 {2},{2},{2}, one {0}, two {1} {1}",
        d.get("formattedMessage"));
    assertEquals("4", d.get("d"));
    Set<String> s = d.keySet();
    assertTrue(s.contains("a"));
    assertTrue(s.contains("b"));
    assertFalse(s.contains("c"));
    String nonExistentKey = "nonExistentKey";
    try {
      d.get(nonExistentKey);
      fail("should have thrown a MissingResourceException");
    } catch (MissingResourceException ex) {
      assertTrue(ex.getMessage(), ex.getMessage().indexOf(
          "accessed keys: " + nonExistentKey + ",d,formattedMessage") != -1);
    }

    /*
     * verify that accessedKeys maintains at least the last 30 entries in the
     * correct order. Steps involved: (i) create expectedKeys array, (ii) access
     * the dictionary, (iii) confirm that accessedKeys is maintained correctly.
     */
    // expectedKeys: nonExistentKey, 9 a's, 9 b's, 9 d's, 2 formattedMessage's
    StringBuffer expectedKeys = new StringBuffer();
    expectedKeys.append(nonExistentKey);
    for (String key : new String[] {"a", "b", "d"}) {
      for (int i = 0; i < 9; i++) {
        expectedKeys.append(",");
        expectedKeys.append(key);
      }
    }
    expectedKeys.append(",formattedMessage,formattedMessage");
    // access 360 keys. last 30 should match expectedKeys
    for (int i = 0; i < 10; i++) {
      for (String key : new String[] {"formattedMessage", "d", "b", "a"}) {
        for (int j = 0; j < 9; j++) {
          d.get(key);
        }
      }
    }
    try {
      d.get(nonExistentKey);
      fail("should have thrown a MissingResourceException");
    } catch (MissingResourceException ex) {
      assertTrue(ex.getMessage(), ex.getMessage().indexOf(
          "accessed keys: " + expectedKeys.toString()) != -1);
    }

    Collection<String> s2 = d.values();
    assertTrue(s2.contains("A"));
    assertTrue(s2.contains("B"));
    Iterator<String> iter = s2.iterator();
    assertEquals("3 {2},{2},{2}, one {0}, two {1} {1}", iter.next());
    assertEquals(4, s2.size());
    Dictionary empty = Dictionary.getDictionary("emptyDic");
    assertEquals(0, empty.keySet().size());
    boolean threwError = false;
    try {
      Dictionary.getDictionary("malformedDic");
    } catch (MissingResourceException e) {
      threwError = true;
    }
    assertTrue(threwError);
  }

  public void testIntConstant() {
    TestConstants types = GWT.create(TestConstants.class);
    assertEquals(0, types.intZero());
    assertEquals(1, types.intOne());
    assertEquals(-1, types.intNegOne());
    assertEquals(Integer.MAX_VALUE, types.intMax());
    assertEquals(Integer.MIN_VALUE, types.intMin());
  }

  public void testLocalizableInner() {
    // Check simple inner
    LocalizableSimpleInner s = GWT.create(Inners.LocalizableSimpleInner.class);
    assertEquals("getLocalizableInner", s.getLocalizableInner());

    LocalizableInnerInner localizableInnerInner = GWT.create(Inners.InnerClass.LocalizableInnerInner.class);
    assertEquals("localizableInnerInner", localizableInnerInner.string());

    // Check success of finding embedded
    OuterLoc lock = GWT.create(OuterLoc.class);
    assertEquals("piglatin", lock.string());

    assertEquals("InnerLoc", Inners.testInnerLoc());
  }

  public void testLocalizableInterfaceInner() {
    Inners inner = new Inners();

    // Simple Inner
    SimpleInner simpleInner = GWT.create(Inners.SimpleInner.class);
    assertEquals(0, simpleInner.intZero());
    assertEquals("Simple Inner", simpleInner.simpleInner());
    assertTrue(inner.testProtectedInner());

    // Has Inner
    HasInner hasInner = GWT.create(Inners.HasInner.class);
    assertEquals("Has Inner", hasInner.hasInner());
    assertEquals(0, hasInner.floatZero(), .0001);

    // Is Inner
    IsInner isInner = GWT.create(IsInner.class);
    assertEquals(2, isInner.isInner());

    // Inner Inner
    InnerInner innerInner = GWT.create(InnerInner.class);
    assertEquals(4.321, innerInner.innerInner(), .0001);
    assertEquals("outer", innerInner.outer());

    // Inner Inner Message
    InnerInnerMessages innerInnerMessages = GWT.create(InnerInnerMessages.class);
    assertEquals("I am a person",
        innerInnerMessages.innerClassMessages("person"));

    // Extends Inner Inner
    ExtendsInnerInner extendsInnerInner = GWT.create(ExtendsInnerInner.class);
    assertEquals("Extends Inner Inner", extendsInnerInner.extendsInnerInner());

    // Protected InnerClass
    InnerClass innerClass = new Inners.InnerClass();
    Map<String, String> extendsAnotherInner = innerClass.testExtendsAnotherInner();
    assertEquals("4.321", extendsAnotherInner.get("innerInner"));
    assertEquals("outer", extendsAnotherInner.get("outer"));

    // ExtendProtectedInner
    String extendProtectedInner = innerClass.testExtendsProtectedInner();
    assertEquals("Extend Protected Inner", extendProtectedInner);
  }

  public void testNestedAnnotations() {
    Nested m = GWT.create(Nested.class);
    // no translation exists in piglatin for nested dollar
    assertEquals("nested dollar", m.nestedDollar());
    assertEquals("estednay underscoray", m.nestedUnderscore());
  }

  public void testShapesFamily() {
    Shapes shapes = GWT.create(Shapes.class);
    // test overload
    assertEquals("aya irclecay", shapes.circle());
    ColorsAndShapesAndConcepts s = GWT.create(ColorsAndShapesAndConcepts.class);
    assertEquals("aya irclecay", s.circle());
    // test converge
    assertEquals("any primary color", s.shapeColor());
    assertEquals("trees", s.green());
    assertEquals("Îñţérñåţîöñåļîžåţîöñ", s.internationalization());
  }

  public void testTestMessages() {
    TestMessages s = GWT.create(TestMessages.class);
    assertEquals("no args", s.args0());
    assertEquals("a,b,c,d,e,f,g,h,i,j", s.args10("a", "b", "c", "d", "e", "f",
        "g", "h", "i", "j"));
    String shouldHave = "x,y, \"a\",\"b\", \"x\", \"y\", \'a\', b, {0}, \'y\'";
    assertEquals(shouldHave, s.argsWithQuotes("x", "y"));
    assertEquals("repeatedArgs: a, b, a, b, a, b, a, b",
        s.testLotsOfUsageOfArgs("a", "b"));
    assertEquals("\"~\" ~~ \"~~~~ \"\"", s.testWithXs());
    assertEquals("お好你好好", s.unicode("好", "好"));
    assertEquals("", s.empty());
    assertEquals("{quoted}", s.quotedBraces());
  }

  public void testTypedMessages() {
    TestTypedMessages typed = GWT.create(TestTypedMessages.class);
    String expected = "int(0) float(1.5), long(0), boolean(true), Object([], char(a), byte(127), short(-32768);";
    assertEquals(expected, typed.testAllTypes(0, (float) 1.5, 0, true,
        new ArrayList<String>(), 'a', Byte.MAX_VALUE, Short.MIN_VALUE));
    String lotsOfInts = typed.testLotsOfInts(1, 2, 3, 4);
    assertEquals("1, 2,3,4 ", lotsOfInts);
    String oneFloat = typed.simpleMessageTest((float) 2.25);
    assertEquals("2.25", oneFloat);
    String singleQuotes = typed.testSingleQuotes("arg");
    assertEquals("'A', 'arg', ','", singleQuotes);
    String testSomeObjectTypes = typed.testSomeObjectTypes(new I18NTest(),
        new StringBuffer("hello"), new Integer("34"), null);
    assertEquals("this(null(" + I18NTest.class.getName()
        + ")), StringBuffer(hello), Integer(34), " + "null(null);",
        testSomeObjectTypes);
  }

  private void assertArrayEquals(String[] shouldBe, String[] test) {
    assertEquals(shouldBe.length, test.length);
    for (int i = 0; i < test.length; i++) {
      assertEquals(shouldBe[i], test[i]);
    }
  }

  private <T> boolean compare(Collection<T> collection1,
      Collection<T> collection2) {
    if (collection1 == null) {
      return (collection2 == null);
    }
    if (collection2 == null) {
      return false;
    }
    if (collection1.size() != collection2.size()) {
      return false;
    }
    for (T element1 : collection1) {
      boolean found = false;
      for (T element2 : collection2) {
        if (element1.equals(element2)) {
          found = true;
          break;
        }
      }
      if (!found) {
        return false;
      }
    }
    return true;
  }

  // compare the map, entrySet, keySet, and values
  private void compareMapsComprehensively(Map<String, String> map,
      Map<String, String> expectedMap) {
    // checking both directions to verify that the equals implementation is
    // correct both ways
    assertEquals(expectedMap, map);
    assertEquals(map, expectedMap);
    assertEquals(expectedMap.entrySet(), map.entrySet());
    assertEquals(map.entrySet(), expectedMap.entrySet());
    assertEquals(expectedMap.keySet(), map.keySet());
    assertEquals(map.keySet(), expectedMap.keySet());
    assertTrue(compare(expectedMap.values(), map.values()));
    assertTrue(compare(map.values(), expectedMap.values()));
  }

  private native void createDummyDictionaries() /*-{
    $wnd.testDic = new Object();
    $wnd.testDic.formattedMessage = "3 {2},{2},{2}, one {0}, two {1} {1}";
    $wnd.testDic.a="A";
    $wnd.testDic.b="B";
    $wnd.testDic.d=4;
    $wnd.emptyDic = new Object();
    $wnd.malformedDic = 4;
  }-*/;

  private Map<String, String> getMapFromArrayUsingASimpleRule(String array[]) {
    Map<String, String> map = new HashMap<String, String>();
    for (String str : array) {
      map.put("key" + str, "value" + str);
    }
    return map;
  }
}
