Initial github release
This commit is contained in:
220
tests/test_command_history.py
Normal file
220
tests/test_command_history.py
Normal file
@@ -0,0 +1,220 @@
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from PyQt5.QtWidgets import QApplication, QLabel, QListWidget
|
||||
|
||||
from pygadmin.widgets.command_history import CommandHistoryDialog
|
||||
from pygadmin.command_history_store import global_command_history_store
|
||||
from pygadmin.configurator import global_app_configurator
|
||||
|
||||
|
||||
class TestCommandHistoryDialogMethods(unittest.TestCase):
|
||||
"""
|
||||
Test the functionality and methods of the command history dialog.
|
||||
"""
|
||||
|
||||
def test_empty_dialog(self):
|
||||
"""
|
||||
Test the dialog without data in the command history store, so the dialog shows a warning about the empty
|
||||
history.
|
||||
"""
|
||||
|
||||
# Get the current command history for saving it during the testing of the method. Later, the current command
|
||||
# history is saved again in the command history store.
|
||||
current_command_history = global_command_history_store.get_command_history_from_yaml_file()
|
||||
|
||||
# Delete all commands from the history, so the history is empty. As a result, the dialog should show the warning
|
||||
# ui.
|
||||
global_command_history_store.delete_all_commands_from_history()
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a command history dialog.
|
||||
command_history_dialog = CommandHistoryDialog()
|
||||
|
||||
# Check for the existence and correct instance of the empty label.
|
||||
assert isinstance(command_history_dialog.empty_label, QLabel)
|
||||
|
||||
# Set the list with the data about the last commands as command history list.
|
||||
global_command_history_store.command_history_list = current_command_history
|
||||
# Save the list in the yaml file again.
|
||||
global_command_history_store.commit_current_list_to_yaml()
|
||||
|
||||
def test_initial_attributes(self):
|
||||
"""
|
||||
Test the initial attributes of the dialog (with an existing command history).
|
||||
"""
|
||||
|
||||
# Define a dictionary with a command and the information about it, so there is at least one command in the
|
||||
# command history.
|
||||
command_dictionary = {"Command": "SELECT * FROM test;",
|
||||
"Identifier": "testuser@testserver:5432/testdb",
|
||||
"Time": "2020-10-01 11:53:59",
|
||||
"Result": [["column 0", "column 1", "column 2"], ["row A", "row B", "row C"],
|
||||
["row D", "row E", "row F"]]}
|
||||
|
||||
global_command_history_store.save_command_history_in_yaml_file(command_dictionary)
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a command history dialog.
|
||||
command_history_dialog = CommandHistoryDialog()
|
||||
|
||||
# Check for the GUI attributes, so the QListWidget and the QLabels.
|
||||
assert isinstance(command_history_dialog.history_list_widget, QListWidget)
|
||||
assert isinstance(command_history_dialog.command_label, QLabel)
|
||||
assert isinstance(command_history_dialog.connection_identifier_label, QLabel)
|
||||
assert isinstance(command_history_dialog.date_time_label, QLabel)
|
||||
# The data list of the table model should be empty at the beginning.
|
||||
assert command_history_dialog.table_model.data_list == []
|
||||
|
||||
# Check for the existence and correct instance of the command history list.
|
||||
assert isinstance(global_command_history_store.command_history_list, list)
|
||||
|
||||
# Clean up, so the testing command is no longer part of the command history store.
|
||||
global_command_history_store.delete_command_from_history(command_dictionary)
|
||||
|
||||
def test_show_command_information_in_labels(self):
|
||||
"""
|
||||
Test the method for showing the command information in the given labels and the table view, so the data list of
|
||||
the table model is checked.
|
||||
"""
|
||||
|
||||
# Define a dictionary with a command and the information about it, so there is at least one command in the
|
||||
# command history.
|
||||
command_dictionary = {"Command": "SELECT * FROM test;",
|
||||
"Identifier": "testuser@testserver:5432/testdb",
|
||||
"Time": "2019-05-04 13:37:00",
|
||||
"Result": [["column 0", "column 1", "column 2"], ["row A", "row B", "row C"],
|
||||
["row D", "row E", "row F"]]}
|
||||
|
||||
global_command_history_store.save_command_history_in_yaml_file(command_dictionary)
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a command history dialog.
|
||||
command_history_dialog = CommandHistoryDialog()
|
||||
|
||||
# Define an index for the last item for iterating. This index is used later for setting the current row as
|
||||
# selection.
|
||||
index_of_last_item = 0
|
||||
# Define an identifier text for finding the command of the previous defined command dictionary.
|
||||
command_identifier_text = "{}\n{}".format(command_dictionary["Command"], command_dictionary["Time"])
|
||||
|
||||
# Iterate over every item in the list widget.
|
||||
for item_count in range(command_history_dialog.history_list_widget.count()):
|
||||
# If the text of the current item is the same as in the command identifier text, use the current item count
|
||||
# as index of the last item.
|
||||
if command_identifier_text == command_history_dialog.history_list_widget.item(item_count).text():
|
||||
index_of_last_item = item_count
|
||||
# End the loop, because further iterating is not necessary. There is already a match.
|
||||
break
|
||||
|
||||
# Set the index of the last item as current row.
|
||||
command_history_dialog.history_list_widget.setCurrentRow(index_of_last_item)
|
||||
|
||||
# Check the labels and the data list of the tree model for the correct list.
|
||||
assert command_history_dialog.command_label.text() == command_dictionary["Command"]
|
||||
assert command_history_dialog.connection_identifier_label.text() == command_dictionary["Identifier"]
|
||||
assert command_history_dialog.date_time_label.text() == command_dictionary["Time"]
|
||||
assert command_history_dialog.table_model.data_list == command_dictionary["Result"]
|
||||
|
||||
# Clean up, so the testing command is no longer part of the command history store.
|
||||
global_command_history_store.delete_command_from_history(command_dictionary)
|
||||
|
||||
def test_get_command_dictionary_of_current_selected_identifier(self):
|
||||
"""
|
||||
Test the method for getting the command dictionary of the current selected identifier in the history list
|
||||
widget.
|
||||
"""
|
||||
|
||||
# Define a dictionary with a command and the information about it, so there is at least one command in the
|
||||
# command history.
|
||||
command_dictionary = {"Command": "SELECT * FROM test;",
|
||||
"Identifier": "testuser@testserver:5432/testdb",
|
||||
"Time": "2019-05-04 13:37:00",
|
||||
"Result": [["column 0", "column 1", "column 2"], ["row A", "row B", "row C"],
|
||||
["row D", "row E", "row F"]]}
|
||||
|
||||
global_command_history_store.save_command_history_in_yaml_file(command_dictionary)
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a command history dialog.
|
||||
command_history_dialog = CommandHistoryDialog()
|
||||
|
||||
# Define an index for the last item for iterating. This index is used later for setting the current row as
|
||||
# selection.
|
||||
index_of_last_item = 0
|
||||
# Define an identifier text for finding the command of the previous defined command dictionary.
|
||||
command_identifier_text = "{}\n{}".format(command_dictionary["Command"], command_dictionary["Time"])
|
||||
|
||||
# Iterate over every item in the list widget.
|
||||
for item_count in range(command_history_dialog.history_list_widget.count()):
|
||||
# If the text of the current item is the same as in the command identifier text, use the current item count
|
||||
# as index of the last item.
|
||||
if command_identifier_text == command_history_dialog.history_list_widget.item(item_count).text():
|
||||
index_of_last_item = item_count
|
||||
# End the loop, because further iterating is not necessary. There is already a match.
|
||||
break
|
||||
|
||||
# Set the index of the last item as current row.
|
||||
command_history_dialog.history_list_widget.setCurrentRow(index_of_last_item)
|
||||
|
||||
# Get the command dictionary of the selected command.
|
||||
selected_command_dictionary = command_history_dialog.get_command_dictionary_of_current_selected_identifier()
|
||||
|
||||
# The dictionary of the selected item should be the command dictionary.
|
||||
assert selected_command_dictionary == command_dictionary
|
||||
|
||||
# Clean up, so the testing command is no longer part of the command history store.
|
||||
global_command_history_store.delete_command_from_history(command_dictionary)
|
||||
|
||||
def test_save_current_command_limit(self):
|
||||
"""
|
||||
Test the function for saving the current command limit with the input in the line edit.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a command history dialog.
|
||||
command_history_dialog = CommandHistoryDialog()
|
||||
|
||||
# Define a new command limit.
|
||||
new_command_limit = 15
|
||||
|
||||
# Set the command limit as string as text of the command limit line edit.
|
||||
command_history_dialog.command_limit_line_edit.setText(str(new_command_limit))
|
||||
# Save the current command limit.
|
||||
command_history_dialog.save_current_command_limit()
|
||||
|
||||
# The command limit in the app configurator should now be the pre-defined new command limit.
|
||||
assert global_app_configurator.get_single_configuration("command_limit") == new_command_limit
|
||||
|
||||
def test_check_valid_command_limit(self):
|
||||
"""
|
||||
Test the function for checking a valid comment limit in the command limit line edit.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a command history dialog.
|
||||
command_history_dialog = CommandHistoryDialog()
|
||||
|
||||
# A normal text, which is not equivalent to None and cannot be casted to an integer, should be invalid.
|
||||
command_history_dialog.command_limit_line_edit.setText("test")
|
||||
assert command_history_dialog.check_valid_command_limit() is False
|
||||
|
||||
# -1 as text can be casted to an integer, but the command limit needs to be larger than 0.
|
||||
command_history_dialog.command_limit_line_edit.setText("-1")
|
||||
assert command_history_dialog.check_valid_command_limit() is False
|
||||
|
||||
# The text None should be accepted.
|
||||
command_history_dialog.command_limit_line_edit.setText("None")
|
||||
assert command_history_dialog.check_valid_command_limit() is True
|
||||
|
||||
# The text 42 can be casted to a valid integer value.
|
||||
command_history_dialog.command_limit_line_edit.setText("42")
|
||||
assert command_history_dialog.check_valid_command_limit() is True
|
||||
|
||||
|
169
tests/test_command_history_store.py
Normal file
169
tests/test_command_history_store.py
Normal file
@@ -0,0 +1,169 @@
|
||||
import unittest
|
||||
import os
|
||||
|
||||
from pygadmin.command_history_store import global_command_history_store
|
||||
from pygadmin.configurator import global_app_configurator
|
||||
|
||||
|
||||
class TestCommandHistoryStoreMethods(unittest.TestCase):
|
||||
"""
|
||||
Test the command history store with its method and its behavior.
|
||||
"""
|
||||
|
||||
def test_path_of_command_history_file(self):
|
||||
"""
|
||||
Check for the existence of the yaml file, which stores the command history.
|
||||
"""
|
||||
|
||||
assert os.path.exists(global_command_history_store.yaml_command_history_file)
|
||||
|
||||
def test_command_history_list(self):
|
||||
"""
|
||||
Test the existence and the correct type of the command history list.
|
||||
"""
|
||||
|
||||
assert isinstance(global_command_history_store.command_history_list, list)
|
||||
|
||||
def test_get_command_history_from_yaml_file(self):
|
||||
"""
|
||||
Test the behavior of the method for getting the current command history from the yaml file.
|
||||
"""
|
||||
|
||||
# Get the current list.
|
||||
command_history_list = global_command_history_store.get_command_history_from_yaml_file()
|
||||
# The result of the method should be the current data list of the command history store.
|
||||
assert command_history_list == global_command_history_store.command_history_list
|
||||
|
||||
def test_commit_current_list_to_yaml(self):
|
||||
"""
|
||||
Test the correct commit of the current list to the yaml file.
|
||||
"""
|
||||
|
||||
# Ensure the correct load of all previous commands in the history.
|
||||
global_command_history_store.get_command_history_from_yaml_file()
|
||||
# The result of committing should be True for a success.
|
||||
assert global_command_history_store.commit_current_list_to_yaml() is True
|
||||
|
||||
def test_save_command_history_in_yaml_file(self):
|
||||
"""
|
||||
Test the function for saving one specific command in the command history.
|
||||
"""
|
||||
|
||||
# Define a dictionary with a command and the information about it.
|
||||
command_dictionary = {"Command": "SELECT * FROM test;",
|
||||
"Identifier": "testuser@testserver:5432/testdb",
|
||||
"Time": "2020-10-01 11:53:59",
|
||||
"Result": [["column 0", "column 1", "column 2"], ["row A", "row B", "row C"],
|
||||
["row D", "row E", "row F"]]}
|
||||
|
||||
# Save the command dictionary in the yaml file.
|
||||
global_command_history_store.save_command_history_in_yaml_file(command_dictionary)
|
||||
# Now the dictionary should be part of the command history list.
|
||||
assert command_dictionary in global_command_history_store.command_history_list
|
||||
|
||||
# Clean up, so the testing command is no longer part of the command history store.
|
||||
global_command_history_store.delete_command_from_history(command_dictionary)
|
||||
|
||||
def test_delete_command_from_history(self):
|
||||
"""
|
||||
Test the deletion of a command from the history.
|
||||
"""
|
||||
|
||||
# Define a dictionary with a command and the information about it.
|
||||
command_dictionary = {"Command": "SELECT * FROM test;",
|
||||
"Identifier": "testuser@testserver:5432/testdb",
|
||||
"Time": "2020-10-01 11:53:59",
|
||||
"Result": [["column 0", "column 1", "column 2"], ["row A", "row B", "row C"],
|
||||
["row D", "row E", "row F"]]}
|
||||
|
||||
# Save the command dictionary in the yaml file.
|
||||
global_command_history_store.save_command_history_in_yaml_file(command_dictionary)
|
||||
|
||||
# The deletion of the dictionary should return True as a success.
|
||||
assert global_command_history_store.delete_command_from_history(command_dictionary) is True
|
||||
# A second try with the same dictionary should return False, because the dictionary is already deleted and can
|
||||
# not be found.
|
||||
assert global_command_history_store.delete_command_from_history(command_dictionary) is False
|
||||
|
||||
def test_delete_all_commands_from_history(self):
|
||||
"""
|
||||
Test the deletion of the complete history.
|
||||
"""
|
||||
|
||||
# Get the current command history for saving it again later.
|
||||
current_command_history = global_command_history_store.get_command_history_from_yaml_file()
|
||||
|
||||
# The deletion of the whole history should be successful.
|
||||
assert global_command_history_store.delete_all_commands_from_history() is True
|
||||
assert global_command_history_store.command_history_list == []
|
||||
|
||||
# Set the previous saved list as command history list for restoring the correct list.
|
||||
global_command_history_store.command_history_list = current_command_history
|
||||
# Save the correct list in the yaml file.
|
||||
global_command_history_store.commit_current_list_to_yaml()
|
||||
|
||||
def test_get_new_command_limit(self):
|
||||
"""
|
||||
Test the method for getting the new command limit in the command history store.
|
||||
"""
|
||||
|
||||
# Define a command limit.
|
||||
command_limit = 100
|
||||
# Set the command limit in the global app configurator.
|
||||
global_app_configurator.set_single_configuration("command_limit", command_limit)
|
||||
global_app_configurator.save_configuration_data()
|
||||
|
||||
# Get the new command limit as attribute of the class.
|
||||
global_command_history_store.get_new_command_limit()
|
||||
|
||||
# The command limit of the global history store should be the command limit, which was set before.
|
||||
assert global_command_history_store.command_limit == command_limit
|
||||
|
||||
def test_adjust_saved_history_to_new_command_limit(self):
|
||||
"""
|
||||
Test the method for adjusting an existing list of commands in the history to a new command limit.
|
||||
"""
|
||||
|
||||
# Define a previous command limit.
|
||||
old_command_limit = 100
|
||||
# Set the command limit in the global app configurator.
|
||||
global_app_configurator.set_single_configuration("command_limit", old_command_limit)
|
||||
global_app_configurator.save_configuration_data()
|
||||
|
||||
# Define a new command limit.
|
||||
command_limit = 10
|
||||
|
||||
# Add new command dictionaries to the command history.
|
||||
for command_number in range(command_limit + 2):
|
||||
# Define a unique command dictionary.
|
||||
command_dictionary = {"Command": "{}".format(command_number),
|
||||
"Identifier": "testuser@testserver:5432/testdb",
|
||||
"Time": "2020-10-01 11:53:{}".format(command_number),
|
||||
"Result": [["column 0", "column 1", "column 2"], ["row A", "row B", "row C"],
|
||||
["row D", "row E", "row F"]]}
|
||||
|
||||
# Save the unique command dictionary in the command history store.
|
||||
global_command_history_store.save_command_history_in_yaml_file(command_dictionary)
|
||||
|
||||
# Set the command limit in the global app configurator.
|
||||
global_app_configurator.set_single_configuration("command_limit", command_limit)
|
||||
global_app_configurator.save_configuration_data()
|
||||
|
||||
# Use the function for adjusting the saved history to the new command list and commit the new list to the yaml
|
||||
# file.
|
||||
global_command_history_store.adjust_saved_history_to_new_command_limit()
|
||||
global_command_history_store.commit_current_list_to_yaml()
|
||||
|
||||
# The length of the list should be the command limit.
|
||||
assert len(global_command_history_store.command_history_list) == command_limit
|
||||
|
||||
# Define a test command dictionary. This dictionary was inserted before, but it was too old, so it should be
|
||||
# deleted.
|
||||
test_command_dictionary = {"Command": "1",
|
||||
"Identifier": "testuser@testserver:5432/testdb",
|
||||
"Time": "2020-10-01 11:53:1",
|
||||
"Result": [["column 0", "column 1", "column 2"], ["row A", "row B", "row C"],
|
||||
["row D", "row E", "row F"]]}
|
||||
|
||||
# The test dictionary should not be part of the command history list, because it is deleted.
|
||||
assert test_command_dictionary not in global_command_history_store.command_history_list
|
107
tests/test_configuration_settings.py
Normal file
107
tests/test_configuration_settings.py
Normal file
@@ -0,0 +1,107 @@
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
from PyQt5.QtWidgets import QApplication, QDialog, QCheckBox, QLineEdit
|
||||
|
||||
from pygadmin.configurator import global_app_configurator
|
||||
from pygadmin.widgets.configuration_settings import ConfigurationSettingsDialog
|
||||
|
||||
|
||||
class TestConfigurationSettingsDialogMethods(unittest.TestCase):
|
||||
"""
|
||||
Test the functionality and methods of the configuration settings dialog.
|
||||
"""
|
||||
|
||||
def test_initial_attributes(self):
|
||||
"""
|
||||
Test the correct class and the initial attributes of the configuration settings dialog.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an dialog.
|
||||
configuration_settings_dialog = ConfigurationSettingsDialog()
|
||||
# Check the correct instance.
|
||||
assert isinstance(configuration_settings_dialog, QDialog)
|
||||
# Check for the correct instance of the configuration dictionary.
|
||||
assert isinstance(configuration_settings_dialog.configuration_dictionary, dict)
|
||||
|
||||
def test_save_current_configuration(self):
|
||||
"""
|
||||
Test the save of the current configuration: Check the text or check box status of the GUI elements and their
|
||||
correct save in the dictionary.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a dialog.
|
||||
configuration_settings_dialog = ConfigurationSettingsDialog()
|
||||
|
||||
# The function should return True for a success.
|
||||
assert configuration_settings_dialog.save_current_configuration() is True
|
||||
|
||||
# Check the correct save of every user input.
|
||||
for description, gui_elements in configuration_settings_dialog.configuration_dictionary.items():
|
||||
# The dialog shows the configurations in a more readable version.
|
||||
description = description.replace(" ", "_")
|
||||
# Get the current configuration.
|
||||
configuration = global_app_configurator.get_single_configuration(description)
|
||||
|
||||
# The second element of gui_elements contains the element for user interaction, so this one is checked.
|
||||
user_element = gui_elements[1]
|
||||
|
||||
# Check for a QCheckBox as potential element.
|
||||
if isinstance(user_element, QCheckBox):
|
||||
# Check for the correct configuration.
|
||||
assert user_element.isChecked() == configuration
|
||||
|
||||
# Check for a QLineEdit as potential element.
|
||||
elif isinstance(user_element, QLineEdit):
|
||||
# Check for the correct configuration.
|
||||
assert configuration == user_element.text()
|
||||
|
||||
def test_save_current_configuration_and_close(self):
|
||||
"""
|
||||
Test the method for saving the current configuration and close after that.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a dialog.
|
||||
configuration_settings_dialog = ConfigurationSettingsDialog()
|
||||
# Ensure a visible dialog.
|
||||
assert configuration_settings_dialog.isVisible() is True
|
||||
# Save the configuration and close the dialog.
|
||||
configuration_settings_dialog.save_current_configuration_and_close()
|
||||
# The dialog should be invisible after a close.
|
||||
assert configuration_settings_dialog.isVisible() is False
|
||||
|
||||
def test_check_for_unsaved_configurations(self):
|
||||
"""
|
||||
Test the method for checking for unsaved configurations.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a dialog.
|
||||
configuration_settings_dialog = ConfigurationSettingsDialog()
|
||||
|
||||
# At this moment, all configurations are saved/freshly initialized.
|
||||
assert configuration_settings_dialog.check_for_unsaved_configuration() is False
|
||||
|
||||
# Change one existing element, so there are unsaved configurations.
|
||||
for gui_elements in configuration_settings_dialog.configuration_dictionary.values():
|
||||
# The second element is the element for user interaction.
|
||||
user_element = gui_elements[1]
|
||||
|
||||
# Check for a checkbox.
|
||||
if isinstance(user_element, QCheckBox):
|
||||
# Get the current state of the checkbox.
|
||||
current_state = user_element.isChecked()
|
||||
# Reverse the state, so there is an unsaved configuration now.
|
||||
user_element.setChecked(not current_state)
|
||||
# Check for an unsaved configuration. This should be True.
|
||||
assert configuration_settings_dialog.check_for_unsaved_configuration() is True
|
||||
# Break the loop after an assertion.
|
||||
break
|
||||
|
152
tests/test_configurator.py
Normal file
152
tests/test_configurator.py
Normal file
@@ -0,0 +1,152 @@
|
||||
import unittest
|
||||
import os
|
||||
|
||||
from pygadmin.configurator import global_app_configurator
|
||||
|
||||
|
||||
class TestConfiguratorMethods(unittest.TestCase):
|
||||
"""
|
||||
Test the app configurator with its methods and behavior.
|
||||
"""
|
||||
|
||||
def test_path_of_configuration_files(self):
|
||||
"""
|
||||
Test the existence of the two file paths.
|
||||
"""
|
||||
|
||||
# Get the path for the general configuration file and test it.
|
||||
configuration_file = global_app_configurator.yaml_app_configuration_file
|
||||
assert os.path.exists(configuration_file)
|
||||
|
||||
# Get the path for the editor style configuration file and test it.
|
||||
editor_style_file = global_app_configurator.yaml_editor_style_configuration_file
|
||||
assert os.path.exists(editor_style_file)
|
||||
|
||||
def test_configuration_dictionary(self):
|
||||
"""
|
||||
Test the correct load of the configuration dictionary.
|
||||
"""
|
||||
|
||||
assert global_app_configurator.configuration_dictionary is not None
|
||||
assert isinstance(global_app_configurator.configuration_dictionary, dict)
|
||||
|
||||
def test_style_configuration_dictionary(self):
|
||||
"""
|
||||
Test the correct load of the editor style dictionary.
|
||||
"""
|
||||
|
||||
assert global_app_configurator.editor_style_dictionary is not None
|
||||
assert isinstance(global_app_configurator.editor_style_dictionary, dict)
|
||||
|
||||
def test_save_configuration_data(self):
|
||||
"""
|
||||
Test the save of all current configuration data, which should return True for a success.
|
||||
"""
|
||||
|
||||
assert global_app_configurator.save_configuration_data() is True
|
||||
|
||||
def test_save_style_data(self):
|
||||
"""
|
||||
Test the save of all current style data, which should return True for a success.
|
||||
"""
|
||||
|
||||
assert global_app_configurator.save_style_configuration_data() is True
|
||||
|
||||
def test_get_all_current_configurations(self):
|
||||
"""
|
||||
Test getting all current configurations. The result should be a dict.
|
||||
"""
|
||||
|
||||
assert isinstance(global_app_configurator.get_all_current_configurations(), dict)
|
||||
|
||||
def test_get_all_current_style_themes(self):
|
||||
"""
|
||||
Test getting all current style themes and the correct structure of the returning dictionary.
|
||||
"""
|
||||
|
||||
# Get the style dictionary.
|
||||
style_dictionary = global_app_configurator.get_all_current_color_style_themes()
|
||||
|
||||
# Test for the right instance.
|
||||
assert isinstance(style_dictionary, dict)
|
||||
|
||||
# Test every value in the dictionary for the correct instance, which should also be a dictionary.
|
||||
for value in style_dictionary.values():
|
||||
assert isinstance(value, dict)
|
||||
|
||||
def test_set_single_configuration(self):
|
||||
"""
|
||||
Set a single configuration and test for correct setting with direct access to the dictionary.
|
||||
"""
|
||||
|
||||
# Define a key and a value for testing.
|
||||
test_key = "test"
|
||||
test_value = True
|
||||
|
||||
# Set the configuration.
|
||||
global_app_configurator.set_single_configuration(test_key, test_value)
|
||||
# Get the value to the key with direct access to the dictionary.
|
||||
assert global_app_configurator.configuration_dictionary[test_key] is test_value
|
||||
|
||||
def test_get_single_configuration(self):
|
||||
"""
|
||||
Set a single configuration and test for the correct setting and getting with the method of the app configurator.
|
||||
"""
|
||||
|
||||
# Define a test key and a test value.
|
||||
test_key = "test"
|
||||
test_value = True
|
||||
|
||||
# Set the configuration.
|
||||
global_app_configurator.set_single_configuration(test_key, test_value)
|
||||
# Get the value to the key with the method of the app configurator.
|
||||
assert global_app_configurator.get_single_configuration(test_key) is test_value
|
||||
|
||||
def test_delete_configuration(self):
|
||||
"""
|
||||
Set a configuration and delete the configuration again for testing the correct deletion. Test also the case for
|
||||
a non existing configuration.
|
||||
"""
|
||||
|
||||
# Define a test key and a test value.
|
||||
test_key = "test"
|
||||
test_value = True
|
||||
|
||||
# Set the configuration.
|
||||
global_app_configurator.set_single_configuration(test_key, test_value)
|
||||
# Delete the configuration based on its key and check if the result is True for a successful deletion.
|
||||
assert global_app_configurator.delete_single_configuration(test_key) is True
|
||||
# Delete the configuration based on its key again, which should fail, so the result is False.
|
||||
assert global_app_configurator.delete_single_configuration(test_key) is False
|
||||
|
||||
def test_get_all_configurations(self):
|
||||
"""
|
||||
Test to get all components and check the correctness with direct access.
|
||||
"""
|
||||
|
||||
configurations = global_app_configurator.get_all_current_configurations()
|
||||
assert configurations == global_app_configurator.configuration_dictionary
|
||||
|
||||
def test_default_color_theme(self):
|
||||
"""
|
||||
Test to get the default color theme.
|
||||
"""
|
||||
|
||||
# Get the color theme out of the global app configurator.
|
||||
color_theme = global_app_configurator.get_single_configuration("color_theme")
|
||||
|
||||
# Proceed, if the editor style dictionary and the color theme is not None. So there are elements in the style
|
||||
# dictionary and there is a color theme.
|
||||
if global_app_configurator.editor_style_dictionary and color_theme:
|
||||
# Get the style description and the style values (as a dictionary).
|
||||
style_description, style_values = global_app_configurator.get_default_color_theme_style()
|
||||
# The first value should be the color theme,
|
||||
assert style_description == color_theme
|
||||
# The second value should contain a dictionary with the different color themes.
|
||||
assert isinstance(style_values, dict)
|
||||
|
||||
# If the color theme or the style dictionary (or both) is None or empty, the result for the default color theme
|
||||
# should also be None.
|
||||
else:
|
||||
assert global_app_configurator.get_default_color_theme_style() is None
|
||||
|
503
tests/test_connection_dialog.py
Normal file
503
tests/test_connection_dialog.py
Normal file
@@ -0,0 +1,503 @@
|
||||
import sys
|
||||
import unittest
|
||||
import keyring
|
||||
|
||||
from PyQt5.QtWidgets import QApplication, QLineEdit, QListWidgetItem
|
||||
|
||||
from pygadmin.widgets.connection_dialog import ConnectionDialogWidget
|
||||
from pygadmin.connectionstore import global_connection_store
|
||||
|
||||
|
||||
class TestConnectionDialogMethods(unittest.TestCase):
|
||||
"""
|
||||
Test the functionality and methods of the connection dialog in some essential aspects.
|
||||
"""
|
||||
|
||||
def test_initial_attributes(self):
|
||||
"""
|
||||
Test basic attributes of the class after initializing.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a dialog.
|
||||
connection_dialog = ConnectionDialogWidget()
|
||||
|
||||
# Check for the connection parameter edit dictionary, which is an essential element to the dialog.
|
||||
assert isinstance(connection_dialog.connection_parameter_edit_dictionary, dict)
|
||||
|
||||
# Check every value in the dictionary for a QLineEdit.
|
||||
for value in connection_dialog.connection_parameter_edit_dictionary.values():
|
||||
# The elements should be QLineEdits.
|
||||
assert isinstance(value, QLineEdit)
|
||||
|
||||
# The label for the status for testing the given connection should have the correct text.
|
||||
assert connection_dialog.test_given_connection_status_label.text() == "Not tested yet"
|
||||
|
||||
def test_check_for_empty_parameter_fields(self):
|
||||
"""
|
||||
Test the function for checking for empty parameter fields.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a dialog.
|
||||
connection_dialog = ConnectionDialogWidget()
|
||||
|
||||
# Get the current result for the check of empty parameter fields. It should not be a simple boolean, so it will
|
||||
# be a list.
|
||||
empty_parameter_result = connection_dialog.check_for_empty_parameter_edit_fields()
|
||||
|
||||
# The first parameter of the result list is a boolean, which should be True in this case.
|
||||
assert empty_parameter_result[0] is True
|
||||
|
||||
# Set to every edit field a value.
|
||||
for edit_field in connection_dialog.connection_parameter_edit_dictionary.values():
|
||||
edit_field.setText("42")
|
||||
|
||||
# After setting values to every edit field, there should not be an empty parameter edit field.
|
||||
assert connection_dialog.check_for_empty_parameter_edit_fields() is False
|
||||
|
||||
def test_check_for_valid_port(self):
|
||||
"""
|
||||
Test the function for checking for a valid port in the port line edit.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a dialog.
|
||||
connection_dialog = ConnectionDialogWidget()
|
||||
|
||||
# Get the port line edit.
|
||||
port_line_edit = connection_dialog.connection_parameter_edit_dictionary["Port"]
|
||||
|
||||
# Set a string, which can not be casted to an int, as text for the port.
|
||||
port_line_edit.setText("This is a triumph. I'm making a note here, huge success.")
|
||||
# The check for a valid port should be False.
|
||||
assert connection_dialog.check_for_valid_port() is False
|
||||
|
||||
# Set a string, which can be casted to an int, as text for the port. The int in this case is invalid.
|
||||
port_line_edit.setText("-42")
|
||||
# The check for a valid port should still be False.
|
||||
assert connection_dialog.check_for_valid_port() is False
|
||||
|
||||
# Set a valid and an int, which can be casted to int, as port.
|
||||
port_line_edit.setText("42")
|
||||
# The check for a valid port should now be True.
|
||||
assert connection_dialog.check_for_valid_port() is True
|
||||
|
||||
def test_check_for_changed_password(self):
|
||||
"""
|
||||
Test the method for checking for a changed password in the QLineEdit for the password compared to the password
|
||||
in the password manager.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a dialog.
|
||||
connection_dialog = ConnectionDialogWidget()
|
||||
|
||||
# Define the name of the service.
|
||||
service = "Pygadmin"
|
||||
# Define the identifier for the password
|
||||
password_identifier = "testuser@random:5432"
|
||||
# Choose a password.
|
||||
password = "unsafe"
|
||||
# Set the password in the keyring.
|
||||
keyring.set_password(service, password_identifier, password)
|
||||
|
||||
# Get the line edit for the password.
|
||||
password_line_edit = connection_dialog.connection_parameter_edit_dictionary["Password"]
|
||||
# Set the currently saved password as text.
|
||||
password_line_edit.setText(password)
|
||||
# The function for checking for a changed password should now be False.
|
||||
assert connection_dialog.check_for_changed_password(password_identifier) is False
|
||||
|
||||
# Change the text in the password line edit to another password.
|
||||
password_line_edit.setText("unsafe again")
|
||||
# Now there should be a changed password compared to the password manager, so the result should be True.
|
||||
assert connection_dialog.check_for_changed_password(password_identifier) is True
|
||||
|
||||
# Clean up, so the password identifier and the password for testing are not a part of the password manager.
|
||||
keyring.delete_password(service, password_identifier)
|
||||
|
||||
def test_set_password_with_identifier(self):
|
||||
"""
|
||||
Test the method for setting a password with its identifier.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a dialog.
|
||||
connection_dialog = ConnectionDialogWidget()
|
||||
|
||||
# Define the identifier for the password
|
||||
password_identifier = "testuser@random:5432"
|
||||
|
||||
# Get the password line edit.
|
||||
password_line_edit = connection_dialog.connection_parameter_edit_dictionary["Password"]
|
||||
# Set a text as password in the password line edit.
|
||||
password_line_edit.setText("unsafe")
|
||||
# The function for setting the password with its identifier should be True.
|
||||
assert connection_dialog.set_password_with_its_identifier(password_identifier) is True
|
||||
|
||||
# Clean up, so the password identifier and the password for testing are not a part of the password manager.
|
||||
keyring.delete_password("Pygadmin", password_identifier)
|
||||
|
||||
def test_valid_find_occurrence_in_list_widget_and_select_item(self):
|
||||
"""
|
||||
Test the method for finding the occurrence of an item in a list widget. The item should be selected after the
|
||||
call of the method. Use valid connection parameters, which are also part of the connection store.
|
||||
"""
|
||||
|
||||
# Define a connection dictionary for saving the connection data in the connection store and creating a
|
||||
# connection identifier later, so the connection is part of the list widget and can be selected.
|
||||
connection_dictionary = {"Host": "random",
|
||||
"Username": "testuser",
|
||||
"Port": 5432,
|
||||
"Database": "postgres"}
|
||||
|
||||
# Save the connection in the connection store.
|
||||
global_connection_store.save_connection_parameters_in_yaml_file(connection_dictionary)
|
||||
# Save the current connections in the connection store in the yaml file.
|
||||
global_connection_store.commit_current_list_to_yaml()
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a dialog.
|
||||
connection_dialog = ConnectionDialogWidget()
|
||||
|
||||
# Define a connection identifier for selecting it in the list widget.
|
||||
connection_identifier = "{}@{}:{}/{}".format(connection_dictionary["Username"], connection_dictionary["Host"],
|
||||
connection_dictionary["Port"], connection_dictionary["Database"])
|
||||
|
||||
# Get the item related to the connection identifier.
|
||||
item = connection_dialog.find_occurrence_in_list_widget_and_select_item(connection_identifier)
|
||||
|
||||
# The item should be a QListWidgetItem.
|
||||
assert isinstance(item, QListWidgetItem)
|
||||
# The text of the item should be the connection identifier.
|
||||
assert item.text() == connection_identifier
|
||||
|
||||
# Get the list of selected items.
|
||||
selected_items = connection_dialog.connection_parameters_list_widget.selectedItems()
|
||||
# Only one item should be selected, so the list should contain only one element.
|
||||
assert len(selected_items) == 1
|
||||
|
||||
# Get the selected item.
|
||||
selected_item = selected_items[0]
|
||||
# The selected item should be the item, which is returned by the function.
|
||||
assert selected_item == item
|
||||
|
||||
# Clean up, so the test connection is no longer part of the connection store.
|
||||
global_connection_store.delete_connection(connection_dictionary)
|
||||
global_connection_store.commit_current_list_to_yaml()
|
||||
|
||||
def test_invalid_find_occurrence_in_list_widget_and_select_item(self):
|
||||
"""
|
||||
Test the method for finding the occurrence of an item in a list widget. Use invalid connection parameters for
|
||||
testing the error case, so the connection identifier is not based on existing connection parameters in the
|
||||
connection store.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a dialog.
|
||||
connection_dialog = ConnectionDialogWidget()
|
||||
|
||||
# Get a non existing item in the list widget.
|
||||
item = connection_dialog.find_occurrence_in_list_widget_and_select_item(None)
|
||||
# The item should be None.
|
||||
assert item is None
|
||||
|
||||
# Check for the selected items in the list widget.
|
||||
selected_items = connection_dialog.connection_parameters_list_widget.selectedItems()
|
||||
# The list of selected items should be empty.
|
||||
assert selected_items == []
|
||||
|
||||
def test_get_all_item_texts_in_list_widget(self):
|
||||
"""
|
||||
Test the method for getting all the texts of the items/connection identifiers in the list widget.
|
||||
"""
|
||||
|
||||
# Create a list for storing all connection identifiers.
|
||||
connection_identifiers = []
|
||||
|
||||
# Use every dictionary of a connection in the connection store to create an identifier for the connection.
|
||||
for connection_dictionary in global_connection_store.connection_parameters_yaml:
|
||||
# Create the connection identifier.
|
||||
identifier = "{}@{}:{}/{}".format(connection_dictionary["Username"], connection_dictionary["Host"],
|
||||
connection_dictionary["Port"], connection_dictionary["Database"])
|
||||
|
||||
# Append the identifier to the list of connection identifiers.
|
||||
connection_identifiers.append(identifier)
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a dialog.
|
||||
connection_dialog = ConnectionDialogWidget()
|
||||
# Get all item texts.
|
||||
item_texts = connection_dialog.get_all_item_texts_in_list_widget()
|
||||
|
||||
# Iterate over every identifier for checking its existence in the item texts.
|
||||
for identifier in connection_identifiers:
|
||||
# The identifier should be part of the item texts.
|
||||
assert identifier in item_texts
|
||||
|
||||
def test_method_for_testing_database_connection(self):
|
||||
"""
|
||||
Test the method for testing for a valid database connection based on the current text in the QLineEdits.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a dialog.
|
||||
connection_dialog = ConnectionDialogWidget()
|
||||
|
||||
# The text of the connection status label should be "Not tested yet", because a connection is not tested.
|
||||
assert connection_dialog.test_given_connection_status_label.text() == "Not tested yet"
|
||||
|
||||
# Set valid connection parameters for testing a connection.
|
||||
connection_dialog.connection_parameter_edit_dictionary["Host"].setText("localhost")
|
||||
connection_dialog.connection_parameter_edit_dictionary["Username"].setText("testuser")
|
||||
connection_dialog.connection_parameter_edit_dictionary["Database"].setText("postgres")
|
||||
connection_dialog.connection_parameter_edit_dictionary["Port"].setText("5432")
|
||||
# Test the connection with the method.
|
||||
connection_dialog.test_current_database_connection()
|
||||
# The label should now show a valid database connection, because valid parameters are used.
|
||||
assert connection_dialog.test_given_connection_status_label.text() == "Connection Valid"
|
||||
|
||||
# Set a new text as host, so after a new test, the connection is invalid.
|
||||
connection_dialog.connection_parameter_edit_dictionary["Host"].setText("localhorst")
|
||||
# After changing the text, the label should switch back to "Not tested yet"
|
||||
assert connection_dialog.test_given_connection_status_label.text() == "Not tested yet"
|
||||
|
||||
# Test the database connection now.
|
||||
connection_dialog.test_current_database_connection()
|
||||
# The label should now show an invalid connection.
|
||||
assert connection_dialog.test_given_connection_status_label.text() == "Connection Invalid"
|
||||
|
||||
def test_insert_parameters_in_edit_fields(self):
|
||||
"""
|
||||
Test the method for inserting parameters in the QLineEdit fields based on the signal for a change in the
|
||||
selection of the list widget.
|
||||
"""
|
||||
|
||||
# Define a connection dictionary for saving the connection data in the connection store and creating a
|
||||
# connection identifier later, so the connection is part of the list widget and can be selected.
|
||||
connection_dictionary = {"Host": "random",
|
||||
"Username": "testuser",
|
||||
"Port": 5432,
|
||||
"Database": "postgres"}
|
||||
|
||||
# Save the connection in the connection store.
|
||||
global_connection_store.save_connection_parameters_in_yaml_file(connection_dictionary)
|
||||
# Save the current connections in the connection store in the yaml file.
|
||||
global_connection_store.commit_current_list_to_yaml()
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a dialog.
|
||||
connection_dialog = ConnectionDialogWidget()
|
||||
|
||||
# Define a connection identifier for selecting it in the list widget.
|
||||
connection_identifier = "{}@{}:{}/{}".format(connection_dictionary["Username"], connection_dictionary["Host"],
|
||||
connection_dictionary["Port"], connection_dictionary["Database"])
|
||||
|
||||
# Select the item based on the connection identifier in the list widget.
|
||||
connection_dialog.find_occurrence_in_list_widget_and_select_item(connection_identifier)
|
||||
|
||||
# Check the correct content of the QLineEdit fields. They should contain the parameters of the connection
|
||||
# dictionary.
|
||||
assert connection_dictionary["Host"] == connection_dialog.connection_parameter_edit_dictionary["Host"].text()
|
||||
assert connection_dictionary["Username"] \
|
||||
== connection_dialog.connection_parameter_edit_dictionary["Username"].text()
|
||||
# Cast the port to string, because it is saved in the dictionary as integer.
|
||||
assert str(connection_dictionary["Port"]) \
|
||||
== connection_dialog.connection_parameter_edit_dictionary["Port"].text()
|
||||
assert connection_dictionary["Database"] \
|
||||
== connection_dialog.connection_parameter_edit_dictionary["Database"].text()
|
||||
|
||||
# Clean up, so the test connection is no longer part of the connection store.
|
||||
global_connection_store.delete_connection(connection_dictionary)
|
||||
global_connection_store.commit_current_list_to_yaml()
|
||||
|
||||
def test_get_selected_connection(self):
|
||||
"""
|
||||
Test the function for getting the selected connection, which returns a boolean and sets a result as an
|
||||
attribute.
|
||||
"""
|
||||
|
||||
# Define a connection dictionary for saving the connection data in the connection store and creating a
|
||||
# connection identifier later, so the connection is part of the list widget and can be selected.
|
||||
connection_dictionary = {"Host": "random",
|
||||
"Username": "testuser",
|
||||
"Port": 5432,
|
||||
"Database": "postgres"}
|
||||
|
||||
# Save the connection in the connection store.
|
||||
global_connection_store.save_connection_parameters_in_yaml_file(connection_dictionary)
|
||||
# Save the current connections in the connection store in the yaml file.
|
||||
global_connection_store.commit_current_list_to_yaml()
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a dialog.
|
||||
connection_dialog = ConnectionDialogWidget()
|
||||
|
||||
# A selected connection is missing, so the method should return False.
|
||||
assert connection_dialog.get_selected_connection() is False
|
||||
|
||||
# Define a connection identifier for selecting it in the list widget.
|
||||
connection_identifier = "{}@{}:{}/{}".format(connection_dictionary["Username"], connection_dictionary["Host"],
|
||||
connection_dictionary["Port"], connection_dictionary["Database"])
|
||||
|
||||
# Select the item related to the connection identifier.
|
||||
connection_dialog.find_occurrence_in_list_widget_and_select_item(connection_identifier)
|
||||
|
||||
# Now the method should return True, because an identifier is selected.
|
||||
assert connection_dialog.get_selected_connection() is True
|
||||
# The dictionary of the selected connection should be the pre-defined connection dictionary.
|
||||
assert connection_dialog.selected_connection_parameters_dictionary == connection_dictionary
|
||||
|
||||
# Clean up, so the test connection is no longer part of the connection store.
|
||||
global_connection_store.delete_connection(connection_dictionary)
|
||||
global_connection_store.commit_current_list_to_yaml()
|
||||
|
||||
def test_valid_delete_selected_connection(self):
|
||||
"""
|
||||
Test the method for deleting the selected database connection with a saved database connection.
|
||||
"""
|
||||
|
||||
# Define a connection dictionary for saving the connection data in the connection store and creating a
|
||||
# connection identifier later, so the connection is part of the list widget and can be selected.
|
||||
connection_dictionary = {"Host": "random",
|
||||
"Username": "testuser",
|
||||
"Port": 5432,
|
||||
"Database": "postgres"}
|
||||
|
||||
# Define a password identifier for setting a password, so it can be deleted.
|
||||
password_identifier = "{}@{}:{}".format(connection_dictionary["Username"], connection_dictionary["Host"],
|
||||
connection_dictionary["Port"])
|
||||
|
||||
keyring.set_password("Pygadmin", password_identifier, "test")
|
||||
|
||||
# Save the connection in the connection store.
|
||||
global_connection_store.save_connection_parameters_in_yaml_file(connection_dictionary)
|
||||
# Save the current connections in the connection store in the yaml file.
|
||||
global_connection_store.commit_current_list_to_yaml()
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a dialog.
|
||||
connection_dialog = ConnectionDialogWidget()
|
||||
|
||||
# Clean up, so the test connection is no longer part of the connection store.
|
||||
global_connection_store.delete_connection(connection_dictionary)
|
||||
global_connection_store.commit_current_list_to_yaml()
|
||||
|
||||
# Define a connection identifier for selecting it in the list widget.
|
||||
connection_identifier = "{}@{}:{}/{}".format(connection_dictionary["Username"], connection_dictionary["Host"],
|
||||
connection_dictionary["Port"], connection_dictionary["Database"])
|
||||
|
||||
# Select the item related to the connection identifier.
|
||||
connection_dialog.find_occurrence_in_list_widget_and_select_item(connection_identifier)
|
||||
|
||||
# The deletion of the selected connection should return True.
|
||||
assert connection_dialog.delete_selected_connection() is True
|
||||
|
||||
def test_invalid_delete_selected_connection(self):
|
||||
"""
|
||||
Test the method for deleting the selected database connection with an unsaved database connection.
|
||||
"""
|
||||
|
||||
# Define a connection dictionary for saving the connection data in the connection store and creating a
|
||||
# connection identifier later, so the connection is part of the list widget and can be selected.
|
||||
connection_dictionary = {"Host": "random",
|
||||
"Username": "testuser",
|
||||
"Port": 5432,
|
||||
"Database": "postgres"}
|
||||
|
||||
# Save the connection in the connection store.
|
||||
global_connection_store.save_connection_parameters_in_yaml_file(connection_dictionary)
|
||||
# Save the current connections in the connection store in the yaml file.
|
||||
global_connection_store.commit_current_list_to_yaml()
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a dialog.
|
||||
connection_dialog = ConnectionDialogWidget()
|
||||
|
||||
# Clean up, so the test connection is no longer part of the connection store.
|
||||
global_connection_store.delete_connection(connection_dictionary)
|
||||
global_connection_store.commit_current_list_to_yaml()
|
||||
|
||||
# Define a connection identifier for selecting it in the list widget.
|
||||
connection_identifier = "{}@{}:{}/{}".format(connection_dictionary["Username"], connection_dictionary["Host"],
|
||||
connection_dictionary["Port"], connection_dictionary["Database"])
|
||||
|
||||
# Select the item related to the connection identifier.
|
||||
connection_dialog.find_occurrence_in_list_widget_and_select_item(connection_identifier)
|
||||
|
||||
# The deletion of the selected connection should not return True.
|
||||
assert connection_dialog.delete_selected_connection() is not True
|
||||
|
||||
def test_check_for_valid_timeout(self):
|
||||
"""
|
||||
Test the method for checking for a valid timeout.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a dialog.
|
||||
connection_dialog = ConnectionDialogWidget()
|
||||
|
||||
# Set the text to an empty string, so a cast to an integer is not possible.
|
||||
connection_dialog.timeout_line_edit.setText("")
|
||||
# The timeout should be invalid.
|
||||
assert connection_dialog.check_for_valid_timeout() is False
|
||||
|
||||
# Set the text to an invalid integer value.
|
||||
connection_dialog.timeout_line_edit.setText("-42")
|
||||
# The timeout should still be invalid.
|
||||
assert connection_dialog.check_for_valid_timeout() is False
|
||||
|
||||
# Set the text to a valid integer value.
|
||||
connection_dialog.timeout_line_edit.setText("42")
|
||||
# The result should now be True.
|
||||
assert connection_dialog.check_for_valid_timeout() is True
|
||||
|
||||
def test_port_checkbox(self):
|
||||
"""
|
||||
Test the correct behavior of the (de)activation of the checkbox for using the standard postgres port.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a dialog.
|
||||
connection_dialog = ConnectionDialogWidget()
|
||||
|
||||
# Get the use postgres port checkbox of the dialog.
|
||||
postgres_port_checkbox = connection_dialog.use_postgres_port_checkbox
|
||||
# Get the port line edit.
|
||||
port_line_edit = connection_dialog.connection_parameter_edit_dictionary["Port"]
|
||||
|
||||
# Set the checkbox unchecked.
|
||||
postgres_port_checkbox.setChecked(False)
|
||||
# Now the port line edit should be empty.
|
||||
assert port_line_edit.text() == ""
|
||||
|
||||
# Define a port text for further testing.
|
||||
port_text = "1337"
|
||||
# Set the text as current text of the port line edit field.
|
||||
port_line_edit.setText(port_text)
|
||||
|
||||
# Set the port checkbox to checked.
|
||||
postgres_port_checkbox.setChecked(True)
|
||||
# Now the port line edit should contain the standard postgres port as text.
|
||||
assert port_line_edit.text() == "5432"
|
||||
|
||||
# Set the port checkbox back to unchecked.
|
||||
postgres_port_checkbox.setChecked(False)
|
||||
# Now the checkbox should contain the port text, which has been set earlier.
|
||||
assert port_line_edit.text() == port_text
|
172
tests/test_connectionfactory.py
Normal file
172
tests/test_connectionfactory.py
Normal file
@@ -0,0 +1,172 @@
|
||||
import unittest
|
||||
|
||||
import psycopg2
|
||||
|
||||
from pygadmin.connectionfactory import global_connection_factory
|
||||
|
||||
|
||||
class TestConnectionFactoryMethods(unittest.TestCase):
|
||||
"""
|
||||
Test the methods and the functionality of the (global) connection factory.
|
||||
"""
|
||||
|
||||
def test_factory_structure(self):
|
||||
"""
|
||||
Check the data structure of the factory: The factory should use a dict for saving the internal connection data.
|
||||
"""
|
||||
|
||||
assert isinstance(global_connection_factory.connections_dictionary, dict)
|
||||
|
||||
def test_valid_get_connection(self):
|
||||
"""
|
||||
Use valid connection parameters for getting a correct connection.
|
||||
"""
|
||||
|
||||
connection = global_connection_factory.get_database_connection("localhost", "testuser", "testdb", 5432, 10000)
|
||||
|
||||
assert isinstance(connection, psycopg2.extensions.connection)
|
||||
|
||||
def test_wrong_password_get_connection(self):
|
||||
"""
|
||||
Use a non existing user for testing a fail in the password storage, so the connection should be set to None.
|
||||
"""
|
||||
|
||||
connection = global_connection_factory.get_database_connection("localhost", "test", "testdb")
|
||||
|
||||
assert connection is None
|
||||
|
||||
def test_invalid_get_connection(self):
|
||||
"""
|
||||
Use invalid connection parameters with an invalid/a non existing database, so the connection should be set to
|
||||
False.
|
||||
"""
|
||||
|
||||
connection = global_connection_factory.get_database_connection("localhost", "testuser", "test")
|
||||
|
||||
assert connection is False
|
||||
|
||||
def test_valid_get_parameters(self):
|
||||
"""
|
||||
Test the method for getting parameters based on a given database connection. Predefine a dictionary with
|
||||
parameters, get the connection based on them and then, get the dictionary for the connection.
|
||||
"""
|
||||
|
||||
# Define database connection parameters in a dictionary. The structure is equivalent to the structure of the
|
||||
# dictionary, which is returned by the function of the factory for a connection.
|
||||
database_parameters = {
|
||||
"host": "localhost",
|
||||
"user": "testuser",
|
||||
"database": "testdb",
|
||||
"port": 5432,
|
||||
}
|
||||
|
||||
# Get a database connection.
|
||||
connection = global_connection_factory.get_database_connection(database_parameters["host"],
|
||||
database_parameters["user"],
|
||||
database_parameters["database"],
|
||||
database_parameters["port"])
|
||||
|
||||
# Get a dictionary based on the established connection.
|
||||
factory_parameters = global_connection_factory.get_database_connection_parameters(connection)
|
||||
|
||||
# The dictionary, which was used to create a connection, and the dictionary, which matches with the connection,
|
||||
# should be equivalent.
|
||||
assert database_parameters == factory_parameters
|
||||
|
||||
def test_invalid_get_parameters(self):
|
||||
"""
|
||||
Test the method for getting connection parameters based on a connection with an invalid connection.
|
||||
"""
|
||||
|
||||
# Use None as database connection, which is obviously not a valid database connection.
|
||||
factory_parameter = global_connection_factory.get_database_connection_parameters(None)
|
||||
|
||||
# For an error case, the method should return None.
|
||||
assert factory_parameter is None
|
||||
|
||||
def test_valid_connection_test(self):
|
||||
"""
|
||||
Use the method of the factory for testing a database connection with valid database connection parameters.
|
||||
"""
|
||||
|
||||
# A password is required for testing. Because this is a pure test environment and the data is more or less
|
||||
# random and the database is localhost, the password is hard coded and visible in this file.
|
||||
connection_possible = global_connection_factory.test_parameters_for_database_connection("localhost", "testuser",
|
||||
"testdb", "test1234")
|
||||
|
||||
# A correct connection should return True.
|
||||
assert connection_possible is True
|
||||
|
||||
def test_invalid_connection_test(self):
|
||||
"""
|
||||
Use the method of the factory for testing a database connection with invalid database connection parameters.
|
||||
"""
|
||||
|
||||
# Use invalid database connection parameters with an incorrect password.
|
||||
connection_possible = global_connection_factory.test_parameters_for_database_connection("localhost", "testuser",
|
||||
"test", "test42")
|
||||
|
||||
print(connection_possible)
|
||||
|
||||
# An invalid connection should return False.
|
||||
assert connection_possible is False
|
||||
|
||||
def test_valid_close_connection(self):
|
||||
"""
|
||||
Test the correct close and delete mechanism for a database connection.
|
||||
"""
|
||||
|
||||
# Get a database connection.
|
||||
connection = global_connection_factory.get_database_connection("localhost", "testuser", "testdb")
|
||||
# Close the connection and get the boolean for closing.
|
||||
connection_closed = global_connection_factory.close_and_remove_database_connection(connection)
|
||||
|
||||
# Check the boolean for closing.
|
||||
assert connection_closed is True
|
||||
# Double check: Try to find the connection parameters, which are related to the database connection. They should
|
||||
# be None for not found.
|
||||
assert global_connection_factory.get_database_connection_parameters(connection) is None
|
||||
|
||||
def test_invalid_close_connection(self):
|
||||
"""
|
||||
Test the close and delete mechanism for an invalid database connection.
|
||||
"""
|
||||
|
||||
# Try to close an invalid database connection.
|
||||
connection_closed = global_connection_factory.close_and_remove_database_connection(None)
|
||||
|
||||
# The result should be not True.
|
||||
assert connection_closed is not True
|
||||
|
||||
def test_connection_reestablish(self):
|
||||
"""
|
||||
Test the method for reestablishing a database connection.
|
||||
"""
|
||||
|
||||
# Define database connection parameters for establishing a connection.
|
||||
database_parameters = {
|
||||
"host": "localhost",
|
||||
"user": "testuser",
|
||||
"database": "testdb",
|
||||
"port": 5432,
|
||||
}
|
||||
|
||||
# Get the first connection related to the given parameters.
|
||||
connection = global_connection_factory.get_database_connection(database_parameters["host"],
|
||||
database_parameters["user"],
|
||||
database_parameters["database"],
|
||||
database_parameters["port"])
|
||||
|
||||
# Use the database parameters for creating a new connection, which is the reestablished old connection.
|
||||
new_connection = global_connection_factory.reestablish_terminated_connection(database_parameters)
|
||||
|
||||
# The old connection should be closed, so the closed attribute should be 1.
|
||||
assert connection.closed == 1
|
||||
# Try to get connection parameters related to the old connection. This should be None, because a match is not
|
||||
# found.
|
||||
assert global_connection_factory.get_database_connection_parameters(connection) is None
|
||||
# The new connection should be open, so the attribute should be 0.
|
||||
assert new_connection.closed == 0
|
||||
# Check for the related connection parameters, which should be the initial dictionary.
|
||||
assert global_connection_factory.get_database_connection_parameters(new_connection) == database_parameters
|
||||
|
251
tests/test_connectionstore.py
Normal file
251
tests/test_connectionstore.py
Normal file
@@ -0,0 +1,251 @@
|
||||
import unittest
|
||||
import os
|
||||
|
||||
from pygadmin.connectionstore import global_connection_store
|
||||
|
||||
|
||||
class TestConnectionStoreMethods(unittest.TestCase):
|
||||
"""
|
||||
Test the connection store with its method and its behavior.
|
||||
"""
|
||||
|
||||
def test_path_of_connection_file(self):
|
||||
"""
|
||||
Test the existence of the file for storing the connection parameters.
|
||||
"""
|
||||
|
||||
assert os.path.exists(global_connection_store.yaml_connection_parameters_file)
|
||||
|
||||
def test_connection_list(self):
|
||||
"""
|
||||
Test the connection list for its correct instance, which is also an implicit test for its existence.
|
||||
"""
|
||||
|
||||
assert isinstance(global_connection_store.connection_parameters_yaml, list)
|
||||
|
||||
def test_get_connection_parameters(self):
|
||||
"""
|
||||
Test the function for getting all connection parameters.
|
||||
"""
|
||||
|
||||
# Use the function for getting the list.
|
||||
connection_parameter_list = global_connection_store.get_connection_parameters_from_yaml_file()
|
||||
# Check, if the returned list is the one, which contains all connection parameters in the connection store.
|
||||
assert connection_parameter_list == global_connection_store.connection_parameters_yaml
|
||||
|
||||
def test_valid_save_connection_parameters(self):
|
||||
"""
|
||||
Test the function for saving connection parameters with valid paramters.
|
||||
"""
|
||||
|
||||
# Define valid parameters.
|
||||
test_parameters = {"Host": "testhost",
|
||||
"Username": "testuser",
|
||||
"Database": "testdb",
|
||||
"Port": 5432}
|
||||
|
||||
# Save the parameters and assume a result, which is True.
|
||||
assert global_connection_store.save_connection_parameters_in_yaml_file(test_parameters) is True
|
||||
|
||||
# Use a clean up with deleting the connection.
|
||||
global_connection_store.delete_connection(test_parameters)
|
||||
|
||||
def test_invalid_save_connection_parameters(self):
|
||||
"""
|
||||
Test the function for saving connection parameters with invalid parameters.
|
||||
"""
|
||||
|
||||
# Use an empty dictionary as invalid parameters.
|
||||
assert global_connection_store.save_connection_parameters_in_yaml_file({}) is False
|
||||
|
||||
def test_duplicate_check(self):
|
||||
"""
|
||||
Test the function for a duplicate check.
|
||||
"""
|
||||
|
||||
# Define test parameters.
|
||||
test_parameters = {"Host": "testhost",
|
||||
"Username": "testuser",
|
||||
"Database": "testdb",
|
||||
"Port": 1337}
|
||||
|
||||
# Save the parameters in the connection store and yaml file.
|
||||
global_connection_store.save_connection_parameters_in_yaml_file(test_parameters)
|
||||
|
||||
# Use the function for checking a duplicate with the test parameters again.
|
||||
assert global_connection_store.check_parameter_for_duplicate(test_parameters) is True
|
||||
|
||||
# Clean up.
|
||||
global_connection_store.delete_connection(test_parameters)
|
||||
|
||||
def test_valid_delete_connection(self):
|
||||
"""
|
||||
Test the function for deleting a connection with saving parameters first and then deleting them.
|
||||
"""
|
||||
|
||||
# Define test parameters.
|
||||
test_parameters = {"Host": "testhost",
|
||||
"Username": "testuser",
|
||||
"Database": "testdb",
|
||||
"Port": 1337}
|
||||
|
||||
# Save the parameters.
|
||||
global_connection_store.save_connection_parameters_in_yaml_file(test_parameters)
|
||||
|
||||
# Delete the parameters and assume a successful deletion.
|
||||
assert global_connection_store.delete_connection(test_parameters) is True
|
||||
|
||||
def test_invalid_delete_connection(self):
|
||||
"""
|
||||
Test the deletion of an invalid connection dictionary.
|
||||
"""
|
||||
|
||||
# Use an empty dictionary as invalid dictionary.
|
||||
assert global_connection_store.delete_connection({}) is False
|
||||
|
||||
def test_valid_change_connection(self):
|
||||
"""
|
||||
Test the change of a connection with a valid connection dictionary and a new dictionary with changed paramters.
|
||||
"""
|
||||
|
||||
# Define the first test parameters.
|
||||
test_parameters = {"Host": "testhost",
|
||||
"Username": "testuser",
|
||||
"Database": "testdb",
|
||||
"Port": 1337}
|
||||
|
||||
# Save the first parameters.
|
||||
global_connection_store.save_connection_parameters_in_yaml_file(test_parameters)
|
||||
|
||||
# Define changed parameters with a different port.
|
||||
changed_test_parameters = {"Host": "testhost",
|
||||
"Username": "testuser",
|
||||
"Database": "testdb",
|
||||
"Port": 5432}
|
||||
|
||||
# Test for the correct change of parameters.
|
||||
assert global_connection_store.change_connection(test_parameters, changed_test_parameters) is True
|
||||
|
||||
# Clean up.
|
||||
global_connection_store.delete_connection(changed_test_parameters)
|
||||
|
||||
def test_invalid_change_connection(self):
|
||||
"""
|
||||
Test the function for changing information about a connection with invalid/duplicate data.
|
||||
"""
|
||||
|
||||
# Define a dictionary with connection parameters.
|
||||
test_parameters = {"Host": "testhost",
|
||||
"Username": "testuser",
|
||||
"Database": "testdb",
|
||||
"Port": 1337}
|
||||
|
||||
# Save the connection.
|
||||
global_connection_store.save_connection_parameters_in_yaml_file(test_parameters)
|
||||
|
||||
# Try to change the connection information, but this test should return False, because it is a duplicate.
|
||||
assert global_connection_store.change_connection(test_parameters, test_parameters) is False
|
||||
|
||||
# Clean up.
|
||||
global_connection_store.delete_connection(test_parameters)
|
||||
|
||||
def test_valid_check_key(self):
|
||||
"""
|
||||
Test the method for checking for the correct keys in the connection dictionary with valid data.
|
||||
"""
|
||||
|
||||
# Define a dictionary with test parameters.
|
||||
test_parameters = {"Host": "testhost",
|
||||
"Username": "testuser",
|
||||
"Database": "testdb",
|
||||
"Port": 1337}
|
||||
|
||||
# Assume a success.
|
||||
assert global_connection_store.check_for_correct_keys_in_dictionary(test_parameters) is True
|
||||
|
||||
def test_invalid_check_key(self):
|
||||
"""
|
||||
Test the method for checking for the correct keys in the dictionary with invalid data.
|
||||
"""
|
||||
|
||||
# Use an empty dictionary as invalid data.
|
||||
assert global_connection_store.check_for_correct_keys_in_dictionary({}) is False
|
||||
|
||||
def test_connection_parameter_number(self):
|
||||
"""
|
||||
Test the method for getting the number of connection parameters.
|
||||
"""
|
||||
|
||||
# Get the length of the list with parameters and compare them with the result of the method.
|
||||
assert len(global_connection_store.connection_parameters_yaml) \
|
||||
== global_connection_store.get_number_of_connection_parameters()
|
||||
|
||||
def test_valid_index_of_connection(self):
|
||||
"""
|
||||
Test the method for getting the index of a connection with a known dictionary and valid data.
|
||||
"""
|
||||
|
||||
# Get the current number of connection parameters before adding new data.
|
||||
current_parameters_number = global_connection_store.get_number_of_connection_parameters()
|
||||
|
||||
# Define a test dictionary.
|
||||
test_parameters = {"Host": "testhost",
|
||||
"Username": "testuser",
|
||||
"Database": "testdb",
|
||||
"Port": 1337}
|
||||
|
||||
# Save the test dictionary.
|
||||
global_connection_store.save_connection_parameters_in_yaml_file(test_parameters)
|
||||
|
||||
# Check for the correct index of the new connection.
|
||||
assert global_connection_store.get_index_of_connection(test_parameters) == current_parameters_number
|
||||
|
||||
# Clean up.
|
||||
global_connection_store.delete_connection(test_parameters)
|
||||
|
||||
def test_invalid_index_of_connection(self):
|
||||
"""
|
||||
Test the method for getting the index of a connection with invalid data and as a result an invalid index.
|
||||
"""
|
||||
|
||||
# Use an empty dictionary as invalid data.
|
||||
assert global_connection_store.get_index_of_connection({}) is None
|
||||
|
||||
def test_valid_connection_at_index(self):
|
||||
"""
|
||||
Test the method for getting an index at a specified position.
|
||||
"""
|
||||
|
||||
# Define test parameters.
|
||||
test_parameters = {"Host": "testhost",
|
||||
"Username": "testuser",
|
||||
"Database": "testdb",
|
||||
"Port": 1337}
|
||||
|
||||
# Save the parameters.
|
||||
global_connection_store.save_connection_parameters_in_yaml_file(test_parameters)
|
||||
|
||||
# After a save of parameters, there has to be a connection at index 0.
|
||||
connection_at_index = global_connection_store.get_connection_at_index(0)
|
||||
|
||||
# Check the connection for the right instance.
|
||||
assert isinstance(connection_at_index, dict)
|
||||
# Check the connection for the correct keys, so the data structure is correct.
|
||||
assert "Host" in connection_at_index
|
||||
assert "Username" in connection_at_index
|
||||
assert "Database" in connection_at_index
|
||||
assert "Port" in connection_at_index
|
||||
|
||||
# Clean up.
|
||||
global_connection_store.delete_connection(test_parameters)
|
||||
|
||||
def test_invalid_connection_at_index(self):
|
||||
"""
|
||||
Test the method for getting a connection at a given index with invalid data.
|
||||
"""
|
||||
|
||||
# Get the current number of connections.
|
||||
current_connection_number = global_connection_store.get_number_of_connection_parameters()
|
||||
# Check for the current number of connection as index (which is None, because the index starts at 0).
|
||||
assert global_connection_store.get_connection_at_index(current_connection_number) is None
|
||||
|
277
tests/test_database_dumper.py
Normal file
277
tests/test_database_dumper.py
Normal file
@@ -0,0 +1,277 @@
|
||||
import os
|
||||
import re
|
||||
import unittest
|
||||
|
||||
from pygadmin.database_dumper import DatabaseDumper
|
||||
from pygadmin.configurator import global_app_configurator
|
||||
|
||||
|
||||
class TestDatabaseDumperMethods(unittest.TestCase):
|
||||
"""
|
||||
Test the class for dumping a database and its behavior.
|
||||
"""
|
||||
|
||||
def test_valid_database_dump(self):
|
||||
"""
|
||||
Use valid data for dumping a database and get the result.
|
||||
"""
|
||||
|
||||
# Use a valid connection and valid dump data.
|
||||
database_dumper = DatabaseDumper("testuser", "testdb", "localhost", 5432, "Table", "test")
|
||||
# Get the result of a database dump.
|
||||
result = database_dumper.dump_database()
|
||||
|
||||
assert result is not None
|
||||
|
||||
def test_invalid_database_dump(self):
|
||||
"""
|
||||
Use invalid data for dumping a database and check the invalid result.
|
||||
"""
|
||||
|
||||
# Use an invalid connection and invalid dump data.
|
||||
database_dumper = DatabaseDumper("testuser", "testdb", "localhost", 1337, "Table", "test")
|
||||
# Get the result of a database dump.
|
||||
result = database_dumper.dump_database()
|
||||
|
||||
assert result is None
|
||||
|
||||
def test_valid_create_pass_file(self):
|
||||
"""
|
||||
Test the method for creating a pass file with valid data.
|
||||
"""
|
||||
|
||||
# Define the relevant data for a dump.
|
||||
user = "testuser"
|
||||
database = "testdb"
|
||||
host = "localhost"
|
||||
port = 5432
|
||||
dump_information = "Table"
|
||||
table_name = "test"
|
||||
|
||||
# Define a password identifier, which is relevant for the creating of a pass file.
|
||||
password_identifier = "{}@{}:{}".format(user, host, port)
|
||||
|
||||
# Create a dumper.
|
||||
database_dumper = DatabaseDumper(user, database, host, port, dump_information, table_name)
|
||||
|
||||
# Get the file path and handler.
|
||||
file_path, file_handler = database_dumper.create_pass_file(password_identifier)
|
||||
|
||||
# Check the file path and the file handler for its existence.
|
||||
assert os.path.exists(file_path) is True
|
||||
assert os.path.exists(file_handler) is True
|
||||
|
||||
def test_invalid_create_pass_file(self):
|
||||
"""
|
||||
Test the creation and usage of a pass file with invalid data, so the host, user and port cannot be found in the
|
||||
password manager. The file creation and usage should function normally.
|
||||
"""
|
||||
|
||||
# Define the relevant data for a dump.
|
||||
user = "testasdf"
|
||||
database = "testdb"
|
||||
host = "unknown"
|
||||
port = 1337
|
||||
dump_information = "Table"
|
||||
table_name = "test"
|
||||
|
||||
# Define a password identifier, which is relevant for the creating of a pass file.
|
||||
password_identifier = "{}@{}:{}".format(user, host, port)
|
||||
|
||||
# Create a dumper.
|
||||
database_dumper = DatabaseDumper(user, database, host, port, dump_information, table_name)
|
||||
|
||||
# Get the file path and handler.
|
||||
file_path, file_handler = database_dumper.create_pass_file(password_identifier)
|
||||
|
||||
# Check the file path and the file handler for its existence, because they should also exist for invalid data.
|
||||
assert os.path.exists(file_path) is True
|
||||
assert os.path.exists(file_handler) is True
|
||||
|
||||
def test_pg_dump_path(self):
|
||||
"""
|
||||
Test the functionality of the method for getting the pg dump path with also checking for the path in the global
|
||||
app configurator.
|
||||
"""
|
||||
|
||||
# Get the pg dump path out of the global app configurator.
|
||||
configurator_dump_path = global_app_configurator.get_single_configuration("pg_dump_path")
|
||||
|
||||
# Create a dumper.
|
||||
database_dumper = DatabaseDumper("testuser", "testdb", "localhost", 5432, "Table", "test")
|
||||
# Get the dump path as accessible attribute of the class.
|
||||
database_dumper.get_pg_dump_path()
|
||||
|
||||
# If a path in the configurator does exist, check for the correct set.
|
||||
if configurator_dump_path is not None and os.path.exists(configurator_dump_path):
|
||||
# The path in the configurator should be the pg dump path of the dumper.
|
||||
assert database_dumper.pg_dump_path == configurator_dump_path
|
||||
|
||||
# The path should not be a None, so it has been set.
|
||||
assert database_dumper.pg_dump_path is not None
|
||||
|
||||
def test_database_pg_dump_statement(self):
|
||||
"""
|
||||
Test the creation of a pg dump statement for a database.
|
||||
"""
|
||||
|
||||
# Define the relevant parameters as local variables.
|
||||
user = "testuser"
|
||||
database = "testdb"
|
||||
host = "localhost"
|
||||
port = 5432
|
||||
dump_information = "Database"
|
||||
information_name = "testdb"
|
||||
|
||||
# Create a dumper.
|
||||
database_dumper = DatabaseDumper(user, database, host, port, dump_information, information_name)
|
||||
# Get the dump path as attribute of the dumper, which is necessary for the dump statement.
|
||||
database_dumper.get_pg_dump_path()
|
||||
# Get the dump statement as attribute of the dumper.
|
||||
database_dumper.get_pg_dump_statement()
|
||||
|
||||
# The statement is a list, so get the list.
|
||||
statement_list = database_dumper.pg_dump_statement
|
||||
|
||||
# Check for the correct instance of the list.
|
||||
assert isinstance(statement_list, list)
|
||||
# Check for the relevant strings and statements as part of the statement list.
|
||||
assert database_dumper.pg_dump_path in statement_list
|
||||
assert "-T*" in statement_list
|
||||
assert "--create" in statement_list
|
||||
assert "--dbname=postgresql://{}@{}:{}/{}".format(user, host, port, database) in statement_list
|
||||
|
||||
def test_table_pg_dump_statement(self):
|
||||
"""
|
||||
Test the creation of a pg dump statement for a table.
|
||||
"""
|
||||
|
||||
# Define the relevant parameters as local variables.
|
||||
user = "testuser"
|
||||
database = "testdb"
|
||||
host = "localhost"
|
||||
port = 5432
|
||||
dump_information = "Table"
|
||||
information_name = "test"
|
||||
|
||||
# Create a dumper.
|
||||
database_dumper = DatabaseDumper(user, database, host, port, dump_information, information_name)
|
||||
# Get the dump path as attribute of the dumper, which is necessary for the dump statement.
|
||||
database_dumper.get_pg_dump_path()
|
||||
# Get the dump statement as attribute of the dumper.
|
||||
database_dumper.get_pg_dump_statement()
|
||||
|
||||
# The statement is a list, so get the list.
|
||||
statement_list = database_dumper.pg_dump_statement
|
||||
|
||||
# Check for the correct instance of the list.
|
||||
assert isinstance(statement_list, list)
|
||||
# Check for the relevant strings and statements as part of the statement list.
|
||||
assert database_dumper.pg_dump_path in statement_list
|
||||
assert "--table={}".format(information_name) in statement_list
|
||||
assert "--schema-only" in statement_list
|
||||
assert "--dbname=postgresql://{}@{}:{}/{}".format(user, host, port, database) in statement_list
|
||||
|
||||
def test_valid_database_dump_clean_result(self):
|
||||
"""
|
||||
Test the dump of a database with valid data and test the clean of the result.
|
||||
"""
|
||||
|
||||
# Use a valid connection and valid dump data.
|
||||
database_dumper = DatabaseDumper("testuser", "testdb", "localhost", 5432, "Table", "test")
|
||||
# Get the result of a database dump.
|
||||
result = database_dumper.dump_database_and_clean_result()
|
||||
|
||||
# The result should be a list.
|
||||
assert isinstance(result, list)
|
||||
|
||||
def test_invalid_database_dump_clean_result(self):
|
||||
"""
|
||||
Test the dump of a database with invalid data and test the clean of the result.
|
||||
"""
|
||||
|
||||
# Use an invalid connection and invalid dump data.
|
||||
database_dumper = DatabaseDumper("testuser", "testdb", "localhost", 1337, "Table", "test")
|
||||
# Get the result of a database dump.
|
||||
result = database_dumper.dump_database()
|
||||
|
||||
assert result is None
|
||||
|
||||
def test_clean_database_result(self):
|
||||
"""
|
||||
Test the clean of the database result.
|
||||
"""
|
||||
|
||||
# Use a valid connection and valid dump data.
|
||||
database_dumper = DatabaseDumper("testuser", "testdb", "localhost", 5432, "Database", "testdb")
|
||||
# Get the result of a database dump.
|
||||
result = database_dumper.dump_database()
|
||||
# Split the result into lines.
|
||||
result_lines = result.stdout.split(os.linesep)
|
||||
# Clean the result.
|
||||
result_list = database_dumper.clean_database_result(result_lines)
|
||||
|
||||
# Check for the correct clean, so only lines with CREATE or ALTER are valid.
|
||||
for line in result_list:
|
||||
assert re.search("CREATE|ALTER", line) is not None
|
||||
|
||||
def test_clean_table_result(self):
|
||||
"""
|
||||
Test the clean of the table result.
|
||||
"""
|
||||
|
||||
# Use a valid connection and valid dump data.
|
||||
database_dumper = DatabaseDumper("testuser", "testdb", "localhost", 5432, "Table", "test")
|
||||
# Get the result of a database dump.
|
||||
result = database_dumper.dump_database()
|
||||
# Split the result into lines.
|
||||
result_lines = result.stdout.split(os.linesep)
|
||||
# Clean the table result.
|
||||
result_list = database_dumper.clean_table_result(result_lines)
|
||||
# Define a bracket count, which counts opened and closed brackets.
|
||||
bracket_count = 0
|
||||
|
||||
# Check every line for a CREATE or open/closed brackets.
|
||||
for line in result_list:
|
||||
assert re.search("CREATE", line) or bracket_count != 0
|
||||
for character in line:
|
||||
if character == "(":
|
||||
bracket_count += 1
|
||||
|
||||
if character == ")":
|
||||
bracket_count -= 1
|
||||
|
||||
def test_clean_view_result(self):
|
||||
"""
|
||||
Test the clean of a view result.
|
||||
"""
|
||||
|
||||
# Use a valid connection and valid dump data.
|
||||
database_dumper = DatabaseDumper("testuser", "testdb", "localhost", 5432, "View", "testview")
|
||||
# Get the result of a database dump.
|
||||
result = database_dumper.dump_database()
|
||||
# Split the result into lines.
|
||||
result_lines = result.stdout.split(os.linesep)
|
||||
# Clean the table result
|
||||
result_list = database_dumper.clean_view_result(result_lines)
|
||||
# This line is set to True after a CREATE VIEW and is set to False after a semicolon, which ends the command.
|
||||
create_view = False
|
||||
|
||||
# Check the result lines.
|
||||
for line in result_list:
|
||||
# The line should contain a CREATE VIEW or the create view should be in a previous line.
|
||||
assert re.search("CREATE VIEW", line) or create_view is True
|
||||
|
||||
create_view = True
|
||||
|
||||
# Check for a semicolon to end the command.
|
||||
for character in line:
|
||||
if character == ";":
|
||||
create_view = False
|
||||
|
||||
def test_invalid_clean_result(self):
|
||||
# Use a valid connection and valid dump data.
|
||||
database_dumper = DatabaseDumper("testuser", "testdb", "localhost", 5432, "Database", "testdb")
|
||||
|
||||
database_dumper.clean_database_result(None)
|
||||
|
160
tests/test_database_query_executor.py
Normal file
160
tests/test_database_query_executor.py
Normal file
@@ -0,0 +1,160 @@
|
||||
import unittest
|
||||
|
||||
from pygadmin.database_query_executor import DatabaseQueryExecutor
|
||||
|
||||
from pygadmin.connectionfactory import global_connection_factory
|
||||
|
||||
|
||||
class TestDatabaseQueryExecutorMethods(unittest.TestCase):
|
||||
"""
|
||||
Test the methods and the functionality of the database query executor.
|
||||
"""
|
||||
|
||||
def test_creation(self):
|
||||
"""
|
||||
Test the creation of an object of the type database query executor.
|
||||
"""
|
||||
|
||||
executor = DatabaseQueryExecutor()
|
||||
|
||||
# Check all relevant data as set to None.
|
||||
assert executor.database_connection is None
|
||||
assert executor.database_query is None
|
||||
assert executor.database_query_parameter is None
|
||||
|
||||
def test_valid_execute_query(self):
|
||||
"""
|
||||
Test the execution of a database query with valid input parameters.
|
||||
"""
|
||||
|
||||
# Create an executor.
|
||||
executor = DatabaseQueryExecutor()
|
||||
# Create a database connection.
|
||||
database_connection = global_connection_factory.get_database_connection("localhost", "testuser", "testdb")
|
||||
# Get the result and the message of a query.
|
||||
result_data_list, query_message = executor.execute_query("SELECT * FROM test;", database_connection.cursor())
|
||||
|
||||
# The first result should be a list.
|
||||
assert isinstance(result_data_list, list)
|
||||
# The second result should be a message as string.
|
||||
assert isinstance(query_message, str)
|
||||
|
||||
def test_invalid_execute_query(self):
|
||||
"""
|
||||
Test the execution of a database query with invalid input parameters.
|
||||
"""
|
||||
|
||||
# Create an executor.
|
||||
executor = DatabaseQueryExecutor()
|
||||
# Create a database connection.
|
||||
database_connection = global_connection_factory.get_database_connection("localhost", "testuser", "testdb")
|
||||
|
||||
# This try statement is used for causing an error and catching it, because with an invalid table, there will
|
||||
# be an error. assertRaise cannot be used, because the resulting error is a psycopg2 error and not a python
|
||||
# exception.
|
||||
try:
|
||||
# Execute a query with an invalid/a undefined table.
|
||||
executor.execute_query("SELECT * FROM testtt;", database_connection.cursor())
|
||||
# Assert something, which is wrong, so the test will fail, if this statement is reached.
|
||||
assert 2 + 2 == 5
|
||||
|
||||
# Use the exception block for the assertion: Reaching this block, something, which is true, will be asserted, so
|
||||
# the test will pass.
|
||||
except Exception as error:
|
||||
assert isinstance(error, Exception)
|
||||
|
||||
def test_valid_connection_with_valid_parameters(self):
|
||||
"""
|
||||
Test the method is_connection_valid of the database query executor with valid database connection parameters and
|
||||
a valid database connection.
|
||||
"""
|
||||
|
||||
# Create an executor.
|
||||
executor = DatabaseQueryExecutor()
|
||||
# Create a database connection.
|
||||
database_connection = global_connection_factory.get_database_connection("localhost", "testuser", "testdb")
|
||||
# Set the new database connection as connection for the executor.
|
||||
executor.database_connection = database_connection
|
||||
|
||||
# The fresh and new connection should be valid.
|
||||
assert executor.is_connection_valid() is True
|
||||
|
||||
# Close the database connection.
|
||||
database_connection.close()
|
||||
|
||||
# Now the connection after a close should be invalid.
|
||||
assert executor.is_connection_valid() is False
|
||||
|
||||
# Clean up: Remove the connection from the connection factory to prevent the further usage of the connection,
|
||||
# which can cause errors or test failures.
|
||||
global_connection_factory.close_and_remove_database_connection(database_connection)
|
||||
|
||||
def test_valid_connection_with_invalid_parameters(self):
|
||||
"""
|
||||
Test the method is_connection_valid with invalid parameters and an invalid database connection.
|
||||
"""
|
||||
|
||||
# Create an executor.
|
||||
executor = DatabaseQueryExecutor()
|
||||
# Set the database connection of the executor to None.
|
||||
executor.database_connection = None
|
||||
|
||||
# The connection should be invalid.
|
||||
assert executor.is_connection_valid() is False
|
||||
|
||||
def test_reestablish_connection(self):
|
||||
"""
|
||||
Test the method for reestablishing a database connection.
|
||||
"""
|
||||
|
||||
# Create an executor.
|
||||
executor = DatabaseQueryExecutor()
|
||||
|
||||
database_connection = global_connection_factory.get_database_connection("localhost", "testuser", "testdb")
|
||||
# Set the new database connection as connection for the executor.
|
||||
executor.database_connection = database_connection
|
||||
|
||||
# Check for a valid connection.
|
||||
assert executor.is_connection_valid() is True
|
||||
# Close the database connection.
|
||||
database_connection.close()
|
||||
# The connection should be invalid after a close.
|
||||
assert executor.is_connection_valid() is False
|
||||
# Reestablish the database connection.
|
||||
executor.reestablish_connection()
|
||||
# The connection should now be valid again.
|
||||
assert executor.is_connection_valid() is True
|
||||
|
||||
def test_valid_connection_check_and_reestablish(self):
|
||||
"""
|
||||
Test the function check_for_valid_connection_and_reestablish of the executor with a valid database connection.
|
||||
"""
|
||||
|
||||
# Create an executor.
|
||||
executor = DatabaseQueryExecutor()
|
||||
|
||||
database_connection = global_connection_factory.get_database_connection("localhost", "testuser", "testdb")
|
||||
# Set the new database connection as connection for the executor.
|
||||
executor.database_connection = database_connection
|
||||
|
||||
# The new connection should return True, because the connection is functional.
|
||||
assert executor.check_for_valid_connection_and_reestablish() is True
|
||||
# Close the database connection.
|
||||
database_connection.close()
|
||||
# Check for a valid connection and reestablish: This should be True, because a connection can be reestablished.
|
||||
assert executor.check_for_valid_connection_and_reestablish() is True
|
||||
|
||||
def test_invalid_connection_check_and_reestablish(self):
|
||||
"""
|
||||
Test the function check_for_valid_connection_and_reestablish of the executor with an invalid database
|
||||
connection.
|
||||
"""
|
||||
|
||||
# Create an executor.
|
||||
executor = DatabaseQueryExecutor()
|
||||
# Set the database connection of the executor to None, which is an invalid database connection.
|
||||
executor.database_connection = None
|
||||
|
||||
# The connection should be invalid. As a result, the connection cannot be reestablished.
|
||||
assert executor.check_for_valid_connection_and_reestablish() is False
|
||||
|
26
tests/test_dock.py
Normal file
26
tests/test_dock.py
Normal file
@@ -0,0 +1,26 @@
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
|
||||
from pygadmin.widgets.dock import DockWidget
|
||||
from pygadmin.widgets.tree import TreeWidget
|
||||
|
||||
|
||||
class TestDockWidgetMethods(unittest.TestCase):
|
||||
"""
|
||||
Test the basic functionality of the dock widget.
|
||||
"""
|
||||
|
||||
def test_initial_attributes(self):
|
||||
"""
|
||||
Test the initial attributes of the dock.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QWidget.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a dock widget.
|
||||
dock_widget = DockWidget()
|
||||
# The tree of the dock widget should be a TreeWidget
|
||||
assert isinstance(dock_widget.tree, TreeWidget)
|
||||
|
279
tests/test_editor.py
Normal file
279
tests/test_editor.py
Normal file
@@ -0,0 +1,279 @@
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
|
||||
from pygadmin.widgets.editor import EditorWidget
|
||||
from pygadmin.models.tablemodel import TableModel
|
||||
from pygadmin.database_query_executor import DatabaseQueryExecutor
|
||||
from pygadmin.connectionfactory import global_connection_factory
|
||||
|
||||
|
||||
class TestEditorWidgetMethods(unittest.TestCase):
|
||||
"""
|
||||
Test the functionality and methods of the editor widget.
|
||||
"""
|
||||
|
||||
def test_initial_attributes(self):
|
||||
"""
|
||||
Check for the correct existence and instance of the initial attributes of the editor.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QWidget.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an editor widget.
|
||||
editor_widget = EditorWidget()
|
||||
|
||||
# Test for the correct instance of the table model.
|
||||
assert isinstance(editor_widget.table_model, TableModel)
|
||||
# The data list of the table model should be empty at the start.
|
||||
assert editor_widget.table_model.data_list == []
|
||||
# The current database connection should be None at the start.
|
||||
assert editor_widget.current_database_connection is None
|
||||
# The connection identifier should be None at at the start.
|
||||
assert editor_widget.connection_identifier is None
|
||||
# Test for the correct instance of the database query executor.
|
||||
assert isinstance(editor_widget.database_query_executor, DatabaseQueryExecutor)
|
||||
|
||||
def test_valid_set_connection_based_on_parameters(self):
|
||||
"""
|
||||
Test the method for setting connection parameters based on parameters in a dictionary with valid connection
|
||||
parameters.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QWidget.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an editor widget.
|
||||
editor_widget = EditorWidget()
|
||||
|
||||
# Define a connection parameter dictionary.
|
||||
connection_dictionary = {"host": "localhost",
|
||||
"database": "postgres",
|
||||
"port": 5432,
|
||||
"user": "testuser"}
|
||||
|
||||
# Get a database connection related to the parameters in the connection dictionary.
|
||||
database_connection = global_connection_factory.get_database_connection(connection_dictionary["host"],
|
||||
connection_dictionary["user"],
|
||||
connection_dictionary["database"],
|
||||
connection_dictionary["port"])
|
||||
|
||||
# Set the database connection of the editor based on the connection dictionary.
|
||||
editor_widget.set_connection_based_on_parameters(connection_dictionary)
|
||||
|
||||
# After a successful set of a database connection, the data list of the table model should still be empty and
|
||||
# without an error message.
|
||||
assert editor_widget.table_model.data_list == []
|
||||
# The database connection of the editor should be the connection based on the connection dictionary.
|
||||
assert editor_widget.current_database_connection == database_connection
|
||||
|
||||
def test_invalid_set_connection_based_on_parameters(self):
|
||||
"""
|
||||
Test the method for setting connection parameters based on parameters in a dictionary with invalid connection
|
||||
parameters.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QWidget.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an editor widget.
|
||||
editor_widget = EditorWidget()
|
||||
|
||||
# Define a connection parameter dictionary. The host parameter is an invalid parameter.
|
||||
connection_dictionary = {"host": "localhorst",
|
||||
"database": "postgres",
|
||||
"port": 5432,
|
||||
"user": "testuser"}
|
||||
|
||||
# Try to set the connection with the function for setting a database connection.
|
||||
editor_widget.set_connection_based_on_parameters(connection_dictionary)
|
||||
|
||||
# After a failed set of a database connection, there should be a warning in the table model.
|
||||
assert editor_widget.table_model.data_list != []
|
||||
# The current database connection should be None after this kind of failure.
|
||||
assert editor_widget.current_database_connection is None
|
||||
|
||||
def test_refresh_table_model(self):
|
||||
"""
|
||||
Test the method for refreshing the table model of the editor.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QWidget.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an editor widget.
|
||||
editor_widget = EditorWidget()
|
||||
|
||||
# Define a list with new data.
|
||||
new_data_list = [["column 1, column 2"], (1, "row A", "row B"), (2, "row C", "row D")]
|
||||
# Use the function for refreshing the data list of the table model.
|
||||
editor_widget.refresh_table_model(new_data_list)
|
||||
# The data list of the table model should be the new data list.
|
||||
assert editor_widget.table_model.data_list == new_data_list
|
||||
|
||||
def test_save_current_statement_in_file(self):
|
||||
"""
|
||||
Test the function for saving the current statement in a file. User input is not necessary, because the file for
|
||||
saving is predefined.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QWidget.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an editor widget.
|
||||
editor_widget = EditorWidget()
|
||||
|
||||
# Define a test text.
|
||||
test_text = "This is a text for testing."
|
||||
# Set the text as text of the query input editor for saving.
|
||||
editor_widget.query_input_editor.setText(test_text)
|
||||
|
||||
# Define a test path.
|
||||
test_path = os.path.join(os.path.expanduser("~"), '.pygadmin_test')
|
||||
# Create the test path.
|
||||
os.mkdir(test_path)
|
||||
# Define a test file.
|
||||
test_file = os.path.join(test_path, "test_file.txt")
|
||||
|
||||
# Use the test file as file for saving in the editor.
|
||||
editor_widget.corresponding_saved_file = test_file
|
||||
# Save the current statement and text of the query input editor in the pre defined test file.
|
||||
editor_widget.save_current_statement_in_file()
|
||||
|
||||
# Open the test file.
|
||||
with open(test_file, "r") as test_file:
|
||||
# Get the text of the file, which should be the currently saved text.
|
||||
saved_editor_text = test_file.read()
|
||||
|
||||
# Remove the file and the path as a clean up.
|
||||
os.remove(test_file.name)
|
||||
os.rmdir(test_path)
|
||||
|
||||
# Check the text: The inserted text in the editor should be the text, which is saved in the file.
|
||||
assert test_text == saved_editor_text
|
||||
|
||||
def test_is_editor_empty(self):
|
||||
"""
|
||||
Test the method for an editor check: Is the editor empty or not?
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QWidget.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an editor widget.
|
||||
editor_widget = EditorWidget()
|
||||
|
||||
# After creating the widget, it should be empty.
|
||||
assert editor_widget.is_editor_empty() is True
|
||||
|
||||
# Set a text to the editor, so it is not empty anymore.
|
||||
editor_widget.query_input_editor.setText("Test Text")
|
||||
# The method should now return False.
|
||||
assert editor_widget.is_editor_empty() is False
|
||||
|
||||
# Set also an title to the editor widget.
|
||||
editor_widget.setWindowTitle("Test Title")
|
||||
# The method should still return False, because the editor is not empty.
|
||||
assert editor_widget.is_editor_empty() is False
|
||||
|
||||
# Set the text of the editor back to an empty string.
|
||||
editor_widget.query_input_editor.setText("")
|
||||
# Set the text to a string with content.
|
||||
editor_widget.setWindowTitle("Test Title")
|
||||
# The editor widget should not be empty.
|
||||
assert editor_widget.is_editor_empty() is False
|
||||
|
||||
def test_get_connection_status_string_for_window_title(self):
|
||||
"""
|
||||
Test the method for determining the connection part of the window title based on the different kinds of
|
||||
connections and their validity.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QWidget.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an editor widget.
|
||||
editor_widget = EditorWidget()
|
||||
|
||||
# After the creation of the editor widget, the connection status string should be an empty string.
|
||||
assert editor_widget.get_connection_status_string_for_window_title() == ""
|
||||
|
||||
# Set the database connection of the editor to False for simulating a failed database connection.
|
||||
editor_widget.current_database_connection = False
|
||||
# Now there should be an alert to a failed connection.
|
||||
assert editor_widget.get_connection_status_string_for_window_title() == "Connection failed: None"
|
||||
|
||||
# Simulate a valid database connection with setting it to True.
|
||||
editor_widget.current_database_connection = True
|
||||
# Define an identifier for the connection simulation.
|
||||
test_identifier = "Test identifier"
|
||||
# Set the test identifier as connection identifier of the editor.
|
||||
editor_widget.connection_identifier = test_identifier
|
||||
# The connection string for the window title should be the connection identifier for a valid database
|
||||
# connection.
|
||||
assert editor_widget.get_connection_status_string_for_window_title() == test_identifier
|
||||
|
||||
def test_get_corresponding_file_name_string_for_window_title_and_description(self):
|
||||
"""
|
||||
Test the method for getting the name of the file save path for the editor to set the correct window title.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QWidget.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an editor widget.
|
||||
editor_widget = EditorWidget()
|
||||
|
||||
# After the creation and without a corresponding saved file, the method should return a tuple of empty strings.
|
||||
assert editor_widget.get_corresponding_file_name_string_for_window_title_and_description() == ("", "")
|
||||
|
||||
# Define a path for the test save file.
|
||||
save_file_path = "test/testfile/"
|
||||
# Define a name for the test save file.
|
||||
save_file_name = "test.sql"
|
||||
# Create a full path with path and name together.
|
||||
full_save_file_path = "{}{}".format(save_file_path, save_file_name)
|
||||
# Set the full path as corresponding saved file for simulating the behavior of a QFileDialog.
|
||||
editor_widget.corresponding_saved_file = full_save_file_path
|
||||
|
||||
# Now the output should be the name of the file and the full path.
|
||||
assert editor_widget.get_corresponding_file_name_string_for_window_title_and_description() == (
|
||||
save_file_name, full_save_file_path)
|
||||
|
||||
def test_get_file_save_status_string_for_window_title(self):
|
||||
"""
|
||||
Test the method for checking the current status of the text in the query input editor of the editor compared to
|
||||
its last saved version.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QWidget.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an editor widget.
|
||||
editor_widget = EditorWidget()
|
||||
|
||||
# The text in the editor should empty, so there should not be a change. The file save string should be empty.
|
||||
assert editor_widget.get_file_save_status_string_for_window_title() == ""
|
||||
|
||||
# Set a text to the editor, so the initial text has changed.
|
||||
editor_widget.query_input_editor.setText("Test text")
|
||||
# After the text change, there should be the information about it in the file save string.
|
||||
assert editor_widget.get_file_save_status_string_for_window_title() == " (*)"
|
||||
|
||||
def test_get_query_in_input_editor(self):
|
||||
# Create an app, because this is necessary for testing a QWidget.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an editor widget.
|
||||
editor_widget = EditorWidget()
|
||||
|
||||
# Define a start text for testing, so this text can be chosen for a plain and simple selection later.
|
||||
test_text_start = "Test"
|
||||
# Define an end text for testing.
|
||||
test_text_end = " Text"
|
||||
# Put the two strings together as test text.
|
||||
test_text = "{}{}".format(test_text_start, test_text_end)
|
||||
# Set the test text as text of the query input editor.
|
||||
editor_widget.query_input_editor.setText(test_text)
|
||||
|
||||
# The query in the query input editor should be the test text.
|
||||
assert editor_widget.get_query_in_input_editor() == test_text
|
||||
|
||||
# Set the selection to the test text start.
|
||||
editor_widget.query_input_editor.setSelection(0, 0, 0, len(test_text_start))
|
||||
# Now the function for getting the query should return the test text start.
|
||||
assert editor_widget.get_query_in_input_editor() == test_text_start
|
||||
|
110
tests/test_editor_appearance_settings.py
Normal file
110
tests/test_editor_appearance_settings.py
Normal file
@@ -0,0 +1,110 @@
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
|
||||
from pygadmin.widgets.editor_appearance_settings import EditorAppearanceSettingsDialog
|
||||
from pygadmin.configurator import global_app_configurator
|
||||
|
||||
|
||||
class TestEditorAppearanceSettingsDialogMethods(unittest.TestCase):
|
||||
"""
|
||||
Test the functionality and methods of the editor appearance settings dialog.
|
||||
"""
|
||||
|
||||
def test_initial_attributes(self):
|
||||
"""
|
||||
Test the existence and correct instance of some initial attributes.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an editor appearance settings dialog.
|
||||
settings_dialog = EditorAppearanceSettingsDialog()
|
||||
|
||||
# Check for the dictionary with the GUI items.
|
||||
assert isinstance(settings_dialog.color_items_dictionary, dict)
|
||||
# Check for the dictionary with the currently existing color themes.
|
||||
assert isinstance(settings_dialog.current_color_themes_dictionary, dict)
|
||||
|
||||
def test_set_selected_item_in_list_widget(self):
|
||||
"""
|
||||
Test the method for selecting a theme with the given name.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an editor appearance settings dialog.
|
||||
settings_dialog = EditorAppearanceSettingsDialog()
|
||||
|
||||
# The theme "Hack" should be available as hard coded theme in the global app configurator.
|
||||
item_to_select = "Hack"
|
||||
# Select the item in the settings dialog.
|
||||
settings_dialog.set_selected_item_in_list_widget(item_to_select)
|
||||
# Get the selected item out of the list of selected items.
|
||||
selected_item = settings_dialog.current_themes_list_widget.selectedItems()[0]
|
||||
# The item to selected and the text of the selected item should be the same.
|
||||
assert item_to_select == selected_item.text()
|
||||
|
||||
def test_get_selected_item_in_list_widget(self):
|
||||
"""
|
||||
Test the function for getting the selected item of the list widget as attribute of the dialog.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an editor appearance settings dialog.
|
||||
settings_dialog = EditorAppearanceSettingsDialog()
|
||||
|
||||
# Clear the selection of the settings dialog. If there is a default theme, the default theme is selected.
|
||||
settings_dialog.current_themes_list_widget.selectionModel().clearSelection()
|
||||
|
||||
# After clearing the selection, the method for getting the selected item should return False, because there is
|
||||
# no selected item.
|
||||
assert settings_dialog.get_selected_item_in_list_widget() is False
|
||||
# The selected list widget item should be None, because there is no selection.
|
||||
assert settings_dialog.selected_list_widget_item is None
|
||||
|
||||
# Choose an item for selecting.
|
||||
item_to_select = "Hack"
|
||||
# Set the selected item in the list widget.
|
||||
settings_dialog.set_selected_item_in_list_widget(item_to_select)
|
||||
|
||||
# Now there should be a selected item in the list widget, so the function returns True.
|
||||
assert settings_dialog.get_selected_item_in_list_widget() is True
|
||||
# The selected item in the list widget should be the item to select.
|
||||
assert settings_dialog.selected_list_widget_item == item_to_select
|
||||
|
||||
def test_save_changes_in_configuration_and_apply(self):
|
||||
"""
|
||||
Test the function for changing the current saves.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an editor appearance settings dialog.
|
||||
settings_dialog = EditorAppearanceSettingsDialog()
|
||||
|
||||
# The function should return True for a successful save.
|
||||
assert settings_dialog.save_changes_in_configuration_and_apply() is True
|
||||
|
||||
def test_set_default_theme(self):
|
||||
"""
|
||||
Test the method for setting a new default theme.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an editor appearance settings dialog.
|
||||
settings_dialog = EditorAppearanceSettingsDialog()
|
||||
|
||||
# Choose an item for selecting.
|
||||
item_to_select = "Hack"
|
||||
# Set the selected item in the list widget.
|
||||
settings_dialog.set_selected_item_in_list_widget(item_to_select)
|
||||
|
||||
# Set the default theme. The selected theme is now the default theme.
|
||||
settings_dialog.set_default_theme()
|
||||
|
||||
# The default theme in the settings dialog should be saved in the global app configurator.
|
||||
assert settings_dialog.default_theme == global_app_configurator.get_single_configuration("color_theme")
|
73
tests/test_lexer.py
Normal file
73
tests/test_lexer.py
Normal file
@@ -0,0 +1,73 @@
|
||||
import unittest
|
||||
|
||||
from PyQt5.QtGui import QColor
|
||||
|
||||
from pygadmin.models.lexer import SQLLexer
|
||||
|
||||
|
||||
class TestLexerMethods(unittest.TestCase):
|
||||
"""
|
||||
Use a class for testing the SQLLexer and its methods.
|
||||
"""
|
||||
|
||||
def test_lexer_color_parameters_dictionary(self):
|
||||
"""
|
||||
Check the color parameter dictionary of the lexer, which should be not empty.
|
||||
"""
|
||||
|
||||
lexer = SQLLexer(None)
|
||||
|
||||
assert lexer.color_parameters_dictionary != {}
|
||||
|
||||
def test_qcolor_lexer(self):
|
||||
"""
|
||||
Check the correct instance of the color in the color parameter dictionary of the lexer.
|
||||
"""
|
||||
|
||||
lexer = SQLLexer(None)
|
||||
|
||||
for value in lexer.color_parameters_dictionary.values():
|
||||
assert isinstance(value, QColor)
|
||||
|
||||
def test_correct_color_parameter_keys(self):
|
||||
"""
|
||||
Check for the right keys in the color parameter dictionary of the lexer.
|
||||
"""
|
||||
|
||||
lexer = SQLLexer(None)
|
||||
# Define the relevant color keys.
|
||||
color_keys = ["default_color", "default_paper_color", "keyword_color", "number_color", "other_keyword_color",
|
||||
"apostrophe_color"]
|
||||
|
||||
# Check every necessary key for its existence.
|
||||
for color in color_keys:
|
||||
assert lexer.color_parameters_dictionary[color]
|
||||
|
||||
def test_set_color(self):
|
||||
"""
|
||||
Test the method of the lexer for setting a color defined by a color dictionary with the color keyword and a
|
||||
QColor for testing the color set.
|
||||
"""
|
||||
|
||||
lexer = SQLLexer(None)
|
||||
# Define a color dictionary with tests.
|
||||
color_dictionary = {"default_color": QColor("ff0000ff"),
|
||||
"default_paper_color": QColor("#ffffff00"),
|
||||
"keyword_color": QColor("#ff00000f"),
|
||||
"number_color": QColor("#ff000f0f"),
|
||||
"other_keyword_color": QColor("#ff0f0f00"),
|
||||
"apostrophe_color": QColor("#ff0f0000")
|
||||
}
|
||||
|
||||
# Set the colors in the lexer.
|
||||
lexer.set_lexer_colors(color_dictionary)
|
||||
|
||||
# Check, if every color has been set properly.
|
||||
assert color_dictionary["default_color"].name() == lexer.defaultColor(10).name()
|
||||
assert color_dictionary["default_paper_color"].name() == lexer.defaultPaper(0).name()
|
||||
assert color_dictionary["default_paper_color"].name() == lexer.color(0).name()
|
||||
assert color_dictionary["keyword_color"].name() == lexer.color(5).name()
|
||||
assert color_dictionary["number_color"].name() == lexer.color(4).name()
|
||||
assert color_dictionary["other_keyword_color"].name() == lexer.color(8).name()
|
||||
assert color_dictionary["apostrophe_color"].name() == lexer.color(7).name()
|
||||
|
206
tests/test_main_window.py
Normal file
206
tests/test_main_window.py
Normal file
@@ -0,0 +1,206 @@
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from PyQt5.QtWidgets import QApplication, QMdiArea, QDockWidget, QMenuBar, QToolBar
|
||||
|
||||
from pygadmin.widgets.main_window import MainWindow
|
||||
from pygadmin.widgets.connection_dialog import ConnectionDialogWidget
|
||||
from pygadmin.widgets.configuration_settings import ConfigurationSettingsDialog
|
||||
from pygadmin.widgets.editor_appearance_settings import EditorAppearanceSettingsDialog
|
||||
from pygadmin.widgets.version_information_dialog import VersionInformationDialog
|
||||
from pygadmin.configurator import global_app_configurator
|
||||
|
||||
|
||||
class TestMainWindowMethods(unittest.TestCase):
|
||||
"""
|
||||
Test the functionality and methods of the main window.
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def set_opening_connection_dialog_to_false():
|
||||
"""
|
||||
Set the configuration for opening a connection dialog at the start of the application/main window to False, so
|
||||
a connection dialog is not displayed.
|
||||
"""
|
||||
|
||||
global_app_configurator.set_single_configuration("open_connection_dialog_at_start", False)
|
||||
|
||||
def test_initial_attributes(self):
|
||||
"""
|
||||
Test the existence and correct instance of some initial attributes.
|
||||
"""
|
||||
|
||||
self.set_opening_connection_dialog_to_false()
|
||||
# Create an app, because this is necessary for testing a QMainWindow.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a main window.
|
||||
main_window = MainWindow()
|
||||
|
||||
# The MdiArea of the main window should be a QMdiArea.
|
||||
assert isinstance(main_window.mdi_area, QMdiArea)
|
||||
# The central widget should be the mdi area.
|
||||
assert main_window.centralWidget() == main_window.mdi_area
|
||||
# The sub window list of the mdi area should contain one item, because there is one editor at the start.
|
||||
assert len(main_window.mdi_area.subWindowList()) == 1
|
||||
|
||||
# The dock widget should be a QDockWidget.
|
||||
assert isinstance(main_window.dock_widget, QDockWidget)
|
||||
|
||||
# The menu bar should be a QMenuBar.
|
||||
assert isinstance(main_window.menu_bar, QMenuBar)
|
||||
# The tool bar should be a QToolBar.
|
||||
assert isinstance(main_window.tool_bar, QToolBar)
|
||||
|
||||
# The status bar should show the message "Ready" at the start.
|
||||
assert main_window.statusBar().currentMessage() == "Ready"
|
||||
|
||||
def test_add_action_to_menu_bar(self):
|
||||
"""
|
||||
Test the correct appending of an action to the menu bar. In this case, the edit menu point is used.
|
||||
"""
|
||||
|
||||
self.set_opening_connection_dialog_to_false()
|
||||
# Create an app, because this is necessary for testing a QMainWindow.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a main window.
|
||||
main_window = MainWindow()
|
||||
|
||||
# Define a name for the new action.
|
||||
new_action_name = "test"
|
||||
|
||||
# The name of the new action should not be the name of an existing action.
|
||||
for action in main_window.edit_menu.actions():
|
||||
assert action.text() != new_action_name
|
||||
|
||||
# Add the action with the new name and a simple test function to the menu bar. Without a menu, the edit menu is
|
||||
# used.
|
||||
main_window.add_action_to_menu_bar(new_action_name, lambda: print("test"))
|
||||
|
||||
# Check for an action with the name of the new action. The result should be one item, because there is one item
|
||||
# with the name of the new action: The new action.
|
||||
matching_action = [action.text() for action in main_window.edit_menu.actions()
|
||||
if action.text() == new_action_name]
|
||||
|
||||
# The list should contain one element.
|
||||
assert len(matching_action) == 1
|
||||
|
||||
def test_add_action_to_tool_bar(self):
|
||||
"""
|
||||
Test the correct appending of an action to the tool bar.
|
||||
"""
|
||||
|
||||
self.set_opening_connection_dialog_to_false()
|
||||
# Create an app, because this is necessary for testing a QMainWindow.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a main window.
|
||||
main_window = MainWindow()
|
||||
|
||||
# Define a name for the new action.
|
||||
new_action_name = "test"
|
||||
|
||||
# The name of the new action should be unique, so there should not be an action with its text/name.
|
||||
for action in main_window.tool_bar.actions():
|
||||
assert new_action_name != action.text()
|
||||
|
||||
# Add the new action to the tool bar. The path for the icon is an invalid test path and the function is only a
|
||||
# simple test function.
|
||||
main_window.add_action_to_tool_bar(new_action_name, "test_path", lambda: print("test"))
|
||||
|
||||
# Check for an action with the name of the new action. The result should be one item, because there is one item
|
||||
# with the name of the new action: The new action.
|
||||
matching_action = [action.text() for action in main_window.tool_bar.actions()
|
||||
if action.text() == new_action_name]
|
||||
|
||||
# The resulting list should contain one element.
|
||||
assert len(matching_action) == 1
|
||||
|
||||
def test_activate_new_connection_dialog(self):
|
||||
"""
|
||||
Test the activation of a new connection dialog.
|
||||
"""
|
||||
|
||||
self.set_opening_connection_dialog_to_false()
|
||||
# Create an app, because this is necessary for testing a QMainWindow.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a main window.
|
||||
main_window = MainWindow()
|
||||
|
||||
# Activate a new connection dialog.
|
||||
main_window.activate_new_connection_dialog()
|
||||
# The new connection dialog should be a connection dialog.
|
||||
assert isinstance(main_window.new_connection_dialog, ConnectionDialogWidget)
|
||||
# The new connection dialog should be visible, because it is active.
|
||||
assert main_window.new_connection_dialog.isVisible() is True
|
||||
|
||||
def test_activate_new_configuration_settings_dialog(self):
|
||||
"""
|
||||
Test the activation of a new configuration settings dialog.
|
||||
"""
|
||||
|
||||
self.set_opening_connection_dialog_to_false()
|
||||
# Create an app, because this is necessary for testing a QMainWindow.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a main window.
|
||||
main_window = MainWindow()
|
||||
|
||||
# Activate a new configuration settings dialog.
|
||||
main_window.activate_new_configuration_settings_dialog()
|
||||
# The new dialog should have the correct type.
|
||||
assert isinstance(main_window.configuration_settings_dialog, ConfigurationSettingsDialog)
|
||||
# The dialog should be visible/active.
|
||||
assert main_window.configuration_settings_dialog.isVisible() is True
|
||||
|
||||
def test_activate_new_editor_appearance_dialog(self):
|
||||
""""
|
||||
Test the activation of a new editor appearance dialog.
|
||||
"""
|
||||
|
||||
self.set_opening_connection_dialog_to_false()
|
||||
# Create an app, because this is necessary for testing a QMainWindow.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a main window.
|
||||
main_window = MainWindow()
|
||||
|
||||
# Activate a new editor appearance settings dialog.
|
||||
main_window.activate_new_editor_appearance_dialog()
|
||||
# The new dialog should have the correct type.
|
||||
assert isinstance(main_window.editor_appearance_dialog, EditorAppearanceSettingsDialog)
|
||||
# The dialog should be visible/active.
|
||||
assert main_window.editor_appearance_dialog.isVisible() is True
|
||||
|
||||
def test_show_status_bar_message(self):
|
||||
"""
|
||||
Test the function for showing a new status bar message.
|
||||
"""
|
||||
|
||||
self.set_opening_connection_dialog_to_false()
|
||||
# Create an app, because this is necessary for testing a QMainWindow.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a main window.
|
||||
main_window = MainWindow()
|
||||
|
||||
# Define a new message for the status bar.
|
||||
new_message = "test"
|
||||
# Set the message in the status bar.
|
||||
main_window.show_status_bar_message(new_message)
|
||||
# The status bar message should be the new message.
|
||||
assert main_window.statusBar().currentMessage() == new_message
|
||||
|
||||
def test_show_version_information_dialog(self):
|
||||
""""
|
||||
Test the activation of a new version information dialog.
|
||||
"""
|
||||
|
||||
self.set_opening_connection_dialog_to_false()
|
||||
# Create an app, because this is necessary for testing a QMainWindow.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a main window.
|
||||
main_window = MainWindow()
|
||||
|
||||
# Show a new version information dialog.
|
||||
main_window.show_version_information_dialog()
|
||||
# The new dialog should have the correct type.
|
||||
assert isinstance(main_window.version_information_dialog, VersionInformationDialog)
|
||||
# The dialog should be visible/active.
|
||||
assert main_window.version_information_dialog.isVisible() is True
|
||||
|
167
tests/test_mdi_area.py
Normal file
167
tests/test_mdi_area.py
Normal file
@@ -0,0 +1,167 @@
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
|
||||
from pygadmin.widgets.mdi_area import MdiArea
|
||||
from pygadmin.widgets.editor import EditorWidget
|
||||
|
||||
from pygadmin.connectionfactory import global_connection_factory
|
||||
|
||||
|
||||
class TestMdiAreaMethods(unittest.TestCase):
|
||||
"""
|
||||
Test the functionality and methods of Mdi area.
|
||||
"""
|
||||
|
||||
def test_initial_attributes(self):
|
||||
"""
|
||||
Test the existence and correct instance of some initial attributes.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QMdiArea.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an MdiArea.
|
||||
mdi_area = MdiArea()
|
||||
|
||||
# The tabs in the MdiArea should be movable.
|
||||
assert mdi_area.tabsMovable() is True
|
||||
# The tabs in the MdiArea should be closable.
|
||||
assert mdi_area.tabsClosable() is True
|
||||
# The view mode should be 1, which is the tab view.
|
||||
assert mdi_area.viewMode() == 1
|
||||
|
||||
def test_generate_editor_widget(self):
|
||||
"""
|
||||
Test the correct generating process of an editor in the MdiArea.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QMdiArea.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an MdiArea.
|
||||
mdi_area = MdiArea()
|
||||
|
||||
# Generate an editor, which is also the return value of the function.
|
||||
generated_editor = mdi_area.generate_editor_tab()
|
||||
# The generated editor should be an editor widget.
|
||||
assert isinstance(generated_editor, EditorWidget)
|
||||
|
||||
# Get the widgets of the sub windows of the MdiArea as list.
|
||||
widget_list = [sub_window.widget() for sub_window in mdi_area.subWindowList()]
|
||||
# The generated editor should be in the widget list.
|
||||
assert generated_editor in widget_list
|
||||
|
||||
def test_change_current_sub_window_and_connection_parameters(self):
|
||||
"""
|
||||
Test the method for setting new database connection parameters in case of an editor change in the MdiArea.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QMdiArea.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an MdiArea.
|
||||
mdi_area = MdiArea()
|
||||
|
||||
# Generate an editor, so there is a current sub window.
|
||||
generated_editor = mdi_area.generate_editor_tab()
|
||||
# Define a dictionary with connection parameters.
|
||||
connection_parameters = {"host": "localhost",
|
||||
"user": "testuser",
|
||||
"database": "testdb",
|
||||
"port": 5432}
|
||||
|
||||
# Set the connection parameters.
|
||||
mdi_area.change_current_sub_window_and_connection_parameters(connection_parameters)
|
||||
# Get the current connection of the editor.
|
||||
editor_connection = generated_editor.current_database_connection
|
||||
# Get the connection dictionary related to the connection of the editor.
|
||||
editor_connection_parameters = global_connection_factory.get_database_connection_parameters(editor_connection)
|
||||
# The connection parameters of the editor should be identical to the initial connection parameters.
|
||||
assert editor_connection_parameters == connection_parameters
|
||||
|
||||
def test_determine_current_editor_widget(self):
|
||||
"""
|
||||
Test the method for determining the current editor widget.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QMdiArea.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an MdiArea.
|
||||
mdi_area = MdiArea()
|
||||
|
||||
# Right after the initialization and without any editor widget, the function for determining the current editor
|
||||
# widget should return None.
|
||||
assert mdi_area.determine_current_editor_widget() is None
|
||||
|
||||
# Generate a new editor tab.
|
||||
generated_editor = mdi_area.generate_editor_tab()
|
||||
# The current editor widget should be the freshly generated editor.
|
||||
assert mdi_area.determine_current_editor_widget() == generated_editor
|
||||
|
||||
def test_determine_empty_editor_widget_with_connection(self):
|
||||
"""
|
||||
Test the method for getting an empty editor widget with a given database connection.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QMdiArea.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an MdiArea.
|
||||
mdi_area = MdiArea()
|
||||
|
||||
# Generate a new editor tab.
|
||||
editor_widget = mdi_area.generate_editor_tab()
|
||||
|
||||
# Define a dictionary with connection parameters for the freshly generated editor widget.
|
||||
first_connection_parameters = {"host": "localhost",
|
||||
"user": "testuser",
|
||||
"database": "testdb",
|
||||
"port": 5432}
|
||||
|
||||
# Get a connection based on the dictionary with connection parameters.
|
||||
connection = global_connection_factory.get_database_connection(first_connection_parameters["host"],
|
||||
first_connection_parameters["user"],
|
||||
first_connection_parameters["database"],
|
||||
first_connection_parameters["port"])
|
||||
|
||||
# Set the new connection as current connection of the generated editor widget.
|
||||
editor_widget.current_database_connection = connection
|
||||
# The editor with the database connection should be the generated editor_widget.
|
||||
assert mdi_area.determine_empty_editor_widget_with_connection(first_connection_parameters) == editor_widget
|
||||
|
||||
# Define a second dictionary with different connection parameters.
|
||||
second_connection_parameters = {"host": "localhost",
|
||||
"user": "testuser",
|
||||
"database": "postgres",
|
||||
"port": 5432}
|
||||
|
||||
# A new generated widget with new connection parameters should not be the first generated editor widget.
|
||||
assert mdi_area.determine_empty_editor_widget_with_connection(second_connection_parameters) != editor_widget
|
||||
|
||||
def test_determine_next_empty_editor_widget(self):
|
||||
"""
|
||||
Test the method for determining the next empty editor widget.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QMdiArea.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an MdiArea.
|
||||
mdi_area = MdiArea()
|
||||
|
||||
# After the initialization and without any editor widgets, the function should return None,
|
||||
assert mdi_area.determine_next_empty_editor_widget() is None
|
||||
|
||||
# Generate an editor widget.
|
||||
first_editor_widget = mdi_area.generate_editor_tab()
|
||||
# The generated widget should be an empty editor widget.
|
||||
assert mdi_area.determine_next_empty_editor_widget() == first_editor_widget
|
||||
|
||||
# Set a text to the editor widget, so it is not empty anymore.
|
||||
first_editor_widget.query_input_editor.setText("Not Empty")
|
||||
# There is only one widget and this widget is not empty, so the function for determining an empty editor widget
|
||||
# should return None.
|
||||
assert mdi_area.determine_next_empty_editor_widget() is None
|
||||
|
||||
# Generate a new editor tab.
|
||||
second_editor_widget = mdi_area.generate_editor_tab()
|
||||
# The freshly generated widget should be the next empty editor widget.
|
||||
assert mdi_area.determine_next_empty_editor_widget() == second_editor_widget
|
||||
|
125
tests/test_node_create_information.py
Normal file
125
tests/test_node_create_information.py
Normal file
@@ -0,0 +1,125 @@
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
|
||||
from pygadmin.widgets.node_create_information import NodeCreateInformationDialog
|
||||
from pygadmin.models.treemodel import DatabaseNode, TableNode, ViewNode
|
||||
|
||||
|
||||
class TestNodeCreateInformationMethods(unittest.TestCase):
|
||||
"""
|
||||
Test the functionality and methods of node create information dialog.
|
||||
"""
|
||||
|
||||
def test_dialog_without_node(self):
|
||||
"""
|
||||
Test the reaction of the dialog to the input of None instead of a node.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an information dialog without a node.
|
||||
node_information_dialog = NodeCreateInformationDialog(None)
|
||||
|
||||
# The window title should assume an error.
|
||||
assert node_information_dialog.windowTitle() == "Node Input Error"
|
||||
|
||||
def test_dialog_with_valid_database_node(self):
|
||||
"""
|
||||
Test the node information dialog with a database node.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a database node for the dialog.
|
||||
database_node = DatabaseNode("testdb", "localhost", "testuser", "testdb", 5432, 10000)
|
||||
# Create an information dialog with the database node.
|
||||
node_information_dialog = NodeCreateInformationDialog(database_node)
|
||||
# The selected node should be the database node.
|
||||
assert node_information_dialog.selected_node == database_node
|
||||
|
||||
# Get the create statement of the node.
|
||||
create_statement = node_information_dialog.get_node_create_statement()
|
||||
self.check_create_statement(create_statement)
|
||||
|
||||
def test_dialog_with_valid_table_node(self):
|
||||
"""
|
||||
Test the node information dialog with a table node.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a table node for the dialog.
|
||||
table_node = TableNode("test", "localhost", "testuser", "testdb", 5432, 10000)
|
||||
# Create an information dialog with the table node.
|
||||
node_information_dialog = NodeCreateInformationDialog(table_node)
|
||||
# The selected node should be the table node.
|
||||
assert node_information_dialog.selected_node == table_node
|
||||
|
||||
# Get the create statement of the node.
|
||||
create_statement = node_information_dialog.get_node_create_statement()
|
||||
self.check_create_statement(create_statement)
|
||||
|
||||
def test_dialog_with_valid_view_node(self):
|
||||
"""
|
||||
Test the node information dialog with a view node.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a view node for the dialog.
|
||||
view_node = ViewNode("testview", "localhost", "testuser", "testdb", 5432, 10000)
|
||||
# Create an information dialog with view node.
|
||||
node_information_dialog = NodeCreateInformationDialog(view_node)
|
||||
# The selected node should be the view node.
|
||||
assert node_information_dialog.selected_node == view_node
|
||||
|
||||
# Get the create statement of the node.
|
||||
create_statement = node_information_dialog.get_node_create_statement()
|
||||
self.check_create_statement(create_statement)
|
||||
|
||||
def test_dialog_with_invalid_node(self):
|
||||
"""
|
||||
Test the dialog with an invalid database node as error case.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a database node with invalid connection parameters. In this case, the port is invalid.
|
||||
database_node = DatabaseNode("testdb", "localhost", "testuser", "testdb", 1337, 10000)
|
||||
node_information_dialog = NodeCreateInformationDialog(database_node)
|
||||
# The selected node should be the database node.
|
||||
assert node_information_dialog.selected_node == database_node
|
||||
# Get the create statement of the node.
|
||||
create_statement = node_information_dialog.get_node_create_statement()
|
||||
self.check_create_statement(create_statement)
|
||||
|
||||
@staticmethod
|
||||
def check_create_statement(create_statement):
|
||||
"""
|
||||
Define a method for checking the create statement of a node. The statement should contain at least one specified
|
||||
word in a list.
|
||||
"""
|
||||
|
||||
# The create statement should not be empty.
|
||||
assert create_statement != ""
|
||||
|
||||
# Define a list with possible sub strings for a create statement. The string "failed" is in the list for the
|
||||
# error case.
|
||||
statement_can_contain_list = ["\nWITH", "\nENCODING", "\nLC_COLLATE", "\nLC_CTYPE", "\nLC_TYPE", "\nALTER",
|
||||
"CREATE", "failed"]
|
||||
|
||||
# Define a boolean for checking the existence of a word in the list. This boolean is used in the for loop and
|
||||
# after the loop, it should be True.
|
||||
contains_string = False
|
||||
|
||||
# Check for the existence of at least one word of the list.
|
||||
for possible_string in statement_can_contain_list:
|
||||
# Check for the string, which could be part of the create statement.
|
||||
if possible_string in create_statement:
|
||||
# Change the check boolean to True.
|
||||
contains_string = True
|
||||
|
||||
# After iterating over the list with words, the boolean for checking should be True.
|
||||
assert contains_string is True
|
32
tests/test_permission_information.py
Normal file
32
tests/test_permission_information.py
Normal file
@@ -0,0 +1,32 @@
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
|
||||
from pygadmin.widgets.permission_information import PermissionInformationDialog
|
||||
from pygadmin.models.treemodel import DatabaseNode, TableNode
|
||||
|
||||
|
||||
class TestPermissionInformationMethods(unittest.TestCase):
|
||||
"""
|
||||
Test the functionality and methods of node create information dialog.
|
||||
"""
|
||||
|
||||
def test_dialog_without_node(self):
|
||||
"""
|
||||
Test the reaction of the dialog to the input of None instead of a node.
|
||||
"""
|
||||
|
||||
app = QApplication(sys.argv)
|
||||
permission_information_dialog = PermissionInformationDialog(None)
|
||||
assert permission_information_dialog.windowTitle() == "Node Input Error"
|
||||
|
||||
def test_dialog_with_node(self):
|
||||
"""
|
||||
Test the dialog with an existing node.
|
||||
"""
|
||||
|
||||
app = QApplication(sys.argv)
|
||||
database_node = DatabaseNode("testdb", "localhost", "testuser", "testdb", 5432, 10000)
|
||||
permission_information_dialog = PermissionInformationDialog(database_node)
|
||||
assert permission_information_dialog.selected_node == database_node
|
109
tests/test_search_replace_widget.py
Normal file
109
tests/test_search_replace_widget.py
Normal file
@@ -0,0 +1,109 @@
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
|
||||
from pygadmin.widgets.editor import EditorWidget
|
||||
from pygadmin.widgets.search_replace_widget import SearchReplaceWidget
|
||||
|
||||
|
||||
class TestSearchPlaceWidgetMethods(unittest.TestCase):
|
||||
"""
|
||||
Test the functionality and methods of the search replace widget.
|
||||
"""
|
||||
|
||||
def test_initial_attributes(self):
|
||||
"""
|
||||
Check for the correct existence and instance of the initial attributes of the search replace widget.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QWidget.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an editor widget as parent for the search replace dialog.
|
||||
editor_widget = EditorWidget()
|
||||
# Create a search replace dialog with the editor widget as a parent
|
||||
search_replace_widget = SearchReplaceWidget(editor_widget)
|
||||
|
||||
# The dictionaries with the search and replace items should exist as dictionaries.
|
||||
assert isinstance(search_replace_widget.search_items, dict)
|
||||
assert isinstance(search_replace_widget.replace_items, dict)
|
||||
|
||||
def test_hide_replace_components(self):
|
||||
"""
|
||||
Test the functionality of the method for hiding the replace components.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QWidget.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an editor widget as parent for the search replace dialog.
|
||||
editor_widget = EditorWidget()
|
||||
# Create a search replace dialog with the editor widget as a parent
|
||||
search_replace_widget = SearchReplaceWidget(editor_widget)
|
||||
# Hide the replace components.
|
||||
search_replace_widget.hide_replace_components()
|
||||
|
||||
# Check every component for hiding.
|
||||
for replace_item in search_replace_widget.replace_items.values():
|
||||
# The replace item should not be visible.
|
||||
assert replace_item.isVisible() is False
|
||||
|
||||
def test_show_replace_components(self):
|
||||
"""
|
||||
Test the method for showing the replace components.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QWidget.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an editor widget as parent for the search replace dialog.
|
||||
editor_widget = EditorWidget()
|
||||
# Create a search replace dialog with the editor widget as a parent
|
||||
search_replace_widget = SearchReplaceWidget(editor_widget)
|
||||
# Show the replace components.
|
||||
search_replace_widget.show_replace_components()
|
||||
|
||||
# Check every component for showing.
|
||||
for replace_item in search_replace_widget.replace_items.values():
|
||||
# The replace item should be visible.
|
||||
assert replace_item.isVisible() is True
|
||||
|
||||
def test_set_search_text(self):
|
||||
"""
|
||||
Test the method for setting the text of the search line edit.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QWidget.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an editor widget as parent for the search replace dialog.
|
||||
editor_widget = EditorWidget()
|
||||
# Create a search replace dialog with the editor widget as a parent
|
||||
search_replace_widget = SearchReplaceWidget(editor_widget)
|
||||
# Define a text for testing.
|
||||
test_text = "Test"
|
||||
# Set the test text.
|
||||
search_replace_widget.set_search_text(test_text)
|
||||
# The test text should be the text of the line edit.
|
||||
assert search_replace_widget.search_items["search_line_edit"].text() == test_text
|
||||
|
||||
def test_get_search_and_replace_text(self):
|
||||
"""
|
||||
Test the method for getting the current text of the search and the replace line edit.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QWidget.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an editor widget as parent for the search replace dialog.
|
||||
editor_widget = EditorWidget()
|
||||
# Create a search replace dialog with the editor widget as a parent
|
||||
search_replace_widget = SearchReplaceWidget(editor_widget)
|
||||
# Define a text for testing.
|
||||
test_text = "Test"
|
||||
|
||||
# Set the text for testing as text of the search line edit.
|
||||
search_replace_widget.search_items["search_line_edit"].setText(test_text)
|
||||
# Now the method for getting the search text should return the test text.
|
||||
assert search_replace_widget.get_search_text() == test_text
|
||||
|
||||
# Set the text for testing as text of the replace line edit.
|
||||
search_replace_widget.replace_items["replace_line_edit"].setText(test_text)
|
||||
# Now the method for getting the replace text should return the test text.
|
||||
assert search_replace_widget.get_replace_text() == test_text
|
47
tests/test_start.py
Normal file
47
tests/test_start.py
Normal file
@@ -0,0 +1,47 @@
|
||||
import unittest
|
||||
import signal
|
||||
import sys
|
||||
|
||||
import faulthandler
|
||||
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
|
||||
from pygadmin.widgets.main_window import MainWindow
|
||||
|
||||
faulthandler.enable()
|
||||
|
||||
|
||||
class TestStartMethods(unittest.TestCase):
|
||||
"""
|
||||
Test the correct start of the application.
|
||||
"""
|
||||
|
||||
def test_start(self):
|
||||
"""
|
||||
Simulate the start of the application like in the main function in __init__.py, but without app.exec(), so a
|
||||
user does not have to end the application manually.
|
||||
"""
|
||||
|
||||
# Define easier ending of the application.
|
||||
signal.signal(signal.SIGINT, signal.SIG_DFL)
|
||||
# Define an app.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a main window.
|
||||
main_window = MainWindow()
|
||||
# Show the main window, but the application just ends.
|
||||
main_window.show()
|
||||
|
||||
def test_start_multiple_times(self):
|
||||
"""
|
||||
Simulate the start multiple times.
|
||||
"""
|
||||
|
||||
for i in range(500):
|
||||
print("Start test {}".format(i))
|
||||
self.test_start()
|
||||
print("Still alive")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
102
tests/test_start_progress_dialog.py
Normal file
102
tests/test_start_progress_dialog.py
Normal file
@@ -0,0 +1,102 @@
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from PyQt5.QtCore import QBasicTimer
|
||||
from PyQt5.QtWidgets import QApplication, QProgressBar, QLabel
|
||||
|
||||
from pygadmin.widgets.start_progress_dialog import StartProgressDialog
|
||||
from pygadmin.connectionstore import global_connection_store
|
||||
|
||||
|
||||
class TestStartProgressDialogMethods(unittest.TestCase):
|
||||
"""
|
||||
Test the functionality and behavior of the start progress dialog.
|
||||
"""
|
||||
|
||||
def test_initial_attributes(self):
|
||||
"""
|
||||
Test the initial attributes of the dialog.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a start progress dialog.
|
||||
start_progress_dialog = StartProgressDialog()
|
||||
|
||||
# There should be a progress bar, because this is the whole idea of having a start progress dialog.
|
||||
assert isinstance(start_progress_dialog.progress_bar, QProgressBar)
|
||||
# There should also be a description label, informing about the current process.
|
||||
assert isinstance(start_progress_dialog.description_label, QLabel)
|
||||
# A timer is required for the functionality of the progress bar.
|
||||
assert isinstance(start_progress_dialog.timer, QBasicTimer)
|
||||
# The step at the beginning should be 0.
|
||||
assert start_progress_dialog.float_step == 0
|
||||
|
||||
def test_progress_bar_with_zero_connections(self):
|
||||
"""
|
||||
Test the functionality of the progress bar without connections in the connection store.
|
||||
"""
|
||||
|
||||
# Make a copy of the current connection list for storing it.
|
||||
connection_list = global_connection_store.get_connection_parameters_from_yaml_file()
|
||||
# Set the current list to an empty list.
|
||||
global_connection_store.connection_parameters_yaml = []
|
||||
# Delete all connections and store the empty list.
|
||||
global_connection_store.commit_current_list_to_yaml()
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a start progress dialog.
|
||||
start_progress_dialog = StartProgressDialog()
|
||||
|
||||
# Start the progress bar without connections.
|
||||
start_progress_dialog.start_progress_bar()
|
||||
|
||||
# Now the float step and the step size should be 100.
|
||||
assert start_progress_dialog.float_step == 100
|
||||
assert start_progress_dialog.step_size == 100
|
||||
|
||||
# Restore the connection list.
|
||||
global_connection_store.connection_parameters_yaml = connection_list
|
||||
global_connection_store.commit_current_list_to_yaml()
|
||||
|
||||
def test_progress_bar_with_connections(self):
|
||||
"""
|
||||
Test the progress bar with existing connections.
|
||||
"""
|
||||
|
||||
# Define one dictionary for one connection.
|
||||
first_connection_dictionary = {"Host": "testhost",
|
||||
"Username": "testuser",
|
||||
"Database": "postgres",
|
||||
"Port": 5432}
|
||||
|
||||
# Define another dictionary for a second connection.
|
||||
second_connection_dictionary = {"Host": "anothertesthost",
|
||||
"Username": "testuser",
|
||||
"Database": "postgres",
|
||||
"Port": 5432}
|
||||
|
||||
# Load the current connections.
|
||||
global_connection_store.get_connection_parameters_from_yaml_file()
|
||||
# Insert the pre-defined dictionaries to the connection store, so there are at least two dictionaries.
|
||||
global_connection_store.save_connection_parameters_in_yaml_file(first_connection_dictionary)
|
||||
global_connection_store.save_connection_parameters_in_yaml_file(second_connection_dictionary)
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a start progress dialog.
|
||||
start_progress_dialog = StartProgressDialog()
|
||||
|
||||
# Start the progress bar.
|
||||
start_progress_dialog.start_progress_bar()
|
||||
|
||||
# Now the step should be start at 0.
|
||||
assert start_progress_dialog.float_step == 0
|
||||
# The step size should be smaller than 100, because there are at least two connection parameters in the global
|
||||
# connection store.
|
||||
assert start_progress_dialog.step_size < 100
|
||||
|
||||
# Clean up, delete the two created connections.
|
||||
global_connection_store.delete_connection(first_connection_dictionary)
|
||||
global_connection_store.delete_connection(second_connection_dictionary)
|
146
tests/test_table_edit.py
Normal file
146
tests/test_table_edit.py
Normal file
@@ -0,0 +1,146 @@
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
|
||||
from pygadmin.models.treemodel import TableNode
|
||||
from pygadmin.widgets.table_edit import TableEditDialog
|
||||
from pygadmin.configurator import global_app_configurator
|
||||
|
||||
|
||||
class TestTableEditDialogMethods(unittest.TestCase):
|
||||
"""
|
||||
Test the basic methods and the behavior of the table edit dialog.
|
||||
"""
|
||||
|
||||
def test_dialog_without_node(self):
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
|
||||
# Add None instead of a node to the dialog.
|
||||
table_edit_dialog = TableEditDialog(None)
|
||||
# The window title of the dialog should be a string with an error.
|
||||
assert table_edit_dialog.windowTitle() == "Node Input Error"
|
||||
|
||||
def test_initial_attributes(self):
|
||||
"""
|
||||
Test the existence of some relevant attributes of the dialog.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
|
||||
# Create an existing and valid table node for testing.
|
||||
table_node = TableNode("test", "localhost", "testuser", "testdb", 5432, 10000)
|
||||
|
||||
# Add the table node to the dialog.
|
||||
table_edit_dialog = TableEditDialog(table_node)
|
||||
|
||||
# The selected table node should be the used table node.
|
||||
assert table_edit_dialog.selected_table_node == table_node
|
||||
# The database connection of the dialog should be the connection of the table node.
|
||||
assert table_edit_dialog.database_connection == table_node._database_connection
|
||||
|
||||
def test_checkbox_initialization(self):
|
||||
"""
|
||||
Test the correct initialization of the checkbox.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
|
||||
# Create an existing and valid table node for testing.
|
||||
table_node = TableNode("test", "localhost", "testuser", "testdb", 5432, 10000)
|
||||
|
||||
# Add the table node to the dialog.
|
||||
table_edit_dialog = TableEditDialog(table_node)
|
||||
|
||||
# Get the current configuration of the checkbox.
|
||||
checkbox_configuration = global_app_configurator.get_single_configuration(
|
||||
table_edit_dialog.checkbox_configuration_name)
|
||||
|
||||
# If the configuration is True, the checkbox should be checked.
|
||||
if checkbox_configuration is True:
|
||||
assert table_edit_dialog.update_immediately_checkbox.isChecked() is True
|
||||
|
||||
# If the configuration is False or None, the checkbox should not be checked.
|
||||
else:
|
||||
assert table_edit_dialog.update_immediately_checkbox.isChecked() is False
|
||||
|
||||
def test_get_select_query(self):
|
||||
"""
|
||||
Test the function for getting the select query with an empty condition in the condition line edit and with a
|
||||
text in the line edit.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
|
||||
# Create an existing and valid table node for testing.
|
||||
table_node = TableNode("test", "localhost", "testuser", "testdb", 5432, 10000)
|
||||
|
||||
# Add the table node to the dialog.
|
||||
table_edit_dialog = TableEditDialog(table_node)
|
||||
|
||||
# The current select query should contain a statement for selecting all values with limit 1000 in the given
|
||||
# table.
|
||||
assert table_edit_dialog.get_select_query() == "SELECT * FROM {} LIMIT 1000".format(
|
||||
table_edit_dialog.selected_table_node.name)
|
||||
|
||||
# Define a where condition for further testing.
|
||||
test_where_condition = "test_column='test_value'"
|
||||
# Set the where condition in the line edit.l
|
||||
table_edit_dialog.condition_line_edit.setText(test_where_condition)
|
||||
|
||||
# The current select query should contain the where condition in addition to the previous select query.
|
||||
assert table_edit_dialog.get_select_query() == "SELECT * FROM {} WHERE {} LIMIT 1000".format(
|
||||
table_edit_dialog.selected_table_node.name, test_where_condition)
|
||||
|
||||
def test_update_statement(self):
|
||||
"""
|
||||
Test the current state of the update label, which contains the update query.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
|
||||
# Create an existing and valid table node for testing.
|
||||
table_node = TableNode("test", "localhost", "testuser", "testdb", 5432, 10000)
|
||||
|
||||
# Add the table node to the dialog.
|
||||
table_edit_dialog = TableEditDialog(table_node)
|
||||
|
||||
# The update label contains the update statement. Without changing a value in the table, the label contains
|
||||
# just an UPDATE with the name of the table.
|
||||
assert table_edit_dialog.update_label.text() == "UPDATE {}".format(table_edit_dialog.selected_table_node.name)
|
||||
|
||||
def test_checkbox_change(self):
|
||||
"""
|
||||
Test the check changes in the checkbox for updating the table immediately.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
|
||||
# Create an existing and valid table node for testing.
|
||||
table_node = TableNode("test", "localhost", "testuser", "testdb", 5432, 10000)
|
||||
|
||||
# Add the table node to the dialog.
|
||||
table_edit_dialog = TableEditDialog(table_node)
|
||||
|
||||
# Set the checkbox to checked.
|
||||
table_edit_dialog.update_immediately_checkbox.setChecked(True)
|
||||
|
||||
# The update elements should be invisible now.
|
||||
assert table_edit_dialog.update_label.isVisible() is False
|
||||
assert table_edit_dialog.update_button.isVisible() is False
|
||||
|
||||
# Set the checkbox to unchecked.
|
||||
table_edit_dialog.update_immediately_checkbox.setChecked(False)
|
||||
|
||||
# The update elements should be visible now.
|
||||
assert table_edit_dialog.update_label.isVisible() is True
|
||||
assert table_edit_dialog.update_button.isVisible() is True
|
||||
|
||||
|
||||
|
43
tests/test_table_information.py
Normal file
43
tests/test_table_information.py
Normal file
@@ -0,0 +1,43 @@
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
|
||||
from pygadmin.widgets.table_information import TableInformationDialog
|
||||
from pygadmin.models.treemodel import TableNode
|
||||
|
||||
|
||||
class TestTableInformationDialogMethods(unittest.TestCase):
|
||||
"""
|
||||
Test the functionality and methods of the table information dialog.
|
||||
"""
|
||||
|
||||
def test_dialog_without_node(self):
|
||||
"""
|
||||
Test the dialog without a valid node and None instead.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a table information dialog with None as node, which is invalid.
|
||||
table_information_dialog = TableInformationDialog(None)
|
||||
|
||||
# The window title of the widget should show an error.
|
||||
assert table_information_dialog.windowTitle() == "Node Input Error"
|
||||
|
||||
def test_initial_attributes_with_node(self):
|
||||
"""
|
||||
Test the initial attributes of the dialog with a valid table node.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Define a valid table node.
|
||||
table_node = TableNode("test", "localhost", "testuser", "testdb", 5432, 10000)
|
||||
# Create a table information dialog with the table node.
|
||||
table_information_dialog = TableInformationDialog(table_node)
|
||||
|
||||
# The selected table node of the dialog should be the created table node.
|
||||
assert table_information_dialog.selected_table_node == table_node
|
||||
# The parameter for full definition is not filled, so it should use the default value True.
|
||||
assert table_information_dialog.full_definition is True
|
138
tests/test_tablemodel.py
Normal file
138
tests/test_tablemodel.py
Normal file
@@ -0,0 +1,138 @@
|
||||
import unittest
|
||||
|
||||
from PyQt5.QtCore import Qt
|
||||
|
||||
from pygadmin.models.tablemodel import TableModel
|
||||
|
||||
|
||||
class TestTableModelMethods(unittest.TestCase):
|
||||
"""
|
||||
Use a class for testing the different methods of the table model.
|
||||
"""
|
||||
|
||||
def test_initial_data_list(self):
|
||||
"""
|
||||
Test the creation of a table model and check the resulting data list.
|
||||
"""
|
||||
|
||||
# Define a data list.
|
||||
test_data = [["column 0", "column 1", "column 2"], ["row A", "row B", "row C"], ["row D", "row E", "row F"]]
|
||||
table_model = TableModel(test_data)
|
||||
# Check the data list of the model.
|
||||
assert test_data == table_model.data_list
|
||||
|
||||
def test_correct_row_count(self):
|
||||
"""
|
||||
Test the correct row count for a normal and valid data list.
|
||||
"""
|
||||
|
||||
test_data = [["column 0", "column 1", "column 2"], ["row A", "row B", "row C"], ["row D", "row E", "row F"]]
|
||||
table_model = TableModel(test_data)
|
||||
# Describe the row count as the length of the test data list - 1, because the header is not a row.
|
||||
assert table_model.rowCount() == len(test_data) - 1
|
||||
|
||||
def test_correct_column_count(self):
|
||||
"""
|
||||
Test the correct column count for a normal and valid data list.
|
||||
"""
|
||||
|
||||
test_data = [["column 0", "column 1", "column 2"], ["row A", "row B", "row C"], ["row D", "row E", "row F"]]
|
||||
table_model = TableModel(test_data)
|
||||
# The first list contains all header elements and describes the number of columns.
|
||||
assert table_model.columnCount() == len(test_data[0])
|
||||
|
||||
def test_data_type(self):
|
||||
"""
|
||||
Test with different types the correct result of the data in the table model. Almost every value should cause the
|
||||
return of a string.
|
||||
"""
|
||||
|
||||
# Define different kinds of test data: Numbers in the header, booleans (and None) as first row, numbers as
|
||||
# second and strings as third.
|
||||
test_data = [[0, 1, 2], [True, False, None], [4, 5, 6], ["test", "1234", "meow"]]
|
||||
table_model = TableModel(test_data)
|
||||
|
||||
# Get the first item in the first row, check for a string and for the correct value.
|
||||
first_row_item = table_model.data(table_model.index(0, 0))
|
||||
assert isinstance(first_row_item, str)
|
||||
assert first_row_item == "True"
|
||||
|
||||
# Get the first item in the second row, check for a string and for the correct value.
|
||||
second_row_item = table_model.data(table_model.index(1, 0))
|
||||
assert isinstance(second_row_item, str)
|
||||
assert second_row_item == "4"
|
||||
|
||||
# Get the first item in the third row, check for a string and for the correct value.
|
||||
third_row_item = table_model.data(table_model.index(2, 0))
|
||||
assert isinstance(third_row_item, str)
|
||||
assert third_row_item == "test"
|
||||
|
||||
# Get the first item in the fourth row, but this row does not exist, so it should return None. None is not
|
||||
# casted to a string, so there is just a check for None.
|
||||
fourth_row_item = table_model.data(table_model.index(3, 0))
|
||||
assert fourth_row_item is None
|
||||
|
||||
def test_horizontal_header_data(self):
|
||||
"""
|
||||
Test the correct display of data with a horizontal header.
|
||||
"""
|
||||
|
||||
# Define a first list as extra list, because this list contains the header.
|
||||
first_list = ["column 0", "column 1", "column 2"]
|
||||
test_data = [first_list, ["row A", "row B", "row C"], ["row D", "row E", "row F"]]
|
||||
table_model = TableModel(test_data)
|
||||
|
||||
# Check every number in the header.
|
||||
for header_description_number in range(len(first_list) - 1):
|
||||
# Get the data in the header by a horizontal orientation.
|
||||
header_data = table_model.headerData(header_description_number, Qt.Horizontal)
|
||||
# Check, if the item in the header is the same as the item in the first list, which is the header list.
|
||||
assert header_data == first_list[header_description_number]
|
||||
|
||||
def test_vertical_header_data(self):
|
||||
"""
|
||||
Test the correct display of data with a vertical header.
|
||||
"""
|
||||
|
||||
test_data = [["column 0", "column 1", "column 2"], ["row A", "row B", "row C"], ["row D", "row E", "row F"]]
|
||||
table_model = TableModel(test_data)
|
||||
|
||||
# Check for every element in the test data list.
|
||||
for row_number in range(len(test_data) - 1):
|
||||
# Get the data at the row number with a vertical orientation.
|
||||
header_data = table_model.headerData(row_number, Qt.Vertical)
|
||||
# The data for a vertical header is numeric, so from 1 to whatever and because of this, off by one needs to
|
||||
# be considered.
|
||||
assert header_data == row_number + 1
|
||||
|
||||
def test_correct_row_count_with_empty_list(self):
|
||||
"""
|
||||
Test the correct row count with an empty data list.
|
||||
"""
|
||||
|
||||
test_data = []
|
||||
table_model = TableModel(test_data)
|
||||
# For an empty list, the row count should be 0.
|
||||
assert table_model.rowCount() == 0
|
||||
|
||||
def test_correct_column_count_with_empty_list(self):
|
||||
"""
|
||||
Test the correct column count with an empty data list.
|
||||
"""
|
||||
|
||||
test_data = []
|
||||
table_model = TableModel(test_data)
|
||||
# For an empty data list, the column count should be 0.
|
||||
assert table_model.columnCount() == 0
|
||||
|
||||
def test_false_type_input(self):
|
||||
"""
|
||||
Test the behavior of the table model for a data list, which is not a list.
|
||||
"""
|
||||
|
||||
# Define the test data as None.
|
||||
test_data = None
|
||||
table_model = TableModel(test_data)
|
||||
# For a data list, which is not a list, the new and internal data list of the table model should be an empty
|
||||
# list.
|
||||
assert table_model.data_list == []
|
146
tests/test_tree.py
Normal file
146
tests/test_tree.py
Normal file
@@ -0,0 +1,146 @@
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
|
||||
from pygadmin.widgets.tree import TreeWidget
|
||||
from pygadmin.connectionstore import global_connection_store
|
||||
from pygadmin.models.treemodel import ServerNode
|
||||
|
||||
|
||||
class TestTreeWidgetMethods(unittest.TestCase):
|
||||
"""
|
||||
Test the basic functionality, correct behavior and some functions of the tree widget.
|
||||
"""
|
||||
|
||||
def test_initial_attributes(self):
|
||||
"""
|
||||
Test some of the initial attributes of the widget.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QWidget.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a tree widget.
|
||||
tree_widget = TreeWidget()
|
||||
|
||||
# At the start of the widget, there should not be a selected index.
|
||||
assert tree_widget.selected_index is False
|
||||
# Check for the existence and correct instance of the server node list.
|
||||
assert isinstance(tree_widget.server_nodes, list)
|
||||
|
||||
def test_find_new_relevant_parameters(self):
|
||||
"""
|
||||
Test the function for finding new relevant connection parameters.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QWidget.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a tree widget.
|
||||
tree_widget = TreeWidget()
|
||||
|
||||
# Add potential existing nodes to the tree widget.
|
||||
for connection_dictionary in tree_widget.find_new_relevant_parameters():
|
||||
new_server_node = ServerNode(connection_dictionary["Host"],
|
||||
connection_dictionary["Host"],
|
||||
connection_dictionary["Username"],
|
||||
connection_dictionary["Port"],
|
||||
connection_dictionary["Timeout"])
|
||||
tree_widget.server_nodes.append(new_server_node)
|
||||
|
||||
# After the start and without new relevant connection parameters, the function should return an empty list.
|
||||
assert tree_widget.find_new_relevant_parameters() == []
|
||||
|
||||
# Define new connection parameters, so new relevant parameters can be found.
|
||||
new_connection_parameters = {"Host": "127.0.01",
|
||||
"Database": "testdb",
|
||||
"Port": 5432,
|
||||
"Username": "testuser"}
|
||||
|
||||
# Get the current number of the connection parameters in the connection store and use it as new position for new
|
||||
# connection parameters.
|
||||
position = global_connection_store.get_number_of_connection_parameters()
|
||||
# Save the new defined connection parameters in the connection store.
|
||||
global_connection_store.save_connection_parameters_in_yaml_file(new_connection_parameters)
|
||||
# Get the new and relevant parameters out of the tree widget.
|
||||
new_relevant_parameters = tree_widget.find_new_relevant_parameters(position)[0]
|
||||
|
||||
# Check for the correct values for the given keys in the dictionary, because they should be identical.
|
||||
assert new_connection_parameters["Database"] == new_relevant_parameters["Database"]
|
||||
assert new_connection_parameters["Host"] == new_relevant_parameters["Host"]
|
||||
assert new_connection_parameters["Port"] == new_relevant_parameters["Port"]
|
||||
assert new_connection_parameters["Username"] == new_relevant_parameters["Username"]
|
||||
|
||||
# Delete the new connection parameters as a clean up.
|
||||
global_connection_store.delete_connection(new_connection_parameters)
|
||||
|
||||
def test_create_new_server_node(self):
|
||||
"""
|
||||
Test the method for creating a new server node.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QWidget.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a tree widget.
|
||||
tree_widget = TreeWidget()
|
||||
|
||||
# Define connection parameters for a new server node.
|
||||
server_node_connection_parameters = {"Host": "testhost",
|
||||
"Database": "testdb",
|
||||
"Port": 5432,
|
||||
"Username": "testuser",
|
||||
"Timeout": 10000}
|
||||
|
||||
# Create a new server node with the tree widget.
|
||||
new_server_node = tree_widget.create_new_server_node(server_node_connection_parameters)
|
||||
# As a result, the created node should be a server node.
|
||||
assert isinstance(new_server_node, ServerNode)
|
||||
|
||||
# Append the node to the list of server nodes, so the next assertion is checked correctly.
|
||||
tree_widget.server_nodes.append(new_server_node)
|
||||
# The creation of a new server node should return None, because there is a duplicate.
|
||||
assert tree_widget.create_new_server_node(server_node_connection_parameters) is None
|
||||
|
||||
def test_check_server_node_for_duplicate(self):
|
||||
"""
|
||||
Test the method for checking the parameters of a potentially new server node for a duplicate.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QWidget.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a tree widget.
|
||||
tree_widget = TreeWidget()
|
||||
|
||||
# Define connection parameters for a new server node.
|
||||
server_node_connection_parameters = {"Host": "testhost",
|
||||
"Database": "testdb",
|
||||
"Port": 5432,
|
||||
"Username": "testuser",
|
||||
"Timeout": 10000}
|
||||
|
||||
# There should not be a server node with the connection parameters of the new server node.
|
||||
assert tree_widget.check_server_node_for_duplicate(server_node_connection_parameters) is False
|
||||
|
||||
# Create a new server node.
|
||||
new_server_node = tree_widget.create_new_server_node(server_node_connection_parameters)
|
||||
# Append the new node to the list of server nodes.
|
||||
tree_widget.server_nodes.append(new_server_node)
|
||||
# The check for a duplicate with the same and old parameters should return True, because there is a duplicate.
|
||||
assert tree_widget.check_server_node_for_duplicate(server_node_connection_parameters) is True
|
||||
|
||||
def test_append_new_node(self):
|
||||
"""
|
||||
Test the method for appending a new node in the tree widget.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QWidget.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a tree widget.
|
||||
tree_widget = TreeWidget()
|
||||
|
||||
# Create a new server node.
|
||||
server_node = ServerNode("testhost", "testhost", "testuser", 5432)
|
||||
# Use the method of the tree widget for appending a new server node.
|
||||
tree_widget.append_new_node(server_node)
|
||||
|
||||
# Check for the existence of the new server node in the server node list of the tree widget.
|
||||
assert server_node in tree_widget.server_nodes
|
82
tests/test_treemodel.py
Normal file
82
tests/test_treemodel.py
Normal file
@@ -0,0 +1,82 @@
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
|
||||
from pygadmin.models.treemodel import ServerNode, DatabaseNode, SchemaNode, TablesNode, ViewsNode, TableNode, ViewNode
|
||||
|
||||
|
||||
class TestTreeMethods(unittest.TestCase):
|
||||
"""
|
||||
Use a class for testing the methods of the tree and the tree model.
|
||||
"""
|
||||
|
||||
def test_create_server_node(self):
|
||||
"""
|
||||
Test the creation of a server node.
|
||||
"""
|
||||
|
||||
# A QApplication is necessary for the usage of a QPixmap, which is part of the Server Node.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a test node with static connection parameters.
|
||||
ServerNode(name="localhost",
|
||||
host="localhost",
|
||||
user="testuser",
|
||||
database="testdb",
|
||||
port=5432,
|
||||
timeout=5000)
|
||||
|
||||
def test_node_children(self):
|
||||
# A QApplication is necessary for the usage of a QPixmap, which is part of the Server Node.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a test node with static connection parameters.
|
||||
server_node = ServerNode(name="localhost",
|
||||
host="localhost",
|
||||
user="testuser",
|
||||
database="testdb",
|
||||
port=5432,
|
||||
timeout=5000)
|
||||
|
||||
# The child at row and column 0 of a server node is a database node for a correct and fully functional database
|
||||
# connection.
|
||||
database_node = server_node.child(0, 0)
|
||||
# Check for the right instance.
|
||||
assert isinstance(database_node, DatabaseNode)
|
||||
|
||||
# The child at row and column 0 of a database node is a schema node.
|
||||
schema_node = database_node.child(0, 0)
|
||||
# Check for the right instance.
|
||||
assert isinstance(schema_node, SchemaNode)
|
||||
|
||||
# The child at row and column 0 of a schema node is a tables node.
|
||||
tables_node = schema_node.child(0, 0)
|
||||
# Check for the right instance.
|
||||
assert isinstance(tables_node, TablesNode)
|
||||
# The child at row 1 and column 0 of a schema node is a views node.
|
||||
views_node = schema_node.child(1, 0)
|
||||
# Check for the right instance.
|
||||
assert isinstance(views_node, ViewsNode)
|
||||
|
||||
# The child at row and column 0 of a tables node is a table node.
|
||||
table_node = tables_node.child(0, 0)
|
||||
# Check for the right instance.
|
||||
assert isinstance(table_node, TableNode)
|
||||
# The child at row and column 0 of a views node is a view node.
|
||||
view_node = views_node.child(0, 0)
|
||||
# Check for the right instance.
|
||||
assert isinstance(view_node, ViewNode)
|
||||
|
||||
def test_invalid_connection_of_node(self):
|
||||
# A QApplication is necessary for the usage of a QPixmap, which is part of the Server Node.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a test node with static connection parameters. The host contains an invalid parameter, which results in
|
||||
# an invalid database connection.
|
||||
server_node = ServerNode(name="localhost",
|
||||
host="local",
|
||||
user="testuser",
|
||||
database="testdb",
|
||||
port=5432,
|
||||
timeout=5000)
|
||||
|
||||
# The child of a server node should be None for an invalid connection.
|
||||
assert server_node.child(0, 0) is None
|
27
tests/test_version_information_dialog.py
Normal file
27
tests/test_version_information_dialog.py
Normal file
@@ -0,0 +1,27 @@
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from PyQt5.QtWidgets import QApplication, QLabel
|
||||
|
||||
from pygadmin.widgets.version_information_dialog import VersionInformationDialog
|
||||
|
||||
|
||||
class TestVersionInformationDialogMethods(unittest.TestCase):
|
||||
"""
|
||||
Test the methods and behavior of the version information dialog.
|
||||
"""
|
||||
|
||||
def test_initial_attributes(self):
|
||||
"""
|
||||
Test the initial attributes of the dialog.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a QDialog.
|
||||
app = QApplication(sys.argv)
|
||||
# Create a version information dialog.
|
||||
version_information_dialog = VersionInformationDialog()
|
||||
|
||||
# The dialog should not be modal.
|
||||
assert version_information_dialog.isModal() is False
|
||||
# The version label should be a QLabel.
|
||||
assert isinstance(version_information_dialog.version_label, QLabel)
|
41
tests/test_widget_icon_adder.py
Normal file
41
tests/test_widget_icon_adder.py
Normal file
@@ -0,0 +1,41 @@
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from PyQt5.QtGui import QIcon
|
||||
from PyQt5.QtWidgets import QApplication, QWidget
|
||||
|
||||
from pygadmin.widgets.widget_icon_adder import IconAdder
|
||||
|
||||
|
||||
class TestWidgetIconAdderMethods(unittest.TestCase):
|
||||
"""
|
||||
Test the functionality of the widget icon adder.
|
||||
"""
|
||||
|
||||
def test_initial_attributes(self):
|
||||
"""
|
||||
Test the initial attributes of the icon adder.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a Qt elements.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an icon adder.
|
||||
icon_adder = IconAdder()
|
||||
# The icon should be a QIcon.
|
||||
assert isinstance(icon_adder.window_icon, QIcon)
|
||||
|
||||
def test_add_icon(self):
|
||||
"""
|
||||
Test the method for adding an icon.
|
||||
"""
|
||||
|
||||
# Create an app, because this is necessary for testing a Qt elements.
|
||||
app = QApplication(sys.argv)
|
||||
# Create an icon adder.
|
||||
icon_adder = IconAdder()
|
||||
# Create a test widget.
|
||||
test_widget = QWidget()
|
||||
# Add an icon to the test widget.
|
||||
icon_adder.add_icon_to_widget(test_widget)
|
||||
# The name of the window icon of the test widget and of the icon adder should be the same.
|
||||
assert test_widget.windowIcon().name() == icon_adder.window_icon.name()
|
Reference in New Issue
Block a user