Revision: 8321
Author: jlaba...@google.com
Date: Mon Jun 28 07:32:05 2010
Log: DefaultSelectionModel#setSelected currently adds an exception even if the default selection state equals the specified state. Also adds test cases for all selection models.

Review at http://gwt-code-reviews.appspot.com/658801

Review by: j...@google.com
http://code.google.com/p/google-web-toolkit/source/detail?r=8321

Added:
 /trunk/user/test/com/google/gwt/view/ViewSuite.java
 /trunk/user/test/com/google/gwt/view/client/AbstractSelectionModelTest.java
 /trunk/user/test/com/google/gwt/view/client/DefaultSelectionModelTest.java
 /trunk/user/test/com/google/gwt/view/client/MultiSelectionModelTest.java
 /trunk/user/test/com/google/gwt/view/client/SingleSelectionModelTest.java
Modified:
 /trunk/user/src/com/google/gwt/view/client/DefaultSelectionModel.java
 /trunk/user/src/com/google/gwt/view/client/SelectionModel.java

=======================================
--- /dev/null
+++ /trunk/user/test/com/google/gwt/view/ViewSuite.java Mon Jun 28 07:32:05 2010
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010 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.view;
+
+import com.google.gwt.junit.tools.GWTTestSuite;
+import com.google.gwt.view.client.AbstractListViewAdapterTest;
+import com.google.gwt.view.client.AbstractSelectionModelTest;
+import com.google.gwt.view.client.AsyncListViewAdapterTest;
+import com.google.gwt.view.client.DefaultNodeInfoTest;
+import com.google.gwt.view.client.DefaultSelectionModelTest;
+import com.google.gwt.view.client.MultiSelectionModelTest;
+import com.google.gwt.view.client.RangeTest;
+import com.google.gwt.view.client.SingleSelectionModelTest;
+
+import junit.framework.Test;
+
+/**
+ * Tests of the view package.
+ */
+public class ViewSuite {
+  public static Test suite() {
+ GWTTestSuite suite = new GWTTestSuite("Test suite for all view classes");
+
+    suite.addTestSuite(AbstractListViewAdapterTest.class);
+    suite.addTestSuite(AbstractSelectionModelTest.class);
+    suite.addTestSuite(AsyncListViewAdapterTest.class);
+    suite.addTestSuite(DefaultNodeInfoTest.class);
+    suite.addTestSuite(DefaultSelectionModelTest.class);
+    suite.addTestSuite(MultiSelectionModelTest.class);
+    suite.addTestSuite(RangeTest.class);
+    suite.addTestSuite(SingleSelectionModelTest.class);
+    return suite;
+  }
+}
=======================================
--- /dev/null
+++ /trunk/user/test/com/google/gwt/view/client/AbstractSelectionModelTest.java Mon Jun 28 07:32:05 2010
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2010 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.view.client;
+
+import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.user.client.Timer;
+import com.google.gwt.view.client.SelectionModel.AbstractSelectionModel;
+import com.google.gwt.view.client.SelectionModel.SelectionChangeEvent;
+import com.google.gwt.view.client.SelectionModel.SelectionChangeHandler;
+
+/**
+ * Tests for {...@link AbstractSelectionModel}.
+ */
+public class AbstractSelectionModelTest extends GWTTestCase {
+
+  /**
+   * A mock {...@link SelectionChangeHandler} used for testing.
+   */
+  private static class MockSelectionChangeHandler implements
+      SelectionChangeHandler {
+
+    private boolean eventFired;
+
+    public void assertEventFired(boolean expected) {
+      assertEquals(expected, eventFired);
+    }
+
+    public void onSelectionChange(SelectionChangeEvent event) {
+      eventFired = true;
+    }
+  }
+
+  /**
+   * A mock {...@link SelectionModel} used for testing.
+   *
+   * @param <T> the data type
+   */
+ private static class MockSelectionModel<T> extends AbstractSelectionModel<T> {
+    public boolean isSelected(T object) {
+      return false;
+    }
+
+    public void setSelected(T object, boolean selected) {
+    }
+  }
+
+  @Override
+  public String getModuleName() {
+    return "com.google.gwt.view.View";
+  }
+
+  public void testFireSelectionChangeEvent() {
+    AbstractSelectionModel<String> model = createSelectionModel();
+    MockSelectionChangeHandler handler = new MockSelectionChangeHandler();
+    model.addSelectionChangeHandler(handler);
+
+    model.fireSelectionChangeEvent();
+    handler.assertEventFired(true);
+  }
+
+  public void testScheduleSelectionChangeEvent() {
+    AbstractSelectionModel<String> model = createSelectionModel();
+ final MockSelectionChangeHandler handler = new MockSelectionChangeHandler() {
+      @Override
+      public void onSelectionChange(SelectionChangeEvent event) {
+        // We should only see one event fired.
+        assertEventFired(false);
+        super.onSelectionChange(event);
+      }
+    };
+    model.addSelectionChangeHandler(handler);
+
+    // Schedule the event multiple times.
+    delayTestFinish(2000);
+    model.scheduleSelectionChangeEvent();
+    model.scheduleSelectionChangeEvent();
+    model.scheduleSelectionChangeEvent();
+    model.scheduleSelectionChangeEvent();
+    model.scheduleSelectionChangeEvent();
+    model.scheduleSelectionChangeEvent();
+    handler.assertEventFired(false);
+
+    new Timer() {
+      @Override
+      public void run() {
+        handler.assertEventFired(true);
+        finishTest();
+      }
+    }.schedule(1000);
+  }
+
+  public void testSetKeyProvider() {
+    AbstractSelectionModel<String> model = createSelectionModel();
+
+    // By default, use the object as a key.
+    assertNull(model.getKeyProvider());
+    assertEquals("test", model.getKey("test"));
+    assertEquals(null, model.getKey(null));
+
+    // Defer to the key provider if one is set.
+    ProvidesKey<String> keyProvider = new ProvidesKey<String>() {
+      public Object getKey(String item) {
+        return item == null ? item : item.toUpperCase();
+      }
+    };
+    model.setKeyProvider(keyProvider);
+    assertEquals(keyProvider, model.getKeyProvider());
+    assertEquals("TEST", model.getKey("test"));
+    assertEquals(null, model.getKey(null));
+  }
+
+  protected AbstractSelectionModel<String> createSelectionModel() {
+    return new MockSelectionModel<String>();
+  }
+}
=======================================
--- /dev/null
+++ /trunk/user/test/com/google/gwt/view/client/DefaultSelectionModelTest.java Mon Jun 28 07:32:05 2010
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2010 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.view.client;
+
+import com.google.gwt.view.client.SelectionModel.SelectionChangeEvent;
+import com.google.gwt.view.client.SelectionModel.SelectionChangeHandler;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Tests for {...@link DefaultSelectionModel}.
+ */
+public class DefaultSelectionModelTest extends AbstractSelectionModelTest {
+
+  /**
+   * A mock {...@link DefaultSelectionModel} used for testing. By default, all
+   * strings that start with "selected" are selected.
+   */
+  private static class MockDefaultSelectionModel extends
+      DefaultSelectionModel<String> {
+
+    @Override
+    public boolean isDefaultSelected(String object) {
+      return object == null ? false : object.startsWith("selected");
+    }
+  }
+
+  public void testIsSelectedWithoutExceptions() {
+    DefaultSelectionModel<String> model = createSelectionModel();
+    assertFalse(model.isSelected(null));
+    assertFalse(model.isSelected("test"));
+    assertTrue(model.isSelected("selected"));
+    assertTrue(model.isSelected("selected0"));
+  }
+
+  public void testSelectedChangeEvent() {
+    DefaultSelectionModel<String> model = createSelectionModel();
+    SelectionChangeHandler handler = new SelectionChangeHandler() {
+      public void onSelectionChange(SelectionChangeEvent event) {
+        finishTest();
+      }
+    };
+    model.addSelectionChangeHandler(handler);
+
+    delayTestFinish(2000);
+    model.setSelected("test", true);
+  }
+
+  public void testSetSelectedDefault() {
+    Map<Object, Boolean> exceptions = new HashMap<Object, Boolean>();
+    DefaultSelectionModel<String> model = createSelectionModel();
+    assertTrue(model.isSelected("selected0"));
+    assertTrue(model.isSelected("selected1"));
+    assertEquals(0, model.getExceptions(exceptions).size());
+
+    model.setSelected("selected0", true);
+    assertTrue(model.isSelected("selected0"));
+    assertTrue(model.isSelected("selected1"));
+    assertEquals(0, model.getExceptions(exceptions).size());
+
+    model.setSelected("selected0", false);
+    assertFalse(model.isSelected("selected0"));
+    assertTrue(model.isSelected("selected1"));
+    assertEquals(1, model.getExceptions(exceptions).size());
+    assertFalse(exceptions.get("selected0"));
+
+    model.setSelected("selected0", true);
+    assertTrue(model.isSelected("selected0"));
+    assertTrue(model.isSelected("selected1"));
+    assertEquals(0, model.getExceptions(exceptions).size());
+  }
+
+  public void testSetSelectedNonDefault() {
+    DefaultSelectionModel<String> model = createSelectionModel();
+    assertFalse(model.isSelected("test0"));
+    assertFalse(model.isSelected("test1"));
+    assertTrue(model.isSelected("selected0"));
+
+    model.setSelected("test0", true);
+    assertTrue(model.isSelected("test0"));
+    assertFalse(model.isSelected("test1"));
+    assertTrue(model.isSelected("selected0"));
+
+    model.setSelected("test1", true);
+    assertTrue(model.isSelected("test0"));
+    assertTrue(model.isSelected("test1"));
+    assertTrue(model.isSelected("selected0"));
+
+    model.setSelected("test1", false);
+    assertTrue(model.isSelected("test0"));
+    assertFalse(model.isSelected("test1"));
+    assertTrue(model.isSelected("selected0"));
+  }
+
+  public void testSetSelectedWithKeyProvider() {
+    Map<Object, Boolean> exceptions = new HashMap<Object, Boolean>();
+    DefaultSelectionModel<String> model = createSelectionModel();
+    ProvidesKey<String> keyProvider = new ProvidesKey<String>() {
+      public Object getKey(String item) {
+        return item.toUpperCase();
+      }
+    };
+    model.setKeyProvider(keyProvider);
+    assertFalse(model.isSelected("test"));
+    assertTrue(model.isSelected("selected0"));
+    assertFalse(model.isSelected("SELECTED0"));
+    assertTrue(model.isSelected("selected1"));
+    assertEquals(0, model.getExceptions(exceptions).size());
+
+    model.setSelected("selected0", true);
+    assertFalse(model.isSelected("test"));
+    assertTrue(model.isSelected("selected0"));
+    assertFalse(model.isSelected("SELECTED0"));
+    assertTrue(model.isSelected("selected1"));
+    assertEquals(0, model.getExceptions(exceptions).size());
+
+    model.setSelected("selected0", false);
+    assertFalse(model.isSelected("test"));
+    assertFalse(model.isSelected("selected0"));
+    assertFalse(model.isSelected("SELECTED0"));
+    assertTrue(model.isSelected("selected1"));
+    assertEquals(1, model.getExceptions(exceptions).size());
+    assertFalse(exceptions.get("SELECTED0"));
+
+    model.setSelected("selected0", true);
+    assertFalse(model.isSelected("test"));
+    assertTrue(model.isSelected("selected0"));
+    assertTrue(model.isSelected("selected1"));
+    assertEquals(0, model.getExceptions(exceptions).size());
+
+    model.setSelected("test", true);
+    assertTrue(model.isSelected("test"));
+    assertTrue(model.isSelected("selected0"));
+    assertTrue(model.isSelected("selected1"));
+    assertEquals(1, model.getExceptions(exceptions).size());
+    assertTrue(exceptions.get("TEST"));
+
+    model.setSelected("test", false);
+    assertFalse(model.isSelected("test"));
+    assertTrue(model.isSelected("selected0"));
+    assertTrue(model.isSelected("selected1"));
+    assertEquals(0, model.getExceptions(exceptions).size());
+  }
+
+  @Override
+  protected DefaultSelectionModel<String> createSelectionModel() {
+    return new MockDefaultSelectionModel();
+  }
+}
=======================================
--- /dev/null
+++ /trunk/user/test/com/google/gwt/view/client/MultiSelectionModelTest.java Mon Jun 28 07:32:05 2010
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2010 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.view.client;
+
+import com.google.gwt.view.client.SelectionModel.SelectionChangeEvent;
+import com.google.gwt.view.client.SelectionModel.SelectionChangeHandler;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Tests for {...@link MultiSelectionModel}.
+ */
+public class MultiSelectionModelTest extends AbstractSelectionModelTest {
+
+  public void testGetSelectedSet() {
+    MultiSelectionModel<String> model = createSelectionModel();
+    Set<String> selected = new HashSet<String>();
+    assertEquals(selected, model.getSelectedSet());
+
+    model.setSelected("test0", true);
+    selected.add("test0");
+    assertEquals(selected, model.getSelectedSet());
+
+    model.setSelected("test1", true);
+    selected.add("test1");
+    assertEquals(selected, model.getSelectedSet());
+
+    model.setSelected("test0", false);
+    selected.remove("test0");
+    assertEquals(selected, model.getSelectedSet());
+  }
+
+  public void testSelectedChangeEvent() {
+    MultiSelectionModel<String> model = createSelectionModel();
+    SelectionChangeHandler handler = new SelectionChangeHandler() {
+      public void onSelectionChange(SelectionChangeEvent event) {
+        finishTest();
+      }
+    };
+    model.addSelectionChangeHandler(handler);
+
+    delayTestFinish(2000);
+    model.setSelected("test", true);
+  }
+
+  public void testSetSelected() {
+    MultiSelectionModel<String> model = createSelectionModel();
+    assertFalse(model.isSelected("test0"));
+
+    model.setSelected("test0", true);
+    assertTrue(model.isSelected("test0"));
+
+    model.setSelected("test1", true);
+    assertTrue(model.isSelected("test1"));
+    assertTrue(model.isSelected("test0"));
+
+    model.setSelected("test1", false);
+    assertFalse(model.isSelected("test1"));
+    assertTrue(model.isSelected("test0"));
+  }
+
+  public void testSetSelectedWithKeyProvider() {
+    MultiSelectionModel<String> model = createSelectionModel();
+    ProvidesKey<String> keyProvider = new ProvidesKey<String>() {
+      public Object getKey(String item) {
+        return item.toUpperCase();
+      }
+    };
+    model.setKeyProvider(keyProvider);
+    assertFalse(model.isSelected("test0"));
+
+    model.setSelected("test0", true);
+    assertTrue(model.isSelected("test0"));
+    assertTrue(model.isSelected("TEST0"));
+
+    model.setSelected("test1", true);
+    assertTrue(model.isSelected("test1"));
+    assertTrue(model.isSelected("TEST1"));
+    assertTrue(model.isSelected("test0"));
+    assertTrue(model.isSelected("TEST0"));
+
+    model.setSelected("test1", false);
+    assertFalse(model.isSelected("test1"));
+    assertFalse(model.isSelected("TEST1"));
+    assertTrue(model.isSelected("test0"));
+    assertTrue(model.isSelected("TEST0"));
+  }
+
+  @Override
+  protected MultiSelectionModel<String> createSelectionModel() {
+    return new MultiSelectionModel<String>();
+  }
+}
=======================================
--- /dev/null
+++ /trunk/user/test/com/google/gwt/view/client/SingleSelectionModelTest.java Mon Jun 28 07:32:05 2010
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2010 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.view.client;
+
+import com.google.gwt.view.client.SelectionModel.SelectionChangeEvent;
+import com.google.gwt.view.client.SelectionModel.SelectionChangeHandler;
+
+/**
+ * Tests for {...@link SingleSelectionModel}.
+ */
+public class SingleSelectionModelTest extends AbstractSelectionModelTest {
+
+  public void testGetSelectedObject() {
+    SingleSelectionModel<String> model = createSelectionModel();
+    assertNull(model.getSelectedObject());
+
+    model.setSelected("test", true);
+    assertEquals("test", model.getSelectedObject());
+
+    model.setSelected("test", false);
+    assertNull(model.getSelectedObject());
+  }
+
+  public void testSelectedChangeEvent() {
+    SingleSelectionModel<String> model = createSelectionModel();
+    SelectionChangeHandler handler = new SelectionChangeHandler() {
+      public void onSelectionChange(SelectionChangeEvent event) {
+        finishTest();
+      }
+    };
+    model.addSelectionChangeHandler(handler);
+
+    delayTestFinish(2000);
+    model.setSelected("test", true);
+  }
+
+  public void testSetSelected() {
+    SingleSelectionModel<String> model = createSelectionModel();
+    assertFalse(model.isSelected("test0"));
+
+    model.setSelected("test0", true);
+    assertTrue(model.isSelected("test0"));
+
+    model.setSelected("test1", true);
+    assertTrue(model.isSelected("test1"));
+    assertFalse(model.isSelected("test0"));
+
+    model.setSelected("test1", false);
+    assertFalse(model.isSelected("test1"));
+    assertFalse(model.isSelected("test0"));
+  }
+
+  public void testSetSelectedWithKeyProvider() {
+    SingleSelectionModel<String> model = createSelectionModel();
+    ProvidesKey<String> keyProvider = new ProvidesKey<String>() {
+      public Object getKey(String item) {
+        return item.toUpperCase();
+      }
+    };
+    model.setKeyProvider(keyProvider);
+    assertFalse(model.isSelected("test0"));
+
+    model.setSelected("test0", true);
+    assertTrue(model.isSelected("test0"));
+    assertTrue(model.isSelected("TEST0"));
+
+    model.setSelected("test1", true);
+    assertTrue(model.isSelected("test1"));
+    assertTrue(model.isSelected("TEST1"));
+    assertFalse(model.isSelected("test0"));
+
+    model.setSelected("test1", false);
+    assertFalse(model.isSelected("test1"));
+    assertFalse(model.isSelected("test0"));
+  }
+
+  @Override
+  protected SingleSelectionModel<String> createSelectionModel() {
+    return new SingleSelectionModel<String>();
+  }
+}
=======================================
--- /trunk/user/src/com/google/gwt/view/client/DefaultSelectionModel.java Tue Jun 22 05:03:01 2010 +++ /trunk/user/src/com/google/gwt/view/client/DefaultSelectionModel.java Mon Jun 28 07:32:05 2010
@@ -73,12 +73,11 @@
    */
   public void setSelected(T object, boolean selected) {
     Object key = getKey(object);
-    Boolean currentlySelected = exceptions.get(key);
-    if (currentlySelected != null
-        && currentlySelected.booleanValue() != selected) {
-      exceptions.remove(key);
-    } else {
+    if (isDefaultSelected(object) != selected) {
+ // If the state is different than the default state, add an exception.
       exceptions.put(key, selected);
+    } else {
+      exceptions.remove(key);
     }

     scheduleSelectionChangeEvent();
=======================================
--- /trunk/user/src/com/google/gwt/view/client/SelectionModel.java Fri May 28 08:44:36 2010 +++ /trunk/user/src/com/google/gwt/view/client/SelectionModel.java Mon Jun 28 07:32:05 2010
@@ -110,6 +110,11 @@

     private final HandlerManager handlerManager = new HandlerManager(this);

+    /**
+     * Set to true if the next scheduled event should be cancelled.
+     */
+    private boolean isEventCancelled;
+
     /**
      * Set to true if an event is scheduled to be fired.
      */
@@ -145,18 +150,30 @@
     public void setKeyProvider(ProvidesKey<T> keyProvider) {
       this.keyProvider = keyProvider;
     }
+
+    protected void fireSelectionChangeEvent() {
+      if (isEventScheduled) {
+        isEventCancelled = true;
+      }
+      SelectionChangeEvent.fire(AbstractSelectionModel.this);
+    }

     /**
* Schedules a {...@link SelectionModel.SelectionChangeEvent} to fire at the
      * end of the current event loop.
      */
     protected void scheduleSelectionChangeEvent() {
+      isEventCancelled = false;
       if (!isEventScheduled) {
         isEventScheduled = true;
         Scheduler.get().scheduleFinally(new ScheduledCommand() {
           public void execute() {
             isEventScheduled = false;
-            SelectionChangeEvent.fire(AbstractSelectionModel.this);
+            if (isEventCancelled) {
+              isEventCancelled = false;
+              return;
+            }
+            fireSelectionChangeEvent();
           }
         });
       }

--
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to