add forgotten files

This commit is contained in:
Philip Ridout 2017-08-07 22:01:16 +01:00
parent 8eb207b67c
commit c4eedc6dca
2 changed files with 304 additions and 0 deletions

116
openlp/core/ui/lib/filedialog.py Executable file
View File

@ -0,0 +1,116 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
""" Patch the QFileDialog so it accepts and returns Path objects"""
from functools import wraps
from pathlib import Path
from PyQt5 import QtWidgets
from openlp.core.common.path import path_to_str, str_to_path
from openlp.core.lib import replace_params
class FileDialog(QtWidgets.QFileDialog):
@classmethod
@wraps(QtWidgets.QFileDialog.getExistingDirectory)
def getExistingDirectory(cls, *args, **kwargs):
"""
Reimplement `getExistingDirectory` so that it can be called with, and return Path objects
:type parent: QtWidgets.QWidget or None
:type caption: str
:type directory: pathlib.Path
:type options: QtWidgets.QFileDialog.Options
:rtype: tuple[Path, str]
"""
args, kwargs = replace_params(args, kwargs, ((2, 'directory', path_to_str),))
return_value = super().getExistingDirectory(*args, **kwargs)
# getExistingDirectory returns a str that represents the path. The string is empty if the user cancels the
# dialog.
return str_to_path(return_value)
@classmethod
@wraps(QtWidgets.QFileDialog.getOpenFileName)
def getOpenFileName(cls, *args, **kwargs):
"""
Reimplement `getOpenFileName` so that it can be called with, and return Path objects
:type parent: QtWidgets.QWidget or None
:type caption: str
:type directory: pathlib.Path
:type filter: str
:type initialFilter: str
:type options: QtWidgets.QFileDialog.Options
:rtype: tuple[Path, str]
"""
args, kwargs = replace_params(args, kwargs, ((2, 'directory', path_to_str),))
file_name, selected_filter = super().getOpenFileName(*args, **kwargs)
# getOpenFileName returns a tuple. The first item is a str that represents the path. The string is empty if
# the user cancels the dialog.
return str_to_path(file_name), selected_filter
@classmethod
def getOpenFileNames(cls, *args, **kwargs):
"""
Reimplement `getOpenFileNames` so that it can be called with, and return Path objects
:type parent: QtWidgets.QWidget or None
:type caption: str
:type directory: pathlib.Path
:type filter: str
:type initialFilter: str
:type options: QtWidgets.QFileDialog.Options
:rtype: tuple[list[Path], str]
"""
args, kwargs = replace_params(args, kwargs, ((2, 'directory', path_to_str),))
file_names, selected_filter = super().getOpenFileNames(*args, **kwargs)
# getSaveFileName returns a tuple. The first item is a list of str's that represents the path. The list is
# empty if the user cancels the dialog.
paths = [str_to_path(path) for path in file_names]
return paths, selected_filter
@classmethod
def getSaveFileName(cls, *args, **kwargs):
"""
Reimplement `getSaveFileName` so that it can be called with, and return Path objects
:type parent: QtWidgets.QWidget or None
:type caption: str
:type directory: pathlib.Path
:type filter: str
:type initialFilter: str
:type options: QtWidgets.QFileDialog.Options
:rtype: tuple[Path or None, str]
"""
args, kwargs = replace_params(args, kwargs, ((2, 'directory', path_to_str),))
file_name, selected_filter = super().getSaveFileName(*args, **kwargs)
# getSaveFileName returns a tuple. The first item represents the path as a str. The string is empty if the user
# cancels the dialog.
return str_to_path(file_name), selected_filter

View File

@ -0,0 +1,188 @@
import os
from unittest import TestCase
from unittest.mock import patch
from pathlib import Path
from PyQt5 import QtWidgets
from openlp.core.ui.lib.filedialog import FileDialog
class TestFileDialogPatches(TestCase):
"""
Tests for the :mod:`openlp.core.ui.lib.filedialogpatches` module
"""
def test_file_dialog(self):
"""
Test that the :class:`FileDialog` instantiates correctly
"""
# GIVEN: The FileDialog class
# WHEN: Creating an instance
instance = FileDialog()
# THEN: The instance should be an instance of QFileDialog
self.assertIsInstance(instance, QtWidgets.QFileDialog)
def test_get_existing_directory_user_abort(self):
"""
Test that `getExistingDirectory` handles the case when the user cancels the dialog
"""
# GIVEN: FileDialog with a mocked QDialog.getExistingDirectory method
# WHEN: Calling FileDialog.getExistingDirectory and the user cancels the dialog returns a empty string
with patch('PyQt5.QtWidgets.QFileDialog.getExistingDirectory', return_value=''):
result = FileDialog.getExistingDirectory()
# THEN: The result should be None
self.assertEqual(result, None)
def test_get_existing_directory_user_accepts(self):
"""
Test that `getExistingDirectory` handles the case when the user accepts the dialog
"""
# GIVEN: FileDialog with a mocked QDialog.getExistingDirectory method
# WHEN: Calling FileDialog.getExistingDirectory, the user chooses a file and accepts the dialog (it returns a
# string pointing to the directory)
with patch('PyQt5.QtWidgets.QFileDialog.getExistingDirectory', return_value=os.path.join('test', 'dir')):
result = FileDialog.getExistingDirectory()
# THEN: getExistingDirectory() should return a Path object pointing to the chosen file
self.assertEqual(result, Path('test', 'dir'))
def test_get_existing_directory_param_order(self):
"""
Test that `getExistingDirectory` passes the parameters to `QFileDialog.getExistingDirectory` in the correct
order
"""
# GIVEN: FileDialog
with patch('openlp.core.ui.lib.filedialog.QtWidgets.QFileDialog.getExistingDirectory', return_value='') \
as mocked_get_existing_directory:
# WHEN: Calling the getExistingDirectory method with all parameters set
FileDialog.getExistingDirectory('Parent', 'Caption', Path('test', 'dir'), 'Options')
# THEN: The `QFileDialog.getExistingDirectory` should have been called with the parameters in the correct
# order
mocked_get_existing_directory.assert_called_once_with('Parent', 'Caption', os.path.join('test', 'dir'),
'Options')
def test_get_open_file_name_user_abort(self):
"""
Test that `getOpenFileName` handles the case when the user cancels the dialog
"""
# GIVEN: FileDialog with a mocked QDialog.getOpenFileName method
# WHEN: Calling FileDialog.getOpenFileName and the user cancels the dialog (it returns a tuple with the first
# value set as an empty string)
with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileName', return_value=('', '')):
result = FileDialog.getOpenFileName()
# THEN: First value should be None
self.assertEqual(result[0], None)
def test_get_open_file_name_user_accepts(self):
"""
Test that `getOpenFileName` handles the case when the user accepts the dialog
"""
# GIVEN: FileDialog with a mocked QDialog.getOpenFileName method
# WHEN: Calling FileDialog.getOpenFileName, the user chooses a file and accepts the dialog (it returns a
# tuple with the first value set as an string pointing to the file)
with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileName',
return_value=(os.path.join('test', 'chosen.file'), '')):
result = FileDialog.getOpenFileName()
# THEN: getOpenFileName() should return a tuple with the first value set to a Path object pointing to the
# chosen file
self.assertEqual(result[0], Path('test', 'chosen.file'))
def test_get_open_file_name_selected_filter(self):
"""
Test that `getOpenFileName` does not modify the selectedFilter as returned by `QFileDialog.getOpenFileName`
"""
# GIVEN: FileDialog with a mocked QDialog.get_save_file_name method
# WHEN: Calling FileDialog.getOpenFileName, and `QFileDialog.getOpenFileName` returns a known `selectedFilter`
with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileName', return_value=('', 'selected filter')):
result = FileDialog.getOpenFileName()
# THEN: getOpenFileName() should return a tuple with the second value set to a the selected filter
self.assertEqual(result[1], 'selected filter')
def test_get_open_file_names_user_abort(self):
"""
Test that `getOpenFileNames` handles the case when the user cancels the dialog
"""
# GIVEN: FileDialog with a mocked QDialog.getOpenFileNames method
# WHEN: Calling FileDialog.getOpenFileNames and the user cancels the dialog (it returns a tuple with the first
# value set as an empty list)
with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileNames', return_value=([], '')):
result = FileDialog.getOpenFileNames()
# THEN: First value should be an empty list
self.assertEqual(result[0], [])
def test_get_open_file_names_user_accepts(self):
"""
Test that `getOpenFileNames` handles the case when the user accepts the dialog
"""
# GIVEN: FileDialog with a mocked QDialog.getOpenFileNames method
# WHEN: Calling FileDialog.getOpenFileNames, the user chooses some files and accepts the dialog (it returns a
# tuple with the first value set as a list of strings pointing to the file)
with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileNames',
return_value=([os.path.join('test', 'chosen.file1'), os.path.join('test', 'chosen.file2')], '')):
result = FileDialog.getOpenFileNames()
# THEN: getOpenFileNames() should return a tuple with the first value set to a list of Path objects pointing
# to the chosen file
self.assertEqual(result[0], [Path('test', 'chosen.file1'), Path('test', 'chosen.file2')])
def test_get_open_file_names_selected_filter(self):
"""
Test that `getOpenFileNames` does not modify the selectedFilter as returned by `QFileDialog.getOpenFileNames`
"""
# GIVEN: FileDialog with a mocked QDialog.getOpenFileNames method
# WHEN: Calling FileDialog.getOpenFileNames, and `QFileDialog.getOpenFileNames` returns a known
# `selectedFilter`
with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileNames', return_value=([], 'selected filter')):
result = FileDialog.getOpenFileNames()
# THEN: getOpenFileNames() should return a tuple with the second value set to a the selected filter
self.assertEqual(result[1], 'selected filter')
def test_get_save_file_name_user_abort(self):
"""
Test that `getSaveFileName` handles the case when the user cancels the dialog
"""
# GIVEN: FileDialog with a mocked QDialog.get_save_file_name method
# WHEN: Calling FileDialog.getSaveFileName and the user cancels the dialog (it returns a tuple with the first
# value set as an empty string)
with patch('PyQt5.QtWidgets.QFileDialog.getSaveFileName', return_value=('', '')):
result = FileDialog.getSaveFileName()
# THEN: First value should be None
self.assertEqual(result[0], None)
def test_get_save_file_name_user_accepts(self):
"""
Test that `getSaveFileName` handles the case when the user accepts the dialog
"""
# GIVEN: FileDialog with a mocked QDialog.getSaveFileName method
# WHEN: Calling FileDialog.getSaveFileName, the user chooses a file and accepts the dialog (it returns a
# tuple with the first value set as an string pointing to the file)
with patch('PyQt5.QtWidgets.QFileDialog.getSaveFileName',
return_value=(os.path.join('test', 'chosen.file'), '')):
result = FileDialog.getSaveFileName()
# THEN: getSaveFileName() should return a tuple with the first value set to a Path object pointing to the
# chosen file
self.assertEqual(result[0], Path('test', 'chosen.file'))
def test_get_save_file_name_selected_filter(self):
"""
Test that `getSaveFileName` does not modify the selectedFilter as returned by `QFileDialog.getSaveFileName`
"""
# GIVEN: FileDialog with a mocked QDialog.get_save_file_name method
# WHEN: Calling FileDialog.getSaveFileName, and `QFileDialog.getSaveFileName` returns a known `selectedFilter`
with patch('PyQt5.QtWidgets.QFileDialog.getSaveFileName', return_value=('', 'selected filter')):
result = FileDialog.getSaveFileName()
# THEN: getSaveFileName() should return a tuple with the second value set to a the selected filter
self.assertEqual(result[1], 'selected filter')