mirror of
https://github.com/jrnl-org/jrnl.git
synced 2025-05-10 00:28:31 +02:00
* fix missed statement from last PR * replace print statement for adding an entry to a journal * clean up linting and format * change print statement over to new print_msg function * make print_msg always print to stderr * change print statement over to new print_msg function * update importer to use new message function * update yaml format to use new message function * code cleanup * update yaml format to use new message function * update yaml format to use new exception handling * update Journal class to use new message function * update install module to use new message function * update config module to use new message function * update upgrade module to properly use new message and exception handling * fix typo * update upgrade module to use new message handling * update welcome message to use new handling * update upgrade module to use new message handling * update upgrade module journal summaries to use new message handling * take out old code * update upgrade module to use new message handling * update upgrade module to use new message handling * update more modules to use new message handling * take out old comment * update deprecated_cmd to use new message handling * update text_exporter with new message handling, get rid of old color constants * get rid of hardcoded text * whitespace changes * rework MsgType into MsgStyle so messages can have different styles * add comment * Move around code to separate concerns of each function a bit more * update create_password and yesno prompt functions for new messaging * fix missing newline for keyboard interrupts * fix misc linting * fix bug with panel titles always showing 'error' after one error * fix missing import * update debug output after uncaught exception * update exception for new exception handling * rewrite yesno function to use new centralized messages * reduce the debug output slightly * clean up print_msgs function * clean up create_password function * clean up misc linting * rename screen_input to hide_input to be more clear * update encrypted journal prompt to use new messaging functionality * fix typo in message key * move rich console into function so we can mock properly * update password mock to use rich console instead of getpass * add more helpful output to then step * fix test by updating expected output * update message to use new functionality * rework mocks in test suite for new messaging functionality * fix linting issue * fix more tests * fix more tests * fix more tests * fix more tests * fix merge bug * update prompt_action_entries to use new messaging functionality * Add new input_method "type" This does the same thing as input_method "pipe" but is more clear what it's doing (typing text into the builtin composer) * get rid of old commented code * get rid of unused code * move some files around Co-authored-by: Micah Jerome Ellison <micah.jerome.ellison@gmail.com>
149 lines
4.9 KiB
Python
149 lines
4.9 KiB
Python
# Copyright (C) 2012-2021 jrnl contributors
|
|
# License: https://www.gnu.org/licenses/gpl-3.0.html
|
|
|
|
from datetime import datetime
|
|
import json
|
|
import os
|
|
import random
|
|
import shutil
|
|
import string
|
|
from unittest.mock import MagicMock
|
|
from unittest.mock import patch
|
|
from xml.etree import ElementTree
|
|
|
|
from pytest_bdd import given
|
|
from pytest_bdd.parsers import parse
|
|
|
|
from jrnl import __version__
|
|
from jrnl.time import __get_pdt_calendar
|
|
|
|
from .fixtures import FailedKeyring
|
|
from .fixtures import TestKeyring
|
|
from .helpers import get_fixture
|
|
|
|
|
|
@given(parse("we {editor_method} to the editor if opened\n{editor_input}"))
|
|
@given(parse("we {editor_method} nothing to the editor if opened"))
|
|
def we_enter_editor(editor_method, editor_input, editor_state):
|
|
file_method = editor_state["intent"]["method"]
|
|
if editor_method == "write":
|
|
file_method = "w+"
|
|
elif editor_method == "append":
|
|
file_method = "a+"
|
|
else:
|
|
assert False, f"Method '{editor_method}' not supported"
|
|
|
|
editor_state["intent"] = {"method": file_method, "input": editor_input}
|
|
|
|
|
|
@given(parse('now is "{date_str}"'))
|
|
def now_is_str(date_str, mock_factories):
|
|
class DatetimeMagicMock(MagicMock):
|
|
# needed because jrnl does some reflection on datetime
|
|
def __instancecheck__(self, subclass):
|
|
return isinstance(subclass, datetime)
|
|
|
|
def mocked_now(tz=None):
|
|
now = datetime.strptime(date_str, "%Y-%m-%d %I:%M:%S %p")
|
|
|
|
if tz:
|
|
time_zone = datetime.utcnow().astimezone().tzinfo
|
|
now = now.replace(tzinfo=time_zone)
|
|
|
|
return now
|
|
|
|
# jrnl uses two different classes to parse dates, so both must be mocked
|
|
datetime_mock = DatetimeMagicMock(wraps=datetime)
|
|
datetime_mock.now.side_effect = mocked_now
|
|
|
|
pdt = __get_pdt_calendar()
|
|
calendar_mock = MagicMock(wraps=pdt)
|
|
calendar_mock.parse.side_effect = lambda date_str_input: pdt.parse(
|
|
date_str_input, mocked_now()
|
|
)
|
|
|
|
mock_factories["datetime"] = lambda: patch("datetime.datetime", new=datetime_mock)
|
|
mock_factories["calendar_parse"] = lambda: patch(
|
|
"jrnl.time.__get_pdt_calendar", return_value=calendar_mock
|
|
)
|
|
|
|
|
|
@given("we have a keyring", target_fixture="keyring")
|
|
@given(parse("we have a {keyring_type} keyring"), target_fixture="keyring")
|
|
def we_have_type_of_keyring(keyring_type):
|
|
if keyring_type == "failed":
|
|
return FailedKeyring()
|
|
else:
|
|
return TestKeyring()
|
|
|
|
|
|
@given(parse('we use the config "{config_file}"'), target_fixture="config_path")
|
|
@given(parse("we use no config"), target_fixture="config_path")
|
|
def we_use_the_config(request, temp_dir, working_dir):
|
|
config_file = get_fixture(request, "config_file")
|
|
|
|
# Move into temp dir as cwd
|
|
os.chdir(temp_dir.name)
|
|
|
|
if not config_file:
|
|
return os.path.join(temp_dir.name, "non_existing_config.yaml")
|
|
|
|
# Copy the config file over
|
|
config_source = os.path.join(working_dir, "data", "configs", config_file)
|
|
config_dest = os.path.join(temp_dir.name, config_file)
|
|
shutil.copy2(config_source, config_dest)
|
|
|
|
# @todo make this only copy some journals over
|
|
# Copy all of the journals over
|
|
journal_source = os.path.join(working_dir, "data", "journals")
|
|
journal_dest = os.path.join(temp_dir.name, "features", "journals")
|
|
shutil.copytree(journal_source, journal_dest)
|
|
|
|
# @todo get rid of this by using default config values
|
|
# merge in version number
|
|
if (
|
|
config_file.endswith("yaml")
|
|
and os.path.exists(config_dest)
|
|
and os.path.getsize(config_dest) > 0
|
|
):
|
|
# Add jrnl version to file for 2.x journals
|
|
with open(config_dest, "a") as cf:
|
|
cf.write("version: {}".format(__version__))
|
|
|
|
return config_dest
|
|
|
|
|
|
@given(parse('the config "{config_file}" exists'), target_fixture="config_path")
|
|
def config_exists(config_file, temp_dir, working_dir):
|
|
config_source = os.path.join(working_dir, "data", "configs", config_file)
|
|
config_dest = os.path.join(temp_dir.name, config_file)
|
|
shutil.copy2(config_source, config_dest)
|
|
|
|
|
|
@given(parse('we use the password "{password}" if prompted'))
|
|
def use_password_forever(password):
|
|
return password
|
|
|
|
|
|
@given("we create a cache directory", target_fixture="cache_dir")
|
|
def create_cache_dir(temp_dir):
|
|
random_str = "".join(random.choices(string.ascii_uppercase + string.digits, k=20))
|
|
|
|
dir_path = os.path.join(temp_dir.name, "cache_" + random_str)
|
|
os.mkdir(dir_path)
|
|
return {"exists": True, "path": dir_path}
|
|
|
|
|
|
@given(parse("we parse the output as {language_name}"), target_fixture="parsed_output")
|
|
def parse_output_as_language(cli_run, language_name):
|
|
language_name = language_name.upper()
|
|
actual_output = cli_run["stdout"]
|
|
|
|
if language_name == "XML":
|
|
parsed_output = ElementTree.fromstring(actual_output)
|
|
elif language_name == "JSON":
|
|
parsed_output = json.loads(actual_output)
|
|
else:
|
|
assert False, f"Language name {language_name} not recognized"
|
|
|
|
return {"lang": language_name, "obj": parsed_output}
|