Merge branch 'develop' into duplicate-keys-1511

This commit is contained in:
Jonathan Wren 2022-07-16 13:54:20 -07:00
commit 552c92fe82
52 changed files with 459 additions and 444 deletions

View file

@ -0,0 +1,45 @@
Feature: Installing jrnl
Scenario: Install jrnl with default options
Given we use no config
When we run "jrnl hello world" and enter
\n
\n
Then the output should contain "Journal 'default' created"
And the default journal "journal.txt" should be in the "." directory
And the config should contain "encrypt: false"
And the version in the config file should be up-to-date
Scenario: Install jrnl with custom relative default journal path
Given we use no config
When we run "jrnl hello world" and enter
default/custom.txt
n
Then the output should contain "Journal 'default' created"
And the default journal "custom.txt" should be in the "default" directory
And the config should contain "encrypt: false"
And the version in the config file should be up-to-date
Scenario: Install jrnl with custom expanded default journal path
Given we use no config
And the home directory is called "home"
When we run "jrnl hello world" and enter
~/custom.txt
n
Then the output should contain "Journal 'default' created"
And the default journal "custom.txt" should be in the "home" directory
And the config should contain "encrypt: false"
And the version in the config file should be up-to-date
Scenario: Install jrnl with encrypted default journal
Given we use no config
When we run "jrnl hello world" and enter
encrypted.txt
y
Then the output should contain "Journal will be encrypted"
And the default journal "encrypted.txt" should be in the "." directory
And the config should contain "encrypt: true"
And the version in the config file should be up-to-date
When we run "jrnl"
Then we should be prompted for a password

View file

@ -13,6 +13,7 @@ scenarios("features/encrypt.feature")
scenarios("features/file_storage.feature")
scenarios("features/format.feature")
scenarios("features/import.feature")
scenarios("features/install.feature")
scenarios("features/multiple_journals.feature")
scenarios("features/override.feature")
scenarios("features/password.feature")

View file

@ -4,9 +4,8 @@
from pytest import mark
from pytest import skip
from jrnl.os_compat import on_windows
from jrnl.os_compat import on_posix
from jrnl.os_compat import on_windows
pytest_plugins = [
"tests.lib.fixtures",

View file

@ -1,23 +1,23 @@
# Copyright (C) 2012-2022 jrnl contributors
# License: https://www.gnu.org/licenses/gpl-3.0.html
from collections import defaultdict
import os
from pathlib import Path
import tempfile
from collections import defaultdict
from collections.abc import Iterable
from pathlib import Path
from unittest.mock import Mock
from unittest.mock import patch
import toml
from keyring import backend
from keyring import errors
from pytest import fixture
from unittest.mock import patch
from unittest.mock import Mock
from .helpers import get_fixture
import toml
from rich.console import Console
from jrnl.config import load_config
from jrnl.os_compat import split_args
from tests.lib.helpers import get_fixture
# --- Keyring --- #
@ -88,6 +88,7 @@ def cli_run(
mock_editor,
mock_user_input,
mock_overrides,
mock_default_journal_path,
):
# Check if we need more mocks
mock_factories.update(mock_args)
@ -96,6 +97,7 @@ def cli_run(
mock_factories.update(mock_editor)
mock_factories.update(mock_config_path)
mock_factories.update(mock_user_input)
mock_factories.update(mock_default_journal_path)
return {
"status": 0,
@ -164,6 +166,19 @@ def mock_config_path(request):
}
@fixture
def mock_default_journal_path(temp_dir):
journal_path = os.path.join(temp_dir.name, "journal.txt")
return {
"default_journal_path_install": lambda: patch(
"jrnl.install.get_default_journal_path", return_value=journal_path
),
"default_journal_path_config": lambda: patch(
"jrnl.config.get_default_journal_path", return_value=journal_path
),
}
@fixture
def temp_dir():
return tempfile.TemporaryDirectory()
@ -216,7 +231,9 @@ def mock_user_input(request, password_input, stdin_input):
return password_input
if isinstance(user_input, Iterable):
return next(user_input)
input_line = next(user_input)
# A raw newline is used to indicate deliberate empty input
return "" if input_line == r"\n" else input_line
# exceptions
return user_input if not kwargs["password"] else password_input

View file

@ -1,12 +1,12 @@
# Copyright (C) 2012-2022 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 datetime import datetime
from unittest.mock import MagicMock
from unittest.mock import patch
from xml.etree import ElementTree
@ -16,10 +16,9 @@ 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
from tests.lib.fixtures import FailedKeyring
from tests.lib.fixtures import TestKeyring
from tests.lib.helpers import get_fixture
@given(parse("we {editor_method} to the editor if opened\n{editor_input}"))
@ -147,3 +146,10 @@ def parse_output_as_language(cli_run, language_name):
assert False, f"Language name {language_name} not recognized"
return {"lang": language_name, "obj": parsed_output}
@given(parse('the home directory is called "{home_dir}"'))
def home_directory(temp_dir, home_dir, monkeypatch):
home_path = os.path.join(temp_dir.name, home_dir)
monkeypatch.setenv("USERPROFILE", home_path) # for windows
monkeypatch.setenv("HOME", home_path) # for *nix

View file

@ -11,11 +11,10 @@ from pytest_bdd.parsers import parse
from ruamel.yaml import YAML
from jrnl.config import scope_config
from .helpers import assert_equal_tags_ignoring_order
from .helpers import does_directory_contain_files
from .helpers import parse_should_or_should_not
from .helpers import get_nested_val
from tests.lib.helpers import assert_equal_tags_ignoring_order
from tests.lib.helpers import does_directory_contain_files
from tests.lib.helpers import get_nested_val
from tests.lib.helpers import parse_should_or_should_not
@then("we should get no error")
@ -97,6 +96,12 @@ def output_should_contain_version(cli_run, toml_version):
assert toml_version in out, toml_version
@then("the version in the config file should be up-to-date")
def config_file_version(config_on_disk, toml_version):
config_version = config_on_disk["version"]
assert config_version == toml_version
@then(parse("the output should be {width:d} columns wide"))
def output_should_be_columns_wide(cli_run, width):
out = cli_run["stdout"]
@ -105,6 +110,22 @@ def output_should_be_columns_wide(cli_run, width):
assert len(line) <= width
@then(
parse(
'the default journal "{journal_file}" should be in the "{journal_dir}" directory'
)
)
def default_journal_location(journal_file, journal_dir, config_on_disk, temp_dir):
default_journal_path = config_on_disk["journals"]["default"]
expected_journal_path = (
os.path.join(temp_dir.name, journal_file)
if journal_dir == "."
else os.path.join(temp_dir.name, journal_dir, journal_file)
)
# Use os.path.samefile here because both paths might not be fully expanded.
assert os.path.samefile(default_journal_path, expected_journal_path)
@then(
parse(
'the config for journal "{journal_name}" {should_or_should_not} contain "{some_yaml}"'

View file

@ -1,8 +1,8 @@
# Copyright (C) 2012-2022 jrnl contributors
# License: https://www.gnu.org/licenses/gpl-3.0.html
from contextlib import ExitStack
import os
from contextlib import ExitStack
from pytest_bdd import when
from pytest_bdd.parsers import parse
@ -23,6 +23,8 @@ def when_we_change_directory(directory_name):
command = '(?P<command>[^"]*)'
input_method = "(?P<input_method>enter|pipe|type)"
all_input = '("(?P<all_input>[^"]*)")'
# Note: A line with only a raw newline r'\n' is treated as
# an empty line of input internally for testing purposes.
@when(parse('we run "jrnl {command}" and {input_method}\n{all_input}'))

View file

@ -1,9 +1,9 @@
# Copyright (C) 2012-2022 jrnl contributors
# License: https://www.gnu.org/licenses/gpl-3.0.html
import pytest
from colorama import Fore
from colorama import Style
import pytest
from jrnl.color import colorize

View file

@ -1,11 +1,12 @@
# Copyright (C) 2012-2022 jrnl contributors
# License: https://www.gnu.org/licenses/gpl-3.0.html
import pytest
import os
from jrnl.install import find_alt_config
import pytest
from jrnl.exception import JrnlException
from jrnl.install import find_alt_config
def test_find_alt_config(request):

View file

@ -1,15 +1,15 @@
# Copyright (C) 2012-2022 jrnl contributors
# License: https://www.gnu.org/licenses/gpl-3.0.html
import random
import string
from unittest import mock
import pytest
import random
import string
import jrnl
from jrnl.jrnl import _display_search_results
from jrnl.args import parse_args
from jrnl.jrnl import _display_search_results
@pytest.fixture

View file

@ -1,6 +1,8 @@
# Copyright (C) 2012-2022 jrnl contributors
# License: https://www.gnu.org/licenses/gpl-3.0.html
from argparse import Namespace
import pytest
from jrnl.override import _convert_dots_to_list
@ -9,8 +11,6 @@ from jrnl.override import _get_key_and_value_from_pair
from jrnl.override import _recursively_apply
from jrnl.override import apply_overrides
from argparse import Namespace
@pytest.fixture()
def minimal_config():

View file

@ -1,16 +1,16 @@
# Copyright (C) 2012-2022 jrnl contributors
# License: https://www.gnu.org/licenses/gpl-3.0.html
import pytest
import random
import string
from os import getenv
from unittest.mock import patch
from jrnl.path import home_dir
from jrnl.path import expand_path
import pytest
from jrnl.path import absolute_path
from jrnl.path import expand_path
from jrnl.path import home_dir
@pytest.fixture