From 3cfd5ca0c8885a85fdedee1af0a99ad2c152f302 Mon Sep 17 00:00:00 2001
From: Caroline Chao <caroline.chao@digia.com>
Date: Thu, 14 Feb 2013 10:00:26 +0100
Subject: [PATCH] TextField: Refactoring API

Clean the TextField API.

Add missing documentation + autotests.

Change-Id: Iafa1763d44e7b45511433f389332485e3feaec9c
Reviewed-by: Jens Bache-Wiig <jens.bache-wiig@digia.com>
---
 src/qtdesktop/TextField.qml                 | 336 ++++----------------
 src/styles/Desktop/TextFieldStyle.qml       |   2 +-
 tests/auto/qtdesktop/data/tst_textfield.qml | 246 ++++++++++++++
 tests/auto/qtdesktop/qtdesktop.pro          |   3 +-
 4 files changed, 315 insertions(+), 272 deletions(-)
 create mode 100644 tests/auto/qtdesktop/data/tst_textfield.qml

diff --git a/src/qtdesktop/TextField.qml b/src/qtdesktop/TextField.qml
index 81c80c2a6..4332f51c0 100644
--- a/src/qtdesktop/TextField.qml
+++ b/src/qtdesktop/TextField.qml
@@ -67,32 +67,27 @@ FocusScope {
         If a validator or input mask has been set, this property will only be true
         if the current text is acceptable to the validator or input mask as a final
         string (not as an intermediate string).
+
+        \sa validator, inputMask
+
     */
-    property alias acceptableInput: textInput.acceptableInput // read only
+    readonly property alias acceptableInput: textInput.acceptableInput // read only
 
     /*!
         \qmlproperty bool TextField::activeFocusOnPress
 
         Whether the TextField should gain active focus on a mouse press. By default this is
-        set to true.
+        set to \c true.
     */
     property alias activeFocusOnPress: textInput.activeFocusOnPress
 
-    /*!
-        \qmlproperty bool TextField::autoScroll
-
-        Whether the TextField should scroll when the text is longer than the width. By default this is
-        set to true.
-    */
-    property alias autoScroll: textInput.autoScroll
-
     /*!
         \qmlproperty bool TextField::canPaste
 
         Returns true if the TextField is writable and the content of the clipboard is
         suitable for pasting into the TextField.
     */
-    property alias canPaste: textInput.canPaste
+    readonly property alias canPaste: textInput.canPaste
 
     /*!
         \qmlproperty bool TextField::canRedo
@@ -100,7 +95,7 @@ FocusScope {
         Returns true if the TextField is writable and there are \l {undo}{undone}
         operations that can be redone.
     */
-    property alias canRedo: textInput.canRedo
+    readonly property alias canRedo: textInput.canRedo
 
     /*!
         \qmlproperty bool TextField::canUndo
@@ -108,51 +103,14 @@ FocusScope {
         Returns true if the TextField is writable and there are previous operations
         that can be undone.
     */
-    property alias canUndo: textInput.canUndo
+    readonly property alias canUndo: textInput.canUndo
 
     /*!
-        \qmlproperty color TextField::color
+        \qmlproperty color TextField::textColor
 
         The text color.
     */
-    property alias color: textInput.color
-
-    /*!
-        \qmlproperty bool TextField::containsMouse
-        This property holds whether the mouse is currently inside the TextField.
-    */
-    property alias containsMouse: mouseArea.containsMouse
-
-    /*!
-        \qmlproperty real TextField::contentHeight
-
-        Returns the height of the text, including the height past the height
-        that is covered if the text does not fit within the set height.
-    */
-    property alias contentHeight: textInput.contentHeight
-
-    /*!
-        \qmlproperty real TextField::contentWidth
-
-        Returns the width of the text, including the width past the width
-        which is covered due to insufficient wrapping if \l wrapMode is set.
-    */
-    property alias contentWidth: textInput.contentWidth
-
-    /*!
-        \qmlproperty Component TextField::cursorDelegate
-        The delegate for the cursor in the TextField.
-
-        If you set a cursorDelegate for a TextField, this delegate will be used for
-        drawing the cursor instead of the standard cursor. An instance of the
-        delegate will be created and managed by the TextField when a cursor is
-        needed, and the x property of delegate instance will be set so as
-        to be one pixel before the top left of the current character.
-
-        Note that the root item of the delegate component must be a QQuickItem or
-        QQuickItem derived item.
-    */
-    property alias cursorDelegate: textInput.cursorDelegate
+    property alias textColor: textInput.color
 
     /*!
         \qmlproperty int TextField::cursorPosition
@@ -160,45 +118,6 @@ FocusScope {
     */
     property alias cursorPosition: textInput.cursorPosition
 
-    /*!
-        \qmlproperty rectangle TextField::cursorRectangle
-
-        The rectangle where the standard text cursor is rendered within the text input.  Read only.
-
-        The position and height of a custom cursorDelegate are updated to follow the cursorRectangle
-        automatically when it changes.  The width of the delegate is unaffected by changes in the
-        cursor rectangle.
-    */
-    property alias cursorRectangle: textInput.cursorRectangle
-
-    /*!
-        \qmlproperty bool TextField::cursorVisible
-        Set to true when the TextField shows a cursor.
-
-        This property is set and unset when the TextField gets active focus, so that other
-        properties can be bound to whether the cursor is currently showing. As it
-        gets set and unset automatically, when you set the value yourself you must
-        keep in mind that your value may be overwritten.
-
-        It can be set directly in script, for example if a KeyProxy might
-        forward keys to it and you desire it to look active when this happens
-        (but without actually giving it active focus).
-
-        It should not be set directly on the item, like in the below QML,
-        as the specified value will be overridden an lost on focus changes.
-
-        \code
-        TextField {
-            text: "Text"
-            cursorVisible: false
-        }
-        \endcode
-
-        In the above snippet the cursor will still become visible when the
-        TextField gains active focus.
-    */
-    property alias cursorVisible: textInput.cursorVisible
-
     /*!
        \qmlproperty string TextField::displayText
 
@@ -209,7 +128,7 @@ FocusScope {
        this property holds the text visible to the user, while
        the \l text property holds the actual entered text.
     */
-    property alias displayText: textInput.displayText
+    readonly property alias displayText: textInput.displayText
 
     /*!
         \qmlproperty enumeration TextField::echoMode
@@ -234,26 +153,40 @@ FocusScope {
 
     /*!
         \qmlproperty enumeration TextField::horizontalAlignment
-        \qmlproperty enumeration TextField::effectiveHorizontalAlignment
-        \qmlproperty enumeration TextField::verticalAlignment
 
-        Sets the alignment of the text within the TextField item's width and height.
+        Sets the alignment of the text within the TextField item's width.
+
         By default, the horizontal text alignment follows the natural alignment of the text,
         for example text that is read from left to right will be aligned to the left.
 
         The valid values for \c horizontalAlignment are \c TextInput.AlignLeft, \c TextInput.AlignRight and
         \c TextInput.AlignHCenter.
 
-        Valid values for \c verticalAlignment are \c TextInput.AlignTop,
-        \c TextInput.AlignBottom \c TextInput.AlignVCenter (default).
-
         When using the attached property LayoutMirroring::enabled to mirror application
         layouts, the horizontal alignment of text will also be mirrored. However, the property
         \c horizontalAlignment will remain unchanged. To query the effective horizontal alignment
         of TextField, use the read-only property \c effectiveHorizontalAlignment.
     */
     property alias horizontalAlignment: textInput.horizontalAlignment
-    property alias effectiveHorizontalAlignment: textInput.effectiveHorizontalAlignment
+
+    /*!
+        \qmlproperty enumeration TextField::effectiveHorizontalAlignment
+
+        Gets the effective horizontal alignment of the text within the TextField item's width.
+
+        To set/get the default horizontal alignment of TextField, use the property \c horizontalAlignment.
+
+    */
+    readonly property alias effectiveHorizontalAlignment: textInput.effectiveHorizontalAlignment
+
+    /*!
+        \qmlproperty enumeration TextField::verticalAlignment
+
+        Sets the alignment of the text within the TextField item's height.
+
+        The valid valid values for \c verticalAlignment are \c TextInput.AlignTop,
+        \c TextInput.AlignBottom \c TextInput.AlignVCenter (default).
+    */
     property alias verticalAlignment: textInput.verticalAlignment
 
     /*!
@@ -267,19 +200,6 @@ FocusScope {
     */
     property alias inputMask: textInput.inputMask
 
-    /*!
-        \qmlproperty bool TextField::inputMethodComposing
-
-        This property holds whether the TextField has partial text input from an
-        input method.
-
-        While it is composing an input method may rely on mouse or key events from
-        the TextField to edit or commit the partial text. This property can be
-        used to determine when to disable event handlers that may interfere with
-        the correct operation of an input method.
-    */
-    property alias inputMethodComposing: textInput.inputMethodComposing
-
     /*!
         \qmlproperty enumeration TextField::inputMethodHints
 
@@ -288,6 +208,8 @@ FocusScope {
 
         The value is a bit-wise combination of flags, or Qt.ImhNone if no hints are set.
 
+        The default value is Qt.ImhNone.
+
         Flags that alter behavior are:
 
         \list
@@ -337,52 +259,16 @@ FocusScope {
         This property can be faster than querying the length the \l text property as it doesn't
         require any copying or conversion of the TextField's internal string data.
     */
-    property alias length: textInput.length
+    readonly property alias length: textInput.length
 
     /*!
         \qmlproperty int TextField::maximumLength
         The maximum permitted length of the text in the TextField.
 
         If the text is too long, it is truncated at the limit.
-
-        By default, this property contains a value of 32767.
     */
     property alias maximumLength: textInput.maximumLength
 
-    /*!
-        \qmlproperty enumeration TextField::mouseSelectionMode
-
-        Specifies how text should be selected using a mouse.
-
-        \list
-        \li TextInput.SelectCharacters - The selection is updated with individual characters. (Default)
-        \li TextInput.SelectWords - The selection is updated with whole words.
-        \endlist
-
-        This property only applies when \l selectByMouse is true.
-    */
-    property alias mouseSelectionMode: textInput.mouseSelectionMode
-
-    /*!
-       \qmlproperty string TextField::passwordCharacter
-
-       This is the character displayed when echoMode is set to Password or
-       PasswordEchoOnEdit. By default it is an asterisk.
-
-       If this property is set to a string with more than one character,
-       the first character is used. If the string is empty, the value
-       is ignored and the property is not set.
-    */
-    property alias passwordCharacter: textInput.passwordCharacter
-
-    /*!
-        \qmlproperty bool TextField::persistentSelection
-
-        Whether the TextField should keep its selection when it loses active focus to another
-        item in the scene. By default this is set to false;
-    */
-    property alias persistentSelection: textInput.persistentSelection
-
     /*!
         \qmlproperty string TextField::placeholderText
 
@@ -395,6 +281,8 @@ FocusScope {
         \qmlproperty bool TextField::readOnly
 
         Sets whether user input can modify the contents of the TextField.
+        The difference from a disabled text field is that it will appear
+        to be active and text can be selected and copied.
 
         If readOnly is set to true, then user input will not affect the text
         property. Any bindings or attempts to set the text property will still
@@ -402,36 +290,6 @@ FocusScope {
     */
     property alias readOnly: textInput.readOnly
 
-    /*!
-        \qmlproperty enumeration TextField::renderType
-
-        Override the default rendering type for this component.
-
-        Supported render types are:
-        \list
-        \li Text.QtRendering - the default
-        \li Text.NativeRendering
-        \endlist
-
-        Select Text.NativeRendering if you prefer text to look native on the target platform and do
-        not require advanced features such as transformation of the text. Using such features in
-        combination with the NativeRendering render type will lend poor and sometimes pixelated
-        results.
-    */
-    property alias renderType: textInput.renderType
-
-    /*!
-        \qmlproperty bool TextField::selectByMouse
-
-        Defaults to true.
-
-        If true, the user can use the mouse to select text in some
-        platform-specific way. Note that for some platforms this may
-        not be an appropriate interaction (eg. may conflict with how
-        the text needs to behave inside a Flickable.
-    */
-    property alias selectByMouse: textInput.selectByMouse
-
     /*!
         \qmlproperty string TextField::selectedText
 
@@ -445,21 +303,7 @@ FocusScope {
         myTextField.text.toString().substring(myTextField.selectionStart, myTextField.selectionEnd);
         \endjs
     */
-    property alias selectedText: textInput.selectedText
-
-    /*!
-        \qmlproperty color TextField::selectedTextColor
-
-        The highlighted text color, used in selections.
-    */
-    property alias selectedTextColor: textInput.selectedTextColor
-
-    /*!
-        \qmlproperty color TextField::selectionColor
-
-        The text highlight color, used behind selections.
-    */
-    property alias selectionColor: textInput.selectionColor
+    readonly property alias selectedText: textInput.selectedText
 
     /*!
         \qmlproperty int TextField::selectionEnd
@@ -471,7 +315,7 @@ FocusScope {
 
         \sa selectionStart, cursorPosition, selectedText
     */
-    property alias selectionEnd: textInput.selectionEnd
+    readonly property alias selectionEnd: textInput.selectionEnd
 
     /*!
         \qmlproperty int TextField::selectionStart
@@ -483,7 +327,7 @@ FocusScope {
 
         \sa selectionEnd, cursorPosition, selectedText
     */
-    property alias selectionStart: textInput.selectionStart
+    readonly property alias selectionStart: textInput.selectionStart
 
     /*!
         \qmlproperty string TextField::text
@@ -497,7 +341,7 @@ FocusScope {
 
         Allows you to set a validator on the TextField. When a validator is set
         the TextField will only accept input which leaves the text property in
-        an acceptable or intermediate state. The accepted signal will only be sent
+        an or intermediate state. The accepted signal will only be sent
         if the text is in an acceptable state when enter is pressed.
 
         Currently supported validators are IntValidator, DoubleValidator and
@@ -518,29 +362,6 @@ FocusScope {
     */
     property alias validator: textInput.validator
 
-    /*!
-        \qmlproperty enumeration TextField::wrapMode
-
-        Set this property to wrap the text to the TextField item's width.
-        The text will only wrap if an explicit width has been set.
-
-        \list
-        \li TextInput.NoWrap - no wrapping will be performed. If the text contains insufficient newlines, then implicitWidth will exceed a set width.
-        \li TextInput.WordWrap - wrapping is done on word boundaries only. If a word is too long, implicitWidth will exceed a set width.
-        \li TextInput.WrapAnywhere - wrapping is done at any point on a line, even if it occurs in the middle of a word.
-        \li TextInput.Wrap - if possible, wrapping occurs at a word boundary; otherwise it will occur at the appropriate point on the line, even in the middle of a word.
-        \endlist
-
-        The default is TextInput.NoWrap. If you set a width, consider using TextInput.Wrap.
-    */
-    property alias wrapMode: textInput.wrapMode
-
-    /*! \internal */
-    property Component style: Qt.createComponent(Settings.THEME_PATH + "/TextFieldStyle.qml", textInput)
-
-    /*! \internal */
-    property var styleHints:[]
-
     /*!
         \qmlsignal TextField::accepted()
 
@@ -615,46 +436,6 @@ FocusScope {
         textInput.paste()
     }
 
-    /*!
-        \qmlmethod int TextField::positionAt(real x, real y, CursorPosition position = CursorBetweenCharacters)
-
-        This function returns the character position at
-        x and y pixels from the top left of the TextField. Position 0 is before the
-        first character, position 1 is after the first character but before the second,
-        and so on until position text.length, which is after all characters.
-
-        This means that for all x values before the first character this function returns 0,
-        and for all x values after the last character this function returns text.length.  If
-        the y value is above the text the position will be that of the nearest character on
-        the first line line and if it is below the text the position of the nearest character
-        on the last line will be returned.
-
-        The cursor position type specifies how the cursor position should be resolved.
-
-        \list
-        \li TextInput.CursorBetweenCharacters - Returns the position between characters that is nearest x.
-        \li TextInput.CursorOnCharacter - Returns the position before the character that is nearest x.
-        \endlist
-    */
-    function positionAt(x, y, cursor) {
-        var p = mapToItem(textInput, x, y);
-        return textInput.positionAt(p.x, p.y, cursor);
-    }
-
-    /*!
-        \qmlmethod rect TextField::positionToRectangle(int pos)
-
-        This function takes a character position and returns the rectangle that the
-        cursor would occupy, if it was placed at that character position.
-
-        This is similar to setting the cursorPosition, and then querying the cursor
-        rectangle, but the cursorPosition is not changed.
-    */
-    function positionToRectangle(pos) {
-        var p = mapToItem(textInput, pos.x, pos.y);
-        return textInput.positionToRectangle(p);
-    }
-
     /*!
         \qmlmethod TextField::redo()
 
@@ -710,6 +491,27 @@ FocusScope {
         textInput.undo();
     }
 
+    /*! \internal */
+    property alias __containsMouse: mouseArea.containsMouse
+
+    /*! \internal */
+    property alias __contentHeight: textInput.contentHeight
+
+    /*! \internal */
+    property alias __contentWidth: textInput.contentWidth
+
+    /*! \internal */
+    property Component style: Qt.createComponent(Settings.THEME_PATH + "/TextFieldStyle.qml", textInput)
+
+    /*! \internal */
+    property var styleHints:[]
+
+    /*! \internal */
+    onFocusChanged: {
+        if (textfield.activeFocus)
+            textInput.forceActiveFocus();
+    }
+
     // Implementation
     implicitWidth: loader.implicitWidth
     implicitHeight: loader.implicitHeight
@@ -732,17 +534,11 @@ FocusScope {
         onClicked: textfield.forceActiveFocus()
     }
 
-    /*! \internal */
-    onFocusChanged: {
-        if (textfield.activeFocus)
-            textInput.forceActiveFocus();
-    }
-
-    TextInput { // see QTBUG-14936
+    TextInput {
         id: textInput
         selectByMouse: true
-        selectionColor: loader.item ? loader.item.selectionColor : "black"
-        selectedTextColor: loader.item ? loader.item.selectedTextColor : "black"
+        selectionColor: loader.item ? loader.item.selectionColor : "darkred"
+        selectedTextColor: loader.item ? loader.item.selectedTextColor : "white"
 
         property Item styleItem: loader.item
         font: styleItem ? styleItem.font : font
@@ -771,7 +567,7 @@ FocusScope {
         color: loader.item ? loader.item.placeholderTextColor : "darkgray"
         clip: true
         elide: Text.ElideRight
-//        renderType: Text.NativeRendering
+        renderType: Text.NativeRendering
         Behavior on opacity { NumberAnimation { duration: 90 } }
     }
     MouseArea {
diff --git a/src/styles/Desktop/TextFieldStyle.qml b/src/styles/Desktop/TextFieldStyle.qml
index 467176318..31fc79ea2 100644
--- a/src/styles/Desktop/TextFieldStyle.qml
+++ b/src/styles/Desktop/TextFieldStyle.qml
@@ -47,7 +47,7 @@ StyleItem {
     elementType: "edit"
     sunken: true
     hasFocus: textfield.activeFocus
-    hover: containsMouse
+    hover: __containsMouse
 
     SystemPalette {
         id: syspal
diff --git a/tests/auto/qtdesktop/data/tst_textfield.qml b/tests/auto/qtdesktop/data/tst_textfield.qml
new file mode 100644
index 000000000..69cd503c5
--- /dev/null
+++ b/tests/auto/qtdesktop/data/tst_textfield.qml
@@ -0,0 +1,246 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Components project.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+**     of its contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtTest 1.0
+
+TestCase {
+    id: testCase
+    name: "Tests_TextField"
+    when: windowShown
+    width: 400
+    height: 400
+
+    function test_text() {
+        var textfield = Qt.createQmlObject('import QtDesktop 1.0; TextField {}', testCase, '')
+
+        compare(textfield.text, "")
+        textfield.text = "hello world"
+        compare(textfield.text, "hello world")
+    }
+
+    function test_maximumLength() {
+        var textfield = Qt.createQmlObject('import QtDesktop 1.0; TextField {}', testCase, '')
+
+        textfield.text = "hello world"
+        textfield.maximumLength = 5
+        compare(textfield.text, "hello")
+    }
+
+    function test_length() {
+        var textfield = Qt.createQmlObject('import QtDesktop 1.0; TextField {}', testCase, '')
+
+        textfield.text = "hello world"
+        compare(textfield.length, 11)
+    }
+
+
+    function test_readonly() {
+        var textfield = Qt.createQmlObject('import QtDesktop 1.0; TextField {}', testCase, '')
+        textfield.forceActiveFocus()
+
+        compare(textfield.readOnly, false)
+        textfield.text = "hello"
+        textfield.readOnly = true
+        keyPress(Qt.Key_9)
+        compare(textfield.text,"hello")
+    }
+
+    function test_inputMask() {
+        var textfield = Qt.createQmlObject('import QtDesktop 1.0; TextField {}', testCase, '')
+        textfield.forceActiveFocus()
+
+        // +/- not required, 1 digit required, 1 aphabetic character required and 2 digits not required
+        textfield.inputMask = "#9A00"
+
+        keyPress(Qt.Key_Minus)
+        compare(textfield.text,"-")
+        compare(textfield.acceptableInput, false)
+
+        keyPress(Qt.Key_9)
+        compare(textfield.text,"-9")
+        compare(textfield.acceptableInput, false)
+
+        keyPress(Qt.Key_B)
+        compare(textfield.text,"-9b")
+        compare(textfield.acceptableInput, true)
+
+        keyPress(Qt.Key_1)
+        compare(textfield.text,"-9b1")
+        compare(textfield.acceptableInput, true)
+
+        keyPress(Qt.Key_1)
+        compare(textfield.text,"-9b11")
+        compare(textfield.acceptableInput, true)
+
+        keyPress(Qt.Key_Backspace)
+        keyPress(Qt.Key_Backspace)
+        keyPress(Qt.Key_Backspace)
+        compare(textfield.text,"-9")
+        compare(textfield.acceptableInput, false)
+
+        keyPress(Qt.Key_3)
+        compare(textfield.acceptableInput, false)
+        compare(textfield.text,"-93")
+    }
+
+    function test_validator() {
+        var textfield = Qt.createQmlObject('import QtQuick 2.0; import QtDesktop 1.0; TextField {validator: RegExpValidator { regExp: /(red|blue|green)?/; }}', testCase, '')
+
+        textfield.text = "blu"
+        compare(textfield.acceptableInput, false)
+
+        textfield.text = "blue"
+        compare(textfield.acceptableInput, true)
+
+        textfield.text = "bluee"
+        compare(textfield.acceptableInput, false)
+    }
+
+    function test_selectAll() {
+        var textfield = Qt.createQmlObject('import QtDesktop 1.0; TextField {}', testCase, '')
+        textfield.forceActiveFocus()
+
+        textfield.text = "this is my text"
+        textfield.selectAll();
+
+        keyPress(Qt.Key_Delete)
+        compare(textfield.text, "")
+    }
+
+    function test_select() {
+        var textfield = Qt.createQmlObject('import QtDesktop 1.0; TextField {}', testCase, '')
+        textfield.forceActiveFocus()
+
+        textfield.text = "this is my text"
+        textfield.select(5, 8);
+
+        compare(textfield.selectionEnd, 8)
+        compare(textfield.selectionStart, 5)
+        compare(textfield.selectedText, "is ")
+        keyPress(Qt.Key_Delete)
+        compare(textfield.text, "this my text")
+    }
+
+    function test_cursorPosition() {
+        var textfield = Qt.createQmlObject('import QtDesktop 1.0; TextField {}', testCase, '')
+        textfield.forceActiveFocus()
+
+        compare(textfield.cursorPosition, 0)
+        keyPress(Qt.Key_M)
+        compare(textfield.cursorPosition, 1)
+        keyPress(Qt.Key_Y)
+        compare(textfield.cursorPosition, 2)
+
+        textfield.cursorPosition = 1
+        keyPress(Qt.Key_A)
+        compare(textfield.text, "may")
+    }
+
+    function test_selectWord() {
+        var textfield = Qt.createQmlObject('import QtDesktop 1.0; TextField {}', testCase, '')
+        textfield.forceActiveFocus()
+
+        textfield.text = "this is my text"
+        textfield.selectWord();
+        compare(textfield.selectedText, "text")
+        textfield.cursorPosition = 2
+        textfield.selectWord();
+        compare(textfield.selectedText, "this")
+    }
+
+    function copy() {
+        var textfield = Qt.createQmlObject('import QtDesktop 1.0; TextField {}', testCase, '')
+        textfield.text = "this is my text"
+        textfield.select(0, 5)
+        textfield.copy()
+    }
+
+    function test_getText() {
+        var textfield = Qt.createQmlObject('import QtDesktop 1.0; TextField {}', testCase, '')
+        textfield.forceActiveFocus()
+
+        textfield.text = "this is my text"
+        var gettext = textfield.getText(0, 4)
+        compare(gettext, "this")
+    }
+
+    function test_insert() {
+        var textfield = Qt.createQmlObject('import QtDesktop 1.0; TextField {}', testCase, '')
+        textfield.forceActiveFocus()
+
+        textfield.text = "this is my text"
+        textfield.insert(8, "not ")
+        compare(textfield.text, "this is not my text")
+    }
+
+    function test_deselect() {
+        var textfield = Qt.createQmlObject('import QtDesktop 1.0; TextField {}', testCase, '')
+        textfield.forceActiveFocus()
+
+        textfield.text = "this is my text"
+        textfield.selectWord();
+        textfield.deselect()
+        compare(textfield.selectedText, "")
+    }
+
+    function test_undo() {
+        var textfield = Qt.createQmlObject('import QtDesktop 1.0; TextField {}', testCase, '')
+        textfield.forceActiveFocus()
+
+        textfield.text = "this is my text"
+        textfield.insert(8, "not ")
+        compare(textfield.canUndo, true)
+        textfield.undo()
+        compare(textfield.text, "this is my text")
+    }
+
+    function test_redo() {
+        var textfield = Qt.createQmlObject('import QtDesktop 1.0; TextField {}', testCase, '')
+        textfield.forceActiveFocus()
+
+        textfield.text = "this is my text"
+        textfield.insert(8, "not ")
+        textfield.undo()
+        compare(textfield.canRedo, true)
+        textfield.redo()
+        compare(textfield.text, "this is not my text")
+    }
+}
diff --git a/tests/auto/qtdesktop/qtdesktop.pro b/tests/auto/qtdesktop/qtdesktop.pro
index 5e07fdbff..054840fce 100644
--- a/tests/auto/qtdesktop/qtdesktop.pro
+++ b/tests/auto/qtdesktop/qtdesktop.pro
@@ -19,6 +19,7 @@ OTHER_FILES += \
     $$PWD/data/tst_tableview.qml \
     $$PWD/data/tst_rangemodel.qml \
     $$PWD/data/tst_scrollarea.qml \
-    $$PWD/data/tst_menu.qml
+    $$PWD/data/tst_menu.qml \
+    $$PWD/data/tst_textfield.qml
 
 DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
-- 
GitLab