test.py 11.2 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#############################################################################
##
## Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
## Contact: http://www.qt-project.org/legal
##
## This file is part of Qt Creator.
##
## Commercial License Usage
## Licensees holding valid commercial Qt licenses may use this file in
## accordance with the commercial license agreement provided with the
## Software or, alternatively, in accordance with the terms contained in
## a written agreement between you and Digia.  For licensing terms and
## conditions see http://qt.digia.com/licensing.  For further information
## use the contact form at http://qt.digia.com/contact-us.
##
## GNU Lesser General Public License Usage
## Alternatively, this file may be used under the terms of the GNU Lesser
## General Public License version 2.1 as published by the Free Software
## Foundation and appearing in the file LICENSE.LGPL included in the
## packaging of this file.  Please review the following information to
## ensure the GNU Lesser General Public License version 2.1 requirements
## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
##
## In addition, as a special exception, Digia gives you certain additional
## rights.  These rights are described in the Digia Qt LGPL Exception
## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
##
#############################################################################

30
31
32
source("../../shared/qtcreator.py")

templateDir = None
Christian Stenger's avatar
Christian Stenger committed
33
searchFinished = False
34
35

def main():
36
    global templateDir
37
    sourceExample = os.path.abspath(sdkPath + "/Examples/4.7/declarative/keyinteraction/focus")
38
39
    qmlFile = os.path.join("qml", "focus.qml")
    if not neededFilePresent(os.path.join(sourceExample, qmlFile)):
40
        return
41
    startApplication("qtcreator" + SettingsPath)
42
43
    if not startedWithoutPluginError():
        return
Christian Stenger's avatar
Christian Stenger committed
44
    # add docs to have the correct tool tips
Robert Loehning's avatar
Robert Loehning committed
45
    addHelpDocumentation([os.path.join(sdkPath, "Documentation", "qt.qch")])
46
    templateDir = prepareTemplate(sourceExample)
Christian Stenger's avatar
Christian Stenger committed
47
    installLazySignalHandler("{type='Core::FutureProgress' unnamed='1'}", "finished()", "__handleFutureProgress__")
48
49
    # using a temporary directory won't mess up a potentially existing
    createNewQtQuickApplication(tempDir(), "untitled", os.path.join(templateDir, qmlFile))
50
    testRenameId()
51
    testFindUsages()
Christian Stenger's avatar
Christian Stenger committed
52
    testHovering()
53
    test.log("Test finished")
54
55
56
    invokeMenuItem("File", "Exit")

def testRenameId():
Christian Stenger's avatar
Christian Stenger committed
57
    global searchFinished
58
59
    test.log("Testing rename of id")
    navTree = waitForObject("{type='Utils::NavigationTreeView' unnamed='1' visible='1' "
60
                            "window=':Qt Creator_Core::Internal::MainWindow'}")
61
    model = navTree.model()
62
63
    files = ["Core.ContextMenu\\.qml", "Core.GridMenu\\.qml", "Core.ListMenu\\.qml", "focus\\.qml"]
    originalTexts = {}
64
    editor = waitForObject(":Qt Creator_QmlJSEditor::QmlJSTextEditorWidget")
65
66
67
68
69
    # temporarily store editor content for synchronizing purpose
    # usage of formerTxt is done because I couldn't get waitForSignal() to work
    # it always stored a different object into the signalObjects map as it looked up afterwards
    # although used objectMap.realName() for both
    formerTxt = editor.plainText
70
71
    for file in files:
        doubleClickFile(navTree, file)
72
73
        # wait until editor content switched to the double-clicked file
        while formerTxt==editor.plainText:
74
            editor = waitForObject(":Qt Creator_QmlJSEditor::QmlJSTextEditorWidget")
75
76
77
        # store content for next round
        formerTxt = editor.plainText
        originalTexts.setdefault(file, "%s" % formerTxt)
78
79
80
        test.log("stored %s's content" % file.replace("Core.","").replace("\\",""))
    # last opened file is the main file focus.qml
    line = "FocusScope\s*\{"
81
82
83
84
    if not placeCursorToLine(editor, line, True):
        test.fatal("File seems to have changed... Canceling current test")
        return False
    type(editor, "<Down>")
Christian Stenger's avatar
Christian Stenger committed
85
    searchFinished = False
86
    invokeContextMenuItem(editor, "Rename Symbol Under Cursor")
Christian Stenger's avatar
Christian Stenger committed
87
    waitFor("searchFinished")
88
89
    type(waitForObject("{leftWidget={text='Replace with:' type='QLabel' unnamed='1' visible='1'} "
                       "type='Find::Internal::WideEnoughLineEdit' unnamed='1' visible='1' "
90
                       "window=':Qt Creator_Core::Internal::MainWindow'}"), "renamedView")
91
92
    clickButton(waitForObject("{text='Replace' type='QToolButton' unnamed='1' visible='1' "
                              "window=':Qt Creator_Core::Internal::MainWindow'}"))
93
94
    # store editor content for synchronizing purpose
    formerTxt = editor.plainText
95
96
    for file in files:
        doubleClickFile(navTree, file)
97
98
        # wait until editor content switched to double-clicked file
        while formerTxt==editor.plainText:
99
            editor = waitForObject(":Qt Creator_QmlJSEditor::QmlJSTextEditorWidget")
100
101
        # store content for next round
        formerTxt = editor.plainText
102
        originalText = originalTexts.get(file).replace("mainView", "renamedView")
103
        test.compare(originalText,formerTxt, "Comparing %s" % file.replace("Core.","").replace("\\",""))
104
    invokeMenuItem("File","Save All")
105

Christian Stenger's avatar
Christian Stenger committed
106
def __invokeFindUsage__(treeView, filename, line, additionalKeyPresses, expectedCount):
Christian Stenger's avatar
Christian Stenger committed
107
    global searchFinished
108
    doubleClickFile(treeView, filename)
109
    editor = waitForObject(":Qt Creator_QmlJSEditor::QmlJSTextEditorWidget")
110
111
112
    if not placeCursorToLine(editor, line, True):
        test.fatal("File seems to have changed... Canceling current test")
        return
Christian Stenger's avatar
Christian Stenger committed
113
    for ty in additionalKeyPresses:
114
        type(editor, ty)
Christian Stenger's avatar
Christian Stenger committed
115
    searchFinished = False
116
    invokeContextMenuItem(editor, "Find Usages")
Christian Stenger's avatar
Christian Stenger committed
117
    waitFor("searchFinished")
118
119
120
121
122
    validateSearchResult(expectedCount)

def testFindUsages():
    test.log("Testing find usage of an ID")
    navTree = waitForObject("{type='Utils::NavigationTreeView' unnamed='1' visible='1' "
123
                            "window=':Qt Creator_Core::Internal::MainWindow'}")
124
125
    __invokeFindUsage__(navTree, "focus\\.qml", "FocusScope\s*\{", ["<Down>"], 6)
    test.log("Testing find usage of a property")
126
    clickButton(waitForObject(":*Qt Creator.Clear_QToolButton"))
Christian Stenger's avatar
Christian Stenger committed
127
128
129
130
    home = "<Home>"
    if platform.system() == "Darwin":
        home = "<Ctrl+Left>"
    __invokeFindUsage__(navTree, "focus\\.qml", "id: window", ["<Down>", "<Down>", home], 26)
131

Christian Stenger's avatar
Christian Stenger committed
132
133
def testHovering():
    navTree = waitForObject("{type='Utils::NavigationTreeView' unnamed='1' visible='1' "
134
                            "window=':Qt Creator_Core::Internal::MainWindow'}")
Christian Stenger's avatar
Christian Stenger committed
135
136
    test.log("Testing hovering elements")
    doubleClickFile(navTree, "focus\\.qml")
137
    editor = waitForObject(":Qt Creator_QmlJSEditor::QmlJSTextEditorWidget")
Christian Stenger's avatar
Christian Stenger committed
138
139
140
141
142
143
144
145
146
    lines=["FocusScope\s*\{", "Rectangle\s*\{"]
    if platform.system() == "Darwin":
        home = "<Ctrl+Left>"
    else:
        home = "<Home>"
    additionalKeyPresses = [home, "<Right>"]
    expectedTypes = ["TextTip", "TextTip"]
    expectedValues = [
                      {'text':'<table><tr><td valign=middle>FocusScope\n<p>The FocusScope object explicitly '
147
                       'creates a focus scope.</p></td><td>&nbsp;&nbsp;<img src=":/texteditor/images/f1.png"></td></tr></table>'},
Christian Stenger's avatar
Christian Stenger committed
148
                      {'text':'<table><tr><td valign=middle>Rectangle\n<p>The Rectangle item provides a filled rectangle with an '
149
                       'optional border.</p></td><td>&nbsp;&nbsp;<img src=":/texteditor/images/f1.png"></td></tr></table>'}
Christian Stenger's avatar
Christian Stenger committed
150
151
152
153
154
                      ]
    alternativeValues = [{"text":"FocusScope"}, {"text":"Rectangle"}]
    verifyHoveringOnEditor(editor, lines, additionalKeyPresses, expectedTypes, expectedValues, alternativeValues)
    test.log("Testing hovering properties")
    doubleClickFile(navTree, "focus\\.qml")
155
    editor = waitForObject(":Qt Creator_QmlJSEditor::QmlJSTextEditorWidget")
Christian Stenger's avatar
Christian Stenger committed
156
157
158
159
160
161
    lines = ['focus:\s*true', 'color:\s*"black"', 'states:\s*State\s*\{', 'transitions:\s*Transition\s*\{']
    expectedTypes = ["TextTip", "TextTip", "TextTip", "TextTip"]
    expectedValues = [
                      {'text':'<table><tr><td valign=middle>boolean<p>This property indicates whether the item has focus '
                       'within the enclosing focus scope. If true, this item will gain active focus when the enclosing '
                       'focus scope gains active focus. In the following example, <tt>input</tt> will be given active focus '
162
                       'when <tt>scope</tt> gains active focus.</p></td><td>&nbsp;&nbsp;<img src=":/texteditor/images/f1.png"'
Christian Stenger's avatar
Christian Stenger committed
163
164
                       '></td></tr></table>'},
                      {'text':'<table><tr><td valign=middle>string<p>This property holds the color used to fill the rectangle.'
165
                       '</p></td><td>&nbsp;&nbsp;<img src=":/texteditor/images/f1.png"></td></tr></table>'},
Christian Stenger's avatar
Christian Stenger committed
166
                      {'text':'<table><tr><td valign=middle>State<p>This property holds a list of states defined by the item.'
167
                       '</p></td><td>&nbsp;&nbsp;<img src=":/texteditor/images/f1.png"></td></tr></table>'},
Christian Stenger's avatar
Christian Stenger committed
168
                      {'text':'<table><tr><td valign=middle>Transition<p>This property holds a list of transitions defined by '
169
                       'the item.</p></td><td>&nbsp;&nbsp;<img src=":/texteditor/images/f1.png"></td></tr></table>'}
Christian Stenger's avatar
Christian Stenger committed
170
171
172
173
174
                      ]
    alternativeValues = [{"text":"boolean"}, {"text":"string"}, {"text":"State"}, {"text":"Transition"}]
    verifyHoveringOnEditor(editor, lines, additionalKeyPresses, expectedTypes, expectedValues, alternativeValues)
    test.log("Testing hovering expressions")
    doubleClickFile(navTree, "focus\\.qml")
175
    editor = waitForObject(":Qt Creator_QmlJSEditor::QmlJSTextEditorWidget")
Christian Stenger's avatar
Christian Stenger committed
176
    lines=['color:\s*"black"', 'color:\s*"#3E606F"']
177
    additionalKeyPresses = ["<Left>"]
Christian Stenger's avatar
Christian Stenger committed
178
    expectedValues = ["black", "#3E606F"]
179
    alternativeValues = [None, "#39616B"]
Christian Stenger's avatar
Christian Stenger committed
180
    expectedTypes = ["ColorTip", "ColorTip"]
181
    verifyHoveringOnEditor(editor, lines, additionalKeyPresses, expectedTypes, expectedValues, alternativeValues)
Christian Stenger's avatar
Christian Stenger committed
182
    doubleClickFile(navTree, "Core.ListMenu\\.qml")
183
    editor = waitForObject(":Qt Creator_QmlJSEditor::QmlJSTextEditorWidget")
Christian Stenger's avatar
Christian Stenger committed
184
185
186
187
    lines=['Rectangle\s*\{.*color:\s*"#D1DBBD"', 'NumberAnimation\s*\{\s*.*Easing.OutQuint\s*\}']
    additionalKeyPresses = ["<Left>", "<Left>", "<Left>", "<Left>"]
    expectedTypes = ["ColorTip", "TextTip"]
    expectedValues = ["#D1DBBD", {"text":"number"}]
188
189
    alternativeValues = ["#D6DBBD", None]
    verifyHoveringOnEditor(editor, lines, additionalKeyPresses, expectedTypes, expectedValues, alternativeValues)
Christian Stenger's avatar
Christian Stenger committed
190

191
def doubleClickFile(navTree, file):
192
    global templateDir
193
    treeElement = ("untitled.QML.%s/qml.%s" %
194
                   (maskSpecialCharsForProjectTree(templateDir),file))
Robert Loehning's avatar
Robert Loehning committed
195
    openDocument(treeElement)
196
197
198
199
200
201
202
203

def __getUnmaskedFilename__(maskedFilename):
    name = maskedFilename.split("\\.")
    path = name[0].rsplit(".", 1)
    if len(path) < 2:
        return ".".join(name)
    else:
        return ".".join((path[1], ".".join(name[1:])))
204

205
206
207
208
209
210
def maskSpecialCharsForProjectTree(filename):
    filename = filename.replace("\\", "/").replace("_", "\\_").replace(".","\\.")
    # undoing mask operations on chars masked by mistake
    filename = filename.replace("/?","\\?").replace("/*","\\*")
    return filename

211
def __handleFutureProgress__(*args):
Christian Stenger's avatar
Christian Stenger committed
212
    global searchFinished
213
    if className(args[0]) == "Core::FutureProgress":
Christian Stenger's avatar
Christian Stenger committed
214
        searchFinished = True