diff options
author | Artur Signell <artur@vaadin.com> | 2016-08-25 13:21:36 +0300 |
---|---|---|
committer | Artur Signell <artur@vaadin.com> | 2016-08-26 11:40:12 +0300 |
commit | 58853fe47bb01a0c0c2b5c380056d22ccccd6f08 (patch) | |
tree | 3a45b08366f53943326e14750d2c4d90f1e1128d /compatibility-server | |
parent | 50f294513f929fcd0e6a519283d5a88e09331081 (diff) | |
download | vaadin-framework-58853fe47bb01a0c0c2b5c380056d22ccccd6f08.tar.gz vaadin-framework-58853fe47bb01a0c0c2b5c380056d22ccccd6f08.zip |
Move old TextField to compatibility package
Change-Id: Ic1e8d3f9859f5e496c0e27e2fece4b5a9da74f01
Diffstat (limited to 'compatibility-server')
34 files changed, 3583 insertions, 1 deletions
diff --git a/compatibility-server/src/main/java/com/vaadin/v7/event/FieldEvents.java b/compatibility-server/src/main/java/com/vaadin/v7/event/FieldEvents.java new file mode 100644 index 0000000000..abd17df49b --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/event/FieldEvents.java @@ -0,0 +1,109 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * 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.vaadin.v7.event; + +import java.io.Serializable; +import java.lang.reflect.Method; + +import com.vaadin.event.ConnectorEventListener; +import com.vaadin.ui.Component; +import com.vaadin.util.ReflectTools; +import com.vaadin.v7.ui.Field; +import com.vaadin.v7.ui.Field.ValueChangeEvent; +import com.vaadin.v7.ui.TextField; + +/** + * Interface that serves as a wrapper for {@link Field} related events. + */ +public interface FieldEvents { + + /** + * TextChangeEvents are fired when the user is editing the text content of a + * field. Most commonly text change events are triggered by typing text with + * keyboard, but e.g. pasting content from clip board to a text field also + * triggers an event. + * <p> + * TextChangeEvents differ from {@link ValueChangeEvent}s so that they are + * triggered repeatedly while the end user is filling the field. + * ValueChangeEvents are not fired until the user for example hits enter or + * focuses another field. Also note the difference that TextChangeEvents are + * only fired if the change is triggered from the user, while + * ValueChangeEvents are also fired if the field value is set by the + * application code. + * <p> + * The {@link TextChangeNotifier}s implementation may decide when exactly + * TextChangeEvents are fired. TextChangeEvents are not necessary fire for + * example on each key press, but buffered with a small delay. The + * {@code TextField} component supports different modes for triggering + * TextChangeEvents. + * + * @see TextChangeListener + * @see TextChangeNotifier + * @see TextField#setTextChangeEventMode(com.vaadin.ui.TextField.TextChangeEventMode) + * @since 6.5 + */ + public static abstract class TextChangeEvent extends Component.Event { + + public TextChangeEvent(Component source) { + super(source); + } + + /** + * @return the text content of the field after the + * {@link TextChangeEvent} + */ + public abstract String getText(); + + /** + * @return the cursor position during after the {@link TextChangeEvent} + */ + public abstract int getCursorPosition(); + } + + /** + * A listener for {@link TextChangeEvent}s. + * + * @since 6.5 + */ + public interface TextChangeListener extends ConnectorEventListener { + + public static String EVENT_ID = "ie"; + public static Method EVENT_METHOD = ReflectTools.findMethod( + TextChangeListener.class, "textChange", TextChangeEvent.class); + + /** + * This method is called repeatedly while the text is edited by a user. + * + * @param event + * the event providing details of the text change + */ + public void textChange(TextChangeEvent event); + } + + /** + * An interface implemented by a {@link Field} supporting + * {@link TextChangeEvent}s. An example a {@link TextField} supports + * {@link TextChangeListener}s. + */ + public interface TextChangeNotifier extends Serializable { + public void addTextChangeListener(TextChangeListener listener); + + public void removeTextChangeListener(TextChangeListener listener); + + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/ui/AbstractTextField.java b/compatibility-server/src/main/java/com/vaadin/v7/ui/AbstractTextField.java new file mode 100644 index 0000000000..f534662583 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/ui/AbstractTextField.java @@ -0,0 +1,813 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * 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.vaadin.v7.ui; + +import java.util.Collection; +import java.util.Map; + +import org.jsoup.nodes.Attributes; +import org.jsoup.nodes.Element; + +import com.vaadin.event.FieldEvents.BlurEvent; +import com.vaadin.event.FieldEvents.BlurListener; +import com.vaadin.event.FieldEvents.BlurNotifier; +import com.vaadin.event.FieldEvents.FocusEvent; +import com.vaadin.event.FieldEvents.FocusListener; +import com.vaadin.event.FieldEvents.FocusNotifier; +import com.vaadin.server.PaintException; +import com.vaadin.server.PaintTarget; +import com.vaadin.shared.v7.ui.textfield.LegacyAbstractTextFieldState; +import com.vaadin.shared.v7.ui.textfield.LegacyTextFieldConstants; +import com.vaadin.ui.LegacyComponent; +import com.vaadin.ui.declarative.DesignAttributeHandler; +import com.vaadin.ui.declarative.DesignContext; +import com.vaadin.v7.event.FieldEvents.TextChangeEvent; +import com.vaadin.v7.event.FieldEvents.TextChangeListener; +import com.vaadin.v7.event.FieldEvents.TextChangeNotifier; + +@Deprecated +public abstract class AbstractTextField extends AbstractField<String> implements + BlurNotifier, FocusNotifier, TextChangeNotifier, LegacyComponent { + + /** + * Null representation. + */ + private String nullRepresentation = "null"; + /** + * Is setting to null from non-null value allowed by setting with null + * representation . + */ + private boolean nullSettingAllowed = false; + /** + * The text content when the last messages to the server was sent. Cleared + * when value is changed. + */ + private String lastKnownTextContent; + + /** + * The position of the cursor when the last message to the server was sent. + */ + private int lastKnownCursorPosition; + + /** + * Flag indicating that a text change event is pending to be triggered. + * Cleared by {@link #setInternalValue(Object)} and when the event is fired. + */ + private boolean textChangeEventPending; + + private boolean isFiringTextChangeEvent = false; + + private TextChangeEventMode textChangeEventMode = TextChangeEventMode.LAZY; + + private final int DEFAULT_TEXTCHANGE_TIMEOUT = 400; + + private int textChangeEventTimeout = DEFAULT_TEXTCHANGE_TIMEOUT; + + /** + * Temporarily holds the new selection position. Cleared on paint. + */ + private int selectionPosition = -1; + + /** + * Temporarily holds the new selection length. + */ + private int selectionLength; + + /** + * Flag used to determine whether we are currently handling a state change + * triggered by a user. Used to properly fire text change event before value + * change event triggered by the client side. + */ + private boolean changingVariables; + + protected AbstractTextField() { + super(); + } + + @Override + protected LegacyAbstractTextFieldState getState() { + return (LegacyAbstractTextFieldState) super.getState(); + } + + @Override + protected LegacyAbstractTextFieldState getState(boolean markAsDirty) { + return (LegacyAbstractTextFieldState) super.getState(markAsDirty); + } + + @Override + public void beforeClientResponse(boolean initial) { + super.beforeClientResponse(initial); + + String value = getValue(); + if (value == null) { + value = getNullRepresentation(); + } + getState().text = value; + } + + @Override + public void paintContent(PaintTarget target) throws PaintException { + + if (selectionPosition != -1) { + target.addAttribute("selpos", selectionPosition); + target.addAttribute("sellen", selectionLength); + selectionPosition = -1; + } + + if (hasListeners(TextChangeEvent.class)) { + target.addAttribute( + LegacyTextFieldConstants.ATTR_TEXTCHANGE_EVENTMODE, + getTextChangeEventMode().toString()); + target.addAttribute( + LegacyTextFieldConstants.ATTR_TEXTCHANGE_TIMEOUT, + getTextChangeTimeout()); + if (lastKnownTextContent != null) { + /* + * The field has be repainted for some reason (e.g. caption, + * size, stylename), but the value has not been changed since + * the last text change event. Let the client side know about + * the value the server side knows. Client side may then ignore + * the actual value, depending on its state. + */ + target.addAttribute( + LegacyTextFieldConstants.ATTR_NO_VALUE_CHANGE_BETWEEN_PAINTS, + true); + } + } + + } + + @Override + public void changeVariables(Object source, Map<String, Object> variables) { + changingVariables = true; + + try { + + // Sets the height set by the user when resize the <textarea>. + String newHeight = (String) variables.get("height"); + if (newHeight != null) { + setHeight(newHeight); + } + + // Sets the width set by the user when resize the <textarea>. + String newWidth = (String) variables.get("width"); + if (newWidth != null) { + setWidth(newWidth); + } + + if (variables.containsKey(LegacyTextFieldConstants.VAR_CURSOR)) { + Integer object = (Integer) variables + .get(LegacyTextFieldConstants.VAR_CURSOR); + lastKnownCursorPosition = object.intValue(); + } + + if (variables.containsKey(LegacyTextFieldConstants.VAR_CUR_TEXT)) { + /* + * NOTE, we might want to develop this further so that on a + * value change event the whole text content don't need to be + * sent from the client to server. Just "commit" the value from + * currentText to the value. + */ + handleInputEventTextChange(variables); + } + + // Sets the text + if (variables.containsKey("text") && !isReadOnly()) { + + // Only do the setting if the string representation of the value + // has been updated + String newValue = (String) variables.get("text"); + + // server side check for max length + if (getMaxLength() != -1 + && newValue.length() > getMaxLength()) { + newValue = newValue.substring(0, getMaxLength()); + } + final String oldValue = getValue(); + if (newValue != null + && (oldValue == null || isNullSettingAllowed()) + && newValue.equals(getNullRepresentation())) { + newValue = null; + } + if (newValue != oldValue + && (newValue == null || !newValue.equals(oldValue))) { + boolean wasModified = isModified(); + setValue(newValue, true); + + // If the modified status changes, or if we have a + // formatter, repaint is needed after all. + if (wasModified != isModified()) { + markAsDirty(); + } + } + } + firePendingTextChangeEvent(); + + if (variables.containsKey(FocusEvent.EVENT_ID)) { + fireEvent(new FocusEvent(this)); + } + if (variables.containsKey(BlurEvent.EVENT_ID)) { + fireEvent(new BlurEvent(this)); + } + } finally { + changingVariables = false; + + } + + } + + @Override + public Class<String> getType() { + return String.class; + } + + /** + * Gets the null-string representation. + * + * <p> + * The null-valued strings are represented on the user interface by + * replacing the null value with this string. If the null representation is + * set null (not 'null' string), painting null value throws exception. + * </p> + * + * <p> + * The default value is string 'null'. + * </p> + * + * @return the String Textual representation for null strings. + * @see TextField#isNullSettingAllowed() + */ + public String getNullRepresentation() { + return nullRepresentation; + } + + /** + * Is setting nulls with null-string representation allowed. + * + * <p> + * If this property is true, writing null-representation string to text + * field always sets the field value to real null. If this property is + * false, null setting is not made, but the null values are maintained. + * Maintenance of null-values is made by only converting the textfield + * contents to real null, if the text field matches the null-string + * representation and the current value of the field is null. + * </p> + * + * <p> + * By default this setting is false + * </p> + * + * @return boolean Should the null-string represenation be always converted + * to null-values. + * @see TextField#getNullRepresentation() + */ + public boolean isNullSettingAllowed() { + return nullSettingAllowed; + } + + /** + * Sets the null-string representation. + * + * <p> + * The null-valued strings are represented on the user interface by + * replacing the null value with this string. If the null representation is + * set null (not 'null' string), painting null value throws exception. + * </p> + * + * <p> + * The default value is string 'null' + * </p> + * + * @param nullRepresentation + * Textual representation for null strings. + * @see TextField#setNullSettingAllowed(boolean) + */ + public void setNullRepresentation(String nullRepresentation) { + this.nullRepresentation = nullRepresentation; + markAsDirty(); + } + + /** + * Sets the null conversion mode. + * + * <p> + * If this property is true, writing null-representation string to text + * field always sets the field value to real null. If this property is + * false, null setting is not made, but the null values are maintained. + * Maintenance of null-values is made by only converting the textfield + * contents to real null, if the text field matches the null-string + * representation and the current value of the field is null. + * </p> + * + * <p> + * By default this setting is false. + * </p> + * + * @param nullSettingAllowed + * Should the null-string representation always be converted to + * null-values. + * @see TextField#getNullRepresentation() + */ + public void setNullSettingAllowed(boolean nullSettingAllowed) { + this.nullSettingAllowed = nullSettingAllowed; + markAsDirty(); + } + + @Override + public boolean isEmpty() { + return super.isEmpty() || getValue().length() == 0; + } + + /** + * Returns the maximum number of characters in the field. Value -1 is + * considered unlimited. Terminal may however have some technical limits. + * + * @return the maxLength + */ + public int getMaxLength() { + return getState(false).maxLength; + } + + /** + * Sets the maximum number of characters in the field. Value -1 is + * considered unlimited. Terminal may however have some technical limits. + * + * @param maxLength + * the maxLength to set + */ + public void setMaxLength(int maxLength) { + getState().maxLength = maxLength; + } + + /** + * Gets the number of columns in the editor. If the number of columns is set + * 0, the actual number of displayed columns is determined implicitly by the + * adapter. + * + * @return the number of columns in the editor. + */ + public int getColumns() { + return getState(false).columns; + } + + /** + * Sets the number of columns in the editor. If the number of columns is set + * 0, the actual number of displayed columns is determined implicitly by the + * adapter. + * + * @param columns + * the number of columns to set. + */ + public void setColumns(int columns) { + if (columns < 0) { + columns = 0; + } + getState().columns = columns; + } + + /** + * Gets the current input prompt. + * + * @see #setInputPrompt(String) + * @return the current input prompt, or null if not enabled + */ + public String getInputPrompt() { + return getState(false).inputPrompt; + } + + /** + * Sets the input prompt - a textual prompt that is displayed when the field + * would otherwise be empty, to prompt the user for input. + * + * @param inputPrompt + */ + public void setInputPrompt(String inputPrompt) { + getState().inputPrompt = inputPrompt; + } + + /* ** Text Change Events ** */ + + private void firePendingTextChangeEvent() { + if (textChangeEventPending && !isFiringTextChangeEvent) { + isFiringTextChangeEvent = true; + textChangeEventPending = false; + try { + fireEvent(new TextChangeEventImpl(this)); + } finally { + isFiringTextChangeEvent = false; + } + } + } + + @Override + protected void setInternalValue(String newValue) { + if (changingVariables && !textChangeEventPending) { + + /* + * TODO check for possible (minor?) issue (not tested) + * + * -field with e.g. PropertyFormatter. + * + * -TextChangeListener and it changes value. + * + * -if formatter again changes the value, do we get an extra + * simulated text change event ? + */ + + /* + * Fire a "simulated" text change event before value change event if + * change is coming from the client side. + * + * Iff there is both value change and textChangeEvent in same + * variable burst, it is a text field in non immediate mode and the + * text change event "flushed" queued value change event. In this + * case textChangeEventPending flag is already on and text change + * event will be fired after the value change event. + */ + if (newValue == null && lastKnownTextContent != null + && !lastKnownTextContent.equals(getNullRepresentation())) { + // Value was changed from something to null representation + lastKnownTextContent = getNullRepresentation(); + textChangeEventPending = true; + } else if (newValue != null + && !newValue.toString().equals(lastKnownTextContent)) { + // Value was changed to something else than null representation + lastKnownTextContent = newValue.toString(); + textChangeEventPending = true; + } + firePendingTextChangeEvent(); + } + + super.setInternalValue(newValue); + } + + @Override + public void setValue(String newValue) throws ReadOnlyException { + super.setValue(newValue); + /* + * Make sure w reset lastKnownTextContent field on value change. The + * clearing must happen here as well because TextChangeListener can + * revert the original value. Client must respect the value in this + * case. LegacyAbstractField optimizes value change if the existing + * value is reset. Also we need to force repaint if the flag is on. + */ + if (lastKnownTextContent != null) { + lastKnownTextContent = null; + markAsDirty(); + } + } + + private void handleInputEventTextChange(Map<String, Object> variables) { + /* + * TODO we could vastly optimize the communication of values by using + * some sort of diffs instead of always sending the whole text content. + * Also on value change events we could use the mechanism. + */ + String object = (String) variables + .get(LegacyTextFieldConstants.VAR_CUR_TEXT); + lastKnownTextContent = object; + textChangeEventPending = true; + } + + /** + * Sets the mode how the TextField triggers {@link TextChangeEvent}s. + * + * @param inputEventMode + * the new mode + * + * @see TextChangeEventMode + */ + public void setTextChangeEventMode(TextChangeEventMode inputEventMode) { + textChangeEventMode = inputEventMode; + markAsDirty(); + } + + /** + * @return the mode used to trigger {@link TextChangeEvent}s. + */ + public TextChangeEventMode getTextChangeEventMode() { + return textChangeEventMode; + } + + /** + * Different modes how the TextField can trigger {@link TextChangeEvent}s. + */ + public enum TextChangeEventMode { + + /** + * An event is triggered on each text content change, most commonly key + * press events. + */ + EAGER, + /** + * Each text change event in the UI causes the event to be communicated + * to the application after a timeout. The length of the timeout can be + * controlled with {@link TextField#setTextChangeTimeout(int)}. Only the + * last input event is reported to the server side if several text + * change events happen during the timeout. + * <p> + * In case of a {@link ValueChangeEvent} the schedule is not kept + * strictly. Before a {@link ValueChangeEvent} a {@link TextChangeEvent} + * is triggered if the text content has changed since the previous + * TextChangeEvent regardless of the schedule. + */ + TIMEOUT, + /** + * An event is triggered when there is a pause of text modifications. + * The length of the pause can be modified with + * {@link TextField#setTextChangeTimeout(int)}. Like with the + * {@link #TIMEOUT} mode, an event is forced before + * {@link ValueChangeEvent}s, even if the user did not keep a pause + * while entering the text. + * <p> + * This is the default mode. + */ + LAZY + } + + @Override + public void addTextChangeListener(TextChangeListener listener) { + addListener(TextChangeListener.EVENT_ID, TextChangeEvent.class, + listener, TextChangeListener.EVENT_METHOD); + } + + /** + * @deprecated As of 7.0, replaced by + * {@link #addTextChangeListener(TextChangeListener)} + **/ + @Deprecated + public void addListener(TextChangeListener listener) { + addTextChangeListener(listener); + } + + @Override + public void removeTextChangeListener(TextChangeListener listener) { + removeListener(TextChangeListener.EVENT_ID, TextChangeEvent.class, + listener); + } + + /** + * @deprecated As of 7.0, replaced by + * {@link #removeTextChangeListener(TextChangeListener)} + **/ + @Deprecated + public void removeListener(TextChangeListener listener) { + removeTextChangeListener(listener); + } + + /** + * The text change timeout modifies how often text change events are + * communicated to the application when {@link #getTextChangeEventMode()} is + * {@link TextChangeEventMode#LAZY} or {@link TextChangeEventMode#TIMEOUT}. + * + * + * @see #getTextChangeEventMode() + * + * @param timeout + * the timeout in milliseconds + */ + public void setTextChangeTimeout(int timeout) { + textChangeEventTimeout = timeout; + markAsDirty(); + } + + /** + * Gets the timeout used to fire {@link TextChangeEvent}s when the + * {@link #getTextChangeEventMode()} is {@link TextChangeEventMode#LAZY} or + * {@link TextChangeEventMode#TIMEOUT}. + * + * @return the timeout value in milliseconds + */ + public int getTextChangeTimeout() { + return textChangeEventTimeout; + } + + public static class TextChangeEventImpl extends TextChangeEvent { + private String curText; + private int cursorPosition; + + private TextChangeEventImpl(final AbstractTextField tf) { + super(tf); + curText = tf.getCurrentTextContent(); + cursorPosition = tf.getCursorPosition(); + } + + @Override + public AbstractTextField getComponent() { + return (AbstractTextField) super.getComponent(); + } + + @Override + public String getText() { + return curText; + } + + @Override + public int getCursorPosition() { + return cursorPosition; + } + + } + + /** + * Gets the current (or the last known) text content in the field. + * <p> + * Note the text returned by this method is not necessary the same that is + * returned by the {@link #getValue()} method. The value is updated when the + * terminal fires a value change event via e.g. blurring the field or by + * pressing enter. The value returned by this method is updated also on + * {@link TextChangeEvent}s. Due to this high dependency to the terminal + * implementation this method is (at least at this point) not published. + * + * @return the text which is currently displayed in the field. + */ + private String getCurrentTextContent() { + if (lastKnownTextContent != null) { + return lastKnownTextContent; + } else { + Object text = getValue(); + if (text == null) { + return getNullRepresentation(); + } + return text.toString(); + } + } + + /** + * Selects all text in the field. + * + * @since 6.4 + */ + public void selectAll() { + String text = getValue() == null ? "" : getValue().toString(); + setSelectionRange(0, text.length()); + } + + /** + * Sets the range of text to be selected. + * + * As a side effect the field will become focused. + * + * @since 6.4 + * + * @param pos + * the position of the first character to be selected + * @param length + * the number of characters to be selected + */ + public void setSelectionRange(int pos, int length) { + selectionPosition = pos; + selectionLength = length; + focus(); + markAsDirty(); + } + + /** + * Sets the cursor position in the field. As a side effect the field will + * become focused. + * + * @since 6.4 + * + * @param pos + * the position for the cursor + */ + public void setCursorPosition(int pos) { + setSelectionRange(pos, 0); + lastKnownCursorPosition = pos; + } + + /** + * Returns the last known cursor position of the field. + * + * <p> + * Note that due to the client server nature or the GWT terminal, Vaadin + * cannot provide the exact value of the cursor position in most situations. + * The value is updated only when the client side terminal communicates to + * TextField, like on {@link ValueChangeEvent}s and {@link TextChangeEvent} + * s. This may change later if a deep push integration is built to Vaadin. + * + * @return the cursor position + */ + public int getCursorPosition() { + return lastKnownCursorPosition; + } + + @Override + public void addFocusListener(FocusListener listener) { + addListener(FocusEvent.EVENT_ID, FocusEvent.class, listener, + FocusListener.focusMethod); + } + + /** + * @deprecated As of 7.0, replaced by + * {@link #addFocusListener(FocusListener)} + **/ + @Deprecated + public void addListener(FocusListener listener) { + addFocusListener(listener); + } + + @Override + public void removeFocusListener(FocusListener listener) { + removeListener(FocusEvent.EVENT_ID, FocusEvent.class, listener); + } + + /** + * @deprecated As of 7.0, replaced by + * {@link #removeFocusListener(FocusListener)} + **/ + @Deprecated + public void removeListener(FocusListener listener) { + removeFocusListener(listener); + } + + @Override + public void addBlurListener(BlurListener listener) { + addListener(BlurEvent.EVENT_ID, BlurEvent.class, listener, + BlurListener.blurMethod); + } + + /** + * @deprecated As of 7.0, replaced by {@link #addBlurListener(BlurListener)} + **/ + @Deprecated + public void addListener(BlurListener listener) { + addBlurListener(listener); + } + + @Override + public void removeBlurListener(BlurListener listener) { + removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener); + } + + /** + * @deprecated As of 7.0, replaced by + * {@link #removeBlurListener(BlurListener)} + **/ + @Deprecated + public void removeListener(BlurListener listener) { + removeBlurListener(listener); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.AbstractField#readDesign(org.jsoup.nodes.Element , + * com.vaadin.ui.declarative.DesignContext) + */ + @Override + public void readDesign(Element design, DesignContext designContext) { + super.readDesign(design, designContext); + Attributes attr = design.attributes(); + if (attr.hasKey("maxlength")) { + setMaxLength(DesignAttributeHandler.readAttribute("maxlength", attr, + Integer.class)); + } + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.AbstractField#getCustomAttributes() + */ + @Override + protected Collection<String> getCustomAttributes() { + Collection<String> customAttributes = super.getCustomAttributes(); + customAttributes.add("maxlength"); + customAttributes.add("max-length"); // to prevent this appearing in + // output + customAttributes.add("cursor-position"); + return customAttributes; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.AbstractField#writeDesign(org.jsoup.nodes.Element, + * com.vaadin.ui.declarative.DesignContext) + */ + @Override + public void writeDesign(Element design, DesignContext designContext) { + super.writeDesign(design, designContext); + AbstractTextField def = (AbstractTextField) designContext + .getDefaultInstance(this); + Attributes attr = design.attributes(); + DesignAttributeHandler.writeAttribute("maxlength", attr, getMaxLength(), + def.getMaxLength(), Integer.class); + } + +} diff --git a/compatibility-server/src/main/java/com/vaadin/v7/ui/TextField.java b/compatibility-server/src/main/java/com/vaadin/v7/ui/TextField.java new file mode 100644 index 0000000000..0bd9511a71 --- /dev/null +++ b/compatibility-server/src/main/java/com/vaadin/v7/ui/TextField.java @@ -0,0 +1,151 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * 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.vaadin.v7.ui; + +import org.jsoup.nodes.Attributes; +import org.jsoup.nodes.Element; + +import com.vaadin.ui.declarative.DesignAttributeHandler; +import com.vaadin.ui.declarative.DesignContext; +import com.vaadin.v7.data.Property; + +/** + * <p> + * A text editor component that can be bound to any bindable Property. The text + * editor supports both multiline and single line modes, default is one-line + * mode. + * </p> + * + * <p> + * Since <code>TextField</code> extends <code>LegacyAbstractField</code> it + * implements the {@link com.vaadin.v7.data.Buffered} interface. A + * <code>TextField</code> is in write-through mode by default, so + * {@link com.vaadin.v7.ui.AbstractField#setWriteThrough(boolean)} + * must be called to enable buffering. + * </p> + * + * @author Vaadin Ltd. + * @since 3.0 + */ +@SuppressWarnings("serial") +@Deprecated +public class TextField extends AbstractTextField { + + /** + * Constructs an empty <code>TextField</code> with no caption. + */ + public TextField() { + clear(); + } + + /** + * Constructs an empty <code>TextField</code> with given caption. + * + * @param caption + * the caption <code>String</code> for the editor. + */ + public TextField(String caption) { + this(); + setCaption(caption); + } + + /** + * Constructs a new <code>TextField</code> that's bound to the specified + * <code>Property</code> and has no caption. + * + * @param dataSource + * the Property to be edited with this editor. + */ + public TextField(Property dataSource) { + setPropertyDataSource(dataSource); + } + + /** + * Constructs a new <code>TextField</code> that's bound to the specified + * <code>Property</code> and has the given caption <code>String</code>. + * + * @param caption + * the caption <code>String</code> for the editor. + * @param dataSource + * the Property to be edited with this editor. + */ + public TextField(String caption, Property dataSource) { + this(dataSource); + setCaption(caption); + } + + /** + * Constructs a new <code>TextField</code> with the given caption and + * initial text contents. The editor constructed this way will not be bound + * to a Property unless + * {@link com.vaadin.v7.data.Property.Viewer#setPropertyDataSource(Property)} + * is called to bind it. + * + * @param caption + * the caption <code>String</code> for the editor. + * @param value + * the initial text content of the editor. + */ + public TextField(String caption, String value) { + setValue(value); + setCaption(caption); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.AbstractTextField#readDesign(org.jsoup.nodes.Element, + * com.vaadin.ui.declarative.DesignContext) + */ + @Override + public void readDesign(Element design, DesignContext designContext) { + super.readDesign(design, designContext); + Attributes attr = design.attributes(); + if (attr.hasKey("value")) { + String newFieldValue = DesignAttributeHandler.readAttribute("value", + attr, String.class); + setValue(newFieldValue, false, true); + } + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.AbstractTextField#writeDesign(org.jsoup.nodes.Element + * , com.vaadin.ui.declarative.DesignContext) + */ + @Override + public void writeDesign(Element design, DesignContext designContext) { + super.writeDesign(design, designContext); + AbstractTextField def = (AbstractTextField) designContext + .getDefaultInstance(this); + Attributes attr = design.attributes(); + DesignAttributeHandler.writeAttribute("value", attr, getValue(), + def.getValue(), String.class); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.AbstractField#clear() + */ + @Override + public void clear() { + setValue(""); + } + +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/AnyEnumToStringConverterTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/AnyEnumToStringConverterTest.java new file mode 100644 index 0000000000..4f0c286d2d --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/AnyEnumToStringConverterTest.java @@ -0,0 +1,129 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * 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.vaadin.v7.tests.data.converter; + +import java.util.Locale; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.tests.data.bean.AnotherTestEnum; +import com.vaadin.tests.data.bean.TestEnum; +import com.vaadin.v7.data.util.ObjectProperty; +import com.vaadin.v7.data.util.converter.Converter; +import com.vaadin.v7.data.util.converter.ReverseConverter; +import com.vaadin.v7.ui.TextField; + +public class AnyEnumToStringConverterTest { + + public class AnyEnumToStringConverter + implements Converter<Enum, String> { + + public AnyEnumToStringConverter() { + } + + @Override + public String convertToModel(Enum value, + Class<? extends String> targetType, Locale locale) + throws com.vaadin.v7.data.util.converter.Converter.ConversionException { + if (value == null) { + return null; + } + + return value.toString(); + } + + @Override + public Enum convertToPresentation(String value, + Class<? extends Enum> targetType, Locale locale) + throws com.vaadin.v7.data.util.converter.Converter.ConversionException { + if (value == null) { + return null; + } + for (Enum e : targetType.getEnumConstants()) { + if (e.toString().equals(value)) { + return e; + } + } + + return null; + } + + @Override + public Class<String> getModelType() { + return String.class; + } + + @Override + public Class<Enum> getPresentationType() { + return Enum.class; + } + + } + + private AnyEnumToStringConverter converter; + + @Before + public void setup() { + converter = new AnyEnumToStringConverter(); + } + + @Test + public void nullConversion() { + Assert.assertEquals(null, converter.convertToModel(null, null, null)); + } + + @Test + public void enumToStringConversion() { + Assert.assertEquals(TestEnum.TWO.toString(), + converter.convertToModel(TestEnum.TWO, String.class, null)); + Assert.assertEquals(AnotherTestEnum.TWO.toString(), converter + .convertToModel(AnotherTestEnum.TWO, String.class, null)); + } + + @Test + public void stringToEnumConversion() { + Assert.assertEquals(TestEnum.TWO, converter.convertToPresentation( + TestEnum.TWO.toString(), TestEnum.class, null)); + Assert.assertEquals(AnotherTestEnum.TWO, + converter.convertToPresentation(AnotherTestEnum.TWO.toString(), + AnotherTestEnum.class, null)); + } + + @Test + public void stringToEnumWithField() { + TextField tf = new TextField(); + tf.setConverter(new ReverseConverter(converter)); + tf.setPropertyDataSource(new ObjectProperty(AnotherTestEnum.TWO)); + Assert.assertEquals(AnotherTestEnum.TWO.toString(), tf.getValue()); + tf.setValue(AnotherTestEnum.ONE.toString()); + Assert.assertEquals(AnotherTestEnum.ONE.toString(), tf.getValue()); + Assert.assertEquals(AnotherTestEnum.ONE, tf.getConvertedValue()); + Assert.assertEquals(AnotherTestEnum.ONE, + tf.getPropertyDataSource().getValue()); + + tf.setPropertyDataSource(new ObjectProperty(TestEnum.TWO)); + Assert.assertEquals(TestEnum.TWO.toString(), tf.getValue()); + tf.setValue(TestEnum.ONE.toString()); + Assert.assertEquals(TestEnum.ONE.toString(), tf.getValue()); + Assert.assertEquals(TestEnum.ONE, tf.getConvertedValue()); + Assert.assertEquals(TestEnum.ONE, + tf.getPropertyDataSource().getValue()); + + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/ConverterFactoryTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/ConverterFactoryTest.java new file mode 100644 index 0000000000..1f3a64cbb7 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/ConverterFactoryTest.java @@ -0,0 +1,128 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * 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.vaadin.v7.tests.data.converter; + +import java.util.Locale; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.server.VaadinSession; +import com.vaadin.tests.util.AlwaysLockedVaadinSession; +import com.vaadin.v7.data.util.converter.Converter; +import com.vaadin.v7.data.util.converter.DefaultConverterFactory; +import com.vaadin.v7.ui.TextField; + +public class ConverterFactoryTest { + + public static class ConvertTo42 + implements Converter<String, Integer> { + + @Override + public Integer convertToModel(String value, + Class<? extends Integer> targetType, Locale locale) + throws com.vaadin.v7.data.util.converter.Converter.ConversionException { + return 42; + } + + @Override + public String convertToPresentation(Integer value, + Class<? extends String> targetType, Locale locale) + throws com.vaadin.v7.data.util.converter.Converter.ConversionException { + return "42"; + } + + @Override + public Class<Integer> getModelType() { + return Integer.class; + } + + @Override + public Class<String> getPresentationType() { + return String.class; + } + + } + + public static class ConverterFactory42 + extends DefaultConverterFactory { + @Override + public <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> createConverter( + Class<PRESENTATION> presentationType, Class<MODEL> modelType) { + if (modelType == Integer.class) { + return (Converter<PRESENTATION, MODEL>) new ConvertTo42(); + } + + return super.createConverter(presentationType, modelType); + } + } + + @Test + public void testApplicationConverterFactoryInBackgroundThread() { + VaadinSession.setCurrent(null); + final VaadinSession appWithCustomIntegerConverter = new AlwaysLockedVaadinSession( + null); + appWithCustomIntegerConverter + .setConverterFactory(new ConverterFactory42()); + + TextField tf = new TextField("", "123") { + @Override + public VaadinSession getSession() { + return appWithCustomIntegerConverter; + } + }; + tf.setConverter(Integer.class); + // The application converter always returns 42. Current application is + // null + Assert.assertEquals(42, tf.getConvertedValue()); + } + + @Test + public void testApplicationConverterFactoryForDetachedComponent() { + final VaadinSession appWithCustomIntegerConverter = new AlwaysLockedVaadinSession( + null); + appWithCustomIntegerConverter + .setConverterFactory(new ConverterFactory42()); + VaadinSession.setCurrent(appWithCustomIntegerConverter); + + TextField tf = new TextField("", "123"); + tf.setConverter(Integer.class); + // The application converter always returns 42. Current application is + // null + Assert.assertEquals(42, tf.getConvertedValue()); + } + + @Test + public void testApplicationConverterFactoryForDifferentThanCurrentApplication() { + final VaadinSession fieldAppWithCustomIntegerConverter = new AlwaysLockedVaadinSession( + null); + fieldAppWithCustomIntegerConverter + .setConverterFactory(new ConverterFactory42()); + VaadinSession.setCurrent(new AlwaysLockedVaadinSession(null)); + + TextField tf = new TextField("", "123") { + @Override + public VaadinSession getSession() { + return fieldAppWithCustomIntegerConverter; + } + }; + tf.setConverter(Integer.class); + + // The application converter always returns 42. Application.getCurrent() + // should not be used + Assert.assertEquals(42, tf.getConvertedValue()); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/DateToLongConverterTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/DateToLongConverterTest.java new file mode 100644 index 0000000000..6300ed9479 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/DateToLongConverterTest.java @@ -0,0 +1,28 @@ +package com.vaadin.v7.tests.data.converter; + +import java.util.Date; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.v7.data.util.converter.DateToLongConverter; + +public class DateToLongConverterTest { + + DateToLongConverter converter = new DateToLongConverter(); + + @Test + public void testNullConversion() { + Assert.assertEquals(null, + converter.convertToModel(null, Long.class, null)); + } + + @Test + public void testValueConversion() { + Date d = new Date(100, 0, 1); + Assert.assertEquals( + Long.valueOf(946677600000l + + (d.getTimezoneOffset() + 120) * 60 * 1000L), + converter.convertToModel(d, Long.class, null)); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/DateToSqlDateConverterTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/DateToSqlDateConverterTest.java new file mode 100644 index 0000000000..35a8c5dbec --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/DateToSqlDateConverterTest.java @@ -0,0 +1,28 @@ +package com.vaadin.v7.tests.data.converter; + +import java.util.Date; +import java.util.Locale; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.v7.data.util.converter.DateToSqlDateConverter; + +public class DateToSqlDateConverterTest { + + DateToSqlDateConverter converter = new DateToSqlDateConverter(); + + @Test + public void testNullConversion() { + Assert.assertEquals(null, + converter.convertToModel(null, java.sql.Date.class, null)); + } + + @Test + public void testValueConversion() { + Date testDate = new Date(100, 0, 1); + long time = testDate.getTime(); + Assert.assertEquals(testDate, converter.convertToModel( + new java.sql.Date(time), java.sql.Date.class, Locale.ENGLISH)); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/DefaultConverterFactoryTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/DefaultConverterFactoryTest.java new file mode 100644 index 0000000000..a157884376 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/DefaultConverterFactoryTest.java @@ -0,0 +1,124 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * 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.vaadin.v7.tests.data.converter; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Date; +import java.util.Locale; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.v7.data.util.converter.DefaultConverterFactory; + +public class DefaultConverterFactoryTest { + + private DefaultConverterFactory factory = new DefaultConverterFactory(); + + @Test + public void stringToBigDecimal() { + assertConverter("14", new BigDecimal("14")); + } + + @Test + public void stringToBigInteger() { + assertConverter("14", new BigInteger("14")); + } + + @Test + public void stringToDouble() { + assertConverter("14", new Double("14")); + } + + @Test + public void stringToFloat() { + assertConverter("14", new Float("14")); + } + + @Test + public void stringToInteger() { + assertConverter("14", new Integer("14")); + } + + @Test + public void stringToLong() { + assertConverter("14", new Long("14")); + } + + @SuppressWarnings("deprecation") + @Test + public void stringToDate() { + assertConverter("Oct 12, 2014 12:00:00 AM", + new Date(2014 - 1900, 10 - 1, 12)); + } + + @Test + public void sqlDateToDate() { + long l = 1413071210000L; + assertConverter(new java.sql.Date(l), new java.util.Date(l)); + } + + @SuppressWarnings("deprecation") + @Test + public void longToDate() { + Date d = new Date(2014 - 1900, 10 - 1, 12); + assertConverter( + 1413061200000L + (d.getTimezoneOffset() + 180) * 60 * 1000L, d); + } + + public enum Foo { + BAR, BAZ; + } + + @Test + public void stringToEnum() { + assertConverter("Bar", Foo.BAR); + } + + @Test + public void stringToShort() { + assertConverter("14", new Short("14")); + } + + @Test + public void stringToByte() { + assertConverter("14", new Byte("14")); + } + + private <T, U> void assertConverter(T t, U u) { + Class<T> tClass = (Class<T>) t.getClass(); + Class<U> uClass = (Class<U>) u.getClass(); + + U tConvertedToU = factory.createConverter(tClass, uClass) + .convertToModel(t, uClass, Locale.ENGLISH); + Assert.assertEquals("Incorrect type of value converted from " + + tClass.getSimpleName() + " to " + uClass.getSimpleName(), + uClass, tConvertedToU.getClass()); + Assert.assertEquals("Incorrect conversion of " + t + " to " + + uClass.getSimpleName(), u, tConvertedToU); + + T uConvertedToT = factory.createConverter(uClass, tClass) + .convertToModel(u, tClass, Locale.ENGLISH); + Assert.assertEquals("Incorrect type of value converted from " + + uClass.getSimpleName() + " to " + tClass.getSimpleName(), + tClass, uConvertedToT.getClass()); + Assert.assertEquals("Incorrect conversion of " + u + " to " + + tClass.getSimpleName(), t, uConvertedToT); + + } + +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/SpecificEnumToStringConverterTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/SpecificEnumToStringConverterTest.java new file mode 100644 index 0000000000..10b4a0065e --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/SpecificEnumToStringConverterTest.java @@ -0,0 +1,125 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * 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.vaadin.v7.tests.data.converter; + +import java.util.Locale; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.tests.data.bean.AnotherTestEnum; +import com.vaadin.tests.data.bean.TestEnum; +import com.vaadin.v7.data.util.ObjectProperty; +import com.vaadin.v7.data.util.converter.Converter; +import com.vaadin.v7.data.util.converter.ReverseConverter; +import com.vaadin.v7.ui.TextField; + +public class SpecificEnumToStringConverterTest { + + public class SpecificEnumToStringConverter + implements Converter<Enum, String> { + + private Class<? extends Enum> enumClass; + + public SpecificEnumToStringConverter(Class<? extends Enum> enumClass) { + this.enumClass = enumClass; + } + + @Override + public String convertToModel(Enum value, + Class<? extends String> targetType, Locale locale) + throws com.vaadin.v7.data.util.converter.Converter.ConversionException { + if (value == null) { + return null; + } + + return value.toString(); + } + + @Override + public Enum convertToPresentation(String value, + Class<? extends Enum> targetType, Locale locale) + throws com.vaadin.v7.data.util.converter.Converter.ConversionException { + if (value == null) { + return null; + } + + for (Enum e : enumClass.getEnumConstants()) { + if (e.toString().equals(value)) { + return e; + } + } + + return null; + } + + @Override + public Class<String> getModelType() { + return String.class; + } + + @Override + public Class<Enum> getPresentationType() { + return (Class<Enum>) enumClass; + } + + } + + SpecificEnumToStringConverter testEnumConverter; + SpecificEnumToStringConverter anotherTestEnumConverter; + + @Before + public void setup() { + testEnumConverter = new SpecificEnumToStringConverter(TestEnum.class); + anotherTestEnumConverter = new SpecificEnumToStringConverter( + AnotherTestEnum.class); + } + + @Test + public void nullConversion() { + Assert.assertEquals(null, + testEnumConverter.convertToModel(null, null, null)); + } + + @Test + public void enumToStringConversion() { + Assert.assertEquals(TestEnum.TWO.toString(), testEnumConverter + .convertToModel(TestEnum.TWO, String.class, null)); + } + + @Test + public void stringToEnumConversion() { + Assert.assertEquals(TestEnum.TWO, + testEnumConverter.convertToPresentation(TestEnum.TWO.toString(), + TestEnum.class, null)); + } + + @Test + public void stringToEnumWithField() { + TextField tf = new TextField(); + tf.setConverter(new ReverseConverter(anotherTestEnumConverter)); + tf.setPropertyDataSource(new ObjectProperty(AnotherTestEnum.TWO)); + Assert.assertEquals(AnotherTestEnum.TWO.toString(), tf.getValue()); + tf.setValue(AnotherTestEnum.ONE.toString()); + Assert.assertEquals(AnotherTestEnum.ONE.toString(), tf.getValue()); + Assert.assertEquals(AnotherTestEnum.ONE, tf.getConvertedValue()); + Assert.assertEquals(AnotherTestEnum.ONE, + tf.getPropertyDataSource().getValue()); + + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToBigDecimalConverterTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToBigDecimalConverterTest.java new file mode 100644 index 0000000000..00e384e594 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToBigDecimalConverterTest.java @@ -0,0 +1,59 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * 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.vaadin.v7.tests.data.converter; + +import java.math.BigDecimal; +import java.util.Locale; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.v7.data.util.converter.StringToBigDecimalConverter; + +public class StringToBigDecimalConverterTest { + + StringToBigDecimalConverter converter = new StringToBigDecimalConverter(); + + @Test + public void testNullConversion() { + Assert.assertEquals(null, + converter.convertToModel(null, BigDecimal.class, null)); + } + + @Test + public void testEmptyStringConversion() { + Assert.assertEquals(null, + converter.convertToModel("", BigDecimal.class, null)); + } + + @Test + public void testValueParsing() { + BigDecimal converted = converter.convertToModel("10", BigDecimal.class, + null); + BigDecimal expected = new BigDecimal(10); + Assert.assertEquals(expected, converted); + } + + @Test + public void testValueFormatting() { + BigDecimal bd = new BigDecimal(12.5); + String expected = "12,5"; + + String converted = converter.convertToPresentation(bd, String.class, + Locale.GERMAN); + Assert.assertEquals(expected, converted); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToBigIntegerConverterTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToBigIntegerConverterTest.java new file mode 100644 index 0000000000..f613950c71 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToBigIntegerConverterTest.java @@ -0,0 +1,64 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * 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.vaadin.v7.tests.data.converter; + +import java.math.BigInteger; +import java.util.Locale; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.v7.data.util.converter.StringToBigIntegerConverter; + +public class StringToBigIntegerConverterTest { + + StringToBigIntegerConverter converter = new StringToBigIntegerConverter(); + + @Test + public void testNullConversion() { + Assert.assertEquals("Null value was converted incorrectly", null, + converter.convertToModel(null, BigInteger.class, null)); + } + + @Test + public void testEmptyStringConversion() { + Assert.assertEquals("Empty value was converted incorrectly", null, + converter.convertToModel("", BigInteger.class, null)); + } + + @Test + public void testValueParsing() { + String bigInt = "1180591620717411303424"; // 2^70 > 2^63 - 1 + BigInteger converted = converter.convertToModel(bigInt, + BigInteger.class, null); + BigInteger expected = new BigInteger(bigInt); + Assert.assertEquals( + "Value bigger than max long was converted incorrectly", + expected, converted); + } + + @Test + public void testValueFormatting() { + BigInteger bd = new BigInteger("1000"); + String expected = "1.000"; + + String converted = converter.convertToPresentation(bd, String.class, + Locale.GERMAN); + Assert.assertEquals( + "Value with specific locale was converted incorrectly", + expected, converted); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToBooleanConverterTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToBooleanConverterTest.java new file mode 100644 index 0000000000..9f94a4185e --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToBooleanConverterTest.java @@ -0,0 +1,82 @@ +package com.vaadin.v7.tests.data.converter; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.v7.data.util.converter.StringToBooleanConverter; + +public class StringToBooleanConverterTest { + + StringToBooleanConverter converter = new StringToBooleanConverter(); + StringToBooleanConverter yesNoConverter = new StringToBooleanConverter( + "yes", "no"); + StringToBooleanConverter localeConverter = new StringToBooleanConverter() { + @Override + public String getFalseString(Locale locale) { + Date d = new Date(3000000000000L); + return SimpleDateFormat + .getDateInstance(SimpleDateFormat.LONG, locale) + .format(d.getTime() + + (d.getTimezoneOffset() + 120) * 60 * 1000L); + } + + @Override + public String getTrueString(Locale locale) { + Date d = new Date(2000000000000L); + return SimpleDateFormat + .getDateInstance(SimpleDateFormat.LONG, locale) + .format(d.getTime() + + (d.getTimezoneOffset() + 120) * 60 * 1000L); + } + }; + + @Test + public void testNullConversion() { + Assert.assertEquals(null, + converter.convertToModel(null, Boolean.class, null)); + } + + @Test + public void testEmptyStringConversion() { + Assert.assertEquals(null, + converter.convertToModel("", Boolean.class, null)); + } + + @Test + public void testValueConversion() { + Assert.assertTrue( + converter.convertToModel("true", Boolean.class, null)); + Assert.assertFalse( + converter.convertToModel("false", Boolean.class, null)); + } + + @Test + public void testYesNoValueConversion() { + Assert.assertTrue( + yesNoConverter.convertToModel("yes", Boolean.class, null)); + Assert.assertFalse( + yesNoConverter.convertToModel("no", Boolean.class, null)); + + Assert.assertEquals("yes", + yesNoConverter.convertToPresentation(true, String.class, null)); + Assert.assertEquals("no", yesNoConverter.convertToPresentation(false, + String.class, null)); + } + + @Test + public void testLocale() { + Assert.assertEquals("May 18, 2033", localeConverter + .convertToPresentation(true, String.class, Locale.US)); + Assert.assertEquals("January 24, 2065", localeConverter + .convertToPresentation(false, String.class, Locale.US)); + + Assert.assertEquals("18. Mai 2033", localeConverter + .convertToPresentation(true, String.class, Locale.GERMANY)); + Assert.assertEquals("24. Januar 2065", localeConverter + .convertToPresentation(false, String.class, Locale.GERMANY)); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToByteConverterTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToByteConverterTest.java new file mode 100644 index 0000000000..1ffc7a020e --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToByteConverterTest.java @@ -0,0 +1,76 @@ +package com.vaadin.v7.tests.data.converter; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.v7.data.util.converter.Converter; +import com.vaadin.v7.data.util.converter.Converter.ConversionException; +import com.vaadin.v7.data.util.converter.ReverseConverter; +import com.vaadin.v7.data.util.converter.StringToByteConverter; + +public class StringToByteConverterTest { + + StringToByteConverter converter = new StringToByteConverter(); + Converter<Byte, String> reverseConverter = new ReverseConverter<Byte, String>( + converter); + + @Test + public void testNullConversion() { + Assert.assertEquals("Null value was converted incorrectly", null, + converter.convertToModel(null, Byte.class, null)); + } + + @Test + public void testReverseNullConversion() { + Assert.assertEquals("Null value reversely was converted incorrectly", + null, + reverseConverter.convertToModel(null, String.class, null)); + } + + @Test + public void testEmptyStringConversion() { + Assert.assertEquals("Empty value was converted incorrectly", null, + converter.convertToModel("", Byte.class, null)); + } + + @Test + public void testValueConversion() { + Assert.assertEquals("Byte value was converted incorrectly", + Byte.valueOf((byte) 10), + converter.convertToModel("10", Byte.class, null)); + } + + @Test + public void testReverseValueConversion() { + Assert.assertEquals("Byte value reversely was converted incorrectly", + reverseConverter.convertToModel((byte) 10, String.class, null), + "10"); + } + + @Test + public void testExtremeByteValueConversion() { + byte b = converter.convertToModel("127", Byte.class, null); + Assert.assertEquals(Byte.MAX_VALUE, b); + b = converter.convertToModel("-128", Byte.class, null); + Assert.assertEquals("Min byte value was converted incorrectly", + Byte.MIN_VALUE, b); + } + + @Test + public void testValueOutOfRange() { + Double[] values = new Double[] { Byte.MAX_VALUE * 2.0, + Byte.MIN_VALUE * 2.0, Long.MAX_VALUE * 2.0, + Long.MIN_VALUE * 2.0 }; + + boolean accepted = false; + for (Number value : values) { + try { + converter.convertToModel(String.format("%.0f", value), + Byte.class, null); + accepted = true; + } catch (ConversionException expected) { + } + } + Assert.assertFalse("Accepted value outside range of int", accepted); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToCollectionConverterTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToCollectionConverterTest.java new file mode 100644 index 0000000000..f6dc22face --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToCollectionConverterTest.java @@ -0,0 +1,172 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * 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.vaadin.v7.tests.data.converter; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Set; +import java.util.Vector; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.v7.data.util.converter.StringToCollectionConverter; +import com.vaadin.v7.data.util.converter.StringToCollectionConverter.CollectionFactory; +import com.vaadin.v7.data.util.converter.StringToEnumConverter; +import com.vaadin.v7.data.util.converter.StringToIntegerConverter; + +/** + * Tests for {@link StringToCollectionConverter}. + * + * @author Vaadin Ltd + */ +public class StringToCollectionConverterTest { + + @Test + public void convertToModel_defaultCtor() { + StringToCollectionConverter converter = new StringToCollectionConverter(); + Collection<?> model = converter.convertToModel("a, b, c", List.class, + null); + Assert.assertTrue("Unexpected model class", model instanceof ArrayList); + Iterator<?> iterator = model.iterator(); + Assert.assertEquals("Incorrect fist token", "a", iterator.next()); + Assert.assertEquals("Incorrect second token", "b", iterator.next()); + Assert.assertEquals("Incorrect third token", "c", iterator.next()); + } + + @Test + public void convertToModel_customDelimiter() { + StringToCollectionConverter converter = new StringToCollectionConverter( + "x"); + Collection<?> model = converter.convertToModel("axbxc", List.class, + null); + Assert.assertTrue("Unexpected model class", model instanceof ArrayList); + Iterator<?> iterator = model.iterator(); + Assert.assertEquals("Incorrect fist token", "a", iterator.next()); + Assert.assertEquals("Incorrect second token", "b", iterator.next()); + Assert.assertEquals("Incorrect third token", "c", iterator.next()); + } + + @Test + public void convertToModel_customConverter() { + StringToCollectionConverter converter = new StringToCollectionConverter( + ",", new StringToIntegerConverter(), Integer.class); + Collection<?> model = converter.convertToModel("6,2,5", List.class, + null); + Assert.assertTrue("Unexpected model class", model instanceof ArrayList); + Iterator<?> iterator = model.iterator(); + Assert.assertEquals("Incorrect fist token", 6, iterator.next()); + Assert.assertEquals("Incorrect second token", 2, iterator.next()); + Assert.assertEquals("Incorrect third token", 5, iterator.next()); + } + + @Test + public void convertToModel_setAsCollection() { + StringToCollectionConverter converter = new StringToCollectionConverter( + " ", new StringToEnumConverter(), TestEnum.class); + Collection<?> model = converter.convertToModel("Z X Y", Set.class, + null); + Assert.assertTrue("Unexpected model class", model instanceof HashSet); + EnumSet<TestEnum> set = EnumSet.allOf(TestEnum.class); + set.removeAll(model); + Assert.assertTrue("Some values are not in resutling collection", + set.isEmpty()); + } + + @Test + public void convertToModel_customFactory() { + CollectionFactory factory = new CollectionFactory() { + + @Override + public Collection<?> createCollection( + Class<? extends Collection> type) { + return new Vector(); + } + }; + StringToCollectionConverter converter = new StringToCollectionConverter( + ", ", null, String.class, factory); + Collection<?> model = converter.convertToModel("a, b, c", + Collection.class, null); + Assert.assertTrue("Unexpected model class", model instanceof Vector); + Iterator<?> iterator = model.iterator(); + Assert.assertEquals("Incorrect fist token", "a", iterator.next()); + Assert.assertEquals("Incorrect second token", "b", iterator.next()); + Assert.assertEquals("Incorrect third token", "c", iterator.next()); + } + + @Test + public void convertToPresentation_default() { + StringToCollectionConverter converter = new StringToCollectionConverter(); + String presentation = converter.convertToPresentation( + Arrays.asList("a", "b", "c"), String.class, null); + + Assert.assertEquals("a, b, c", presentation); + } + + @Test + public void convertToPresentation_customDelimiter() { + StringToCollectionConverter converter = new StringToCollectionConverter( + "x"); + String presentation = converter.convertToPresentation( + Arrays.asList("a", "b", "c"), String.class, null); + + Assert.assertEquals("axbxc", presentation); + } + + @Test + public void convertToPresentation_customConverter() { + StringToCollectionConverter converter = new StringToCollectionConverter( + ",", new StringToEnumConverter(), TestEnum.class); + String presentation = converter.convertToPresentation( + Arrays.asList(TestEnum.Z, TestEnum.Y), String.class, null); + + Assert.assertEquals("Z,Y", presentation); + } + + @Test + public void convertToModel_singleItem() { + StringToCollectionConverter converter = new StringToCollectionConverter(); + Collection<?> model = converter.convertToModel("a", List.class, null); + Iterator<?> iterator = model.iterator(); + Assert.assertEquals("Incorrect fist token", "a", iterator.next()); + Assert.assertFalse("More than one item detected after conversation", + iterator.hasNext()); + } + + @Test + public void convertToModel_null() { + StringToCollectionConverter converter = new StringToCollectionConverter(); + Assert.assertNull(converter.convertToModel(null, ArrayList.class, + Locale.ENGLISH)); + } + + @Test + public void convertToPresentation_null() { + StringToCollectionConverter converter = new StringToCollectionConverter(); + Assert.assertNull(converter.convertToPresentation(null, String.class, + Locale.ENGLISH)); + } + + public enum TestEnum { + X, Y, Z; + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToDateConverterTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToDateConverterTest.java new file mode 100644 index 0000000000..c778e9e731 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToDateConverterTest.java @@ -0,0 +1,32 @@ +package com.vaadin.v7.tests.data.converter; + +import java.util.Date; +import java.util.Locale; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.v7.data.util.converter.StringToDateConverter; + +public class StringToDateConverterTest { + + StringToDateConverter converter = new StringToDateConverter(); + + @Test + public void testNullConversion() { + Assert.assertEquals(null, + converter.convertToModel(null, Date.class, null)); + } + + @Test + public void testEmptyStringConversion() { + Assert.assertEquals(null, + converter.convertToModel("", Date.class, null)); + } + + @Test + public void testValueConversion() { + Assert.assertEquals(new Date(100, 0, 1), converter.convertToModel( + "Jan 1, 2000 12:00:00 AM", Date.class, Locale.ENGLISH)); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToDoubleConverterTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToDoubleConverterTest.java new file mode 100644 index 0000000000..a0891ecefe --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToDoubleConverterTest.java @@ -0,0 +1,29 @@ +package com.vaadin.v7.tests.data.converter; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.v7.data.util.converter.StringToDoubleConverter; + +public class StringToDoubleConverterTest { + + StringToDoubleConverter converter = new StringToDoubleConverter(); + + @Test + public void testNullConversion() { + Assert.assertEquals(null, + converter.convertToModel(null, Double.class, null)); + } + + @Test + public void testEmptyStringConversion() { + Assert.assertEquals(null, + converter.convertToModel("", Double.class, null)); + } + + @Test + public void testValueConversion() { + Double value = converter.convertToModel("10", Double.class, null); + Assert.assertEquals(10.0d, value, 0.01d); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToEnumConverterTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToEnumConverterTest.java new file mode 100644 index 0000000000..a86b8b82e0 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToEnumConverterTest.java @@ -0,0 +1,135 @@ +package com.vaadin.v7.tests.data.converter; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.v7.data.util.converter.Converter; +import com.vaadin.v7.data.util.converter.Converter.ConversionException; +import com.vaadin.v7.data.util.converter.ReverseConverter; +import com.vaadin.v7.data.util.converter.StringToEnumConverter; + +public class StringToEnumConverterTest { + + public static enum FooEnum { + VALUE1, SOME_VALUE, FOO_BAR_BAZ, Bar, nonStandardCase, _HUGH; + } + + public static enum EnumWithCustomToString { + ONE, TWO, THREE; + + @Override + public String toString() { + return "case " + (ordinal() + 1); + } + } + + public static enum EnumWithAmbigousToString { + FOO, FOOBAR, FOO_BAR; + + @Override + public String toString() { + return name().replaceAll("_", ""); + } + } + + StringToEnumConverter converter = new StringToEnumConverter(); + Converter<Enum, String> reverseConverter = new ReverseConverter<Enum, String>( + converter); + + private String convertToString(Enum value) { + return converter.convertToPresentation(value, String.class, null); + } + + public Enum convertToEnum(String string, Class<? extends Enum> type) { + return converter.convertToModel(string, type, null); + } + + @Test + public void testEmptyStringConversion() { + Assert.assertEquals(null, + converter.convertToModel("", Enum.class, null)); + } + + @Test + public void testInvalidEnumClassConversion() { + try { + converter.convertToModel("Foo", Enum.class, null); + Assert.fail("No exception thrown"); + } catch (ConversionException e) { + // OK + } + } + + @Test + public void testNullConversion() { + Assert.assertEquals(null, + converter.convertToModel(null, Enum.class, null)); + } + + @Test + public void testReverseNullConversion() { + Assert.assertEquals(null, + reverseConverter.convertToModel(null, String.class, null)); + } + + @Test + public void testValueConversion() { + Assert.assertEquals(FooEnum.VALUE1, + converter.convertToModel("Value1", FooEnum.class, null)); + Assert.assertEquals(FooEnum.SOME_VALUE, + converter.convertToModel("Some value", FooEnum.class, null)); + Assert.assertEquals(FooEnum.FOO_BAR_BAZ, + converter.convertToModel("Foo bar baz", FooEnum.class, null)); + Assert.assertEquals(FooEnum.Bar, + converter.convertToModel("Bar", FooEnum.class, null)); + Assert.assertEquals(FooEnum.nonStandardCase, converter + .convertToModel("Nonstandardcase", FooEnum.class, null)); + Assert.assertEquals(FooEnum._HUGH, + converter.convertToModel("_hugh", FooEnum.class, null)); + } + + @Test + public void testReverseValueConversion() { + Assert.assertEquals("Value1", reverseConverter + .convertToModel(FooEnum.VALUE1, String.class, null)); + Assert.assertEquals("Some value", reverseConverter + .convertToModel(FooEnum.SOME_VALUE, String.class, null)); + Assert.assertEquals("Foo bar baz", reverseConverter + .convertToModel(FooEnum.FOO_BAR_BAZ, String.class, null)); + Assert.assertEquals("Bar", reverseConverter.convertToModel(FooEnum.Bar, + String.class, null)); + Assert.assertEquals("Nonstandardcase", reverseConverter + .convertToModel(FooEnum.nonStandardCase, String.class, null)); + Assert.assertEquals("_hugh", reverseConverter + .convertToModel(FooEnum._HUGH, String.class, null)); + + } + + @Test + public void preserveFormattingWithCustomToString() { + for (EnumWithCustomToString e : EnumWithCustomToString.values()) { + Assert.assertEquals(e.toString(), convertToString(e)); + } + } + + @Test + public void findEnumWithCustomToString() { + for (EnumWithCustomToString e : EnumWithCustomToString.values()) { + Assert.assertSame(e, + convertToEnum(e.toString(), EnumWithCustomToString.class)); + Assert.assertSame(e, + convertToEnum(e.name(), EnumWithCustomToString.class)); + } + } + + @Test + public void unambigousValueInEnumWithAmbigous_succeed() { + Assert.assertSame(EnumWithAmbigousToString.FOO, + convertToEnum("foo", EnumWithAmbigousToString.class)); + } + + @Test(expected = ConversionException.class) + public void ambigousValue_throws() { + convertToEnum("foobar", EnumWithAmbigousToString.class); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToFloatConverterTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToFloatConverterTest.java new file mode 100644 index 0000000000..70c408b808 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToFloatConverterTest.java @@ -0,0 +1,29 @@ +package com.vaadin.v7.tests.data.converter; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.v7.data.util.converter.StringToFloatConverter; + +public class StringToFloatConverterTest { + + StringToFloatConverter converter = new StringToFloatConverter(); + + @Test + public void testNullConversion() { + Assert.assertEquals(null, + converter.convertToModel(null, Float.class, null)); + } + + @Test + public void testEmptyStringConversion() { + Assert.assertEquals(null, + converter.convertToModel("", Float.class, null)); + } + + @Test + public void testValueConversion() { + Assert.assertEquals(Float.valueOf(10), + converter.convertToModel("10", Float.class, null)); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToIntegerConverterTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToIntegerConverterTest.java new file mode 100644 index 0000000000..0cc8e646dc --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToIntegerConverterTest.java @@ -0,0 +1,48 @@ +package com.vaadin.v7.tests.data.converter; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.v7.data.util.converter.Converter.ConversionException; +import com.vaadin.v7.data.util.converter.StringToIntegerConverter; + +public class StringToIntegerConverterTest { + + StringToIntegerConverter converter = new StringToIntegerConverter(); + + @Test + public void testNullConversion() { + Assert.assertEquals(null, + converter.convertToModel(null, Integer.class, null)); + } + + @Test + public void testEmptyStringConversion() { + Assert.assertEquals(null, + converter.convertToModel("", Integer.class, null)); + } + + @Test + public void testValueOutOfRange() { + Double[] values = new Double[] { Integer.MAX_VALUE * 2.0, + Integer.MIN_VALUE * 2.0, Long.MAX_VALUE * 2.0, + Long.MIN_VALUE * 2.0 }; + + boolean accepted = false; + for (Number value : values) { + try { + converter.convertToModel(String.format("%.0f", value), + Integer.class, null); + accepted = true; + } catch (ConversionException expected) { + } + } + Assert.assertFalse("Accepted value outside range of int", accepted); + } + + @Test + public void testValueConversion() { + Assert.assertEquals(Integer.valueOf(10), + converter.convertToModel("10", Integer.class, null)); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToLongConverterTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToLongConverterTest.java new file mode 100644 index 0000000000..5e5b9f1d86 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToLongConverterTest.java @@ -0,0 +1,78 @@ +package com.vaadin.v7.tests.data.converter; + +import java.util.Locale; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.v7.data.util.converter.Converter; +import com.vaadin.v7.data.util.converter.ReverseConverter; +import com.vaadin.v7.data.util.converter.StringToLongConverter; + +public class StringToLongConverterTest { + + StringToLongConverter converter = new StringToLongConverter(); + Converter<Long, String> reverseConverter = new ReverseConverter<Long, String>( + converter); + + @Test + public void testNullConversion() { + Assert.assertEquals(null, + converter.convertToModel(null, Long.class, null)); + } + + @Test + public void testReverseNullConversion() { + Assert.assertEquals(null, + reverseConverter.convertToModel(null, String.class, null)); + } + + @Test + public void testEmptyStringConversion() { + Assert.assertEquals(null, + converter.convertToModel("", Long.class, null)); + } + + @Test + public void testValueConversion() { + Assert.assertEquals(Long.valueOf(10), + converter.convertToModel("10", Long.class, null)); + } + + @Test + public void testReverseValueConversion() { + Assert.assertEquals( + reverseConverter.convertToModel(10L, String.class, null), "10"); + } + + @Test + public void testExtremeLongValueConversion() { + long l = converter.convertToModel("9223372036854775807", Long.class, + null); + Assert.assertEquals(Long.MAX_VALUE, l); + l = converter.convertToModel("-9223372036854775808", Long.class, null); + Assert.assertEquals(Long.MIN_VALUE, l); + } + + @Test + public void testExtremeReverseLongValueConversion() { + String str = reverseConverter.convertToModel(Long.MAX_VALUE, + String.class, Locale.ENGLISH); + Assert.assertEquals("9,223,372,036,854,775,807", str); + str = reverseConverter.convertToModel(Long.MIN_VALUE, String.class, + Locale.ENGLISH); + Assert.assertEquals("-9,223,372,036,854,775,808", str); + } + + @Test + public void testOutOfBoundsValueConversion() { + // Long.MAX_VALUE+1 is converted to Long.MAX_VALUE + long l = converter.convertToModel("9223372036854775808", Long.class, + null); + Assert.assertEquals(Long.MAX_VALUE, l); + // Long.MIN_VALUE-1 is converted to Long.MIN_VALUE + l = converter.convertToModel("-9223372036854775809", Long.class, null); + Assert.assertEquals(Long.MIN_VALUE, l); + + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToShortConverterTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToShortConverterTest.java new file mode 100644 index 0000000000..a2a7332fd1 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/data/converter/StringToShortConverterTest.java @@ -0,0 +1,76 @@ +package com.vaadin.v7.tests.data.converter; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.v7.data.util.converter.Converter; +import com.vaadin.v7.data.util.converter.Converter.ConversionException; +import com.vaadin.v7.data.util.converter.ReverseConverter; +import com.vaadin.v7.data.util.converter.StringToShortConverter; + +public class StringToShortConverterTest { + + StringToShortConverter converter = new StringToShortConverter(); + Converter<Short, String> reverseConverter = new ReverseConverter<Short, String>( + converter); + + @Test + public void testNullConversion() { + Assert.assertEquals("Null value was converted incorrectly", null, + converter.convertToModel(null, Short.class, null)); + } + + @Test + public void testReverseNullConversion() { + Assert.assertEquals("Null value reversely was converted incorrectly", + null, + reverseConverter.convertToModel(null, String.class, null)); + } + + @Test + public void testEmptyStringConversion() { + Assert.assertEquals("Empty value was converted incorrectly", null, + converter.convertToModel("", Short.class, null)); + } + + @Test + public void testValueConversion() { + Assert.assertEquals("Short value was converted incorrectly", + Short.valueOf((short) 10), + converter.convertToModel("10", Short.class, null)); + } + + @Test + public void testReverseValueConversion() { + Assert.assertEquals("Short value reversely was converted incorrectly", + reverseConverter.convertToModel((short) 10, String.class, null), + "10"); + } + + @Test + public void testExtremeShortValueConversion() { + short b = converter.convertToModel("32767", Short.class, null); + Assert.assertEquals(Short.MAX_VALUE, b); + b = converter.convertToModel("-32768", Short.class, null); + Assert.assertEquals("Min short value was converted incorrectly", + Short.MIN_VALUE, b); + } + + @Test + public void testValueOutOfRange() { + Double[] values = new Double[] { Integer.MAX_VALUE * 2.0, + Integer.MIN_VALUE * 2.0, Long.MAX_VALUE * 2.0, + Long.MIN_VALUE * 2.0 }; + + boolean accepted = false; + for (Number value : values) { + try { + converter.convertToModel(String.format("%.0f", value), + Short.class, null); + accepted = true; + } catch (ConversionException expected) { + } + } + Assert.assertFalse("Accepted value outside range of int", accepted); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/server/EventRouterTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/EventRouterTest.java new file mode 100644 index 0000000000..7731941ca6 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/EventRouterTest.java @@ -0,0 +1,40 @@ +package com.vaadin.v7.tests.server; + +import org.junit.Test; + +import com.vaadin.v7.data.Property.ValueChangeEvent; +import com.vaadin.v7.data.Property.ValueChangeListener; +import com.vaadin.v7.ui.TextField; + +public class EventRouterTest { + + int innerListenerCalls = 0; + + @Test + public void testAddInEventListener() { + final TextField tf = new TextField(); + + final ValueChangeListener outer = new ValueChangeListener() { + + @Override + public void valueChange(ValueChangeEvent event) { + ValueChangeListener inner = new ValueChangeListener() { + + @Override + public void valueChange(ValueChangeEvent event) { + innerListenerCalls++; + System.out.println("The inner listener was called"); + } + }; + + tf.addListener(inner); + } + }; + + tf.addListener(outer); + tf.setValue("abc"); // No inner listener calls, adds one inner + tf.setValue("def"); // One inner listener call, adds one inner + tf.setValue("ghi"); // Two inner listener calls, adds one inner + assert (innerListenerCalls == 3); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/tests/server/PropertysetItemListenersTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/PropertysetItemListenersTest.java index 883130db32..8d1f432170 100644 --- a/compatibility-server/src/test/java/com/vaadin/tests/server/PropertysetItemListenersTest.java +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/PropertysetItemListenersTest.java @@ -1,4 +1,4 @@ -package com.vaadin.tests.server; +package com.vaadin.v7.tests.server; import com.vaadin.tests.server.component.AbstractListenerMethodsTestBase; import com.vaadin.v7.data.Item.PropertySetChangeEvent; diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/AbsFieldDataSourceLocaleChangeTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/AbsFieldDataSourceLocaleChangeTest.java new file mode 100644 index 0000000000..5cc57a75b7 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/AbsFieldDataSourceLocaleChangeTest.java @@ -0,0 +1,65 @@ +package com.vaadin.v7.tests.server.component.abstractfield; + +import java.text.NumberFormat; +import java.util.Locale; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.server.VaadinSession; +import com.vaadin.tests.util.AlwaysLockedVaadinSession; +import com.vaadin.ui.UI; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.v7.data.util.converter.StringToIntegerConverter; +import com.vaadin.v7.ui.TextField; + +public class AbsFieldDataSourceLocaleChangeTest { + + private VaadinSession vaadinSession; + private UI ui; + + @Before + public void setup() { + vaadinSession = new AlwaysLockedVaadinSession(null); + VaadinSession.setCurrent(vaadinSession); + ui = new UI() { + + @Override + protected void init(VaadinRequest request) { + + } + }; + ui.setSession(vaadinSession); + UI.setCurrent(ui); + } + + @Test + public void localeChangesOnAttach() { + TextField tf = new TextField(); + + tf.setConverter(new StringToIntegerConverter() { + @Override + protected NumberFormat getFormat(Locale locale) { + if (locale == null) { + NumberFormat format = super.getFormat(locale); + format.setGroupingUsed(false); + format.setMinimumIntegerDigits(10); + return format; + } + return super.getFormat(locale); + } + }); + tf.setImmediate(true); + tf.setConvertedValue(10000); + Assert.assertEquals("0000010000", tf.getValue()); + + VerticalLayout vl = new VerticalLayout(); + ui.setContent(vl); + ui.setLocale(new Locale("en", "US")); + + vl.addComponent(tf); + Assert.assertEquals("10,000", tf.getValue()); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/AbsFieldValidatorsTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/AbsFieldValidatorsTest.java new file mode 100644 index 0000000000..09ab8fe65f --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/AbsFieldValidatorsTest.java @@ -0,0 +1,79 @@ +package com.vaadin.v7.tests.server.component.abstractfield; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.easymock.EasyMock; +import org.junit.Test; + +import com.vaadin.v7.data.Validator; +import com.vaadin.v7.ui.AbstractField; + +public class AbsFieldValidatorsTest { + + AbstractField<Object> field = new AbstractField<Object>() { + @Override + public Class getType() { + return Object.class; + } + }; + + Validator validator = EasyMock.createMock(Validator.class); + Validator validator2 = EasyMock.createMock(Validator.class); + + @Test + public void testAddValidator() { + assertNotNull(field.getValidators()); + assertEquals(0, field.getValidators().size()); + + field.addValidator(validator); + assertEquals(1, field.getValidators().size()); + assertTrue(field.getValidators().contains(validator)); + + field.addValidator(validator2); + assertEquals(2, field.getValidators().size()); + assertTrue(field.getValidators().contains(validator)); + assertTrue(field.getValidators().contains(validator2)); + } + + @Test + public void testRemoveValidator() { + field.addValidator(validator); + field.addValidator(validator2); + + field.removeValidator(validator); + assertNotNull(field.getValidators()); + assertEquals(1, field.getValidators().size()); + assertFalse(field.getValidators().contains(validator)); + assertTrue(field.getValidators().contains(validator2)); + + field.removeValidator(validator2); + assertNotNull(field.getValidators()); + assertEquals(0, field.getValidators().size()); + assertFalse(field.getValidators().contains(validator)); + assertFalse(field.getValidators().contains(validator2)); + } + + @Test + public void testRemoveAllValidators() { + field.addValidator(validator); + field.addValidator(validator2); + + field.removeAllValidators(); + assertNotNull(field.getValidators()); + assertEquals(0, field.getValidators().size()); + assertFalse(field.getValidators().contains(validator)); + assertFalse(field.getValidators().contains(validator2)); + } + + @Test + public void nonImmediateFieldWithValidator() { + field.setImmediate(false); + field.addValidator(validator); + assertFalse("field should be non-immediate because explicitly set", + field.isImmediate()); + } + +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/AbsFieldValueConversionErrorTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/AbsFieldValueConversionErrorTest.java new file mode 100644 index 0000000000..4def8caca7 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/AbsFieldValueConversionErrorTest.java @@ -0,0 +1,92 @@ +package com.vaadin.v7.tests.server.component.abstractfield; + +import static org.junit.Assert.fail; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.tests.data.bean.Address; +import com.vaadin.tests.data.bean.Country; +import com.vaadin.tests.data.bean.Person; +import com.vaadin.tests.data.bean.Sex; +import com.vaadin.v7.data.Validator.InvalidValueException; +import com.vaadin.v7.data.util.converter.Converter.ConversionException; +import com.vaadin.v7.data.util.MethodProperty; +import com.vaadin.v7.data.util.converter.StringToIntegerConverter; +import com.vaadin.v7.ui.TextField; + +public class AbsFieldValueConversionErrorTest { + + Person paulaBean = new Person("Paula", "Brilliant", "paula@brilliant.com", + 34, Sex.FEMALE, + new Address("Paula street 1", 12345, "P-town", Country.FINLAND)); + + @Test + public void testValidateConversionErrorParameters() { + TextField tf = new TextField(); + tf.setConverter(new StringToIntegerConverter()); + tf.setPropertyDataSource(new MethodProperty<String>(paulaBean, "age")); + tf.setConversionError("(Type: {0}) Converter exception message: {1}"); + tf.setValue("abc"); + try { + tf.validate(); + fail(); + } catch (InvalidValueException e) { + Assert.assertEquals( + "(Type: Integer) Converter exception message: Could not convert 'abc' to java.lang.Integer", + e.getMessage()); + } + + } + + @Test + public void testConvertToModelConversionErrorParameters() { + TextField tf = new TextField(); + tf.setConverter(new StringToIntegerConverter()); + tf.setPropertyDataSource(new MethodProperty<String>(paulaBean, "age")); + tf.setConversionError("(Type: {0}) Converter exception message: {1}"); + tf.setValue("abc"); + try { + tf.getConvertedValue(); + fail(); + } catch (ConversionException e) { + Assert.assertEquals( + "(Type: Integer) Converter exception message: Could not convert 'abc' to java.lang.Integer", + e.getMessage()); + } + + } + + @Test + public void testNullConversionMessages() { + TextField tf = new TextField(); + tf.setConverter(new StringToIntegerConverter()); + tf.setPropertyDataSource(new MethodProperty<String>(paulaBean, "age")); + tf.setConversionError(null); + tf.setValue("abc"); + try { + tf.validate(); + fail(); + } catch (InvalidValueException e) { + Assert.assertEquals(null, e.getMessage()); + } + + } + + @Test + public void testDefaultConversionErrorMessage() { + TextField tf = new TextField(); + tf.setConverter(new StringToIntegerConverter()); + tf.setPropertyDataSource(new MethodProperty<String>(paulaBean, "age")); + tf.setValue("abc"); + + try { + tf.validate(); + fail(); + } catch (InvalidValueException e) { + Assert.assertEquals("Could not convert value to Integer", + e.getMessage()); + } + + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/AbsFieldValueConversionsTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/AbsFieldValueConversionsTest.java new file mode 100644 index 0000000000..6594ed9351 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/AbsFieldValueConversionsTest.java @@ -0,0 +1,216 @@ +package com.vaadin.v7.tests.server.component.abstractfield; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Locale; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.server.VaadinSession; +import com.vaadin.tests.data.bean.Address; +import com.vaadin.tests.data.bean.Country; +import com.vaadin.tests.data.bean.Person; +import com.vaadin.tests.data.bean.Sex; +import com.vaadin.tests.util.AlwaysLockedVaadinSession; +import com.vaadin.v7.data.util.MethodProperty; +import com.vaadin.v7.data.util.ObjectProperty; +import com.vaadin.v7.data.util.converter.Converter; +import com.vaadin.v7.data.util.converter.Converter.ConversionException; +import com.vaadin.v7.data.util.converter.StringToIntegerConverter; +import com.vaadin.v7.ui.TextField; + +public class AbsFieldValueConversionsTest { + + Person paulaBean = new Person("Paula", "Brilliant", "paula@brilliant.com", + 34, Sex.FEMALE, + new Address("Paula street 1", 12345, "P-town", Country.FINLAND)); + + /** + * Java uses a non-breaking space (ascii 160) instead of space when + * formatting + */ + private static final char FORMATTED_SPACE = 160; + + @Test + public void testWithoutConversion() { + TextField tf = new TextField(); + tf.setPropertyDataSource( + new MethodProperty<String>(paulaBean, "firstName")); + assertEquals("Paula", tf.getValue()); + assertEquals("Paula", tf.getPropertyDataSource().getValue()); + tf.setValue("abc"); + assertEquals("abc", tf.getValue()); + assertEquals("abc", tf.getPropertyDataSource().getValue()); + assertEquals("abc", paulaBean.getFirstName()); + } + + @Test + public void testNonmodifiedBufferedFieldConversion() { + VaadinSession.setCurrent(new AlwaysLockedVaadinSession(null)); + TextField tf = new TextField("salary"); + tf.setBuffered(true); + tf.setLocale(new Locale("en", "US")); + ObjectProperty<Integer> ds = new ObjectProperty<Integer>(123456789); + tf.setPropertyDataSource(ds); + assertEquals((Integer) 123456789, ds.getValue()); + assertEquals("123,456,789", tf.getValue()); + tf.setLocale(new Locale("fi", "FI")); + assertEquals((Integer) 123456789, ds.getValue()); + assertEquals("123" + FORMATTED_SPACE + "456" + FORMATTED_SPACE + "789", + tf.getValue()); + + } + + @Test + public void testModifiedBufferedFieldConversion() { + VaadinSession.setCurrent(new AlwaysLockedVaadinSession(null)); + TextField tf = new TextField("salary"); + tf.setBuffered(true); + tf.setLocale(new Locale("en", "US")); + ObjectProperty<Integer> ds = new ObjectProperty<Integer>(123456789); + tf.setPropertyDataSource(ds); + assertEquals((Integer) 123456789, ds.getValue()); + assertEquals("123,456,789", tf.getValue()); + tf.setValue("123,123"); + assertEquals((Integer) 123456789, ds.getValue()); + assertEquals("123,123", tf.getValue()); + + tf.setLocale(new Locale("fi", "FI")); + assertEquals((Integer) 123456789, ds.getValue()); + // Value should not be updated when field is buffered + assertEquals("123,123", tf.getValue()); + } + + @Test + public void testStringIdentityConversion() { + TextField tf = new TextField(); + tf.setConverter(new Converter<String, String>() { + + @Override + public String convertToModel(String value, + Class<? extends String> targetType, Locale locale) { + return value; + } + + @Override + public String convertToPresentation(String value, + Class<? extends String> targetType, Locale locale) { + return value; + } + + @Override + public Class<String> getModelType() { + return String.class; + } + + @Override + public Class<String> getPresentationType() { + return String.class; + } + }); + tf.setPropertyDataSource( + new MethodProperty<String>(paulaBean, "firstName")); + assertEquals("Paula", tf.getValue()); + assertEquals("Paula", tf.getPropertyDataSource().getValue()); + tf.setValue("abc"); + assertEquals("abc", tf.getValue()); + assertEquals("abc", tf.getPropertyDataSource().getValue()); + assertEquals("abc", paulaBean.getFirstName()); + } + + @Test + public void testIntegerStringConversion() { + TextField tf = new TextField(); + + tf.setConverter(new StringToIntegerConverter()); + tf.setPropertyDataSource(new MethodProperty<Integer>(paulaBean, "age")); + assertEquals(34, tf.getPropertyDataSource().getValue()); + assertEquals("34", tf.getValue()); + tf.setValue("12"); + assertEquals(12, tf.getPropertyDataSource().getValue()); + assertEquals("12", tf.getValue()); + tf.getPropertyDataSource().setValue(42); + assertEquals(42, tf.getPropertyDataSource().getValue()); + assertEquals("42", tf.getValue()); + } + + @Test + public void testChangeReadOnlyFieldLocale() { + VaadinSession.setCurrent(new AlwaysLockedVaadinSession(null)); + + TextField tf = new TextField("salary"); + tf.setLocale(new Locale("en", "US")); + ObjectProperty<Integer> ds = new ObjectProperty<Integer>(123456789); + ds.setReadOnly(true); + tf.setPropertyDataSource(ds); + assertEquals((Integer) 123456789, ds.getValue()); + assertEquals("123,456,789", tf.getValue()); + tf.setLocale(new Locale("fi", "FI")); + assertEquals((Integer) 123456789, ds.getValue()); + assertEquals("123" + FORMATTED_SPACE + "456" + FORMATTED_SPACE + "789", + tf.getValue()); + } + + // Now specific to Integer because StringToNumberConverter has been removed + public static class NumberBean { + private Integer number; + + public Integer getNumber() { + return number; + } + + public void setNumber(Integer number) { + this.number = number; + } + + } + + @Test + public void testNumberDoubleConverterChange() { + final VaadinSession a = new AlwaysLockedVaadinSession(null); + VaadinSession.setCurrent(a); + TextField tf = new TextField() { + @Override + public VaadinSession getSession() { + return a; + } + }; + NumberBean nb = new NumberBean(); + nb.setNumber(490); + + tf.setPropertyDataSource(new MethodProperty<Number>(nb, "number")); + assertEquals(490, tf.getPropertyDataSource().getValue()); + assertEquals("490", tf.getValue()); + + Converter c1 = tf.getConverter(); + + tf.setPropertyDataSource(new MethodProperty<Number>(nb, "number")); + Converter c2 = tf.getConverter(); + assertTrue( + "StringToInteger converter is ok for integer types and should stay even though property is changed", + c1 == c2); + assertEquals(490, tf.getPropertyDataSource().getValue()); + assertEquals("490", tf.getValue()); + + } + + @Test + public void testNullConverter() { + TextField tf = new TextField("foo"); + tf.setConverter(new StringToIntegerConverter()); + tf.setPropertyDataSource(new ObjectProperty<Integer>(12)); + tf.setConverter((Converter) null); + try { + Object v = tf.getConvertedValue(); + System.out.println(v); + Assert.fail( + "Trying to convert String -> Integer should fail when there is no converter"); + } catch (ConversionException e) { + // ok, should happen when there is no converter but conversion is + // needed + } + } + +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/AbstractFieldDeclarativeTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/AbstractFieldDeclarativeTest.java new file mode 100644 index 0000000000..ea420100c2 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/AbstractFieldDeclarativeTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * 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.vaadin.v7.tests.server.component.abstractfield; + +import org.junit.Test; + +import com.vaadin.tests.design.DeclarativeTestBase; +import com.vaadin.ui.AbstractField; +import com.vaadin.ui.TextField; + +/** + * Tests declarative support for implementations of {@link AbstractField}. + * + * @since 7.4 + * @author Vaadin Ltd + */ +public class AbstractFieldDeclarativeTest + extends DeclarativeTestBase<AbstractField<?>> { + + @Test + public void testPlainText() { + // FIXME + // String design = "<vaadin-text-field readonly tabindex=3" + // + "required" + // + "/>"; + // AbstractField<String> tf = new TextField(); + // tf.setRequired(true); + // tf.setTabIndex(3); + // tf.setReadOnly(true); + // testRead(design, tf); + // testWrite(design, tf); + // + // // Test with readonly=false + // design = design.replace("readonly", ""); + // tf.setReadOnly(false); + // testRead(design, tf); + // testWrite(design, tf); + } + + @Test + public void testModelReadOnly() { + // Test that read only value coming from property data source is not + // written to design. + String design = "<vaadin-text-field readonly value=test></vaadin-text-field>"; + AbstractField<String> component = new TextField(); + component.setReadOnly(true); + component.setValue("test"); + // FIXME (?) current implementation only + // disables client-side modification + testWrite(design, component); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/AbstractFieldReadOnlyTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/AbstractFieldReadOnlyTest.java new file mode 100644 index 0000000000..9f0871106d --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/AbstractFieldReadOnlyTest.java @@ -0,0 +1,51 @@ +package com.vaadin.v7.tests.server.component.abstractfield; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.vaadin.tests.data.bean.Address; +import com.vaadin.tests.data.bean.Country; +import com.vaadin.tests.data.bean.Person; +import com.vaadin.tests.data.bean.Sex; +import com.vaadin.ui.Label; +import com.vaadin.v7.data.Property.ReadOnlyStatusChangeEvent; +import com.vaadin.v7.data.Property.ReadOnlyStatusChangeListener; +import com.vaadin.v7.data.util.MethodProperty; +import com.vaadin.v7.ui.TextField; + +public class AbstractFieldReadOnlyTest { + + Person paulaBean = new Person("Paula", "Brilliant", "paula@brilliant.com", + 34, Sex.FEMALE, + new Address("Paula street 1", 12345, "P-town", Country.FINLAND)); + + @Test + public void testReadOnlyProperty() { + TextField tf = new TextField(); + tf.setPropertyDataSource( + new MethodProperty<String>(paulaBean, "firstName")); + assertFalse(tf.isReadOnly()); + tf.getPropertyDataSource().setReadOnly(true); + assertTrue(tf.isReadOnly()); + } + + @Test + public void testReadOnlyEventFromProperty() { + final Label valueStore = new Label(""); + TextField tf = new TextField(); + tf.addReadOnlyStatusChangeListener(new ReadOnlyStatusChangeListener() { + @Override + public void readOnlyStatusChange(ReadOnlyStatusChangeEvent event) { + valueStore.setValue("event received!"); + } + }); + tf.setPropertyDataSource( + new MethodProperty<String>(paulaBean, "firstName")); + assertTrue(valueStore.getValue().isEmpty()); + tf.getPropertyDataSource().setReadOnly(true); + assertFalse(valueStore.getValue().isEmpty()); + } + +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/DefaultConverterFactoryTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/DefaultConverterFactoryTest.java new file mode 100644 index 0000000000..03b92aaa6e --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/DefaultConverterFactoryTest.java @@ -0,0 +1,138 @@ +package com.vaadin.v7.tests.server.component.abstractfield; + +import static org.junit.Assert.assertEquals; + +import java.math.BigDecimal; +import java.util.Locale; + +import org.junit.Test; + +import com.vaadin.server.VaadinSession; +import com.vaadin.tests.data.bean.Address; +import com.vaadin.tests.data.bean.Country; +import com.vaadin.tests.data.bean.Person; +import com.vaadin.tests.data.bean.Sex; +import com.vaadin.tests.util.AlwaysLockedVaadinSession; +import com.vaadin.v7.data.util.MethodProperty; +import com.vaadin.v7.ui.TextField; + +public class DefaultConverterFactoryTest { + + public static class FloatBean { + float f1; + Float f2; + + public FloatBean(float f1, Float f2) { + this.f1 = f1; + this.f2 = f2; + } + + public float getF1() { + return f1; + } + + public void setF1(float f1) { + this.f1 = f1; + } + + public Float getF2() { + return f2; + } + + public void setF2(Float f2) { + this.f2 = f2; + } + + } + + public static class LongBean { + long l1; + Long l2; + + public LongBean(long l1, Long l2) { + this.l1 = l1; + this.l2 = l2; + } + + public long getL1() { + return l1; + } + + public void setL1(long l1) { + this.l1 = l1; + } + + public Long getL2() { + return l2; + } + + public void setL2(Long l2) { + this.l2 = l2; + } + + } + + Person paulaBean = new Person("Paula", "Brilliant", "paula@brilliant.com", + 34, Sex.FEMALE, + new Address("Paula street 1", 12345, "P-town", Country.FINLAND)); + { + paulaBean.setSalary(49000); + BigDecimal rent = new BigDecimal(57223); + rent = rent.scaleByPowerOfTen(-2); + paulaBean.setRent(rent); + } + + @Test + public void testFloatConversion() { + VaadinSession sess = new AlwaysLockedVaadinSession(null); + VaadinSession.setCurrent(sess); + + TextField tf = new TextField(); + tf.setLocale(new Locale("en", "US")); + tf.setPropertyDataSource( + new MethodProperty<Integer>(new FloatBean(12f, 23f), "f2")); + assertEquals("23", tf.getValue()); + tf.setValue("24"); + assertEquals("24", tf.getValue()); + assertEquals(24f, tf.getConvertedValue()); + assertEquals(24f, tf.getPropertyDataSource().getValue()); + } + + @Test + public void testLongConversion() { + VaadinSession sess = new AlwaysLockedVaadinSession(null); + VaadinSession.setCurrent(sess); + + TextField tf = new TextField(); + tf.setLocale(new Locale("en", "US")); + tf.setPropertyDataSource(new MethodProperty<Integer>( + new LongBean(12, 1982739187238L), "l2")); + assertEquals("1,982,739,187,238", tf.getValue()); + tf.setValue("1982739187239"); + assertEquals("1,982,739,187,239", tf.getValue()); + assertEquals(1982739187239L, tf.getConvertedValue()); + assertEquals(1982739187239L, tf.getPropertyDataSource().getValue()); + } + + @Test + public void testDefaultNumberConversion() { + VaadinSession app = new AlwaysLockedVaadinSession(null); + VaadinSession.setCurrent(app); + TextField tf = new TextField(); + tf.setLocale(new Locale("en", "US")); + tf.setPropertyDataSource( + new MethodProperty<Integer>(paulaBean, "salary")); + assertEquals("49,000", tf.getValue()); + + tf.setLocale(new Locale("fi", "FI")); + // FIXME: The following line should not be necessary and should be + // removed + tf.setPropertyDataSource( + new MethodProperty<Integer>(paulaBean, "salary")); + String value = tf.getValue(); + // Java uses a non-breaking space (ascii 160) instead of space when + // formatting + String expected = "49" + (char) 160 + "000"; + assertEquals(expected, value); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/RemoveListenersOnDetachTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/RemoveListenersOnDetachTest.java new file mode 100644 index 0000000000..82cb2751ff --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstractfield/RemoveListenersOnDetachTest.java @@ -0,0 +1,106 @@ +package com.vaadin.v7.tests.server.component.abstractfield; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.server.VaadinSession; +import com.vaadin.tests.util.AlwaysLockedVaadinSession; +import com.vaadin.ui.UI; +import com.vaadin.v7.data.Property; +import com.vaadin.v7.data.util.AbstractProperty; +import com.vaadin.v7.data.util.converter.Converter.ConversionException; +import com.vaadin.v7.ui.AbstractField; + +public class RemoveListenersOnDetachTest { + + int numValueChanges = 0; + int numReadOnlyChanges = 0; + + AbstractField field = new AbstractField() { + final private VaadinSession application = new AlwaysLockedVaadinSession( + null); + private UI uI = new UI() { + + @Override + protected void init(VaadinRequest request) { + + } + + @Override + public VaadinSession getSession() { + return application; + } + + }; + + @Override + public Class<?> getType() { + return String.class; + } + + @Override + public void valueChange(Property.ValueChangeEvent event) { + super.valueChange(event); + numValueChanges++; + } + + @Override + public void readOnlyStatusChange( + Property.ReadOnlyStatusChangeEvent event) { + super.readOnlyStatusChange(event); + numReadOnlyChanges++; + } + + @Override + public com.vaadin.ui.UI getUI() { + return uI; + } + + @Override + public VaadinSession getSession() { + return application; + } + }; + + Property<String> property = new AbstractProperty<String>() { + @Override + public String getValue() { + return null; + } + + @Override + public void setValue(String newValue) + throws ReadOnlyException, ConversionException { + fireValueChange(); + } + + @Override + public Class<String> getType() { + return String.class; + } + }; + + @Test + public void testAttachDetach() { + field.setPropertyDataSource(property); + + property.setValue(null); + property.setReadOnly(true); + assertEquals(1, numValueChanges); + assertEquals(1, numReadOnlyChanges); + + field.attach(); + property.setValue(null); + property.setReadOnly(false); + assertEquals(2, numValueChanges); + assertEquals(2, numReadOnlyChanges); + + field.detach(); + property.setValue(null); + property.setReadOnly(true); + assertEquals(2, numValueChanges); + assertEquals(2, numReadOnlyChanges); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstracttextfield/AbstractTextFieldListenersTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstracttextfield/AbstractTextFieldListenersTest.java new file mode 100644 index 0000000000..022bdd075b --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/abstracttextfield/AbstractTextFieldListenersTest.java @@ -0,0 +1,34 @@ +package com.vaadin.v7.tests.server.component.abstracttextfield; + +import org.junit.Test; + +import com.vaadin.event.FieldEvents.BlurEvent; +import com.vaadin.event.FieldEvents.BlurListener; +import com.vaadin.event.FieldEvents.FocusEvent; +import com.vaadin.event.FieldEvents.FocusListener; +import com.vaadin.tests.server.component.AbstractListenerMethodsTestBase; +import com.vaadin.v7.event.FieldEvents.TextChangeEvent; +import com.vaadin.v7.event.FieldEvents.TextChangeListener; +import com.vaadin.v7.ui.TextField; + +public class AbstractTextFieldListenersTest + extends AbstractListenerMethodsTestBase { + + @Test + public void testTextChangeListenerAddGetRemove() throws Exception { + testListenerAddGetRemove(TextField.class, TextChangeEvent.class, + TextChangeListener.class); + } + + @Test + public void testFocusListenerAddGetRemove() throws Exception { + testListenerAddGetRemove(TextField.class, FocusEvent.class, + FocusListener.class); + } + + @Test + public void testBlurListenerAddGetRemove() throws Exception { + testListenerAddGetRemove(TextField.class, BlurEvent.class, + BlurListener.class); + } +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/textfield/TextFieldTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/textfield/TextFieldTest.java new file mode 100644 index 0000000000..79f1640257 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/textfield/TextFieldTest.java @@ -0,0 +1,50 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * 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.vaadin.v7.tests.server.component.textfield; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.v7.data.util.ObjectProperty; +import com.vaadin.v7.ui.TextField; + +public class TextFieldTest { + + @Test + public void initiallyEmpty() { + TextField tf = new TextField(); + Assert.assertTrue(tf.isEmpty()); + } + + @Test + public void emptyAfterClearUsingPDS() { + TextField tf = new TextField( + new ObjectProperty<String>("foo")); + Assert.assertFalse(tf.isEmpty()); + tf.clear(); + Assert.assertTrue(tf.isEmpty()); + } + + @Test + public void emptyAfterClear() { + TextField tf = new TextField(); + tf.setValue("foobar"); + Assert.assertFalse(tf.isEmpty()); + tf.clear(); + Assert.assertTrue(tf.isEmpty()); + } + +} diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/textfield/TextFieldValueChangeTest.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/textfield/TextFieldValueChangeTest.java new file mode 100644 index 0000000000..bb286296b4 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/textfield/TextFieldValueChangeTest.java @@ -0,0 +1,131 @@ +package com.vaadin.v7.tests.server.component.textfield; + +import java.util.HashMap; +import java.util.Map; + +import org.easymock.EasyMock; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.tests.server.components.AbstractFieldValueChangeTestBase; +import com.vaadin.v7.data.Property.ValueChangeEvent; +import com.vaadin.v7.data.util.ObjectProperty; +import com.vaadin.v7.ui.AbstractField; +import com.vaadin.v7.ui.TextField; + +/** + * Check that the value change listener for a text field is triggered exactly + * once when setting the value, at the correct time. + * + * See <a href="http://dev.vaadin.com/ticket/4394">Ticket 4394</a>. + */ +public class TextFieldValueChangeTest + extends AbstractFieldValueChangeTestBase<String> { + + @Before + public void setUp() { + super.setUp(new TextField()); + } + + /** + * Case where the text field only uses its internal buffer, no external + * property data source. + */ + @Test + public void testNoDataSource() { + getField().setPropertyDataSource(null); + + expectValueChangeFromSetValueNotCommit(); + } + + @Override + protected void setValue(AbstractField<String> field) { + Map<String, Object> variables = new HashMap<String, Object>(); + variables.put("text", "newValue"); + ((TextField) field).changeVariables(field, variables); + } + + /** + * Test that field propagates value change events originating from property, + * but don't fire value change events twice if value has only changed once. + * + * + * TODO make test field type agnostic (eg. combobox) + */ + @Test + public void testValueChangeEventPropagationWithReadThrough() { + ObjectProperty<String> property = new ObjectProperty<String>(""); + getField().setPropertyDataSource(property); + + // defaults, buffering off + getField().setBuffered(false); + + // Expectations and start test + getListener().valueChange(EasyMock.isA(ValueChangeEvent.class)); + EasyMock.replay(getListener()); + + // Add listener and set the value -> should end up in listener once + getField().addListener(getListener()); + + property.setValue("Foo"); + + // Ensure listener was called once + EasyMock.verify(getListener()); + + // get value should not fire value change again + Object value = getField().getValue(); + Assert.assertEquals("Foo", value); + + // Ensure listener still has been called only once + EasyMock.verify(getListener()); + } + + /** + * Value change events from property should not propagate if read through is + * false. Execpt when the property is being set. + * + * TODO make test field type agnostic (eg. combobox) + */ + @Test + public void testValueChangePropagationWithReadThroughOff() { + final String initialValue = "initial"; + ObjectProperty<String> property = new ObjectProperty<String>( + initialValue); + + // set buffering + getField().setBuffered(true); + + // Value change should only happen once, when setting the property, + // further changes via property should not cause value change listener + // in field to be notified + getListener().valueChange(EasyMock.isA(ValueChangeEvent.class)); + EasyMock.replay(getListener()); + + getField().addListener(getListener()); + getField().setPropertyDataSource(property); + + // Ensure listener was called once + EasyMock.verify(getListener()); + + // modify property value, should not fire value change in field as the + // read buffering is on (read through == false) + property.setValue("Foo"); + + // Ensure listener still has been called only once + EasyMock.verify(getListener()); + + // get value should not fire value change again + Object value = getField().getValue(); + + // field value should be different from the original value and current + // proeprty value + boolean isValueEqualToInitial = value.equals(initialValue); + Assert.assertTrue(isValueEqualToInitial); + + // Ensure listener still has been called only once + EasyMock.verify(getListener()); + + } + +} |