mirror of
https://github.com/jrnl-org/jrnl.git
synced 2025-06-27 21:16:14 +02:00
Implement datetime handling in pytest-bdd
- This was awful and convoluted Co-authored-by: Micah Jerome Ellison <micah.jerome.ellison@gmail.com>
This commit is contained in:
parent
cda07bf8d9
commit
4aabb73847
16 changed files with 133 additions and 87 deletions
17
tests/unit/test_color.py
Normal file
17
tests/unit/test_color.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
import pytest
|
||||
|
||||
from jrnl.color import colorize
|
||||
from colorama import Fore, Style
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def data_fixture():
|
||||
string = "Zwei peanuts walked into a bar"
|
||||
yield string
|
||||
|
||||
|
||||
def test_colorize(data_fixture):
|
||||
string = data_fixture
|
||||
colorized_string = colorize(string, "BLUE", True)
|
||||
|
||||
assert colorized_string == Style.BRIGHT + Fore.BLUE + string + Style.RESET_ALL
|
23
tests/unit/test_display.py
Normal file
23
tests/unit/test_display.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
import argparse
|
||||
import jrnl
|
||||
import pytest
|
||||
from unittest import mock
|
||||
from jrnl.jrnl import _display_search_results
|
||||
|
||||
|
||||
# fmt: off
|
||||
# see: https://github.com/psf/black/issues/664
|
||||
@pytest.mark.parametrize("export_format", [ "pretty", "short","markdown"])
|
||||
#fmt: on
|
||||
@mock.patch.object(argparse, "Namespace", return_value={"export": "markdown", "filename": "irrele.vant"})
|
||||
def test_export_format(mock_args, export_format):
|
||||
|
||||
test_journal = jrnl.Journal.Journal
|
||||
mock_args.export = export_format
|
||||
#fmt: off
|
||||
# see: https://github.com/psf/black/issues/664
|
||||
with mock.patch("builtins.print") as mock_spy_print, \
|
||||
mock.patch('jrnl.Journal.Journal.pprint') as mock_pprint:
|
||||
_display_search_results(mock_args, test_journal)
|
||||
mock_spy_print.assert_called_once_with(mock_pprint())
|
||||
#fmt: on
|
19
tests/unit/test_exception.py
Normal file
19
tests/unit/test_exception.py
Normal file
|
@ -0,0 +1,19 @@
|
|||
import textwrap
|
||||
|
||||
from jrnl.exception import JrnlError
|
||||
|
||||
|
||||
def test_config_directory_exception_message():
|
||||
ex = JrnlError(
|
||||
"ConfigDirectoryIsFile", config_directory_path="/config/directory/path"
|
||||
)
|
||||
|
||||
assert ex.message == textwrap.dedent(
|
||||
"""
|
||||
The path to your jrnl configuration directory is a file, not a directory:
|
||||
|
||||
/config/directory/path
|
||||
|
||||
Removing this file will allow jrnl to save its configuration.
|
||||
"""
|
||||
)
|
28
tests/unit/test_export.py
Normal file
28
tests/unit/test_export.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
from jrnl.exception import JrnlError
|
||||
from jrnl.plugins.fancy_exporter import check_provided_linewrap_viability
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def datestr():
|
||||
yield "2020-10-20 16:59"
|
||||
|
||||
|
||||
def build_card_header(datestr):
|
||||
top_left_corner = "┎─╮"
|
||||
content = top_left_corner + datestr
|
||||
return content
|
||||
|
||||
|
||||
class TestFancy:
|
||||
def test_too_small_linewrap(self, datestr):
|
||||
|
||||
journal = "test_journal"
|
||||
content = build_card_header(datestr)
|
||||
|
||||
total_linewrap = 12
|
||||
|
||||
with pytest.raises(JrnlError) as e:
|
||||
check_provided_linewrap_viability(total_linewrap, [content], journal)
|
||||
assert e.value.error_type == "LineWrapTooSmallForDateFormat"
|
13
tests/unit/test_install.py
Normal file
13
tests/unit/test_install.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
from unittest import mock
|
||||
import pytest
|
||||
import sys
|
||||
|
||||
|
||||
@pytest.mark.filterwarnings(
|
||||
"ignore:.*imp module is deprecated.*"
|
||||
) # ansiwrap spits out an unrelated warning
|
||||
def test_initialize_autocomplete_runs_without_readline():
|
||||
from jrnl import install
|
||||
|
||||
with mock.patch.dict(sys.modules, {"readline": None}):
|
||||
install._initialize_autocomplete() # should not throw exception
|
87
tests/unit/test_os_compat.py
Normal file
87
tests/unit/test_os_compat.py
Normal file
|
@ -0,0 +1,87 @@
|
|||
from unittest import mock
|
||||
import pytest
|
||||
|
||||
from jrnl.os_compat import on_windows
|
||||
from jrnl.os_compat import on_posix
|
||||
from jrnl.os_compat import split_args
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"systems",
|
||||
[
|
||||
["linux", False],
|
||||
["win32", True],
|
||||
["cygwin", False],
|
||||
["msys", False],
|
||||
["darwin", False],
|
||||
["os2", False],
|
||||
["os2emx", False],
|
||||
["riscos", False],
|
||||
["atheos", False],
|
||||
["freebsd7", False],
|
||||
["freebsd8", False],
|
||||
["freebsdN", False],
|
||||
["openbsd6", False],
|
||||
],
|
||||
)
|
||||
def test_on_windows(systems):
|
||||
osname, expected_on_windows = systems[0], systems[1]
|
||||
with mock.patch("jrnl.os_compat.platform", osname):
|
||||
assert on_windows() == expected_on_windows
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"systems",
|
||||
[
|
||||
["linux", True],
|
||||
["win32", False],
|
||||
["cygwin", True],
|
||||
["msys", True],
|
||||
["darwin", True],
|
||||
["os2", True],
|
||||
["os2emx", True],
|
||||
["riscos", True],
|
||||
["atheos", True],
|
||||
["freebsd7", True],
|
||||
["freebsd8", True],
|
||||
["freebsdN", True],
|
||||
["openbsd6", True],
|
||||
],
|
||||
)
|
||||
def test_on_posix(systems):
|
||||
osname, expected_on_posix = systems[0], systems[1]
|
||||
with mock.patch("jrnl.os_compat.platform", osname):
|
||||
assert on_posix() == expected_on_posix
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"args",
|
||||
[
|
||||
["notepad", ["notepad"]],
|
||||
["subl -w", ["subl", "-w"]],
|
||||
[
|
||||
'"C:\\Program Files\\Sublime Text 3\\subl.exe" -w',
|
||||
['"C:\\Program Files\\Sublime Text 3\\subl.exe"', "-w"],
|
||||
],
|
||||
],
|
||||
)
|
||||
def test_split_args_on_windows(args):
|
||||
input_arguments, expected_split_args = args[0], args[1]
|
||||
with mock.patch("jrnl.os_compat.on_windows", lambda: True):
|
||||
assert split_args(input_arguments) == expected_split_args
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"args",
|
||||
[
|
||||
["vim", ["vim"]],
|
||||
[
|
||||
'vim -f +Goyo +Limelight "+set spell linebreak"',
|
||||
["vim", "-f", "+Goyo", "+Limelight", '"+set spell linebreak"'],
|
||||
],
|
||||
],
|
||||
)
|
||||
def test_split_args_on_not_windows(args):
|
||||
input_arguments, expected_split_args = args[0], args[1]
|
||||
with mock.patch("jrnl.os_compat.on_windows", lambda: True):
|
||||
assert split_args(input_arguments) == expected_split_args
|
79
tests/unit/test_override.py
Normal file
79
tests/unit/test_override.py
Normal file
|
@ -0,0 +1,79 @@
|
|||
import pytest
|
||||
|
||||
from jrnl.override import (
|
||||
apply_overrides,
|
||||
_recursively_apply,
|
||||
_get_config_node,
|
||||
_get_key_and_value_from_pair,
|
||||
_convert_dots_to_list,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def minimal_config():
|
||||
cfg = {
|
||||
"colors": {"body": "red", "date": "green"},
|
||||
"default": "/tmp/journal.jrnl",
|
||||
"editor": "vim",
|
||||
"journals": {"default": "/tmp/journals/journal.jrnl"},
|
||||
}
|
||||
return cfg
|
||||
|
||||
|
||||
def test_apply_override(minimal_config):
|
||||
overrides = [["editor", "nano"]]
|
||||
apply_overrides(overrides, minimal_config)
|
||||
assert minimal_config["editor"] == "nano"
|
||||
|
||||
|
||||
def test_override_dot_notation(minimal_config):
|
||||
overrides = [["colors.body", "blue"]]
|
||||
|
||||
cfg = apply_overrides(overrides=overrides, base_config=minimal_config)
|
||||
assert cfg["colors"] == {"body": "blue", "date": "green"}
|
||||
|
||||
|
||||
def test_multiple_overrides(minimal_config):
|
||||
overrides = [
|
||||
["colors.title", "magenta"],
|
||||
["editor", "nano"],
|
||||
["journals.burner", "/tmp/journals/burner.jrnl"],
|
||||
] # as returned by parse_args, saved in parser.config_override
|
||||
|
||||
cfg = apply_overrides(overrides, minimal_config)
|
||||
assert cfg["editor"] == "nano"
|
||||
assert cfg["colors"]["title"] == "magenta"
|
||||
assert "burner" in cfg["journals"]
|
||||
assert cfg["journals"]["burner"] == "/tmp/journals/burner.jrnl"
|
||||
|
||||
|
||||
def test_recursively_apply():
|
||||
cfg = {"colors": {"body": "red", "title": "green"}}
|
||||
cfg = _recursively_apply(cfg, ["colors", "body"], "blue")
|
||||
assert cfg["colors"]["body"] == "blue"
|
||||
|
||||
|
||||
def test_get_config_node(minimal_config):
|
||||
assert len(minimal_config.keys()) == 4
|
||||
assert _get_config_node(minimal_config, "editor") == "vim"
|
||||
assert _get_config_node(minimal_config, "display_format") == None
|
||||
|
||||
|
||||
def test_get_kv_from_pair():
|
||||
pair = {"ab.cde": "fgh"}
|
||||
k, v = _get_key_and_value_from_pair(pair)
|
||||
assert k == "ab.cde"
|
||||
assert v == "fgh"
|
||||
|
||||
|
||||
class TestDotNotationToList:
|
||||
def test_unpack_dots_to_list(self):
|
||||
|
||||
keys = "a.b.c.d.e.f"
|
||||
keys_list = _convert_dots_to_list(keys)
|
||||
assert len(keys_list) == 6
|
||||
|
||||
def test_sequential_delimiters(self):
|
||||
k = "g.r..h.v"
|
||||
k_l = _convert_dots_to_list(k)
|
||||
assert len(k_l) == 4
|
292
tests/unit/test_parse_args.py
Normal file
292
tests/unit/test_parse_args.py
Normal file
|
@ -0,0 +1,292 @@
|
|||
import shlex
|
||||
|
||||
import pytest
|
||||
|
||||
from jrnl.args import parse_args
|
||||
from jrnl.config import make_yaml_valid_dict
|
||||
|
||||
|
||||
def cli_as_dict(str):
|
||||
cli = shlex.split(str)
|
||||
args = parse_args(cli)
|
||||
return vars(args)
|
||||
|
||||
|
||||
def expected_args(**kwargs):
|
||||
default_args = {
|
||||
"contains": None,
|
||||
"debug": False,
|
||||
"delete": False,
|
||||
"edit": False,
|
||||
"end_date": None,
|
||||
"today_in_history": False,
|
||||
"month": None,
|
||||
"day": None,
|
||||
"year": None,
|
||||
"excluded": [],
|
||||
"export": False,
|
||||
"filename": None,
|
||||
"limit": None,
|
||||
"on_date": None,
|
||||
"preconfig_cmd": None,
|
||||
"postconfig_cmd": None,
|
||||
"short": False,
|
||||
"starred": False,
|
||||
"start_date": None,
|
||||
"strict": False,
|
||||
"tags": False,
|
||||
"text": [],
|
||||
"config_override": [],
|
||||
}
|
||||
return {**default_args, **kwargs}
|
||||
|
||||
|
||||
def test_empty():
|
||||
assert cli_as_dict("") == expected_args()
|
||||
|
||||
|
||||
def test_contains_alone():
|
||||
assert cli_as_dict("-contains whatever") == expected_args(contains="whatever")
|
||||
|
||||
|
||||
def test_debug_alone():
|
||||
assert cli_as_dict("--debug") == expected_args(debug=True)
|
||||
|
||||
|
||||
def test_delete_alone():
|
||||
assert cli_as_dict("--delete") == expected_args(delete=True)
|
||||
|
||||
|
||||
def test_diagnostic_alone():
|
||||
from jrnl.commands import preconfig_diagnostic
|
||||
|
||||
assert cli_as_dict("--diagnostic") == expected_args(
|
||||
preconfig_cmd=preconfig_diagnostic
|
||||
)
|
||||
|
||||
|
||||
def test_edit_alone():
|
||||
assert cli_as_dict("--edit") == expected_args(edit=True)
|
||||
|
||||
|
||||
def test_encrypt_alone():
|
||||
from jrnl.commands import postconfig_encrypt
|
||||
|
||||
assert cli_as_dict("--encrypt") == expected_args(postconfig_cmd=postconfig_encrypt)
|
||||
|
||||
|
||||
def test_decrypt_alone():
|
||||
from jrnl.commands import postconfig_decrypt
|
||||
|
||||
assert cli_as_dict("--decrypt") == expected_args(postconfig_cmd=postconfig_decrypt)
|
||||
|
||||
|
||||
def test_end_date_alone():
|
||||
expected = expected_args(end_date="2020-01-01")
|
||||
assert expected == cli_as_dict("-until 2020-01-01")
|
||||
assert expected == cli_as_dict("-to 2020-01-01")
|
||||
|
||||
|
||||
def test_not_alone():
|
||||
assert cli_as_dict("-not test") == expected_args(excluded=["test"])
|
||||
|
||||
|
||||
def test_not_multiple_alone():
|
||||
assert cli_as_dict("-not one -not two") == expected_args(excluded=["one", "two"])
|
||||
assert cli_as_dict("-not one -not two -not three") == expected_args(
|
||||
excluded=["one", "two", "three"]
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"cli",
|
||||
[
|
||||
"two -not one -not three",
|
||||
"-not one two -not three",
|
||||
"-not one -not three two",
|
||||
],
|
||||
)
|
||||
def test_not_mixed(cli):
|
||||
result = expected_args(excluded=["one", "three"], text=["two"])
|
||||
assert cli_as_dict(cli) == result
|
||||
|
||||
|
||||
def test_not_interspersed():
|
||||
result = expected_args(excluded=["one", "three"], text=["two", "two", "two"])
|
||||
assert cli_as_dict("two -not one two -not three two") == result
|
||||
|
||||
|
||||
def test_export_alone():
|
||||
assert cli_as_dict("--export json") == expected_args(export="json")
|
||||
|
||||
|
||||
def test_import_alone():
|
||||
from jrnl.commands import postconfig_import
|
||||
|
||||
assert cli_as_dict("--import") == expected_args(postconfig_cmd=postconfig_import)
|
||||
|
||||
|
||||
def test_file_flag_alone():
|
||||
assert cli_as_dict("--file test.txt") == expected_args(filename="test.txt")
|
||||
assert cli_as_dict("--file 'lorem ipsum.txt'") == expected_args(
|
||||
filename="lorem ipsum.txt"
|
||||
)
|
||||
|
||||
|
||||
def test_limit_alone():
|
||||
assert cli_as_dict("-n 5") == expected_args(limit=5)
|
||||
assert cli_as_dict("-n 999") == expected_args(limit=999)
|
||||
|
||||
|
||||
def test_limit_shorthand_alone():
|
||||
assert cli_as_dict("-5") == expected_args(limit=5)
|
||||
assert cli_as_dict("-999") == expected_args(limit=999)
|
||||
|
||||
|
||||
def test_list_alone():
|
||||
from jrnl.commands import postconfig_list
|
||||
|
||||
assert cli_as_dict("--ls") == expected_args(postconfig_cmd=postconfig_list)
|
||||
|
||||
|
||||
def test_on_date_alone():
|
||||
assert cli_as_dict("-on 'saturday'") == expected_args(on_date="saturday")
|
||||
|
||||
|
||||
def test_month_alone():
|
||||
assert cli_as_dict("-month 1") == expected_args(month="1")
|
||||
assert cli_as_dict("-month 01") == expected_args(month="01")
|
||||
assert cli_as_dict("-month January") == expected_args(month="January")
|
||||
assert cli_as_dict("-month Jan") == expected_args(month="Jan")
|
||||
|
||||
|
||||
def test_day_alone():
|
||||
assert cli_as_dict("-day 1") == expected_args(day="1")
|
||||
assert cli_as_dict("-day 01") == expected_args(day="01")
|
||||
|
||||
|
||||
def test_year_alone():
|
||||
assert cli_as_dict("-year 2021") == expected_args(year="2021")
|
||||
assert cli_as_dict("-year 21") == expected_args(year="21")
|
||||
|
||||
|
||||
def test_today_in_history_alone():
|
||||
assert cli_as_dict("-today-in-history") == expected_args(today_in_history=True)
|
||||
|
||||
|
||||
def test_short_alone():
|
||||
assert cli_as_dict("--short") == expected_args(short=True)
|
||||
|
||||
|
||||
def test_starred_alone():
|
||||
assert cli_as_dict("-starred") == expected_args(starred=True)
|
||||
|
||||
|
||||
def test_start_date_alone():
|
||||
assert cli_as_dict("-from 2020-01-01") == expected_args(start_date="2020-01-01")
|
||||
assert cli_as_dict("-from 'January 1st'") == expected_args(start_date="January 1st")
|
||||
|
||||
|
||||
def test_and_alone():
|
||||
assert cli_as_dict("-and") == expected_args(strict=True)
|
||||
|
||||
|
||||
def test_tags_alone():
|
||||
assert cli_as_dict("--tags") == expected_args(tags=True)
|
||||
|
||||
|
||||
def test_text_alone():
|
||||
assert cli_as_dict("lorem ipsum dolor sit amet") == expected_args(
|
||||
text=["lorem", "ipsum", "dolor", "sit", "amet"]
|
||||
)
|
||||
|
||||
|
||||
def test_version_alone():
|
||||
from jrnl.commands import preconfig_version
|
||||
|
||||
assert cli_as_dict("--version") == expected_args(preconfig_cmd=preconfig_version)
|
||||
|
||||
|
||||
def test_editor_override():
|
||||
|
||||
parsed_args = cli_as_dict('--config-override editor "nano"')
|
||||
assert parsed_args == expected_args(config_override=[["editor", "nano"]])
|
||||
|
||||
|
||||
def test_color_override():
|
||||
assert cli_as_dict("--config-override colors.body blue") == expected_args(
|
||||
config_override=[["colors.body", "blue"]]
|
||||
)
|
||||
|
||||
|
||||
def test_multiple_overrides():
|
||||
parsed_args = cli_as_dict(
|
||||
'--config-override colors.title green --config-override editor "nano" --config-override journal.scratchpad "/tmp/scratchpad"'
|
||||
)
|
||||
assert parsed_args == expected_args(
|
||||
config_override=[
|
||||
["colors.title", "green"],
|
||||
["editor", "nano"],
|
||||
["journal.scratchpad", "/tmp/scratchpad"],
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
# @see https://github.com/jrnl-org/jrnl/issues/520
|
||||
@pytest.mark.parametrize(
|
||||
"cli",
|
||||
[
|
||||
"-and second @oldtag @newtag",
|
||||
"second @oldtag @newtag -and",
|
||||
"second -and @oldtag @newtag",
|
||||
"second @oldtag -and @newtag",
|
||||
],
|
||||
)
|
||||
def test_and_ordering(cli):
|
||||
result = expected_args(strict=True, text=["second", "@oldtag", "@newtag"])
|
||||
assert cli_as_dict(cli) == result
|
||||
|
||||
|
||||
# @see https://github.com/jrnl-org/jrnl/issues/520
|
||||
@pytest.mark.parametrize(
|
||||
"cli",
|
||||
[
|
||||
"--edit second @oldtag @newtag",
|
||||
"second @oldtag @newtag --edit",
|
||||
"second --edit @oldtag @newtag",
|
||||
"second @oldtag --edit @newtag",
|
||||
],
|
||||
)
|
||||
def test_edit_ordering(cli):
|
||||
result = expected_args(edit=True, text=["second", "@oldtag", "@newtag"])
|
||||
assert cli_as_dict(cli) == result
|
||||
|
||||
|
||||
class TestDeserialization:
|
||||
@pytest.mark.parametrize(
|
||||
"input_str",
|
||||
[
|
||||
["editor", "nano"],
|
||||
["colors.title", "blue"],
|
||||
["default", "/tmp/egg.txt"],
|
||||
],
|
||||
)
|
||||
def test_deserialize_multiword_strings(self, input_str):
|
||||
|
||||
runtime_config = make_yaml_valid_dict(input_str)
|
||||
assert runtime_config.__class__ == dict
|
||||
assert input_str[0] in runtime_config.keys()
|
||||
assert runtime_config[input_str[0]] == input_str[1]
|
||||
|
||||
def test_deserialize_multiple_datatypes(self):
|
||||
cfg = make_yaml_valid_dict(["linewrap", "23"])
|
||||
assert cfg["linewrap"] == 23
|
||||
|
||||
cfg = make_yaml_valid_dict(["encrypt", "false"])
|
||||
assert cfg["encrypt"] == False
|
||||
|
||||
cfg = make_yaml_valid_dict(["editor", "vi -c startinsert"])
|
||||
assert cfg["editor"] == "vi -c startinsert"
|
||||
|
||||
cfg = make_yaml_valid_dict(["highlight", "true"])
|
||||
assert cfg["highlight"] == True
|
22
tests/unit/test_time.py
Normal file
22
tests/unit/test_time.py
Normal file
|
@ -0,0 +1,22 @@
|
|||
import datetime
|
||||
|
||||
from jrnl import time
|
||||
|
||||
|
||||
def test_default_hour_is_added():
|
||||
assert time.parse(
|
||||
"2020-06-20", inclusive=False, default_hour=9, default_minute=0, bracketed=False
|
||||
) == datetime.datetime(2020, 6, 20, 9)
|
||||
|
||||
|
||||
def test_default_minute_is_added():
|
||||
assert (
|
||||
time.parse(
|
||||
"2020-06-20",
|
||||
inclusive=False,
|
||||
default_hour=0,
|
||||
default_minute=30,
|
||||
bracketed=False,
|
||||
)
|
||||
== datetime.datetime(2020, 6, 20, 0, 30)
|
||||
)
|
Loading…
Add table
Add a link
Reference in a new issue