From bc42f74b2bed6439fc7e15e600edbf19de4682c0 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 19 Mar 2022 12:30:23 -0700 Subject: [PATCH] Reformat additional messages and finish centralizing exception handling (#1424) * Update and modularize exception handling cc #1024 #1141 - Stack traces are no longer shown to users unless the --debug flag is being used - Errors, warnings, and other messages contain color as needed - Converted error messages to Enum - Adds print_msg function to centralize output (this should replace all other output in other modules) Co-authored-by: Micah Jerome Ellison * format with black * add message to catch-all exception block * Unskip some tests (#1399) * remove skip_editor test and tag * remove useless test * unskip blank input test * formatting * rename test so it doesn't overwrite other test * unskip some dayone tests that now work * Bump ipython from 7.28.0 to 7.31.1 (#1401) Bumps [ipython](https://github.com/ipython/ipython) from 7.28.0 to 7.31.1. - [Release notes](https://github.com/ipython/ipython/releases) - [Commits](https://github.com/ipython/ipython/compare/7.28.0...7.31.1) --- updated-dependencies: - dependency-name: ipython dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Update changelog [ci skip] * Bump asteval from 0.9.25 to 0.9.26 (#1400) Bumps [asteval](https://github.com/newville/asteval) from 0.9.25 to 0.9.26. - [Release notes](https://github.com/newville/asteval/releases) - [Commits](https://github.com/newville/asteval/compare/0.9.25...0.9.26) --- updated-dependencies: - dependency-name: asteval dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Update changelog [ci skip] * Bump black from 21.12b0 to 22.1.0 (#1404) * Bump black from 21.12b0 to 22.1.0 Bumps [black](https://github.com/psf/black) from 21.12b0 to 22.1.0. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/commits/22.1.0) --- updated-dependencies: - dependency-name: black dependency-type: direct:development ... Signed-off-by: dependabot[bot] * Run make format Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Micah Jerome Ellison * Update changelog [ci skip] * Add reference documentation to docs site and separate out "Tips and Tricks" and "External Editors" from "Recipes" (#1332) * First draft of command line reference, mostly pulled from help screen * Add first draft of config file reference, mostly pulled from advanced.md * Clean up config file doc for readability * Add --config-file and remove examples from CLI reference * Add warning about time zone in timeformat * More small changes, and adding template config keyword * Cleaning up and re-ordering config file reference * Clean up reference and anything else from advanced documentation that can live elsewhere and linking to config file reference wherever config file is mentioned * Fix syntax highlighting in command line reference, clean up content a bit, include --diagnostic * Mention version config key * Apply minor changes suggested in PR review * Rename "recipes" to "Tips and Tricks", pull "External Editors" out of it into its own page, and redirect old recipes link to tips-and-tricks * Revert broken mkdocs-redirects usage from last commit * Update changelog [ci skip] * Add --co alias for --config-override (#1397) * Add hash as a default tag symbol (#1398) * Update changelog [ci skip] * Increment version to v2.8.4-beta2 * Update changelog [ci skip] * Increment version to v2.8.4 * Update changelog [ci skip] * Bump pytest from 6.2.5 to 7.0.0 (#1407) Bumps [pytest](https://github.com/pytest-dev/pytest) from 6.2.5 to 7.0.0. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/6.2.5...7.0.0) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Update changelog [ci skip] * Drop support for Python 3.7 and 3.8 (#1412) * Remove Python 3.7 and 3.8 from github actions workflows * Update lockfile after running poetry update a couple times * Update poetry lock * Remove Python 3.7 and 3.8 from pyproject.toml and run poetry lock * Update changelog [ci skip] * Tidy up git ignore (#1414) * cleaned gitignore and add comments * removed colon for readbility * alphabetize files in sections Co-authored-by: nelnog * fix behavior that was confusing pytest * update test to match new message * whitespace change * clean up error for manually stopping the inline editor * udpate error to use new exception handling * move some exceptions and errors to the new exception handling * add line breaks to keyboard interrupt so it looks more like other exceptions * add handling for exceptions that happen earlier in the flow * add new 'NothingToDelete' error to replace old behavior * get rid of old exception * add new exception handling to 'nothing saved to file' errors * move exception for no editor configured into new handling * move exception for no alt config to new handling * get rid of old exception handling for encrypted journal * Move error for too many wrong passwords into new handling * fix merge errors * replace sys.exit call with new exception handling * replace sys.exit call with new exception handling * replace sys.exit call with new exception handling * reformat with black * clean up old code * clean up old code * clean up linting issue * update uncaught exception for new handling * update test * fix mangled lock file Co-authored-by: Micah Jerome Ellison Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jrnl Bot Co-authored-by: Nelson <35701520+nelnog@users.noreply.github.com> Co-authored-by: nelnog --- jrnl/EncryptedJournal.py | 29 +++++++-------- jrnl/Journal.py | 13 ++----- jrnl/cli.py | 40 ++++++++++++++------- jrnl/config.py | 10 ++++-- jrnl/editor.py | 22 +++++------- jrnl/exception.py | 10 ------ jrnl/install.py | 44 +++++++++-------------- jrnl/jrnl.py | 59 ++++++++++++++---------------- jrnl/messages.py | 60 ++++++++++++++++++++++++++++++- jrnl/output.py | 2 +- jrnl/plugins/jrnl_importer.py | 12 +++++-- jrnl/upgrade.py | 47 ++++++++++++------------ tests/bdd/features/delete.feature | 1 + tests/bdd/features/write.feature | 2 +- tests/unit/test_config_file.py | 7 ++-- tests/unit/test_export.py | 1 - 16 files changed, 205 insertions(+), 154 deletions(-) diff --git a/jrnl/EncryptedJournal.py b/jrnl/EncryptedJournal.py index 7354e7a2a..704a091ab 100644 --- a/jrnl/EncryptedJournal.py +++ b/jrnl/EncryptedJournal.py @@ -21,6 +21,11 @@ from .Journal import LegacyJournal from .prompt import create_password +from jrnl.exception import JrnlException +from jrnl.messages import Message +from jrnl.messages import MsgText +from jrnl.messages import MsgType + def make_key(password): password = password.encode("utf-8") @@ -53,11 +58,11 @@ def decrypt_content( password = getpass.getpass() result = decrypt_func(password) attempt += 1 - if result is not None: - return result - else: - print("Extremely wrong password.", file=sys.stderr) - sys.exit(1) + + if result is None: + raise JrnlException(Message(MsgText.PasswordMaxTriesExceeded, MsgType.ERROR)) + + return result class EncryptedJournal(Journal): @@ -121,15 +126,11 @@ def _store(self, filename, text): @classmethod def from_journal(cls, other: Journal): new_journal = super().from_journal(other) - try: - new_journal.password = ( - other.password - if hasattr(other, "password") - else create_password(other.name) - ) - except KeyboardInterrupt: - print("[Interrupted while creating new journal]", file=sys.stderr) - sys.exit(1) + new_journal.password = ( + other.password + if hasattr(other, "password") + else create_password(other.name) + ) return new_journal diff --git a/jrnl/Journal.py b/jrnl/Journal.py index 17de129f6..bf446a927 100644 --- a/jrnl/Journal.py +++ b/jrnl/Journal.py @@ -431,13 +431,6 @@ def open_journal(journal_name, config, legacy=False): from . import EncryptedJournal - try: - if legacy: - return EncryptedJournal.LegacyEncryptedJournal( - journal_name, **config - ).open() - return EncryptedJournal.EncryptedJournal(journal_name, **config).open() - except KeyboardInterrupt: - # Since encrypted journals prompt for a password, it's easy for a user to ctrl+c out - print("[Interrupted while opening journal]", file=sys.stderr) - sys.exit(1) + if legacy: + return EncryptedJournal.LegacyEncryptedJournal(journal_name, **config).open() + return EncryptedJournal.EncryptedJournal(journal_name, **config).open() diff --git a/jrnl/cli.py b/jrnl/cli.py index 03b4f2f0c..cd33f2ec7 100644 --- a/jrnl/cli.py +++ b/jrnl/cli.py @@ -5,9 +5,10 @@ import sys import traceback -from jrnl.jrnl import run -from jrnl.args import parse_args +from .jrnl import run +from .args import parse_args from jrnl.output import print_msg + from jrnl.exception import JrnlException from jrnl.messages import Message from jrnl.messages import MsgText @@ -36,25 +37,40 @@ def cli(manual_args=None): configure_logger(args.debug) logging.debug("Parsed args: %s", args) - return run(args) + status_code = run(args) except JrnlException as e: + status_code = 1 e.print() - return 1 except KeyboardInterrupt: - print_msg(Message(MsgText.KeyboardInterruptMsg, MsgType.WARNING)) - return 1 + status_code = 1 + print_msg("\nKeyboardInterrupt", "\nAborted by user", msg=Message.ERROR) except Exception as e: + # uncaught exception + status_code = 1 + debug = False try: - is_debug = args.debug # type: ignore + if args.debug: # type: ignore + debug = True except NameError: - # error happened before args were parsed - is_debug = "--debug" in sys.argv[1:] + # This should only happen when the exception + # happened before the args were parsed + if "--debug" in sys.argv: + debug = True - if is_debug: + if debug: + print("\n") traceback.print_tb(sys.exc_info()[2]) - print_msg(Message(MsgText.UncaughtException, MsgType.ERROR, {"exception": e})) - return 1 + print_msg( + Message( + MsgText.UncaughtException, + MsgType.ERROR, + {"name": type(e).__name__, "exception": e}, + ) + ) + + # This should be the only exit point + return status_code diff --git a/jrnl/config.py b/jrnl/config.py index 63de05867..2b07b14bb 100644 --- a/jrnl/config.py +++ b/jrnl/config.py @@ -197,9 +197,13 @@ def get_journal_name(args, config): args.text = args.text[1:] if args.journal_name not in config["journals"]: - print("No default journal configured.", file=sys.stderr) - print(list_journals(config), file=sys.stderr) - sys.exit(1) + raise JrnlException( + Message( + MsgText.NoDefaultJournal, + MsgType.ERROR, + {"journals": list_journals(config)}, + ), + ) logging.debug("Using journal name: %s", args.journal_name) return args diff --git a/jrnl/editor.py b/jrnl/editor.py index 81ca659ac..24c625de5 100644 --- a/jrnl/editor.py +++ b/jrnl/editor.py @@ -3,11 +3,8 @@ import subprocess import sys import tempfile -import textwrap from pathlib import Path -from jrnl.color import ERROR_COLOR -from jrnl.color import RESET_COLOR from jrnl.os_compat import on_windows from jrnl.os_compat import split_args from jrnl.output import print_msg @@ -32,22 +29,21 @@ def get_text_from_editor(config, template=""): try: subprocess.call(split_args(config["editor"]) + [tmpfile]) - except FileNotFoundError as e: - error_msg = f""" - {ERROR_COLOR}{str(e)}{RESET_COLOR} - - Please check the 'editor' key in your config file for errors: - {repr(config['editor'])} - """ - print(textwrap.dedent(error_msg).strip(), file=sys.stderr) - exit(1) + except FileNotFoundError: + raise JrnlException( + Message( + MsgText.EditorMisconfigured, + MsgType.ERROR, + {"editor_key": config["editor"]}, + ) + ) with open(tmpfile, "r", encoding="utf-8") as f: raw = f.read() os.remove(tmpfile) if not raw: - print("[Nothing saved to file]", file=sys.stderr) + raise JrnlException(Message(MsgText.NoTextReceived, MsgType.ERROR)) return raw diff --git a/jrnl/exception.py b/jrnl/exception.py index 76da211db..fdfa61a44 100644 --- a/jrnl/exception.py +++ b/jrnl/exception.py @@ -4,16 +4,6 @@ from jrnl.output import print_msg -class UserAbort(Exception): - pass - - -class UpgradeValidationException(Exception): - """Raised when the contents of an upgraded journal do not match the old journal""" - - pass - - class JrnlException(Exception): """Common exceptions raised by jrnl.""" diff --git a/jrnl/install.py b/jrnl/install.py index b2b583cfb..306b44e15 100644 --- a/jrnl/install.py +++ b/jrnl/install.py @@ -14,10 +14,14 @@ from .config import load_config from .config import save_config from .config import verify_config_colors -from .exception import UserAbort from .prompt import yesno from .upgrade import is_old_version +from jrnl.exception import JrnlException +from jrnl.messages import Message +from jrnl.messages import MsgText +from jrnl.messages import MsgType + def upgrade_config(config_data, alt_config_path=None): """Checks if there are keys missing in a given config dict, and if so, updates the config file accordingly. @@ -47,14 +51,14 @@ def find_default_config(): def find_alt_config(alt_config): - if os.path.exists(alt_config): - return alt_config - else: - print( - "Alternate configuration file not found at path specified.", file=sys.stderr + if not os.path.exists(alt_config): + raise JrnlException( + Message( + MsgText.AltConfigNotFound, MsgType.ERROR, {"config_file": alt_config} + ) ) - print("Exiting.", file=sys.stderr) - sys.exit(1) + + return alt_config def load_or_install_jrnl(alt_config_path): @@ -72,32 +76,16 @@ def load_or_install_jrnl(alt_config_path): config = load_config(config_path) if is_old_version(config_path): - from . import upgrade - - try: - upgrade.upgrade_jrnl(config_path) - except upgrade.UpgradeValidationException: - print("Aborting upgrade.", file=sys.stderr) - print( - "Please tell us about this problem at the following URL:", - file=sys.stderr, - ) - print( - "https://github.com/jrnl-org/jrnl/issues/new?title=UpgradeValidationException", - file=sys.stderr, - ) - print("Exiting.", file=sys.stderr) - sys.exit(1) + from jrnl import upgrade + + upgrade.upgrade_jrnl(config_path) upgrade_config(config, alt_config_path) verify_config_colors(config) else: logging.debug("Configuration file not found, installing jrnl...") - try: - config = install() - except KeyboardInterrupt: - raise UserAbort("Installation aborted") + config = install() logging.debug('Using configuration "%s"', config) return config diff --git a/jrnl/jrnl.py b/jrnl/jrnl.py index 232eb7028..8014b628e 100644 --- a/jrnl/jrnl.py +++ b/jrnl/jrnl.py @@ -7,17 +7,19 @@ from . import install from . import plugins from .Journal import open_journal -from .color import ERROR_COLOR -from .color import RESET_COLOR from .config import get_journal_name from .config import scope_config from .config import get_config_path from .editor import get_text_from_editor from .editor import get_text_from_stdin -from .exception import UserAbort from . import time from .override import apply_overrides +from jrnl.exception import JrnlException +from jrnl.messages import Message +from jrnl.messages import MsgText +from jrnl.messages import MsgType + def run(args): """ @@ -35,18 +37,14 @@ def run(args): return args.preconfig_cmd(args) # Load the config, and extract journal name - try: - config = install.load_or_install_jrnl(args.config_file_path) - original_config = config.copy() + config = install.load_or_install_jrnl(args.config_file_path) + original_config = config.copy() - # Apply config overrides - config = apply_overrides(args, config) + # Apply config overrides + config = apply_overrides(args, config) - args = get_journal_name(args, config) - config = scope_config(config, args.journal_name) - except UserAbort as err: - print(f"\n{err}", file=sys.stderr) - sys.exit(1) + args = get_journal_name(args, config) + config = scope_config(config, args.journal_name) # Run post-config command now that config is ready if callable(args.postconfig_cmd): @@ -138,7 +136,9 @@ def write_mode(args, config, journal, **kwargs): if not raw: logging.error("Write mode: couldn't get raw text") - sys.exit() + raise JrnlException( + Message(MsgText.JrnlExceptionMessage.NoTextReceived, MsgType.ERROR) + ) logging.debug( 'Write mode: appending raw text to journal "%s": %s', args.journal_name, raw @@ -202,11 +202,13 @@ def _get_editor_template(config, **kwargs): logging.debug("Write mode: template loaded: %s", template) except OSError: logging.error("Write mode: template not loaded") - print( - f"[Could not read template at '{config['template']}']", - file=sys.stderr, + raise JrnlException( + Message( + MsgText.CantReadTemplate, + MsgType.ERROR, + {"template": config["template"]}, + ) ) - sys.exit(1) return template @@ -243,16 +245,13 @@ def _edit_search_results(config, journal, old_entries, **kwargs): 3. Write modifications to journal """ if not config["editor"]: - print( - f""" - [{ERROR_COLOR}ERROR{RESET_COLOR}: There is no editor configured.] - - Please specify an editor in config file ({get_config_path()}) - to use the --edit option. - """, - file=sys.stderr, + raise JrnlException( + Message( + MsgText.EditorNotConfigured, + MsgType.ERROR, + {"config_file": get_config_path()}, + ) ) - sys.exit(1) # separate entries we are not editing other_entries = [e for e in old_entries if e not in journal.entries] @@ -310,11 +309,7 @@ def _pluralize_entry(num): def _delete_search_results(journal, old_entries, **kwargs): if not journal.entries: - print( - "[No entries deleted, because the search returned no results.]", - file=sys.stderr, - ) - sys.exit(1) + raise JrnlException(Message(MsgText.NothingToDelete, MsgType.ERROR)) entries_to_delete = journal.prompt_delete_entries() diff --git a/jrnl/messages.py b/jrnl/messages.py index eed0cbaef..e6a1933a7 100644 --- a/jrnl/messages.py +++ b/jrnl/messages.py @@ -26,7 +26,7 @@ def __str__(self) -> str: # --- Exceptions ---# UncaughtException = """ - ERROR + {name} {exception} This is probably a bug. Please file an issue at: @@ -61,6 +61,14 @@ def __str__(self) -> str: KeyboardInterruptMsg = "Aborted by user" + CantReadTemplate = """ + Unreadable template + Could not read template file at: + {template} + """ + + NoDefaultJournal = "No default journal configured\n{journals}" + # --- Journal status ---# JournalNotSaved = "Entry NOT saved to journal" @@ -72,6 +80,56 @@ def __str__(self) -> str: HowToQuitWindows = "Ctrl+z and then Enter" HowToQuitLinux = "Ctrl+d" + EditorMisconfigured = """ + No such file or directory: '{editor_key}' + + Please check the 'editor' key in your config file for errors: + editor: '{editor_key}' + """ + + EditorNotConfigured = """ + There is no editor configured + + To use the --edit option, please specify an editor your config file: + {config_file} + + For examples of how to configure an external editor, see: + https://jrnl.sh/en/stable/external-editors/ + """ + + NoTextReceived = """ + Nothing saved to file + """ + + # --- Upgrade --- # + JournalFailedUpgrade = """ + The following journal{s} failed to upgrade: + {failed_journals} + + Please tell us about this problem at the following URL: + https://github.com/jrnl-org/jrnl/issues/new?title=JournalFailedUpgrade + """ + + UpgradeAborted = "jrnl was NOT upgraded" + + ImportAborted = "Entries were NOT imported" + + # -- Config --- # + AltConfigNotFound = """ + Alternate configuration file not found at the given path: + {config_file} + """ + + # --- Password --- # + PasswordMaxTriesExceeded = """ + Too many attempts with wrong password + """ + + # --- Search --- # + NothingToDelete = """ + No entries to delete, because the search returned no results + """ + class Message(NamedTuple): text: MsgText diff --git a/jrnl/output.py b/jrnl/output.py index 4f28b96ab..f31a02e26 100644 --- a/jrnl/output.py +++ b/jrnl/output.py @@ -29,7 +29,7 @@ def list_journals(configuration): from . import config """List the journals specified in the configuration file""" - result = f"Journals defined in {config.get_config_path()}\n" + result = f"Journals defined in config ({config.get_config_path()})\n" ml = min(max(len(k) for k in configuration["journals"]), 20) for journal, cfg in configuration["journals"].items(): result += " * {:{}} -> {}\n".format( diff --git a/jrnl/plugins/jrnl_importer.py b/jrnl/plugins/jrnl_importer.py index 214fc70b4..54dd2ab83 100644 --- a/jrnl/plugins/jrnl_importer.py +++ b/jrnl/plugins/jrnl_importer.py @@ -4,6 +4,11 @@ import sys +from jrnl.exception import JrnlException +from jrnl.messages import Message +from jrnl.messages import MsgText +from jrnl.messages import MsgType + class JRNLImporter: """This plugin imports entries from other jrnl files.""" @@ -22,8 +27,11 @@ def import_(journal, input=None): try: other_journal_txt = sys.stdin.read() except KeyboardInterrupt: - print("[Entries NOT imported into journal.]", file=sys.stderr) - sys.exit(0) + raise JrnlException( + Message(MsgText.KeyboardInterruptMsg, MsgType.ERROR), + Message(MsgText.ImportAborted, MsgType.WARNING), + ) + journal.import_(other_journal_txt) new_cnt = len(journal.entries) print( diff --git a/jrnl/upgrade.py b/jrnl/upgrade.py index 158f8de3f..3027f4e7e 100644 --- a/jrnl/upgrade.py +++ b/jrnl/upgrade.py @@ -10,10 +10,15 @@ from .config import is_config_json from .config import load_config from .config import scope_config -from .exception import UpgradeValidationException -from .exception import UserAbort from .prompt import yesno +from jrnl.output import print_msg + +from jrnl.exception import JrnlException +from jrnl.messages import Message +from jrnl.messages import MsgText +from jrnl.messages import MsgType + def backup(filename, binary=False): print(f" Created a backup at {filename}.backup", file=sys.stderr) @@ -27,13 +32,9 @@ def backup(filename, binary=False): backup.write(contents) except FileNotFoundError: print(f"\nError: {filename} does not exist.") - try: - cont = yesno(f"\nCreate {filename}?", default=False) - if not cont: - raise KeyboardInterrupt - - except KeyboardInterrupt: - raise UserAbort("jrnl NOT upgraded, exiting.") + cont = yesno(f"\nCreate {filename}?", default=False) + if not cont: + raise JrnlException(Message(MsgText.UpgradeAborted), MsgType.WARNING) def check_exists(path): @@ -121,12 +122,9 @@ def upgrade_jrnl(config_path): file=sys.stderr, ) - try: - cont = yesno("\nContinue upgrading jrnl?", default=False) - if not cont: - raise KeyboardInterrupt - except KeyboardInterrupt: - raise UserAbort("jrnl NOT upgraded, exiting.") + cont = yesno("\nContinue upgrading jrnl?", default=False) + if not cont: + raise JrnlException(Message(MsgText.UpgradeAborted), MsgType.WARNING) for journal_name, path in encrypted_journals.items(): print( @@ -154,16 +152,19 @@ def upgrade_jrnl(config_path): failed_journals = [j for j in all_journals if not j.validate_parsing()] if len(failed_journals) > 0: - print( - "\nThe following journal{} failed to upgrade:\n{}".format( - "s" if len(failed_journals) > 1 else "", - "\n".join(j.name for j in failed_journals), - ), - file=sys.stderr, + print_msg("Aborting upgrade.", msg=Message.NORMAL) + + raise JrnlException( + Message( + MsgText.JournalFailedUpgrade, + MsgType.ERROR, + { + "s": "s" if len(failed_journals) > 1 else "", + "failed_journals": "\n".join(j.name for j in failed_journals), + }, + ) ) - raise UpgradeValidationException - # write all journals - or - don't for j in all_journals: j.write() diff --git a/tests/bdd/features/delete.feature b/tests/bdd/features/delete.feature index cfbe08ee2..fe323966a 100644 --- a/tests/bdd/features/delete.feature +++ b/tests/bdd/features/delete.feature @@ -41,6 +41,7 @@ Feature: Delete entries from journal Scenario Outline: Delete flag with nonsense input deletes nothing (issue #932) Given we use the config "" When we run "jrnl --delete asdfasdf" + Then the output should contain "No entries to delete" When we run "jrnl -99 --short" Then the output should be 2020-08-29 11:11 Entry the first. diff --git a/tests/bdd/features/write.feature b/tests/bdd/features/write.feature index 062c5fef6..60f220021 100644 --- a/tests/bdd/features/write.feature +++ b/tests/bdd/features/write.feature @@ -78,7 +78,7 @@ Feature: Writing new entries. And we write nothing to the editor if opened And we use the password "test" if prompted When we run "jrnl --edit" - Then the error output should contain "[Nothing saved to file]" + Then the error output should contain "Nothing saved to file" And the editor should have been called Examples: configs diff --git a/tests/unit/test_config_file.py b/tests/unit/test_config_file.py index 04766f4a3..f9cdb7ecd 100644 --- a/tests/unit/test_config_file.py +++ b/tests/unit/test_config_file.py @@ -2,6 +2,7 @@ import os from jrnl.install import find_alt_config +from jrnl.exception import JrnlException def test_find_alt_config(request): @@ -14,9 +15,9 @@ def test_find_alt_config(request): def test_find_alt_config_not_exist(request): bad_config_path = os.path.join( - request.fspath.dirname, "..", "data", "configs", "not-existing-config.yaml" + request.fspath.dirname, "..", "data", "configs", "does-not-exist.yaml" ) - with pytest.raises(SystemExit) as ex: + with pytest.raises(JrnlException) as ex: found_alt_config = find_alt_config(bad_config_path) assert found_alt_config is not None - assert isinstance(ex.value, SystemExit) + assert isinstance(ex.value, JrnlException) diff --git a/tests/unit/test_export.py b/tests/unit/test_export.py index 05c29a1f7..1ca8856f3 100644 --- a/tests/unit/test_export.py +++ b/tests/unit/test_export.py @@ -1,7 +1,6 @@ import pytest from jrnl.exception import JrnlException - from jrnl.plugins.fancy_exporter import check_provided_linewrap_viability