mirror of
https://github.com/jrnl-org/jrnl.git
synced 2025-07-03 23:16:14 +02:00
Merge branch 'develop' into #1170-alternate-config-file
This commit is contained in:
commit
70aa5989ea
133 changed files with 706 additions and 4869 deletions
|
@ -17,8 +17,8 @@ Feature: Delete entries from journal
|
|||
| config_file |
|
||||
| basic_onefile.yaml |
|
||||
| basic_encrypted.yaml |
|
||||
# | basic_folder.yaml | @todo
|
||||
# | basic_dayone.yaml | @todo
|
||||
| basic_folder.yaml |
|
||||
# | basic_dayone.yaml | @todo
|
||||
|
||||
|
||||
Scenario Outline: Backing out of interactive delete does not change journal
|
||||
|
@ -66,7 +66,7 @@ Feature: Delete entries from journal
|
|||
Examples: Configs
|
||||
| config_file |
|
||||
| basic_onefile.yaml |
|
||||
# | basic_folder.yaml | @todo
|
||||
| basic_folder.yaml |
|
||||
# | basic_dayone.yaml | @todo
|
||||
|
||||
|
||||
|
@ -82,7 +82,7 @@ Feature: Delete entries from journal
|
|||
Examples: Configs
|
||||
| config_file |
|
||||
| basic_onefile.yaml |
|
||||
# | basic_folder.yaml | @todo
|
||||
| basic_folder.yaml |
|
||||
# | basic_dayone.yaml | @todo
|
||||
|
||||
|
||||
|
@ -98,7 +98,7 @@ Feature: Delete entries from journal
|
|||
Examples: Configs
|
||||
| config_file |
|
||||
| basic_onefile.yaml |
|
||||
# | basic_folder.yaml | @todo
|
||||
| basic_folder.yaml |
|
||||
# | basic_dayone.yaml | @todo
|
||||
|
||||
|
||||
|
@ -114,7 +114,7 @@ Feature: Delete entries from journal
|
|||
Examples: Configs
|
||||
| config_file |
|
||||
| basic_onefile.yaml |
|
||||
# | basic_folder.yaml | @todo
|
||||
| basic_folder.yaml |
|
||||
# | basic_dayone.yaml | @todo
|
||||
|
||||
|
||||
|
@ -130,7 +130,7 @@ Feature: Delete entries from journal
|
|||
Examples: Configs
|
||||
| config_file |
|
||||
| basic_onefile.yaml |
|
||||
# | basic_folder.yaml | @todo
|
||||
| basic_folder.yaml |
|
||||
# | basic_dayone.yaml | @todo
|
||||
|
||||
|
||||
|
@ -146,7 +146,7 @@ Feature: Delete entries from journal
|
|||
Examples: Configs
|
||||
| config_file |
|
||||
| basic_onefile.yaml |
|
||||
# | basic_folder.yaml | @todo
|
||||
| basic_folder.yaml |
|
||||
# | basic_dayone.yaml | @todo
|
||||
|
||||
|
||||
|
@ -162,7 +162,7 @@ Feature: Delete entries from journal
|
|||
Examples: Configs
|
||||
| config_file |
|
||||
| basic_onefile.yaml |
|
||||
# | basic_folder.yaml | @todo
|
||||
| basic_folder.yaml |
|
||||
# | basic_dayone.yaml | @todo
|
||||
|
||||
|
||||
|
@ -178,5 +178,5 @@ Feature: Delete entries from journal
|
|||
Examples: Configs
|
||||
| config_file |
|
||||
| basic_onefile.yaml |
|
||||
# | basic_folder.yaml | @todo
|
||||
| basic_folder.yaml |
|
||||
# | basic_dayone.yaml | @todo
|
||||
|
|
|
@ -28,15 +28,37 @@ Feature: Encrypting and decrypting journals
|
|||
# This should warn the user that the journal is already encrypted
|
||||
|
||||
|
||||
Scenario: Encrypting a journal
|
||||
Scenario Outline: Encrypting a journal
|
||||
Given we use the config "simple.yaml"
|
||||
When we run "jrnl --encrypt" and enter
|
||||
swordfish
|
||||
swordfish
|
||||
n
|
||||
Then we should see the message "Journal encrypted"
|
||||
Then we should get no error
|
||||
And we should see the message "Journal encrypted"
|
||||
And the config for journal "default" should contain "encrypt: true"
|
||||
When we run "jrnl -n 1" and enter "swordfish"
|
||||
Then we should be prompted for a password
|
||||
And the output should contain "2013-06-10 15:40 Life is good"
|
||||
|
||||
|
||||
Scenario Outline: Running jrnl with encrypt: true on unencryptable journals
|
||||
Given we use the config "<config_file>"
|
||||
When we run "jrnl --config-override encrypt true here is a new entry"
|
||||
Then the error output should contain "this type of journal can't be encrypted"
|
||||
|
||||
Examples: configs
|
||||
| config_file |
|
||||
| basic_folder.yaml |
|
||||
| basic_dayone.yaml |
|
||||
|
||||
|
||||
Scenario Outline: Attempt to encrypt a folder or DayOne journal should result in an error
|
||||
Given we use the config "<config_file>"
|
||||
When we run "jrnl --encrypt"
|
||||
Then the error output should contain "can't be encrypted"
|
||||
|
||||
Examples: configs
|
||||
| config_file |
|
||||
| basic_folder.yaml |
|
||||
| basic_dayone.yaml |
|
||||
|
|
|
@ -1,5 +1,33 @@
|
|||
Feature: Custom formats
|
||||
|
||||
Scenario Outline: Short printing via --format flag
|
||||
Given we use the config "<config_file>"
|
||||
And we use the password "test" if prompted
|
||||
When we run "jrnl --format short -3"
|
||||
Then we should get no error
|
||||
|
||||
Examples: configs
|
||||
| config_file |
|
||||
| basic_onefile.yaml |
|
||||
| basic_encrypted.yaml |
|
||||
| basic_folder.yaml |
|
||||
| basic_dayone.yaml |
|
||||
|
||||
|
||||
Scenario Outline: Pretty Printing aka the Default
|
||||
Given we use the config "<config_file>"
|
||||
And we use the password "test" if prompted
|
||||
When we run "jrnl --format pretty -3"
|
||||
Then we should get no error
|
||||
|
||||
Examples: configs
|
||||
| config_file |
|
||||
| basic_onefile.yaml |
|
||||
| basic_encrypted.yaml |
|
||||
| basic_folder.yaml |
|
||||
| basic_dayone.yaml |
|
||||
|
||||
|
||||
Scenario Outline: JSON format
|
||||
Given we use the config "<config_file>"
|
||||
And we use the password "test" if prompted
|
||||
|
@ -296,6 +324,22 @@ Feature: Custom formats
|
|||
| basic_folder.yaml |
|
||||
| basic_dayone.yaml |
|
||||
|
||||
|
||||
Scenario Outline: Export fancy with small linewrap
|
||||
Given we use the config "<config_file>"
|
||||
And we use the password "test" if prompted
|
||||
When we run "jrnl --config-override linewrap 35 --format fancy -3"
|
||||
Then we should get no error
|
||||
And the output should be 35 columns wide
|
||||
|
||||
Examples: configs
|
||||
| config_file |
|
||||
| basic_onefile.yaml |
|
||||
| basic_encrypted.yaml |
|
||||
| basic_folder.yaml |
|
||||
| basic_dayone.yaml |
|
||||
|
||||
|
||||
@todo
|
||||
Scenario Outline: Exporting fancy
|
||||
# Needs better emoji support
|
||||
|
|
|
@ -11,7 +11,7 @@ Feature: Importing data
|
|||
| config_file |
|
||||
| basic_onefile.yaml |
|
||||
| basic_encrypted.yaml |
|
||||
# | basic_folder.yaml | @todo
|
||||
| basic_folder.yaml |
|
||||
# | basic_dayone.yaml | @todo
|
||||
|
||||
Scenario Outline: --import allows new large entry from stdin
|
||||
|
@ -34,7 +34,7 @@ Feature: Importing data
|
|||
| config_file |
|
||||
| basic_onefile.yaml |
|
||||
| basic_encrypted.yaml |
|
||||
# | basic_folder.yaml | @todo
|
||||
| basic_folder.yaml |
|
||||
# | basic_dayone.yaml | @todo
|
||||
|
||||
Scenario Outline: --import allows multiple new entries from stdin
|
||||
|
@ -56,7 +56,7 @@ Feature: Importing data
|
|||
| config_file |
|
||||
| basic_onefile.yaml |
|
||||
| basic_encrypted.yaml |
|
||||
# | basic_folder.yaml | @todo
|
||||
| basic_folder.yaml |
|
||||
# | basic_dayone.yaml | @todo
|
||||
|
||||
Scenario: --import allows import new entries from file
|
||||
|
|
|
@ -88,3 +88,9 @@ Feature: Multiple journals
|
|||
these three eyes
|
||||
n
|
||||
Then the output should contain "Encrypted journal 'new_encrypted' created"
|
||||
|
||||
Scenario: Read and write to journal with emoji name
|
||||
Given we use the config "multiple.yaml"
|
||||
When we run "jrnl ✨ Adding entry to sparkly journal"
|
||||
When we run "jrnl ✨ -1"
|
||||
Then the output should contain "Adding entry to sparkly journal"
|
||||
|
|
90
tests/bdd/features/override.feature
Normal file
90
tests/bdd/features/override.feature
Normal file
|
@ -0,0 +1,90 @@
|
|||
Feature: Implementing Runtime Overrides for Select Configuration Keys
|
||||
|
||||
Scenario: Override configured editor with built-in input === editor:''
|
||||
Given we use the config "basic_encrypted.yaml"
|
||||
And we use the password "test" if prompted
|
||||
When we run "jrnl --config-override editor ''"
|
||||
Then the stdin prompt should have been called
|
||||
And the editor should not have been called
|
||||
|
||||
|
||||
Scenario: Postconfig commands with overrides
|
||||
Given we use the config "basic_encrypted.yaml"
|
||||
And we use the password "test" if prompted
|
||||
When we run "jrnl --decrypt --config-override highlight false --config-override editor nano"
|
||||
Then the config in memory should contain "highlight: false"
|
||||
Then the editor should not have been called
|
||||
|
||||
|
||||
Scenario: Override configured linewrap with a value of 23
|
||||
Given we use the config "simple.yaml"
|
||||
And we use the password "test" if prompted
|
||||
When we run "jrnl -2 --config-override linewrap 23 --format fancy"
|
||||
Then the output should be
|
||||
┎─────╮2013-06-09 15:39
|
||||
┃ My ╘═══════════════╕
|
||||
┃ fir st ent ry. │
|
||||
┠╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
┃ Everything is │
|
||||
┃ alright │
|
||||
┖─────────────────────┘
|
||||
┎─────╮2013-06-10 15:40
|
||||
┃ Lif ╘═══════════════╕
|
||||
┃ e is goo d. │
|
||||
┠╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
┃ But I'm better. │
|
||||
┖─────────────────────┘
|
||||
|
||||
|
||||
Scenario: Override color selections with runtime overrides
|
||||
Given we use the config "basic_encrypted.yaml"
|
||||
And we use the password "test" if prompted
|
||||
When we run "jrnl -1 --config-override colors.body blue"
|
||||
Then the config in memory should contain "colors.body: blue"
|
||||
|
||||
|
||||
Scenario: Apply multiple config overrides
|
||||
Given we use the config "basic_encrypted.yaml"
|
||||
And we use the password "test" if prompted
|
||||
When we run "jrnl -1 --config-override colors.body green --config-override editor 'nano'"
|
||||
Then the config in memory should contain
|
||||
editor: nano
|
||||
colors:
|
||||
title: none
|
||||
body: green
|
||||
tags: none
|
||||
date: none
|
||||
|
||||
|
||||
Scenario: Override default journal
|
||||
Given we use the config "basic_dayone.yaml"
|
||||
And we use the password "test" if prompted
|
||||
When we run "jrnl --config-override journals.default features/journals/simple.journal 20 Mar 2000: The rain in Spain comes from clouds"
|
||||
Then we should get no error
|
||||
And we should see the message "Entry added"
|
||||
When we run "jrnl -3 --config-override journals.default features/journals/simple.journal"
|
||||
Then the output should be
|
||||
2000-03-20 09:00 The rain in Spain comes from clouds
|
||||
|
||||
2013-06-09 15:39 My first entry.
|
||||
| Everything is alright
|
||||
|
||||
2013-06-10 15:40 Life is good.
|
||||
| But I'm better.
|
||||
|
||||
|
||||
Scenario: Make an entry into an overridden journal
|
||||
Given we use the config "basic_dayone.yaml"
|
||||
And we use the password "test" if prompted
|
||||
When we run "jrnl --config-override journals.temp features/journals/simple.journal temp Sep 06 1969: @say Ni"
|
||||
Then we should get no error
|
||||
And we should see the message "Entry added"
|
||||
When we run "jrnl --config-override journals.temp features/journals/simple.journal temp -3"
|
||||
Then the output should be
|
||||
1969-09-06 09:00 @say Ni
|
||||
|
||||
2013-06-09 15:39 My first entry.
|
||||
| Everything is alright
|
||||
|
||||
2013-06-10 15:40 Life is good.
|
||||
| But I'm better.
|
|
@ -10,6 +10,7 @@ scenarios("features/file_storage.feature")
|
|||
scenarios("features/format.feature")
|
||||
scenarios("features/import.feature")
|
||||
scenarios("features/multiple_journals.feature")
|
||||
scenarios("features/override.feature")
|
||||
scenarios("features/password.feature")
|
||||
scenarios("features/search.feature")
|
||||
scenarios("features/star.feature")
|
||||
|
|
|
@ -12,6 +12,7 @@ journals:
|
|||
new_encrypted:
|
||||
encrypt: true
|
||||
journal: features/journals/new_encrypted.journal
|
||||
✨: features/journals/simple.journal
|
||||
linewrap: 80
|
||||
tagsymbols: '@'
|
||||
timeformat: '%Y-%m-%d %H:%M'
|
||||
|
|
|
@ -143,10 +143,15 @@ def user_input():
|
|||
|
||||
|
||||
@fixture
|
||||
def config_data(config_path):
|
||||
def config_on_disk(config_path):
|
||||
return load_config(config_path)
|
||||
|
||||
|
||||
@fixture
|
||||
def config_in_memory():
|
||||
return dict()
|
||||
|
||||
|
||||
@fixture
|
||||
def journal_name():
|
||||
return None
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Copyright (C) 2012-2021 jrnl contributors
|
||||
# License: https://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
import functools
|
||||
import os
|
||||
|
||||
|
||||
|
@ -38,3 +39,13 @@ def assert_equal_tags_ignoring_order(
|
|||
[actual_tags, expected_tags],
|
||||
[expected_content, actual_content],
|
||||
]
|
||||
|
||||
|
||||
# @see: https://stackoverflow.com/a/65782539/569146
|
||||
def get_nested_val(dictionary, path, *default):
|
||||
try:
|
||||
return functools.reduce(lambda x, y: x[y], path.split("."), dictionary)
|
||||
except KeyError:
|
||||
if default:
|
||||
return default[0]
|
||||
raise
|
||||
|
|
|
@ -15,6 +15,7 @@ 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
|
||||
|
||||
|
||||
@then("we should get no error")
|
||||
|
@ -84,6 +85,14 @@ def output_should_contain_version(cli_run, toml_version):
|
|||
assert toml_version in out, 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"]
|
||||
out_lines = out.splitlines()
|
||||
for line in out_lines:
|
||||
assert len(line) <= width
|
||||
|
||||
|
||||
@then(parse('we should see the message "{text}"'))
|
||||
def should_see_the_message(text, cli_run):
|
||||
out = cli_run["stderr"]
|
||||
|
@ -102,17 +111,18 @@ def should_see_the_message(text, cli_run):
|
|||
)
|
||||
@then(parse('the config {should_or_should_not} contain "{some_yaml}"'))
|
||||
@then(parse("the config {should_or_should_not} contain\n{some_yaml}"))
|
||||
def config_var(config_data, journal_name, should_or_should_not, some_yaml):
|
||||
def config_var_on_disk(config_on_disk, journal_name, should_or_should_not, some_yaml):
|
||||
we_should = parse_should_or_should_not(should_or_should_not)
|
||||
|
||||
actual = config_data
|
||||
actual = config_on_disk
|
||||
if journal_name:
|
||||
actual = actual["journals"][journal_name]
|
||||
|
||||
expected = yaml.load(some_yaml, Loader=yaml.FullLoader)
|
||||
expected = yaml.load(some_yaml, Loader=yaml.SafeLoader)
|
||||
|
||||
actual_slice = actual
|
||||
if type(actual) is dict:
|
||||
# `expected` objects formatted in yaml only compare one level deep
|
||||
actual_slice = {key: actual.get(key, None) for key in expected.keys()}
|
||||
|
||||
if we_should:
|
||||
|
@ -121,6 +131,40 @@ def config_var(config_data, journal_name, should_or_should_not, some_yaml):
|
|||
assert expected != actual_slice
|
||||
|
||||
|
||||
@then(
|
||||
parse(
|
||||
'the config in memory for journal "{journal_name}" {should_or_should_not} contain "{some_yaml}"'
|
||||
)
|
||||
)
|
||||
@then(
|
||||
parse(
|
||||
'the config in memory for journal "{journal_name}" {should_or_should_not} contain\n{some_yaml}'
|
||||
)
|
||||
)
|
||||
@then(parse('the config in memory {should_or_should_not} contain "{some_yaml}"'))
|
||||
@then(parse("the config in memory {should_or_should_not} contain\n{some_yaml}"))
|
||||
def config_var_in_memory(
|
||||
config_in_memory, journal_name, should_or_should_not, some_yaml
|
||||
):
|
||||
we_should = parse_should_or_should_not(should_or_should_not)
|
||||
|
||||
actual = config_in_memory["overrides"]
|
||||
if journal_name:
|
||||
actual = actual["journals"][journal_name]
|
||||
|
||||
expected = yaml.load(some_yaml, Loader=yaml.SafeLoader)
|
||||
|
||||
actual_slice = actual
|
||||
if type(actual) is dict:
|
||||
# `expected` objects formatted in yaml only compare one level deep
|
||||
actual_slice = {key: get_nested_val(actual, key) for key in expected.keys()}
|
||||
|
||||
if we_should:
|
||||
assert expected == actual_slice
|
||||
else:
|
||||
assert expected != actual_slice
|
||||
|
||||
|
||||
@then("we should be prompted for a password")
|
||||
def password_was_called(cli_run):
|
||||
assert cli_run["mocks"]["getpass"].called
|
||||
|
@ -137,15 +181,15 @@ def assert_dir_contains_files(file_list, cache_dir):
|
|||
|
||||
|
||||
@then(parse("the journal directory should contain\n{file_list}"))
|
||||
def journal_directory_should_contain(config_data, file_list):
|
||||
scoped_config = scope_config(config_data, "default")
|
||||
def journal_directory_should_contain(config_on_disk, file_list):
|
||||
scoped_config = scope_config(config_on_disk, "default")
|
||||
|
||||
assert does_directory_contain_files(file_list, scoped_config["journal"])
|
||||
|
||||
|
||||
@then(parse('journal "{journal_name}" should not exist'))
|
||||
def journal_directory_should_not_exist(config_data, journal_name):
|
||||
scoped_config = scope_config(config_data, journal_name)
|
||||
def journal_directory_should_not_exist(config_on_disk, journal_name):
|
||||
scoped_config = scope_config(config_on_disk, journal_name)
|
||||
|
||||
assert not does_directory_contain_files(
|
||||
scoped_config["journal"], "."
|
||||
|
@ -153,8 +197,8 @@ def journal_directory_should_not_exist(config_data, journal_name):
|
|||
|
||||
|
||||
@then(parse("the journal {should_or_should_not} exist"))
|
||||
def journal_should_not_exist(config_data, should_or_should_not):
|
||||
scoped_config = scope_config(config_data, "default")
|
||||
def journal_should_not_exist(config_on_disk, should_or_should_not):
|
||||
scoped_config = scope_config(config_on_disk, "default")
|
||||
expected_path = scoped_config["journal"]
|
||||
|
||||
contains_files = does_directory_contain_files(expected_path, ".")
|
||||
|
@ -301,15 +345,34 @@ def count_elements(number, item, cli_run):
|
|||
assert len(xml_tree.findall(".//" + item)) == number
|
||||
|
||||
|
||||
@then(parse("the editor should have been called"))
|
||||
@then(parse("the editor should have been called with {num_args} arguments"))
|
||||
def count_editor_args(num_args, cli_run, editor_state):
|
||||
assert cli_run["mocks"]["editor"].called
|
||||
@then(parse("the editor {should_or_should_not} have been called"))
|
||||
@then(
|
||||
parse(
|
||||
"the editor {should_or_should_not} have been called with {num_args} arguments"
|
||||
)
|
||||
)
|
||||
def count_editor_args(num_args, cli_run, editor_state, should_or_should_not):
|
||||
we_should = parse_should_or_should_not(should_or_should_not)
|
||||
|
||||
if we_should:
|
||||
assert cli_run["mocks"]["editor"].called
|
||||
else:
|
||||
assert not cli_run["mocks"]["editor"].called
|
||||
|
||||
if isinstance(num_args, int):
|
||||
assert len(editor_state["command"]) == int(num_args)
|
||||
|
||||
|
||||
@then(parse("the stdin prompt {should_or_should_not} have been called"))
|
||||
def stdin_prompt_called(cli_run, should_or_should_not):
|
||||
we_should = parse_should_or_should_not(should_or_should_not)
|
||||
|
||||
if we_should:
|
||||
assert cli_run["mocks"]["stdin"].called
|
||||
else:
|
||||
assert not cli_run["mocks"]["stdin"].called
|
||||
|
||||
|
||||
@then(parse('the editor filename should end with "{suffix}"'))
|
||||
def editor_filename_suffix(suffix, editor_state):
|
||||
editor_filename = editor_state["tmpfile"]["name"]
|
||||
|
|
|
@ -34,6 +34,7 @@ def when_we_change_directory(directory_name):
|
|||
def we_run(
|
||||
command,
|
||||
config_path,
|
||||
config_in_memory,
|
||||
user_input,
|
||||
cli_run,
|
||||
capsys,
|
||||
|
@ -63,7 +64,19 @@ def we_run(
|
|||
password = user_input
|
||||
|
||||
with ExitStack() as stack:
|
||||
# Always mock
|
||||
from jrnl.override import apply_overrides
|
||||
|
||||
def my_overrides(*args, **kwargs):
|
||||
result = apply_overrides(*args, **kwargs)
|
||||
config_in_memory["overrides"] = result
|
||||
return result
|
||||
|
||||
stack.enter_context(
|
||||
patch("jrnl.jrnl.apply_overrides", side_effect=my_overrides)
|
||||
)
|
||||
|
||||
# Conditionally mock
|
||||
stack.enter_context(patch("sys.argv", ["jrnl"] + args))
|
||||
|
||||
mock_stdin = stack.enter_context(
|
||||
|
|
|
@ -6,6 +6,8 @@ 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():
|
||||
|
@ -18,31 +20,61 @@ def minimal_config():
|
|||
return cfg
|
||||
|
||||
|
||||
def expected_args(overrides):
|
||||
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 Namespace(**{**default_args, **overrides})
|
||||
|
||||
|
||||
def test_apply_override(minimal_config):
|
||||
overrides = [["editor", "nano"]]
|
||||
apply_overrides(overrides, minimal_config)
|
||||
overrides = {"config_override": [["editor", "nano"]]}
|
||||
apply_overrides(expected_args(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"}
|
||||
overrides = {"config_override": [["colors.body", "blue"]]}
|
||||
apply_overrides(expected_args(overrides), minimal_config)
|
||||
assert minimal_config["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
|
||||
overrides = {
|
||||
"config_override": [
|
||||
["colors.title", "magenta"],
|
||||
["editor", "nano"],
|
||||
["journals.burner", "/tmp/journals/burner.jrnl"],
|
||||
]
|
||||
}
|
||||
|
||||
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"
|
||||
actual = apply_overrides(expected_args(overrides), minimal_config)
|
||||
assert actual["editor"] == "nano"
|
||||
assert actual["colors"]["title"] == "magenta"
|
||||
assert "burner" in actual["journals"]
|
||||
assert actual["journals"]["burner"] == "/tmp/journals/burner.jrnl"
|
||||
|
||||
|
||||
def test_recursively_apply():
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue