Move AutoBean package to com.google.web.bindery.autobean package.
http://code.google.com/p/google-web-toolkit/issues/detail?id=6253
Review at http://gwt-code-reviews.appspot.com/1414803
Patch by: bobv
Review by: rjrjr


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10007 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/test/com/google/web/bindery/autobean/shared/SplittableTest.java b/user/test/com/google/web/bindery/autobean/shared/SplittableTest.java
new file mode 100644
index 0000000..46a6baf
--- /dev/null
+++ b/user/test/com/google/web/bindery/autobean/shared/SplittableTest.java
@@ -0,0 +1,330 @@
+/*
+ * Copyright 2011 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.web.bindery.autobean.shared;
+
+import com.google.web.bindery.autobean.gwt.client.impl.JsoSplittable;
+import com.google.web.bindery.autobean.shared.impl.AutoBeanCodexImpl;
+import com.google.web.bindery.autobean.shared.impl.AutoBeanCodexImpl.Coder;
+import com.google.web.bindery.autobean.shared.impl.AutoBeanCodexImpl.EncodeState;
+import com.google.web.bindery.autobean.shared.impl.SplittableList;
+import com.google.web.bindery.autobean.shared.impl.SplittableSimpleMap;
+import com.google.web.bindery.autobean.shared.impl.StringQuoter;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.junit.client.GWTTestCase;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Tests for the underlying Splittable implementation. This test class is not
+ * indicative of code that users would write, it's simply doing spot-checks of
+ * functionality that AbstractAutoBean depends on.
+ */
+public class SplittableTest extends GWTTestCase {
+
+  /**
+   * 
+   */
+  private static final EncodeState testState = EncodeState.forTesting();
+
+  @Override
+  public String getModuleName() {
+    return "com.google.web.bindery.autobean.AutoBean";
+  }
+
+  public void testBasicProperties() {
+    Splittable data = StringQuoter.split("{\"a\":true, \"b\":3, \"c\":\"string\", \"d\":null}");
+    assertTrue("isBoolean", data.get("a").isBoolean());
+    assertTrue("asBoolean", data.get("a").asBoolean());
+    assertTrue("isNumber", data.get("b").isNumber());
+    assertEquals(3.0, data.get("b").asNumber());
+    assertTrue("isString", data.get("c").isString());
+    assertEquals("string", data.get("c").asString());
+    assertTrue("isNull", data.isNull("d"));
+    assertNull("should be null", data.get("d"));
+  }
+
+  /**
+   * Ensure that hashcodes don't leak into the payload.
+   */
+  public void testHashCode() {
+    Splittable data = StringQuoter.split("{\"a\":\"b\"}");
+    int hash = data.hashCode();
+    String payload = data.getPayload();
+    assertFalse(payload, payload.contains("$H"));
+    assertFalse(payload, payload.contains(String.valueOf(hash)));
+    assertEquals(hash, data.hashCode());
+  }
+
+  /**
+   * Splittables are implemented by a couple of different concrete types. We'll
+   * use this method to make sure that the correct implementation type is being
+   * used in various circumstances.
+   */
+  public void testImplementationChoice() {
+    Splittable s = StringQuoter.split("[1,false,\"true\"]");
+    if (GWT.isScript()) {
+      assertTrue("s should be JsoSplittable", s instanceof JsoSplittable);
+      assertTrue("s[0] should be JsoSplittable", s.get(0) instanceof JsoSplittable);
+      assertTrue("s[1] should be JsoSplittable", s.get(1) instanceof JsoSplittable);
+      assertTrue("s[2] should be JsoSplittable", s.get(2) instanceof JsoSplittable);
+    } else {
+      // Using the same types in both pure-JRE and DevMode to avoid JSNI
+      // overhead
+      assertTrue("s should be JsonSplittable", s.getClass().getName().endsWith("JsonSplittable"));
+      assertTrue("s[0] should be JsonSplittable", s.get(0).getClass().getName().endsWith(
+          "JsonSplittable"));
+      assertTrue("s[1] should be JsonSplittable", s.get(1).getClass().getName().endsWith(
+          "JsonSplittable"));
+      assertTrue("s[2] should be JsonSplittable", s.get(2).getClass().getName().endsWith(
+          "JsonSplittable"));
+    }
+  }
+
+  public void testIndexed() {
+    Splittable s = StringQuoter.createIndexed();
+    assertTrue(s.isIndexed());
+    assertFalse(s.isKeyed());
+    assertFalse(s.isString());
+    assertEquals(0, s.size());
+
+    string("foo").assign(s, 0);
+    string("bar").assign(s, 1);
+    string("baz").assign(s, 2);
+
+    assertEquals(3, s.size());
+    assertEquals("[\"foo\",\"bar\",\"baz\"]", s.getPayload());
+
+    string("quux").assign(s, 1);
+    assertEquals("[\"foo\",\"quux\",\"baz\"]", s.getPayload());
+
+    Splittable s2 = s.deepCopy();
+    assertNotSame(s, s2);
+    assertEquals(s.size(), s2.size());
+    for (int i = 0, j = s.size(); i < j; i++) {
+      assertEquals(s.get(i).asString(), s2.get(i).asString());
+    }
+
+    s.setSize(2);
+    assertEquals(2, s.size());
+    assertEquals("[\"foo\",\"quux\"]", s.getPayload());
+
+    // Make sure reified values aren't in the payload
+    Object o = new Object();
+    s.setReified("reified", o);
+    assertFalse(s.getPayload().contains("reified"));
+    assertFalse(s.getPayload().contains("__s"));
+    assertSame(o, s.getReified("reified"));
+  }
+
+  public void testKeyed() {
+    Splittable s = StringQuoter.createSplittable();
+    assertFalse(s.isIndexed());
+    assertTrue(s.isKeyed());
+    assertFalse(s.isString());
+    assertTrue(s.getPropertyKeys().isEmpty());
+
+    string("bar").assign(s, "foo");
+    string("quux").assign(s, "baz");
+
+    // Actual iteration order is undefined
+    assertEquals(new HashSet<String>(Arrays.asList("foo", "baz")), new HashSet<String>(s
+        .getPropertyKeys()));
+
+    assertFalse(s.isNull("foo"));
+    assertTrue(s.isNull("bar"));
+
+    assertEquals("bar", s.get("foo").asString());
+    assertEquals("quux", s.get("baz").asString());
+
+    String payload = s.getPayload();
+    assertTrue(payload.startsWith("{"));
+    assertTrue(payload.endsWith("}"));
+    assertTrue(payload.contains("\"foo\":\"bar\""));
+    assertTrue(payload.contains("\"baz\":\"quux\""));
+
+    Splittable s2 = s.deepCopy();
+    assertNotSame(s, s2);
+    assertEquals("bar", s2.get("foo").asString());
+    assertEquals("quux", s2.get("baz").asString());
+
+    // Make sure reified values aren't in the payload
+    Object o = new Object();
+    s.setReified("reified", o);
+    assertFalse("Should not see reified in " + s.getPayload(), s.getPayload().contains("reified"));
+    assertFalse("Should not see __s in " + s.getPayload(), s.getPayload().contains("__s"));
+    assertSame(o, s.getReified("reified"));
+  }
+
+  public void testNested() {
+    Splittable s = StringQuoter.split("{\"a\":{\"foo\":\"bar\"}}");
+    Splittable a = s.get("a");
+    assertNotNull(a);
+    assertEquals("bar", a.get("foo").asString());
+    assertSame(a, s.get("a"));
+    assertEquals(a, s.get("a"));
+  }
+
+  /**
+   * Tests attributes of the {@link Splittable#NULL} field.
+   */
+  public void testNull() {
+    Splittable n = Splittable.NULL;
+    if (GWT.isScript()) {
+      assertNull(n);
+    } else {
+      assertNotNull(n);
+    }
+    assertFalse("boolean", n.isBoolean());
+    assertFalse("indexed", n.isIndexed());
+    assertFalse("keyed", n.isKeyed());
+    assertFalse("string", n.isString());
+    assertEquals("null", n.getPayload());
+  }
+
+  /**
+   * Extra tests in here due to potential to confuse {@code false} and
+   * {@code null} values.
+   */
+  public void testSplittableListBoolean() {
+    Coder boolCoder = AutoBeanCodexImpl.valueCoder(Boolean.class);
+    Splittable s = StringQuoter.createIndexed();
+    bool(false).assign(s, 0);
+    assertFalse("0 should not be null", s.isNull(0));
+    assertTrue("s[0] should be a boolean", s.get(0).isBoolean());
+    assertFalse("s[0] should be false", s.get(0).asBoolean());
+    assertNotNull("Null decode", ValueCodex.decode(Boolean.class, s.get(0)));
+    Object decodedBoolean = boolCoder.decode(testState, s.get(0));
+    assertNotNull("decode should not return null", decodedBoolean);
+    assertFalse("decoded value should be false", (Boolean) decodedBoolean);
+
+    bool(true).assign(s, 1);
+    assertTrue("s[1] should be a boolean", s.get(1).isBoolean());
+    assertTrue("s[1] should be true", s.get(1).asBoolean());
+    assertTrue("boolCoder 1", (Boolean) boolCoder.decode(testState, s.get(1)));
+
+    Splittable.NULL.assign(s, 2);
+    assertTrue("3 should be null", s.isNull(3));
+    assertEquals("payload", "[false,true,null]", s.getPayload());
+    List<Boolean> boolList = new SplittableList<Boolean>(s, boolCoder, testState);
+    assertEquals("boolList", Arrays.<Boolean> asList(false, true, null), boolList);
+  }
+
+  /**
+   * Extra tests in here due to potential to confuse 0 and {@code null} values.
+   */
+  public void testSplittableListNumbers() {
+    Coder intCoder = AutoBeanCodexImpl.valueCoder(Integer.class);
+    Coder doubleCoder = AutoBeanCodexImpl.valueCoder(Double.class);
+    Splittable s = StringQuoter.createIndexed();
+    number(0).assign(s, 0);
+    assertFalse("0 should not be null", s.isNull(0));
+    assertTrue("s[0] should be a number", s.get(0).isNumber());
+    assertNotNull("Null decode", ValueCodex.decode(Integer.class, s.get(0)));
+    Object decodedInt = intCoder.decode(testState, s.get(0));
+    assertNotNull("decode should not return null", decodedInt);
+    assertEquals("intCoder 0", Integer.valueOf(0), decodedInt);
+    assertEquals("doubleCoder 0", Double.valueOf(0), doubleCoder.decode(testState, s.get(0)));
+
+    number(3.141592).assign(s, 1);
+    assertEquals("intCoder 1", Integer.valueOf(3), intCoder.decode(testState, s.get(1)));
+    assertEquals("doubleCoder 1", Double.valueOf(3.141592), doubleCoder.decode(testState, s.get(1)));
+
+    number(42).assign(s, 2);
+    Splittable.NULL.assign(s, 3);
+    assertTrue("3 should be null", s.isNull(3));
+    assertEquals("payload", "[0,3.141592,42,null]", s.getPayload());
+    List<Double> doubleList = new SplittableList<Double>(s, doubleCoder, testState);
+    assertEquals(Double.valueOf(0), doubleList.get(0));
+    assertEquals("doubleList", Arrays.<Double> asList(0d, 3.141592, 42d, null), doubleList);
+
+    // Don't share backing data between lists
+    s = StringQuoter.split("[0,3.141592,42,null]");
+    List<Integer> intList = new SplittableList<Integer>(s, intCoder, testState);
+    assertEquals("intList", Arrays.<Integer> asList(0, 3, 42, null), intList);
+  }
+
+  public void testSplittableListString() {
+    Splittable data = StringQuoter.split("[\"Hello\",\"World\"]");
+    SplittableList<String> list =
+        new SplittableList<String>(data, AutoBeanCodexImpl.valueCoder(String.class), testState);
+    assertEquals(2, list.size());
+    assertEquals(Arrays.asList("Hello", "World"), list);
+    list.set(0, "Goodbye");
+    assertEquals(Arrays.asList("Goodbye", "World"), list);
+    assertEquals("[\"Goodbye\",\"World\"]", data.getPayload());
+    list.remove(0);
+    assertEquals(Arrays.asList("World"), list);
+    assertEquals("[\"World\"]", data.getPayload());
+    list.add("Wide");
+    list.add("Web");
+    assertEquals(Arrays.asList("World", "Wide", "Web"), list);
+    assertEquals("[\"World\",\"Wide\",\"Web\"]", data.getPayload());
+  }
+
+  public void testSplittableMapStringString() {
+    Splittable data = StringQuoter.split("{\"foo\":\"bar\",\"baz\":\"quux\",\"isNull\":null}");
+    assertTrue("isNull should be null", data.isNull("isNull"));
+    assertFalse("isNull should not be undefined", data.isUndefined("isNull"));
+    Map<String, String> map =
+        new SplittableSimpleMap<String, String>(data, AutoBeanCodexImpl.valueCoder(String.class),
+            AutoBeanCodexImpl.valueCoder(String.class), testState);
+    assertEquals(3, map.size());
+    assertEquals("bar", map.get("foo"));
+    assertEquals("quux", map.get("baz"));
+    assertTrue("Map should have isNull key", map.containsKey("isNull"));
+    assertNull(map.get("isNull"));
+    assertFalse("Map should not have unknown key", map.containsKey("unknown"));
+
+    map.put("bar", "foo2");
+    assertEquals("foo2", map.get("bar"));
+    String payload = data.getPayload();
+    assertTrue(payload.contains("\"bar\":\"foo2\""));
+    assertTrue(payload.contains("\"isNull\":null"));
+  }
+
+  public void testString() {
+    Splittable s = string("Hello '\" World!");
+    assertFalse(s.isIndexed());
+    assertFalse(s.isKeyed());
+    assertTrue(s.isString());
+    assertEquals("Hello '\" World!", s.asString());
+    assertEquals("\"Hello '\\\" World!\"", s.getPayload());
+  }
+
+  public void testStringEmpty() {
+    Splittable s = string("");
+    assertFalse(s.isIndexed());
+    assertFalse(s.isKeyed());
+    assertTrue(s.isString());
+    assertEquals("", s.asString());
+    assertEquals("\"\"", s.getPayload());
+  }
+
+  private Splittable bool(boolean value) {
+    return StringQuoter.split(String.valueOf(value));
+  }
+
+  private Splittable number(double number) {
+    return StringQuoter.split(String.valueOf(number));
+  }
+
+  private Splittable string(String value) {
+    return StringQuoter.split(StringQuoter.quote(value));
+  }
+}