diff --git a/.gitignore b/.gitignore index 8802201..a60c4d3 100644 --- a/.gitignore +++ b/.gitignore @@ -22,15 +22,14 @@ linux/flatpak/.flatpak-builder **/__pycache__/ .ropeproject .vscode +*.kdev4 +.kdev4 +.coverage build docs/html .directory -*.kdev4 *.lpf *.lgg *.spec -.kdev4 -AccountFree.pro -AccountFree.pro.user *.egg-info/ *.tar.gz diff --git a/LogarithmPlotter/util/config.py b/LogarithmPlotter/util/config.py index 8ab83b2..d295caa 100644 --- a/LogarithmPlotter/util/config.py +++ b/LogarithmPlotter/util/config.py @@ -21,7 +21,6 @@ from platform import system from json import load, dumps from PySide6.QtCore import QLocale, QTranslator - DEFAULT_SETTINGS = { "check_for_updates": True, "reset_redo_stack": True, @@ -38,7 +37,7 @@ DEFAULT_SETTINGS = { "default_graph": { "xzoom": 100, "yzoom": 10, - "xmin": 5/10, + "xmin": 5 / 10, "ymax": 25, "xaxisstep": "4", "yaxisstep": "4", @@ -55,41 +54,47 @@ DEFAULT_SETTINGS = { # Create config directory CONFIG_PATH = { "Linux": path.join(environ["XDG_CONFIG_HOME"], "LogarithmPlotter") - if "XDG_CONFIG_HOME" in environ else - path.join(path.expanduser("~"), ".config", "LogarithmPlotter"), + if "XDG_CONFIG_HOME" in environ else + path.join(path.expanduser("~"), ".config", "LogarithmPlotter"), "Windows": path.join(path.expandvars('%APPDATA%'), "LogarithmPlotter", "config"), "Darwin": path.join(path.expanduser("~"), "Library", "Application Support", "LogarithmPlotter"), }[system()] CONFIG_FILE = path.join(CONFIG_PATH, "config.json") -initialized = False current_config = DEFAULT_SETTINGS +class UnknownNamespaceError(Exception): pass + + def init(): """ Initializes the config and loads all possible settings from the file if needs be. """ + global current_config + current_config = DEFAULT_SETTINGS makedirs(CONFIG_PATH, exist_ok=True) if path.exists(CONFIG_FILE): - cfg_data = load(open(CONFIG_FILE, 'r', -1, 'utf8')) + cfg_data = load(open(CONFIG_FILE, 'r', -1, 'utf8')) for setting_name in cfg_data: if type(cfg_data[setting_name]) == dict: for setting_name2 in cfg_data[setting_name]: - setSetting(setting_name+"."+setting_name2, cfg_data[setting_name][setting_name2]) + setSetting(setting_name + "." + setting_name2, cfg_data[setting_name][setting_name2]) else: setSetting(setting_name, cfg_data[setting_name]) -def save(): + +def save(file=CONFIG_FILE): """ Saves the config to the path. """ - write_file = open(CONFIG_FILE, 'w', -1, 'utf8') + write_file = open(file, 'w', -1, 'utf8') write_file.write(dumps(current_config)) write_file.close() + def getSetting(namespace): """ Returns a setting from a namespace. @@ -103,9 +108,10 @@ def getSetting(namespace): setting = setting[name] else: # return namespace # Return original name - raise ValueError('Setting ' + namespace + ' doesn\'t exist. Debug: ', setting, name) + raise UnknownNamespaceError(f"Setting {namespace} doesn't exist. Debug: {setting}, {name}") return setting + def setSetting(namespace, data): """ Sets a setting at a namespace with data. @@ -119,6 +125,6 @@ def setSetting(namespace, data): if name in setting: setting = setting[name] else: - raise ValueError('Setting {} doesn\'t exist. Debug: {}, {}'.format(namespace, setting, name)) + raise UnknownNamespaceError(f"Setting {namespace} doesn't exist. Debug: {setting}, {name}") else: setting[name] = data diff --git a/LogarithmPlotter/util/helper.py b/LogarithmPlotter/util/helper.py index a802cc4..c7c92d8 100644 --- a/LogarithmPlotter/util/helper.py +++ b/LogarithmPlotter/util/helper.py @@ -32,6 +32,9 @@ from LogarithmPlotter import __VERSION__ from LogarithmPlotter.util import config +class InvalidFileException(Exception): pass + + class ChangelogFetcher(QRunnable): def __init__(self, helper): QRunnable.__init__(self) @@ -94,8 +97,8 @@ class Helper(QObject): pass elif data[:3] == "LPF": # More recent version of LogarithmPlotter file, but incompatible with the current format - msg = QCoreApplication.translate("This file was created by a more recent version of LogarithmPlotter and cannot be backloaded in LogarithmPlotter v{}.\nPlease update LogarithmPlotter to open this file.".format(__VERSION__)) - raise Exception(msg) + msg = QCoreApplication.translate("This file was created by a more recent version of LogarithmPlotter and cannot be backloaded in LogarithmPlotter v{}.\nPlease update LogarithmPlotter to open this file.") + raise InvalidFileException(msg.format(__VERSION__)) else: raise Exception("Invalid LogarithmPlotter file.") except Exception as e: # If file can't be loaded @@ -131,7 +134,6 @@ class Helper(QObject): @Slot(str, result=float) def getSettingInt(self, namespace): - print('Getting', namespace, config.getSetting(namespace)) return config.getSetting(namespace) @Slot(str, result=bool) diff --git a/LogarithmPlotter/util/js.py b/LogarithmPlotter/util/js.py index 6cdd0b2..b00c645 100644 --- a/LogarithmPlotter/util/js.py +++ b/LogarithmPlotter/util/js.py @@ -18,6 +18,7 @@ from PySide6.QtQml import QJSValue +class InvalidAttributeValueException(Exception): pass class PyJSValue: """ @@ -38,15 +39,32 @@ class PyJSValue: elif isinstance(value, PyJSValue): # Set property self.qjs_value.setProperty(key, value.qjs_value) - else: - print('Setting', key, value) + elif isinstance(value, QJSValue): self.qjs_value.setProperty(key, value) + elif type(value) in (int, float, str, bool): + self.qjs_value.setProperty(key, QJSValue(value)) + else: + raise InvalidAttributeValueException(f"Invalid value {value} of type {type(value)} being set to {key}.") + + def __eq__(self, other): + if isinstance(other, PyJSValue): + return self.qjs_value.equals(other.qjs_value) + elif isinstance(other, QJSValue): + return self.qjs_value.equals(other) + elif type(other) in (int, float, str, bool): + return self.qjs_value.equals(QJSValue(other)) + else: + return False def __call__(self, *args, **kwargs): + value = None if self.qjs_value.isCallable(): if self._parent is None: - return self.qjs_value.call(args) + value = self.qjs_value.call(args) else: - return self.qjs_value.callWithInstance(self._parent, args) + value = self.qjs_value.callWithInstance(self._parent, args) else: - raise ValueError('Cannot call non-function JS value.') + raise InvalidAttributeValueException('Cannot call non-function JS value.') + if isinstance(value, QJSValue): + value = PyJSValue(value) + return value diff --git a/README.md b/README.md index 7f092e3..0745682 100644 --- a/README.md +++ b/README.md @@ -41,11 +41,6 @@ For all builds, you need [Python 3](https://python.org) with [PySide6](https://p - To build the snap, you need [snapcraft](https://snapcraft.io) installed. - Run `package-linux.sh`. - -### Linux - -Run `bash linux/install_local.sh` - ## Contribute There are several ways to contribute to LogarithmPlotter. @@ -54,6 +49,14 @@ There are several ways to contribute to LogarithmPlotter. - You can help the development of LogarithmPlotter. In order to get started, take a look at the [wiki](https://git.ad5001.eu/Ad5001/LogarithmPlotter/wiki/_pages). +## Tests + +To run LogarithmPlotter's test, use the following: + +- Python + - Install `pytest` and `pytest-cov` + - Run `pytest --cov` + ## Legal notice LogarithmPlotter - 2D plotter software to make BODE plots, sequences and repartition functions. Copyright (C) 2021-2024 Ad5001 diff --git a/tests/python/test_config.py b/tests/python/test_config.py new file mode 100644 index 0000000..493b0f1 --- /dev/null +++ b/tests/python/test_config.py @@ -0,0 +1,10 @@ +import unittest + + +class MyTestCase(unittest.TestCase): + def test_something(self): + self.assertEqual(True, False) # add assertion here + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/python/test_helper.py b/tests/python/test_helper.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/python/test_pyjs.py b/tests/python/test_pyjs.py new file mode 100644 index 0000000..e69de29