From 15bac5d7815a2fd4eec7155e5c119ba8dab58fc7 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 19 Apr 2010 13:42:28 +0000 Subject: [PATCH] Merged fixes from 6.3: * Build updates * Fixes for #4418,#4562,#4514,#4536,#4533 * Test case updates * DevelopmentServerLauncher fix svn changeset:12649/svn branch:6.4 --- build/build.xml | 1 + src/com/vaadin/data/Container.java | 17 +- .../vaadin/data/util/BeanItemContainer.java | 3 +- src/com/vaadin/data/util/ListSet.java | 84 +++- .../vaadin/event/DataBoundTransferable.java | 9 +- src/com/vaadin/event/dd/DropHandler.java | 5 +- src/com/vaadin/event/dd/DropTarget.java | 5 +- src/com/vaadin/event/dd/TargetDetails.java | 4 +- .../dd/acceptcriteria/AcceptCriterion.java | 8 +- .../launcher/DevelopmentServerLauncher.java | 6 +- src/com/vaadin/launcher/jetty-webdefault.xml | 402 ++++++++++++++++++ .../terminal/gwt/client/VBrowserDetails.java | 78 ++-- .../server/AbstractCommunicationManager.java | 6 + .../tests/components/select/MultiSelect.java | 31 ++ .../components/select/NativeSelects.html | 177 ++++++++ .../components/select/NativeSelects.java | 153 +++++++ .../tests/components/table/TableSorting.java | 67 +++ .../tests/server/BrowserUserAgentParser.java | 18 + .../container/BeanItemContainerSortTest.java | 35 +- 19 files changed, 1040 insertions(+), 69 deletions(-) create mode 100644 src/com/vaadin/launcher/jetty-webdefault.xml create mode 100644 tests/src/com/vaadin/tests/components/select/MultiSelect.java create mode 100644 tests/src/com/vaadin/tests/components/select/NativeSelects.html create mode 100644 tests/src/com/vaadin/tests/components/select/NativeSelects.java create mode 100644 tests/src/com/vaadin/tests/components/table/TableSorting.java diff --git a/build/build.xml b/build/build.xml index 71f32c3ee5..d3b8f02370 100644 --- a/build/build.xml +++ b/build/build.xml @@ -676,6 +676,7 @@ + diff --git a/src/com/vaadin/data/Container.java b/src/com/vaadin/data/Container.java index 6dbcfe779f..874b683eb4 100644 --- a/src/com/vaadin/data/Container.java +++ b/src/com/vaadin/data/Container.java @@ -573,10 +573,9 @@ public interface Container extends Serializable { * visible in the container. *

*

- * When an {@link com.vaadin.data.Ordered} or - * {@link com.vaadin.data.Indexed} container is filtered, all operations of - * these interfaces should only use the filtered contents and the filtered - * indices to the container. + * When an {@link Ordered} or {@link Indexed} container is filtered, all + * operations of these interfaces should only use the filtered contents and + * the filtered indices to the container. *

*

* How filtering is performed when a {@link Hierarchical} container @@ -584,11 +583,11 @@ public interface Container extends Serializable { * documented in the implementing class. *

*

- * Adding items (if supported) to a filtered {@link com.vaadin.data.Ordered} - * or {@link com.vaadin.data.Indexed} container should insert them - * immediately after the indicated visible item. The unfiltered position of - * items added at index 0, at index {@link com.vaadin.data.Container#size()} - * or at an undefined position is up to the implementation. + * Adding items (if supported) to a filtered {@link Ordered} or + * {@link Indexed} container should insert them immediately after the + * indicated visible item. The unfiltered position of items added at index + * 0, at index {@link com.vaadin.data.Container#size()} or at an undefined + * position is up to the implementation. *

* * @since 5.0 diff --git a/src/com/vaadin/data/util/BeanItemContainer.java b/src/com/vaadin/data/util/BeanItemContainer.java index 3e3c4a5538..e99f219dbb 100644 --- a/src/com/vaadin/data/util/BeanItemContainer.java +++ b/src/com/vaadin/data/util/BeanItemContainer.java @@ -444,7 +444,8 @@ public class BeanItemContainer implements Indexed, Sortable, Filterable, LinkedList sortables = new LinkedList(); for (Object propertyId : getContainerPropertyIds()) { Class propertyType = getType(propertyId); - if (Comparable.class.isAssignableFrom(propertyType)) { + if (Comparable.class.isAssignableFrom(propertyType) + || propertyType.isPrimitive()) { sortables.add(propertyId); } } diff --git a/src/com/vaadin/data/util/ListSet.java b/src/com/vaadin/data/util/ListSet.java index 0a3d954a3e..4c689ec361 100644 --- a/src/com/vaadin/data/util/ListSet.java +++ b/src/com/vaadin/data/util/ListSet.java @@ -5,20 +5,30 @@ package com.vaadin.data.util; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; /** * ListSet is an internal Vaadin class which implements a combination of a List - * and a Set. The main purpose of this class is to provide a fast + * and a Set. The main purpose of this class is to provide a list with a fast * {@link #contains(Object)} method. Each inserted object must by unique (as - * specified by {@link #equals(Object)}). + * specified by {@link #equals(Object)}). The {@link #set(int, Object)} method + * allows duplicates because of the way {@link Collections#sort(java.util.List)} + * works. * * This class is subject to change and should not be used outside Vaadin core. */ public class ListSet extends ArrayList { private HashSet itemSet = null; + /** + * Contains a map from an element to the number of duplicates it has. Used + * to temporarily allow duplicates in the list. + */ + private HashMap duplicates = new HashMap(); + public ListSet() { super(); itemSet = new HashSet(); @@ -35,7 +45,7 @@ public class ListSet extends ArrayList { itemSet = new HashSet(initialCapacity); } - // Delegate contains operations to the set + // Delegate contains operations to the set @Override public boolean contains(Object o) { return itemSet.contains(o); @@ -46,11 +56,11 @@ public class ListSet extends ArrayList { return itemSet.containsAll(c); } - // Methods for updating the set when the list is updated. + // Methods for updating the set when the list is updated. @Override public boolean add(E e) { if (contains(e)) { - // Duplicates are not allowed + // Duplicates are not allowed return false; } @@ -69,7 +79,7 @@ public class ListSet extends ArrayList { @Override public void add(int index, E element) { if (contains(element)) { - // Duplicates are not allowed + // Duplicates are not allowed return; } @@ -173,20 +183,76 @@ public class ListSet extends ArrayList { @Override public E set(int index, E element) { if (contains(element)) { - // Element already exist in the list + // Element already exist in the list if (get(index) == element) { - // At the same position, nothing to be done + // At the same position, nothing to be done return element; + } else { + // Adding at another position. We assume this is a sort + // operation and temporarily allow it. + + // We could just remove (null) the old element and keep the list + // unique. This would require finding the index of the old + // element (indexOf(element)) which is not a fast operation in a + // list. So we instead allow duplicates temporarily. + addDuplicate(element); } } E old = super.set(index, element); - itemSet.remove(old); + removeFromSet(old); itemSet.add(element); return old; } + /** + * Removes "e" from the set if it no longer exists in the list. + * + * @param e + */ + private void removeFromSet(E e) { + Integer dupl = duplicates.get(e); + if (dupl != null) { + // A duplicate was present so we only decrement the duplicate count + // and continue + if (dupl == 1) { + // This is what always should happen. A sort sets the items one + // by one, temporarily breaking the uniqueness requirement. + duplicates.remove(e); + } else { + duplicates.put(e, dupl - 1); + } + } else { + // The "old" value is no longer in the list. + itemSet.remove(e); + } + + } + + /** + * Marks the "element" can be found more than once from the list. Allowed in + * {@link #set(int, Object)} to make sorting work. + * + * @param element + */ + private void addDuplicate(E element) { + Integer nr = duplicates.get(element); + if (nr == null) { + nr = 1; + } else { + nr++; + } + + /* + * Store the number of duplicates of this element so we know later on if + * we should remove an element from the set or if it was a duplicate (in + * removeFromSet) + */ + duplicates.put(element, nr); + + } + @SuppressWarnings("unchecked") @Override public Object clone() { diff --git a/src/com/vaadin/event/DataBoundTransferable.java b/src/com/vaadin/event/DataBoundTransferable.java index edef4c4427..8fb3143e7a 100644 --- a/src/com/vaadin/event/DataBoundTransferable.java +++ b/src/com/vaadin/event/DataBoundTransferable.java @@ -14,7 +14,8 @@ import com.vaadin.ui.Component; * (identified by its Id) and optionally also a property identifier (e.g. a * table column identifier when transferring a single table cell). * - * The component must implement the interface {@link Container.Viewer}. + * The component must implement the interface + * {@link com.vaadin.data.Container.Viewer}. * * In most cases, receivers of data transfers should depend on this class * instead of its concrete subclasses. @@ -47,13 +48,13 @@ public abstract class DataBoundTransferable extends TransferableImpl { /** * Returns the container data source from which the transfer occurs. * - * {@link Container.Viewer#getContainerDataSource()} is used to obtain the - * underlying container of the source component. + * {@link com.vaadin.data.Container.Viewer#getContainerDataSource()} is used + * to obtain the underlying container of the source component. * * @return Container */ public Container getSourceContainer() { - Component sourceComponent = getSourceComponent(); + Component sourceComponent = getSourceComponent(); if (sourceComponent instanceof Container.Viewer) { return ((Container.Viewer) sourceComponent) .getContainerDataSource(); diff --git a/src/com/vaadin/event/dd/DropHandler.java b/src/com/vaadin/event/dd/DropHandler.java index c9a28b5343..c0176207ed 100644 --- a/src/com/vaadin/event/dd/DropHandler.java +++ b/src/com/vaadin/event/dd/DropHandler.java @@ -14,8 +14,9 @@ import com.vaadin.event.dd.acceptcriteria.ServerSideCriterion; * DropHandlers contain the actual business logic for drag and drop operations. *

* The {@link #drop(DragAndDropEvent)} method is used to receive the transferred - * data and the #getAcceptCriterion()} method contains the (possibly client side - * verifiable) criterion whether the dragged data will be handled at all. + * data and the {@link #getAcceptCriterion()} method contains the (possibly + * client side verifiable) criterion whether the dragged data will be handled at + * all. * * @since 6.3 * diff --git a/src/com/vaadin/event/dd/DropTarget.java b/src/com/vaadin/event/dd/DropTarget.java index 31c6754f6f..fcb9670f6f 100644 --- a/src/com/vaadin/event/dd/DropTarget.java +++ b/src/com/vaadin/event/dd/DropTarget.java @@ -27,12 +27,11 @@ public interface DropTarget extends Component { * {@link DropHandler}. Implementation may for exmaple translate the drop * target details provided by the client side (drop target) to meaningful * server side values. If null is returned the terminal implementation will - * automatically create a {@link TargetDetails} with raw client side - * data. + * automatically create a {@link TargetDetails} with raw client side data. * * @see DragSource#getTransferable(Map) * - * @param rawVariables + * @param clientVariables * data passed from the DropTargets client side counterpart. * @return A DropTargetDetails object with the translated data or null to * use a default implementation. diff --git a/src/com/vaadin/event/dd/TargetDetails.java b/src/com/vaadin/event/dd/TargetDetails.java index f83edf84d1..bd2e41c63c 100644 --- a/src/com/vaadin/event/dd/TargetDetails.java +++ b/src/com/vaadin/event/dd/TargetDetails.java @@ -22,10 +22,10 @@ import com.vaadin.ui.Tree.TreeTargetDetails; public interface TargetDetails extends Serializable { /** - * Gets target data associated to given string key + * Gets target data associated with the given string key * * @param key - * @return + * @return The data associated with the key */ public Object getData(String key); diff --git a/src/com/vaadin/event/dd/acceptcriteria/AcceptCriterion.java b/src/com/vaadin/event/dd/acceptcriteria/AcceptCriterion.java index a2b631de56..6370ddad01 100644 --- a/src/com/vaadin/event/dd/acceptcriteria/AcceptCriterion.java +++ b/src/com/vaadin/event/dd/acceptcriteria/AcceptCriterion.java @@ -62,11 +62,11 @@ public interface AcceptCriterion extends Serializable { public void paintResponse(PaintTarget target) throws PaintException; /** - * Validates the data in event to be appropriate for - * {@link DropHandler#drop(com.vaadin.event.dd.DropEvent)} method. + * Validates the data in event to be appropriate for the + * {@link DropHandler#drop(DragAndDropEvent)} method. *

- * Note that even if your criterion is matched on client side, it is a very - * good manner to validate the data on server side too. + * Note that even if your criterion is validated on client side, you should + * always validate the data on server side too. * * @param dragEvent * @return diff --git a/src/com/vaadin/launcher/DevelopmentServerLauncher.java b/src/com/vaadin/launcher/DevelopmentServerLauncher.java index bf17002436..ef02f8817f 100644 --- a/src/com/vaadin/launcher/DevelopmentServerLauncher.java +++ b/src/com/vaadin/launcher/DevelopmentServerLauncher.java @@ -4,6 +4,7 @@ package com.vaadin.launcher; +import java.io.File; import java.util.HashMap; import java.util.Map; @@ -82,9 +83,12 @@ public class DevelopmentServerLauncher { server.setConnectors(new Connector[] { connector }); final WebAppContext webappcontext = new WebAppContext(); + String path = DevelopmentServerLauncher.class.getPackage() + .getName().replace(".", File.separator); + webappcontext.setDefaultsDescriptor(path + File.separator + + "jetty-webdefault.xml"); webappcontext.setContextPath(serverArgs.get("context")); webappcontext.setWar(serverArgs.get("webroot")); - server.setHandler(webappcontext); server.start(); diff --git a/src/com/vaadin/launcher/jetty-webdefault.xml b/src/com/vaadin/launcher/jetty-webdefault.xml new file mode 100644 index 0000000000..e5b7ececae --- /dev/null +++ b/src/com/vaadin/launcher/jetty-webdefault.xml @@ -0,0 +1,402 @@ + + + + + + + + + + + + + + + + + + + + + + + Default web.xml file. + This file is applied to a Web application before it's own WEB_INF/web.xml file + + + + + + + + + + org.mortbay.jetty.webapp.NoTLDJarPattern + start.jar|ant-.*\.jar|dojo-.*\.jar|jetty-.*\.jar|jsp-api-.*\.jar|junit-.*\.jar|servlet-api-.*\.jar|dnsns\.jar|rt\.jar|jsse\.jar|tools\.jar|sunpkcs11\.jar|sunjce_provider\.jar|xerces.*\.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + default + org.mortbay.jetty.servlet.DefaultServlet + + acceptRanges + true + + + dirAllowed + true + + + redirectWelcome + false + + + maxCacheSize + 256000000 + + + maxCachedFileSize + 10000000 + + + maxCachedFiles + 1000 + + + cacheType + both + + + gzip + true + + + useFileMappedBuffer + false + + + 0 + + + default / + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jsp + org.apache.jasper.servlet.JspServlet + + logVerbosityLevel + DEBUG + + + fork + false + + + xpoweredBy + false + + + 0 + + + + jsp + *.jsp + *.jspf + *.jspx + *.xsp + *.JSP + *.JSPF + *.JSPX + *.XSP + + + + + + + + + + + + + + + + + + + + + + + + + + + + 30 + + + + + + + + + + + + + index.html + index.htm + index.jsp + + + + + arISO-8859-6 + beISO-8859-5 + bgISO-8859-5 + caISO-8859-1 + csISO-8859-2 + daISO-8859-1 + deISO-8859-1 + elISO-8859-7 + enISO-8859-1 + esISO-8859-1 + etISO-8859-1 + fiISO-8859-1 + frISO-8859-1 + hrISO-8859-2 + huISO-8859-2 + isISO-8859-1 + itISO-8859-1 + iwISO-8859-8 + jaShift_JIS + koEUC-KR + ltISO-8859-2 + lvISO-8859-2 + mkISO-8859-5 + nlISO-8859-1 + noISO-8859-1 + plISO-8859-2 + ptISO-8859-1 + roISO-8859-2 + ruISO-8859-5 + shISO-8859-5 + skISO-8859-2 + slISO-8859-2 + sqISO-8859-2 + srISO-8859-5 + svISO-8859-1 + trISO-8859-9 + ukISO-8859-5 + zhGB2312 + zh_TWBig5 + + + + + Disable TRACE + / + TRACE + + + + + + diff --git a/src/com/vaadin/terminal/gwt/client/VBrowserDetails.java b/src/com/vaadin/terminal/gwt/client/VBrowserDetails.java index d9f585e44f..92b3dedf1f 100644 --- a/src/com/vaadin/terminal/gwt/client/VBrowserDetails.java +++ b/src/com/vaadin/terminal/gwt/client/VBrowserDetails.java @@ -57,41 +57,57 @@ public class VBrowserDetails implements Serializable { isFirefox = userAgent.indexOf(" firefox/") != -1; // Rendering engine version - if (isGecko) { - String tmp = userAgent.substring(userAgent.indexOf("rv:") + 3); - tmp = tmp.replaceFirst("(\\.[0-9]+).+", "$1"); - browserEngineVersion = Float.parseFloat(tmp); - } else if (isWebKit) { - String tmp = userAgent.substring(userAgent.indexOf("webkit/") + 7); - tmp = tmp.replaceFirst("([0-9]+)[^0-9].+", "$1"); - browserEngineVersion = Float.parseFloat(tmp); + try { + if (isGecko) { + int rvPos = userAgent.indexOf("rv:"); + if (rvPos >= 0) { + String tmp = userAgent.substring(rvPos + 3); + tmp = tmp.replaceFirst("(\\.[0-9]+).+", "$1"); + browserEngineVersion = Float.parseFloat(tmp); + } + } else if (isWebKit) { + String tmp = userAgent + .substring(userAgent.indexOf("webkit/") + 7); + tmp = tmp.replaceFirst("([0-9]+)[^0-9].+", "$1"); + browserEngineVersion = Float.parseFloat(tmp); + } + } catch (Exception e) { + // Browser engine version parsing failed + System.err.println("Browser engine version parsing failed for: " + + userAgent); } // Browser version - if (isIE) { - String ieVersionString = userAgent.substring(userAgent - .indexOf("msie ") + 5); - ieVersionString = safeSubstring(ieVersionString, 0, ieVersionString - .indexOf(";")); - parseVersionString(ieVersionString); - } else if (isFirefox) { - int i = userAgent.indexOf(" firefox/") + 9; - parseVersionString(safeSubstring(userAgent, i, i + 5)); - } else if (isChrome) { - int i = userAgent.indexOf(" chrome/") + 8; - parseVersionString(safeSubstring(userAgent, i, i + 5)); - } else if (isSafari) { - int i = userAgent.indexOf(" version/") + 9; - parseVersionString(safeSubstring(userAgent, i, i + 5)); - } else if (isOpera) { - int i = userAgent.indexOf(" version/"); - if (i != -1) { - // Version present in Opera 10 and newer - i += 9; // " version/".length - } else { - i = userAgent.indexOf("opera/") + 6; + try { + if (isIE) { + String ieVersionString = userAgent.substring(userAgent + .indexOf("msie ") + 5); + ieVersionString = safeSubstring(ieVersionString, 0, + ieVersionString.indexOf(";")); + parseVersionString(ieVersionString); + } else if (isFirefox) { + int i = userAgent.indexOf(" firefox/") + 9; + parseVersionString(safeSubstring(userAgent, i, i + 5)); + } else if (isChrome) { + int i = userAgent.indexOf(" chrome/") + 8; + parseVersionString(safeSubstring(userAgent, i, i + 5)); + } else if (isSafari) { + int i = userAgent.indexOf(" version/") + 9; + parseVersionString(safeSubstring(userAgent, i, i + 5)); + } else if (isOpera) { + int i = userAgent.indexOf(" version/"); + if (i != -1) { + // Version present in Opera 10 and newer + i += 9; // " version/".length + } else { + i = userAgent.indexOf("opera/") + 6; + } + parseVersionString(safeSubstring(userAgent, i, i + 5)); } - parseVersionString(safeSubstring(userAgent, i, i + 5)); + } catch (Exception e) { + // Browser version parsing failed + System.err.println("Browser version parsing failed for: " + + userAgent); } // Operating system diff --git a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java index f326846c68..98b95b2a7c 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java @@ -1672,6 +1672,12 @@ public abstract class AbstractCommunicationManager implements i.remove(); } else { Window componentsRoot = component.getWindow(); + if (componentsRoot == null) { + // This should not happen unless somebody has overriden + // getApplication or getWindow in an illegal way. + throw new IllegalStateException( + "component.getWindow() returned null for a component attached to the application"); + } if (componentsRoot.getParent() != null) { // this is a subwindow componentsRoot = (Window) componentsRoot.getParent(); diff --git a/tests/src/com/vaadin/tests/components/select/MultiSelect.java b/tests/src/com/vaadin/tests/components/select/MultiSelect.java new file mode 100644 index 0000000000..66ca41d829 --- /dev/null +++ b/tests/src/com/vaadin/tests/components/select/MultiSelect.java @@ -0,0 +1,31 @@ +package com.vaadin.tests.components.select; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Select; + +public class MultiSelect extends TestBase { + + @Override + protected void setup() { + Select selectComponent = new Select(); + selectComponent.setMultiSelect(true); + + String[] selection = { "One", "Hund", "Three" }; + for (String word : selection) { + selectComponent.addItem(word); + } + + addComponent(selectComponent); + } + + @Override + protected String getDescription() { + return "The select is in multi select mode and should be rendered as such"; + } + + @Override + protected Integer getTicketNumber() { + return 4553; + } + +} diff --git a/tests/src/com/vaadin/tests/components/select/NativeSelects.html b/tests/src/com/vaadin/tests/components/select/NativeSelects.html new file mode 100644 index 0000000000..caff14b5b4 --- /dev/null +++ b/tests/src/com/vaadin/tests/components/select/NativeSelects.html @@ -0,0 +1,177 @@ + + + + + + +New Test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
New Test
open/run/com.vaadin.tests.components.select.NativeSelects?restartApplication
waitForVaadin
selectvaadin=runcomvaadintestscomponentsselectNativeSelects::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VNativeSelect[0]/domChild[0]label=The second item
waitForVaadin
selectvaadin=runcomvaadintestscomponentsselectNativeSelects::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VNativeSelect[0]/domChild[0]label=an item 1
waitForVaadin
selectvaadin=runcomvaadintestscomponentsselectNativeSelects::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[7]/VNativeSelect[0]/domChild[0]label=The second item
waitForVaadin
selectvaadin=runcomvaadintestscomponentsselectNativeSelects::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[8]/VNativeSelect[0]/domChild[0]label=an item 1
waitForVaadin
screenCaptureenabled-readwrite-noerror
mouseClickvaadin=runcomvaadintestscomponentsselectNativeSelects::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VCheckBox[0]/domChild[0]7,6
waitForVaadin
screenCaptureenabled-readonly-noerror
mouseClickvaadin=runcomvaadintestscomponentsselectNativeSelects::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[0]/VCheckBox[0]/domChild[0]31,6
waitForVaadin
screenCaptureenabled-readonly-error
mouseClickvaadin=runcomvaadintestscomponentsselectNativeSelects::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VCheckBox[0]/domChild[0]3,9
waitForVaadin
screenCaptureenabled-readwrite-error
mouseClickvaadin=runcomvaadintestscomponentsselectNativeSelects::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[2]/VCheckBox[0]/domChild[0]32,6
waitForVaadin
screenCapturedisabled-readwrite-error
mouseClickvaadin=runcomvaadintestscomponentsselectNativeSelects::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[0]/VCheckBox[0]/domChild[0]47,6
waitForVaadin
screenCapturedisabled-readwrite-noerror
mouseClickvaadin=runcomvaadintestscomponentsselectNativeSelects::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VCheckBox[0]/domChild[0]31,11
waitForVaadin
screenCapturedisabled-readonly-noerror
mouseClickvaadin=runcomvaadintestscomponentsselectNativeSelects::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[0]/VCheckBox[0]/domChild[0]42,4
waitForVaadin
screenCapturedisabled-readonly-error
+ + diff --git a/tests/src/com/vaadin/tests/components/select/NativeSelects.java b/tests/src/com/vaadin/tests/components/select/NativeSelects.java new file mode 100644 index 0000000000..46b5267e28 --- /dev/null +++ b/tests/src/com/vaadin/tests/components/select/NativeSelects.java @@ -0,0 +1,153 @@ +package com.vaadin.tests.components.select; + +import java.util.ArrayList; +import java.util.List; + +import com.vaadin.tests.components.ComponentTestCase; +import com.vaadin.ui.Button; +import com.vaadin.ui.CheckBox; +import com.vaadin.ui.Component; +import com.vaadin.ui.NativeSelect; +import com.vaadin.ui.Button.ClickEvent; + +public class NativeSelects extends ComponentTestCase { + + private static final Object CAPTION = "caption"; + NativeSelect label[] = new NativeSelect[20]; + + @Override + protected void setup() { + super.setup(); + + NativeSelect s; + + s = createNativeSelect(null); + s.setWidth(null); + addTestComponent(s); + + s = createNativeSelect("Undefined wide, empty select"); + s.setWidth(null); + addTestComponent(s); + + s = createNativeSelect("Undefined wide select with 5 items"); + s.setWidth(null); + addItem(s, "The first item"); + addItem(s, "The second item"); + addItem(s, "The third item"); + addItem(s, "The fourth item"); + addItem(s, "The fifth item"); + addTestComponent(s); + + s = createNativeSelect("Undefined wide select with 50 items"); + s.setWidth(null); + populate(s, 50); + addTestComponent(s); + + s = createNativeSelect(null); + s.setWidth("100px"); + addTestComponent(s); + + s = createNativeSelect("100px wide, empty select"); + s.setWidth("100px"); + addTestComponent(s); + + s = createNativeSelect("150px wide select with 5 items"); + s.setWidth("150px"); + addItem(s, "The first item"); + addItem(s, "The second item"); + addItem(s, "The third item"); + addItem(s, "The fourth item"); + addItem(s, "The fifth item"); + addTestComponent(s); + + s = createNativeSelect("200px wide select with 50 items"); + s.setWidth("200px"); + populate(s, 50); + addTestComponent(s); + + } + + private void populate(NativeSelect s, int nr) { + String text = " an item "; + + String caption = ""; + for (int i = 0; i < nr; i++) { + if (i % 2 == 0) { + caption += text; + } else { + caption += i; + } + + addItem(s, caption); + } + + } + + private void addItem(NativeSelect s, String string) { + Object id = s.addItem(); + s.getItem(id).getItemProperty(CAPTION).setValue(string); + + } + + private NativeSelect createNativeSelect(String caption) { + NativeSelect s = new NativeSelect(); + + s.addContainerProperty(CAPTION, String.class, ""); + s.setItemCaptionPropertyId(CAPTION); + s.setCaption(caption); + + return s; + } + + @Override + protected String getDescription() { + return "A generic test for Labels in different configurations"; + } + + @Override + protected List createActions() { + ArrayList actions = new ArrayList(); + + CheckBox errorIndicators = new CheckBox("Error indicators", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + Button b = event.getButton(); + boolean enabled = (Boolean) b.getValue(); + setErrorIndicators(enabled); + + } + }); + + CheckBox enabled = new CheckBox("Enabled", new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + Button b = event.getButton(); + boolean enabled = (Boolean) b.getValue(); + setEnabled(enabled); + } + }); + + CheckBox readonly = new CheckBox("Readonly", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + Button b = event.getButton(); + boolean enabled = (Boolean) b.getValue(); + setReadOnly(enabled); + } + }); + + errorIndicators.setValue(new Boolean(false)); + readonly.setValue(new Boolean(false)); + enabled.setValue(new Boolean(true)); + + errorIndicators.setImmediate(true); + readonly.setImmediate(true); + enabled.setImmediate(true); + + actions.add(errorIndicators); + actions.add(readonly); + actions.add(enabled); + + return actions; + } + +} diff --git a/tests/src/com/vaadin/tests/components/table/TableSorting.java b/tests/src/com/vaadin/tests/components/table/TableSorting.java new file mode 100644 index 0000000000..4cbb1934e4 --- /dev/null +++ b/tests/src/com/vaadin/tests/components/table/TableSorting.java @@ -0,0 +1,67 @@ +package com.vaadin.tests.components.table; + +import java.io.Serializable; + +import com.vaadin.data.Property; +import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.data.util.BeanItemContainer; +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Label; +import com.vaadin.ui.Table; + +public class TableSorting extends TestBase { + + @Override + public void setup() { + final Label showID = new Label(""); + final Table testTable = new Table(); + + BeanItemContainer cont = new BeanItemContainer( + TestItem.class); + + for (int i = 0; i < 20; i++) { + TestItem ti = new TestItem(); + ti.setTestName("Name_" + i); + cont.addBean(ti); + } + testTable.setContainerDataSource(cont); + testTable.setImmediate(true); + testTable.setSelectable(true); + testTable.setMultiSelect(false); + testTable.setVisibleColumns(new Object[] { "testName" }); + + // Handle selection change. + testTable.addListener(new Property.ValueChangeListener() { + public void valueChange(ValueChangeEvent event) { + System.out.println("ValueChanged: " + + testTable.getValue().toString()); + showID.setCaption("ID: " + testTable.getValue().toString()); + } + }); + addComponent(testTable); + addComponent(showID); + } + + public class TestItem implements Serializable { + private static final long serialVersionUID = -745849615488792221L; + private String testName; + + public String getTestName() { + return testName; + } + + public void setTestName(String testName) { + this.testName = testName; + } + } + + @Override + protected String getDescription() { + return "Click the header to sort the table, then click on \"Name_10\". This should show ID: com.vaadin.tests.components.table.TableSorting$TestItem@ below the table"; + } + + @Override + protected Integer getTicketNumber() { + return 4537; + } +} \ No newline at end of file diff --git a/tests/src/com/vaadin/tests/server/BrowserUserAgentParser.java b/tests/src/com/vaadin/tests/server/BrowserUserAgentParser.java index 168b99a19b..c1fa4e82f6 100644 --- a/tests/src/com/vaadin/tests/server/BrowserUserAgentParser.java +++ b/tests/src/com/vaadin/tests/server/BrowserUserAgentParser.java @@ -11,6 +11,8 @@ public class BrowserUserAgentParser extends TestCase { private static final String FIREFOX35_WINDOWS = "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8 (.NET CLR 3.5.30729) FirePHP/0.4"; private static final String FIREFOX36_WINDOWS = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)"; private static final String FIREFOX36B_MAC = "UAString mozilla/5.0 (macintosh; u; intel mac os x 10.6; en-us; rv:1.9.2) gecko/20100115 firefox/3.6"; + private static final String FIREFOX_30B5_MAC = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9b5) Gecko/2008032619 Firefox/3.0b5"; + private static final String KONQUEROR_LINUX = "Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.5 (like Gecko) (Exabot-Thumbnails)"; private static final String IE6_WINDOWS = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)"; private static final String IE7_WINDOWS = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"; @@ -106,6 +108,22 @@ public class BrowserUserAgentParser extends TestCase { assertWindows(bd); } + public void testFirefox30b5() { + VBrowserDetails bd = new VBrowserDetails(FIREFOX_30B5_MAC); + assertGecko(bd); + assertFirefox(bd); + assertBrowserMajorVersion(bd, 3); + assertBrowserMinorVersion(bd, 0); + assertEngineVersion(bd, 1.9f); + assertMacOSX(bd); + } + + public void testKonquerorLinux() { + // Just ensure detection does not crash + VBrowserDetails bd = new VBrowserDetails(KONQUEROR_LINUX); + assertLinux(bd); + } + public void testFirefox36b() { VBrowserDetails bd = new VBrowserDetails(FIREFOX36B_MAC); assertGecko(bd); diff --git a/tests/src/com/vaadin/tests/server/container/BeanItemContainerSortTest.java b/tests/src/com/vaadin/tests/server/container/BeanItemContainerSortTest.java index eb46da776f..1320d57653 100644 --- a/tests/src/com/vaadin/tests/server/container/BeanItemContainerSortTest.java +++ b/tests/src/com/vaadin/tests/server/container/BeanItemContainerSortTest.java @@ -14,6 +14,16 @@ public class BeanItemContainerSortTest { public class Person { private String name; + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + private int age; + public void setName(String name) { this.name = name; } @@ -23,14 +33,19 @@ public class BeanItemContainerSortTest { } } - String[] names = new String[] { "Antti", "Ville", "Sirkka", "Jaakko" }; + String[] names = new String[] { "Antti", "Ville", "Sirkka", "Jaakko", + "Pekka", "John" }; + int[] ages = new int[] { 10, 20, 50, 12, 64, 67 }; + String[] sortedByAge = new String[] { names[0], names[3], names[1], + names[2], names[4], names[5] }; public BeanItemContainer getContainer() { BeanItemContainer bc = new BeanItemContainer( Person.class); - for (String name : names) { + for (int i = 0; i < names.length; i++) { Person p = new Person(); - p.setName(name); + p.setName(names[i]); + p.setAge(ages[i]); bc.addBean(p); } return bc; @@ -55,6 +70,7 @@ public class BeanItemContainerSortTest { int i = 0; for (String string : asList) { Person idByIndex = container.getIdByIndex(i++); + Assert.assertTrue(container.containsId(idByIndex)); Assert.assertEquals(string, idByIndex.getName()); } } @@ -64,4 +80,17 @@ public class BeanItemContainerSortTest { testSort(false); } + @Test + public void primitiveSorting() { + BeanItemContainer container = getContainer(); + container.sort(new Object[] { "age" }, new boolean[] { true }); + + int i = 0; + for (String string : sortedByAge) { + Person idByIndex = container.getIdByIndex(i++); + Assert.assertTrue(container.containsId(idByIndex)); + Assert.assertEquals(string, idByIndex.getName()); + } + + } } -- 2.39.5