mirror of
https://github.com/jrnl-org/jrnl.git
synced 2025-05-10 00:28:31 +02:00
* added new CLI argument option --config-file * pass argument and fetch alt config file if specified * argparse argument setting update * argument alias --cf added * documentation update - usage of CLI argument * fixed name-clash + unit tests * feature test added * #1170-alternate-config-file: Auto stash before rebase of "refs/heads/#1170-alternate-config-file" * Update docs/advanced.md Co-authored-by: Jonathan Wren <jonathan@nowandwren.com> * BDD tests added * Begin migrating/rewording --cf tests in pytest-bdd. Uses current directory instead of deep directory structure, but requires a given for each config file referenced * Fix issue where specifying a config-file that needs to be upgraded ended up upgrading the user config file instead * Uncomment and rework remaining tests for pytest-bdd instead of behave * Fix copytree for Python 3.7 (which doesn't support dirs_exist_ok) * Minor fixes to alternative config examples * Remove behave tests (behave is no longer in use) * Move config file unit test to unit test dir and use pytext path fixture instead of current directory to find test data * Use explicit "given the config exists" for copying config files instead of shoehorning in "given we use the config" twice * Change when/when to when/and * Clarify scenarios and fix indentation * Confirm primary config file isn't modified when encrypting/decrypting a journal in an alternate config file * Remove try/except on copytree since I'm no longer using the same Co-authored-by: Jonathan Wren <jonathan@nowandwren.com> Co-authored-by: Micah Jerome Ellison <micah.jerome.ellison@gmail.com>
142 lines
4.8 KiB
Python
142 lines
4.8 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 keyring import set_keyring
|
|
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
|
|
|
|
|
|
@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>"'))
|
|
@given(parse('now is "{date_str}"'))
|
|
def now_is_str(date_str, mocks):
|
|
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()
|
|
)
|
|
|
|
mocks["datetime"] = patch("datetime.datetime", new=datetime_mock)
|
|
mocks["calendar_parse"] = 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":
|
|
set_keyring(FailedKeyring())
|
|
else:
|
|
set_keyring(TestKeyring())
|
|
|
|
|
|
@given(parse('we use the config "{config_file}"'), target_fixture="config_path")
|
|
@given('we use the config "<config_file>"', target_fixture="config_path")
|
|
def we_use_the_config(config_file, temp_dir, working_dir):
|
|
# Move into temp dir as cwd
|
|
os.chdir(temp_dir.name)
|
|
|
|
# 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):
|
|
# 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")
|
|
@given('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 "{pw}" if prompted'), target_fixture="password")
|
|
def use_password_forever(pw):
|
|
return pw
|
|
|
|
|
|
@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}
|