From 525cf2353e3a4d2957f0992a8078175c640aa1f4 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Thu, 3 May 2012 11:47:35 +0200 Subject: [PATCH 1/4] Squish: Support more than one breakpoint per file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ic33e039fe5aea9caed5a3e992a74938e331e2a4b Reviewed-by: Robert Löhning --- tests/system/shared/debugger.py | 21 ++++++++------- tests/system/shared/utils.py | 27 ++++++++++--------- .../suite_debugger/tst_simple_debug/test.py | 8 +++--- 3 files changed, 30 insertions(+), 26 deletions(-) diff --git a/tests/system/shared/debugger.py b/tests/system/shared/debugger.py index cfe40bfaeb5..dc173ad20ae 100644 --- a/tests/system/shared/debugger.py +++ b/tests/system/shared/debugger.py @@ -35,7 +35,7 @@ def takeDebuggerLog(): return debuggerLog # function to set breakpoints for the current project -# on the given file,line pairs inside the given dict +# on the given file,line pairs inside the given list of dicts # the lines are treated as regular expression def setBreakpointsForCurrentProject(filesAndLines): # internal helper for setBreakpointsForCurrentProject @@ -52,18 +52,19 @@ def setBreakpointsForCurrentProject(filesAndLines): switchViewTo(ViewConstants.DEBUG) removeOldBreakpoints() - if not filesAndLines or not isinstance(filesAndLines, dict): - test.fatal("This function only takes a non-empty dict.") + if not filesAndLines or not isinstance(filesAndLines, (list,tuple)): + test.fatal("This function only takes a non-empty list/tuple holding dicts.") return False navTree = waitForObject("{type='Utils::NavigationTreeView' unnamed='1' visible='1' " "window=':Qt Creator_Core::Internal::MainWindow'}", 20000) - for curFile,curLine in filesAndLines.iteritems(): - fName = __doubleClickFile__(navTree, curFile) - editor = getEditorForFileSuffix(curFile) - if not placeCursorToLine(editor, curLine, True): - return False - invokeMenuItem("Debug", "Toggle Breakpoint") - test.log('Set breakpoint in %s' % fName, curLine) + for current in filesAndLines: + for curFile,curLine in current.iteritems(): + fName = __doubleClickFile__(navTree, curFile) + editor = getEditorForFileSuffix(curFile) + if not placeCursorToLine(editor, curLine, True): + return False + invokeMenuItem("Debug", "Toggle Breakpoint") + test.log('Set breakpoint in %s' % fName, curLine) try: breakPointTreeView = waitForObject("{type='Debugger::Internal::BreakWindow' visible='1' " "windowTitle='Breakpoints' name='Debugger.Docks.Break'}") diff --git a/tests/system/shared/utils.py b/tests/system/shared/utils.py index 9809b6f00d1..ca971c6842a 100644 --- a/tests/system/shared/utils.py +++ b/tests/system/shared/utils.py @@ -375,7 +375,8 @@ def checkDebuggingLibrary(targVersion, targets): # param keepOptionsOpen set to True if the Options dialog should stay open when # leaving this function # param additionalFunction pass a function or name of a defined function to execute -# for each item on the list of Qt versions +# for each correctly configured item on the list of Qt versions +# (Qt versions having no assigned toolchain, failing qmake,... will be skipped) # this function must take at least 2 parameters - the first is the target name # and the second the version of the current selected Qt version item # param argsForAdditionalFunc you can specify as much parameters as you want to pass @@ -411,17 +412,19 @@ def iterateQtVersions(keepOptionsOpen=False, additionalFunction=None, *argsForAd target = matches.group("target").strip() version = matches.group("version").strip() result.append({target:version}) - if additionalFunction: - try: - if isinstance(additionalFunction, (str, unicode)): - currResult = globals()[additionalFunction](target, version, *argsForAdditionalFunc) - else: - currResult = additionalFunction(target, version, *argsForAdditionalFunc) - except: - currResult = None - test.fatal("Function to additionally execute on Options Dialog could not be found or " - "an exception occured while executing it.") - additionalResult.append(currResult) + if additionalFunction: + try: + if isinstance(additionalFunction, (str, unicode)): + currResult = globals()[additionalFunction](target, version, *argsForAdditionalFunc) + else: + currResult = additionalFunction(target, version, *argsForAdditionalFunc) + except: + import sys + t,v,tb = sys.exc_info() + currResult = None + test.fatal("Function to additionally execute on Options Dialog could not be found or " + "an exception occured while executing it.", "%s(%s)" % (str(t), str(v))) + additionalResult.append(currResult) if not keepOptionsOpen: clickButton(waitForObject(":Options.Cancel_QPushButton")) if additionalFunction: diff --git a/tests/system/suite_debugger/tst_simple_debug/test.py b/tests/system/suite_debugger/tst_simple_debug/test.py index 69f40d59360..b7c818aa2eb 100644 --- a/tests/system/suite_debugger/tst_simple_debug/test.py +++ b/tests/system/suite_debugger/tst_simple_debug/test.py @@ -25,10 +25,10 @@ def main(): 'running: true', 'onTriggered: console.log("Break here")']) invokeMenuItem("File", "Save All") - filesAndLines = { - "%s.QML.qml/%s.main\\.qml" % (projectName,projectName) : 'onTriggered:.*', - "%s.Sources.main\\.cpp" % projectName : "viewer.setOrientation\\(.+\\);" - } + filesAndLines = [ + { "%s.QML.qml/%s.main\\.qml" % (projectName,projectName) : 'onTriggered.*' }, + { "%s.Sources.main\\.cpp" % projectName : "viewer.setOrientation\\(.+\\);" } + ] test.log("Setting breakpoints") result = setBreakpointsForCurrentProject(filesAndLines) if result: From a71b76867540d63c9c46899f288249d92924a03c Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Mon, 21 May 2012 16:24:23 +0200 Subject: [PATCH 2/4] Squish: Added fatals when no Qt version was found Change-Id: I1d1f4f378ef60107a488477bce40dacaabbe4109 Reviewed-by: Christian Stenger --- tests/system/suite_CCOM/tst_CCOM01/test.py | 5 ++++- tests/system/suite_SCOM/tst_SCOM01/test.py | 5 ++++- tests/system/suite_SCOM/tst_SCOM04/test.py | 5 ++++- tests/system/suite_debugger/tst_build_new_project/test.py | 5 ++++- tests/system/suite_debugger/tst_cli_output_console/test.py | 5 ++++- tests/system/suite_general/tst_build_speedcrunch/test.py | 5 ++++- 6 files changed, 24 insertions(+), 6 deletions(-) diff --git a/tests/system/suite_CCOM/tst_CCOM01/test.py b/tests/system/suite_CCOM/tst_CCOM01/test.py index 733943d1600..985ec0bcf9b 100755 --- a/tests/system/suite_CCOM/tst_CCOM01/test.py +++ b/tests/system/suite_CCOM/tst_CCOM01/test.py @@ -14,7 +14,10 @@ def main(): # open example project openQmakeProject(examplePath) # build and wait until finished - on all (except Qt 4.7.0 (would fail)) build configurations - for config in iterateBuildConfigs(1, 0, "(?!.*4\.7\.0.*)"): + availableConfigs = iterateBuildConfigs(1, 0, "(?!.*4\.7\.0.*)") + if not availableConfigs: + test.fatal("Haven't found a suitable Qt version (anything except Qt 4.7.0) - leaving without building.") + for config in availableConfigs: selectBuildConfig(1, 0, config) # try to build project test.log("Testing build configuration: " + config) diff --git a/tests/system/suite_SCOM/tst_SCOM01/test.py b/tests/system/suite_SCOM/tst_SCOM01/test.py index 4b4fb5f21e9..0bc53c39126 100644 --- a/tests/system/suite_SCOM/tst_SCOM01/test.py +++ b/tests/system/suite_SCOM/tst_SCOM01/test.py @@ -7,7 +7,10 @@ def main(): # create qt quick application createNewQtQuickApplication(tempDir(), "SampleApp") # build it - on all (except Qt 4.7.0 (would fail)) build configurations - for config in iterateBuildConfigs(1, 0, "(?!.*4\.7\.0.*)"): + availableConfigs = iterateBuildConfigs(1, 0, "(?!.*4\.7\.0.*)") + if not availableConfigs: + test.fatal("Haven't found a suitable Qt version (anything except Qt 4.7.0) - leaving without building.") + for config in availableConfigs: selectBuildConfig(1, 0, config) # try to compile test.log("Testing build configuration: " + config) diff --git a/tests/system/suite_SCOM/tst_SCOM04/test.py b/tests/system/suite_SCOM/tst_SCOM04/test.py index fecef36c571..bb4a99f10e0 100644 --- a/tests/system/suite_SCOM/tst_SCOM04/test.py +++ b/tests/system/suite_SCOM/tst_SCOM04/test.py @@ -17,7 +17,10 @@ def main(): # save all invokeMenuItem("File", "Save All") # build it - on all (except Qt 4.7.0 (would fail)) build configurations - for config in iterateBuildConfigs(1, 0, "(?!.*4\.7\.0.*)"): + availableConfigs = iterateBuildConfigs(1, 0, "(?!.*4\.7\.0.*)") + if not availableConfigs: + test.fatal("Haven't found a suitable Qt version (anything except Qt 4.7.0) - leaving without building.") + for config in availableConfigs: selectBuildConfig(1, 0, config) # try to compile test.log("Testing build configuration: " + config) diff --git a/tests/system/suite_debugger/tst_build_new_project/test.py b/tests/system/suite_debugger/tst_build_new_project/test.py index 73a46f61eee..cd33ccfbbf8 100644 --- a/tests/system/suite_debugger/tst_build_new_project/test.py +++ b/tests/system/suite_debugger/tst_build_new_project/test.py @@ -6,7 +6,10 @@ project = "SquishProject" def main(): startApplication("qtcreator" + SettingsPath) createProject_Qt_Console(projectsPath, project) - for config in iterateBuildConfigs(1, 0): + availableConfigs = iterateBuildConfigs(1, 0) + if not availableConfigs: + test.fatal("Haven't found a suitable Qt version - leaving without building.") + for config in availableConfigs: selectBuildConfig(1, 0, config) test.log("Testing build configuration: " + config) runAndCloseApp() diff --git a/tests/system/suite_debugger/tst_cli_output_console/test.py b/tests/system/suite_debugger/tst_cli_output_console/test.py index 50c8a7645c1..692c01a5bd9 100644 --- a/tests/system/suite_debugger/tst_cli_output_console/test.py +++ b/tests/system/suite_debugger/tst_cli_output_console/test.py @@ -37,7 +37,10 @@ def main(): test.verify("CONFIG += console" in str(proEditor.plainText), "Verifying that program is configured with console") setRunInTerminal(1, 0, False) - for config in iterateBuildConfigs(1, 0): + availableConfigs = iterateBuildConfigs(1, 0) + if not availableConfigs: + test.fatal("Haven't found a suitable Qt version - leaving without building.") + for config in availableConfigs: selectBuildConfig(1, 0, config) test.log("Testing build configuration: " + config) diff --git a/tests/system/suite_general/tst_build_speedcrunch/test.py b/tests/system/suite_general/tst_build_speedcrunch/test.py index cd2c09879a3..147cc967fc8 100644 --- a/tests/system/suite_general/tst_build_speedcrunch/test.py +++ b/tests/system/suite_general/tst_build_speedcrunch/test.py @@ -27,7 +27,10 @@ def main(): fancyToolButton = waitForObject(":*Qt Creator_Core::Internal::FancyToolButton") qtVerPattern = re.compile("\d\.\d(\.\d+)?") - for config in iterateBuildConfigs(1, 0, "(Desktop )?Qt.*Release"): + availableConfigs = iterateBuildConfigs(1, 0, "(Desktop )?Qt.*Release") + if not availableConfigs: + test.fatal("Haven't found a suitable Qt version (need Release build) - leaving without building.") + for config in availableConfigs: qtVersion = qtVerPattern.search(config) if qtVersion: qtVersion = qtVersion.group() From 53fb9d4ae84443ceca67ed6ac793a82640274209 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Wed, 23 May 2012 15:36:30 +0200 Subject: [PATCH 3/4] Squish: Simplified placeCursorToLine Change-Id: Ib56bc7b2596ac61233e147fb62f763a594abe9df Reviewed-by: Christian Stenger --- tests/system/shared/editor_utils.py | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/tests/system/shared/editor_utils.py b/tests/system/shared/editor_utils.py index 2ebf8205f99..ae5fc8cfde6 100644 --- a/tests/system/shared/editor_utils.py +++ b/tests/system/shared/editor_utils.py @@ -5,7 +5,7 @@ import re; # and goes to the end of the line # line can be a regex - but if so, remember to set isRegex to True # the function returns True if this went fine, False on error -def placeCursorToLine(editor,line,isRegex=False): +def placeCursorToLine(editor, line, isRegex=False): cursor = editor.textCursor() oldPosition = 0 cursor.setPosition(oldPosition) @@ -15,26 +15,17 @@ def placeCursorToLine(editor,line,isRegex=False): regex = re.compile(line) while not found: currentLine = str(lineUnderCursor(editor)).strip() - if isRegex: - if regex.match(currentLine): - found = True - else: - moveTextCursor(editor, QTextCursor.Down, QTextCursor.MoveAnchor) - if oldPosition==editor.textCursor().position(): - break - oldPosition = editor.textCursor().position() - else: - if currentLine==line: - found = True - else: - moveTextCursor(editor, QTextCursor.Down, QTextCursor.MoveAnchor) - if oldPosition==editor.textCursor().position(): - break - oldPosition = editor.textCursor().position() + found = isRegex and regex.match(currentLine) or not isRegex and currentLine == line + if not found: + type(editor, "") + newPosition = editor.textCursor().position() + if oldPosition == newPosition: + break + oldPosition = newPosition if not found: test.fatal("Couldn't find line matching\n\n%s\n\nLeaving test..." % line) return False - cursor=editor.textCursor() + cursor = editor.textCursor() cursor.movePosition(QTextCursor.EndOfLine, QTextCursor.MoveAnchor) editor.setTextCursor(cursor) return True From ea63b86e49d2f15eb2aff1548aae1fce1af70090 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Fri, 25 May 2012 11:52:01 +0200 Subject: [PATCH 4/4] Squish: Replaced function moveTextCursor Change-Id: Ie4cccd0de668690a3d66baf422bcfff7acae7345 Reviewed-by: Christian Stenger --- tests/system/shared/editor_utils.py | 15 -------------- tests/system/suite_QMLS/tst_QMLS02/test.py | 5 +++-- tests/system/suite_QMLS/tst_QMLS03/test.py | 9 +++++--- tests/system/suite_QMLS/tst_QMLS04/test.py | 3 ++- tests/system/suite_QMLS/tst_QMLS05/test.py | 24 ++++++++++------------ 5 files changed, 22 insertions(+), 34 deletions(-) diff --git a/tests/system/shared/editor_utils.py b/tests/system/shared/editor_utils.py index ae5fc8cfde6..8f7b74026f4 100644 --- a/tests/system/shared/editor_utils.py +++ b/tests/system/shared/editor_utils.py @@ -30,21 +30,6 @@ def placeCursorToLine(editor, line, isRegex=False): editor.setTextCursor(cursor) return True -# this function moves the text cursor of an editor by using Qt internal functions -# this is more reliable (especially on Mac) than the type() approach -# param editor an editor object -# param moveOperation a value of enum MoveOperation (of QTextCursor) -# param moveAnchor a value of enum MoveMode (of QTextCursor) -# param n how often repeat the move operation? -def moveTextCursor(editor, moveOperation, moveAnchor, n=1): - if not editor or isinstance(editor, (str,unicode)): - test.fatal("Either got a NoneType or a string instead of an editor object") - return False - textCursor = editor.textCursor() - result = textCursor.movePosition(moveOperation, moveAnchor, n) - editor.setTextCursor(textCursor) - return result - # this function returns True if a QMenu is # popped up above the given editor # param editor is the editor where the menu should appear diff --git a/tests/system/suite_QMLS/tst_QMLS02/test.py b/tests/system/suite_QMLS/tst_QMLS02/test.py index 3c65ac020f4..7f29524b83c 100644 --- a/tests/system/suite_QMLS/tst_QMLS02/test.py +++ b/tests/system/suite_QMLS/tst_QMLS02/test.py @@ -16,8 +16,9 @@ def main(): "Verifying if error is properly reported") # repair error - go to written line placeCursorToLine(editorArea, testingCodeLine) - moveTextCursor(editorArea, QTextCursor.Left, QTextCursor.MoveAnchor, 14) - moveTextCursor(editorArea, QTextCursor.Right, QTextCursor.KeepAnchor, 1) + for i in range(14): + type(editorArea, "") + type(editorArea, "") type(editorArea, "c") # invoke QML parsing invokeMenuItem("Tools", "QML/JS", "Run Checks") diff --git a/tests/system/suite_QMLS/tst_QMLS03/test.py b/tests/system/suite_QMLS/tst_QMLS03/test.py index c492a4d2684..bbd4facd237 100644 --- a/tests/system/suite_QMLS/tst_QMLS03/test.py +++ b/tests/system/suite_QMLS/tst_QMLS03/test.py @@ -59,7 +59,8 @@ def main(): if not placeCursorToLine(editorArea, "Rectangle {"): invokeMenuItem("File", "Exit") return - moveTextCursor(editorArea, QTextCursor.Left, QTextCursor.MoveAnchor, 5) + for i in range(5): + type(editorArea, "") ctxtMenu = openContextMenuOnTextCursorPosition(editorArea) activateItem(waitForObjectItem(objectMap.realName(ctxtMenu), "Find Usages")) # check if usage was properly found @@ -77,7 +78,8 @@ def main(): if not placeCursorToLine(editorArea, "anchors { left: parent.left; top: parent.top; right: parent.right; bottom: parent.verticalCenter }"): invokeMenuItem("File", "Exit") return - moveTextCursor(editorArea, QTextCursor.Left, QTextCursor.MoveAnchor, 87) + for i in range(87): + type(editorArea, "") invokeMenuItem("Tools", "QML/JS", "Find Usages") # check if usage was properly found expectedResults = [ExpectedResult("color-animation.qml", 50, "anchors { left: parent.left; top: parent.top; right: parent.right; bottom: parent.verticalCenter }"), @@ -94,7 +96,8 @@ def main(): if not placeCursorToLine(editorArea, "SequentialAnimation on opacity {"): invokeMenuItem("File", "Exit") return - moveTextCursor(editorArea, QTextCursor.Left, QTextCursor.MoveAnchor, 5) + for i in range(5): + type(editorArea, "") type(editorArea, "") # check if usage was properly found expectedResults = [ExpectedResult("color-animation.qml", 87, "SequentialAnimation on opacity {")] diff --git a/tests/system/suite_QMLS/tst_QMLS04/test.py b/tests/system/suite_QMLS/tst_QMLS04/test.py index e62b72dc6ae..e14f79804a4 100644 --- a/tests/system/suite_QMLS/tst_QMLS04/test.py +++ b/tests/system/suite_QMLS/tst_QMLS04/test.py @@ -5,7 +5,8 @@ def main(): editorArea = startQtCreatorWithNewAppAtQMLEditor(projectDir, "SampleApp", "Text {") if not editorArea: return - moveTextCursor(editorArea, QTextCursor.Left, QTextCursor.MoveAnchor, 5) + for i in range(5): + type(editorArea, "") # invoke Refactoring - Move Component into separate file ctxtMenu = openContextMenuOnTextCursorPosition(editorArea) activateItem(waitForObjectItem(objectMap.realName(ctxtMenu), "Refactoring")) diff --git a/tests/system/suite_QMLS/tst_QMLS05/test.py b/tests/system/suite_QMLS/tst_QMLS05/test.py index 694460eea32..f2e0fb50720 100644 --- a/tests/system/suite_QMLS/tst_QMLS05/test.py +++ b/tests/system/suite_QMLS/tst_QMLS05/test.py @@ -4,12 +4,17 @@ def main(): editorArea = startQtCreatorWithNewAppAtQMLEditor(tempDir(), "SampleApp", "Text {") if not editorArea: return - moveTextCursor(editorArea, QTextCursor.StartOfLine, QTextCursor.MoveAnchor) + homeKey = "" + if platform.system() == "Darwin": + homeKey = "" + for i in range(2): + type(editorArea, homeKey) type(editorArea, "") - moveTextCursor(editorArea, QTextCursor.Up, QTextCursor.MoveAnchor) + type(editorArea, "") type(editorArea, "") type(editorArea, "Item { x: 10; y: 20; width: 10 }") - moveTextCursor(editorArea, QTextCursor.Left, QTextCursor.MoveAnchor, 30) + for i in range(30): + type(editorArea, "") invokeMenuItem("File", "Save All") # activate menu and apply 'Refactoring - Split initializer' numLinesExpected = len(str(editorArea.plainText).splitlines()) + 4 @@ -20,16 +25,9 @@ def main(): waitFor("len(str(editorArea.plainText).splitlines()) == numLinesExpected", 5000) # verify if refactoring was properly applied - each part on separate line verifyMessage = "Verifying split initializer functionality at element line." - verifyCurrentLine(editorArea, "Item {", verifyMessage) - moveTextCursor(editorArea, QTextCursor.Down, QTextCursor.MoveAnchor, 1) - verifyCurrentLine(editorArea, "x: 10;", verifyMessage) - moveTextCursor(editorArea, QTextCursor.Down, QTextCursor.MoveAnchor, 1) - verifyCurrentLine(editorArea, "y: 20;", verifyMessage) - moveTextCursor(editorArea, QTextCursor.Down, QTextCursor.MoveAnchor, 1) - verifyCurrentLine(editorArea, "width: 10", verifyMessage) - moveTextCursor(editorArea, QTextCursor.Down, QTextCursor.MoveAnchor, 1) - verifyCurrentLine(editorArea, "}", verifyMessage) - moveTextCursor(editorArea, QTextCursor.Down, QTextCursor.MoveAnchor, 1) + for line in ["Item {", "x: 10;", "y: 20;", "width: 10", "}"]: + verifyCurrentLine(editorArea, line, verifyMessage) + type(editorArea, "") #save and exit invokeMenuItem("File", "Save All") invokeMenuItem("File", "Exit")