summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorChristian Stenger <christian.stenger@digia.com>2012-10-19 17:36:14 +0200
committerChristian Stenger <christian.stenger@digia.com>2012-11-01 17:09:40 +0100
commit47289addff4e23f049d38ad368defe77d403a56a (patch)
tree3800ac2a461d23e498c5609fb9245991c13a95eb /tests
parent270207f77e60bcb60bcd9d134f4b17ad79f4cdfd (diff)
downloadqt-creator-47289addff4e23f049d38ad368defe77d403a56a.tar.gz
Squish: Test handling of read only files
Change-Id: I459fdaed7338f5343b760da47e9652baf78986f0 Reviewed-by: Robert Loehning <robert.loehning@digia.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/system/objects.map3
-rw-r--r--tests/system/shared/editor_utils.py6
-rw-r--r--tests/system/shared/fs_utils.py33
-rw-r--r--tests/system/shared/qtcreator.py1
-rw-r--r--tests/system/suite_debugger/tst_cli_output_console/test.py3
-rw-r--r--tests/system/suite_editors/suite.conf2
-rw-r--r--tests/system/suite_editors/tst_modify_readonly/test.py136
7 files changed, 177 insertions, 7 deletions
diff --git a/tests/system/objects.map b/tests/system/objects.map
index 98896e6c4f..a8f6172529 100644
--- a/tests/system/objects.map
+++ b/tests/system/objects.map
@@ -54,6 +54,7 @@
:Next_QPushButton {text~='(Next.*|Continue)' type='QPushButton' visible='1'}
:Open File.File name:_QLabel {name='fileNameLabel' text='File name:' type='QLabel' visible='1' window=':Open File_QFileDialog'}
:Open File_QFileDialog {name='QFileDialog' type='QFileDialog' visible='1' windowTitle='Open File'}
+:OpenDocuments_QTreeView {name='editorList' type='QTreeView' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:OpenProject_QStyleItem {clip='false' container=':Qt Creator_QDeclarativeView' enabled='true' text='Open Project' type='LinkedText' unnamed='1' visible='true'}
:Options.Cancel_QPushButton {text='Cancel' type='QPushButton' unnamed='1' visible='1' window=':Options_Core::Internal::SettingsDialog'}
:Options.OK_QPushButton {text='OK' type='QPushButton' unnamed='1' visible='1' window=':Options_Core::Internal::SettingsDialog'}
@@ -87,10 +88,12 @@
:Qt Creator_Core::Internal::CommandComboBox {type='Core::Internal::CommandComboBox' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator_Core::Internal::MainWindow {type='Core::Internal::MainWindow' visible='1' windowTitle?='*Qt Creator'}
:Qt Creator_CppEditor::Internal::CPPEditorWidget {type='CppEditor::Internal::CPPEditorWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
+:Qt Creator_FilenameQComboBox {type='QComboBox' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator_Find::Internal::SearchResultTreeView {type='Find::Internal::SearchResultTreeView' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator_Help::Internal::HelpViewer {type='Help::Internal::HelpViewer' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator_HelpSelector_QComboBox {occurrence='3' type='QComboBox' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator_Issues_Core::Internal::OutputPaneToggleButton {occurrence='1' type='Core::Internal::OutputPaneToggleButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
+:Qt Creator_ProFileEditorWidget {type='Qt4ProjectManager::Internal::ProFileEditorWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator_QDeclarativeView {type='QDeclarativeView' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator_QHelpContentWidget {type='QHelpContentWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator_QTableView {type='QTableView' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
diff --git a/tests/system/shared/editor_utils.py b/tests/system/shared/editor_utils.py
index 7f96fc189b..7200725346 100644
--- a/tests/system/shared/editor_utils.py
+++ b/tests/system/shared/editor_utils.py
@@ -218,13 +218,11 @@ def getEditorForFileSuffix(curFile):
glslEditorSuffixes= ["frag", "vert", "fsh", "vsh", "glsl", "shader", "gsh"]
suffix = __getFileSuffix__(curFile)
if suffix in cppEditorSuffixes:
- editor = waitForObject("{type='CppEditor::Internal::CPPEditorWidget' unnamed='1' "
- "visible='1' window=':Qt Creator_Core::Internal::MainWindow'}")
+ editor = waitForObject(":Qt Creator_CppEditor::Internal::CPPEditorWidget")
elif suffix in qmlEditorSuffixes:
editor = waitForObject(":Qt Creator_QmlJSEditor::QmlJSTextEditorWidget")
elif suffix in proEditorSuffixes:
- editor = waitForObject("{type='Qt4ProjectManager::Internal::ProFileEditorWidget' unnamed='1' "
- "visible='1' window=':Qt Creator_Core::Internal::MainWindow'}")
+ editor = waitForObject(":Qt Creator_ProFileEditorWidget")
elif suffix in glslEditorSuffixes:
editor = waitForObject("{type='GLSLEditor::GLSLTextEditorWidget' unnamed='1' "
"visible='1' window=':Qt Creator_Core::Internal::MainWindow'}")
diff --git a/tests/system/shared/fs_utils.py b/tests/system/shared/fs_utils.py
new file mode 100644
index 0000000000..b261860a01
--- /dev/null
+++ b/tests/system/shared/fs_utils.py
@@ -0,0 +1,33 @@
+import stat
+
+# this function modifies all (regular) files inside the given dirPath to have specified permissions
+# ATTENTION: it won't process the directory recursively
+def changeFilePermissions(dirPath, readPerm, writePerm, excludeFileNames=None):
+ permission = 0
+ if readPerm:
+ permission |= stat.S_IREAD
+ if writePerm:
+ permission |= stat.S_IWRITE
+ if excludeFileNames == None:
+ excludeFileNames = []
+ elif isinstance(excludeFileNames, (str, unicode)):
+ excludeFileNames = [excludeFileNames]
+ if not isinstance(excludeFileNames, (tuple, list)):
+ test.warning("File names to exclude must be of type str, unicode, list, tuple or None - "
+ "ignoring parameter this time.")
+ excludeFileNames = []
+ if not os.path.isdir(dirPath):
+ test.warning("Could not find directory '%s'." % dirPath)
+ return False
+ filePaths = [os.path.join(dirPath, fileName) for fileName in os.listdir(dirPath)
+ if fileName not in excludeFileNames]
+ for filePath in filter(os.path.isfile, filePaths):
+ os.chmod(filePath, permission)
+ return True
+
+def isWritable(pathToFile):
+ if os.path.exists(pathToFile):
+ return os.access(pathToFile, os.W_OK)
+ else:
+ test.warning("Path to check for writability does not exist.")
+ return False
diff --git a/tests/system/shared/qtcreator.py b/tests/system/shared/qtcreator.py
index e48fe4ad37..66324cc7af 100644
--- a/tests/system/shared/qtcreator.py
+++ b/tests/system/shared/qtcreator.py
@@ -17,6 +17,7 @@ testSettings.logScreenshotOnError = True
source("../../shared/classes.py")
source("../../shared/utils.py")
+source("../../shared/fs_utils.py")
source("../../shared/build_utils.py")
source("../../shared/project.py")
source("../../shared/editor_utils.py")
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 f04e0e4959..6900aef542 100644
--- a/tests/system/suite_debugger/tst_cli_output_console/test.py
+++ b/tests/system/suite_debugger/tst_cli_output_console/test.py
@@ -31,8 +31,7 @@ def main():
# Rely on code completion for closing bracket
invokeMenuItem("File", "Save All")
selectFromLocator(project + ".pro")
- proEditor = waitForObject("{type='Qt4ProjectManager::Internal::ProFileEditorWidget' unnamed='1' visible='1'"
- "window=':Qt Creator_Core::Internal::MainWindow'}", 20000)
+ proEditor = waitForObject(":Qt Creator_ProFileEditorWidget", 20000)
test.verify("CONFIG += console" in str(proEditor.plainText), "Verifying that program is configured with console")
setRunInTerminal(1, 0, False)
diff --git a/tests/system/suite_editors/suite.conf b/tests/system/suite_editors/suite.conf
index 46c8bb025c..5a93d56846 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 tst_rename_macros tst_basic_cpp_support tst_select_all tst_qml_indent tst_qml_editor
+TEST_CASES=tst_basic_cpp_support tst_memberoperator tst_modify_readonly tst_qml_editor tst_qml_indent tst_rename_macros tst_select_all
VERSION=2
WRAPPERS=Qt
diff --git a/tests/system/suite_editors/tst_modify_readonly/test.py b/tests/system/suite_editors/tst_modify_readonly/test.py
new file mode 100644
index 0000000000..c5de75a853
--- /dev/null
+++ b/tests/system/suite_editors/tst_modify_readonly/test.py
@@ -0,0 +1,136 @@
+source("../../shared/qtcreator.py")
+
+def main():
+ global testFolder
+ cppEditorStr = ":Qt Creator_CppEditor::Internal::CPPEditorWidget"
+ proEditorStr = ":Qt Creator_ProFileEditorWidget"
+ testFolder = prepareTemplate(os.path.abspath(os.path.join(os.getcwd(), "..", "shared",
+ "simplePlainCPP")))
+ if testFolder == None:
+ test.fatal("Could not prepare test files - leaving test")
+ return
+ if not changeFilePermissions(testFolder, True, False, "testfiles.pro"):
+ test.fatal("Could not set permissions for files to read-only - test will likely fail.")
+ startApplication("qtcreator" + SettingsPath)
+ openQmakeProject(os.path.join(testFolder, "testfiles.pro"))
+ modifiedUnsaved = []
+ readOnlyFiles = []
+ currentFile = testModifyFile("testfiles.Sources.main\\.cpp", cppEditorStr, "{", True)
+ modifiedUnsaved.append(currentFile)
+ readOnlyFiles.append(currentFile)
+ currentFile = testModifyFile("testfiles.testfiles\\.pro", proEditorStr, "CONFIG -= qt", False)
+ modifiedUnsaved.append(currentFile)
+ currentFile = testModifyFile("testfiles.Headers.testfile\\.h", cppEditorStr, "{", True)
+ modifiedUnsaved.append(currentFile)
+ readOnlyFiles.append(currentFile)
+ invokeMenuItem("File", "Exit")
+ testSaveChangesAndMakeWritable(modifiedUnsaved, readOnlyFiles)
+
+def testModifyFile(fileName, editor, line, expectWarning):
+ readOnlyWarningStr = ("{text='<b>Warning:</b> You are changing a read-only file.' type='QLabel'"
+ " unnamed='1' window=':Qt Creator_Core::Internal::MainWindow'}")
+ simpleFName = simpleFileName(fileName)
+ test.log("Opening file '%s'" % simpleFName)
+ openDocument(fileName)
+ fileNameCombo = waitForObject(":Qt Creator_FilenameQComboBox")
+ test.compare(str(fileNameCombo.currentText), simpleFName,
+ "Verifying content of file name combo box.")
+ checkOpenDocumentsContains(simpleFName)
+ if not placeCursorToLine(editor, line):
+ return
+ type(editor, "<Return>")
+ try:
+ waitForObject(readOnlyWarningStr, 3000)
+ if expectWarning:
+ test.passes("Warning about changing a read-only file appeared.")
+ else:
+ test.fail("Warning about changing a read-only file appeared, although changing "
+ "a writable file. (%s)" % simpleFName)
+ except:
+ if expectWarning:
+ test.fail("Warning about changing a read-only file missing. (%s)" % simpleFName)
+ else:
+ test.passes("Warning about changing a read-only file does not come up "
+ "(changing a writable file).")
+ test.compare(str(fileNameCombo.currentText), "%s*" % simpleFName,
+ "Verifying content of file name combo box.")
+ return checkOpenDocumentsContains("%s*" % simpleFName)
+
+def testSaveChangesAndMakeWritable(modifiedFiles, readOnlyFiles):
+ saveDlgStr = ("{name='Core__Internal__SaveItemsDialog' type='Core::Internal::SaveItemsDialog' "
+ "visible='1' windowTitle='Save Changes'}")
+ readOnlyMBoxStr = ("{type='QMessageBox' unnamed='1' visible='1' text~='The file <i>.+</i> "
+ "is read only\.'}")
+ cannotResetStr = ("{text='Cannot set permissions to writable.' type='QMessageBox' "
+ "unnamed='1' visible='1'}")
+ filePattern = re.compile('The file <i>(.+)</i> is read only\.')
+ try:
+ waitForObject(saveDlgStr)
+ except:
+ test.fail("Save Changes dialog did not come up, but was expected to appear.")
+ return
+ treeWidget = waitForObject("{name='treeWidget' type='QTreeWidget' visible='1' window=%s}"
+ % saveDlgStr)
+ checkUnsavedChangesContains(treeWidget.model(), modifiedFiles)
+ clickButton(waitForObject("{text='Save All' type='QPushButton' unnamed='1' visible='1' "
+ "window=%s}" % saveDlgStr))
+ # iterating over the readOnlyFiles (order is unpredictable)
+ for i in range(len(readOnlyFiles)):
+ try:
+ currentText = str(waitForObject(readOnlyMBoxStr, 3000).text)
+ currentFile = filePattern.match(currentText).group(1)
+ clickButton(waitForObject("{text='Make Writable' type='QPushButton' unnamed='1' "
+ "visible='1' window=%s}" % readOnlyMBoxStr))
+ try:
+ waitForObject(cannotResetStr, 3000)
+ # should not be possible
+ test.fail("Could not reset file '%s' to writable state." % currentFile)
+ clickButton("{text='OK' type='QPushButton' window=%s}" % cannotResetStr)
+ except:
+ if isWritable(currentFile):
+ test.passes("File '%s' resetted to writable state and saved." % currentFile)
+ if currentFile in readOnlyFiles:
+ readOnlyFiles.remove(currentFile)
+ else:
+ test.fatal("Creator states file '%s' is read-only - but supposed to be "
+ "writable." % currentFile)
+ else:
+ test.fail("Creator states file '%s' had been made writable - "
+ "but it's still read only." % currentFile)
+ except:
+ test.fail("Missing QMessageBox about a read only file.")
+ if not test.verify(len(readOnlyFiles) == 0,
+ "Checking whether all files have been handled correctly."):
+ try:
+ invokeMenuItem("File", "Exit")
+ waitForObject(saveDlgStr)
+ clickButton(waitForObject("{text='Do not Save' type='QPushButton' unnamed='1' "
+ "visible='1' window=%s}" % saveDlgStr))
+ except:
+ pass
+
+def checkOpenDocumentsContains(itemName):
+ openDocsTreeViewModel = waitForObject(":OpenDocuments_QTreeView").model()
+ result = None
+ found = False
+ for index in dumpIndices(openDocsTreeViewModel):
+ if str(index.data()) == itemName:
+ found = True
+ result = index.toolTip
+ break
+ test.verify(found, "Check whether 'Open Documents' contains '%s'" % itemName)
+ return result
+
+def checkUnsavedChangesContains(model, filePaths):
+ foundItems = map(lambda x: os.path.join(x[0], x[1]), zip(dumpItems(model,column=1),
+ dumpItems(model, column=0)))
+ test.compare(set(foundItems), set(filePaths),
+ "Verifying whether modified (unsaved) files do match expected.")
+
+def simpleFileName(navigatorFileName):
+ return ".".join(navigatorFileName.split(".")[-2:]).replace("\\","")
+
+def cleanup():
+ global testFolder
+ if testFolder:
+ changeFilePermissions(testFolder, True, True, "testfiles.pro")