From a1a3da9d2df561206e077c58aae8e23cfd98e122 Mon Sep 17 00:00:00 2001
From: Christian Stenger <christian.stenger@digia.com>
Date: Tue, 9 Oct 2012 15:00:17 +0200
Subject: [PATCH] Squish: Add test for renaming macros

Change-Id: I9c9bc9556234ec321c6e3723f5276a0b66f6c90a
Reviewed-by: Robert Loehning <robert.loehning@digia.com>
---
 tests/system/shared/editor_utils.py           |  11 ++
 tests/system/shared/project.py                |  29 +++-
 .../shared/simplePlainCPP/main.cpp            |  11 ++
 .../shared/simplePlainCPP/testfile.cpp        |  14 ++
 .../shared/simplePlainCPP/testfile.h          |  11 ++
 .../shared/simplePlainCPP/testfiles.pro       |  11 ++
 tests/system/suite_editors/suite.conf         |   2 +-
 .../suite_editors/tst_rename_macros/test.py   | 153 ++++++++++++++++++
 8 files changed, 240 insertions(+), 2 deletions(-)
 create mode 100644 tests/system/suite_editors/shared/simplePlainCPP/main.cpp
 create mode 100644 tests/system/suite_editors/shared/simplePlainCPP/testfile.cpp
 create mode 100644 tests/system/suite_editors/shared/simplePlainCPP/testfile.h
 create mode 100644 tests/system/suite_editors/shared/simplePlainCPP/testfiles.pro
 create mode 100644 tests/system/suite_editors/tst_rename_macros/test.py

diff --git a/tests/system/shared/editor_utils.py b/tests/system/shared/editor_utils.py
index 04b7ead8c4f..f7573e19470 100644
--- a/tests/system/shared/editor_utils.py
+++ b/tests/system/shared/editor_utils.py
@@ -295,3 +295,14 @@ def invokeFindUsage(editor, line, typeOperation, n=1):
         type(editor, typeOperation)
     invokeContextMenuItem(editor, "Find Usages")
     return True
+
+def openDocument(treeElement):
+    try:
+        navigator = waitForObject(":Qt Creator_Utils::NavigationTreeView")
+        fileName = waitForObjectItem(navigator, treeElement).text
+        doubleClickItem(navigator, treeElement, 5, 5, 0, Qt.LeftButton)
+        mainWindow = waitForObject(":Qt Creator_Core::Internal::MainWindow")
+        waitFor("fileName in str(mainWindow.windowTitle)")
+        return True
+    except:
+        return False
diff --git a/tests/system/shared/project.py b/tests/system/shared/project.py
index 1c2f7d5d6a3..28b54dcae9e 100644
--- a/tests/system/shared/project.py
+++ b/tests/system/shared/project.py
@@ -452,7 +452,11 @@ def __getSupportedPlatforms__(text, getAsStrings=False):
 # copy example project (sourceExample is path to project) to temporary directory inside repository
 def prepareTemplate(sourceExample):
     templateDir = os.path.abspath(tempDir() + "/template")
-    shutil.copytree(sourceExample, templateDir)
+    try:
+        shutil.copytree(sourceExample, templateDir)
+    except:
+        test.fatal("Error while copying '%s' to '%s'" % (sourceExample, templateDir))
+        return None
     return templateDir
 
 def __sortFilenamesOSDependent__(filenames):
@@ -498,3 +502,26 @@ def compareProjectTree(rootObject, dataset):
                       'Line %s in dataset' % str(i + 1))
             return
     test.passes("No errors found in project tree")
+
+def addCPlusPlusFileToCurrentProject(name, template, forceOverwrite=False):
+    if name == None:
+        test.fatal("File must have a name - got None.")
+        return
+    __createProjectOrFileSelectType__("  C++", template, isProject=False)
+    window = "{type='Utils::FileWizardDialog' unnamed='1' visible='1'}"
+    basePath = str(waitForObject("{type='Utils::BaseValidatingLineEdit' unnamed='1' visible='1' "
+                                 "window=%s}" % window).text)
+    lineEdit = waitForObject("{name='nameLineEdit' type='Utils::FileNameValidatingLineEdit' "
+                             "visible='1' window=%s}" % window)
+    replaceEditorContent(lineEdit, name)
+    clickButton(waitForObject(":Next_QPushButton"))
+    __createProjectHandleLastPage__()
+    if (os.path.exists(os.path.join(basePath, name))):
+        overwriteDialog = "{type='Core::Internal::PromptOverwriteDialog' unnamed='1' visible='1'}"
+        waitForObject(overwriteDialog)
+        if forceOverwrite:
+            buttonToClick = 'OK'
+        else:
+            buttonToClick = 'Cancel'
+        clickButton("{text='%s' type='QPushButton' unnamed='1' visible='1' window=%s}"
+                    % (buttonToClick, overwriteDialog))
diff --git a/tests/system/suite_editors/shared/simplePlainCPP/main.cpp b/tests/system/suite_editors/shared/simplePlainCPP/main.cpp
new file mode 100644
index 00000000000..84bb10f4380
--- /dev/null
+++ b/tests/system/suite_editors/shared/simplePlainCPP/main.cpp
@@ -0,0 +1,11 @@
+#include <iostream>
+#include "testfile.h"
+
+using namespace std;
+
+int main()
+{
+  cout << "Hello World!" << endl;
+  return 0;
+}
+
diff --git a/tests/system/suite_editors/shared/simplePlainCPP/testfile.cpp b/tests/system/suite_editors/shared/simplePlainCPP/testfile.cpp
new file mode 100644
index 00000000000..cffb1a78478
--- /dev/null
+++ b/tests/system/suite_editors/shared/simplePlainCPP/testfile.cpp
@@ -0,0 +1,14 @@
+#include "testfile.h"
+
+class SomeClass
+{
+public:
+    SomeClass() {}
+    void function1(int a);
+};
+
+bool function1(int a) {
+  SOME_MACRO_NAME(a)
+  return a;
+}
+
diff --git a/tests/system/suite_editors/shared/simplePlainCPP/testfile.h b/tests/system/suite_editors/shared/simplePlainCPP/testfile.h
new file mode 100644
index 00000000000..0fc49694e4b
--- /dev/null
+++ b/tests/system/suite_editors/shared/simplePlainCPP/testfile.h
@@ -0,0 +1,11 @@
+class AnyClass
+{
+public:
+    AnyClass() {}
+};
+
+#define SOME_MACRO_NAME( X )\
+{\
+  (X) = 1;\
+}\
+
diff --git a/tests/system/suite_editors/shared/simplePlainCPP/testfiles.pro b/tests/system/suite_editors/shared/simplePlainCPP/testfiles.pro
new file mode 100644
index 00000000000..2a0c8bcf737
--- /dev/null
+++ b/tests/system/suite_editors/shared/simplePlainCPP/testfiles.pro
@@ -0,0 +1,11 @@
+TEMPLATE = app
+CONFIG += console
+CONFIG -= app_bundle
+CONFIG -= qt
+
+SOURCES += main.cpp \
+    testfile.cpp
+
+HEADERS += \
+    testfile.h
+
diff --git a/tests/system/suite_editors/suite.conf b/tests/system/suite_editors/suite.conf
index 717453e22dc..95c4b7e506d 100644
--- a/tests/system/suite_editors/suite.conf
+++ b/tests/system/suite_editors/suite.conf
@@ -7,6 +7,6 @@ HOOK_SUB_PROCESSES=false
 IMPLICITAUTSTART=0
 LANGUAGE=Python
 OBJECTMAP=../objects.map
-TEST_CASES=tst_memberoperator
+TEST_CASES=tst_memberoperator tst_rename_macros
 VERSION=2
 WRAPPERS=Qt
diff --git a/tests/system/suite_editors/tst_rename_macros/test.py b/tests/system/suite_editors/tst_rename_macros/test.py
new file mode 100644
index 00000000000..79cee380f1a
--- /dev/null
+++ b/tests/system/suite_editors/tst_rename_macros/test.py
@@ -0,0 +1,153 @@
+source("../../shared/qtcreator.py")
+
+cppEditorStr = ":Qt Creator_CppEditor::Internal::CPPEditorWidget"
+
+def main():
+    global cppEditorStr
+    folder = prepareTemplate(os.path.abspath(os.path.join(os.getcwd(), "..", "shared",
+                                                          "simplePlainCPP")))
+    if folder == None:
+        test.fatal("Could not prepare test files - leaving test")
+        return
+    proFile = os.path.join(folder, "testfiles.pro")
+    startApplication("qtcreator" + SettingsPath)
+    openQmakeProject(proFile)
+    if not testRenameMacroAfterSourceModification():
+        return
+    addCPlusPlusFileToCurrentProject("anothertestfile.h", "C++ Header File")
+    if not testRenameMacroAfterSourceMoving():
+        return
+    invokeMenuItem("File", "Save All")
+    invokeMenuItem("File", "Exit")
+
+def testRenameMacroAfterSourceModification():
+    def __deleteAnyClass__():
+        global cppEditorStr
+        if platform.system() == 'Darwin':
+            type(cppEditorStr, "<Command+Left>")
+        else:
+            type(cppEditorStr, "<Home>")
+        for i in range(5):
+            type(cppEditorStr, "<Shift+Down>")
+        type(cppEditorStr, "<Delete>")
+
+    test.log("Testing rename macro after modifying source.")
+    formerTexts = {}
+    content = openDocumentPlaceCursor("testfiles.Headers.testfile\\.h",
+                                      "class AnyClass", __deleteAnyClass__)
+    if not content:
+        return False
+    formerTexts["testfiles.Headers.testfile\\.h"] = content
+    content = openDocumentPlaceCursor("testfiles.Sources.testfile\\.cpp", "SOME_MACRO_NAME(a)")
+    if not content:
+        return False
+    formerTexts["testfiles.Sources.testfile\\.cpp"] = content
+    performMacroRenaming('SOME_OTHER_MACRO_NAME')
+    verifyChangedContent(formerTexts, "SOME_MACRO_NAME", "SOME_OTHER_MACRO_NAME")
+    revertChanges(formerTexts)
+    return True
+
+def testRenameMacroAfterSourceMoving():
+    def __cut__():
+        global cppEditorStr
+        if platform.system() == 'Darwin':
+            type(cppEditorStr, "<Command+Left>")
+        else:
+            type(cppEditorStr, "<Home>")
+        for i in range(4):
+            type(cppEditorStr, "<Shift+Down>")
+        invokeMenuItem("Edit", "Cut")
+
+    def __paste__():
+        global cppEditorStr
+        type(cppEditorStr, "<Return>")
+        invokeMenuItem("Edit", "Paste")
+
+    def __insertInclude__():
+        global cppEditorStr
+        typeLines(cppEditorStr, ['', '#include "anothertestfile.h"'])
+
+    test.log("Testing rename macro after moving source.")
+    formerTexts = {}
+    content = openDocumentPlaceCursor("testfiles.Headers.testfile\\.h",
+                                      "#define SOME_MACRO_NAME( X )\\", __cut__)
+    if not content:
+        return False
+    formerTexts["testfiles.Headers.testfile\\.h"] = content
+    content = openDocumentPlaceCursor("testfiles.Headers.anothertestfile\\.h",
+                                      "#define ANOTHERTESTFILE_H", __paste__)
+    if not content:
+        return False
+    formerTexts["testfiles.Headers.anothertestfile\\.h"] = content
+    content = openDocumentPlaceCursor('testfiles.Sources.testfile\\.cpp',
+                                      '#include "testfile.h"', __insertInclude__)
+    if not content:
+        return False
+    formerTexts["testfiles.Sources.testfile\\.cpp"] = content
+    placeCursorToLine(cppEditorStr, "SOME_MACRO_NAME(a)")
+    performMacroRenaming("COMPLETELY_DIFFERENT_MACRO_NAME")
+    verifyChangedContent(formerTexts, "SOME_MACRO_NAME", "COMPLETELY_DIFFERENT_MACRO_NAME")
+    revertChanges(formerTexts)
+    return True
+
+def openDocumentPlaceCursor(doc, line, additionalFunction=None):
+    global cppEditorStr
+    if openDocument(doc) and placeCursorToLine(cppEditorStr, line):
+        if additionalFunction:
+            additionalFunction()
+        return str(waitForObject(cppEditorStr).plainText)
+    else:
+        earlyExit("Open %s or placing cursor to line (%s) failed." % (simpleFileName(doc), line))
+        return None
+
+def performMacroRenaming(newMacroName):
+    for i in range(10):
+        type(cppEditorStr, "<Left>")
+    invokeContextMenuItem(waitForObject(cppEditorStr), "Refactor",
+                          "Rename Symbol Under Cursor")
+    validateSearchResult(2)
+    replaceLineEdit = waitForObject("{leftWidget={text='Replace with:' type='QLabel' "
+                                    "unnamed='1' visible='1'} "
+                                    "type='Find::Internal::WideEnoughLineEdit' unnamed='1' "
+                                    "visible='1' "
+                                    "window=':Qt Creator_Core::Internal::MainWindow'}")
+    replaceEditorContent(replaceLineEdit, newMacroName)
+    clickButton(waitForObject("{text='Replace' type='QToolButton' unnamed='1' visible='1' "
+                              "window=':Qt Creator_Core::Internal::MainWindow'}"))
+
+def verifyChangedContent(origTexts, replacedSymbol, replacement):
+    global cppEditorStr
+    successfullyCompared = []
+    for fileName,text in origTexts.iteritems():
+        if openDocument(fileName):
+            successfullyCompared.append(test.compare(waitForObject(cppEditorStr).plainText,
+                                                     text.replace(replacedSymbol, replacement),
+                                                     "Verifying content of %s" %
+                                                     simpleFileName(fileName)))
+        else:
+            successfullyCompared.append(False)
+            test.fail("Failed to open document %s" % simpleFileName(fileName))
+    if successfullyCompared.count(True) == len(origTexts):
+        test.passes("Successfully compared %d changed files" % len(origTexts))
+    else:
+        test.fail("Verifyied %d files - %d have been successfully changed and %d failed to "
+                  "change correctly." % (len(origTexts), successfullyCompared.count(True),
+                                         successfullyCompared.count(False)))
+
+def revertChanges(files):
+    for f in files:
+        simpleName = simpleFileName(f)
+        if openDocument(f):
+            invokeMenuItem('File', 'Revert "%s" to Saved' % simpleName)
+            clickButton(waitForObject(":Revert to Saved.Proceed_QPushButton"))
+            test.log("Reverted changes inside %s" % simpleName)
+        else:
+            test.fail("Could not open %s for reverting changes" % simpleName)
+
+def simpleFileName(navigatorFileName):
+    return ".".join(navigatorFileName.split(".")[-2:]).replace("\\","")
+
+def earlyExit(details="No additional information"):
+    test.fail("Something went wrong running this test", details)
+    invokeMenuItem("File", "Save All")
+    invokeMenuItem("File", "Exit")
-- 
GitLab